45#include "applications/dynamicProps/HBondJump.hpp"
49#include "utils/Constants.hpp"
50#include "utils/Revision.hpp"
54 HBondJump::HBondJump(SimInfo* info,
const std::string& filename,
55 const std::string& sele1,
const std::string& sele2,
56 double OOcut,
double thetaCut,
double OHcut) :
57 TimeCorrFunc<RealType>(info, filename, sele1, sele2),
58 OOCut_(OOcut), thetaCut_(thetaCut), OHCut_(OHcut),
59 sele1_minus_common_(info), sele2_minus_common_(info), common_(info) {
60 setCorrFuncType(
"HBondJump");
61 setOutputName(
getPrefix(dumpFilename_) +
".jump");
63 std::stringstream params;
64 params <<
" OOcut = " << OOCut_ <<
", thetacut = " << thetaCut_
65 <<
", OHcut = " << OHCut_;
66 const std::string paramString = params.str();
67 setParameterString(paramString);
69 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
70 evaluator1_.loadScriptString(selectionScript1_);
72 if (!evaluator1_.isDynamic()) {
73 seleMan1_.setSelectionSet(evaluator1_.evaluate());
74 validateSelection(seleMan1_);
77 if (uniqueSelections_) {
78 evaluator2_.loadScriptString(selectionScript2_);
79 if (!evaluator2_.isDynamic()) {
80 seleMan2_.setSelectionSet(evaluator2_.evaluate());
81 validateSelection(seleMan2_);
85 if (!evaluator1_.isDynamic() && !evaluator2_.isDynamic()) {
87 common_ = seleMan1_ & seleMan2_;
88 sele1_minus_common_ = seleMan1_ - common_;
89 sele2_minus_common_ = seleMan2_ - common_;
93 GIDtoH_.resize(nFrames_);
94 hydrogen_.resize(nFrames_);
95 acceptor_.resize(nFrames_);
96 lastAcceptor_.resize(nFrames_);
97 acceptorStartFrame_.resize(nFrames_);
98 selected_.resize(nFrames_);
101 void HBondJump::computeFrame(
int istep) {
103 GIDtoH_[istep].resize(info_->getNGlobalAtoms(), -1);
108 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
109 if (evaluator1_.isDynamic()) {
110 seleMan1_.setSelectionSet(evaluator1_.evaluate());
112 if (uniqueSelections_ && evaluator2_.isDynamic()) {
113 seleMan2_.setSelectionSet(evaluator2_.evaluate());
115 if (evaluator1_.isDynamic() || evaluator2_.isDynamic()) {
116 common_ = seleMan1_ & seleMan2_;
117 sele1_minus_common_ = seleMan1_ - common_;
118 sele2_minus_common_ = seleMan2_ - common_;
122 processNonOverlapping(istep, sele1_minus_common_, seleMan2_);
123 processNonOverlapping(istep, common_, sele2_minus_common_);
124 processOverlapping(istep, common_);
127 void HBondJump::correlation() {
129 std::vector<int>::iterator i1;
131 int index1, index2, count, gid, aInd1, aInd2;
133 for (
int i = 0; i < nFrames_; ++i) {
134 RealType time1 = times_[i];
137 for (
int j = i; j < nFrames_; ++j) {
142 RealType time2 = times_[j];
144 if (fabs((time2 - time1) - (j - i) * deltaTime_) > 1.0e-4) {
145 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
146 "HBondJump::correlation Error: sampleTime (%f)\n"
147 "\tin %s does not match actual time-spacing between\n"
148 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
149 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
150 painCave.isFatal = 1;
154 int timeBin = int((time2 - time1) / deltaTime_ + 0.5);
161 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
164 index1 = GIDtoH_[i][gid];
167 index2 = GIDtoH_[j][gid];
169 if (selected_[i][index1]) {
172 if (acceptor_[i][index1] == -1) {
173 aInd1 = lastAcceptor_[i][index1];
175 aInd1 = acceptor_[i][index1];
178 if (acceptor_[j][index2] == -1) {
179 aInd2 = lastAcceptor_[j][index2];
181 aInd2 = acceptor_[j][index2];
187 if (aInd1 != aInd2) {
193 if (acceptorStartFrame_[i][index1] !=
194 acceptorStartFrame_[j][index2]) {
205 histogram_[timeBin] += corrVal;
206 count_[timeBin] += count;
211 void HBondJump::postCorrelate() {
212 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
214 histogram_[i] /= count_[i];
218 histogram_[i] = 1.0 - histogram_[i];
222 void HBondJump::processNonOverlapping(
int frame, SelectionManager& sman1,
223 SelectionManager& sman2) {
227 std::vector<Molecule::HBondDonor*>::iterator hbdi;
228 Molecule::HBondDonor* hbd;
229 std::vector<Atom*>::iterator hbai;
231 int hInd, index, aInd;
238 for (mol1 = sman1.beginSelectedMolecule(i); mol1 != NULL;
239 mol1 = sman1.nextSelectedMolecule(i)) {
240 for (mol2 = sman2.beginSelectedMolecule(j); mol2 != NULL;
241 mol2 = sman2.nextSelectedMolecule(j)) {
243 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
244 hbd = mol1->nextHBondDonor(hbdi)) {
245 hInd = hbd->donatedHydrogen->getGlobalIndex();
246 index = GIDtoH_[frame][hInd];
247 aInd = acceptor_[frame][index];
249 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
250 hba = mol2->nextHBondAcceptor(hbai)) {
251 if (hba->getGlobalIndex() == aInd) {
252 selected_[frame][index] =
true;
258 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
259 hbd = mol2->nextHBondDonor(hbdi)) {
260 hInd = hbd->donatedHydrogen->getGlobalIndex();
261 index = GIDtoH_[frame][hInd];
262 aInd = acceptor_[frame][index];
264 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
265 hba = mol1->nextHBondAcceptor(hbai)) {
266 if (hba->getGlobalIndex() == aInd) {
267 selected_[frame][index] =
true;
275 void HBondJump::processOverlapping(
int frame, SelectionManager& sman) {
280 std::vector<Molecule::HBondDonor*>::iterator hbdi;
281 Molecule::HBondDonor* hbd;
282 std::vector<Atom*>::iterator hbai;
284 int hInd, index, aInd;
291 for (mol1 = sman.beginSelectedMolecule(i); mol1 != NULL;
292 mol1 = sman.nextSelectedMolecule(i)) {
294 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
295 hbd = mol1->nextHBondDonor(hbdi)) {
296 hInd = hbd->donatedHydrogen->getGlobalIndex();
297 index = GIDtoH_[frame][hInd];
298 aInd = acceptor_[frame][index];
300 for (j = i, mol2 = sman.nextSelectedMolecule(j); mol2 != NULL;
301 mol2 = sman.nextSelectedMolecule(j)) {
302 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
303 hba = mol2->nextHBondAcceptor(hbai)) {
304 if (hba->getGlobalIndex() == aInd) {
305 selected_[frame][index] =
true;
311 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
312 hba = mol1->nextHBondAcceptor(hbai)) {
313 aInd = hba->getGlobalIndex();
315 for (j = i, mol2 = sman.nextSelectedMolecule(j); mol2 != NULL;
316 mol2 = sman.nextSelectedMolecule(j)) {
317 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
318 hbd = mol2->nextHBondDonor(hbdi)) {
319 hInd = hbd->donatedHydrogen->getGlobalIndex();
320 index = GIDtoH_[frame][hInd];
322 if (acceptor_[frame][index] == aInd) {
323 selected_[frame][index] =
true;
331 void HBondJump::findHBonds(
int frame) {
334 SimInfo::MoleculeIterator mi, mj;
335 std::vector<Molecule::HBondDonor*>::iterator hbdi;
336 Molecule::HBondDonor* hbd;
337 std::vector<Atom*>::iterator hbai;
339 Vector3d dPos, hPos, aPos;
340 int hInd, index, aInd;
343 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
344 mol1 = info_->nextMolecule(mi)) {
345 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
346 hbd = mol1->nextHBondDonor(hbdi)) {
347 hInd = hbd->donatedHydrogen->getGlobalIndex();
348 index = registerHydrogen(frame, hInd);
352 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
353 mol1 = info_->nextMolecule(mi)) {
354 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
355 hbd = mol1->nextHBondDonor(hbdi)) {
356 hInd = hbd->donatedHydrogen->getGlobalIndex();
357 index = GIDtoH_[frame][hInd];
359 dPos = hbd->donorAtom->getPos();
360 hPos = hbd->donatedHydrogen->getPos();
362 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
363 mol2 = info_->nextMolecule(mj)) {
364 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
365 hba = mol2->nextHBondAcceptor(hbai)) {
366 aPos = hba->getPos();
368 if (isHBond(dPos, hPos, aPos)) {
369 aInd = hba->getGlobalIndex();
370 registerHydrogenBond(frame, index, hInd, aInd);
376 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
377 hba = mol1->nextHBondAcceptor(hbai)) {
378 aPos = hba->getPos();
380 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
381 mol2 = info_->nextMolecule(mj)) {
382 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
383 hbd = mol2->nextHBondDonor(hbdi)) {
384 hInd = hbd->donatedHydrogen->getGlobalIndex();
386 index = GIDtoH_[frame][hInd];
388 dPos = hbd->donorAtom->getPos();
389 hPos = hbd->donatedHydrogen->getPos();
391 if (isHBond(dPos, hPos, aPos)) {
392 aInd = hba->getGlobalIndex();
393 registerHydrogenBond(frame, index, hInd, aInd);
401 bool HBondJump::isHBond(Vector3d donorPos, Vector3d hydrogenPos,
402 Vector3d acceptorPos) {
403 Vector3d DA = acceptorPos - donorPos;
404 currentSnapshot_->wrapVector(DA);
405 RealType DAdist = DA.
length();
409 if (DAdist < OOCut_) {
410 Vector3d DH = hydrogenPos - donorPos;
411 currentSnapshot_->wrapVector(DH);
412 RealType DHdist = DH.
length();
414 Vector3d HA = acceptorPos - hydrogenPos;
415 currentSnapshot_->wrapVector(HA);
416 RealType HAdist = HA.
length();
418 RealType ctheta =
dot(DH, DA) / (DHdist * DAdist);
419 RealType theta = acos(ctheta) * 180.0 / Constants::PI;
422 if (theta < thetaCut_ && HAdist < OHCut_) {
return true; }
427 int HBondJump::registerHydrogen(
int frame,
int hIndex) {
431 if (GIDtoH_[frame][hIndex] == -1) {
432 index = hydrogen_[frame].size();
433 GIDtoH_[frame][hIndex] = index;
434 hydrogen_[frame].push_back(hIndex);
435 acceptor_[frame].push_back(-1);
436 selected_[frame].push_back(
false);
439 lastAcceptor_[frame].push_back(-1);
440 acceptorStartFrame_[frame].push_back(frame);
443 int prevIndex = GIDtoH_[frame - 1][hIndex];
444 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
445 acceptorStartFrame_[frame].push_back(
446 acceptorStartFrame_[frame - 1][prevIndex]);
450 index = GIDtoH_[frame][hIndex];
455 void HBondJump::registerHydrogenBond(
int frame,
int index,
int hIndex,
457 acceptor_[frame][index] = acceptorIndex;
458 lastAcceptor_[frame][index] = acceptorIndex;
461 acceptorStartFrame_[frame][index] = frame;
463 int prevIndex = GIDtoH_[frame - 1][hIndex];
464 if (acceptorIndex != lastAcceptor_[frame - 1][prevIndex]) {
465 acceptorStartFrame_[frame][index] = frame;
467 acceptorStartFrame_[frame][index] =
468 acceptorStartFrame_[frame - 1][prevIndex];
473 HBondJumpZ::HBondJumpZ(SimInfo* info,
const std::string& filename,
474 const std::string& sele1,
const std::string& sele2,
475 double OOcut,
double thetaCut,
double OHcut,
476 int nZBins,
int axis) :
477 HBondJump(info, filename, sele1, sele2, OOcut, thetaCut, OHcut),
478 nZBins_(nZBins), axis_(axis) {
479 setCorrFuncType(
"HBondJumpZ");
480 setOutputName(
getPrefix(dumpFilename_) +
".jumpZ");
495 zbin_.resize(nFrames_);
496 histogram_.resize(nTimeBins_);
497 counts_.resize(nTimeBins_);
498 for (
unsigned int i = 0; i < nTimeBins_; i++) {
499 histogram_[i].resize(nZBins_);
500 std::fill(histogram_[i].begin(), histogram_[i].end(), 0.0);
501 counts_[i].resize(nZBins_);
502 std::fill(counts_[i].begin(), counts_[i].end(), 0);
506 void HBondJumpZ::findHBonds(
int frame) {
509 SimInfo::MoleculeIterator mi, mj;
510 std::vector<Molecule::HBondDonor*>::iterator hbdi;
511 Molecule::HBondDonor* hbd;
512 std::vector<Atom*>::iterator hbai;
514 Vector3d dPos, hPos, aPos, pos;
515 int hInd, index, aInd, zBin;
517 Mat3x3d hmat = currentSnapshot_->getHmat();
518 RealType halfBoxZ_ = hmat(axis_, axis_) / 2.0;
521 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
522 mol1 = info_->nextMolecule(mi)) {
523 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
524 hbd = mol1->nextHBondDonor(hbdi)) {
525 hInd = hbd->donatedHydrogen->getGlobalIndex();
526 index = registerHydrogen(frame, hInd);
530 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
531 mol1 = info_->nextMolecule(mi)) {
532 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
533 hbd = mol1->nextHBondDonor(hbdi)) {
534 hInd = hbd->donatedHydrogen->getGlobalIndex();
535 index = GIDtoH_[frame][hInd];
537 dPos = hbd->donorAtom->getPos();
538 hPos = hbd->donatedHydrogen->getPos();
540 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
541 mol2 = info_->nextMolecule(mj)) {
542 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
543 hba = mol2->nextHBondAcceptor(hbai)) {
544 aPos = hba->getPos();
546 if (isHBond(dPos, hPos, aPos)) {
547 aInd = hba->getGlobalIndex();
548 registerHydrogenBond(frame, index, hInd, aInd);
550 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
551 currentSnapshot_->wrapVector(pos);
553 int(nZBins_ * (halfBoxZ_ + pos[axis_]) / hmat(axis_, axis_));
554 zbin_[frame][index] = zBin;
560 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
561 hba = mol1->nextHBondAcceptor(hbai)) {
562 aPos = hba->getPos();
564 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
565 mol2 = info_->nextMolecule(mj)) {
566 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
567 hbd = mol2->nextHBondDonor(hbdi)) {
568 hInd = hbd->donatedHydrogen->getGlobalIndex();
570 index = GIDtoH_[frame][hInd];
572 dPos = hbd->donorAtom->getPos();
573 hPos = hbd->donatedHydrogen->getPos();
575 if (isHBond(dPos, hPos, aPos)) {
576 aInd = hba->getGlobalIndex();
577 registerHydrogenBond(frame, index, hInd, aInd);
579 if (info_->getSimParams()->getUsePeriodicBoundaryConditions())
580 currentSnapshot_->wrapVector(pos);
582 int(nZBins_ * (halfBoxZ_ + pos[axis_]) / hmat(axis_, axis_));
583 zbin_[frame][index] = zBin;
591 int HBondJumpZ::registerHydrogen(
int frame,
int hIndex) {
595 if (GIDtoH_[frame][hIndex] == -1) {
596 index = hydrogen_[frame].size();
597 GIDtoH_[frame][hIndex] = index;
598 hydrogen_[frame].push_back(hIndex);
599 acceptor_[frame].push_back(-1);
600 selected_[frame].push_back(
false);
601 zbin_[frame].push_back(-1);
604 lastAcceptor_[frame].push_back(-1);
605 acceptorStartFrame_[frame].push_back(frame);
608 int prevIndex = GIDtoH_[frame - 1][hIndex];
609 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
610 acceptorStartFrame_[frame].push_back(
611 acceptorStartFrame_[frame - 1][prevIndex]);
615 index = GIDtoH_[frame][hIndex];
620 void HBondJumpZ::correlation() {
622 std::vector<int>::iterator i1;
623 int index1, index2, gid, aInd1, aInd2, zBin;
625 for (
int i = 0; i < nFrames_; ++i) {
626 RealType time1 = times_[i];
629 for (
int j = i; j < nFrames_; ++j) {
634 RealType time2 = times_[j];
636 if (fabs((time2 - time1) - (j - i) * deltaTime_) > 1.0e-4) {
637 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
638 "HBondJump::correlation Error: sampleTime (%f)\n"
639 "\tin %s does not match actual time-spacing between\n"
640 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
641 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
642 painCave.isFatal = 1;
646 int timeBin = int((time2 - time1) / deltaTime_ + 0.5);
650 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
653 index1 = GIDtoH_[i][gid];
656 index2 = GIDtoH_[j][gid];
658 if (selected_[i][index1]) {
659 zBin = zbin_[i][index1];
660 counts_[timeBin][zBin]++;
662 if (acceptor_[i][index1] == -1) {
663 aInd1 = lastAcceptor_[i][index1];
665 aInd1 = acceptor_[i][index1];
668 if (acceptor_[j][index2] == -1) {
669 aInd2 = lastAcceptor_[j][index2];
671 aInd2 = acceptor_[j][index2];
677 if (aInd1 != aInd2) {
679 histogram_[timeBin][zBin] += 1;
683 if (acceptorStartFrame_[i][index1] !=
684 acceptorStartFrame_[j][index2]) {
687 histogram_[timeBin][zBin] += 1;
690 histogram_[timeBin][zBin] += 0;
699 void HBondJumpZ::postCorrelate() {
700 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
701 for (
unsigned int j = 0; j < nZBins_; ++j) {
702 if (counts_[i][j] > 0) {
703 histogram_[i][j] /= counts_[i][j];
705 histogram_[i][j] = 0;
707 histogram_[i][j] = 1.0 - histogram_[i][j];
712 void HBondJumpZ::writeCorrelate() {
713 ofstream ofs(outputFilename_.c_str());
718 ofs <<
"# " << getCorrFuncType() <<
"\n";
719 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
720 ofs <<
"# " << r.getBuildDate() <<
"\n";
721 ofs <<
"# selection script1: \"" << selectionScript1_;
722 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
723 ofs <<
"# privilegedAxis computed as " << axisLabel_ <<
" axis \n";
724 if (!paramString_.empty())
725 ofs <<
"# parameters: " << paramString_ <<
"\n";
726 ofs <<
"#time\tcorrVal\n";
728 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
729 ofs << times_[i] - times_[0];
731 for (
unsigned int j = 0; j < nZBins_; ++j) {
732 ofs <<
"\t" << histogram_[i][j];
738 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
739 "HBondJumpZ::writeCorrelate Error: fail to open %s\n",
740 outputFilename_.c_str());
741 painCave.isFatal = 1;
748 HBondJumpR::HBondJumpR(SimInfo* info,
const std::string& filename,
749 const std::string& sele1,
const std::string& sele2,
750 const std::string& sele3, RealType OOcut,
751 RealType thetaCut, RealType OHcut, RealType len,
753 HBondJump(info, filename, sele1, sele2, OOcut, thetaCut, OHcut),
754 len_(len), nRBins_(nRBins), seleMan3_(info_), selectionScript3_(sele3),
756 setCorrFuncType(
"HBondJumpR");
757 setOutputName(
getPrefix(dumpFilename_) +
".jumpR");
759 rbin_.resize(nFrames_);
760 histogram_.resize(nTimeBins_);
761 counts_.resize(nTimeBins_);
762 for (
unsigned int i = 0; i < nTimeBins_; i++) {
763 histogram_[i].resize(nRBins_);
764 counts_[i].resize(nRBins_);
767 evaluator3_.loadScriptString(selectionScript3_);
768 if (!evaluator3_.isDynamic()) {
769 seleMan3_.setSelectionSet(evaluator3_.evaluate());
772 deltaR_ = len_ / nRBins_;
775 void HBondJumpR::findHBonds(
int frame) {
778 SimInfo::MoleculeIterator mi, mj;
779 std::vector<Molecule::HBondDonor*>::iterator hbdi;
780 Molecule::HBondDonor* hbd;
781 std::vector<Atom*>::iterator hbai;
783 Vector3d dPos, hPos, aPos, pos;
784 int hInd, index, aInd;
790 if (evaluator3_.isDynamic()) {
791 seleMan3_.setSelectionSet(evaluator3_.evaluate());
794 bool usePeriodicBoundaryConditions_ =
795 info_->getSimParams()->getUsePeriodicBoundaryConditions();
798 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
799 mol1 = info_->nextMolecule(mi)) {
800 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
801 hbd = mol1->nextHBondDonor(hbdi)) {
802 hInd = hbd->donatedHydrogen->getGlobalIndex();
803 index = registerHydrogen(frame, hInd);
807 for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
808 mol1 = info_->nextMolecule(mi)) {
809 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
810 hbd = mol1->nextHBondDonor(hbdi)) {
811 hInd = hbd->donatedHydrogen->getGlobalIndex();
812 index = GIDtoH_[frame][hInd];
814 dPos = hbd->donorAtom->getPos();
815 hPos = hbd->donatedHydrogen->getPos();
817 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
818 mol2 = info_->nextMolecule(mj)) {
819 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
820 hba = mol2->nextHBondAcceptor(hbai)) {
821 aPos = hba->getPos();
823 if (isHBond(dPos, hPos, aPos)) {
824 aInd = hba->getGlobalIndex();
825 registerHydrogenBond(frame, index, hInd, aInd);
828 RealType shortest = HONKING_LARGE_VALUE;
831 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
832 sd3 = seleMan3_.nextSelected(isd3)) {
833 vec = pos - sd3->getPos();
835 if (usePeriodicBoundaryConditions_)
836 currentSnapshot_->wrapVector(vec);
840 if (r < shortest) shortest = r;
843 int whichBin = int(shortest / deltaR_);
844 if (whichBin <
int(nRBins_)) { rbin_[frame][index] = whichBin; }
850 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
851 hba = mol1->nextHBondAcceptor(hbai)) {
852 aPos = hba->getPos();
854 for (mj = mi, mol2 = info_->beginMolecule(mj); mol2 != NULL;
855 mol2 = info_->nextMolecule(mj)) {
856 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
857 hbd = mol2->nextHBondDonor(hbdi)) {
858 hInd = hbd->donatedHydrogen->getGlobalIndex();
860 index = GIDtoH_[frame][hInd];
862 dPos = hbd->donorAtom->getPos();
863 hPos = hbd->donatedHydrogen->getPos();
865 if (isHBond(dPos, hPos, aPos)) {
866 aInd = hba->getGlobalIndex();
867 registerHydrogenBond(frame, index, hInd, aInd);
869 RealType shortest = HONKING_LARGE_VALUE;
872 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
873 sd3 = seleMan3_.nextSelected(isd3)) {
874 vec = pos - sd3->getPos();
876 if (usePeriodicBoundaryConditions_)
877 currentSnapshot_->wrapVector(vec);
881 if (r < shortest) shortest = r;
884 int whichBin = int(shortest / deltaR_);
885 if (whichBin <
int(nRBins_)) { rbin_[frame][index] = whichBin; }
893 int HBondJumpR::registerHydrogen(
int frame,
int hIndex) {
897 if (GIDtoH_[frame][hIndex] == -1) {
898 index = hydrogen_[frame].size();
900 GIDtoH_[frame][hIndex] = index;
901 hydrogen_[frame].push_back(hIndex);
902 acceptor_[frame].push_back(-1);
903 selected_[frame].push_back(
false);
904 rbin_[frame].push_back(-1);
907 lastAcceptor_[frame].push_back(-1);
908 acceptorStartFrame_[frame].push_back(frame);
911 int prevIndex = GIDtoH_[frame - 1][hIndex];
912 lastAcceptor_[frame].push_back(lastAcceptor_[frame - 1][prevIndex]);
913 acceptorStartFrame_[frame].push_back(
914 acceptorStartFrame_[frame - 1][prevIndex]);
918 index = GIDtoH_[frame][hIndex];
923 void HBondJumpR::correlation() {
925 std::vector<int>::iterator i1;
926 int index1, index2, gid, aInd1, aInd2;
928 for (
int i = 0; i < nFrames_; ++i) {
929 RealType time1 = times_[i];
932 for (
int j = i; j < nFrames_; ++j) {
937 RealType time2 = times_[j];
939 if (fabs((time2 - time1) - (j - i) * deltaTime_) > 1.0e-4) {
940 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
941 "HBondJump::correlation Error: sampleTime (%f)\n"
942 "\tin %s does not match actual time-spacing between\n"
943 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
944 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
945 painCave.isFatal = 1;
949 int timeBin = int((time2 - time1) / deltaTime_ + 0.5);
953 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
956 index1 = GIDtoH_[i][gid];
959 index2 = GIDtoH_[j][gid];
961 if (selected_[i][index1]) {
962 if (
int rBin {rbin_[i][index1]}; rBin != -1) {
963 counts_[timeBin][rBin]++;
965 if (acceptor_[i][index1] == -1) {
966 aInd1 = lastAcceptor_[i][index1];
968 aInd1 = acceptor_[i][index1];
971 if (acceptor_[j][index2] == -1) {
972 aInd2 = lastAcceptor_[j][index2];
974 aInd2 = acceptor_[j][index2];
980 if (aInd1 != aInd2) {
982 histogram_[timeBin][rBin] += 1;
986 if (acceptorStartFrame_[i][index1] !=
987 acceptorStartFrame_[j][index2]) {
990 histogram_[timeBin][rBin] += 1;
993 histogram_[timeBin][rBin] += 0;
1003 void HBondJumpR::postCorrelate() {
1004 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
1005 for (
unsigned int j = 0; j < nRBins_; ++j) {
1006 if (counts_[i][j] > 0) {
1007 histogram_[i][j] /= counts_[i][j];
1009 histogram_[i][j] = 0;
1011 histogram_[i][j] = 1.0 - histogram_[i][j];
1016 void HBondJumpR::writeCorrelate() {
1017 ofstream ofs(outputFilename_.c_str());
1019 if (ofs.is_open()) {
1022 ofs <<
"# " << getCorrFuncType() <<
"\n";
1023 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
1024 ofs <<
"# " << r.getBuildDate() <<
"\n";
1025 ofs <<
"# selection script1: \"" << selectionScript1_;
1026 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
1027 if (!paramString_.empty())
1028 ofs <<
"# parameters: " << paramString_ <<
"\n";
1029 ofs <<
"#time\tcorrVal\n";
1031 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
1032 ofs << times_[i] - times_[0];
1034 for (
unsigned int j = 0; j < nRBins_; ++j) {
1035 ofs <<
"\t" << histogram_[i][j];
1041 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
1042 "HBondJumpR::writeCorrelate Error: fail to open %s\n",
1043 outputFilename_.c_str());
1044 painCave.isFatal = 1;
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)