ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/BondOrderParameter.cpp
Revision: 1785
Committed: Wed Aug 22 18:43:27 2012 UTC (12 years, 8 months ago) by jmichalk
File size: 13891 byte(s)
Log Message:
Trunk: The changes in this commit are confined to applications/staticProps and for the most part deal with a misspelling of initialize.

The one other change took place in StaticProps.cpp and deals with the default treatment of sele2. It had previously been set to 'select all' which seems to go against what would be desired by not specifying it with regard to proper operations of many of the analysis programs ( g of r's especially)

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 * [4] , Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). *
41 * Created by J. Daniel Gezelter on 09/26/06.
42 * @author J. Daniel Gezelter
43 * @version $Id$
44 *
45 */
46
47 #include "applications/staticProps/BondOrderParameter.hpp"
48 #include "utils/simError.h"
49 #include "io/DumpReader.hpp"
50 #include "primitives/Molecule.hpp"
51 #include "utils/NumericConstant.hpp"
52 #include "math/Wigner3jm.hpp"
53
54 using namespace MATPACK;
55 namespace OpenMD {
56
57 BondOrderParameter::BondOrderParameter(SimInfo* info,
58 const std::string& filename,
59 const std::string& sele,
60 double rCut, int nbins) : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info), seleMan_(info){
61
62 setOutputName(getPrefix(filename) + ".bo");
63
64 evaluator_.loadScriptString(sele);
65 if (!evaluator_.isDynamic()) {
66 seleMan_.setSelectionSet(evaluator_.evaluate());
67 }
68
69 // Set up cutoff radius and order of the Legendre Polynomial:
70
71 rCut_ = rCut;
72 nBins_ = nbins;
73 Qcount_.resize(lMax_+1);
74 Wcount_.resize(lMax_+1);
75
76 // Q can take values from 0 to 1
77
78 MinQ_ = 0.0;
79 MaxQ_ = 1.1;
80 deltaQ_ = (MaxQ_ - MinQ_) / nbins;
81
82 // W_6 for icosahedral clusters is 11 / sqrt(4199) = 0.169754, so we'll
83 // use values for MinW_ and MaxW_ that are slightly larger than this:
84
85 MinW_ = -1.1;
86 MaxW_ = 1.1;
87 deltaW_ = (MaxW_ - MinW_) / nbins;
88
89 // Make arrays for Wigner3jm
90 RealType* THRCOF = new RealType[2*lMax_+1];
91 // Variables for Wigner routine
92 RealType lPass, m1Pass, m2m, m2M;
93 int error, mSize;
94 mSize = 2*lMax_+1;
95
96 for (int l = 0; l <= lMax_; l++) {
97 lPass = (RealType)l;
98 for (int m1 = -l; m1 <= l; m1++) {
99 m1Pass = (RealType)m1;
100
101 std::pair<int,int> lm = std::make_pair(l, m1);
102
103 // Zero work array
104 for (int ii = 0; ii < 2*l + 1; ii++){
105 THRCOF[ii] = 0.0;
106 }
107
108 // Get Wigner coefficients
109 Wigner3jm(lPass, lPass, lPass,
110 m1Pass, m2m, m2M,
111 THRCOF, mSize, error);
112
113 m2Min[lm] = (int)floor(m2m);
114 m2Max[lm] = (int)floor(m2M);
115
116 for (int mmm = 0; mmm <= (int)(m2M - m2m); mmm++) {
117 w3j[lm].push_back(THRCOF[mmm]);
118 }
119 }
120 }
121 delete [] THRCOF;
122 THRCOF = NULL;
123 }
124
125 BondOrderParameter::~BondOrderParameter() {
126 Q_histogram_.clear();
127 W_histogram_.clear();
128 for (int l = 0; l <= lMax_; l++) {
129 for (int m = -l; m <= l; m++) {
130 w3j[std::make_pair(l,m)].clear();
131 }
132 }
133 w3j.clear();
134 m2Min.clear();
135 m2Max.clear();
136 }
137
138 void BondOrderParameter::initializeHistogram() {
139 for (int bin = 0; bin < nBins_; bin++) {
140 for (int l = 0; l <= lMax_; l++) {
141 Q_histogram_[std::make_pair(bin,l)] = 0;
142 W_histogram_[std::make_pair(bin,l)] = 0;
143 }
144 }
145 }
146
147 void BondOrderParameter::process() {
148 Molecule* mol;
149 Atom* atom;
150 RigidBody* rb;
151 int myIndex;
152 SimInfo::MoleculeIterator mi;
153 Molecule::RigidBodyIterator rbIter;
154 Molecule::AtomIterator ai;
155 StuntDouble* sd;
156 Vector3d vec;
157 RealType costheta;
158 RealType phi;
159 RealType r;
160 std::map<std::pair<int,int>,ComplexType> q;
161 std::vector<RealType> q_l;
162 std::vector<RealType> q2;
163 std::vector<ComplexType> w;
164 std::vector<ComplexType> w_hat;
165 std::map<std::pair<int,int>,ComplexType> QBar;
166 std::vector<RealType> Q2;
167 std::vector<RealType> Q;
168 std::vector<ComplexType> W;
169 std::vector<ComplexType> W_hat;
170 int nBonds, Nbonds;
171 SphericalHarmonic sphericalHarmonic;
172 int i;
173
174 DumpReader reader(info_, dumpFilename_);
175 int nFrames = reader.getNFrames();
176 frameCounter_ = 0;
177
178 q_l.resize(lMax_+1);
179 q2.resize(lMax_+1);
180 w.resize(lMax_+1);
181 w_hat.resize(lMax_+1);
182
183 Q2.resize(lMax_+1);
184 Q.resize(lMax_+1);
185 W.resize(lMax_+1);
186 W_hat.resize(lMax_+1);
187 Nbonds = 0;
188
189 for (int istep = 0; istep < nFrames; istep += step_) {
190 reader.readFrame(istep);
191 frameCounter_++;
192 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
193
194 if (evaluator_.isDynamic()) {
195 seleMan_.setSelectionSet(evaluator_.evaluate());
196 }
197
198 // update the positions of atoms which belong to the rigidbodies
199
200 for (mol = info_->beginMolecule(mi); mol != NULL;
201 mol = info_->nextMolecule(mi)) {
202 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
203 rb = mol->nextRigidBody(rbIter)) {
204 rb->updateAtoms();
205 }
206 }
207
208 // outer loop is over the selected StuntDoubles:
209
210 for (sd = seleMan_.beginSelected(i); sd != NULL;
211 sd = seleMan_.nextSelected(i)) {
212
213 myIndex = sd->getGlobalIndex();
214 nBonds = 0;
215
216 for (int l = 0; l <= lMax_; l++) {
217 for (int m = -l; m <= l; m++) {
218 q[std::make_pair(l,m)] = 0.0;
219 }
220 }
221
222 // inner loop is over all other atoms in the system:
223
224 for (mol = info_->beginMolecule(mi); mol != NULL;
225 mol = info_->nextMolecule(mi)) {
226 for (atom = mol->beginAtom(ai); atom != NULL;
227 atom = mol->nextAtom(ai)) {
228
229 if (atom->getGlobalIndex() != myIndex) {
230
231 vec = sd->getPos() - atom->getPos();
232
233 if (usePeriodicBoundaryConditions_)
234 currentSnapshot_->wrapVector(vec);
235
236 // Calculate "bonds" and build Q_lm(r) where
237 // Q_lm = Y_lm(theta(r),phi(r))
238 // The spherical harmonics are wrt any arbitrary coordinate
239 // system, we choose standard spherical coordinates
240
241 r = vec.length();
242
243 // Check to see if neighbor is in bond cutoff
244
245 if (r < rCut_) {
246 costheta = vec.z() / r;
247 phi = atan2(vec.y(), vec.x());
248
249 for (int l = 0; l <= lMax_; l++) {
250 sphericalHarmonic.setL(l);
251 for(int m = -l; m <= l; m++){
252 sphericalHarmonic.setM(m);
253 q[std::make_pair(l,m)] += sphericalHarmonic.getValueAt(costheta, phi);
254
255 }
256 }
257 nBonds++;
258 }
259 }
260 }
261 }
262
263
264 for (int l = 0; l <= lMax_; l++) {
265 q2[l] = 0.0;
266 for (int m = -l; m <= l; m++){
267 q[std::make_pair(l,m)] /= (RealType)nBonds;
268
269 q2[l] += norm(q[std::make_pair(l,m)]);
270 }
271 q_l[l] = sqrt(q2[l] * 4.0 * NumericConstant::PI / (RealType)(2*l + 1));
272 }
273
274 // Find Third Order Invariant W_l
275
276 for (int l = 0; l <= lMax_; l++) {
277 w[l] = 0.0;
278 for (int m1 = -l; m1 <= l; m1++) {
279 std::pair<int,int> lm = std::make_pair(l, m1);
280 for (int mmm = 0; mmm <= (m2Max[lm] - m2Min[lm]); mmm++) {
281 int m2 = m2Min[lm] + mmm;
282 int m3 = -m1-m2;
283 w[l] += w3j[lm][mmm] * q[lm] *
284 q[std::make_pair(l,m2)] * q[std::make_pair(l,m3)];
285 }
286 }
287
288 w_hat[l] = w[l] / pow(q2[l], RealType(1.5));
289 }
290
291 collectHistogram(q_l, w_hat);
292
293 Nbonds += nBonds;
294 for (int l = 0; l <= lMax_; l++) {
295 for (int m = -l; m <= l; m++) {
296 QBar[std::make_pair(l,m)] += (RealType)nBonds*q[std::make_pair(l,m)];
297 }
298 }
299 }
300 }
301
302 // Normalize Qbar2
303 for (int l = 0; l <= lMax_; l++) {
304 for (int m = -l; m <= l; m++){
305 QBar[std::make_pair(l,m)] /= Nbonds;
306 }
307 }
308
309 // Find second order invariant Q_l
310
311 for (int l = 0; l <= lMax_; l++) {
312 Q2[l] = 0.0;
313 for (int m = -l; m <= l; m++){
314 Q2[l] += norm(QBar[std::make_pair(l,m)]);
315 }
316 Q[l] = sqrt(Q2[l] * 4.0 * NumericConstant::PI / (RealType)(2*l + 1));
317 }
318
319 // Find Third Order Invariant W_l
320
321 for (int l = 0; l <= lMax_; l++) {
322 W[l] = 0.0;
323 for (int m1 = -l; m1 <= l; m1++) {
324 std::pair<int,int> lm = std::make_pair(l, m1);
325 for (int mmm = 0; mmm <= (m2Max[lm] - m2Min[lm]); mmm++) {
326 int m2 = m2Min[lm] + mmm;
327 int m3 = -m1-m2;
328 W[l] += w3j[lm][mmm] * QBar[lm] *
329 QBar[std::make_pair(l,m2)] * QBar[std::make_pair(l,m3)];
330 }
331 }
332
333 W_hat[l] = W[l] / pow(Q2[l], RealType(1.5));
334 }
335
336 writeOrderParameter(Q, W_hat);
337 }
338
339 void BondOrderParameter::collectHistogram(std::vector<RealType> q,
340 std::vector<ComplexType> what) {
341
342 for (int l = 0; l <= lMax_; l++) {
343 if (q[l] >= MinQ_ && q[l] < MaxQ_) {
344 int qbin = (q[l] - MinQ_) / deltaQ_;
345 Q_histogram_[std::make_pair(qbin,l)] += 1;
346 Qcount_[l]++;
347 } else {
348 sprintf( painCave.errMsg,
349 "q_l value outside reasonable range\n");
350 painCave.severity = OPENMD_ERROR;
351 painCave.isFatal = 1;
352 simError();
353 }
354 }
355
356 for (int l = 0; l <= lMax_; l++) {
357 if (real(what[l]) >= MinW_ && real(what[l]) < MaxW_) {
358 int wbin = (real(what[l]) - MinW_) / deltaW_;
359 W_histogram_[std::make_pair(wbin,l)] += 1;
360 Wcount_[l]++;
361 } else {
362 sprintf( painCave.errMsg,
363 "Re[w_hat] value (%lf) outside reasonable range\n", real(what[l]));
364 painCave.severity = OPENMD_ERROR;
365 painCave.isFatal = 1;
366 simError();
367 }
368 }
369
370 }
371
372
373 void BondOrderParameter::writeOrderParameter(std::vector<RealType> Q,
374 std::vector<ComplexType> What) {
375
376 std::ofstream osq((getOutputFileName() + "q").c_str());
377
378 if (osq.is_open()) {
379
380 osq << "# Bond Order Parameters\n";
381 osq << "# selection: (" << selectionScript_ << ")\n";
382 osq << "# \n";
383 for (int l = 0; l <= lMax_; l++) {
384 osq << "# <Q_" << l << ">: " << Q[l] << "\n";
385 }
386 // Normalize by number of frames and write it out:
387 for (int i = 0; i < nBins_; ++i) {
388 RealType Qval = MinQ_ + (i + 0.5) * deltaQ_;
389 osq << Qval;
390 for (int l = 0; l <= lMax_; l++) {
391
392 osq << "\t" << (RealType)Q_histogram_[std::make_pair(i,l)]/(RealType)Qcount_[l]/deltaQ_;
393 }
394 osq << "\n";
395 }
396
397 osq.close();
398
399 } else {
400 sprintf(painCave.errMsg, "BondOrderParameter: unable to open %s\n",
401 (getOutputFileName() + "q").c_str());
402 painCave.isFatal = 1;
403 simError();
404 }
405
406 std::ofstream osw((getOutputFileName() + "w").c_str());
407
408 if (osw.is_open()) {
409 osw << "# Bond Order Parameters\n";
410 osw << "# selection: (" << selectionScript_ << ")\n";
411 osw << "# \n";
412 for (int l = 0; l <= lMax_; l++) {
413 osw << "# <W_" << l << ">: " << real(What[l]) << "\t" << imag(What[l]) << "\n";
414 }
415 // Normalize by number of frames and write it out:
416 for (int i = 0; i < nBins_; ++i) {
417 RealType Wval = MinW_ + (i + 0.5) * deltaW_;
418 osw << Wval;
419 for (int l = 0; l <= lMax_; l++) {
420
421 osw << "\t" << (RealType)W_histogram_[std::make_pair(i,l)]/(RealType)Wcount_[l]/deltaW_;
422 }
423 osw << "\n";
424 }
425
426 osw.close();
427 } else {
428 sprintf(painCave.errMsg, "BondOrderParameter: unable to open %s\n",
429 (getOutputFileName() + "w").c_str());
430 painCave.isFatal = 1;
431 simError();
432 }
433
434 }
435 }

Properties

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