48#include "applications/staticProps/SCDOrderParameter.hpp"
56#include "utils/simError.h"
60 SCDElem::SCDElem(
SimInfo* info,
const std::string& sele1,
61 const std::string& sele2,
const std::string& sele3) :
63 sele2_(sele2), sele3_(sele3) {
64 usePeriodicBoundaryConditions_ =
65 info->getSimParams()->getUsePeriodicBoundaryConditions();
67 SelectionManager seleMan1_(info);
68 SelectionManager seleMan2_(info);
69 SelectionManager seleMan3_(info);
70 SelectionEvaluator evaluator1_(info);
71 SelectionEvaluator evaluator2_(info);
72 SelectionEvaluator evaluator3_(info);
74 evaluator1_.loadScriptString(sele1_);
75 evaluator2_.loadScriptString(sele2_);
76 evaluator3_.loadScriptString(sele3_);
78 if (!evaluator1_.isDynamic()) {
79 seleMan1_.setSelectionSet(evaluator1_.evaluate());
81 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
82 "dynamic selection is not allowed\n");
83 painCave.severity = OPENMD_ERROR;
88 if (!evaluator2_.isDynamic()) {
89 seleMan2_.setSelectionSet(evaluator2_.evaluate());
91 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
92 "dynamic selection is not allowed\n");
93 painCave.severity = OPENMD_ERROR;
98 if (!evaluator3_.isDynamic()) {
99 seleMan3_.setSelectionSet(evaluator3_.evaluate());
101 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
102 "dynamic selection is not allowed\n");
103 painCave.severity = OPENMD_ERROR;
104 painCave.isFatal = 1;
108 int nselected1 = seleMan1_.getSelectionCount();
109 int nselected2 = seleMan2_.getSelectionCount();
110 int nselected3 = seleMan3_.getSelectionCount();
112 if (nselected1 != nselected2 || nselected1 != nselected3) {
113 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
114 "The number of selected Stuntdoubles must be the same\n");
115 painCave.severity = OPENMD_ERROR;
116 painCave.isFatal = 1;
126 for (sd1 = seleMan1_.beginSelected(i), sd2 = seleMan2_.beginSelected(j),
127 sd3 = seleMan3_.beginSelected(k);
128 sd1 != NULL && sd2 != NULL && sd3 != NULL;
129 sd1 = seleMan1_.nextSelected(i), sd2 = seleMan2_.nextSelected(j),
130 sd3 = seleMan3_.nextSelected(k)) {
131 tuples_.push_back(std::make_tuple(sd1, sd2, sd3));
135 RealType SCDElem::calcSCD(Snapshot* snapshot) {
136 Vector3d normal(0.0, 0.0, 1.0);
139 for (
auto& [first, second, third] : tuples_) {
141 Vector3d zAxis = third->getPos() - first->getPos();
142 if (usePeriodicBoundaryConditions_) snapshot->wrapVector(zAxis);
143 Vector3d v12 = second->getPos() - first->getPos();
144 if (usePeriodicBoundaryConditions_) snapshot->wrapVector(v12);
145 Vector3d xAxis =
cross(v12, zAxis);
146 Vector3d yAxis =
cross(zAxis, xAxis);
151 RealType cosThetaX =
dot(xAxis, normal);
152 RealType sxx = 0.5 * (3 * cosThetaX * cosThetaX - 1.0);
153 RealType cosThetaY =
dot(yAxis, normal);
154 RealType syy = 0.5 * (3 * cosThetaY * cosThetaY - 1.0);
155 scd += 2.0 / 3.0 * sxx + 1.0 / 3.0 * syy;
158 scd /= tuples_.size();
163 SCDOrderParameter::SCDOrderParameter(SimInfo* info,
164 const std::string& filename,
165 const std::string& sele1,
166 const std::string& sele2,
167 const std::string& sele3) :
168 StaticAnalyser(info, filename, 1) {
169 setOutputName(
getPrefix(filename) +
".scd");
171 scdElems_.push_back(SCDElem(info, sele1, sele2, sele3));
172 scdParam_.resize(scdElems_.size());
173 std::fill(scdParam_.begin(), scdParam_.end(), 0.0);
176 SCDOrderParameter::SCDOrderParameter(SimInfo* info,
177 const std::string& filename,
178 const std::string& molname,
179 int beginIndex,
int endIndex) :
180 StaticAnalyser(info, filename, 1) {
181 setOutputName(
getPrefix(filename) +
".scd");
183 assert(beginIndex >= 0 && endIndex >= 0 && beginIndex <= endIndex - 2);
184 for (
int i = beginIndex; i <= endIndex - 2; ++i) {
185 std::string selectionTemplate =
"select " + molname +
".";
186 std::string sele1 = selectionTemplate + OpenMD_itoa(i);
187 std::string sele2 = selectionTemplate + OpenMD_itoa(i + 1);
188 std::string sele3 = selectionTemplate + OpenMD_itoa(i + 2);
190 scdElems_.push_back(SCDElem(info, sele1, sele2, sele3));
193 scdParam_.resize(scdElems_.size());
194 std::fill(scdParam_.begin(), scdParam_.end(), 0.0);
197 void SCDOrderParameter::process() {
198 DumpReader reader(info_, dumpFilename_);
199 int nFrames = reader.getNFrames();
201 for (
int i = 0; i < nFrames; i += step_) {
203 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
205 for (std::size_t j = 0; j < scdElems_.size(); ++j) {
206 scdParam_[j] += scdElems_[j].calcSCD(currentSnapshot_);
210 int nProcessed = nFrames / step_;
211 for (std::size_t j = 0; j < scdElems_.size(); ++j) {
212 scdParam_[j] /= nProcessed;
218 void SCDOrderParameter::writeSCD() {
219 std::ofstream os(getOutputFileName().c_str());
220 os <<
"#scd parameter\n";
221 for (std::size_t i = 0; i < scdElems_.size(); ++i) {
222 os <<
"#[column " << i + 1 <<
"]\t"
223 <<
"sele1: \"" << scdElems_[i].getSelection1() <<
"\",\t"
224 <<
"sele2: \"" << scdElems_[i].getSelection2() <<
"\",\t"
225 <<
"sele3: \"" << scdElems_[i].getSelection3() <<
"\"\n";
228 for (std::size_t i = 0; i < scdElems_.size(); ++i) {
229 os << scdParam_[i] <<
"\t";
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
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)