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 : {
52 : private:
53 : // print extra info about the basis set
54 : bool print_debug_info_;
55 : // to check if the basis set has been defined
56 : bool has_been_set;
57 : // description of the basis set
58 : std::string description_;
59 : // the type of the basis set
60 : std::string type_;
61 : // the maximum order of the basis functions
62 : unsigned int norder_;
63 : // the total number of basis functions
64 : unsigned int nbasis_;
65 : // the keywords used to invoke the basis set
66 : std::vector<std::string> bf_keywords_;
67 : // prefix for the basis function labels
68 : std::string bf_label_prefix_;
69 : // label of each basis function
70 : std::vector<std::string> bf_labels_;
71 : // if the basis functions are periodic or not
72 : bool periodic_;
73 : // if the basis functions are defined on a bounded interval or not
74 : bool interval_bounded_;
75 : // the intrinsic interval of the basis functions
76 : std::string interval_intrinsic_min_str_;
77 : std::string interval_intrinsic_max_str_;
78 : double interval_intrinsic_min_;
79 : double interval_intrinsic_max_;
80 : double interval_intrinsic_range_;
81 : double interval_intrinsic_mean_;
82 : // the defined (translated) interval of the basis functions
83 : std::string interval_min_str_;
84 : std::string interval_max_str_;
85 : double interval_min_;
86 : double interval_max_;
87 : double interval_range_;
88 : double interval_mean_;
89 : // the derivative term in the chain rule coming from the translation of the interval
90 : double argT_derivf_;
91 : // calculate numerically the integrals of the basis functions over the intervals
92 : bool numerical_uniform_integrals_;
93 : unsigned int nbins_;
94 : // the integrals of the basis functions over the interval on which they are defined
95 : std::vector <double> uniform_integrals_;
96 : //
97 : VesBias* vesbias_pntr_;
98 : Action* action_pntr_;
99 : //
100 : void getAllValuesNumericalDerivs(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
101 :
102 : protected:
103 : // setup various stuff
104 : void setupBF();
105 : void setupInterval();
106 : void setNumericalIntegrationBins(const unsigned int nbins) {nbins_=nbins;}
107 : void numericalUniformIntegrals();
108 : std::vector<double> numericalTargetDistributionIntegralsFromGrid(const Grid*) const ;
109 : virtual void setupLabels();
110 : virtual void setupUniformIntegrals();
111 : template<typename T>
112 : void addKeywordToList(const std::string&, const T);
113 : template<typename T>
114 : void addKeywordToList(const std::string&, const std::vector<T>&);
115 : void addKeywordToList(const std::string&, const bool);
116 : //
117 111 : void setPeriodic() {periodic_=true;}
118 138 : void setNonPeriodic() {periodic_=false;}
119 249 : void setIntervalBounded() {interval_bounded_=true;}
120 : void setIntervalNonBounded() {interval_bounded_=false;}
121 249 : void setType(const std::string& type_in) {type_=type_in;}
122 249 : void setDescription(const std::string& description_in) {description_=description_in;}
123 : //
124 : void setNumberOfBasisFunctions(const unsigned int);
125 12 : void setOrder(const unsigned int norder_in) {norder_=norder_in;}
126 : void setIntrinsicInterval(const double, const double);
127 : void setIntrinsicInterval(const std::string&, const std::string&);
128 : void setInterval(const double, const double);
129 : void setInterval(const std::string&, const std::string&);
130 : //
131 : double intrinsicIntervalMin() const {return interval_intrinsic_min_;}
132 1752567 : double intrinsicIntervalMax() const {return interval_intrinsic_max_;}
133 : std::string intrinsicIntervalMinStr() const {return interval_intrinsic_min_str_;}
134 : std::string intrinsicIntervalMaxStr() const {return interval_intrinsic_max_str_;}
135 : //
136 : void setUniformIntegral(const unsigned int, const double);
137 : void setUniformIntegrals(const std::vector<double>&);
138 : void setAllUniformIntegralsToZero();
139 : //
140 : void setLabelPrefix(const std::string&);
141 : void setLabel(const unsigned int, const std::string&);
142 : void setLabels(const std::vector<std::string>&);
143 :
144 : public:
145 : static void registerKeywords(Keywords&);
146 : explicit BasisFunctions(const ActionOptions&ao);
147 : bool hasBeenSet() const {return has_been_set;}
148 : std::string getType() const {return type_;}
149 : std::string getDescription() const {return description_;}
150 33615870 : unsigned int getOrder() const {return norder_;}
151 13201612 : unsigned int getNumberOfBasisFunctions() const {return nbasis_;}
152 112559 : unsigned int numberOfBasisFunctions() const {return nbasis_;}
153 : unsigned int getSize() const {return nbasis_;}
154 2661456 : bool arePeriodic() const {return periodic_;}
155 : bool intervalBounded() const {return interval_bounded_;}
156 204981 : double intervalMin() const {return interval_min_;}
157 281 : double intervalMax() const {return interval_max_;}
158 300134 : double intervalRange() const {return interval_range_;}
159 : double intervalMean() const {return interval_mean_;}
160 30352118 : double intervalDerivf() const {return argT_derivf_;}
161 601 : std::string intervalMinStr() const {return interval_min_str_;}
162 601 : std::string intervalMaxStr() const {return interval_max_str_;}
163 133 : std::vector<double> getUniformIntegrals() const {return uniform_integrals_;}
164 : std::vector<double> getTargetDistributionIntegrals(const TargetDistribution*) const;
165 : //
166 : std::vector<std::string> getKeywordList() const {return bf_keywords_;}
167 : std::string getKeywordString() const;
168 : //
169 787685 : std::string getBasisFunctionLabel(const unsigned int index) const {return bf_labels_[index];}
170 : std::vector<std::string> getBasisFunctionLabels() const {return bf_labels_;}
171 : //
172 : void linkVesBias(VesBias*);
173 : void linkAction(Action*);
174 : VesBias* getPntrToVesBias() const;
175 : Action* getPntrToAction() const;
176 : //
177 : double translateArgument(const double, bool&) const;
178 : double checkIfArgumentInsideInterval(const double, bool&) const;
179 : //
180 0 : void apply() override {};
181 0 : void calculate() override {};
182 : // calculate the value for the n-th basis function
183 : double getValue(const double, const unsigned int, double&, bool&) const;
184 : // calculate the values for all basis functions
185 : virtual void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const = 0;
186 : //virtual void get2ndDerivatives(const double, std::vector<double>&)=0;
187 : void printInfo() const;
188 : //
189 : 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;
190 : 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;
191 : };
192 :
193 :
194 : inline
195 249 : void BasisFunctions::setNumberOfBasisFunctions(const unsigned int nbasis_in) {
196 249 : nbasis_=nbasis_in;
197 249 : bf_labels_.assign(nbasis_,"");
198 249 : uniform_integrals_.assign(nbasis_,0.0);
199 249 : }
200 :
201 :
202 : inline
203 : VesBias* BasisFunctions::getPntrToVesBias() const {
204 : plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
205 : return vesbias_pntr_;
206 : }
207 :
208 :
209 : inline
210 : Action* BasisFunctions::getPntrToAction() const {
211 : plumed_massert(action_pntr_!=NULL,"the action has not been linked");
212 : return action_pntr_;
213 : }
214 :
215 :
216 : inline
217 : void BasisFunctions::setUniformIntegral(const unsigned index, const double value) {
218 264 : uniform_integrals_[index] = value;
219 : }
220 :
221 :
222 : inline
223 : void BasisFunctions::setUniformIntegrals(const std::vector<double>& uniform_integrals_in) {
224 : plumed_assert(uniform_integrals_in.size()==nbasis_);
225 : uniform_integrals_ = uniform_integrals_in;
226 : }
227 :
228 :
229 : inline
230 159 : void BasisFunctions::setAllUniformIntegralsToZero() {
231 159 : uniform_integrals_.assign(nbasis_,0.0);
232 159 : }
233 :
234 : inline
235 : void BasisFunctions::setLabelPrefix(const std::string& bf_label_prefix_in) {
236 68 : bf_label_prefix_ = bf_label_prefix_in;
237 68 : }
238 :
239 :
240 : inline
241 : void BasisFunctions::setLabel(const unsigned int index, const std::string& label) {
242 1140 : bf_labels_[index] = label;
243 3238 : }
244 :
245 :
246 : inline
247 : void BasisFunctions::setLabels(const std::vector<std::string>& bf_labels_in) {
248 : bf_labels_ = bf_labels_in;
249 : }
250 :
251 :
252 : inline
253 : double BasisFunctions::translateArgument(const double arg, bool& inside_interval) const {
254 : // NOTE: only works for symmetric intrinsic intervals
255 : inside_interval=true;
256 4895662 : double argT = (arg-interval_mean_)*argT_derivf_;
257 4895662 : if(argT < interval_intrinsic_min_) {
258 433 : inside_interval=false;
259 433 : argT=interval_intrinsic_min_;
260 : }
261 4895229 : else if(argT > interval_intrinsic_max_) {
262 13665 : inside_interval=false;
263 13665 : argT=interval_intrinsic_max_;
264 : }
265 : return argT;
266 : }
267 :
268 :
269 : inline
270 : double BasisFunctions::checkIfArgumentInsideInterval(const double arg, bool& inside_interval) const {
271 62249 : inside_interval=true;
272 : double argT = arg;
273 947044 : if(arg < interval_min_) {
274 362 : inside_interval=false;
275 362 : argT=interval_min_;
276 : }
277 946682 : else if(arg > interval_max_) {
278 369 : inside_interval=false;
279 369 : argT=interval_max_;
280 : }
281 : return argT;
282 : }
283 :
284 :
285 :
286 : template<typename T>
287 877 : void BasisFunctions::addKeywordToList(const std::string& keyword, const T value) {
288 : std::string str_value;
289 877 : Tools::convert(value,str_value);
290 1754 : bf_keywords_.push_back(keyword+"="+str_value);
291 877 : }
292 :
293 :
294 : template<typename T>
295 2 : void BasisFunctions::addKeywordToList(const std::string& keyword, const std::vector<T>& values) {
296 : std::string str_value;
297 : std::string str_keywordvalues;
298 2 : Tools::convert(values[0],str_value);
299 4 : str_keywordvalues = keyword + "=" + str_value;
300 5 : for(unsigned int i=1; i<values.size(); i++) {
301 3 : Tools::convert(values[i],str_value);
302 6 : str_keywordvalues += "," + str_value;
303 : }
304 2 : bf_keywords_.push_back(str_keywordvalues);
305 2 : }
306 :
307 :
308 : inline
309 : void BasisFunctions::addKeywordToList(const std::string& keyword, const bool value) {
310 87 : if(value) {bf_keywords_.push_back(keyword);}
311 : }
312 :
313 :
314 : }
315 : }
316 :
317 : #endif
|