Changeset 1907a7 for src/molecules.cpp


Ignore:
Timestamp:
Apr 2, 2009, 4:12:54 PM (16 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:
ca3ccc
Parents:
d8b94a
Message:

Basic implementation of Multiple molecules.

builder.cpp:

molecules.hpp:

moleculelist.cpp:

  • replaced listofmolecules array by STL list everywhere (only smaller changes necessary)
  • new merging function: SimpleMerge, SimpleAdd, SimpleMultiMerge, SimpleMultiAdd, (EmbedMerge, ScatterMerge ... both not finished). Add does not while merge does delete the src molecules.
  • new function: Enumerate(). Output of all molecules with number of atoms and chemical formula
  • new function: NumberOfActiveMolecules(). Counts the number of molecules in the list with ActiveFlag set.
  • new function: insert(). Inserts a molecule into the list with a unique index

molecules.cpp:

  • new function: SetNameFromFilename. Takes basename of a filename and sets name accordingly.
  • new function: UnlinkAtom. Only removes atom from list, does not delete it from memory.

atom.cpp:

  • Output() also accepts specific comment instead of "# molecule nr ..."
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecules.cpp

    rd8b94a r1907a7  
    6262        cell_size[0] = cell_size[2] = cell_size[5]= 20.;
    6363        cell_size[1] = cell_size[3] = cell_size[4]= 0.;
     64        strcpy(name,"none");
    6465};
    6566
     
    596597        cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    597598        return false;
     599};
     600
     601/** Set molecule::name from the basename without suffix in the given \a *filename.
     602 * \param *filename filename
     603 */
     604void 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);
    598614};
    599615
     
    11871203};
    11881204
    1189 /** Removes atom from molecule list.
     1205/** Removes atom from molecule list and deletes it.
    11901206 * \param *pointer atom to be removed
    11911207 * \return true - succeeded, false - atom not found in list
     
    12011217        Trajectories.erase(pointer);
    12021218        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 */
     1225bool 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;
    12031238};
    12041239
     
    17271762                                                };
    17281763                                                AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1729                
     1764
    17301765                                        }
    17311766
     
    25292564                                        cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    25302565                                }
    2531                                 //FragmentList->ListOfMolecules[NumberOfFragments++] = StoreFragmentFromKeySet(out, CurrentSet, IsAngstroem);
    25322566                        }
    25332567                }
     
    30883122        //if (FragmentationToDo) {              // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    30893123                // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3090                 BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
     3124                BondFragments = new MoleculeListClass();
    30913125                int k=0;
    30923126                for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    30933127                        KeySet test = (*runner).first;
    30943128                        *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));
    30963130                        k++;
    30973131                }
    3098                 *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
     3132                *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    30993133
    31003134                // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3101                 if (BondFragments->NumberOfMolecules != 0) {
     3135                if (BondFragments->ListOfMolecules.size() != 0) {
    31023136                        // create the SortIndex from BFS labels to order in the config file
    31033137                        CreateMappingLabelsToConfigSequence(out, SortIndex);
    31043138
    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;
    31063140                        if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    31073141                                *out << Verbose(1) << "All configs written." << endl;
     
    36293663};
    36303664
    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 infamous
    3633  * 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 in
    3635  * 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. And
    3637  * finally, the ShortestPath is needed for removing vertices from the snake stack during the back-
    3638  * stepping.
    3639  * \param *out output stream for debugging
    3640  * \param Order number of atoms in each fragment
    3641  * \param *configuration configuration for writing config files for each fragment
    3642  * \return List of all unique fragments with \a Order atoms
    3643  */
    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 itself
    3654         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 list
    3664         *out << Verbose(3) << "Resetting labels, parent, predecessor, color and shortest path lists." << endl;
    3665         for (int i=0;i<AtomCount;i++) { // reset all atom labels
    3666                 // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons
    3667                 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 exists
    3676         TouchedStack->ClearStack();
    3677         Walker = start->next;
    3678         while ((Walker != end)
    3679 #ifdef ADDHYDROGEN
    3680          && (Walker->type->Z == 1)
    3681 #endif
    3682                                                                                                 ) { // search for first non-hydrogen atom
    3683                 *out << Verbose(4) << "Current Root candidate is " << Walker->Name << "." << endl;
    3684                 Walker = Walker->next;
    3685         }
    3686         if (Walker != end)
    3687                 RootStack->Push(Walker);
    3688         else
    3689                 *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 stack
    3695                 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 AtomStack
    3699                 PredecessorList[Root->nr] = Root;
    3700                 TouchedStack->Push(Root);
    3701                 *out << Verbose(0) << "Root for this loop is: " << Root->Name << ".\n";
    3702 
    3703                 // clear snake stack
    3704                 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 stacks
    3714                         if (Labels[Walker->nr] == -1)   {       // give atom a unique, monotonely increasing number
    3715                                 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 search
    3722                                         *out << ", coloring bond " << *Binder << " black";
    3723                                         ColorEdgeList[Binder->nr] = black; // mark this bond as used
    3724                                 }
    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 changed
    3728                                 }
    3729                                 if ((ShortestPathList[Walker->nr] < Order) && (ColorVertexList[Walker->nr] != darkgray)) {      // if not already on snake stack
    3730                                         SnakeStack->Push(Walker);
    3731                                         ColorVertexList[Walker->nr] = darkgray; // mark as dark gray of on snake stack
    3732                                 }
    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 fragment
    3737                         if (SnakeStack->ItemCount() == Order) { // is stack full?
    3738                                 // store the fragment if it is one and get a removal candidate
    3739                                 Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration);
    3740                                 // remove the candidate if one was found
    3741                                 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 marking
    3745                                         if (Walker == Removal) { // if the current atom is to be removed, we also have to take a step back
    3746                                                 Walker = PredecessorList[Removal->nr];
    3747                                                 *out << Verbose(2) << "Stepping back to " << Walker->Name << "." << endl;
    3748                                         }
    3749                                 }
    3750                         } else
    3751                                 Removal = NULL;
    3752 
    3753                         // finally, look for a white neighbour as the next Walker
    3754                         Binder = NULL;
    3755                         if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) {    // don't look, if a new walker has been set above
    3756                                 *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 neighbour
    3758                                 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 us
    3764                                                         *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    3765                                                         //ColorVertexList[OtherAtom->nr] = lightgray;           // mark as explored
    3766                                                 } else { // otherwise check its colour and element
    3767                                                         if (
    3768 #ifdef ADDHYDROGEN
    3769                                                         (OtherAtom->type->Z != 1) &&
    3770 #endif
    3771                                                                                 (ColorEdgeList[Binder->nr] == white)) { // skip hydrogen, look for unexplored vertices
    3772                                                                 *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 back
    3774                                                                 //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                                                                 else
    3786                                                                         *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 black
    3796                                         *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 together
    3821         *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 removed
    3827                 TempLeaf = Leaflet;
    3828                 Leaflet = Leaflet->previous;
    3829                 delete(TempLeaf);
    3830         };
    3831 
    3832         // free memory and exit
    3833         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 
    38463665/** Structure containing all values in power set combination generation.
    38473666 */
Note: See TracChangeset for help on using the changeset viewer.