Changeset ce7cc5 for src/molecule_graph.cpp
- Timestamp:
- Oct 18, 2009, 5:52:47 PM (15 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:
- 43587e
- Parents:
- ba4170
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule_graph.cpp
rba4170 rce7cc5 983 983 }; 984 984 985 struct BFSAccounting { 986 atom **PredecessorList; 987 int *ShortestPathList; 988 enum Shading *ColorList; 989 class StackClass<atom *> *AtomStack; 990 int AtomCount; 991 int BondOrder; 992 atom *Root; 993 }; 994 995 void BreadthFirstSearchAdd_Init(struct BFSAccounting &BFS, atom *&Root, int AtomCount, int BondOrder, atom **AddedAtomList = NULL) 996 { 997 BFS.AtomCount = AtomCount; 998 BFS.BondOrder = BondOrder; 999 BFS.PredecessorList = Malloc<atom*>(AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList"); 1000 BFS.ShortestPathList = Malloc<int>(AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList"); 1001 BFS.ColorList = Malloc<enum Shading>(AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList"); 1002 BFS.AtomStack = new StackClass<atom *>(AtomCount); 1003 1004 BFS.Root = Root; 1005 BFS.AtomStack->ClearStack(); 1006 BFS.AtomStack->Push(Root); 1007 1008 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 1009 for (int i=AtomCount;i--;) { 1010 BFS.PredecessorList[i] = NULL; 1011 BFS.ShortestPathList[i] = -1; 1012 if ((AddedAtomList != NULL) && (AddedAtomList[i] != NULL)) // mark already present atoms (i.e. Root and maybe others) as visited 1013 BFS.ColorList[i] = lightgray; 1014 else 1015 BFS.ColorList[i] = white; 1016 } 1017 BFS.ShortestPathList[Root->nr] = 0; 1018 }; 1019 1020 void BreadthFirstSearchAdd_Free(struct BFSAccounting &BFS) 1021 { 1022 Free(&BFS.PredecessorList); 1023 Free(&BFS.ShortestPathList); 1024 Free(&BFS.ColorList); 1025 delete(BFS.AtomStack); 1026 BFS.AtomCount = 0; 1027 }; 1028 1029 1030 void BreadthFirstSearchAdd_UnvisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) 1031 { 1032 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 1033 BFS.ColorList[OtherAtom->nr] = lightgray; 1034 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1035 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr]+1; 1036 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((BFS.ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1037 if ((((BFS.ShortestPathList[OtherAtom->nr] < BFS.BondOrder) && (Binder != Bond))) ) { // Check for maximum distance 1038 *out << Verbose(3); 1039 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far 1040 AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom); 1041 *out << "Added OtherAtom " << OtherAtom->Name; 1042 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1043 *out << " and bond " << *(AddedBondList[Binder->nr]) << ", "; 1044 } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place) 1045 *out << "Not adding OtherAtom " << OtherAtom->Name; 1046 if (AddedBondList[Binder->nr] == NULL) { 1047 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1048 *out << ", added Bond " << *(AddedBondList[Binder->nr]); 1049 } else 1050 *out << ", not added Bond "; 1051 } 1052 *out << ", putting OtherAtom into queue." << endl; 1053 BFS.AtomStack->Push(OtherAtom); 1054 } else { // out of bond order, then replace 1055 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic)) 1056 BFS.ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic) 1057 if (Binder == Bond) 1058 *out << Verbose(3) << "Not Queueing, is the Root bond"; 1059 else if (BFS.ShortestPathList[OtherAtom->nr] >= BFS.BondOrder) 1060 *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BFS.BondOrder; 1061 if (!Binder->Cyclic) 1062 *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl; 1063 if (AddedBondList[Binder->nr] == NULL) { 1064 if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate 1065 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1066 } else { 1067 #ifdef ADDHYDROGEN 1068 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1069 exit(1); 1070 #endif 1071 } 1072 } 1073 } 1074 }; 1075 1076 void BreadthFirstSearchAdd_VisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) 1077 { 1078 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 1079 // This has to be a cyclic bond, check whether it's present ... 1080 if (AddedBondList[Binder->nr] == NULL) { 1081 if ((Binder != Bond) && (Binder->Cyclic) && (((BFS.ShortestPathList[Walker->nr]+1) < BFS.BondOrder))) { 1082 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1083 } else { // if it's root bond it has to broken (otherwise we would not create the fragments) 1084 #ifdef ADDHYDROGEN 1085 if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1086 exit(1); 1087 #endif 1088 } 1089 } 1090 }; 985 1091 986 1092 /** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList. … … 998 1104 void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem) 999 1105 { 1000 atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList"); 1001 int *ShortestPathList = Malloc<int>(AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList"); 1002 enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList"); 1003 class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount); 1106 struct BFSAccounting BFS; 1004 1107 atom *Walker = NULL, *OtherAtom = NULL; 1108 bond *Binder = NULL; 1005 1109 1006 1110 // add Root if not done yet 1007 AtomStack->ClearStack();1008 1111 if (AddedAtomList[Root->nr] == NULL) // add Root if not yet present 1009 1112 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root); 1010 AtomStack->Push(Root); 1011 1012 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 1013 for (int i=AtomCount;i--;) { 1014 PredecessorList[i] = NULL; 1015 ShortestPathList[i] = -1; 1016 if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited 1017 ColorList[i] = lightgray; 1018 else 1019 ColorList[i] = white; 1020 } 1021 ShortestPathList[Root->nr] = 0; 1113 1114 BreadthFirstSearchAdd_Init(BFS, Root, BondOrder, AtomCount, AddedAtomList); 1022 1115 1023 1116 // and go on ... Queue always contains all lightgray vertices 1024 while (! AtomStack->IsEmpty()) {1117 while (!BFS.AtomStack->IsEmpty()) { 1025 1118 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance. 1026 1119 // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again 1027 1120 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and 1028 1121 // followed by n+1 till top of stack. 1029 Walker = AtomStack->PopFirst(); // pop oldest added1122 Walker = BFS.AtomStack->PopFirst(); // pop oldest added 1030 1123 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << Walker->ListOfBonds.size() << " bonds." << endl; 1031 1124 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1032 1125 if ((*Runner) != NULL) { // don't look at bond equal NULL 1126 Binder = (*Runner); 1033 1127 OtherAtom = (*Runner)->GetOtherAtom(Walker); 1034 1128 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl; 1035 if (ColorList[OtherAtom->nr] == white) { 1036 if ((*Runner) != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 1037 ColorList[OtherAtom->nr] = lightgray; 1038 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1039 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 1040 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1041 if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && ((*Runner) != Bond))) ) { // Check for maximum distance 1042 *out << Verbose(3); 1043 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far 1044 AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom); 1045 *out << "Added OtherAtom " << OtherAtom->Name; 1046 AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner)); 1047 *out << " and bond " << *(AddedBondList[(*Runner)->nr]) << ", "; 1048 } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place) 1049 *out << "Not adding OtherAtom " << OtherAtom->Name; 1050 if (AddedBondList[(*Runner)->nr] == NULL) { 1051 AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner)); 1052 *out << ", added Bond " << *(AddedBondList[(*Runner)->nr]); 1053 } else 1054 *out << ", not added Bond "; 1055 } 1056 *out << ", putting OtherAtom into queue." << endl; 1057 AtomStack->Push(OtherAtom); 1058 } else { // out of bond order, then replace 1059 if ((AddedAtomList[OtherAtom->nr] == NULL) && ((*Runner)->Cyclic)) 1060 ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic) 1061 if ((*Runner) == Bond) 1062 *out << Verbose(3) << "Not Queueing, is the Root bond"; 1063 else if (ShortestPathList[OtherAtom->nr] >= BondOrder) 1064 *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder; 1065 if (!(*Runner)->Cyclic) 1066 *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl; 1067 if (AddedBondList[(*Runner)->nr] == NULL) { 1068 if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate 1069 AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner)); 1070 } else { 1071 #ifdef ADDHYDROGEN 1072 if (!Mol->AddHydrogenReplacementAtom(out, (*Runner), AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1073 exit(1); 1074 #endif 1075 } 1076 } 1077 } 1129 if (BFS.ColorList[OtherAtom->nr] == white) { 1130 BreadthFirstSearchAdd_UnvisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem); 1078 1131 } else { 1079 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 1080 // This has to be a cyclic bond, check whether it's present ... 1081 if (AddedBondList[(*Runner)->nr] == NULL) { 1082 if (((*Runner) != Bond) && ((*Runner)->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 1083 AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner)); 1084 } else { // if it's root bond it has to broken (otherwise we would not create the fragments) 1085 #ifdef ADDHYDROGEN 1086 if(!Mol->AddHydrogenReplacementAtom(out, (*Runner), AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1087 exit(1); 1088 #endif 1089 } 1090 } 1132 BreadthFirstSearchAdd_VisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem); 1091 1133 } 1092 1134 } 1093 1135 } 1094 ColorList[Walker->nr] = black;1136 BFS.ColorList[Walker->nr] = black; 1095 1137 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 1096 1138 } 1097 Free(&PredecessorList); 1098 Free(&ShortestPathList); 1099 Free(&ColorList); 1100 delete(AtomStack); 1139 BreadthFirstSearchAdd_Free(BFS); 1101 1140 }; 1102 1141
Note:
See TracChangeset
for help on using the changeset viewer.