/* * Read input parameters. */ void MdPairEnergyCoefficients::readParameters(std::istream& in) { readInterval(in); readOutputFileName(in); read<PairSelector>(in, "selector", selector_); read<int>(in, "maxMoleculeNeighbors", maxMoleculeNeighbors_); // Allocate int iSpecies; moleculeNeighbors_.allocate(nSpecies_); twoMoleculePairEnergy_.allocate(nSpecies_); for (iSpecies = 0; iSpecies < nSpecies_; ++iSpecies) { Species *speciesPtr; int nMolecule; int iMolecule; speciesPtr = &system().simulation().species(iSpecies); nMolecule = speciesPtr->capacity(); moleculeNeighbors_[iSpecies].allocate(nMolecule); twoMoleculePairEnergy_[iSpecies].allocate(nMolecule); for (iMolecule = 0; iMolecule < nMolecule; ++iMolecule) { moleculeNeighbors_[iSpecies][iMolecule]. allocate(maxMoleculeNeighbors_); } } fileMaster().openOutputFile(outputFileName(".dat"), outputFile_); isInitialized_ = true; }
/* * Load state from a binary file archive. */ void McMuExchange::loadParameters(Serializable::IArchive& ar) { loadInterval(ar); loadOutputFileName(ar); loadParameter(ar, "speciesId", speciesId_); ar >> nAtom_; Species* speciesPtr; speciesPtr = &(system().simulation().species(speciesId_)); if (nAtom_ != speciesPtr->nAtom()) { UTIL_THROW("Inconsistent values of nAtom on loading"); } newTypeIds_.allocate(nAtom_); loadDArray(ar, "newTypeIds", newTypeIds_, nAtom_); flipAtomIds_.allocate(nAtom_); isAtomFlipped_.allocate(nAtom_); for (int i = 0; i < nAtom_; ++i) { if (newTypeIds_[i] != speciesPtr->atomTypeId(i)) { flipAtomIds_.append(i); isAtomFlipped_[i] = 1; } else { isAtomFlipped_[i] = 0; } } accumulators_.allocate(speciesPtr->capacity()); ar >> nMolecule_; for (int i = 0; i < nMolecule_; ++i) { ar >> accumulators_[i]; } isInitialized_ = true; }
/* * Initialize all Angle objects for Molecules of one Species. * * This functions assigns pointers to Atoms and angle types ids within a * contiguous block of Angle objects, and sets a pointer in each Molecule * to the first Angle in the associated block. */ void Simulation::initializeSpeciesAngles(int iSpecies) { if (nAngleType_ <= 0) { UTIL_THROW("nAngleType must be positive"); } Species* speciesPtr = 0; Molecule *moleculePtr = 0; Angle *anglePtr = 0; Atom *firstAtomPtr, *atom0Ptr, *atom1Ptr, *atom2Ptr; int iMol, iAngle, atom0Id, atom1Id, atom2Id, type; int capacity, nAngle; speciesPtr = &species(iSpecies); capacity = speciesPtr->capacity(); nAngle = speciesPtr->nAngle(); // Initialize pointers before loop moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]]; anglePtr = &angles_[firstAngleIds_[iSpecies]]; // Loop over molecules in Species for (iMol = 0; iMol < capacity; ++iMol) { firstAtomPtr = &(moleculePtr->atom(0)); moleculePtr->setFirstAngle(*anglePtr); moleculePtr->setNAngle(nAngle); if (nAngle > 0) { // Create angles for a molecule for (iAngle = 0; iAngle < nAngle; ++iAngle) { // Get pointers to atoms spanning the angle and angle type atom0Id = speciesPtr->speciesAngle(iAngle).atomId(0); atom1Id = speciesPtr->speciesAngle(iAngle).atomId(1); atom2Id = speciesPtr->speciesAngle(iAngle).atomId(2); type = speciesPtr->speciesAngle(iAngle).typeId(); atom0Ptr = firstAtomPtr + atom0Id; atom1Ptr = firstAtomPtr + atom1Id; atom2Ptr = firstAtomPtr + atom2Id; // Set fields of the Angle object anglePtr->setAtom(0, *atom0Ptr); anglePtr->setAtom(1, *atom1Ptr); anglePtr->setAtom(2, *atom2Ptr); anglePtr->setTypeId(type); ++anglePtr; } } ++moleculePtr; } }
/* * Initialize all Dihedral objects for Molecules of one Species. * * This functions assigns pointers to Atoms and Dihedral types ids within * a contiguous block of Dihedral objects, and sets a pointer in each * Molecule to the first Dihedral in the associated block. */ void Simulation::initializeSpeciesDihedrals(int iSpecies) { Species* speciesPtr = 0; Molecule *moleculePtr = 0; Dihedral *dihedralPtr = 0; Atom *firstAtomPtr, *atom0Ptr, *atom1Ptr, *atom2Ptr, *atom3Ptr; int iMol, iDihedral, atom0Id, atom1Id, atom2Id, atom3Id, type; int capacity, nDihedral; speciesPtr = &species(iSpecies); capacity = speciesPtr->capacity(); nDihedral = speciesPtr->nDihedral(); // Initialize pointers before loop moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]]; dihedralPtr = &dihedrals_[firstDihedralIds_[iSpecies]]; // Loop over molecules in Species for (iMol = 0; iMol < capacity; ++iMol) { firstAtomPtr = &(moleculePtr->atom(0)); moleculePtr->setFirstDihedral(*dihedralPtr); moleculePtr->setNDihedral(nDihedral); if (nDihedral > 0) { // Create dihedrals for a molecule for (iDihedral = 0; iDihedral < nDihedral; ++iDihedral) { // Get local indices for atoms and dihedral type atom0Id = speciesPtr->speciesDihedral(iDihedral).atomId(0); atom1Id = speciesPtr->speciesDihedral(iDihedral).atomId(1); atom2Id = speciesPtr->speciesDihedral(iDihedral).atomId(2); atom3Id = speciesPtr->speciesDihedral(iDihedral).atomId(3); type = speciesPtr->speciesDihedral(iDihedral).typeId(); // Calculate atom pointers atom0Ptr = firstAtomPtr + atom0Id; atom1Ptr = firstAtomPtr + atom1Id; atom2Ptr = firstAtomPtr + atom2Id; atom3Ptr = firstAtomPtr + atom3Id; // Set fields of the Dihedral object dihedralPtr->setAtom(0, *atom0Ptr); dihedralPtr->setAtom(1, *atom1Ptr); dihedralPtr->setAtom(2, *atom2Ptr); dihedralPtr->setAtom(3, *atom3Ptr); dihedralPtr->setTypeId(type); ++dihedralPtr; } } ++moleculePtr; } }
/* * Load state from an archive. */ void MdPairEnergyCoefficients::loadParameters(Serializable::IArchive& ar) { loadInterval(ar); loadOutputFileName(ar); fileMaster().openOutputFile(outputFileName(".dat"), outputFile_); loadParameter<PairSelector>(ar, "selector", selector_); loadParameter<int>(ar, "maxMoleculeNeighbors", maxMoleculeNeighbors_); int nAtomType, nSpecies; ar & nAtomType; ar & nSpecies; if (nAtomType != nAtomType_) { UTIL_THROW("Inconsistent values of nAtomType"); } if (nSpecies != nSpecies_) { UTIL_THROW("Inconsistent values of nSpecies"); } // Allocate moleculeNeighbors and twoMoleculePairEnergy. int iSpecies; moleculeNeighbors_.allocate(nSpecies_); twoMoleculePairEnergy_.allocate(nSpecies_); for (iSpecies = 0; iSpecies < nSpecies_; ++iSpecies) { Species *speciesPtr; int nMolecule; int iMolecule; speciesPtr = &system().simulation().species(iSpecies); nMolecule = speciesPtr->capacity(); moleculeNeighbors_[iSpecies].allocate(nMolecule); twoMoleculePairEnergy_[iSpecies].allocate(nMolecule); for (iMolecule = 0; iMolecule < nMolecule; ++iMolecule) { moleculeNeighbors_[iSpecies][iMolecule]. allocate(maxMoleculeNeighbors_); } } ar & pairEnergyAccumulator_; ar & moleculePESqAccumulator_; ar & twoMoleculePESqAccumulator_; ar & pESqAccumulator_; isInitialized_ = true; }
/* * Initialize all Molecule and Atom objects for one Species (private). * * This function creates associations between Species, Molecule, and * Atom objects for all molecules of one species, and sets atom typeIds. * * For each molecule, it sets the id, species pointer, nAtom, and the * firstAtom pointer. The molecule id is only unique within each species. * * For each atom, it sets the molecule pointer and an integer typeId. * * This method also pushes all molecules of the species onto the * reservoir, pushing them in order of decreasing molecule id. */ void Simulation::initializeSpecies(int iSpecies) { Species* speciesPtr; Molecule* moleculePtr; Atom* atomPtr; int iMol, iAtom; int capacity, nAtom; speciesPtr = &species(iSpecies); capacity = speciesPtr->capacity(); nAtom = speciesPtr->nAtom(); // Initialize pointers before loop moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]]; atomPtr = &atoms_[firstAtomIds_[iSpecies]]; // Loop over all molecules in Species for (iMol = 0; iMol < capacity; ++iMol) { // Initialize a Molecule moleculePtr->setId(iMol); moleculePtr->setSpecies(*speciesPtr); moleculePtr->setNAtom(nAtom); moleculePtr->setFirstAtom(*atomPtr); // Loop over atoms in a molecule, set molecule and atom TypeId for (iAtom = 0; iAtom < nAtom; ++iAtom) { atomPtr->setMolecule(*moleculePtr); atomPtr->setTypeId(speciesPtr->atomTypeId(iAtom)); ++atomPtr; } ++moleculePtr; } // Push all molecules of this species onto the reservoir stack // Push on in reverse order, so that they pop off in sequence moleculePtr = &molecules_[firstMoleculeIds_[iSpecies] + capacity - 1]; for (iMol = 0; iMol < capacity; ++iMol) { speciesPtr->reservoir().push(*moleculePtr); --moleculePtr; } }
/* * Initial setup. */ void ClusterIdentifier::initialize(int speciesId, int atomTypeId, double cutoff) { // Set member variables speciesId_ = speciesId; atomTypeId_ = atomTypeId; cutoff_ = cutoff; // Allocate memory Species* speciesPtr = &system().simulation().species(speciesId); int moleculeCapacity = speciesPtr->capacity(); links_.allocate(moleculeCapacity); clusters_.reserve(64); int atomCapacity = system().simulation().atomCapacity(); cellList_.setAtomCapacity(atomCapacity); // Note: We must set the cellist atom capacity to the total atom capacity, // even though we are only interested in clusters of one species, because // the celllist atom capacity sets the maximum allowed atom index value. }
/* * Initialize all Bond objects for Molecules of one Species. (private) * * This functions assigns pointers to Atoms and bond types ids within a * contiguous block of Bond objects, and sets a pointer in each Molecule * to the first Bond in the associated block. */ void Simulation::initializeSpeciesBonds(int iSpecies) { if (nBondType_ <= 0) { UTIL_THROW("nBondType_ must be positive"); } Species* speciesPtr = 0; Molecule* moleculePtr = 0; Bond* bondPtr = 0; Atom* firstAtomPtr; Atom* atom0Ptr; Atom* atom1Ptr; int iMol, iBond, atom0Id, atom1Id, type; int capacity, nBond; speciesPtr = &species(iSpecies); nBond = speciesPtr->nBond(); capacity = speciesPtr->capacity(); // Initialize pointers before loop moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]]; bondPtr = &bonds_[firstBondIds_[iSpecies]]; // Loop over molecules in Species for (iMol = 0; iMol < capacity; ++iMol) { firstAtomPtr = &(moleculePtr->atom(0)); moleculePtr->setFirstBond(*bondPtr); moleculePtr->setNBond(nBond); if (nBond > 0) { // Create bonds for a molecule for (iBond = 0; iBond < nBond; ++iBond) { // Get pointers to bonded atoms and bond type atom0Id = speciesPtr->speciesBond(iBond).atomId(0); atom1Id = speciesPtr->speciesBond(iBond).atomId(1); type = speciesPtr->speciesBond(iBond).typeId(); atom0Ptr = firstAtomPtr + atom0Id; atom1Ptr = firstAtomPtr + atom1Id; // Set fields of the Bond object bondPtr->setAtom(0, *atom0Ptr); bondPtr->setAtom(1, *atom1Ptr); bondPtr->setTypeId(type); // If MaskBonded, add each bonded atom to its partners Mask if (maskedPairPolicy_ == MaskBonded) { atom0Ptr->mask().append(*atom1Ptr); atom1Ptr->mask().append(*atom0Ptr); } ++bondPtr; } } ++moleculePtr; } }
/* * Allocate and initialize all private data (private method). * * Allocates global arrays (molecules_, atoms_, bonds_, angles_) and the * arrays first<class>Ids_ of integers to species blocks. Initializes: * * - Capacity values and first<class>Ptr_ addresses. * - Integer ids for Species and Molecule objects. * - Pointers between Species, Molecule, and Atom objects * - Atom typeIds and all Bond and Angle objects. */ void Simulation::initialize() { //Preconditions assert(nSpecies() > 0); if (nSpecies() <= 0) { UTIL_THROW("Error: nSpecies() <= 0 in Simulation::initialize()"); } if (nBondType_ < 0) { UTIL_THROW("Error: nBondType < 0 in Simulation::initialize()"); } #ifdef INTER_ANGLE if (nAngleType_ < 0) { UTIL_THROW("Error: nAngleType < 0 in Simulation::initialize()"); } #endif #ifdef INTER_DIHEDRAL if (nDihedralType_ < 0) { UTIL_THROW("Error: nDihedralType < 0 in Simulation::initialize()"); } #endif #ifdef MCMD_LINK if (nLinkType_ < 0) { UTIL_THROW("Error: nLinkType_ < 0 in Simulation::initialize()"); } #endif Species *speciesPtr; int nAtom, nBond, iSpecies; int capacity; #ifdef INTER_ANGLE int nAngle; #endif #ifdef INTER_DIHEDRAL int nDihedral; #endif // Allocate arrays of pointers to first object in a species block. firstMoleculeIds_.allocate(nSpecies()); firstAtomIds_.allocate(nSpecies()); if (nBondType_ > 0) { firstBondIds_.allocate(nSpecies()); } #ifdef INTER_ANGLE if (nAngleType_ > 0) { firstAngleIds_.allocate(nSpecies()); } #endif #ifdef INTER_DIHEDRAL if (nDihedralType_ > 0) { firstDihedralIds_.allocate(nSpecies()); } #endif // Count Molecules, Atoms and Groups. moleculeCapacity_ = 0; atomCapacity_ = 0; bondCapacity_ = 0; #ifdef INTER_ANGLE angleCapacity_ = 0; #endif #ifdef INTER_DIHEDRAL dihedralCapacity_ = 0; #endif for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) { speciesPtr = &species(iSpecies); // Check species id if (speciesPtr->id() != iSpecies) { UTIL_THROW("Inconsistent species ids"); } //speciesPtr->setId(iSpecies); // Set indexes of first objects of the blocks for this species firstMoleculeIds_[iSpecies] = moleculeCapacity_; firstAtomIds_[iSpecies] = atomCapacity_; if (nBondType_ > 0) { firstBondIds_[iSpecies] = bondCapacity_; } #ifdef INTER_ANGLE if (nAngleType_ > 0) { firstAngleIds_[iSpecies] = angleCapacity_; } #endif #ifdef INTER_DIHEDRAL if (nDihedralType_ > 0) { firstDihedralIds_[iSpecies] = dihedralCapacity_; } #endif // Increment total capacity values capacity = speciesPtr->capacity(); nAtom = speciesPtr->nAtom(); moleculeCapacity_ += capacity; atomCapacity_ += capacity*nAtom; if (nBondType_ > 0) { nBond = speciesPtr->nBond(); bondCapacity_ += capacity*nBond; } #ifdef INTER_ANGLE if (nAngleType_ > 0) { nAngle = speciesPtr->nAngle(); angleCapacity_ += capacity*nAngle; } #endif #ifdef INTER_DIHEDRAL if (nDihedralType_ > 0) { nDihedral = speciesPtr->nDihedral(); dihedralCapacity_ += capacity*nDihedral; } #endif } // Allocate global array of atoms (static member of Atom class). Atom::allocate(atomCapacity_, atoms_); // Allocate other global arrays (members of Simulation). molecules_.allocate(moleculeCapacity_); // Initialize all Atoms and Molecule objects. for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) { speciesPtr = &species(iSpecies); initializeSpecies(iSpecies); } // Initialize bonds. if (nBondType_ > 0) { if (bondCapacity_ > 0) { bonds_.allocate(bondCapacity_); } else { bonds_.allocate(1); } for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) { initializeSpeciesBonds(iSpecies); } } #ifdef INTER_ANGLE // Initialize angles. if (nAngleType_ > 0) { if (angleCapacity_ > 0) { angles_.allocate(angleCapacity_); } else { angles_.allocate(1); } for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) { initializeSpeciesAngles(iSpecies); } } #endif #ifdef INTER_DIHEDRAL // Initialize dihedrals. if (nDihedralType_ > 0) { if (dihedralCapacity_ > 0) { dihedrals_.allocate(dihedralCapacity_); } else { dihedrals_.allocate(1); } for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) { initializeSpeciesDihedrals(iSpecies); } } #endif }