45#include "io/EAMAtomTypesSectionParser.hpp"
51#include "types/AtomType.hpp"
52#include "types/EAMAdapter.hpp"
53#include "utils/simError.h"
56#define FIX_UNUSED(X) (void)(X)
62 EAMAtomTypesSectionParser::EAMAtomTypesSectionParser(
63 ForceFieldOptions& options) :
65 setSectionName(
"EAMAtomTypes");
68 void EAMAtomTypesSectionParser::parseLine(ForceField& ff,
const string& line,
70 eus_ = options_.getMetallicEnergyUnitScaling();
71 dus_ = options_.getDistanceUnitScaling();
73 StringTokenizer tokenizer(line);
74 int nTokens = tokenizer.countTokens();
76 if (tokenizer.countTokens() >= 2) {
77 std::string atomTypeName = tokenizer.nextToken();
78 std::string eamParameterType = tokenizer.nextToken();
80 AtomType* atomType = ff.getAtomType(atomTypeName);
81 if (atomType != NULL) {
82 EAMAdapter ea = EAMAdapter(atomType);
83 toUpper(eamParameterType);
85 if (eamParameterType ==
"FUNCFL") {
86 std::string funcflFile = tokenizer.nextToken();
87 parseFuncflFile(ff, ea, funcflFile, atomType->getIdent());
88 }
else if (eamParameterType ==
"ZHOU" ||
89 eamParameterType ==
"ZHOU2001") {
91 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
92 "EAMAtomTypesSectionParser Error: "
93 "Not enough tokens at line %d\n",
98 std::string lattice = tokenizer.nextToken();
100 RealType re = dus_ * tokenizer.nextTokenAsDouble();
101 RealType fe = tokenizer.nextTokenAsDouble();
102 RealType rhoe = tokenizer.nextTokenAsDouble();
103 RealType alpha = tokenizer.nextTokenAsDouble();
104 RealType beta = tokenizer.nextTokenAsDouble();
105 RealType A = eus_ * tokenizer.nextTokenAsDouble();
106 RealType B = eus_ * tokenizer.nextTokenAsDouble();
107 RealType kappa = tokenizer.nextTokenAsDouble();
108 RealType lambda = tokenizer.nextTokenAsDouble();
109 std::vector<RealType> Fn;
110 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
111 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
112 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
113 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
114 std::vector<RealType> F;
115 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
116 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
117 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
118 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
119 RealType eta = tokenizer.nextTokenAsDouble();
120 RealType Fe = eus_ * tokenizer.nextTokenAsDouble();
122 ea.makeZhou2001(lattice, re, fe, rhoe, alpha, beta, A, B, kappa,
123 lambda, Fn, F, eta, Fe);
125 }
else if (eamParameterType ==
"ZHOU2004") {
127 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
128 "EAMAtomTypesSectionParser Error: "
129 "Not enough tokens at line %d\n",
131 painCave.isFatal = 1;
134 std::string lattice = tokenizer.nextToken();
136 RealType re = dus_ * tokenizer.nextTokenAsDouble();
137 RealType fe = tokenizer.nextTokenAsDouble();
138 RealType rhoe = tokenizer.nextTokenAsDouble();
139 RealType rhos = tokenizer.nextTokenAsDouble();
140 RealType alpha = tokenizer.nextTokenAsDouble();
141 RealType beta = tokenizer.nextTokenAsDouble();
142 RealType A = eus_ * tokenizer.nextTokenAsDouble();
143 RealType B = eus_ * tokenizer.nextTokenAsDouble();
144 RealType kappa = tokenizer.nextTokenAsDouble();
145 RealType lambda = tokenizer.nextTokenAsDouble();
146 std::vector<RealType> Fn;
147 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
148 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
149 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
150 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
151 std::vector<RealType> F;
152 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
153 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
154 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
155 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
156 RealType eta = tokenizer.nextTokenAsDouble();
157 RealType Fe = eus_ * tokenizer.nextTokenAsDouble();
158 RealType rhol = tokenizer.nextTokenAsDouble();
159 RealType rhoh = tokenizer.nextTokenAsDouble();
161 ea.makeZhou2004(lattice, re, fe, rhoe, rhos, alpha, beta, A, B,
162 kappa, lambda, Fn, F, eta, Fe, rhol, rhoh);
165 }
else if (eamParameterType ==
"ZHOU2005") {
167 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
168 "EAMAtomTypesSectionParser Error: "
169 "Not enough tokens at line %d\n",
171 painCave.isFatal = 1;
174 std::string lattice = tokenizer.nextToken();
176 RealType re = dus_ * tokenizer.nextTokenAsDouble();
177 RealType fe = tokenizer.nextTokenAsDouble();
178 RealType rhoe = tokenizer.nextTokenAsDouble();
179 RealType rhos = tokenizer.nextTokenAsDouble();
180 RealType alpha = tokenizer.nextTokenAsDouble();
181 RealType beta = tokenizer.nextTokenAsDouble();
182 RealType A = eus_ * tokenizer.nextTokenAsDouble();
183 RealType B = eus_ * tokenizer.nextTokenAsDouble();
184 RealType kappa = tokenizer.nextTokenAsDouble();
185 RealType lambda = tokenizer.nextTokenAsDouble();
186 std::vector<RealType> Fn;
187 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
188 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
189 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
190 Fn.push_back(eus_ * tokenizer.nextTokenAsDouble());
191 std::vector<RealType> F;
192 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
193 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
194 F.push_back(eus_ * tokenizer.nextTokenAsDouble());
195 RealType F3minus = eus_ * tokenizer.nextTokenAsDouble();
196 RealType F3plus = eus_ * tokenizer.nextTokenAsDouble();
197 RealType eta = tokenizer.nextTokenAsDouble();
198 RealType Fe = eus_ * tokenizer.nextTokenAsDouble();
200 ea.makeZhou2005(lattice, re, fe, rhoe, rhos, alpha, beta, A, B,
201 kappa, lambda, Fn, F, F3minus, F3plus, eta, Fe);
203 }
else if (eamParameterType ==
"ZHOU2005OXYGEN") {
205 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
206 "EAMAtomTypesSectionParser Error: "
207 "Not enough tokens at line %d\n",
209 painCave.isFatal = 1;
212 RealType re = dus_ * tokenizer.nextTokenAsDouble();
213 RealType fe = tokenizer.nextTokenAsDouble();
214 RealType alpha = tokenizer.nextTokenAsDouble();
215 RealType beta = tokenizer.nextTokenAsDouble();
216 RealType A = eus_ * tokenizer.nextTokenAsDouble();
217 RealType B = eus_ * tokenizer.nextTokenAsDouble();
218 RealType kappa = tokenizer.nextTokenAsDouble();
219 RealType lambda = tokenizer.nextTokenAsDouble();
220 RealType gamma = tokenizer.nextTokenAsDouble();
221 RealType nu = tokenizer.nextTokenAsDouble();
223 std::vector<RealType> OrhoLimits;
224 OrhoLimits.push_back(tokenizer.nextTokenAsDouble());
225 OrhoLimits.push_back(tokenizer.nextTokenAsDouble());
226 OrhoLimits.push_back(tokenizer.nextTokenAsDouble());
227 OrhoLimits.push_back(tokenizer.nextTokenAsDouble());
228 OrhoLimits.push_back(tokenizer.nextTokenAsDouble());
230 std::vector<RealType> OrhoE;
231 OrhoE.push_back(tokenizer.nextTokenAsDouble());
232 OrhoE.push_back(tokenizer.nextTokenAsDouble());
233 OrhoE.push_back(tokenizer.nextTokenAsDouble());
234 OrhoE.push_back(tokenizer.nextTokenAsDouble());
235 OrhoE.push_back(tokenizer.nextTokenAsDouble());
237 std::vector<std::vector<RealType>> OF;
239 OF[0].push_back(eus_ * tokenizer.nextTokenAsDouble());
240 OF[0].push_back(eus_ * tokenizer.nextTokenAsDouble());
241 OF[0].push_back(eus_ * tokenizer.nextTokenAsDouble());
242 OF[0].push_back(eus_ * tokenizer.nextTokenAsDouble());
244 OF[1].push_back(eus_ * tokenizer.nextTokenAsDouble());
245 OF[1].push_back(eus_ * tokenizer.nextTokenAsDouble());
246 OF[1].push_back(eus_ * tokenizer.nextTokenAsDouble());
248 OF[2].push_back(eus_ * tokenizer.nextTokenAsDouble());
249 OF[2].push_back(eus_ * tokenizer.nextTokenAsDouble());
250 OF[2].push_back(eus_ * tokenizer.nextTokenAsDouble());
252 OF[3].push_back(eus_ * tokenizer.nextTokenAsDouble());
253 OF[3].push_back(eus_ * tokenizer.nextTokenAsDouble());
254 OF[3].push_back(eus_ * tokenizer.nextTokenAsDouble());
256 OF[4].push_back(eus_ * tokenizer.nextTokenAsDouble());
257 OF[4].push_back(eus_ * tokenizer.nextTokenAsDouble());
258 OF[4].push_back(eus_ * tokenizer.nextTokenAsDouble());
260 ea.makeZhou2005Oxygen(re, fe, alpha, beta, A, B, kappa, lambda,
261 gamma, nu, OrhoLimits, OrhoE, OF);
263 }
else if (eamParameterType ==
"ZHOUROSE") {
265 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
266 "EAMAtomTypesSectionParser Error: "
267 "Not enough tokens at line %d\n",
269 painCave.isFatal = 1;
272 RealType re = dus_ * tokenizer.nextTokenAsDouble();
273 RealType fe = tokenizer.nextTokenAsDouble();
274 RealType rhoe = tokenizer.nextTokenAsDouble();
275 RealType alpha = tokenizer.nextTokenAsDouble();
276 RealType beta = tokenizer.nextTokenAsDouble();
277 RealType A = eus_ * tokenizer.nextTokenAsDouble();
278 RealType B = eus_ * tokenizer.nextTokenAsDouble();
279 RealType kappa = tokenizer.nextTokenAsDouble();
280 RealType lambda = tokenizer.nextTokenAsDouble();
281 RealType F0 = eus_ * tokenizer.nextTokenAsDouble();
283 ea.makeZhouRose(re, fe, rhoe, alpha, beta, A, B, kappa, lambda, F0);
285 }
else if (eamParameterType ==
"OXYFUNCFL") {
287 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
288 "EAMAtomTypesSectionParser Error: "
289 "Not enough tokens at line %d\n",
291 painCave.isFatal = 1;
294 std::string funcflFile = tokenizer.nextToken();
296 RealType re = dus_ * tokenizer.nextTokenAsDouble();
297 RealType fe = tokenizer.nextTokenAsDouble();
298 RealType alpha = tokenizer.nextTokenAsDouble();
299 RealType beta = tokenizer.nextTokenAsDouble();
300 RealType A = eus_ * tokenizer.nextTokenAsDouble();
301 RealType B = eus_ * tokenizer.nextTokenAsDouble();
302 RealType kappa = tokenizer.nextTokenAsDouble();
303 RealType lambda = tokenizer.nextTokenAsDouble();
305 ifstrstream* ppfStream = ff.openForceFieldFile(funcflFile);
306 const int bufferSize = 65535;
307 char buffer[bufferSize];
310 ppfStream->getline(buffer, bufferSize);
312 std::vector<RealType> F;
316 if (ppfStream->getline(buffer, bufferSize)) {
317 StringTokenizer tokenizer1(buffer);
319 if (tokenizer1.countTokens() == 2) {
320 nrho = tokenizer1.nextTokenAsInt();
321 drho = tokenizer1.nextTokenAsDouble();
323 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
324 "EAMAtomTypesSectionParser Error: "
325 "Not enough tokens\n");
326 painCave.isFatal = 1;
331 parseEAMArray(*ppfStream, F, nrho);
335 std::transform(F.begin(), F.end(), F.begin(),
336 std::bind(std::multiplies<RealType>(), eus_,
337 std::placeholders::_1));
339 ea.makeOxygenFuncfl(re, fe, alpha, beta, A, B, kappa, lambda, drho,
343 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
344 "EAMAtomTypesSectionParser Error: %s "
345 "is not a recognized EAM type\n",
346 eamParameterType.c_str());
347 painCave.isFatal = 1;
352 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
353 "EAMAtomTypesSectionParser Error: "
354 "Can not find AtomType [%s]\n",
355 atomTypeName.c_str());
356 painCave.isFatal = 1;
361 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
362 "EAMAtomTypesSectionParser Error: "
363 "Not enough tokens at line %d\n",
365 painCave.isFatal = 1;
370 void EAMAtomTypesSectionParser::parseFuncflFile(ForceField& ff, EAMAdapter ea,
371 const string& funcflFile,
373 ifstrstream* ppfStream = ff.openForceFieldFile(funcflFile);
374 const int bufferSize = 65535;
375 char buffer[bufferSize];
378 ppfStream->getline(buffer, bufferSize);
384 RealType latticeConstant(0.0);
393 std::vector<RealType> F;
394 std::vector<RealType> Z;
395 std::vector<RealType> rho;
397 if (ppfStream->getline(buffer, bufferSize)) {
398 StringTokenizer tokenizer1(buffer);
400 if (tokenizer1.countTokens() >= 4) {
401 atomicNumber = tokenizer1.nextTokenAsInt();
402 atomicMass = tokenizer1.nextTokenAsDouble();
403 latticeConstant = tokenizer1.nextTokenAsDouble() * dus_;
404 lattice = tokenizer1.nextToken();
406 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
407 "EAMAtomTypesSectionParser Error: "
408 "Not enough tokens\n");
409 painCave.isFatal = 1;
414 FIX_UNUSED(atomicNumber);
415 FIX_UNUSED(atomicMass);
417 if (ppfStream->getline(buffer, bufferSize)) {
418 StringTokenizer tokenizer2(buffer);
420 if (tokenizer2.countTokens() >= 5) {
421 nrho = tokenizer2.nextTokenAsInt();
422 drho = tokenizer2.nextTokenAsDouble();
423 nr = tokenizer2.nextTokenAsInt();
424 dr = tokenizer2.nextTokenAsDouble() * dus_;
425 rcut = tokenizer2.nextTokenAsDouble() * dus_;
427 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
428 "EAMAtomTypesSectionParser Error: "
429 "Not enough tokens\n");
430 painCave.isFatal = 1;
435 parseEAMArray(*ppfStream, F, nrho);
436 parseEAMArray(*ppfStream, Z, nr);
437 parseEAMArray(*ppfStream, rho, nr);
441 F.begin(), F.end(), F.begin(),
442 std::bind(std::multiplies<RealType>(), eus_, std::placeholders::_1));
444 ea.makeFuncfl(latticeConstant, lattice, nrho, drho, nr, dr, rcut, Z, rho,
450 void EAMAtomTypesSectionParser::parseEAMArray(istream& input,
451 std::vector<RealType>& array,
453 const int dataPerLine = 5;
454 if (num % dataPerLine != 0) {}
456 int nlinesToRead = num / dataPerLine;
458 const int bufferSize = 65535;
459 char buffer[bufferSize];
462 while (lineCount < nlinesToRead && input.getline(buffer, bufferSize)) {
463 StringTokenizer tokenizer(buffer);
464 if (tokenizer.countTokens() >= dataPerLine) {
465 for (
int i = 0; i < dataPerLine; ++i) {
466 array.push_back(tokenizer.nextTokenAsDouble());
469 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
470 "EAMAtomTypesSectionParser Error: "
471 "Not enough tokens\n");
472 painCave.isFatal = 1;
478 if (lineCount < nlinesToRead) {
479 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
480 "EAMAtomTypesSectionParser Error: "
481 "Not enough lines to read\n");
482 painCave.isFatal = 1;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.