ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/SpatialStatistics.cpp
Revision: 1876
Committed: Fri May 17 17:10:11 2013 UTC (11 years, 11 months ago) by gezelter
Original Path: branches/development/src/applications/staticProps/SpatialStatistics.cpp
File size: 12699 byte(s)
Log Message:
Compilation and portability fixes

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, 234107 (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/SpatialStatistics.hpp"
44 #include "io/DumpReader.hpp"
45 #include "primitives/Molecule.hpp"
46 #ifdef _MSC_VER
47 #define isnan(x) _isnan((x))
48 #define isinf(x) (!_finite(x) && !_isnan(x))
49 #endif
50
51 namespace OpenMD {
52
53 SpatialStatistics::SpatialStatistics(SimInfo* info, const string& filename,
54 const string& sele, int nbins)
55 : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info),
56 seleMan_(info), nBins_(nbins){
57
58 evaluator_.loadScriptString(sele);
59 if (!evaluator_.isDynamic()) {
60 seleMan_.setSelectionSet(evaluator_.evaluate());
61 }
62
63 // Pre-load an OutputData for the count of objects:
64 counts_ = new OutputData;
65 counts_->units = "objects";
66 counts_->title = "Objects";
67 counts_->dataType = odtReal;
68 counts_->dataHandling = odhTotal;
69 counts_->accumulator.reserve(nBins_);
70 for (int i = 0; i < nBins_; i++)
71 counts_->accumulator.push_back( new Accumulator() );
72
73 setOutputName(getPrefix(filename) + ".spst");
74 }
75
76 SpatialStatistics::~SpatialStatistics() {
77 vector<OutputData*>::iterator i;
78 OutputData* outputData;
79
80 for(outputData = beginOutputData(i); outputData;
81 outputData = nextOutputData(i)) {
82 delete outputData;
83 }
84 data_.clear();
85
86 delete counts_;
87 }
88
89
90 void SpatialStatistics::process() {
91
92 DumpReader reader(info_, dumpFilename_);
93 int nFrames = reader.getNFrames();
94 nProcessed_ = nFrames/step_;
95
96 for (int istep = 0; istep < nFrames; istep += step_) {
97 reader.readFrame(istep);
98 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
99 processFrame(istep);
100 }
101 writeOutput();
102 }
103
104
105 void SpatialStatistics::processFrame(int istep) {
106 Molecule* mol;
107 RigidBody* rb;
108 StuntDouble* sd;
109 SimInfo::MoleculeIterator mi;
110 Molecule::RigidBodyIterator rbIter;
111 int i;
112
113 for (mol = info_->beginMolecule(mi); mol != NULL;
114 mol = info_->nextMolecule(mi)) {
115
116 // change the positions of atoms which belong to the rigidbodies
117
118 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
119 rb = mol->nextRigidBody(rbIter)) {
120 rb->updateAtoms();
121 }
122 }
123
124 if (evaluator_.isDynamic()) {
125 seleMan_.setSelectionSet(evaluator_.evaluate());
126 }
127
128 // loop over the selected atoms:
129
130 for (sd = seleMan_.beginSelected(i); sd != NULL;
131 sd = seleMan_.nextSelected(i)) {
132
133 // figure out where that object is:
134
135 Vector3d pos = sd->getPos();
136
137 int bin = getBin(pos);
138
139 // forward the work of statistics on to the subclass:
140
141 processStuntDouble( sd, bin );
142
143 dynamic_cast<Accumulator *>(counts_->accumulator[bin])->add(1);
144 }
145 }
146
147
148 void SpatialStatistics::writeOutput() {
149
150 vector<OutputData*>::iterator i;
151 OutputData* outputData;
152
153 ofstream outStream(outputFilename_.c_str());
154 if (outStream.is_open()) {
155
156 //write title
157 outStream << "# SPATIAL STATISTICS\n";
158 outStream << "#";
159
160 for(outputData = beginOutputData(i); outputData;
161 outputData = nextOutputData(i)) {
162 outStream << "\t" << outputData->title <<
163 "(" << outputData->units << ")";
164 // add some extra tabs for column alignment
165 if (outputData->dataType == odtVector3) outStream << "\t\t";
166 }
167
168 outStream << std::endl;
169
170 outStream.precision(8);
171
172 for (int j = 0; j < nBins_; j++) {
173
174 int counts = counts_->accumulator[j]->count();
175
176 if (counts > 0) {
177 for(outputData = beginOutputData(i); outputData;
178 outputData = nextOutputData(i)) {
179
180 int n = outputData->accumulator[j]->count();
181 if (n != 0) {
182 writeData( outStream, outputData, j );
183 }
184 }
185 outStream << std::endl;
186 }
187 }
188
189 outStream << "#######################################################\n";
190 outStream << "# Standard Deviations in those quantities follow:\n";
191 outStream << "#######################################################\n";
192
193 for (int j = 0; j < nBins_; j++) {
194 int counts = counts_->accumulator[j]->count();
195 if (counts > 0) {
196
197 outStream << "#";
198 for(outputData = beginOutputData(i); outputData;
199 outputData = nextOutputData(i)) {
200
201 int n = outputData->accumulator[j]->count();
202 if (n != 0) {
203 writeStdDev( outStream, outputData, j );
204 }
205 }
206 outStream << std::endl;
207 }
208 }
209
210 outStream.flush();
211 outStream.close();
212
213 } else {
214 sprintf(painCave.errMsg, "SpatialStatistics: unable to open %s\n",
215 outputFilename_.c_str());
216 painCave.isFatal = 1;
217 simError();
218 }
219 }
220
221
222 void SpatialStatistics::writeData(ostream& os, OutputData* dat,
223 unsigned int bin) {
224 assert(int(bin) < nBins_);
225 int n = dat->accumulator[bin]->count();
226 if (n == 0) return;
227
228 if( dat->dataType == odtReal ) {
229 RealType r;
230 dynamic_cast<Accumulator*>(dat->accumulator[bin])->getAverage(r);
231 if (isinf(r) || isnan(r) ) {
232 sprintf( painCave.errMsg,
233 "SpatialStatistics detected a numerical error writing:\n"
234 "\t%s for bin %u",
235 dat->title.c_str(), bin);
236 painCave.isFatal = 1;
237 simError();
238 }
239 if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
240 os << "\t" << r;
241
242 } else if ( dat->dataType == odtVector3 ) {
243 Vector3d v;
244 dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getAverage(v);
245 if (isinf(v[0]) || isnan(v[0]) ||
246 isinf(v[1]) || isnan(v[1]) ||
247 isinf(v[2]) || isnan(v[2]) ) {
248 sprintf( painCave.errMsg,
249 "SpatialStatistics detected a numerical error writing:\n"
250 "\t%s for bin %u",
251 dat->title.c_str(), bin);
252 painCave.isFatal = 1;
253 simError();
254 }
255 if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
256 os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
257 }
258 }
259
260 void SpatialStatistics::writeStdDev(ostream& os, OutputData* dat,
261 unsigned int bin) {
262 assert(int(bin) < nBins_);
263 int n = dat->accumulator[bin]->count();
264 if (n == 0) return;
265
266 if( dat->dataType == odtReal ) {
267 RealType r;
268 dynamic_cast<Accumulator*>(dat->accumulator[bin])->getStdDev(r);
269 if (isinf(r) || isnan(r) ) {
270 sprintf( painCave.errMsg,
271 "SpatialStatistics detected a numerical error writing:\n"
272 "\tstandard deviation of %s for bin %u",
273 dat->title.c_str(), bin);
274 painCave.isFatal = 1;
275 simError();
276 }
277 if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
278 os << "\t" << r;
279
280 } else if ( dat->dataType == odtVector3 ) {
281 Vector3d v;
282 dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getStdDev(v);
283 if (isinf(v[0]) || isnan(v[0]) ||
284 isinf(v[1]) || isnan(v[1]) ||
285 isinf(v[2]) || isnan(v[2]) ) {
286 sprintf( painCave.errMsg,
287 "SpatialStatistics detected a numerical error writing:\n"
288 "\tstandard deviation of %s for bin %u",
289 dat->title.c_str(), bin);
290 painCave.isFatal = 1;
291 simError();
292 }
293 if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
294 os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
295 }
296 }
297
298
299 OutputData* SpatialStatistics::beginOutputData(vector<OutputData*>::iterator& i) {
300 i = data_.begin();
301 return i != data_.end()? *i : NULL;
302 }
303
304 OutputData* SpatialStatistics::nextOutputData(vector<OutputData*>::iterator& i){
305 ++i;
306 return i != data_.end()? *i: NULL;
307 }
308
309
310 SlabStatistics::SlabStatistics(SimInfo* info, const string& filename,
311 const string& sele, int nbins) :
312 SpatialStatistics(info, filename, sele, nbins) {
313
314 z_ = new OutputData;
315 z_->units = "Angstroms";
316 z_->title = "Z";
317 z_->dataType = odtReal;
318 z_->dataHandling = odhAverage;
319 z_->accumulator.reserve(nbins);
320 for (int i = 0; i < nbins; i++)
321 z_->accumulator.push_back( new Accumulator() );
322 data_.push_back(z_);
323 }
324
325 SlabStatistics::~SlabStatistics() {
326 delete z_;
327 }
328
329
330 void SlabStatistics::processFrame(int istep) {
331 RealType z;
332 hmat_ = currentSnapshot_->getHmat();
333 for (int i = 0; i < nBins_; i++) {
334 z = (((RealType)i + 0.5) / (RealType)nBins_) * hmat_(2,2);
335 dynamic_cast<Accumulator*>(z_->accumulator[i])->add(z);
336 }
337 volume_ = currentSnapshot_->getVolume();
338
339 SpatialStatistics::processFrame(istep);
340 }
341
342 int SlabStatistics::getBin(Vector3d pos) {
343 currentSnapshot_->wrapVector(pos);
344 // which bin is this stuntdouble in?
345 // wrapped positions are in the range [-0.5*hmat(2,2), +0.5*hmat(2,2)]
346 // Shift molecules by half a box to have bins start at 0
347 // The modulo operator is used to wrap the case when we are
348 // beyond the end of the bins back to the beginning.
349 return int(nBins_ * (pos.z() / hmat_(2,2) + 0.5)) % nBins_;
350 }
351
352 ShellStatistics::ShellStatistics(SimInfo* info, const string& filename,
353 const string& sele, int nbins) :
354 SpatialStatistics(info, filename, sele, nbins), coordinateOrigin_(V3Zero) {
355
356 binWidth_ = 1.0;
357
358 r_ = new OutputData;
359 r_->units = "Angstroms";
360 r_->title = "R";
361 r_->dataType = odtReal;
362 r_->dataHandling = odhAverage;
363 r_->accumulator.reserve(nbins);
364 for (int i = 0; i < nbins; i++)
365 r_->accumulator.push_back( new Accumulator() );
366 data_.push_back(r_);
367
368 for (int i = 0; i < nbins; i++) {
369 RealType r = (((RealType)i + 0.5) * binWidth_);
370 dynamic_cast<Accumulator*>(r_->accumulator[i])->add(r);
371 }
372 }
373
374 ShellStatistics::~ShellStatistics() {
375 delete r_;
376 }
377
378 int ShellStatistics::getBin(Vector3d pos) {
379 Vector3d rPos = pos - coordinateOrigin_;
380 return int(rPos.length() / binWidth_);
381 }
382 }
383

Properties

Name Value
svn:eol-style native