OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
icosahedralBuilder.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 <config.h>
46
47#include "brains/SimCreator.hpp"
48#include "brains/SimInfo.hpp"
53#include "io/DumpWriter.hpp"
54#include "utils/MoLocator.hpp"
55
56using namespace OpenMD;
57using namespace std;
58
59void createMdFile(const std::string& oldMdFileName,
60 const std::string& newMdFileName, int nMol) {
61 ifstream oldMdFile;
62 ofstream newMdFile;
63 const int MAXLEN = 65535;
64 char buffer[MAXLEN];
65
66 // create new .omd file based on old .omd file
67 oldMdFile.open(oldMdFileName.c_str());
68 newMdFile.open(newMdFileName.c_str());
69 oldMdFile.getline(buffer, MAXLEN);
70
71 while (!oldMdFile.eof()) {
72 // correct molecule number
73 if (strstr(buffer, "nMol") != NULL) {
74 snprintf(buffer, MAXLEN, "\tnMol = %i;", nMol);
75 newMdFile << buffer << std::endl;
76 } else {
77 newMdFile << buffer << std::endl;
78 }
79
80 oldMdFile.getline(buffer, MAXLEN);
81 }
82
83 oldMdFile.close();
84 newMdFile.close();
85}
86
87int main(int argc, char* argv[]) {
88 gengetopt_args_info args_info;
89 std::string inputFileName;
90 std::string outputFileName;
91
92 MoLocator* locator;
93 RealType latticeConstant(0.0);
94 int nShells(-1);
95
96 DumpWriter* writer;
97
98 // Parse Command Line Arguments
99 if (cmdline_parser(argc, argv, &args_info) != 0) exit(1);
100
101 /* get input file name */
102 if (args_info.inputs_num)
103 inputFileName = args_info.inputs[0];
104 else {
105 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
106 "No input .omd file name was specified "
107 "on the command line");
108 painCave.isFatal = 1;
109 cmdline_parser_print_help();
110 simError();
111 }
112
113 if (args_info.shells_given ||
114 (args_info.cuboctahedron_given || args_info.truncatedCube_given)) {
115 nShells = args_info.shells_arg;
116 if (nShells < 0) {
117 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
118 "icosahedralBuilder: The number of shells\n"
119 "\tmust be greater than or equal to zero.");
120 painCave.isFatal = 1;
121 cmdline_parser_print_help();
122 simError();
123 }
124 } else {
125 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
126 "icosahedralBuilder: The number of shells\n"
127 "\tis required to build a Mackay Icosahedron.");
128 painCave.isFatal = 1;
129 cmdline_parser_print_help();
130 simError();
131 }
132
133 if (args_info.latticeConstant_given) {
134 latticeConstant = args_info.latticeConstant_arg;
135 } else {
136 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
137 "icosahedralBuilder: No lattice constant\n"
138 "\tgiven.");
139 painCave.isFatal = 1;
140 cmdline_parser_print_help();
141 simError();
142 }
143
144 /* parse md file and set up the system */
145 SimCreator oldCreator;
146 SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
147
148 vector<Vector3d> Points;
149 if (args_info.ico_given) {
150 Icosahedron* ico = new Icosahedron();
151 Points = ico->getPoints(nShells);
152 } else if (args_info.deca_given) {
153 RegularDecahedron* deca = new RegularDecahedron(nShells);
154 Points = deca->getPoints();
155 } else if (args_info.ino_given) {
156 int columnAtoms = args_info.columnAtoms_arg;
157 InoDecahedron* ino = new InoDecahedron(columnAtoms, nShells);
158 Points = ino->getPoints();
159 } else if (args_info.marks_given) {
160 int columnAtoms = args_info.columnAtoms_arg;
161 int twinAtoms = args_info.twinAtoms_arg;
162 Decahedron* marks = new Decahedron(columnAtoms, nShells, twinAtoms);
163 Points = marks->getPoints();
164 } else if (args_info.stone_given) {
165 int columnAtoms = args_info.columnAtoms_arg;
166 int twinAtoms = args_info.twinAtoms_arg;
167 int truncatedPlanes = args_info.truncatedPlanes_arg;
169 columnAtoms, nShells, twinAtoms, truncatedPlanes);
170 Points = csd->getPoints();
171 } else if (args_info.cuboctahedron_given || args_info.truncatedCube_given) {
172 std::string lattice;
173 int unitCells = 0;
174 if (args_info.lattice_given) {
175 lattice = args_info.lattice_arg;
176 } else {
177 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
178 "icosahedralBuilder: No lattice type given.");
179 painCave.isFatal = 1;
180 cmdline_parser_print_help();
181 simError();
182 }
183 if (args_info.unitCells_given) {
184 unitCells = args_info.unitCells_arg;
185 } else {
186 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
187 "icosahedralBuilder: Must specify unit cells.");
188 painCave.isFatal = 1;
189 cmdline_parser_print_help();
190 simError();
191 }
192 if (args_info.truncatedCube_given) {
193 int truncatedPlanes = args_info.truncatedPlanes_arg;
194 TruncatedCube* tc =
195 new TruncatedCube(lattice, unitCells, truncatedPlanes);
196 Points = tc->getPoints();
197 } else {
198 RegularCuboctahedron* rc = new RegularCuboctahedron(lattice, unitCells);
199 Points = rc->getPoints();
200 }
201 }
202
203 outputFileName = args_info.output_arg;
204
205 // create a new .omd file on fly which corrects the number of
206 // molecules
207
208 createMdFile(inputFileName, outputFileName, Points.size());
209
210 delete oldInfo;
211
212 SimCreator newCreator;
213 SimInfo* NewInfo = newCreator.createSim(outputFileName, false);
214
215 // Place molecules
216 Molecule* mol;
217 SimInfo::MoleculeIterator mi;
218 mol = NewInfo->beginMolecule(mi);
219
220 int l = 0;
221
222 locator =
223 new MoLocator(NewInfo->getMoleculeStamp(0), NewInfo->getForceField());
224
225 Vector3d boxMax;
226 Vector3d boxMin;
227
228 for (unsigned int n = 0; n < Points.size(); n++) {
229 mol = NewInfo->getMoleculeByGlobalIndex(l);
230
231 Vector3d location;
232 if (args_info.cuboctahedron_given || args_info.truncatedCube_given) {
233 // The cubic structures are built with a unit spacing between cells
234 location = Points[n] * latticeConstant;
235 } else {
236 // The polyhedra are built with a unit spacing between atoms,
237 // which in an FCC lattice should be multiplied by a / sqrt(2).
238 location = Points[n] * latticeConstant / sqrt(2.0);
239 }
240 Vector3d orientation = Vector3d(0, 0, 1.0);
241
242 if (n == 0) {
243 boxMax = location;
244 boxMin = location;
245 } else {
246 for (int i = 0; i < 3; i++) {
247 boxMax[i] = max(boxMax[i], location[i]);
248 boxMin[i] = min(boxMin[i], location[i]);
249 }
250 }
251
252 locator->placeMol(location, orientation, mol);
253 l++;
254 }
255
256 Mat3x3d boundingBox;
257 boundingBox(0, 0) = 10.0 * (boxMax[0] - boxMin[0]);
258 boundingBox(1, 1) = 10.0 * (boxMax[1] - boxMin[1]);
259 boundingBox(2, 2) = 10.0 * (boxMax[2] - boxMin[2]);
260
261 // set Hmat
262 NewInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(boundingBox);
263
264 // create dumpwriter and write out the coordinates
265 writer = new DumpWriter(NewInfo, outputFileName);
266
267 if (writer == NULL) {
268 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
269 "Error in creating dumpwriter object ");
270 painCave.isFatal = 1;
271 simError();
272 }
273
274 writer->writeDump();
275
276 // deleting the writer will put the closing at the end of the dump file
277
278 delete writer;
279
280 // clean up by calling simError.....
281 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
282 "A new OpenMD file called \"%s\" has been "
283 "generated.\n",
284 outputFileName.c_str());
285 painCave.isFatal = 0;
286 painCave.severity = OPENMD_INFO;
287 simError();
288 return 0;
289}
Cuboctahedron cluster structure generator.
Decahedron cluster structure generator.
Icosahedron cluster structure generator.
Creates the regular decahedron, Ino decahedron, or truncated (Marks) decahedron structures (depending...
Create the Mackay icosahedron structure.
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
The header file for the command line option parser generated by GNU Gengetopt version 2....
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Where the command line options are stored.