48#include "applications/dynamicProps/HBondPersistence.hpp"
52#include "utils/Constants.hpp"
55 HBondPersistence::HBondPersistence(
SimInfo* info,
const std::string& filename,
56 const std::string& sele1,
57 const std::string& sele2,
double OOcut,
58 double thetaCut,
double OHcut) :
60 OOCut_(OOcut), thetaCut_(thetaCut), OHCut_(OHcut) {
61 setCorrFuncType(
"HBondPersistence");
62 setOutputName(
getPrefix(dumpFilename_) +
".HBpersistence");
64 std::stringstream params;
65 params <<
" OOcut = " << OOCut_ <<
", thetacut = " << thetaCut_
66 <<
", OHcut = " << OHCut_;
67 const std::string paramString = params.str();
68 setParameterString(paramString);
71 GIDtoDonor_.resize(nFrames_);
72 DonorToGID_.resize(nFrames_);
73 acceptor_.resize(nFrames_);
76 void HBondPersistence::computeFrame(
int istep) {
79 std::vector<Molecule::HBondDonor*>::iterator hbdi;
80 Molecule::HBondDonor* hbd;
81 std::vector<Atom*>::iterator hbai;
90 RealType DAdist, DHdist, HAdist, theta, ctheta;
92 int hInd, aInd, index;
95 GIDtoDonor_[istep].resize(info_->getNGlobalAtoms(), -1);
97 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
99 if (evaluator1_.isDynamic()) {
100 seleMan1_.setSelectionSet(evaluator1_.evaluate());
103 if (uniqueSelections_ && evaluator2_.isDynamic()) {
104 seleMan2_.setSelectionSet(evaluator2_.evaluate());
107 for (mol1 = seleMan1_.beginSelectedMolecule(ii); mol1 != NULL;
108 mol1 = seleMan1_.nextSelectedMolecule(ii)) {
109 for (mol2 = seleMan2_.beginSelectedMolecule(jj); mol2 != NULL;
110 mol2 = seleMan2_.nextSelectedMolecule(jj)) {
112 for (hbd = mol1->beginHBondDonor(hbdi); hbd != NULL;
113 hbd = mol1->nextHBondDonor(hbdi)) {
114 dPos = hbd->donorAtom->getPos();
115 hPos = hbd->donatedHydrogen->getPos();
117 currentSnapshot_->wrapVector(DH);
118 DHdist = DH.length();
120 hInd = hbd->donatedHydrogen->getGlobalIndex();
124 for (hba = mol2->beginHBondAcceptor(hbai); hba != NULL;
125 hba = mol2->nextHBondAcceptor(hbai)) {
126 aPos = hba->getPos();
128 currentSnapshot_->wrapVector(DA);
129 DAdist = DA.length();
133 if (DAdist < OOCut_) {
135 currentSnapshot_->wrapVector(HA);
136 HAdist = HA.length();
138 ctheta =
dot(DH, DA) / (DHdist * DAdist);
139 theta = acos(ctheta) * 180.0 / Constants::PI;
142 if (theta < thetaCut_ && HAdist < OHCut_) {
144 aInd = hba->getGlobalIndex();
146 index = acceptor_[istep].size();
147 GIDtoDonor_[istep][hInd] = index;
149 acceptor_[istep].push_back(aInd);
150 DonorToGID_[istep].push_back(hInd);
157 for (hbd = mol2->beginHBondDonor(hbdi); hbd != NULL;
158 hbd = mol2->nextHBondDonor(hbdi)) {
159 dPos = hbd->donorAtom->getPos();
160 hPos = hbd->donatedHydrogen->getPos();
162 currentSnapshot_->wrapVector(DH);
163 DHdist = DH.length();
165 hInd = hbd->donatedHydrogen->getGlobalIndex();
169 for (hba = mol1->beginHBondAcceptor(hbai); hba != NULL;
170 hba = mol1->nextHBondAcceptor(hbai)) {
171 aPos = hba->getPos();
173 currentSnapshot_->wrapVector(DA);
174 DAdist = DA.length();
178 if (DAdist < OOCut_) {
180 currentSnapshot_->wrapVector(HA);
181 HAdist = HA.length();
183 ctheta =
dot(DH, DA) / (DHdist * DAdist);
184 theta = acos(ctheta) * 180.0 / Constants::PI;
187 if (theta < thetaCut_ && HAdist < OHCut_) {
189 aInd = hba->getGlobalIndex();
190 index = acceptor_[istep].size();
191 GIDtoDonor_[istep][hInd] = index;
193 acceptor_[istep].push_back(aInd);
194 DonorToGID_[istep].push_back(hInd);
203 void HBondPersistence::correlation() {
205 std::vector<int>::iterator i1;
208 int index1, index2, count, gid;
210 for (
int i = 0; i < nFrames_; ++i) {
211 RealType time1 = times_[i];
214 for (
int j = i; j < nFrames_; ++j) {
219 RealType time2 = times_[j];
221 if (fabs((time2 - time1) - (j - i) * deltaTime_) > 1.0e-4) {
222 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
223 "HBondPersistence::correlation Error: sampleTime (%f)\n"
224 "\tin %s does not match actual time-spacing between\n"
225 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
226 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
227 painCave.isFatal = 1;
231 int timeBin = int((time2 - time1) / deltaTime_ + 0.5);
238 for (i1 = s1.begin(); i1 != s1.end(); ++i1) {
242 index1 = GIDtoDonor_[i][gid];
245 index2 = GIDtoDonor_[j][gid];
253 if (acceptor_[i][index1] == acceptor_[j][index2])
259 histogram_[timeBin] += corrVal;
260 count_[timeBin] += count;
265 void HBondPersistence::postCorrelate() {
266 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
268 histogram_[i] /= count_[i];
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...
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)