OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
omd2omd.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
45#include <fstream>
46#include <iostream>
47#include <string>
48
50#include "brains/Register.hpp"
51#include "brains/SimCreator.hpp"
52#include "brains/SimInfo.hpp"
53#include "brains/Thermo.hpp"
54#include "io/DumpReader.hpp"
55#include "io/DumpWriter.hpp"
56#include "math/Quaternion.hpp"
57#include "omd2omdCmd.hpp"
58#include "types/FluctuatingChargeAdapter.hpp"
59#include "utils/Constants.hpp"
60#include "utils/simError.h"
61
62using namespace OpenMD;
63
64using namespace std;
65
66void createMdFile(const std::string& oldMdFileName,
67 const std::string& newMdFileName, std::vector<int> nMol);
68
69int main(int argc, char* argv[]) {
70 gengetopt_args_info args_info;
71 string dumpFileName;
72 string outFileName;
73
74 // parse the command line option
75 if (cmdline_parser(argc, argv, &args_info) != 0) { exit(1); }
76
77 // get the dumpfile name and meta-data file name
78 if (args_info.input_given) {
79 dumpFileName = args_info.input_arg;
80 } else {
81 strcpy(painCave.errMsg, "No input file name was specified.\n");
82 painCave.isFatal = 1;
83 simError();
84 }
85
86 if (args_info.output_given) {
87 outFileName = args_info.output_arg;
88 } else {
89 strcpy(painCave.errMsg, "No output file name was specified.\n");
90 painCave.isFatal = 1;
91 simError();
92 }
93
94 // convert the input angles to radians for computation
95 double phi = args_info.rotatePhi_arg * (Constants::PI / 180.0);
96 double theta = args_info.rotateTheta_arg * (Constants::PI / 180.0);
97 double psi = args_info.rotatePsi_arg * (Constants::PI / 180.0);
98
99 Mat3x3d rotMatrix = Mat3x3d(0.0);
100
101 rotMatrix.setupRotMat(phi, theta, psi);
102
103 Vector3i repeat = Vector3i(args_info.repeatX_arg, args_info.repeatY_arg,
104 args_info.repeatZ_arg);
105
106 Mat3x3d repeatD = Mat3x3d(0.0);
107 repeatD(0, 0) = repeat.x();
108 repeatD(1, 1) = repeat.y();
109 repeatD(2, 2) = repeat.z();
110
111 Vector3d translate =
112 Vector3d(args_info.translateX_arg, args_info.translateY_arg,
113 args_info.translateZ_arg);
114
115 // parse md file and set up the system
116
117 SimCreator oldCreator;
118 SimInfo* oldInfo = oldCreator.createSim(dumpFileName, false);
119 Globals* simParams = oldInfo->getSimParams();
120 std::vector<Component*> components = simParams->getComponents();
121 std::vector<int> nMol;
122 for (vector<Component*>::iterator i = components.begin();
123 i != components.end(); ++i) {
124 int nMolOld = (*i)->getNMol();
125 int nMolNew = nMolOld * repeat.x() * repeat.y() * repeat.z();
126 nMol.push_back(nMolNew);
127 }
128
129 createMdFile(dumpFileName, outFileName, nMol);
130
131 SimCreator newCreator;
132 SimInfo* newInfo = newCreator.createSim(outFileName, false);
133
134 DumpReader* dumpReader = new DumpReader(oldInfo, dumpFileName);
135 int nframes = dumpReader->getNFrames();
136
137 DumpWriter* writer = new DumpWriter(newInfo, outFileName);
138 if (writer == NULL) {
139 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
140 "error in creating DumpWriter");
141 painCave.isFatal = 1;
142 simError();
143 }
144
145 SimInfo::MoleculeIterator miter;
146 Molecule::IntegrableObjectIterator iiter;
147 Molecule::RigidBodyIterator rbIter;
148 Molecule* mol;
149 StuntDouble* sd;
150 StuntDouble* sdNew;
151 RigidBody* rb;
152 Mat3x3d oldHmat;
153 Mat3x3d rotHmat;
154 Mat3x3d newHmat;
155 Snapshot* oldSnap;
156 Snapshot* newSnap;
157 Vector3d oldPos;
158 Vector3d newPos;
159 Vector3d relPos;
160 Vector3d COM;
161 Vector3d molCOM;
162 Thermo thermo(oldInfo);
163 AtomType* atype;
164
165 for (int i = 0; i < nframes; i++) {
166 cerr << "frame = " << i << "\n";
167 dumpReader->readFrame(i);
168 oldSnap = oldInfo->getSnapshotManager()->getCurrentSnapshot();
169 newSnap = newInfo->getSnapshotManager()->getCurrentSnapshot();
170
171 newSnap->setID(oldSnap->getID());
172 newSnap->setTime(oldSnap->getTime());
173
174 oldHmat = oldSnap->getHmat();
175 rotHmat = rotMatrix * oldHmat;
176 newHmat = repeatD * rotHmat;
177 newSnap->setHmat(newHmat);
178
179 newSnap->setThermostat(oldSnap->getThermostat());
180 newSnap->setBarostat(oldSnap->getBarostat());
181
182 // Do one loop to re-center and re-rewrap the old system
183
184 if (args_info.noCOM_flag) {
185 COM = V3Zero;
186 } else {
187 COM = thermo.getCom();
188 }
189
190 for (mol = oldInfo->beginMolecule(miter); mol != NULL;
191 mol = oldInfo->nextMolecule(miter)) {
192
193 if (args_info.repairMolecules_arg == 1) {
194 molCOM = mol->getCom();
195 }
196
197 for (sd = mol->beginIntegrableObject(iiter); sd != NULL;
198 sd = mol->nextIntegrableObject(iiter)) {
199
200 if (args_info.repairMolecules_arg == 1) {
201
202 relPos = sd->getPos() - molCOM;
203 oldPos = molCOM - COM;
204
205 if (!args_info.noWrap_flag) {
206 oldSnap->wrapVector(relPos);
207 oldSnap->wrapVector(oldPos);
208 }
209
210 oldPos += relPos;
211
212 } else {
213
214 oldPos = sd->getPos() - COM;
215
216 if (!args_info.noWrap_flag) {
217 oldSnap->wrapVector(oldPos);
218 }
219
220 }
221 sd->setPos(oldPos);
222 }
223 }
224
225 // now a second pass through to translate and rotate into the new
226
227 int newIndex = 0;
228 for (mol = oldInfo->beginMolecule(miter); mol != NULL;
229 mol = oldInfo->nextMolecule(miter)) {
230
231 for (int ii = 0; ii < repeat.x(); ii++) {
232 for (int jj = 0; jj < repeat.y(); jj++) {
233 for (int kk = 0; kk < repeat.z(); kk++) {
234
235 Vector3d trans = Vector3d(ii, jj, kk);
236
237 for (sd = mol->beginIntegrableObject(iiter); sd != NULL;
238 sd = mol->nextIntegrableObject(iiter)) {
239
240 oldPos = sd->getPos();
241
242 newPos = rotMatrix * oldPos + trans * oldHmat + translate;
243
244 sdNew = newInfo->getIOIndexToIntegrableObject(newIndex);
245 sdNew->setPos(newPos);
246 sdNew->setVel(rotMatrix * sd->getVel());
247
248 if (sd->isDirectional()) {
249 Mat3x3d bodyRotMat = sd->getA();
250 bodyRotMat = bodyRotMat * rotMatrix.inverse();
251 sdNew->setA(bodyRotMat);
252 sdNew->setJ(rotMatrix * sd->getJ());
253 }
254
255 if (sd->isAtom()) {
256 atype = static_cast<Atom*>(sd)->getAtomType();
258 if (fqa.isFluctuatingCharge()) {
259 RealType charge = sd->getFlucQPos();
260 sdNew->setFlucQPos(charge);
261 RealType cv = sd->getFlucQVel();
262 sdNew->setFlucQVel(cv);
263 }
264 }
265
266 newIndex++;
267 }
268 }
269 }
270 }
271 }
272
273 // update atoms of rigidbody
274 for (mol = newInfo->beginMolecule(miter); mol != NULL;
275 mol = newInfo->nextMolecule(miter)) {
276 // change the positions of atoms which belong to the rigidbodies
277 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
278 rb = mol->nextRigidBody(rbIter)) {
279 rb->updateAtoms();
280 rb->updateAtomVel();
281 }
282 }
283
284 writer->writeDump();
285 }
286 // deleting the writer will put the closing at the end of the dump file.
287 delete writer;
288 delete oldInfo;
289}
290
291void createMdFile(const std::string& oldMdFileName,
292 const std::string& newMdFileName, std::vector<int> nMol) {
293 ifstream oldMdFile;
294 ofstream newMdFile;
295 const int MAXLEN = 65535;
296 char buffer[MAXLEN];
297
298 // create new .omd file based on old .omd file
299
300 oldMdFile.open(oldMdFileName.c_str());
301 newMdFile.open(newMdFileName.c_str());
302
303 oldMdFile.getline(buffer, MAXLEN);
304
305 std::size_t i = 0;
306 while (!oldMdFile.eof()) {
307 // correct molecule number
308 if (strstr(buffer, "nMol") != NULL) {
309 if (i < nMol.size()) {
310 snprintf(buffer, MAXLEN, "\tnMol = %i;", nMol.at(i));
311 newMdFile << buffer << std::endl;
312 i++;
313 }
314 } else
315 newMdFile << buffer << std::endl;
316
317 oldMdFile.getline(buffer, MAXLEN);
318 }
319
320 oldMdFile.close();
321 newMdFile.close();
322
323 if (i != nMol.size()) {
324 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
325 "Couldn't replace the correct number of nMol\n"
326 "\tstatements in component blocks.");
327 painCave.isFatal = 1;
328 simError();
329 }
330}
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition AtomType.hpp:66
int getNFrames()
Returns the number of frames in the dump file.
Vector3d getCom()
Returns the current center of mass position of this molecule.
Definition Molecule.cpp:298
void updateAtoms()
update the positions of atoms belong to this rigidbody
The only responsibility of SimCreator is to parse the meta-data file and create a SimInfo instance ba...
SimInfo * createSim(const std::string &mdFileName, bool loadInitCoords=true)
Setup Simulation.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:93
Molecule * beginMolecule(MoleculeIterator &i)
Returns the first molecule in this SimInfo and intialize the iterator.
Definition SimInfo.cpp:240
Molecule * nextMolecule(MoleculeIterator &i)
Returns the next avaliable Molecule based on the iterator.
Definition SimInfo.cpp:245
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
Definition SimInfo.hpp:248
StuntDouble * getIOIndexToIntegrableObject(int index)
return an integral objects by its global index.
Definition SimInfo.cpp:1027
The Snapshot class is a repository storing dynamic data during a Simulation.
Definition Snapshot.hpp:147
Mat3x3d getHmat()
Returns the H-Matrix.
Definition Snapshot.cpp:214
void setHmat(const Mat3x3d &m)
Sets the H-Matrix.
Definition Snapshot.cpp:217
void setID(int id)
Sets the id of this Snapshot.
Definition Snapshot.cpp:195
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
Definition Snapshot.cpp:337
int getID()
Returns the id of this Snapshot.
Definition Snapshot.cpp:192
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
SquareMatrix3< Real > inverse() const
Sets the value of this matrix to the inverse of itself.
void setupRotMat(const Vector3< Real > &eulerAngles)
Sets this matrix to a rotation matrix by three euler angles @ param euler.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
void setFlucQVel(RealType cvel)
Sets the current charge velocity of this stuntDouble.
RotMat3x3d getA()
Returns the current rotation matrix of this stuntDouble.
Vector3d getVel()
Returns the current velocity of this stuntDouble.
virtual void setA(const RotMat3x3d &a)
Sets the current rotation matrix of this stuntDouble.
void setFlucQPos(RealType charge)
Sets the current fluctuating charge of this stuntDouble.
Vector3d getPos()
Returns the current position of this stuntDouble.
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
void setPos(const Vector3d &pos)
Sets the current position of this stuntDouble.
void setVel(const Vector3d &vel)
Sets the current velocity of this stuntDouble.
Vector3d getJ()
Returns the current angular momentum of this stuntDouble (body -fixed).
bool isAtom()
Tests if this stuntDouble is an atom.
bool isDirectional()
Tests if this stuntDouble is a directional one.
void setJ(const Vector3d &angMom)
Sets the current angular momentum of this stuntDouble (body-fixed).
RealType getFlucQVel()
Returns the current charge velocity of this stuntDouble.
Real & z()
Returns reference of the third element of Vector3.
Definition Vector3.hpp:120
Real & x()
Returns reference of the first element of Vector3.
Definition Vector3.hpp:96
Real & y()
Returns reference of the second element of Vector3.
Definition Vector3.hpp:108
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
The header file for the command line option parser generated by GNU Gengetopt version 2....
Where the command line options are stored.
double translateY_arg
translate all y coordinates by some amount (default='0.0').
int repeatY_arg
The number of images to repeat in the y direction (default='0').
unsigned int output_given
Whether output was given.
double translateZ_arg
translate all z coordinates by some amount (default='0.0').
int noCOM_flag
do not use Center of Mass as origin of the box (default=off).
int repeatX_arg
The number of images to repeat in the x direction (default='0').
double rotateTheta_arg
rotate all coordinates Euler angle Theta (default='0.0').
int repairMolecules_arg
rewrap molecules around the molecular center of mass (default='1').
char * output_arg
output file name.
char * input_arg
input dump file.
int repeatZ_arg
The number of images to repeat in the z direction (default='0').
int noWrap_flag
do not rewrap coordinates into the box (default=off).
double rotatePhi_arg
rotate all coordinates Euler angle Phi (default='0.0').
unsigned int input_given
Whether input was given.
double rotatePsi_arg
rotate all coordinates Euler angle Psi (default='0.0').
double translateX_arg
translate all x coordinates by some amount (default='0.0').