ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/staticProps/BOPofR.cpp
Revision: 1665
Committed: Tue Nov 22 20:38:56 2011 UTC (13 years, 5 months ago) by gezelter
File size: 11575 byte(s)
Log Message:
updated copyright notices

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/BOPofR.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 BOPofR::BOPofR(SimInfo* info, const std::string& filename, const std::string& sele, double rCut,
58 int nbins, RealType len) : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info), seleMan_(info){
59
60 setOutputName(getPrefix(filename) + ".bo");
61
62 evaluator_.loadScriptString(sele);
63 if (!evaluator_.isDynamic()) {
64 seleMan_.setSelectionSet(evaluator_.evaluate());
65 }
66
67 // Set up cutoff radius and order of the Legendre Polynomial:
68
69 rCut_ = rCut;
70 nBins_ = nbins;
71 len_ = len;
72
73 deltaR_ = len_/nBins_;
74 RCount_.resize(nBins_);
75 WofR_.resize(nBins_);
76 QofR_.resize(nBins_);
77
78 for (int i = 0; i < nBins_; i++){
79 RCount_[i] = 0;
80 WofR_[i] = 0;
81 QofR_[i] = 0;
82 }
83
84 // Make arrays for Wigner3jm
85 RealType* THRCOF = new RealType[2*lMax_+1];
86 // Variables for Wigner routine
87 RealType lPass, m1Pass, m2m, m2M;
88 int error, mSize;
89 mSize = 2*lMax_+1;
90
91 for (int l = 0; l <= lMax_; l++) {
92 lPass = (RealType)l;
93 for (int m1 = -l; m1 <= l; m1++) {
94 m1Pass = (RealType)m1;
95
96 std::pair<int,int> lm = std::make_pair(l, m1);
97
98 // Zero work array
99 for (int ii = 0; ii < 2*l + 1; ii++){
100 THRCOF[ii] = 0.0;
101 }
102
103 // Get Wigner coefficients
104 Wigner3jm(lPass, lPass, lPass,
105 m1Pass, m2m, m2M,
106 THRCOF, mSize, error);
107
108 m2Min[lm] = (int)floor(m2m);
109 m2Max[lm] = (int)floor(m2M);
110
111 for (int mmm = 0; mmm <= (int)(m2M - m2m); mmm++) {
112 w3j[lm].push_back(THRCOF[mmm]);
113 }
114 }
115 }
116
117 delete [] THRCOF;
118 THRCOF = NULL;
119
120 }
121
122 BOPofR::~BOPofR() {
123 /*
124 std::cerr << "Freeing stuff" << std::endl;
125 for (int l = 0; l <= lMax_; l++) {
126 for (int m = -l; m <= l; m++) {
127 w3j[std::make_pair(l,m)].clear();
128 }
129 }
130 std::cerr << "w3j made free...." << std::endl;
131 for (int bin = 0; bin < nBins_; bin++) {
132 QofR_[bin].clear();
133 WofR_[bin].clear();
134 RCount_[bin].clear();
135 }
136 std::cout << "R arrays made free...." << std::endl;
137 w3j.clear();
138 m2Min.clear();
139 m2Max.clear();
140 RCount_.clear();
141 WofR_.clear();
142 QofR_.clear();
143 */
144 }
145
146
147 void BOPofR::initalizeHistogram() {
148 for (int i = 0; i < nBins_; i++){
149 RCount_[i] = 0;
150 WofR_[i] = 0;
151 QofR_[i] = 0;
152 }
153 }
154
155
156 void BOPofR::process() {
157 Molecule* mol;
158 Atom* atom;
159 RigidBody* rb;
160 int myIndex;
161 SimInfo::MoleculeIterator mi;
162 Molecule::RigidBodyIterator rbIter;
163 Molecule::AtomIterator ai;
164 StuntDouble* sd;
165 Vector3d vec;
166 RealType costheta;
167 RealType phi;
168 RealType r;
169 RealType dist;
170 Vector3d rCOM;
171 RealType distCOM;
172 Vector3d pos;
173 Vector3d CenterOfMass;
174 std::map<std::pair<int,int>,ComplexType> q;
175 std::vector<RealType> q_l;
176 std::vector<RealType> q2;
177 std::vector<ComplexType> w;
178 std::vector<ComplexType> w_hat;
179 std::map<std::pair<int,int>,ComplexType> QBar;
180 std::vector<RealType> Q2;
181 std::vector<RealType> Q;
182 std::vector<ComplexType> W;
183 std::vector<ComplexType> W_hat;
184 int nBonds, Nbonds;
185 SphericalHarmonic sphericalHarmonic;
186 int i, j;
187
188 DumpReader reader(info_, dumpFilename_);
189 int nFrames = reader.getNFrames();
190 frameCounter_ = 0;
191
192 q_l.resize(lMax_+1);
193 q2.resize(lMax_+1);
194 w.resize(lMax_+1);
195 w_hat.resize(lMax_+1);
196
197 Q2.resize(lMax_+1);
198 Q.resize(lMax_+1);
199 W.resize(lMax_+1);
200 W_hat.resize(lMax_+1);
201 Nbonds = 0;
202
203 for (int istep = 0; istep < nFrames; istep += step_) {
204 reader.readFrame(istep);
205 frameCounter_++;
206 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
207 CenterOfMass = info_->getCom();
208 if (evaluator_.isDynamic()) {
209 seleMan_.setSelectionSet(evaluator_.evaluate());
210 }
211
212 // update the positions of atoms which belong to the rigidbodies
213
214 for (mol = info_->beginMolecule(mi); mol != NULL;
215 mol = info_->nextMolecule(mi)) {
216 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
217 rb = mol->nextRigidBody(rbIter)) {
218 rb->updateAtoms();
219 }
220 }
221
222 // outer loop is over the selected StuntDoubles:
223
224 for (sd = seleMan_.beginSelected(i); sd != NULL;
225 sd = seleMan_.nextSelected(i)) {
226
227 myIndex = sd->getGlobalIndex();
228
229 nBonds = 0;
230
231 for (int l = 0; l <= lMax_; l++) {
232 for (int m = -l; m <= l; m++) {
233 q[std::make_pair(l,m)] = 0.0;
234 }
235 }
236 pos = sd->getPos();
237 rCOM = CenterOfMass - pos;
238 if (usePeriodicBoundaryConditions_)
239 currentSnapshot_->wrapVector(rCOM);
240 distCOM = rCOM.length();
241
242 // inner loop is over all other atoms in the system:
243
244 for (mol = info_->beginMolecule(mi); mol != NULL;
245 mol = info_->nextMolecule(mi)) {
246 for (atom = mol->beginAtom(ai); atom != NULL;
247 atom = mol->nextAtom(ai)) {
248
249 if (atom->getGlobalIndex() != myIndex) {
250 vec = pos - atom->getPos();
251
252 if (usePeriodicBoundaryConditions_)
253 currentSnapshot_->wrapVector(vec);
254
255 // Calculate "bonds" and build Q_lm(r) where
256 // Q_lm = Y_lm(theta(r),phi(r))
257 // The spherical harmonics are wrt any arbitrary coordinate
258 // system, we choose standard spherical coordinates
259
260 r = vec.length();
261
262 // Check to see if neighbor is in bond cutoff
263
264 if (r < rCut_) {
265 costheta = vec.z() / r;
266 phi = atan2(vec.y(), vec.x());
267
268 for (int l = 0; l <= lMax_; l++) {
269 sphericalHarmonic.setL(l);
270 for(int m = -l; m <= l; m++){
271 sphericalHarmonic.setM(m);
272 q[std::make_pair(l,m)] += sphericalHarmonic.getValueAt(costheta, phi);
273 }
274 }
275 nBonds++;
276 }
277 }
278 }
279 }
280
281
282 for (int l = 0; l <= lMax_; l++) {
283 q2[l] = 0.0;
284 for (int m = -l; m <= l; m++){
285 q[std::make_pair(l,m)] /= (RealType)nBonds;
286 q2[l] += norm(q[std::make_pair(l,m)]);
287 }
288 q_l[l] = sqrt(q2[l] * 4.0 * NumericConstant::PI / (RealType)(2*l + 1));
289 }
290
291 // Find Third Order Invariant W_l
292
293 for (int l = 0; l <= lMax_; l++) {
294 w[l] = 0.0;
295 for (int m1 = -l; m1 <= l; m1++) {
296 std::pair<int,int> lm = std::make_pair(l, m1);
297 for (int mmm = 0; mmm <= (m2Max[lm] - m2Min[lm]); mmm++) {
298 int m2 = m2Min[lm] + mmm;
299 int m3 = -m1-m2;
300 w[l] += w3j[lm][mmm] * q[lm] *
301 q[std::make_pair(l,m2)] * q[std::make_pair(l,m3)];
302 }
303 }
304
305 w_hat[l] = w[l] / pow(q2[l], 1.5);
306 }
307
308 collectHistogram(q_l, w_hat, distCOM);
309
310 // printf( "%s %18.10g %18.10g %18.10g %18.10g \n", sd->getType().c_str(),pos[0],pos[1],pos[2],real(w_hat[6]));
311
312 }
313 }
314
315 writeOrderParameter();
316 }
317
318 void BOPofR::collectHistogram(std::vector<RealType> q,
319 std::vector<ComplexType> what, RealType distCOM) {
320
321 if ( distCOM < len_){
322 // Figure out where this distance goes...
323 int whichBin = distCOM / deltaR_;
324 RCount_[whichBin]++;
325
326 if(real(what[6]) < -0.15){
327 WofR_[whichBin]++;
328 }
329 if(q[6] > 0.5){
330 QofR_[whichBin]++;
331 }
332 }
333
334 }
335
336 void BOPofR::writeOrderParameter() {
337
338 std::ofstream osq((getOutputFileName() + "qr").c_str());
339
340 if (osq.is_open()) {
341
342 // Normalize by number of frames and write it out:
343
344 for (int i = 0; i < nBins_; ++i) {
345 RealType Rval = (i + 0.5) * deltaR_;
346 osq << Rval;
347 if (RCount_[i] == 0){
348 osq << "\t" << 0;
349 osq << "\n";
350 }else{
351 osq << "\t" << (RealType)QofR_[i]/(RealType)RCount_[i];
352 osq << "\n";
353 }
354 }
355
356 osq.close();
357
358 } else {
359 sprintf(painCave.errMsg, "BOPofR: unable to open %s\n",
360 (getOutputFileName() + "q").c_str());
361 painCave.isFatal = 1;
362 simError();
363 }
364
365 std::ofstream osw((getOutputFileName() + "wr").c_str());
366
367 if (osw.is_open()) {
368 // Normalize by number of frames and write it out:
369 for (int i = 0; i < nBins_; ++i) {
370 RealType Rval = deltaR_ * (i + 0.5);
371 osw << Rval;
372 if (RCount_[i] == 0){
373 osw << "\t" << 0;
374 osw << "\n";
375 }else{
376 osw << "\t" << (RealType)WofR_[i]/(RealType)RCount_[i];
377 osw << "\n";
378 }
379 }
380
381 osw.close();
382 } else {
383 sprintf(painCave.errMsg, "BOPofR: unable to open %s\n",
384 (getOutputFileName() + "w").c_str());
385 painCave.isFatal = 1;
386 simError();
387
388 }
389
390 }
391 }

Properties

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