48#include "selection/DistanceFinder.hpp"
58 DistanceFinder::DistanceFinder(
SimInfo* info) : info_(info) {
59 nObjects_.push_back(info_->getNGlobalAtoms() +
60 info_->getNGlobalRigidBodies());
61 nObjects_.push_back(info_->getNGlobalBonds());
62 nObjects_.push_back(info_->getNGlobalBends());
63 nObjects_.push_back(info_->getNGlobalTorsions());
64 nObjects_.push_back(info_->getNGlobalInversions());
65 nObjects_.push_back(info_->getNGlobalMolecules());
67 stuntdoubles_.resize(nObjects_[STUNTDOUBLE]);
68 bonds_.resize(nObjects_[BOND]);
69 bends_.resize(nObjects_[BEND]);
70 torsions_.resize(nObjects_[TORSION]);
71 inversions_.resize(nObjects_[INVERSION]);
72 molecules_.resize(nObjects_[MOLECULE]);
74 SimInfo::MoleculeIterator mi;
75 Molecule::AtomIterator ai;
76 Molecule::RigidBodyIterator rbIter;
77 Molecule::BondIterator bondIter;
78 Molecule::BendIterator bendIter;
79 Molecule::TorsionIterator torsionIter;
80 Molecule::InversionIterator inversionIter;
90 for (mol = info_->beginMolecule(mi); mol != NULL;
91 mol = info_->nextMolecule(mi)) {
92 molecules_[mol->getGlobalIndex()] = mol;
94 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
95 stuntdoubles_[atom->getGlobalIndex()] = atom;
97 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
98 rb = mol->nextRigidBody(rbIter)) {
99 stuntdoubles_[rb->getGlobalIndex()] = rb;
101 for (bond = mol->beginBond(bondIter); bond != NULL;
102 bond = mol->nextBond(bondIter)) {
103 bonds_[bond->getGlobalIndex()] = bond;
105 for (bend = mol->beginBend(bendIter); bend != NULL;
106 bend = mol->nextBend(bendIter)) {
107 bends_[bend->getGlobalIndex()] = bend;
109 for (torsion = mol->beginTorsion(torsionIter); torsion != NULL;
110 torsion = mol->nextTorsion(torsionIter)) {
111 torsions_[torsion->getGlobalIndex()] = torsion;
113 for (inversion = mol->beginInversion(inversionIter); inversion != NULL;
114 inversion = mol->nextInversion(inversionIter)) {
115 inversions_[inversion->getGlobalIndex()] = inversion;
120 SelectionSet DistanceFinder::find(
const SelectionSet& bs,
122 return findImpl(bs, distance, -1);
125 SelectionSet DistanceFinder::find(
const SelectionSet& bs, RealType distance,
127 return findImpl(bs, distance, frame);
130 SelectionSet DistanceFinder::findImpl(
const SelectionSet& bs,
131 RealType distance,
int frame) {
132 const bool useCurrent = (frame < 0);
133 Snapshot* currSnapshot = useCurrent
134 ? info_->getSnapshotManager()->getCurrentSnapshot()
135 : info_->getSnapshotManager()->getSnapshot(frame);
138 auto getPos = [useCurrent, frame](StuntDouble* sd) -> Vector3d {
139 return useCurrent ? sd->getPos() : sd->getPos(frame);
141 auto getCom = [useCurrent, frame](Molecule* mol) -> Vector3d {
142 return useCurrent ? mol->getCom() : mol->getCom(frame);
145 SelectionSet bsResult(nObjects_);
146 assert(bsResult.size() == bs.size());
153 MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);
156 for (
unsigned int j = 0; j < stuntdoubles_.size(); ++j) {
157 if (stuntdoubles_[j] != NULL) {
158 if (stuntdoubles_[j]->isRigidBody()) {
159 RigidBody* rb =
static_cast<RigidBody*
>(stuntdoubles_[j]);
160 useCurrent ? rb->updateAtoms() : rb->updateAtoms(frame);
167 auto checkDistance = [&](
const Vector3d& centerPos,
const Vector3d& pos,
168 OpenMDBitSet& bits,
size_t idx) {
169 Vector3d r = centerPos - pos;
170 currSnapshot->wrapVector(r);
171 if (r.length() <= distance) { bits.setBitOn(idx); }
174 SelectionSet bsTemp = bs;
175 bsTemp = bsTemp.parallelReduce();
177 for (
size_t i = 0; i < bsTemp.bitsets_[
STUNTDOUBLE].size(); ++i) {
178 if (!bsTemp.bitsets_[STUNTDOUBLE][i])
continue;
183 mol = info_->getGlobalMolMembership(i);
184 proc = info_->getMolToProc(mol);
186 if (proc == worldRank) {
187 centerPos = getPos(stuntdoubles_[i]);
188 data[0] = centerPos.x();
189 data[1] = centerPos.y();
190 data[2] = centerPos.z();
191 MPI_Bcast(data, 3, MPI_REALTYPE, proc, MPI_COMM_WORLD);
193 MPI_Bcast(data, 3, MPI_REALTYPE, proc, MPI_COMM_WORLD);
194 centerPos = Vector3d(data);
197 centerPos = getPos(stuntdoubles_[i]);
201 for (
size_t j = 0; j < molecules_.size(); ++j) {
202 if (molecules_[j] != NULL)
203 checkDistance(centerPos, getCom(molecules_[j]),
204 bsResult.bitsets_[MOLECULE], j);
208 for (
size_t j = 0; j < stuntdoubles_.size(); ++j) {
209 if (stuntdoubles_[j] != NULL)
210 checkDistance(centerPos, getPos(stuntdoubles_[j]),
211 bsResult.bitsets_[STUNTDOUBLE], j);
215 for (
size_t j = 0; j < bonds_.size(); ++j) {
216 if (bonds_[j] != NULL) {
217 Vector3d loc = getPos(bonds_[j]->getAtomA())
218 + getPos(bonds_[j]->getAtomB());
219 checkDistance(centerPos, loc / 2.0,
220 bsResult.bitsets_[BOND], j);
225 for (
size_t j = 0; j < bends_.size(); ++j) {
226 if (bends_[j] != NULL) {
227 Vector3d loc = getPos(bends_[j]->getAtomA())
228 + getPos(bends_[j]->getAtomB())
229 + getPos(bends_[j]->getAtomC());
230 checkDistance(centerPos, loc / 3.0,
231 bsResult.bitsets_[BEND], j);
236 for (
size_t j = 0; j < torsions_.size(); ++j) {
237 if (torsions_[j] != NULL) {
238 Vector3d loc = getPos(torsions_[j]->getAtomA())
239 + getPos(torsions_[j]->getAtomB())
240 + getPos(torsions_[j]->getAtomC())
241 + getPos(torsions_[j]->getAtomD());
242 checkDistance(centerPos, loc / 4.0,
243 bsResult.bitsets_[TORSION], j);
248 for (
size_t j = 0; j < inversions_.size(); ++j) {
249 if (inversions_[j] != NULL) {
250 Vector3d loc = getPos(inversions_[j]->getAtomA())
251 + getPos(inversions_[j]->getAtomB())
252 + getPos(inversions_[j]->getAtomC())
253 + getPos(inversions_[j]->getAtomD());
254 checkDistance(centerPos, loc / 4.0,
255 bsResult.bitsets_[INVERSION], j);
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
@ STUNTDOUBLE
StuntDoubles (Atoms & RigidBodies).