62#include "primitives/GhostTorsion.hpp"
63#include "types/AtomType.hpp"
64#include "types/BendTypeParser.hpp"
65#include "types/BondTypeParser.hpp"
67#include "types/FixedChargeAdapter.hpp"
68#include "types/InversionTypeParser.hpp"
69#include "types/TorsionTypeParser.hpp"
71#include "utils/simError.h"
75 void MoleculeCreator::createOverrideAtomTypes(
ForceField* ff,
84 size_t nAtom = molStamp->getNAtoms();
86 for (
size_t i = 0; i < nAtom; ++i) {
87 stamp = molStamp->getAtomStamp(i);
88 AtomType* atomType = ff->getAtomType(stamp->getType());
90 if (atomType == NULL) {
91 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
92 "Can not find Matching Atom Type for[%s]",
93 stamp->getType().c_str());
99 if (stamp->hasOverride()) {
100 std::string baseType = atomType->getName();
101 RealType oc = stamp->getOverrideCharge();
104 std::ostringstream ss;
106 std::string atomTypeOverrideName = baseType +
"_q=" + ss.str();
110 AtomType* atB = ff->getAtomType(atomTypeOverrideName);
114 AtomType* atomTypeOverride =
new AtomType();
116 atomTypeOverride->useBase(atomType);
117 int ident = ff->getNAtomType();
118 atomTypeOverride->setIdent(ident);
119 atomTypeOverride->setName(atomTypeOverrideName);
120 ff->addAtomType(atomTypeOverrideName, atomTypeOverride);
121 FixedChargeAdapter fca = FixedChargeAdapter(atomTypeOverride);
123 ff->getForceFieldOptions().getChargeUnitScaling() * oc;
124 fca.makeFixedCharge(charge);
134 Molecule* mol =
new Molecule(globalIndex, molStamp);
138 AtomStamp* currentAtomStamp;
139 size_t nAtom = molStamp->getNAtoms();
140 for (
size_t i = 0; i < nAtom; ++i) {
141 currentAtomStamp = molStamp->getAtomStamp(i);
142 atom =
createAtom(ff, currentAtomStamp, localIndexMan);
148 RigidBodyStamp* currentRigidBodyStamp;
149 size_t nRigidbodies = molStamp->getNRigidBodies();
151 for (
size_t i = 0; i < nRigidbodies; ++i) {
152 currentRigidBodyStamp = molStamp->getRigidBodyStamp(i);
153 rb = createRigidBody(molStamp, mol, currentRigidBodyStamp, localIndexMan);
154 mol->addRigidBody(rb);
159 BondStamp* currentBondStamp;
160 size_t nBonds = molStamp->getNBonds();
162 for (
size_t i = 0; i < nBonds; ++i) {
163 currentBondStamp = molStamp->getBondStamp(i);
164 bond = createBond(ff, mol, currentBondStamp, localIndexMan);
170 BendStamp* currentBendStamp;
171 size_t nBends = molStamp->getNBends();
172 for (
size_t i = 0; i < nBends; ++i) {
173 currentBendStamp = molStamp->getBendStamp(i);
174 bend = createBend(ff, mol, currentBendStamp, localIndexMan);
180 TorsionStamp* currentTorsionStamp;
181 size_t nTorsions = molStamp->getNTorsions();
182 for (
size_t i = 0; i < nTorsions; ++i) {
183 currentTorsionStamp = molStamp->getTorsionStamp(i);
184 torsion = createTorsion(ff, mol, currentTorsionStamp, localIndexMan);
185 mol->addTorsion(torsion);
189 Inversion* inversion;
190 InversionStamp* currentInversionStamp;
191 size_t nInversions = molStamp->getNInversions();
192 for (
size_t i = 0; i < nInversions; ++i) {
193 currentInversionStamp = molStamp->getInversionStamp(i);
195 createInversion(ff, mol, currentInversionStamp, localIndexMan);
196 if (inversion != NULL) { mol->addInversion(inversion); }
200 CutoffGroup* cutoffGroup;
201 CutoffGroupStamp* currentCutoffGroupStamp;
202 size_t nCutoffGroups = molStamp->getNCutoffGroups();
203 for (
size_t i = 0; i < nCutoffGroups; ++i) {
204 currentCutoffGroupStamp = molStamp->getCutoffGroupStamp(i);
206 createCutoffGroup(mol, currentCutoffGroupStamp, localIndexMan);
207 mol->addCutoffGroup(cutoffGroup);
211 std::vector<Atom*> freeAtoms;
212 std::vector<Atom*>::iterator ai;
213 std::vector<Atom*>::iterator fai;
216 for (atom = mol->beginAtom(fai); atom != NULL; atom = mol->nextAtom(fai)) {
217 freeAtoms.push_back(atom);
220 Molecule::CutoffGroupIterator ci;
223 for (cg = mol->beginCutoffGroup(ci); cg != NULL;
224 cg = mol->nextCutoffGroup(ci)) {
225 for (atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
227 freeAtoms.erase(std::remove(freeAtoms.begin(), freeAtoms.end(), atom),
235 for (fai = freeAtoms.begin(); fai != freeAtoms.end(); ++fai) {
236 cutoffGroup = createCutoffGroup(mol, *fai, localIndexMan);
237 mol->addCutoffGroup(cutoffGroup);
241 createConstraintPair(mol);
244 for (std::size_t i = 0; i < molStamp->getNConstraints(); ++i) {
245 ConstraintStamp* cStamp = molStamp->getConstraintStamp(i);
249 atomA = mol->getAtomAt(cStamp->getA());
250 atomB = mol->getAtomAt(cStamp->getB());
251 assert(atomA && atomB);
253 bool printConstraintForce =
false;
255 if (cStamp->havePrintConstraintForce()) {
256 printConstraintForce = cStamp->getPrintConstraintForce();
259 if (!cStamp->haveConstrainedDistance()) {
260 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
261 "Constraint Error: A non-bond constraint was specified\n"
262 "\twithout providing a value for the constrainedDistance.\n");
263 painCave.isFatal = 1;
266 RealType
distance = cStamp->getConstrainedDistance();
267 ConstraintElem* consElemA =
new ConstraintElem(atomA);
268 ConstraintElem* consElemB =
new ConstraintElem(atomB);
269 ConstraintPair* cPair =
new ConstraintPair(
270 consElemA, consElemB,
distance, printConstraintForce);
271 mol->addConstraintPair(cPair);
277 createConstraintElem(mol);
281 if (molStamp->haveConstrainTotalCharge()) {
282 mol->setConstrainTotalCharge(molStamp->getConstrainTotalCharge());
297 if (atomType == NULL) {
298 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
299 "Can not find Matching Atom Type for[%s]",
300 stamp->getType().c_str());
302 painCave.isFatal = 1;
306 if (stamp->hasOverride()) {
307 std::string baseType = atomType->getName();
308 RealType oc = stamp->getOverrideCharge();
311 std::ostringstream ss;
313 std::string atomTypeOverrideName = baseType +
"_q=" + ss.str();
323 atomTypeOverride->useBase(atomType);
324 int ident = ff->getNAtomType();
325 atomTypeOverride->setIdent(ident);
326 atomTypeOverride->setName(atomTypeOverrideName);
327 ff->addAtomType(atomTypeOverrideName, atomTypeOverride);
330 ff->getForceFieldOptions().getChargeUnitScaling() * oc;
331 fca.makeFixedCharge(charge);
333 atomType = atomTypeOverride;
342 if (atomType->isDirectional()) {
347 atom =
new Atom(atomType);
355 RigidBody* MoleculeCreator::createRigidBody(
364 nAtoms = rbStamp->getNMembers();
365 for (std::size_t i = 0; i < nAtoms; ++i) {
369 atom = mol->getAtomAt(rbStamp->getMemberAt(i));
370 atomStamp = molStamp->getAtomStamp(rbStamp->getMemberAt(i));
371 rb->addAtom(atom, atomStamp);
396 BondTypeParser btParser;
397 BondType* bondType = NULL;
401 atomA = mol->getAtomAt(stamp->getA());
402 atomB = mol->getAtomAt(stamp->getB());
404 assert(atomA && atomB);
406 if (stamp->hasOverride()) {
408 bondType = btParser.parseTypeAndPars(stamp->getOverrideType(),
409 stamp->getOverridePars());
410 }
catch (OpenMDException& e) {
411 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
412 "MoleculeCreator Error: %s "
414 e.what(), mol->getType().c_str());
415 painCave.isFatal = 1;
420 bondType = ff->getBondType(atomA->getType(), atomB->getType());
422 if (bondType == NULL) {
423 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
424 "Can not find Matching Bond Type for[%s, %s]",
425 atomA->getType().c_str(), atomB->getType().c_str());
427 painCave.isFatal = 1;
432 Bond* bond =
new Bond(atomA, atomB, bondType);
435 bond->setLocalIndex(localIndexMan->getNextBondIndex());
443 std::string s = OpenMD_itoa(mol->getNBonds(), 10);
444 bond->setName(mol->getType() +
"_Bond_" + s.c_str());
451 BendTypeParser btParser;
452 BendType* bendType = NULL;
455 std::vector<int> bendAtoms = stamp->getMembers();
456 if (bendAtoms.size() == 3) {
457 Atom* atomA = mol->getAtomAt(bendAtoms[0]);
458 Atom* atomB = mol->getAtomAt(bendAtoms[1]);
459 Atom* atomC = mol->getAtomAt(bendAtoms[2]);
461 assert(atomA && atomB && atomC);
463 if (stamp->hasOverride()) {
465 bendType = btParser.parseTypeAndPars(stamp->getOverrideType(),
466 stamp->getOverridePars());
467 }
catch (OpenMDException& e) {
468 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
469 "MoleculeCreator Error: %s "
471 e.what(), mol->getType().c_str());
472 painCave.isFatal = 1;
477 ff->getBendType(atomA->getType().c_str(), atomB->getType().c_str(),
478 atomC->getType().c_str());
480 if (bendType == NULL) {
481 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
482 "Can not find Matching Bend Type for[%s, %s, %s]",
483 atomA->getType().c_str(), atomB->getType().c_str(),
484 atomC->getType().c_str());
486 painCave.isFatal = 1;
491 bend =
new Bend(atomA, atomB, atomC, bendType);
493 }
else if (bendAtoms.size() == 2 && stamp->haveGhostVectorSource()) {
494 int ghostIndex = stamp->getGhostVectorSource();
496 ghostIndex != bendAtoms[0] ? bendAtoms[0] : bendAtoms[1];
497 Atom* normalAtom = mol->getAtomAt(normalIndex);
498 DirectionalAtom* ghostAtom =
499 dynamic_cast<DirectionalAtom*
>(mol->getAtomAt(ghostIndex));
500 if (ghostAtom == NULL) {
501 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
502 "Can not cast Atom to DirectionalAtom");
503 painCave.isFatal = 1;
507 if (stamp->hasOverride()) {
509 bendType = btParser.parseTypeAndPars(stamp->getOverrideType(),
510 stamp->getOverridePars());
511 }
catch (OpenMDException& e) {
512 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
513 "MoleculeCreator Error: %s "
515 e.what(), mol->getType().c_str());
516 painCave.isFatal = 1;
520 bendType = ff->getBendType(normalAtom->getType(), ghostAtom->getType(),
523 if (bendType == NULL) {
524 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
525 "Can not find Matching Bend Type for[%s, %s, %s]",
526 normalAtom->getType().c_str(), ghostAtom->getType().c_str(),
529 painCave.isFatal = 1;
534 bend =
new GhostBend(normalAtom, ghostAtom, bendType);
546 std::string s = OpenMD_itoa(mol->getNBends(), 10);
547 bend->setName(mol->getType() +
"_Bend_" + s.c_str());
554 TorsionTypeParser ttParser;
555 TorsionType* torsionType = NULL;
556 Torsion* torsion = NULL;
558 std::vector<int> torsionAtoms = stamp->getMembers();
559 if (torsionAtoms.size() < 3) {
return torsion; }
561 Atom* atomA = mol->getAtomAt(torsionAtoms[0]);
562 Atom* atomB = mol->getAtomAt(torsionAtoms[1]);
563 Atom* atomC = mol->getAtomAt(torsionAtoms[2]);
565 if (torsionAtoms.size() == 4) {
566 Atom* atomD = mol->getAtomAt(torsionAtoms[3]);
568 assert(atomA && atomB && atomC && atomD);
570 if (stamp->hasOverride()) {
572 torsionType = ttParser.parseTypeAndPars(stamp->getOverrideType(),
573 stamp->getOverridePars());
574 }
catch (OpenMDException& e) {
575 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
576 "MoleculeCreator Error: %s "
578 e.what(), mol->getType().c_str());
579 painCave.isFatal = 1;
583 torsionType = ff->getTorsionType(atomA->getType(), atomB->getType(),
584 atomC->getType(), atomD->getType());
585 if (torsionType == NULL) {
586 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
587 "Can not find Matching Torsion Type for[%s, %s, %s, %s]",
588 atomA->getType().c_str(), atomB->getType().c_str(),
589 atomC->getType().c_str(), atomD->getType().c_str());
591 painCave.isFatal = 1;
596 torsion =
new Torsion(atomA, atomB, atomC, atomD, torsionType);
598 DirectionalAtom* dAtom =
dynamic_cast<DirectionalAtom*
>(
599 mol->getAtomAt(stamp->getGhostVectorSource()));
601 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
602 "Can not cast Atom to DirectionalAtom");
603 painCave.isFatal = 1;
607 if (stamp->hasOverride()) {
609 torsionType = ttParser.parseTypeAndPars(stamp->getOverrideType(),
610 stamp->getOverridePars());
611 }
catch (OpenMDException& e) {
612 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
613 "MoleculeCreator Error: %s "
615 e.what(), mol->getType().c_str());
616 painCave.isFatal = 1;
620 torsionType = ff->getTorsionType(atomA->getType(), atomB->getType(),
621 atomC->getType(),
"GHOST");
623 if (torsionType == NULL) {
624 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
625 "Can not find Matching Torsion Type for[%s, %s, %s, %s]",
626 atomA->getType().c_str(), atomB->getType().c_str(),
627 atomC->getType().c_str(),
"GHOST");
629 painCave.isFatal = 1;
634 torsion =
new GhostTorsion(atomA, atomB, dAtom, torsionType);
638 torsion->
setLocalIndex(localIndexMan->getNextTorsionIndex());
647 std::string s = OpenMD_itoa(mol->getNTorsions(), 10);
648 torsion->setName(mol->getType() +
"_Torsion_" + s.c_str());
652 Inversion* MoleculeCreator::createInversion(
655 InversionTypeParser itParser;
656 InversionType* inversionType = NULL;
657 Inversion* inversion = NULL;
659 int center = stamp->getCenter();
660 std::vector<int> satellites = stamp->getSatellites();
661 if (satellites.size() != 3) {
return inversion; }
663 Atom* atomA = mol->getAtomAt(center);
664 Atom* atomB = mol->getAtomAt(satellites[0]);
665 Atom* atomC = mol->getAtomAt(satellites[1]);
666 Atom* atomD = mol->getAtomAt(satellites[2]);
668 assert(atomA && atomB && atomC && atomD);
670 if (stamp->hasOverride()) {
672 inversionType = itParser.parseTypeAndPars(stamp->getOverrideType(),
673 stamp->getOverridePars());
674 }
catch (OpenMDException& e) {
675 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
676 "MoleculeCreator Error: %s "
678 e.what(), mol->getType().c_str());
679 painCave.isFatal = 1;
683 inversionType = ff->getInversionType(atomA->getType(), atomB->getType(),
684 atomC->getType(), atomD->getType());
686 if (inversionType == NULL) {
688 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
689 "No Matching Inversion Type for[%s, %s, %s, %s]\n"
690 "\t(May not be a problem: not all inversions are parametrized)\n",
691 atomA->getType().c_str(), atomB->getType().c_str(),
692 atomC->getType().c_str(), atomD->getType().c_str());
694 painCave.isFatal = 0;
695 painCave.severity = OPENMD_INFO;
699 if (inversionType != NULL) {
700 inversion =
new Inversion(atomA, atomB, atomC, atomD, inversionType);
704 inversion->setLocalIndex(localIndexMan->getNextInversionIndex());
713 std::string s = OpenMD_itoa(mol->getNInversions(), 10);
714 inversion->setName(mol->getType() +
"_Inversion_" + s.c_str());
727 cg =
new CutoffGroup();
729 nAtoms = stamp->getNMembers();
730 for (
size_t i = 0; i < nAtoms; ++i) {
731 atom = mol->getAtomAt(stamp->getMemberAt(i));
737 cg->setLocalIndex(localIndexMan->getNextCutoffGroupIndex());
745 cg =
new CutoffGroup();
749 cg->setLocalIndex(localIndexMan->getNextCutoffGroupIndex());
754 void MoleculeCreator::createConstraintPair(
Molecule* mol) {
756 Molecule::BondIterator bi;
758 ConstraintPair* cPair;
760 for (bond = mol->beginBond(bi); bond != NULL; bond = mol->nextBond(bi)) {
761 BondType* bt = bond->getBondType();
763 if (
typeid(FixedBondType) ==
typeid(*bt)) {
764 FixedBondType* fbt =
dynamic_cast<FixedBondType*
>(bt);
766 ConstraintElem* consElemA =
new ConstraintElem(bond->getAtomA());
767 ConstraintElem* consElemB =
new ConstraintElem(bond->getAtomB());
768 cPair =
new ConstraintPair(consElemA, consElemB,
769 fbt->getEquilibriumBondLength(),
false);
770 mol->addConstraintPair(cPair);
777 void MoleculeCreator::createConstraintElem(
Molecule* mol) {
778 ConstraintPair* consPair;
779 Molecule::ConstraintPairIterator cpi;
780 std::set<StuntDouble*> sdSet;
781 for (consPair = mol->beginConstraintPair(cpi); consPair != NULL;
782 consPair = mol->nextConstraintPair(cpi)) {
783 StuntDouble* sdA = consPair->getConsElem1()->getStuntDouble();
784 if (sdSet.find(sdA) == sdSet.end()) {
786 mol->addConstraintElem(
new ConstraintElem(sdA));
789 StuntDouble* sdB = consPair->getConsElem2()->getStuntDouble();
790 if (sdSet.find(sdB) == sdSet.end()) {
792 mol->addConstraintElem(
new ConstraintElem(sdB));
AtomType is what OpenMD looks to for unchanging data about an atom.
AtomType * getAtomType(const std::string &at)
getAtomType by string
"utils/LocalIndexManager.hpp"
virtual Atom * createAtom(ForceField *ff, AtomStamp *stamp, LocalIndexManager *localIndexMan)
Create an atom by its stamp.
size_t getNRigidBodies()
Returns the total number of rigid bodies in this molecule.
std::string getType()
Returns the name of the molecule.
virtual void setType(const std::string &name)
Sets the name of this stuntRealType.
void calcRefCoords()
calculates the reference coordinates
void setLocalIndex(int index)
Sets the local index of this ShortRangeInteraction.
void setLocalIndex(int index)
Sets the local index of this stuntDouble.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.