OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ParameterManager.hpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#ifndef UTILS_PARAMETERMANAGER_HPP
49#define UTILS_PARAMETERMANAGER_HPP
50
51#include <config.h>
52
53#include <cstdio>
54#include <cstdlib>
55#include <iostream>
56#include <map>
57#include <string>
58#include <vector>
59
60#include "utils/CaseConversion.hpp"
62#include "utils/simError.h"
63
64template<typename T>
66
67// string
68template<>
69struct ParameterTraits<std::string> {
70 using RepType = std::string; // Representation type of the value
71
72 template<typename T>
73 static bool convert(T, RepType&) {
74 return false;
75 } // !NB everything is ok
76
77 template<typename T>
78 static RepType convert(T v) {
79 RepType tmp;
80 convert(v, tmp);
81 return tmp;
82 }
83
84 static bool convert(RepType v, RepType& r) {
85 r = v;
86 return true;
87 }
88
89 static std::string getParamType() { return "string"; }
90};
91// bool
92template<>
93struct ParameterTraits<bool> {
94 using RepType = bool;
95
96 template<typename T>
97 static bool convert(T, RepType&) {
98 return false;
99 }
100
101 template<typename T>
102 static RepType convert(T v) {
103 RepType tmp {};
104 convert(v, tmp);
105 return tmp;
106 }
107
108 static bool convert(std::string v, RepType& r) {
109 OpenMD::toLower(v);
110 bool result = false;
111 if (v == "true") {
112 r = true;
113 result = true;
114 } else if (v == "false") {
115 r = false;
116 result = true;
117 }
118
119 return result;
120 }
121
122 static bool convert(bool b, RepType& r) {
123 r = b;
124 return true;
125 }
126
127 static std::string getParamType() { return "bool"; }
128};
129
130// int
131template<>
132struct ParameterTraits<int> {
133 using RepType = int;
134
135 template<typename T>
136 static bool convert(T, RepType&) {
137 return false;
138 }
139
140 template<typename T>
141 static RepType convert(T v) {
142 RepType tmp {};
143 convert(v, tmp);
144 return tmp;
145 }
146
147 static bool convert(RepType v, RepType& r) {
148 r = v;
149 return true;
150 }
151
152 static std::string getParamType() { return "int"; }
153};
154
155// int
156template<>
157struct ParameterTraits<unsigned long int> {
158 using RepType = unsigned long int;
159
160 template<typename T>
161 static bool convert(T, RepType&) {
162 return false;
163 }
164
165 template<typename T>
166 static RepType convert(T v) {
167 RepType tmp {};
168 convert(v, tmp);
169 return tmp;
170 }
171
172 static bool convert(RepType v, RepType& r) {
173 r = v;
174 return true;
175 }
176
177 static bool convert(int v, RepType& r) {
178 r = static_cast<unsigned long int>(v);
179 return true;
180 }
181
182 static std::string getParamType() { return "unsigned long int"; }
183};
184
185// RealType
186template<>
187struct ParameterTraits<RealType> {
188 using RepType = RealType;
189
190 template<typename T>
191 static bool convert(T, RepType&) {
192 return false;
193 }
194
195 template<typename T>
196 static RepType convert(T v) {
197 RepType tmp {};
198 convert(v, tmp);
199 return tmp;
200 }
201
202 static bool convert(RepType v, RepType& r) {
203 r = v;
204 return true;
205 }
206
207 static bool convert(int v, RepType& r) {
208 r = static_cast<RealType>(v);
209 return true;
210 }
211
212 static bool convert(unsigned long int v, RepType& r) {
213 r = static_cast<RealType>(v);
214 return true;
215 }
216
217 static std::string getParamType() { return "RealType"; }
218};
219
220// Pair of ints
221template<>
222struct ParameterTraits<std::pair<int, int>> {
223 using RepType = std::pair<int, int>;
224
225 template<typename T>
226 static bool convert(T, RepType&) {
227 return false;
228 }
229
230 template<typename T>
231 static RepType convert(T v) {
232 RepType tmp;
233 convert(v, tmp);
234 return tmp;
235 }
236
237 static bool convert(RepType v, RepType& r) {
238 r = v;
239 return true;
240 }
241
242 static bool convert(std::string v, RepType& r) {
243 OpenMD::StringTokenizer tokenizer(v, " ;,\t\n\r");
244 if (tokenizer.countTokens() == 2) {
245 int atom1 = tokenizer.nextTokenAsInt();
246 int atom2 = tokenizer.nextTokenAsInt();
247 r = std::make_pair(atom1, atom2);
248 return true;
249 } else {
250 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
251 "ParameterManager Error: "
252 "Incorrect number of tokens to make a pair!\n");
253 painCave.severity = OPENMD_ERROR;
254 painCave.isFatal = 1;
255 simError();
256 }
257 return false;
258 }
259
260 static std::string getParamType() { return "std::pair<int, int>"; }
261};
262
263template<>
264struct ParameterTraits<std::vector<RealType>> {
265 using RepType = std::vector<RealType>;
266
267 template<typename T>
268 static bool convert(T, RepType&) {
269 return false;
270 }
271
272 template<typename T>
273 static RepType convert(T v) {
274 RepType tmp;
275 convert(v, tmp);
276 return tmp;
277 }
278
279 static bool convert(RepType v, RepType& r) {
280 r = v;
281 return true;
282 }
283
284 static bool convert(std::string v, RepType& r) {
285 std::cerr << "calling tokenizer\n";
286 OpenMD::StringTokenizer tokenizer(v, " ();,\t\n\r");
287 unsigned int size = tokenizer.countTokens();
288 r = std::vector<RealType>(size, 0.0);
289 for (unsigned int i = 0; i < size; i++) {
290 RealType v = tokenizer.nextTokenAsDouble();
291 r[i] = v;
292 }
293 return true;
294 }
295
296 static std::string getParamType() { return "std::vector<RealType>"; }
297};
298
299class ParameterBase {
300public:
301 ParameterBase() :
302 keyword_(), optional_(false), defaultValue_(false), empty_(true) {}
303 virtual ~ParameterBase() {}
304 bool isOptional() const { return optional_; }
305 void setOptional(bool optional) { optional_ = optional; }
306 bool hasDefaultValue() const { return defaultValue_; }
307 virtual bool isValid() { return true; }
308 const std::string& getKeyword() { return keyword_; }
309 void setKeyword(const std::string& keyword) { keyword_ = keyword; }
310 bool empty() const { return empty_; }
311 virtual bool setData(std::string) = 0;
312 virtual bool setData(int) = 0;
313 virtual bool setData(unsigned long int) = 0;
314 virtual bool setData(RealType) = 0;
315 virtual bool setData(std::pair<int, int>) = 0;
316 virtual bool setData(std::vector<RealType>) = 0;
317 virtual bool setData(bool) = 0;
318 virtual std::string getParamType() = 0;
319
320protected:
321 std::string keyword_;
322 bool optional_;
323 bool defaultValue_;
324 bool empty_;
325};
326
327template<class ParamType>
328class Parameter : public ParameterBase {
329public:
330 using ValueType = ParameterTraits<ParamType>;
331
332 void setDefaultValue(const ParamType& value) {
333 data_ = value;
334 defaultValue_ = true;
335 empty_ = false;
336 }
337 ParamType getData() { return data_; }
338
339 virtual bool setData(std::string sval) {
340 return internalSetData<std::string>(sval);
341 }
342 virtual bool setData(int ival) { return internalSetData<int>(ival); }
343 virtual bool setData(unsigned long int lival) {
344 return internalSetData<unsigned long int>(lival);
345 }
346 virtual bool setData(RealType dval) {
347 return internalSetData<RealType>(dval);
348 }
349 virtual bool setData(std::pair<int, int> pval) {
350 return internalSetData<std::pair<int, int>>(pval);
351 }
352 virtual bool setData(std::vector<RealType> pval) {
353 return internalSetData<std::vector<RealType>>(pval);
354 }
355 virtual bool setData(bool bval) {
356 return internalSetData<bool>(bval);
357 }
358
359 virtual std::string getParamType() {
361 }
362
363private:
364 template<class T>
365 bool internalSetData(T data) {
366 ParamType tmp {};
367 bool result = ValueType::convert(data, tmp);
368 if (result) {
369 empty_ = false;
370 data_ = tmp;
371 }
372 return result;
373 }
374
375private:
376 ParamType data_;
377};
378
379#define DeclareParameter(NAME, TYPE) \
380private: \
381 Parameter<TYPE> NAME; \
382 \
383public: \
384 bool have##NAME() { return !NAME.empty(); } \
385 TYPE get##NAME() { return NAME.getData(); }
386
387#define DeclareAlterableParameter(NAME, TYPE) \
388private: \
389 Parameter<TYPE> NAME; \
390 \
391public: \
392 bool have##NAME() { return !NAME.empty(); } \
393 TYPE get##NAME() { return NAME.getData(); } \
394 bool set##NAME(TYPE s) { return NAME.setData(s); }
395
396#define DefineParameter(NAME, KEYWORD) \
397 NAME.setKeyword(KEYWORD); \
398 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
399 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
400
401#define DefineOptionalParameter(NAME, KEYWORD) \
402 NAME.setKeyword(KEYWORD); \
403 NAME.setOptional(true); \
404 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
405 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
406
407#define DefineOptionalParameterWithDefaultValue(NAME, KEYWORD, DEFAULTVALUE) \
408 NAME.setKeyword(KEYWORD); \
409 NAME.setOptional(true); \
410 NAME.setDefaultValue(DEFAULTVALUE); \
411 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
412 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
413
414#define CheckParameter(NAME, CONSTRAINT) \
415 if (!NAME.empty()) { \
416 if (!(CONSTRAINT)(NAME.getData())) { \
417 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH, \
418 "Error in checking %s : should be %s\n", \
419 NAME.getKeyword().c_str(), \
420 (CONSTRAINT).getConstraintDescription().c_str()); \
421 painCave.isFatal = 1; \
422 painCave.severity = OPENMD_ERROR; \
423 simError(); \
424 } \
425 }
426
427#endif
The string tokenizer class allows an application to break a string into tokens The set of delimiters ...
int countTokens()
Calculates the number of times that this tokenizer's nextToken method can be called before it generat...
int nextTokenAsInt()
Returns the next token from this string tokenizer as an integer.
RealType nextTokenAsDouble()
Returns the next token from this string tokenizer as a RealType.