48#include "applications/dynamicProps/cOHz.hpp"
53#include "utils/Revision.hpp"
54#include "utils/simError.h"
57 COHZ::COHZ(
SimInfo* info,
const std::string& filename,
58 const std::string& sele1,
const std::string& sele2,
int order,
59 int nZbins,
int axis) :
61 nZBins_(nZbins), axis_(axis) {
62 setCorrFuncType(
"Legendre Correlation Function");
63 setOutputName(
getPrefix(dumpFilename_) +
".lcorr");
65 std::stringstream params;
66 params <<
" order = " << order <<
", nzbins = " << nZBins_;
67 const std::string paramString = params.str();
68 setParameterString(paramString);
70 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
73 xaxis_ = (axis_ + 1) % 3;
74 yaxis_ = (axis_ + 2) % 3;
89 rotMats_.resize(nTimeBins_);
90 zbin_.resize(nTimeBins_);
91 histogram_.resize(nTimeBins_);
92 counts_.resize(nTimeBins_);
93 for (
unsigned int i = 0; i < nTimeBins_; i++) {
94 histogram_[i].resize(nZBins_);
95 std::fill(histogram_[i].begin(), histogram_[i].end(),
96 Vector<RealType, 4>(0.0));
97 counts_[i].resize(nZBins_);
98 std::fill(counts_[i].begin(), counts_[i].end(), 0);
100 LegendrePolynomial polynomial(order);
101 legendre_ = polynomial.getLegendrePolynomial(order);
104 void COHZ::computeFrame(
int frame) {
105 Mat3x3d hmat = currentSnapshot_->getHmat();
106 boxZ_ = hmat(axis_, axis_);
107 halfBoxZ_ = boxZ_ / 2.0;
109 MoleculeACF<Vector<RealType, 4>>::computeFrame(frame);
112 int COHZ::computeProperty1(
int frame, Molecule* mol) {
113 RotMat3x3d A = mol->getRigidBodyAt(0)->getA();
114 rotMats_[frame].push_back(A);
116 Vector3d pos = mol->getCom();
117 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
118 currentSnapshot_->wrapVector(pos);
119 int zBin = int(nZBins_ * (halfBoxZ_ + pos[axis_]) / boxZ_);
120 zbin_[frame].push_back(zBin);
122 return rotMats_[frame].size() - 1;
125 Vector<RealType, 4> COHZ::calcCorrVal(
int frame1,
int frame2,
int id1,
145 Vector3d v1y = rotMats_[frame1][id1].getRow(yaxis_);
146 Vector3d v1z = rotMats_[frame1][id1].getRow(axis_);
148 Vector3d v2y = rotMats_[frame2][id2].getRow(yaxis_);
149 Vector3d v2z = rotMats_[frame2][id2].getRow(axis_);
151 Vector3d u1 = 0.81649 * v1y + 0.57736 * v1z;
152 Vector3d u2 = 0.81649 * v2y + 0.57736 * v2z;
154 Vector3d w1 = -0.81649 * v1y + 0.57736 * v1z;
155 Vector3d w2 = -0.81649 * v2y + 0.57736 * v2z;
157 Vector3d h1 = 1.63298 * v1y;
158 Vector3d h2 = 1.63298 * v2y;
161 Vector<RealType, 4> r(0.0);
162 r[0] = legendre_.evaluate(
dot(v1z, v2z) / (v1z.length() * v2z.length()));
163 r[1] = legendre_.evaluate(
dot(u1, u2) / (u1.length() * u2.length()));
164 r[2] = legendre_.evaluate(
dot(w1, w2) / (w1.length() * w2.length()));
165 r[3] = legendre_.evaluate(
dot(h1, h2) / (h1.length() * h2.length()));
169 void COHZ::correlateFrames(
int frame1,
int frame2,
int timeBin) {
173 std::vector<int>::iterator i1;
174 std::vector<int>::iterator i2;
176 Vector<RealType, 4> corrVal(0.0);
178 s1 = sele1ToIndex_[frame1];
180 if (uniqueSelections_)
181 s2 = sele2ToIndex_[frame2];
183 s2 = sele1ToIndex_[frame2];
185 for (i1 = s1.begin(), i2 = s2.begin(); i1 != s1.end() && i2 != s2.end();
192 while (i1 != s1.end() && *i1 < *i2) {
196 while (i2 != s2.end() && *i2 < *i1) {
200 if (i1 == s1.end() || i2 == s2.end())
break;
202 corrVal = calcCorrVal(frame1, frame2, i1 - s1.begin(), i2 - s2.begin());
203 int zBin = zbin_[frame1][i1 - s1.begin()];
205 histogram_[timeBin][zBin] += corrVal;
206 counts_[timeBin][zBin]++;
210 void COHZ::postCorrelate() {
211 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
212 for (
unsigned int j = 0; j < nZBins_; ++j) {
213 if (counts_[i][j] > 0) { histogram_[i][j] /= counts_[i][j]; }
218 void COHZ::validateSelection(SelectionManager&) {
221 for (mol = seleMan1_.beginSelectedMolecule(i); mol != NULL;
222 mol = seleMan1_.nextSelectedMolecule(i)) {
223 if (mol->getNRigidBodies() < 1) {
224 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
225 "COHZ::validateSelection Error: "
226 "at least one selected molecule does not have a rigid body\n");
227 painCave.isFatal = 1;
233 void COHZ::writeCorrelate() {
234 std::string Dfile = getOutputFileName() +
"D";
235 std::string OHfile = getOutputFileName() +
"OH";
236 std::string HHfile = getOutputFileName() +
"HH";
238 std::ofstream ofs1(Dfile.c_str());
239 std::ofstream ofs2(OHfile.c_str());
240 std::ofstream ofs3(HHfile.c_str());
242 if (ofs1.is_open()) {
245 ofs1 <<
"# " << getCorrFuncType() <<
" for dipole vectors in water\n";
246 ofs1 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
247 ofs1 <<
"# " << r.getBuildDate() <<
"\n";
248 ofs1 <<
"# selection script1: \"" << selectionScript1_;
249 ofs1 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
250 ofs1 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
251 if (!paramString_.empty())
252 ofs1 <<
"# parameters: " << paramString_ <<
"\n";
254 ofs1 <<
"#time\tPn(costheta_z)\n";
256 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
257 ofs1 << times_[i] - times_[0];
259 for (
unsigned int j = 0; j < nZBins_; ++j) {
260 ofs1 <<
"\t" << histogram_[i][j][0];
266 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
267 "COHz::writeCorrelate Error: failed to open %s\n",
269 painCave.isFatal = 1;
274 if (ofs2.is_open()) {
277 ofs2 <<
"# " << getCorrFuncType() <<
" for OH bond vectors in water\n";
278 ofs2 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
279 ofs2 <<
"# " << r.getBuildDate() <<
"\n";
280 ofs2 <<
"# selection script1: \"" << selectionScript1_;
281 ofs2 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
282 ofs2 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
283 if (!paramString_.empty())
284 ofs2 <<
"# parameters: " << paramString_ <<
"\n";
286 ofs2 <<
"#time\tPn(costheta_z)\n";
288 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
289 ofs2 << times_[i] - times_[0];
291 for (
unsigned int j = 0; j < nZBins_; ++j) {
292 ofs2 <<
"\t" << 0.5 * (histogram_[i][j][1] + histogram_[i][j][2]);
298 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
299 "COHz::writeCorrelate Error: failed to open %s\n",
301 painCave.isFatal = 1;
306 if (ofs3.is_open()) {
309 ofs3 <<
"# " << getCorrFuncType() <<
" for HH bond vectors in water\n";
310 ofs3 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
311 ofs3 <<
"# " << r.getBuildDate() <<
"\n";
312 ofs3 <<
"# selection script1: \"" << selectionScript1_;
313 ofs3 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
314 ofs3 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
315 if (!paramString_.empty())
316 ofs3 <<
"# parameters: " << paramString_ <<
"\n";
318 ofs3 <<
"#time\tPn(costheta_z)\n";
320 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
321 ofs3 << times_[i] - times_[0];
323 for (
unsigned int j = 0; j < nZBins_; ++j) {
324 ofs3 <<
"\t" << histogram_[i][j][3];
330 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
331 "COHz::writeCorrelate Error: failed to open %s\n",
333 painCave.isFatal = 1;
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.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)