- Timestamp:
- Jul 30, 2008, 1:11:30 PM (16 years ago)
- 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:
- af6d8f
- Parents:
- 683914
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
r683914 r41baaf 1442 1442 void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem) 1443 1443 { 1444 atom *Walker = NULL, *OtherWalker = NULL ;1445 int No, NoBonds ;1444 atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL; 1445 int No, NoBonds, CandidateBondNo; 1446 1446 int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j; 1447 1447 molecule **CellList; … … 1556 1556 CreateListOfBondsPerAtom(out); 1557 1557 1558 // correct Bond degree of each bond by checking of updated(!) sum of bond degree for an atom match its valence count 1559 // bond degrres are correctled iteratively by one, so that 2-2 instead of 1-3 or 3-1 corrections are favoured: We want 1560 // a rather symmetric distribution of higher bond degrees 1558 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees, 1559 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene 1560 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of 1561 // double bonds as was expected. 1561 1562 if (BondCount != 0) { 1562 1563 NoCyclicBonds = 0; … … 1567 1568 while (Walker->next != end) { // go through every atom 1568 1569 Walker = Walker->next; 1569 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners 1570 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); 1571 // count valence of first partner (updated!), might have changed during last bond partner 1572 NoBonds = 0; 1573 for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) 1574 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree; 1575 *out << Verbose(3) << "Walker: " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 1576 if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check NoBonds of other atom 1570 // count valence of first partner 1571 NoBonds = 0; 1572 for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) 1573 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree; 1574 *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 1575 if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch 1576 Candidate = NULL; 1577 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners 1578 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); 1577 1579 // count valence of second partner 1578 1580 NoBonds = 0; 1579 1581 for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++) 1580 1582 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree; 1581 *out << Verbose(3) << "OtherWalker: " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 1582 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) // increase bond degree by one 1583 ListOfBondsPerAtom[Walker->nr][i]->BondDegree++; 1583 *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 1584 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate 1585 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first 1586 Candidate = OtherWalker; 1587 CandidateBondNo = i; 1588 *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl; 1589 } 1590 } 1584 1591 } 1592 if (Candidate != NULL) { 1593 ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++; 1594 *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl; 1595 } 1585 1596 } 1586 1597 } … … 1801 1812 1802 1813 /** Analyses the cycles found and returns minimum of all cycle lengths. 1814 * We begin with a list of Back edges found during DepthFirstSearchAnalysis(). We go through this list - one end is the Root, 1815 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as 1816 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds 1817 * as cyclic and print out the cycles. 1803 1818 * \param *out output stream for debugging 1804 1819 * \param *BackEdgeStack stack with all back edges found during DFS scan … … 1812 1827 enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList"); 1813 1828 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 1814 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms 1829 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms (that need to be reset after BFS loop) 1815 1830 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL; 1816 1831 bond *Binder = NULL, *BackEdge = NULL; … … 1843 1858 BFSStack->Push(Walker); 1844 1859 TouchedStack->Push(Walker); 1845 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;1860 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 1846 1861 OtherAtom = NULL; 1847 while ((Walker != Root) && ((OtherAtom == NULL) || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))){ // look for Root1862 do { // look for Root 1848 1863 Walker = BFSStack->PopFirst(); 1849 //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;1864 *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl; 1850 1865 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 1851 1866 Binder = ListOfBondsPerAtom[Walker->nr][i]; 1852 1867 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder) 1853 1868 OtherAtom = Binder->GetOtherAtom(Walker); 1854 //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 1855 if (ColorList[OtherAtom->nr] == white) { 1856 TouchedStack->Push(OtherAtom); 1857 ColorList[OtherAtom->nr] = lightgray; 1858 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1859 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 1860 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1861 if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 1862 //*out << Verbose(3) << "Putting OtherAtom into queue." << endl; 1863 BFSStack->Push(OtherAtom); 1869 #ifdef ADDHYDROGEN 1870 if (OtherAtom->type->Z != 1) { 1871 #endif 1872 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 1873 if (ColorList[OtherAtom->nr] == white) { 1874 TouchedStack->Push(OtherAtom); 1875 ColorList[OtherAtom->nr] = lightgray; 1876 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1877 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 1878 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1879 //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 1880 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; 1881 BFSStack->Push(OtherAtom); 1882 //} 1883 } else { 1884 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 1864 1885 } 1886 if (OtherAtom == Root) 1887 break; 1888 #ifdef ADDHYDROGEN 1865 1889 } else { 1866 //*out << Verbose(3) << "Not Adding, has already been visited." << endl; 1890 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; 1891 ColorList[OtherAtom->nr] = black; 1867 1892 } 1893 #endif 1868 1894 } else { 1869 //*out << Verbose(3) << "Not Visiting, is aback edge." << endl;1895 *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl; 1870 1896 } 1871 1897 } 1872 1898 ColorList[Walker->nr] = black; 1873 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 1874 } 1899 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 1900 if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand 1901 // step through predecessor list 1902 while (OtherAtom != BackEdge->rightatom) { 1903 if (!OtherAtom->GetTrueFather()->IsCyclic) // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet 1904 break; 1905 else 1906 OtherAtom = PredecessorList[OtherAtom->nr]; 1907 } 1908 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already 1909 *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\ 1910 do { 1911 OtherAtom = TouchedStack->PopLast(); 1912 if (PredecessorList[OtherAtom->nr] == Walker) { 1913 *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl; 1914 PredecessorList[OtherAtom->nr] = NULL; 1915 ShortestPathList[OtherAtom->nr] = -1; 1916 ColorList[OtherAtom->nr] = white; 1917 BFSStack->RemoveItem(OtherAtom); 1918 } 1919 } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL)); 1920 TouchedStack->Push(OtherAtom); // last was wrongly popped 1921 OtherAtom = BackEdge->rightatom; // set to not Root 1922 } else 1923 OtherAtom = Root; 1924 } 1925 } while ((OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))); 1875 1926 1876 if ( Walker== Root) {1927 if (OtherAtom == Root) { 1877 1928 // now climb back the predecessor list and thus find the cycle members 1878 1929 NumCycles++; … … 1880 1931 Root->GetTrueFather()->IsCyclic = true; 1881 1932 *out << Verbose(1) << "Found ring contains: "; 1933 Walker = Root; 1882 1934 while (Walker != BackEdge->rightatom) { 1883 1935 *out << Walker->Name << " <-> ";
Note:
See TracChangeset
for help on using the changeset viewer.