OpenMD 3.0
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 appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45#ifndef UTILS_PARAMETERMANAGER_HPP
46#define UTILS_PARAMETERMANAGER_HPP
47
48#include <config.h>
49
50#include <cstdio>
51#include <cstdlib>
52#include <iostream>
53#include <map>
54#include <string>
55#include <vector>
56
57#include "utils/CaseConversion.hpp"
59#include "utils/simError.h"
60
61template<typename T>
63
64// string
65template<>
66struct ParameterTraits<std::string> {
67 using RepType = std::string; // Representation type of the value
68
69 template<typename T>
70 static bool convert(T, RepType&) {
71 return false;
72 } // !NB everything is ok
73
74 template<typename T>
75 static RepType convert(T v) {
76 RepType tmp;
77 convert(v, tmp);
78 return tmp;
79 }
80
81 static bool convert(RepType v, RepType& r) {
82 r = v;
83 return true;
84 }
85
86 static std::string getParamType() { return "string"; }
87};
88// bool
89template<>
90struct ParameterTraits<bool> {
91 using RepType = bool;
92
93 template<typename T>
94 static bool convert(T, RepType&) {
95 return false;
96 }
97
98 template<typename T>
99 static RepType convert(T v) {
100 RepType tmp;
101 convert(v, tmp);
102 return tmp;
103 }
104
105 static bool convert(std::string v, RepType& r) {
106 OpenMD::toLower(v);
107 bool result = false;
108 if (v == "true") {
109 r = true;
110 result = true;
111 } else if (v == "false") {
112 r = false;
113 result = true;
114 }
115
116 return result;
117 }
118
119 static std::string getParamType() { return "bool"; }
120};
121
122// int
123template<>
124struct ParameterTraits<int> {
125 using RepType = int;
126
127 template<typename T>
128 static bool convert(T, RepType&) {
129 return false;
130 }
131
132 template<typename T>
133 static RepType convert(T v) {
134 RepType tmp;
135 convert(v, tmp);
136 return tmp;
137 }
138
139 static bool convert(RepType v, RepType& r) {
140 r = v;
141 return true;
142 }
143
144 static std::string getParamType() { return "int"; }
145};
146
147// int
148template<>
149struct ParameterTraits<unsigned long int> {
150 using RepType = unsigned long int;
151
152 template<typename T>
153 static bool convert(T, RepType&) {
154 return false;
155 }
156
157 template<typename T>
158 static RepType convert(T v) {
159 RepType tmp;
160 convert(v, tmp);
161 return tmp;
162 }
163
164 static bool convert(RepType v, RepType& r) {
165 r = v;
166 return true;
167 }
168
169 static bool convert(int v, RepType& r) {
170 r = static_cast<unsigned long int>(v);
171 return true;
172 }
173
174 static std::string getParamType() { return "unsigned long int"; }
175};
176
177// RealType
178template<>
179struct ParameterTraits<RealType> {
180 using RepType = RealType;
181
182 template<typename T>
183 static bool convert(T, RepType&) {
184 return false;
185 }
186
187 template<typename T>
188 static RepType convert(T v) {
189 RepType tmp;
190 convert(v, tmp);
191 return tmp;
192 }
193
194 static bool convert(RepType v, RepType& r) {
195 r = v;
196 return true;
197 }
198
199 static bool convert(int v, RepType& r) {
200 r = static_cast<RealType>(v);
201 return true;
202 }
203
204 static bool convert(unsigned long int v, RepType& r) {
205 r = static_cast<RealType>(v);
206 return true;
207 }
208
209 static std::string getParamType() { return "RealType"; }
210};
211
212// Pair of ints
213template<>
214struct ParameterTraits<std::pair<int, int>> {
215 using RepType = std::pair<int, int>;
216
217 template<typename T>
218 static bool convert(T, RepType&) {
219 return false;
220 }
221
222 template<typename T>
223 static RepType convert(T v) {
224 RepType tmp;
225 convert(v, tmp);
226 return tmp;
227 }
228
229 static bool convert(RepType v, RepType& r) {
230 r = v;
231 return true;
232 }
233
234 static bool convert(std::string v, RepType& r) {
235 OpenMD::StringTokenizer tokenizer(v, " ;,\t\n\r");
236 if (tokenizer.countTokens() == 2) {
237 int atom1 = tokenizer.nextTokenAsInt();
238 int atom2 = tokenizer.nextTokenAsInt();
239 r = std::make_pair(atom1, atom2);
240 return true;
241 } else {
242 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
243 "ParameterManager Error: "
244 "Incorrect number of tokens to make a pair!\n");
245 painCave.severity = OPENMD_ERROR;
246 painCave.isFatal = 1;
247 simError();
248 }
249 return false;
250 }
251
252 static std::string getParamType() { return "std::pair<int, int>"; }
253};
254
255template<>
256struct ParameterTraits<std::vector<RealType>> {
257 using RepType = std::vector<RealType>;
258
259 template<typename T>
260 static bool convert(T, RepType&) {
261 return false;
262 }
263
264 template<typename T>
265 static RepType convert(T v) {
266 RepType tmp;
267 convert(v, tmp);
268 return tmp;
269 }
270
271 static bool convert(RepType v, RepType& r) {
272 r = v;
273 return true;
274 }
275
276 static bool convert(std::string v, RepType& r) {
277 std::cerr << "calling tokenizer\n";
278 OpenMD::StringTokenizer tokenizer(v, " ();,\t\n\r");
279 unsigned int size = tokenizer.countTokens();
280 r = std::vector<RealType>(size, 0.0);
281 for (unsigned int i = 0; i < size; i++) {
282 RealType v = tokenizer.nextTokenAsDouble();
283 r[i] = v;
284 }
285 return true;
286 }
287
288 static std::string getParamType() { return "std::vector<RealType>"; }
289};
290
292public:
293 ParameterBase() :
294 keyword_(), optional_(false), defaultValue_(false), empty_(true) {}
295 virtual ~ParameterBase() {}
296 bool isOptional() { return optional_; }
297 void setOptional(bool optional) { optional_ = optional; }
298 bool hasDefaultValue() { return defaultValue_; }
299 virtual bool isValid() { return true; }
300 const std::string& getKeyword() { return keyword_; }
301 void setKeyword(const std::string& keyword) { keyword_ = keyword; }
302 bool empty() { return empty_; }
303 virtual bool setData(std::string) = 0;
304 virtual bool setData(int) = 0;
305 virtual bool setData(unsigned long int) = 0;
306 virtual bool setData(RealType) = 0;
307 virtual bool setData(std::pair<int, int>) = 0;
308 virtual bool setData(std::vector<RealType>) = 0;
309 virtual std::string getParamType() = 0;
310
311protected:
312 std::string keyword_;
313 bool optional_;
314 bool defaultValue_;
315 bool empty_;
316};
317
318template<class ParamType>
319class Parameter : public ParameterBase {
320public:
322
323 void setDefaultValue(const ParamType& value) {
324 data_ = value;
325 defaultValue_ = true;
326 empty_ = false;
327 }
328 ParamType getData() { return data_; }
329
330 virtual bool setData(std::string sval) {
331 return internalSetData<std::string>(sval);
332 }
333 virtual bool setData(int ival) { return internalSetData<int>(ival); }
334 virtual bool setData(unsigned long int lival) {
335 return internalSetData<unsigned long int>(lival);
336 }
337 virtual bool setData(RealType dval) {
338 return internalSetData<RealType>(dval);
339 }
340 virtual bool setData(std::pair<int, int> pval) {
341 return internalSetData<std::pair<int, int>>(pval);
342 }
343 virtual bool setData(std::vector<RealType> pval) {
344 return internalSetData<std::vector<RealType>>(pval);
345 }
346
347 virtual std::string getParamType() {
349 }
350
351private:
352 template<class T>
353 bool internalSetData(T data) {
354 ParamType tmp;
355 bool result = ValueType::convert(data, tmp);
356 if (result) {
357 empty_ = false;
358 data_ = tmp;
359 }
360 return result;
361 }
362
363private:
364 ParamType data_;
365};
366
367#define DeclareParameter(NAME, TYPE) \
368private: \
369 Parameter<TYPE> NAME; \
370 \
371public: \
372 bool have##NAME() { return !NAME.empty(); } \
373 TYPE get##NAME() { return NAME.getData(); }
374
375#define DeclareAlterableParameter(NAME, TYPE) \
376private: \
377 Parameter<TYPE> NAME; \
378 \
379public: \
380 bool have##NAME() { return !NAME.empty(); } \
381 TYPE get##NAME() { return NAME.getData(); } \
382 bool set##NAME(TYPE s) { return NAME.setData(s); }
383
384#define DefineParameter(NAME, KEYWORD) \
385 NAME.setKeyword(KEYWORD); \
386 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
387 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
388
389#define DefineOptionalParameter(NAME, KEYWORD) \
390 NAME.setKeyword(KEYWORD); \
391 NAME.setOptional(true); \
392 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
393 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
394
395#define DefineOptionalParameterWithDefaultValue(NAME, KEYWORD, DEFAULTVALUE) \
396 NAME.setKeyword(KEYWORD); \
397 NAME.setOptional(true); \
398 NAME.setDefaultValue(DEFAULTVALUE); \
399 parameters_.insert(std::map<std::string, ParameterBase*>::value_type( \
400 std::string(KEYWORD), static_cast<ParameterBase*>(&NAME)));
401
402#define CheckParameter(NAME, CONSTRAINT) \
403 if (!NAME.empty()) { \
404 if (!(CONSTRAINT)(NAME.getData())) { \
405 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH, \
406 "Error in checking %s : should be %s\n", \
407 NAME.getKeyword().c_str(), \
408 (CONSTRAINT).getConstraintDescription().c_str()); \
409 painCave.isFatal = 1; \
410 painCave.severity = OPENMD_ERROR; \
411 simError(); \
412 } \
413 }
414
415#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.