ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/HBondGeometric.cpp
(Generate patch)

Comparing trunk/src/applications/staticProps/HBondGeometric.cpp (file contents):
Revision 2050 by gezelter, Tue Jan 6 21:53:12 2015 UTC vs.
Revision 2071 by gezelter, Sat Mar 7 21:41:51 2015 UTC

# Line 56 | Line 56 | namespace OpenMD {
56                                   const std::string& sele2,
57                                   double rCut, double thetaCut, int nbins) :
58      StaticAnalyser(info, filename),
59 <    selectionScript1_(sele1), evaluator1_(info), seleMan1_(info),
60 <    selectionScript2_(sele2), evaluator2_(info), seleMan2_(info){
59 >    selectionScript1_(sele1), seleMan1_(info), evaluator1_(info),
60 >    selectionScript2_(sele2), seleMan2_(info), evaluator2_(info) {
61      
62      setOutputName(getPrefix(filename) + ".hbg");
63  
# Line 99 | Line 99 | namespace OpenMD {
99    }
100    
101    void HBondGeometric::process() {
102 <    Molecule* mol;
103 <    StuntDouble* sd1;
104 <    StuntDouble* sd2;
102 >    Molecule* mol1;
103 >    Molecule* mol2;
104      RigidBody* rb1;
105 <    RigidBody* rb2;
105 >    Molecule::HBondDonor* hbd1;
106 >    Molecule::HBondDonor* hbd2;
107 >    std::vector<Molecule::HBondDonor*>::iterator hbdi;
108 >    std::vector<Molecule::HBondDonor*>::iterator hbdj;
109 >    std::vector<Atom*>::iterator hbai;
110 >    std::vector<Atom*>::iterator hbaj;
111 >    Atom* hba1;
112 >    Atom* hba2;
113      SimInfo::MoleculeIterator mi;
114      Molecule::RigidBodyIterator rbIter;
115      Molecule::IntegrableObjectIterator ioi;
116 +    Vector3d dPos;
117 +    Vector3d aPos;
118 +    Vector3d hPos;
119 +    Vector3d DH;
120 +    Vector3d DA;
121 +    RealType DAdist, DHdist, theta, ctheta;
122      int ii, jj;
111    std::string rbName;
112    std::vector<Atom *> atoms1;
113    std::vector<Atom *> atoms2;
114    std::vector<Atom *>::iterator ai1;
115    std::vector<Atom *>::iterator ai2;
116    Vector3d O1pos, O2pos;
117    Vector3d H1apos, H1bpos, H2apos, H2bpos;
123      int nHB, nA, nD;
124  
125      DumpReader reader(info_, dumpFilename_);    
# Line 128 | Line 133 | namespace OpenMD {
133      
134        // update the positions of atoms which belong to the rigidbodies
135        
136 <      for (mol = info_->beginMolecule(mi); mol != NULL;
137 <           mol = info_->nextMolecule(mi)) {
138 <        for (rb1 = mol->beginRigidBody(rbIter); rb1 != NULL;
139 <             rb1 = mol->nextRigidBody(rbIter)) {
136 >      for (mol1 = info_->beginMolecule(mi); mol1 != NULL;
137 >           mol1 = info_->nextMolecule(mi)) {
138 >        for (rb1 = mol1->beginRigidBody(rbIter); rb1 != NULL;
139 >             rb1 = mol1->nextRigidBody(rbIter)) {
140            rb1->updateAtoms();
141          }        
142        }          
# Line 143 | Line 148 | namespace OpenMD {
148          seleMan2_.setSelectionSet(evaluator2_.evaluate());
149        }
150        
151 <      for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) {
152 <        if (sd1->isRigidBody()) {
148 <          rb1 = dynamic_cast<RigidBody*>(sd1);
149 <          atoms1 = rb1->getAtoms();
150 <          
151 <          int nH = 0;
152 <          int nO = 0;
153 <          
154 <          for (ai1 = atoms1.begin(); ai1 != atoms1.end(); ++ai1) {
155 <            std::string atName =  (*ai1)->getType();
156 <            // query the force field for the AtomType associated with this
157 <            // atomTypeName:
158 <            AtomType* at = ff_->getAtomType(atName);
159 <            // get the chain of base types for this atom type:
160 <            std::vector<AtomType*> ayb = at->allYourBase();
161 <            // use the last type in the chain of base types for the name:
162 <            std::string bn = ayb[ayb.size()-1]->getName();
163 <            
164 <            bool isH = bn.compare("H") == 0 ? true : false;
165 <            bool isO = bn.compare("O") == 0 ? true : false;
166 <            
167 <            if (isO && nO == 0) {
168 <              O1pos = (*ai1)->getPos();
169 <              nO++;
170 <            }
171 <            if (isH) {
172 <              if (nH == 0) {
173 <                H1apos =  (*ai1)->getPos();
174 <              }
175 <              if (nH == 1) {
176 <                H1bpos =  (*ai1)->getPos();
177 <              }
178 <              nH++;
179 <            }
180 <          }
181 <        }
151 >      for (mol1 = seleMan1_.beginSelectedMolecule(ii);
152 >           mol1 != NULL; mol1 = seleMan1_.nextSelectedMolecule(ii)) {
153  
154 <
154 >        // We're collecting statistics on the molecules in selection 1:
155          nHB = 0;
156          nA = 0;
157          nD = 0;
158          
159 <        for (sd2 = seleMan2_.beginSelected(jj); sd2 != NULL; sd2 = seleMan2_.nextSelected(jj)) {
159 >        for (mol2 = seleMan2_.beginSelectedMolecule(jj);
160 >             mol2 != NULL; mol2 = seleMan2_.nextSelectedMolecule(jj)) {
161 >          
162 >          // loop over the possible donors in molecule 1:
163 >          for (hbd1 = mol1->beginHBondDonor(hbdi); hbd1 != NULL;
164 >               hbd1 = mol1->nextHBondDonor(hbdi)) {
165 >            dPos = hbd1->donorAtom->getPos();
166 >            hPos = hbd1->donatedHydrogen->getPos();
167 >            DH = hPos - dPos;
168 >            currentSnapshot_->wrapVector(DH);
169 >            DHdist = DH.length();
170  
171 <          if (sd1 == sd2) continue;
172 <          
173 <          if (sd2->isRigidBody()) {
174 <            rb2 = dynamic_cast<RigidBody*>(sd2);
175 <            atoms2 = rb2->getAtoms();
176 <            
177 <            int nH = 0;
197 <            int nO = 0;
198 <            
199 <            for (ai2 = atoms2.begin(); ai2 != atoms2.end(); ++ai2) {
200 <              std::string atName =  (*ai2)->getType();
201 <              // query the force field for the AtomType associated with this
202 <              // atomTypeName:
203 <              AtomType* at = ff_->getAtomType(atName);
204 <              // get the chain of base types for this atom type:
205 <              std::vector<AtomType*> ayb = at->allYourBase();
206 <              // use the last type in the chain of base types for the name:
207 <              std::string bn = ayb[ayb.size()-1]->getName();
208 <              
209 <              bool isH = bn.compare("H") == 0 ? true : false;
210 <              bool isO = bn.compare("O") == 0 ? true : false;
171 >            // loop over the possible acceptors in molecule 2:
172 >            for (hba2 = mol2->beginHBondAcceptor(hbaj); hba2 != NULL;
173 >                 hba2 = mol2->nextHBondAcceptor(hbaj)) {
174 >              aPos = hba2->getPos();
175 >              DA = aPos - dPos;              
176 >              currentSnapshot_->wrapVector(DA);
177 >              DAdist = DA.length();
178  
179 <              if (isO && nO == 0) {
180 <                O2pos = (*ai2)->getPos();
181 <                  nO++;
182 <              }
183 <              if (isH) {
184 <                if (nH == 0) {
185 <                  H2apos =  (*ai2)->getPos();
179 >              // Distance criteria: are the donor and acceptor atoms
180 >              // close enough?
181 >              if (DAdist < rCut_) {
182 >
183 >                ctheta = dot(DH, DA) / (DHdist * DAdist);
184 >                theta = acos(ctheta) * 180.0 / M_PI;
185 >
186 >                // Angle criteria: are the D-H and D-A and vectors close?
187 >                if (theta < thetaCut_) {
188 >                  // molecule 1 is a Hbond donor:
189 >                  nHB++;
190 >                  nD++;
191                  }
192 <                if (nH == 1) {
193 <                  H2bpos =  (*ai2)->getPos();
194 <                }
195 <                nH++;
196 <              }
197 <            }
192 >              }            
193 >            }            
194 >          }
195 >
196 >          // now loop over the possible acceptors in molecule 1:
197 >          for (hba1 = mol1->beginHBondAcceptor(hbai); hba1 != NULL;
198 >               hba1 = mol1->nextHBondAcceptor(hbai)) {
199 >            aPos = hba1->getPos();
200              
201 <            // Do our testing:
202 <            Vector3d Odiff = O2pos - O1pos;
203 <            currentSnapshot_->wrapVector(Odiff);
204 <            RealType Odist = Odiff.length();
231 <            if (Odist < rCut_) {
232 <              // OH vectors:
233 <              Vector3d HO1a = H1apos - O1pos;
234 <              Vector3d HO1b = H1bpos - O1pos;
235 <              Vector3d HO2a = H2apos - O2pos;
236 <              Vector3d HO2b = H2bpos - O2pos;
237 <              // wrapped in case a molecule is split across boundaries:
238 <              currentSnapshot_->wrapVector(HO1a);
239 <              currentSnapshot_->wrapVector(HO1b);
240 <              currentSnapshot_->wrapVector(HO2a);
241 <              currentSnapshot_->wrapVector(HO2a);
242 <              // cos thetas:
243 <              RealType ctheta1a = dot(HO1a, Odiff) / (Odist * HO1a.length());
244 <              RealType ctheta1b = dot(HO1b, Odiff) / (Odist * HO1b.length());
245 <              RealType ctheta2a = dot(HO2a, -Odiff) / (Odist * HO2a.length());
246 <              RealType ctheta2b = dot(HO2b, -Odiff) / (Odist * HO2b.length());
201 >            // loop over the possible donors in molecule 2:
202 >            for (hbd2 = mol2->beginHBondDonor(hbdj); hbd2 != NULL;
203 >               hbd2 = mol2->nextHBondDonor(hbdj)) {
204 >              dPos = hbd2->donorAtom->getPos();
205  
206 <              RealType theta1a = acos(ctheta1a) * 180.0 / M_PI;
207 <              RealType theta1b = acos(ctheta1b) * 180.0 / M_PI;
208 <              RealType theta2a = acos(ctheta2a) * 180.0 / M_PI;
209 <              RealType theta2b = acos(ctheta2b) * 180.0 / M_PI;
210 <
211 <              if (theta1a < thetaCut_) {
212 <                // molecule 1 is a Hbond donor:
213 <                nHB++;
214 <                nD++;
206 >              DA = aPos - dPos;
207 >              currentSnapshot_->wrapVector(DA);
208 >              DAdist = DA.length();
209 >              
210 >              // Distance criteria: are the donor and acceptor atoms
211 >              // close enough?
212 >              if (DAdist < rCut_) {
213 >                hPos = hbd2->donatedHydrogen->getPos();
214 >                DH = hPos - dPos;
215 >                currentSnapshot_->wrapVector(DH);
216 >                DHdist = DH.length();
217 >                ctheta = dot(DH, DA) / (DHdist * DAdist);
218 >                theta = acos(ctheta) * 180.0 / M_PI;
219 >                // Angle criteria: are the D-H and D-A and vectors close?
220 >                if (theta < thetaCut_) {
221 >                  // molecule 1 is a Hbond acceptor:
222 >                  nHB++;
223 >                  nA++;
224 >                }                
225                }
226 <              if (theta1b < thetaCut_) {
259 <                // molecule 1 is a Hbond donor:
260 <                nHB++;
261 <                nD++;
262 <              }
263 <              if (theta2a < thetaCut_) {
264 <                // molecule 1 is a Hbond acceptor:
265 <                nHB++;
266 <                nA++;
267 <              }
268 <              if (theta2b < thetaCut_) {
269 <                // molecule 1 is a Hbond acceptor:
270 <                nHB++;
271 <                nA++;
272 <              }
273 <            }            
226 >            }
227            }
228 <        }
228 >        }                
229          collectHistogram(nHB, nA, nD);
230        }
231      }
# Line 291 | Line 244 | namespace OpenMD {
244    void HBondGeometric::writeHistogram() {
245          
246      std::ofstream osq(getOutputFileName().c_str());
294    cerr << "nSelected = " << nSelected_ << "\n";
247  
248      if (osq.is_open()) {
249        
250        osq << "# HydrogenBonding Statistics\n";
251        osq << "# selection1: (" << selectionScript1_ << ")"
252            << "\tselection2: (" << selectionScript2_ <<  ")\n";
253 <      osq << "# p(nHBonds)\tp(nAcceptor)\tp(nDonor)\n";
253 >      osq << "# molecules in selection1: " << nSelected_ << "\n";
254 >      osq << "# nHBonds\tnAcceptor\tnDonor\tp(nHBonds)\tp(nAcceptor)\tp(nDonor)\n";
255        // Normalize by number of frames and write it out:
256        for (int i = 0; i < nBins_; ++i) {
257          osq << i;
258 +        osq << "\t" << nHBonds_[i];
259 +        osq << "\t" << nAcceptor_[i];
260 +        osq << "\t" << nDonor_[i];
261          osq << "\t" << (RealType) (nHBonds_[i]) / nSelected_;
262          osq << "\t" << (RealType) (nAcceptor_[i]) / nSelected_;
263          osq << "\t" << (RealType) (nDonor_[i]) / nSelected_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines