OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
BendTypeParser.cpp
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#include "types/BendTypeParser.hpp"
45
46#include <string>
47
48#include "io/BendTypesSectionParser.hpp"
50#include "types/CosineSeriesBendType.hpp"
51#include "types/CubicBendType.hpp"
56#include "types/SDKBendType.hpp"
58#include "utils/Constants.hpp"
59#include "utils/OpenMDException.hpp"
60#include "utils/StringUtils.hpp"
61
62namespace OpenMD {
63
64 BendTypeParser::BendTypeParser() {
65 stringToEnumMap_["Harmonic"] = btHarmonic;
66 stringToEnumMap_["GhostBend"] = btGhostBend;
67 stringToEnumMap_["UreyBradley"] = btUreyBradley;
68 stringToEnumMap_["Cubic"] = btCubic;
69 stringToEnumMap_["Quartic"] = btQuartic;
70 stringToEnumMap_["Polynomial"] = btPolynomial;
71 stringToEnumMap_["Cosine"] = btCosine;
72 stringToEnumMap_["SDK"] = btSDK;
73 stringToEnumMap_["CosineSeries"] = btCosineSeries;
74 stringToEnumMap_["HarmonicSine"] = btHarmonicSine;
75 }
76
77 BendType* BendTypeParser::parseTypeAndPars(const std::string& type,
78 std::vector<RealType> pars) {
79 std::string line(type);
80
81 std::vector<RealType>::iterator it;
82 for (it = pars.begin(); it != pars.end(); ++it) {
83 line.append("\t");
84 line.append(std::to_string(*it));
85 }
86 // Assume all overrides know about our functional forms:
87 return parseLine(line, 1.0);
88 }
89
90 BendType* BendTypeParser::parseLine(const std::string& line,
91 RealType kScale) {
92 StringTokenizer tokenizer(line);
93 BendType* bendType = NULL;
94 int nTokens = tokenizer.countTokens();
95 RealType theta0, ktheta;
96 RealType deg2rad = Constants::PI / 180.0;
97
98 if (nTokens < 2) {
99 throw OpenMDException("BendTypeParser: Not enough tokens");
100 }
101
102 BendTypeEnum bt = getBendTypeEnum(tokenizer.nextToken());
103 nTokens -= 1;
104
105 // switch is a nightmare to maintain
106 switch (bt) {
107 case btHarmonic:
108
109 if (nTokens < 2) {
110 throw OpenMDException("BendTypeParser: Not enough tokens");
111 } else {
112 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
113 ktheta = tokenizer.nextTokenAsDouble() * kScale;
114 bendType = new HarmonicBendType(theta0, ktheta);
115 }
116 break;
117 case btGhostBend:
118 if (nTokens < 2) {
119 throw OpenMDException("BendTypeParser: Not enough tokens");
120 } else {
121 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
122 ktheta = tokenizer.nextTokenAsDouble() * kScale;
123 bendType = new HarmonicBendType(theta0, ktheta);
124 }
125 break;
126
127 case btUreyBradley:
128 if (nTokens < 4) {
129 throw OpenMDException("BendTypeParser: Not enough tokens");
130 } else {
131 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
132 ktheta = tokenizer.nextTokenAsDouble();
133 RealType s0 = tokenizer.nextTokenAsDouble();
134 RealType kub = tokenizer.nextTokenAsDouble();
135 bendType = new UreyBradleyBendType(theta0, ktheta, s0, kub);
136 }
137 break;
138
139 case btCubic:
140 if (nTokens < 5) {
141 throw OpenMDException("BendTypeParser: Not enough tokens");
142 } else {
143 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
144 RealType k3 = tokenizer.nextTokenAsDouble();
145 RealType k2 = tokenizer.nextTokenAsDouble();
146 RealType k1 = tokenizer.nextTokenAsDouble();
147 RealType k0 = tokenizer.nextTokenAsDouble();
148
149 bendType = new CubicBendType(theta0, k3, k2, k1, k0);
150 }
151 break;
152
153 case btQuartic:
154 if (nTokens < 6) {
155 throw OpenMDException("BendTypeParser: Not enough tokens");
156 } else {
157 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
158 RealType k4 = tokenizer.nextTokenAsDouble();
159 RealType k3 = tokenizer.nextTokenAsDouble();
160 RealType k2 = tokenizer.nextTokenAsDouble();
161 RealType k1 = tokenizer.nextTokenAsDouble();
162 RealType k0 = tokenizer.nextTokenAsDouble();
163
164 bendType = new QuarticBendType(theta0, k4, k3, k2, k1, k0);
165 }
166 break;
167
168 case btPolynomial: {
169 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
170 nTokens -= 1;
171 if (nTokens < 2 || nTokens % 2 != 0) {
172 throw OpenMDException("BendTypeParser: Not enough tokens");
173 } else {
174 int nPairs = nTokens / 2;
175 int power;
176 RealType coefficient;
177 PolynomialBendType* pbt = new PolynomialBendType(theta0);
178
179 for (int i = 0; i < nPairs; ++i) {
180 power = tokenizer.nextTokenAsInt();
181 coefficient = tokenizer.nextTokenAsDouble();
182 pbt->setCoefficient(power, coefficient);
183 }
184 }
185 } break;
186
187 case btCosine:
188
189 if (nTokens < 2) {
190 throw OpenMDException("BendTypeParser: Not enough tokens");
191 } else {
192 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
193 ktheta = tokenizer.nextTokenAsDouble();
194 bendType = new CosineBendType(theta0, ktheta);
195 }
196 break;
197
198 case btSDK:
199 if (nTokens < 6) {
200 throw OpenMDException("BendTypeParser: Not enough tokens");
201 } else {
202 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
203 ktheta = tokenizer.nextTokenAsDouble();
204 RealType sigma = tokenizer.nextTokenAsDouble();
205 RealType epsilon = tokenizer.nextTokenAsDouble();
206 int nRep = tokenizer.nextTokenAsInt();
207 int mAtt = tokenizer.nextTokenAsInt();
208 bendType = new SDKBendType(theta0, ktheta, sigma, epsilon, nRep, mAtt);
209 }
210 break;
211
212 case btCosineSeries:
213
214 if (nTokens < 2) {
215 throw OpenMDException("BendTypeParser: Not enough tokens");
216 } else {
217 theta0 = tokenizer.nextTokenAsDouble() * deg2rad;
218 ktheta = tokenizer.nextTokenAsDouble() * kScale;
219 bendType = new CosineSeriesBendType(theta0, ktheta);
220 }
221 break;
222
223 case btHarmonicSine:
224
225 if (nTokens < 1) {
226 throw OpenMDException("BendTypeParser: Not enough tokens");
227 } else {
228 ktheta = tokenizer.nextTokenAsDouble() * kScale;
229 bendType = new HarmonicSineBendType(ktheta);
230 }
231 break;
232
233 case btUnknown:
234 default:
235 throw OpenMDException("BendTypeParser: Unknown Bend Type");
236 }
237
238 return bendType;
239 }
240
241 BendTypeParser::BendTypeEnum BendTypeParser::getBendTypeEnum(
242 const std::string& str) {
243 std::map<std::string, BendTypeEnum>::iterator i;
244 i = stringToEnumMap_.find(str);
245
246 return i == stringToEnumMap_.end() ? btUnknown : i->second;
247 }
248
249} // namespace OpenMD
A simple harmonic bend using the cosine of the angle instead of the angle itself:
A bend used primarily in UFF that utilizes a Fourier series in terms of the cosine of the bend angle:
A bend using the square of the sine of the angle instead of the angle itself:
"types/PolynomialBendType.hpp"
The string tokenizer class allows an application to break a string into tokens The set of delimiters ...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.