45#include "primitives/GhostTorsion.hpp"
51#include "utils/Constants.hpp"
55 GhostTorsion::GhostTorsion(Atom* atom1, Atom* atom2,
56 DirectionalAtom* ghostAtom, TorsionType* tt) :
57 Torsion(atom1, atom2, ghostAtom, ghostAtom, tt) {}
59 void GhostTorsion::calcForce(RealType& angle,
bool doParticlePot) {
60 DirectionalAtom* ghostAtom =
static_cast<DirectionalAtom*
>(atoms_[2]);
62 Vector3d pos1 = atoms_[0]->getPos();
63 Vector3d pos2 = atoms_[1]->getPos();
64 Vector3d pos3 = ghostAtom->getPos();
66 Vector3d r21 = pos1 - pos2;
67 snapshotMan_->getCurrentSnapshot()->wrapVector(r21);
68 Vector3d r32 = pos2 - pos3;
69 snapshotMan_->getCurrentSnapshot()->wrapVector(r32);
70 Vector3d r43 = ghostAtom->getA().transpose().getColumn(2);
73 Vector3d A =
cross(r21, r32);
74 RealType rA = A.length();
75 Vector3d B =
cross(r32, r43);
76 RealType rB = B.length();
84 if (rA * rB < OpenMD::epsilon)
return;
90 RealType cos_phi =
dot(A, B);
93 torsionType_->calcForce(cos_phi, potential_, dVdcosPhi);
95 Vector3d dcosdA = (cos_phi * A - B) / rA;
96 Vector3d dcosdB = (cos_phi * B - A) / rB;
98 Vector3d f1 = dVdcosPhi *
cross(r32, dcosdA);
99 Vector3d f2 = dVdcosPhi * (
cross(r43, dcosdB) -
cross(r21, dcosdA));
100 Vector3d f3 = dVdcosPhi *
cross(dcosdB, r32);
102 atoms_[0]->addFrc(f1);
103 atoms_[1]->addFrc(f2 - f1);
105 ghostAtom->addFrc(-f2);
108 ghostAtom->addTrq(
cross(r43, f3));
111 atoms_[0]->addParticlePot(potential_);
112 atoms_[1]->addParticlePot(potential_);
113 ghostAtom->addParticlePot(potential_);
116 angle = acos(cos_phi) / Constants::PI * 180.0;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Vector3< Real > cross(const Vector3< Real > &v1, const Vector3< Real > &v2)
Returns the cross product of two Vectors.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.