45#include "applications/staticProps/RippleOP.hpp"
49#include "types/MultipoleAdapter.hpp"
50#include "utils/simError.h"
54 RippleOP::RippleOP(SimInfo* info,
const std::string& filename,
55 const std::string& sele1,
const std::string& sele2) :
56 StaticAnalyser(info, filename, 1),
57 selectionScript1_(sele1), selectionScript2_(sele2), seleMan1_(info),
58 seleMan2_(info), evaluator1_(info), evaluator2_(info) {
59 setOutputName(
getPrefix(filename) +
".rp2");
61 evaluator1_.loadScriptString(sele1);
62 evaluator2_.loadScriptString(sele2);
64 if (!evaluator1_.isDynamic()) {
65 seleMan1_.setSelectionSet(evaluator1_.evaluate());
67 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
68 "--sele1 must be static selection\n");
69 painCave.severity = OPENMD_ERROR;
74 if (!evaluator2_.isDynamic()) {
75 seleMan2_.setSelectionSet(evaluator2_.evaluate());
77 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
78 "--sele2 must be static selection\n");
79 painCave.severity = OPENMD_ERROR;
84 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
86 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
87 "The number of selected Stuntdoubles are not the same in --sele1 "
89 painCave.severity = OPENMD_ERROR;
98 for (sd1 = seleMan1_.beginSelected(i), sd2 = seleMan2_.beginSelected(j);
99 sd1 != NULL && sd2 != NULL;
100 sd1 = seleMan1_.nextSelected(i), sd2 = seleMan2_.nextSelected(j)) {
101 sdPairs_.push_back(std::make_pair(sd1, sd2));
105 void RippleOP::process() {
109 bool usePeriodicBoundaryConditions_ =
110 info_->getSimParams()->getUsePeriodicBoundaryConditions();
112 DumpReader reader(info_, dumpFilename_);
113 int nFrames = reader.getNFrames();
115 for (
int i = 0; i < nFrames; i += step_) {
117 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
118 int nMolecules = info_->getNGlobalMolecules();
125 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL;
126 sd3 = seleMan2_.nextSelected(i1)) {
127 Vector3d pos1 = sd3->getPos();
128 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(pos1);
132 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL;
133 sd3 = seleMan2_.nextSelected(i1)) {
134 Vector3d pos1 = sd3->getPos();
137 RealType avgZ = sumZ / (RealType)nMolecules;
139 Mat3x3d orderTensorHeadUpper(0.0);
140 Mat3x3d orderTensorTail(0.0);
141 Mat3x3d orderTensorHeadLower(0.0);
142 for (j1 = seleMan1_.beginSelected(i1); j1 != NULL;
143 j1 = seleMan1_.nextSelected(i1)) {
144 Vector3d pos = j1->getPos();
145 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(pos);
146 Vector3d vecHeadUpper;
147 if (pos.z() >= avgZ) {
148 AtomType* atype1 =
static_cast<Atom*
>(j1)->getAtomType();
149 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
151 vecHeadUpper = j1->getDipole();
153 vecHeadUpper = j1->getA().transpose() * V3Z;
156 Vector3d vecHeadLower;
157 if (pos.z() <= avgZ) {
158 AtomType* atype1 =
static_cast<Atom*
>(j1)->getAtomType();
159 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
161 vecHeadLower = j1->getDipole();
163 vecHeadLower = j1->getA().transpose() * V3Z;
166 orderTensorHeadUpper += outProduct(vecHeadUpper, vecHeadUpper);
167 orderTensorHeadLower += outProduct(vecHeadLower, vecHeadLower);
169 for (j2 = seleMan2_.beginSelected(i1); j2 != NULL;
170 j2 = seleMan2_.nextSelected(i1)) {
175 Vector3d vecTail = j2->getA().transpose() * V3Z;
176 orderTensorTail += outProduct(vecTail, vecTail);
180 orderTensorHeadUpper /= (RealType)nUpper;
181 orderTensorHeadLower /= (RealType)nLower;
182 orderTensorHeadUpper -= (RealType)(1.0 / 3.0) * Mat3x3d::identity();
183 orderTensorHeadLower -= (RealType)(1.0 / 3.0) * Mat3x3d::identity();
185 orderTensorTail /= (RealType)nTail;
186 orderTensorTail -= (RealType)(1.0 / 3.0) * Mat3x3d::identity();
188 Vector3d eigenvaluesHeadUpper, eigenvaluesHeadLower, eigenvaluesTail;
189 Mat3x3d eigenvectorsHeadUpper, eigenvectorsHeadLower, eigenvectorsTail;
190 Mat3x3d::diagonalize(orderTensorHeadUpper, eigenvaluesHeadUpper,
191 eigenvectorsHeadUpper);
192 Mat3x3d::diagonalize(orderTensorHeadLower, eigenvaluesHeadLower,
193 eigenvectorsHeadLower);
194 Mat3x3d::diagonalize(orderTensorTail, eigenvaluesTail, eigenvectorsTail);
196 int whichUpper(-1), whichLower(-1), whichTail(-1);
197 RealType maxEvalUpper = 0.0;
198 RealType maxEvalLower = 0.0;
199 RealType maxEvalTail = 0.0;
200 for (
int k = 0; k < 3; k++) {
201 if (fabs(eigenvaluesHeadUpper[k]) > maxEvalUpper) {
203 maxEvalUpper = fabs(eigenvaluesHeadUpper[k]);
206 RealType p2HeadUpper = 1.5 * maxEvalUpper;
207 for (
int k = 0; k < 3; k++) {
208 if (fabs(eigenvaluesHeadLower[k]) > maxEvalLower) {
210 maxEvalLower = fabs(eigenvaluesHeadLower[k]);
213 RealType p2HeadLower = 1.5 * maxEvalLower;
214 for (
int k = 0; k < 3; k++) {
215 if (fabs(eigenvaluesTail[k]) > maxEvalTail) {
217 maxEvalTail = fabs(eigenvaluesTail[k]);
220 RealType p2Tail = 1.5 * maxEvalTail;
223 Vector3d directorHeadUpper = eigenvectorsHeadUpper.getColumn(whichUpper);
224 if (directorHeadUpper[0] < 0) { directorHeadUpper.
negate(); }
225 Vector3d directorHeadLower = eigenvectorsHeadLower.getColumn(whichLower);
226 if (directorHeadLower[0] < 0) { directorHeadLower.
negate(); }
227 Vector3d directorTail = eigenvectorsTail.getColumn(whichTail);
228 if (directorTail[0] < 0) { directorTail.
negate(); }
230 OrderParam paramHeadUpper, paramHeadLower, paramTail;
231 paramHeadUpper.p2 = p2HeadUpper;
232 paramHeadUpper.director = directorHeadUpper;
233 paramHeadLower.p2 = p2HeadLower;
234 paramHeadLower.director = directorHeadLower;
235 paramTail.p2 = p2Tail;
236 paramTail.director = directorTail;
238 orderParamsHeadUpper_.push_back(paramHeadUpper);
239 orderParamsHeadLower_.push_back(paramHeadLower);
240 orderParamsTail_.push_back(paramTail);
243 OrderParam sumOPHeadUpper, errsumOPHeadUpper;
244 OrderParam sumOPHeadLower, errsumOPHeadLower;
245 OrderParam sumOPTail, errsumOPTail;
247 sumOPHeadUpper.p2 = 0.0;
248 errsumOPHeadUpper.p2 = 0.0;
249 sumOPHeadLower.p2 = 0.0;
250 errsumOPHeadLower.p2 = 0.0;
251 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
252 sumOPHeadUpper.p2 += orderParamsHeadUpper_[i].p2;
253 sumOPHeadUpper.director[0] += orderParamsHeadUpper_[i].director[0];
254 sumOPHeadUpper.director[1] += orderParamsHeadUpper_[i].director[1];
255 sumOPHeadUpper.director[2] += orderParamsHeadUpper_[i].director[2];
259 sumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size();
260 avgOPHeadUpper.director[0] =
261 sumOPHeadUpper.director[0] / (RealType)orderParamsHeadUpper_.size();
262 avgOPHeadUpper.director[1] =
263 sumOPHeadUpper.director[1] / (RealType)orderParamsHeadUpper_.size();
264 avgOPHeadUpper.director[2] =
265 sumOPHeadUpper.director[2] / (RealType)orderParamsHeadUpper_.size();
266 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
267 errsumOPHeadUpper.p2 +=
268 pow((orderParamsHeadUpper_[i].p2 - avgOPHeadUpper.p2), 2);
271 sqrt(errsumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size());
272 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
273 sumOPHeadLower.p2 += orderParamsHeadLower_[i].p2;
274 sumOPHeadLower.director[0] += orderParamsHeadLower_[i].director[0];
275 sumOPHeadLower.director[1] += orderParamsHeadLower_[i].director[1];
276 sumOPHeadLower.director[2] += orderParamsHeadLower_[i].director[2];
280 sumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size();
281 avgOPHeadLower.director[0] =
282 sumOPHeadLower.director[0] / (RealType)orderParamsHeadLower_.size();
283 avgOPHeadLower.director[1] =
284 sumOPHeadLower.director[1] / (RealType)orderParamsHeadLower_.size();
285 avgOPHeadLower.director[2] =
286 sumOPHeadLower.director[2] / (RealType)orderParamsHeadLower_.size();
287 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
288 errsumOPHeadLower.p2 +=
289 pow((orderParamsHeadLower_[i].p2 - avgOPHeadLower.p2), 2);
292 sqrt(errsumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size());
295 errsumOPTail.p2 = 0.0;
296 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
297 sumOPTail.p2 += orderParamsTail_[i].p2;
298 sumOPTail.director[0] += orderParamsTail_[i].director[0];
299 sumOPTail.director[1] += orderParamsTail_[i].director[1];
300 sumOPTail.director[2] += orderParamsTail_[i].director[2];
303 avgOPTail.p2 = sumOPTail.p2 / (RealType)orderParamsTail_.size();
304 avgOPTail.director[0] =
305 sumOPTail.director[0] / (RealType)orderParamsTail_.size();
306 avgOPTail.director[1] =
307 sumOPTail.director[1] / (RealType)orderParamsTail_.size();
308 avgOPTail.director[2] =
309 sumOPTail.director[2] / (RealType)orderParamsTail_.size();
310 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
311 errsumOPTail.p2 += pow((orderParamsTail_[i].p2 - avgOPTail.p2), 2);
313 errOPTail.p2 = sqrt(errsumOPTail.p2 / (RealType)orderParamsTail_.size());
318 void RippleOP::writeP2() {
319 std::ofstream os(getOutputFileName().c_str());
320 os <<
"#selection1: (" << selectionScript1_ <<
")\n";
321 os <<
"#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
323 os << avgOPHeadUpper.p2 <<
"\t" << errOPHeadUpper.p2 <<
"\t"
324 << avgOPHeadUpper.director[0] <<
"\t" << avgOPHeadUpper.director[1]
325 <<
"\t" << avgOPHeadUpper.director[2] <<
"\n";
327 os << avgOPHeadLower.p2 <<
"\t" << errOPHeadLower.p2 <<
"\t"
328 << avgOPHeadLower.director[0] <<
"\t" << avgOPHeadLower.director[1]
329 <<
"\t" << avgOPHeadLower.director[2] <<
"\n";
331 os <<
"selection2: (" << selectionScript2_ <<
")\n";
332 os <<
"#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
334 os << avgOPTail.p2 <<
"\t" << errOPTail.p2 <<
"\t" << avgOPTail.director[0]
335 <<
"\t" << avgOPTail.director[1] <<
"\t" << avgOPTail.director[2]
Real & z()
Returns reference of the third element of Vector3.
void negate()
Negates the value of this vector in place.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)