OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
simpleBuilder.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 <cmath>
46#include <cstdio>
47#include <cstdlib>
48#include <cstring>
49#include <fstream>
50#include <iostream>
51#include <map>
52#include <string>
53
54#include "brains/Register.hpp"
55#include "brains/SimCreator.hpp"
56#include "brains/SimInfo.hpp"
57#include "io/DumpWriter.hpp"
58#include "lattice/Lattice.hpp"
61#include "math/Vector3.hpp"
62#include "simpleBuilderCmd.hpp"
63#include "utils/MoLocator.hpp"
64#include "utils/StringUtils.hpp"
65
66using namespace std;
67using namespace OpenMD;
68
69void createMdFile(const std::string& oldMdFileName,
70 const std::string& newMdFileName, int nMol);
71
72int main(int argc, char* argv[]) {
74
75 gengetopt_args_info args_info;
76 std::string latticeType;
77 std::string inputFileName;
78 std::string outputFileName;
79 Lattice* simpleLat;
80 RealType latticeConstant;
81 std::vector<RealType> lc;
82 const RealType rhoConvertConst = 1.66053886;
83 RealType density;
84 int nx, ny, nz;
85 Mat3x3d hmat;
86 MoLocator* locator;
87 std::vector<Vector3d> latticePos;
88 std::vector<Vector3d> latticeOrt;
89 int nMolPerCell;
90 DumpWriter* writer;
91
92 // parse command line arguments
93 if (cmdline_parser(argc, argv, &args_info) != 0) exit(1);
94
95 density = args_info.density_arg;
96
97 // get lattice type
98 latticeType = "FCC";
99 if (args_info.lattice_given) { latticeType = args_info.lattice_arg; }
100
101 simpleLat = LatticeFactory::getInstance().createLattice(latticeType);
102
103 if (simpleLat == NULL) {
104 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
105 "Lattice Factory can not create %s lattice\n",
106 latticeType.c_str());
107 painCave.isFatal = 1;
108 simError();
109 }
110 nMolPerCell = simpleLat->getNumSitesPerCell();
111
112 // get the number of unit cells in each direction:
113
114 nx = args_info.nx_arg;
115
116 if (nx <= 0) {
117 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
118 "The number of unit cells in the x direction "
119 "must be greater than 0.");
120 painCave.isFatal = 1;
121 simError();
122 }
123
124 ny = args_info.ny_arg;
125
126 if (ny <= 0) {
127 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
128 "The number of unit cells in the y direction "
129 "must be greater than 0.");
130 painCave.isFatal = 1;
131 simError();
132 }
133
134 nz = args_info.nz_arg;
135
136 if (nz <= 0) {
137 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
138 "The number of unit cells in the z direction "
139 "must be greater than 0.");
140 painCave.isFatal = 1;
141 simError();
142 }
143
144 int nSites = nMolPerCell * nx * ny * nz;
145
146 // get input file name
147 if (args_info.inputs_num)
148 inputFileName = args_info.inputs[0];
149 else {
150 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
151 "No input .omd file name was specified "
152 "on the command line");
153 painCave.isFatal = 1;
154 simError();
155 }
156
157 // parse md file and set up the system
158
159 SimCreator oldCreator;
160 SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
161
162 // Calculate lattice constant (in Angstroms)
163
164 RealType avgMass = MoLocator::getMolMass(oldInfo->getMoleculeStamp(0),
165 oldInfo->getForceField());
166
167 latticeConstant = pow(rhoConvertConst * nMolPerCell * avgMass / density,
168 (RealType)(1.0 / 3.0));
169
170 // Set the lattice constant
171
172 lc.push_back(latticeConstant);
173 simpleLat->setLatticeConstant(lc);
174
175 // Calculate the lattice sites and fill the lattice vector.
176
177 // Get the standard orientations of the cell sites
178
179 latticeOrt = simpleLat->getLatticePointsOrt();
180
181 vector<Vector3d> sites;
182 vector<Vector3d> orientations;
183
184 for (int i = 0; i < nx; i++) {
185 for (int j = 0; j < ny; j++) {
186 for (int k = 0; k < nz; k++) {
187 // Get the position of the cell sites
188
189 simpleLat->getLatticePointsPos(latticePos, i, j, k);
190
191 for (int l = 0; l < nMolPerCell; l++) {
192 sites.push_back(latticePos[l]);
193 orientations.push_back(latticeOrt[l]);
194 }
195 }
196 }
197 }
198
199 outputFileName = args_info.output_arg;
200
201 // create a new .omd file on the fly which corrects the number of molecules
202
203 createMdFile(inputFileName, outputFileName, nSites);
204
205 delete oldInfo;
206
207 // We need to read in the new SimInfo object, then Parse the
208 // md file and set up the system
209
210 SimCreator newCreator;
211 SimInfo* newInfo = newCreator.createSim(outputFileName, false);
212
213 // fill Hmat
214
215 hmat(0, 0) = nx * latticeConstant;
216 hmat(0, 1) = 0.0;
217 hmat(0, 2) = 0.0;
218
219 hmat(1, 0) = 0.0;
220 hmat(1, 1) = ny * latticeConstant;
221 hmat(1, 2) = 0.0;
222
223 hmat(2, 0) = 0.0;
224 hmat(2, 1) = 0.0;
225 hmat(2, 2) = nz * latticeConstant;
226
227 // Set Hmat
228
229 newInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
230
231 // place the molecules
232
233 Molecule* mol;
234 locator =
235 new MoLocator(newInfo->getMoleculeStamp(0), newInfo->getForceField());
236 for (int n = 0; n < nSites; n++) {
237 mol = newInfo->getMoleculeByGlobalIndex(n);
238 locator->placeMol(sites[n], orientations[n], mol);
239 }
240
241 // Create DumpWriter and write out the coordinates
242
243 writer = new DumpWriter(newInfo, outputFileName);
244
245 if (writer == NULL) {
246 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
247 "error in creating DumpWriter");
248 painCave.isFatal = 1;
249 simError();
250 }
251
252 writer->writeDump();
253
254 // deleting the writer will put the closing at the end of the dump file.
255
256 delete writer;
257
258 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
259 "A new OpenMD file called \"%s\" has been generated.\n",
260 outputFileName.c_str());
261 painCave.isFatal = 0;
262 painCave.severity = OPENMD_INFO;
263 simError();
264 return 0;
265}
266
267void createMdFile(const std::string& oldMdFileName,
268 const std::string& newMdFileName, int nMol) {
269 ifstream oldMdFile;
270 ofstream newMdFile;
271 const int MAXLEN = 65535;
272 char buffer[MAXLEN];
273
274 // create new .omd file based on old .omd file
275 oldMdFile.open(oldMdFileName.c_str());
276 newMdFile.open(newMdFileName.c_str());
277
278 oldMdFile.getline(buffer, MAXLEN);
279
280 while (!oldMdFile.eof()) {
281 // correct molecule number
282 if (strstr(buffer, "nMol") != NULL) {
283 snprintf(buffer, MAXLEN, "\t\tnMol = %d;", nMol);
284 newMdFile << buffer << std::endl;
285 } else
286 newMdFile << buffer << std::endl;
287
288 oldMdFile.getline(buffer, MAXLEN);
289 }
290
291 oldMdFile.close();
292 newMdFile.close();
293}
static LatticeFactory & getInstance()
Returns an instance of Lattice factory.
The only responsibility of SimCreator is to parse the meta-data file and create a SimInfo instance ba...
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:93
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
void registerLattice()
Register all lattice.
Definition Register.cpp:131
The header file for the command line option parser generated by GNU Gengetopt version 2....
Where the command line options are stored.