/* * Build the PairList, i.e., populate it with atom pairs. */ void PairList::build(CellList& cellList, bool reverseUpdateFlag) { // Precondition assert(isAllocated()); Cell::NeighborArray neighbors; double dRSq, cutoffSq; const Cell* cellPtr; Atom* atom1Ptr; Atom* atom2Ptr; Mask* maskPtr; Vector dr; int na; // number of atoms in this cell int nn; // number of neighbors for a cell int atom2Id; // atom Id for second atom int i, j; bool foundNeighbor; // Set maximum squared-separation for pairs in Pairlist cutoffSq = cutoff_*cutoff_; // Initialize counters for primary atoms and neighbors atom1Ptrs_.clear(); atom2Ptrs_.clear(); first_.clear(); first_.append(0); // Find all neighbors (cell list) cellPtr = cellList.begin(); while (cellPtr) { cellPtr->getNeighbors(neighbors, reverseUpdateFlag); na = cellPtr->nAtom(); nn = neighbors.size(); // Loop over primary atoms (atom1) in primary cell for (i = 0; i < na; ++i) { atom1Ptr = neighbors[i]; maskPtr = &(atom1Ptr->mask()); foundNeighbor = false; // Loop over secondary atoms (atom2) in primary cell for (j = 0; j < na; ++j) { atom2Ptr = neighbors[j]; if (atom2Ptr > atom1Ptr) { atom2Id = atom2Ptr->id(); if (!maskPtr->isMasked(atom2Id)) { dr.subtract(atom2Ptr->position(), atom1Ptr->position()); dRSq = dr.square(); if (dRSq < cutoffSq) { // If first neighbor of atom1, add atom1 to atom1Ptrs_ if (!foundNeighbor) { atom1Ptrs_.append(atom1Ptr); foundNeighbor = true; } // Append 2nd atom to atom2Ptrs_[] atom2Ptrs_.append(atom2Ptr); } } } } // Atoms in neighboring cells for (j = na; j < nn; ++j) { atom2Ptr = neighbors[j]; atom2Id = atom2Ptr->id(); if (!maskPtr->isMasked(atom2Id)) { dr.subtract(atom2Ptr->position(), atom1Ptr->position()); dRSq = dr.square(); if (dRSq < cutoffSq) { // If first_ neighbor, record iAtomId in atom1Ptrs_ if (!foundNeighbor) { atom1Ptrs_.append(atom1Ptr); foundNeighbor = true; } // Append Id of 2nd atom in pair to atom2Ptrs_[] atom2Ptrs_.append(atom2Ptr); } } } // When finished with atom1, set next element of first_ array. if (foundNeighbor) { first_.append(atom2Ptrs_.size()); } } // Advance to next cell in a linked list cellPtr = cellPtr->nextCellPtr(); } // Postconditions if (atom1Ptrs_.size()) { if (first_.size() != atom1Ptrs_.size() + 1) { UTIL_THROW("Array size problem"); } if (first_[0] != 0) { UTIL_THROW("Incorrect first element of first_"); } if (first_[atom1Ptrs_.size()] != atom2Ptrs_.size()) { UTIL_THROW("Incorrect last element of first_"); } } // Increment buildCounter_= number of times the list has been built. ++buildCounter_; // Increment maxima if (atom1Ptrs_.size() > maxNAtomLocal_) { maxNAtomLocal_ = atom1Ptrs_.size(); } if (atom2Ptrs_.size() > maxNPairLocal_) { maxNPairLocal_ = atom2Ptrs_.size(); } }
/* * Evaluate change in energy, add Boltzmann factor to accumulator. */ void McMuExchange::sample(long iStep) { if (isAtInterval(iStep)) { // Preconditions if (!system().energyEnsemble().isIsothermal()) { UTIL_THROW("EnergyEnsemble is not isothermal"); } if (nMolecule_ != system().nMolecule(speciesId_)) { UTIL_THROW("nMolecule has changed since setup"); } McPairPotential& potential = system().pairPotential(); const CellList& cellList = potential.cellList(); System::MoleculeIterator molIter; Atom* ptr0 = 0; // Pointer to first atom in molecule Atom* ptr1 = 0; // Pointer to flipped atom Atom* ptr2 = 0; // Pointer to neighboring atom Mask* maskPtr = 0; // Mask of flipped atom double rsq, dE, beta, boltzmann; int j, k, nNeighbor, nFlip; int i1, i2, id1, id2, t1, t2, t1New, iMol; beta = system().energyEnsemble().beta(); nFlip = flipAtomIds_.size(); // Loop over molecules in species iMol = 0; system().begin(speciesId_, molIter); for ( ; molIter.notEnd(); ++molIter) { dE = 0.0; ptr0 = &molIter->atom(0); // Loop over flipped atoms for (j = 0; j < nFlip; ++j) { i1 = flipAtomIds_[j]; t1New = newTypeIds_[i1]; ptr1 = &molIter->atom(i1); id1 = ptr1->id(); t1 = ptr1->typeId(); maskPtr = &(ptr1->mask()); // Loop over neighboring atoms cellList.getNeighbors(ptr1->position(), neighbors_); nNeighbor = neighbors_.size(); for (k = 0; k < nNeighbor; ++k) { ptr2 = neighbors_[k]; id2 = ptr2->id(); // Check if atoms are identical if (id2 != id1) { // Check if pair is masked if (!maskPtr->isMasked(*ptr2)) { rsq = boundary().distanceSq(ptr1->position(), ptr2->position()); t2 = ptr2->typeId(); if (&(ptr1->molecule()) != &(ptr2->molecule())) { // Intermolecular atom pair dE -= potential.energy(rsq, t1, t2); dE += potential.energy(rsq, t1New, t2); } else { // Intramolecular atom pair if (id2 > id1) { dE -= potential.energy(rsq, t1, t2); i2 = (int)(ptr2 - ptr0); t2 = newTypeIds_[i2]; dE += potential.energy(rsq, t1New, t2); } else { i2 = (int)(ptr2 - ptr0); if (!isAtomFlipped_[i2]) { dE -= potential.energy(rsq, t1, t2); t2 = newTypeIds_[i2]; dE += potential.energy(rsq, t1New, t2); } } } } } } // end loop over neighbors } // end loop over flipped atoms boltzmann = exp(-beta*dE); accumulators_[iMol].sample(boltzmann); ++iMol; } // end loop over molecules } }
/* * Build the PairList, i.e., populate it with atom pairs. */ void PairList::build(CellList& cellList, bool reverseUpdateFlag) { // Precondition assert(isAllocated()); Cell::NeighborArray neighbors; double cutoffSq; const Cell* cellPtr; CellAtom* atom1Ptr; CellAtom* atom2Ptr; Mask* maskPtr; Vector dr; int na; // number of atoms in this cell int nn; // number of neighbors for a cell int i, j; bool hasNeighbor; // Set maximum squared-separation for pairs in Pairlist cutoffSq = cutoff_*cutoff_; // Initialize counters for primary atoms and neighbors atom1Ptrs_.clear(); atom2Ptrs_.clear(); first_.clear(); first_.append(0); // Copy positions and ids into cell list cellList.update(); // Find all neighbors (cell list) cellPtr = cellList.begin(); while (cellPtr) { na = cellPtr->nAtom(); // # of atoms in cell if (na) { cellPtr->getNeighbors(neighbors, reverseUpdateFlag); nn = neighbors.size(); // Loop over primary atoms (atom1) in primary cell for (i = 0; i < na; ++i) { atom1Ptr = neighbors[i]; maskPtr = atom1Ptr->maskPtr(); // Loop over secondary atoms hasNeighbor = false; for (j = i + 1; j < nn; ++j) { atom2Ptr = neighbors[j]; dr.subtract(atom2Ptr->position(), atom1Ptr->position()); if (dr.square() < cutoffSq && !maskPtr->isMasked(atom2Ptr->id())) { atom2Ptrs_.append(atom2Ptr->ptr()); hasNeighbor = true; } } // Complete processing of atom1. if (hasNeighbor) { atom1Ptrs_.append(atom1Ptr->ptr()); first_.append(atom2Ptrs_.size()); } } // for ia } // if (na) // Advance to next cell in a linked list cellPtr = cellPtr->nextCellPtr(); } // Postconditions if (atom1Ptrs_.size()) { if (first_.size() != atom1Ptrs_.size() + 1) { UTIL_THROW("Array size problem"); } if (first_[0] != 0) { UTIL_THROW("Incorrect first element of first_"); } if (first_[atom1Ptrs_.size()] != atom2Ptrs_.size()) { UTIL_THROW("Incorrect last element of first_"); } } // Increment buildCounter_= number of times the list has been built. ++buildCounter_; // Increment maxima if (atom1Ptrs_.size() > maxNAtomLocal_) { maxNAtomLocal_ = atom1Ptrs_.size(); } if (atom2Ptrs_.size() > maxNPairLocal_) { maxNPairLocal_ = atom2Ptrs_.size(); } }