48#include "applications/dynamicProps/HBondJump.hpp"
52#include "utils/Constants.hpp"
53#include "utils/Revision.hpp"
57 HBondJump::HBondJump(
SimInfo* info,
const std::string& filename,
58 const std::string& sele1,
const std::string& sele2,
59 double OOcut,
double thetaCut,
double OHcut) :
61 OOCut_(OOcut), thetaCut_(thetaCut), OHCut_(OHcut),
62 sele1_minus_common_(info), sele2_minus_common_(info), common_(info) {
63 setCorrFuncType(
"HBondJump");
64 setOutputName(
getPrefix(dumpFilename_) +
".jump");
66 std::stringstream params;
67 params <<
" OOcut = " << OOCut_ <<
", thetacut = " << thetaCut_
68 <<
", OHcut = " << OHCut_;
69 const std::string paramString = params.str();
70 setParameterString(paramString);
72 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
73 evaluator1_.loadScriptString(selectionScript1_);
75 if (!evaluator1_.isDynamic()) {
76 seleMan1_.setSelectionSet(evaluator1_.evaluate());
77 validateSelection(seleMan1_);
80 if (uniqueSelections_) {
81 evaluator2_.loadScriptString(selectionScript2_);
82 if (!evaluator2_.isDynamic()) {
83 seleMan2_.setSelectionSet(evaluator2_.evaluate());
84 validateSelection(seleMan2_);
88 if (!evaluator1_.isDynamic() && !evaluator2_.isDynamic()) {
90 common_ = seleMan1_ & seleMan2_;
91 sele1_minus_common_ = seleMan1_ - common_;
92 sele2_minus_common_ = seleMan2_ - common_;
96 GIDtoH_.resize(nFrames_);
97 hydrogen_.resize(nFrames_);
98 acceptor_.resize(nFrames_);
99 lastAcceptor_.resize(nFrames_);
100 acceptorStartFrame_.resize(nFrames_);
101 selected_.resize(nFrames_);
104 void HBondJump::computeFrame(
int istep) {
106 GIDtoH_[istep].resize(info_->getNGlobalAtoms(), -1);
111 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
112 if (evaluator1_.isDynamic()) {
113 seleMan1_.setSelectionSet(evaluator1_.evaluate());
115 if (uniqueSelections_ && evaluator2_.isDynamic()) {
116 seleMan2_.setSelectionSet(evaluator2_.evaluate());
118 if (evaluator1_.isDynamic() || evaluator2_.isDynamic()) {
119 common_ = seleMan1_ & seleMan2_;
120 sele1_minus_common_ = seleMan1_ - common_;
121 sele2_minus_common_ = seleMan2_ - common_;
125 processNonOverlapping(istep, sele1_minus_common_, seleMan2_);
126 processNonOverlapping(istep, common_, sele2_minus_common_);
127 processOverlapping(istep, common_);
130 void HBondJump::correlation() {
132 std::vector<int>::iterator i1;
134 int index1, index2, count, gid, aInd1, aInd2;
136 for (
int i = 0; i < nFrames_; ++i) {
137 RealType time1 = times_[i];
140 for (
int j = i; j < nFrames_; ++j) {
145 RealType time2 = times_[j];
147 if (std::fabs((time2 - time1) - (j - i) * dtMean_) >
148 6 * dtSigma_ * (j - i)) {
149 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
150 "HBondJump::correlation Error: mean sampleTime (%f)\n"
151 "\tin %s does not match actual time-spacing between\n"
152 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
153 dtMean_, dumpFilename_.c_str(), i, time1, j, time2);
154 if (allowTimeFuzz_) {
155 painCave.isFatal = 0;
156 painCave.severity = OPENMD_INFO;
158 painCave.isFatal = 1;
159 painCave.severity = OPENMD_ERROR;
164 int timeBin = (nFrames_ == 1) ? 0 : int((time2 - time1)/dtMean_ + 0.5);
171 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
174 index1 = GIDtoH_[i][gid];
177 index2 = GIDtoH_[j][gid];
179 if (selected_[i][index1]) {
182 if (acceptor_[i][index1] == -1) {
183 aInd1 = lastAcceptor_[i][index1];
185 aInd1 = acceptor_[i][index1];
188 if (acceptor_[j][index2] == -1) {
189 aInd2 = lastAcceptor_[j][index2];
191 aInd2 = acceptor_[j][index2];
197 if (aInd1 != aInd2) {
203 if (acceptorStartFrame_[i][index1] !=
204 acceptorStartFrame_[j][index2]) {
215 histogram_[timeBin] += corrVal;
216 count_[timeBin] += count;
221 void HBondJump::postCorrelate() {
222 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
224 histogram_[i] /= count_[i];
228 histogram_[i] = 1.0 - histogram_[i];
232 void HBondJump::processNonOverlapping(
int frame, SelectionManager& sman1,
233 SelectionManager& sman2) {
237 std::vector<Molecule::HBondDonor*>::iterator hbdi;
238 Molecule::HBondDonor* hbd;
239 std::vector<Atom*>::iterator hbai;
241 int hInd, index, aInd;
248 for (mol1 = sman1.beginSelectedMolecule(i); mol1 != NULL;
249 mol1 = sman1.nextSelectedMolecule(i)) {
250 for (mol2 = sman2.beginSelectedMolecule(j); mol2 != NULL;
251 mol2 = sman2.nextSelectedMolecule(j)) {
253 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
254 hbd = mol1->nextHBondDonor(hbdi)) {
255 hInd = hbd->donatedHydrogen->getGlobalIndex();
256 index = GIDtoH_[frame][hInd];
257 aInd = acceptor_[frame][index];
259 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
260 hba = mol2->nextHBondAcceptor(hbai)) {
261 if (hba->getGlobalIndex() == aInd) {
262 selected_[frame][index] =
true;
268 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
269 hbd = mol2->nextHBondDonor(hbdi)) {
270 hInd = hbd->donatedHydrogen->getGlobalIndex();
271 index = GIDtoH_[frame][hInd];
272 aInd = acceptor_[frame][index];
274 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
275 hba = mol1->nextHBondAcceptor(hbai)) {
276 if (hba->getGlobalIndex() == aInd) {
277 selected_[frame][index] =
true;
285 void HBondJump::processOverlapping(
int frame, SelectionManager& sman) {
290 std::vector<Molecule::HBondDonor*>::iterator hbdi;
291 Molecule::HBondDonor* hbd;
292 std::vector<Atom*>::iterator hbai;
294 int hInd, index, aInd;
301 for (mol1 = sman.beginSelectedMolecule(i); mol1 != NULL;
302 mol1 = sman.nextSelectedMolecule(i)) {
304 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
305 hbd = mol1->nextHBondDonor(hbdi)) {
306 hInd = hbd->donatedHydrogen->getGlobalIndex();
307 index = GIDtoH_[frame][hInd];
308 aInd = acceptor_[frame][index];
310 for (j = i, mol2 = sman.nextSelectedMolecule(j); mol2 != NULL;
311 mol2 = sman.nextSelectedMolecule(j)) {
312 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
313 hba = mol2->nextHBondAcceptor(hbai)) {
314 if (hba->getGlobalIndex() == aInd) {
315 selected_[frame][index] =
true;
321 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
322 hba = mol1->nextHBondAcceptor(hbai)) {
323 aInd = hba->getGlobalIndex();
325 for (j = i, mol2 = sman.nextSelectedMolecule(j); mol2 != NULL;
326 mol2 = sman.nextSelectedMolecule(j)) {
327 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
328 hbd = mol2->nextHBondDonor(hbdi)) {
329 hInd = hbd->donatedHydrogen->getGlobalIndex();
330 index = GIDtoH_[frame][hInd];
332 if (acceptor_[frame][index] == aInd) {
333 selected_[frame][index] =
true;
341 void HBondJump::findHBonds(
int frame) {
344 SimInfo::MoleculeIterator mi, mj;
345 std::vector<Molecule::HBondDonor*>::iterator hbdi;
346 Molecule::HBondDonor* hbd;
347 std::vector<Atom*>::iterator hbai;
349 Vector3d dPos, hPos, aPos;
350 int hInd, index, aInd;
353 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
354 mol1 = info_->nextMolecule(mi)) {
355 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
356 hbd = mol1->nextHBondDonor(hbdi)) {
357 hInd = hbd->donatedHydrogen->getGlobalIndex();
358 index = registerHydrogen(frame, hInd);
362 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
363 mol1 = info_->nextMolecule(mi)) {
364 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
365 hbd = mol1->nextHBondDonor(hbdi)) {
366 hInd = hbd->donatedHydrogen->getGlobalIndex();
367 index = GIDtoH_[frame][hInd];
369 dPos = hbd->donorAtom->getPos();
370 hPos = hbd->donatedHydrogen->getPos();
372 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
373 mol2 = info_->nextMolecule(mj)) {
374 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
375 hba = mol2->nextHBondAcceptor(hbai)) {
376 aPos = hba->getPos();
378 if (isHBond(dPos, hPos, aPos)) {
379 aInd = hba->getGlobalIndex();
380 registerHydrogenBond(frame, index, hInd, aInd);
386 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
387 hba = mol1->nextHBondAcceptor(hbai)) {
388 aPos = hba->getPos();
390 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
391 mol2 = info_->nextMolecule(mj)) {
392 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
393 hbd = mol2->nextHBondDonor(hbdi)) {
394 hInd = hbd->donatedHydrogen->getGlobalIndex();
396 index = GIDtoH_[frame][hInd];
398 dPos = hbd->donorAtom->getPos();
399 hPos = hbd->donatedHydrogen->getPos();
401 if (isHBond(dPos, hPos, aPos)) {
402 aInd = hba->getGlobalIndex();
403 registerHydrogenBond(frame, index, hInd, aInd);
411 bool HBondJump::isHBond(Vector3d donorPos, Vector3d hydrogenPos,
412 Vector3d acceptorPos) {
413 Vector3d DA = acceptorPos - donorPos;
414 currentSnapshot_->wrapVector(DA);
415 RealType DAdist = DA.
length();
419 if (DAdist < OOCut_) {
420 Vector3d DH = hydrogenPos - donorPos;
421 currentSnapshot_->wrapVector(DH);
422 RealType DHdist = DH.
length();
424 Vector3d HA = acceptorPos - hydrogenPos;
425 currentSnapshot_->wrapVector(HA);
426 RealType HAdist = HA.
length();
428 RealType ctheta =
dot(DH, DA) / (DHdist * DAdist);
429 RealType theta = acos(ctheta) * 180.0 / Constants::PI;
432 if (theta < thetaCut_ && HAdist < OHCut_) {
return true; }
437 int HBondJump::registerHydrogen(
int frame,
int hIndex) {
441 if (GIDtoH_[frame][hIndex] == -1) {
442 index = hydrogen_[frame].size();
443 GIDtoH_[frame][hIndex] = index;
444 hydrogen_[frame].push_back(hIndex);
445 acceptor_[frame].push_back(-1);
446 selected_[frame].push_back(
false);
449 lastAcceptor_[frame].push_back(-1);
450 acceptorStartFrame_[frame].push_back(frame);
453 int prevIndex = GIDtoH_[frame - 1][hIndex];
454 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
455 acceptorStartFrame_[frame].push_back(
456 acceptorStartFrame_[frame - 1][prevIndex]);
460 index = GIDtoH_[frame][hIndex];
465 void HBondJump::registerHydrogenBond(
int frame,
int index,
int hIndex,
467 acceptor_[frame][index] = acceptorIndex;
468 lastAcceptor_[frame][index] = acceptorIndex;
471 acceptorStartFrame_[frame][index] = frame;
473 int prevIndex = GIDtoH_[frame - 1][hIndex];
474 if (acceptorIndex != lastAcceptor_[frame - 1][prevIndex]) {
475 acceptorStartFrame_[frame][index] = frame;
477 acceptorStartFrame_[frame][index] =
478 acceptorStartFrame_[frame - 1][prevIndex];
483 HBondJumpZ::HBondJumpZ(SimInfo* info,
const std::string& filename,
484 const std::string& sele1,
const std::string& sele2,
485 double OOcut,
double thetaCut,
double OHcut,
486 int nZBins,
int axis) :
487 HBondJump(info, filename, sele1, sele2, OOcut, thetaCut, OHcut),
488 nZBins_(nZBins), axis_(axis) {
489 setCorrFuncType(
"HBondJumpZ");
490 setOutputName(
getPrefix(dumpFilename_) +
".jumpZ");
505 zbin_.resize(nFrames_);
506 histogram_.resize(nTimeBins_);
507 counts_.resize(nTimeBins_);
508 for (
unsigned int i = 0; i < nTimeBins_; i++) {
509 histogram_[i].resize(nZBins_);
510 std::fill(histogram_[i].begin(), histogram_[i].end(), 0.0);
511 counts_[i].resize(nZBins_);
512 std::fill(counts_[i].begin(), counts_[i].end(), 0);
516 void HBondJumpZ::findHBonds(
int frame) {
519 SimInfo::MoleculeIterator mi, mj;
520 std::vector<Molecule::HBondDonor*>::iterator hbdi;
521 Molecule::HBondDonor* hbd;
522 std::vector<Atom*>::iterator hbai;
524 Vector3d dPos, hPos, aPos, pos;
525 int hInd, index, aInd, zBin;
527 Mat3x3d hmat = currentSnapshot_->getHmat();
528 RealType halfBoxZ_ = hmat(axis_, axis_) / 2.0;
531 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
532 mol1 = info_->nextMolecule(mi)) {
533 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
534 hbd = mol1->nextHBondDonor(hbdi)) {
535 hInd = hbd->donatedHydrogen->getGlobalIndex();
536 index = registerHydrogen(frame, hInd);
540 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
541 mol1 = info_->nextMolecule(mi)) {
542 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
543 hbd = mol1->nextHBondDonor(hbdi)) {
544 hInd = hbd->donatedHydrogen->getGlobalIndex();
545 index = GIDtoH_[frame][hInd];
547 dPos = hbd->donorAtom->getPos();
548 hPos = hbd->donatedHydrogen->getPos();
550 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
551 mol2 = info_->nextMolecule(mj)) {
552 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
553 hba = mol2->nextHBondAcceptor(hbai)) {
554 aPos = hba->getPos();
556 if (isHBond(dPos, hPos, aPos)) {
557 aInd = hba->getGlobalIndex();
558 registerHydrogenBond(frame, index, hInd, aInd);
560 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
561 currentSnapshot_->wrapVector(pos);
563 int(nZBins_ * (halfBoxZ_ + pos[axis_]) / hmat(axis_, axis_));
564 zbin_[frame][index] = zBin;
570 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
571 hba = mol1->nextHBondAcceptor(hbai)) {
572 aPos = hba->getPos();
574 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
575 mol2 = info_->nextMolecule(mj)) {
576 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
577 hbd = mol2->nextHBondDonor(hbdi)) {
578 hInd = hbd->donatedHydrogen->getGlobalIndex();
580 index = GIDtoH_[frame][hInd];
582 dPos = hbd->donorAtom->getPos();
583 hPos = hbd->donatedHydrogen->getPos();
585 if (isHBond(dPos, hPos, aPos)) {
586 aInd = hba->getGlobalIndex();
587 registerHydrogenBond(frame, index, hInd, aInd);
589 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
590 currentSnapshot_->wrapVector(pos);
592 int(nZBins_ * (halfBoxZ_ + pos[axis_]) / hmat(axis_, axis_));
593 zbin_[frame][index] = zBin;
601 int HBondJumpZ::registerHydrogen(
int frame,
int hIndex) {
605 if (GIDtoH_[frame][hIndex] == -1) {
606 index = hydrogen_[frame].size();
607 GIDtoH_[frame][hIndex] = index;
608 hydrogen_[frame].push_back(hIndex);
609 acceptor_[frame].push_back(-1);
610 selected_[frame].push_back(
false);
611 zbin_[frame].push_back(-1);
614 lastAcceptor_[frame].push_back(-1);
615 acceptorStartFrame_[frame].push_back(frame);
618 int prevIndex = GIDtoH_[frame - 1][hIndex];
619 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
620 acceptorStartFrame_[frame].push_back(
621 acceptorStartFrame_[frame - 1][prevIndex]);
625 index = GIDtoH_[frame][hIndex];
630 void HBondJumpZ::correlation() {
632 std::vector<int>::iterator i1;
633 int index1, index2, gid, aInd1, aInd2, zBin;
635 for (
int i = 0; i < nFrames_; ++i) {
636 RealType time1 = times_[i];
639 for (
int j = i; j < nFrames_; ++j) {
644 RealType time2 = times_[j];
646 if (std::fabs((time2 - time1) - (j - i) * dtMean_) >
647 6 * dtSigma_ * (j - i)) {
648 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
649 "HBondJump::correlation Error: mean sampleTime (%f)\n"
650 "\tin %s does not match actual time-spacing between\n"
651 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
652 dtMean_, dumpFilename_.c_str(), i, time1, j, time2);
653 if (allowTimeFuzz_) {
654 painCave.isFatal = 0;
655 painCave.severity = OPENMD_INFO;
657 painCave.isFatal = 1;
658 painCave.severity = OPENMD_ERROR;
663 int timeBin = (nFrames_ == 1) ? 0 : int((time2 - time1)/dtMean_ + 0.5);
667 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
670 index1 = GIDtoH_[i][gid];
673 index2 = GIDtoH_[j][gid];
675 if (selected_[i][index1]) {
676 zBin = zbin_[i][index1];
677 counts_[timeBin][zBin]++;
679 if (acceptor_[i][index1] == -1) {
680 aInd1 = lastAcceptor_[i][index1];
682 aInd1 = acceptor_[i][index1];
685 if (acceptor_[j][index2] == -1) {
686 aInd2 = lastAcceptor_[j][index2];
688 aInd2 = acceptor_[j][index2];
694 if (aInd1 != aInd2) {
696 histogram_[timeBin][zBin] += 1;
700 if (acceptorStartFrame_[i][index1] !=
701 acceptorStartFrame_[j][index2]) {
704 histogram_[timeBin][zBin] += 1;
707 histogram_[timeBin][zBin] += 0;
716 void HBondJumpZ::postCorrelate() {
717 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
718 for (
unsigned int j = 0; j < nZBins_; ++j) {
719 if (counts_[i][j] > 0) {
720 histogram_[i][j] /= counts_[i][j];
722 histogram_[i][j] = 0;
724 histogram_[i][j] = 1.0 - histogram_[i][j];
729 void HBondJumpZ::writeCorrelate() {
730 ofstream ofs(outputFilename_.c_str());
735 ofs <<
"# " << getCorrFuncType() <<
"\n";
736 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
737 ofs <<
"# " << r.getBuildDate() <<
"\n";
738 ofs <<
"# selection script1: \"" << selectionScript1_;
739 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
740 ofs <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
741 if (!paramString_.empty())
742 ofs <<
"# parameters: " << paramString_ <<
"\n";
743 ofs <<
"#time\tcorrVal\n";
745 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
746 ofs << times_[i] - times_[0];
748 for (
unsigned int j = 0; j < nZBins_; ++j) {
749 ofs <<
"\t" << histogram_[i][j];
755 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
756 "HBondJumpZ::writeCorrelate Error: fail to open %s\n",
757 outputFilename_.c_str());
758 painCave.isFatal = 1;
765 HBondJumpR::HBondJumpR(SimInfo* info,
const std::string& filename,
766 const std::string& sele1,
const std::string& sele2,
767 const std::string& sele3, RealType OOcut,
768 RealType thetaCut, RealType OHcut, RealType len,
770 HBondJump(info, filename, sele1, sele2, OOcut, thetaCut, OHcut),
771 len_(len), nRBins_(nRBins), seleMan3_(info_), selectionScript3_(sele3),
773 setCorrFuncType(
"HBondJumpR");
774 setOutputName(
getPrefix(dumpFilename_) +
".jumpR");
776 rbin_.resize(nFrames_);
777 histogram_.resize(nTimeBins_);
778 counts_.resize(nTimeBins_);
779 for (
unsigned int i = 0; i < nTimeBins_; i++) {
780 histogram_[i].resize(nRBins_);
781 counts_[i].resize(nRBins_);
784 evaluator3_.loadScriptString(selectionScript3_);
785 if (!evaluator3_.isDynamic()) {
786 seleMan3_.setSelectionSet(evaluator3_.evaluate());
789 deltaR_ = len_ / nRBins_;
792 void HBondJumpR::findHBonds(
int frame) {
795 SimInfo::MoleculeIterator mi, mj;
796 std::vector<Molecule::HBondDonor*>::iterator hbdi;
797 Molecule::HBondDonor* hbd;
798 std::vector<Atom*>::iterator hbai;
800 Vector3d dPos, hPos, aPos, pos;
801 int hInd, index, aInd;
807 if (evaluator3_.isDynamic()) {
808 seleMan3_.setSelectionSet(evaluator3_.evaluate());
811 if (seleMan3_.getSelectionCount() == 0) {
812 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
813 "HBondJump:findHBonds: third selection has no objects at frame"
814 "%d, skipping frame.\n",
816 painCave.severity = OPENMD_WARNING;
817 painCave.isFatal = 0;
822 bool usePeriodicBoundaryConditions_ =
823 info_->getSimParams()->getUsePeriodicBoundaryConditions();
826 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
827 mol1 = info_->nextMolecule(mi)) {
828 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
829 hbd = mol1->nextHBondDonor(hbdi)) {
830 hInd = hbd->donatedHydrogen->getGlobalIndex();
831 index = registerHydrogen(frame, hInd);
835 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
836 mol1 = info_->nextMolecule(mi)) {
837 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
838 hbd = mol1->nextHBondDonor(hbdi)) {
839 hInd = hbd->donatedHydrogen->getGlobalIndex();
840 index = GIDtoH_[frame][hInd];
842 dPos = hbd->donorAtom->getPos();
843 hPos = hbd->donatedHydrogen->getPos();
845 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
846 mol2 = info_->nextMolecule(mj)) {
847 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
848 hba = mol2->nextHBondAcceptor(hbai)) {
849 aPos = hba->getPos();
851 if (isHBond(dPos, hPos, aPos)) {
852 aInd = hba->getGlobalIndex();
853 registerHydrogenBond(frame, index, hInd, aInd);
856 RealType shortest = HONKING_LARGE_VALUE;
859 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
860 sd3 = seleMan3_.nextSelected(isd3)) {
861 vec = pos - sd3->getPos();
863 if (usePeriodicBoundaryConditions_)
864 currentSnapshot_->wrapVector(vec);
868 if (r < shortest) shortest = r;
871 int whichBin = int(shortest / deltaR_);
872 if (whichBin <
int(nRBins_)) { rbin_[frame][index] = whichBin; }
878 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
879 hba = mol1->nextHBondAcceptor(hbai)) {
880 aPos = hba->getPos();
882 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
883 mol2 = info_->nextMolecule(mj)) {
884 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
885 hbd = mol2->nextHBondDonor(hbdi)) {
886 hInd = hbd->donatedHydrogen->getGlobalIndex();
888 index = GIDtoH_[frame][hInd];
890 dPos = hbd->donorAtom->getPos();
891 hPos = hbd->donatedHydrogen->getPos();
893 if (isHBond(dPos, hPos, aPos)) {
894 aInd = hba->getGlobalIndex();
895 registerHydrogenBond(frame, index, hInd, aInd);
897 RealType shortest = HONKING_LARGE_VALUE;
900 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
901 sd3 = seleMan3_.nextSelected(isd3)) {
902 vec = pos - sd3->getPos();
904 if (usePeriodicBoundaryConditions_)
905 currentSnapshot_->wrapVector(vec);
909 if (r < shortest) shortest = r;
912 int whichBin = int(shortest / deltaR_);
913 if (whichBin <
int(nRBins_)) { rbin_[frame][index] = whichBin; }
921 int HBondJumpR::registerHydrogen(
int frame,
int hIndex) {
925 if (GIDtoH_[frame][hIndex] == -1) {
926 index = hydrogen_[frame].size();
928 GIDtoH_[frame][hIndex] = index;
929 hydrogen_[frame].push_back(hIndex);
930 acceptor_[frame].push_back(-1);
931 selected_[frame].push_back(
false);
932 rbin_[frame].push_back(-1);
935 lastAcceptor_[frame].push_back(-1);
936 acceptorStartFrame_[frame].push_back(frame);
939 int prevIndex = GIDtoH_[frame - 1][hIndex];
940 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
941 acceptorStartFrame_[frame].push_back(
942 acceptorStartFrame_[frame - 1][prevIndex]);
946 index = GIDtoH_[frame][hIndex];
951 void HBondJumpR::correlation() {
953 std::vector<int>::iterator i1;
954 int index1, index2, gid, aInd1, aInd2;
956 for (
int i = 0; i < nFrames_; ++i) {
957 RealType time1 = times_[i];
960 for (
int j = i; j < nFrames_; ++j) {
965 RealType time2 = times_[j];
967 if (std::fabs((time2 - time1) - (j - i) * dtMean_) >
968 6 * dtSigma_ * (j - i)) {
969 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
970 "HBondJump::correlation Error: mean sampleTime (%f)\n"
971 "\tin %s does not match actual time-spacing between\n"
972 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
973 dtMean_, dumpFilename_.c_str(), i, time1, j, time2);
974 if (allowTimeFuzz_) {
975 painCave.isFatal = 0;
976 painCave.severity = OPENMD_INFO;
978 painCave.isFatal = 1;
979 painCave.severity = OPENMD_ERROR;
984 int timeBin = (nFrames_ == 1) ? 0 : int((time2 - time1)/dtMean_ + 0.5);
988 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
991 index1 = GIDtoH_[i][gid];
994 index2 = GIDtoH_[j][gid];
996 if (selected_[i][index1]) {
997 if (int rBin {rbin_[i][index1]}; rBin != -1) {
998 counts_[timeBin][rBin]++;
1000 if (acceptor_[i][index1] == -1) {
1001 aInd1 = lastAcceptor_[i][index1];
1003 aInd1 = acceptor_[i][index1];
1006 if (acceptor_[j][index2] == -1) {
1007 aInd2 = lastAcceptor_[j][index2];
1009 aInd2 = acceptor_[j][index2];
1015 if (aInd1 != aInd2) {
1017 histogram_[timeBin][rBin] += 1;
1021 if (acceptorStartFrame_[i][index1] !=
1022 acceptorStartFrame_[j][index2]) {
1025 histogram_[timeBin][rBin] += 1;
1028 histogram_[timeBin][rBin] += 0;
1038 void HBondJumpR::postCorrelate() {
1039 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
1040 for (
unsigned int j = 0; j < nRBins_; ++j) {
1041 if (counts_[i][j] > 0) {
1042 histogram_[i][j] /= counts_[i][j];
1044 histogram_[i][j] = 0;
1046 histogram_[i][j] = 1.0 - histogram_[i][j];
1051 void HBondJumpR::writeCorrelate() {
1052 ofstream ofs(outputFilename_.c_str());
1054 if (ofs.is_open()) {
1057 ofs <<
"# " << getCorrFuncType() <<
"\n";
1058 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
1059 ofs <<
"# " << r.getBuildDate() <<
"\n";
1060 ofs <<
"# selection script1: \"" << selectionScript1_;
1061 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
1062 if (!paramString_.empty())
1063 ofs <<
"# parameters: " << paramString_ <<
"\n";
1064 ofs <<
"#time\tcorrVal\n";
1066 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
1067 ofs << times_[i] - times_[0];
1069 for (
unsigned int j = 0; j < nRBins_; ++j) {
1070 ofs <<
"\t" << histogram_[i][j];
1076 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
1077 "HBondJumpR::writeCorrelate Error: fail to open %s\n",
1078 outputFilename_.c_str());
1079 painCave.isFatal = 1;
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Computes a correlation function by scanning a trajectory once to precompute quantities to be correlat...
Real length() const
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)