Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #ifndef __PLUMED_gridtools_GridVessel_h 23 : #define __PLUMED_gridtools_GridVessel_h 24 : 25 : #include <string> 26 : #include <cstring> 27 : #include <vector> 28 : #include "vesselbase/AveragingVessel.h" 29 : 30 : namespace PLMD { 31 : namespace gridtools { 32 : 33 : class GridVessel : public vesselbase::AveragingVessel { 34 : friend class ActionWithInputGrid; 35 : friend class DumpGrid; 36 : private: 37 : /// The way that grid points are constructed 38 : enum {flat,fibonacci} gtype; 39 : /// Have the minimum and maximum for the grid been set 40 : bool bounds_set; 41 : /// The number of points in the grid 42 : unsigned npoints; 43 : /// Stuff for fibonacci grids 44 : double root5, golden, igolden, log_golden2; 45 : /// Fib increment here is equal to 2*pi*(INVERSE GOLDEN RATIO) 46 : double fib_offset, fib_increment, fib_shift; 47 : std::vector<std::vector<unsigned> > fib_nlist; 48 : /// Units for Gaussian Cube file 49 : double cube_units; 50 : /// This flag is used to check if the user has created a valid input 51 : bool foundprint; 52 : /// The minimum and maximum of the grid stored as doubles 53 : std::vector<double> min, max; 54 : /// The numerical distance between adjacent grid points 55 : std::vector<unsigned> stride; 56 : /// The number of bins in each grid direction 57 : std::vector<unsigned> nbin; 58 : /// The grid point that was requested last by getGridPointCoordinates 59 : unsigned currentGridPoint; 60 : /// The forces that will be output at the end of the calculation 61 : std::vector<double> finalForces; 62 : protected: 63 : /// Is forced 64 : bool wasforced; 65 : /// Forces acting on grid elements 66 : std::vector<double> forces; 67 : /// Do we have derivatives 68 : bool noderiv; 69 : /// The names of the various columns in the grid file 70 : std::vector<std::string> arg_names; 71 : /// The number of pieces of information we are storing for each 72 : /// point in the grid 73 : unsigned nper; 74 : /// Is this direction periodic 75 : std::vector<bool> pbc; 76 : /// The minimum and maximum in the grid stored as strings 77 : std::vector<std::string> str_min, str_max; 78 : /// The spacing between grid points 79 : std::vector<double> dx; 80 : /// The dimensionality of the grid 81 : unsigned dimension; 82 : /// Which grid points are we actively accumulating 83 : std::vector<bool> active; 84 : /// Convert a point in space the the correspoinding grid point 85 : unsigned getIndex( const std::vector<double>& p ) const ; 86 : /// Get the index of the closest point on the fibonacci sphere 87 : unsigned getFibonacciIndex( const std::vector<double>& p ) const ; 88 : /// Get the flat grid coordinates 89 : void getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const ; 90 : /// Get the coordinates on the Fibonacci grid 91 : void getFibonacciCoordinates( const unsigned& ipoint, std::vector<double>& x ) const ; 92 : public: 93 : /// keywords 94 : static void registerKeywords( Keywords& keys ); 95 : /// Constructor 96 : explicit GridVessel( const vesselbase::VesselOptions& ); 97 : /// Remove the derivatives 98 : void setNoDerivatives(); 99 : /// Get the type of grid we are using 100 : std::string getType() const ; 101 : /// Set the minimum and maximum of the grid 102 : virtual void setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax, const std::vector<unsigned>& nbins, const std::vector<double>& spacing ); 103 : /// Get the cutoff to use for the Fibonacci spheres 104 : virtual double getFibonacciCutoff() const ; 105 : /// Setup the grid if it is a fibonacci grid on the surface of a sphere 106 : void setupFibonacciGrid( const unsigned& np ); 107 : /// Get a description of the grid to output to the log 108 : std::string description() override; 109 : /// Convert an index into indices 110 : void convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const ; 111 : /// Flatten the grid and get the grid index for a point 112 : unsigned getIndex( const std::vector<unsigned>& indices ) const ; 113 : /// Get the indices fof a point 114 : void getIndices( const unsigned& index, std::vector<unsigned>& indices ) const ; 115 : /// Get the indices of a particular point 116 : void getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const ; 117 : /// Operations on one of the elements of grid point i 118 : void setGridElement( const unsigned&, const unsigned&, const double& ); 119 : /// Add data to an element of the grid 120 : void addToGridElement( const unsigned& ipoint, const unsigned& jelement, const double& value ); 121 : /// Operations on one of the elements of grid point specified by vector 122 : double getGridElement( const std::vector<unsigned>&, const unsigned& ) const ; 123 : void setGridElement( const std::vector<unsigned>&, const unsigned&, const double& ); 124 : /// Set the values and derivatives of a particular element 125 : void setValueAndDerivatives( const unsigned&, const unsigned&, const double&, const std::vector<double>& ); 126 : /// Set the size of the buffer equal to nper*npoints 127 : void resize() override; 128 : /// Get the number of points in the grid 129 : unsigned getNumberOfPoints() const; 130 : /// Get the coordinates for a point in the grid 131 : void getGridPointCoordinates( const unsigned&, std::vector<double>& ) const ; 132 : void getGridPointCoordinates( const unsigned&, std::vector<unsigned>&, std::vector<double>& ) const ; 133 : /// Get the dimensionality of the function 134 : unsigned getDimension() const ; 135 : /// Get the number of components in the vector stored on each grid point 136 : virtual unsigned getNumberOfComponents() const ; 137 : /// Is the grid periodic in the ith direction 138 : bool isPeriodic( const unsigned& i ) const ; 139 : /// Get the number of quantities we have stored at each grid point 140 : unsigned getNumberOfQuantities() const ; 141 : /// Get the number of grid points for each dimension 142 : std::vector<unsigned> getNbin() const ; 143 : /// Get the name of the ith component 144 : std::string getComponentName( const unsigned& i ) const ; 145 : /// Get the vector containing the minimum value of the grid in each dimension 146 : std::vector<std::string> getMin() const ; 147 : /// Get the vector containing the maximum value of the grid in each dimension 148 : std::vector<std::string> getMax() const ; 149 : /// Get the number of points needed in the buffer 150 : virtual unsigned getNumberOfBufferPoints() const ; 151 : /// Get the stride (the distance between the grid points of an index) 152 : const std::vector<unsigned>& getStride() const ; 153 : /// Return the volume of one of the grid cells 154 : double getCellVolume() const ; 155 : /// Get the value of the ith grid element 156 : virtual double getGridElement( const unsigned&, const unsigned& ) const ; 157 : /// Get the set of points neighouring a particular location in space 158 : void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh, 159 : unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ; 160 : /// Get the neighbors for a set of indices of a point 161 : void getNeighbors( const std::vector<unsigned>& indices, const std::vector<unsigned>& nneigh, 162 : unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const ; 163 : /// Get the points neighboring a particular spline point 164 : void getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const ; 165 : /// Get the spacing between grid points 166 : const std::vector<double>& getGridSpacing() const ; 167 : /// Get the extent of the grid in one of the axis 168 : double getGridExtent( const unsigned& i ) const ; 169 : /// Copy data from the action into the grid 170 : void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override; 171 : /// Finish the calculation 172 : void finish( const std::vector<double>& buffer ) override; 173 : /// This ensures that Gaussian cube fies are in correct units 174 : void setCubeUnits( const double& units ); 175 : /// This ensures that Gaussian cube files are in correct units 176 : double getCubeUnits() const ; 177 : /// Return a string containing the input to the grid so we can clone it 178 : std::string getInputString() const ; 179 : /// Does this have derivatives 180 : bool noDerivatives() const ; 181 : /// Get the value and derivatives at a particular location using spline interpolation 182 : double getValueAndDerivatives( const std::vector<double>& x, const unsigned& ind, std::vector<double>& der ) const ; 183 : /// Deactivate all the grid points 184 : void activateThesePoints( const std::vector<bool>& to_activate ); 185 : /// Is this point active 186 : bool inactive( const unsigned& ip ) const ; 187 : /// This retrieves the final force 188 0 : virtual void getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) { 189 0 : plumed_error(); 190 : } 191 : /// Apply the forces 192 : void setForce( const std::vector<double>& inforces ); 193 : /// Was a force added to the grid 194 : bool wasForced() const ; 195 : /// And retrieve the forces 196 : bool applyForce( std::vector<double>& fforces ) override; 197 : }; 198 : 199 : inline 200 : unsigned GridVessel::getNumberOfQuantities() const { 201 440217 : return nper; 202 : } 203 : 204 : inline 205 : unsigned GridVessel::getNumberOfPoints() const { 206 873010 : return npoints; 207 : } 208 : 209 : inline 210 611 : const std::vector<double>& GridVessel::getGridSpacing() const { 211 611 : if( gtype==flat ) { 212 611 : return dx; 213 : } 214 0 : plumed_merror("dont understand what spacing means for spherical grids"); 215 : } 216 : 217 : inline 218 4 : double GridVessel::getCellVolume() const { 219 4 : if( gtype==flat ) { 220 : double myvol=1.0; 221 8 : for(unsigned i=0; i<dimension; ++i) { 222 5 : myvol *= dx[i]; 223 : } 224 : return myvol; 225 : } else { 226 1 : return 4*pi / static_cast<double>( getNumberOfPoints() ); 227 : } 228 : } 229 : 230 : inline 231 : unsigned GridVessel::getDimension() const { 232 938458 : return dimension; 233 : } 234 : 235 : inline 236 : bool GridVessel::isPeriodic( const unsigned& i ) const { 237 : plumed_dbg_assert( gtype==flat ); 238 7859 : return pbc[i]; 239 : } 240 : 241 : inline 242 : std::string GridVessel::getComponentName( const unsigned& i ) const { 243 1012634 : return arg_names[i]; 244 : } 245 : 246 : inline 247 47 : unsigned GridVessel::getNumberOfComponents() const { 248 47 : if( noderiv ) { 249 15 : return nper; 250 : } 251 32 : return nper / ( dimension + 1 ); 252 : } 253 : 254 : inline 255 : double GridVessel::getGridExtent( const unsigned& i ) const { 256 : plumed_dbg_assert( gtype==flat ); 257 40 : return max[i] - min[i]; 258 : } 259 : 260 : inline 261 : bool GridVessel::noDerivatives() const { 262 14312 : return noderiv; 263 : } 264 : 265 : inline 266 21151408 : bool GridVessel::inactive( const unsigned& ip ) const { 267 : plumed_dbg_assert( ip<npoints ); 268 21151408 : return !active[ip]; 269 : } 270 : 271 : inline 272 : const std::vector<unsigned>& GridVessel::getStride() const { 273 : plumed_dbg_assert( gtype==flat ); 274 : return stride; 275 : } 276 : 277 : inline 278 71 : unsigned GridVessel::getNumberOfBufferPoints() const { 279 321 : return npoints; 280 : } 281 : 282 : inline 283 26251 : std::string GridVessel::getType() const { 284 26251 : if( gtype==flat ) { 285 25829 : return "flat"; 286 422 : } else if( gtype==fibonacci ) { 287 422 : return "fibonacci"; 288 : } 289 0 : plumed_error(); 290 : } 291 : 292 : inline 293 2 : double GridVessel::getFibonacciCutoff() const { 294 2 : return 0.0; 295 : } 296 : 297 : } 298 : } 299 : #endif