Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2021 The VES code team
3 : (see the PEOPLE-VES file at the root of this folder for a list of names)
4 :
5 : See http://www.ves-code.org for more information.
6 :
7 : This file is part of VES code module.
8 :
9 : The VES code module 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 : The VES code module 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 the VES code module. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #ifndef __PLUMED_ves_BasisFunctions_h
23 : #define __PLUMED_ves_BasisFunctions_h
24 :
25 : #include "core/Action.h"
26 :
27 : #include <vector>
28 : #include <string>
29 : #include <cmath>
30 :
31 :
32 : #define PLUMED_VES_BASISFUNCTIONS_INIT(ao) BasisFunctions(ao)
33 :
34 : namespace PLMD {
35 :
36 : /**
37 : \ingroup INHERIT
38 : Abstract base class for implenting new 1D basis sets.
39 : */
40 :
41 : class Action;
42 : class Grid;
43 :
44 : namespace ves {
45 :
46 : class VesBias;
47 : class TargetDistribution;
48 :
49 : class BasisFunctions :
50 : public Action {
51 : private:
52 : // print extra info about the basis set
53 : bool print_debug_info_;
54 : // to check if the basis set has been defined
55 : bool has_been_set;
56 : // description of the basis set
57 : std::string description_;
58 : // the type of the basis set
59 : std::string type_;
60 : // the maximum order of the basis functions
61 : unsigned int norder_;
62 : // the total number of basis functions
63 : unsigned int nbasis_;
64 : // the keywords used to invoke the basis set
65 : std::vector<std::string> bf_keywords_;
66 : // prefix for the basis function labels
67 : std::string bf_label_prefix_;
68 : // label of each basis function
69 : std::vector<std::string> bf_labels_;
70 : // if the basis functions are periodic or not
71 : bool periodic_;
72 : // if the basis functions are defined on a bounded interval or not
73 : bool interval_bounded_;
74 : // the intrinsic interval of the basis functions
75 : std::string interval_intrinsic_min_str_;
76 : std::string interval_intrinsic_max_str_;
77 : double interval_intrinsic_min_;
78 : double interval_intrinsic_max_;
79 : double interval_intrinsic_range_;
80 : double interval_intrinsic_mean_;
81 : // the defined (translated) interval of the basis functions
82 : std::string interval_min_str_;
83 : std::string interval_max_str_;
84 : double interval_min_;
85 : double interval_max_;
86 : double interval_range_;
87 : double interval_mean_;
88 : // the derivative term in the chain rule coming from the translation of the interval
89 : double argT_derivf_;
90 : // calculate numerically the integrals of the basis functions over the intervals
91 : bool numerical_uniform_integrals_;
92 : unsigned int nbins_;
93 : // the integrals of the basis functions over the interval on which they are defined
94 : std::vector <double> uniform_integrals_;
95 : //
96 : VesBias* vesbias_pntr_;
97 : Action* action_pntr_;
98 : //
99 : void getAllValuesNumericalDerivs(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
100 :
101 : protected:
102 : // setup various stuff
103 : void setupBF();
104 : void setupInterval();
105 : void setNumericalIntegrationBins(const unsigned int nbins) {
106 : nbins_=nbins;
107 : }
108 : void numericalUniformIntegrals();
109 : std::vector<double> numericalTargetDistributionIntegralsFromGrid(const Grid*) const ;
110 : virtual void setupLabels();
111 : virtual void setupUniformIntegrals();
112 : template<typename T>
113 : void addKeywordToList(const std::string&, const T);
114 : template<typename T>
115 : void addKeywordToList(const std::string&, const std::vector<T>&);
116 : void addKeywordToList(const std::string&, const bool);
117 : //
118 : void setPeriodic() {
119 111 : periodic_=true;
120 8 : }
121 : void setNonPeriodic() {
122 138 : periodic_=false;
123 57 : }
124 : void setIntervalBounded() {
125 249 : interval_bounded_=true;
126 : }
127 : void setIntervalNonBounded() {
128 : interval_bounded_=false;
129 : }
130 : void setType(const std::string& type_in) {
131 249 : type_=type_in;
132 249 : }
133 : void setDescription(const std::string& description_in) {
134 249 : description_=description_in;
135 249 : }
136 : //
137 : void setNumberOfBasisFunctions(const unsigned int);
138 : void setOrder(const unsigned int norder_in) {
139 12 : norder_=norder_in;
140 : }
141 : void setIntrinsicInterval(const double, const double);
142 : void setIntrinsicInterval(const std::string&, const std::string&);
143 : void setInterval(const double, const double);
144 : void setInterval(const std::string&, const std::string&);
145 : //
146 : double intrinsicIntervalMin() const {
147 : return interval_intrinsic_min_;
148 : }
149 : double intrinsicIntervalMax() const {
150 1752567 : return interval_intrinsic_max_;
151 : }
152 : std::string intrinsicIntervalMinStr() const {
153 : return interval_intrinsic_min_str_;
154 : }
155 : std::string intrinsicIntervalMaxStr() const {
156 : return interval_intrinsic_max_str_;
157 : }
158 : //
159 : void setUniformIntegral(const unsigned int, const double);
160 : void setUniformIntegrals(const std::vector<double>&);
161 : void setAllUniformIntegralsToZero();
162 : //
163 : void setLabelPrefix(const std::string&);
164 : void setLabel(const unsigned int, const std::string&);
165 : void setLabels(const std::vector<std::string>&);
166 :
167 : public:
168 : static void registerKeywords(Keywords&);
169 : explicit BasisFunctions(const ActionOptions&ao);
170 : bool hasBeenSet() const {
171 : return has_been_set;
172 : }
173 : std::string getType() const {
174 : return type_;
175 : }
176 : std::string getDescription() const {
177 : return description_;
178 : }
179 : unsigned int getOrder() const {
180 33615870 : return norder_;
181 : }
182 : unsigned int getNumberOfBasisFunctions() const {
183 13201612 : return nbasis_;
184 : }
185 : unsigned int numberOfBasisFunctions() const {
186 112559 : return nbasis_;
187 : }
188 : unsigned int getSize() const {
189 : return nbasis_;
190 : }
191 : bool arePeriodic() const {
192 2661456 : return periodic_;
193 : }
194 : bool intervalBounded() const {
195 : return interval_bounded_;
196 : }
197 : double intervalMin() const {
198 204981 : return interval_min_;
199 : }
200 : double intervalMax() const {
201 281 : return interval_max_;
202 : }
203 : double intervalRange() const {
204 300134 : return interval_range_;
205 : }
206 : double intervalMean() const {
207 : return interval_mean_;
208 : }
209 : double intervalDerivf() const {
210 30352118 : return argT_derivf_;
211 : }
212 : std::string intervalMinStr() const {
213 601 : return interval_min_str_;
214 : }
215 : std::string intervalMaxStr() const {
216 601 : return interval_max_str_;
217 : }
218 : std::vector<double> getUniformIntegrals() const {
219 133 : return uniform_integrals_;
220 : }
221 : std::vector<double> getTargetDistributionIntegrals(const TargetDistribution*) const;
222 : //
223 : std::vector<std::string> getKeywordList() const {
224 : return bf_keywords_;
225 : }
226 : std::string getKeywordString() const;
227 : //
228 : std::string getBasisFunctionLabel(const unsigned int index) const {
229 787685 : return bf_labels_[index];
230 : }
231 : std::vector<std::string> getBasisFunctionLabels() const {
232 : return bf_labels_;
233 : }
234 : //
235 : void linkVesBias(VesBias*);
236 : void linkAction(Action*);
237 : VesBias* getPntrToVesBias() const;
238 : Action* getPntrToAction() const;
239 : //
240 : double translateArgument(const double, bool&) const;
241 : double checkIfArgumentInsideInterval(const double, bool&) const;
242 : //
243 0 : void apply() override {};
244 0 : void calculate() override {};
245 : // calculate the value for the n-th basis function
246 : double getValue(const double, const unsigned int, double&, bool&) const;
247 : // calculate the values for all basis functions
248 : virtual void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const = 0;
249 : //virtual void get2ndDerivatives(const double, std::vector<double>&)=0;
250 : void printInfo() const;
251 : //
252 : void getMultipleValue(const std::vector<double>&, std::vector<double>&, std::vector<std::vector<double> >&, std::vector<std::vector<double> >&, const bool numerical_deriv=false) const;
253 : void writeBasisFunctionsToFile(OFile&, OFile&, const std::string& min_in, const std::string& max_in, unsigned int nbins=1000, const bool ignore_periodicity=false, const std::string& output_fmt_values="%15.8f", const std::string& output_fmt_derivs="%15.8f", const bool numerical_deriv=false) const;
254 : };
255 :
256 :
257 : inline
258 249 : void BasisFunctions::setNumberOfBasisFunctions(const unsigned int nbasis_in) {
259 249 : nbasis_=nbasis_in;
260 249 : bf_labels_.assign(nbasis_,"");
261 249 : uniform_integrals_.assign(nbasis_,0.0);
262 249 : }
263 :
264 :
265 : inline
266 : VesBias* BasisFunctions::getPntrToVesBias() const {
267 : plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
268 : return vesbias_pntr_;
269 : }
270 :
271 :
272 : inline
273 : Action* BasisFunctions::getPntrToAction() const {
274 : plumed_massert(action_pntr_!=NULL,"the action has not been linked");
275 : return action_pntr_;
276 : }
277 :
278 :
279 : inline
280 : void BasisFunctions::setUniformIntegral(const unsigned index, const double value) {
281 264 : uniform_integrals_[index] = value;
282 : }
283 :
284 :
285 : inline
286 : void BasisFunctions::setUniformIntegrals(const std::vector<double>& uniform_integrals_in) {
287 : plumed_assert(uniform_integrals_in.size()==nbasis_);
288 : uniform_integrals_ = uniform_integrals_in;
289 : }
290 :
291 :
292 : inline
293 159 : void BasisFunctions::setAllUniformIntegralsToZero() {
294 159 : uniform_integrals_.assign(nbasis_,0.0);
295 159 : }
296 :
297 : inline
298 : void BasisFunctions::setLabelPrefix(const std::string& bf_label_prefix_in) {
299 68 : bf_label_prefix_ = bf_label_prefix_in;
300 68 : }
301 :
302 :
303 : inline
304 : void BasisFunctions::setLabel(const unsigned int index, const std::string& label) {
305 1140 : bf_labels_[index] = label;
306 3238 : }
307 :
308 :
309 : inline
310 : void BasisFunctions::setLabels(const std::vector<std::string>& bf_labels_in) {
311 : bf_labels_ = bf_labels_in;
312 : }
313 :
314 :
315 : inline
316 : double BasisFunctions::translateArgument(const double arg, bool& inside_interval) const {
317 : // NOTE: only works for symmetric intrinsic intervals
318 : inside_interval=true;
319 4895662 : double argT = (arg-interval_mean_)*argT_derivf_;
320 4895662 : if(argT < interval_intrinsic_min_) {
321 433 : inside_interval=false;
322 433 : argT=interval_intrinsic_min_;
323 4895229 : } else if(argT > interval_intrinsic_max_) {
324 13665 : inside_interval=false;
325 13665 : argT=interval_intrinsic_max_;
326 : }
327 : return argT;
328 : }
329 :
330 :
331 : inline
332 : double BasisFunctions::checkIfArgumentInsideInterval(const double arg, bool& inside_interval) const {
333 62249 : inside_interval=true;
334 : double argT = arg;
335 947044 : if(arg < interval_min_) {
336 362 : inside_interval=false;
337 362 : argT=interval_min_;
338 946682 : } else if(arg > interval_max_) {
339 369 : inside_interval=false;
340 369 : argT=interval_max_;
341 : }
342 : return argT;
343 : }
344 :
345 :
346 :
347 : template<typename T>
348 877 : void BasisFunctions::addKeywordToList(const std::string& keyword, const T value) {
349 : std::string str_value;
350 877 : Tools::convert(value,str_value);
351 1754 : bf_keywords_.push_back(keyword+"="+str_value);
352 877 : }
353 :
354 :
355 : template<typename T>
356 2 : void BasisFunctions::addKeywordToList(const std::string& keyword, const std::vector<T>& values) {
357 : std::string str_value;
358 : std::string str_keywordvalues;
359 2 : Tools::convert(values[0],str_value);
360 4 : str_keywordvalues = keyword + "=" + str_value;
361 5 : for(unsigned int i=1; i<values.size(); i++) {
362 3 : Tools::convert(values[i],str_value);
363 6 : str_keywordvalues += "," + str_value;
364 : }
365 2 : bf_keywords_.push_back(str_keywordvalues);
366 2 : }
367 :
368 :
369 : inline
370 : void BasisFunctions::addKeywordToList(const std::string& keyword, const bool value) {
371 81 : if(value) {
372 19 : bf_keywords_.push_back(keyword);
373 : }
374 : }
375 :
376 :
377 : }
378 : }
379 :
380 : #endif
|