47#include "types/DirectionalAdapter.hpp"
48#include "types/MultipoleAdapter.hpp"
49#include "utils/simError.h"
53 DirectionalAtom::DirectionalAtom(AtomType* dAtomType) : Atom(dAtomType) {
56 DirectionalAdapter da = DirectionalAdapter(dAtomType);
59 MultipoleAdapter ma = MultipoleAdapter(dAtomType);
60 if (ma.isDipole()) { dipole_ = ma.getDipole(); }
61 if (ma.isQuadrupole()) { quadrupole_ = ma.getQuadrupole(); }
66 Mat3x3d inertiaTensor = getI();
67 for (
int i = 0; i < 3; i++) {
68 if (fabs(inertiaTensor(i, i)) < OpenMD::epsilon) {
75 if (nLinearAxis > 1) {
77 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
78 "Directional Atom warning.\n"
79 "\tOpenMD found more than one axis in this directional atom with a "
81 "\tmoment of inertia.");
87 Mat3x3d DirectionalAtom::getI() {
return I_; }
90 ((snapshotMan_->getPrevSnapshot())->*storage_).aMat[localIndex_] = a;
92 if (atomType_->isMultipole()) {
95 if (atomType_->isDipole()) {
96 ((snapshotMan_->getPrevSnapshot())->*storage_).dipole[localIndex_] =
100 if (atomType_->isQuadrupole()) {
101 ((snapshotMan_->getPrevSnapshot())->*storage_).quadrupole[localIndex_] =
102 atrans * quadrupole_ * a;
108 ((snapshotMan_->getCurrentSnapshot())->*storage_).aMat[localIndex_] = a;
110 if (atomType_->isMultipole()) {
113 if (atomType_->isDipole()) {
114 ((snapshotMan_->getCurrentSnapshot())->*storage_).dipole[localIndex_] =
118 if (atomType_->isQuadrupole()) {
119 ((snapshotMan_->getCurrentSnapshot())->*storage_)
120 .quadrupole[localIndex_] = atrans * quadrupole_ * a;
125 void DirectionalAtom::setA(
const RotMat3x3d& a,
int snapshotNo) {
126 ((snapshotMan_->getSnapshot(snapshotNo))->*storage_).aMat[localIndex_] = a;
128 if (atomType_->isMultipole()) {
131 if (atomType_->isDipole()) {
132 ((snapshotMan_->getSnapshot(snapshotNo))->*storage_)
133 .dipole[localIndex_] = atrans * dipole_;
136 if (atomType_->isQuadrupole()) {
137 ((snapshotMan_->getSnapshot(snapshotNo))->*storage_)
138 .quadrupole[localIndex_] = atrans * quadrupole_ * a;
143 void DirectionalAtom::rotateBy(
const RotMat3x3d& m) { setA(m * getA()); }
145 std::vector<RealType> DirectionalAtom::getGrad() {
146 std::vector<RealType> grad(6, 0.0);
151 RealType cphi, sphi, ctheta, stheta;
159 myEuler = getA().toEulerAngles();
169 if (fabs(stheta) < 1.0E-9) { stheta = 1.0E-9; }
171 ephi[0] = -sphi * ctheta / stheta;
172 ephi[1] = cphi * ctheta / stheta;
179 epsi[0] = sphi / stheta;
180 epsi[1] = -cphi / stheta;
184 for (
int j = 0; j < 3; j++)
187 for (
int j = 0; j < 3; j++) {
188 grad[3] -= torque[j] * ephi[j];
189 grad[4] -= torque[j] * etheta[j];
190 grad[5] -= torque[j] * epsi[j];
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.