Changeset 6ac7ee for src/molecules.cpp


Ignore:
Timestamp:
Feb 9, 2009, 5:24:10 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:
d8b94a
Parents:
124df1
git-author:
Frederik Heber <heber@…> (02/09/09 15:55:37)
git-committer:
Frederik Heber <heber@…> (02/09/09 17:24:10)
Message:

Merge branch 'ConcaveHull' of ../espack2 into ConcaveHull

Conflicts:

molecuilder/src/boundary.cpp
molecuilder/src/boundary.hpp
molecuilder/src/builder.cpp
molecuilder/src/linkedcell.cpp
molecuilder/src/linkedcell.hpp
molecuilder/src/vector.cpp
molecuilder/src/vector.hpp
util/src/NanoCreator.c

Basically, this resulted from a lot of conversions two from spaces to one tab, which is my standard indentation. The mess was caused by eclipse auto-indenting. And in espack2:ConcaveHull was the new stuff, so all from ConcaveHull was replaced in case of doubt.
Additionally, vector had ofstream << operator instead ostream << ...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecules.cpp

    • Property mode changed from 100644 to 100755
    r124df1 r6ac7ee  
    1616double LSQ (const gsl_vector * x, void * params)
    1717{
    18   double sum = 0.;
    19   struct LSQ_params *par = (struct LSQ_params *)params;
    20   Vector **vectors = par->vectors;
    21   int num = par->num;
    22 
    23   for (int i=num;i--;) {
    24     for(int j=NDIM;j--;)
    25       sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
    26   }
    27 
    28   return sum;
     18        double sum = 0.;
     19        struct LSQ_params *par = (struct LSQ_params *)params;
     20        Vector **vectors = par->vectors;
     21        int num = par->num;
     22
     23        for (int i=num;i--;) {
     24                for(int j=NDIM;j--;)
     25                        sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
     26        }
     27
     28        return sum;
    2929};
    3030
     
    3636molecule::molecule(periodentafel *teil)
    3737{
    38   // init atom chain list
    39   start = new atom;
    40   end = new atom;
    41   start->father = NULL;
    42   end->father = NULL;
    43   link(start,end);
    44   // init bond chain list
    45   first = new bond(start, end, 1, -1);
    46   last = new bond(start, end, 1, -1);
    47   link(first,last);
    48   // other stuff
    49   MDSteps = 0;
    50   last_atom = 0;
    51   elemente = teil;
    52   AtomCount = 0;
    53   BondCount = 0;
    54   NoNonBonds = 0;
     38        // init atom chain list
     39        start = new atom;
     40        end = new atom;
     41        start->father = NULL;
     42        end->father = NULL;
     43        link(start,end);
     44        // init bond chain list
     45        first = new bond(start, end, 1, -1);
     46        last = new bond(start, end, 1, -1);
     47        link(first,last);
     48        // other stuff
     49        MDSteps = 0;
     50        last_atom = 0;
     51        elemente = teil;
     52        AtomCount = 0;
     53        BondCount = 0;
     54        NoNonBonds = 0;
    5555        NoNonHydrogen = 0;
    56   NoCyclicBonds = 0;
    57   ListOfBondsPerAtom = NULL;
    58   NumberOfBondsPerAtom = NULL;
    59   ElementCount = 0;
    60   for(int i=MAX_ELEMENTS;i--;)
    61     ElementsInMolecule[i] = 0;
    62   cell_size[0] = cell_size[2] = cell_size[5]= 20.;
    63   cell_size[1] = cell_size[3] = cell_size[4]= 0.;
     56        NoCyclicBonds = 0;
     57        ListOfBondsPerAtom = NULL;
     58        NumberOfBondsPerAtom = NULL;
     59        ElementCount = 0;
     60        for(int i=MAX_ELEMENTS;i--;)
     61                ElementsInMolecule[i] = 0;
     62        cell_size[0] = cell_size[2] = cell_size[5]= 20.;
     63        cell_size[1] = cell_size[3] = cell_size[4]= 0.;
    6464};
    6565
     
    6969molecule::~molecule()
    7070{
    71   if (ListOfBondsPerAtom != NULL)
    72     for(int i=AtomCount;i--;)
    73       Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
    74   Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
    75   Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
    76   CleanupMolecule();
    77   delete(first);
    78   delete(last);
    79   delete(end);
    80   delete(start);
     71        if (ListOfBondsPerAtom != NULL)
     72                for(int i=AtomCount;i--;)
     73                        Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
     74        Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
     75        Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
     76        CleanupMolecule();
     77        delete(first);
     78        delete(last);
     79        delete(end);
     80        delete(start);
    8181};
    8282
     
    8888bool molecule::AddAtom(atom *pointer)
    8989{
    90   if (pointer != NULL) {
    91     pointer->sort = &pointer->nr;
    92     pointer->nr = last_atom++;  // increase number within molecule
    93     AtomCount++;
    94     if (pointer->type != NULL) {
    95       if (ElementsInMolecule[pointer->type->Z] == 0)
    96         ElementCount++;
    97       ElementsInMolecule[pointer->type->Z]++; // increase number of elements
    98       if (pointer->type->Z != 1)
    99         NoNonHydrogen++;
    100       if (pointer->Name == NULL) {
    101         Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
    102         pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
    103         sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
    104       }
    105     }
    106     return add(pointer, end);
    107   } else
    108     return false;
     90        if (pointer != NULL) {
     91                pointer->sort = &pointer->nr;
     92                pointer->nr = last_atom++;      // increase number within molecule
     93                AtomCount++;
     94                if (pointer->type != NULL) {
     95                        if (ElementsInMolecule[pointer->type->Z] == 0)
     96                                ElementCount++;
     97                        ElementsInMolecule[pointer->type->Z]++; // increase number of elements
     98                        if (pointer->type->Z != 1)
     99                                NoNonHydrogen++;
     100                        if (pointer->Name == NULL) {
     101                                Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
     102                                pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
     103                                sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
     104                        }
     105                }
     106                return add(pointer, end);
     107        } else
     108                return false;
    109109};
    110110
     
    116116atom * molecule::AddCopyAtom(atom *pointer)
    117117{
    118   if (pointer != NULL) {
    119         atom *walker = new atom();
    120         walker->type = pointer->type;   // copy element of atom
    121         walker->x.CopyVector(&pointer->x); // copy coordination
    122     walker->v.CopyVector(&pointer->v); // copy velocity
    123     walker->FixedIon = pointer->FixedIon;
    124     walker->sort = &walker->nr;
    125     walker->nr = last_atom++;  // increase number within molecule
    126     walker->father = pointer; //->GetTrueFather();
    127     walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
    128     strcpy (walker->Name, pointer->Name);
    129     add(walker, end);
    130     if ((pointer->type != NULL) && (pointer->type->Z != 1))
    131       NoNonHydrogen++;
    132     AtomCount++;
    133     return walker;
    134   } else
    135     return NULL;
     118        if (pointer != NULL) {
     119                atom *walker = new atom();
     120                walker->type = pointer->type;   // copy element of atom
     121                walker->x.CopyVector(&pointer->x); // copy coordination
     122                walker->v.CopyVector(&pointer->v); // copy velocity
     123                walker->FixedIon = pointer->FixedIon;
     124                walker->sort = &walker->nr;
     125                walker->nr = last_atom++;       // increase number within molecule
     126                walker->father = pointer; //->GetTrueFather();
     127                walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
     128                strcpy (walker->Name, pointer->Name);
     129                add(walker, end);
     130                if ((pointer->type != NULL) && (pointer->type->Z != 1))
     131                        NoNonHydrogen++;
     132                AtomCount++;
     133                return walker;
     134        } else
     135                return NULL;
    136136};
    137137
     
    141141 * -# Single Bond: Simply add new atom with bond distance rescaled to typical hydrogen one
    142142 * -# Double Bond: Here, we need the **BondList of the \a *origin atom, by scanning for the other bonds instead of
    143  *    *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
    144  *    The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
    145  *    replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
    146  *    element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
    147  *    hydrogens forming this angle with *origin.
     143 *              *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
     144 *              The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
     145 *              replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
     146 *              element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
     147 *              hydrogens forming this angle with *origin.
    148148 * -# Triple Bond: The idea is to set up a tetraoid (C1-H1-H2-H3) (however the lengths \f$b\f$ of the sides of the base
    149  *    triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
    150  *    determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
    151  *    We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
    152  *    \f[ h = l \cdot \cos{\left (\frac{\alpha}{2} \right )} \qquad b = 2l \cdot \sin{\left (\frac{\alpha}{2} \right)} \quad \rightarrow \quad d = l \cdot \sqrt{\cos^2{\left (\frac{\alpha}{2} \right)}-\frac{1}{3}\cdot\sin^2{\left (\frac{\alpha}{2}\right )}}
    153  *    \f]
    154  *    vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
    155  *    the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
    156  *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    157  *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    158  *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
    159  *    \f]
    160  *    as the coordination of all three atoms in the coordinate system of these three vectors:
    161  *    \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$.
     149 *              triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
     150 *              determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
     151 *              We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
     152 *              \f[ h = l \cdot \cos{\left (\frac{\alpha}{2} \right )} \qquad b = 2l \cdot \sin{\left (\frac{\alpha}{2} \right)} \quad \rightarrow \quad d = l \cdot \sqrt{\cos^2{\left (\frac{\alpha}{2} \right)}-\frac{1}{3}\cdot\sin^2{\left (\frac{\alpha}{2}\right )}}
     153 *              \f]
     154 *              vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
     155 *              the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
     156 *              The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
     157 *              the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
     158 *              \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     159 *              \f]
     160 *              as the coordination of all three atoms in the coordinate system of these three vectors:
     161 *              \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$.
    162162 *
    163163 * \param *out output stream for debugging
     
    167167 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    168168 * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    169  * \param NumBond  number of bonds in \a **BondList
     169 * \param NumBond       number of bonds in \a **BondList
    170170 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    171171 * \return number of atoms added, if < bond::BondDegree then something went wrong
     
    174174bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
    175175{
    176   double bondlength;  // bond length of the bond to be replaced/cut
    177   double bondangle;  // bond angle of the bond to be replaced/cut
    178   double BondRescale;  // rescale value for the hydrogen bond length
    179   bool AllWentWell = true;    // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
    180   bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
    181   atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
    182   double b,l,d,f,g, alpha, factors[NDIM];    // hold temporary values in triple bond case for coordination determination
    183   Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
    184   Vector InBondvector;    // vector in direction of *Bond
    185   bond *Binder = NULL;
    186   double *matrix;
     176        double bondlength;      // bond length of the bond to be replaced/cut
     177        double bondangle;       // bond angle of the bond to be replaced/cut
     178        double BondRescale;      // rescale value for the hydrogen bond length
     179        bool AllWentWell = true;                // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
     180        bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
     181        atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
     182        double b,l,d,f,g, alpha, factors[NDIM];         // hold temporary values in triple bond case for coordination determination
     183        Vector Orthovector1, Orthovector2;      // temporary vectors in coordination construction
     184        Vector InBondvector;            // vector in direction of *Bond
     185        bond *Binder = NULL;
     186        double *matrix;
    187187
    188188//      *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
    189   // create vector in direction of bond
    190   InBondvector.CopyVector(&TopReplacement->x);
    191   InBondvector.SubtractVector(&TopOrigin->x);
    192   bondlength = InBondvector.Norm();
    193 
    194   // is greater than typical bond distance? Then we have to correct periodically
    195   // the problem is not the H being out of the box, but InBondvector have the wrong direction
    196   // due to TopReplacement or Origin being on the wrong side!
    197   if (bondlength > BondDistance) {
    198 //    *out << Verbose(4) << "InBondvector is: ";
    199 //    InBondvector.Output(out);
    200 //    *out << endl;
    201     Orthovector1.Zero();
    202     for (int i=NDIM;i--;) {
    203       l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
    204       if (fabs(l) > BondDistance) { // is component greater than bond distance
    205         Orthovector1.x[i] = (l < 0) ? -1. : +1.;
    206       } // (signs are correct, was tested!)
    207     }
    208     matrix = ReturnFullMatrixforSymmetric(cell_size);
    209     Orthovector1.MatrixMultiplication(matrix);
    210     InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
    211     Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
    212     bondlength = InBondvector.Norm();
    213 //    *out << Verbose(4) << "Corrected InBondvector is now: ";
    214 //    InBondvector.Output(out);
    215 //    *out << endl;
    216   } // periodic correction finished
    217 
    218   InBondvector.Normalize();
    219   // get typical bond length and store as scale factor for later
    220   BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    221   if (BondRescale == -1) {
    222     cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223     return false;
    224     BondRescale = bondlength;
    225   } else {
    226     if (!IsAngstroem)
    227       BondRescale /= (1.*AtomicLengthToAngstroem);
    228   }
    229 
    230   // discern single, double and triple bonds
    231   switch(TopBond->BondDegree) {
    232     case 1:
    233       FirstOtherAtom = new atom();    // new atom
    234       FirstOtherAtom->type = elemente->FindElement(1);  // element is Hydrogen
    235       FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    236       FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    237       if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
    238         FirstOtherAtom->father = TopReplacement;
    239         BondRescale = bondlength;
    240       } else {
    241         FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
    242       }
    243       InBondvector.Scale(&BondRescale);  // rescale the distance vector to Hydrogen bond length
    244       FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
    245       FirstOtherAtom->x.AddVector(&InBondvector);  // ... and add distance vector to replacement atom
    246       AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    247 //      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    248 //      FirstOtherAtom->x.Output(out);
    249 //      *out << endl;
    250       Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    251       Binder->Cyclic = false;
    252       Binder->Type = TreeEdge;
    253       break;
    254     case 2:
    255       // determine two other bonds (warning if there are more than two other) plus valence sanity check
    256       for (int i=0;i<NumBond;i++) {
    257         if (BondList[i] != TopBond) {
    258           if (FirstBond == NULL) {
    259             FirstBond = BondList[i];
    260             FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    261           } else if (SecondBond == NULL) {
    262             SecondBond = BondList[i];
    263             SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    264           } else {
    265             *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
    266           }
    267         }
    268       }
    269       if (SecondOtherAtom == NULL) {  // then we have an atom with valence four, but only 3 bonds: one to replace and one which is TopBond (third is FirstBond)
    270         SecondBond = TopBond;
    271         SecondOtherAtom = TopReplacement;
    272       }
    273       if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    274 //        *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
    275 
    276         // determine the plane of these two with the *origin
    277         AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
    278       } else {
    279         Orthovector1.GetOneNormalVector(&InBondvector);
    280       }
    281       //*out << Verbose(3)<< "Orthovector1: ";
    282       //Orthovector1.Output(out);
    283       //*out << endl;
    284       // orthogonal vector and bond vector between origin and replacement form the new plane
    285       Orthovector1.MakeNormalVector(&InBondvector);
    286       Orthovector1.Normalize();
    287       //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    288 
    289       // create the two Hydrogens ...
    290       FirstOtherAtom = new atom();
    291       SecondOtherAtom = new atom();
    292       FirstOtherAtom->type = elemente->FindElement(1);
    293       SecondOtherAtom->type = elemente->FindElement(1);
    294       FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    295       FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    296       SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    297       SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    298       FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
    299       SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
    300       bondangle = TopOrigin->type->HBondAngle[1];
    301       if (bondangle == -1) {
    302         *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    303         return false;
    304         bondangle = 0;
    305       }
    306       bondangle *= M_PI/180./2.;
    307 //      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
    308 //      InBondvector.Output(out);
    309 //      *out << endl;
    310 //      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
    311 //      Orthovector1.Output(out);
    312 //      *out << endl;
    313 //      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
    314       FirstOtherAtom->x.Zero();
    315       SecondOtherAtom->x.Zero();
    316       for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
    317         FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
    318         SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    319       }
    320       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    321       SecondOtherAtom->x.Scale(&BondRescale);
    322       //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    323       for(int i=NDIM;i--;) { // and make relative to origin atom
    324         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    325         SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326       }
    327       // ... and add to molecule
    328       AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    329       AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    330 //      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    331 //      FirstOtherAtom->x.Output(out);
    332 //      *out << endl;
    333 //      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    334 //      SecondOtherAtom->x.Output(out);
    335 //      *out << endl;
    336       Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    337       Binder->Cyclic = false;
    338       Binder->Type = TreeEdge;
    339       Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    340       Binder->Cyclic = false;
    341       Binder->Type = TreeEdge;
    342       break;
    343     case 3:
    344       // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
    345       FirstOtherAtom = new atom();
    346       SecondOtherAtom = new atom();
    347       ThirdOtherAtom = new atom();
    348       FirstOtherAtom->type = elemente->FindElement(1);
    349       SecondOtherAtom->type = elemente->FindElement(1);
    350       ThirdOtherAtom->type = elemente->FindElement(1);
    351       FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    352       FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    353       SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    354       SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    355       ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    356       ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
    357       FirstOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
    358       SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
    359       ThirdOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
    360 
    361       // we need to vectors orthonormal the InBondvector
    362       AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
    363 //      *out << Verbose(3) << "Orthovector1: ";
    364 //      Orthovector1.Output(out);
    365 //      *out << endl;
    366       AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    367 //      *out << Verbose(3) << "Orthovector2: ";
    368 //      Orthovector2.Output(out);
    369 //      *out << endl;
    370 
    371       // create correct coordination for the three atoms
    372       alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
    373       l = BondRescale;        // desired bond length
    374       b = 2.*l*sin(alpha);    // base length of isosceles triangle
    375       d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);  // length for InBondvector
    376       f = b/sqrt(3.);  // length for Orthvector1
    377       g = b/2.;        // length for Orthvector2
    378 //      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
    379 //      *out << Verbose(3) << "The three Bond lengths: " << sqrt(d*d+f*f) << ", " << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << ", "  << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << endl;
    380       factors[0] = d;
    381       factors[1] = f;
    382       factors[2] = 0.;
    383       FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    384       factors[1] = -0.5*f;
    385       factors[2] = g;
    386       SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387       factors[2] = -g;
    388       ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    389 
    390       // rescale each to correct BondDistance
    391 //      FirstOtherAtom->x.Scale(&BondRescale);
    392 //      SecondOtherAtom->x.Scale(&BondRescale);
    393 //      ThirdOtherAtom->x.Scale(&BondRescale);
    394 
    395       // and relative to *origin atom
    396       FirstOtherAtom->x.AddVector(&TopOrigin->x);
    397       SecondOtherAtom->x.AddVector(&TopOrigin->x);
    398       ThirdOtherAtom->x.AddVector(&TopOrigin->x);
    399 
    400       // ... and add to molecule
    401       AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    402       AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    403       AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
    404 //      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    405 //      FirstOtherAtom->x.Output(out);
    406 //      *out << endl;
    407 //      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    408 //      SecondOtherAtom->x.Output(out);
    409 //      *out << endl;
    410 //      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
    411 //      ThirdOtherAtom->x.Output(out);
    412 //      *out << endl;
    413       Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    414       Binder->Cyclic = false;
    415       Binder->Type = TreeEdge;
    416       Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    417       Binder->Cyclic = false;
    418       Binder->Type = TreeEdge;
    419       Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
    420       Binder->Cyclic = false;
    421       Binder->Type = TreeEdge;
    422       break;
    423     default:
    424       cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
    425       AllWentWell = false;
    426       break;
    427   }
     189        // create vector in direction of bond
     190        InBondvector.CopyVector(&TopReplacement->x);
     191        InBondvector.SubtractVector(&TopOrigin->x);
     192        bondlength = InBondvector.Norm();
     193
     194        // is greater than typical bond distance? Then we have to correct periodically
     195        // the problem is not the H being out of the box, but InBondvector have the wrong direction
     196        // due to TopReplacement or Origin being on the wrong side!
     197        if (bondlength > BondDistance) {
     198//              *out << Verbose(4) << "InBondvector is: ";
     199//              InBondvector.Output(out);
     200//              *out << endl;
     201                Orthovector1.Zero();
     202                for (int i=NDIM;i--;) {
     203                        l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
     204                        if (fabs(l) > BondDistance) { // is component greater than bond distance
     205                                Orthovector1.x[i] = (l < 0) ? -1. : +1.;
     206                        } // (signs are correct, was tested!)
     207                }
     208                matrix = ReturnFullMatrixforSymmetric(cell_size);
     209                Orthovector1.MatrixMultiplication(matrix);
     210                InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
     211                Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
     212                bondlength = InBondvector.Norm();
     213//              *out << Verbose(4) << "Corrected InBondvector is now: ";
     214//              InBondvector.Output(out);
     215//              *out << endl;
     216        } // periodic correction finished
     217
     218        InBondvector.Normalize();
     219        // get typical bond length and store as scale factor for later
     220        BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
     221        if (BondRescale == -1) {
     222                cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     223                return false;
     224                BondRescale = bondlength;
     225        } else {
     226                if (!IsAngstroem)
     227                        BondRescale /= (1.*AtomicLengthToAngstroem);
     228        }
     229
     230        // discern single, double and triple bonds
     231        switch(TopBond->BondDegree) {
     232                case 1:
     233                        FirstOtherAtom = new atom();            // new atom
     234                        FirstOtherAtom->type = elemente->FindElement(1);        // element is Hydrogen
     235                        FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     236                        FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     237                        if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
     238                                FirstOtherAtom->father = TopReplacement;
     239                                BondRescale = bondlength;
     240                        } else {
     241                                FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
     242                        }
     243                        InBondvector.Scale(&BondRescale);        // rescale the distance vector to Hydrogen bond length
     244                        FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
     245                        FirstOtherAtom->x.AddVector(&InBondvector);     // ... and add distance vector to replacement atom
     246                        AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     247//                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     248//                      FirstOtherAtom->x.Output(out);
     249//                      *out << endl;
     250                        Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     251                        Binder->Cyclic = false;
     252                        Binder->Type = TreeEdge;
     253                        break;
     254                case 2:
     255                        // determine two other bonds (warning if there are more than two other) plus valence sanity check
     256                        for (int i=0;i<NumBond;i++) {
     257                                if (BondList[i] != TopBond) {
     258                                        if (FirstBond == NULL) {
     259                                                FirstBond = BondList[i];
     260                                                FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     261                                        } else if (SecondBond == NULL) {
     262                                                SecondBond = BondList[i];
     263                                                SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     264                                        } else {
     265                                                *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     266                                        }
     267                                }
     268                        }
     269                        if (SecondOtherAtom == NULL) {  // then we have an atom with valence four, but only 3 bonds: one to replace and one which is TopBond (third is FirstBond)
     270                                SecondBond = TopBond;
     271                                SecondOtherAtom = TopReplacement;
     272                        }
     273                        if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
     274//                              *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
     275
     276                                // determine the plane of these two with the *origin
     277                                AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     278                        } else {
     279                                Orthovector1.GetOneNormalVector(&InBondvector);
     280                        }
     281                        //*out << Verbose(3)<< "Orthovector1: ";
     282                        //Orthovector1.Output(out);
     283                        //*out << endl;
     284                        // orthogonal vector and bond vector between origin and replacement form the new plane
     285                        Orthovector1.MakeNormalVector(&InBondvector);
     286                        Orthovector1.Normalize();
     287                        //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
     288
     289                        // create the two Hydrogens ...
     290                        FirstOtherAtom = new atom();
     291                        SecondOtherAtom = new atom();
     292                        FirstOtherAtom->type = elemente->FindElement(1);
     293                        SecondOtherAtom->type = elemente->FindElement(1);
     294                        FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     295                        FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     296                        SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     297                        SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     298                        FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
     299                        SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
     300                        bondangle = TopOrigin->type->HBondAngle[1];
     301                        if (bondangle == -1) {
     302                                *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     303                                return false;
     304                                bondangle = 0;
     305                        }
     306                        bondangle *= M_PI/180./2.;
     307//                      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
     308//                      InBondvector.Output(out);
     309//                      *out << endl;
     310//                      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
     311//                      Orthovector1.Output(out);
     312//                      *out << endl;
     313//                      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
     314                        FirstOtherAtom->x.Zero();
     315                        SecondOtherAtom->x.Zero();
     316                        for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
     317                                FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
     318                                SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
     319                        }
     320                        FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     321                        SecondOtherAtom->x.Scale(&BondRescale);
     322                        //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
     323                        for(int i=NDIM;i--;) { // and make relative to origin atom
     324                                FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     325                                SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
     326                        }
     327                        // ... and add to molecule
     328                        AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     329                        AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     330//                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     331//                      FirstOtherAtom->x.Output(out);
     332//                      *out << endl;
     333//                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     334//                      SecondOtherAtom->x.Output(out);
     335//                      *out << endl;
     336                        Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     337                        Binder->Cyclic = false;
     338                        Binder->Type = TreeEdge;
     339                        Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     340                        Binder->Cyclic = false;
     341                        Binder->Type = TreeEdge;
     342                        break;
     343                case 3:
     344                        // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
     345                        FirstOtherAtom = new atom();
     346                        SecondOtherAtom = new atom();
     347                        ThirdOtherAtom = new atom();
     348                        FirstOtherAtom->type = elemente->FindElement(1);
     349                        SecondOtherAtom->type = elemente->FindElement(1);
     350                        ThirdOtherAtom->type = elemente->FindElement(1);
     351                        FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     352                        FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     353                        SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     354                        SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     355                        ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     356                        ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
     357                        FirstOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
     358                        SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
     359                        ThirdOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
     360
     361                        // we need to vectors orthonormal the InBondvector
     362                        AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
     363//                      *out << Verbose(3) << "Orthovector1: ";
     364//                      Orthovector1.Output(out);
     365//                      *out << endl;
     366                        AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
     367//                      *out << Verbose(3) << "Orthovector2: ";
     368//                      Orthovector2.Output(out);
     369//                      *out << endl;
     370
     371                        // create correct coordination for the three atoms
     372                        alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     373                        l = BondRescale;                                // desired bond length
     374                        b = 2.*l*sin(alpha);            // base length of isosceles triangle
     375                        d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);    // length for InBondvector
     376                        f = b/sqrt(3.); // length for Orthvector1
     377                        g = b/2.;                                // length for Orthvector2
     378//                      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
     379//                      *out << Verbose(3) << "The three Bond lengths: " << sqrt(d*d+f*f) << ", " << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << ", "    << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << endl;
     380                        factors[0] = d;
     381                        factors[1] = f;
     382                        factors[2] = 0.;
     383                        FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     384                        factors[1] = -0.5*f;
     385                        factors[2] = g;
     386                        SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     387                        factors[2] = -g;
     388                        ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     389
     390                        // rescale each to correct BondDistance
     391//                      FirstOtherAtom->x.Scale(&BondRescale);
     392//                      SecondOtherAtom->x.Scale(&BondRescale);
     393//                      ThirdOtherAtom->x.Scale(&BondRescale);
     394
     395                        // and relative to *origin atom
     396                        FirstOtherAtom->x.AddVector(&TopOrigin->x);
     397                        SecondOtherAtom->x.AddVector(&TopOrigin->x);
     398                        ThirdOtherAtom->x.AddVector(&TopOrigin->x);
     399
     400                        // ... and add to molecule
     401                        AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     402                        AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     403                        AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
     404//                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     405//                      FirstOtherAtom->x.Output(out);
     406//                      *out << endl;
     407//                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     408//                      SecondOtherAtom->x.Output(out);
     409//                      *out << endl;
     410//                      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
     411//                      ThirdOtherAtom->x.Output(out);
     412//                      *out << endl;
     413                        Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     414                        Binder->Cyclic = false;
     415                        Binder->Type = TreeEdge;
     416                        Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     417                        Binder->Cyclic = false;
     418                        Binder->Type = TreeEdge;
     419                        Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
     420                        Binder->Cyclic = false;
     421                        Binder->Type = TreeEdge;
     422                        break;
     423                default:
     424                        cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
     425                        AllWentWell = false;
     426                        break;
     427        }
    428428
    429429//      *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
    430   return AllWentWell;
     430        return AllWentWell;
    431431};
    432432
     
    438438bool molecule::AddXYZFile(string filename)
    439439{
    440   istringstream *input = NULL;
    441   int NumberOfAtoms = 0; // atom number in xyz read
    442   int i, j; // loop variables
    443   atom *Walker = NULL;  // pointer to added atom
    444   char shorthand[3];  // shorthand for atom name
    445   ifstream xyzfile;  // xyz file
    446   string line;    // currently parsed line
    447   double x[3];    // atom coordinates
    448 
    449   xyzfile.open(filename.c_str());
    450   if (!xyzfile)
    451     return false;
    452 
    453   getline(xyzfile,line,'\n'); // Read numer of atoms in file
    454   input = new istringstream(line);
    455   *input >> NumberOfAtoms;
    456   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    457   getline(xyzfile,line,'\n'); // Read comment
    458   cout << Verbose(1) << "Comment: " << line << endl;
    459 
    460   if (MDSteps == 0) // no atoms yet present
    461     MDSteps++;
    462   for(i=0;i<NumberOfAtoms;i++){
    463     Walker = new atom;
    464     getline(xyzfile,line,'\n');
    465     istringstream *item = new istringstream(line);
    466     //istringstream input(line);
    467     //cout << Verbose(1) << "Reading: " << line << endl;
    468     *item >> shorthand;
    469     *item >> x[0];
    470     *item >> x[1];
    471     *item >> x[2];
    472     Walker->type = elemente->FindElement(shorthand);
    473     if (Walker->type == NULL) {
    474       cerr << "Could not parse the element at line: '" << line << "', setting to H.";
    475       Walker->type = elemente->FindElement(1);
    476     }
    477     if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
    478       Trajectories[Walker].R.resize(MDSteps+10);
    479       Trajectories[Walker].U.resize(MDSteps+10);
    480       Trajectories[Walker].F.resize(MDSteps+10);
    481     }
    482     for(j=NDIM;j--;) {
    483       Walker->x.x[j] = x[j];
    484       Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
    485       Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
    486       Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
    487     }
    488     AddAtom(Walker);  // add to molecule
    489     delete(item);
    490   }
    491   xyzfile.close();
    492   delete(input);
    493   return true;
     440        istringstream *input = NULL;
     441        int NumberOfAtoms = 0; // atom number in xyz read
     442        int i, j; // loop variables
     443        atom *Walker = NULL;    // pointer to added atom
     444        char shorthand[3];      // shorthand for atom name
     445        ifstream xyzfile;        // xyz file
     446        string line;            // currently parsed line
     447        double x[3];            // atom coordinates
     448
     449        xyzfile.open(filename.c_str());
     450        if (!xyzfile)
     451                return false;
     452
     453        getline(xyzfile,line,'\n'); // Read numer of atoms in file
     454        input = new istringstream(line);
     455        *input >> NumberOfAtoms;
     456        cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     457        getline(xyzfile,line,'\n'); // Read comment
     458        cout << Verbose(1) << "Comment: " << line << endl;
     459
     460        if (MDSteps == 0) // no atoms yet present
     461                MDSteps++;
     462        for(i=0;i<NumberOfAtoms;i++){
     463                Walker = new atom;
     464                getline(xyzfile,line,'\n');
     465                istringstream *item = new istringstream(line);
     466                //istringstream input(line);
     467                //cout << Verbose(1) << "Reading: " << line << endl;
     468                *item >> shorthand;
     469                *item >> x[0];
     470                *item >> x[1];
     471                *item >> x[2];
     472                Walker->type = elemente->FindElement(shorthand);
     473                if (Walker->type == NULL) {
     474                        cerr << "Could not parse the element at line: '" << line << "', setting to H.";
     475                        Walker->type = elemente->FindElement(1);
     476                }
     477                if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
     478                        Trajectories[Walker].R.resize(MDSteps+10);
     479                        Trajectories[Walker].U.resize(MDSteps+10);
     480                        Trajectories[Walker].F.resize(MDSteps+10);
     481                }
     482                for(j=NDIM;j--;) {
     483                        Walker->x.x[j] = x[j];
     484                        Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
     485                        Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
     486                        Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
     487                }
     488                AddAtom(Walker);        // add to molecule
     489                delete(item);
     490        }
     491        xyzfile.close();
     492        delete(input);
     493        return true;
    494494};
    495495
     
    499499molecule *molecule::CopyMolecule()
    500500{
    501   molecule *copy = new molecule(elemente);
    502   atom *CurrentAtom = NULL;
    503   atom *LeftAtom = NULL, *RightAtom = NULL;
    504   atom *Walker = NULL;
    505 
    506   // copy all atoms
    507   Walker = start;
    508   while(Walker->next != end) {
    509     Walker = Walker->next;
    510     CurrentAtom = copy->AddCopyAtom(Walker);
    511   }
    512 
    513   // copy all bonds
    514   bond *Binder = first;
    515   bond *NewBond = NULL;
    516   while(Binder->next != last) {
    517     Binder = Binder->next;
    518     // get the pendant atoms of current bond in the copy molecule
    519     LeftAtom = copy->start;
    520     while (LeftAtom->next != copy->end) {
    521       LeftAtom = LeftAtom->next;
    522       if (LeftAtom->father == Binder->leftatom)
    523         break;
    524     }
    525     RightAtom = copy->start;
    526     while (RightAtom->next != copy->end) {
    527       RightAtom = RightAtom->next;
    528       if (RightAtom->father == Binder->rightatom)
    529         break;
    530     }
    531     NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
    532     NewBond->Cyclic = Binder->Cyclic;
    533     if (Binder->Cyclic)
    534       copy->NoCyclicBonds++;
    535     NewBond->Type = Binder->Type;
    536   }
    537   // correct fathers
    538   Walker = copy->start;
    539   while(Walker->next != copy->end) {
    540     Walker = Walker->next;
    541     if (Walker->father->father == Walker->father)  // same atom in copy's father points to itself
    542       Walker->father = Walker;  // set father to itself (copy of a whole molecule)
    543     else
    544      Walker->father = Walker->father->father;  // set father to original's father
    545   }
    546   // copy values
    547   copy->CountAtoms((ofstream *)&cout);
    548   copy->CountElements();
    549   if (first->next != last) {  // if adjaceny list is present
    550     copy->BondDistance = BondDistance;
    551     copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    552   }
    553 
    554   return copy;
     501        molecule *copy = new molecule(elemente);
     502        atom *CurrentAtom = NULL;
     503        atom *LeftAtom = NULL, *RightAtom = NULL;
     504        atom *Walker = NULL;
     505
     506        // copy all atoms
     507        Walker = start;
     508        while(Walker->next != end) {
     509                Walker = Walker->next;
     510                CurrentAtom = copy->AddCopyAtom(Walker);
     511        }
     512
     513        // copy all bonds
     514        bond *Binder = first;
     515        bond *NewBond = NULL;
     516        while(Binder->next != last) {
     517                Binder = Binder->next;
     518                // get the pendant atoms of current bond in the copy molecule
     519                LeftAtom = copy->start;
     520                while (LeftAtom->next != copy->end) {
     521                        LeftAtom = LeftAtom->next;
     522                        if (LeftAtom->father == Binder->leftatom)
     523                                break;
     524                }
     525                RightAtom = copy->start;
     526                while (RightAtom->next != copy->end) {
     527                        RightAtom = RightAtom->next;
     528                        if (RightAtom->father == Binder->rightatom)
     529                                break;
     530                }
     531                NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
     532                NewBond->Cyclic = Binder->Cyclic;
     533                if (Binder->Cyclic)
     534                        copy->NoCyclicBonds++;
     535                NewBond->Type = Binder->Type;
     536        }
     537        // correct fathers
     538        Walker = copy->start;
     539        while(Walker->next != copy->end) {
     540                Walker = Walker->next;
     541                if (Walker->father->father == Walker->father)    // same atom in copy's father points to itself
     542                        Walker->father = Walker;        // set father to itself (copy of a whole molecule)
     543                else
     544                 Walker->father = Walker->father->father;       // set father to original's father
     545        }
     546        // copy values
     547        copy->CountAtoms((ofstream *)&cout);
     548        copy->CountElements();
     549        if (first->next != last) {      // if adjaceny list is present
     550                copy->BondDistance = BondDistance;
     551                copy->CreateListOfBondsPerAtom((ofstream *)&cout);
     552        }
     553
     554        return copy;
    555555};
    556556
     
    563563bond * molecule::AddBond(atom *atom1, atom *atom2, int degree=1)
    564564{
    565   bond *Binder = NULL;
    566   if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    567     Binder = new bond(atom1, atom2, degree, BondCount++);
    568     if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    569       NoNonBonds++;
    570     add(Binder, last);
    571   } else {
    572     cerr << Verbose(1) << "ERROR: Could not add bond between " << atom1->Name << " and " << atom2->Name << " as one or both are not present in the molecule." << endl;
    573   }
    574   return Binder;
     565        bond *Binder = NULL;
     566        if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
     567                Binder = new bond(atom1, atom2, degree, BondCount++);
     568                if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
     569                        NoNonBonds++;
     570                add(Binder, last);
     571        } else {
     572                cerr << Verbose(1) << "ERROR: Could not add bond between " << atom1->Name << " and " << atom2->Name << " as one or both are not present in the molecule." << endl;
     573        }
     574        return Binder;
    575575};
    576576
     
    582582bool molecule::RemoveBond(bond *pointer)
    583583{
    584   //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    585   removewithoutcheck(pointer);
    586   return true;
     584        //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     585        removewithoutcheck(pointer);
     586        return true;
    587587};
    588588
     
    594594bool molecule::RemoveBonds(atom *BondPartner)
    595595{
    596   cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    597   return false;
     596        cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     597        return false;
    598598};
    599599
     
    603603void molecule::SetBoxDimension(Vector *dim)
    604604{
    605   cell_size[0] = dim->x[0];
    606   cell_size[1] = 0.;
    607   cell_size[2] = dim->x[1];
    608   cell_size[3] = 0.;
    609   cell_size[4] = 0.;
    610   cell_size[5] = dim->x[2];
     605        cell_size[0] = dim->x[0];
     606        cell_size[1] = 0.;
     607        cell_size[2] = dim->x[1];
     608        cell_size[3] = 0.;
     609        cell_size[4] = 0.;
     610        cell_size[5] = dim->x[2];
    611611};
    612612
     
    617617bool molecule::CenterInBox(ofstream *out, Vector *BoxLengths)
    618618{
    619   bool status = true;
    620   atom *ptr = NULL;
    621   Vector *min = new Vector;
    622   Vector *max = new Vector;
    623 
    624   // gather min and max for each axis
    625   ptr = start->next;  // start at first in list
    626   if (ptr != end) {  //list not empty?
    627     for (int i=NDIM;i--;) {
    628       max->x[i] = ptr->x.x[i];
    629       min->x[i] = ptr->x.x[i];
    630     }
    631     while (ptr->next != end) {  // continue with second if present
    632       ptr = ptr->next;
    633       //ptr->Output(1,1,out);
    634       for (int i=NDIM;i--;) {
    635         max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    636         min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    637       }
    638     }
    639   }
    640   // sanity check
    641   for(int i=NDIM;i--;) {
    642     if (max->x[i] - min->x[i] > BoxLengths->x[i])
    643       status = false;
    644   }
    645   // warn if check failed
    646   if (!status)
    647     *out << "WARNING: molecule is bigger than defined box!" << endl;
    648   else {  // else center in box
    649     max->AddVector(min);
    650     max->Scale(-1.);
    651     max->AddVector(BoxLengths);
    652     max->Scale(0.5);
    653     Translate(max);
    654   }
    655 
    656   // free and exit
    657   delete(min);
    658   delete(max);
    659   return status;
     619        bool status = true;
     620        atom *ptr = NULL;
     621        Vector *min = new Vector;
     622        Vector *max = new Vector;
     623
     624        // gather min and max for each axis
     625        ptr = start->next;      // start at first in list
     626        if (ptr != end) {        //list not empty?
     627                for (int i=NDIM;i--;) {
     628                        max->x[i] = ptr->x.x[i];
     629                        min->x[i] = ptr->x.x[i];
     630                }
     631                while (ptr->next != end) {      // continue with second if present
     632                        ptr = ptr->next;
     633                        //ptr->Output(1,1,out);
     634                        for (int i=NDIM;i--;) {
     635                                max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     636                                min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     637                        }
     638                }
     639        }
     640        // sanity check
     641        for(int i=NDIM;i--;) {
     642                if (max->x[i] - min->x[i] > BoxLengths->x[i])
     643                        status = false;
     644        }
     645        // warn if check failed
     646        if (!status)
     647                *out << "WARNING: molecule is bigger than defined box!" << endl;
     648        else {  // else center in box
     649                max->AddVector(min);
     650                max->Scale(-1.);
     651                max->AddVector(BoxLengths);
     652                max->Scale(0.5);
     653                Translate(max);
     654        }
     655
     656        // free and exit
     657        delete(min);
     658        delete(max);
     659        return status;
    660660};
    661661
     
    666666void molecule::CenterEdge(ofstream *out, Vector *max)
    667667{
    668   Vector *min = new Vector;
    669 
    670 //  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    671   atom *ptr = start->next;  // start at first in list
    672   if (ptr != end) {  //list not empty?
    673     for (int i=NDIM;i--;) {
    674       max->x[i] = ptr->x.x[i];
    675       min->x[i] = ptr->x.x[i];
    676     }
    677     while (ptr->next != end) {  // continue with second if present
    678       ptr = ptr->next;
    679       //ptr->Output(1,1,out);
    680       for (int i=NDIM;i--;) {
    681         max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    682         min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    683       }
    684     }
    685 //    *out << Verbose(4) << "Maximum is ";
    686 //    max->Output(out);
    687 //    *out << ", Minimum is ";
    688 //    min->Output(out);
    689 //    *out << endl;
    690     min->Scale(-1.);
    691     max->AddVector(min);
    692     Translate(min);
    693   }
    694   delete(min);
    695 //  *out << Verbose(3) << "End of CenterEdge." << endl;
     668        Vector *min = new Vector;
     669
     670//      *out << Verbose(3) << "Begin of CenterEdge." << endl;
     671        atom *ptr = start->next;        // start at first in list
     672        if (ptr != end) {        //list not empty?
     673                for (int i=NDIM;i--;) {
     674                        max->x[i] = ptr->x.x[i];
     675                        min->x[i] = ptr->x.x[i];
     676                }
     677                while (ptr->next != end) {      // continue with second if present
     678                        ptr = ptr->next;
     679                        //ptr->Output(1,1,out);
     680                        for (int i=NDIM;i--;) {
     681                                max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     682                                min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     683                        }
     684                }
     685//              *out << Verbose(4) << "Maximum is ";
     686//              max->Output(out);
     687//              *out << ", Minimum is ";
     688//              min->Output(out);
     689//              *out << endl;
     690                min->Scale(-1.);
     691                max->AddVector(min);
     692                Translate(min);
     693        }
     694        delete(min);
     695//      *out << Verbose(3) << "End of CenterEdge." << endl;
    696696};
    697697
     
    702702void molecule::CenterOrigin(ofstream *out, Vector *center)
    703703{
    704   int Num = 0;
    705   atom *ptr = start->next;  // start at first in list
    706 
    707   for(int i=NDIM;i--;) // zero center vector
    708     center->x[i] = 0.;
    709 
    710   if (ptr != end) {  //list not empty?
    711     while (ptr->next != end) {  // continue with second if present
    712       ptr = ptr->next;
    713       Num++;
    714       center->AddVector(&ptr->x);
    715     }
    716     center->Scale(-1./Num); // divide through total number (and sign for direction)
    717     Translate(center);
    718   }
     704        int Num = 0;
     705        atom *ptr = start->next;        // start at first in list
     706
     707        for(int i=NDIM;i--;) // zero center vector
     708                center->x[i] = 0.;
     709
     710        if (ptr != end) {        //list not empty?
     711                while (ptr->next != end) {      // continue with second if present
     712                        ptr = ptr->next;
     713                        Num++;
     714                        center->AddVector(&ptr->x);
     715                }
     716                center->Scale(-1./Num); // divide through total number (and sign for direction)
     717                Translate(center);
     718        }
    719719};
    720720
     
    725725Vector * molecule::DetermineCenterOfAll(ofstream *out)
    726726{
    727   atom *ptr = start->next;  // start at first in list
    728   Vector *a = new Vector();
    729   Vector tmp;
    730   double Num = 0;
    731 
    732   a->Zero();
    733 
    734   if (ptr != end) {  //list not empty?
    735     while (ptr->next != end) {  // continue with second if present
    736       ptr = ptr->next;
    737       Num += 1.;
    738       tmp.CopyVector(&ptr->x);
    739       a->AddVector(&tmp);
    740     }
    741     a->Scale(-1./Num); // divide through total mass (and sign for direction)
    742   }
    743   //cout << Verbose(1) << "Resulting center of gravity: ";
    744   //a->Output(out);
    745   //cout << endl;
    746   return a;
     727        atom *ptr = start->next;        // start at first in list
     728        Vector *a = new Vector();
     729        Vector tmp;
     730        double Num = 0;
     731
     732        a->Zero();
     733
     734        if (ptr != end) {        //list not empty?
     735                while (ptr->next != end) {      // continue with second if present
     736                        ptr = ptr->next;
     737                        Num += 1.;
     738                        tmp.CopyVector(&ptr->x);
     739                        a->AddVector(&tmp);
     740                }
     741                a->Scale(-1./Num); // divide through total mass (and sign for direction)
     742        }
     743        //cout << Verbose(1) << "Resulting center of gravity: ";
     744        //a->Output(out);
     745        //cout << endl;
     746        return a;
    747747};
    748748
     
    753753Vector * molecule::DetermineCenterOfGravity(ofstream *out)
    754754{
    755         atom *ptr = start->next;  // start at first in list
     755        atom *ptr = start->next;        // start at first in list
    756756        Vector *a = new Vector();
    757757        Vector tmp;
    758   double Num = 0;
     758        double Num = 0;
    759759
    760760        a->Zero();
    761761
    762   if (ptr != end) {  //list not empty?
    763     while (ptr->next != end) {  // continue with second if present
    764       ptr = ptr->next;
    765       Num += ptr->type->mass;
    766       tmp.CopyVector(&ptr->x);
    767       tmp.Scale(ptr->type->mass);  // scale by mass
    768       a->AddVector(&tmp);
    769     }
    770     a->Scale(-1./Num); // divide through total mass (and sign for direction)
    771   }
    772 //  *out << Verbose(1) << "Resulting center of gravity: ";
    773 //  a->Output(out);
    774 //  *out << endl;
    775   return a;
     762        if (ptr != end) {        //list not empty?
     763                while (ptr->next != end) {      // continue with second if present
     764                        ptr = ptr->next;
     765                        Num += ptr->type->mass;
     766                        tmp.CopyVector(&ptr->x);
     767                        tmp.Scale(ptr->type->mass);     // scale by mass
     768                        a->AddVector(&tmp);
     769                }
     770                a->Scale(-1./Num); // divide through total mass (and sign for direction)
     771        }
     772//      *out << Verbose(1) << "Resulting center of gravity: ";
     773//      a->Output(out);
     774//      *out << endl;
     775        return a;
    776776};
    777777
     
    782782void molecule::CenterGravity(ofstream *out, Vector *center)
    783783{
    784   if (center == NULL) {
    785     DetermineCenter(*center);
    786     Translate(center);
    787     delete(center);
    788   } else {
    789     Translate(center);
    790   }
     784        if (center == NULL) {
     785                DetermineCenter(*center);
     786                Translate(center);
     787                delete(center);
     788        } else {
     789                Translate(center);
     790        }
    791791};
    792792
     
    796796void molecule::Scale(double **factor)
    797797{
    798   atom *ptr = start;
    799 
    800   while (ptr->next != end) {
    801     ptr = ptr->next;
    802     for (int j=0;j<MDSteps;j++)
    803       Trajectories[ptr].R.at(j).Scale(factor);
    804     ptr->x.Scale(factor);
    805   }
     798        atom *ptr = start;
     799
     800        while (ptr->next != end) {
     801                ptr = ptr->next;
     802                for (int j=0;j<MDSteps;j++)
     803                        Trajectories[ptr].R.at(j).Scale(factor);
     804                ptr->x.Scale(factor);
     805        }
    806806};
    807807
     
    811811void molecule::Translate(const Vector *trans)
    812812{
    813   atom *ptr = start;
    814 
    815   while (ptr->next != end) {
    816     ptr = ptr->next;
    817     for (int j=0;j<MDSteps;j++)
    818       Trajectories[ptr].R.at(j).Translate(trans);
    819     ptr->x.Translate(trans);
    820   }
     813        atom *ptr = start;
     814
     815        while (ptr->next != end) {
     816                ptr = ptr->next;
     817                for (int j=0;j<MDSteps;j++)
     818                        Trajectories[ptr].R.at(j).Translate(trans);
     819                ptr->x.Translate(trans);
     820        }
    821821};
    822822
     
    826826void molecule::Mirror(const Vector *n)
    827827{
    828   atom *ptr = start;
    829 
    830   while (ptr->next != end) {
    831     ptr = ptr->next;
    832     for (int j=0;j<MDSteps;j++)
    833       Trajectories[ptr].R.at(j).Mirror(n);
    834     ptr->x.Mirror(n);
    835   }
     828        atom *ptr = start;
     829
     830        while (ptr->next != end) {
     831                ptr = ptr->next;
     832                for (int j=0;j<MDSteps;j++)
     833                        Trajectories[ptr].R.at(j).Mirror(n);
     834                ptr->x.Mirror(n);
     835        }
    836836};
    837837
     
    841841void molecule::DetermineCenter(Vector &Center)
    842842{
    843   atom *Walker = start;
    844   bond *Binder = NULL;
    845   double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    846   double tmp;
    847   bool flag;
    848   Vector Testvector, Translationvector;
    849 
    850   do {
    851     Center.Zero();
    852     flag = true;
    853     while (Walker->next != end) {
    854       Walker = Walker->next;
     843        atom *Walker = start;
     844        bond *Binder = NULL;
     845        double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     846        double tmp;
     847        bool flag;
     848        Vector Testvector, Translationvector;
     849
     850        do {
     851                Center.Zero();
     852                flag = true;
     853                while (Walker->next != end) {
     854                        Walker = Walker->next;
    855855#ifdef ADDHYDROGEN
    856       if (Walker->type->Z != 1) {
     856                        if (Walker->type->Z != 1) {
    857857#endif
    858         Testvector.CopyVector(&Walker->x);
    859         Testvector.InverseMatrixMultiplication(matrix);
    860         Translationvector.Zero();
    861         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    862           Binder = ListOfBondsPerAtom[Walker->nr][i];
    863           if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    864             for (int j=0;j<NDIM;j++) {
    865               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    866               if ((fabs(tmp)) > BondDistance) {
    867                 flag = false;
    868                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
    869                 if (tmp > 0)
    870                   Translationvector.x[j] -= 1.;
    871                 else
    872                   Translationvector.x[j] += 1.;
    873               }
    874             }
    875         }
    876         Testvector.AddVector(&Translationvector);
    877         Testvector.MatrixMultiplication(matrix);
    878         Center.AddVector(&Testvector);
    879         cout << Verbose(1) << "vector is: ";
    880         Testvector.Output((ofstream *)&cout);
    881         cout << endl;
     858                                Testvector.CopyVector(&Walker->x);
     859                                Testvector.InverseMatrixMultiplication(matrix);
     860                                Translationvector.Zero();
     861                                for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     862                                        Binder = ListOfBondsPerAtom[Walker->nr][i];
     863                                        if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     864                                                for (int j=0;j<NDIM;j++) {
     865                                                        tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     866                                                        if ((fabs(tmp)) > BondDistance) {
     867                                                                flag = false;
     868                                                                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     869                                                                if (tmp > 0)
     870                                                                        Translationvector.x[j] -= 1.;
     871                                                                else
     872                                                                        Translationvector.x[j] += 1.;
     873                                                        }
     874                                                }
     875                                }
     876                                Testvector.AddVector(&Translationvector);
     877                                Testvector.MatrixMultiplication(matrix);
     878                                Center.AddVector(&Testvector);
     879                                cout << Verbose(1) << "vector is: ";
     880                                Testvector.Output((ofstream *)&cout);
     881                                cout << endl;
    882882#ifdef ADDHYDROGEN
    883         // now also change all hydrogens
    884         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    885           Binder = ListOfBondsPerAtom[Walker->nr][i];
    886           if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    887             Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
    888             Testvector.InverseMatrixMultiplication(matrix);
    889             Testvector.AddVector(&Translationvector);
    890             Testvector.MatrixMultiplication(matrix);
    891             Center.AddVector(&Testvector);
    892             cout << Verbose(1) << "Hydrogen vector is: ";
    893             Testvector.Output((ofstream *)&cout);
    894             cout << endl;
    895           }
    896         }
    897       }
     883                                // now also change all hydrogens
     884                                for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     885                                        Binder = ListOfBondsPerAtom[Walker->nr][i];
     886                                        if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
     887                                                Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     888                                                Testvector.InverseMatrixMultiplication(matrix);
     889                                                Testvector.AddVector(&Translationvector);
     890                                                Testvector.MatrixMultiplication(matrix);
     891                                                Center.AddVector(&Testvector);
     892                                                cout << Verbose(1) << "Hydrogen vector is: ";
     893                                                Testvector.Output((ofstream *)&cout);
     894                                                cout << endl;
     895                                        }
     896                                }
     897                        }
    898898#endif
    899     }
    900   } while (!flag);
    901   Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
    902   Center.Scale(1./(double)AtomCount);
     899                }
     900        } while (!flag);
     901        Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
     902        Center.Scale(1./(double)AtomCount);
    903903};
    904904
     
    909909void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate)
    910910{
    911         atom *ptr = start;  // start at first in list
     911        atom *ptr = start;      // start at first in list
    912912        double InertiaTensor[NDIM*NDIM];
    913913        Vector *CenterOfGravity = DetermineCenterOfGravity(out);
     
    938938        *out << "The inertia tensor is:" << endl;
    939939        for(int i=0;i<NDIM;i++) {
    940           for(int j=0;j<NDIM;j++)
    941             *out << InertiaTensor[i*NDIM+j] << " ";
    942           *out << endl;
     940                for(int j=0;j<NDIM;j++)
     941                        *out << InertiaTensor[i*NDIM+j] << " ";
     942                *out << endl;
    943943        }
    944944        *out << endl;
     
    960960        // check whether we rotate or not
    961961        if (DoRotate) {
    962           *out << Verbose(1) << "Transforming molecule into PAS ... ";
    963           // the eigenvectors specify the transformation matrix
    964           ptr = start;
    965           while (ptr->next != end) {
    966             ptr = ptr->next;
    967             for (int j=0;j<MDSteps;j++)
    968               Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
    969             ptr->x.MatrixMultiplication(evec->data);
    970           }
    971           *out << "done." << endl;
    972 
    973           // summing anew for debugging (resulting matrix has to be diagonal!)
    974           // reset inertia tensor
    975     for(int i=0;i<NDIM*NDIM;i++)
    976       InertiaTensor[i] = 0.;
    977 
    978     // sum up inertia tensor
    979     ptr = start;
    980     while (ptr->next != end) {
    981       ptr = ptr->next;
    982       Vector x;
    983       x.CopyVector(&ptr->x);
    984       //x.SubtractVector(CenterOfGravity);
    985       InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    986       InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    987       InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    988       InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    989       InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    990       InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    991       InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    992       InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    993       InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    994     }
    995     // print InertiaTensor for debugging
    996     *out << "The inertia tensor is:" << endl;
    997     for(int i=0;i<NDIM;i++) {
    998       for(int j=0;j<NDIM;j++)
    999         *out << InertiaTensor[i*NDIM+j] << " ";
    1000       *out << endl;
    1001     }
    1002     *out << endl;
     962                *out << Verbose(1) << "Transforming molecule into PAS ... ";
     963                // the eigenvectors specify the transformation matrix
     964                ptr = start;
     965                while (ptr->next != end) {
     966                        ptr = ptr->next;
     967                        for (int j=0;j<MDSteps;j++)
     968                                Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
     969                        ptr->x.MatrixMultiplication(evec->data);
     970                }
     971                *out << "done." << endl;
     972
     973                // summing anew for debugging (resulting matrix has to be diagonal!)
     974                // reset inertia tensor
     975                for(int i=0;i<NDIM*NDIM;i++)
     976                        InertiaTensor[i] = 0.;
     977
     978                // sum up inertia tensor
     979                ptr = start;
     980                while (ptr->next != end) {
     981                        ptr = ptr->next;
     982                        Vector x;
     983                        x.CopyVector(&ptr->x);
     984                        //x.SubtractVector(CenterOfGravity);
     985                        InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     986                        InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     987                        InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     988                        InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     989                        InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     990                        InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     991                        InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     992                        InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     993                        InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     994                }
     995                // print InertiaTensor for debugging
     996                *out << "The inertia tensor is:" << endl;
     997                for(int i=0;i<NDIM;i++) {
     998                        for(int j=0;j<NDIM;j++)
     999                                *out << InertiaTensor[i*NDIM+j] << " ";
     1000                        *out << endl;
     1001                }
     1002                *out << endl;
    10031003        }
    10041004
     
    10201020bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
    10211021{
    1022   element *runner = elemente->start;
    1023   atom *walker = NULL;
    1024   int AtomNo;
    1025   ifstream input(file);
    1026   string token;
    1027   stringstream item;
    1028   double a, IonMass;
    1029   ForceMatrix Force;
    1030   Vector tmpvector;
    1031 
    1032   CountElements();  // make sure ElementsInMolecule is up to date
    1033 
    1034   // check file
    1035   if (input == NULL) {
    1036     return false;
    1037   } else {
    1038     // parse file into ForceMatrix
    1039     if (!Force.ParseMatrix(file, 0,0,0)) {
    1040       cerr << "Could not parse Force Matrix file " << file << "." << endl;
    1041       return false;
    1042     }
    1043     if (Force.RowCounter[0] != AtomCount) {
    1044       cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
    1045       return false;
    1046     }
    1047     // correct Forces
    1048 //    for(int d=0;d<NDIM;d++)
    1049 //      tmpvector.x[d] = 0.;
    1050 //    for(int i=0;i<AtomCount;i++)
    1051 //      for(int d=0;d<NDIM;d++) {
    1052 //        tmpvector.x[d] += Force.Matrix[0][i][d+5];
    1053 //      }
    1054 //    for(int i=0;i<AtomCount;i++)
    1055 //      for(int d=0;d<NDIM;d++) {
    1056 //        Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
    1057 //      }
    1058     // and perform Verlet integration for each atom with position, velocity and force vector
    1059     runner = elemente->start;
    1060     while (runner->next != elemente->end) { // go through every element
    1061       runner = runner->next;
    1062       IonMass = runner->mass;
    1063       a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1064       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1065         AtomNo = 0;
    1066         walker = start;
    1067         while (walker->next != end) { // go through every atom of this element
    1068           walker = walker->next;
    1069           if (walker->type == runner) { // if this atom fits to element
    1070             // check size of vectors
    1071             if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1072               //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1073               Trajectories[walker].R.resize(MDSteps+10);
    1074               Trajectories[walker].U.resize(MDSteps+10);
    1075               Trajectories[walker].F.resize(MDSteps+10);
    1076             }
    1077             // 1. calculate x(t+\delta t)
    1078             for (int d=0; d<NDIM; d++) {
    1079               Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
    1080               Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1081               Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
    1082               Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass;     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    1083             }
    1084             // 2. Calculate v(t+\delta t)
    1085             for (int d=0; d<NDIM; d++) {
    1086               Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1087               Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
    1088             }
    1089 //            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1090 //            for (int d=0;d<NDIM;d++)
    1091 //              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
    1092 //            cout << ")\t(";
    1093 //            for (int d=0;d<NDIM;d++)
    1094 //              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
    1095 //            cout << ")" << endl;
    1096             // next atom
    1097             AtomNo++;
    1098           }
    1099         }
    1100       }
    1101     }
    1102   }
    1103 //  // correct velocities (rather momenta) so that center of mass remains motionless
    1104 //  tmpvector.zero()
    1105 //  IonMass = 0.;
    1106 //  walker = start;
    1107 //  while (walker->next != end) { // go through every atom
    1108 //    walker = walker->next;
    1109 //    IonMass += walker->type->mass;  // sum up total mass
    1110 //    for(int d=0;d<NDIM;d++) {
    1111 //      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1112 //    }
    1113 //  }
    1114 //  walker = start;
    1115 //  while (walker->next != end) { // go through every atom of this element
    1116 //    walker = walker->next;
    1117 //    for(int d=0;d<NDIM;d++) {
    1118 //      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
    1119 //    }
    1120 //  }
    1121   MDSteps++;
    1122 
    1123 
    1124   // exit
    1125   return true;
     1022        element *runner = elemente->start;
     1023        atom *walker = NULL;
     1024        int AtomNo;
     1025        ifstream input(file);
     1026        string token;
     1027        stringstream item;
     1028        double a, IonMass;
     1029        ForceMatrix Force;
     1030        Vector tmpvector;
     1031
     1032        CountElements();        // make sure ElementsInMolecule is up to date
     1033
     1034        // check file
     1035        if (input == NULL) {
     1036                return false;
     1037        } else {
     1038                // parse file into ForceMatrix
     1039                if (!Force.ParseMatrix(file, 0,0,0)) {
     1040                        cerr << "Could not parse Force Matrix file " << file << "." << endl;
     1041                        return false;
     1042                }
     1043                if (Force.RowCounter[0] != AtomCount) {
     1044                        cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
     1045                        return false;
     1046                }
     1047                // correct Forces
     1048//              for(int d=0;d<NDIM;d++)
     1049//                      tmpvector.x[d] = 0.;
     1050//              for(int i=0;i<AtomCount;i++)
     1051//                      for(int d=0;d<NDIM;d++) {
     1052//                              tmpvector.x[d] += Force.Matrix[0][i][d+5];
     1053//                      }
     1054//              for(int i=0;i<AtomCount;i++)
     1055//                      for(int d=0;d<NDIM;d++) {
     1056//                              Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
     1057//                      }
     1058                // and perform Verlet integration for each atom with position, velocity and force vector
     1059                runner = elemente->start;
     1060                while (runner->next != elemente->end) { // go through every element
     1061                        runner = runner->next;
     1062                        IonMass = runner->mass;
     1063                        a = delta_t*0.5/IonMass;                                // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1064                        if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1065                                AtomNo = 0;
     1066                                walker = start;
     1067                                while (walker->next != end) { // go through every atom of this element
     1068                                        walker = walker->next;
     1069                                        if (walker->type == runner) { // if this atom fits to element
     1070                                                // check size of vectors
     1071                                                if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1072                                                        //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1073                                                        Trajectories[walker].R.resize(MDSteps+10);
     1074                                                        Trajectories[walker].U.resize(MDSteps+10);
     1075                                                        Trajectories[walker].F.resize(MDSteps+10);
     1076                                                }
     1077                                                // 1. calculate x(t+\delta t)
     1078                                                for (int d=0; d<NDIM; d++) {
     1079                                                        Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
     1080                                                        Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1081                                                        Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1082                                                        Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass;             // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
     1083                                                }
     1084                                                // 2. Calculate v(t+\delta t)
     1085                                                for (int d=0; d<NDIM; d++) {
     1086                                                        Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1087                                                        Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
     1088                                                }
     1089//                                              cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1090//                                              for (int d=0;d<NDIM;d++)
     1091//                                                      cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";                                 // next step
     1092//                                              cout << ")\t(";
     1093//                                              for (int d=0;d<NDIM;d++)
     1094//                                                      cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";                                 // next step
     1095//                                              cout << ")" << endl;
     1096                                                // next atom
     1097                                                AtomNo++;
     1098                                        }
     1099                                }
     1100                        }
     1101                }
     1102        }
     1103//      // correct velocities (rather momenta) so that center of mass remains motionless
     1104//      tmpvector.zero()
     1105//      IonMass = 0.;
     1106//      walker = start;
     1107//      while (walker->next != end) { // go through every atom
     1108//              walker = walker->next;
     1109//              IonMass += walker->type->mass;  // sum up total mass
     1110//              for(int d=0;d<NDIM;d++) {
     1111//                      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1112//              }
     1113//      }
     1114//      walker = start;
     1115//      while (walker->next != end) { // go through every atom of this element
     1116//              walker = walker->next;
     1117//              for(int d=0;d<NDIM;d++) {
     1118//                      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
     1119//              }
     1120//      }
     1121        MDSteps++;
     1122
     1123
     1124        // exit
     1125        return true;
    11261126};
    11271127
     
    11311131void molecule::Align(Vector *n)
    11321132{
    1133   atom *ptr = start;
    1134   double alpha, tmp;
    1135   Vector z_axis;
    1136   z_axis.x[0] = 0.;
    1137   z_axis.x[1] = 0.;
    1138   z_axis.x[2] = 1.;
    1139 
    1140   // rotate on z-x plane
    1141   cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
    1142   alpha = atan(-n->x[0]/n->x[2]);
    1143   cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
    1144   while (ptr->next != end) {
    1145     ptr = ptr->next;
    1146     tmp = ptr->x.x[0];
    1147     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1148     ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1149     for (int j=0;j<MDSteps;j++) {
    1150       tmp = Trajectories[ptr].R.at(j).x[0];
    1151       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1152       Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1153     }
    1154   }
    1155   // rotate n vector
    1156   tmp = n->x[0];
    1157   n->x[0] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    1158   n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1159   cout << Verbose(1) << "alignment vector after first rotation: ";
    1160   n->Output((ofstream *)&cout);
    1161   cout << endl;
    1162 
    1163   // rotate on z-y plane
    1164   ptr = start;
    1165   alpha = atan(-n->x[1]/n->x[2]);
    1166   cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
    1167   while (ptr->next != end) {
    1168     ptr = ptr->next;
    1169     tmp = ptr->x.x[1];
    1170     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1171     ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1172     for (int j=0;j<MDSteps;j++) {
    1173       tmp = Trajectories[ptr].R.at(j).x[1];
    1174       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1175       Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1176     }
    1177   }
    1178   // rotate n vector (for consistency check)
    1179   tmp = n->x[1];
    1180   n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    1181   n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1182 
    1183   cout << Verbose(1) << "alignment vector after second rotation: ";
    1184   n->Output((ofstream *)&cout);
    1185   cout << Verbose(1) << endl;
    1186   cout << Verbose(0) << "End of Aligning all atoms." << endl;
     1133        atom *ptr = start;
     1134        double alpha, tmp;
     1135        Vector z_axis;
     1136        z_axis.x[0] = 0.;
     1137        z_axis.x[1] = 0.;
     1138        z_axis.x[2] = 1.;
     1139
     1140        // rotate on z-x plane
     1141        cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
     1142        alpha = atan(-n->x[0]/n->x[2]);
     1143        cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
     1144        while (ptr->next != end) {
     1145                ptr = ptr->next;
     1146                tmp = ptr->x.x[0];
     1147                ptr->x.x[0] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1148                ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1149                for (int j=0;j<MDSteps;j++) {
     1150                        tmp = Trajectories[ptr].R.at(j).x[0];
     1151                        Trajectories[ptr].R.at(j).x[0] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1152                        Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1153                }
     1154        }
     1155        // rotate n vector
     1156        tmp = n->x[0];
     1157        n->x[0] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
     1158        n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
     1159        cout << Verbose(1) << "alignment vector after first rotation: ";
     1160        n->Output((ofstream *)&cout);
     1161        cout << endl;
     1162
     1163        // rotate on z-y plane
     1164        ptr = start;
     1165        alpha = atan(-n->x[1]/n->x[2]);
     1166        cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
     1167        while (ptr->next != end) {
     1168                ptr = ptr->next;
     1169                tmp = ptr->x.x[1];
     1170                ptr->x.x[1] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1171                ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1172                for (int j=0;j<MDSteps;j++) {
     1173                        tmp = Trajectories[ptr].R.at(j).x[1];
     1174                        Trajectories[ptr].R.at(j).x[1] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1175                        Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1176                }
     1177        }
     1178        // rotate n vector (for consistency check)
     1179        tmp = n->x[1];
     1180        n->x[1] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
     1181        n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
     1182
     1183        cout << Verbose(1) << "alignment vector after second rotation: ";
     1184        n->Output((ofstream *)&cout);
     1185        cout << Verbose(1) << endl;
     1186        cout << Verbose(0) << "End of Aligning all atoms." << endl;
    11871187};
    11881188
     
    11931193bool molecule::RemoveAtom(atom *pointer)
    11941194{
    1195   if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    1196     ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    1197   else
    1198     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    1199   if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    1200     ElementCount--;
    1201   Trajectories.erase(pointer);
    1202   return remove(pointer, start, end);
     1195        if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1196                ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element
     1197        else
     1198                cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1199        if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     1200                ElementCount--;
     1201        Trajectories.erase(pointer);
     1202        return remove(pointer, start, end);
    12031203};
    12041204
     
    12081208bool molecule::CleanupMolecule()
    12091209{
    1210   return (cleanup(start,end) && cleanup(first,last));
     1210        return (cleanup(start,end) && cleanup(first,last));
    12111211};
    12121212
     
    12151215 * \return pointer to atom or NULL
    12161216 */
    1217 atom * molecule::FindAtom(int Nr)  const{
    1218   atom * walker = find(&Nr, start,end);
    1219   if (walker != NULL) {
    1220     //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
    1221     return walker;
    1222   } else {
    1223     cout << Verbose(0) << "Atom not found in list." << endl;
    1224     return NULL;
    1225   }
     1217atom * molecule::FindAtom(int Nr)       const{
     1218        atom * walker = find(&Nr, start,end);
     1219        if (walker != NULL) {
     1220                //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
     1221                return walker;
     1222        } else {
     1223                cout << Verbose(0) << "Atom not found in list." << endl;
     1224                return NULL;
     1225        }
    12261226};
    12271227
     
    12311231atom * molecule::AskAtom(string text)
    12321232{
    1233   int No;
    1234   atom *ion = NULL;
    1235   do {
    1236     //cout << Verbose(0) << "============Atom list==========================" << endl;
    1237     //mol->Output((ofstream *)&cout);
    1238     //cout << Verbose(0) << "===============================================" << endl;
    1239     cout << Verbose(0) << text;
    1240     cin >> No;
    1241     ion = this->FindAtom(No);
    1242   } while (ion == NULL);
    1243   return ion;
     1233        int No;
     1234        atom *ion = NULL;
     1235        do {
     1236                //cout << Verbose(0) << "============Atom list==========================" << endl;
     1237                //mol->Output((ofstream *)&cout);
     1238                //cout << Verbose(0) << "===============================================" << endl;
     1239                cout << Verbose(0) << text;
     1240                cin >> No;
     1241                ion = this->FindAtom(No);
     1242        } while (ion == NULL);
     1243        return ion;
    12441244};
    12451245
     
    12501250bool molecule::CheckBounds(const Vector *x) const
    12511251{
    1252   bool result = true;
    1253   int j =-1;
    1254   for (int i=0;i<NDIM;i++) {
    1255     j += i+1;
    1256     result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
    1257   }
    1258   //return result;
    1259   return true; /// probably not gonna use the check no more
     1252        bool result = true;
     1253        int j =-1;
     1254        for (int i=0;i<NDIM;i++) {
     1255                j += i+1;
     1256                result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
     1257        }
     1258        //return result;
     1259        return true; /// probably not gonna use the check no more
    12601260};
    12611261
     
    12671267double LeastSquareDistance (const gsl_vector * x, void * params)
    12681268{
    1269   double res = 0, t;
    1270   Vector a,b,c,d;
    1271   struct lsq_params *par = (struct lsq_params *)params;
    1272   atom *ptr = par->mol->start;
    1273 
    1274   // initialize vectors
    1275   a.x[0] = gsl_vector_get(x,0);
    1276   a.x[1] = gsl_vector_get(x,1);
    1277   a.x[2] = gsl_vector_get(x,2);
    1278   b.x[0] = gsl_vector_get(x,3);
    1279   b.x[1] = gsl_vector_get(x,4);
    1280   b.x[2] = gsl_vector_get(x,5);
    1281   // go through all atoms
    1282   while (ptr != par->mol->end) {
    1283     ptr = ptr->next;
    1284     if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
    1285       c.CopyVector(&ptr->x);  // copy vector to temporary one
    1286       c.SubtractVector(&a);  // subtract offset vector
    1287       t = c.ScalarProduct(&b);          // get direction parameter
    1288       d.CopyVector(&b);      // and create vector
    1289       d.Scale(&t);
    1290       c.SubtractVector(&d);  // ... yielding distance vector
    1291       res += d.ScalarProduct((const Vector *)&d);        // add squared distance
    1292     }
    1293   }
    1294   return res;
     1269        double res = 0, t;
     1270        Vector a,b,c,d;
     1271        struct lsq_params *par = (struct lsq_params *)params;
     1272        atom *ptr = par->mol->start;
     1273
     1274        // initialize vectors
     1275        a.x[0] = gsl_vector_get(x,0);
     1276        a.x[1] = gsl_vector_get(x,1);
     1277        a.x[2] = gsl_vector_get(x,2);
     1278        b.x[0] = gsl_vector_get(x,3);
     1279        b.x[1] = gsl_vector_get(x,4);
     1280        b.x[2] = gsl_vector_get(x,5);
     1281        // go through all atoms
     1282        while (ptr != par->mol->end) {
     1283                ptr = ptr->next;
     1284                if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
     1285                        c.CopyVector(&ptr->x);  // copy vector to temporary one
     1286                        c.SubtractVector(&a);    // subtract offset vector
     1287                        t = c.ScalarProduct(&b);                                        // get direction parameter
     1288                        d.CopyVector(&b);                        // and create vector
     1289                        d.Scale(&t);
     1290                        c.SubtractVector(&d);    // ... yielding distance vector
     1291                        res += d.ScalarProduct((const Vector *)&d);                             // add squared distance
     1292                }
     1293        }
     1294        return res;
    12951295};
    12961296
     
    13001300void molecule::GetAlignvector(struct lsq_params * par) const
    13011301{
    1302     int np = 6;
    1303 
    1304   const gsl_multimin_fminimizer_type *T =
    1305     gsl_multimin_fminimizer_nmsimplex;
    1306   gsl_multimin_fminimizer *s = NULL;
    1307   gsl_vector *ss;
    1308   gsl_multimin_function minex_func;
    1309 
    1310   size_t iter = 0, i;
    1311   int status;
    1312   double size;
    1313 
    1314   /* Initial vertex size vector */
    1315   ss = gsl_vector_alloc (np);
    1316 
    1317   /* Set all step sizes to 1 */
    1318   gsl_vector_set_all (ss, 1.0);
    1319 
    1320   /* Starting point */
    1321   par->x = gsl_vector_alloc (np);
    1322   par->mol = this;
    1323 
    1324    gsl_vector_set (par->x, 0, 0.0);  // offset
    1325   gsl_vector_set (par->x, 1, 0.0);
    1326   gsl_vector_set (par->x, 2, 0.0);
    1327    gsl_vector_set (par->x, 3, 0.0);  // direction
    1328   gsl_vector_set (par->x, 4, 0.0);
    1329   gsl_vector_set (par->x, 5, 1.0);
    1330 
    1331   /* Initialize method and iterate */
    1332   minex_func.f = &LeastSquareDistance;
    1333   minex_func.n = np;
    1334   minex_func.params = (void *)par;
    1335 
    1336   s = gsl_multimin_fminimizer_alloc (T, np);
    1337   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1338 
    1339   do
    1340     {
    1341       iter++;
    1342       status = gsl_multimin_fminimizer_iterate(s);
    1343 
    1344       if (status)
    1345         break;
    1346 
    1347       size = gsl_multimin_fminimizer_size (s);
    1348       status = gsl_multimin_test_size (size, 1e-2);
    1349 
    1350       if (status == GSL_SUCCESS)
    1351         {
    1352           printf ("converged to minimum at\n");
    1353         }
    1354 
    1355       printf ("%5d ", (int)iter);
    1356       for (i = 0; i < (size_t)np; i++)
    1357         {
    1358           printf ("%10.3e ", gsl_vector_get (s->x, i));
    1359         }
    1360       printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    1361     }
    1362   while (status == GSL_CONTINUE && iter < 100);
    1363 
    1364   for (i=0;i<(size_t)np;i++)
    1365     gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
    1366   //gsl_vector_free(par->x);
    1367   gsl_vector_free(ss);
    1368   gsl_multimin_fminimizer_free (s);
     1302                int np = 6;
     1303
     1304        const gsl_multimin_fminimizer_type *T =
     1305                gsl_multimin_fminimizer_nmsimplex;
     1306        gsl_multimin_fminimizer *s = NULL;
     1307        gsl_vector *ss;
     1308        gsl_multimin_function minex_func;
     1309
     1310        size_t iter = 0, i;
     1311        int status;
     1312        double size;
     1313
     1314        /* Initial vertex size vector */
     1315        ss = gsl_vector_alloc (np);
     1316
     1317        /* Set all step sizes to 1 */
     1318        gsl_vector_set_all (ss, 1.0);
     1319
     1320        /* Starting point */
     1321        par->x = gsl_vector_alloc (np);
     1322        par->mol = this;
     1323
     1324         gsl_vector_set (par->x, 0, 0.0);       // offset
     1325        gsl_vector_set (par->x, 1, 0.0);
     1326        gsl_vector_set (par->x, 2, 0.0);
     1327         gsl_vector_set (par->x, 3, 0.0);       // direction
     1328        gsl_vector_set (par->x, 4, 0.0);
     1329        gsl_vector_set (par->x, 5, 1.0);
     1330
     1331        /* Initialize method and iterate */
     1332        minex_func.f = &LeastSquareDistance;
     1333        minex_func.n = np;
     1334        minex_func.params = (void *)par;
     1335
     1336        s = gsl_multimin_fminimizer_alloc (T, np);
     1337        gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
     1338
     1339        do
     1340                {
     1341                        iter++;
     1342                        status = gsl_multimin_fminimizer_iterate(s);
     1343
     1344                        if (status)
     1345                                break;
     1346
     1347                        size = gsl_multimin_fminimizer_size (s);
     1348                        status = gsl_multimin_test_size (size, 1e-2);
     1349
     1350                        if (status == GSL_SUCCESS)
     1351                                {
     1352                                        printf ("converged to minimum at\n");
     1353                                }
     1354
     1355                        printf ("%5d ", (int)iter);
     1356                        for (i = 0; i < (size_t)np; i++)
     1357                                {
     1358                                        printf ("%10.3e ", gsl_vector_get (s->x, i));
     1359                                }
     1360                        printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     1361                }
     1362        while (status == GSL_CONTINUE && iter < 100);
     1363
     1364        for (i=0;i<(size_t)np;i++)
     1365                gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     1366        //gsl_vector_free(par->x);
     1367        gsl_vector_free(ss);
     1368        gsl_multimin_fminimizer_free (s);
    13691369};
    13701370
     
    13741374bool molecule::Output(ofstream *out)
    13751375{
    1376   element *runner;
    1377   atom *walker = NULL;
    1378   int ElementNo, AtomNo;
    1379   CountElements();
    1380 
    1381   if (out == NULL) {
    1382     return false;
    1383   } else {
    1384     *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1385     ElementNo = 0;
    1386     runner = elemente->start;
    1387     while (runner->next != elemente->end) { // go through every element
    1388                 runner = runner->next;
    1389       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1390         ElementNo++;
    1391         AtomNo = 0;
    1392         walker = start;
    1393         while (walker->next != end) { // go through every atom of this element
    1394           walker = walker->next;
    1395           if (walker->type == runner) { // if this atom fits to element
    1396             AtomNo++;
    1397             walker->Output(ElementNo, AtomNo, out); // removed due to trajectories
    1398           }
    1399         }
    1400       }
    1401     }
    1402     return true;
    1403   }
     1376        element *runner;
     1377        atom *walker = NULL;
     1378        int ElementNo, AtomNo;
     1379        CountElements();
     1380
     1381        if (out == NULL) {
     1382                return false;
     1383        } else {
     1384                *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1385                ElementNo = 0;
     1386                runner = elemente->start;
     1387                while (runner->next != elemente->end) { // go through every element
     1388                        runner = runner->next;
     1389                        if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1390                                ElementNo++;
     1391                                AtomNo = 0;
     1392                                walker = start;
     1393                                while (walker->next != end) { // go through every atom of this element
     1394                                        walker = walker->next;
     1395                                        if (walker->type == runner) { // if this atom fits to element
     1396                                                AtomNo++;
     1397                                                walker->Output(ElementNo, AtomNo, out); // removed due to trajectories
     1398                                        }
     1399                                }
     1400                        }
     1401                }
     1402                return true;
     1403        }
    14041404};
    14051405
     
    14091409bool molecule::OutputTrajectories(ofstream *out)
    14101410{
    1411   element *runner = NULL;
    1412   atom *walker = NULL;
    1413   int ElementNo, AtomNo;
    1414   CountElements();
    1415 
    1416   if (out == NULL) {
    1417     return false;
    1418   } else {
    1419     for (int step = 0; step < MDSteps; step++) {
    1420       if (step == 0) {
    1421         *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1422       } else {
    1423         *out << "# ====== MD step " << step << " =========" << endl;
    1424       }
    1425       ElementNo = 0;
    1426       runner = elemente->start;
    1427       while (runner->next != elemente->end) { // go through every element
    1428         runner = runner->next;
    1429         if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1430           ElementNo++;
    1431           AtomNo = 0;
    1432           walker = start;
    1433           while (walker->next != end) { // go through every atom of this element
    1434             walker = walker->next;
    1435             if (walker->type == runner) { // if this atom fits to element
    1436               AtomNo++;
    1437               *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"  << fixed << setprecision(9) << showpoint;
    1438               *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
    1439               *out << "\t" << walker->FixedIon;
    1440               if (Trajectories[walker].U.at(step).Norm() > MYEPSILON)
    1441                 *out << "\t" << scientific << setprecision(6) << Trajectories[walker].U.at(step).x[0] << "\t" << Trajectories[walker].U.at(step).x[1] << "\t" << Trajectories[walker].U.at(step).x[2] << "\t";
    1442               if (Trajectories[walker].F.at(step).Norm() > MYEPSILON)
    1443                 *out << "\t" << scientific << setprecision(6) << Trajectories[walker].F.at(step).x[0] << "\t" << Trajectories[walker].F.at(step).x[1] << "\t" << Trajectories[walker].F.at(step).x[2] << "\t";
    1444               *out << "\t# Number in molecule " << walker->nr << endl;
    1445             }
    1446           }
    1447         }
    1448       }
    1449     }
    1450     return true;
    1451   }
     1411        element *runner = NULL;
     1412        atom *walker = NULL;
     1413        int ElementNo, AtomNo;
     1414        CountElements();
     1415
     1416        if (out == NULL) {
     1417                return false;
     1418        } else {
     1419                for (int step = 0; step < MDSteps; step++) {
     1420                        if (step == 0) {
     1421                                *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1422                        } else {
     1423                                *out << "# ====== MD step " << step << " =========" << endl;
     1424                        }
     1425                        ElementNo = 0;
     1426                        runner = elemente->start;
     1427                        while (runner->next != elemente->end) { // go through every element
     1428                                runner = runner->next;
     1429                                if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1430                                        ElementNo++;
     1431                                        AtomNo = 0;
     1432                                        walker = start;
     1433                                        while (walker->next != end) { // go through every atom of this element
     1434                                                walker = walker->next;
     1435                                                if (walker->type == runner) { // if this atom fits to element
     1436                                                        AtomNo++;
     1437                                                        *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"        << fixed << setprecision(9) << showpoint;
     1438                                                        *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
     1439                                                        *out << "\t" << walker->FixedIon;
     1440                                                        if (Trajectories[walker].U.at(step).Norm() > MYEPSILON)
     1441                                                                *out << "\t" << scientific << setprecision(6) << Trajectories[walker].U.at(step).x[0] << "\t" << Trajectories[walker].U.at(step).x[1] << "\t" << Trajectories[walker].U.at(step).x[2] << "\t";
     1442                                                        if (Trajectories[walker].F.at(step).Norm() > MYEPSILON)
     1443                                                                *out << "\t" << scientific << setprecision(6) << Trajectories[walker].F.at(step).x[0] << "\t" << Trajectories[walker].F.at(step).x[1] << "\t" << Trajectories[walker].F.at(step).x[2] << "\t";
     1444                                                        *out << "\t# Number in molecule " << walker->nr << endl;
     1445                                                }
     1446                                        }
     1447                                }
     1448                        }
     1449                }
     1450                return true;
     1451        }
    14521452};
    14531453
     
    14571457void molecule::OutputListOfBonds(ofstream *out) const
    14581458{
    1459   *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    1460   atom *Walker = start;
    1461   while (Walker->next != end) {
    1462     Walker = Walker->next;
     1459        *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
     1460        atom *Walker = start;
     1461        while (Walker->next != end) {
     1462                Walker = Walker->next;
    14631463#ifdef ADDHYDROGEN
    1464     if (Walker->type->Z != 1) {  // regard only non-hydrogen
     1464                if (Walker->type->Z != 1) {      // regard only non-hydrogen
    14651465#endif
    1466       *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
    1467       for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    1468         *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
    1469       }
     1466                        *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
     1467                        for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     1468                                *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
     1469                        }
    14701470#ifdef ADDHYDROGEN
    1471     }
     1471                }
    14721472#endif
    1473   }
    1474   *out << endl;
     1473        }
     1474        *out << endl;
    14751475};
    14761476
     
    14781478 * \param *out stream pointer
    14791479 */
    1480 bool molecule::Checkout(ofstream *out)  const
     1480bool molecule::Checkout(ofstream *out)  const
    14811481{
    14821482        return elemente->Checkout(out, ElementsInMolecule);
     
    14881488bool molecule::OutputTrajectoriesXYZ(ofstream *out)
    14891489{
    1490   atom *walker = NULL;
    1491   int No = 0;
    1492   time_t now;
    1493 
    1494   now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
    1495   walker = start;
    1496   while (walker->next != end) { // go through every atom and count
    1497     walker = walker->next;
    1498     No++;
    1499   }
    1500   if (out != NULL) {
    1501     for (int step=0;step<MDSteps;step++) {
    1502       *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
    1503       walker = start;
    1504       while (walker->next != end) { // go through every atom of this element
    1505         walker = walker->next;
    1506         *out << walker->type->symbol << "\t" << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2] << endl;
    1507       }
    1508     }
    1509     return true;
    1510   } else
    1511     return false;
     1490        atom *walker = NULL;
     1491        int No = 0;
     1492        time_t now;
     1493
     1494        now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
     1495        walker = start;
     1496        while (walker->next != end) { // go through every atom and count
     1497                walker = walker->next;
     1498                No++;
     1499        }
     1500        if (out != NULL) {
     1501                for (int step=0;step<MDSteps;step++) {
     1502                        *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     1503                        walker = start;
     1504                        while (walker->next != end) { // go through every atom of this element
     1505                                walker = walker->next;
     1506                                *out << walker->type->symbol << "\t" << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2] << endl;
     1507                        }
     1508                }
     1509                return true;
     1510        } else
     1511                return false;
    15121512};
    15131513
     
    15171517bool molecule::OutputXYZ(ofstream *out) const
    15181518{
    1519   atom *walker = NULL;
    1520   int AtomNo = 0, ElementNo;
    1521   time_t now;
    1522   element *runner = NULL;
    1523 
    1524   now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
    1525   walker = start;
    1526   while (walker->next != end) { // go through every atom and count
    1527     walker = walker->next;
    1528     AtomNo++;
    1529   }
    1530   if (out != NULL) {
    1531     *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    1532     ElementNo = 0;
    1533     runner = elemente->start;
    1534     while (runner->next != elemente->end) { // go through every element
    1535                 runner = runner->next;
    1536       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1537         ElementNo++;
    1538         walker = start;
    1539         while (walker->next != end) { // go through every atom of this element
    1540           walker = walker->next;
    1541           if (walker->type == runner) { // if this atom fits to element
    1542             walker->OutputXYZLine(out);
    1543           }
    1544         }
    1545       }
    1546     }
    1547     return true;
    1548   } else
    1549     return false;
     1519        atom *walker = NULL;
     1520        int AtomNo = 0, ElementNo;
     1521        time_t now;
     1522        element *runner = NULL;
     1523
     1524        now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
     1525        walker = start;
     1526        while (walker->next != end) { // go through every atom and count
     1527                walker = walker->next;
     1528                AtomNo++;
     1529        }
     1530        if (out != NULL) {
     1531                *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
     1532                ElementNo = 0;
     1533                runner = elemente->start;
     1534                while (runner->next != elemente->end) { // go through every element
     1535                        runner = runner->next;
     1536                        if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1537                                ElementNo++;
     1538                                walker = start;
     1539                                while (walker->next != end) { // go through every atom of this element
     1540                                        walker = walker->next;
     1541                                        if (walker->type == runner) { // if this atom fits to element
     1542                                                walker->OutputXYZLine(out);
     1543                                        }
     1544                                }
     1545                        }
     1546                }
     1547                return true;
     1548        } else
     1549                return false;
    15501550};
    15511551
     
    15571557        int i = 0;
    15581558        atom *Walker = start;
    1559   while (Walker->next != end) {
    1560     Walker = Walker->next;
    1561     i++;
    1562   }
    1563   if ((AtomCount == 0) || (i != AtomCount)) {
    1564     *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
    1565         AtomCount = i;
    1566 
    1567     // count NonHydrogen atoms and give each atom a unique name
    1568     if (AtomCount != 0) {
    1569             i=0;
    1570             NoNonHydrogen = 0;
    1571       Walker = start;
    1572             while (Walker->next != end) {
    1573               Walker = Walker->next;
    1574               Walker->nr = i;  // update number in molecule (for easier referencing in FragmentMolecule lateron)
    1575               if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1576                 NoNonHydrogen++;
    1577               Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    1578               Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
    1579               sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
    1580         *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
    1581               i++;
    1582             }
    1583     } else
    1584         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    1585   }
     1559        while (Walker->next != end) {
     1560                Walker = Walker->next;
     1561                i++;
     1562        }
     1563        if ((AtomCount == 0) || (i != AtomCount)) {
     1564                *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
     1565                AtomCount = i;
     1566
     1567                // count NonHydrogen atoms and give each atom a unique name
     1568                if (AtomCount != 0) {
     1569                        i=0;
     1570                        NoNonHydrogen = 0;
     1571                        Walker = start;
     1572                        while (Walker->next != end) {
     1573                                Walker = Walker->next;
     1574                                Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron)
     1575                                if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
     1576                                        NoNonHydrogen++;
     1577                                Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
     1578                                Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     1579                                sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
     1580                                *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
     1581                                i++;
     1582                        }
     1583                } else
     1584                        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     1585        }
    15861586};
    15871587
     
    15911591{
    15921592        int i = 0;
    1593   for(i=MAX_ELEMENTS;i--;)
    1594         ElementsInMolecule[i] = 0;
     1593        for(i=MAX_ELEMENTS;i--;)
     1594                ElementsInMolecule[i] = 0;
    15951595        ElementCount = 0;
    15961596
    1597   atom *walker = start;
    1598   while (walker->next != end) {
    1599     walker = walker->next;
    1600     ElementsInMolecule[walker->type->Z]++;
    1601     i++;
    1602   }
    1603   for(i=MAX_ELEMENTS;i--;)
    1604         ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
     1597        atom *walker = start;
     1598        while (walker->next != end) {
     1599                walker = walker->next;
     1600                ElementsInMolecule[walker->type->Z]++;
     1601                i++;
     1602        }
     1603        for(i=MAX_ELEMENTS;i--;)
     1604                ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
    16051605};
    16061606
     
    16121612int molecule::CountCyclicBonds(ofstream *out)
    16131613{
    1614   int No = 0;
    1615   int *MinimumRingSize = NULL;
    1616   MoleculeLeafClass *Subgraphs = NULL;
    1617   class StackClass<bond *> *BackEdgeStack = NULL;
    1618   bond *Binder = first;
    1619   if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
    1620     *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
    1621     Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    1622     while (Subgraphs->next != NULL) {
    1623       Subgraphs = Subgraphs->next;
    1624       delete(Subgraphs->previous);
    1625     }
    1626     delete(Subgraphs);
    1627     delete[](MinimumRingSize);
    1628   }
    1629   while(Binder->next != last) {
    1630     Binder = Binder->next;
    1631     if (Binder->Cyclic)
    1632       No++;
    1633   }
    1634   delete(BackEdgeStack);
    1635   return No;
     1614        int No = 0;
     1615        int *MinimumRingSize = NULL;
     1616        MoleculeLeafClass *Subgraphs = NULL;
     1617        class StackClass<bond *> *BackEdgeStack = NULL;
     1618        bond *Binder = first;
     1619        if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
     1620                *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
     1621                Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     1622                while (Subgraphs->next != NULL) {
     1623                        Subgraphs = Subgraphs->next;
     1624                        delete(Subgraphs->previous);
     1625                }
     1626                delete(Subgraphs);
     1627                delete[](MinimumRingSize);
     1628        }
     1629        while(Binder->next != last) {
     1630                Binder = Binder->next;
     1631                if (Binder->Cyclic)
     1632                        No++;
     1633        }
     1634        delete(BackEdgeStack);
     1635        return No;
    16361636};
    16371637/** Returns Shading as a char string.
     
    16411641string molecule::GetColor(enum Shading color)
    16421642{
    1643   switch(color) {
    1644     case white:
    1645       return "white";
    1646       break;
    1647     case lightgray:
    1648       return "lightgray";
    1649       break;
    1650     case darkgray:
    1651       return "darkgray";
    1652       break;
    1653     case black:
    1654       return "black";
    1655       break;
    1656     default:
    1657       return "uncolored";
    1658       break;
    1659   };
     1643        switch(color) {
     1644                case white:
     1645                        return "white";
     1646                        break;
     1647                case lightgray:
     1648                        return "lightgray";
     1649                        break;
     1650                case darkgray:
     1651                        return "darkgray";
     1652                        break;
     1653                case black:
     1654                        return "black";
     1655                        break;
     1656                default:
     1657                        return "uncolored";
     1658                        break;
     1659        };
    16601660};
    16611661
     
    16661666void molecule::CalculateOrbitals(class config &configuration)
    16671667{
    1668   configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
    1669   for(int i=MAX_ELEMENTS;i--;) {
    1670     if (ElementsInMolecule[i] != 0) {
    1671       //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
    1672       configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
    1673     }
    1674   }
    1675   configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
    1676   configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
    1677   configuration.MaxPsiDouble /= 2;
    1678   configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
    1679   if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
    1680     configuration.ProcPEGamma /= 2;
    1681     configuration.ProcPEPsi *= 2;
    1682   } else {
    1683     configuration.ProcPEGamma *= configuration.ProcPEPsi;
    1684     configuration.ProcPEPsi = 1;
    1685   }
    1686   configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
     1668        configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
     1669        for(int i=MAX_ELEMENTS;i--;) {
     1670                if (ElementsInMolecule[i] != 0) {
     1671                        //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
     1672                        configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
     1673                }
     1674        }
     1675        configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
     1676        configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
     1677        configuration.MaxPsiDouble /= 2;
     1678        configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
     1679        if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
     1680                configuration.ProcPEGamma /= 2;
     1681                configuration.ProcPEPsi *= 2;
     1682        } else {
     1683                configuration.ProcPEGamma *= configuration.ProcPEPsi;
     1684                configuration.ProcPEPsi = 1;
     1685        }
     1686        configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
    16871687};
    16881688
     
    16971697                        atom *Walker, *OtherWalker;
    16981698
    1699                 if (!input)
    1700                 {
    1701                         cout << Verbose(1) << "Opening silica failed \n";
    1702                 };
     1699                                        if (!input)
     1700                                        {
     1701                                                cout << Verbose(1) << "Opening silica failed \n";
     1702                                        };
    17031703
    17041704                        *input >> ws >> atom1;
    17051705                        *input >> ws >> atom2;
    1706                 cout << Verbose(1) << "Scanning file\n";
    1707                 while (!input->eof()) // Check whether we read everything already
    1708                 {
     1706                                        cout << Verbose(1) << "Scanning file\n";
     1707                                        while (!input->eof()) // Check whether we read everything already
     1708                                        {
    17091709                                *input >> ws >> atom1;
    17101710                                *input >> ws >> atom2;
    1711                         if(atom2<atom1) //Sort indices of atoms in order
    1712                         {
    1713                                 temp=atom1;
    1714                                 atom1=atom2;
    1715                                 atom2=temp;
    1716                         };
    1717 
    1718                         Walker=start;
    1719                         while(Walker-> nr != atom1) // Find atom corresponding to first index
    1720                         {
    1721                                 Walker = Walker->next;
    1722                         };
    1723                         OtherWalker = Walker->next;
    1724                         while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    1725                         {
    1726                                 OtherWalker= OtherWalker->next;
    1727                         };
    1728                         AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1729                        
    1730                 }
    1731 
    1732                 CreateListOfBondsPerAtom(out);
     1711                                                if(atom2<atom1) //Sort indices of atoms in order
     1712                                                {
     1713                                                        temp=atom1;
     1714                                                        atom1=atom2;
     1715                                                        atom2=temp;
     1716                                                };
     1717
     1718                                                Walker=start;
     1719                                                while(Walker-> nr != atom1) // Find atom corresponding to first index
     1720                                                {
     1721                                                        Walker = Walker->next;
     1722                                                };
     1723                                                OtherWalker = Walker->next;
     1724                                                while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     1725                                                {
     1726                                                        OtherWalker= OtherWalker->next;
     1727                                                };
     1728                                                AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     1729               
     1730                                        }
     1731
     1732                                        CreateListOfBondsPerAtom(out);
    17331733
    17341734};
     
    17411741 * To make it O(N log N) the function uses the linked-cell technique as follows:
    17421742 * The procedure is step-wise:
    1743  *  -# Remove every bond in list
    1744  *  -# Count the atoms in the molecule with CountAtoms()
    1745  *  -# partition cell into smaller linked cells of size \a bonddistance
    1746  *  -# put each atom into its corresponding cell
    1747  *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    1748  *  -# create the list of bonds via CreateListOfBondsPerAtom()
    1749  *  -# correct the bond degree iteratively (single->double->triple bond)
    1750  *  -# finally print the bond list to \a *out if desired
     1743 *      -# Remove every bond in list
     1744 *      -# Count the atoms in the molecule with CountAtoms()
     1745 *      -# partition cell into smaller linked cells of size \a bonddistance
     1746 *      -# put each atom into its corresponding cell
     1747 *      -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
     1748 *      -# create the list of bonds via CreateListOfBondsPerAtom()
     1749 *      -# correct the bond degree iteratively (single->double->triple bond)
     1750 *      -# finally print the bond list to \a *out if desired
    17511751 * \param *out out stream for printing the matrix, NULL if no output
    17521752 * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
     
    17561756{
    17571757
    1758   atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    1759   int No, NoBonds, CandidateBondNo;
    1760   int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
    1761   molecule **CellList;
    1762   double distance, MinDistance, MaxDistance;
    1763   double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    1764   Vector x;
    1765   int FalseBondDegree = 0;
    1766 
    1767   BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    1768   *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
    1769   // remove every bond from the list
    1770   if ((first->next != last) && (last->previous != first)) {  // there are bonds present
    1771     cleanup(first,last);
    1772   }
    1773 
    1774   // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    1775   CountAtoms(out);
    1776   *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
    1777 
    1778   if (AtomCount != 0) {
    1779     // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
    1780     j=-1;
    1781     for (int i=0;i<NDIM;i++) {
    1782       j += i+1;
    1783       divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    1784       //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
    1785     }
    1786     // 2a. allocate memory for the cell list
    1787     NumberCells = divisor[0]*divisor[1]*divisor[2];
    1788     *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
    1789     CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
    1790     for (int i=NumberCells;i--;)
    1791       CellList[i] = NULL;
    1792 
    1793     // 2b. put all atoms into its corresponding list
    1794     Walker = start;
    1795     while(Walker->next != end) {
    1796       Walker = Walker->next;
    1797       //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
    1798       //Walker->x.Output(out);
    1799       //*out << "." << endl;
    1800       // compute the cell by the atom's coordinates
    1801       j=-1;
    1802       for (int i=0;i<NDIM;i++) {
    1803         j += i+1;
    1804         x.CopyVector(&(Walker->x));
    1805         x.KeepPeriodic(out, matrix);
    1806         n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
    1807       }
    1808       index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    1809       //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    1810       // add copy atom to this cell
    1811       if (CellList[index] == NULL)  // allocate molecule if not done
    1812         CellList[index] = new molecule(elemente);
    1813       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    1814       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    1815     }
    1816     //for (int i=0;i<NumberCells;i++)
    1817       //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1818 
    1819 
    1820     // 3a. go through every cell
    1821     for (N[0]=divisor[0];N[0]--;)
    1822       for (N[1]=divisor[1];N[1]--;)
    1823         for (N[2]=divisor[2];N[2]--;) {
    1824           Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
    1825           if (CellList[Index] != NULL) { // if there atoms in this cell
    1826             //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
    1827             // 3b. for every atom therein
    1828             Walker = CellList[Index]->start;
    1829             while (Walker->next != CellList[Index]->end) {  // go through every atom
    1830               Walker = Walker->next;
    1831               //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1832               // 3c. check for possible bond between each atom in this and every one in the 27 cells
    1833               for (n[0]=-1;n[0]<=1;n[0]++)
    1834                 for (n[1]=-1;n[1]<=1;n[1]++)
    1835                   for (n[2]=-1;n[2]<=1;n[2]++) {
    1836                      // compute the index of this comparison cell and make it periodic
    1837                     index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2];
    1838                     //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
    1839                     if (CellList[index] != NULL) {  // if there are any atoms in this cell
    1840                       OtherWalker = CellList[index]->start;
    1841                       while(OtherWalker->next != CellList[index]->end) {  // go through every atom in this cell
    1842                         OtherWalker = OtherWalker->next;
    1843                         //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    1844                         /// \todo periodic check is missing here!
    1845                         //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistance(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    1846                         MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    1847                         MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    1848                         MaxDistance = MinDistance + BONDTHRESHOLD;
    1849                         MinDistance -= BONDTHRESHOLD;
    1850                         distance =   OtherWalker->x.PeriodicDistance(&(Walker->x), cell_size);
    1851                         if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    1852                           //*out << Verbose(0) << "Adding Bond between " << *Walker << " and " << *OtherWalker << "." << endl;
    1853                           AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
    1854                           BondCount++;
    1855                         } else {
    1856                           //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
    1857                         }
    1858                       }
    1859                     }
    1860                   }
    1861             }
    1862           }
    1863         }
    1864 
    1865 
    1866 
    1867     // 4. free the cell again
    1868     for (int i=NumberCells;i--;)
    1869       if (CellList[i] != NULL) {
    1870         delete(CellList[i]);
    1871       }
    1872     Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1873 
    1874     // create the adjacency list per atom
    1875     CreateListOfBondsPerAtom(out);
    1876 
    1877     // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    1878     // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    1879     // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    1880     // double bonds as was expected.
     1758        atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
     1759        int No, NoBonds, CandidateBondNo;
     1760        int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
     1761        molecule **CellList;
     1762        double distance, MinDistance, MaxDistance;
     1763        double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     1764        Vector x;
     1765        int FalseBondDegree = 0;
     1766
     1767        BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
     1768        *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     1769        // remove every bond from the list
     1770        if ((first->next != last) && (last->previous != first)) {       // there are bonds present
     1771                cleanup(first,last);
     1772        }
     1773
     1774        // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
     1775        CountAtoms(out);
     1776        *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
     1777
     1778        if (AtomCount != 0) {
     1779                // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
     1780                j=-1;
     1781                for (int i=0;i<NDIM;i++) {
     1782                        j += i+1;
     1783                        divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
     1784                        //*out << Verbose(1) << "divisor[" << i << "]   = " << divisor[i] << "." << endl;
     1785                }
     1786                // 2a. allocate memory for the cell list
     1787                NumberCells = divisor[0]*divisor[1]*divisor[2];
     1788                *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
     1789                CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
     1790                for (int i=NumberCells;i--;)
     1791                        CellList[i] = NULL;
     1792
     1793                // 2b. put all atoms into its corresponding list
     1794                Walker = start;
     1795                while(Walker->next != end) {
     1796                        Walker = Walker->next;
     1797                        //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
     1798                        //Walker->x.Output(out);
     1799                        //*out << "." << endl;
     1800                        // compute the cell by the atom's coordinates
     1801                        j=-1;
     1802                        for (int i=0;i<NDIM;i++) {
     1803                                j += i+1;
     1804                                x.CopyVector(&(Walker->x));
     1805                                x.KeepPeriodic(out, matrix);
     1806                                n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
     1807                        }
     1808                        index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
     1809                        //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
     1810                        // add copy atom to this cell
     1811                        if (CellList[index] == NULL)    // allocate molecule if not done
     1812                                CellList[index] = new molecule(elemente);
     1813                        OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
     1814                        //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     1815                }
     1816                //for (int i=0;i<NumberCells;i++)
     1817                        //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
     1818
     1819
     1820                // 3a. go through every cell
     1821                for (N[0]=divisor[0];N[0]--;)
     1822                        for (N[1]=divisor[1];N[1]--;)
     1823                                for (N[2]=divisor[2];N[2]--;) {
     1824                                        Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
     1825                                        if (CellList[Index] != NULL) { // if there atoms in this cell
     1826                                                //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
     1827                                                // 3b. for every atom therein
     1828                                                Walker = CellList[Index]->start;
     1829                                                while (Walker->next != CellList[Index]->end) {  // go through every atom
     1830                                                        Walker = Walker->next;
     1831                                                        //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
     1832                                                        // 3c. check for possible bond between each atom in this and every one in the 27 cells
     1833                                                        for (n[0]=-1;n[0]<=1;n[0]++)
     1834                                                                for (n[1]=-1;n[1]<=1;n[1]++)
     1835                                                                        for (n[2]=-1;n[2]<=1;n[2]++) {
     1836                                                                                 // compute the index of this comparison cell and make it periodic
     1837                                                                                index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2];
     1838                                                                                //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
     1839                                                                                if (CellList[index] != NULL) {  // if there are any atoms in this cell
     1840                                                                                        OtherWalker = CellList[index]->start;
     1841                                                                                        while(OtherWalker->next != CellList[index]->end) {      // go through every atom in this cell
     1842                                                                                                OtherWalker = OtherWalker->next;
     1843                                                                                                //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
     1844                                                                                                /// \todo periodic check is missing here!
     1845                                                                                                //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     1846                                                                                                MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
     1847                                                                                                MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
     1848                                                                                                MaxDistance = MinDistance + BONDTHRESHOLD;
     1849                                                                                                MinDistance -= BONDTHRESHOLD;
     1850                                                                                                distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
     1851                                                                                                if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
     1852                                                                                                        //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
     1853                                                                                                        AddBond(Walker->father, OtherWalker->father, 1);        // also increases molecule::BondCount
     1854                                                                                                } else {
     1855                                                                                                        //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     1856                                                                                                }
     1857                                                                                        }
     1858                                                                                }
     1859                                                                        }
     1860                                                }
     1861                                        }
     1862                                }
     1863
     1864
     1865
     1866                // 4. free the cell again
     1867                for (int i=NumberCells;i--;)
     1868                        if (CellList[i] != NULL) {
     1869                                delete(CellList[i]);
     1870                        }
     1871                Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
     1872
     1873                // create the adjacency list per atom
     1874                CreateListOfBondsPerAtom(out);
     1875
     1876                // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
     1877                // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     1878                // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
     1879                // double bonds as was expected.
    18811880                if (BondCount != 0) {
    1882       NoCyclicBonds = 0;
    1883                   *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    1884                   do {
    1885                     No = 0; // No acts as breakup flag (if 1 we still continue)
    1886         Walker = start;
    1887         while (Walker->next != end) { // go through every atom
    1888           Walker = Walker->next;
    1889           // count valence of first partner
    1890           NoBonds = 0;
    1891           for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
    1892             NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    1893           *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1894           if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    1895             Candidate = NULL;
    1896             CandidateBondNo = -1;
    1897             for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    1898               OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    1899                     // count valence of second partner
    1900               NoBonds = 0;
    1901               for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    1902                 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    1903               *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1904                     if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    1905                       if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    1906                   Candidate = OtherWalker;
    1907                   CandidateBondNo = i;
    1908                         *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    1909                       }
    1910                     }
    1911                   }
    1912             if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    1913               ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    1914               *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    1915             } else
    1916               *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    1917               FalseBondDegree++;
    1918           }
    1919                     }
    1920                   } while (No);
     1881                        NoCyclicBonds = 0;
     1882                        *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     1883                        do {
     1884                                No = 0; // No acts as breakup flag (if 1 we still continue)
     1885                                Walker = start;
     1886                                while (Walker->next != end) { // go through every atom
     1887                                        Walker = Walker->next;
     1888                                        // count valence of first partner
     1889                                        NoBonds = 0;
     1890                                        for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
     1891                                                NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     1892                                        *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1893                                        if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
     1894                                                Candidate = NULL;
     1895                                                CandidateBondNo = -1;
     1896                                                for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
     1897                                                        OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1898                                                        // count valence of second partner
     1899                                                        NoBonds = 0;
     1900                                                        for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
     1901                                                                NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
     1902                                                        *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1903                                                        if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     1904                                                                if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
     1905                                                                        Candidate = OtherWalker;
     1906                                                                        CandidateBondNo = i;
     1907                                                                        *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
     1908                                                                }
     1909                                                        }
     1910                                                }
     1911                                                if ((Candidate != NULL) && (CandidateBondNo != -1)) {
     1912                                                        ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
     1913                                                        *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
     1914                                                } else
     1915                                                        *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
     1916                                                        FalseBondDegree++;
     1917                                        }
     1918                                }
     1919                        } while (No);
    19211920                *out << " done." << endl;
    19221921                } else
    19231922                        *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    1924           *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    1925 
    1926           // output bonds for debugging (if bond chain list was correctly installed)
    1927           *out << Verbose(1) << endl << "From contents of bond chain list:";
    1928           bond *Binder = first;
    1929     while(Binder->next != last) {
    1930       Binder = Binder->next;
     1923                *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     1924
     1925                // output bonds for debugging (if bond chain list was correctly installed)
     1926                *out << Verbose(1) << endl << "From contents of bond chain list:";
     1927                bond *Binder = first;
     1928                while(Binder->next != last) {
     1929                        Binder = Binder->next;
    19311930                        *out << *Binder << "\t" << endl;
    1932     }
    1933     *out << endl;
    1934   } else
    1935         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    1936   *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    1937   Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
     1931                }
     1932                *out << endl;
     1933        } else
     1934                *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     1935        *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
     1936        Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    19381937
    19391938};
     
    19511950MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
    19521951{
    1953   class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    1954   BackEdgeStack = new StackClass<bond *> (BondCount);
    1955   MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    1956   MoleculeLeafClass *LeafWalker = SubGraphs;
    1957   int CurrentGraphNr = 0, OldGraphNr;
    1958   int ComponentNumber = 0;
    1959   atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
    1960   bond *Binder = NULL;
    1961   bool BackStepping = false;
    1962 
    1963   *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    1964 
    1965   ResetAllBondsToUnused();
    1966   ResetAllAtomNumbers();
    1967   InitComponentNumbers();
    1968   BackEdgeStack->ClearStack();
    1969   while (Root != end) { // if there any atoms at all
    1970     // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
    1971     AtomStack->ClearStack();
    1972 
    1973     // put into new subgraph molecule and add this to list of subgraphs
    1974     LeafWalker = new MoleculeLeafClass(LeafWalker);
    1975     LeafWalker->Leaf = new molecule(elemente);
    1976     LeafWalker->Leaf->AddCopyAtom(Root);
    1977 
    1978     OldGraphNr = CurrentGraphNr;
    1979     Walker = Root;
    1980     do { // (10)
    1981       do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
    1982         if (!BackStepping) { // if we don't just return from (8)
    1983           Walker->GraphNr = CurrentGraphNr;
    1984           Walker->LowpointNr = CurrentGraphNr;
    1985           *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
    1986           AtomStack->Push(Walker);
    1987           CurrentGraphNr++;
    1988         }
    1989         do { // (3) if Walker has no unused egdes, go to (5)
    1990           BackStepping = false; // reset backstepping flag for (8)
    1991           if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
    1992             Binder = FindNextUnused(Walker);
    1993           if (Binder == NULL)
    1994             break;
    1995           *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
    1996           // (4) Mark Binder used, ...
    1997           Binder->MarkUsed(black);
    1998           OtherAtom = Binder->GetOtherAtom(Walker);
    1999           *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
    2000           if (OtherAtom->GraphNr != -1) {
    2001             // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
    2002             Binder->Type = BackEdge;
    2003             BackEdgeStack->Push(Binder);
    2004             Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
    2005             *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
    2006           } else {
    2007             // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
    2008             Binder->Type = TreeEdge;
    2009             OtherAtom->Ancestor = Walker;
    2010             Walker = OtherAtom;
    2011             *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
    2012             break;
    2013           }
    2014           Binder = NULL;
    2015         } while (1);  // (3)
    2016         if (Binder == NULL) {
    2017           *out << Verbose(2) << "No more Unused Bonds." << endl;
    2018           break;
    2019         } else
    2020           Binder = NULL;
    2021       } while (1);  // (2)
    2022 
    2023       // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished!
    2024       if ((Walker == Root) && (Binder == NULL))
    2025         break;
    2026 
    2027       // (5) if Ancestor of Walker is ...
    2028       *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    2029       if (Walker->Ancestor->GraphNr != Root->GraphNr) {
    2030         // (6)  (Ancestor of Walker is not Root)
    2031         if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
    2032           // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
    2033           Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
    2034           *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
    2035         } else {
    2036           // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
    2037           Walker->Ancestor->SeparationVertex = true;
    2038           *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
    2039           SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
    2040           *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
    2041           SetNextComponentNumber(Walker, ComponentNumber);
    2042           *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2043           do {
    2044             OtherAtom = AtomStack->PopLast();
    2045             LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2046             SetNextComponentNumber(OtherAtom, ComponentNumber);
    2047             *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2048           } while (OtherAtom != Walker);
    2049           ComponentNumber++;
    2050         }
    2051         // (8) Walker becomes its Ancestor, go to (3)
    2052         *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
    2053         Walker = Walker->Ancestor;
    2054         BackStepping = true;
    2055       }
    2056       if (!BackStepping) {  // coming from (8) want to go to (3)
    2057         // (9) remove all from stack till Walker (including), these and Root form a component
    2058         AtomStack->Output(out);
    2059         SetNextComponentNumber(Root, ComponentNumber);
    2060         *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2061         SetNextComponentNumber(Walker, ComponentNumber);
    2062         *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2063         do {
    2064           OtherAtom = AtomStack->PopLast();
    2065           LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2066           SetNextComponentNumber(OtherAtom, ComponentNumber);
    2067           *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2068         } while (OtherAtom != Walker);
    2069         ComponentNumber++;
    2070 
    2071         // (11) Root is separation vertex,  set Walker to Root and go to (4)
    2072         Walker = Root;
    2073         Binder = FindNextUnused(Walker);
    2074         *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
    2075         if (Binder != NULL) { // Root is separation vertex
    2076           *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
    2077           Walker->SeparationVertex = true;
    2078         }
    2079       }
    2080     } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
    2081 
    2082     // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2083     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    2084     LeafWalker->Leaf->Output(out);
    2085     *out << endl;
    2086 
    2087     // step on to next root
    2088     while ((Root != end) && (Root->GraphNr != -1)) {
    2089       //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    2090       if (Root->GraphNr != -1) // if already discovered, step on
    2091         Root = Root->next;
    2092     }
    2093   }
    2094   // set cyclic bond criterium on "same LP" basis
    2095   Binder = first;
    2096   while(Binder->next != last) {
    2097     Binder = Binder->next;
    2098     if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
    2099       Binder->Cyclic = true;
    2100       NoCyclicBonds++;
    2101     }
    2102   }
    2103 
    2104 
    2105   *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    2106   Walker = start;
    2107   while (Walker->next != end) {
    2108     Walker = Walker->next;
    2109     *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    2110     OutputComponentNumber(out, Walker);
    2111     *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    2112   }
    2113 
    2114   *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    2115   Binder = first;
    2116   while(Binder->next != last) {
    2117     Binder = Binder->next;
    2118     *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    2119     *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    2120     OutputComponentNumber(out, Binder->leftatom);
    2121     *out << " ===  ";
    2122     *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    2123     OutputComponentNumber(out, Binder->rightatom);
    2124     *out << ">." << endl;
    2125     if (Binder->Cyclic) // cyclic ??
    2126       *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    2127   }
    2128 
    2129   // free all and exit
    2130   delete(AtomStack);
    2131   *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    2132   return SubGraphs;
     1952        class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     1953        BackEdgeStack = new StackClass<bond *> (BondCount);
     1954        MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
     1955        MoleculeLeafClass *LeafWalker = SubGraphs;
     1956        int CurrentGraphNr = 0, OldGraphNr;
     1957        int ComponentNumber = 0;
     1958        atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
     1959        bond *Binder = NULL;
     1960        bool BackStepping = false;
     1961
     1962        *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
     1963
     1964        ResetAllBondsToUnused();
     1965        ResetAllAtomNumbers();
     1966        InitComponentNumbers();
     1967        BackEdgeStack->ClearStack();
     1968        while (Root != end) { // if there any atoms at all
     1969                // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
     1970                AtomStack->ClearStack();
     1971
     1972                // put into new subgraph molecule and add this to list of subgraphs
     1973                LeafWalker = new MoleculeLeafClass(LeafWalker);
     1974                LeafWalker->Leaf = new molecule(elemente);
     1975                LeafWalker->Leaf->AddCopyAtom(Root);
     1976
     1977                OldGraphNr = CurrentGraphNr;
     1978                Walker = Root;
     1979                do { // (10)
     1980                        do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
     1981                                if (!BackStepping) { // if we don't just return from (8)
     1982                                        Walker->GraphNr = CurrentGraphNr;
     1983                                        Walker->LowpointNr = CurrentGraphNr;
     1984                                        *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
     1985                                        AtomStack->Push(Walker);
     1986                                        CurrentGraphNr++;
     1987                                }
     1988                                do { // (3) if Walker has no unused egdes, go to (5)
     1989                                        BackStepping = false; // reset backstepping flag for (8)
     1990                                        if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
     1991                                                Binder = FindNextUnused(Walker);
     1992                                        if (Binder == NULL)
     1993                                                break;
     1994                                        *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
     1995                                        // (4) Mark Binder used, ...
     1996                                        Binder->MarkUsed(black);
     1997                                        OtherAtom = Binder->GetOtherAtom(Walker);
     1998                                        *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
     1999                                        if (OtherAtom->GraphNr != -1) {
     2000                                                // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
     2001                                                Binder->Type = BackEdge;
     2002                                                BackEdgeStack->Push(Binder);
     2003                                                Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
     2004                                                *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
     2005                                        } else {
     2006                                                // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
     2007                                                Binder->Type = TreeEdge;
     2008                                                OtherAtom->Ancestor = Walker;
     2009                                                Walker = OtherAtom;
     2010                                                *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
     2011                                                break;
     2012                                        }
     2013                                        Binder = NULL;
     2014                                } while (1);    // (3)
     2015                                if (Binder == NULL) {
     2016                                        *out << Verbose(2) << "No more Unused Bonds." << endl;
     2017                                        break;
     2018                                } else
     2019                                        Binder = NULL;
     2020                        } while (1);    // (2)
     2021
     2022                        // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished!
     2023                        if ((Walker == Root) && (Binder == NULL))
     2024                                break;
     2025
     2026                        // (5) if Ancestor of Walker is ...
     2027                        *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
     2028                        if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     2029                                // (6)  (Ancestor of Walker is not Root)
     2030                                if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
     2031                                        // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
     2032                                        Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
     2033                                        *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
     2034                                } else {
     2035                                        // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
     2036                                        Walker->Ancestor->SeparationVertex = true;
     2037                                        *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
     2038                                        SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
     2039                                        *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
     2040                                        SetNextComponentNumber(Walker, ComponentNumber);
     2041                                        *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2042                                        do {
     2043                                                OtherAtom = AtomStack->PopLast();
     2044                                                LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2045                                                SetNextComponentNumber(OtherAtom, ComponentNumber);
     2046                                                *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2047                                        } while (OtherAtom != Walker);
     2048                                        ComponentNumber++;
     2049                                }
     2050                                // (8) Walker becomes its Ancestor, go to (3)
     2051                                *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
     2052                                Walker = Walker->Ancestor;
     2053                                BackStepping = true;
     2054                        }
     2055                        if (!BackStepping) {    // coming from (8) want to go to (3)
     2056                                // (9) remove all from stack till Walker (including), these and Root form a component
     2057                                AtomStack->Output(out);
     2058                                SetNextComponentNumber(Root, ComponentNumber);
     2059                                *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2060                                SetNextComponentNumber(Walker, ComponentNumber);
     2061                                *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2062                                do {
     2063                                        OtherAtom = AtomStack->PopLast();
     2064                                        LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2065                                        SetNextComponentNumber(OtherAtom, ComponentNumber);
     2066                                        *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2067                                } while (OtherAtom != Walker);
     2068                                ComponentNumber++;
     2069
     2070                                // (11) Root is separation vertex,      set Walker to Root and go to (4)
     2071                                Walker = Root;
     2072                                Binder = FindNextUnused(Walker);
     2073                                *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
     2074                                if (Binder != NULL) { // Root is separation vertex
     2075                                        *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
     2076                                        Walker->SeparationVertex = true;
     2077                                }
     2078                        }
     2079                } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
     2080
     2081                // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
     2082                *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2083                LeafWalker->Leaf->Output(out);
     2084                *out << endl;
     2085
     2086                // step on to next root
     2087                while ((Root != end) && (Root->GraphNr != -1)) {
     2088                        //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
     2089                        if (Root->GraphNr != -1) // if already discovered, step on
     2090                                Root = Root->next;
     2091                }
     2092        }
     2093        // set cyclic bond criterium on "same LP" basis
     2094        Binder = first;
     2095        while(Binder->next != last) {
     2096                Binder = Binder->next;
     2097                if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
     2098                        Binder->Cyclic = true;
     2099                        NoCyclicBonds++;
     2100                }
     2101        }
     2102
     2103
     2104        *out << Verbose(1) << "Final graph info for each atom is:" << endl;
     2105        Walker = start;
     2106        while (Walker->next != end) {
     2107                Walker = Walker->next;
     2108                *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
     2109                OutputComponentNumber(out, Walker);
     2110                *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
     2111        }
     2112
     2113        *out << Verbose(1) << "Final graph info for each bond is:" << endl;
     2114        Binder = first;
     2115        while(Binder->next != last) {
     2116                Binder = Binder->next;
     2117                *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
     2118                *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
     2119                OutputComponentNumber(out, Binder->leftatom);
     2120                *out << " ===   ";
     2121                *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
     2122                OutputComponentNumber(out, Binder->rightatom);
     2123                *out << ">." << endl;
     2124                if (Binder->Cyclic) // cyclic ??
     2125                        *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     2126        }
     2127
     2128        // free all and exit
     2129        delete(AtomStack);
     2130        *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     2131        return SubGraphs;
    21332132};
    21342133
     
    21432142 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
    21442143 */
    2145 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *  BackEdgeStack, int *&MinimumRingSize)
    2146 {
    2147   atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2148   int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    2149   enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2150   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);  // will hold the current ring
    2151   class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);  // contains all "touched" atoms (that need to be reset after BFS loop)
    2152   atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
    2153   bond *Binder = NULL, *BackEdge = NULL;
    2154   int RingSize, NumCycles, MinRingSize = -1;
    2155 
    2156   // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    2157   for (int i=AtomCount;i--;) {
    2158     PredecessorList[i] = NULL;
    2159     ShortestPathList[i] = -1;
    2160     ColorList[i] = white;
    2161   }
    2162 
    2163   *out << Verbose(1) << "Back edge list - ";
    2164   BackEdgeStack->Output(out);
    2165 
    2166   *out << Verbose(1) << "Analysing cycles ... " << endl;
    2167   NumCycles = 0;
    2168   while (!BackEdgeStack->IsEmpty()) {
    2169     BackEdge = BackEdgeStack->PopFirst();
    2170     // this is the target
    2171     Root = BackEdge->leftatom;
    2172     // this is the source point
    2173     Walker = BackEdge->rightatom;
    2174     ShortestPathList[Walker->nr] = 0;
    2175     BFSStack->ClearStack();  // start with empty BFS stack
    2176     BFSStack->Push(Walker);
    2177     TouchedStack->Push(Walker);
    2178     *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2179     OtherAtom = NULL;
    2180     do {  // look for Root
    2181       Walker = BFSStack->PopFirst();
    2182       *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2183       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2184         Binder = ListOfBondsPerAtom[Walker->nr][i];
    2185         if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    2186           OtherAtom = Binder->GetOtherAtom(Walker);
     2144void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *        BackEdgeStack, int *&MinimumRingSize)
     2145{
     2146        atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2147        int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
     2148        enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
     2149        class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);        // will hold the current ring
     2150        class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);    // contains all "touched" atoms (that need to be reset after BFS loop)
     2151        atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     2152        bond *Binder = NULL, *BackEdge = NULL;
     2153        int RingSize, NumCycles, MinRingSize = -1;
     2154
     2155        // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     2156        for (int i=AtomCount;i--;) {
     2157                PredecessorList[i] = NULL;
     2158                ShortestPathList[i] = -1;
     2159                ColorList[i] = white;
     2160        }
     2161
     2162        *out << Verbose(1) << "Back edge list - ";
     2163        BackEdgeStack->Output(out);
     2164
     2165        *out << Verbose(1) << "Analysing cycles ... " << endl;
     2166        NumCycles = 0;
     2167        while (!BackEdgeStack->IsEmpty()) {
     2168                BackEdge = BackEdgeStack->PopFirst();
     2169                // this is the target
     2170                Root = BackEdge->leftatom;
     2171                // this is the source point
     2172                Walker = BackEdge->rightatom;
     2173                ShortestPathList[Walker->nr] = 0;
     2174                BFSStack->ClearStack(); // start with empty BFS stack
     2175                BFSStack->Push(Walker);
     2176                TouchedStack->Push(Walker);
     2177                *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2178                OtherAtom = NULL;
     2179                do {    // look for Root
     2180                        Walker = BFSStack->PopFirst();
     2181                        *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2182                        for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2183                                Binder = ListOfBondsPerAtom[Walker->nr][i];
     2184                                if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     2185                                        OtherAtom = Binder->GetOtherAtom(Walker);
    21872186#ifdef ADDHYDROGEN
    2188           if (OtherAtom->type->Z != 1) {
     2187                                        if (OtherAtom->type->Z != 1) {
    21892188#endif
    2190             *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2191             if (ColorList[OtherAtom->nr] == white) {
    2192               TouchedStack->Push(OtherAtom);
    2193               ColorList[OtherAtom->nr] = lightgray;
    2194               PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    2195               ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2196               *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    2197               //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    2198                 *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
    2199                 BFSStack->Push(OtherAtom);
    2200               //}
    2201             } else {
    2202               *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2203             }
    2204             if (OtherAtom == Root)
    2205               break;
     2189                                                *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2190                                                if (ColorList[OtherAtom->nr] == white) {
     2191                                                        TouchedStack->Push(OtherAtom);
     2192                                                        ColorList[OtherAtom->nr] = lightgray;
     2193                                                        PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
     2194                                                        ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2195                                                        *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     2196                                                        //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
     2197                                                                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     2198                                                                BFSStack->Push(OtherAtom);
     2199                                                        //}
     2200                                                } else {
     2201                                                        *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2202                                                }
     2203                                                if (OtherAtom == Root)
     2204                                                        break;
    22062205#ifdef ADDHYDROGEN
    2207           } else {
    2208             *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
    2209             ColorList[OtherAtom->nr] = black;
    2210           }
     2206                                        } else {
     2207                                                *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     2208                                                ColorList[OtherAtom->nr] = black;
     2209                                        }
    22112210#endif
    2212         } else {
    2213           *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
    2214         }
    2215       }
    2216       ColorList[Walker->nr] = black;
    2217       *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2218       if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
    2219         // step through predecessor list
    2220         while (OtherAtom != BackEdge->rightatom) {
    2221           if (!OtherAtom->GetTrueFather()->IsCyclic)  // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
    2222             break;
    2223           else
    2224             OtherAtom = PredecessorList[OtherAtom->nr];
    2225         }
    2226         if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
    2227           *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
    2228           do {
    2229             OtherAtom = TouchedStack->PopLast();
    2230             if (PredecessorList[OtherAtom->nr] == Walker) {
    2231               *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
    2232               PredecessorList[OtherAtom->nr] = NULL;
    2233               ShortestPathList[OtherAtom->nr] = -1;
    2234               ColorList[OtherAtom->nr] = white;
    2235               BFSStack->RemoveItem(OtherAtom);
    2236             }
    2237           } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
    2238           TouchedStack->Push(OtherAtom);  // last was wrongly popped
    2239           OtherAtom = BackEdge->rightatom; // set to not Root
    2240         } else
    2241           OtherAtom = Root;
    2242       }
    2243     } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2244 
    2245     if (OtherAtom == Root) {
    2246       // now climb back the predecessor list and thus find the cycle members
    2247       NumCycles++;
    2248       RingSize = 1;
    2249       Root->GetTrueFather()->IsCyclic = true;
    2250       *out << Verbose(1) << "Found ring contains: ";
    2251       Walker = Root;
    2252       while (Walker != BackEdge->rightatom) {
    2253         *out << Walker->Name << " <-> ";
    2254         Walker = PredecessorList[Walker->nr];
    2255         Walker->GetTrueFather()->IsCyclic = true;
    2256         RingSize++;
    2257       }
    2258       *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
    2259       // walk through all and set MinimumRingSize
    2260       Walker = Root;
    2261       MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2262       while (Walker != BackEdge->rightatom) {
    2263         Walker = PredecessorList[Walker->nr];
    2264         if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
    2265           MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2266       }
    2267       if ((RingSize < MinRingSize) || (MinRingSize == -1))
    2268         MinRingSize = RingSize;
    2269     } else {
    2270       *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    2271     }
    2272 
    2273     // now clean the lists
    2274     while (!TouchedStack->IsEmpty()){
    2275       Walker = TouchedStack->PopFirst();
    2276       PredecessorList[Walker->nr] = NULL;
    2277       ShortestPathList[Walker->nr] = -1;
    2278       ColorList[Walker->nr] = white;
    2279     }
    2280   }
    2281   if (MinRingSize != -1) {
    2282     // go over all atoms
    2283     Root = start;
    2284     while(Root->next != end) {
    2285       Root = Root->next;
    2286 
    2287       if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    2288         Walker = Root;
    2289         ShortestPathList[Walker->nr] = 0;
    2290         BFSStack->ClearStack();  // start with empty BFS stack
    2291         BFSStack->Push(Walker);
    2292         TouchedStack->Push(Walker);
    2293         //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2294         OtherAtom = Walker;
    2295         while (OtherAtom != NULL) {  // look for Root
    2296           Walker = BFSStack->PopFirst();
    2297           //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2298           for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2299             Binder = ListOfBondsPerAtom[Walker->nr][i];
    2300             if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
    2301               OtherAtom = Binder->GetOtherAtom(Walker);
    2302               //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2303               if (ColorList[OtherAtom->nr] == white) {
    2304                 TouchedStack->Push(OtherAtom);
    2305                 ColorList[OtherAtom->nr] = lightgray;
    2306                 PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    2307                 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2308                 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    2309                 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
    2310                   MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
    2311                   OtherAtom = NULL; //break;
    2312                   break;
    2313                 } else
    2314                   BFSStack->Push(OtherAtom);
    2315               } else {
    2316                 //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2317               }
    2318             } else {
    2319               //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
    2320             }
    2321           }
    2322           ColorList[Walker->nr] = black;
    2323           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2324         }
    2325 
    2326         // now clean the lists
    2327         while (!TouchedStack->IsEmpty()){
    2328           Walker = TouchedStack->PopFirst();
    2329           PredecessorList[Walker->nr] = NULL;
    2330           ShortestPathList[Walker->nr] = -1;
    2331           ColorList[Walker->nr] = white;
    2332         }
    2333       }
    2334       *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
    2335     }
    2336     *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
    2337   } else
    2338     *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
    2339 
    2340   Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2341   Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
    2342   Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
    2343   delete(BFSStack);
     2211                                } else {
     2212                                        *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
     2213                                }
     2214                        }
     2215                        ColorList[Walker->nr] = black;
     2216                        *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2217                        if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
     2218                                // step through predecessor list
     2219                                while (OtherAtom != BackEdge->rightatom) {
     2220                                        if (!OtherAtom->GetTrueFather()->IsCyclic)      // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
     2221                                                break;
     2222                                        else
     2223                                                OtherAtom = PredecessorList[OtherAtom->nr];
     2224                                }
     2225                                if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
     2226                                        *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
     2227                                        do {
     2228                                                OtherAtom = TouchedStack->PopLast();
     2229                                                if (PredecessorList[OtherAtom->nr] == Walker) {
     2230                                                        *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
     2231                                                        PredecessorList[OtherAtom->nr] = NULL;
     2232                                                        ShortestPathList[OtherAtom->nr] = -1;
     2233                                                        ColorList[OtherAtom->nr] = white;
     2234                                                        BFSStack->RemoveItem(OtherAtom);
     2235                                                }
     2236                                        } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
     2237                                        TouchedStack->Push(OtherAtom);  // last was wrongly popped
     2238                                        OtherAtom = BackEdge->rightatom; // set to not Root
     2239                                } else
     2240                                        OtherAtom = Root;
     2241                        }
     2242                } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
     2243
     2244                if (OtherAtom == Root) {
     2245                        // now climb back the predecessor list and thus find the cycle members
     2246                        NumCycles++;
     2247                        RingSize = 1;
     2248                        Root->GetTrueFather()->IsCyclic = true;
     2249                        *out << Verbose(1) << "Found ring contains: ";
     2250                        Walker = Root;
     2251                        while (Walker != BackEdge->rightatom) {
     2252                                *out << Walker->Name << " <-> ";
     2253                                Walker = PredecessorList[Walker->nr];
     2254                                Walker->GetTrueFather()->IsCyclic = true;
     2255                                RingSize++;
     2256                        }
     2257                        *out << Walker->Name << "       with a length of " << RingSize << "." << endl << endl;
     2258                        // walk through all and set MinimumRingSize
     2259                        Walker = Root;
     2260                        MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2261                        while (Walker != BackEdge->rightatom) {
     2262                                Walker = PredecessorList[Walker->nr];
     2263                                if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
     2264                                        MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2265                        }
     2266                        if ((RingSize < MinRingSize) || (MinRingSize == -1))
     2267                                MinRingSize = RingSize;
     2268                } else {
     2269                        *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
     2270                }
     2271
     2272                // now clean the lists
     2273                while (!TouchedStack->IsEmpty()){
     2274                        Walker = TouchedStack->PopFirst();
     2275                        PredecessorList[Walker->nr] = NULL;
     2276                        ShortestPathList[Walker->nr] = -1;
     2277                        ColorList[Walker->nr] = white;
     2278                }
     2279        }
     2280        if (MinRingSize != -1) {
     2281                // go over all atoms
     2282                Root = start;
     2283                while(Root->next != end) {
     2284                        Root = Root->next;
     2285
     2286                        if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
     2287                                Walker = Root;
     2288                                ShortestPathList[Walker->nr] = 0;
     2289                                BFSStack->ClearStack(); // start with empty BFS stack
     2290                                BFSStack->Push(Walker);
     2291                                TouchedStack->Push(Walker);
     2292                                //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2293                                OtherAtom = Walker;
     2294                                while (OtherAtom != NULL) {     // look for Root
     2295                                        Walker = BFSStack->PopFirst();
     2296                                        //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2297                                        for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2298                                                Binder = ListOfBondsPerAtom[Walker->nr][i];
     2299                                                if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
     2300                                                        OtherAtom = Binder->GetOtherAtom(Walker);
     2301                                                        //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2302                                                        if (ColorList[OtherAtom->nr] == white) {
     2303                                                                TouchedStack->Push(OtherAtom);
     2304                                                                ColorList[OtherAtom->nr] = lightgray;
     2305                                                                PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
     2306                                                                ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2307                                                                //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     2308                                                                if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
     2309                                                                        MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
     2310                                                                        OtherAtom = NULL; //break;
     2311                                                                        break;
     2312                                                                } else
     2313                                                                        BFSStack->Push(OtherAtom);
     2314                                                        } else {
     2315                                                                //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2316                                                        }
     2317                                                } else {
     2318                                                        //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
     2319                                                }
     2320                                        }
     2321                                        ColorList[Walker->nr] = black;
     2322                                        //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2323                                }
     2324
     2325                                // now clean the lists
     2326                                while (!TouchedStack->IsEmpty()){
     2327                                        Walker = TouchedStack->PopFirst();
     2328                                        PredecessorList[Walker->nr] = NULL;
     2329                                        ShortestPathList[Walker->nr] = -1;
     2330                                        ColorList[Walker->nr] = white;
     2331                                }
     2332                        }
     2333                        *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
     2334                }
     2335                *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
     2336        } else
     2337                *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
     2338
     2339        Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2340        Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
     2341        Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
     2342        delete(BFSStack);
    23442343};
    23452344
     
    23512350void molecule::SetNextComponentNumber(atom *vertex, int nr)
    23522351{
    2353   int i=0;
    2354   if (vertex != NULL) {
    2355     for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
    2356       if (vertex->ComponentNr[i] == -1) {  // check if not yet used
    2357         vertex->ComponentNr[i] = nr;
    2358         break;
    2359       }
    2360       else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
    2361         break;  // breaking here will not cause error!
    2362     }
    2363     if (i == NumberOfBondsPerAtom[vertex->nr])
    2364       cerr << "Error: All Component entries are already occupied!" << endl;
    2365   } else
    2366       cerr << "Error: Given vertex is NULL!" << endl;
     2352        int i=0;
     2353        if (vertex != NULL) {
     2354                for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
     2355                        if (vertex->ComponentNr[i] == -1) {      // check if not yet used
     2356                                vertex->ComponentNr[i] = nr;
     2357                                break;
     2358                        }
     2359                        else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
     2360                                break;  // breaking here will not cause error!
     2361                }
     2362                if (i == NumberOfBondsPerAtom[vertex->nr])
     2363                        cerr << "Error: All Component entries are already occupied!" << endl;
     2364        } else
     2365                        cerr << "Error: Given vertex is NULL!" << endl;
    23672366};
    23682367
     
    23722371void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    23732372{
    2374   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2375     *out << vertex->ComponentNr[i] << "  ";
     2373        for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2374                *out << vertex->ComponentNr[i] << "     ";
    23762375};
    23772376
     
    23802379void molecule::InitComponentNumbers()
    23812380{
    2382   atom *Walker = start;
    2383   while(Walker->next != end) {
    2384     Walker = Walker->next;
    2385     if (Walker->ComponentNr != NULL)
    2386       Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
    2387     Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    2388     for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
    2389       Walker->ComponentNr[i] = -1;
    2390   }
     2381        atom *Walker = start;
     2382        while(Walker->next != end) {
     2383                Walker = Walker->next;
     2384                if (Walker->ComponentNr != NULL)
     2385                        Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
     2386                Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
     2387                for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
     2388                        Walker->ComponentNr[i] = -1;
     2389        }
    23912390};
    23922391
     
    23972396bond * molecule::FindNextUnused(atom *vertex)
    23982397{
    2399   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2400     if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    2401       return(ListOfBondsPerAtom[vertex->nr][i]);
    2402   return NULL;
     2398        for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2399                if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
     2400                        return(ListOfBondsPerAtom[vertex->nr][i]);
     2401        return NULL;
    24032402};
    24042403
     
    24082407void molecule::ResetAllBondsToUnused()
    24092408{
    2410   bond *Binder = first;
    2411   while (Binder->next != last) {
    2412     Binder = Binder->next;
    2413     Binder->ResetUsed();
    2414   }
     2409        bond *Binder = first;
     2410        while (Binder->next != last) {
     2411                Binder = Binder->next;
     2412                Binder->ResetUsed();
     2413        }
    24152414};
    24162415
     
    24192418void molecule::ResetAllAtomNumbers()
    24202419{
    2421   atom *Walker = start;
    2422   while (Walker->next != end) {
    2423     Walker = Walker->next;
    2424     Walker->GraphNr  = -1;
    2425   }
     2420        atom *Walker = start;
     2421        while (Walker->next != end) {
     2422                Walker = Walker->next;
     2423                Walker->GraphNr = -1;
     2424        }
    24262425};
    24272426
     
    24322431void OutputAlreadyVisited(ofstream *out, int *list)
    24332432{
    2434   *out << Verbose(4) << "Already Visited Bonds:\t";
    2435   for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
    2436   *out << endl;
     2433        *out << Verbose(4) << "Already Visited Bonds:\t";
     2434        for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
     2435        *out << endl;
    24372436};
    24382437
     
    24402439 * The upper limit is
    24412440 * \f[
    2442  *  n = N \cdot C^k
     2441 *      n = N \cdot C^k
    24432442 * \f]
    24442443 * where \f$C=2^c\f$ and c is the maximum bond degree over N number of atoms.
     
    24492448int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    24502449{
    2451   int c = 0;
    2452   int FragmentCount;
    2453   // get maximum bond degree
    2454   atom *Walker = start;
    2455   while (Walker->next != end) {
    2456     Walker = Walker->next;
    2457     c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
    2458   }
    2459   FragmentCount = NoNonHydrogen*(1 << (c*order));
    2460   *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    2461   return FragmentCount;
     2450        int c = 0;
     2451        int FragmentCount;
     2452        // get maximum bond degree
     2453        atom *Walker = start;
     2454        while (Walker->next != end) {
     2455                Walker = Walker->next;
     2456                c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     2457        }
     2458        FragmentCount = NoNonHydrogen*(1 << (c*order));
     2459        *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
     2460        return FragmentCount;
    24622461};
    24632462
     
    24702469bool molecule::ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet)
    24712470{
    2472   stringstream line;
    2473   int AtomNr;
    2474   int status = 0;
    2475 
    2476   line.str(buffer);
    2477   while (!line.eof()) {
    2478     line >> AtomNr;
    2479     if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2480       CurrentSet.insert(AtomNr);  // insert at end, hence in same order as in file!
    2481       status++;
    2482     } // else it's "-1" or else and thus must not be added
    2483   }
    2484   *out << Verbose(1) << "The scanned KeySet is ";
    2485   for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
    2486     *out << (*runner) << "\t";
    2487   }
    2488   *out << endl;
    2489   return (status != 0);
     2471        stringstream line;
     2472        int AtomNr;
     2473        int status = 0;
     2474
     2475        line.str(buffer);
     2476        while (!line.eof()) {
     2477                line >> AtomNr;
     2478                if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2479                        CurrentSet.insert(AtomNr);      // insert at end, hence in same order as in file!
     2480                        status++;
     2481                } // else it's "-1" or else and thus must not be added
     2482        }
     2483        *out << Verbose(1) << "The scanned KeySet is ";
     2484        for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
     2485                *out << (*runner) << "\t";
     2486        }
     2487        *out << endl;
     2488        return (status != 0);
    24902489};
    24912490
     
    25022501bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList)
    25032502{
    2504   bool status = true;
    2505   ifstream InputFile;
    2506   stringstream line;
    2507   GraphTestPair testGraphInsert;
    2508   int NumberOfFragments = 0;
    2509   double TEFactor;
    2510   char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2511 
    2512   if (FragmentList == NULL) { // check list pointer
    2513     FragmentList = new Graph;
    2514   }
    2515 
    2516   // 1st pass: open file and read
    2517   *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
    2518   sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
    2519   InputFile.open(filename);
    2520   if (InputFile != NULL) {
    2521     // each line represents a new fragment
    2522     char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
    2523     // 1. parse keysets and insert into temp. graph
    2524     while (!InputFile.eof()) {
    2525       InputFile.getline(buffer, MAXSTRINGSIZE);
    2526       KeySet CurrentSet;
    2527       if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
    2528         testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1)));  // store fragment number and current factor
    2529         if (!testGraphInsert.second) {
    2530           cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    2531         }
    2532         //FragmentList->ListOfMolecules[NumberOfFragments++] = StoreFragmentFromKeySet(out, CurrentSet, IsAngstroem);
    2533       }
    2534     }
    2535     // 2. Free and done
    2536     InputFile.close();
    2537     InputFile.clear();
    2538     Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
    2539     *out << Verbose(1) << "done." << endl;
    2540   } else {
    2541     *out << Verbose(1) << "File " << filename << " not found." << endl;
    2542     status = false;
    2543   }
    2544 
    2545   // 2nd pass: open TEFactors file and read
    2546   *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
    2547   sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
    2548   InputFile.open(filename);
    2549   if (InputFile != NULL) {
    2550     // 3. add found TEFactors to each keyset
    2551     NumberOfFragments = 0;
    2552     for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
    2553       if (!InputFile.eof()) {
    2554         InputFile >> TEFactor;
    2555         (*runner).second.second = TEFactor;
    2556         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    2557       } else {
    2558         status = false;
    2559         break;
    2560       }
    2561     }
    2562     // 4. Free and done
    2563     InputFile.close();
    2564     *out << Verbose(1) << "done." << endl;
    2565   } else {
    2566     *out << Verbose(1) << "File " << filename << " not found." << endl;
    2567     status = false;
    2568   }
    2569 
    2570   // free memory
    2571   Free((void **)&filename, "molecule::ParseKeySetFile - filename");
    2572 
    2573   return status;
     2503        bool status = true;
     2504        ifstream InputFile;
     2505        stringstream line;
     2506        GraphTestPair testGraphInsert;
     2507        int NumberOfFragments = 0;
     2508        double TEFactor;
     2509        char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
     2510
     2511        if (FragmentList == NULL) { // check list pointer
     2512                FragmentList = new Graph;
     2513        }
     2514
     2515        // 1st pass: open file and read
     2516        *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     2517        sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
     2518        InputFile.open(filename);
     2519        if (InputFile != NULL) {
     2520                // each line represents a new fragment
     2521                char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
     2522                // 1. parse keysets and insert into temp. graph
     2523                while (!InputFile.eof()) {
     2524                        InputFile.getline(buffer, MAXSTRINGSIZE);
     2525                        KeySet CurrentSet;
     2526                        if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
     2527                                testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
     2528                                if (!testGraphInsert.second) {
     2529                                        cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
     2530                                }
     2531                                //FragmentList->ListOfMolecules[NumberOfFragments++] = StoreFragmentFromKeySet(out, CurrentSet, IsAngstroem);
     2532                        }
     2533                }
     2534                // 2. Free and done
     2535                InputFile.close();
     2536                InputFile.clear();
     2537                Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
     2538                *out << Verbose(1) << "done." << endl;
     2539        } else {
     2540                *out << Verbose(1) << "File " << filename << " not found." << endl;
     2541                status = false;
     2542        }
     2543
     2544        // 2nd pass: open TEFactors file and read
     2545        *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     2546        sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
     2547        InputFile.open(filename);
     2548        if (InputFile != NULL) {
     2549                // 3. add found TEFactors to each keyset
     2550                NumberOfFragments = 0;
     2551                for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
     2552                        if (!InputFile.eof()) {
     2553                                InputFile >> TEFactor;
     2554                                (*runner).second.second = TEFactor;
     2555                                *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2556                        } else {
     2557                                status = false;
     2558                                break;
     2559                        }
     2560                }
     2561                // 4. Free and done
     2562                InputFile.close();
     2563                *out << Verbose(1) << "done." << endl;
     2564        } else {
     2565                *out << Verbose(1) << "File " << filename << " not found." << endl;
     2566                status = false;
     2567        }
     2568
     2569        // free memory
     2570        Free((void **)&filename, "molecule::ParseKeySetFile - filename");
     2571
     2572        return status;
    25742573};
    25752574
     
    25822581bool molecule::StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path)
    25832582{
    2584   ofstream output;
    2585   bool status =  true;
    2586   string line;
    2587 
    2588   // open KeySet file
    2589   line = path;
    2590   line.append("/");
    2591   line += FRAGMENTPREFIX;
    2592   line += KEYSETFILE;
    2593   output.open(line.c_str(), ios::out);
    2594   *out << Verbose(1) << "Saving key sets of the total graph ... ";
    2595   if(output != NULL) {
    2596     for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2597       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    2598         if (sprinter != (*runner).first.begin())
    2599           output << "\t";
    2600         output << *sprinter;
    2601       }
    2602       output << endl;
    2603     }
    2604     *out << "done." << endl;
    2605   } else {
    2606     cerr << "Unable to open " << line << " for writing keysets!" << endl;
    2607     status = false;
    2608   }
    2609   output.close();
    2610   output.clear();
    2611 
    2612   // open TEFactors file
    2613   line = path;
    2614   line.append("/");
    2615   line += FRAGMENTPREFIX;
    2616   line += TEFACTORSFILE;
    2617   output.open(line.c_str(), ios::out);
    2618   *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
    2619   if(output != NULL) {
    2620     for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
    2621       output << (*runner).second.second << endl;
    2622     *out << Verbose(1) << "done." << endl;
    2623   } else {
    2624     *out << Verbose(1) << "failed to open " << line << "." << endl;
    2625     status = false;
    2626   }
    2627   output.close();
    2628 
    2629   return status;
     2583        ofstream output;
     2584        bool status =   true;
     2585        string line;
     2586
     2587        // open KeySet file
     2588        line = path;
     2589        line.append("/");
     2590        line += FRAGMENTPREFIX;
     2591        line += KEYSETFILE;
     2592        output.open(line.c_str(), ios::out);
     2593        *out << Verbose(1) << "Saving key sets of the total graph ... ";
     2594        if(output != NULL) {
     2595                for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
     2596                        for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     2597                                if (sprinter != (*runner).first.begin())
     2598                                        output << "\t";
     2599                                output << *sprinter;
     2600                        }
     2601                        output << endl;
     2602                }
     2603                *out << "done." << endl;
     2604        } else {
     2605                cerr << "Unable to open " << line << " for writing keysets!" << endl;
     2606                status = false;
     2607        }
     2608        output.close();
     2609        output.clear();
     2610
     2611        // open TEFactors file
     2612        line = path;
     2613        line.append("/");
     2614        line += FRAGMENTPREFIX;
     2615        line += TEFACTORSFILE;
     2616        output.open(line.c_str(), ios::out);
     2617        *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
     2618        if(output != NULL) {
     2619                for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
     2620                        output << (*runner).second.second << endl;
     2621                *out << Verbose(1) << "done." << endl;
     2622        } else {
     2623                *out << Verbose(1) << "failed to open " << line << "." << endl;
     2624                status = false;
     2625        }
     2626        output.close();
     2627
     2628        return status;
    26302629};
    26312630
     
    26382637bool molecule::StoreAdjacencyToFile(ofstream *out, char *path)
    26392638{
    2640   ofstream AdjacencyFile;
    2641   atom *Walker = NULL;
    2642   stringstream line;
    2643   bool status = true;
    2644 
    2645   line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2646   AdjacencyFile.open(line.str().c_str(), ios::out);
    2647   *out << Verbose(1) << "Saving adjacency list ... ";
    2648   if (AdjacencyFile != NULL) {
    2649     Walker = start;
    2650     while(Walker->next != end) {
    2651       Walker = Walker->next;
    2652       AdjacencyFile << Walker->nr << "\t";
    2653       for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    2654         AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    2655       AdjacencyFile << endl;
    2656     }
    2657     AdjacencyFile.close();
    2658     *out << Verbose(1) << "done." << endl;
    2659   } else {
    2660     *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    2661     status = false;
    2662   }
    2663 
    2664   return status;
     2639        ofstream AdjacencyFile;
     2640        atom *Walker = NULL;
     2641        stringstream line;
     2642        bool status = true;
     2643
     2644        line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2645        AdjacencyFile.open(line.str().c_str(), ios::out);
     2646        *out << Verbose(1) << "Saving adjacency list ... ";
     2647        if (AdjacencyFile != NULL) {
     2648                Walker = start;
     2649                while(Walker->next != end) {
     2650                        Walker = Walker->next;
     2651                        AdjacencyFile << Walker->nr << "\t";
     2652                        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
     2653                                AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
     2654                        AdjacencyFile << endl;
     2655                }
     2656                AdjacencyFile.close();
     2657                *out << Verbose(1) << "done." << endl;
     2658        } else {
     2659                *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     2660                status = false;
     2661        }
     2662
     2663        return status;
    26652664};
    26662665
     
    26732672bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    26742673{
    2675   ifstream File;
    2676   stringstream filename;
    2677   bool status = true;
    2678   char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2679 
    2680   filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2681   File.open(filename.str().c_str(), ios::out);
    2682   *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
    2683   if (File != NULL) {
    2684     // allocate storage structure
    2685     int NonMatchNumber = 0;  // will number of atoms with differing bond structure
    2686     int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    2687     int CurrentBondsOfAtom;
    2688 
    2689     // Parse the file line by line and count the bonds
    2690     while (!File.eof()) {
    2691       File.getline(buffer, MAXSTRINGSIZE);
    2692       stringstream line;
    2693       line.str(buffer);
    2694       int AtomNr = -1;
    2695       line >> AtomNr;
    2696       CurrentBondsOfAtom = -1; // we count one too far due to line end
    2697       // parse into structure
    2698       if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2699         while (!line.eof())
    2700           line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    2701         // compare against present bonds
    2702         //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    2703         if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    2704           for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    2705             int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    2706             int j = 0;
    2707             for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    2708             if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
    2709               ListOfAtoms[AtomNr] = NULL;
    2710               NonMatchNumber++;
    2711               status = false;
    2712               //out << "[" << id << "]\t";
    2713             } else {
    2714               //out << id << "\t";
    2715             }
    2716           }
    2717           //out << endl;
    2718         } else {
    2719           *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
    2720           status = false;
    2721         }
    2722       }
    2723     }
    2724     File.close();
    2725     File.clear();
    2726     if (status) { // if equal we parse the KeySetFile
    2727       *out << Verbose(1) << "done: Equal." << endl;
    2728       status = true;
    2729     } else
    2730       *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    2731     Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
    2732   } else {
    2733     *out << Verbose(1) << "Adjacency file not found." << endl;
    2734     status = false;
    2735   }
    2736   *out << endl;
    2737   Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2738 
    2739   return status;
     2674        ifstream File;
     2675        stringstream filename;
     2676        bool status = true;
     2677        char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2678
     2679        filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2680        File.open(filename.str().c_str(), ios::out);
     2681        *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
     2682        if (File != NULL) {
     2683                // allocate storage structure
     2684                int NonMatchNumber = 0; // will number of atoms with differing bond structure
     2685                int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
     2686                int CurrentBondsOfAtom;
     2687
     2688                // Parse the file line by line and count the bonds
     2689                while (!File.eof()) {
     2690                        File.getline(buffer, MAXSTRINGSIZE);
     2691                        stringstream line;
     2692                        line.str(buffer);
     2693                        int AtomNr = -1;
     2694                        line >> AtomNr;
     2695                        CurrentBondsOfAtom = -1; // we count one too far due to line end
     2696                        // parse into structure
     2697                        if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2698                                while (!line.eof())
     2699                                        line >> CurrentBonds[ ++CurrentBondsOfAtom ];
     2700                                // compare against present bonds
     2701                                //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
     2702                                if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
     2703                                        for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
     2704                                                int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
     2705                                                int j = 0;
     2706                                                for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
     2707                                                if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
     2708                                                        ListOfAtoms[AtomNr] = NULL;
     2709                                                        NonMatchNumber++;
     2710                                                        status = false;
     2711                                                        //out << "[" << id << "]\t";
     2712                                                } else {
     2713                                                        //out << id << "\t";
     2714                                                }
     2715                                        }
     2716                                        //out << endl;
     2717                                } else {
     2718                                        *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
     2719                                        status = false;
     2720                                }
     2721                        }
     2722                }
     2723                File.close();
     2724                File.clear();
     2725                if (status) { // if equal we parse the KeySetFile
     2726                        *out << Verbose(1) << "done: Equal." << endl;
     2727                        status = true;
     2728                } else
     2729                        *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
     2730                Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
     2731        } else {
     2732                *out << Verbose(1) << "Adjacency file not found." << endl;
     2733                status = false;
     2734        }
     2735        *out << endl;
     2736        Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2737
     2738        return status;
    27402739};
    27412740
     
    27512750bool molecule::CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path)
    27522751{
    2753   atom *Walker = start;
    2754   bool status = false;
    2755   ifstream InputFile;
    2756 
    2757   // initialize mask list
    2758   for(int i=AtomCount;i--;)
    2759     AtomMask[i] = false;
    2760 
    2761   if (Order < 0) { // adaptive increase of BondOrder per site
    2762     if (AtomMask[AtomCount] == true)  // break after one step
    2763       return false;
    2764     // parse the EnergyPerFragment file
    2765     char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
    2766     sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
    2767     InputFile.open(buffer, ios::in);
    2768     if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
    2769       // transmorph graph keyset list into indexed KeySetList
    2770       map<int,KeySet> IndexKeySetList;
    2771       for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
    2772         IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
    2773       }
    2774       int lines = 0;
    2775       // count the number of lines, i.e. the number of fragments
    2776       InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2777       InputFile.getline(buffer, MAXSTRINGSIZE);
    2778       while(!InputFile.eof()) {
    2779         InputFile.getline(buffer, MAXSTRINGSIZE);
    2780         lines++;
    2781       }
    2782       //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;  // one endline too much
    2783       InputFile.clear();
    2784       InputFile.seekg(ios::beg);
    2785       map<int, pair<double,int> > AdaptiveCriteriaList;  // (Root No., (Value, Order)) !
    2786       int No, FragOrder;
    2787       double Value;
    2788       // each line represents a fragment root (Atom::nr) id and its energy contribution
    2789       InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2790       InputFile.getline(buffer, MAXSTRINGSIZE);
    2791       while(!InputFile.eof()) {
    2792         InputFile.getline(buffer, MAXSTRINGSIZE);
    2793         if (strlen(buffer) > 2) {
    2794           //*out << Verbose(2) << "Scanning: " << buffer << endl;
    2795           stringstream line(buffer);
    2796           line >> FragOrder;
    2797           line >> ws >> No;
    2798           line >> ws >> Value; // skip time entry
    2799           line >> ws >> Value;
    2800           No -= 1;  // indices start at 1 in file, not 0
    2801           //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    2802 
    2803           // clean the list of those entries that have been superceded by higher order terms already
    2804           map<int,KeySet>::iterator marker = IndexKeySetList.find(No);    // find keyset to Frag No.
    2805           if (marker != IndexKeySetList.end()) {  // if found
    2806             Value *= 1 + MYEPSILON*(*((*marker).second.begin()));    // in case of equal energies this makes em not equal without changing anything actually
    2807             // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
    2808             pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2809             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    2810             if (!InsertedElement.second) { // this root is already present
    2811               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
    2812                 //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
    2813                 {  // if value is smaller, update value and order
    2814                 (*PresentItem).second.first = fabs(Value);
    2815                 (*PresentItem).second.second = FragOrder;
    2816                 *out << Verbose(2) << "Updated element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2817               } else {
    2818                 *out << Verbose(2) << "Did not update element " <<  (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
    2819               }
    2820             } else {
    2821               *out << Verbose(2) << "Inserted element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2822             }
    2823           } else {
    2824             *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
    2825           }
    2826         }
    2827       }
    2828       // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
    2829       map<double, pair<int,int> > FinalRootCandidates;
    2830       *out << Verbose(1) << "Root candidate list is: " << endl;
    2831       for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
    2832         Walker = FindAtom((*runner).first);
    2833         if (Walker != NULL) {
    2834           //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
    2835           if (!Walker->MaxOrder) {
    2836             *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
    2837             FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
    2838           } else {
    2839             *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
    2840           }
    2841         } else {
    2842           cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
    2843         }
    2844       }
    2845       // pick the ones still below threshold and mark as to be adaptively updated
    2846       for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
    2847         No = (*runner).second.first;
    2848         Walker = FindAtom(No);
    2849         //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2850           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    2851           AtomMask[No] = true;
    2852           status = true;
    2853         //} else
    2854           //*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;
    2855       }
    2856       // close and done
    2857       InputFile.close();
    2858       InputFile.clear();
    2859     } else {
    2860       cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
    2861       while (Walker->next != end) {
    2862         Walker = Walker->next;
    2863     #ifdef ADDHYDROGEN
    2864         if (Walker->type->Z != 1) // skip hydrogen
    2865     #endif
    2866         {
    2867           AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
    2868           status = true;
    2869         }
    2870       }
    2871     }
    2872     Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
    2873     // pick a given number of highest values and set AtomMask
    2874   } else { // global increase of Bond Order
    2875     while (Walker->next != end) {
    2876       Walker = Walker->next;
    2877   #ifdef ADDHYDROGEN
    2878       if (Walker->type->Z != 1) // skip hydrogen
    2879   #endif
    2880       {
    2881         AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
    2882         if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
    2883           status = true;
    2884       }
    2885     }
    2886     if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    2887       status = true;
    2888 
    2889     if (!status) {
    2890       if (Order == 0)
    2891         *out << Verbose(1) << "Single stepping done." << endl;
    2892       else
    2893         *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
    2894     }
    2895   }
    2896 
    2897   // print atom mask for debugging
    2898   *out << "              ";
    2899   for(int i=0;i<AtomCount;i++)
    2900     *out << (i % 10);
    2901   *out << endl << "Atom mask is: ";
    2902   for(int i=0;i<AtomCount;i++)
    2903     *out << (AtomMask[i] ? "t" : "f");
    2904   *out << endl;
    2905 
    2906   return status;
     2752        atom *Walker = start;
     2753        bool status = false;
     2754        ifstream InputFile;
     2755
     2756        // initialize mask list
     2757        for(int i=AtomCount;i--;)
     2758                AtomMask[i] = false;
     2759
     2760        if (Order < 0) { // adaptive increase of BondOrder per site
     2761                if (AtomMask[AtomCount] == true)        // break after one step
     2762                        return false;
     2763                // parse the EnergyPerFragment file
     2764                char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
     2765                sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
     2766                InputFile.open(buffer, ios::in);
     2767                if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
     2768                        // transmorph graph keyset list into indexed KeySetList
     2769                        map<int,KeySet> IndexKeySetList;
     2770                        for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
     2771                                IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
     2772                        }
     2773                        int lines = 0;
     2774                        // count the number of lines, i.e. the number of fragments
     2775                        InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2776                        InputFile.getline(buffer, MAXSTRINGSIZE);
     2777                        while(!InputFile.eof()) {
     2778                                InputFile.getline(buffer, MAXSTRINGSIZE);
     2779                                lines++;
     2780                        }
     2781                        //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;      // one endline too much
     2782                        InputFile.clear();
     2783                        InputFile.seekg(ios::beg);
     2784                        map<int, pair<double,int> > AdaptiveCriteriaList;       // (Root No., (Value, Order)) !
     2785                        int No, FragOrder;
     2786                        double Value;
     2787                        // each line represents a fragment root (Atom::nr) id and its energy contribution
     2788                        InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2789                        InputFile.getline(buffer, MAXSTRINGSIZE);
     2790                        while(!InputFile.eof()) {
     2791                                InputFile.getline(buffer, MAXSTRINGSIZE);
     2792                                if (strlen(buffer) > 2) {
     2793                                        //*out << Verbose(2) << "Scanning: " << buffer << endl;
     2794                                        stringstream line(buffer);
     2795                                        line >> FragOrder;
     2796                                        line >> ws >> No;
     2797                                        line >> ws >> Value; // skip time entry
     2798                                        line >> ws >> Value;
     2799                                        No -= 1;        // indices start at 1 in file, not 0
     2800                                        //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
     2801
     2802                                        // clean the list of those entries that have been superceded by higher order terms already
     2803                                        map<int,KeySet>::iterator marker = IndexKeySetList.find(No);            // find keyset to Frag No.
     2804                                        if (marker != IndexKeySetList.end()) {  // if found
     2805                                                Value *= 1 + MYEPSILON*(*((*marker).second.begin()));            // in case of equal energies this makes em not equal without changing anything actually
     2806                                                // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
     2807                                                pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
     2808                                                map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     2809                                                if (!InsertedElement.second) { // this root is already present
     2810                                                        if ((*PresentItem).second.second < FragOrder)   // if order there is lower, update entry with higher-order term
     2811                                                                //if ((*PresentItem).second.first < (*runner).first)            // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
     2812                                                                {       // if value is smaller, update value and order
     2813                                                                (*PresentItem).second.first = fabs(Value);
     2814                                                                (*PresentItem).second.second = FragOrder;
     2815                                                                *out << Verbose(2) << "Updated element (" <<    (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2816                                                        } else {
     2817                                                                *out << Verbose(2) << "Did not update element " <<      (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
     2818                                                        }
     2819                                                } else {
     2820                                                        *out << Verbose(2) << "Inserted element (" <<   (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2821                                                }
     2822                                        } else {
     2823                                                *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
     2824                                        }
     2825                                }
     2826                        }
     2827                        // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
     2828                        map<double, pair<int,int> > FinalRootCandidates;
     2829                        *out << Verbose(1) << "Root candidate list is: " << endl;
     2830                        for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
     2831                                Walker = FindAtom((*runner).first);
     2832                                if (Walker != NULL) {
     2833                                        //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2834                                        if (!Walker->MaxOrder) {
     2835                                                *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
     2836                                                FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
     2837                                        } else {
     2838                                                *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
     2839                                        }
     2840                                } else {
     2841                                        cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
     2842                                }
     2843                        }
     2844                        // pick the ones still below threshold and mark as to be adaptively updated
     2845                        for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
     2846                                No = (*runner).second.first;
     2847                                Walker = FindAtom(No);
     2848                                //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
     2849                                        *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     2850                                        AtomMask[No] = true;
     2851                                        status = true;
     2852                                //} else
     2853                                        //*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;
     2854                        }
     2855                        // close and done
     2856                        InputFile.close();
     2857                        InputFile.clear();
     2858                } else {
     2859                        cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
     2860                        while (Walker->next != end) {
     2861                                Walker = Walker->next;
     2862                #ifdef ADDHYDROGEN
     2863                                if (Walker->type->Z != 1) // skip hydrogen
     2864                #endif
     2865                                {
     2866                                        AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
     2867                                        status = true;
     2868                                }
     2869                        }
     2870                }
     2871                Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
     2872                // pick a given number of highest values and set AtomMask
     2873        } else { // global increase of Bond Order
     2874                while (Walker->next != end) {
     2875                        Walker = Walker->next;
     2876        #ifdef ADDHYDROGEN
     2877                        if (Walker->type->Z != 1) // skip hydrogen
     2878        #endif
     2879                        {
     2880                                AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
     2881                                if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
     2882                                        status = true;
     2883                        }
     2884                }
     2885                if ((Order == 0) && (AtomMask[AtomCount] == false))     // single stepping, just check
     2886                        status = true;
     2887
     2888                if (!status) {
     2889                        if (Order == 0)
     2890                                *out << Verbose(1) << "Single stepping done." << endl;
     2891                        else
     2892                                *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2893                }
     2894        }
     2895
     2896        // print atom mask for debugging
     2897        *out << "                                                       ";
     2898        for(int i=0;i<AtomCount;i++)
     2899                *out << (i % 10);
     2900        *out << endl << "Atom mask is: ";
     2901        for(int i=0;i<AtomCount;i++)
     2902                *out << (AtomMask[i] ? "t" : "f");
     2903        *out << endl;
     2904
     2905        return status;
    29072906};
    29082907
     
    29142913bool molecule::CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex)
    29152914{
    2916   element *runner = elemente->start;
    2917   int AtomNo = 0;
    2918   atom *Walker = NULL;
    2919 
    2920   if (SortIndex != NULL) {
    2921     *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
    2922     return false;
    2923   }
    2924   SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
    2925   for(int i=AtomCount;i--;)
    2926     SortIndex[i] = -1;
    2927   while (runner->next != elemente->end) { // go through every element
    2928     runner = runner->next;
    2929     if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    2930       Walker = start;
    2931       while (Walker->next != end) { // go through every atom of this element
    2932         Walker = Walker->next;
    2933         if (Walker->type->Z == runner->Z) // if this atom fits to element
    2934           SortIndex[Walker->nr] = AtomNo++;
    2935       }
    2936     }
    2937   }
    2938   return true;
     2915        element *runner = elemente->start;
     2916        int AtomNo = 0;
     2917        atom *Walker = NULL;
     2918
     2919        if (SortIndex != NULL) {
     2920                *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     2921                return false;
     2922        }
     2923        SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
     2924        for(int i=AtomCount;i--;)
     2925                SortIndex[i] = -1;
     2926        while (runner->next != elemente->end) { // go through every element
     2927                runner = runner->next;
     2928                if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     2929                        Walker = start;
     2930                        while (Walker->next != end) { // go through every atom of this element
     2931                                Walker = Walker->next;
     2932                                if (Walker->type->Z == runner->Z) // if this atom fits to element
     2933                                        SortIndex[Walker->nr] = AtomNo++;
     2934                        }
     2935                }
     2936        }
     2937        return true;
    29392938};
    29402939
     
    29452944y contribution", and that's why this consciously not done in the following loop)
    29462945 * -# in a loop over all subgraphs
    2947  *  -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
    2948  *  -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
     2946 *      -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
     2947 *      -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
    29492948 * -# combines the generated molecule lists from all subgraphs
    29502949 * -# saves to disk: fragment configs, adjacency, orderatsite, keyset files
     
    29602959{
    29612960        MoleculeListClass *BondFragments = NULL;
    2962   int *SortIndex = NULL;
    2963   int *MinimumRingSize = new int[AtomCount];
    2964   int FragmentCounter;
    2965   MoleculeLeafClass *MolecularWalker = NULL;
    2966   MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
    2967   fstream File;
    2968   bool FragmentationToDo = true;
    2969   class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
    2970   bool CheckOrder = false;
    2971   Graph **FragmentList = NULL;
    2972   Graph *ParsedFragmentList = NULL;
    2973   Graph TotalGraph;    // graph with all keysets however local numbers
    2974   int TotalNumberOfKeySets = 0;
    2975   atom **ListOfAtoms = NULL;
    2976   atom ***ListOfLocalAtoms = NULL;
    2977   bool *AtomMask = NULL;
    2978 
    2979   *out << endl;
     2961        int *SortIndex = NULL;
     2962        int *MinimumRingSize = new int[AtomCount];
     2963        int FragmentCounter;
     2964        MoleculeLeafClass *MolecularWalker = NULL;
     2965        MoleculeLeafClass *Subgraphs = NULL;                    // list of subgraphs from DFS analysis
     2966        fstream File;
     2967        bool FragmentationToDo = true;
     2968        class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
     2969        bool CheckOrder = false;
     2970        Graph **FragmentList = NULL;
     2971        Graph *ParsedFragmentList = NULL;
     2972        Graph TotalGraph;                // graph with all keysets however local numbers
     2973        int TotalNumberOfKeySets = 0;
     2974        atom **ListOfAtoms = NULL;
     2975        atom ***ListOfLocalAtoms = NULL;
     2976        bool *AtomMask = NULL;
     2977
     2978        *out << endl;
    29802979#ifdef ADDHYDROGEN
    2981   *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
     2980        *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
    29822981#else
    2983   *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
     2982        *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
    29842983#endif
    29852984
    2986   // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    2987 
    2988   // ===== 1. Check whether bond structure is same as stored in files ====
    2989 
    2990   // fill the adjacency list
    2991   CreateListOfBondsPerAtom(out);
    2992 
    2993   // create lookup table for Atom::nr
    2994   FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    2995 
    2996   // === compare it with adjacency file ===
    2997   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    2998   Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    2999 
    3000   // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    3001   Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    3002   // fill the bond structure of the individually stored subgraphs
    3003   Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
    3004   // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
    3005   for(int i=AtomCount;i--;)
    3006     MinimumRingSize[i] = AtomCount;
    3007   MolecularWalker = Subgraphs;
    3008   FragmentCounter = 0;
    3009   while (MolecularWalker->next != NULL) {
    3010     MolecularWalker = MolecularWalker->next;
    3011     LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    3012 //    // check the list of local atoms for debugging
    3013 //    *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
    3014 //    for (int i=0;i<AtomCount;i++)
    3015 //      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
    3016 //        *out << "\tNULL";
    3017 //      else
    3018 //        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3019     *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3020     MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3021     *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3022     MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3023     *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3024     delete(LocalBackEdgeStack);
    3025   }
    3026 
    3027   // ===== 3. if structure still valid, parse key set file and others =====
    3028   FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
    3029 
    3030   // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    3031   FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3032 
    3033   // =================================== Begin of FRAGMENTATION ===============================
    3034   // ===== 6a. assign each keyset to its respective subgraph =====
    3035   Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    3036 
    3037   // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
    3038   KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
    3039   AtomMask = new bool[AtomCount+1];
    3040   AtomMask[AtomCount] = false;
    3041   FragmentationToDo = false;  // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
    3042   while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
    3043     FragmentationToDo = FragmentationToDo || CheckOrder;
    3044     AtomMask[AtomCount] = true;  // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3045     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    3046     Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    3047 
    3048     // ===== 7. fill the bond fragment list =====
    3049     FragmentCounter = 0;
    3050     MolecularWalker = Subgraphs;
    3051     while (MolecularWalker->next != NULL) {
    3052       MolecularWalker = MolecularWalker->next;
    3053       *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3054       //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
    3055       if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3056         // call BOSSANOVA method
    3057         *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
    3058         MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
    3059       } else {
    3060         cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
    3061       }
    3062       FragmentCounter++;  // next fragment list
    3063     }
    3064   }
    3065   delete[](RootStack);
    3066   delete[](AtomMask);
    3067   delete(ParsedFragmentList);
    3068   delete[](MinimumRingSize);
    3069 
    3070 
    3071   // ==================================== End of FRAGMENTATION ============================================
    3072 
    3073   // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    3074   Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3075 
    3076   // free subgraph memory again
    3077   FragmentCounter = 0;
    3078   if (Subgraphs != NULL) {
    3079     while (Subgraphs->next != NULL) {
    3080       Subgraphs = Subgraphs->next;
    3081       delete(FragmentList[FragmentCounter++]);
    3082       delete(Subgraphs->previous);
    3083     }
    3084     delete(Subgraphs);
    3085   }
    3086   Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
    3087 
    3088   // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    3089   //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    3090     // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3091     BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
    3092     int k=0;
    3093     for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    3094       KeySet test = (*runner).first;
    3095       *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    3096       BondFragments->ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);
    3097       k++;
    3098     }
    3099     *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3100 
    3101     // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3102     if (BondFragments->NumberOfMolecules != 0) {
    3103       // create the SortIndex from BFS labels to order in the config file
    3104       CreateMappingLabelsToConfigSequence(out, SortIndex);
    3105 
    3106       *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    3107       if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    3108         *out << Verbose(1) << "All configs written." << endl;
    3109       else
    3110         *out << Verbose(1) << "Some config writing failed." << endl;
    3111 
    3112       // store force index reference file
    3113       BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3114 
    3115       // store keysets file
    3116       StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3117 
    3118       // store Adjacency file
    3119       StoreAdjacencyToFile(out, configuration->configpath);
    3120 
    3121       // store Hydrogen saturation correction file
    3122       BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3123 
    3124       // store adaptive orders into file
    3125       StoreOrderAtSiteFile(out, configuration->configpath);
    3126 
    3127       // restore orbital and Stop values
    3128       CalculateOrbitals(*configuration);
    3129 
    3130       // free memory for bond part
    3131       *out << Verbose(1) << "Freeing bond memory" << endl;
    3132       delete(FragmentList); // remove bond molecule from memory
    3133       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    3134     } else
    3135       *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3136   //} else
    3137   //  *out << Verbose(1) << "No fragments to store." << endl;
    3138   *out << Verbose(0) << "End of bond fragmentation." << endl;
    3139 
    3140   return ((int)(!FragmentationToDo)+1);    // 1 - continue, 2 - stop (no fragmentation occured)
     2985        // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
     2986
     2987        // ===== 1. Check whether bond structure is same as stored in files ====
     2988
     2989        // fill the adjacency list
     2990        CreateListOfBondsPerAtom(out);
     2991
     2992        // create lookup table for Atom::nr
     2993        FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
     2994
     2995        // === compare it with adjacency file ===
     2996        FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     2997        Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
     2998
     2999        // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
     3000        Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     3001        // fill the bond structure of the individually stored subgraphs
     3002        Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);     // we want to keep the created ListOfLocalAtoms
     3003        // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
     3004        for(int i=AtomCount;i--;)
     3005                MinimumRingSize[i] = AtomCount;
     3006        MolecularWalker = Subgraphs;
     3007        FragmentCounter = 0;
     3008        while (MolecularWalker->next != NULL) {
     3009                MolecularWalker = MolecularWalker->next;
     3010                LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     3011//              // check the list of local atoms for debugging
     3012//              *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
     3013//              for (int i=0;i<AtomCount;i++)
     3014//                      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
     3015//                              *out << "\tNULL";
     3016//                      else
     3017//                              *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3018                *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3019                MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3020                *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3021                MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3022                *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3023                delete(LocalBackEdgeStack);
     3024        }
     3025
     3026        // ===== 3. if structure still valid, parse key set file and others =====
     3027        FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     3028
     3029        // ===== 4. check globally whether there's something to do actually (first adaptivity check)
     3030        FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
     3031
     3032        // =================================== Begin of FRAGMENTATION ===============================
     3033        // ===== 6a. assign each keyset to its respective subgraph =====
     3034        Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
     3035
     3036        // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
     3037        KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
     3038        AtomMask = new bool[AtomCount+1];
     3039        AtomMask[AtomCount] = false;
     3040        FragmentationToDo = false;      // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
     3041        while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
     3042                FragmentationToDo = FragmentationToDo || CheckOrder;
     3043                AtomMask[AtomCount] = true;      // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
     3044                // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3045                Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
     3046
     3047                // ===== 7. fill the bond fragment list =====
     3048                FragmentCounter = 0;
     3049                MolecularWalker = Subgraphs;
     3050                while (MolecularWalker->next != NULL) {
     3051                        MolecularWalker = MolecularWalker->next;
     3052                        *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
     3053                        //MolecularWalker->Leaf->OutputListOfBonds(out);        // output ListOfBondsPerAtom for debugging
     3054                        if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3055                                // call BOSSANOVA method
     3056                                *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     3057                                MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
     3058                        } else {
     3059                                cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
     3060                        }
     3061                        FragmentCounter++;      // next fragment list
     3062                }
     3063        }
     3064        delete[](RootStack);
     3065        delete[](AtomMask);
     3066        delete(ParsedFragmentList);
     3067        delete[](MinimumRingSize);
     3068
     3069
     3070        // ==================================== End of FRAGMENTATION ============================================
     3071
     3072        // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
     3073        Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
     3074
     3075        // free subgraph memory again
     3076        FragmentCounter = 0;
     3077        if (Subgraphs != NULL) {
     3078                while (Subgraphs->next != NULL) {
     3079                        Subgraphs = Subgraphs->next;
     3080                        delete(FragmentList[FragmentCounter++]);
     3081                        delete(Subgraphs->previous);
     3082                }
     3083                delete(Subgraphs);
     3084        }
     3085        Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
     3086
     3087        // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
     3088        //if (FragmentationToDo) {              // we should always store the fragments again as coordination might have changed slightly without changing bond structure
     3089                // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     3090                BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
     3091                int k=0;
     3092                for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     3093                        KeySet test = (*runner).first;
     3094                        *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     3095                        BondFragments->ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);
     3096                        k++;
     3097                }
     3098                *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
     3099
     3100                // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     3101                if (BondFragments->NumberOfMolecules != 0) {
     3102                        // create the SortIndex from BFS labels to order in the config file
     3103                        CreateMappingLabelsToConfigSequence(out, SortIndex);
     3104
     3105                        *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
     3106                        if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     3107                                *out << Verbose(1) << "All configs written." << endl;
     3108                        else
     3109                                *out << Verbose(1) << "Some config writing failed." << endl;
     3110
     3111                        // store force index reference file
     3112                        BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     3113
     3114                        // store keysets file
     3115                        StoreKeySetFile(out, TotalGraph, configuration->configpath);
     3116
     3117                        // store Adjacency file
     3118                        StoreAdjacencyToFile(out, configuration->configpath);
     3119
     3120                        // store Hydrogen saturation correction file
     3121                        BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     3122
     3123                        // store adaptive orders into file
     3124                        StoreOrderAtSiteFile(out, configuration->configpath);
     3125
     3126                        // restore orbital and Stop values
     3127                        CalculateOrbitals(*configuration);
     3128
     3129                        // free memory for bond part
     3130                        *out << Verbose(1) << "Freeing bond memory" << endl;
     3131                        delete(FragmentList); // remove bond molecule from memory
     3132                        Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3133                } else
     3134                        *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     3135        //} else
     3136        //      *out << Verbose(1) << "No fragments to store." << endl;
     3137        *out << Verbose(0) << "End of bond fragmentation." << endl;
     3138
     3139        return ((int)(!FragmentationToDo)+1);           // 1 - continue, 2 - stop (no fragmentation occured)
    31413140};
    31423141
     
    31513150bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
    31523151{
    3153   bool status = true;
    3154   if (ReferenceStack->IsEmpty()) {
    3155     cerr << "ReferenceStack is empty!" << endl;
    3156     return false;
    3157   }
    3158   bond *Binder = ReferenceStack->PopFirst();
    3159   bond *FirstBond = Binder;  // mark the first bond, so that we don't loop through the stack indefinitely
    3160   atom *Walker = NULL, *OtherAtom = NULL;
    3161   ReferenceStack->Push(Binder);
    3162 
    3163   do {  // go through all bonds and push local ones
    3164     Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3165     if (Walker != NULL) // if this Walker exists in the subgraph ...
    3166         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3167         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3168               if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3169               LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3152        bool status = true;
     3153        if (ReferenceStack->IsEmpty()) {
     3154                cerr << "ReferenceStack is empty!" << endl;
     3155                return false;
     3156        }
     3157        bond *Binder = ReferenceStack->PopFirst();
     3158        bond *FirstBond = Binder;        // mark the first bond, so that we don't loop through the stack indefinitely
     3159        atom *Walker = NULL, *OtherAtom = NULL;
     3160        ReferenceStack->Push(Binder);
     3161
     3162        do {    // go through all bonds and push local ones
     3163                Walker = ListOfLocalAtoms[Binder->leftatom->nr];        // get one atom in the reference molecule
     3164                if (Walker != NULL) // if this Walker exists in the subgraph ...
     3165                        for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {           // go through the local list of bonds
     3166                                OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3167                                if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3168                                        LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    31703169                                        *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3171                 break;
    3172             }
    3173         }
    3174     Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3170                                        break;
     3171                                }
     3172                        }
     3173                Binder = ReferenceStack->PopFirst();    // loop the stack for next item
    31753174                *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    3176     ReferenceStack->Push(Binder);
    3177   } while (FirstBond != Binder);
    3178 
    3179   return status;
     3175                ReferenceStack->Push(Binder);
     3176        } while (FirstBond != Binder);
     3177
     3178        return status;
    31803179};
    31813180
     
    31883187bool molecule::StoreOrderAtSiteFile(ofstream *out, char *path)
    31893188{
    3190   stringstream line;
    3191   ofstream file;
    3192 
    3193   line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3194   file.open(line.str().c_str());
    3195   *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
    3196   if (file != NULL) {
    3197     atom *Walker = start;
    3198     while (Walker->next != end) {
    3199       Walker = Walker->next;
    3200       file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
    3201       *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    3202     }
    3203     file.close();
    3204     *out << Verbose(1) << "done." << endl;
    3205     return true;
    3206   } else {
    3207     *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3208     return false;
    3209   }
     3189        stringstream line;
     3190        ofstream file;
     3191
     3192        line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3193        file.open(line.str().c_str());
     3194        *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
     3195        if (file != NULL) {
     3196                atom *Walker = start;
     3197                while (Walker->next != end) {
     3198                        Walker = Walker->next;
     3199                        file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
     3200                        *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
     3201                }
     3202                file.close();
     3203                *out << Verbose(1) << "done." << endl;
     3204                return true;
     3205        } else {
     3206                *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3207                return false;
     3208        }
    32103209};
    32113210
     
    32193218bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path)
    32203219{
    3221   unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3222   bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3223   bool status;
    3224   int AtomNr, value;
    3225   stringstream line;
    3226   ifstream file;
    3227 
    3228   *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
    3229   for(int i=AtomCount;i--;)
    3230     OrderArray[i] = 0;
    3231   line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3232   file.open(line.str().c_str());
    3233   if (file != NULL) {
    3234     for (int i=AtomCount;i--;) { // initialise with 0
    3235       OrderArray[i] = 0;
    3236       MaxArray[i] = 0;
    3237     }
    3238     while (!file.eof()) { // parse from file
    3239       AtomNr = -1;
    3240       file >> AtomNr;
    3241       if (AtomNr != -1) {  // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
    3242         file >> value;
    3243         OrderArray[AtomNr] = value;
    3244         file >> value;
    3245         MaxArray[AtomNr] = value;
    3246         //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
    3247       }
    3248     }
    3249     atom *Walker = start;
    3250     while (Walker->next != end) { // fill into atom classes
    3251       Walker = Walker->next;
    3252       Walker->AdaptiveOrder = OrderArray[Walker->nr];
    3253       Walker->MaxOrder = MaxArray[Walker->nr];
    3254       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    3255     }
    3256     file.close();
    3257     *out << Verbose(1) << "done." << endl;
    3258     status = true;
    3259   } else {
    3260     *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3261     status = false;
    3262   }
    3263   Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3264   Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3265 
    3266   *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    3267   return status;
     3220        unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3221        bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3222        bool status;
     3223        int AtomNr, value;
     3224        stringstream line;
     3225        ifstream file;
     3226
     3227        *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
     3228        for(int i=AtomCount;i--;)
     3229                OrderArray[i] = 0;
     3230        line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3231        file.open(line.str().c_str());
     3232        if (file != NULL) {
     3233                for (int i=AtomCount;i--;) { // initialise with 0
     3234                        OrderArray[i] = 0;
     3235                        MaxArray[i] = 0;
     3236                }
     3237                while (!file.eof()) { // parse from file
     3238                        AtomNr = -1;
     3239                        file >> AtomNr;
     3240                        if (AtomNr != -1) {      // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
     3241                                file >> value;
     3242                                OrderArray[AtomNr] = value;
     3243                                file >> value;
     3244                                MaxArray[AtomNr] = value;
     3245                                //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
     3246                        }
     3247                }
     3248                atom *Walker = start;
     3249                while (Walker->next != end) { // fill into atom classes
     3250                        Walker = Walker->next;
     3251                        Walker->AdaptiveOrder = OrderArray[Walker->nr];
     3252                        Walker->MaxOrder = MaxArray[Walker->nr];
     3253                        *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3254                }
     3255                file.close();
     3256                *out << Verbose(1) << "done." << endl;
     3257                status = true;
     3258        } else {
     3259                *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3260                status = false;
     3261        }
     3262        Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3263        Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3264
     3265        *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
     3266        return status;
    32683267};
    32693268
     
    32763275void molecule::CreateListOfBondsPerAtom(ofstream *out)
    32773276{
    3278   bond *Binder = NULL;
    3279   atom *Walker = NULL;
    3280   int TotalDegree;
    3281   *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    3282 
    3283   // re-allocate memory
    3284   *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    3285   if (ListOfBondsPerAtom != NULL) {
    3286     for(int i=AtomCount;i--;)
    3287       Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
    3288     Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
    3289   }
    3290   if (NumberOfBondsPerAtom != NULL)
    3291     Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
    3292   ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    3293   NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    3294 
    3295   // reset bond counts per atom
    3296   for(int i=AtomCount;i--;)
    3297     NumberOfBondsPerAtom[i] = 0;
    3298   // count bonds per atom
    3299   Binder = first;
    3300   while (Binder->next != last) {
    3301     Binder = Binder->next;
    3302     NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    3303     NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    3304   }
    3305   for(int i=AtomCount;i--;) {
    3306     // allocate list of bonds per atom
    3307     ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    3308     // clear the list again, now each NumberOfBondsPerAtom marks current free field
    3309     NumberOfBondsPerAtom[i] = 0;
    3310   }
    3311   // fill the list
    3312   Binder = first;
    3313   while (Binder->next != last) {
    3314     Binder = Binder->next;
    3315     ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    3316     ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    3317   }
    3318 
    3319   // output list for debugging
    3320   *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    3321   Walker = start;
    3322   while (Walker->next != end) {
    3323     Walker = Walker->next;
    3324     *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    3325     TotalDegree = 0;
    3326     for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    3327       *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
    3328       TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    3329     }
    3330     *out << " -- TotalDegree: " << TotalDegree << endl;
    3331   }
    3332   *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
     3277        bond *Binder = NULL;
     3278        atom *Walker = NULL;
     3279        int TotalDegree;
     3280        *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
     3281
     3282        // re-allocate memory
     3283        *out << Verbose(2) << "(Re-)Allocating memory." << endl;
     3284        if (ListOfBondsPerAtom != NULL) {
     3285                for(int i=AtomCount;i--;)
     3286                        Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
     3287                Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
     3288        }
     3289        if (NumberOfBondsPerAtom != NULL)
     3290                Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
     3291        ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
     3292        NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
     3293
     3294        // reset bond counts per atom
     3295        for(int i=AtomCount;i--;)
     3296                NumberOfBondsPerAtom[i] = 0;
     3297        // count bonds per atom
     3298        Binder = first;
     3299        while (Binder->next != last) {
     3300                Binder = Binder->next;
     3301                NumberOfBondsPerAtom[Binder->leftatom->nr]++;
     3302                NumberOfBondsPerAtom[Binder->rightatom->nr]++;
     3303        }
     3304        for(int i=AtomCount;i--;) {
     3305                // allocate list of bonds per atom
     3306                ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
     3307                // clear the list again, now each NumberOfBondsPerAtom marks current free field
     3308                NumberOfBondsPerAtom[i] = 0;
     3309        }
     3310        // fill the list
     3311        Binder = first;
     3312        while (Binder->next != last) {
     3313                Binder = Binder->next;
     3314                ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
     3315                ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
     3316        }
     3317
     3318        // output list for debugging
     3319        *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
     3320        Walker = start;
     3321        while (Walker->next != end) {
     3322                Walker = Walker->next;
     3323                *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
     3324                TotalDegree = 0;
     3325                for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     3326                        *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
     3327                        TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     3328                }
     3329                *out << " -- TotalDegree: " << TotalDegree << endl;
     3330        }
     3331        *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    33333332};
    33343333
     
    33473346void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    33483347{
    3349   atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3350   int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
    3351   enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
    3352   class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    3353   atom *Walker = NULL, *OtherAtom = NULL;
    3354   bond *Binder = NULL;
    3355 
    3356   // add Root if not done yet
    3357   AtomStack->ClearStack();
    3358   if (AddedAtomList[Root->nr] == NULL)  // add Root if not yet present
    3359     AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
    3360   AtomStack->Push(Root);
    3361 
    3362   // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    3363   for (int i=AtomCount;i--;) {
    3364     PredecessorList[i] = NULL;
    3365     ShortestPathList[i] = -1;
    3366     if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
    3367       ColorList[i] = lightgray;
    3368     else
    3369       ColorList[i] = white;
    3370   }
    3371   ShortestPathList[Root->nr] = 0;
    3372 
    3373   // and go on ... Queue always contains all lightgray vertices
    3374   while (!AtomStack->IsEmpty()) {
    3375     // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
    3376     // 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
    3377     // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
    3378     // followed by n+1 till top of stack.
    3379     Walker = AtomStack->PopFirst(); // pop oldest added
    3380     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    3381     for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    3382       Binder = ListOfBondsPerAtom[Walker->nr][i];
    3383       if (Binder != NULL) { // don't look at bond equal NULL
    3384         OtherAtom = Binder->GetOtherAtom(Walker);
    3385         *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    3386         if (ColorList[OtherAtom->nr] == white) {
    3387           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)
    3388             ColorList[OtherAtom->nr] = lightgray;
    3389           PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    3390           ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3391           *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;
    3392           if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    3393             *out << Verbose(3);
    3394             if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    3395               AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    3396               *out << "Added OtherAtom " << OtherAtom->Name;
    3397               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3398               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3399               AddedBondList[Binder->nr]->Type = Binder->Type;
    3400               *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
    3401             } 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)
    3402               *out << "Not adding OtherAtom " << OtherAtom->Name;
    3403               if (AddedBondList[Binder->nr] == NULL) {
    3404                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3405                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3406                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3407                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
    3408               } else
    3409                 *out << ", not added Bond ";
    3410             }
    3411             *out << ", putting OtherAtom into queue." << endl;
    3412             AtomStack->Push(OtherAtom);
    3413           } else { // out of bond order, then replace
    3414             if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
    3415               ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    3416             if (Binder == Bond)
    3417               *out << Verbose(3) << "Not Queueing, is the Root bond";
    3418             else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    3419               *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    3420             if (!Binder->Cyclic)
    3421               *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    3422             if (AddedBondList[Binder->nr] == NULL) {
    3423               if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    3424                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3425                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3426                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3427               } else {
     3348        atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3349        int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
     3350        enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
     3351        class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     3352        atom *Walker = NULL, *OtherAtom = NULL;
     3353        bond *Binder = NULL;
     3354
     3355        // add Root if not done yet
     3356        AtomStack->ClearStack();
     3357        if (AddedAtomList[Root->nr] == NULL)    // add Root if not yet present
     3358                AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
     3359        AtomStack->Push(Root);
     3360
     3361        // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     3362        for (int i=AtomCount;i--;) {
     3363                PredecessorList[i] = NULL;
     3364                ShortestPathList[i] = -1;
     3365                if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
     3366                        ColorList[i] = lightgray;
     3367                else
     3368                        ColorList[i] = white;
     3369        }
     3370        ShortestPathList[Root->nr] = 0;
     3371
     3372        // and go on ... Queue always contains all lightgray vertices
     3373        while (!AtomStack->IsEmpty()) {
     3374                // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
     3375                // 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
     3376                // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
     3377                // followed by n+1 till top of stack.
     3378                Walker = AtomStack->PopFirst(); // pop oldest added
     3379                *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3380                for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     3381                        Binder = ListOfBondsPerAtom[Walker->nr][i];
     3382                        if (Binder != NULL) { // don't look at bond equal NULL
     3383                                OtherAtom = Binder->GetOtherAtom(Walker);
     3384                                *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     3385                                if (ColorList[OtherAtom->nr] == white) {
     3386                                        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)
     3387                                                ColorList[OtherAtom->nr] = lightgray;
     3388                                        PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
     3389                                        ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     3390                                        *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;
     3391                                        if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
     3392                                                *out << Verbose(3);
     3393                                                if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
     3394                                                        AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
     3395                                                        *out << "Added OtherAtom " << OtherAtom->Name;
     3396                                                        AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3397                                                        AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3398                                                        AddedBondList[Binder->nr]->Type = Binder->Type;
     3399                                                        *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     3400                                                } 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)
     3401                                                        *out << "Not adding OtherAtom " << OtherAtom->Name;
     3402                                                        if (AddedBondList[Binder->nr] == NULL) {
     3403                                                                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3404                                                                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3405                                                                AddedBondList[Binder->nr]->Type = Binder->Type;
     3406                                                                *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     3407                                                        } else
     3408                                                                *out << ", not added Bond ";
     3409                                                }
     3410                                                *out << ", putting OtherAtom into queue." << endl;
     3411                                                AtomStack->Push(OtherAtom);
     3412                                        } else { // out of bond order, then replace
     3413                                                if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     3414                                                        ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
     3415                                                if (Binder == Bond)
     3416                                                        *out << Verbose(3) << "Not Queueing, is the Root bond";
     3417                                                else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
     3418                                                        *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
     3419                                                if (!Binder->Cyclic)
     3420                                                        *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
     3421                                                if (AddedBondList[Binder->nr] == NULL) {
     3422                                                        if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
     3423                                                                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3424                                                                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3425                                                                AddedBondList[Binder->nr]->Type = Binder->Type;
     3426                                                        } else {
    34283427#ifdef ADDHYDROGEN
    3429                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3430                   exit(1);
     3428                                                                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3429                                                                        exit(1);
    34313430#endif
    3432               }
    3433             }
    3434           }
    3435         } else {
    3436           *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    3437           // This has to be a cyclic bond, check whether it's present ...
    3438           if (AddedBondList[Binder->nr] == NULL) {
    3439             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    3440               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3441               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3442               AddedBondList[Binder->nr]->Type = Binder->Type;
    3443             } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
     3431                                                        }
     3432                                                }
     3433                                        }
     3434                                } else {
     3435                                        *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     3436                                        // This has to be a cyclic bond, check whether it's present ...
     3437                                        if (AddedBondList[Binder->nr] == NULL) {
     3438                                                if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     3439                                                        AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3440                                                        AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3441                                                        AddedBondList[Binder->nr]->Type = Binder->Type;
     3442                                                } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    34443443#ifdef ADDHYDROGEN
    3445               if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3446                 exit(1);
     3444                                                        if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3445                                                                exit(1);
    34473446#endif
    3448             }
    3449           }
    3450         }
    3451       }
    3452     }
    3453     ColorList[Walker->nr] = black;
    3454     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    3455   }
    3456   Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3457   Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
    3458   Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
    3459   delete(AtomStack);
     3447                                                }
     3448                                        }
     3449                                }
     3450                        }
     3451                }
     3452                ColorList[Walker->nr] = black;
     3453                *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3454        }
     3455        Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3456        Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
     3457        Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
     3458        delete(AtomStack);
    34603459};
    34613460
     
    34713470bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
    34723471{
    3473   atom *Walker = NULL, *OtherAtom = NULL;
    3474   bool status = true;
    3475   atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
    3476 
    3477   *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3478 
    3479   // reset parent list
    3480   *out << Verbose(3) << "Resetting ParentList." << endl;
    3481   for (int i=Father->AtomCount;i--;)
    3482     ParentList[i] = NULL;
    3483 
    3484   // fill parent list with sons
    3485   *out << Verbose(3) << "Filling Parent List." << endl;
    3486   Walker = start;
    3487   while (Walker->next != end) {
    3488     Walker = Walker->next;
    3489     ParentList[Walker->father->nr] = Walker;
    3490     // Outputting List for debugging
    3491     *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<  " is " << ParentList[Walker->father->nr] << "." << endl;
    3492   }
    3493 
    3494   // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
    3495   *out << Verbose(3) << "Creating bonds." << endl;
    3496   Walker = Father->start;
    3497   while (Walker->next != Father->end) {
    3498     Walker = Walker->next;
    3499     if (ParentList[Walker->nr] != NULL) {
    3500       if (ParentList[Walker->nr]->father != Walker) {
    3501         status = false;
    3502       } else {
    3503         for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    3504           OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3505           if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    3506             *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    3507             AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
    3508           }
    3509         }
    3510       }
    3511     }
    3512   }
    3513 
    3514   Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
    3515   *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
    3516   return status;
     3472        atom *Walker = NULL, *OtherAtom = NULL;
     3473        bool status = true;
     3474        atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
     3475
     3476        *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
     3477
     3478        // reset parent list
     3479        *out << Verbose(3) << "Resetting ParentList." << endl;
     3480        for (int i=Father->AtomCount;i--;)
     3481                ParentList[i] = NULL;
     3482
     3483        // fill parent list with sons
     3484        *out << Verbose(3) << "Filling Parent List." << endl;
     3485        Walker = start;
     3486        while (Walker->next != end) {
     3487                Walker = Walker->next;
     3488                ParentList[Walker->father->nr] = Walker;
     3489                // Outputting List for debugging
     3490                *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<        " is " << ParentList[Walker->father->nr] << "." << endl;
     3491        }
     3492
     3493        // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
     3494        *out << Verbose(3) << "Creating bonds." << endl;
     3495        Walker = Father->start;
     3496        while (Walker->next != Father->end) {
     3497                Walker = Walker->next;
     3498                if (ParentList[Walker->nr] != NULL) {
     3499                        if (ParentList[Walker->nr]->father != Walker) {
     3500                                status = false;
     3501                        } else {
     3502                                for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
     3503                                        OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3504                                        if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
     3505                                                *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     3506                                                AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     3507                                        }
     3508                                }
     3509                        }
     3510                }
     3511        }
     3512
     3513        Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
     3514        *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
     3515        return status;
    35173516};
    35183517
     
    35263525int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
    35273526{
    3528   atom *Runner = NULL;
    3529   int SP, Removal;
    3530 
    3531   *out << Verbose(2) << "Looking for removal candidate." << endl;
    3532   SP = -1; //0;  // not -1, so that Root is never removed
    3533   Removal = -1;
    3534   for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
    3535     Runner = FindAtom((*runner));
    3536     if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
    3537       if (ShortestPathList[(*runner)] > SP) {  // remove the oldest one with longest shortest path
    3538         SP = ShortestPathList[(*runner)];
    3539         Removal = (*runner);
    3540       }
    3541     }
    3542   }
    3543   return Removal;
     3527        atom *Runner = NULL;
     3528        int SP, Removal;
     3529
     3530        *out << Verbose(2) << "Looking for removal candidate." << endl;
     3531        SP = -1; //0;   // not -1, so that Root is never removed
     3532        Removal = -1;
     3533        for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
     3534                Runner = FindAtom((*runner));
     3535                if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
     3536                        if (ShortestPathList[(*runner)] > SP) { // remove the oldest one with longest shortest path
     3537                                SP = ShortestPathList[(*runner)];
     3538                                Removal = (*runner);
     3539                        }
     3540                }
     3541        }
     3542        return Removal;
    35443543};
    35453544
     
    35543553molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem)
    35553554{
    3556   atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
    3557   atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
    3558   molecule *Leaf = new molecule(elemente);
    3559   bool LonelyFlag = false;
    3560   int size;
    3561 
    3562 //  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3563 
    3564   Leaf->BondDistance = BondDistance;
    3565   for(int i=NDIM*2;i--;)
    3566     Leaf->cell_size[i] = cell_size[i];
    3567 
    3568   // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
    3569   for(int i=AtomCount;i--;)
    3570     SonList[i] = NULL;
    3571 
    3572   // first create the minimal set of atoms from the KeySet
    3573   size = 0;
    3574   for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
    3575     FatherOfRunner = FindAtom((*runner));  // find the id
    3576     SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
    3577     size++;
    3578   }
    3579 
    3580   // create the bonds between all: Make it an induced subgraph and add hydrogen
    3581 //  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
    3582   Runner = Leaf->start;
    3583   while (Runner->next != Leaf->end) {
    3584     Runner = Runner->next;
    3585     LonelyFlag = true;
    3586     FatherOfRunner = Runner->father;
    3587     if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    3588       // create all bonds
    3589       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    3590         OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    3591 //        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    3592         if (SonList[OtherFather->nr] != NULL) {
    3593 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    3594           if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    3595 //            *out << Verbose(3) << "Adding Bond: ";
    3596 //            *out <<
    3597             Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    3598 //            *out << "." << endl;
    3599             //NumBonds[Runner->nr]++;
    3600           } else {
    3601 //            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    3602           }
    3603           LonelyFlag = false;
    3604         } else {
    3605 //          *out << ", who has no son in this fragment molecule." << endl;
     3555        atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
     3556        atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
     3557        molecule *Leaf = new molecule(elemente);
     3558        bool LonelyFlag = false;
     3559        int size;
     3560
     3561//      *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
     3562
     3563        Leaf->BondDistance = BondDistance;
     3564        for(int i=NDIM*2;i--;)
     3565                Leaf->cell_size[i] = cell_size[i];
     3566
     3567        // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     3568        for(int i=AtomCount;i--;)
     3569                SonList[i] = NULL;
     3570
     3571        // first create the minimal set of atoms from the KeySet
     3572        size = 0;
     3573        for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
     3574                FatherOfRunner = FindAtom((*runner));   // find the id
     3575                SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
     3576                size++;
     3577        }
     3578
     3579        // create the bonds between all: Make it an induced subgraph and add hydrogen
     3580//      *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     3581        Runner = Leaf->start;
     3582        while (Runner->next != Leaf->end) {
     3583                Runner = Runner->next;
     3584                LonelyFlag = true;
     3585                FatherOfRunner = Runner->father;
     3586                if (SonList[FatherOfRunner->nr] != NULL)        {       // check if this, our father, is present in list
     3587                        // create all bonds
     3588                        for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3589                                OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     3590//                              *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
     3591                                if (SonList[OtherFather->nr] != NULL) {
     3592//                                      *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     3593                                        if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
     3594//                                              *out << Verbose(3) << "Adding Bond: ";
     3595//                                              *out <<
     3596                                                Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     3597//                                              *out << "." << endl;
     3598                                                //NumBonds[Runner->nr]++;
     3599                                        } else {
     3600//                                              *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
     3601                                        }
     3602                                        LonelyFlag = false;
     3603                                } else {
     3604//                                      *out << ", who has no son in this fragment molecule." << endl;
    36063605#ifdef ADDHYDROGEN
    3607           //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    3608           if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    3609             exit(1);
     3606                                        //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
     3607                                        if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     3608                                                exit(1);
    36103609#endif
    3611           //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
    3612         }
    3613       }
    3614     } else {
    3615       *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
    3616     }
    3617     if ((LonelyFlag) && (size > 1)) {
    3618       *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
    3619     }
     3610                                        //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     3611                                }
     3612                        }
     3613                } else {
     3614                        *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
     3615                }
     3616                if ((LonelyFlag) && (size > 1)) {
     3617                        *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
     3618                }
    36203619#ifdef ADDHYDROGEN
    3621     while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    3622       Runner = Runner->next;
     3620                while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
     3621                        Runner = Runner->next;
    36233622#endif
    3624   }
    3625   Leaf->CreateListOfBondsPerAtom(out);
    3626   //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    3627   Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
    3628 //  *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
    3629   return Leaf;
     3623        }
     3624        Leaf->CreateListOfBondsPerAtom(out);
     3625        //Leaflet->Leaf->ScanForPeriodicCorrection(out);
     3626        Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
     3627//      *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
     3628        return Leaf;
    36303629};
    36313630
     
    36463645MoleculeListClass * molecule::CreateListOfUniqueFragmentsOfOrder(ofstream *out, int Order, config *configuration)
    36473646{
    3648   atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");
    3649   int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");
    3650   int *Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");
    3651   enum Shading *ColorVertexList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");
    3652   enum Shading *ColorEdgeList = (enum Shading *) Malloc(sizeof(enum Shading)*BondCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorBondList");
    3653   StackClass<atom *> *RootStack = new StackClass<atom *>(AtomCount);
    3654   StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    3655   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!
    3656   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
    3657   MoleculeListClass *FragmentList = NULL;
    3658   atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
    3659   bond *Binder = NULL;
    3660   int RunningIndex = 0, FragmentCounter = 0;
    3661 
    3662   *out << Verbose(1) << "Begin of CreateListOfUniqueFragmentsOfOrder." << endl;
    3663 
    3664   // reset parent list
    3665   *out << Verbose(3) << "Resetting labels, parent, predecessor, color and shortest path lists." << endl;
    3666   for (int i=0;i<AtomCount;i++) { // reset all atom labels
    3667     // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons
     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
    36683667                Labels[i] = -1;
    3669     SonList[i] = NULL;
    3670     PredecessorList[i] = NULL;
    3671     ColorVertexList[i] = white;
    3672     ShortestPathList[i] = -1;
    3673   }
    3674   for (int i=0;i<BondCount;i++)
    3675     ColorEdgeList[i] = white;
     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;
    36763675        RootStack->ClearStack();        // clearstack and push first atom if exists
    3677   TouchedStack->ClearStack();
    3678   Walker = start->next;
    3679   while ((Walker != end)
     3676        TouchedStack->ClearStack();
     3677        Walker = start->next;
     3678        while ((Walker != end)
    36803679#ifdef ADDHYDROGEN
    3681   && (Walker->type->Z == 1)
     3680        && (Walker->type->Z == 1)
    36823681#endif
    3683                         ) { // search for first non-hydrogen atom
    3684     *out << Verbose(4) << "Current Root candidate is " << Walker->Name << "." << endl;
    3685     Walker = Walker->next;
    3686   }
    3687   if (Walker != end)
    3688     RootStack->Push(Walker);
    3689   else
    3690     *out << Verbose(0) << "ERROR: Could not find an appropriate Root atom!" << endl;
    3691   *out << Verbose(3) << "Root " << Walker->Name << " is on AtomStack, beginning loop through all vertices ..." << endl;
    3692 
    3693   ///// OUTER LOOP ////////////
    3694   while (!RootStack->IsEmpty()) {
    3695         // get new root vertex from atom stack
    3696         Root = RootStack->PopFirst();
    3697     ShortestPathList[Root->nr] = 0;
    3698     if (Labels[Root->nr] == -1)
    3699       Labels[Root->nr] = RunningIndex++; // prevent it from getting again on AtomStack
    3700     PredecessorList[Root->nr] = Root;
    3701     TouchedStack->Push(Root);
    3702     *out << Verbose(0) << "Root for this loop is: " << Root->Name << ".\n";
     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";
    37033702
    37043703                // clear snake stack
    3705           SnakeStack->ClearStack();
    3706     //SnakeStack->TestImplementation(out, start->next);
    3707 
    3708     ///// INNER LOOP ////////////
    3709     // Problems:
    3710     // - what about cyclic bonds?
    3711     Walker = Root;
    3712         do {
    3713       *out << Verbose(1) << "Current Walker is: " << Walker->Name;
    3714       // initial setting of the new Walker: label, color, shortest path and put on stacks
    3715                 if (Labels[Walker->nr] == -1)   {       // give atom a unique, monotonely increasing number
    3716                         Labels[Walker->nr] = RunningIndex++;
    3717         RootStack->Push(Walker);
    3718       }
    3719       *out << ", has label " << Labels[Walker->nr];
    3720                 if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) {     // color it if newly discovered and push on stacks (and if within reach!)
    3721         if ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white)) {
    3722           // Binder ought to be set still from last neighbour search
    3723           *out << ", coloring bond " << *Binder << " black";
    3724           ColorEdgeList[Binder->nr] = black; // mark this bond as used
    3725         }
    3726         if (ShortestPathList[Walker->nr] == -1) {
    3727           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
    3728           TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    3729         }
    3730         if ((ShortestPathList[Walker->nr] < Order) && (ColorVertexList[Walker->nr] != darkgray)) {  // if not already on snake stack
    3731           SnakeStack->Push(Walker);
    3732           ColorVertexList[Walker->nr] = darkgray; // mark as dark gray of on snake stack
    3733         }
    3734                 }
    3735       *out << ", SP of " << ShortestPathList[Walker->nr]  << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl;
    3736 
    3737       // then check the stack for a newly stumbled upon fragment
    3738                 if (SnakeStack->ItemCount() == Order) { // is stack full?
    3739         // store the fragment if it is one and get a removal candidate
    3740         Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration);
    3741         // remove the candidate if one was found
    3742         if (Removal != NULL) {
    3743           *out << Verbose(2) << "Removing item " << Removal->Name << " with SP of " << ShortestPathList[Removal->nr] << " from snake stack." << endl;
    3744           SnakeStack->RemoveItem(Removal);
    3745           ColorVertexList[Removal->nr] = lightgray; // return back to not on snake stack but explored marking
    3746           if (Walker == Removal) { // if the current atom is to be removed, we also have to take a step back
    3747             Walker = PredecessorList[Removal->nr];
    3748             *out << Verbose(2) << "Stepping back to " << Walker->Name << "." << endl;
    3749           }
    3750         }
    3751                 } else
    3752         Removal = NULL;
    3753 
    3754       // finally, look for a white neighbour as the next Walker
    3755       Binder = NULL;
    3756       if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) {  // don't look, if a new walker has been set above
    3757         *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl;
    3758                         OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour
    3759         if (ShortestPathList[Walker->nr] < Order) {
    3760                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    3761             Binder = ListOfBondsPerAtom[Walker->nr][i];
    3762             *out << Verbose(2) << "Current bond is " << *Binder << ": ";
    3763                                 OtherAtom = Binder->GetOtherAtom(Walker);
    3764             if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    3765               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    3766               //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    3767             } else { // otherwise check its colour and element
    3768                                 if (
     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 (
    37693768#ifdef ADDHYDROGEN
    3770               (OtherAtom->type->Z != 1) &&
     3769                                                        (OtherAtom->type->Z != 1) &&
    37713770#endif
    3772                     (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
    3773                 *out << "Moving along " << GetColor(ColorEdgeList[Binder->nr]) << " bond " << Binder << " to " << ((ColorVertexList[OtherAtom->nr] == white) ? "unexplored" : "explored") << " item: " << OtherAtom->Name << "." << endl;
    3774                 // i find it currently rather sensible to always set the predecessor in order to find one's way back
    3775                 //if (PredecessorList[OtherAtom->nr] == NULL) {
    3776                 PredecessorList[OtherAtom->nr] = Walker;
    3777                 *out << Verbose(3) << "Setting Predecessor of " << OtherAtom->Name << " to " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    3778                 //} else {
    3779                 //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    3780                 //}
    3781                 Walker = OtherAtom;
    3782                 break;
    3783               } else {
    3784                 if (OtherAtom->type->Z == 1)
    3785                   *out << "Links to a hydrogen atom." << endl;
    3786                 else
    3787                   *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    3788               }
    3789             }
    3790                         }
    3791         } else {  // means we have stepped beyond the horizon: Return!
    3792           Walker = PredecessorList[Walker->nr];
    3793           OtherAtom = Walker;
    3794           *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    3795         }
    3796                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
    3797           *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    3798                                 ColorVertexList[Walker->nr] = black;
    3799                                 Walker = PredecessorList[Walker->nr];
    3800                         }
    3801       }
    3802         } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    3803     *out << Verbose(2) << "Inner Looping is finished." << endl;
    3804 
    3805     // if we reset all AtomCount atoms, we have again technically O(N^2) ...
    3806     *out << Verbose(2) << "Resetting lists." << endl;
    3807     Walker = NULL;
    3808     Binder = NULL;
    3809     while (!TouchedStack->IsEmpty()) {
    3810       Walker = TouchedStack->PopLast();
    3811       *out << Verbose(3) << "Re-initialising entries of " << *Walker << "." << endl;
    3812       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    3813         ColorEdgeList[ListOfBondsPerAtom[Walker->nr][i]->nr] = white;
    3814       PredecessorList[Walker->nr] = NULL;
    3815       ColorVertexList[Walker->nr] = white;
    3816       ShortestPathList[Walker->nr] = -1;
    3817     }
    3818   }
    3819   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
    3820 
    3821   // copy together
    3822   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
    3823   FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    3824   RunningIndex = 0;
    3825   while ((Leaflet != NULL) && (RunningIndex < FragmentCounter))  {
    3826     FragmentList->ListOfMolecules[RunningIndex++] = Leaflet->Leaf;
    3827     Leaflet->Leaf = NULL; // prevent molecule from being removed
    3828     TempLeaf = Leaflet;
    3829     Leaflet = Leaflet->previous;
    3830     delete(TempLeaf);
    3831   };
    3832 
    3833   // free memory and exit
    3834   Free((void **)&PredecessorList, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");
    3835   Free((void **)&ShortestPathList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");
    3836   Free((void **)&Labels, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");
    3837   Free((void **)&ColorVertexList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");
    3838   delete(RootStack);
    3839   delete(TouchedStack);
    3840   delete(SnakeStack);
    3841 
    3842   *out << Verbose(1) << "End of CreateListOfUniqueFragmentsOfOrder." << endl;
    3843   return FragmentList;
     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;
    38443843};
    38453844*/
     
    38483847 */
    38493848struct UniqueFragments {
    3850   config *configuration;
    3851   atom *Root;
    3852   Graph *Leaflet;
    3853   KeySet *FragmentSet;
    3854   int ANOVAOrder;
    3855   int FragmentCounter;
    3856   int CurrentIndex;
    3857   double TEFactor;
    3858   int *ShortestPathList;
    3859   bool **UsedList;
    3860   bond **BondsPerSPList;
    3861   int *BondsPerSPCount;
     3849        config *configuration;
     3850        atom *Root;
     3851        Graph *Leaflet;
     3852        KeySet *FragmentSet;
     3853        int ANOVAOrder;
     3854        int FragmentCounter;
     3855        int CurrentIndex;
     3856        double TEFactor;
     3857        int *ShortestPathList;
     3858        bool **UsedList;
     3859        bond **BondsPerSPList;
     3860        int *BondsPerSPCount;
    38623861};
    38633862
    38643863/** From a given set of Bond sorted by Shortest Path distance, create all possible fragments of size \a SetDimension.
    38653864 * -# loops over every possible combination (2^dimension of edge set)
    3866  *  -# inserts current set, if there's still space left
    3867  *    -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
     3865 *      -# inserts current set, if there's still space left
     3866 *              -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
    38683867ance+1
    3869  *    -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
    3870  *  -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
     3868 *              -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
     3869 *      -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
    38713870distance) and current set
    38723871 * \param *out output stream for debugging
     
    38783877void molecule::SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder)
    38793878{
    3880   atom *OtherWalker = NULL;
    3881   int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
    3882   int NumCombinations;
    3883   bool bit;
    3884   int bits, TouchedIndex, SubSetDimension, SP, Added;
    3885   int Removal;
    3886   int SpaceLeft;
    3887   int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
    3888   bond *Binder = NULL;
    3889   bond **BondsList = NULL;
    3890   KeySetTestPair TestKeySetInsert;
    3891 
    3892   NumCombinations = 1 << SetDimension;
    3893 
    3894   // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    3895   // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    3896   // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3897 
    3898   *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    3899   *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " <<  NumCombinations-1 << " combination(s)." << endl;
    3900 
    3901   // initialised touched list (stores added atoms on this level)
    3902   *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    3903   for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    3904     TouchedList[TouchedIndex] = -1;
    3905   TouchedIndex = 0;
    3906 
    3907   // create every possible combination of the endpieces
    3908   *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
    3909   for (int i=1;i<NumCombinations;i++) {  // sweep through all power set combinations (skip empty set!)
    3910     // count the set bit of i
    3911     bits = 0;
    3912     for (int j=SetDimension;j--;)
    3913       bits += (i & (1 << j)) >> j;
    3914 
    3915     *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    3916     if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
    3917       // --1-- add this set of the power set of bond partners to the snake stack
    3918       Added = 0;
    3919       for (int j=0;j<SetDimension;j++) {  // pull out every bit by shifting
    3920         bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    3921         if (bit) {  // if bit is set, we add this bond partner
    3922                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    3923           //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    3924           *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3925           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    3926           if (TestKeySetInsert.second) {
    3927             TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
    3928             Added++;
    3929           } else {
    3930             *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
    3931           }
    3932             //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
    3933           //}
    3934         } else {
    3935           *out << Verbose(2+verbosity) << "Not adding." << endl;
    3936         }
    3937       }
    3938 
    3939       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    3940       if (SpaceLeft > 0) {
    3941         *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
    3942         if (SubOrder > 1) {    // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
    3943           // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
    3944           SP = RootDistance+1;  // this is the next level
    3945           // first count the members in the subset
    3946           SubSetDimension = 0;
    3947           Binder = FragmentSearch->BondsPerSPList[2*SP];                // start node for this level
    3948           while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {              // compare to end node of this level
    3949             Binder = Binder->next;
    3950             for (int k=TouchedIndex;k--;) {
    3951               if (Binder->Contains(TouchedList[k]))  // if we added this very endpiece
    3952                 SubSetDimension++;
    3953             }
    3954           }
    3955           // then allocate and fill the list
    3956           BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
    3957           SubSetDimension = 0;
    3958           Binder = FragmentSearch->BondsPerSPList[2*SP];
    3959           while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
    3960             Binder = Binder->next;
    3961             for (int k=0;k<TouchedIndex;k++) {
    3962               if (Binder->leftatom->nr == TouchedList[k])  // leftatom is always the close one
    3963                 BondsList[SubSetDimension++] = Binder;
    3964             }
    3965           }
    3966           *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3967           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    3968           Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    3969         }
    3970       } else {
    3971         // --2-- otherwise store the complete fragment
    3972         *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
    3973         // store fragment as a KeySet
    3974         *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    3975         for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3976           *out << (*runner) << " ";
    3977         *out << endl;
    3978         //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
    3979           //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
    3980         InsertFragmentIntoGraph(out, FragmentSearch);
    3981         //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
    3982         //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    3983       }
    3984 
    3985       // --3-- remove all added items in this level from snake stack
    3986       *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
    3987       for(int j=0;j<TouchedIndex;j++) {
    3988         Removal = TouchedList[j];
    3989         *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
    3990         FragmentSearch->FragmentSet->erase(Removal);
    3991         TouchedList[j] = -1;
    3992       }
    3993       *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    3994       for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3995         *out << (*runner) << " ";
    3996       *out << endl;
    3997       TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
    3998     } else {
    3999       *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
    4000     }
    4001   }
    4002   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    4003   *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
     3879        atom *OtherWalker = NULL;
     3880        int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
     3881        int NumCombinations;
     3882        bool bit;
     3883        int bits, TouchedIndex, SubSetDimension, SP, Added;
     3884        int Removal;
     3885        int SpaceLeft;
     3886        int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
     3887        bond *Binder = NULL;
     3888        bond **BondsList = NULL;
     3889        KeySetTestPair TestKeySetInsert;
     3890
     3891        NumCombinations = 1 << SetDimension;
     3892
     3893        // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
     3894        // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
     3895        // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
     3896
     3897        *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     3898        *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " <<     NumCombinations-1 << " combination(s)." << endl;
     3899
     3900        // initialised touched list (stores added atoms on this level)
     3901        *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
     3902        for (TouchedIndex=SubOrder+1;TouchedIndex--;)   // empty touched list
     3903                TouchedList[TouchedIndex] = -1;
     3904        TouchedIndex = 0;
     3905
     3906        // create every possible combination of the endpieces
     3907        *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     3908        for (int i=1;i<NumCombinations;i++) {   // sweep through all power set combinations (skip empty set!)
     3909                // count the set bit of i
     3910                bits = 0;
     3911                for (int j=SetDimension;j--;)
     3912                        bits += (i & (1 << j)) >> j;
     3913
     3914                *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
     3915                if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     3916                        // --1-- add this set of the power set of bond partners to the snake stack
     3917                        Added = 0;
     3918                        for (int j=0;j<SetDimension;j++) {      // pull out every bit by shifting
     3919                                bit = ((i & (1 << j)) != 0);    // mask the bit for the j-th bond
     3920                                if (bit) {      // if bit is set, we add this bond partner
     3921                                        OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
     3922                                        //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
     3923                                        *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
     3924                                        TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     3925                                        if (TestKeySetInsert.second) {
     3926                                                TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     3927                                                Added++;
     3928                                        } else {
     3929                                                *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
     3930                                        }
     3931                                                //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
     3932                                        //}
     3933                                } else {
     3934                                        *out << Verbose(2+verbosity) << "Not adding." << endl;
     3935                                }
     3936                        }
     3937
     3938                        SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     3939                        if (SpaceLeft > 0) {
     3940                                *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     3941                                if (SubOrder > 1) {             // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
     3942                                        // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
     3943                                        SP = RootDistance+1;    // this is the next level
     3944                                        // first count the members in the subset
     3945                                        SubSetDimension = 0;
     3946                                        Binder = FragmentSearch->BondsPerSPList[2*SP];          // start node for this level
     3947                                        while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {                // compare to end node of this level
     3948                                                Binder = Binder->next;
     3949                                                for (int k=TouchedIndex;k--;) {
     3950                                                        if (Binder->Contains(TouchedList[k]))    // if we added this very endpiece
     3951                                                                SubSetDimension++;
     3952                                                }
     3953                                        }
     3954                                        // then allocate and fill the list
     3955                                        BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
     3956                                        SubSetDimension = 0;
     3957                                        Binder = FragmentSearch->BondsPerSPList[2*SP];
     3958                                        while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
     3959                                                Binder = Binder->next;
     3960                                                for (int k=0;k<TouchedIndex;k++) {
     3961                                                        if (Binder->leftatom->nr == TouchedList[k])      // leftatom is always the close one
     3962                                                                BondsList[SubSetDimension++] = Binder;
     3963                                                }
     3964                                        }
     3965                                        *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
     3966                                        SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     3967                                        Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
     3968                                }
     3969                        } else {
     3970                                // --2-- otherwise store the complete fragment
     3971                                *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
     3972                                // store fragment as a KeySet
     3973                                *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
     3974                                for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3975                                        *out << (*runner) << " ";
     3976                                *out << endl;
     3977                                //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     3978                                        //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
     3979                                InsertFragmentIntoGraph(out, FragmentSearch);
     3980                                //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
     3981                                //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
     3982                        }
     3983
     3984                        // --3-- remove all added items in this level from snake stack
     3985                        *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     3986                        for(int j=0;j<TouchedIndex;j++) {
     3987                                Removal = TouchedList[j];
     3988                                *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
     3989                                FragmentSearch->FragmentSet->erase(Removal);
     3990                                TouchedList[j] = -1;
     3991                        }
     3992                        *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
     3993                        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3994                                *out << (*runner) << " ";
     3995                        *out << endl;
     3996                        TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     3997                } else {
     3998                        *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
     3999                }
     4000        }
     4001        Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     4002        *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    40044003};
    40054004
     
    40124011bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    40134012{
    4014   atom *Walker = NULL, *Walker2 = NULL;
    4015   bool BondStatus = false;
    4016   int size;
    4017 
    4018   *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    4019   *out << Verbose(2) << "Disconnected atom: ";
    4020 
    4021   // count number of atoms in graph
    4022   size = 0;
    4023   for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
    4024     size++;
    4025   if (size > 1)
    4026     for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
    4027       Walker = FindAtom(*runner);
    4028       BondStatus = false;
    4029       for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    4030         Walker2 = FindAtom(*runners);
    4031         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    4032           if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
    4033             BondStatus = true;
    4034             break;
    4035           }
    4036           if (BondStatus)
    4037             break;
    4038         }
    4039       }
    4040       if (!BondStatus) {
    4041         *out << (*Walker) << endl;
    4042         return false;
    4043       }
    4044     }
    4045   else {
    4046     *out << "none." << endl;
    4047     return true;
    4048   }
    4049   *out << "none." << endl;
    4050 
    4051   *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
    4052 
    4053   return true;
     4013        atom *Walker = NULL, *Walker2 = NULL;
     4014        bool BondStatus = false;
     4015        int size;
     4016
     4017        *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
     4018        *out << Verbose(2) << "Disconnected atom: ";
     4019
     4020        // count number of atoms in graph
     4021        size = 0;
     4022        for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
     4023                size++;
     4024        if (size > 1)
     4025                for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
     4026                        Walker = FindAtom(*runner);
     4027                        BondStatus = false;
     4028                        for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
     4029                                Walker2 = FindAtom(*runners);
     4030                                for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     4031                                        if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     4032                                                BondStatus = true;
     4033                                                break;
     4034                                        }
     4035                                        if (BondStatus)
     4036                                                break;
     4037                                }
     4038                        }
     4039                        if (!BondStatus) {
     4040                                *out << (*Walker) << endl;
     4041                                return false;
     4042                        }
     4043                }
     4044        else {
     4045                *out << "none." << endl;
     4046                return true;
     4047        }
     4048        *out << "none." << endl;
     4049
     4050        *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
     4051
     4052        return true;
    40544053}
    40554054
     
    40714070int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    40724071{
    4073   int SP, AtomKeyNr;
    4074   atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
    4075   bond *Binder = NULL;
    4076   bond *CurrentEdge = NULL;
    4077   bond **BondsList = NULL;
    4078   int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    4079   int Counter = FragmentSearch.FragmentCounter;
    4080   int RemainingWalkers;
    4081 
    4082   *out << endl;
    4083   *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
    4084 
    4085   // prepare Label and SP arrays of the BFS search
    4086   FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
    4087 
    4088   // prepare root level (SP = 0) and a loop bond denoting Root
    4089   for (int i=1;i<Order;i++)
    4090     FragmentSearch.BondsPerSPCount[i] = 0;
    4091   FragmentSearch.BondsPerSPCount[0] = 1;
    4092   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    4093   add(Binder, FragmentSearch.BondsPerSPList[1]);
    4094 
    4095   // do a BFS search to fill the SP lists and label the found vertices
    4096   // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    4097   // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    4098   // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4099   // (EdgeinSPLevel) of this tree ...
    4100   // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    4101   // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
    4102   *out << endl;
    4103   *out << Verbose(0) << "Starting BFS analysis ..." << endl;
    4104   for (SP = 0; SP < (Order-1); SP++) {
    4105     *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
    4106     if (SP > 0) {
    4107       *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
    4108       FragmentSearch.BondsPerSPCount[SP] = 0;
    4109     } else
    4110       *out << "." << endl;
    4111 
    4112     RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
    4113     CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];    /// start of this SP level's list
    4114     while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {    /// end of this SP level's list
    4115       CurrentEdge = CurrentEdge->next;
    4116       RemainingWalkers--;
    4117       Walker = CurrentEdge->rightatom;    // rightatom is always the one more distant
    4118       Predecessor = CurrentEdge->leftatom;    // ... and leftatom is predecessor
    4119       AtomKeyNr = Walker->nr;
    4120       *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
    4121       // check for new sp level
    4122       // go through all its bonds
    4123       *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    4124       for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
    4125         Binder = ListOfBondsPerAtom[AtomKeyNr][i];
    4126         OtherWalker = Binder->GetOtherAtom(Walker);
    4127         if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    4128   #ifdef ADDHYDROGEN
    4129         && (OtherWalker->type->Z != 1)
    4130   #endif
    4131                                                               ) {  // skip hydrogens and restrict to fragment
    4132           *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
    4133           // set the label if not set (and push on root stack as well)
    4134           if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
    4135             FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
    4136             *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
    4137             // add the bond in between to the SP list
    4138             Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
    4139             add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
    4140             FragmentSearch.BondsPerSPCount[SP+1]++;
    4141             *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
    4142           } else {
    4143             if (OtherWalker != Predecessor)
    4144               *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
    4145             else
    4146               *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
    4147           }
    4148         } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
    4149       }
    4150     }
    4151   }
    4152 
    4153   // outputting all list for debugging
    4154   *out << Verbose(0) << "Printing all found lists." << endl;
    4155   for(int i=1;i<Order;i++) {    // skip the root edge in the printing
    4156     Binder = FragmentSearch.BondsPerSPList[2*i];
    4157     *out << Verbose(1) << "Current SP level is " << i << "." << endl;
    4158     while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4159       Binder = Binder->next;
    4160       *out << Verbose(2) << *Binder << endl;
    4161     }
    4162   }
    4163 
    4164   // creating fragments with the found edge sets  (may be done in reverse order, faster)
    4165   SP = -1;  // the Root <-> Root edge must be subtracted!
    4166   for(int i=Order;i--;) { // sum up all found edges
    4167     Binder = FragmentSearch.BondsPerSPList[2*i];
    4168     while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4169       Binder = Binder->next;
    4170       SP ++;
    4171     }
    4172   }
    4173   *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
    4174   if (SP >= (Order-1)) {
    4175     // start with root (push on fragment stack)
    4176     *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4177     FragmentSearch.FragmentSet->clear();
    4178     *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    4179     // prepare the subset and call the generator
    4180     BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    4181     BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4182 
    4183     SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4184 
    4185     Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    4186   } else {
    4187     *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
    4188   }
    4189 
    4190   // as FragmentSearch structure is used only once, we don't have to clean it anymore
    4191   // remove root from stack
    4192   *out << Verbose(0) << "Removing root again from stack." << endl;
    4193   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    4194 
    4195   // free'ing the bonds lists
    4196   *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
    4197   for(int i=Order;i--;) {
    4198     *out << Verbose(1) << "Current SP level is " << i << ": ";
    4199     Binder = FragmentSearch.BondsPerSPList[2*i];
    4200     while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4201       Binder = Binder->next;
    4202       // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
    4203       FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
    4204       FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
    4205     }
    4206     // delete added bonds
    4207     cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
    4208     // also start and end node
    4209     *out << "cleaned." << endl;
    4210   }
    4211 
    4212   // return list
    4213   *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    4214   return (FragmentSearch.FragmentCounter - Counter);
     4072        int SP, AtomKeyNr;
     4073        atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
     4074        bond *Binder = NULL;
     4075        bond *CurrentEdge = NULL;
     4076        bond **BondsList = NULL;
     4077        int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
     4078        int Counter = FragmentSearch.FragmentCounter;
     4079        int RemainingWalkers;
     4080
     4081        *out << endl;
     4082        *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
     4083
     4084        // prepare Label and SP arrays of the BFS search
     4085        FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
     4086
     4087        // prepare root level (SP = 0) and a loop bond denoting Root
     4088        for (int i=1;i<Order;i++)
     4089                FragmentSearch.BondsPerSPCount[i] = 0;
     4090        FragmentSearch.BondsPerSPCount[0] = 1;
     4091        Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     4092        add(Binder, FragmentSearch.BondsPerSPList[1]);
     4093
     4094        // do a BFS search to fill the SP lists and label the found vertices
     4095        // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
     4096        // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
     4097        // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
     4098        // (EdgeinSPLevel) of this tree ...
     4099        // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
     4100        // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     4101        *out << endl;
     4102        *out << Verbose(0) << "Starting BFS analysis ..." << endl;
     4103        for (SP = 0; SP < (Order-1); SP++) {
     4104                *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
     4105                if (SP > 0) {
     4106                        *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
     4107                        FragmentSearch.BondsPerSPCount[SP] = 0;
     4108                } else
     4109                        *out << "." << endl;
     4110
     4111                RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
     4112                CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];              /// start of this SP level's list
     4113                while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {            /// end of this SP level's list
     4114                        CurrentEdge = CurrentEdge->next;
     4115                        RemainingWalkers--;
     4116                        Walker = CurrentEdge->rightatom;                // rightatom is always the one more distant
     4117                        Predecessor = CurrentEdge->leftatom;            // ... and leftatom is predecessor
     4118                        AtomKeyNr = Walker->nr;
     4119                        *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
     4120                        // check for new sp level
     4121                        // go through all its bonds
     4122                        *out << Verbose(1) << "Going through all bonds of Walker." << endl;
     4123                        for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
     4124                                Binder = ListOfBondsPerAtom[AtomKeyNr][i];
     4125                                OtherWalker = Binder->GetOtherAtom(Walker);
     4126                                if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
     4127        #ifdef ADDHYDROGEN
     4128                                && (OtherWalker->type->Z != 1)
     4129        #endif
     4130                                                                                                                                                                                                                                                        ) {     // skip hydrogens and restrict to fragment
     4131                                        *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     4132                                        // set the label if not set (and push on root stack as well)
     4133                                        if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     4134                                                FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
     4135                                                *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
     4136                                                // add the bond in between to the SP list
     4137                                                Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
     4138                                                add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
     4139                                                FragmentSearch.BondsPerSPCount[SP+1]++;
     4140                                                *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
     4141                                        } else {
     4142                                                if (OtherWalker != Predecessor)
     4143                                                        *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
     4144                                                else
     4145                                                        *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
     4146                                        }
     4147                                } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
     4148                        }
     4149                }
     4150        }
     4151
     4152        // outputting all list for debugging
     4153        *out << Verbose(0) << "Printing all found lists." << endl;
     4154        for(int i=1;i<Order;i++) {              // skip the root edge in the printing
     4155                Binder = FragmentSearch.BondsPerSPList[2*i];
     4156                *out << Verbose(1) << "Current SP level is " << i << "." << endl;
     4157                while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4158                        Binder = Binder->next;
     4159                        *out << Verbose(2) << *Binder << endl;
     4160                }
     4161        }
     4162
     4163        // creating fragments with the found edge sets  (may be done in reverse order, faster)
     4164        SP = -1;        // the Root <-> Root edge must be subtracted!
     4165        for(int i=Order;i--;) { // sum up all found edges
     4166                Binder = FragmentSearch.BondsPerSPList[2*i];
     4167                while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4168                        Binder = Binder->next;
     4169                        SP ++;
     4170                }
     4171        }
     4172        *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
     4173        if (SP >= (Order-1)) {
     4174                // start with root (push on fragment stack)
     4175                *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
     4176                FragmentSearch.FragmentSet->clear();
     4177                *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
     4178                // prepare the subset and call the generator
     4179                BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
     4180                BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
     4181
     4182                SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
     4183
     4184                Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
     4185        } else {
     4186                *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
     4187        }
     4188
     4189        // as FragmentSearch structure is used only once, we don't have to clean it anymore
     4190        // remove root from stack
     4191        *out << Verbose(0) << "Removing root again from stack." << endl;
     4192        FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4193
     4194        // free'ing the bonds lists
     4195        *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
     4196        for(int i=Order;i--;) {
     4197                *out << Verbose(1) << "Current SP level is " << i << ": ";
     4198                Binder = FragmentSearch.BondsPerSPList[2*i];
     4199                while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4200                        Binder = Binder->next;
     4201                        // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
     4202                        FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
     4203                        FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
     4204                }
     4205                // delete added bonds
     4206                cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
     4207                // also start and end node
     4208                *out << "cleaned." << endl;
     4209        }
     4210
     4211        // return list
     4212        *out << Verbose(0) << "End of PowerSetGenerator." << endl;
     4213        return (FragmentSearch.FragmentCounter - Counter);
    42154214};
    42164215
     
    42234222void molecule::ScanForPeriodicCorrection(ofstream *out)
    42244223{
    4225   bond *Binder = NULL;
    4226   bond *OtherBinder = NULL;
    4227   atom *Walker = NULL;
    4228   atom *OtherWalker = NULL;
    4229   double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    4230   enum Shading *ColorList = NULL;
    4231   double tmp;
    4232   Vector Translationvector;
    4233   //class StackClass<atom *> *CompStack = NULL;
    4234   class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    4235   bool flag = true;
    4236 
    4237   *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
    4238 
    4239   ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
    4240   while (flag) {
    4241     // remove bonds that are beyond bonddistance
    4242     for(int i=NDIM;i--;)
    4243       Translationvector.x[i] = 0.;
    4244     // scan all bonds
    4245     Binder = first;
    4246     flag = false;
    4247     while ((!flag) && (Binder->next != last)) {
    4248       Binder = Binder->next;
    4249       for (int i=NDIM;i--;) {
    4250         tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
    4251         //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
    4252         if (tmp > BondDistance) {
    4253           OtherBinder = Binder->next; // note down binding partner for later re-insertion
    4254           unlink(Binder);  // unlink bond
    4255           *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
    4256           flag = true;
    4257           break;
    4258         }
    4259       }
    4260     }
    4261     if (flag) {
    4262       // create translation vector from their periodically modified distance
    4263       for (int i=NDIM;i--;) {
    4264         tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
    4265         if (fabs(tmp) > BondDistance)
    4266           Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
    4267       }
    4268       Translationvector.MatrixMultiplication(matrix);
    4269       //*out << Verbose(3) << "Translation vector is ";
    4270       Translationvector.Output(out);
    4271       *out << endl;
    4272       // apply to all atoms of first component via BFS
    4273       for (int i=AtomCount;i--;)
    4274         ColorList[i] = white;
    4275       AtomStack->Push(Binder->leftatom);
    4276       while (!AtomStack->IsEmpty()) {
    4277         Walker = AtomStack->PopFirst();
    4278         //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
    4279         ColorList[Walker->nr] = black;    // mark as explored
    4280         Walker->x.AddVector(&Translationvector); // translate
    4281         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    4282           if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    4283             OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    4284             if (ColorList[OtherWalker->nr] == white) {
    4285               AtomStack->Push(OtherWalker); // push if yet unexplored
    4286             }
    4287           }
    4288         }
    4289       }
    4290       // re-add bond
    4291       link(Binder, OtherBinder);
    4292     } else {
    4293       *out << Verbose(3) << "No corrections for this fragment." << endl;
    4294     }
    4295     //delete(CompStack);
    4296   }
    4297 
    4298   // free allocated space from ReturnFullMatrixforSymmetric()
    4299   delete(AtomStack);
    4300   Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
    4301   Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
    4302   *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
     4224        bond *Binder = NULL;
     4225        bond *OtherBinder = NULL;
     4226        atom *Walker = NULL;
     4227        atom *OtherWalker = NULL;
     4228        double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     4229        enum Shading *ColorList = NULL;
     4230        double tmp;
     4231        Vector Translationvector;
     4232        //class StackClass<atom *> *CompStack = NULL;
     4233        class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     4234        bool flag = true;
     4235
     4236        *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
     4237
     4238        ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
     4239        while (flag) {
     4240                // remove bonds that are beyond bonddistance
     4241                for(int i=NDIM;i--;)
     4242                        Translationvector.x[i] = 0.;
     4243                // scan all bonds
     4244                Binder = first;
     4245                flag = false;
     4246                while ((!flag) && (Binder->next != last)) {
     4247                        Binder = Binder->next;
     4248                        for (int i=NDIM;i--;) {
     4249                                tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
     4250                                //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
     4251                                if (tmp > BondDistance) {
     4252                                        OtherBinder = Binder->next; // note down binding partner for later re-insertion
     4253                                        unlink(Binder); // unlink bond
     4254                                        *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
     4255                                        flag = true;
     4256                                        break;
     4257                                }
     4258                        }
     4259                }
     4260                if (flag) {
     4261                        // create translation vector from their periodically modified distance
     4262                        for (int i=NDIM;i--;) {
     4263                                tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
     4264                                if (fabs(tmp) > BondDistance)
     4265                                        Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
     4266                        }
     4267                        Translationvector.MatrixMultiplication(matrix);
     4268                        //*out << Verbose(3) << "Translation vector is ";
     4269                        Translationvector.Output(out);
     4270                        *out << endl;
     4271                        // apply to all atoms of first component via BFS
     4272                        for (int i=AtomCount;i--;)
     4273                                ColorList[i] = white;
     4274                        AtomStack->Push(Binder->leftatom);
     4275                        while (!AtomStack->IsEmpty()) {
     4276                                Walker = AtomStack->PopFirst();
     4277                                //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
     4278                                ColorList[Walker->nr] = black;          // mark as explored
     4279                                Walker->x.AddVector(&Translationvector); // translate
     4280                                for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
     4281                                        if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
     4282                                                OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     4283                                                if (ColorList[OtherWalker->nr] == white) {
     4284                                                        AtomStack->Push(OtherWalker); // push if yet unexplored
     4285                                                }
     4286                                        }
     4287                                }
     4288                        }
     4289                        // re-add bond
     4290                        link(Binder, OtherBinder);
     4291                } else {
     4292                        *out << Verbose(3) << "No corrections for this fragment." << endl;
     4293                }
     4294                //delete(CompStack);
     4295        }
     4296
     4297        // free allocated space from ReturnFullMatrixforSymmetric()
     4298        delete(AtomStack);
     4299        Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
     4300        Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
     4301        *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
    43034302};
    43044303
     
    43094308double * molecule::ReturnFullMatrixforSymmetric(double *symm)
    43104309{
    4311   double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
    4312   matrix[0] = symm[0];
    4313   matrix[1] = symm[1];
    4314   matrix[2] = symm[3];
    4315   matrix[3] = symm[1];
    4316   matrix[4] = symm[2];
    4317   matrix[5] = symm[4];
    4318   matrix[6] = symm[3];
    4319   matrix[7] = symm[4];
    4320   matrix[8] = symm[5];
    4321   return matrix;
     4310        double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
     4311        matrix[0] = symm[0];
     4312        matrix[1] = symm[1];
     4313        matrix[2] = symm[3];
     4314        matrix[3] = symm[1];
     4315        matrix[4] = symm[2];
     4316        matrix[5] = symm[4];
     4317        matrix[6] = symm[3];
     4318        matrix[7] = symm[4];
     4319        matrix[8] = symm[5];
     4320        return matrix;
    43224321};
    43234322
    43244323bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
    43254324{
    4326   //cout << "my check is used." << endl;
    4327   if (SubgraphA.size() < SubgraphB.size()) {
    4328     return true;
    4329   } else {
    4330     if (SubgraphA.size() > SubgraphB.size()) {
    4331       return false;
    4332     } else {
    4333       KeySet::iterator IteratorA = SubgraphA.begin();
    4334       KeySet::iterator IteratorB = SubgraphB.begin();
    4335       while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
    4336         if ((*IteratorA) <  (*IteratorB))
    4337           return true;
    4338         else if ((*IteratorA) > (*IteratorB)) {
    4339             return false;
    4340           } // else, go on to next index
    4341         IteratorA++;
    4342         IteratorB++;
    4343       } // end of while loop
    4344     }// end of check in case of equal sizes
    4345   }
    4346   return false; // if we reach this point, they are equal
     4325        //cout << "my check is used." << endl;
     4326        if (SubgraphA.size() < SubgraphB.size()) {
     4327                return true;
     4328        } else {
     4329                if (SubgraphA.size() > SubgraphB.size()) {
     4330                        return false;
     4331                } else {
     4332                        KeySet::iterator IteratorA = SubgraphA.begin();
     4333                        KeySet::iterator IteratorB = SubgraphB.begin();
     4334                        while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
     4335                                if ((*IteratorA) <      (*IteratorB))
     4336                                        return true;
     4337                                else if ((*IteratorA) > (*IteratorB)) {
     4338                                                return false;
     4339                                        } // else, go on to next index
     4340                                IteratorA++;
     4341                                IteratorB++;
     4342                        } // end of while loop
     4343                }// end of check in case of equal sizes
     4344        }
     4345        return false; // if we reach this point, they are equal
    43474346};
    43484347
    43494348//bool operator < (KeySet SubgraphA, KeySet SubgraphB)
    43504349//{
    4351 //  return KeyCompare(SubgraphA, SubgraphB);
     4350//      return KeyCompare(SubgraphA, SubgraphB);
    43524351//};
    43534352
     
    43614360inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment)
    43624361{
    4363   GraphTestPair testGraphInsert;
    4364 
    4365   testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor)));  // store fragment number and current factor
    4366   if (testGraphInsert.second) {
    4367     *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
    4368     Fragment->FragmentCounter++;
    4369   } else {
    4370     *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4371     ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;  // increase the "created" counter
    4372     *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
    4373   }
     4362        GraphTestPair testGraphInsert;
     4363
     4364        testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor))); // store fragment number and current factor
     4365        if (testGraphInsert.second) {
     4366                *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
     4367                Fragment->FragmentCounter++;
     4368        } else {
     4369                *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4370                ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;       // increase the "created" counter
     4371                *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
     4372        }
    43744373};
    43754374//void inline InsertIntoGraph(ofstream *out, KeyStack &stack, Graph &graph, int *counter, double factor)
    43764375//{
    4377 //  // copy stack contents to set and call overloaded function again
    4378 //  KeySet set;
    4379 //  for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
    4380 //    set.insert((*runner));
    4381 //  InsertIntoGraph(out, set, graph, counter, factor);
     4376//      // copy stack contents to set and call overloaded function again
     4377//      KeySet set;
     4378//      for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
     4379//              set.insert((*runner));
     4380//      InsertIntoGraph(out, set, graph, counter, factor);
    43824381//};
    43834382
     
    43904389inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
    43914390{
    4392   GraphTestPair testGraphInsert;
    4393 
    4394   for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
    4395     testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
    4396     if (testGraphInsert.second) {
    4397       *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
    4398     } else {
    4399       *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4400       ((*(testGraphInsert.first)).second).second += (*runner).second.second;
    4401       *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
    4402     }
    4403   }
     4391        GraphTestPair testGraphInsert;
     4392
     4393        for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
     4394                testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
     4395                if (testGraphInsert.second) {
     4396                        *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
     4397                } else {
     4398                        *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4399                        ((*(testGraphInsert.first)).second).second += (*runner).second.second;
     4400                        *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
     4401                }
     4402        }
    44044403};
    44054404
     
    44084407 * -# constructs a complete keyset of the molecule
    44094408 * -# In a loop over all possible roots from the given rootstack
    4410  *  -# increases order of root site
    4411  *  -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
    4412  *  -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
     4409 *      -# increases order of root site
     4410 *      -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
     4411 *      -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
    44134412as the restricted one and each site in the set as the root)
    4414  *  -# these are merged into a fragment list of keysets
     4413 *      -# these are merged into a fragment list of keysets
    44154414 * -# All fragment lists (for all orders, i.e. from all destination fields) are merged into one list for return
    44164415 * Important only is that we create all fragments, it is not important if we create them more than once
     
    44244423void molecule::FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize)
    44254424{
    4426   Graph ***FragmentLowerOrdersList = NULL;
    4427   int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
    4428   int counter = 0, Order;
    4429   int UpgradeCount = RootStack.size();
    4430   KeyStack FragmentRootStack;
    4431   int RootKeyNr, RootNr;
    4432   struct UniqueFragments FragmentSearch;
    4433 
    4434   *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    4435 
    4436   // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
    4437   // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
    4438   NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4439   FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4440 
    4441   // initialise the fragments structure
    4442   FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    4443   FragmentSearch.FragmentCounter = 0;
    4444   FragmentSearch.FragmentSet = new KeySet;
    4445   FragmentSearch.Root = FindAtom(RootKeyNr);
    4446   for (int i=AtomCount;i--;) {
    4447     FragmentSearch.ShortestPathList[i] = -1;
    4448   }
    4449 
    4450   // Construct the complete KeySet which we need for topmost level only (but for all Roots)
    4451   atom *Walker = start;
    4452   KeySet CompleteMolecule;
    4453   while (Walker->next != end) {
    4454     Walker = Walker->next;
    4455     CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4456   }
    4457 
    4458   // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as
    4459   // each has to be split up. E.g. for the second level we have one from 5th, one from 4th, two from 3th (which in turn is one from 5th, one from 4th),
    4460   // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
    4461   // with the order along the cells as this: 5433222211111111 for BondOrder 5 needing 16=pow(2,5-1) cells (only we use bit-shifting which is faster)
    4462   RootNr = 0;  // counts through the roots in RootStack
    4463   while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
    4464     RootKeyNr = RootStack.front();
    4465     RootStack.pop_front();
    4466     Walker = FindAtom(RootKeyNr);
    4467     // check cyclic lengths
    4468     //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    4469     //  *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;
    4470     //} else
    4471     {
    4472       // increase adaptive order by one
    4473       Walker->GetTrueFather()->AdaptiveOrder++;
    4474       Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4475 
    4476       // initialise Order-dependent entries of UniqueFragments structure
    4477       FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4478       FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4479       for (int i=Order;i--;) {
    4480         FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    4481         FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    4482         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];    // intertwine these two
    4483         FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    4484         FragmentSearch.BondsPerSPCount[i] = 0;
    4485       }
    4486 
    4487       // allocate memory for all lower level orders in this 1D-array of ptrs
    4488       NumLevels = 1 << (Order-1); // (int)pow(2,Order);
    4489       FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4490       for (int i=0;i<NumLevels;i++)
    4491         FragmentLowerOrdersList[RootNr][i] = NULL;
    4492 
    4493       // create top order where nothing is reduced
    4494       *out << Verbose(0) << "==============================================================================================================" << endl;
    4495       *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4496 
    4497       // Create list of Graphs of current Bond Order (i.e. F_{ij})
    4498       FragmentLowerOrdersList[RootNr][0] =  new Graph;
    4499       FragmentSearch.TEFactor = 1.;
    4500       FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];      // set to insertion graph
    4501       FragmentSearch.Root = Walker;
    4502       NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
    4503       *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4504       if (NumMoleculesOfOrder[RootNr] != 0) {
    4505         NumMolecules = 0;
    4506 
    4507         // we don't have to dive into suborders! These keysets are all already created on lower orders!
    4508         // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4509 
    4510 //        if ((NumLevels >> 1) > 0) {
    4511 //          // create lower order fragments
    4512 //          *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
    4513 //          Order = Walker->AdaptiveOrder;
    4514 //          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)
    4515 //            // step down to next order at (virtual) boundary of powers of 2 in array
    4516 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    4517 //              Order--;
    4518 //            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
    4519 //            for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
    4520 //              int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
    4521 //              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    4522 //              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
     4425        Graph ***FragmentLowerOrdersList = NULL;
     4426        int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
     4427        int counter = 0, Order;
     4428        int UpgradeCount = RootStack.size();
     4429        KeyStack FragmentRootStack;
     4430        int RootKeyNr, RootNr;
     4431        struct UniqueFragments FragmentSearch;
     4432
     4433        *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
     4434
     4435        // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
     4436        // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
     4437        NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4438        FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4439
     4440        // initialise the fragments structure
     4441        FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
     4442        FragmentSearch.FragmentCounter = 0;
     4443        FragmentSearch.FragmentSet = new KeySet;
     4444        FragmentSearch.Root = FindAtom(RootKeyNr);
     4445        for (int i=AtomCount;i--;) {
     4446                FragmentSearch.ShortestPathList[i] = -1;
     4447        }
     4448
     4449        // Construct the complete KeySet which we need for topmost level only (but for all Roots)
     4450        atom *Walker = start;
     4451        KeySet CompleteMolecule;
     4452        while (Walker->next != end) {
     4453                Walker = Walker->next;
     4454                CompleteMolecule.insert(Walker->GetTrueFather()->nr);
     4455        }
     4456
     4457        // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as
     4458        // each has to be split up. E.g. for the second level we have one from 5th, one from 4th, two from 3th (which in turn is one from 5th, one from 4th),
     4459        // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
     4460        // with the order along the cells as this: 5433222211111111 for BondOrder 5 needing 16=pow(2,5-1) cells (only we use bit-shifting which is faster)
     4461        RootNr = 0;      // counts through the roots in RootStack
     4462        while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
     4463                RootKeyNr = RootStack.front();
     4464                RootStack.pop_front();
     4465                Walker = FindAtom(RootKeyNr);
     4466                // check cyclic lengths
     4467                //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
     4468                //      *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;
     4469                //} else
     4470                {
     4471                        // increase adaptive order by one
     4472                        Walker->GetTrueFather()->AdaptiveOrder++;
     4473                        Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
     4474
     4475                        // initialise Order-dependent entries of UniqueFragments structure
     4476                        FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4477                        FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4478                        for (int i=Order;i--;) {
     4479                                FragmentSearch.BondsPerSPList[2*i] = new bond();                // start node
     4480                                FragmentSearch.BondsPerSPList[2*i+1] = new bond();      // end node
     4481                                FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];                // intertwine these two
     4482                                FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
     4483                                FragmentSearch.BondsPerSPCount[i] = 0;
     4484                        }
     4485
     4486                        // allocate memory for all lower level orders in this 1D-array of ptrs
     4487                        NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     4488                        FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4489                        for (int i=0;i<NumLevels;i++)
     4490                                FragmentLowerOrdersList[RootNr][i] = NULL;
     4491
     4492                        // create top order where nothing is reduced
     4493                        *out << Verbose(0) << "==============================================================================================================" << endl;
     4494                        *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
     4495
     4496                        // Create list of Graphs of current Bond Order (i.e. F_{ij})
     4497                        FragmentLowerOrdersList[RootNr][0] =    new Graph;
     4498                        FragmentSearch.TEFactor = 1.;
     4499                        FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];                    // set to insertion graph
     4500                        FragmentSearch.Root = Walker;
     4501                        NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
     4502                        *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4503                        if (NumMoleculesOfOrder[RootNr] != 0) {
     4504                                NumMolecules = 0;
     4505
     4506                                // we don't have to dive into suborders! These keysets are all already created on lower orders!
     4507                                // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
     4508
     4509//                              if ((NumLevels >> 1) > 0) {
     4510//                                      // create lower order fragments
     4511//                                      *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
     4512//                                      Order = Walker->AdaptiveOrder;
     4513//                                      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)
     4514//                                              // step down to next order at (virtual) boundary of powers of 2 in array
     4515//                                              while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4516//                                                      Order--;
     4517//                                              *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     4518//                                              for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
     4519//                                                      int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
     4520//                                                      *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
     4521//                                                      *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    45234522//
    4524 //              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    4525 //              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
    4526 //              //NumMolecules = 0;
    4527 //              FragmentLowerOrdersList[RootNr][dest] = new Graph;
    4528 //              for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
    4529 //                for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    4530 //                  Graph TempFragmentList;
    4531 //                  FragmentSearch.TEFactor = -(*runner).second.second;
    4532 //                  FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
    4533 //                  FragmentSearch.Root = FindAtom(*sprinter);
    4534 //                  NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
    4535 //                  // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
    4536 //                  *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
    4537 //                  InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
    4538 //                }
    4539 //              }
    4540 //              *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
    4541 //            }
    4542 //          }
    4543 //        }
    4544       } else {
    4545         Walker->GetTrueFather()->MaxOrder = true;
    4546 //        *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
    4547       }
    4548       // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
    4549       //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
    4550       TotalNumMolecules += NumMoleculesOfOrder[RootNr];
    4551 //      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4552       RootStack.push_back(RootKeyNr); // put back on stack
    4553       RootNr++;
    4554 
    4555       // free Order-dependent entries of UniqueFragments structure for next loop cycle
    4556       Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4557       for (int i=Order;i--;) {
    4558         delete(FragmentSearch.BondsPerSPList[2*i]);
    4559         delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4560       }
    4561       Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4562     }
    4563   }
    4564   *out << Verbose(0) << "==============================================================================================================" << endl;
    4565   *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
    4566   *out << Verbose(0) << "==============================================================================================================" << endl;
    4567 
    4568   // cleanup FragmentSearch structure
    4569   Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    4570   delete(FragmentSearch.FragmentSet);
    4571 
    4572   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    4573   // 5433222211111111
    4574   // 43221111
    4575   // 3211
    4576   // 21
    4577   // 1
    4578 
    4579   // Subsequently, we combine all into a single list (FragmentList)
    4580 
    4581   *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
    4582   if (FragmentList == NULL) {
    4583     FragmentList = new Graph;
    4584     counter = 0;
    4585   } else {
    4586     counter = FragmentList->size();
    4587   }
    4588   RootNr = 0;
    4589   while (!RootStack.empty()) {
    4590     RootKeyNr = RootStack.front();
    4591     RootStack.pop_front();
    4592     Walker = FindAtom(RootKeyNr);
    4593     NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    4594     for(int i=0;i<NumLevels;i++) {
    4595       if (FragmentLowerOrdersList[RootNr][i] != NULL) {
    4596         InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
    4597         delete(FragmentLowerOrdersList[RootNr][i]);
    4598       }
    4599     }
    4600     Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4601     RootNr++;
    4602   }
    4603   Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4604   Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4605 
    4606   *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
     4523//                                                      // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
     4524//                                                      //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     4525//                                                      //NumMolecules = 0;
     4526//                                                      FragmentLowerOrdersList[RootNr][dest] = new Graph;
     4527//                                                      for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
     4528//                                                              for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     4529//                                                                      Graph TempFragmentList;
     4530//                                                                      FragmentSearch.TEFactor = -(*runner).second.second;
     4531//                                                                      FragmentSearch.Leaflet = &TempFragmentList;                     // set to insertion graph
     4532//                                                                      FragmentSearch.Root = FindAtom(*sprinter);
     4533//                                                                      NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
     4534//                                                                      // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
     4535//                                                                      *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
     4536//                                                                      InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
     4537//                                                              }
     4538//                                                      }
     4539//                                                      *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
     4540//                                              }
     4541//                                      }
     4542//                              }
     4543                        } else {
     4544                                Walker->GetTrueFather()->MaxOrder = true;
     4545//                              *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
     4546                        }
     4547                        // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
     4548                        //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
     4549                        TotalNumMolecules += NumMoleculesOfOrder[RootNr];
     4550//                      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4551                        RootStack.push_back(RootKeyNr); // put back on stack
     4552                        RootNr++;
     4553
     4554                        // free Order-dependent entries of UniqueFragments structure for next loop cycle
     4555                        Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4556                        for (int i=Order;i--;) {
     4557                                delete(FragmentSearch.BondsPerSPList[2*i]);
     4558                                delete(FragmentSearch.BondsPerSPList[2*i+1]);
     4559                        }
     4560                        Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4561                }
     4562        }
     4563        *out << Verbose(0) << "==============================================================================================================" << endl;
     4564        *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
     4565        *out << Verbose(0) << "==============================================================================================================" << endl;
     4566
     4567        // cleanup FragmentSearch structure
     4568        Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
     4569        delete(FragmentSearch.FragmentSet);
     4570
     4571        // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4572        // 5433222211111111
     4573        // 43221111
     4574        // 3211
     4575        // 21
     4576        // 1
     4577
     4578        // Subsequently, we combine all into a single list (FragmentList)
     4579
     4580        *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
     4581        if (FragmentList == NULL) {
     4582                FragmentList = new Graph;
     4583                counter = 0;
     4584        } else {
     4585                counter = FragmentList->size();
     4586        }
     4587        RootNr = 0;
     4588        while (!RootStack.empty()) {
     4589                RootKeyNr = RootStack.front();
     4590                RootStack.pop_front();
     4591                Walker = FindAtom(RootKeyNr);
     4592                NumLevels = 1 << (Walker->AdaptiveOrder - 1);
     4593                for(int i=0;i<NumLevels;i++) {
     4594                        if (FragmentLowerOrdersList[RootNr][i] != NULL) {
     4595                                InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
     4596                                delete(FragmentLowerOrdersList[RootNr][i]);
     4597                        }
     4598                }
     4599                Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4600                RootNr++;
     4601        }
     4602        Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4603        Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4604
     4605        *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    46074606};
    46084607
     
    46144613inline int CompareDoubles (const void * a, const void * b)
    46154614{
    4616   if (*(double *)a > *(double *)b)
    4617     return -1;
    4618   else if (*(double *)a < *(double *)b)
    4619     return 1;
    4620   else
    4621     return 0;
     4615        if (*(double *)a > *(double *)b)
     4616                return -1;
     4617        else if (*(double *)a < *(double *)b)
     4618                return 1;
     4619        else
     4620                return 0;
    46224621};
    46234622
     
    46304629int * molecule::IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold)
    46314630{
    4632   int flag;
    4633   double *Distances = NULL, *OtherDistances = NULL;
    4634   Vector CenterOfGravity, OtherCenterOfGravity;
    4635   size_t *PermMap = NULL, *OtherPermMap = NULL;
    4636   int *PermutationMap = NULL;
    4637   atom *Walker = NULL;
    4638   bool result = true; // status of comparison
    4639 
    4640   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    4641   /// first count both their atoms and elements and update lists thereby ...
    4642   //*out << Verbose(0) << "Counting atoms, updating list" << endl;
    4643   CountAtoms(out);
    4644   OtherMolecule->CountAtoms(out);
    4645   CountElements();
    4646   OtherMolecule->CountElements();
    4647 
    4648   /// ... and compare:
    4649   /// -# AtomCount
    4650   if (result) {
    4651     if (AtomCount != OtherMolecule->AtomCount) {
    4652       *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4653       result = false;
    4654     } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4655   }
    4656   /// -# ElementCount
    4657   if (result) {
    4658     if (ElementCount != OtherMolecule->ElementCount) {
    4659       *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4660       result = false;
    4661     } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4662   }
    4663   /// -# ElementsInMolecule
    4664   if (result) {
    4665     for (flag=MAX_ELEMENTS;flag--;) {
    4666       //*out << Verbose(5) << "Element " <<  flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
    4667       if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
    4668         break;
    4669     }
    4670     if (flag < MAX_ELEMENTS) {
    4671       *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
    4672       result = false;
    4673     } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
    4674   }
    4675   /// then determine and compare center of gravity for each molecule ...
    4676   if (result) {
    4677     *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    4678     DetermineCenter(CenterOfGravity);
    4679     OtherMolecule->DetermineCenter(OtherCenterOfGravity);
    4680     *out << Verbose(5) << "Center of Gravity: ";
    4681     CenterOfGravity.Output(out);
    4682     *out << endl << Verbose(5) << "Other Center of Gravity: ";
    4683     OtherCenterOfGravity.Output(out);
    4684     *out << endl;
    4685     if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    4686       *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4687       result = false;
    4688     }
    4689   }
    4690 
    4691   /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    4692   if (result) {
    4693     *out << Verbose(5) << "Calculating distances" << endl;
    4694     Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    4695     OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4696     Walker = start;
    4697     while (Walker->next != end) {
    4698       Walker = Walker->next;
    4699       Distances[Walker->nr] = CenterOfGravity.Distance(&Walker->x);
    4700     }
    4701     Walker = OtherMolecule->start;
    4702     while (Walker->next != OtherMolecule->end) {
    4703       Walker = Walker->next;
    4704       OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    4705     }
    4706 
    4707     /// ... sort each list (using heapsort (o(N log N)) from GSL)
    4708     *out << Verbose(5) << "Sorting distances" << endl;
    4709     PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    4710     OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4711     gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    4712     gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    4713     PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4714     *out << Verbose(5) << "Combining Permutation Maps" << endl;
    4715     for(int i=AtomCount;i--;)
    4716       PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4717 
    4718     /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    4719     *out << Verbose(4) << "Comparing distances" << endl;
    4720     flag = 0;
    4721     for (int i=0;i<AtomCount;i++) {
    4722       *out << Verbose(5) << "Distances: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
    4723       if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold)
    4724         flag = 1;
    4725     }
    4726     Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    4727     Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4728 
    4729     /// free memory
    4730     Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
    4731     Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4732     if (flag) { // if not equal
    4733       Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4734       result = false;
    4735     }
    4736   }
    4737   /// return pointer to map if all distances were below \a threshold
    4738   *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
    4739   if (result) {
    4740     *out << Verbose(3) << "Result: Equal." << endl;
    4741     return PermutationMap;
    4742   } else {
    4743     *out << Verbose(3) << "Result: Not equal." << endl;
    4744     return NULL;
    4745   }
     4631        int flag;
     4632        double *Distances = NULL, *OtherDistances = NULL;
     4633        Vector CenterOfGravity, OtherCenterOfGravity;
     4634        size_t *PermMap = NULL, *OtherPermMap = NULL;
     4635        int *PermutationMap = NULL;
     4636        atom *Walker = NULL;
     4637        bool result = true; // status of comparison
     4638
     4639        *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     4640        /// first count both their atoms and elements and update lists thereby ...
     4641        //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     4642        CountAtoms(out);
     4643        OtherMolecule->CountAtoms(out);
     4644        CountElements();
     4645        OtherMolecule->CountElements();
     4646
     4647        /// ... and compare:
     4648        /// -# AtomCount
     4649        if (result) {
     4650                if (AtomCount != OtherMolecule->AtomCount) {
     4651                        *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4652                        result = false;
     4653                } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4654        }
     4655        /// -# ElementCount
     4656        if (result) {
     4657                if (ElementCount != OtherMolecule->ElementCount) {
     4658                        *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4659                        result = false;
     4660                } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4661        }
     4662        /// -# ElementsInMolecule
     4663        if (result) {
     4664                for (flag=MAX_ELEMENTS;flag--;) {
     4665                        //*out << Verbose(5) << "Element " <<   flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
     4666                        if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
     4667                                break;
     4668                }
     4669                if (flag < MAX_ELEMENTS) {
     4670                        *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
     4671                        result = false;
     4672                } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
     4673        }
     4674        /// then determine and compare center of gravity for each molecule ...
     4675        if (result) {
     4676                *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
     4677                DetermineCenter(CenterOfGravity);
     4678                OtherMolecule->DetermineCenter(OtherCenterOfGravity);
     4679                *out << Verbose(5) << "Center of Gravity: ";
     4680                CenterOfGravity.Output(out);
     4681                *out << endl << Verbose(5) << "Other Center of Gravity: ";
     4682                OtherCenterOfGravity.Output(out);
     4683                *out << endl;
     4684                if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
     4685                        *out << Verbose(4) << "Centers of gravity don't match." << endl;
     4686                        result = false;
     4687                }
     4688        }
     4689
     4690        /// ... then make a list with the euclidian distance to this center for each atom of both molecules
     4691        if (result) {
     4692                *out << Verbose(5) << "Calculating distances" << endl;
     4693                Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
     4694                OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4695                Walker = start;
     4696                while (Walker->next != end) {
     4697                        Walker = Walker->next;
     4698                        Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
     4699                }
     4700                Walker = OtherMolecule->start;
     4701                while (Walker->next != OtherMolecule->end) {
     4702                        Walker = Walker->next;
     4703                        OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
     4704                }
     4705
     4706                /// ... sort each list (using heapsort (o(N log N)) from GSL)
     4707                *out << Verbose(5) << "Sorting distances" << endl;
     4708                PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
     4709                OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4710                gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
     4711                gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
     4712                PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4713                *out << Verbose(5) << "Combining Permutation Maps" << endl;
     4714                for(int i=AtomCount;i--;)
     4715                        PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
     4716
     4717                /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
     4718                *out << Verbose(4) << "Comparing distances" << endl;
     4719                flag = 0;
     4720                for (int i=0;i<AtomCount;i++) {
     4721                        *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<      threshold << endl;
     4722                        if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
     4723                                flag = 1;
     4724                }
     4725                Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
     4726                Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4727
     4728                /// free memory
     4729                Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     4730                Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4731                if (flag) { // if not equal
     4732                        Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4733                        result = false;
     4734                }
     4735        }
     4736        /// return pointer to map if all distances were below \a threshold
     4737        *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     4738        if (result) {
     4739                *out << Verbose(3) << "Result: Equal." << endl;
     4740                return PermutationMap;
     4741        } else {
     4742                *out << Verbose(3) << "Result: Not equal." << endl;
     4743                return NULL;
     4744        }
    47464745};
    47474746
     
    47554754int * molecule::GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule)
    47564755{
    4757   atom *Walker = NULL, *OtherWalker = NULL;
    4758   *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
    4759   int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");  //Calloc
    4760   for (int i=AtomCount;i--;)
    4761     AtomicMap[i] = -1;
    4762   if (OtherMolecule == this) {  // same molecule
    4763     for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
    4764       AtomicMap[i] = i;
    4765     *out << Verbose(4) << "Map is trivial." << endl;
    4766   } else {
    4767     *out << Verbose(4) << "Map is ";
    4768     Walker = start;
    4769     while (Walker->next != end) {
    4770       Walker = Walker->next;
    4771       if (Walker->father == NULL) {
    4772         AtomicMap[Walker->nr] = -2;
    4773       } else {
    4774         OtherWalker = OtherMolecule->start;
    4775         while (OtherWalker->next != OtherMolecule->end) {
    4776           OtherWalker = OtherWalker->next;
    4777       //for (int i=0;i<AtomCount;i++) { // search atom
    4778         //for (int j=0;j<OtherMolecule->AtomCount;j++) {
    4779           //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
    4780           if (Walker->father == OtherWalker)
    4781             AtomicMap[Walker->nr] = OtherWalker->nr;
    4782         }
    4783       }
    4784       *out << AtomicMap[Walker->nr] << "\t";
    4785     }
    4786     *out << endl;
    4787   }
    4788   *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
    4789   return AtomicMap;
     4756        atom *Walker = NULL, *OtherWalker = NULL;
     4757        *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
     4758        int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");   //Calloc
     4759        for (int i=AtomCount;i--;)
     4760                AtomicMap[i] = -1;
     4761        if (OtherMolecule == this) {    // same molecule
     4762                for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
     4763                        AtomicMap[i] = i;
     4764                *out << Verbose(4) << "Map is trivial." << endl;
     4765        } else {
     4766                *out << Verbose(4) << "Map is ";
     4767                Walker = start;
     4768                while (Walker->next != end) {
     4769                        Walker = Walker->next;
     4770                        if (Walker->father == NULL) {
     4771                                AtomicMap[Walker->nr] = -2;
     4772                        } else {
     4773                                OtherWalker = OtherMolecule->start;
     4774                                while (OtherWalker->next != OtherMolecule->end) {
     4775                                        OtherWalker = OtherWalker->next;
     4776                        //for (int i=0;i<AtomCount;i++) { // search atom
     4777                                //for (int j=0;j<OtherMolecule->AtomCount;j++) {
     4778                                        //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
     4779                                        if (Walker->father == OtherWalker)
     4780                                                AtomicMap[Walker->nr] = OtherWalker->nr;
     4781                                }
     4782                        }
     4783                        *out << AtomicMap[Walker->nr] << "\t";
     4784                }
     4785                *out << endl;
     4786        }
     4787        *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
     4788        return AtomicMap;
    47904789};
    47914790
     
    48014800bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    48024801{
    4803   double temperature;
    4804   atom *Walker = NULL;
    4805   // test stream
    4806   if (output == NULL)
    4807     return false;
    4808   else
    4809     *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    4810   for (int step=startstep;step < endstep; step++) { // loop over all time steps
    4811     temperature = 0.;
    4812     Walker = start;
    4813     while (Walker->next != end) {
    4814       Walker = Walker->next;
    4815       for (int i=NDIM;i--;)
    4816         temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
    4817     }
    4818     *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
    4819   }
    4820   return true;
    4821 };
     4802        double temperature;
     4803        atom *Walker = NULL;
     4804        // test stream
     4805        if (output == NULL)
     4806                return false;
     4807        else
     4808                *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
     4809        for (int step=startstep;step < endstep; step++) { // loop over all time steps
     4810                temperature = 0.;
     4811                Walker = start;
     4812                while (Walker->next != end) {
     4813                        Walker = Walker->next;
     4814                        for (int i=NDIM;i--;)
     4815                                temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
     4816                }
     4817                *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
     4818        }
     4819        return true;
     4820};
Note: See TracChangeset for help on using the changeset viewer.