ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/TetrahedralityParamZ.cpp
Revision: 1843
Committed: Tue Jan 29 20:58:08 2013 UTC (12 years, 3 months ago) by gezelter
File size: 8480 byte(s)
Log Message:
Simplified the Tetrahedrality [Qk(z)] analysis code.

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 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
42 */
43
44 #include "applications/staticProps/TetrahedralityParamZ.hpp"
45 #include "utils/simError.h"
46 #include "io/DumpReader.hpp"
47 #include "primitives/Molecule.hpp"
48 #include "utils/NumericConstant.hpp"
49 #include <vector>
50 #include <algorithm>
51 #include <fstream>
52
53 using namespace std;
54 namespace OpenMD {
55 TetrahedralityParamZ::TetrahedralityParamZ(SimInfo* info,
56 const std::string& filename,
57 const std::string& sele,
58 double rCut, int nzbins)
59 : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info),
60 seleMan_(info), nZBins_(nzbins) {
61
62 evaluator_.loadScriptString(sele);
63 if (!evaluator_.isDynamic()) {
64 seleMan_.setSelectionSet(evaluator_.evaluate());
65 }
66
67 // Set up cutoff radius:
68 rCut_ = rCut;
69
70 // fixed number of bins
71 sliceQ_.resize(nZBins_);
72 sliceCount_.resize(nZBins_);
73 std::fill(sliceQ_.begin(), sliceQ_.end(), 0.0);
74 std::fill(sliceCount_.begin(), sliceCount_.end(), 0);
75
76 setOutputName(getPrefix(filename) + ".Qz");
77 }
78
79 TetrahedralityParamZ::~TetrahedralityParamZ() {
80 sliceQ_.clear();
81 sliceCount_.clear();
82 zBox_.clear();
83 }
84
85 void TetrahedralityParamZ::process() {
86 Molecule* mol;
87 StuntDouble* sd;
88 StuntDouble* sd2;
89 StuntDouble* sdi;
90 StuntDouble* sdj;
91 RigidBody* rb;
92 int myIndex;
93 SimInfo::MoleculeIterator mi;
94 Molecule::IntegrableObjectIterator ioi;
95 Molecule::RigidBodyIterator rbIter;
96 Vector3d vec;
97 Vector3d ri, rj, rk, rik, rkj;
98 RealType r;
99 RealType cospsi;
100 RealType Qk;
101 std::vector<std::pair<RealType,StuntDouble*> > myNeighbors;
102 int isd;
103
104 DumpReader reader(info_, dumpFilename_);
105 int nFrames = reader.getNFrames();
106
107 for (int istep = 0; istep < nFrames; istep += step_) {
108 reader.readFrame(istep);
109 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
110
111 Mat3x3d hmat = currentSnapshot_->getHmat();
112 zBox_.push_back(hmat(2,2));
113
114 RealType halfBoxZ_ = hmat(2,2) / 2.0;
115
116 if (evaluator_.isDynamic()) {
117 seleMan_.setSelectionSet(evaluator_.evaluate());
118 }
119
120 // update the positions of atoms which belong to the rigidbodies
121 for (mol = info_->beginMolecule(mi); mol != NULL;
122 mol = info_->nextMolecule(mi)) {
123 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
124 rb = mol->nextRigidBody(rbIter)) {
125 rb->updateAtoms();
126 }
127 }
128
129 // outer loop is over the selected StuntDoubles:
130 for (sd = seleMan_.beginSelected(isd); sd != NULL;
131 sd = seleMan_.nextSelected(isd)) {
132
133 myIndex = sd->getGlobalIndex();
134
135 Qk = 1.0;
136 myNeighbors.clear();
137
138 // inner loop is over all StuntDoubles in the system:
139
140 for (mol = info_->beginMolecule(mi); mol != NULL;
141 mol = info_->nextMolecule(mi)) {
142
143 for (sd2 = mol->beginIntegrableObject(ioi); sd2 != NULL;
144 sd2 = mol->nextIntegrableObject(ioi)) {
145
146 if (sd2->getGlobalIndex() != myIndex) {
147
148 vec = sd->getPos() - sd2->getPos();
149
150 if (usePeriodicBoundaryConditions_)
151 currentSnapshot_->wrapVector(vec);
152
153 r = vec.length();
154
155 // Check to see if neighbor is in bond cutoff
156
157 if (r < rCut_) {
158 myNeighbors.push_back(std::make_pair(r,sd2));
159 }
160 }
161 }
162 }
163
164 // Sort the vector using predicate and std::sort
165 std::sort(myNeighbors.begin(), myNeighbors.end());
166
167 // Use only the 4 closest neighbors to do the rest of the work:
168
169 int nbors = myNeighbors.size()> 4 ? 4 : myNeighbors.size();
170 int nang = int (0.5 * (nbors * (nbors - 1)));
171
172 rk = sd->getPos();
173
174 for (int i = 0; i < nbors-1; i++) {
175
176 sdi = myNeighbors[i].second;
177 ri = sdi->getPos();
178 rik = rk - ri;
179 if (usePeriodicBoundaryConditions_)
180 currentSnapshot_->wrapVector(rik);
181
182 rik.normalize();
183
184 for (int j = i+1; j < nbors; j++) {
185
186 sdj = myNeighbors[j].second;
187 rj = sdj->getPos();
188 rkj = rk - rj;
189 if (usePeriodicBoundaryConditions_)
190 currentSnapshot_->wrapVector(rkj);
191 rkj.normalize();
192
193 cospsi = dot(rik,rkj);
194
195 // Calculates scaled Qk for each molecule using calculated
196 // angles from 4 or fewer nearest neighbors.
197 Qk -= (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
198 }
199 }
200
201 if (nang > 0) {
202 if (usePeriodicBoundaryConditions_)
203 currentSnapshot_->wrapVector(rk);
204
205 int binNo = int(nZBins_ * (halfBoxZ_ + rk.z()) / hmat(2,2));
206 sliceQ_[binNo] += Qk;
207 sliceCount_[binNo] += 1;
208 }
209 }
210 }
211 writeQz();
212 }
213
214 void TetrahedralityParamZ::writeQz() {
215
216 // compute average box length:
217
218 RealType zSum = 0.0;
219 for (std::vector<RealType>::iterator j = zBox_.begin();
220 j != zBox_.end(); ++j) {
221 zSum += *j;
222 }
223 RealType zAve = zSum / zBox_.size();
224
225 std::ofstream qZstream(outputFilename_.c_str());
226 if (qZstream.is_open()) {
227 qZstream << "#Tetrahedrality Parameters (z)\n";
228 qZstream << "#nFrames:\t" << zBox_.size() << "\n";
229 qZstream << "#selection: (" << selectionScript_ << ")\n";
230 qZstream << "#z\tQk\n";
231 for (unsigned int i = 0; i < sliceQ_.size(); ++i) {
232 RealType z = zAve * (i+0.5) / sliceQ_.size();
233 qZstream << z << "\t" << sliceQ_[i] / sliceCount_[i] << "\n";
234 }
235
236 } else {
237 sprintf(painCave.errMsg, "TetrahedralityParamZ: unable to open %s\n",
238 outputFilename_.c_str());
239 painCave.isFatal = 1;
240 simError();
241 }
242 qZstream.close();
243 }
244 }
245
246
247

Properties

Name Value
svn:executable *