11 #include <simp/species/SpeciesGroup.tpp> 12 #include <util/format/Int.h> 81 read<int>(in,
"nAtom",
nAtom_);
87 readOptional<int>(in,
"nBond",
nBond_);
97 readOptional<int>(in,
"nAngle",
nAngle_);
107 readOptional<int>(in,
"nDihedral",
nDihedral_);
109 if (nDihedral_ > 0) {
110 readDArray<SpeciesDihedral>(in,
"speciesDihedrals",
123 loadParameter<int>(ar,
"nAtom",
nAtom_);
128 loadParameter<int>(ar,
"nBond",
nBond_);
137 loadParameter<int>(ar,
"nAngle",
nAngle_);
146 loadParameter<int>(ar,
"nDihedral",
nDihedral_);
149 loadDArray<SpeciesDihedral>(ar,
"speciesDihedrals",
168 for (
int j = 0; j <
nAtom_; j++) {
175 if (
Label(
"nBond",
false).match(in)) {
180 for (
int j = 0; j <
nBond_; j++) {
190 if (
Label(
"nAngle",
false).match(in)) {
195 for (
int j = 0; j <
nAngle_; j++) {
205 if (
Label(
"nDihedral",
false).match(in)) {
242 for (
int atomId = 0; atomId <
nAtom_; ++atomId) {
243 UTIL_CHECK(atomBondIdArrays_[atomId].size() == 0);
245 int bondId, atomId1, atomId2;
246 for (bondId = 0; bondId <
nBond_; ++bondId) {
251 atomBondIdArrays_[atomId1].append(bondId);
252 atomBondIdArrays_[atomId2].append(bondId);
263 for (
int atomId = 0; atomId <
nAtom_; ++atomId) {
264 UTIL_CHECK(atomAngleIdArrays_[atomId].size() == 0);
266 int angleId, atomId1, atomId2, atomId3;
267 for (angleId = 0; angleId <
nAngle_; ++angleId) {
274 atomAngleIdArrays_[atomId1].append(angleId);
275 atomAngleIdArrays_[atomId2].append(angleId);
276 atomAngleIdArrays_[atomId3].append(angleId);
285 UTIL_CHECK(atomDihedralIdArrays_.isAllocated());
287 for (
int atomId = 0; atomId <
nAtom_; ++atomId) {
288 UTIL_CHECK(atomDihedralIdArrays_[atomId].size() == 0);
290 int dihedralId, atomId1, atomId2, atomId3, atomId4;
291 for (dihedralId = 0; dihedralId <
nDihedral_; ++dihedralId) {
300 atomDihedralIdArrays_[atomId1].append(dihedralId);
301 atomDihedralIdArrays_[atomId2].append(dihedralId);
302 atomDihedralIdArrays_[atomId3].append(dihedralId);
303 atomDihedralIdArrays_[atomId4].append(dihedralId);
331 if (nDihedral_ > 0) {
343 std::string xIndent =
indent;
347 out << indent <<
"nAtom " <<
nAtom_;
348 for (
int iAtom = 0; iAtom <
nAtom_; iAtom++) {
349 out << endl << xIndent <<
Int(iAtom,2) <<
" " 355 out << endl << indent <<
"nBond " <<
nBond_;
356 for (
int iBond = 0; iBond <
nBond_; iBond++) {
357 out << endl << xIndent <<
Int(iBond,2) <<
" " 365 out << endl << indent <<
"nAngle " <<
nAngle_;
366 for (
int iAngle = 0; iAngle <
nAngle_; iAngle++) {
367 out << endl << xIndent <<
Int(iAngle,2) <<
" " 375 out << endl << indent <<
"nDihedral " <<
nDihedral_;
376 for (
int iDihedral = 0; iDihedral <
nDihedral_; iDihedral++) {
377 out << endl << xIndent <<
Int(iDihedral,2) <<
" " 393 int index, count, typeId;
394 in >>
Label(
"nAtom") >> count;
395 if (count !=
nAtom()) match =
false;
396 for (
int iAtom = 0; iAtom <
nAtom_; iAtom++) {
397 in >> index >> typeId;
398 if (index != iAtom) match =
false;
403 if (
Label(
"nBond",
false).match(in)) {
405 if (count !=
nBond()) match =
false;
407 for (
int iBond = 0; iBond <
nBond_; iBond++) {
408 in >> index >> i0 >> i1 >> typeId;
416 if (
Label(
"nAngle",
false).match(in)) {
418 if (count !=
nAngle()) match =
false;
420 for (
int iAngle = 0; iAngle <
nAngle_; iAngle++) {
421 in >> index >> i0 >> i1 >> i2 >> typeId;
430 if (
Label(
"nDihedral",
false).match(in)) {
434 for (
int iDihedral = 0; iDihedral <
nDihedral_; iDihedral++) {
435 in >> index >> i0 >> i1 >> i2 >> i3 >> typeId;
455 if (
id < 0)
UTIL_THROW(
"Negative species id");
465 { mutatorPtr_ = mutatorPtr; }
495 for (
int i = 0; i <
nAtom_; ++i) {
516 atomBondIdArrays_.allocate(
nAtom_);
531 assert(atomId1 >= 0);
532 assert(atomId2 >= 0);
543 atomBondIdArrays_[atomId1].append(bondId);
544 atomBondIdArrays_[atomId2].append(bondId);
557 UTIL_CHECK(!atomAngleIdArrays_.isAllocated());
559 atomAngleIdArrays_.allocate(
nAtom_);
570 int angleId,
int atomId1,
int atomId2,
int atomId3,
int angleType)
573 assert(angleId >= 0);
574 assert(atomId1 >= 0);
575 assert(atomId2 >= 0);
576 assert(atomId3 >= 0);
589 atomAngleIdArrays_[atomId1].append(angleId);
590 atomAngleIdArrays_[atomId2].append(angleId);
591 atomAngleIdArrays_[atomId3].append(angleId);
603 UTIL_CHECK(!atomDihedralIdArrays_.isAllocated());
605 atomDihedralIdArrays_.allocate(
nAtom_);
617 int atomId3,
int atomId4,
int dihedralType)
620 assert(dihedralId >= 0);
621 assert(atomId1 >= 0);
622 assert(atomId2 >= 0);
623 assert(atomId3 >= 0);
624 assert(atomId4 >= 0);
639 atomDihedralIdArrays_[atomId1].append(dihedralId);
640 atomDihedralIdArrays_[atomId2].append(dihedralId);
641 atomDihedralIdArrays_[atomId3].append(dihedralId);
642 atomDihedralIdArrays_[atomId4].append(dihedralId);
658 for (
int i = 0; i <
nAtom_; ++i) {
660 UTIL_THROW(
"Negative AtomTypeIds_ in non-mutable Species");
673 int atomId, bondId, atomId0, atomId1, j;
675 for (bondId = 0; bondId <
nBond_; ++bondId) {
681 if (atomId0 < 0 || atomId0 >=
nAtom_) {
682 UTIL_THROW(
"Invalid atomId0 in speciesBonds_");
684 if (atomId1 < 0 || atomId1 >=
nAtom_) {
685 UTIL_THROW(
"Invalid atomId1 in speciesBonds_");
687 if (atomId0 == atomId1) {
688 UTIL_THROW(
"Equal atom ids in a SpeciesBond");
693 for (j = 0; j < atomBondIdArrays_[atomId0].size(); ++j) {
694 if (atomBondIdArrays_[atomId0][j] == bondId) {
700 UTIL_THROW(
"BondId missing from atomBondIdArrays_");
705 for (j = 0; j < atomBondIdArrays_[atomId1].size(); ++j) {
706 if (atomBondIdArrays_[atomId1][j] == bondId) {
712 UTIL_THROW(
"BondId missing from atomBondIdArrays_");
719 for (atomId = 0; atomId <
nAtom_; ++atomId) {
720 for (j = 0; j < atomBondIdArrays_[atomId].size(); ++j) {
721 bondId = atomBondIdArrays_[atomId][j];
723 if (bondId < 0 || bondId >= nBond_)
728 if (atomId != atomId0 && atomId != atomId1)
729 UTIL_THROW(
"Inconsistency in atomBondId and bond");
734 if (bondCounter != 2*nBond_) {
735 UTIL_THROW(
"Inconsistency in total number of bonds");
748 int angleId,
id, id2, atomId, atomId2(-1), j;
750 for (angleId = 0; angleId <
nAngle_; ++angleId) {
752 for (
id = 0;
id < 3; ++
id) {
756 if (atomId < 0 || atomId >=
nAtom_) {
757 UTIL_THROW(
"Invalid atomId in speciesAngles_");
759 for (id2 =
id + 1; id2 < 3; ++id2) {
761 if (atomId2 == atomId) {
762 UTIL_THROW(
"Equal atom ids in a SpeciesAngle");
768 for (j = 0; j < atomAngleIdArrays_[atomId].size(); ++j) {
769 if (atomAngleIdArrays_[atomId][j] == angleId) {
775 UTIL_THROW(
"AngleId missing from atomAngleIdArrays_");
782 int angleCounter = 0;
784 for (atomId = 0; atomId <
nAtom_; ++atomId) {
785 for (j = 0; j < atomAngleIdArrays_[atomId].size(); ++j) {
786 angleId = atomAngleIdArrays_[atomId][j];
787 if (angleId < 0 || angleId >= nAngle_)
791 for (
id = 0;
id < 3; ++
id) {
793 if (atomId2 == atomId) {
799 UTIL_THROW(
"Inconsistency in atomAngleId and angle");
804 if (angleCounter != 3*nAngle_) {
805 UTIL_THROW(
"Inconsistency in total number of angles");
814 UTIL_CHECK(atomDihedralIdArrays_.isAllocated());
818 int dihedralId, tId, tId2, tAtomId, tAtomId2, j;
821 for (dihedralId = 0; dihedralId <
nDihedral_; ++dihedralId) {
823 for (tId = 0; tId < 4; ++tId) {
827 if (tAtomId < 0 || tAtomId >=
nAtom_) {
828 UTIL_THROW(
"Invalid atomId in speciesDihedral_");
830 for (tId2 = tId + 1; tId2 < 4; ++tId2) {
832 if (tAtomId2 == tAtomId) {
833 UTIL_THROW(
"Equal atom ids in a SpeciesDihedral");
839 for (j = 0; j < atomDihedralIdArrays_[tAtomId].size(); ++j) {
840 if (atomDihedralIdArrays_[tAtomId][j] == dihedralId) {
846 UTIL_THROW(
"DihedralId missing from atomDihedralIdArrays_");
853 int dihedralCounter = 0;
855 for (tAtomId = 0; tAtomId <
nAtom_; ++tAtomId) {
856 for (j = 0; j < atomDihedralIdArrays_[tAtomId].size(); ++j) {
857 dihedralId = atomDihedralIdArrays_[tAtomId][j];
858 if (dihedralId < 0 || dihedralId >= nDihedral_)
862 for (tId = 0; tId < 4; ++tId) {
864 if (tAtomId2 == tAtomId) {
870 UTIL_THROW(
"Inconsistency in atomDihedralId and dihedral");
875 if (dihedralCounter != 4*nDihedral_) {
876 UTIL_THROW(
"Inconsistency in total number of dihedrals");
884 UTIL_THROW(
"Species not allocated but moleculeCapacity != 0");
void setAtomType(int atomId, int atomType)
Set the type for one atom in a generic molecule of this Species.
const SpeciesDihedral & speciesDihedral(int iDihedral) const
Get a specific SpeciesDihedral object, by local angle index.
int nAtom() const
Get number of atoms per molecule for this Species.
int moleculeCapacity_
Number of molecules associated with the species.
DArray< SpeciesDihedral > speciesDihedrals_
Array of SpeciesDihedrals, indexed by local dihedral id.
void setMutatorPtr(McMd::SpeciesMutator *mutatorPtr)
Set pointer to associated McMd::SpeciesMutator for a mutable species.
void writeStructure(std::ostream &out, std::string indent=std::string())
Write molecular structure in config/topology file format.
DArray< SpeciesBond > speciesBonds_
Array of SpeciesBonds for all bonds, indexed by local bond id.
virtual void readSpeciesParam(std::istream &in)
Define chemical structure for this Species.
virtual ~Species()
Destructor.
void allocateAtoms()
Allocate and initialize array of atom type Ids.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
Mix-in class for mutable subclasses of Species.
void allocateDihedrals()
Allocate arrays associated with dihedrals.
static bool isClear()
Is the input buffer clear?
int nAtom_
Number of atoms per molecule.
Saving / output archive for binary ostream.
DArray< int > atomTypeIds_
Array of atom type Ids, indexed by local atom id.
const SpeciesBond & speciesBond(int iBond) const
Get a specific SpeciesBond object, by local bond index.
int nDihedral() const
Get number of dihedrals per molecule for this Species.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
DArray< SpeciesAngle > speciesAngles_
Array of SpeciesAngles for all angles, indexed by local angle id.
void makeDihedral(int dihedralId, int atomId1, int atomId2, int atomId3, int atomId4, int dihedralType)
Add a dihedral to the chemical structure of a generic molecule.
Utility classes for scientific computation.
const SpeciesAngle & speciesAngle(int iAngle) const
Get a specific SpeciesAngle object, by local angle index.
Wrapper for an int, for formatted ostream output.
bool matchStructure(std::istream &in)
Read structure, return true iff it matches existing structure.
int nDihedral_
Number of dihedrals per molecule.
bool isAllocated() const
Return true if the DArray has been allocated, false otherwise.
int nAngle_
Number of angles per molecule.
bool isValid() const
Return true if Species is valid, or throw an Exception.
virtual void readParameters(std::istream &in)
Read parameters and initialize structure for this species.
void makeBond(int bondId, int atomId1, int atomId2, int bondType)
Add a bond to the chemical structure of a generic molecule.
void setId(int id)
Set integer id for this Species.
A label string in a file format.
void allocateBonds()
Allocate arrays associated with Bonds.
int id_
Integer index for this Species.
int id() const
Get integer id of this Species.
Saving archive for binary istream.
int atomId(int i) const
Get the local id for a specific Atom.
void makeAngle(int angleId, int atomId1, int atomId2, int atomId3, int angleType)
Add an angle to the chemical structure of a generic molecule.
void readStructure(std::istream &in)
Read structure from config/topology file format.
bool isMutable() const
Is this a mutable Species?
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
void setClassName(const char *className)
Set class name string.
virtual void loadSpeciesParam(Serializable::IArchive &ar)
Define chemical structure for this Species.
void allocate()
Allocate chemical structure arrays.
int capacity() const
Return allocated size.
void allocate(int capacity)
Allocate the underlying C array.
int nBond() const
Get number of bonds per molecule for this Species.
int nAngle() const
Get number of angles per molecule for this Species.
std::string indent() const
Return indent string for this object (string of spaces).
int nBond_
Number of bonds per molecule.
void initializeAtomGroupIdArrays()
Initialize all atom groupId arrays (point from atoms to groups).
void allocateAngles()
Allocate arrays associated with angles.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.