61#include "brains/Register.hpp"
64#include "io/DumpWriter.hpp"
65#include "lattice/Lattice.hpp"
70#include "shapedLatticeEllipsoid.hpp"
71#include "shapedLatticeRod.hpp"
72#include "utils/MoLocator.hpp"
77void createMdFile(
const std::string& oldMdFileName,
78 const std::string& newMdFileName, std::vector<int> numMol);
80int main(
int argc,
char* argv[]) {
84 std::string latticeType;
85 std::string inputFileName;
86 std::string outputFileName;
89 double latticeConstant;
96 if (cmdline_parser(argc, argv, &args_info) != 0) exit(1);
103 inputFileName = args_info.
inputs[0];
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;
120 Globals* simParams = oldInfo->getSimParams();
122 vector<Vector3d> sites;
123 vector<Vector3d> orientations;
127 rodLength, rodRadius);
128 sites = nanoEllipsoid.getSites();
129 orientations = nanoEllipsoid.getOrientations();
135 sites = nanoRod.getSites();
136 orientations = nanoRod.getOrientations();
140 std::random_device rd;
142 std::mt19937 gen(rd());
144 std::vector<std::size_t> vacancyTargets;
145 vector<bool> isVacancy;
150 for (std::size_t i = 0; i < sites.size(); i++)
151 isVacancy.push_back(
false);
158 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
159 "vacancyPercent was set to a non-sensical value.");
160 painCave.isFatal = 1;
177 if (vIR >= 0.0 && vOR <= rodRadius && vOR >= vIR) {
178 for (std::size_t i = 0; i < sites.size(); i++) {
181 if (myR >= vIR && myR <= vOR) { vacancyTargets.push_back(i); }
183 std::shuffle(vacancyTargets.begin(), vacancyTargets.end(), gen);
185 std::size_t nTargets = vacancyTargets.size();
186 vacancyTargets.resize((
int)(vF * nTargets));
188 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
189 "Removing %d atoms from randomly-selected\n"
190 "\tsites between %lf and %lf.",
191 (
int)vacancyTargets.size(), vIR, vOR);
192 painCave.isFatal = 0;
193 painCave.severity = OPENMD_INFO;
197 for (std::size_t i = 0; i < sites.size(); i++) {
199 for (std::size_t j = 0; j < vacancyTargets.size(); j++) {
200 if (i == vacancyTargets[j]) vac =
true;
202 isVacancy.push_back(vac);
206 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
207 "Something is strange about the vacancy\n"
208 "\tinner or outer radii. Check their values.");
209 painCave.isFatal = 1;
216 std::size_t nSites = sites.size() - vacancyTargets.size();
222 std::vector<Component*> components = simParams->getComponents();
223 std::vector<RealType> molFractions;
224 std::vector<RealType> shellRadii;
225 std::vector<int> nMol;
226 std::map<int, int> componentFromSite;
227 nComponents = components.size();
231 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
232 "Specify either molFraction or shellRadius "
233 "arguments, but not both!");
234 painCave.isFatal = 1;
238 if (nComponents == 1) {
239 molFractions.push_back(1.0);
240 shellRadii.push_back(rodRadius);
243 for (
int i = 0; i < nComponents; i++) {
247 RealType remainingFraction = 1.0;
248 for (
int i = 0; i < nComponents - 1; i++) {
250 remainingFraction -= molFractions[i];
252 molFractions.push_back(remainingFraction);
254 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
255 "nanorodBuilder can't figure out molFractions "
256 "for all of the components in the <MetaData> block.");
257 painCave.isFatal = 1;
262 for (
int i = 0; i < nComponents; i++) {
266 for (
int i = 0; i < nComponents - 1; i++) {
269 shellRadii.push_back(rodRadius);
272 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
273 "nanorodBuilder can't figure out the\n"
274 "\tshell radii for all of the components in the <MetaData> block.");
275 painCave.isFatal = 1;
279 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
280 "You have a multi-component <MetaData> block,\n"
281 "\tbut have not specified either molFraction or shellRadius "
283 painCave.isFatal = 1;
288 RealType totalFraction = 0.0;
292 for (
int i = 0; i < nComponents; i++) {
293 if (molFractions.at(i) < 0.0) {
294 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
295 "One of the requested molFractions was"
297 painCave.isFatal = 1;
300 if (molFractions.at(i) > 1.0) {
301 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
302 "One of the requested molFractions was"
303 " greater than one!");
304 painCave.isFatal = 1;
307 totalFraction += molFractions.at(i);
309 if (abs(totalFraction - 1.0) > 1e-6) {
310 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
311 "The sum of molFractions was not close enough to 1.0");
312 painCave.isFatal = 1;
316 int remaining = nSites;
317 for (
int i = 0; i < nComponents - 1; i++) {
318 nMol.push_back(
int((RealType)nSites * molFractions.at(i)));
319 remaining -= nMol.at(i);
321 nMol.push_back(remaining);
325 std::size_t totalMolecules = 0;
326 for (
int i = 0; i < nComponents; i++) {
327 molFractions[i] = (RealType)(nMol.at(i)) / (RealType)nSites;
328 totalMolecules += nMol.at(i);
330 if (totalMolecules != nSites) {
331 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
332 "Computed total number of molecules is not equal "
333 "to the number of lattice sites!");
334 painCave.isFatal = 1;
338 for (
unsigned int i = 0; i < shellRadii.size(); i++) {
339 if (shellRadii.at(i) > rodRadius + 1e-6) {
340 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
341 "One of the shellRadius values exceeds the rod Radius.");
342 painCave.isFatal = 1;
345 if (shellRadii.at(i) <= 0.0) {
346 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
347 "One of the shellRadius values is smaller than zero!");
348 painCave.isFatal = 1;
357 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
358 "Creating a randomized spherically-capped nanorod.");
359 painCave.isFatal = 0;
360 painCave.severity = OPENMD_INFO;
364 for (std::size_t i = 0; i < sites.size(); i++)
365 if (!isVacancy[i]) ids.push_back(i);
367 std::shuffle(ids.begin(), ids.end(), gen);
370 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
371 "Creating an fcc nanorod.");
372 painCave.isFatal = 0;
373 painCave.severity = OPENMD_INFO;
377 int myComponent = -1;
379 nMol.resize(nComponents);
384 for (
unsigned int i = 0; i < sites.size(); i++) {
400 componentFromSite[i] = myComponent;
414 createMdFile(inputFileName, outputFileName, nMol);
423 SimInfo::MoleculeIterator mi;
428 for (
int i = 0; i < nComponents; i++) {
434 for (
unsigned int n = 0; n < sites.size(); n++) {
436 if (componentFromSite[n] == i) {
438 locator->placeMol(sites[n], orientations[n], mol);
444 for (
int n = 0; n < nMol.at(i); n++) {
446 locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
453 hmat(0, 0) = 10.0 * rodRadius;
458 hmat(1, 1) = 10.0 * rodRadius;
463 hmat(2, 2) = 5.0 * rodLength + 2.0 * rodRadius;
469 writer =
new DumpWriter(NewInfo, outputFileName);
471 if (writer == NULL) {
472 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
473 "Error in creating dumpwriter object ");
474 painCave.isFatal = 1;
485 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
486 "A new OpenMD file called \"%s\" has been "
488 outputFileName.c_str());
489 painCave.isFatal = 0;
490 painCave.severity = OPENMD_INFO;
495void createMdFile(
const std::string& oldMdFileName,
496 const std::string& newMdFileName, std::vector<int> nMol) {
499 const int MAXLEN = 65535;
503 oldMdFile.open(oldMdFileName.c_str());
504 newMdFile.open(newMdFileName.c_str());
505 oldMdFile.getline(buffer, MAXLEN);
508 while (!oldMdFile.eof()) {
510 if (strstr(buffer,
"nMol") != NULL) {
511 if (i < nMol.size()) {
512 snprintf(buffer, MAXLEN,
"\tnMol = %i;", nMol.at(i));
513 newMdFile << buffer << std::endl;
517 newMdFile << buffer << std::endl;
519 oldMdFile.getline(buffer, MAXLEN);
525 if (i != nMol.size()) {
526 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
527 "Couldn't replace the correct number of nMol\n"
528 "\tstatements in component blocks. Make sure that all\n"
529 "\tcomponents in the template file have nMol=1");
530 painCave.isFatal = 1;
void cmdline_parser_print_help(void)
Print the help.
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.
Molecule * beginMolecule(MoleculeIterator &i)
Returns the first molecule in this SimInfo and intialize the iterator.
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.
Real length() const
Returns the length of this vector.
Implements an ellipsoid-shaped lattice.
Implements a spherically-capped rod-shaped lattice.
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 int vacancyInnerRadius_given
Whether vacancyInnerRadius was given.
double vacancyPercent_arg
Percentage of atoms to remove from within vacancy range.
double vacancyOuterRadius_arg
Radius arround core-shell where vacancies should be located.
unsigned inputs_num
unamed options number
unsigned int molFraction_given
Whether molFraction was given.
int ellipsoid_flag
Build an Ellipsoid instead of a rod.
double length_arg
maximum length (default='100').
double * molFraction_arg
Builds a multi-component random alloy nanoparticle.
char * output_arg
output file name.
char ** inputs
unamed options (options without names)
double * shellRadius_arg
Radius containing within it only molecules of a specific component.
unsigned int shellRadius_given
Whether shellRadius was given.
double radius_arg
Nanoparticle radius in Angstroms.
double vacancyInnerRadius_arg
Radius arround core-shell where vacancies should be located.
unsigned int vacancyPercent_given
Whether vacancyPercent was given.
double latticeConstant_arg
Lattice spacing in Angstroms for cubic lattice.
unsigned int vacancyOuterRadius_given
Whether vacancyOuterRadius was given.