47#include "applications/staticProps/P2R.hpp"
54#include "brains/Thermo.hpp"
57#include "utils/Revision.hpp"
58#include "utils/simError.h"
62 P2R::P2R(SimInfo* info,
const std::string& filename,
const std::string& sele1,
64 StaticAnalyser(info, filename, nbins),
65 doVect_(true), doOffset_(false), selectionScript1_(sele1),
66 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info) {
67 evaluator1_.loadScriptString(sele1);
68 if (!evaluator1_.isDynamic()) {
69 seleMan1_.setSelectionSet(evaluator1_.evaluate());
73 "2nd order Legendre Polynomial Correlation using r as reference axis");
74 setOutputName(
getPrefix(filename) +
".P2R");
75 std::stringstream params;
76 const std::string paramString = params.str();
77 setParameterString(paramString);
80 P2R::P2R(SimInfo* info,
const std::string& filename,
const std::string& sele1,
81 const std::string& sele2,
unsigned int nbins) :
82 StaticAnalyser(info, filename, nbins),
83 doVect_(false), doOffset_(false), selectionScript1_(sele1),
84 selectionScript2_(sele2), seleMan1_(info), seleMan2_(info),
85 evaluator1_(info), evaluator2_(info) {
86 evaluator1_.loadScriptString(sele1);
87 if (!evaluator1_.isDynamic()) {
88 seleMan1_.setSelectionSet(evaluator1_.evaluate());
91 evaluator2_.loadScriptString(sele2);
92 if (!evaluator2_.isDynamic()) {
93 seleMan2_.setSelectionSet(evaluator2_.evaluate());
97 "2nd order Legendre Polynomial Correlation using r as reference axis");
98 setOutputName(
getPrefix(filename) +
".P2R");
99 std::stringstream params;
100 const std::string paramString = params.str();
101 setParameterString(paramString);
104 P2R::P2R(SimInfo* info,
const std::string& filename,
const std::string& sele1,
105 int seleOffset,
unsigned int nbins) :
106 StaticAnalyser(info, filename, nbins),
107 doVect_(false), doOffset_(true), doOffset2_(false),
108 selectionScript1_(sele1), seleMan1_(info), seleMan2_(info),
109 evaluator1_(info), evaluator2_(info), seleOffset_(seleOffset) {
110 evaluator1_.loadScriptString(sele1);
111 if (!evaluator1_.isDynamic()) {
112 seleMan1_.setSelectionSet(evaluator1_.evaluate());
116 "2nd order Legendre Polynomial Correlation using r as reference axis");
117 setOutputName(
getPrefix(filename) +
".P2R");
118 std::stringstream params;
119 const std::string paramString = params.str();
120 setParameterString(paramString);
123 P2R::P2R(SimInfo* info,
const std::string& filename,
const std::string& sele1,
124 int seleOffset,
int seleOffset2,
unsigned int nbins) :
125 StaticAnalyser(info, filename, nbins),
126 doVect_(false), doOffset_(true), doOffset2_(true),
127 selectionScript1_(sele1), seleMan1_(info), seleMan2_(info),
128 evaluator1_(info), evaluator2_(info), seleOffset_(seleOffset),
129 seleOffset2_(seleOffset2) {
130 evaluator1_.loadScriptString(sele1);
131 if (!evaluator1_.isDynamic()) {
132 seleMan1_.setSelectionSet(evaluator1_.evaluate());
136 "2nd order Legendre Polynomial Correlation using r as reference axis");
137 setOutputName(
getPrefix(filename) +
".P2R");
138 std::stringstream params;
139 const std::string paramString = params.str();
140 setParameterString(paramString);
143 void P2R::process() {
148 bool usePeriodicBoundaryConditions_ =
149 info_->getSimParams()->getUsePeriodicBoundaryConditions();
151 Thermo thermo(info_);
152 DumpReader reader(info_, dumpFilename_);
153 int nFrames = reader.getNFrames();
155 nProcessed_ = nFrames / step_;
159 for (
int istep = 0; istep < nFrames; istep += step_) {
160 reader.readFrame(istep);
161 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
163 Vector3d CenterOfMass = thermo.getCom();
165 if (evaluator1_.isDynamic()) {
166 seleMan1_.setSelectionSet(evaluator1_.evaluate());
170 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
171 sd1 = seleMan1_.nextSelected(ii)) {
172 Vector3d pos = sd1->getPos();
174 Vector3d r1 = CenterOfMass - pos;
177 if (sd1->isDirectional()) {
178 Vector3d vec = sd1->getA().transpose() * V3Z;
181 RealType cosangle =
dot(r1, vec);
183 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
189 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
190 sd1 = seleMan1_.nextSelected(ii)) {
197 int sd1Aind = sd1->getGlobalIndex() + seleOffset2_;
198 StuntDouble* sd1A = info_->getIOIndexToIntegrableObject(sd1Aind);
199 r1 = CenterOfMass - sd1A->getPos();
201 r1 = CenterOfMass - sd1->getPos();
204 if (usePeriodicBoundaryConditions_)
205 currentSnapshot_->wrapVector(r1);
207 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
208 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
210 Vector3d r2 = CenterOfMass - sd2->getPos();
211 if (usePeriodicBoundaryConditions_)
212 currentSnapshot_->wrapVector(r2);
214 Vector3d rc = 0.5 * (r1 + r2);
215 if (usePeriodicBoundaryConditions_)
216 currentSnapshot_->wrapVector(rc);
218 Vector3d vec = r1 - r2;
219 if (usePeriodicBoundaryConditions_)
220 currentSnapshot_->wrapVector(vec);
224 RealType cosangle =
dot(rc, vec);
225 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
229 if (evaluator2_.isDynamic()) {
230 seleMan2_.setSelectionSet(evaluator2_.evaluate());
233 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
234 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
235 "In frame %d, the number of selected StuntDoubles are\n"
236 "\tnot the same in --sele1 and sele2\n",
238 painCave.severity = OPENMD_INFO;
239 painCave.isFatal = 0;
243 for (sd1 = seleMan1_.beginSelected(ii),
244 sd2 = seleMan2_.beginSelected(jj);
245 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
246 sd2 = seleMan2_.nextSelected(jj)) {
247 Vector3d r1 = CenterOfMass - sd1->getPos();
248 if (usePeriodicBoundaryConditions_)
249 currentSnapshot_->wrapVector(r1);
251 Vector3d r2 = CenterOfMass - sd2->getPos();
252 if (usePeriodicBoundaryConditions_)
253 currentSnapshot_->wrapVector(r2);
255 Vector3d rc = 0.5 * (r1 + r2);
256 if (usePeriodicBoundaryConditions_)
257 currentSnapshot_->wrapVector(rc);
259 Vector3d vec = r1 - r2;
260 if (usePeriodicBoundaryConditions_)
261 currentSnapshot_->wrapVector(vec);
265 RealType cosangle =
dot(rc, vec);
266 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
276 void P2R::processHistogram() {
277 if (count_ > 0) P2_ /= count_;
280 void P2R::writeP2R() {
281 std::ofstream ofs(outputFilename_.c_str());
285 ofs <<
"# " << getAnalysisType() <<
"\n";
286 ofs <<
"# OpenMD " << rev.getFullRevision() <<
"\n";
287 ofs <<
"# " << rev.getBuildDate() <<
"\n";
288 ofs <<
"#nFrames:\t" << nProcessed_ <<
"\n";
289 ofs <<
"#selection1: (" << selectionScript1_ <<
")";
290 if (!doVect_) { ofs <<
"\tselection2: (" << selectionScript2_ <<
")"; }
292 if (!paramString_.empty())
293 ofs <<
"# parameters: " << paramString_ <<
"\n";
295 ofs <<
"#P2 correlation:\n";
299 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
300 "P2R: unable to open %s\n", outputFilename_.c_str());
301 painCave.isFatal = 1;
308 P2Z::P2Z(SimInfo* info,
const std::string& filename,
const std::string& sele1,
309 unsigned int nbins,
int axis) :
310 P2R(info, filename, sele1, nbins),
325 setAnalysisType(
"2nd order Legendre Polynomial Correlation using " +
326 axisLabel_ +
" as reference axis");
327 setOutputName(
getPrefix(filename) +
".P2Z");
328 std::stringstream params;
329 const std::string paramString = params.str();
330 setParameterString(paramString);
333 P2Z::P2Z(SimInfo* info,
const std::string& filename,
const std::string& sele1,
334 const std::string& sele2,
unsigned int nbins,
int axis) :
335 P2R(info, filename, sele1, sele2, nbins),
350 setAnalysisType(
"2nd order Legendre Polynomial Correlation using " +
351 axisLabel_ +
" as reference axis");
352 setOutputName(
getPrefix(filename) +
".P2Z");
353 std::stringstream params;
354 const std::string paramString = params.str();
355 setParameterString(paramString);
358 P2Z::P2Z(SimInfo* info,
const std::string& filename,
const std::string& sele1,
359 int seleOffset,
unsigned int nbins,
int axis) :
360 P2R(info, filename, sele1, seleOffset, nbins),
375 setAnalysisType(
"2nd order Legendre Polynomial Correlation using " +
376 axisLabel_ +
" as reference axis");
377 setOutputName(
getPrefix(filename) +
".P2Z");
378 std::stringstream params;
379 const std::string paramString = params.str();
380 setParameterString(paramString);
383 P2Z::P2Z(SimInfo* info,
const std::string& filename,
const std::string& sele1,
384 int seleOffset,
int seleOffset2,
unsigned int nbins,
int axis) :
385 P2R(info, filename, sele1, seleOffset, seleOffset2, nbins),
400 setAnalysisType(
"2nd order Legendre Polynomial Correlation using " +
401 axisLabel_ +
" as reference axis");
402 setOutputName(
getPrefix(filename) +
".P2Z");
403 std::stringstream params;
404 const std::string paramString = params.str();
405 setParameterString(paramString);
408 void P2Z::process() {
409 Vector3d zhat = V3Zero;
416 bool usePeriodicBoundaryConditions_ =
417 info_->getSimParams()->getUsePeriodicBoundaryConditions();
419 DumpReader reader(info_, dumpFilename_);
420 int nFrames = reader.getNFrames();
422 nProcessed_ = nFrames / step_;
426 for (
int istep = 0; istep < nFrames; istep += step_) {
427 reader.readFrame(istep);
428 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
430 if (evaluator1_.isDynamic()) {
431 seleMan1_.setSelectionSet(evaluator1_.evaluate());
435 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
436 sd1 = seleMan1_.nextSelected(ii)) {
439 if (sd1->isDirectional()) {
440 Vector3d vec = sd1->getA().transpose() * V3Z;
442 RealType cosangle =
dot(zhat, vec);
444 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
450 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
451 sd1 = seleMan1_.nextSelected(ii)) {
458 int sd1Aind = sd1->getGlobalIndex() + seleOffset2_;
459 StuntDouble* sd1A = info_->getIOIndexToIntegrableObject(sd1Aind);
465 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
466 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
468 Vector3d r2 = sd2->getPos();
469 Vector3d vec = r1 - r2;
471 if (usePeriodicBoundaryConditions_)
472 currentSnapshot_->wrapVector(vec);
475 RealType cosangle =
dot(zhat, vec);
476 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
480 if (evaluator2_.isDynamic()) {
481 seleMan2_.setSelectionSet(evaluator2_.evaluate());
484 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
485 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
486 "In frame %d, the number of selected StuntDoubles are\n"
487 "\tnot the same in --sele1 and sele2\n",
489 painCave.severity = OPENMD_INFO;
490 painCave.isFatal = 0;
494 for (sd1 = seleMan1_.beginSelected(ii),
495 sd2 = seleMan2_.beginSelected(jj);
496 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
497 sd2 = seleMan2_.nextSelected(jj)) {
498 Vector3d r1 = sd1->getPos();
499 Vector3d r2 = sd2->getPos();
500 Vector3d vec = r1 - r2;
502 if (usePeriodicBoundaryConditions_)
503 currentSnapshot_->wrapVector(vec);
506 RealType cosangle =
dot(zhat, vec);
507 P2_ += 0.5 * (3.0 * cosangle * cosangle - 1.0);
void normalize()
Normalizes this vector in place.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)