45#include "applications/dynamicProps/cOHz.hpp"
50#include "utils/Revision.hpp"
51#include "utils/simError.h"
54 COHZ::COHZ(
SimInfo* info,
const std::string& filename,
55 const std::string& sele1,
const std::string& sele2,
int order,
56 int nZbins,
int axis) :
58 nZBins_(nZbins), axis_(axis) {
59 setCorrFuncType(
"Legendre Correlation Function");
60 setOutputName(
getPrefix(dumpFilename_) +
".lcorr");
62 std::stringstream params;
63 params <<
" order = " << order <<
", nzbins = " << nZBins_;
64 const std::string paramString = params.str();
65 setParameterString(paramString);
67 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
70 xaxis_ = (axis_ + 1) % 3;
71 yaxis_ = (axis_ + 2) % 3;
86 rotMats_.resize(nTimeBins_);
87 zbin_.resize(nTimeBins_);
88 histogram_.resize(nTimeBins_);
89 counts_.resize(nTimeBins_);
90 for (
unsigned int i = 0; i < nTimeBins_; i++) {
91 histogram_[i].resize(nZBins_);
92 std::fill(histogram_[i].begin(), histogram_[i].end(),
94 counts_[i].resize(nZBins_);
95 std::fill(counts_[i].begin(), counts_[i].end(), 0);
98 legendre_ = polynomial.getLegendrePolynomial(order);
101 void COHZ::computeFrame(
int frame) {
103 boxZ_ = hmat(axis_, axis_);
104 halfBoxZ_ = boxZ_ / 2.0;
109 int COHZ::computeProperty1(
int frame,
Molecule* mol) {
111 rotMats_[frame].push_back(A);
114 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
116 int zBin = int(nZBins_ * (halfBoxZ_ + pos[axis_]) / boxZ_);
117 zbin_[frame].push_back(zBin);
119 return rotMats_[frame].size() - 1;
142 Vector3d v1y = rotMats_[frame1][id1].getRow(yaxis_);
143 Vector3d v1z = rotMats_[frame1][id1].getRow(axis_);
145 Vector3d v2y = rotMats_[frame2][id2].getRow(yaxis_);
146 Vector3d v2z = rotMats_[frame2][id2].getRow(axis_);
148 Vector3d u1 = 0.81649 * v1y + 0.57736 * v1z;
149 Vector3d u2 = 0.81649 * v2y + 0.57736 * v2z;
151 Vector3d w1 = -0.81649 * v1y + 0.57736 * v1z;
152 Vector3d w2 = -0.81649 * v2y + 0.57736 * v2z;
159 r[0] = legendre_.
evaluate(
dot(v1z, v2z) / (v1z.length() * v2z.length()));
166 void COHZ::correlateFrames(
int frame1,
int frame2,
int timeBin) {
170 std::vector<int>::iterator i1;
171 std::vector<int>::iterator i2;
175 s1 = sele1ToIndex_[frame1];
177 if (uniqueSelections_)
178 s2 = sele2ToIndex_[frame2];
180 s2 = sele1ToIndex_[frame2];
182 for (i1 = s1.begin(), i2 = s2.begin(); i1 != s1.end() && i2 != s2.end();
189 while (i1 != s1.end() && *i1 < *i2) {
193 while (i2 != s2.end() && *i2 < *i1) {
197 if (i1 == s1.end() || i2 == s2.end())
break;
199 corrVal = calcCorrVal(frame1, frame2, i1 - s1.begin(), i2 - s2.begin());
200 int zBin = zbin_[frame1][i1 - s1.begin()];
202 histogram_[timeBin][zBin] += corrVal;
203 counts_[timeBin][zBin]++;
207 void COHZ::postCorrelate() {
208 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
209 for (
unsigned int j = 0; j < nZBins_; ++j) {
210 if (counts_[i][j] > 0) { histogram_[i][j] /= counts_[i][j]; }
221 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
222 "COHZ::validateSelection Error: "
223 "at least one selected molecule does not have a rigid body\n");
224 painCave.isFatal = 1;
230 void COHZ::writeCorrelate() {
231 std::string Dfile = getOutputFileName() +
"D";
232 std::string OHfile = getOutputFileName() +
"OH";
233 std::string HHfile = getOutputFileName() +
"HH";
235 std::ofstream ofs1(Dfile.c_str());
236 std::ofstream ofs2(OHfile.c_str());
237 std::ofstream ofs3(HHfile.c_str());
239 if (ofs1.is_open()) {
242 ofs1 <<
"# " << getCorrFuncType() <<
" for dipole vectors in water\n";
243 ofs1 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
244 ofs1 <<
"# " << r.getBuildDate() <<
"\n";
245 ofs1 <<
"# selection script1: \"" << selectionScript1_;
246 ofs1 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
247 ofs1 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
248 if (!paramString_.empty())
249 ofs1 <<
"# parameters: " << paramString_ <<
"\n";
251 ofs1 <<
"#time\tPn(costheta_z)\n";
253 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
254 ofs1 << times_[i] - times_[0];
256 for (
unsigned int j = 0; j < nZBins_; ++j) {
257 ofs1 <<
"\t" << histogram_[i][j][0];
263 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
264 "COHz::writeCorrelate Error: failed to open %s\n",
266 painCave.isFatal = 1;
271 if (ofs2.is_open()) {
274 ofs2 <<
"# " << getCorrFuncType() <<
" for OH bond vectors in water\n";
275 ofs2 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
276 ofs2 <<
"# " << r.getBuildDate() <<
"\n";
277 ofs2 <<
"# selection script1: \"" << selectionScript1_;
278 ofs2 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
279 ofs2 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
280 if (!paramString_.empty())
281 ofs2 <<
"# parameters: " << paramString_ <<
"\n";
283 ofs2 <<
"#time\tPn(costheta_z)\n";
285 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
286 ofs2 << times_[i] - times_[0];
288 for (
unsigned int j = 0; j < nZBins_; ++j) {
289 ofs2 <<
"\t" << 0.5 * (histogram_[i][j][1] + histogram_[i][j][2]);
295 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
296 "COHz::writeCorrelate Error: failed to open %s\n",
298 painCave.isFatal = 1;
303 if (ofs3.is_open()) {
306 ofs3 <<
"# " << getCorrFuncType() <<
" for HH bond vectors in water\n";
307 ofs3 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
308 ofs3 <<
"# " << r.getBuildDate() <<
"\n";
309 ofs3 <<
"# selection script1: \"" << selectionScript1_;
310 ofs3 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
311 ofs3 <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
312 if (!paramString_.empty())
313 ofs3 <<
"# parameters: " << paramString_ <<
"\n";
315 ofs3 <<
"#time\tPn(costheta_z)\n";
317 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
318 ofs3 << times_[i] - times_[0];
320 for (
unsigned int j = 0; j < nZBins_; ++j) {
321 ofs3 <<
"\t" << histogram_[i][j][3];
327 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
328 "COHz::writeCorrelate Error: failed to open %s\n",
330 painCave.isFatal = 1;
A collection of Legendre Polynomials.
size_t getNRigidBodies()
Returns the total number of rigid bodies in this molecule.
Vector3d getCom()
Returns the current center of mass position of this molecule.
Real evaluate(const Real &x)
Calculates the value of this Polynomial evaluated at the given x value.
Molecule * nextSelectedMolecule(int &i)
Finds the next selected Molecule in the selection.
Molecule * beginSelectedMolecule(int &i)
Finds the first selected Molecule in the selection.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Mat3x3d getHmat()
Returns the H-Matrix.
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
RotMat3x3d getA()
Returns the current rotation matrix of this stuntDouble.
Real length()
Returns the length of this vector.
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)