Changeset dfe8ef for src/bondgraph.cpp


Ignore:
Timestamp:
Mar 30, 2010, 6:52:14 PM (15 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
62c9c0
Parents:
f18185
git-author:
Frederik Heber <heber@…> (03/30/10 18:49:01)
git-committer:
Frederik Heber <heber@…> (03/30/10 18:52:14)
Message:

BUGFIX: CountHydrogenBridgeBonds() was half-broken, CountBondsOfThree() double-counted.

  • CountBondsOfThree() was counting O-H molecules as having a H-O-H and also a O-H-O triple bond because of a missing break.
  • CountHydrogenBridgeBonds() was broken in several places:
    • Checking for Hydrogen on the other oxygen atom is not part of the criteria by Marry, Rotenberg and Turq.
    • HydrogenFlag could have been set by previous atom making next hydrogen also a h-bridge bond.

Found thanks to newly implemented unit test CountBondsUnitTest.

Signed-off-by: Frederik Heber <heber@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/bondgraph.cpp

    rf18185 rdfe8ef  
    183183  atom *Walker = NULL;
    184184  atom *Runner = NULL;
    185   atom *Hydrogen = NULL;
    186   atom *OtherHydrogen = NULL;
    187185  Vector OHBond;
    188186  Vector OOBond;
    189187  int count = 0;
    190   bool HydrogenFlag = false;
    191   bool OtherHydrogenFlag = false;
    192188  bool InterfaceFlag = false;
    193189  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin();MolWalker != molecules->ListOfMolecules.end(); MolWalker++) {
     
    202198            // check distance
    203199            const double distance = Runner->x.DistanceSquared(&Walker->x);
    204             if (distance < HBRIDGEDISTANCE*HBRIDGEDISTANCE) {
    205               // get hydrogen, check for InterfaceElement
    206               HydrogenFlag = false;
    207               OtherHydrogenFlag = false;
     200            if ((distance > MYEPSILON) && (distance < HBRIDGEDISTANCE*HBRIDGEDISTANCE)) { // distance >0 means  different atoms
    208201              InterfaceFlag = (InterfaceElement == NULL);
    209202              // on other atom(Runner) we check for bond to interface element
    210               for (BondList::const_iterator BondRunner = Runner->ListOfBonds.begin(); BondRunner != Runner->ListOfBonds.end(); BondRunner++) {
     203              for (BondList::const_iterator BondRunner = Runner->ListOfBonds.begin(); ((!InterfaceFlag) && (BondRunner != Runner->ListOfBonds.end())); BondRunner++) {
    211204                atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Runner);
    212                 if (!OtherHydrogenFlag && (OtherAtom->type->Z == 1)) {
    213                   OtherHydrogen = OtherAtom;
    214                   OtherHydrogenFlag = true;
    215                 }
    216205                InterfaceFlag = InterfaceFlag || (OtherAtom->type == InterfaceElement);
    217206              }
    218               // on this element (Walker) we check for bond to hydrogen, i.e. part of water molecule
    219               for (BondList::const_iterator BondRunner = Walker->ListOfBonds.begin(); BondRunner != Walker->ListOfBonds.end(); BondRunner++) {
    220                 atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
    221                 if (!HydrogenFlag && (OtherAtom->type->Z == 1)) {
    222                   Hydrogen = OtherAtom;
    223                   HydrogenFlag = true;
    224                 }
    225               }
    226               if (InterfaceFlag && HydrogenFlag) {
    227                 if ((Walker->nr < Runner->nr) || (!OtherHydrogenFlag)) {
    228                   // check angle
    229                   OHBond.CopyVector(&Hydrogen->x);
    230                   OHBond.SubtractVector(&Walker->x);
    231                   OOBond.CopyVector(&Runner->x);
    232                   OOBond.SubtractVector(&Walker->x);
    233                   const double angle = OHBond.Angle(&OOBond);
    234                   if (angle < M_PI*(30./180.)) {
    235                     DoLog(1) && (Log() << Verbose(1) << Walker->Name << ", " << Hydrogen->Name << " and " << Runner->Name << " have a hydrogen bridge bond with " << sqrt(distance) << " and at angle " << (180./M_PI)*angle << " degrees." << endl);
    236                     count++;
     207              if (InterfaceFlag) {
     208                // on this element (Walker) we check for bond to hydrogen, i.e. part of water molecule
     209                for (BondList::const_iterator BondRunner = Walker->ListOfBonds.begin(); BondRunner != Walker->ListOfBonds.end(); BondRunner++) {
     210                  atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
     211                  if (OtherAtom->type->Z == 1) {
     212                    // check angle
     213                    OHBond.CopyVector(&OtherAtom->x);
     214                    OHBond.SubtractVector(&Walker->x);
     215                    OOBond.CopyVector(&Runner->x);
     216                    OOBond.SubtractVector(&Walker->x);
     217                    const double angle = OHBond.Angle(&OOBond);
     218                    if (angle < M_PI*(30./180.)) {
     219                      DoLog(1) && (Log() << Verbose(1) << Walker->Name << ", " << OtherAtom->Name << " and " << Runner->Name << " have a hydrogen bridge bond with " << sqrt(distance) << " and at angle " << (180./M_PI)*angle << " degrees." << endl);
     220                      count++;
     221                      break;
     222                    }
    237223                  }
    238224                }
     
    305291          atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
    306292          for (int i=0;i<2;i++)
    307             MatchFlag[i] = MatchFlag[i] || (OtherAtom->type == ElementArray[i]);
     293            if ((!MatchFlag[i]) && (OtherAtom->type == ElementArray[i])) {
     294              MatchFlag[i] = true;
     295              break;  // each bonding atom can match at most one element we are looking for
     296            }
    308297        }
    309298        result = true;
    310         for (int i=0;i<2;i++)
     299        for (int i=0;i<2;i++) // gather results
    311300          result = result && MatchFlag[i];
    312         if (result) {
     301        if (result) { // check results
    313302          count++;
    314303          DoLog(1) && (Log() << Verbose(1) << first->name << "-" << second->name << "-" << third->name << " bond found at " << *Walker << "." << endl);
Note: See TracChangeset for help on using the changeset viewer.