OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ShapeBuilder.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#include "hydrodynamics/ShapeBuilder.hpp"
48
49#include "hydrodynamics/CompositeShape.hpp"
50#include "hydrodynamics/Ellipsoid.hpp"
51#include "hydrodynamics/Sphere.hpp"
52#include "types/GayBerneAdapter.hpp"
53#include "types/LennardJonesAdapter.hpp"
54
55namespace OpenMD {
56
57 Shape* ShapeBuilder::createShape(StuntDouble* sd) {
58 Shape* currShape = NULL;
59 if (sd->isDirectionalAtom()) {
60 currShape = internalCreateShape(static_cast<DirectionalAtom*>(sd));
61 } else if (sd->isAtom()) {
62 currShape = internalCreateShape(static_cast<Atom*>(sd));
63 } else if (sd->isRigidBody()) {
64 currShape = internalCreateShape(static_cast<RigidBody*>(sd));
65 }
66 return currShape;
67 }
68
69 Shape* ShapeBuilder::createShape(Molecule* mol) {
70 Molecule::IntegrableObjectIterator j;
71 StuntDouble* sd;
72
73 if (mol->getNAtoms() == 1) {
74 Shape* molShape = createShape(mol->getAtomAt(0));
75 return molShape;
76 } else {
77 CompositeShape* molShape = new CompositeShape();
78 for (sd = mol->beginIntegrableObject(j); sd != NULL;
79 sd = mol->nextIntegrableObject(j)) {
80 Shape* currShape = createShape(sd);
81 if (currShape != NULL) { molShape->addShape(currShape); }
82 }
83 molShape->setName(mol->getType());
84 return molShape;
85 }
86 return NULL;
87 }
88
89 Shape* ShapeBuilder::internalCreateShape(Atom* atom) {
90 AtomType* atomType = atom->getAtomType();
91 Shape* currShape = NULL;
92 LennardJonesAdapter lja = LennardJonesAdapter(atomType);
93 if (lja.isLennardJones()) {
94 currShape = new Sphere(atom->getPos(), lja.getSigma() / 2.0);
95 currShape->setName(atom->getType());
96 } else {
97 int obanum(0);
98 std::vector<AtomType*> atChain = atomType->allYourBase();
99 std::vector<AtomType*>::iterator i;
100 for (i = atChain.begin(); i != atChain.end(); ++i) {
101 obanum = etab.GetAtomicNum((*i)->getName().c_str());
102 if (obanum != 0) {
103 currShape = new Sphere(atom->getPos(), etab.GetVdwRad(obanum));
104 currShape->setName(atom->getType());
105 break;
106 }
107 }
108 if (obanum == 0) {
109 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
110 "Could not find atom type in default element.txt\n");
111 painCave.severity = OPENMD_ERROR;
112 painCave.isFatal = 1;
113 simError();
114 }
115 }
116 return currShape;
117 }
118
119 Shape* ShapeBuilder::internalCreateShape(DirectionalAtom* datom) {
120 AtomType* atomType = datom->getAtomType();
121 Shape* currShape = NULL;
122 LennardJonesAdapter lja = LennardJonesAdapter(atomType);
123 GayBerneAdapter gba = GayBerneAdapter(atomType);
124 if (gba.isGayBerne()) {
125 currShape = new Ellipsoid(datom->getPos(), gba.getL() / 2.0,
126 gba.getD() / 2.0, datom->getA());
127 } else if (lja.isLennardJones()) {
128 currShape = new Sphere(datom->getPos(), lja.getSigma() / 2.0);
129 } else {
130 int obanum = etab.GetAtomicNum((datom->getType()).c_str());
131 if (obanum != 0) {
132 currShape = new Sphere(datom->getPos(), etab.GetVdwRad(obanum));
133 } else {
134 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
135 "Could not find atom type in default element.txt\n");
136 painCave.severity = OPENMD_ERROR;
137 painCave.isFatal = 1;
138 simError();
139 }
140 }
141 currShape->setName(datom->getType());
142 return currShape;
143 }
144
145 Shape* ShapeBuilder::internalCreateShape(RigidBody* rb) {
146 std::vector<Atom*>::iterator ai;
147 CompositeShape* compositeShape = new CompositeShape;
148 Atom* atom;
149 for (atom = rb->beginAtom(ai); atom != NULL; atom = rb->nextAtom(ai)) {
150 Shape* currShape = NULL;
151 if (atom->isDirectionalAtom()) {
152 currShape = internalCreateShape(static_cast<DirectionalAtom*>(atom));
153 } else if (atom->isAtom()) {
154 currShape = internalCreateShape(static_cast<Atom*>(atom));
155 }
156 if (currShape != NULL) {
157 compositeShape->addShape(currShape);
158 compositeShape->setName(rb->getType());
159 }
160 }
161 return compositeShape;
162 }
163} // namespace OpenMD
RealType GetVdwRad(int atomicnum)
int GetAtomicNum(const char *str)
"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.