58#include "brains/Register.hpp"
61#include "io/DumpWriter.hpp"
62#include "lattice/Lattice.hpp"
67#include "utils/MoLocator.hpp"
73void createMdFile(
const std::string& oldMdFileName,
74 const std::string& newMdFileName, std::vector<int> nMol);
76int main(
int argc,
char* argv[]) {
80 std::string latticeType;
81 std::string inputFileName;
82 std::string outputFileName;
84 RealType latticeConstant;
85 std::vector<RealType> lc;
86 const RealType rhoConvertConst = 1.661;
91 std::vector<Vector3d> latticePos;
92 std::vector<Vector3d> latticeOrt;
97 if (cmdline_parser(argc, argv, &args_info) != 0) exit(1);
107 if (simpleLat == NULL) {
108 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
109 "Lattice Factory can not create %s lattice\n",
110 latticeType.c_str());
111 painCave.isFatal = 1;
114 nMolPerCell = simpleLat->getNumSitesPerCell();
121 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
122 "The number of unit cells in the x direction "
123 "must be greater than 0.");
124 painCave.isFatal = 1;
131 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
132 "The number of unit cells in the y direction "
133 "must be greater than 0.");
134 painCave.isFatal = 1;
141 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
142 "The number of unit cells in the z direction "
143 "must be greater than 0.");
144 painCave.isFatal = 1;
148 int nSites = nMolPerCell * nx * ny * nz;
152 inputFileName = args_info.
inputs[0];
154 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
155 "No input .omd file name was specified "
156 "on the command line");
157 painCave.isFatal = 1;
165 Globals* simParams = oldInfo->getSimParams();
169 std::vector<Component*> components = simParams->getComponents();
170 std::vector<RealType> molFractions;
171 std::vector<RealType> molecularMasses;
172 std::vector<int> nMol;
173 std::size_t nComponents = components.size();
175 if (nComponents == 1) {
176 molFractions.push_back(1.0);
179 for (std::size_t i = 0; i < nComponents; i++) {
183 RealType remainingFraction = 1.0;
184 for (std::size_t i = 0; i < nComponents - 1; i++) {
186 remainingFraction -= molFractions[i];
188 molFractions.push_back(remainingFraction);
190 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
191 "randomBuilder can't figure out molFractions "
192 "for all of the components in the <MetaData> block.");
193 painCave.isFatal = 1;
200 RealType totalFraction = 0.0;
202 for (std::size_t i = 0; i < nComponents; i++) {
203 if (molFractions.at(i) < 0.0) {
204 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
205 "One of the requested molFractions was"
207 painCave.isFatal = 1;
210 if (molFractions.at(i) > 1.0) {
211 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
212 "One of the requested molFractions was"
213 " greater than one!");
214 painCave.isFatal = 1;
217 totalFraction += molFractions.at(i);
219 if (abs(totalFraction - 1.0) > 1e-6) {
220 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
221 "The sum of molFractions was not close enough to 1.0");
222 painCave.isFatal = 1;
226 int remaining = nSites;
227 for (std::size_t i = 0; i < nComponents - 1; i++) {
228 nMol.push_back(
int((RealType)nSites * molFractions.at(i)));
229 remaining -= nMol.at(i);
231 nMol.push_back(remaining);
235 int totalMolecules = 0;
236 RealType totalMass = 0.0;
237 for (std::size_t i = 0; i < nComponents; i++) {
238 molFractions[i] = (RealType)(nMol.at(i)) / (RealType)nSites;
239 totalMolecules += nMol.at(i);
240 molecularMasses.push_back(MoLocator::getMolMass(
242 totalMass += (RealType)(nMol.at(i)) * molecularMasses.at(i);
244 RealType avgMass = totalMass / (RealType)totalMolecules;
246 if (totalMolecules != nSites) {
247 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
248 "Computed total number of molecules is not equal "
249 "to the number of lattice sites!");
250 painCave.isFatal = 1;
254 latticeConstant = pow(rhoConvertConst * nMolPerCell * avgMass / density,
255 (RealType)(1.0 / 3.0));
259 lc.push_back(latticeConstant);
260 simpleLat->setLatticeConstant(lc);
266 latticeOrt = simpleLat->getLatticePointsOrt();
268 vector<Vector3d> sites;
269 vector<Vector3d> orientations;
271 for (
int i = 0; i < nx; i++) {
272 for (
int j = 0; j < ny; j++) {
273 for (
int k = 0; k < nz; k++) {
276 simpleLat->getLatticePointsPos(latticePos, i, j, k);
278 for (
int l = 0; l < nMolPerCell; l++) {
279 sites.push_back(latticePos[l]);
280 orientations.push_back(latticeOrt[l]);
290 createMdFile(inputFileName, outputFileName, nMol);
302 hmat(0, 0) = nx * latticeConstant;
307 hmat(1, 1) = ny * latticeConstant;
312 hmat(2, 2) = nz * latticeConstant;
323 for (std::size_t i = 0; i < sites.size(); i++)
327 std::random_device rd;
329 std::mt19937 gen(rd());
331 std::shuffle(ids.begin(), ids.end(), gen);
335 for (std::size_t i = 0; i < nComponents; i++) {
338 for (
int n = 0; n < nMol.at(i); n++) {
340 locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
347 writer =
new DumpWriter(newInfo, outputFileName);
349 if (writer == NULL) {
350 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
351 "error in creating DumpWriter");
352 painCave.isFatal = 1;
362 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
363 "A new OpenMD file called \"%s\" has been "
365 outputFileName.c_str());
366 painCave.isFatal = 0;
367 painCave.severity = OPENMD_INFO;
372void createMdFile(
const std::string& oldMdFileName,
373 const std::string& newMdFileName, std::vector<int> nMol) {
376 const int MAXLEN = 65535;
381 oldMdFile.open(oldMdFileName.c_str());
382 newMdFile.open(newMdFileName.c_str());
384 oldMdFile.getline(buffer, MAXLEN);
387 while (!oldMdFile.eof()) {
389 if (strstr(buffer,
"nMol") != NULL) {
390 if (i < nMol.size()) {
391 snprintf(buffer, MAXLEN,
"\tnMol = %i;", nMol.at(i));
392 newMdFile << buffer << std::endl;
396 newMdFile << buffer << std::endl;
398 oldMdFile.getline(buffer, MAXLEN);
404 if (i != nMol.size()) {
405 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
406 "Couldn't replace the correct number of nMol\n"
407 "\tstatements in component blocks. Make sure that all\n"
408 "\tcomponents in the template file have nMol=1");
409 painCave.isFatal = 1;
Lattice * createLattice(const std::string &id)
Looks up the type identifier in the internal map.
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...
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...
Molecule * getMoleculeByGlobalIndex(int index)
Finds a molecule with a specified global index.
ForceField * getForceField()
Returns the force field.
MoleculeStamp * getMoleculeStamp(int id)
Returns the molecule stamp.
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
void setHmat(const Mat3x3d &m)
Sets the H-Matrix.
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
void registerLattice()
Register all lattice.
The header file for the command line option parser generated by GNU Gengetopt version 2....
Where the command line options are stored.
unsigned inputs_num
unamed options number
unsigned int molFraction_given
Whether molFraction was given.
unsigned int lattice_given
Whether lattice was given.
double * molFraction_arg
Builds a multi-component random alloy nanoparticle.
char * output_arg
output file name.
char ** inputs
unamed options (options without names)
int ny_arg
number of unit cells in y.
int nz_arg
number of unit cells in z.
double density_arg
density (g/cm^3).
int nx_arg
number of unit cells in x.
char * lattice_arg
Lattice Type.