# | Line 6 | Line 6 | |
---|---|---|
6 | * redistribute this software in source and binary code form, provided | |
7 | * that the following conditions are met: | |
8 | * | |
9 | < | * 1. Acknowledgement of the program authors must be made in any |
10 | < | * publication of scientific results based in part on use of the |
11 | < | * program. An acceptable form of acknowledgement is citation of |
12 | < | * the article in which the program was described (Matthew |
13 | < | * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher |
14 | < | * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented |
15 | < | * Parallel Simulation Engine for Molecular Dynamics," |
16 | < | * J. Comput. Chem. 26, pp. 252-271 (2005)) |
17 | < | * |
18 | < | * 2. Redistributions of source code must retain the above copyright |
9 | > | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | < | * 3. Redistributions in binary form must reproduce the above copyright |
12 | > | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the | |
15 | * distribution. | |
# | Line 37 | Line 28 | |
28 | * arising out of the use of or inability to use software, even if the | |
29 | * University of Notre Dame has been advised of the possibility of | |
30 | * such damages. | |
31 | + | * |
32 | + | * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your |
33 | + | * research, please cite the appropriate papers when you publish your |
34 | + | * work. Good starting points are: |
35 | + | * |
36 | + | * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005). |
37 | + | * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006). |
38 | + | * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008). |
39 | + | * [4] Vardeman & Gezelter, in progress (2009). |
40 | */ | |
41 | ||
42 | #include "applications/staticProps/RippleOP.hpp" | |
# | Line 44 | Line 44 | |
44 | #include "io/DumpReader.hpp" | |
45 | #include "primitives/Molecule.hpp" | |
46 | #include "utils/NumericConstant.hpp" | |
47 | < | namespace oopse { |
47 | > | namespace OpenMD { |
48 | ||
49 | ||
50 | RippleOP::RippleOP(SimInfo* info, const std::string& filename, const std::string& sele1, const std::string& sele2) | |
# | Line 62 | Line 62 | namespace oopse { | |
62 | }else { | |
63 | sprintf( painCave.errMsg, | |
64 | "--sele1 must be static selection\n"); | |
65 | < | painCave.severity = OOPSE_ERROR; |
65 | > | painCave.severity = OPENMD_ERROR; |
66 | painCave.isFatal = 1; | |
67 | simError(); | |
68 | } | |
# | Line 72 | Line 72 | namespace oopse { | |
72 | }else { | |
73 | sprintf( painCave.errMsg, | |
74 | "--sele2 must be static selection\n"); | |
75 | < | painCave.severity = OOPSE_ERROR; |
75 | > | painCave.severity = OPENMD_ERROR; |
76 | painCave.isFatal = 1; | |
77 | simError(); | |
78 | } | |
# | Line 80 | Line 80 | namespace oopse { | |
80 | if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount() ) { | |
81 | sprintf( painCave.errMsg, | |
82 | "The number of selected Stuntdoubles are not the same in --sele1 and sele2\n"); | |
83 | < | painCave.severity = OOPSE_ERROR; |
83 | > | painCave.severity = OPENMD_ERROR; |
84 | painCave.isFatal = 1; | |
85 | simError(); | |
86 | ||
# | Line 104 | Line 104 | namespace oopse { | |
104 | RigidBody* rb; | |
105 | SimInfo::MoleculeIterator mi; | |
106 | Molecule::RigidBodyIterator rbIter; | |
107 | + | |
108 | + | StuntDouble* j1; |
109 | + | StuntDouble* j2; |
110 | + | StuntDouble* sd3; |
111 | ||
112 | DumpReader reader(info_, dumpFilename_); | |
113 | int nFrames = reader.getNFrames(); | |
114 | < | |
114 | > | |
115 | for (int i = 0; i < nFrames; i += step_) { | |
116 | reader.readFrame(i); | |
117 | currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); | |
118 | + | int nMolecules = info_->getNGlobalMolecules(); |
119 | + | int i1; |
120 | + | int nUpper=0; |
121 | + | int nLower=0; |
122 | + | int nTail=0; |
123 | + | RealType sumZ = 0.0; |
124 | ||
115 | – | |
125 | for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { | |
126 | //change the positions of atoms which belong to the rigidbodies | |
127 | for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { | |
128 | rb->updateAtoms(); | |
129 | } | |
130 | } | |
131 | + | |
132 | + | for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL; sd3 = seleMan2_.nextSelected(i1)) { |
133 | + | Vector3d pos1 = sd3->getPos(); |
134 | + | if (usePeriodicBoundaryConditions_) |
135 | + | currentSnapshot_->wrapVector(pos1); |
136 | + | sd3->setPos(pos1); |
137 | + | } |
138 | + | |
139 | + | for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL; sd3 = seleMan2_.nextSelected(i1)) { |
140 | + | Vector3d pos1 = sd3->getPos(); |
141 | + | sumZ += pos1.z(); |
142 | + | } |
143 | + | RealType avgZ = sumZ / (RealType) nMolecules; |
144 | ||
145 | < | Mat3x3d orderTensorHead(0.0), orderTensorTail(0.0); |
146 | < | for (std::vector<std::pair<StuntDouble*, StuntDouble*> >::iterator j = sdPairs_.begin(); j != sdPairs_.end(); ++j) { |
147 | < | Vector3d vecHead = j->first->getElectroFrame().getColumn(2); |
148 | < | Vector3d vecTail = j->second->getA().getColumn(2); |
149 | < | orderTensorHead +=outProduct(vecHead, vecHead); |
145 | > | Mat3x3d orderTensorHeadUpper(0.0), orderTensorTail(0.0), orderTensorHeadLower(0.0); |
146 | > | // for (std::vector<std::pair<StuntDouble*, StuntDouble*> >::iterator j = sdPairs_.begin(); j != sdPairs_.end(); ++j) { |
147 | > | for (j1 = seleMan1_.beginSelected(i1); j1 != NULL; j1 = seleMan1_.nextSelected(i1)) { |
148 | > | Vector3d pos = j1->getPos(); |
149 | > | if (usePeriodicBoundaryConditions_) |
150 | > | currentSnapshot_->wrapVector(pos); |
151 | > | Vector3d vecHeadUpper; |
152 | > | if (pos.z() >= avgZ){ |
153 | > | vecHeadUpper = j1->getElectroFrame().getColumn(2); |
154 | > | nUpper++; |
155 | > | } |
156 | > | Vector3d vecHeadLower; |
157 | > | if (pos.z() <= avgZ){ |
158 | > | vecHeadLower = j1->getElectroFrame().getColumn(2); |
159 | > | nLower++; |
160 | > | } |
161 | > | orderTensorHeadUpper +=outProduct(vecHeadUpper, vecHeadUpper); |
162 | > | orderTensorHeadLower +=outProduct(vecHeadLower, vecHeadLower); |
163 | > | } |
164 | > | for (j2 = seleMan2_.beginSelected(i1); j2 != NULL; j2 = seleMan2_.nextSelected(i1)) { |
165 | > | // The lab frame vector corresponding to the body-fixed |
166 | > | // z-axis is simply the second column of A.transpose() |
167 | > | // or, identically, the second row of A itself. |
168 | > | |
169 | > | Vector3d vecTail = j2->getA().getRow(2); |
170 | orderTensorTail +=outProduct(vecTail, vecTail); | |
171 | + | nTail++; |
172 | } | |
130 | – | |
131 | – | orderTensorHead /= sdPairs_.size(); |
132 | – | orderTensorHead -= (RealType)(1.0/3.0) * Mat3x3d::identity(); |
173 | ||
174 | < | orderTensorTail /= sdPairs_.size(); |
174 | > | orderTensorHeadUpper /= (RealType) nUpper; |
175 | > | orderTensorHeadLower /= (RealType) nLower; |
176 | > | orderTensorHeadUpper -= (RealType)(1.0/3.0) * Mat3x3d::identity(); |
177 | > | orderTensorHeadLower -= (RealType)(1.0/3.0) * Mat3x3d::identity(); |
178 | > | |
179 | > | orderTensorTail /= (RealType) nTail; |
180 | orderTensorTail -= (RealType)(1.0/3.0) * Mat3x3d::identity(); | |
181 | ||
182 | < | Vector3d eigenvaluesHead, eigenvaluesTail; |
183 | < | Mat3x3d eigenvectorsHead, eigenvectorsTail; |
184 | < | Mat3x3d::diagonalize(orderTensorHead, eigenvaluesHead, eigenvectorsHead); |
182 | > | Vector3d eigenvaluesHeadUpper, eigenvaluesHeadLower, eigenvaluesTail; |
183 | > | Mat3x3d eigenvectorsHeadUpper, eigenvectorsHeadLower, eigenvectorsTail; |
184 | > | Mat3x3d::diagonalize(orderTensorHeadUpper, eigenvaluesHeadUpper, eigenvectorsHeadUpper); |
185 | > | Mat3x3d::diagonalize(orderTensorHeadLower, eigenvaluesHeadLower, eigenvectorsHeadLower); |
186 | Mat3x3d::diagonalize(orderTensorTail, eigenvaluesTail, eigenvectorsTail); | |
187 | ||
188 | < | int which; |
189 | < | RealType maxEval = 0.0; |
188 | > | int whichUpper, whichLower, whichTail; |
189 | > | RealType maxEvalUpper = 0.0; |
190 | > | RealType maxEvalLower = 0.0; |
191 | > | RealType maxEvalTail = 0.0; |
192 | for(int k = 0; k< 3; k++){ | |
193 | < | if(fabs(eigenvaluesHead[k]) > maxEval){ |
194 | < | which = k; |
195 | < | maxEval = fabs(eigenvaluesHead[k]); |
193 | > | if(fabs(eigenvaluesHeadUpper[k]) > maxEvalUpper){ |
194 | > | whichUpper = k; |
195 | > | maxEvalUpper = fabs(eigenvaluesHeadUpper[k]); |
196 | } | |
197 | } | |
198 | < | RealType p2Head = 1.5 * maxEval; |
151 | < | maxEval = 0.0; |
198 | > | RealType p2HeadUpper = 1.5 * maxEvalUpper; |
199 | for(int k = 0; k< 3; k++){ | |
200 | < | if(fabs(eigenvaluesTail[k]) > maxEval){ |
201 | < | which = k; |
202 | < | maxEval = fabs(eigenvaluesTail[k]); |
200 | > | if(fabs(eigenvaluesHeadLower[k]) > maxEvalLower){ |
201 | > | whichLower = k; |
202 | > | maxEvalLower = fabs(eigenvaluesHeadLower[k]); |
203 | } | |
204 | } | |
205 | < | RealType p2Tail = 1.5 * maxEval; |
205 | > | RealType p2HeadLower = 1.5 * maxEvalLower; |
206 | > | for(int k = 0; k< 3; k++){ |
207 | > | if(fabs(eigenvaluesTail[k]) > maxEvalTail){ |
208 | > | whichTail = k; |
209 | > | maxEvalTail = fabs(eigenvaluesTail[k]); |
210 | > | } |
211 | > | } |
212 | > | RealType p2Tail = 1.5 * maxEvalTail; |
213 | ||
214 | //the eigen vector is already normalized in SquareMatrix3::diagonalize | |
215 | < | Vector3d directorHead = eigenvectorsHead.getColumn(which); |
216 | < | if (directorHead[0] < 0) { |
217 | < | directorHead.negate(); |
215 | > | Vector3d directorHeadUpper = eigenvectorsHeadUpper.getColumn(whichUpper); |
216 | > | if (directorHeadUpper[0] < 0) { |
217 | > | directorHeadUpper.negate(); |
218 | } | |
219 | < | Vector3d directorTail = eigenvectorsTail.getColumn(which); |
219 | > | Vector3d directorHeadLower = eigenvectorsHeadLower.getColumn(whichLower); |
220 | > | if (directorHeadLower[0] < 0) { |
221 | > | directorHeadLower.negate(); |
222 | > | } |
223 | > | Vector3d directorTail = eigenvectorsTail.getColumn(whichTail); |
224 | if (directorTail[0] < 0) { | |
225 | directorTail.negate(); | |
226 | } | |
227 | ||
228 | < | OrderParam paramHead, paramTail; |
229 | < | paramHead.p2 = p2Head; |
230 | < | paramHead.director = directorHead; |
228 | > | OrderParam paramHeadUpper, paramHeadLower, paramTail; |
229 | > | paramHeadUpper.p2 = p2HeadUpper; |
230 | > | paramHeadUpper.director = directorHeadUpper; |
231 | > | paramHeadLower.p2 = p2HeadLower; |
232 | > | paramHeadLower.director = directorHeadLower; |
233 | paramTail.p2 = p2Tail; | |
234 | paramTail.director = directorTail; | |
235 | ||
236 | < | orderParamsHead_.push_back(paramHead); |
236 | > | orderParamsHeadUpper_.push_back(paramHeadUpper); |
237 | > | orderParamsHeadLower_.push_back(paramHeadLower); |
238 | orderParamsTail_.push_back(paramTail); | |
239 | ||
240 | } | |
241 | ||
242 | < | OrderParam sumOPHead, errsumOPHead; |
242 | > | OrderParam sumOPHeadUpper, errsumOPHeadUpper; |
243 | > | OrderParam sumOPHeadLower, errsumOPHeadLower; |
244 | OrderParam sumOPTail, errsumOPTail; | |
245 | ||
246 | < | sumOPHead.p2 = 0.0; |
247 | < | errsumOPHead.p2 = 0.0; |
248 | < | for (std::size_t i = 0; i < orderParamsHead_.size(); ++i) { |
249 | < | sumOPHead.p2 += orderParamsHead_[i].p2; |
250 | < | sumOPHead.director[0] += orderParamsHead_[i].director[0]; |
251 | < | sumOPHead.director[1] += orderParamsHead_[i].director[1]; |
252 | < | sumOPHead.director[2] += orderParamsHead_[i].director[2]; |
246 | > | sumOPHeadUpper.p2 = 0.0; |
247 | > | errsumOPHeadUpper.p2 = 0.0; |
248 | > | sumOPHeadLower.p2 = 0.0; |
249 | > | errsumOPHeadLower.p2 = 0.0; |
250 | > | for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) { |
251 | > | sumOPHeadUpper.p2 += orderParamsHeadUpper_[i].p2; |
252 | > | sumOPHeadUpper.director[0] += orderParamsHeadUpper_[i].director[0]; |
253 | > | sumOPHeadUpper.director[1] += orderParamsHeadUpper_[i].director[1]; |
254 | > | sumOPHeadUpper.director[2] += orderParamsHeadUpper_[i].director[2]; |
255 | } | |
256 | ||
257 | < | avgOPHead.p2 = sumOPHead.p2 / (RealType)orderParamsHead_.size(); |
258 | < | avgOPHead.director[0] = sumOPHead.director[0] / (RealType)orderParamsHead_.size(); |
259 | < | avgOPHead.director[1] = sumOPHead.director[1] / (RealType)orderParamsHead_.size(); |
260 | < | avgOPHead.director[2] = sumOPHead.director[2] / (RealType)orderParamsHead_.size(); |
261 | < | for (std::size_t i = 0; i < orderParamsHead_.size(); ++i) { |
262 | < | errsumOPHead.p2 += pow((orderParamsHead_[i].p2 - avgOPHead.p2), 2); |
257 | > | avgOPHeadUpper.p2 = sumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size(); |
258 | > | avgOPHeadUpper.director[0] = sumOPHeadUpper.director[0] / (RealType)orderParamsHeadUpper_.size(); |
259 | > | avgOPHeadUpper.director[1] = sumOPHeadUpper.director[1] / (RealType)orderParamsHeadUpper_.size(); |
260 | > | avgOPHeadUpper.director[2] = sumOPHeadUpper.director[2] / (RealType)orderParamsHeadUpper_.size(); |
261 | > | for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) { |
262 | > | errsumOPHeadUpper.p2 += pow((orderParamsHeadUpper_[i].p2 - avgOPHeadUpper.p2), 2); |
263 | } | |
264 | < | errOPHead.p2 = sqrt(errsumOPHead.p2 / (RealType)orderParamsHead_.size()); |
264 | > | errOPHeadUpper.p2 = sqrt(errsumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size()); |
265 | > | for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) { |
266 | > | sumOPHeadLower.p2 += orderParamsHeadLower_[i].p2; |
267 | > | sumOPHeadLower.director[0] += orderParamsHeadLower_[i].director[0]; |
268 | > | sumOPHeadLower.director[1] += orderParamsHeadLower_[i].director[1]; |
269 | > | sumOPHeadLower.director[2] += orderParamsHeadLower_[i].director[2]; |
270 | > | } |
271 | ||
272 | + | avgOPHeadLower.p2 = sumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size(); |
273 | + | avgOPHeadLower.director[0] = sumOPHeadLower.director[0] / (RealType)orderParamsHeadLower_.size(); |
274 | + | avgOPHeadLower.director[1] = sumOPHeadLower.director[1] / (RealType)orderParamsHeadLower_.size(); |
275 | + | avgOPHeadLower.director[2] = sumOPHeadLower.director[2] / (RealType)orderParamsHeadLower_.size(); |
276 | + | for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) { |
277 | + | errsumOPHeadLower.p2 += pow((orderParamsHeadLower_[i].p2 - avgOPHeadLower.p2), 2); |
278 | + | } |
279 | + | errOPHeadLower.p2 = sqrt(errsumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size()); |
280 | + | |
281 | sumOPTail.p2 = 0.0; | |
282 | errsumOPTail.p2 = 0.0; | |
283 | for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) { | |
# | Line 227 | Line 306 | namespace oopse { | |
306 | os<< "#selection1: (" << selectionScript1_ << ")\n"; | |
307 | os << "#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n"; | |
308 | ||
309 | < | os << avgOPHead.p2 << "\t" |
310 | < | << errOPHead.p2 << "\t" |
311 | < | << avgOPHead.director[0] << "\t" |
312 | < | << avgOPHead.director[1] << "\t" |
313 | < | << avgOPHead.director[2] << "\n"; |
309 | > | os << avgOPHeadUpper.p2 << "\t" |
310 | > | << errOPHeadUpper.p2 << "\t" |
311 | > | << avgOPHeadUpper.director[0] << "\t" |
312 | > | << avgOPHeadUpper.director[1] << "\t" |
313 | > | << avgOPHeadUpper.director[2] << "\n"; |
314 | > | |
315 | > | os << avgOPHeadLower.p2 << "\t" |
316 | > | << errOPHeadLower.p2 << "\t" |
317 | > | << avgOPHeadLower.director[0] << "\t" |
318 | > | << avgOPHeadLower.director[1] << "\t" |
319 | > | << avgOPHeadLower.director[2] << "\n"; |
320 | ||
321 | os << "selection2: (" << selectionScript2_ << ")\n"; | |
322 | os << "#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n"; |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |