OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
OtherVisitor.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 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#include "visitors/OtherVisitor.hpp"
49
50#include <memory>
51
52#include "brains/SimInfo.hpp"
53#include "brains/Thermo.hpp"
57#include "selection/SelectionManager.hpp"
58
59namespace OpenMD {
60
61 void WrappingVisitor::visit(Atom* atom) { internalVisit(atom); }
62
63 void WrappingVisitor::visit(DirectionalAtom* datom) { internalVisit(datom); }
64
65 void WrappingVisitor::visit(RigidBody* rb) { internalVisit(rb); }
66
67 void WrappingVisitor::internalVisit(StuntDouble* sd) {
68 std::shared_ptr<GenericData> data;
69 std::shared_ptr<AtomData> atomData;
70 std::shared_ptr<AtomInfo> atomInfo;
71 std::vector<std::shared_ptr<AtomInfo>>::iterator i;
72
73 data = sd->getPropertyByName("ATOMDATA");
74
75 if (data != nullptr) {
76 atomData = std::dynamic_pointer_cast<AtomData>(data);
77
78 if (atomData == nullptr) return;
79 } else
80 return;
81
82 Snapshot* currSnapshot = info->getSnapshotManager()->getCurrentSnapshot();
83
84 for (atomInfo = atomData->beginAtomInfo(i); atomInfo;
85 atomInfo = atomData->nextAtomInfo(i)) {
86 Vector3d newPos = atomInfo->pos - origin_;
87 currSnapshot->wrapVector(newPos);
88 atomInfo->pos = newPos;
89 }
90 }
91
92 void WrappingVisitor::update() {
93 if (useCom_) {
94 Thermo thermo(info);
95 origin_ = thermo.getCom();
96 }
97 }
98
99 const std::string WrappingVisitor::toString() {
100 char buffer[65535];
101 std::string result;
102
103 snprintf(
104 buffer, 65535,
105 "------------------------------------------------------------------\n");
106 result += buffer;
107
108 snprintf(buffer, 65535, "Visitor name: %s\n", visitorName.c_str());
109 result += buffer;
110
111 snprintf(buffer, 65535,
112 "Visitor Description: wrapping atoms back to periodic box\n");
113 result += buffer;
114
115 snprintf(
116 buffer, 65535,
117 "------------------------------------------------------------------\n");
118 result += buffer;
119
120 return result;
121 }
122
123 //----------------------------------------------------------------------------//
124
125 ReplicateVisitor::ReplicateVisitor(SimInfo* info, Vector3i opt) :
126 BaseVisitor(), replicateOpt(opt) {
127 this->info = info;
128 visitorName = "ReplicateVisitor";
129
130 // generate the replicate directions
131 for (int i = 0; i <= replicateOpt[0]; i++) {
132 for (int j = 0; j <= replicateOpt[1]; j++) {
133 for (int k = 0; k <= replicateOpt[2]; k++) {
134 // skip original frame
135 if (i == 0 && j == 0 && k == 0) {
136 continue;
137 } else {
138 dir.push_back(Vector3d((RealType)i, (RealType)j, (RealType)k));
139 }
140 }
141 }
142 }
143 }
144
145 void ReplicateVisitor::visit(Atom* atom) { internalVisit(atom); }
146
147 void ReplicateVisitor::visit(DirectionalAtom* datom) { internalVisit(datom); }
148
149 void ReplicateVisitor::visit(RigidBody* rb) { internalVisit(rb); }
150
151 void ReplicateVisitor::internalVisit(StuntDouble* sd) {
152 std::shared_ptr<GenericData> data;
153 std::shared_ptr<AtomData> atomData;
154
155 // if there is not atom data, just skip it
156 data = sd->getPropertyByName("ATOMDATA");
157
158 if (data != nullptr) {
159 atomData = std::dynamic_pointer_cast<AtomData>(data);
160
161 if (atomData == nullptr) { return; }
162 } else {
163 return;
164 }
165
166 Snapshot* currSnapshot = info->getSnapshotManager()->getCurrentSnapshot();
167 Mat3x3d box = currSnapshot->getHmat();
168
169 std::vector<std::shared_ptr<AtomInfo>> atomInfoList = atomData->getData();
170
171 replicate(atomInfoList, atomData, box);
172 }
173
174 void ReplicateVisitor::replicate(
175 std::vector<std::shared_ptr<AtomInfo>>& infoList,
176 std::shared_ptr<AtomData> data, const Mat3x3d& box) {
177 std::shared_ptr<AtomInfo> newAtomInfo;
178 std::vector<Vector3d>::iterator dirIter;
179 std::vector<std::shared_ptr<AtomInfo>>::iterator i;
180
181 for (dirIter = dir.begin(); dirIter != dir.end(); ++dirIter) {
182 for (i = infoList.begin(); i != infoList.end(); ++i) {
183 newAtomInfo = std::make_shared<AtomInfo>();
184 *newAtomInfo = *(*i);
185 newAtomInfo->pos += box * (*dirIter);
186 data->addAtomInfo(newAtomInfo);
187 }
188 }
189 }
190
191 const std::string ReplicateVisitor::toString() {
192 char buffer[65535];
193 std::string result;
194
195 snprintf(
196 buffer, 65535,
197 "--------------------------------------------------------------\n");
198 result += buffer;
199
200 snprintf(buffer, 65535, "Visitor name: %s\n", visitorName.c_str());
201 result += buffer;
202
203 snprintf(
204 buffer, 65535,
205 "Visitor Description: replicate the atoms in different direction\n");
206 result += buffer;
207
208 // print the replicate direction
209 snprintf(buffer, 65535, "repeatX = %d:\n", replicateOpt[0]);
210 result += buffer;
211
212 snprintf(buffer, 65535, "repeatY = %d:\n", replicateOpt[1]);
213 result += buffer;
214
215 snprintf(buffer, 65535, "repeatZ = %d:\n", replicateOpt[2]);
216 result += buffer;
217
218 snprintf(
219 buffer, 65535,
220 "--------------------------------------------------------------\n");
221 result += buffer;
222
223 return result;
224 }
225
226 //------------------------------------------------------------------------//
227
228 XYZVisitor::XYZVisitor(SimInfo* info) :
229 BaseVisitor(), seleMan(info), evaluator(info), doPositions_(true),
230 doVelocities_(false), doForces_(false), doVectors_(false),
231 doCharges_(false), doElectricFields_(false), doGlobalIDs_(false) {
232 this->info = info;
233 visitorName = "XYZVisitor";
234
235 evaluator.loadScriptString("select all");
236
237 if (!evaluator.isDynamic()) {
238 seleMan.setSelectionSet(evaluator.evaluate());
239 }
240 }
241
242 XYZVisitor::XYZVisitor(SimInfo* info, const std::string& script) :
243 BaseVisitor(), seleMan(info), evaluator(info), doPositions_(true),
244 doVelocities_(false), doForces_(false), doVectors_(false),
245 doCharges_(false), doElectricFields_(false), doGlobalIDs_(false) {
246 this->info = info;
247 visitorName = "XYZVisitor";
248
249 evaluator.loadScriptString(script);
250
251 if (!evaluator.isDynamic()) {
252 seleMan.setSelectionSet(evaluator.evaluate());
253 }
254 }
255
256 void XYZVisitor::visit(Atom* atom) {
257 if (isSelected(atom)) internalVisit(atom);
258 }
259
260 void XYZVisitor::visit(DirectionalAtom* datom) {
261 if (isSelected(datom)) internalVisit(datom);
262 }
263
264 void XYZVisitor::visit(RigidBody* rb) {
265 if (isSelected(rb)) internalVisit(rb);
266 }
267
268 void XYZVisitor::update() {
269 // if dynamic, we need to re-evaluate the selection
270 if (evaluator.isDynamic()) {
271 seleMan.setSelectionSet(evaluator.evaluate());
272 }
273 }
274
275 void XYZVisitor::internalVisit(StuntDouble* sd) {
276 std::shared_ptr<GenericData> data;
277 std::shared_ptr<AtomData> atomData;
278 std::shared_ptr<AtomInfo> atomInfo;
279 std::vector<std::shared_ptr<AtomInfo>>::iterator i;
280 char buffer[1024];
281
282 // if there is not atom data, just skip it
283 data = sd->getPropertyByName("ATOMDATA");
284
285 if (data != nullptr) {
286 atomData = std::dynamic_pointer_cast<AtomData>(data);
287
288 if (atomData == nullptr) return;
289 } else
290 return;
291
292 for (atomInfo = atomData->beginAtomInfo(i); atomInfo;
293 atomInfo = atomData->nextAtomInfo(i)) {
294 std::string line;
295 snprintf(buffer, 1024, "%s", atomInfo->atomTypeName.c_str());
296 line += buffer;
297
298 if (doPositions_) {
299 snprintf(buffer, 1024, "%15.8f%15.8f%15.8f", atomInfo->pos[0],
300 atomInfo->pos[1], atomInfo->pos[2]);
301 line += buffer;
302 }
303 if (doCharges_ && atomInfo->hasCharge) {
304 snprintf(buffer, 1024, "%15.8f", atomInfo->charge);
305 line += buffer;
306 }
307 if (doVectors_ && atomInfo->hasVector) {
308 snprintf(buffer, 1024, "%15.8f%15.8f%15.8f", atomInfo->vec[0],
309 atomInfo->vec[1], atomInfo->vec[2]);
310 line += buffer;
311 }
312 if (doVelocities_ && atomInfo->hasVelocity) {
313 snprintf(buffer, 1024, "%15.8f%15.8f%15.8f", atomInfo->vel[0],
314 atomInfo->vel[1], atomInfo->vel[2]);
315 line += buffer;
316 }
317 if (doForces_ && atomInfo->hasForce) {
318 snprintf(buffer, 1024, "%15.8f%15.8f%15.8f", atomInfo->frc[0],
319 atomInfo->frc[1], atomInfo->frc[2]);
320 line += buffer;
321 }
322 if (doElectricFields_ && atomInfo->hasElectricField) {
323 snprintf(buffer, 1024, "%15.8f%15.8f%15.8f", atomInfo->eField[0],
324 atomInfo->eField[1], atomInfo->eField[2]);
325 line += buffer;
326 }
327 if (doGlobalIDs_) {
328 snprintf(buffer, 1024, "%10d", atomInfo->globalID);
329 line += buffer;
330 }
331
332 frame.push_back(line);
333 }
334 }
335
336 bool XYZVisitor::isSelected(StuntDouble* sd) {
337 return seleMan.isSelected(sd);
338 }
339
340 void XYZVisitor::writeFrame(std::ostream& outStream) {
341 std::vector<std::string>::iterator i;
342 char buffer[1024];
343
344 if (frame.empty())
345 std::cerr << "Current Frame does not contain any atoms" << std::endl;
346
347 // total number of atoms
348 outStream << frame.size() << std::endl;
349
350 // write comment line
351 Snapshot* currSnapshot = info->getSnapshotManager()->getCurrentSnapshot();
352 Mat3x3d box = currSnapshot->getHmat();
353
354 snprintf(buffer, 1024,
355 "%15.8f;%15.8f%15.8f%15.8f;%15.8f%15.8f%15.8f;%15.8f%15.8f%15.8f",
356 currSnapshot->getTime(), box(0, 0), box(0, 1), box(0, 2),
357 box(1, 0), box(1, 1), box(1, 2), box(2, 0), box(2, 1), box(2, 2));
358
359 outStream << buffer << std::endl;
360
361 for (i = frame.begin(); i != frame.end(); ++i)
362 outStream << *i << std::endl;
363 }
364
365 std::string XYZVisitor::trimmedName(const std::string& atomTypeName) {
366 return atomTypeName.substr(0, atomTypeName.find('-'));
367 }
368
369 const std::string XYZVisitor::toString() {
370 char buffer[65535];
371 std::string result;
372
373 snprintf(
374 buffer, 65535,
375 "------------------------------------------------------------------\n");
376 result += buffer;
377
378 snprintf(buffer, 65535, "Visitor name: %s\n", visitorName.c_str());
379 result += buffer;
380
381 snprintf(
382 buffer, 65535,
383 "Visitor Description: assemble the atom data and output xyz file\n");
384 result += buffer;
385
386 snprintf(
387 buffer, 65535,
388 "------------------------------------------------------------------\n");
389 result += buffer;
390
391 return result;
392 }
393
394 //----------------------------------------------------------------------------//
395
396 void PrepareVisitor::internalVisit(Atom* atom) {
397 std::shared_ptr<GenericData> data;
398
399 // if visited property is existed, remove it
400 data = atom->getPropertyByName("VISITED");
401
402 if (data != nullptr) { atom->removeProperty("VISITED"); }
403
404 // remove atomdata
405 data = atom->getPropertyByName("ATOMDATA");
406
407 if (data != nullptr) {
408 std::shared_ptr<AtomData> atomData =
409 std::dynamic_pointer_cast<AtomData>(data);
410
411 if (atomData != NULL) atom->removeProperty("ATOMDATA");
412 }
413 }
414
415 void PrepareVisitor::internalVisit(RigidBody* rb) {
416 std::shared_ptr<GenericData> data;
417 std::shared_ptr<AtomData> atomData;
418 std::vector<Atom*> myAtoms;
419 std::vector<Atom*>::iterator atomIter;
420
421 // if visited property is existed, remove it
422 data = rb->getPropertyByName("VISITED");
423
424 if (data != nullptr) { rb->removeProperty("VISITED"); }
425
426 // remove atomdata
427 data = rb->getPropertyByName("ATOMDATA");
428
429 if (data != nullptr) {
430 atomData = std::dynamic_pointer_cast<AtomData>(data);
431
432 if (atomData != NULL) rb->removeProperty("ATOMDATA");
433 }
434
435 myAtoms = rb->getAtoms();
436
437 for (atomIter = myAtoms.begin(); atomIter != myAtoms.end(); ++atomIter)
438 internalVisit(*atomIter);
439 }
440
441 const std::string PrepareVisitor::toString() {
442 char buffer[65535];
443 std::string result;
444
445 snprintf(
446 buffer, 65535,
447 "------------------------------------------------------------------\n");
448 result += buffer;
449
450 snprintf(buffer, 65535, "Visitor name: %s", visitorName.c_str());
451 result += buffer;
452
453 snprintf(buffer, 65535,
454 "Visitor Description: prepare for operation of other vistors\n");
455 result += buffer;
456
457 snprintf(
458 buffer, 65535,
459 "------------------------------------------------------------------\n");
460 result += buffer;
461
462 return result;
463 }
464
465 //----------------------------------------------------------------------------//
466
467 WaterTypeVisitor::WaterTypeVisitor() {
468 visitorName = "WaterTypeVisitor";
469 waterTypeList.insert("TIP3P_RB_0");
470 waterTypeList.insert("TIP3P-FB_RB_0");
471 waterTypeList.insert("TIP4P_RB_0");
472 waterTypeList.insert("TIP4P-Ice_RB_0");
473 waterTypeList.insert("TIP4P-Ew_RB_0");
474 waterTypeList.insert("TIP4P-2005_RB_0");
475 waterTypeList.insert("TIP4P-FB_RB_0");
476 waterTypeList.insert("TIP5P_RB_0");
477 waterTypeList.insert("TIP5P-E_RB_0");
478 waterTypeList.insert("SPCE_RB_0");
479 waterTypeList.insert("SPC_RB_0");
480 waterTypeList.insert("SPC-HW_RB_0");
481 waterTypeList.insert("NE6_RB_0");
482 waterTypeList.insert("OPC_RB_0");
483 waterTypeList.insert("OPC3_RB_0");
484 }
485
486 void WaterTypeVisitor::visit(RigidBody* rb) {
487 std::string rbName;
488 std::vector<Atom*> myAtoms;
489 std::vector<Atom*>::iterator atomIter;
490 std::vector<std::shared_ptr<AtomInfo>>::iterator i;
491 std::shared_ptr<AtomData> atomData;
492
493 rbName = rb->getType();
494
495 if (waterTypeList.find(rbName) != waterTypeList.end()) {
496 myAtoms = rb->getAtoms();
497
498 for (atomIter = myAtoms.begin(); atomIter != myAtoms.end(); ++atomIter) {
499 std::shared_ptr<GenericData> data =
500 (*atomIter)->getPropertyByName("ATOMDATA");
501
502 if (data != nullptr) {
503 atomData = std::dynamic_pointer_cast<AtomData>(data);
504
505 if (atomData == nullptr) continue;
506 } else
507 continue;
508
509 for (std::shared_ptr<AtomInfo> atomInfo = atomData->beginAtomInfo(i);
510 atomInfo; atomInfo = atomData->nextAtomInfo(i)) {
511 atomInfo->atomTypeName = trimmedName(atomInfo->atomTypeName);
512 }
513 }
514 }
515 }
516
517 std::string WaterTypeVisitor::trimmedName(const std::string& atomTypeName) {
518 return atomTypeName.substr(0, atomTypeName.find('_'));
519 }
520
521 const std::string WaterTypeVisitor::toString() {
522 char buffer[65535];
523 std::string result;
524
525 snprintf(
526 buffer, 65535,
527 "------------------------------------------------------------------\n");
528 result += buffer;
529
530 snprintf(buffer, 65535, "Visitor name: %s\n", visitorName.c_str());
531 result += buffer;
532
533 snprintf(buffer, 65535,
534 "Visitor Description: Replace the atom type in water model\n");
535 result += buffer;
536
537 snprintf(
538 buffer, 65535,
539 "------------------------------------------------------------------\n");
540 result += buffer;
541
542 return result;
543 }
544
545} // namespace OpenMD
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
"Don't move, or you're dead! Stand up! Captain, we've got them!"
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.