OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
Stats.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45#include "brains/Stats.hpp"
46
47#include <iomanip>
48#include <sstream>
49
50#include "brains/Thermo.hpp"
51#include "utils/MemoryUtils.hpp"
52
53namespace OpenMD {
54
55 Stats::Stats(SimInfo* info) : info_(info), isInit_(false) {
56 if (!isInit_) {
57 init();
58 isInit_ = true;
59 }
60 }
61
62 Stats::~Stats() {
63 for (auto& data : data_) {
64 if (!data.accumulatorArray2d.empty())
65 Utils::deletePointers(data.accumulatorArray2d);
66 else
67 delete data.accumulator;
68 }
69 }
70
71 void Stats::init() {
72 data_.resize(Stats::ENDINDEX);
73
74 StatsData time;
75 time.units = "fs";
76 time.title = "Time";
77 time.dataType = "RealType";
78 time.accumulator = new Accumulator();
79 data_[TIME] = time;
80 statsMap_["TIME"] = TIME;
81
82 StatsData total_energy;
83 total_energy.units = "kcal/mol";
84 total_energy.title = "Total Energy";
85 total_energy.dataType = "RealType";
86 total_energy.accumulator = new Accumulator();
87 data_[TOTAL_ENERGY] = total_energy;
88 statsMap_["TOTAL_ENERGY"] = TOTAL_ENERGY;
89
90 StatsData potential_energy;
91 potential_energy.units = "kcal/mol";
92 potential_energy.title = "Potential Energy";
93 potential_energy.dataType = "RealType";
94 potential_energy.accumulator = new Accumulator();
95 data_[POTENTIAL_ENERGY] = potential_energy;
96 statsMap_["POTENTIAL_ENERGY"] = POTENTIAL_ENERGY;
97
98 StatsData kinetic_energy;
99 kinetic_energy.units = "kcal/mol";
100 kinetic_energy.title = "Kinetic Energy";
101 kinetic_energy.dataType = "RealType";
102 kinetic_energy.accumulator = new Accumulator();
103 data_[KINETIC_ENERGY] = kinetic_energy;
104 statsMap_["KINETIC_ENERGY"] = KINETIC_ENERGY;
105
106 StatsData temperature;
107 temperature.units = "K";
108 temperature.title = "Temperature";
109 temperature.dataType = "RealType";
110 temperature.accumulator = new Accumulator();
111 data_[TEMPERATURE] = temperature;
112 statsMap_["TEMPERATURE"] = TEMPERATURE;
113
114 StatsData pressure;
115 pressure.units = "atm";
116 pressure.title = "Pressure";
117 pressure.dataType = "RealType";
118 pressure.accumulator = new Accumulator();
119 data_[PRESSURE] = pressure;
120 statsMap_["PRESSURE"] = PRESSURE;
121
122 StatsData volume;
123 volume.units = "A^3";
124 volume.title = "Volume";
125 volume.dataType = "RealType";
126 volume.accumulator = new Accumulator();
127 data_[VOLUME] = volume;
128 statsMap_["VOLUME"] = VOLUME;
129
130 StatsData hullvolume;
131 hullvolume.units = "A^3";
132 hullvolume.title = "Hull Volume";
133 hullvolume.dataType = "RealType";
134 hullvolume.accumulator = new Accumulator();
135 data_[HULLVOLUME] = hullvolume;
136 statsMap_["HULLVOLUME"] = HULLVOLUME;
137
138 StatsData gyrvolume;
139 gyrvolume.units = "A^3";
140 gyrvolume.title = "Gyrational Volume";
141 gyrvolume.dataType = "RealType";
142 gyrvolume.accumulator = new Accumulator();
143 data_[GYRVOLUME] = gyrvolume;
144 statsMap_["GYRVOLUME"] = GYRVOLUME;
145
146 StatsData conserved_quantity;
147 conserved_quantity.units = "kcal/mol";
148 conserved_quantity.title = "Conserved Quantity";
149 conserved_quantity.dataType = "RealType";
150 conserved_quantity.accumulator = new Accumulator();
151 data_[CONSERVED_QUANTITY] = conserved_quantity;
152 statsMap_["CONSERVED_QUANTITY"] = CONSERVED_QUANTITY;
153
154 StatsData translational_kinetic;
155 translational_kinetic.units = "kcal/mol";
156 translational_kinetic.title = "Translational Kinetic";
157 translational_kinetic.dataType = "RealType";
158 translational_kinetic.accumulator = new Accumulator();
159 data_[TRANSLATIONAL_KINETIC] = translational_kinetic;
160 statsMap_["TRANSLATIONAL_KINETIC"] = TRANSLATIONAL_KINETIC;
161
162 StatsData rotational_kinetic;
163 rotational_kinetic.units = "kcal/mol";
164 rotational_kinetic.title = "Rotational Kinetic";
165 rotational_kinetic.dataType = "RealType";
166 rotational_kinetic.accumulator = new Accumulator();
167 data_[ROTATIONAL_KINETIC] = rotational_kinetic;
168 statsMap_["ROTATIONAL_KINETIC"] = ROTATIONAL_KINETIC;
169
170 StatsData electronic_kinetic;
171 electronic_kinetic.units = "kcal/mol";
172 electronic_kinetic.title = "Electronic Kinetic";
173 electronic_kinetic.dataType = "RealType";
174 electronic_kinetic.accumulator = new Accumulator();
175 data_[ELECTRONIC_KINETIC] = electronic_kinetic;
176 statsMap_["ELECTRONIC_KINETIC"] = ELECTRONIC_KINETIC;
177
178 StatsData long_range_potential;
179 long_range_potential.units = "kcal/mol";
180 long_range_potential.title = "Long Range Potential";
181 long_range_potential.dataType = "RealType";
182 long_range_potential.accumulator = new Accumulator();
183 data_[LONG_RANGE_POTENTIAL] = long_range_potential;
184 statsMap_["LONG_RANGE_POTENTIAL"] = LONG_RANGE_POTENTIAL;
185
186 StatsData vanderwaals_potential;
187 vanderwaals_potential.units = "kcal/mol";
188 vanderwaals_potential.title = "van der waals Potential";
189 vanderwaals_potential.dataType = "RealType";
190 vanderwaals_potential.accumulator = new Accumulator();
191 data_[VANDERWAALS_POTENTIAL] = vanderwaals_potential;
192 statsMap_["VANDERWAALS_POTENTIAL"] = VANDERWAALS_POTENTIAL;
193
194 StatsData electrostatic_potential;
195 electrostatic_potential.units = "kcal/mol";
196 electrostatic_potential.title = "Electrostatic Potential";
197 electrostatic_potential.dataType = "RealType";
198 electrostatic_potential.accumulator = new Accumulator();
199 data_[ELECTROSTATIC_POTENTIAL] = electrostatic_potential;
200 statsMap_["ELECTROSTATIC_POTENTIAL"] = ELECTROSTATIC_POTENTIAL;
201
202 StatsData metallic_potential;
203 metallic_potential.units = "kcal/mol";
204 metallic_potential.title = "Metallic Potential";
205 metallic_potential.dataType = "RealType";
206 metallic_potential.accumulator = new Accumulator();
207 data_[METALLIC_POTENTIAL] = metallic_potential;
208 statsMap_["METALLIC_POTENTIAL"] = METALLIC_POTENTIAL;
209
210 StatsData metallic_embedding;
211 metallic_embedding.units = "kcal/mol";
212 metallic_embedding.title = "Metallic Embedding";
213 metallic_embedding.dataType = "RealType";
214 metallic_embedding.accumulator = new Accumulator();
215 data_[METALLIC_EMBEDDING] = metallic_embedding;
216 statsMap_["METALLIC_EMBEDDING"] = METALLIC_EMBEDDING;
217
218 StatsData metallic_pair;
219 metallic_pair.units = "kcal/mol";
220 metallic_pair.title = "Metallic Pair";
221 metallic_pair.dataType = "RealType";
222 metallic_pair.accumulator = new Accumulator();
223 data_[METALLIC_PAIR] = metallic_pair;
224 statsMap_["METALLIC_PAIR"] = METALLIC_PAIR;
225
226 StatsData hydrogenbonding_potential;
227 hydrogenbonding_potential.units = "kcal/mol";
228 hydrogenbonding_potential.title = "Hydrogen Bonding Pot.";
229 hydrogenbonding_potential.dataType = "RealType";
230 hydrogenbonding_potential.accumulator = new Accumulator();
231 data_[HYDROGENBONDING_POTENTIAL] = hydrogenbonding_potential;
232 statsMap_["HYDROGENBONDING_POTENTIAL"] = HYDROGENBONDING_POTENTIAL;
233
234 StatsData reciprocal_potential;
235 reciprocal_potential.units = "kcal/mol";
236 reciprocal_potential.title = "Reciprocal Space Pot.";
237 reciprocal_potential.dataType = "RealType";
238 reciprocal_potential.accumulator = new Accumulator();
239 data_[RECIPROCAL_POTENTIAL] = reciprocal_potential;
240 statsMap_["RECIPROCAL_POTENTIAL"] = RECIPROCAL_POTENTIAL;
241
242 StatsData surface_potential;
243 surface_potential.units = "kcal/mol";
244 surface_potential.title = "Surface Potential";
245 surface_potential.dataType = "RealType";
246 surface_potential.accumulator = new Accumulator();
247 data_[SURFACE_POTENTIAL] = surface_potential;
248 statsMap_["SURFACE_POTENTIAL"] = SURFACE_POTENTIAL;
249
250 StatsData short_range_potential;
251 short_range_potential.units = "kcal/mol";
252 short_range_potential.title = "Short Range Potential";
253 short_range_potential.dataType = "RealType";
254 short_range_potential.accumulator = new Accumulator();
255 data_[SHORT_RANGE_POTENTIAL] = short_range_potential;
256 statsMap_["SHORT_RANGE_POTENTIAL"] = SHORT_RANGE_POTENTIAL;
257
258 StatsData bond_potential;
259 bond_potential.units = "kcal/mol";
260 bond_potential.title = "Bond Potential";
261 bond_potential.dataType = "RealType";
262 bond_potential.accumulator = new Accumulator();
263 data_[BOND_POTENTIAL] = bond_potential;
264 statsMap_["BOND_POTENTIAL"] = BOND_POTENTIAL;
265
266 StatsData bend_potential;
267 bend_potential.units = "kcal/mol";
268 bend_potential.title = "Bend Potential";
269 bend_potential.dataType = "RealType";
270 bend_potential.accumulator = new Accumulator();
271 data_[BEND_POTENTIAL] = bend_potential;
272 statsMap_["BEND_POTENTIAL"] = BEND_POTENTIAL;
273
274 StatsData dihedral_potential;
275 dihedral_potential.units = "kcal/mol";
276 dihedral_potential.title = "Dihedral Potential";
277 dihedral_potential.dataType = "RealType";
278 dihedral_potential.accumulator = new Accumulator();
279 data_[DIHEDRAL_POTENTIAL] = dihedral_potential;
280 statsMap_["DIHEDRAL_POTENTIAL"] = DIHEDRAL_POTENTIAL;
281
282 StatsData inversion_potential;
283 inversion_potential.units = "kcal/mol";
284 inversion_potential.title = "Inversion Potential";
285 inversion_potential.dataType = "RealType";
286 inversion_potential.accumulator = new Accumulator();
287 data_[INVERSION_POTENTIAL] = inversion_potential;
288 statsMap_["INVERSION_POTENTIAL"] = INVERSION_POTENTIAL;
289
290 StatsData vraw;
291 vraw.units = "kcal/mol";
292 vraw.title = "Raw Potential";
293 vraw.dataType = "RealType";
294 vraw.accumulator = new Accumulator();
295 data_[RAW_POTENTIAL] = vraw;
296 statsMap_["RAW_POTENTIAL"] = RAW_POTENTIAL;
297
298 StatsData vrestraint;
299 vrestraint.units = "kcal/mol";
300 vrestraint.title = "Restraint Potential";
301 vrestraint.dataType = "RealType";
302 vrestraint.accumulator = new Accumulator();
303 data_[RESTRAINT_POTENTIAL] = vrestraint;
304 statsMap_["RESTRAINT_POTENTIAL"] = RESTRAINT_POTENTIAL;
305
306 StatsData vexcluded;
307 vexcluded.units = "kcal/mol";
308 vexcluded.title = "Excluded Potential";
309 vexcluded.dataType = "RealType";
310 vexcluded.accumulator = new Accumulator();
311 data_[EXCLUDED_POTENTIAL] = vexcluded;
312 statsMap_["EXCLUDED_POTENTIAL"] = EXCLUDED_POTENTIAL;
313
314 StatsData pressure_tensor;
315 pressure_tensor.units = "amu/fs^2/A";
316 pressure_tensor.title = "Pressure Tensor";
317 pressure_tensor.dataType = "Mat3x3d";
318 pressure_tensor.accumulator = new MatrixAccumulator();
319 data_[PRESSURE_TENSOR] = pressure_tensor;
320 statsMap_["PRESSURE_TENSOR"] = PRESSURE_TENSOR;
321
322 // virial tensor added
323 StatsData virial_tensor;
324 virial_tensor.units = "kcal/mol";
325 virial_tensor.title = "Virial Tensor";
326 virial_tensor.dataType = "Mat3x3d";
327 virial_tensor.accumulator = new MatrixAccumulator();
328 data_[VIRIAL_TENSOR] = virial_tensor;
329 statsMap_["VIRIAL_TENSOR"] = VIRIAL_TENSOR;
330
331 StatsData system_dipole;
332 system_dipole.units = "C m";
333 system_dipole.title = "System Dipole";
334 system_dipole.dataType = "Vector3d";
335 system_dipole.accumulator = new VectorAccumulator();
336 data_[SYSTEM_DIPOLE] = system_dipole;
337 statsMap_["SYSTEM_DIPOLE"] = SYSTEM_DIPOLE;
338
339 StatsData system_quadrupole;
340 system_quadrupole.units = "C m^2";
341 system_quadrupole.title = "System Quadrupole";
342 system_quadrupole.dataType = "Mat3x3d";
343 system_quadrupole.accumulator = new MatrixAccumulator();
344 data_[SYSTEM_QUADRUPOLE] = system_quadrupole;
345 statsMap_["SYSTEM_QUADRUPOLE"] = SYSTEM_QUADRUPOLE;
346
347 StatsData tagged_pair_distance;
348 tagged_pair_distance.units = "A";
349 tagged_pair_distance.title = "Tagged Pair Distance";
350 tagged_pair_distance.dataType = "RealType";
351 tagged_pair_distance.accumulator = new Accumulator();
352 data_[TAGGED_PAIR_DISTANCE] = tagged_pair_distance;
353 statsMap_["TAGGED_PAIR_DISTANCE"] = TAGGED_PAIR_DISTANCE;
354
355 StatsData shadowh;
356 shadowh.units = "kcal/mol";
357 shadowh.title = "Shadow Hamiltonian";
358 shadowh.dataType = "RealType";
359 shadowh.accumulator = new Accumulator();
360 data_[SHADOWH] = shadowh;
361 statsMap_["SHADOWH"] = SHADOWH;
362
363 StatsData helfandmoment;
364 helfandmoment.units = "A*kcal/mol";
365 helfandmoment.title = "Thermal Helfand Moment";
366 helfandmoment.dataType = "Vector3d";
367 helfandmoment.accumulator = new VectorAccumulator();
368 data_[HELFANDMOMENT] = helfandmoment;
369 statsMap_["HELFANDMOMENT"] = HELFANDMOMENT;
370
371 StatsData heatflux;
372 heatflux.units = "amu/fs^3";
373 heatflux.title = "Heat Flux";
374 heatflux.dataType = "Vector3d";
375 heatflux.accumulator = new VectorAccumulator();
376 data_[HEATFLUX] = heatflux;
377 statsMap_["HEATFLUX"] = HEATFLUX;
378
379 StatsData electronic_temperature;
380 electronic_temperature.units = "K";
381 electronic_temperature.title = "Electronic Temperature";
382 electronic_temperature.dataType = "RealType";
383 electronic_temperature.accumulator = new Accumulator();
384 data_[ELECTRONIC_TEMPERATURE] = electronic_temperature;
385 statsMap_["ELECTRONIC_TEMPERATURE"] = ELECTRONIC_TEMPERATURE;
386
387 StatsData com;
388 com.units = "A";
389 com.title = "Center of Mass";
390 com.dataType = "Vector3d";
391 com.accumulator = new VectorAccumulator();
392 data_[COM] = com;
393 statsMap_["COM"] = COM;
394
395 StatsData comVel;
396 comVel.units = "A/fs";
397 comVel.title = "COM Velocity";
398 comVel.dataType = "Vector3d";
399 comVel.accumulator = new VectorAccumulator();
400 data_[COM_VELOCITY] = comVel;
401 statsMap_["COM_VELOCITY"] = COM_VELOCITY;
402
403 StatsData angMom;
404 angMom.units = "amu A^2/fs";
405 angMom.title = "Angular Momentum";
406 angMom.dataType = "Vector3d";
407 angMom.accumulator = new VectorAccumulator();
408 data_[ANGULAR_MOMENTUM] = angMom;
409 statsMap_["ANGULAR_MOMENTUM"] = ANGULAR_MOMENTUM;
410
411 StatsData potSelection;
412 potSelection.units = "kcal/mol";
413 potSelection.title = "Selection Potentials";
414 potSelection.dataType = "potVec";
415 potSelection.accumulator = new PotVecAccumulator();
416 data_[POTENTIAL_SELECTION] = potSelection;
417 statsMap_["POTENTIAL_SELECTION"] = POTENTIAL_SELECTION;
418
419 StatsData netCharge;
420 netCharge.units = "e";
421 netCharge.title = "Net Charge";
422 netCharge.dataType = "RealType";
423 netCharge.accumulator = new Accumulator();
424 data_[NET_CHARGE] = netCharge;
425 statsMap_["NET_CHARGE"] = NET_CHARGE;
426
427 StatsData chargeMomentum;
428 chargeMomentum.units = "kcal fs / e / mol";
429 chargeMomentum.title = "Charge Momentum";
430 chargeMomentum.dataType = "RealType";
431 chargeMomentum.accumulator = new Accumulator();
432 data_[CHARGE_MOMENTUM] = chargeMomentum;
433 statsMap_["CHARGE_MOMENTUM"] = CHARGE_MOMENTUM;
434
435 StatsData currentDensity;
436 currentDensity.units = "amps / m^2";
437 currentDensity.title = "Current Density: total, then by AtomType";
438 currentDensity.dataType = "Array2d";
439 unsigned int nCols = 3 * (info_->getSimulatedAtomTypes().size()) + 3;
440 currentDensity.accumulatorArray2d.resize(nCols);
441 for (unsigned int j = 0; j < nCols; j++) {
442 currentDensity.accumulatorArray2d[j] = new Accumulator();
443 }
444 data_[CURRENT_DENSITY] = currentDensity;
445 statsMap_["CURRENT_DENSITY"] = CURRENT_DENSITY;
446
447 // Now, set some defaults in the mask:
448
449 Globals* simParams = info_->getSimParams();
450 std::string statFileFormatString = simParams->getStatFileFormat();
451 parseStatFileFormat(statFileFormatString);
452
453 // if we're doing a thermodynamic integration, we'll want the raw
454 // potential as well as the full potential:
455
456 if (simParams->getUseThermodynamicIntegration()) {
457 statsMask_.set(RAW_POTENTIAL);
458 statsMask_.set(RESTRAINT_POTENTIAL);
459 }
460
461 // if we've got restraints turned on, we'll also want a report of the
462 // total harmonic restraints
463 if (simParams->getUseRestraints()) {
464 statsMask_.set(RAW_POTENTIAL);
465 statsMask_.set(RESTRAINT_POTENTIAL);
466 }
467
468 if (simParams->havePrintPressureTensor() &&
469 simParams->getPrintPressureTensor()) {
470 statsMask_.set(PRESSURE_TENSOR);
471 }
472
473 if (simParams->havePrintVirialTensor() &&
474 simParams->getPrintVirialTensor()) {
475 statsMask_.set(VIRIAL_TENSOR);
476 }
477
478 // Why do we have both of these?
479 if (simParams->getAccumulateBoxDipole()) { statsMask_.set(SYSTEM_DIPOLE); }
480 if (info_->getCalcBoxDipole()) { statsMask_.set(SYSTEM_DIPOLE); }
481
482 // Why do we have both of these?
483 if (simParams->getAccumulateBoxQuadrupole()) {
484 statsMask_.set(SYSTEM_QUADRUPOLE);
485 }
486 if (info_->getCalcBoxQuadrupole()) { statsMask_.set(SYSTEM_QUADRUPOLE); }
487
488 if (simParams->havePrintHeatFlux()) {
489 if (simParams->getPrintHeatFlux()) { statsMask_.set(HEATFLUX); }
490 }
491
492 if (simParams->haveTaggedAtomPair() &&
493 simParams->havePrintTaggedPairDistance()) {
494 if (simParams->getPrintTaggedPairDistance()) {
495 statsMask_.set(TAGGED_PAIR_DISTANCE);
496 }
497 }
498
499 if (simParams->havePotentialSelection()) {
500 statsMask_.set(POTENTIAL_SELECTION);
501 }
502 }
503
504 int Stats::getPrecision() {
505 Globals* simParams = info_->getSimParams();
506 int statFilePrecision = simParams->getStatFilePrecision();
507 return statFilePrecision;
508 }
509
510 void Stats::parseStatFileFormat(const std::string& format) {
511 StringTokenizer tokenizer(format, " ,;|\t\n\r");
512
513 while (tokenizer.hasMoreTokens()) {
514 std::string token(tokenizer.nextToken());
515 toUpper(token);
516 StatsMapType::iterator i = statsMap_.find(token);
517 if (i != statsMap_.end()) {
518 statsMask_.set(i->second);
519 } else {
520 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
521 "Stats::parseStatFileFormat: %s is not a recognized\n"
522 "\tstatFileFormat keyword.\n",
523 token.c_str());
524 painCave.isFatal = 0;
525 painCave.severity = OPENMD_ERROR;
526 simError();
527 }
528 }
529 }
530
531 std::string Stats::getTitle(int index) {
532 assert(index >= 0 && index < ENDINDEX);
533 return data_[index].title;
534 }
535
536 std::string Stats::getUnits(int index) {
537 assert(index >= 0 && index < ENDINDEX);
538 return data_[index].units;
539 }
540
541 std::string Stats::getDataType(int index) {
542 assert(index >= 0 && index < ENDINDEX);
543 return data_[index].dataType;
544 }
545
546 void Stats::collectStats() {
547 Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
548 Thermo thermo(info_);
549
550 for (unsigned int i = 0; i < statsMask_.size(); ++i) {
551 if (statsMask_[i]) {
552 switch (i) {
553 case TIME:
554 dynamic_cast<Accumulator*>(data_[i].accumulator)
555 ->add(snap->getTime());
556 break;
557 case KINETIC_ENERGY:
558 dynamic_cast<Accumulator*>(data_[i].accumulator)
559 ->add(thermo.getKinetic());
560 break;
561 case POTENTIAL_ENERGY:
562 dynamic_cast<Accumulator*>(data_[i].accumulator)
563 ->add(thermo.getPotential());
564 break;
565 case TOTAL_ENERGY:
566 dynamic_cast<Accumulator*>(data_[i].accumulator)
567 ->add(thermo.getTotalEnergy());
568 break;
569 case TEMPERATURE:
570 dynamic_cast<Accumulator*>(data_[i].accumulator)
571 ->add(thermo.getTemperature());
572 break;
573 case PRESSURE:
574 dynamic_cast<Accumulator*>(data_[i].accumulator)
575 ->add(thermo.getPressure());
576 break;
577 case VOLUME:
578 dynamic_cast<Accumulator*>(data_[i].accumulator)
579 ->add(thermo.getVolume());
580 break;
581 case CONSERVED_QUANTITY:
582 dynamic_cast<Accumulator*>(data_[i].accumulator)
583 ->add(snap->getConservedQuantity());
584 break;
585 case PRESSURE_TENSOR:
586 dynamic_cast<MatrixAccumulator*>(data_[i].accumulator)
587 ->add(thermo.getPressureTensor());
588 break;
589 // virial Tensor
590 case VIRIAL_TENSOR:
591 dynamic_cast<MatrixAccumulator*>(data_[i].accumulator)
592 ->add(snap->getVirialTensor());
593 break;
594
595 case SYSTEM_DIPOLE:
596 dynamic_cast<VectorAccumulator*>(data_[i].accumulator)
597 ->add(thermo.getSystemDipole());
598 break;
599 case SYSTEM_QUADRUPOLE:
600 dynamic_cast<MatrixAccumulator*>(data_[i].accumulator)
601 ->add(thermo.getSystemQuadrupole());
602 break;
603 case HEATFLUX:
604 dynamic_cast<VectorAccumulator*>(data_[i].accumulator)
605 ->add(thermo.getHeatFlux());
606 break;
607 case HULLVOLUME:
608 dynamic_cast<Accumulator*>(data_[i].accumulator)
609 ->add(thermo.getHullVolume());
610 break;
611 case GYRVOLUME:
612 dynamic_cast<Accumulator*>(data_[i].accumulator)
613 ->add(thermo.getGyrationalVolume());
614 break;
615 case TRANSLATIONAL_KINETIC:
616 dynamic_cast<Accumulator*>(data_[i].accumulator)
617 ->add(thermo.getTranslationalKinetic());
618 break;
619 case ROTATIONAL_KINETIC:
620 dynamic_cast<Accumulator*>(data_[i].accumulator)
621 ->add(thermo.getRotationalKinetic());
622 break;
623 case ELECTRONIC_KINETIC:
624 dynamic_cast<Accumulator*>(data_[i].accumulator)
625 ->add(thermo.getElectronicKinetic());
626 break;
627 case LONG_RANGE_POTENTIAL:
628 dynamic_cast<Accumulator*>(data_[i].accumulator)
629 ->add(snap->getLongRangePotential());
630 break;
631 case VANDERWAALS_POTENTIAL:
632 dynamic_cast<Accumulator*>(data_[i].accumulator)
633 ->add(snap->getLongRangePotentials()[VANDERWAALS_FAMILY]);
634 break;
635 case ELECTROSTATIC_POTENTIAL:
636 dynamic_cast<Accumulator*>(data_[i].accumulator)
637 ->add(snap->getLongRangePotentials()[ELECTROSTATIC_FAMILY] +
638 snap->getSelfPotentials()[ELECTROSTATIC_FAMILY]);
639 break;
640 case METALLIC_POTENTIAL:
641 dynamic_cast<Accumulator*>(data_[i].accumulator)
642 ->add(snap->getSelfPotentials()[METALLIC_EMBEDDING_FAMILY] +
643 snap->getLongRangePotentials()[METALLIC_PAIR_FAMILY]);
644 break;
645 case METALLIC_EMBEDDING:
646 dynamic_cast<Accumulator*>(data_[i].accumulator)
647 ->add(snap->getSelfPotentials()[METALLIC_EMBEDDING_FAMILY]);
648 break;
649 case METALLIC_PAIR:
650 dynamic_cast<Accumulator*>(data_[i].accumulator)
651 ->add(snap->getLongRangePotentials()[METALLIC_PAIR_FAMILY]);
652 break;
653 case HYDROGENBONDING_POTENTIAL:
654 dynamic_cast<Accumulator*>(data_[i].accumulator)
655 ->add(snap->getLongRangePotentials()[HYDROGENBONDING_FAMILY]);
656 break;
657 case RECIPROCAL_POTENTIAL:
658 dynamic_cast<Accumulator*>(data_[i].accumulator)
659 ->add(snap->getReciprocalPotential());
660 break;
661 case SURFACE_POTENTIAL:
662 dynamic_cast<Accumulator*>(data_[i].accumulator)
663 ->add(snap->getSurfacePotential());
664 break;
665 case SHORT_RANGE_POTENTIAL:
666 dynamic_cast<Accumulator*>(data_[i].accumulator)
667 ->add(snap->getShortRangePotential());
668 break;
669 case BOND_POTENTIAL:
670 dynamic_cast<Accumulator*>(data_[i].accumulator)
671 ->add(snap->getBondPotential());
672 break;
673 case BEND_POTENTIAL:
674 dynamic_cast<Accumulator*>(data_[i].accumulator)
675 ->add(snap->getBendPotential());
676 break;
677 case DIHEDRAL_POTENTIAL:
678 dynamic_cast<Accumulator*>(data_[i].accumulator)
679 ->add(snap->getTorsionPotential());
680 break;
681 case INVERSION_POTENTIAL:
682 dynamic_cast<Accumulator*>(data_[i].accumulator)
683 ->add(snap->getInversionPotential());
684 break;
685 case RAW_POTENTIAL:
686 dynamic_cast<Accumulator*>(data_[i].accumulator)
687 ->add(snap->getRawPotential());
688 break;
689 case RESTRAINT_POTENTIAL:
690 dynamic_cast<Accumulator*>(data_[i].accumulator)
691 ->add(snap->getRestraintPotential());
692 break;
693 case EXCLUDED_POTENTIAL:
694 dynamic_cast<Accumulator*>(data_[i].accumulator)
695 ->add(snap->getExcludedPotential());
696 break;
697 case TAGGED_PAIR_DISTANCE:
698 dynamic_cast<Accumulator*>(data_[i].accumulator)
699 ->add(thermo.getTaggedAtomPairDistance());
700 break;
701 case ELECTRONIC_TEMPERATURE:
702 dynamic_cast<Accumulator*>(data_[i].accumulator)
703 ->add(thermo.getElectronicTemperature());
704 break;
705 case COM:
706 dynamic_cast<VectorAccumulator*>(data_[i].accumulator)
707 ->add(thermo.getCom());
708 break;
709 case COM_VELOCITY:
710 dynamic_cast<VectorAccumulator*>(data_[i].accumulator)
711 ->add(thermo.getComVel());
712 break;
713 case ANGULAR_MOMENTUM:
714 dynamic_cast<VectorAccumulator*>(data_[i].accumulator)
715 ->add(thermo.getAngularMomentum());
716 break;
717 case POTENTIAL_SELECTION:
718 dynamic_cast<PotVecAccumulator*>(data_[i].accumulator)
719 ->add(thermo.getSelectionPotentials());
720 break;
721 case NET_CHARGE:
722 dynamic_cast<Accumulator*>(data_[i].accumulator)
723 ->add(thermo.getNetCharge());
724 break;
725 case CHARGE_MOMENTUM:
726 dynamic_cast<Accumulator*>(data_[i].accumulator)
727 ->add(thermo.getChargeMomentum());
728 break;
729 case CURRENT_DENSITY:
730 unsigned int k = 0;
731 std::vector<Vector3d> Jc = thermo.getCurrentDensity();
732 for (unsigned int j = 0; j < Jc.size(); ++j) {
733 dynamic_cast<Accumulator*>(data_[i].accumulatorArray2d[k++])
734 ->add(Jc[j][0]);
735 dynamic_cast<Accumulator*>(data_[i].accumulatorArray2d[k++])
736 ->add(Jc[j][1]);
737 dynamic_cast<Accumulator*>(data_[i].accumulatorArray2d[k++])
738 ->add(Jc[j][2]);
739 }
740 break;
741
742 /*
743 case SHADOWH:
744 dynamic_cast<Accumulator
745 *>(data_[i].accumulator)->add(thermo.getShadowHamiltionian());
746 break; case HELFANDMOMENT: dynamic_cast<Accumulator
747 *>(data_[i].accumulator)->add(thermo.getHelfandMoment()); break;
748 */
749 }
750 }
751 }
752 }
753
754 int Stats::getIntData(int index) {
755 assert(index >= 0 && index < ENDINDEX);
756 RealType value;
757 dynamic_cast<Accumulator*>(data_[index].accumulator)->getLastValue(value);
758 return (int)value;
759 }
760 RealType Stats::getRealData(int index) {
761 assert(index >= 0 && index < ENDINDEX);
762 RealType value(0.0);
763 dynamic_cast<Accumulator*>(data_[index].accumulator)->getLastValue(value);
764 return value;
765 }
766 Vector3d Stats::getVectorData(int index) {
767 assert(index >= 0 && index < ENDINDEX);
768 Vector3d value;
769 dynamic_cast<VectorAccumulator*>(data_[index].accumulator)
770 ->getLastValue(value);
771 return value;
772 }
773 potVec Stats::getPotVecData(int index) {
774 assert(index >= 0 && index < ENDINDEX);
775 potVec value;
776 dynamic_cast<PotVecAccumulator*>(data_[index].accumulator)
777 ->getLastValue(value);
778 return value;
779 }
780 Mat3x3d Stats::getMatrixData(int index) {
781 assert(index >= 0 && index < ENDINDEX);
782 Mat3x3d value;
783 dynamic_cast<MatrixAccumulator*>(data_[index].accumulator)
784 ->getLastValue(value);
785 return value;
786 }
787 std::vector<RealType> Stats::getArrayData(int index) {
788 assert(index >= 0 && index < ENDINDEX);
789 std::vector<RealType> value;
790 RealType v;
791 for (unsigned int i = 0; i < data_[index].accumulatorArray2d.size(); ++i) {
792 dynamic_cast<Accumulator*>(data_[index].accumulatorArray2d[i])
793 ->getLastValue(v);
794 value.push_back(v);
795 }
796 return value;
797 }
798
799 int Stats::getIntAverage(int index) {
800 assert(index >= 0 && index < ENDINDEX);
801 RealType value;
802 dynamic_cast<Accumulator*>(data_[index].accumulator)->getAverage(value);
803 return (int)value;
804 }
805 RealType Stats::getRealAverage(int index) {
806 assert(index >= 0 && index < ENDINDEX);
807 RealType value(0.0);
808 dynamic_cast<Accumulator*>(data_[index].accumulator)->getAverage(value);
809 return value;
810 }
811 Vector3d Stats::getVectorAverage(int index) {
812 assert(index >= 0 && index < ENDINDEX);
813 Vector3d value;
814 dynamic_cast<VectorAccumulator*>(data_[index].accumulator)
815 ->getAverage(value);
816 return value;
817 }
818 potVec Stats::getPotVecAverage(int index) {
819 assert(index >= 0 && index < ENDINDEX);
820 potVec value;
821 dynamic_cast<PotVecAccumulator*>(data_[index].accumulator)
822 ->getAverage(value);
823 return value;
824 }
825 Mat3x3d Stats::getMatrixAverage(int index) {
826 assert(index >= 0 && index < ENDINDEX);
827 Mat3x3d value;
828 dynamic_cast<MatrixAccumulator*>(data_[index].accumulator)
829 ->getAverage(value);
830 return value;
831 }
832 std::vector<RealType> Stats::getArrayAverage(int index) {
833 assert(index >= 0 && index < ENDINDEX);
834 std::vector<RealType> value;
835 RealType v;
836 for (unsigned int i = 0; i < data_[index].accumulatorArray2d.size(); ++i) {
837 dynamic_cast<Accumulator*>(data_[index].accumulatorArray2d[i])
838 ->getAverage(v);
839 value.push_back(v);
840 }
841 return value;
842 }
843
844 int Stats::getIntError(int index) {
845 assert(index >= 0 && index < ENDINDEX);
846 RealType value;
847 dynamic_cast<Accumulator*>(data_[index].accumulator)
848 ->get95percentConfidenceInterval(value);
849 return (int)value;
850 }
851 RealType Stats::getRealError(int index) {
852 assert(index >= 0 && index < ENDINDEX);
853 RealType value(0.0);
854 dynamic_cast<Accumulator*>(data_[index].accumulator)
855 ->get95percentConfidenceInterval(value);
856 return value;
857 }
858 Vector3d Stats::getVectorError(int index) {
859 assert(index >= 0 && index < ENDINDEX);
860 Vector3d value;
861 dynamic_cast<VectorAccumulator*>(data_[index].accumulator)
862 ->get95percentConfidenceInterval(value);
863 return value;
864 }
865 potVec Stats::getPotVecError(int index) {
866 assert(index >= 0 && index < ENDINDEX);
867 potVec value;
868 dynamic_cast<PotVecAccumulator*>(data_[index].accumulator)
869 ->get95percentConfidenceInterval(value);
870 return value;
871 }
872 Mat3x3d Stats::getMatrixError(int index) {
873 assert(index >= 0 && index < ENDINDEX);
874 Mat3x3d value;
875 dynamic_cast<MatrixAccumulator*>(data_[index].accumulator)
876 ->get95percentConfidenceInterval(value);
877 return value;
878 }
879 std::vector<RealType> Stats::getArrayError(int index) {
880 assert(index >= 0 && index < ENDINDEX);
881 std::vector<RealType> value;
882 RealType v;
883 for (unsigned int i = 0; i < data_[index].accumulatorArray2d.size(); ++i) {
884 dynamic_cast<Accumulator*>(data_[index].accumulatorArray2d[i])
885 ->get95percentConfidenceInterval(v);
886 value.push_back(v);
887 }
888 return value;
889 }
890
891 Stats::StatsBitSet Stats::getStatsMask() { return statsMask_; }
892 Stats::StatsMapType Stats::getStatsMap() { return statsMap_; }
893 void Stats::setStatsMask(Stats::StatsBitSet mask) { statsMask_ = mask; }
894
895 std::string Stats::getStatsReport() {
896 std::stringstream report;
897#if defined(_MSC_VER)
898 std::string pm = " +/- ";
899 std::string luc = "[";
900 std::string lex = "|";
901 std::string llc = "[";
902 std::string ruc = "]";
903 std::string rex = "|";
904 std::string rlc = "]";
905#else
906 std::string pm = " \u00B1 ";
907 std::string luc = "\u23A1";
908 std::string lex = "\u23A2";
909 std::string llc = "\u23A3";
910 std::string ruc = "\u23A4";
911 std::string rex = "\u23A5";
912 std::string rlc = "\u23A6";
913#endif
914
915 int nSamp = dynamic_cast<Accumulator*>(data_[TIME].accumulator)->count();
916
917 std::string head(79, '#');
918 report << head << std::endl;
919 report << "# Status Report:" << std::string(62, ' ') << "#" << std::endl;
920 report << "# " << right << setw(24) << "Total Time:";
921 report << setw(12) << getRealData(TIME);
922 report << " " << setw(17) << left << getUnits(TIME)
923 << " #" << std::endl;
924 report << "# " << right << setw(24) << "Number of Samples:";
925 report << setw(12) << nSamp;
926 report << " #" << std::endl;
927
928 for (unsigned int i = 0; i < statsMask_.size(); ++i) {
929 if (statsMask_[i] && i != TIME) {
930 if (getDataType(i) == "RealType") {
931 report << "# " << right << setw(23) << getTitle(i) << ":";
932 report << right << setw(12) << getRealAverage(i);
933 report << pm << left << setw(12) << getRealError(i);
934 report << " " << left << setw(17) << getUnits(i);
935 report << " #" << std::endl;
936
937 } else if (getDataType(i) == "Vector3d") {
938 Vector3d s = getVectorAverage(i);
939 Vector3d e = getVectorError(i);
940
941 report << "# ";
942 report << luc << right << setw(12) << s(0) << ruc << " ";
943 report << luc << right << setw(12) << e(0);
944 report << ruc << " #" << std::endl;
945
946 report << "# " << right << setw(23) << getTitle(i) << ":";
947
948 report << lex << right << setw(12) << s(1) << rex << pm;
949 report << lex << right << setw(12) << e(1) << rex << " ";
950 report << left << setw(17) << getUnits(i) << " #";
951 report << std::endl;
952
953 report << "# ";
954 report << llc << right << setw(12) << s(2) << rlc << " ";
955 report << llc << right << setw(12) << e(2);
956 report << rlc << " #" << std::endl;
957
958 } else if (getDataType(i) == "potVec") {
959 potVec s = getPotVecAverage(i);
960 potVec e = getPotVecError(i);
961
962 report << "# " << right << setw(23) << getTitle(i);
963 report << ": #";
964 report << std::endl;
965
966 for (unsigned int j = 1; j < N_INTERACTION_FAMILIES; j++) {
967 switch (j) {
969 report << "# " << right << setw(24) << "van der Waals:";
970 break;
972 report << "# " << right << setw(24) << "Electrostatic:";
973 break;
974 case METALLIC_EMBEDDING:
975 report << "# " << right << setw(24) << "Metallic Embedding:";
976 break;
977 case METALLIC_PAIR:
978 report << "# " << right << setw(24) << "Metallic Pair:";
979 break;
981 report << "# " << right << setw(24) << "Hydrogen Bonding:";
982 break;
983 case BONDED_FAMILY:
984 report << "# " << right << setw(24) << "Bonded (1-2,1-3,1-4):";
985 break;
986 default:
987 report << "# " << right << setw(24) << "Unknown:";
988 break;
989 }
990 report << right << setw(12) << s[j];
991 report << pm << left << setw(12) << e[j];
992 report << " " << left << setw(17) << getUnits(i) << " #";
993 report << std::endl;
994 }
995
996 } else if (getDataType(i) == "Mat3x3d") {
997 Mat3x3d s = getMatrixAverage(i);
998 Mat3x3d e = getMatrixError(i);
999
1000 report << "# ";
1001 report << luc << right << setw(12) << s(0, 0) << " ";
1002 report << right << setw(12) << s(0, 1) << " ";
1003 report << right << setw(12) << s(0, 2) << ruc << " #";
1004 report << std::endl;
1005
1006 report << "# " << right << setw(23) << getTitle(i) << ":";
1007
1008 report << lex << right << setw(12) << s(1, 0) << " ";
1009 report << right << setw(12) << s(1, 1) << " ";
1010 report << right << setw(12) << s(1, 2) << rex << " ";
1011 report << left << setw(11) << getUnits(i) << "#" << std::endl;
1012
1013 report << "# ";
1014 report << llc << right << setw(12) << s(2, 0) << " ";
1015 report << right << setw(12) << s(2, 1) << " ";
1016 report << right << setw(12) << s(2, 2) << rlc << " #";
1017 report << std::endl;
1018
1019 report << "# ";
1020 report << luc << right << setw(12) << e(0, 0) << " ";
1021 report << right << setw(12) << e(0, 1) << " ";
1022 report << right << setw(12) << e(0, 2) << ruc << " #";
1023 report << std::endl;
1024
1025 report << "# " << pm;
1026
1027 report << lex << right << setw(12) << e(1, 0) << " ";
1028 report << right << setw(12) << e(1, 1) << " ";
1029 report << right << setw(12) << e(1, 2) << rex << " #";
1030 report << std::endl;
1031
1032 report << "# ";
1033 report << llc << right << setw(12) << e(2, 0) << " ";
1034 report << right << setw(12) << e(2, 1) << " ";
1035 report << right << setw(12) << e(2, 2) << rlc << " #";
1036 report << std::endl;
1037 }
1038 }
1039 }
1040 report << head << std::endl;
1041
1042 return report.str();
1043 }
1044
1045} // namespace OpenMD
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
@ HYDROGENBONDING_FAMILY
Short-range directional interactions.
@ VANDERWAALS_FAMILY
Long-range dispersion and short-range pauli repulsion.
@ METALLIC_EMBEDDING_FAMILY
Transition metal interactions involving electron density.
@ BONDED_FAMILY
directly bonded 1-2, 1-3, or 1-4 interactions
@ METALLIC_PAIR_FAMILY
Transition metal interactions involving pair potentials.
@ ELECTROSTATIC_FAMILY
Coulombic and point-multipole interactions.