RealType GofROmega::evaluateAngle(StuntDouble* sd1, StuntDouble* sd2, StuntDouble* sd3) { bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); Vector3d v1; Vector3d v2; v1 = sd3->getPos() - sd1->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(v1); if (!sd2->isDirectional()) { sprintf(painCave.errMsg, "GofROmega: attempted to use a non-directional object: %s\n", sd2->getType().c_str()); painCave.isFatal = 1; simError(); } if (sd2->isAtom()) { AtomType* atype2 = static_cast<Atom*>(sd2)->getAtomType(); MultipoleAdapter ma2 = MultipoleAdapter(atype2); if (ma2.isDipole() ) v2 = sd2->getDipole(); else v2 = sd2->getA().transpose() * V3Z; } else { v2 = sd2->getA().transpose() * V3Z; } v1.normalize(); v2.normalize(); return dot(v1, v2); }
void GofXyz::initializeHistogram() { // Calculate the center of mass of the molecule of selected // StuntDouble in selection1 if (!evaluator3_.isDynamic()) { seleMan3_.setSelectionSet(evaluator3_.evaluate()); } assert(seleMan1_.getSelectionCount() == seleMan3_.getSelectionCount()); bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); // The Dipole direction of selection3 and position of selection3 will // be used to determine the y-z plane // v1 = s3 -s1, // z = origin.dipole // x = v1 X z // y = z X x rotMats_.clear(); int i; int j; StuntDouble* sd1; StuntDouble* sd3; for (sd1 = seleMan1_.beginSelected(i), sd3 = seleMan3_.beginSelected(j); sd1 != NULL || sd3 != NULL; sd1 = seleMan1_.nextSelected(i), sd3 = seleMan3_.nextSelected(j)) { Vector3d r3 = sd3->getPos(); Vector3d r1 = sd1->getPos(); Vector3d v1 = r3 - r1; if (usePeriodicBoundaryConditions_) info_->getSnapshotManager()->getCurrentSnapshot()->wrapVector(v1); AtomType* atype1 = static_cast<Atom*>(sd1)->getAtomType(); MultipoleAdapter ma1 = MultipoleAdapter(atype1); Vector3d zaxis; if (ma1.isDipole()) zaxis = sd1->getDipole(); else zaxis = sd1->getA().transpose() * V3Z; Vector3d xaxis = cross(v1, zaxis); Vector3d yaxis = cross(zaxis, xaxis); xaxis.normalize(); yaxis.normalize(); zaxis.normalize(); RotMat3x3d rotMat; rotMat.setRow(0, xaxis); rotMat.setRow(1, yaxis); rotMat.setRow(2, zaxis); rotMats_.insert(std::map<int, RotMat3x3d>::value_type(sd1->getGlobalIndex(), rotMat)); } }
RealType GofROmega::evaluateAngle(StuntDouble* sd1, StuntDouble* sd2) { Vector3d v1, v2; if (!sd1->isDirectional()) { sprintf(painCave.errMsg, "GofROmega: attempted to use a non-directional object: %s\n", sd1->getType().c_str()); painCave.isFatal = 1; simError(); } if (sd1->isAtom()){ AtomType* atype1 = static_cast<Atom*>(sd1)->getAtomType(); MultipoleAdapter ma1 = MultipoleAdapter(atype1); if (ma1.isDipole() ) v1 = sd1->getDipole(); else v1 = sd1->getA().transpose() * V3Z; } else { v1 = sd1->getA().transpose() * V3Z; } if (!sd2->isDirectional()) { sprintf(painCave.errMsg, "GofROmega attempted to use a non-directional object: %s\n", sd2->getType().c_str()); painCave.isFatal = 1; simError(); } if (sd2->isAtom()) { AtomType* atype2 = static_cast<Atom*>(sd2)->getAtomType(); MultipoleAdapter ma2 = MultipoleAdapter(atype2); if (ma2.isDipole() ) v2 = sd2->getDipole(); else v2 = sd2->getA().transpose() * V3Z; } else { v2 = sd2->getA().transpose() * V3Z; } v1.normalize(); v2.normalize(); return dot(v1, v2); }
RealType GofRTheta::evaluateAngle(StuntDouble* sd1, StuntDouble* sd2) { bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); Vector3d pos1 = sd1->getPos(); Vector3d pos2 = sd2->getPos(); Vector3d r12 = pos2 - pos1; if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(r12); r12.normalize(); Vector3d vec; if (!sd1->isDirectional()) { sprintf(painCave.errMsg, "GofRTheta: attempted to use a non-directional object: %s\n", sd1->getType().c_str()); painCave.isFatal = 1; simError(); } if (sd1->isAtom()) { AtomType* atype1 = static_cast<Atom*>(sd1)->getAtomType(); MultipoleAdapter ma1 = MultipoleAdapter(atype1); if (ma1.isDipole() ) vec = sd1->getDipole(); else vec = sd1->getA().transpose() * V3Z; } else { vec = sd1->getA().transpose() * V3Z; } vec.normalize(); return dot(r12, vec); }
DirectionalAtom::DirectionalAtom(AtomType* dAtomType) : Atom(dAtomType) { objType_= otDAtom; DirectionalAdapter da = DirectionalAdapter(dAtomType); I_ = da.getI(); MultipoleAdapter ma = MultipoleAdapter(dAtomType); if (ma.isDipole()) { dipole_ = ma.getDipole(); } if (ma.isQuadrupole()) { quadrupole_ = ma.getQuadrupole(); } // Check if one of the diagonal inertia tensor of this directional // atom is zero: int nLinearAxis = 0; Mat3x3d inertiaTensor = getI(); for (int i = 0; i < 3; i++) { if (fabs(inertiaTensor(i, i)) < OpenMD::epsilon) { linear_ = true; linearAxis_ = i; ++ nLinearAxis; } } if (nLinearAxis > 1) { sprintf( painCave.errMsg, "Directional Atom warning.\n" "\tOpenMD found more than one axis in this directional atom with a vanishing \n" "\tmoment of inertia."); painCave.isFatal = 0; simError(); } }