45#include "applications/staticProps/SCDOrderParameter.hpp"
53#include "utils/simError.h"
57 SCDElem::SCDElem(SimInfo* info,
const std::string& sele1,
58 const std::string& sele2,
const std::string& sele3) :
60 sele2_(sele2), sele3_(sele3) {
61 usePeriodicBoundaryConditions_ =
62 info->getSimParams()->getUsePeriodicBoundaryConditions();
64 SelectionManager seleMan1_(info);
65 SelectionManager seleMan2_(info);
66 SelectionManager seleMan3_(info);
67 SelectionEvaluator evaluator1_(info);
68 SelectionEvaluator evaluator2_(info);
69 SelectionEvaluator evaluator3_(info);
71 evaluator1_.loadScriptString(sele1_);
72 evaluator2_.loadScriptString(sele2_);
73 evaluator3_.loadScriptString(sele3_);
75 if (!evaluator1_.isDynamic()) {
76 seleMan1_.setSelectionSet(evaluator1_.evaluate());
78 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
79 "dynamic selection is not allowed\n");
80 painCave.severity = OPENMD_ERROR;
85 if (!evaluator2_.isDynamic()) {
86 seleMan2_.setSelectionSet(evaluator2_.evaluate());
88 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
89 "dynamic selection is not allowed\n");
90 painCave.severity = OPENMD_ERROR;
95 if (!evaluator3_.isDynamic()) {
96 seleMan3_.setSelectionSet(evaluator3_.evaluate());
98 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
99 "dynamic selection is not allowed\n");
100 painCave.severity = OPENMD_ERROR;
101 painCave.isFatal = 1;
105 int nselected1 = seleMan1_.getSelectionCount();
106 int nselected2 = seleMan2_.getSelectionCount();
107 int nselected3 = seleMan3_.getSelectionCount();
109 if (nselected1 != nselected2 || nselected1 != nselected3) {
110 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
111 "The number of selected Stuntdoubles must be the same\n");
112 painCave.severity = OPENMD_ERROR;
113 painCave.isFatal = 1;
123 for (sd1 = seleMan1_.beginSelected(i), sd2 = seleMan2_.beginSelected(j),
124 sd3 = seleMan3_.beginSelected(k);
125 sd1 != NULL && sd2 != NULL && sd3 != NULL;
126 sd1 = seleMan1_.nextSelected(i), sd2 = seleMan2_.nextSelected(j),
127 sd3 = seleMan3_.nextSelected(k)) {
128 tuples_.push_back(std::make_tuple(sd1, sd2, sd3));
132 RealType SCDElem::calcSCD(Snapshot* snapshot) {
133 Vector3d normal(0.0, 0.0, 1.0);
136 for (
auto& [first, second, third] : tuples_) {
138 Vector3d zAxis = third->getPos() - first->getPos();
139 if (usePeriodicBoundaryConditions_) snapshot->wrapVector(zAxis);
140 Vector3d v12 = second->getPos() - first->getPos();
141 if (usePeriodicBoundaryConditions_) snapshot->wrapVector(v12);
142 Vector3d xAxis =
cross(v12, zAxis);
143 Vector3d yAxis =
cross(zAxis, xAxis);
148 RealType cosThetaX =
dot(xAxis, normal);
149 RealType sxx = 0.5 * (3 * cosThetaX * cosThetaX - 1.0);
150 RealType cosThetaY =
dot(yAxis, normal);
151 RealType syy = 0.5 * (3 * cosThetaY * cosThetaY - 1.0);
152 scd += 2.0 / 3.0 * sxx + 1.0 / 3.0 * syy;
155 scd /= tuples_.size();
160 SCDOrderParameter::SCDOrderParameter(SimInfo* info,
161 const std::string& filename,
162 const std::string& sele1,
163 const std::string& sele2,
164 const std::string& sele3) :
165 StaticAnalyser(info, filename, 1) {
166 setOutputName(
getPrefix(filename) +
".scd");
168 scdElems_.push_back(SCDElem(info, sele1, sele2, sele3));
169 scdParam_.resize(scdElems_.size());
170 std::fill(scdParam_.begin(), scdParam_.end(), 0.0);
173 SCDOrderParameter::SCDOrderParameter(SimInfo* info,
174 const std::string& filename,
175 const std::string& molname,
176 int beginIndex,
int endIndex) :
177 StaticAnalyser(info, filename, 1) {
178 setOutputName(
getPrefix(filename) +
".scd");
180 assert(beginIndex >= 0 && endIndex >= 0 && beginIndex <= endIndex - 2);
181 for (
int i = beginIndex; i <= endIndex - 2; ++i) {
182 std::string selectionTemplate =
"select " + molname +
".";
183 std::string sele1 = selectionTemplate + OpenMD_itoa(i);
184 std::string sele2 = selectionTemplate + OpenMD_itoa(i + 1);
185 std::string sele3 = selectionTemplate + OpenMD_itoa(i + 2);
187 scdElems_.push_back(SCDElem(info, sele1, sele2, sele3));
190 scdParam_.resize(scdElems_.size());
191 std::fill(scdParam_.begin(), scdParam_.end(), 0.0);
194 void SCDOrderParameter::process() {
195 DumpReader reader(info_, dumpFilename_);
196 int nFrames = reader.getNFrames();
198 for (
int i = 0; i < nFrames; i += step_) {
200 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
202 for (std::size_t j = 0; j < scdElems_.size(); ++j) {
203 scdParam_[j] += scdElems_[j].calcSCD(currentSnapshot_);
207 int nProcessed = nFrames / step_;
208 for (std::size_t j = 0; j < scdElems_.size(); ++j) {
209 scdParam_[j] /= nProcessed;
215 void SCDOrderParameter::writeSCD() {
216 std::ofstream os(getOutputFileName().c_str());
217 os <<
"#scd parameter\n";
218 for (std::size_t i = 0; i < scdElems_.size(); ++i) {
219 os <<
"#[column " << i + 1 <<
"]\t"
220 <<
"sele1: \"" << scdElems_[i].getSelection1() <<
"\",\t"
221 <<
"sele2: \"" << scdElems_[i].getSelection2() <<
"\",\t"
222 <<
"sele3: \"" << scdElems_[i].getSelection3() <<
"\"\n";
225 for (std::size_t i = 0; i < scdElems_.size(); ++i) {
226 os << scdParam_[i] <<
"\t";
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Vector3< Real > cross(const Vector3< Real > &v1, const Vector3< Real > &v2)
Returns the cross product of two Vectors.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)