ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/staticProps/RippleOP.cpp
Revision: 1787
Committed: Wed Aug 29 18:13:11 2012 UTC (12 years, 8 months ago) by gezelter
File size: 13816 byte(s)
Log Message:
Massive multipole rewrite

File Contents

# Content
1 /*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * The University of Notre Dame grants you ("Licensee") a
5 * non-exclusive, royalty free, license to use, modify and
6 * redistribute this software in source and binary code form, provided
7 * that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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.
16 *
17 * This software is provided "AS IS," without a warranty of any
18 * kind. All express or implied conditions, representations and
19 * warranties, including any implied warranty of merchantability,
20 * fitness for a particular purpose or non-infringement, are hereby
21 * excluded. The University of Notre Dame and its licensors shall not
22 * be liable for any damages suffered by licensee as a result of
23 * using, modifying or distributing the software or its
24 * derivatives. In no event will the University of Notre Dame or its
25 * licensors be liable for any lost revenue, profit or data, or for
26 * direct, indirect, special, consequential, incidental or punitive
27 * damages, however caused and regardless of the theory of liability,
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] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43 #include "applications/staticProps/RippleOP.hpp"
44 #include "utils/simError.h"
45 #include "io/DumpReader.hpp"
46 #include "primitives/Molecule.hpp"
47 #include "utils/NumericConstant.hpp"
48 #include "types/MultipoleAdapter.hpp"
49 namespace OpenMD {
50
51
52 RippleOP::RippleOP(SimInfo* info, const std::string& filename, const std::string& sele1, const std::string& sele2)
53 : StaticAnalyser(info, filename),
54 selectionScript1_(sele1), selectionScript2_(sele2), evaluator1_(info), evaluator2_(info),
55 seleMan1_(info), seleMan2_(info){
56
57 setOutputName(getPrefix(filename) + ".rp2");
58
59 evaluator1_.loadScriptString(sele1);
60 evaluator2_.loadScriptString(sele2);
61
62 if (!evaluator1_.isDynamic()) {
63 seleMan1_.setSelectionSet(evaluator1_.evaluate());
64 }else {
65 sprintf( painCave.errMsg,
66 "--sele1 must be static selection\n");
67 painCave.severity = OPENMD_ERROR;
68 painCave.isFatal = 1;
69 simError();
70 }
71
72 if (!evaluator2_.isDynamic()) {
73 seleMan2_.setSelectionSet(evaluator2_.evaluate());
74 }else {
75 sprintf( painCave.errMsg,
76 "--sele2 must be static selection\n");
77 painCave.severity = OPENMD_ERROR;
78 painCave.isFatal = 1;
79 simError();
80 }
81
82 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount() ) {
83 sprintf( painCave.errMsg,
84 "The number of selected Stuntdoubles are not the same in --sele1 and sele2\n");
85 painCave.severity = OPENMD_ERROR;
86 painCave.isFatal = 1;
87 simError();
88
89 }
90
91 int i;
92 int j;
93 StuntDouble* sd1;
94 StuntDouble* sd2;
95 for (sd1 = seleMan1_.beginSelected(i), sd2 = seleMan2_.beginSelected(j);
96 sd1 != NULL && sd2 != NULL;
97 sd1 = seleMan1_.nextSelected(i), sd2 = seleMan2_.nextSelected(j)) {
98
99 sdPairs_.push_back(std::make_pair(sd1, sd2));
100 }
101
102 }
103
104 void RippleOP::process() {
105 Molecule* mol;
106 RigidBody* rb;
107 SimInfo::MoleculeIterator mi;
108 Molecule::RigidBodyIterator rbIter;
109
110 StuntDouble* j1;
111 StuntDouble* j2;
112 StuntDouble* sd3;
113
114 DumpReader reader(info_, dumpFilename_);
115 int nFrames = reader.getNFrames();
116
117 for (int i = 0; i < nFrames; i += step_) {
118 reader.readFrame(i);
119 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
120 int nMolecules = info_->getNGlobalMolecules();
121 int i1;
122 int nUpper=0;
123 int nLower=0;
124 int nTail=0;
125 RealType sumZ = 0.0;
126
127 for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
128 //change the positions of atoms which belong to the rigidbodies
129 for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) {
130 rb->updateAtoms();
131 }
132 }
133
134 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL; sd3 = seleMan2_.nextSelected(i1)) {
135 Vector3d pos1 = sd3->getPos();
136 if (usePeriodicBoundaryConditions_)
137 currentSnapshot_->wrapVector(pos1);
138 sd3->setPos(pos1);
139 }
140
141 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL; sd3 = seleMan2_.nextSelected(i1)) {
142 Vector3d pos1 = sd3->getPos();
143 sumZ += pos1.z();
144 }
145 RealType avgZ = sumZ / (RealType) nMolecules;
146
147 Mat3x3d orderTensorHeadUpper(0.0), orderTensorTail(0.0), orderTensorHeadLower(0.0);
148 // for (std::vector<std::pair<StuntDouble*, StuntDouble*> >::iterator j = sdPairs_.begin(); j != sdPairs_.end(); ++j) {
149 for (j1 = seleMan1_.beginSelected(i1); j1 != NULL; j1 = seleMan1_.nextSelected(i1)) {
150 Vector3d pos = j1->getPos();
151 if (usePeriodicBoundaryConditions_)
152 currentSnapshot_->wrapVector(pos);
153 Vector3d vecHeadUpper;
154 if (pos.z() >= avgZ){
155 AtomType* atype1 = static_cast<Atom*>(j1)->getAtomType();
156 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
157 if (ma1.isDipole())
158 vecHeadUpper = j1->getDipole();
159 else
160 vecHeadUpper = j1->getA().transpose()*V3Z;
161 nUpper++;
162 }
163 Vector3d vecHeadLower;
164 if (pos.z() <= avgZ){
165 AtomType* atype1 = static_cast<Atom*>(j1)->getAtomType();
166 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
167 if (ma1.isDipole())
168 vecHeadLower = j1->getDipole();
169 else
170 vecHeadLower = j1->getA().transpose() * V3Z;
171 nLower++;
172 }
173 orderTensorHeadUpper +=outProduct(vecHeadUpper, vecHeadUpper);
174 orderTensorHeadLower +=outProduct(vecHeadLower, vecHeadLower);
175 }
176 for (j2 = seleMan2_.beginSelected(i1); j2 != NULL; j2 = seleMan2_.nextSelected(i1)) {
177 // The lab frame vector corresponding to the body-fixed
178 // z-axis is simply the second column of A.transpose()
179 // or, identically, the second row of A itself.
180
181 Vector3d vecTail = j2->getA().getRow(2);
182 orderTensorTail +=outProduct(vecTail, vecTail);
183 nTail++;
184 }
185
186 orderTensorHeadUpper /= (RealType) nUpper;
187 orderTensorHeadLower /= (RealType) nLower;
188 orderTensorHeadUpper -= (RealType)(1.0/3.0) * Mat3x3d::identity();
189 orderTensorHeadLower -= (RealType)(1.0/3.0) * Mat3x3d::identity();
190
191 orderTensorTail /= (RealType) nTail;
192 orderTensorTail -= (RealType)(1.0/3.0) * Mat3x3d::identity();
193
194 Vector3d eigenvaluesHeadUpper, eigenvaluesHeadLower, eigenvaluesTail;
195 Mat3x3d eigenvectorsHeadUpper, eigenvectorsHeadLower, eigenvectorsTail;
196 Mat3x3d::diagonalize(orderTensorHeadUpper, eigenvaluesHeadUpper, eigenvectorsHeadUpper);
197 Mat3x3d::diagonalize(orderTensorHeadLower, eigenvaluesHeadLower, eigenvectorsHeadLower);
198 Mat3x3d::diagonalize(orderTensorTail, eigenvaluesTail, eigenvectorsTail);
199
200 int whichUpper, whichLower, whichTail;
201 RealType maxEvalUpper = 0.0;
202 RealType maxEvalLower = 0.0;
203 RealType maxEvalTail = 0.0;
204 for(int k = 0; k< 3; k++){
205 if(fabs(eigenvaluesHeadUpper[k]) > maxEvalUpper){
206 whichUpper = k;
207 maxEvalUpper = fabs(eigenvaluesHeadUpper[k]);
208 }
209 }
210 RealType p2HeadUpper = 1.5 * maxEvalUpper;
211 for(int k = 0; k< 3; k++){
212 if(fabs(eigenvaluesHeadLower[k]) > maxEvalLower){
213 whichLower = k;
214 maxEvalLower = fabs(eigenvaluesHeadLower[k]);
215 }
216 }
217 RealType p2HeadLower = 1.5 * maxEvalLower;
218 for(int k = 0; k< 3; k++){
219 if(fabs(eigenvaluesTail[k]) > maxEvalTail){
220 whichTail = k;
221 maxEvalTail = fabs(eigenvaluesTail[k]);
222 }
223 }
224 RealType p2Tail = 1.5 * maxEvalTail;
225
226 //the eigen vector is already normalized in SquareMatrix3::diagonalize
227 Vector3d directorHeadUpper = eigenvectorsHeadUpper.getColumn(whichUpper);
228 if (directorHeadUpper[0] < 0) {
229 directorHeadUpper.negate();
230 }
231 Vector3d directorHeadLower = eigenvectorsHeadLower.getColumn(whichLower);
232 if (directorHeadLower[0] < 0) {
233 directorHeadLower.negate();
234 }
235 Vector3d directorTail = eigenvectorsTail.getColumn(whichTail);
236 if (directorTail[0] < 0) {
237 directorTail.negate();
238 }
239
240 OrderParam paramHeadUpper, paramHeadLower, paramTail;
241 paramHeadUpper.p2 = p2HeadUpper;
242 paramHeadUpper.director = directorHeadUpper;
243 paramHeadLower.p2 = p2HeadLower;
244 paramHeadLower.director = directorHeadLower;
245 paramTail.p2 = p2Tail;
246 paramTail.director = directorTail;
247
248 orderParamsHeadUpper_.push_back(paramHeadUpper);
249 orderParamsHeadLower_.push_back(paramHeadLower);
250 orderParamsTail_.push_back(paramTail);
251
252 }
253
254 OrderParam sumOPHeadUpper, errsumOPHeadUpper;
255 OrderParam sumOPHeadLower, errsumOPHeadLower;
256 OrderParam sumOPTail, errsumOPTail;
257
258 sumOPHeadUpper.p2 = 0.0;
259 errsumOPHeadUpper.p2 = 0.0;
260 sumOPHeadLower.p2 = 0.0;
261 errsumOPHeadLower.p2 = 0.0;
262 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
263 sumOPHeadUpper.p2 += orderParamsHeadUpper_[i].p2;
264 sumOPHeadUpper.director[0] += orderParamsHeadUpper_[i].director[0];
265 sumOPHeadUpper.director[1] += orderParamsHeadUpper_[i].director[1];
266 sumOPHeadUpper.director[2] += orderParamsHeadUpper_[i].director[2];
267 }
268
269 avgOPHeadUpper.p2 = sumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size();
270 avgOPHeadUpper.director[0] = sumOPHeadUpper.director[0] / (RealType)orderParamsHeadUpper_.size();
271 avgOPHeadUpper.director[1] = sumOPHeadUpper.director[1] / (RealType)orderParamsHeadUpper_.size();
272 avgOPHeadUpper.director[2] = sumOPHeadUpper.director[2] / (RealType)orderParamsHeadUpper_.size();
273 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
274 errsumOPHeadUpper.p2 += pow((orderParamsHeadUpper_[i].p2 - avgOPHeadUpper.p2), 2);
275 }
276 errOPHeadUpper.p2 = sqrt(errsumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size());
277 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
278 sumOPHeadLower.p2 += orderParamsHeadLower_[i].p2;
279 sumOPHeadLower.director[0] += orderParamsHeadLower_[i].director[0];
280 sumOPHeadLower.director[1] += orderParamsHeadLower_[i].director[1];
281 sumOPHeadLower.director[2] += orderParamsHeadLower_[i].director[2];
282 }
283
284 avgOPHeadLower.p2 = sumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size();
285 avgOPHeadLower.director[0] = sumOPHeadLower.director[0] / (RealType)orderParamsHeadLower_.size();
286 avgOPHeadLower.director[1] = sumOPHeadLower.director[1] / (RealType)orderParamsHeadLower_.size();
287 avgOPHeadLower.director[2] = sumOPHeadLower.director[2] / (RealType)orderParamsHeadLower_.size();
288 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
289 errsumOPHeadLower.p2 += pow((orderParamsHeadLower_[i].p2 - avgOPHeadLower.p2), 2);
290 }
291 errOPHeadLower.p2 = sqrt(errsumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size());
292
293 sumOPTail.p2 = 0.0;
294 errsumOPTail.p2 = 0.0;
295 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
296 sumOPTail.p2 += orderParamsTail_[i].p2;
297 sumOPTail.director[0] += orderParamsTail_[i].director[0];
298 sumOPTail.director[1] += orderParamsTail_[i].director[1];
299 sumOPTail.director[2] += orderParamsTail_[i].director[2];
300 }
301
302 avgOPTail.p2 = sumOPTail.p2 / (RealType)orderParamsTail_.size();
303 avgOPTail.director[0] = sumOPTail.director[0] / (RealType)orderParamsTail_.size();
304 avgOPTail.director[1] = sumOPTail.director[1] / (RealType)orderParamsTail_.size();
305 avgOPTail.director[2] = sumOPTail.director[2] / (RealType)orderParamsTail_.size();
306 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
307 errsumOPTail.p2 += pow((orderParamsTail_[i].p2 - avgOPTail.p2), 2);
308 }
309 errOPTail.p2 = sqrt(errsumOPTail.p2 / (RealType)orderParamsTail_.size());
310
311 writeP2();
312
313 }
314
315 void RippleOP::writeP2() {
316
317 std::ofstream os(getOutputFileName().c_str());
318 os<< "#selection1: (" << selectionScript1_ << ")\n";
319 os << "#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
320
321 os << avgOPHeadUpper.p2 << "\t"
322 << errOPHeadUpper.p2 << "\t"
323 << avgOPHeadUpper.director[0] << "\t"
324 << avgOPHeadUpper.director[1] << "\t"
325 << avgOPHeadUpper.director[2] << "\n";
326
327 os << avgOPHeadLower.p2 << "\t"
328 << errOPHeadLower.p2 << "\t"
329 << avgOPHeadLower.director[0] << "\t"
330 << avgOPHeadLower.director[1] << "\t"
331 << avgOPHeadLower.director[2] << "\n";
332
333 os << "selection2: (" << selectionScript2_ << ")\n";
334 os << "#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
335
336 os << avgOPTail.p2 << "\t"
337 << errOPTail.p2 << "\t"
338 << avgOPTail.director[0] << "\t"
339 << avgOPTail.director[1] << "\t"
340 << avgOPTail.director[2] << "\n";
341 }
342
343 }
344

Properties

Name Value
svn:executable *
svn:keywords Author Id Revision Date