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 implementing 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 139 : periodic_=false;
123 57 : }
124 : void setIntervalBounded() {
125 250 : interval_bounded_=true;
126 : }
127 : void setIntervalNonBounded() {
128 : interval_bounded_=false;
129 : }
130 : void setType(const std::string& type_in) {
131 250 : type_=type_in;
132 250 : }
133 : void setDescription(const std::string& description_in) {
134 250 : description_=description_in;
135 250 : }
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 33616204 : return norder_;
181 : }
182 : unsigned int getNumberOfBasisFunctions() const {
183 13201725 : 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 2661457 : 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 30352451 : return argT_derivf_;
211 : }
212 : std::string intervalMinStr() const {
213 602 : return interval_min_str_;
214 : }
215 : std::string intervalMaxStr() const {
216 602 : return interval_max_str_;
217 : }
218 : std::vector<double> getUniformIntegrals() const {
219 134 : 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 787689 : 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 : void printInfo() const;
250 : //
251 : 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;
252 : 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;
253 : };
254 :
255 :
256 : inline
257 250 : void BasisFunctions::setNumberOfBasisFunctions(const unsigned int nbasis_in) {
258 250 : nbasis_=nbasis_in;
259 250 : bf_labels_.assign(nbasis_,"");
260 250 : uniform_integrals_.assign(nbasis_,0.0);
261 250 : }
262 :
263 :
264 : inline
265 : VesBias* BasisFunctions::getPntrToVesBias() const {
266 : plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
267 : return vesbias_pntr_;
268 : }
269 :
270 :
271 : inline
272 : Action* BasisFunctions::getPntrToAction() const {
273 : plumed_massert(action_pntr_!=NULL,"the action has not been linked");
274 : return action_pntr_;
275 : }
276 :
277 :
278 : inline
279 : void BasisFunctions::setUniformIntegral(const unsigned index, const double value) {
280 265 : uniform_integrals_[index] = value;
281 : }
282 :
283 :
284 : inline
285 : void BasisFunctions::setUniformIntegrals(const std::vector<double>& uniform_integrals_in) {
286 : plumed_assert(uniform_integrals_in.size()==nbasis_);
287 : uniform_integrals_ = uniform_integrals_in;
288 : }
289 :
290 :
291 : inline
292 160 : void BasisFunctions::setAllUniformIntegralsToZero() {
293 160 : uniform_integrals_.assign(nbasis_,0.0);
294 160 : }
295 :
296 : inline
297 : void BasisFunctions::setLabelPrefix(const std::string& bf_label_prefix_in) {
298 69 : bf_label_prefix_ = bf_label_prefix_in;
299 69 : }
300 :
301 :
302 : inline
303 : void BasisFunctions::setLabel(const unsigned int index, const std::string& label) {
304 1140 : bf_labels_[index] = label;
305 3238 : }
306 :
307 :
308 : inline
309 : void BasisFunctions::setLabels(const std::vector<std::string>& bf_labels_in) {
310 : bf_labels_ = bf_labels_in;
311 : }
312 :
313 :
314 : inline
315 : double BasisFunctions::translateArgument(const double arg, bool& inside_interval) const {
316 : // NOTE: only works for symmetric intrinsic intervals
317 : inside_interval=true;
318 4895773 : double argT = (arg-interval_mean_)*argT_derivf_;
319 4895773 : if(argT < interval_intrinsic_min_) {
320 445 : inside_interval=false;
321 445 : argT=interval_intrinsic_min_;
322 4895328 : } else if(argT > interval_intrinsic_max_) {
323 13677 : inside_interval=false;
324 13677 : argT=interval_intrinsic_max_;
325 : }
326 : return argT;
327 : }
328 :
329 :
330 : inline
331 : double BasisFunctions::checkIfArgumentInsideInterval(const double arg, bool& inside_interval) const {
332 62249 : inside_interval=true;
333 : double argT = arg;
334 947044 : if(arg < interval_min_) {
335 362 : inside_interval=false;
336 362 : argT=interval_min_;
337 946682 : } else if(arg > interval_max_) {
338 369 : inside_interval=false;
339 369 : argT=interval_max_;
340 : }
341 : return argT;
342 : }
343 :
344 :
345 :
346 : template<typename T>
347 880 : void BasisFunctions::addKeywordToList(const std::string& keyword, const T value) {
348 : std::string str_value;
349 880 : Tools::convert(value,str_value);
350 1760 : bf_keywords_.push_back(keyword+"="+str_value);
351 880 : }
352 :
353 :
354 : template<typename T>
355 2 : void BasisFunctions::addKeywordToList(const std::string& keyword, const std::vector<T>& values) {
356 : std::string str_value;
357 : std::string str_keywordvalues;
358 2 : Tools::convert(values[0],str_value);
359 2 : str_keywordvalues = keyword + "=" + str_value;
360 5 : for(unsigned int i=1; i<values.size(); i++) {
361 3 : Tools::convert(values[i],str_value);
362 3 : str_keywordvalues += "," + str_value;
363 : }
364 2 : bf_keywords_.push_back(str_keywordvalues);
365 5 : }
366 :
367 :
368 : inline
369 : void BasisFunctions::addKeywordToList(const std::string& keyword, const bool value) {
370 82 : if(value) {
371 19 : bf_keywords_.push_back(keyword);
372 : }
373 : }
374 :
375 :
376 : }
377 : }
378 :
379 : #endif
|