Changeset 1907a7 for src/molecules.cpp
- Timestamp:
- Apr 2, 2009, 4:12:54 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:
- ca3ccc
- Parents:
- d8b94a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
rd8b94a r1907a7 62 62 cell_size[0] = cell_size[2] = cell_size[5]= 20.; 63 63 cell_size[1] = cell_size[3] = cell_size[4]= 0.; 64 strcpy(name,"none"); 64 65 }; 65 66 … … 596 597 cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl; 597 598 return false; 599 }; 600 601 /** Set molecule::name from the basename without suffix in the given \a *filename. 602 * \param *filename filename 603 */ 604 void molecule::SetNameFromFilename(char *filename) 605 { 606 int length = 0; 607 char *molname = strrchr(filename, '/')+sizeof(char); // search for filename without dirs 608 char *endname = strrchr(filename, '.'); 609 if ((endname == NULL) || (endname < molname)) 610 length = strlen(molname); 611 else 612 length = strlen(molname) - strlen(endname); 613 strncpy(name, molname, length); 598 614 }; 599 615 … … 1187 1203 }; 1188 1204 1189 /** Removes atom from molecule list .1205 /** Removes atom from molecule list and deletes it. 1190 1206 * \param *pointer atom to be removed 1191 1207 * \return true - succeeded, false - atom not found in list … … 1201 1217 Trajectories.erase(pointer); 1202 1218 return remove(pointer, start, end); 1219 }; 1220 1221 /** Removes atom from molecule list, but does not delete it. 1222 * \param *pointer atom to be removed 1223 * \return true - succeeded, false - atom not found in list 1224 */ 1225 bool molecule::UnlinkAtom(atom *pointer) 1226 { 1227 if (pointer == NULL) 1228 return false; 1229 if (ElementsInMolecule[pointer->type->Z] != 0) // this would indicate an error 1230 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 1231 else 1232 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 1233 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 1234 ElementCount--; 1235 Trajectories.erase(pointer); 1236 unlink(pointer); 1237 return true; 1203 1238 }; 1204 1239 … … 1727 1762 }; 1728 1763 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices. 1729 1764 1730 1765 } 1731 1766 … … 2529 2564 cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl; 2530 2565 } 2531 //FragmentList->ListOfMolecules[NumberOfFragments++] = StoreFragmentFromKeySet(out, CurrentSet, IsAngstroem);2532 2566 } 2533 2567 } … … 3088 3122 //if (FragmentationToDo) { // we should always store the fragments again as coordination might have changed slightly without changing bond structure 3089 3123 // allocate memory for the pointer array and transmorph graphs into full molecular fragments 3090 BondFragments = new MoleculeListClass( TotalGraph.size(), AtomCount);3124 BondFragments = new MoleculeListClass(); 3091 3125 int k=0; 3092 3126 for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) { 3093 3127 KeySet test = (*runner).first; 3094 3128 *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl; 3095 BondFragments-> ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);3129 BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration)); 3096 3130 k++; 3097 3131 } 3098 *out << k << "/" << BondFragments-> NumberOfMolecules<< " fragments generated from the keysets." << endl;3132 *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl; 3099 3133 3100 3134 // ===== 9. Save fragments' configuration and keyset files et al to disk === 3101 if (BondFragments-> NumberOfMolecules!= 0) {3135 if (BondFragments->ListOfMolecules.size() != 0) { 3102 3136 // create the SortIndex from BFS labels to order in the config file 3103 3137 CreateMappingLabelsToConfigSequence(out, SortIndex); 3104 3138 3105 *out << Verbose(1) << "Writing " << BondFragments-> NumberOfMolecules<< " possible bond fragmentation configs" << endl;3139 *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl; 3106 3140 if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex)) 3107 3141 *out << Verbose(1) << "All configs written." << endl; … … 3629 3663 }; 3630 3664 3631 /** Creates \a MoleculeListClass of all unique fragments of the \a molecule containing \a Order atoms or vertices.3632 * The picture to have in mind is that of a DFS "snake" of a certain length \a Order, i.e. as in the infamous3633 * computer game, that winds through the connected graph representing the molecule. Color (white,3634 * lightgray, darkgray, black) indicates whether a vertex has been discovered so far or not. Labels will help in3635 * creating only unique fragments and not additional ones with vertices simply in different sequence.3636 * The Predecessor is always the one that came before in discovering, needed on backstepping. And3637 * finally, the ShortestPath is needed for removing vertices from the snake stack during the back-3638 * stepping.3639 * \param *out output stream for debugging3640 * \param Order number of atoms in each fragment3641 * \param *configuration configuration for writing config files for each fragment3642 * \return List of all unique fragments with \a Order atoms3643 */3644 /*3645 MoleculeListClass * molecule::CreateListOfUniqueFragmentsOfOrder(ofstream *out, int Order, config *configuration)3646 {3647 atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");3648 int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");3649 int *Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");3650 enum Shading *ColorVertexList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");3651 enum Shading *ColorEdgeList = (enum Shading *) Malloc(sizeof(enum Shading)*BondCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorBondList");3652 StackClass<atom *> *RootStack = new StackClass<atom *>(AtomCount);3653 StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself3654 StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack!3655 MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;3656 MoleculeListClass *FragmentList = NULL;3657 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;3658 bond *Binder = NULL;3659 int RunningIndex = 0, FragmentCounter = 0;3660 3661 *out << Verbose(1) << "Begin of CreateListOfUniqueFragmentsOfOrder." << endl;3662 3663 // reset parent list3664 *out << Verbose(3) << "Resetting labels, parent, predecessor, color and shortest path lists." << endl;3665 for (int i=0;i<AtomCount;i++) { // reset all atom labels3666 // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons3667 Labels[i] = -1;3668 SonList[i] = NULL;3669 PredecessorList[i] = NULL;3670 ColorVertexList[i] = white;3671 ShortestPathList[i] = -1;3672 }3673 for (int i=0;i<BondCount;i++)3674 ColorEdgeList[i] = white;3675 RootStack->ClearStack(); // clearstack and push first atom if exists3676 TouchedStack->ClearStack();3677 Walker = start->next;3678 while ((Walker != end)3679 #ifdef ADDHYDROGEN3680 && (Walker->type->Z == 1)3681 #endif3682 ) { // search for first non-hydrogen atom3683 *out << Verbose(4) << "Current Root candidate is " << Walker->Name << "." << endl;3684 Walker = Walker->next;3685 }3686 if (Walker != end)3687 RootStack->Push(Walker);3688 else3689 *out << Verbose(0) << "ERROR: Could not find an appropriate Root atom!" << endl;3690 *out << Verbose(3) << "Root " << Walker->Name << " is on AtomStack, beginning loop through all vertices ..." << endl;3691 3692 ///// OUTER LOOP ////////////3693 while (!RootStack->IsEmpty()) {3694 // get new root vertex from atom stack3695 Root = RootStack->PopFirst();3696 ShortestPathList[Root->nr] = 0;3697 if (Labels[Root->nr] == -1)3698 Labels[Root->nr] = RunningIndex++; // prevent it from getting again on AtomStack3699 PredecessorList[Root->nr] = Root;3700 TouchedStack->Push(Root);3701 *out << Verbose(0) << "Root for this loop is: " << Root->Name << ".\n";3702 3703 // clear snake stack3704 SnakeStack->ClearStack();3705 //SnakeStack->TestImplementation(out, start->next);3706 3707 ///// INNER LOOP ////////////3708 // Problems:3709 // - what about cyclic bonds?3710 Walker = Root;3711 do {3712 *out << Verbose(1) << "Current Walker is: " << Walker->Name;3713 // initial setting of the new Walker: label, color, shortest path and put on stacks3714 if (Labels[Walker->nr] == -1) { // give atom a unique, monotonely increasing number3715 Labels[Walker->nr] = RunningIndex++;3716 RootStack->Push(Walker);3717 }3718 *out << ", has label " << Labels[Walker->nr];3719 if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) { // color it if newly discovered and push on stacks (and if within reach!)3720 if ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white)) {3721 // Binder ought to be set still from last neighbour search3722 *out << ", coloring bond " << *Binder << " black";3723 ColorEdgeList[Binder->nr] = black; // mark this bond as used3724 }3725 if (ShortestPathList[Walker->nr] == -1) {3726 ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;3727 TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed3728 }3729 if ((ShortestPathList[Walker->nr] < Order) && (ColorVertexList[Walker->nr] != darkgray)) { // if not already on snake stack3730 SnakeStack->Push(Walker);3731 ColorVertexList[Walker->nr] = darkgray; // mark as dark gray of on snake stack3732 }3733 }3734 *out << ", SP of " << ShortestPathList[Walker->nr] << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl;3735 3736 // then check the stack for a newly stumbled upon fragment3737 if (SnakeStack->ItemCount() == Order) { // is stack full?3738 // store the fragment if it is one and get a removal candidate3739 Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration);3740 // remove the candidate if one was found3741 if (Removal != NULL) {3742 *out << Verbose(2) << "Removing item " << Removal->Name << " with SP of " << ShortestPathList[Removal->nr] << " from snake stack." << endl;3743 SnakeStack->RemoveItem(Removal);3744 ColorVertexList[Removal->nr] = lightgray; // return back to not on snake stack but explored marking3745 if (Walker == Removal) { // if the current atom is to be removed, we also have to take a step back3746 Walker = PredecessorList[Removal->nr];3747 *out << Verbose(2) << "Stepping back to " << Walker->Name << "." << endl;3748 }3749 }3750 } else3751 Removal = NULL;3752 3753 // finally, look for a white neighbour as the next Walker3754 Binder = NULL;3755 if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) { // don't look, if a new walker has been set above3756 *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl;3757 OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour3758 if (ShortestPathList[Walker->nr] < Order) {3759 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {3760 Binder = ListOfBondsPerAtom[Walker->nr][i];3761 *out << Verbose(2) << "Current bond is " << *Binder << ": ";3762 OtherAtom = Binder->GetOtherAtom(Walker);3763 if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us3764 *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;3765 //ColorVertexList[OtherAtom->nr] = lightgray; // mark as explored3766 } else { // otherwise check its colour and element3767 if (3768 #ifdef ADDHYDROGEN3769 (OtherAtom->type->Z != 1) &&3770 #endif3771 (ColorEdgeList[Binder->nr] == white)) { // skip hydrogen, look for unexplored vertices3772 *out << "Moving along " << GetColor(ColorEdgeList[Binder->nr]) << " bond " << Binder << " to " << ((ColorVertexList[OtherAtom->nr] == white) ? "unexplored" : "explored") << " item: " << OtherAtom->Name << "." << endl;3773 // i find it currently rather sensible to always set the predecessor in order to find one's way back3774 //if (PredecessorList[OtherAtom->nr] == NULL) {3775 PredecessorList[OtherAtom->nr] = Walker;3776 *out << Verbose(3) << "Setting Predecessor of " << OtherAtom->Name << " to " << PredecessorList[OtherAtom->nr]->Name << "." << endl;3777 //} else {3778 // *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;3779 //}3780 Walker = OtherAtom;3781 break;3782 } else {3783 if (OtherAtom->type->Z == 1)3784 *out << "Links to a hydrogen atom." << endl;3785 else3786 *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;3787 }3788 }3789 }3790 } else { // means we have stepped beyond the horizon: Return!3791 Walker = PredecessorList[Walker->nr];3792 OtherAtom = Walker;3793 *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;3794 }3795 if (Walker != OtherAtom) { // if no white neighbours anymore, color it black3796 *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;3797 ColorVertexList[Walker->nr] = black;3798 Walker = PredecessorList[Walker->nr];3799 }3800 }3801 } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));3802 *out << Verbose(2) << "Inner Looping is finished." << endl;3803 3804 // if we reset all AtomCount atoms, we have again technically O(N^2) ...3805 *out << Verbose(2) << "Resetting lists." << endl;3806 Walker = NULL;3807 Binder = NULL;3808 while (!TouchedStack->IsEmpty()) {3809 Walker = TouchedStack->PopLast();3810 *out << Verbose(3) << "Re-initialising entries of " << *Walker << "." << endl;3811 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)3812 ColorEdgeList[ListOfBondsPerAtom[Walker->nr][i]->nr] = white;3813 PredecessorList[Walker->nr] = NULL;3814 ColorVertexList[Walker->nr] = white;3815 ShortestPathList[Walker->nr] = -1;3816 }3817 }3818 *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;3819 3820 // copy together3821 *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;3822 FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);3823 RunningIndex = 0;3824 while ((Leaflet != NULL) && (RunningIndex < FragmentCounter)) {3825 FragmentList->ListOfMolecules[RunningIndex++] = Leaflet->Leaf;3826 Leaflet->Leaf = NULL; // prevent molecule from being removed3827 TempLeaf = Leaflet;3828 Leaflet = Leaflet->previous;3829 delete(TempLeaf);3830 };3831 3832 // free memory and exit3833 Free((void **)&PredecessorList, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");3834 Free((void **)&ShortestPathList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");3835 Free((void **)&Labels, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");3836 Free((void **)&ColorVertexList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");3837 delete(RootStack);3838 delete(TouchedStack);3839 delete(SnakeStack);3840 3841 *out << Verbose(1) << "End of CreateListOfUniqueFragmentsOfOrder." << endl;3842 return FragmentList;3843 };3844 */3845 3846 3665 /** Structure containing all values in power set combination generation. 3847 3666 */
Note:
See TracChangeset
for help on using the changeset viewer.