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