45#include "applications/staticProps/P2OrderParameter.hpp"
49#include "utils/Constants.hpp"
50#include "utils/simError.h"
55 P2OrderParameter::P2OrderParameter(SimInfo* info,
const string& filename,
56 const string& sele1) :
57 StaticAnalyser(info, filename, 1),
58 doVect_(true), doOffset_(false), selectionScript1_(sele1),
59 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info) {
60 setOutputName(
getPrefix(filename) +
".p2");
62 evaluator1_.loadScriptString(sele1);
65 P2OrderParameter::P2OrderParameter(SimInfo* info,
const string& filename,
66 const string& sele1,
const string& sele2) :
67 StaticAnalyser(info, filename, 1),
68 doVect_(false), doOffset_(false), selectionScript1_(sele1),
69 selectionScript2_(sele2), seleMan1_(info), seleMan2_(info),
70 evaluator1_(info), evaluator2_(info) {
71 setOutputName(
getPrefix(filename) +
".p2");
73 evaluator1_.loadScriptString(sele1);
74 evaluator2_.loadScriptString(sele2);
77 P2OrderParameter::P2OrderParameter(SimInfo* info,
const string& filename,
78 const string& sele1,
int seleOffset) :
79 StaticAnalyser(info, filename, 1),
80 doVect_(false), doOffset_(true), selectionScript1_(sele1),
81 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info),
82 seleOffset_(seleOffset) {
83 setOutputName(
getPrefix(filename) +
".p2");
85 evaluator1_.loadScriptString(sele1);
88 void P2OrderParameter::process() {
94 bool usePeriodicBoundaryConditions_ =
95 info_->getSimParams()->getUsePeriodicBoundaryConditions();
97 DumpReader reader(info_, dumpFilename_);
98 int nFrames = reader.getNFrames();
100 for (
int i = 0; i < nFrames; i += step_) {
102 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
104 Mat3x3d orderTensor(0.0);
107 seleMan1_.setSelectionSet(evaluator1_.evaluate());
110 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
111 sd1 = seleMan1_.nextSelected(ii)) {
112 if (sd1->isDirectional()) {
113 Vector3d vec = sd1->getA().transpose() * V3Z;
116 orderTensor += outProduct(vec, vec);
121 orderTensor /= vecCount;
125 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
126 sd1 = seleMan1_.nextSelected(ii)) {
131 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
132 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
134 Vector3d vec = sd1->getPos() - sd2->getPos();
136 if (usePeriodicBoundaryConditions_)
137 currentSnapshot_->wrapVector(vec);
141 orderTensor += outProduct(vec, vec);
145 orderTensor /= vecCount;
147 seleMan2_.setSelectionSet(evaluator2_.evaluate());
149 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
150 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
151 "In frame %d, the number of selected StuntDoubles are\n"
152 "\tnot the same in --sele1 and sele2\n",
154 painCave.severity = OPENMD_INFO;
155 painCave.isFatal = 0;
159 for (sd1 = seleMan1_.beginSelected(ii),
160 sd2 = seleMan2_.beginSelected(jj);
161 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
162 sd2 = seleMan2_.nextSelected(jj)) {
163 Vector3d vec = sd1->getPos() - sd2->getPos();
165 if (usePeriodicBoundaryConditions_)
166 currentSnapshot_->wrapVector(vec);
170 orderTensor += outProduct(vec, vec);
174 orderTensor /= vecCount;
179 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
180 "In frame %d, the number of selected vectors was zero.\n"
181 "\tThis will not give a meaningful order parameter.",
183 painCave.severity = OPENMD_ERROR;
184 painCave.isFatal = 1;
188 orderTensor -= (RealType)(1.0 / 3.0) * Mat3x3d::identity();
190 Vector3d eigenvalues;
191 Mat3x3d eigenvectors;
193 Mat3x3d::diagonalize(orderTensor, eigenvalues, eigenvectors);
196 RealType maxEval = 0.0;
197 for (
int k = 0; k < 3; k++) {
198 if (fabs(eigenvalues[k]) > maxEval) {
200 maxEval = fabs(eigenvalues[k]);
203 RealType p2 = 1.5 * maxEval;
206 Vector3d director = eigenvectors.getColumn(which);
209 RealType angle = 0.0;
213 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
214 sd1 = seleMan1_.nextSelected(ii)) {
215 if (sd1->isDirectional()) {
216 Vector3d vec = sd1->getA().transpose() * V3Z;
218 angle += acos(
dot(vec, director));
222 angle = angle / (vecCount * Constants::PI) * 180.0;
226 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
227 sd1 = seleMan1_.nextSelected(ii)) {
232 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
233 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
235 Vector3d vec = sd1->getPos() - sd2->getPos();
236 if (usePeriodicBoundaryConditions_)
237 currentSnapshot_->wrapVector(vec);
239 angle += acos(
dot(vec, director));
242 angle = angle / (vecCount * Constants::PI) * 180.0;
245 for (sd1 = seleMan1_.beginSelected(ii),
246 sd2 = seleMan2_.beginSelected(jj);
247 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
248 sd2 = seleMan2_.nextSelected(jj)) {
249 Vector3d vec = sd1->getPos() - sd2->getPos();
250 if (usePeriodicBoundaryConditions_)
251 currentSnapshot_->wrapVector(vec);
253 angle += acos(
dot(vec, director));
256 angle = angle / (vecCount * Constants::PI) * 180.0;
262 param.director = director;
265 orderParams_.push_back(param);
271 void P2OrderParameter::writeP2() {
272 ofstream os(getOutputFileName().c_str());
273 os <<
"#P2 Order parameter\n";
274 os <<
"#selection1: (" << selectionScript1_ <<
")\t";
275 if (!doVect_) { os <<
"selection2: (" << selectionScript2_ <<
")\n"; }
276 os <<
"#p2\tdirector_x\tdirector_y\tdirector_z\tangle(degree)\n";
279 RealType angleSum {};
280 Vector3d directorSum(0.0);
282 for (
size_t i = 0; i < orderParams_.size(); ++i) {
283 p2Sum += orderParams_[i].p2;
284 directorSum += orderParams_[i].director;
285 angleSum += orderParams_[i].angle;
288 p2Sum /= orderParams_.size();
289 directorSum /= orderParams_.size();
290 angleSum /= orderParams_.size();
292 os << p2Sum <<
"\t" << directorSum[0] <<
"\t" << directorSum[1] <<
"\t"
293 << directorSum[2] <<
"\t" << angleSum <<
"\n";
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)