48#include "applications/staticProps/P2OrderParameter.hpp"
52#include "utils/Constants.hpp"
53#include "utils/simError.h"
58 P2OrderParameter::P2OrderParameter(
SimInfo* info,
const string& filename,
59 const string& sele1) :
61 doVect_(true), doOffset_(false), selectionScript1_(sele1),
62 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info) {
63 setOutputName(
getPrefix(filename) +
".p2");
65 evaluator1_.loadScriptString(sele1);
68 P2OrderParameter::P2OrderParameter(SimInfo* info,
const string& filename,
69 const string& sele1,
const string& sele2) :
70 StaticAnalyser(info, filename, 1),
71 doVect_(false), doOffset_(false), selectionScript1_(sele1),
72 selectionScript2_(sele2), seleMan1_(info), seleMan2_(info),
73 evaluator1_(info), evaluator2_(info) {
74 setOutputName(
getPrefix(filename) +
".p2");
76 evaluator1_.loadScriptString(sele1);
77 evaluator2_.loadScriptString(sele2);
80 P2OrderParameter::P2OrderParameter(SimInfo* info,
const string& filename,
81 const string& sele1,
int seleOffset) :
82 StaticAnalyser(info, filename, 1),
83 doVect_(false), doOffset_(true), selectionScript1_(sele1),
84 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info),
85 seleOffset_(seleOffset) {
86 setOutputName(
getPrefix(filename) +
".p2");
88 evaluator1_.loadScriptString(sele1);
91 void P2OrderParameter::process() {
97 bool usePeriodicBoundaryConditions_ =
98 info_->getSimParams()->getUsePeriodicBoundaryConditions();
100 DumpReader reader(info_, dumpFilename_);
101 int nFrames = reader.getNFrames();
103 for (
int i = 0; i < nFrames; i += step_) {
105 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
107 Mat3x3d orderTensor(0.0);
110 seleMan1_.setSelectionSet(evaluator1_.evaluate());
113 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
114 sd1 = seleMan1_.nextSelected(ii)) {
115 if (sd1->isDirectional()) {
116 Vector3d vec = sd1->getA().transpose() * V3Z;
119 orderTensor += outProduct(vec, vec);
124 orderTensor /= vecCount;
128 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
129 sd1 = seleMan1_.nextSelected(ii)) {
134 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
135 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
137 Vector3d vec = sd1->getPos() - sd2->getPos();
139 if (usePeriodicBoundaryConditions_)
140 currentSnapshot_->wrapVector(vec);
144 orderTensor += outProduct(vec, vec);
148 orderTensor /= vecCount;
150 seleMan2_.setSelectionSet(evaluator2_.evaluate());
152 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
153 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
154 "In frame %d, the number of selected StuntDoubles are\n"
155 "\tnot the same in --sele1 and sele2\n",
157 painCave.severity = OPENMD_INFO;
158 painCave.isFatal = 0;
162 for (sd1 = seleMan1_.beginSelected(ii),
163 sd2 = seleMan2_.beginSelected(jj);
164 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
165 sd2 = seleMan2_.nextSelected(jj)) {
166 Vector3d vec = sd1->getPos() - sd2->getPos();
168 if (usePeriodicBoundaryConditions_)
169 currentSnapshot_->wrapVector(vec);
173 orderTensor += outProduct(vec, vec);
177 orderTensor /= vecCount;
182 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
183 "In frame %d, the number of selected vectors was zero.\n"
184 "\tThis will not give a meaningful order parameter.",
186 painCave.severity = OPENMD_ERROR;
187 painCave.isFatal = 1;
193 Vector3d eigenvalues;
194 Mat3x3d eigenvectors;
199 RealType maxEval = 0.0;
200 for (
int k = 0; k < 3; k++) {
201 if (fabs(eigenvalues[k]) > maxEval) {
203 maxEval = fabs(eigenvalues[k]);
206 RealType p2 = 1.5 * maxEval;
209 Vector3d director = eigenvectors.getColumn(which);
212 RealType angle = 0.0;
216 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
217 sd1 = seleMan1_.nextSelected(ii)) {
218 if (sd1->isDirectional()) {
219 Vector3d vec = sd1->getA().transpose() * V3Z;
221 angle += acos(
dot(vec, director));
225 angle = angle / (vecCount * Constants::PI) * 180.0;
229 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
230 sd1 = seleMan1_.nextSelected(ii)) {
235 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
236 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
238 Vector3d vec = sd1->getPos() - sd2->getPos();
239 if (usePeriodicBoundaryConditions_)
240 currentSnapshot_->wrapVector(vec);
242 angle += acos(
dot(vec, director));
245 angle = angle / (vecCount * Constants::PI) * 180.0;
248 for (sd1 = seleMan1_.beginSelected(ii),
249 sd2 = seleMan2_.beginSelected(jj);
250 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
251 sd2 = seleMan2_.nextSelected(jj)) {
252 Vector3d vec = sd1->getPos() - sd2->getPos();
253 if (usePeriodicBoundaryConditions_)
254 currentSnapshot_->wrapVector(vec);
256 angle += acos(
dot(vec, director));
259 angle = angle / (vecCount * Constants::PI) * 180.0;
265 param.director = director;
268 orderParams_.push_back(param);
274 void P2OrderParameter::writeP2() {
275 ofstream os(getOutputFileName().c_str());
276 os <<
"#P2 Order parameter\n";
277 os <<
"#selection1: (" << selectionScript1_ <<
")\t";
278 if (!doVect_) { os <<
"selection2: (" << selectionScript2_ <<
")\n"; }
279 os <<
"#p2\tdirector_x\tdirector_y\tdirector_z\tangle(degree)\n";
282 RealType angleSum {};
283 Vector3d directorSum(0.0);
285 for (
size_t i = 0; i < orderParams_.size(); ++i) {
286 p2Sum += orderParams_[i].p2;
287 directorSum += orderParams_[i].director;
288 angleSum += orderParams_[i].angle;
291 p2Sum /= orderParams_.size();
292 directorSum /= orderParams_.size();
293 angleSum /= orderParams_.size();
295 os << p2Sum <<
"\t" << directorSum[0] <<
"\t" << directorSum[1] <<
"\t"
296 << directorSum[2] <<
"\t" << angleSum <<
"\n";
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
static SquareMatrix< Real, Dim > identity()
Returns an identity matrix.
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)