OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ParamConstraint.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 IO_PARAMCONSTRAINT_HPP
49#define IO_PARAMCONSTRAINT_HPP
50
51#include <sstream>
52
53#include "utils/CaseConversion.hpp"
55
56namespace OpenMD {
57 /**
58 * This class allows to recognize constraint predicates, so that they can be
59 * combined using composition operators. Every constraint predicate must be
60 * derived from this class
61 */
62 template<typename Derived>
64 std::string getConstraintDescription() { return description_; }
65
66 protected:
67 std::string description_;
68 };
69
70 struct NotEmptyConstraint : public ParamConstraintFacade<NotEmptyConstraint> {
71 NotEmptyConstraint() { description_ = "nonempty"; }
72 bool operator()(const std::string& data) const { return !data.empty(); }
73 };
74
75 struct ZeroConstraint : public ParamConstraintFacade<ZeroConstraint> {
76 ZeroConstraint() { this->description_ = "zero"; }
77 template<typename DataType>
78 bool operator()(DataType data) const {
79 return data == 0;
80 }
81 };
82
83 struct NonZeroConstraint : public ParamConstraintFacade<NonZeroConstraint> {
84 NonZeroConstraint() { this->description_ = "nonzero"; }
85
86 template<typename DataType>
87 bool operator()(DataType data) const {
88 return data != 0;
89 }
90 };
91
92 struct PositiveConstraint : public ParamConstraintFacade<PositiveConstraint> {
93 PositiveConstraint() { this->description_ = "positive"; }
94 template<typename DataType>
95 bool operator()(DataType data) const {
96 return data > 0;
97 }
98 };
99
100 struct NonPositiveConstraint :
101 public ParamConstraintFacade<NonPositiveConstraint> {
102 NonPositiveConstraint() { this->description_ = "nonpositive"; }
103 template<typename DataType>
104 bool operator()(DataType data) const {
105 return data <= 0;
106 }
107 };
108
109 struct NegativeConstraint : public ParamConstraintFacade<NegativeConstraint> {
110 NegativeConstraint() { this->description_ = "negative"; }
111 template<typename DataType>
112 bool operator()(DataType data) const {
113 return data < 0;
114 }
115 };
116
117 struct NonNegativeConstraint :
118 public ParamConstraintFacade<NonNegativeConstraint> {
119 NonNegativeConstraint() { this->description_ = "nonnegative"; }
120 template<typename DataType>
121 bool operator()(DataType data) const {
122 return data >= 0;
123 }
124 };
125
126 struct EvenConstraint : public ParamConstraintFacade<EvenConstraint> {
127 EvenConstraint() { this->description_ = "even"; }
128 template<typename DataType>
129 bool operator()(DataType data) const {
130 return data % 2 == 0;
131 }
132 };
133
134 template<typename T>
135 struct LessThanConstraint :
136 public ParamConstraintFacade<LessThanConstraint<T>> {
137 LessThanConstraint(T rhs) : rhs_(rhs) {
138 std::stringstream iss;
139 iss << "less than " << rhs;
140 this->description_ = iss.str();
141 }
142 template<typename DataType>
143 bool operator()(DataType data) const {
144 return data < rhs_;
145 }
146
147 private:
148 T rhs_;
149 };
150
151 template<typename T>
152 struct LessThanOrEqualToConstraint :
153 public ParamConstraintFacade<LessThanOrEqualToConstraint<T>> {
154 LessThanOrEqualToConstraint(T rhs) : rhs_(rhs) {
155 std::stringstream iss;
156 iss << "less than or equal to" << rhs;
157 this->description_ = iss.str();
158 }
159
160 template<typename DataType>
161 bool operator()(DataType data) const {
162 return data <= rhs_;
163 }
164
165 private:
166 T rhs_;
167 };
168
169 template<typename T>
170 struct EqualConstraint : public ParamConstraintFacade<EqualConstraint<T>> {
171 EqualConstraint(T rhs) : rhs_(rhs) {
172 std::stringstream iss;
173 iss << "equal to" << rhs;
174 this->description_ = iss.str();
175 }
176 template<typename DataType>
177 bool operator()(DataType data) const {
178 return data == rhs_;
179 }
180
181 private:
182 T rhs_;
183 };
184
185 struct EqualIgnoreCaseConstraint :
186 public ParamConstraintFacade<EqualIgnoreCaseConstraint> {
187 EqualIgnoreCaseConstraint(std::string rhs) :
188 rhs_(OpenMD::toUpperCopy(rhs)) {
189 std::stringstream iss;
190 iss << "equal to (case insensitive) " << rhs;
191 this->description_ = iss.str();
192 }
193
194 bool operator()(std::string data) const {
195 return OpenMD::toUpperCopy(data) == rhs_;
196 }
197
198 private:
199 std::string rhs_;
200 };
201
202 struct ContainsConstraint :
203 public ParamConstraintFacade<EqualIgnoreCaseConstraint> {
204 ContainsConstraint(std::string rhs) : rhs_(OpenMD::toUpperCopy(rhs)) {
205 std::stringstream iss;
206 iss << "contains " << rhs;
207 this->description_ = iss.str();
208 }
209
210 bool operator()(std::string data) const {
211 OpenMD::StringTokenizer tokenizer(OpenMD::toUpperCopy(data),
212 " ,;|\t\n\r");
213 while (tokenizer.hasMoreTokens()) {
214 if (tokenizer.nextToken() == rhs_) { return true; }
215 }
216
217 return false;
218 }
219
220 private:
221 std::string rhs_;
222 };
223
224 template<typename T>
225 struct GreaterThanConstraint :
226 public ParamConstraintFacade<GreaterThanConstraint<T>> {
227 GreaterThanConstraint(T rhs) : rhs_(rhs) {
228 std::stringstream iss;
229 iss << "greater than" << rhs;
230 this->description_ = iss.str();
231 }
232 template<typename DataType>
233 bool operator()(DataType data) const {
234 return data > rhs_;
235 }
236
237 private:
238 T rhs_;
239 };
240
241 template<typename T>
242 struct GreaterThanOrEqualTo :
243 public ParamConstraintFacade<GreaterThanOrEqualTo<T>> {
244 GreaterThanOrEqualTo(T rhs) : rhs_(rhs) {
245 std::stringstream iss;
246 iss << "greater than or equal to" << rhs;
247 this->description_ = iss.str();
248 }
249 template<typename DataType>
250 bool operator()(DataType data) const {
251 return data >= rhs_;
252 }
253
254 private:
255 T rhs_;
256 };
257
258 // class_and composition predicate
259 template<typename Cons1T, typename Cons2T>
260 struct AndParamConstraint :
261 public ParamConstraintFacade<AndParamConstraint<Cons1T, Cons2T>> {
262 public:
263 AndParamConstraint(Cons1T cons1, Cons2T cons2) :
264 cons1_(cons1), cons2_(cons2) {
265 std::stringstream iss;
266 iss << "(" << cons1_.getConstraintDescription() << " and "
267 << cons2_.getConstraintDescription() << ")";
268 this->description_ = iss.str();
269 }
270
271 template<typename DataType>
272 bool operator()(DataType data) const {
273 return cons1_(data) && cons2_(data);
274 }
275
276 private:
277 Cons1T cons1_;
278 Cons2T cons2_;
279 };
280
281 template<typename Cons1T, typename Cons2T>
282 struct OrParamConstraint :
283 public ParamConstraintFacade<OrParamConstraint<Cons1T, Cons2T>> {
284 public:
285 OrParamConstraint(Cons1T cons1, Cons2T cons2) :
286 cons1_(cons1), cons2_(cons2) {
287 std::stringstream iss;
288 iss << cons1_.getConstraintDescription() << " or "
289 << cons2_.getConstraintDescription() << "";
290 this->description_ = iss.str();
291 }
292
293 template<typename DataType>
294 bool operator()(DataType data) const {
295 return cons1_(data) || cons2_(data);
296 }
297
298 private:
299 Cons1T cons1_;
300 Cons2T cons2_;
301 };
302
303 template<typename ConsT>
304 struct NotParamConstraint :
305 public ParamConstraintFacade<NotParamConstraint<ConsT>> {
306 public:
307 NotParamConstraint(ConsT cons) : cons_(cons) {
308 std::stringstream iss;
309 iss << "(not" << cons_.getConstraintDescription() << ")";
310 this->description_ = iss.str();
311 }
312
313 template<typename DataType>
314 bool operator()(DataType data) const {
315 return !cons_(data);
316 }
317
318 private:
319 ConsT cons_;
320 };
321
322 template<typename Cons1T, typename Cons2T>
323 inline AndParamConstraint<Cons1T, Cons2T> operator&&(
325 const ParamConstraintFacade<Cons2T>& cons2) {
327 *static_cast<const Cons1T*>(&cons1),
328 *static_cast<const Cons2T*>(&cons2));
329 }
330
331 template<typename Cons1T, typename Cons2T>
332 inline OrParamConstraint<Cons1T, Cons2T> operator||(
333 const ParamConstraintFacade<Cons1T>& cons1,
334 const ParamConstraintFacade<Cons2T>& cons2) {
335 return OrParamConstraint<Cons1T, Cons2T>(
336 *static_cast<const Cons1T*>(&cons1),
337 *static_cast<const Cons2T*>(&cons2));
338 }
339
340 template<typename ConsT>
341 inline NotParamConstraint<ConsT> operator!(
342 const ParamConstraintFacade<ConsT>& cons) {
343 return NotParamConstraint<ConsT>(*static_cast<const ConsT*>(&cons));
344 }
345
346 NotEmptyConstraint isNotEmpty();
347 ZeroConstraint isZero();
348
350 PositiveConstraint isPositive();
351 NonPositiveConstraint isNonPositive();
352
353 NegativeConstraint isNegative();
354
355 NonNegativeConstraint isNonNegative();
356 EvenConstraint isEven();
357
358 template<typename T>
359 inline LessThanConstraint<T> isLessThan(T& v) {
360 return LessThanConstraint<T>(v);
361 }
362
363 template<typename T>
364 inline LessThanOrEqualToConstraint<T> isLessThanOrEqualTo(T& v) {
366 }
367
368 template<typename T>
369 inline EqualConstraint<T> isEqual(T& v) {
370 return EqualConstraint<T>(v);
371 }
372
373 template<typename T>
374 inline GreaterThanConstraint<T> isGreaterThan(T& v) {
375 return GreaterThanConstraint<T>(v);
376 }
377
378 template<typename T>
379 inline GreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(T& v) {
380 return GreaterThanOrEqualTo<T>(v);
381 }
382
383 EqualIgnoreCaseConstraint isEqualIgnoreCase(std::string str);
384} // namespace OpenMD
385
386#endif
The string tokenizer class allows an application to break a string into tokens The set of delimiters ...
std::string nextToken()
Returns the next token from this string tokenizer.
bool hasMoreTokens()
Tests if there are more tokens available from this tokenizer's string.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
This class allows to recognize constraint predicates, so that they can be combined using composition ...