Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-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_tools_Grid_h
23 : #define __PLUMED_tools_Grid_h
24 :
25 : #include <vector>
26 : #include <array>
27 : #include <string>
28 : #include <map>
29 : #include <cmath>
30 : #include <memory>
31 : #include <cstddef>
32 :
33 : #include "Exception.h"
34 :
35 : namespace PLMD {
36 :
37 :
38 : // simple function to enable various weighting
39 :
40 : class WeightBase {
41 : public:
42 : virtual double projectInnerLoop(double &input, double &v)=0;
43 : virtual double projectOuterLoop(double &v)=0;
44 : virtual ~WeightBase() {}
45 : };
46 :
47 3 : class BiasWeight:public WeightBase {
48 : public:
49 : double beta,invbeta;
50 : double shift=0.0;
51 3 : explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
52 : //double projectInnerLoop(double &input, double &v) override {return input+exp(beta*v);}
53 : //double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
54 13603 : double projectInnerLoop(double &input, double &v) override {
55 13603 : auto betav=beta*v;
56 13603 : auto x=betav-shift;
57 13603 : if(x>0) {
58 1187 : shift=betav;
59 1187 : return input*std::exp(-x)+1;
60 : } else {
61 12416 : return input+std::exp(x);
62 : }
63 : }
64 187 : double projectOuterLoop(double &v) override {
65 187 : auto res=-invbeta*(std::log(v)+shift);
66 187 : shift=0.0;
67 187 : return res;
68 : }
69 : };
70 :
71 : class ProbWeight:public WeightBase {
72 : public:
73 : double beta,invbeta;
74 : explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
75 : double projectInnerLoop(double &input, double &v) override {return input+v;}
76 : double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
77 : };
78 :
79 :
80 :
81 :
82 :
83 :
84 : class Value;
85 : class IFile;
86 : class OFile;
87 : class KernelFunctions;
88 : class Communicator;
89 :
90 : /// \ingroup TOOLBOX
91 : class GridBase
92 : {
93 : public:
94 : // we use a size_t here
95 : // should be 8 bytes on all 64-bit machines
96 : // and more portable than "unsigned long long"
97 : typedef std::size_t index_t;
98 : // to restore old implementation (unsigned) use the following instead:
99 : // typedef unsigned index_t;
100 : /// Maximum dimension (exaggerated value).
101 : /// Can be used to replace local std::vectors with std::arrays (allocated on stack).
102 : static constexpr std::size_t maxdim=16;
103 :
104 :
105 : /**
106 : Auxiliary class for accelerating grid calculations.
107 :
108 : Many functions in the Grid class have loops running over the dimensions.
109 : These loops are always with a little number of iterations, so would likely
110 : benefit unrolling. Even better, if the compiler knew the dimension a priori
111 : it could remove the loops in most common cases (e.g. dimension=1 or 2).
112 :
113 : To obtain this, I added this AcceleratorBase class. Specifically:
114 : - Any method in the Grid class that is a bottleneck in performance and
115 : has a loop can be moved to this auxiliary class.
116 : - The method should be declared here as a pure virtual function
117 : of class AcceleratorBase. The implementation instead goes in
118 : class Accelerator
119 : - Class Accelerator is derived from AcceleratorBase but depends on
120 : dimension as a template variable.
121 : - The function AcceleratorBase::create takes case of constructing
122 : accelerators for each possible value of dimension.
123 :
124 : The trick works because we don't expect dimension to ever be very
125 : high. By restricting it to <=16, we can have a limited number of
126 : compiled instances. The compiler will choose at runtime which one should
127 : be used.
128 :
129 : This class, as well as the derived classes, are expected to be
130 : empty. In other words, they only contain the pointer to a virtual
131 : table that the compiler will use to call the proper implementation
132 : variant, with the correct dimension.
133 :
134 : \warning
135 : Interface might change at any time.
136 : Do not use this outside of class GridBase and children.
137 : */
138 : class AcceleratorBase {
139 : public:
140 : /// Creates an accelerator with proper dimension
141 : static std::unique_ptr<AcceleratorBase> create(unsigned dim);
142 : virtual ~AcceleratorBase() = default;
143 : /// Can be used to check which value of dimension was used
144 : virtual unsigned getDimension() const=0;
145 : virtual std::vector<GridBase::index_t> getNeighbors(const GridBase& grid, const std::vector<unsigned> & nbin_,const std::vector<bool> & pbc_,const unsigned* indices,std::size_t indices_size, const std::vector<unsigned> &nneigh) const=0;
146 : virtual GridBase::index_t getIndex(const GridBase& grid, const std::vector<unsigned> & nbin_, const unsigned* indices,std::size_t indices_size) const=0;
147 : virtual void getPoint(const std::vector<double> & min_,const std::vector<double> & dx_, const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const=0;
148 : virtual void getIndices(const std::vector<unsigned> & nbin_, GridBase::index_t index, unsigned* indices, std::size_t indices_size) const=0;
149 : virtual void getIndices(const std::vector<double> & min_,const std::vector<double> & dx_, const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const=0;
150 : };
151 :
152 : /**
153 : Auxiliary class for managing AcceleratorBase.
154 :
155 : class GridBase should contain a std::unique_ptr<AcceleratorBase>, which
156 : can be used to access the specialized versions. However, this would
157 : make a GridBase object not copyable. Instead of redefining
158 : copy constructor and copy assignment for GridBase, which has a lot of
159 : members, we use this wrapper class that just manages the lifetime
160 : of the underlying Accelerator object.
161 :
162 : The underlying object is made accessible through the -> operator,
163 : so that one can simply call functions as accelerator->function.
164 :
165 : \warning
166 : Interface might change at any time.
167 : Do not use this outside of class GridBase and children.
168 : */
169 2963 : class AcceleratorHandler {
170 : /// This is the underlying pointer.
171 : std::unique_ptr<AcceleratorBase> ptr;
172 : public:
173 : /// Enable access to methods of AcceleratorBase
174 : const AcceleratorBase* operator->() const {
175 : return ptr.get();
176 : }
177 : /// Enable access to methods of AcceleratorBase
178 : AcceleratorBase* operator->() {
179 : return ptr.get();
180 : }
181 : /// Conversion to bool allows to check if the ptr has been set
182 : explicit operator bool() const noexcept {
183 : return bool(ptr);
184 : }
185 : /// Move constructor
186 49 : AcceleratorHandler(const AcceleratorHandler& other):
187 49 : ptr((other.ptr?AcceleratorBase::create(other->getDimension()):nullptr))
188 49 : {}
189 : /// Move assignment
190 1457 : AcceleratorHandler & operator=(const AcceleratorHandler & other) {
191 1457 : if(this!=&other) {
192 : ptr.reset();
193 2914 : if(other.ptr) ptr=AcceleratorBase::create(other->getDimension());
194 : }
195 1457 : return *this;
196 : }
197 : /// Constructor without arguments result in a non-usable accelerator (dimension is unspecified)
198 : AcceleratorHandler() = default;
199 : /// Constructor with an argument creates an accelerator with a fixed dimensionality
200 1457 : AcceleratorHandler(unsigned dimension):
201 1457 : ptr(AcceleratorBase::create(dimension))
202 : {}
203 : };
204 :
205 : protected:
206 : AcceleratorHandler accelerator;
207 : std::string funcname;
208 : std::vector<std::string> argnames;
209 : std::vector<std::string> str_min_, str_max_;
210 : std::vector<double> min_,max_,dx_;
211 : std::vector<unsigned> nbin_;
212 : std::vector<bool> pbc_;
213 : index_t maxsize_;
214 : unsigned dimension_;
215 : bool dospline_, usederiv_;
216 : std::string fmt_; // format for output
217 : /// get "neighbors" for spline
218 : unsigned getSplineNeighbors(const unsigned* indices, std::size_t indices_size, index_t* neighbors, std::size_t neighbors_size)const;
219 : // std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
220 :
221 :
222 : public:
223 : /// this constructor here is Value-aware
224 : GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
225 : const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
226 : bool usederiv);
227 : /// this constructor here is not Value-aware
228 : GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
229 : const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
230 : bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
231 : const std::vector<std::string> &pmax );
232 : /// this is the real initializator
233 : void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
234 : const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
235 : const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
236 : /// get lower boundary
237 : std::vector<std::string> getMin() const;
238 : /// get upper boundary
239 : std::vector<std::string> getMax() const;
240 : /// get bin size
241 : std::vector<double> getDx() const;
242 : double getDx(index_t j) const ;
243 : /// get bin volume
244 : double getBinVolume() const;
245 : /// get number of bins
246 : std::vector<unsigned> getNbin() const;
247 : /// get if periodic
248 : std::vector<bool> getIsPeriodic() const;
249 : /// get grid dimension
250 : unsigned getDimension() const;
251 : /// get argument names of this grid
252 : std::vector<std::string> getArgNames() const;
253 : /// get if the grid has derivatives
254 1986398 : bool hasDerivatives() const {return usederiv_;}
255 :
256 : /// methods to handle grid indices
257 : void getIndices(index_t index, std::vector<unsigned>& rindex) const;
258 : void getIndices(index_t index, unsigned* rindex_data, std::size_t rindex_size) const;
259 : void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
260 : void getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const;
261 : std::vector<unsigned> getIndices(index_t index) const;
262 : std::vector<unsigned> getIndices(const std::vector<double> & x) const;
263 : index_t getIndex(const unsigned* indices,std::size_t indices_size) const;
264 : index_t getIndex(const std::vector<unsigned> & indices) const;
265 : index_t getIndex(const std::vector<double> & x) const;
266 : std::vector<double> getPoint(index_t index) const;
267 : std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
268 : std::vector<double> getPoint(const std::vector<double> & x) const;
269 : /// faster versions relying on preallocated vectors
270 : void getPoint(index_t index,std::vector<double> & point) const;
271 : void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
272 : void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
273 : void getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const;
274 : void getPoint(const unsigned* indices_data,std::size_t indices_size,double* point,std::size_t point_size) const;
275 :
276 : /// get neighbors
277 : std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
278 : std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
279 : std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
280 : /// get nearest neighbors (those separated by exactly one lattice unit)
281 : std::vector<index_t> getNearestNeighbors(const index_t index) const;
282 : std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
283 :
284 : /// write header for grid file
285 : void writeHeader(OFile& file);
286 :
287 : /// read grid from file
288 : static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
289 : /// read grid from file and check boundaries are what is expected from input
290 : static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&, IFile&,
291 : const std::vector<std::string>&,const std::vector<std::string>&,
292 : const std::vector<unsigned>&,bool,bool,bool);
293 : /// get grid size
294 : virtual index_t getSize() const=0;
295 : /// get grid value
296 : virtual double getValue(index_t index) const=0;
297 : double getValue(const std::vector<unsigned> & indices) const;
298 : double getValue(const std::vector<double> & x) const;
299 : /// get grid value and derivatives
300 : virtual double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const=0;
301 : double getValueAndDerivatives(index_t index, std::vector<double>& der) const;
302 : double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
303 : double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
304 :
305 : /// set grid value
306 : virtual void setValue(index_t index, double value)=0;
307 : void setValue(const std::vector<unsigned> & indices, double value);
308 : /// set grid value and derivatives
309 : virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
310 : void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
311 : /// add to grid value
312 : virtual void addValue(index_t index, double value)=0;
313 : void addValue(const std::vector<unsigned> & indices, double value);
314 : /// add to grid value and derivatives
315 : virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
316 : void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
317 : /// add a kernel function to the grid
318 : void addKernel( const KernelFunctions& kernel );
319 :
320 : /// get minimum value
321 : virtual double getMinValue() const = 0;
322 : /// get maximum value
323 : virtual double getMaxValue() const = 0;
324 :
325 : /// dump grid on file
326 : virtual void writeToFile(OFile&)=0;
327 : /// dump grid to gaussian cube file
328 : void writeCubeFile(OFile&, const double& lunit);
329 :
330 3012 : virtual ~GridBase() = default;
331 :
332 : /// set output format
333 197 : void setOutputFmt(const std::string & ss) {fmt_=ss;}
334 : /// reset output format to the default %14.9f format
335 : void resetToDefaultOutputFmt() {fmt_="%14.9f";}
336 : ///
337 : /// Find the maximum over paths of the minimum value of the gridded function along the paths
338 : /// for all paths of neighboring grid lattice points from a source point to a sink point.
339 : double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
340 : };
341 :
342 : class Grid : public GridBase
343 : {
344 : std::vector<double> grid_;
345 : std::vector<double> der_;
346 : double contour_location=0.0;
347 : public:
348 1323 : Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
349 : const std::vector<std::string> & gmax,
350 1323 : const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
351 1323 : GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
352 : {
353 1323 : grid_.assign(maxsize_,0.0);
354 1323 : if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
355 1323 : }
356 : /// this constructor here is not Value-aware
357 128 : Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
358 : const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
359 : bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
360 128 : const std::vector<std::string> &pmax ):
361 128 : GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
362 : {
363 128 : grid_.assign(maxsize_,0.0);
364 128 : if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
365 128 : }
366 : index_t getSize() const override;
367 : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
368 : using GridBase::getValue;
369 : using GridBase::getValueAndDerivatives;
370 : using GridBase::setValue;
371 : using GridBase::setValueAndDerivatives;
372 : using GridBase::addValue;
373 : using GridBase::addValueAndDerivatives;
374 : /// get grid value
375 : double getValue(index_t index) const override;
376 : /// get grid value and derivatives
377 : double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
378 : /// set grid value
379 : void setValue(index_t index, double value) override;
380 : /// set grid value and derivatives
381 : void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
382 : /// add to grid value
383 : void addValue(index_t index, double value) override;
384 : /// add to grid value and derivatives
385 : void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
386 :
387 : /// get minimum value
388 : double getMinValue() const override;
389 : /// get maximum value
390 : double getMaxValue() const override;
391 : /// Scale all grid values and derivatives by a constant factor
392 : void scaleAllValuesAndDerivatives( const double& scalef );
393 : /// Takes the scalef times the logarithm of all grid values and derivatives
394 : void logAllValuesAndDerivatives( const double& scalef );
395 : /// dump grid on file
396 : void writeToFile(OFile&) override;
397 :
398 : /// Set the minimum value of the grid to zero and translates accordingly
399 : void setMinToZero();
400 : /// apply function: takes pointer to function that accepts a double and apply
401 : void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
402 : /// Get the difference from the contour
403 : double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
404 : /// Find a set of points on a contour in the function
405 : void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
406 : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
407 : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
408 : /// to enable many types of weighting
409 : Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj );
410 : void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
411 : void mpiSumValuesAndDerivatives( Communicator& comm );
412 : /// Integrate the function calculated on the grid
413 : double integrate( std::vector<unsigned>& npoints );
414 : void clear();
415 : };
416 :
417 :
418 : class SparseGrid : public GridBase
419 : {
420 :
421 : std::map<index_t,double> map_;
422 : std::map< index_t,std::vector<double> > der_;
423 :
424 : public:
425 6 : SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
426 : const std::vector<std::string> & gmax,
427 6 : const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
428 6 : GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
429 :
430 : index_t getSize() const override;
431 : index_t getMaxSize() const;
432 :
433 : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
434 : using GridBase::getValue;
435 : using GridBase::getValueAndDerivatives;
436 : using GridBase::setValue;
437 : using GridBase::setValueAndDerivatives;
438 : using GridBase::addValue;
439 : using GridBase::addValueAndDerivatives;
440 :
441 : /// get grid value
442 : double getValue(index_t index) const override;
443 : /// get grid value and derivatives
444 : double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
445 :
446 : /// set grid value
447 : void setValue(index_t index, double value) override;
448 : /// set grid value and derivatives
449 : void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
450 : /// add to grid value
451 : void addValue(index_t index, double value) override;
452 : /// add to grid value and derivatives
453 : void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
454 :
455 : /// get minimum value
456 : double getMinValue() const override;
457 : /// get maximum value
458 : double getMaxValue() const override;
459 : /// dump grid on file
460 : void writeToFile(OFile&) override;
461 :
462 18 : virtual ~SparseGrid() = default;
463 : };
464 :
465 :
466 : inline
467 5900587 : GridBase::index_t GridBase::getIndex(const unsigned* indices,std::size_t indices_size) const {
468 : plumed_dbg_assert(accelerator);
469 5900587 : return accelerator->getIndex(*this,nbin_,indices,indices_size);
470 : }
471 :
472 : inline
473 4791554 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
474 : plumed_dbg_assert(indices.size()==dimension_);
475 4791554 : return getIndex(indices.data(),indices.size());
476 : }
477 :
478 : inline
479 1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
480 : plumed_dbg_assert(x.size()==dimension_);
481 : std::array<unsigned,maxdim> indices;
482 1100069 : getIndices(x,indices.data(),dimension_);
483 1100069 : return getIndex(indices.data(),dimension_);
484 : }
485 :
486 : inline
487 7877712 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
488 7877712 : std::vector<unsigned> indices(dimension_);
489 7877712 : getIndices(index,indices.data(),indices.size());
490 7877712 : return indices;
491 : }
492 :
493 : inline
494 37819738 : void GridBase::getIndices(index_t index, unsigned* indices, std::size_t indices_size) const {
495 37819738 : plumed_assert(indices_size==dimension_);
496 37819738 : plumed_assert(accelerator);
497 37819738 : accelerator->getIndices(nbin_,index,indices,dimension_);
498 37819738 : }
499 :
500 : inline
501 : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
502 : if (indices.size()!=dimension_) indices.resize(dimension_);
503 : getIndices(index,indices.data(),indices.size());
504 : }
505 :
506 : inline
507 : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
508 : plumed_dbg_assert(x.size()==dimension_);
509 : std::vector<unsigned> indices(dimension_);
510 : getIndices(x,indices);
511 : return indices;
512 : }
513 :
514 : inline
515 : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
516 : indices.resize(dimension_);
517 : getIndices(x,indices.data(),indices.size());
518 : }
519 :
520 : inline
521 1103807 : void GridBase::getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const {
522 : plumed_dbg_assert(x.size()==dimension_);
523 : plumed_dbg_assert(rindex_size==dimension_);
524 1103807 : accelerator->getIndices(min_,dx_,x,rindex_data,rindex_size);
525 1103807 : }
526 :
527 : inline
528 32656902 : void GridBase::getPoint(const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const {
529 : plumed_dbg_assert(indices_size==dimension_);
530 : plumed_dbg_assert(point_size==dimension_);
531 : plumed_dbg_assert(accelerator);
532 32656902 : accelerator->getPoint(min_,dx_,indices,indices_size,point,point_size);
533 32656902 : }
534 :
535 : inline
536 2720102 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
537 : plumed_dbg_assert(indices.size()==dimension_);
538 2720102 : std::vector<double> x(dimension_);
539 2720102 : getPoint(indices,x);
540 2720102 : return x;
541 : }
542 :
543 : inline
544 28822337 : std::vector<double> GridBase::getPoint(index_t index) const {
545 : plumed_dbg_assert(index<maxsize_);
546 28822337 : std::vector<double> x(dimension_);
547 28822337 : getPoint(index,x);
548 28822337 : return x;
549 : }
550 :
551 : inline
552 : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
553 : plumed_dbg_assert(x.size()==dimension_);
554 : std::vector<double> r(dimension_);
555 : getPoint(x,r);
556 : return r;
557 : }
558 :
559 : inline
560 29933062 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
561 : plumed_dbg_assert(index<maxsize_);
562 : std::array<unsigned,maxdim> indices;
563 29933062 : getIndices(index,indices.data(),dimension_);
564 29933062 : getPoint(indices.data(),dimension_,point);
565 29933062 : }
566 :
567 : inline
568 2720102 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
569 : plumed_dbg_assert(indices.size()==dimension_);
570 : plumed_dbg_assert(point.size()==dimension_);
571 2720102 : getPoint(indices.data(),indices.size(),point.data(),point.size());
572 2720102 : }
573 :
574 : inline
575 29933062 : void GridBase::getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const {
576 : plumed_dbg_assert(indices_size==dimension_);
577 : plumed_dbg_assert(point.size()==dimension_);
578 29933062 : getPoint(indices_data,indices_size,point.data(),point.size());
579 29933062 : }
580 :
581 : inline
582 : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
583 : plumed_dbg_assert(x.size()==dimension_);
584 : std::array<unsigned,maxdim> indices;
585 : getIndices(x,indices.data(),dimension_);
586 : getPoint(indices.data(),dimension_,point.data(),point.size());
587 : }
588 :
589 : inline
590 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
591 : plumed_dbg_assert(accelerator);
592 : return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),indices.size(),nneigh);
593 : }
594 :
595 : inline
596 4223 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
597 : plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
598 : std::array<unsigned,maxdim> indices;
599 : plumed_dbg_assert(accelerator);
600 4223 : accelerator->getIndices(min_,dx_,x,indices.data(),dimension_);
601 4223 : return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
602 : }
603 :
604 : inline
605 19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
606 : plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
607 : std::array<unsigned,maxdim> indices;
608 : plumed_dbg_assert(accelerator);
609 19153 : accelerator->getIndices(nbin_,index,indices.data(),dimension_);
610 19153 : return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
611 : }
612 :
613 :
614 :
615 :
616 :
617 : }
618 :
619 : #endif
|