48#include "applications/staticProps/RippleOP.hpp"
52#include "types/MultipoleAdapter.hpp"
53#include "utils/simError.h"
57 RippleOP::RippleOP(
SimInfo* info,
const std::string& filename,
58 const std::string& sele1,
const std::string& sele2) :
60 selectionScript1_(sele1), selectionScript2_(sele2), seleMan1_(info),
61 seleMan2_(info), evaluator1_(info), evaluator2_(info) {
62 setOutputName(
getPrefix(filename) +
".rp2");
64 evaluator1_.loadScriptString(sele1);
65 evaluator2_.loadScriptString(sele2);
67 if (!evaluator1_.isDynamic()) {
68 seleMan1_.setSelectionSet(evaluator1_.evaluate());
70 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
71 "--sele1 must be static selection\n");
72 painCave.severity = OPENMD_ERROR;
77 if (!evaluator2_.isDynamic()) {
78 seleMan2_.setSelectionSet(evaluator2_.evaluate());
80 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
81 "--sele2 must be static selection\n");
82 painCave.severity = OPENMD_ERROR;
87 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
89 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
90 "The number of selected Stuntdoubles are not the same in --sele1 "
92 painCave.severity = OPENMD_ERROR;
101 for (sd1 = seleMan1_.beginSelected(i), sd2 = seleMan2_.beginSelected(j);
102 sd1 != NULL && sd2 != NULL;
103 sd1 = seleMan1_.nextSelected(i), sd2 = seleMan2_.nextSelected(j)) {
104 sdPairs_.push_back(std::make_pair(sd1, sd2));
108 void RippleOP::process() {
112 bool usePeriodicBoundaryConditions_ =
113 info_->getSimParams()->getUsePeriodicBoundaryConditions();
115 DumpReader reader(info_, dumpFilename_);
116 int nFrames = reader.getNFrames();
118 for (
int i = 0; i < nFrames; i += step_) {
120 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
121 int nMolecules = info_->getNGlobalMolecules();
128 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL;
129 sd3 = seleMan2_.nextSelected(i1)) {
130 Vector3d pos1 = sd3->getPos();
131 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(pos1);
135 for (sd3 = seleMan2_.beginSelected(i1); sd3 != NULL;
136 sd3 = seleMan2_.nextSelected(i1)) {
137 Vector3d pos1 = sd3->getPos();
140 RealType avgZ = sumZ / (RealType)nMolecules;
142 Mat3x3d orderTensorHeadUpper(0.0);
143 Mat3x3d orderTensorTail(0.0);
144 Mat3x3d orderTensorHeadLower(0.0);
145 for (j1 = seleMan1_.beginSelected(i1); j1 != NULL;
146 j1 = seleMan1_.nextSelected(i1)) {
147 Vector3d pos = j1->getPos();
148 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(pos);
149 Vector3d vecHeadUpper;
150 if (pos.z() >= avgZ) {
151 AtomType* atype1 =
static_cast<Atom*
>(j1)->getAtomType();
152 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
154 vecHeadUpper = j1->getDipole();
156 vecHeadUpper = j1->getA().transpose() * V3Z;
159 Vector3d vecHeadLower;
160 if (pos.z() <= avgZ) {
161 AtomType* atype1 =
static_cast<Atom*
>(j1)->getAtomType();
162 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
164 vecHeadLower = j1->getDipole();
166 vecHeadLower = j1->getA().transpose() * V3Z;
169 orderTensorHeadUpper += outProduct(vecHeadUpper, vecHeadUpper);
170 orderTensorHeadLower += outProduct(vecHeadLower, vecHeadLower);
172 for (j2 = seleMan2_.beginSelected(i1); j2 != NULL;
173 j2 = seleMan2_.nextSelected(i1)) {
178 Vector3d vecTail = j2->getA().transpose() * V3Z;
179 orderTensorTail += outProduct(vecTail, vecTail);
183 orderTensorHeadUpper /= (RealType)nUpper;
184 orderTensorHeadLower /= (RealType)nLower;
188 orderTensorTail /= (RealType)nTail;
191 Vector3d eigenvaluesHeadUpper, eigenvaluesHeadLower, eigenvaluesTail;
192 Mat3x3d eigenvectorsHeadUpper, eigenvectorsHeadLower, eigenvectorsTail;
194 eigenvectorsHeadUpper);
196 eigenvectorsHeadLower);
199 int whichUpper(-1), whichLower(-1), whichTail(-1);
200 RealType maxEvalUpper = 0.0;
201 RealType maxEvalLower = 0.0;
202 RealType maxEvalTail = 0.0;
203 for (
int k = 0; k < 3; k++) {
204 if (fabs(eigenvaluesHeadUpper[k]) > maxEvalUpper) {
206 maxEvalUpper = fabs(eigenvaluesHeadUpper[k]);
209 RealType p2HeadUpper = 1.5 * maxEvalUpper;
210 for (
int k = 0; k < 3; k++) {
211 if (fabs(eigenvaluesHeadLower[k]) > maxEvalLower) {
213 maxEvalLower = fabs(eigenvaluesHeadLower[k]);
216 RealType p2HeadLower = 1.5 * maxEvalLower;
217 for (
int k = 0; k < 3; k++) {
218 if (fabs(eigenvaluesTail[k]) > maxEvalTail) {
220 maxEvalTail = fabs(eigenvaluesTail[k]);
223 RealType p2Tail = 1.5 * maxEvalTail;
226 Vector3d directorHeadUpper = eigenvectorsHeadUpper.getColumn(whichUpper);
227 if (directorHeadUpper[0] < 0) { directorHeadUpper.negate(); }
228 Vector3d directorHeadLower = eigenvectorsHeadLower.getColumn(whichLower);
229 if (directorHeadLower[0] < 0) { directorHeadLower.negate(); }
230 Vector3d directorTail = eigenvectorsTail.getColumn(whichTail);
231 if (directorTail[0] < 0) { directorTail.negate(); }
233 OrderParam paramHeadUpper, paramHeadLower, paramTail;
234 paramHeadUpper.p2 = p2HeadUpper;
235 paramHeadUpper.director = directorHeadUpper;
236 paramHeadLower.p2 = p2HeadLower;
237 paramHeadLower.director = directorHeadLower;
238 paramTail.p2 = p2Tail;
239 paramTail.director = directorTail;
241 orderParamsHeadUpper_.push_back(paramHeadUpper);
242 orderParamsHeadLower_.push_back(paramHeadLower);
243 orderParamsTail_.push_back(paramTail);
246 OrderParam sumOPHeadUpper, errsumOPHeadUpper;
247 OrderParam sumOPHeadLower, errsumOPHeadLower;
248 OrderParam sumOPTail, errsumOPTail;
250 sumOPHeadUpper.p2 = 0.0;
251 errsumOPHeadUpper.p2 = 0.0;
252 sumOPHeadLower.p2 = 0.0;
253 errsumOPHeadLower.p2 = 0.0;
254 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
255 sumOPHeadUpper.p2 += orderParamsHeadUpper_[i].p2;
256 sumOPHeadUpper.director[0] += orderParamsHeadUpper_[i].director[0];
257 sumOPHeadUpper.director[1] += orderParamsHeadUpper_[i].director[1];
258 sumOPHeadUpper.director[2] += orderParamsHeadUpper_[i].director[2];
262 sumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size();
263 avgOPHeadUpper.director[0] =
264 sumOPHeadUpper.director[0] / (RealType)orderParamsHeadUpper_.size();
265 avgOPHeadUpper.director[1] =
266 sumOPHeadUpper.director[1] / (RealType)orderParamsHeadUpper_.size();
267 avgOPHeadUpper.director[2] =
268 sumOPHeadUpper.director[2] / (RealType)orderParamsHeadUpper_.size();
269 for (std::size_t i = 0; i < orderParamsHeadUpper_.size(); ++i) {
270 errsumOPHeadUpper.p2 +=
271 pow((orderParamsHeadUpper_[i].p2 - avgOPHeadUpper.p2), 2);
274 sqrt(errsumOPHeadUpper.p2 / (RealType)orderParamsHeadUpper_.size());
275 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
276 sumOPHeadLower.p2 += orderParamsHeadLower_[i].p2;
277 sumOPHeadLower.director[0] += orderParamsHeadLower_[i].director[0];
278 sumOPHeadLower.director[1] += orderParamsHeadLower_[i].director[1];
279 sumOPHeadLower.director[2] += orderParamsHeadLower_[i].director[2];
283 sumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size();
284 avgOPHeadLower.director[0] =
285 sumOPHeadLower.director[0] / (RealType)orderParamsHeadLower_.size();
286 avgOPHeadLower.director[1] =
287 sumOPHeadLower.director[1] / (RealType)orderParamsHeadLower_.size();
288 avgOPHeadLower.director[2] =
289 sumOPHeadLower.director[2] / (RealType)orderParamsHeadLower_.size();
290 for (std::size_t i = 0; i < orderParamsHeadLower_.size(); ++i) {
291 errsumOPHeadLower.p2 +=
292 pow((orderParamsHeadLower_[i].p2 - avgOPHeadLower.p2), 2);
295 sqrt(errsumOPHeadLower.p2 / (RealType)orderParamsHeadLower_.size());
298 errsumOPTail.p2 = 0.0;
299 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
300 sumOPTail.p2 += orderParamsTail_[i].p2;
301 sumOPTail.director[0] += orderParamsTail_[i].director[0];
302 sumOPTail.director[1] += orderParamsTail_[i].director[1];
303 sumOPTail.director[2] += orderParamsTail_[i].director[2];
306 avgOPTail.p2 = sumOPTail.p2 / (RealType)orderParamsTail_.size();
307 avgOPTail.director[0] =
308 sumOPTail.director[0] / (RealType)orderParamsTail_.size();
309 avgOPTail.director[1] =
310 sumOPTail.director[1] / (RealType)orderParamsTail_.size();
311 avgOPTail.director[2] =
312 sumOPTail.director[2] / (RealType)orderParamsTail_.size();
313 for (std::size_t i = 0; i < orderParamsTail_.size(); ++i) {
314 errsumOPTail.p2 += pow((orderParamsTail_[i].p2 - avgOPTail.p2), 2);
316 errOPTail.p2 = sqrt(errsumOPTail.p2 / (RealType)orderParamsTail_.size());
321 void RippleOP::writeP2() {
322 std::ofstream os(getOutputFileName().c_str());
323 os <<
"#selection1: (" << selectionScript1_ <<
")\n";
324 os <<
"#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
326 os << avgOPHeadUpper.p2 <<
"\t" << errOPHeadUpper.p2 <<
"\t"
327 << avgOPHeadUpper.director[0] <<
"\t" << avgOPHeadUpper.director[1]
328 <<
"\t" << avgOPHeadUpper.director[2] <<
"\n";
330 os << avgOPHeadLower.p2 <<
"\t" << errOPHeadLower.p2 <<
"\t"
331 << avgOPHeadLower.director[0] <<
"\t" << avgOPHeadLower.director[1]
332 <<
"\t" << avgOPHeadLower.director[2] <<
"\n";
334 os <<
"selection2: (" << selectionScript2_ <<
")\n";
335 os <<
"#p2\terror\tdirector_x\tdirector_y\tdiretor_z\n";
337 os << avgOPTail.p2 <<
"\t" << errOPTail.p2 <<
"\t" << avgOPTail.director[0]
338 <<
"\t" << avgOPTail.director[1] <<
"\t" << avgOPTail.director[2]
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.
Real & z()
Returns reference of the third element of Vector3.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)