Ignore:
Timestamp:
Mar 1, 2011, 12:49:28 PM (14 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:
0cbad2
Parents:
ce5f05
git-author:
Frederik Heber <heber@…> (02/26/11 00:10:05)
git-committer:
Frederik Heber <heber@…> (03/01/11 12:49:28)
Message:

Moved molecule::CreateAdjacencyList over to class BondGraph.

to make this possible we had to:

other changes:

TESTFIXES:

  • the regression test for all Actions mentioned above that don't create adjacency themselves anymore needed to be prepended with --select-all-atoms --create-adjacency.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecule_graph.cpp

    rce5f05 r3738f0  
    111111}
    112112
    113 /** Creates an adjacency list of the molecule.
    114  * Generally, we use the CSD approach to bond recognition, that is the the distance
    115  * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    116  * a threshold t = 0.4 Angstroem.
    117  * To make it O(N log N) the function uses the linked-cell technique as follows:
    118  * The procedure is step-wise:
    119  *  -# Remove every bond in list
    120  *  -# Count the atoms in the molecule with CountAtoms()
    121  *  -# partition cell into smaller linked cells of size \a bonddistance
    122  *  -# put each atom into its corresponding cell
    123  *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    124  *  -# correct the bond degree iteratively (single->double->triple bond)
    125  *  -# finally print the bond list to \a *out if desired
    126  * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
    127  * \param IsAngstroem whether coordinate system is gauged to Angstroem or Bohr radii
    128  * \param *minmaxdistance function to give upper and lower bound on whether particle is bonded to some other
    129  * \param *BG BondGraph with the member function above or NULL, if just standard covalent should be used.
    130  */
    131 void molecule::CreateAdjacencyList(
    132     double bonddistance,
    133     bool IsAngstroem,
    134     void (BondGraph::*minmaxdistance)(const BondedParticle * const , const BondedParticle * const , double &, double &, bool),
    135     BondGraph *BG)
    136 {
    137   atom *Walker = NULL;
    138   atom *OtherWalker = NULL;
    139   int n[NDIM];
    140   double MinDistance, MaxDistance;
    141   LinkedCell *LC = NULL;
    142   bool free_BG = false;
    143   Box &domain = World::getInstance().getDomain();
    144 
    145   DoLog(0) && (Log() << Verbose(0) << "Begin of CreateAdjacencyList." << endl);
    146   // remove every bond from the list
    147   for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) {
    148     BondList& ListOfBonds = (*AtomRunner)->getListOfBonds();
    149     for(BondList::iterator BondRunner = ListOfBonds.begin();
    150         !ListOfBonds.empty();
    151         BondRunner = ListOfBonds.begin())
    152       if ((*BondRunner)->leftatom == *AtomRunner)
    153         delete((*BondRunner));
    154   }
    155 
    156   // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    157   DoLog(1) && (Log() << Verbose(1) << "AtomCount " << getAtomCount() << " and bonddistance is " << bonddistance << "." << endl);
    158 
    159   if ((getAtomCount() > 1) && (bonddistance > 0.1)) {
    160     DoLog(2) && (Log() << Verbose(2) << "Creating Linked Cell structure ... " << endl);
    161     PointCloudAdaptor<molecule> cloud(this, name);
    162     LC = new LinkedCell(cloud, bonddistance);
    163 
    164     // create a list to map Tesselpoint::Nr to atom *
    165     DoLog(2) && (Log() << Verbose(2) << "Creating TesselPoint to atom map ... " << endl);
    166 
    167     // set numbers for atoms that can later be used
    168     int i=0;
    169     for(internal_iterator iter = atoms.begin();iter!= atoms.end(); ++iter){
    170       (*iter)->setNr(i++);
    171     }
    172 
    173     // 3a. go through every cell
    174     DoLog(2) && (Log() << Verbose(2) << "Celling ... " << endl);
    175     for (LC->n[0] = 0; LC->n[0] < LC->N[0]; LC->n[0]++)
    176       for (LC->n[1] = 0; LC->n[1] < LC->N[1]; LC->n[1]++)
    177         for (LC->n[2] = 0; LC->n[2] < LC->N[2]; LC->n[2]++) {
    178           const TesselPointSTLList *List = LC->GetCurrentCell();
    179           Log() << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
    180           if (List != NULL) {
    181             for (TesselPointSTLList::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    182               Walker = dynamic_cast<atom*>(*Runner);
    183               ASSERT(Walker,"Tesselpoint that was not an atom retrieved from LinkedNode");
    184               Log() << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    185               // 3c. check for possible bond between each atom in this and every one in the 27 cells
    186               for (n[0] = -1; n[0] <= 1; n[0]++)
    187                 for (n[1] = -1; n[1] <= 1; n[1]++)
    188                   for (n[2] = -1; n[2] <= 1; n[2]++) {
    189                     const TesselPointSTLList *OtherList = LC->GetRelativeToCurrentCell(n);
    190                     if (OtherList != NULL) {
    191                       Log() << Verbose(2) << "Current relative cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
    192                       for (TesselPointSTLList::const_iterator OtherRunner = OtherList->begin(); OtherRunner != OtherList->end(); OtherRunner++) {
    193                         if ((*OtherRunner)->getNr() > Walker->getNr()) {
    194                           OtherWalker = dynamic_cast<atom*>(*OtherRunner);
    195                           ASSERT(OtherWalker,"TesselPoint that was not an atom retrieved from LinkedNode");
    196                           (BG->*minmaxdistance)(Walker, OtherWalker, MinDistance, MaxDistance, IsAngstroem);
    197                           const double distance = domain.periodicDistanceSquared(OtherWalker->getPosition(),Walker->getPosition());
    198                           Log() << Verbose(1) << "Checking distance " << distance << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    199                           const bool status = (distance <= MaxDistance * MaxDistance) && (distance >= MinDistance * MinDistance);
    200                           Log() << Verbose(1) << "MinDistance is " << MinDistance << " and MaxDistance is " << MaxDistance << "." << endl;
    201                           if (OtherWalker->father->getNr() > Walker->father->getNr()) {
    202                             if (status) { // create bond if distance is smaller
    203                               Log() << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    204                               AddBond(Walker->father, OtherWalker->father, 1); // also increases molecule::BondCount
    205                             } else {
    206                               Log() << Verbose(1) << "Not Adding: distance too great." << endl;
    207                             }
    208                           } else {
    209                             Log() << Verbose(1) << "Not Adding: Wrong order of labels." << endl;
    210                           }
    211                         }
    212                       }
    213                     }
    214                   }
    215             }
    216           }
    217         }
    218     delete (LC);
    219     DoLog(1) && (Log() << Verbose(1) << "I detected " << getBondCount() << " bonds in the molecule." << endl);
    220 
    221     // correct bond degree by comparing valence and bond degree
    222     DoLog(2) && (Log() << Verbose(2) << "Correcting bond degree ... " << endl);
    223     CorrectBondDegree();
    224 
    225     // output bonds for debugging (if bond chain list was correctly installed)
    226     for(molecule::internal_iterator iter = atoms.begin(); iter != atoms.end(); ++iter)
    227       (*iter)->OutputBondOfAtom((std::ostream &)std::cout);
    228   } else
    229     DoLog(1) && (Log() << Verbose(1) << "AtomCount is " << getAtomCount() << ", thus no bonds, no connections!." << endl);
    230   DoLog(0) && (Log() << Verbose(0) << "End of CreateAdjacencyList." << endl);
    231   if (free_BG)
    232     delete(BG);
    233 }
    234 ;
    235 
    236113/** Checks for presence of bonds within atom list.
    237114 * TODO: more sophisticated check for bond structure (e.g. connected subgraph, ...)
     
    265142}
    266143;
    267 
    268 /** correct bond degree by comparing valence and bond degree.
    269  * correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    270  * iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    271  * preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    272  * double bonds as was expected.
    273  * \return number of bonds that could not be corrected
    274  */
    275 int molecule::CorrectBondDegree() const
    276 {
    277   int No = 0, OldNo = -1;
    278 
    279   if (getBondCount() != 0) {
    280     DoLog(1) && (Log() << Verbose(1) << "Correcting Bond degree of each bond ... " << endl);
    281     do {
    282       OldNo = No;
    283       No=0;
    284       BOOST_FOREACH(atom *atom,atoms){
    285         No+=atom->CorrectBondDegree();
    286       }
    287     } while (OldNo != No);
    288     DoLog(0) && (Log() << Verbose(0) << " done." << endl);
    289   } else {
    290     DoLog(1) && (Log() << Verbose(1) << "BondCount is " << getBondCount() << ", no bonds between any of the " << getAtomCount() << " atoms." << endl);
    291   }
    292   DoLog(0) && (Log() << Verbose(0) << No << " bonds could not be corrected." << endl);
    293 
    294   return (No);
    295 }
    296144
    297145
Note: See TracChangeset for help on using the changeset viewer.