45#include "applications/dynamicProps/HBondPersistence.hpp"
49#include "utils/Constants.hpp"
52 HBondPersistence::HBondPersistence(SimInfo* info,
const std::string& filename,
53 const std::string& sele1,
54 const std::string& sele2,
double OOcut,
55 double thetaCut,
double OHcut) :
56 TimeCorrFunc<RealType>(info, filename, sele1, sele2),
57 OOCut_(OOcut), thetaCut_(thetaCut), OHCut_(OHcut) {
58 setCorrFuncType(
"HBondPersistence");
59 setOutputName(
getPrefix(dumpFilename_) +
".HBpersistence");
61 std::stringstream params;
62 params <<
" OOcut = " << OOCut_ <<
", thetacut = " << thetaCut_
63 <<
", OHcut = " << OHCut_;
64 const std::string paramString = params.str();
65 setParameterString(paramString);
68 GIDtoDonor_.resize(nFrames_);
69 DonorToGID_.resize(nFrames_);
70 acceptor_.resize(nFrames_);
73 void HBondPersistence::computeFrame(
int istep) {
76 std::vector<Molecule::HBondDonor*>::iterator hbdi;
77 Molecule::HBondDonor* hbd;
78 std::vector<Atom*>::iterator hbai;
87 RealType DAdist, DHdist, HAdist, theta, ctheta;
89 int hInd, aInd, index;
92 GIDtoDonor_[istep].resize(info_->getNGlobalAtoms(), -1);
94 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
96 if (evaluator1_.isDynamic()) {
97 seleMan1_.setSelectionSet(evaluator1_.evaluate());
100 if (uniqueSelections_ && evaluator2_.isDynamic()) {
101 seleMan2_.setSelectionSet(evaluator2_.evaluate());
104 for (mol1 = seleMan1_.beginSelectedMolecule(ii); mol1 != NULL;
105 mol1 = seleMan1_.nextSelectedMolecule(ii)) {
106 for (mol2 = seleMan2_.beginSelectedMolecule(jj); mol2 != NULL;
107 mol2 = seleMan2_.nextSelectedMolecule(jj)) {
109 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
110 hbd = mol1->nextHBondDonor(hbdi)) {
111 dPos = hbd->donorAtom->getPos();
112 hPos = hbd->donatedHydrogen->getPos();
114 currentSnapshot_->wrapVector(DH);
117 hInd = hbd->donatedHydrogen->getGlobalIndex();
121 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
122 hba = mol2->nextHBondAcceptor(hbai)) {
123 aPos = hba->getPos();
125 currentSnapshot_->wrapVector(DA);
126 DAdist = DA.length();
130 if (DAdist < OOCut_) {
132 currentSnapshot_->wrapVector(HA);
133 HAdist = HA.length();
135 ctheta =
dot(DH, DA) / (DHdist * DAdist);
136 theta = acos(ctheta) * 180.0 / Constants::PI;
139 if (theta < thetaCut_ && HAdist < OHCut_) {
141 aInd = hba->getGlobalIndex();
143 index = acceptor_[istep].size();
144 GIDtoDonor_[istep][hInd] = index;
146 acceptor_[istep].push_back(aInd);
147 DonorToGID_[istep].push_back(hInd);
154 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
155 hbd = mol2->nextHBondDonor(hbdi)) {
156 dPos = hbd->donorAtom->getPos();
157 hPos = hbd->donatedHydrogen->getPos();
159 currentSnapshot_->wrapVector(DH);
160 DHdist = DH.length();
162 hInd = hbd->donatedHydrogen->getGlobalIndex();
166 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
167 hba = mol1->nextHBondAcceptor(hbai)) {
168 aPos = hba->getPos();
170 currentSnapshot_->wrapVector(DA);
171 DAdist = DA.length();
175 if (DAdist < OOCut_) {
177 currentSnapshot_->wrapVector(HA);
178 HAdist = HA.length();
180 ctheta =
dot(DH, DA) / (DHdist * DAdist);
181 theta = acos(ctheta) * 180.0 / Constants::PI;
184 if (theta < thetaCut_ && HAdist < OHCut_) {
186 aInd = hba->getGlobalIndex();
187 index = acceptor_[istep].size();
188 GIDtoDonor_[istep][hInd] = index;
190 acceptor_[istep].push_back(aInd);
191 DonorToGID_[istep].push_back(hInd);
200 void HBondPersistence::correlation() {
202 std::vector<int>::iterator i1;
205 int index1, index2, count, gid;
207 for (
int i = 0; i < nFrames_; ++i) {
208 RealType time1 = times_[i];
211 for (
int j = i; j < nFrames_; ++j) {
216 RealType time2 = times_[j];
218 if (fabs((time2 - time1) - (j - i) * deltaTime_) > 1.0e-4) {
219 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
220 "HBondPersistence::correlation Error: sampleTime (%f)\n"
221 "\tin %s does not match actual time-spacing between\n"
222 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
223 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
224 painCave.isFatal = 1;
228 int timeBin = int((time2 - time1) / deltaTime_ + 0.5);
235 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
239 index1 = GIDtoDonor_[i][gid];
242 index2 = GIDtoDonor_[j][gid];
250 if (acceptor_[i][index1] == acceptor_[j][index2])
256 histogram_[timeBin] += corrVal;
257 count_[timeBin] += count;
262 void HBondPersistence::postCorrelate() {
263 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
265 histogram_[i] /= count_[i];
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)