# | Line 42 | Line 42 | namespace oopse { | |
---|---|---|
42 | #include "primitives/DirectionalAtom.hpp" | |
43 | #include "utils/simError.h" | |
44 | namespace oopse { | |
45 | < | |
45 | > | |
46 | DirectionalAtom::DirectionalAtom(DirectionalAtomType* dAtomType) | |
47 | : Atom(dAtomType){ | |
48 | < | objType_= otDAtom; |
49 | < | if (dAtomType->isMultipole()) { |
50 | < | electroBodyFrame_ = dAtomType->getElectroBodyFrame(); |
48 | > | objType_= otDAtom; |
49 | > | if (dAtomType->isMultipole()) { |
50 | > | electroBodyFrame_ = dAtomType->getElectroBodyFrame(); |
51 | > | } |
52 | > | |
53 | > | // Check if one of the diagonal inertia tensor of this directional |
54 | > | // atom is zero: |
55 | > | int nLinearAxis = 0; |
56 | > | Mat3x3d inertiaTensor = getI(); |
57 | > | for (int i = 0; i < 3; i++) { |
58 | > | if (fabs(inertiaTensor(i, i)) < oopse::epsilon) { |
59 | > | linear_ = true; |
60 | > | linearAxis_ = i; |
61 | > | ++ nLinearAxis; |
62 | } | |
52 | – | |
53 | – | //check if one of the diagonal inertia tensor of this directional atom is zero |
54 | – | int nLinearAxis = 0; |
55 | – | Mat3x3d inertiaTensor = getI(); |
56 | – | for (int i = 0; i < 3; i++) { |
57 | – | if (fabs(inertiaTensor(i, i)) < oopse::epsilon) { |
58 | – | linear_ = true; |
59 | – | linearAxis_ = i; |
60 | – | ++ nLinearAxis; |
61 | – | } |
62 | – | } |
63 | – | |
64 | – | if (nLinearAxis > 1) { |
65 | – | sprintf( painCave.errMsg, |
66 | – | "Directional Atom error.\n" |
67 | – | "\tOOPSE found more than one axis in this directional atom with a vanishing \n" |
68 | – | "\tmoment of inertia."); |
69 | – | painCave.isFatal = 1; |
70 | – | simError(); |
71 | – | } |
72 | – | |
63 | } | |
64 | ||
65 | + | if (nLinearAxis > 1) { |
66 | + | sprintf( painCave.errMsg, |
67 | + | "Directional Atom warning.\n" |
68 | + | "\tOOPSE found more than one axis in this directional atom with a vanishing \n" |
69 | + | "\tmoment of inertia."); |
70 | + | painCave.isFatal = 0; |
71 | + | simError(); |
72 | + | } |
73 | + | } |
74 | + | |
75 | Mat3x3d DirectionalAtom::getI() { | |
76 | return static_cast<DirectionalAtomType*>(getAtomType())->getI(); | |
77 | } | |
78 | < | |
78 | > | |
79 | void DirectionalAtom::setPrevA(const RotMat3x3d& a) { | |
80 | ((snapshotMan_->getPrevSnapshot())->*storage_).aMat[localIndex_] = a; | |
81 | if (atomType_->isMultipole()) { | |
82 | ((snapshotMan_->getPrevSnapshot())->*storage_).electroFrame[localIndex_] = a.transpose() * electroBodyFrame_; | |
83 | } | |
84 | } | |
85 | < | |
86 | < | |
85 | > | |
86 | > | |
87 | void DirectionalAtom::setA(const RotMat3x3d& a) { | |
88 | ((snapshotMan_->getCurrentSnapshot())->*storage_).aMat[localIndex_] = a; | |
89 | < | |
89 | > | |
90 | if (atomType_->isMultipole()) { | |
91 | ((snapshotMan_->getCurrentSnapshot())->*storage_).electroFrame[localIndex_] = a.transpose() * electroBodyFrame_; | |
92 | } | |
93 | } | |
94 | < | |
94 | > | |
95 | void DirectionalAtom::setA(const RotMat3x3d& a, int snapshotNo) { | |
96 | ((snapshotMan_->getSnapshot(snapshotNo))->*storage_).aMat[localIndex_] = a; | |
97 | < | |
97 | > | |
98 | if (atomType_->isMultipole()) { | |
99 | ((snapshotMan_->getSnapshot(snapshotNo))->*storage_).electroFrame[localIndex_] = a.transpose() * electroBodyFrame_; | |
100 | } | |
101 | } | |
102 | < | |
102 | > | |
103 | void DirectionalAtom::rotateBy(const RotMat3x3d& m) { | |
104 | setA(m *getA()); | |
105 | } | |
106 | < | |
107 | < | std::vector<double> DirectionalAtom::getGrad() { |
108 | < | std::vector<double> grad(6, 0.0); |
106 | > | |
107 | > | std::vector<RealType> DirectionalAtom::getGrad() { |
108 | > | std::vector<RealType> grad(6, 0.0); |
109 | Vector3d force; | |
110 | Vector3d torque; | |
111 | Vector3d myEuler; | |
112 | < | double phi, theta, psi; |
113 | < | double cphi, sphi, ctheta, stheta; |
112 | > | RealType phi, theta, psi; |
113 | > | RealType cphi, sphi, ctheta, stheta; |
114 | Vector3d ephi; | |
115 | Vector3d etheta; | |
116 | Vector3d epsi; | |
117 | < | |
117 | > | |
118 | force = getFrc(); | |
119 | torque =getTrq(); | |
120 | myEuler = getA().toEulerAngles(); | |
121 | < | |
121 | > | |
122 | phi = myEuler[0]; | |
123 | theta = myEuler[1]; | |
124 | psi = myEuler[2]; | |
125 | < | |
125 | > | |
126 | cphi = cos(phi); | |
127 | sphi = sin(phi); | |
128 | ctheta = cos(theta); | |
129 | stheta = sin(theta); | |
130 | < | |
130 | > | |
131 | // get unit vectors along the phi, theta and psi rotation axes | |
132 | < | |
132 | > | |
133 | ephi[0] = 0.0; | |
134 | ephi[1] = 0.0; | |
135 | ephi[2] = 1.0; | |
136 | < | |
136 | > | |
137 | etheta[0] = cphi; | |
138 | etheta[1] = sphi; | |
139 | etheta[2] = 0.0; | |
140 | < | |
140 | > | |
141 | epsi[0] = stheta * cphi; | |
142 | epsi[1] = stheta * sphi; | |
143 | epsi[2] = ctheta; | |
144 | < | |
144 | > | |
145 | //gradient is equal to -force | |
146 | for (int j = 0 ; j<3; j++) | |
147 | grad[j] = -force[j]; | |
148 | < | |
149 | < | for (int j = 0; j < 3; j++ ) { |
150 | < | |
148 | > | |
149 | > | for (int j = 0; j < 3; j++ ) { |
150 | grad[3] -= torque[j]*ephi[j]; | |
151 | grad[4] -= torque[j]*etheta[j]; | |
152 | < | grad[5] -= torque[j]*epsi[j]; |
154 | < | |
152 | > | grad[5] -= torque[j]*epsi[j]; |
153 | } | |
154 | ||
155 | return grad; | |
156 | } | |
157 | < | |
157 | > | |
158 | void DirectionalAtom::accept(BaseVisitor* v) { | |
159 | v->visit(this); | |
160 | < | } |
163 | < | |
160 | > | } |
161 | } | |
162 |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |