Changeset 4aa03a for src/molecules.cpp
- Timestamp:
- Jul 31, 2008, 2:05:37 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:
- fb9364
- Parents:
- af6d8f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
raf6d8f r4aa03a 2523 2523 No = (*runner).second.first; 2524 2524 Walker = FindAtom(No); 2525 if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {2525 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) { 2526 2526 *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 2527 2527 AtomMask[No] = true; 2528 2528 status = true; 2529 } else2530 *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl;2529 //} else 2530 //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl; 2531 2531 } 2532 2532 // close and done … … 2556 2556 { 2557 2557 AtomMask[Walker->nr] = true; // include all (non-hydrogen) atoms 2558 if ((Order != 0) && (Walker->AdaptiveOrder < Order) && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))2558 if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr])) 2559 2559 status = true; 2560 2560 } 2561 2561 } 2562 2562 if ((Order == 0) && (AtomMask[AtomCount] == true)) // single stepping, just check 2563 status = false;2563 status = true; 2564 2564 2565 2565 if (!status) … … 3152 3152 atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList"); 3153 3153 molecule *Leaf = new molecule(elemente); 3154 bool LonelyFlag = false; 3155 int size; 3154 3156 3155 3157 // *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl; … … 3164 3166 3165 3167 // first create the minimal set of atoms from the KeySet 3168 size = 0; 3166 3169 for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) { 3167 3170 FatherOfRunner = FindAtom((*runner)); // find the id 3168 3171 SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner); 3172 size++; 3169 3173 } 3170 3174 … … 3174 3178 while (Runner->next != Leaf->end) { 3175 3179 Runner = Runner->next; 3180 LonelyFlag = true; 3176 3181 FatherOfRunner = Runner->father; 3177 3182 if (SonList[FatherOfRunner->nr] != NULL) { // check if this, our father, is present in list … … 3191 3196 // *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl; 3192 3197 } 3198 LonelyFlag = false; 3193 3199 } else { 3194 3200 // *out << ", who has no son in this fragment molecule." << endl; … … 3202 3208 } else { 3203 3209 *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl; 3210 } 3211 if ((LonelyFlag) && (size > 1)) { 3212 *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl; 3204 3213 } 3205 3214 #ifdef ADDHYDROGEN … … 3468 3477 int NumCombinations; 3469 3478 bool bit; 3470 int bits, TouchedIndex, SubSetDimension, SP ;3479 int bits, TouchedIndex, SubSetDimension, SP, Added; 3471 3480 int Removal; 3481 int SpaceLeft; 3472 3482 int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList"); 3473 3483 bond *Binder = NULL; 3474 3484 bond **BondsList = NULL; 3485 KeySetTestPair TestKeySetInsert; 3475 3486 3476 3487 NumCombinations = 1 << SetDimension; … … 3500 3511 if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue 3501 3512 // --1-- add this set of the power set of bond partners to the snake stack 3513 Added = 0; 3502 3514 for (int j=0;j<SetDimension;j++) { // pull out every bit by shifting 3503 3515 bit = ((i & (1 << j)) != 0); // mask the bit for the j-th bond … … 3508 3520 //*out << Verbose(2+verbosity) << "Not used so far, label " << FragmentSearch->Labels[OtherWalker->nr] << " is bigger than Root's " << FragmentSearch->Labels[FragmentSearch->Root->nr] << "." << endl; 3509 3521 *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl; 3510 TouchedList[TouchedIndex++] = OtherWalker->nr; // note as added 3511 FragmentSearch->FragmentSet->insert(OtherWalker->nr); 3522 TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 3523 if (TestKeySetInsert.second) { 3524 TouchedList[TouchedIndex++] = OtherWalker->nr; // note as added 3525 Added++; 3526 } else { 3527 *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl; 3528 } 3512 3529 //FragmentSearch->UsedList[OtherWalker->nr][i] = true; 3513 3530 //} … … 3517 3534 } 3518 3535 3519 if (bits < SubOrder) { 3520 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << (SubOrder - bits) << "." << endl; 3521 // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion 3522 SP = RootDistance+1; // this is the next level 3523 // first count the members in the subset 3524 SubSetDimension = 0; 3525 Binder = FragmentSearch->BondsPerSPList[2*SP]; // start node for this level 3526 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { // compare to end node of this level 3527 Binder = Binder->next; 3528 for (int k=TouchedIndex;k--;) { 3529 if (Binder->Contains(TouchedList[k])) // if we added this very endpiece 3530 SubSetDimension++; 3536 SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 3537 if (SpaceLeft > 0) { 3538 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl; 3539 if (SubOrder > 1) { // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order 3540 // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion 3541 SP = RootDistance+1; // this is the next level 3542 // first count the members in the subset 3543 SubSetDimension = 0; 3544 Binder = FragmentSearch->BondsPerSPList[2*SP]; // start node for this level 3545 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { // compare to end node of this level 3546 Binder = Binder->next; 3547 for (int k=TouchedIndex;k--;) { 3548 if (Binder->Contains(TouchedList[k])) // if we added this very endpiece 3549 SubSetDimension++; 3550 } 3531 3551 } 3552 // then allocate and fill the list 3553 BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList"); 3554 SubSetDimension = 0; 3555 Binder = FragmentSearch->BondsPerSPList[2*SP]; 3556 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { 3557 Binder = Binder->next; 3558 for (int k=0;k<TouchedIndex;k++) { 3559 if (Binder->leftatom->nr == TouchedList[k]) // leftatom is always the close one 3560 BondsList[SubSetDimension++] = Binder; 3561 } 3562 } 3563 *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl; 3564 SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 3565 Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList"); 3532 3566 } 3533 // then allocate and fill the list3534 BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");3535 SubSetDimension = 0;3536 Binder = FragmentSearch->BondsPerSPList[2*SP];3537 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {3538 Binder = Binder->next;3539 for (int k=0;k<TouchedIndex;k++) {3540 if (Binder->leftatom->nr == TouchedList[k]) // leftatom is always the close one3541 BondsList[SubSetDimension++] = Binder;3542 }3543 }3544 *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;3545 SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);3546 Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");3547 3567 } else { 3548 3568 // --2-- otherwise store the complete fragment … … 3552 3572 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++) 3553 3573 *out << (*runner) << " "; 3574 *out << endl; 3575 if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet)) 3576 *out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl; 3554 3577 InsertFragmentIntoGraph(out, FragmentSearch); 3555 3578 //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList); … … 3577 3600 *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl; 3578 3601 }; 3602 3603 /** For a given keyset \a *Fragment, checks whether it is connected in the current molecule. 3604 * \param *out output stream for debugging 3605 * \param *Fragment Keyset of fragment's vertices 3606 * \return true - connected, false - disconnected 3607 * \note this is O(n^2) for it's just a bug checker not meant for permanent use! 3608 */ 3609 bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment) 3610 { 3611 atom *Walker = NULL, *Walker2 = NULL; 3612 bool BondStatus = false; 3613 int size; 3614 3615 *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl; 3616 *out << Verbose(2) << "Disconnected atom: "; 3617 3618 // count number of atoms in graph 3619 size = 0; 3620 for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) 3621 size++; 3622 if (size > 1) 3623 for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) { 3624 Walker = FindAtom(*runner); 3625 BondStatus = false; 3626 for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) { 3627 Walker2 = FindAtom(*runners); 3628 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) { 3629 if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) { 3630 BondStatus = true; 3631 break; 3632 } 3633 if (BondStatus) 3634 break; 3635 } 3636 } 3637 if (!BondStatus) { 3638 *out << (*Walker) << endl; 3639 return false; 3640 } 3641 } 3642 else { 3643 *out << "none." << endl; 3644 return true; 3645 } 3646 *out << "none." << endl; 3647 3648 *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl; 3649 3650 return true; 3651 } 3579 3652 3580 3653 /** Creates a list of all unique fragments of certain vertex size from a given graph \a Fragment for a given root vertex in the context of \a this molecule. … … 3596 3669 { 3597 3670 int SP, UniqueIndex, AtomKeyNr; 3598 int *NumberOfAtomsSPLevel = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *SPLevelCount"); 3599 atom *Walker = NULL, *OtherWalker = NULL; 3671 atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL; 3600 3672 bond *Binder = NULL; 3673 bond *CurrentEdge = NULL; 3601 3674 bond **BondsList = NULL; 3602 KeyStack AtomStack;3603 atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::PowerSetGenerator: **PredecessorList");3604 3675 int RootKeyNr = FragmentSearch.Root->nr; 3605 3676 int Counter = FragmentSearch.FragmentCounter; 3606 3607 for (int i=AtomCount;i--;) { 3608 PredecessorList[i] = NULL; 3609 } 3677 int RemainingWalkers; 3610 3678 3611 3679 *out << endl; 3612 3680 *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl; 3613 3681 3682 // prepare Label and SP arrays of the BFS search 3614 3683 UniqueIndex = 0; 3615 3684 if (FragmentSearch.Labels[RootKeyNr] == -1) 3616 3685 FragmentSearch.Labels[RootKeyNr] = UniqueIndex++; 3617 3686 FragmentSearch.ShortestPathList[RootKeyNr] = 0; 3618 // prepare the atom stack counters (number of atoms with certain SP on stack) 3619 for (int i=Order;i--;) 3620 NumberOfAtomsSPLevel[i] = 0; 3621 NumberOfAtomsSPLevel[0] = 1; // for root 3622 SP = -1; 3687 3688 // prepare root level (SP = 0) and a loop bond denoting Root 3689 for (int i=1;i<Order;i++) 3690 FragmentSearch.BondsPerSPCount[i] = 0; 3691 FragmentSearch.BondsPerSPCount[0] = 1; 3692 Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 3693 add(Binder, FragmentSearch.BondsPerSPList[1]); 3694 3695 // do a BFS search to fill the SP lists and label the found vertices 3696 // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into 3697 // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning 3698 // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth 3699 // (EdgeinSPLevel) of this tree ... 3700 // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence 3701 // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction. 3623 3702 *out << endl; 3624 3703 *out << Verbose(0) << "Starting BFS analysis ..." << endl; 3625 // push as first on atom stack and goooo ... 3626 AtomStack.clear(); 3627 AtomStack.push_back(RootKeyNr); 3628 *out << Verbose(0) << "Cleared AtomStack and pushed root as first item onto it." << endl; 3629 // do a BFS search to fill the SP lists and label the found vertices 3630 while (!AtomStack.empty()) { 3631 // pop next atom 3632 AtomKeyNr = AtomStack.front(); 3633 AtomStack.pop_front(); 3634 if (SP != -1) 3635 NumberOfAtomsSPLevel[SP]--; 3636 if ((SP == -1) || (NumberOfAtomsSPLevel[SP] == -1)) { 3637 SP++; 3638 NumberOfAtomsSPLevel[SP]--; // carry over "-1" to next level 3639 *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with 0 item(s)"; 3640 if (SP > 0) 3641 *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl; 3642 else 3643 *out << "." << endl; 3704 for (SP = 0; SP < (Order-1); SP++) { 3705 *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)"; 3706 if (SP > 0) { 3707 *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl; 3644 3708 FragmentSearch.BondsPerSPCount[SP] = 0; 3645 } else { 3646 *out << Verbose(1) << "Still " << NumberOfAtomsSPLevel[SP]+1 << " on this SP (" << SP << ") level, currently having " << FragmentSearch.BondsPerSPCount[SP] << " item(s)." << endl; 3647 } 3648 Walker = FindAtom(AtomKeyNr); 3649 *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and label " << FragmentSearch.Labels[AtomKeyNr] << " and SP of " << SP << "." << endl; 3650 // check for new sp level 3651 // go through all its bonds 3652 *out << Verbose(1) << "Going through all bonds of Walker." << endl; 3653 for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) { 3654 Binder = ListOfBondsPerAtom[AtomKeyNr][i]; 3655 OtherWalker = Binder->GetOtherAtom(Walker); 3656 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end()) 3657 #ifdef ADDHYDROGEN 3658 && (OtherWalker->type->Z != 1) 3659 #endif 3660 ) { // skip hydrogens and restrict to fragment 3661 *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl; 3662 // set the label if not set (and push on root stack as well) 3663 if (FragmentSearch.Labels[OtherWalker->nr] == -1) { 3664 FragmentSearch.Labels[OtherWalker->nr] = UniqueIndex++; 3665 *out << Verbose(3) << "Set label to " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl; 3666 } else { 3667 *out << Verbose(3) << "Label is already " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl; 3668 } 3669 if ((OtherWalker != PredecessorList[AtomKeyNr]) && (OtherWalker->nr > RootKeyNr)) { // only pass through those with label bigger than Root's 3670 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1; 3671 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl; 3672 if (FragmentSearch.ShortestPathList[OtherWalker->nr] < Order) { // only pass through those within reach of Order 3673 // push for exploration on stack (only if the SP of OtherWalker is longer than of Walker! (otherwise it has been added already!) 3674 if (FragmentSearch.ShortestPathList[OtherWalker->nr] > SP) { 3675 if (FragmentSearch.ShortestPathList[OtherWalker->nr] < (Order-1)) { 3676 *out << Verbose(3) << "Putting on atom stack for further exploration." << endl; 3677 PredecessorList[OtherWalker->nr] = Walker; // note down the one further up the exploration tree 3678 AtomStack.push_back(OtherWalker->nr); 3679 NumberOfAtomsSPLevel[FragmentSearch.ShortestPathList[OtherWalker->nr]]++; 3680 } else { 3681 *out << Verbose(3) << "Not putting on atom stack, is at end of reach." << endl; 3682 } 3683 // add the bond in between to the SP list 3684 Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant 3685 add(Binder, FragmentSearch.BondsPerSPList[2*SP+1]); 3686 FragmentSearch.BondsPerSPCount[SP]++; 3687 *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP] << " item(s)." << endl; 3688 } else *out << Verbose(3) << "Not putting on atom stack, nor adding bond, as " << *OtherWalker << "'s SP is shorter than Walker's." << endl; 3689 } else *out << Verbose(3) << "Not continuing, as " << *OtherWalker << " is out of reach of order " << Order << "." << endl; 3690 } else *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->nr << " is smaller than that of Root " << RootKeyNr << " or this is my predecessor." << endl; 3691 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl; 3692 } 3693 } 3694 // reset predecessor list 3695 for(int i=0;i<Order;i++) { 3696 Binder = FragmentSearch.BondsPerSPList[2*i]; 3697 *out << Verbose(1) << "Current SP level is " << i << "." << endl; 3698 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) { 3699 Binder = Binder->next; 3700 PredecessorList[Binder->rightatom->nr] = NULL; // By construction "OtherAtom" is always Bond::rightatom! 3701 } 3702 } 3703 *out << endl; 3709 } else 3710 *out << "." << endl; 3711 3712 RemainingWalkers = FragmentSearch.BondsPerSPCount[SP]; 3713 CurrentEdge = FragmentSearch.BondsPerSPList[2*SP]; /// start of this SP level's list 3714 while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) { /// end of this SP level's list 3715 CurrentEdge = CurrentEdge->next; 3716 RemainingWalkers--; 3717 Walker = CurrentEdge->rightatom; // rightatom is always the one more distant 3718 Predecessor = CurrentEdge->leftatom; // ... and leftatom is predecessor 3719 AtomKeyNr = Walker->nr; 3720 *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and label " << FragmentSearch.Labels[AtomKeyNr] << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl; 3721 // check for new sp level 3722 // go through all its bonds 3723 *out << Verbose(1) << "Going through all bonds of Walker." << endl; 3724 for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) { 3725 Binder = ListOfBondsPerAtom[AtomKeyNr][i]; 3726 OtherWalker = Binder->GetOtherAtom(Walker); 3727 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end()) 3728 #ifdef ADDHYDROGEN 3729 && (OtherWalker->type->Z != 1) 3730 #endif 3731 ) { // skip hydrogens and restrict to fragment 3732 *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl; 3733 // set the label if not set (and push on root stack as well) 3734 if (FragmentSearch.Labels[OtherWalker->nr] == -1) { 3735 FragmentSearch.Labels[OtherWalker->nr] = UniqueIndex++; 3736 *out << Verbose(3) << "Set label to " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl; 3737 } else { 3738 *out << Verbose(3) << "Label is already " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl; 3739 } 3740 if ((OtherWalker != Predecessor) && (OtherWalker->nr > RootKeyNr)) { // only pass through those with label bigger than Root's 3741 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1; 3742 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl; 3743 // add the bond in between to the SP list 3744 Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant 3745 add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]); 3746 FragmentSearch.BondsPerSPCount[SP+1]++; 3747 *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl; 3748 } else *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->nr << " is smaller than that of Root " << RootKeyNr << " or this is my predecessor " << *Predecessor << "." << endl; 3749 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl; 3750 } 3751 } 3752 } 3704 3753 3705 3754 // outputting all list for debugging 3706 3755 *out << Verbose(0) << "Printing all found lists." << endl; 3707 for(int i= 0;i<Order;i++) {3756 for(int i=1;i<Order;i++) { // skip the root edge in the printing 3708 3757 Binder = FragmentSearch.BondsPerSPList[2*i]; 3709 3758 *out << Verbose(1) << "Current SP level is " << i << "." << endl; … … 3715 3764 3716 3765 // creating fragments with the found edge sets (may be done in reverse order, faster) 3717 SP = 0;3766 SP = -1; // the Root <-> Root edge must be subtracted! 3718 3767 for(int i=Order;i--;) { // sum up all found edges 3719 3768 Binder = FragmentSearch.BondsPerSPList[2*i]; … … 3728 3777 *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl; 3729 3778 FragmentSearch.FragmentSet->clear(); 3730 FragmentSearch.FragmentSet->insert(FragmentSearch.Root->nr); 3779 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl; 3780 // prepare the subset and call the generator 3781 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList"); 3782 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next; // on SP level 0 there's only the root bond 3731 3783 3732 if (FragmentSearch.FragmentSet->size() == (unsigned int) Order) { 3733 *out << Verbose(0) << "Enough items on stack already for a fragment!" << endl; 3734 // store fragment as a KeySet 3735 *out << Verbose(2) << "Found a new fragment[" << FragmentSearch.FragmentCounter << "], local nr.s are: "; 3736 for(KeySet::iterator runner = FragmentSearch.FragmentSet->begin(); runner != FragmentSearch.FragmentSet->end(); runner++) { 3737 *out << (*runner) << " "; 3738 } 3739 *out << endl; 3740 InsertFragmentIntoGraph(out, &FragmentSearch); 3741 } else { 3742 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl; 3743 // prepare the subset and call the generator 3744 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList"); 3745 Binder = FragmentSearch.BondsPerSPList[0]; 3746 for(int i=0;i<FragmentSearch.BondsPerSPCount[0];i++) { 3747 Binder = Binder->next; 3748 BondsList[i] = Binder; 3749 } 3750 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order-1); 3751 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList"); 3752 } 3784 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order); 3785 3786 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList"); 3753 3787 } else { 3754 3788 *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl; … … 3777 3811 } 3778 3812 3779 // free allocated memory3780 Free((void **)&NumberOfAtomsSPLevel, "molecule::PowerSetGenerator: *SPLevelCount");3781 Free((void **)&PredecessorList, "molecule::PowerSetGenerator: **PredecessorList");3782 3783 3813 // return list 3784 3814 *out << Verbose(0) << "End of PowerSetGenerator." << endl; … … 4039 4069 Walker = FindAtom(RootKeyNr); 4040 4070 // check cyclic lengths 4041 if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) { 4042 *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl; 4043 } else { 4071 //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) { 4072 // *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl; 4073 //} else 4074 { 4044 4075 // increase adaptive order by one 4045 4076 Walker->GetTrueFather()->AdaptiveOrder++; … … 4060 4091 NumLevels = 1 << (Order-1); // (int)pow(2,Order); 4061 4092 FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]"); 4093 for (int i=0;i<NumLevels;i++) 4094 FragmentLowerOrdersList[RootNr][i] = NULL; 4062 4095 4063 4096 // create top order where nothing is reduced 4064 4097 *out << Verbose(0) << "==============================================================================================================" << endl; 4065 *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", NumLevels is " << NumLevels << ", " << (RootStack.size()-RootNr -1) << " Roots remaining." << endl;4098 *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", NumLevels is " << NumLevels << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; 4066 4099 4067 4100 // Create list of Graphs of current Bond Order (i.e. F_{ij}) … … 4072 4105 NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule); 4073 4106 *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl; 4074 NumMolecules = 0; 4075 4076 if ((NumLevels >> 1) > 0) { 4077 // create lower order fragments 4078 *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl; 4079 Order = Walker->AdaptiveOrder; 4080 for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again) 4081 // step down to next order at (virtual) boundary of powers of 2 in array 4082 while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order)) 4083 Order--; 4084 *out << Verbose(0) << "Current Order is: " << Order << "." << endl; 4085 for (int SubOrder=Order-1;SubOrder>0;SubOrder--) { 4086 int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1))); 4087 *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl; 4088 *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl; 4089 4090 // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules 4091 //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl; 4092 //NumMolecules = 0; 4093 FragmentLowerOrdersList[RootNr][dest] = new Graph; 4094 for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) { 4095 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 4096 Graph TempFragmentList; 4097 FragmentSearch.TEFactor = -(*runner).second.second; 4098 FragmentSearch.Leaflet = &TempFragmentList; // set to insertion graph 4099 FragmentSearch.Root = FindAtom(*sprinter); 4100 NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first); 4101 // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest] 4102 *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl; 4103 InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules); 4107 if (NumMoleculesOfOrder[RootNr] != 0) { 4108 NumMolecules = 0; 4109 4110 if ((NumLevels >> 1) > 0) { 4111 // create lower order fragments 4112 *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl; 4113 Order = Walker->AdaptiveOrder; 4114 for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again) 4115 // step down to next order at (virtual) boundary of powers of 2 in array 4116 while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order)) 4117 Order--; 4118 *out << Verbose(0) << "Current Order is: " << Order << "." << endl; 4119 for (int SubOrder=Order-1;SubOrder>0;SubOrder--) { 4120 int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1))); 4121 *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl; 4122 *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl; 4123 4124 // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules 4125 //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl; 4126 //NumMolecules = 0; 4127 FragmentLowerOrdersList[RootNr][dest] = new Graph; 4128 for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) { 4129 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 4130 Graph TempFragmentList; 4131 FragmentSearch.TEFactor = -(*runner).second.second; 4132 FragmentSearch.Leaflet = &TempFragmentList; // set to insertion graph 4133 FragmentSearch.Root = FindAtom(*sprinter); 4134 NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first); 4135 // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest] 4136 *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl; 4137 InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules); 4138 } 4104 4139 } 4140 *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl; 4105 4141 } 4106 *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;4107 4142 } 4108 4143 } 4144 } else { 4145 *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl; 4109 4146 } 4110 4147 // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
Note:
See TracChangeset
for help on using the changeset viewer.