Changeset 042f82 for src/molecules.cpp


Ignore:
Timestamp:
Jul 23, 2009, 2:21:57 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, Candidate_v1.7.0, 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:
36ec71
Parents:
205ccd
Message:

fixed indentation from tabs to two spaces.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecules.cpp

    r205ccd r042f82  
    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;
    55         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.;
    64         strcpy(name,"none");
     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;
     55  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.;
     64  strcpy(name,"none");
    6565};
    6666
     
    7070molecule::~molecule()
    7171{
    72         if (ListOfBondsPerAtom != NULL)
    73                 for(int i=AtomCount;i--;)
    74                         Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
    75         Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
    76         Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
    77         CleanupMolecule();
    78         delete(first);
    79         delete(last);
    80         delete(end);
    81         delete(start);
     72  if (ListOfBondsPerAtom != NULL)
     73    for(int i=AtomCount;i--;)
     74      Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
     75  Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
     76  Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
     77  CleanupMolecule();
     78  delete(first);
     79  delete(last);
     80  delete(end);
     81  delete(start);
    8282};
    8383
     
    8989bool molecule::AddAtom(atom *pointer)
    9090{
    91         if (pointer != NULL) {
    92                 pointer->sort = &pointer->nr;
    93                 pointer->nr = last_atom++;      // increase number within molecule
    94                 AtomCount++;
    95                 if (pointer->type != NULL) {
    96                         if (ElementsInMolecule[pointer->type->Z] == 0)
    97                                 ElementCount++;
    98                         ElementsInMolecule[pointer->type->Z]++; // increase number of elements
    99                         if (pointer->type->Z != 1)
    100                                 NoNonHydrogen++;
    101                         if (pointer->Name == NULL) {
    102                                 Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
    103                                 pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
    104                                 sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
    105                         }
    106                 }
    107                 return add(pointer, end);
    108         } else
    109                 return false;
     91  if (pointer != NULL) {
     92    pointer->sort = &pointer->nr;
     93    pointer->nr = last_atom++;  // increase number within molecule
     94    AtomCount++;
     95    if (pointer->type != NULL) {
     96      if (ElementsInMolecule[pointer->type->Z] == 0)
     97        ElementCount++;
     98      ElementsInMolecule[pointer->type->Z]++; // increase number of elements
     99      if (pointer->type->Z != 1)
     100        NoNonHydrogen++;
     101      if (pointer->Name == NULL) {
     102        Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
     103        pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
     104        sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
     105      }
     106    }
     107    return add(pointer, end);
     108  } else
     109    return false;
    110110};
    111111
     
    117117atom * molecule::AddCopyAtom(atom *pointer)
    118118{
    119         if (pointer != NULL) {
    120                 atom *walker = new atom();
    121                 walker->type = pointer->type;   // copy element of atom
    122                 walker->x.CopyVector(&pointer->x); // copy coordination
    123                 walker->v.CopyVector(&pointer->v); // copy velocity
    124                 walker->FixedIon = pointer->FixedIon;
    125                 walker->sort = &walker->nr;
    126                 walker->nr = last_atom++;       // increase number within molecule
    127                 walker->father = pointer; //->GetTrueFather();
    128                 walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
    129                 strcpy (walker->Name, pointer->Name);
    130                 add(walker, end);
    131                 if ((pointer->type != NULL) && (pointer->type->Z != 1))
    132                         NoNonHydrogen++;
    133                 AtomCount++;
    134                 return walker;
    135         } else
    136                 return NULL;
     119  if (pointer != NULL) {
     120    atom *walker = new atom();
     121    walker->type = pointer->type;  // copy element of atom
     122    walker->x.CopyVector(&pointer->x); // copy coordination
     123    walker->v.CopyVector(&pointer->v); // copy velocity
     124    walker->FixedIon = pointer->FixedIon;
     125    walker->sort = &walker->nr;
     126    walker->nr = last_atom++;  // increase number within molecule
     127    walker->father = pointer; //->GetTrueFather();
     128    walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
     129    strcpy (walker->Name, pointer->Name);
     130    add(walker, end);
     131    if ((pointer->type != NULL) && (pointer->type->Z != 1))
     132      NoNonHydrogen++;
     133    AtomCount++;
     134    return walker;
     135  } else
     136    return NULL;
    137137};
    138138
     
    142142 * -# Single Bond: Simply add new atom with bond distance rescaled to typical hydrogen one
    143143 * -# Double Bond: Here, we need the **BondList of the \a *origin atom, by scanning for the other bonds instead of
    144  *              *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
    145  *              The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
    146  *              replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
    147  *              element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
    148  *              hydrogens forming this angle with *origin.
     144 *    *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
     145 *    The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
     146 *    replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
     147 *    element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
     148 *    hydrogens forming this angle with *origin.
    149149 * -# 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
    150  *              triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
    151  *              determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
    152  *              We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
    153  *              \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 )}}
    154  *              \f]
    155  *              vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
    156  *              the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
    157  *              The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    158  *              the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    159  *              \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
    160  *              \f]
    161  *              as the coordination of all three atoms in the coordinate system of these three vectors:
    162  *              \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$.
     150 *    triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
     151 *    determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
     152 *    We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
     153 *    \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 )}}
     154 *    \f]
     155 *    vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
     156 *    the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
     157 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
     158 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
     159 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     160 *    \f]
     161 *    as the coordination of all three atoms in the coordinate system of these three vectors:
     162 *    \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$.
    163163 *
    164164 * \param *out output stream for debugging
     
    168168 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    169169 * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    170  * \param NumBond       number of bonds in \a **BondList
     170 * \param NumBond  number of bonds in \a **BondList
    171171 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    172172 * \return number of atoms added, if < bond::BondDegree then something went wrong
     
    175175bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
    176176{
    177         double bondlength;      // bond length of the bond to be replaced/cut
    178         double bondangle;       // bond angle of the bond to be replaced/cut
    179         double BondRescale;      // rescale value for the hydrogen bond length
    180         bool AllWentWell = true;                // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
    181         bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
    182         atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
    183         double b,l,d,f,g, alpha, factors[NDIM];         // hold temporary values in triple bond case for coordination determination
    184         Vector Orthovector1, Orthovector2;      // temporary vectors in coordination construction
    185         Vector InBondvector;            // vector in direction of *Bond
    186         bond *Binder = NULL;
    187         double *matrix;
    188 
    189 //      *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
    190         // create vector in direction of bond
    191         InBondvector.CopyVector(&TopReplacement->x);
    192         InBondvector.SubtractVector(&TopOrigin->x);
    193         bondlength = InBondvector.Norm();
    194 
    195         // is greater than typical bond distance? Then we have to correct periodically
    196         // the problem is not the H being out of the box, but InBondvector have the wrong direction
    197         // due to TopReplacement or Origin being on the wrong side!
    198         if (bondlength > BondDistance) {
    199 //              *out << Verbose(4) << "InBondvector is: ";
    200 //              InBondvector.Output(out);
    201 //              *out << endl;
    202                 Orthovector1.Zero();
    203                 for (int i=NDIM;i--;) {
    204                         l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
    205                         if (fabs(l) > BondDistance) { // is component greater than bond distance
    206                                 Orthovector1.x[i] = (l < 0) ? -1. : +1.;
    207                         } // (signs are correct, was tested!)
    208                 }
    209                 matrix = ReturnFullMatrixforSymmetric(cell_size);
    210                 Orthovector1.MatrixMultiplication(matrix);
    211                 InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
    212                 Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
    213                 bondlength = InBondvector.Norm();
    214 //              *out << Verbose(4) << "Corrected InBondvector is now: ";
    215 //              InBondvector.Output(out);
    216 //              *out << endl;
    217         } // periodic correction finished
    218 
    219         InBondvector.Normalize();
    220         // get typical bond length and store as scale factor for later
    221         BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    222         if (BondRescale == -1) {
    223                 cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    224                 return false;
    225                 BondRescale = bondlength;
    226         } else {
    227                 if (!IsAngstroem)
    228                         BondRescale /= (1.*AtomicLengthToAngstroem);
    229         }
    230 
    231         // discern single, double and triple bonds
    232         switch(TopBond->BondDegree) {
    233                 case 1:
    234                         FirstOtherAtom = new atom();            // new atom
    235                         FirstOtherAtom->type = elemente->FindElement(1);        // element is Hydrogen
    236                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    237                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    238                         if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
    239                                 FirstOtherAtom->father = TopReplacement;
    240                                 BondRescale = bondlength;
    241                         } else {
    242                                 FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
    243                         }
    244                         InBondvector.Scale(&BondRescale);        // rescale the distance vector to Hydrogen bond length
    245                         FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
    246                         FirstOtherAtom->x.AddVector(&InBondvector);     // ... and add distance vector to replacement atom
    247                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    248 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    249 //                      FirstOtherAtom->x.Output(out);
    250 //                      *out << endl;
    251                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    252                         Binder->Cyclic = false;
    253                         Binder->Type = TreeEdge;
    254                         break;
    255                 case 2:
    256                         // determine two other bonds (warning if there are more than two other) plus valence sanity check
    257                         for (int i=0;i<NumBond;i++) {
    258                                 if (BondList[i] != TopBond) {
    259                                         if (FirstBond == NULL) {
    260                                                 FirstBond = BondList[i];
    261                                                 FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    262                                         } else if (SecondBond == NULL) {
    263                                                 SecondBond = BondList[i];
    264                                                 SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    265                                         } else {
    266                                                 *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
    267                                         }
    268                                 }
    269                         }
    270                         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)
    271                                 SecondBond = TopBond;
    272                                 SecondOtherAtom = TopReplacement;
    273                         }
    274                         if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    275 //                              *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;
    276 
    277                                 // determine the plane of these two with the *origin
    278                                 AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
    279                         } else {
    280                                 Orthovector1.GetOneNormalVector(&InBondvector);
    281                         }
    282                         //*out << Verbose(3)<< "Orthovector1: ";
    283                         //Orthovector1.Output(out);
    284                         //*out << endl;
    285                         // orthogonal vector and bond vector between origin and replacement form the new plane
    286                         Orthovector1.MakeNormalVector(&InBondvector);
    287                         Orthovector1.Normalize();
    288                         //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    289 
    290                         // create the two Hydrogens ...
    291                         FirstOtherAtom = new atom();
    292                         SecondOtherAtom = new atom();
    293                         FirstOtherAtom->type = elemente->FindElement(1);
    294                         SecondOtherAtom->type = elemente->FindElement(1);
    295                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    296                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    297                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    298                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    299                         FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
    300                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    301                         bondangle = TopOrigin->type->HBondAngle[1];
    302                         if (bondangle == -1) {
    303                                 *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    304                                 return false;
    305                                 bondangle = 0;
    306                         }
    307                         bondangle *= M_PI/180./2.;
    308 //                      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
    309 //                      InBondvector.Output(out);
    310 //                      *out << endl;
    311 //                      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
    312 //                      Orthovector1.Output(out);
    313 //                      *out << endl;
    314 //                      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
    315                         FirstOtherAtom->x.Zero();
    316                         SecondOtherAtom->x.Zero();
    317                         for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
    318                                 FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
    319                                 SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    320                         }
    321                         FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    322                         SecondOtherAtom->x.Scale(&BondRescale);
    323                         //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    324                         for(int i=NDIM;i--;) { // and make relative to origin atom
    325                                 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326                                 SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    327                         }
    328                         // ... and add to molecule
    329                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    330                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    331 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    332 //                      FirstOtherAtom->x.Output(out);
    333 //                      *out << endl;
    334 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    335 //                      SecondOtherAtom->x.Output(out);
    336 //                      *out << endl;
    337                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    338                         Binder->Cyclic = false;
    339                         Binder->Type = TreeEdge;
    340                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    341                         Binder->Cyclic = false;
    342                         Binder->Type = TreeEdge;
    343                         break;
    344                 case 3:
    345                         // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
    346                         FirstOtherAtom = new atom();
    347                         SecondOtherAtom = new atom();
    348                         ThirdOtherAtom = new atom();
    349                         FirstOtherAtom->type = elemente->FindElement(1);
    350                         SecondOtherAtom->type = elemente->FindElement(1);
    351                         ThirdOtherAtom->type = elemente->FindElement(1);
    352                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    353                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    354                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    355                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    356                         ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    357                         ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
    358                         FirstOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    359                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    360                         ThirdOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    361 
    362                         // we need to vectors orthonormal the InBondvector
    363                         AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
    364 //                      *out << Verbose(3) << "Orthovector1: ";
    365 //                      Orthovector1.Output(out);
    366 //                      *out << endl;
    367                         AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    368 //                      *out << Verbose(3) << "Orthovector2: ";
    369 //                      Orthovector2.Output(out);
    370 //                      *out << endl;
    371 
    372                         // create correct coordination for the three atoms
    373                         alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
    374                         l = BondRescale;                                // desired bond length
    375                         b = 2.*l*sin(alpha);            // base length of isosceles triangle
    376                         d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);    // length for InBondvector
    377                         f = b/sqrt(3.); // length for Orthvector1
    378                         g = b/2.;                                // length for Orthvector2
    379 //                      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
    380 //                      *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;
    381                         factors[0] = d;
    382                         factors[1] = f;
    383                         factors[2] = 0.;
    384                         FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    385                         factors[1] = -0.5*f;
    386                         factors[2] = g;
    387                         SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    388                         factors[2] = -g;
    389                         ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    390 
    391                         // rescale each to correct BondDistance
    392 //                      FirstOtherAtom->x.Scale(&BondRescale);
    393 //                      SecondOtherAtom->x.Scale(&BondRescale);
    394 //                      ThirdOtherAtom->x.Scale(&BondRescale);
    395 
    396                         // and relative to *origin atom
    397                         FirstOtherAtom->x.AddVector(&TopOrigin->x);
    398                         SecondOtherAtom->x.AddVector(&TopOrigin->x);
    399                         ThirdOtherAtom->x.AddVector(&TopOrigin->x);
    400 
    401                         // ... and add to molecule
    402                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    403                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    404                         AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
    405 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    406 //                      FirstOtherAtom->x.Output(out);
    407 //                      *out << endl;
    408 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    409 //                      SecondOtherAtom->x.Output(out);
    410 //                      *out << endl;
    411 //                      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
    412 //                      ThirdOtherAtom->x.Output(out);
    413 //                      *out << endl;
    414                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    415                         Binder->Cyclic = false;
    416                         Binder->Type = TreeEdge;
    417                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    418                         Binder->Cyclic = false;
    419                         Binder->Type = TreeEdge;
    420                         Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
    421                         Binder->Cyclic = false;
    422                         Binder->Type = TreeEdge;
    423                         break;
    424                 default:
    425                         cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
    426                         AllWentWell = false;
    427                         break;
    428         }
    429 
    430 //      *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
    431         return AllWentWell;
     177  double bondlength;  // bond length of the bond to be replaced/cut
     178  double bondangle;  // bond angle of the bond to be replaced/cut
     179  double BondRescale;  // rescale value for the hydrogen bond length
     180  bool AllWentWell = true;    // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
     181  bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
     182  atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
     183  double b,l,d,f,g, alpha, factors[NDIM];    // hold temporary values in triple bond case for coordination determination
     184  Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
     185  Vector InBondvector;    // vector in direction of *Bond
     186  bond *Binder = NULL;
     187  double *matrix;
     188
     189//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     190  // create vector in direction of bond
     191  InBondvector.CopyVector(&TopReplacement->x);
     192  InBondvector.SubtractVector(&TopOrigin->x);
     193  bondlength = InBondvector.Norm();
     194
     195  // is greater than typical bond distance? Then we have to correct periodically
     196  // the problem is not the H being out of the box, but InBondvector have the wrong direction
     197  // due to TopReplacement or Origin being on the wrong side!
     198  if (bondlength > BondDistance) {
     199//    *out << Verbose(4) << "InBondvector is: ";
     200//    InBondvector.Output(out);
     201//    *out << endl;
     202    Orthovector1.Zero();
     203    for (int i=NDIM;i--;) {
     204      l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
     205      if (fabs(l) > BondDistance) { // is component greater than bond distance
     206        Orthovector1.x[i] = (l < 0) ? -1. : +1.;
     207      } // (signs are correct, was tested!)
     208    }
     209    matrix = ReturnFullMatrixforSymmetric(cell_size);
     210    Orthovector1.MatrixMultiplication(matrix);
     211    InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
     212    Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
     213    bondlength = InBondvector.Norm();
     214//    *out << Verbose(4) << "Corrected InBondvector is now: ";
     215//    InBondvector.Output(out);
     216//    *out << endl;
     217  } // periodic correction finished
     218
     219  InBondvector.Normalize();
     220  // get typical bond length and store as scale factor for later
     221  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
     222  if (BondRescale == -1) {
     223    cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     224    return false;
     225    BondRescale = bondlength;
     226  } else {
     227    if (!IsAngstroem)
     228      BondRescale /= (1.*AtomicLengthToAngstroem);
     229  }
     230
     231  // discern single, double and triple bonds
     232  switch(TopBond->BondDegree) {
     233    case 1:
     234      FirstOtherAtom = new atom();    // new atom
     235      FirstOtherAtom->type = elemente->FindElement(1);  // element is Hydrogen
     236      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     237      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     238      if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
     239        FirstOtherAtom->father = TopReplacement;
     240        BondRescale = bondlength;
     241      } else {
     242        FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
     243      }
     244      InBondvector.Scale(&BondRescale);  // rescale the distance vector to Hydrogen bond length
     245      FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
     246      FirstOtherAtom->x.AddVector(&InBondvector);  // ... and add distance vector to replacement atom
     247      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     248//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     249//      FirstOtherAtom->x.Output(out);
     250//      *out << endl;
     251      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     252      Binder->Cyclic = false;
     253      Binder->Type = TreeEdge;
     254      break;
     255    case 2:
     256      // determine two other bonds (warning if there are more than two other) plus valence sanity check
     257      for (int i=0;i<NumBond;i++) {
     258        if (BondList[i] != TopBond) {
     259          if (FirstBond == NULL) {
     260            FirstBond = BondList[i];
     261            FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     262          } else if (SecondBond == NULL) {
     263            SecondBond = BondList[i];
     264            SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     265          } else {
     266            *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     267          }
     268        }
     269      }
     270      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)
     271        SecondBond = TopBond;
     272        SecondOtherAtom = TopReplacement;
     273      }
     274      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
     275//        *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;
     276
     277        // determine the plane of these two with the *origin
     278        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     279      } else {
     280        Orthovector1.GetOneNormalVector(&InBondvector);
     281      }
     282      //*out << Verbose(3)<< "Orthovector1: ";
     283      //Orthovector1.Output(out);
     284      //*out << endl;
     285      // orthogonal vector and bond vector between origin and replacement form the new plane
     286      Orthovector1.MakeNormalVector(&InBondvector);
     287      Orthovector1.Normalize();
     288      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
     289
     290      // create the two Hydrogens ...
     291      FirstOtherAtom = new atom();
     292      SecondOtherAtom = new atom();
     293      FirstOtherAtom->type = elemente->FindElement(1);
     294      SecondOtherAtom->type = elemente->FindElement(1);
     295      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     296      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     297      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     298      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     299      FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
     300      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     301      bondangle = TopOrigin->type->HBondAngle[1];
     302      if (bondangle == -1) {
     303        *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     304        return false;
     305        bondangle = 0;
     306      }
     307      bondangle *= M_PI/180./2.;
     308//      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
     309//      InBondvector.Output(out);
     310//      *out << endl;
     311//      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
     312//      Orthovector1.Output(out);
     313//      *out << endl;
     314//      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
     315      FirstOtherAtom->x.Zero();
     316      SecondOtherAtom->x.Zero();
     317      for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
     318        FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
     319        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
     320      }
     321      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     322      SecondOtherAtom->x.Scale(&BondRescale);
     323      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
     324      for(int i=NDIM;i--;) { // and make relative to origin atom
     325        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     326        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
     327      }
     328      // ... and add to molecule
     329      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     330      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     331//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     332//      FirstOtherAtom->x.Output(out);
     333//      *out << endl;
     334//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     335//      SecondOtherAtom->x.Output(out);
     336//      *out << endl;
     337      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     338      Binder->Cyclic = false;
     339      Binder->Type = TreeEdge;
     340      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     341      Binder->Cyclic = false;
     342      Binder->Type = TreeEdge;
     343      break;
     344    case 3:
     345      // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
     346      FirstOtherAtom = new atom();
     347      SecondOtherAtom = new atom();
     348      ThirdOtherAtom = new atom();
     349      FirstOtherAtom->type = elemente->FindElement(1);
     350      SecondOtherAtom->type = elemente->FindElement(1);
     351      ThirdOtherAtom->type = elemente->FindElement(1);
     352      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     353      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     354      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     355      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     356      ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     357      ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
     358      FirstOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     359      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     360      ThirdOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     361
     362      // we need to vectors orthonormal the InBondvector
     363      AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
     364//      *out << Verbose(3) << "Orthovector1: ";
     365//      Orthovector1.Output(out);
     366//      *out << endl;
     367      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
     368//      *out << Verbose(3) << "Orthovector2: ";
     369//      Orthovector2.Output(out);
     370//      *out << endl;
     371
     372      // create correct coordination for the three atoms
     373      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     374      l = BondRescale;        // desired bond length
     375      b = 2.*l*sin(alpha);    // base length of isosceles triangle
     376      d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);  // length for InBondvector
     377      f = b/sqrt(3.);  // length for Orthvector1
     378      g = b/2.;        // length for Orthvector2
     379//      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
     380//      *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;
     381      factors[0] = d;
     382      factors[1] = f;
     383      factors[2] = 0.;
     384      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     385      factors[1] = -0.5*f;
     386      factors[2] = g;
     387      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     388      factors[2] = -g;
     389      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     390
     391      // rescale each to correct BondDistance
     392//      FirstOtherAtom->x.Scale(&BondRescale);
     393//      SecondOtherAtom->x.Scale(&BondRescale);
     394//      ThirdOtherAtom->x.Scale(&BondRescale);
     395
     396      // and relative to *origin atom
     397      FirstOtherAtom->x.AddVector(&TopOrigin->x);
     398      SecondOtherAtom->x.AddVector(&TopOrigin->x);
     399      ThirdOtherAtom->x.AddVector(&TopOrigin->x);
     400
     401      // ... and add to molecule
     402      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     403      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     404      AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
     405//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     406//      FirstOtherAtom->x.Output(out);
     407//      *out << endl;
     408//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     409//      SecondOtherAtom->x.Output(out);
     410//      *out << endl;
     411//      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
     412//      ThirdOtherAtom->x.Output(out);
     413//      *out << endl;
     414      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     415      Binder->Cyclic = false;
     416      Binder->Type = TreeEdge;
     417      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     418      Binder->Cyclic = false;
     419      Binder->Type = TreeEdge;
     420      Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
     421      Binder->Cyclic = false;
     422      Binder->Type = TreeEdge;
     423      break;
     424    default:
     425      cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
     426      AllWentWell = false;
     427      break;
     428  }
     429
     430//  *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
     431  return AllWentWell;
    432432};
    433433
     
    439439bool molecule::AddXYZFile(string filename)
    440440{
    441         istringstream *input = NULL;
    442         int NumberOfAtoms = 0; // atom number in xyz read
    443         int i, j; // loop variables
    444         atom *Walker = NULL;    // pointer to added atom
    445         char shorthand[3];      // shorthand for atom name
    446         ifstream xyzfile;        // xyz file
    447         string line;            // currently parsed line
    448         double x[3];            // atom coordinates
    449 
    450         xyzfile.open(filename.c_str());
    451         if (!xyzfile)
    452                 return false;
    453 
    454         getline(xyzfile,line,'\n'); // Read numer of atoms in file
    455         input = new istringstream(line);
    456         *input >> NumberOfAtoms;
    457         cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    458         getline(xyzfile,line,'\n'); // Read comment
    459         cout << Verbose(1) << "Comment: " << line << endl;
    460 
    461         if (MDSteps == 0) // no atoms yet present
    462                 MDSteps++;
    463         for(i=0;i<NumberOfAtoms;i++){
    464                 Walker = new atom;
    465                 getline(xyzfile,line,'\n');
    466                 istringstream *item = new istringstream(line);
    467                 //istringstream input(line);
    468                 //cout << Verbose(1) << "Reading: " << line << endl;
    469                 *item >> shorthand;
    470                 *item >> x[0];
    471                 *item >> x[1];
    472                 *item >> x[2];
    473                 Walker->type = elemente->FindElement(shorthand);
    474                 if (Walker->type == NULL) {
    475                         cerr << "Could not parse the element at line: '" << line << "', setting to H.";
    476                         Walker->type = elemente->FindElement(1);
    477                 }
    478                 if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
    479                         Trajectories[Walker].R.resize(MDSteps+10);
    480                         Trajectories[Walker].U.resize(MDSteps+10);
    481                         Trajectories[Walker].F.resize(MDSteps+10);
    482                 }
    483                 for(j=NDIM;j--;) {
    484                         Walker->x.x[j] = x[j];
    485                         Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
    486                         Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
    487                         Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
    488                 }
    489                 AddAtom(Walker);        // add to molecule
    490                 delete(item);
    491         }
    492         xyzfile.close();
    493         delete(input);
    494         return true;
     441  istringstream *input = NULL;
     442  int NumberOfAtoms = 0; // atom number in xyz read
     443  int i, j; // loop variables
     444  atom *Walker = NULL;  // pointer to added atom
     445  char shorthand[3];  // shorthand for atom name
     446  ifstream xyzfile;  // xyz file
     447  string line;    // currently parsed line
     448  double x[3];    // atom coordinates
     449
     450  xyzfile.open(filename.c_str());
     451  if (!xyzfile)
     452    return false;
     453
     454  getline(xyzfile,line,'\n'); // Read numer of atoms in file
     455  input = new istringstream(line);
     456  *input >> NumberOfAtoms;
     457  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     458  getline(xyzfile,line,'\n'); // Read comment
     459  cout << Verbose(1) << "Comment: " << line << endl;
     460
     461  if (MDSteps == 0) // no atoms yet present
     462    MDSteps++;
     463  for(i=0;i<NumberOfAtoms;i++){
     464    Walker = new atom;
     465    getline(xyzfile,line,'\n');
     466    istringstream *item = new istringstream(line);
     467    //istringstream input(line);
     468    //cout << Verbose(1) << "Reading: " << line << endl;
     469    *item >> shorthand;
     470    *item >> x[0];
     471    *item >> x[1];
     472    *item >> x[2];
     473    Walker->type = elemente->FindElement(shorthand);
     474    if (Walker->type == NULL) {
     475      cerr << "Could not parse the element at line: '" << line << "', setting to H.";
     476      Walker->type = elemente->FindElement(1);
     477    }
     478    if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
     479      Trajectories[Walker].R.resize(MDSteps+10);
     480      Trajectories[Walker].U.resize(MDSteps+10);
     481      Trajectories[Walker].F.resize(MDSteps+10);
     482    }
     483    for(j=NDIM;j--;) {
     484      Walker->x.x[j] = x[j];
     485      Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
     486      Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
     487      Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
     488    }
     489    AddAtom(Walker);  // add to molecule
     490    delete(item);
     491  }
     492  xyzfile.close();
     493  delete(input);
     494  return true;
    495495};
    496496
     
    500500molecule *molecule::CopyMolecule()
    501501{
    502         molecule *copy = new molecule(elemente);
    503         atom *CurrentAtom = NULL;
    504         atom *LeftAtom = NULL, *RightAtom = NULL;
    505         atom *Walker = NULL;
    506 
    507         // copy all atoms
    508         Walker = start;
    509         while(Walker->next != end) {
    510                 Walker = Walker->next;
    511                 CurrentAtom = copy->AddCopyAtom(Walker);
    512         }
    513 
    514         // copy all bonds
    515         bond *Binder = first;
    516         bond *NewBond = NULL;
    517         while(Binder->next != last) {
    518                 Binder = Binder->next;
    519                 // get the pendant atoms of current bond in the copy molecule
    520                 LeftAtom = copy->start;
    521                 while (LeftAtom->next != copy->end) {
    522                         LeftAtom = LeftAtom->next;
    523                         if (LeftAtom->father == Binder->leftatom)
    524                                 break;
    525                 }
    526                 RightAtom = copy->start;
    527                 while (RightAtom->next != copy->end) {
    528                         RightAtom = RightAtom->next;
    529                         if (RightAtom->father == Binder->rightatom)
    530                                 break;
    531                 }
    532                 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
    533                 NewBond->Cyclic = Binder->Cyclic;
    534                 if (Binder->Cyclic)
    535                         copy->NoCyclicBonds++;
    536                 NewBond->Type = Binder->Type;
    537         }
    538         // correct fathers
    539         Walker = copy->start;
    540         while(Walker->next != copy->end) {
    541                 Walker = Walker->next;
    542                 if (Walker->father->father == Walker->father)    // same atom in copy's father points to itself
    543                         Walker->father = Walker;        // set father to itself (copy of a whole molecule)
    544                 else
    545                  Walker->father = Walker->father->father;       // set father to original's father
    546         }
    547         // copy values
    548         copy->CountAtoms((ofstream *)&cout);
    549         copy->CountElements();
    550         if (first->next != last) {      // if adjaceny list is present
    551                 copy->BondDistance = BondDistance;
    552                 copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    553         }
    554 
    555         return copy;
     502  molecule *copy = new molecule(elemente);
     503  atom *CurrentAtom = NULL;
     504  atom *LeftAtom = NULL, *RightAtom = NULL;
     505  atom *Walker = NULL;
     506
     507  // copy all atoms
     508  Walker = start;
     509  while(Walker->next != end) {
     510    Walker = Walker->next;
     511    CurrentAtom = copy->AddCopyAtom(Walker);
     512  }
     513
     514  // copy all bonds
     515  bond *Binder = first;
     516  bond *NewBond = NULL;
     517  while(Binder->next != last) {
     518    Binder = Binder->next;
     519    // get the pendant atoms of current bond in the copy molecule
     520    LeftAtom = copy->start;
     521    while (LeftAtom->next != copy->end) {
     522      LeftAtom = LeftAtom->next;
     523      if (LeftAtom->father == Binder->leftatom)
     524        break;
     525    }
     526    RightAtom = copy->start;
     527    while (RightAtom->next != copy->end) {
     528      RightAtom = RightAtom->next;
     529      if (RightAtom->father == Binder->rightatom)
     530        break;
     531    }
     532    NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
     533    NewBond->Cyclic = Binder->Cyclic;
     534    if (Binder->Cyclic)
     535      copy->NoCyclicBonds++;
     536    NewBond->Type = Binder->Type;
     537  }
     538  // correct fathers
     539  Walker = copy->start;
     540  while(Walker->next != copy->end) {
     541    Walker = Walker->next;
     542    if (Walker->father->father == Walker->father)  // same atom in copy's father points to itself
     543      Walker->father = Walker;  // set father to itself (copy of a whole molecule)
     544    else
     545     Walker->father = Walker->father->father;  // set father to original's father
     546  }
     547  // copy values
     548  copy->CountAtoms((ofstream *)&cout);
     549  copy->CountElements();
     550  if (first->next != last) {  // if adjaceny list is present
     551    copy->BondDistance = BondDistance;
     552    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
     553  }
     554
     555  return copy;
    556556};
    557557
     
    564564bond * molecule::AddBond(atom *atom1, atom *atom2, int degree=1)
    565565{
    566         bond *Binder = NULL;
    567         if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    568                 Binder = new bond(atom1, atom2, degree, BondCount++);
    569                 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    570                         NoNonBonds++;
    571                 add(Binder, last);
    572         } else {
    573                 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;
    574         }
    575         return Binder;
     566  bond *Binder = NULL;
     567  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
     568    Binder = new bond(atom1, atom2, degree, BondCount++);
     569    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
     570      NoNonBonds++;
     571    add(Binder, last);
     572  } else {
     573    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;
     574  }
     575  return Binder;
    576576};
    577577
     
    583583bool molecule::RemoveBond(bond *pointer)
    584584{
    585         //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    586         removewithoutcheck(pointer);
    587         return true;
     585  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     586  removewithoutcheck(pointer);
     587  return true;
    588588};
    589589
     
    595595bool molecule::RemoveBonds(atom *BondPartner)
    596596{
    597         cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    598         return false;
     597  cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     598  return false;
    599599};
    600600
     
    619619void molecule::SetBoxDimension(Vector *dim)
    620620{
    621         cell_size[0] = dim->x[0];
    622         cell_size[1] = 0.;
    623         cell_size[2] = dim->x[1];
    624         cell_size[3] = 0.;
    625         cell_size[4] = 0.;
    626         cell_size[5] = dim->x[2];
     621  cell_size[0] = dim->x[0];
     622  cell_size[1] = 0.;
     623  cell_size[2] = dim->x[1];
     624  cell_size[3] = 0.;
     625  cell_size[4] = 0.;
     626  cell_size[5] = dim->x[2];
    627627};
    628628
     
    632632bool molecule::CenterInBox(ofstream *out)
    633633{
    634         bool status = true;
    635         atom *ptr = NULL;
    636         Vector x;
    637         double *M = ReturnFullMatrixforSymmetric(cell_size);
     634  bool status = true;
     635  atom *ptr = NULL;
     636  Vector x;
     637  double *M = ReturnFullMatrixforSymmetric(cell_size);
    638638  double *Minv = x.InverseMatrix(M);
    639         double value;
    640 
    641 //      cout << "The box matrix is :" << endl;
     639  double value;
     640
     641//  cout << "The box matrix is :" << endl;
    642642//  for (int i=0;i<NDIM;++i) {
    643643//    for (int j=0;j<NDIM;++j)
     
    651651//    cout << endl;
    652652//  }
    653         // go through all atoms
     653  // go through all atoms
    654654  ptr = start->next;  // start at first in list
    655655  if (ptr != end) {  //list not empty?
     
    676676  delete(M);
    677677  delete(Minv);
    678         return status;
     678  return status;
    679679};
    680680
     
    685685void molecule::CenterEdge(ofstream *out, Vector *max)
    686686{
    687         Vector *min = new Vector;
    688 
    689 //      *out << Verbose(3) << "Begin of CenterEdge." << endl;
    690         atom *ptr = start->next;        // start at first in list
    691         if (ptr != end) {        //list not empty?
    692                 for (int i=NDIM;i--;) {
    693                         max->x[i] = ptr->x.x[i];
    694                         min->x[i] = ptr->x.x[i];
    695                 }
    696                 while (ptr->next != end) {      // continue with second if present
    697                         ptr = ptr->next;
    698                         //ptr->Output(1,1,out);
    699                         for (int i=NDIM;i--;) {
    700                                 max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    701                                 min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    702                         }
    703                 }
    704 //              *out << Verbose(4) << "Maximum is ";
    705 //              max->Output(out);
    706 //              *out << ", Minimum is ";
    707 //              min->Output(out);
    708 //              *out << endl;
    709                 min->Scale(-1.);
    710                 max->AddVector(min);
    711                 Translate(min);
    712         }
    713         delete(min);
    714 //      *out << Verbose(3) << "End of CenterEdge." << endl;
     687  Vector *min = new Vector;
     688
     689//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
     690  atom *ptr = start->next;  // start at first in list
     691  if (ptr != end) {  //list not empty?
     692    for (int i=NDIM;i--;) {
     693      max->x[i] = ptr->x.x[i];
     694      min->x[i] = ptr->x.x[i];
     695    }
     696    while (ptr->next != end) {  // continue with second if present
     697      ptr = ptr->next;
     698      //ptr->Output(1,1,out);
     699      for (int i=NDIM;i--;) {
     700        max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     701        min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     702      }
     703    }
     704//    *out << Verbose(4) << "Maximum is ";
     705//    max->Output(out);
     706//    *out << ", Minimum is ";
     707//    min->Output(out);
     708//    *out << endl;
     709    min->Scale(-1.);
     710    max->AddVector(min);
     711    Translate(min);
     712  }
     713  delete(min);
     714//  *out << Verbose(3) << "End of CenterEdge." << endl;
    715715};
    716716
     
    721721void molecule::CenterOrigin(ofstream *out, Vector *center)
    722722{
    723         int Num = 0;
    724         atom *ptr = start->next;        // start at first in list
    725 
    726         for(int i=NDIM;i--;) // zero center vector
    727                 center->x[i] = 0.;
    728 
    729         if (ptr != end) {        //list not empty?
    730                 while (ptr->next != end) {      // continue with second if present
    731                         ptr = ptr->next;
    732                         Num++;
    733                         center->AddVector(&ptr->x);
    734                 }
    735                 center->Scale(-1./Num); // divide through total number (and sign for direction)
    736                 Translate(center);
    737         }
     723  int Num = 0;
     724  atom *ptr = start->next;  // start at first in list
     725
     726  for(int i=NDIM;i--;) // zero center vector
     727    center->x[i] = 0.;
     728
     729  if (ptr != end) {  //list not empty?
     730    while (ptr->next != end) {  // continue with second if present
     731      ptr = ptr->next;
     732      Num++;
     733      center->AddVector(&ptr->x);
     734    }
     735    center->Scale(-1./Num); // divide through total number (and sign for direction)
     736    Translate(center);
     737  }
    738738};
    739739
     
    744744Vector * molecule::DetermineCenterOfAll(ofstream *out)
    745745{
    746         atom *ptr = start->next;        // start at first in list
    747         Vector *a = new Vector();
    748         Vector tmp;
    749         double Num = 0;
    750 
    751         a->Zero();
    752 
    753         if (ptr != end) {        //list not empty?
    754                 while (ptr->next != end) {      // continue with second if present
    755                         ptr = ptr->next;
    756                         Num += 1.;
    757                         tmp.CopyVector(&ptr->x);
    758                         a->AddVector(&tmp);
    759                 }
    760                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    761         }
    762         //cout << Verbose(1) << "Resulting center of gravity: ";
    763         //a->Output(out);
    764         //cout << endl;
    765         return a;
     746  atom *ptr = start->next;  // start at first in list
     747  Vector *a = new Vector();
     748  Vector tmp;
     749  double Num = 0;
     750
     751  a->Zero();
     752
     753  if (ptr != end) {  //list not empty?
     754    while (ptr->next != end) {  // continue with second if present
     755      ptr = ptr->next;
     756      Num += 1.;
     757      tmp.CopyVector(&ptr->x);
     758      a->AddVector(&tmp);
     759    }
     760    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     761  }
     762  //cout << Verbose(1) << "Resulting center of gravity: ";
     763  //a->Output(out);
     764  //cout << endl;
     765  return a;
    766766};
    767767
     
    772772Vector * molecule::DetermineCenterOfGravity(ofstream *out)
    773773{
    774         atom *ptr = start->next;        // start at first in list
    775         Vector *a = new Vector();
    776         Vector tmp;
    777         double Num = 0;
    778 
    779         a->Zero();
    780 
    781         if (ptr != end) {        //list not empty?
    782                 while (ptr->next != end) {      // continue with second if present
    783                         ptr = ptr->next;
    784                         Num += ptr->type->mass;
    785                         tmp.CopyVector(&ptr->x);
    786                         tmp.Scale(ptr->type->mass);     // scale by mass
    787                         a->AddVector(&tmp);
    788                 }
    789                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    790         }
    791 //      *out << Verbose(1) << "Resulting center of gravity: ";
    792 //      a->Output(out);
    793 //      *out << endl;
    794         return a;
     774  atom *ptr = start->next;  // start at first in list
     775  Vector *a = new Vector();
     776  Vector tmp;
     777  double Num = 0;
     778
     779  a->Zero();
     780
     781  if (ptr != end) {  //list not empty?
     782    while (ptr->next != end) {  // continue with second if present
     783      ptr = ptr->next;
     784      Num += ptr->type->mass;
     785      tmp.CopyVector(&ptr->x);
     786      tmp.Scale(ptr->type->mass);  // scale by mass
     787      a->AddVector(&tmp);
     788    }
     789    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     790  }
     791//  *out << Verbose(1) << "Resulting center of gravity: ";
     792//  a->Output(out);
     793//  *out << endl;
     794  return a;
    795795};
    796796
     
    801801void molecule::CenterGravity(ofstream *out, Vector *center)
    802802{
    803         if (center == NULL) {
    804                 DetermineCenter(*center);
    805                 Translate(center);
    806                 delete(center);
    807         } else {
    808                 Translate(center);
    809         }
     803  if (center == NULL) {
     804    DetermineCenter(*center);
     805    Translate(center);
     806    delete(center);
     807  } else {
     808    Translate(center);
     809  }
    810810};
    811811
     
    815815void molecule::Scale(double **factor)
    816816{
    817         atom *ptr = start;
    818 
    819         while (ptr->next != end) {
    820                 ptr = ptr->next;
    821                 for (int j=0;j<MDSteps;j++)
    822                         Trajectories[ptr].R.at(j).Scale(factor);
    823                 ptr->x.Scale(factor);
    824         }
     817  atom *ptr = start;
     818
     819  while (ptr->next != end) {
     820    ptr = ptr->next;
     821    for (int j=0;j<MDSteps;j++)
     822      Trajectories[ptr].R.at(j).Scale(factor);
     823    ptr->x.Scale(factor);
     824  }
    825825};
    826826
     
    830830void molecule::Translate(const Vector *trans)
    831831{
    832         atom *ptr = start;
    833 
    834         while (ptr->next != end) {
    835                 ptr = ptr->next;
    836                 for (int j=0;j<MDSteps;j++)
    837                         Trajectories[ptr].R.at(j).Translate(trans);
    838                 ptr->x.Translate(trans);
    839         }
     832  atom *ptr = start;
     833
     834  while (ptr->next != end) {
     835    ptr = ptr->next;
     836    for (int j=0;j<MDSteps;j++)
     837      Trajectories[ptr].R.at(j).Translate(trans);
     838    ptr->x.Translate(trans);
     839  }
    840840};
    841841
     
    900900void molecule::Mirror(const Vector *n)
    901901{
    902         atom *ptr = start;
    903 
    904         while (ptr->next != end) {
    905                 ptr = ptr->next;
    906                 for (int j=0;j<MDSteps;j++)
    907                         Trajectories[ptr].R.at(j).Mirror(n);
    908                 ptr->x.Mirror(n);
    909         }
     902  atom *ptr = start;
     903
     904  while (ptr->next != end) {
     905    ptr = ptr->next;
     906    for (int j=0;j<MDSteps;j++)
     907      Trajectories[ptr].R.at(j).Mirror(n);
     908    ptr->x.Mirror(n);
     909  }
    910910};
    911911
     
    915915void molecule::DetermineCenter(Vector &Center)
    916916{
    917         atom *Walker = start;
    918         bond *Binder = NULL;
    919         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    920         double tmp;
    921         bool flag;
    922         Vector Testvector, Translationvector;
    923 
    924         do {
    925                 Center.Zero();
    926                 flag = true;
    927                 while (Walker->next != end) {
    928                         Walker = Walker->next;
     917  atom *Walker = start;
     918  bond *Binder = NULL;
     919  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     920  double tmp;
     921  bool flag;
     922  Vector Testvector, Translationvector;
     923
     924  do {
     925    Center.Zero();
     926    flag = true;
     927    while (Walker->next != end) {
     928      Walker = Walker->next;
    929929#ifdef ADDHYDROGEN
    930                         if (Walker->type->Z != 1) {
     930      if (Walker->type->Z != 1) {
    931931#endif
    932                                 Testvector.CopyVector(&Walker->x);
    933                                 Testvector.InverseMatrixMultiplication(matrix);
    934                                 Translationvector.Zero();
    935                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    936                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    937                                         if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    938                                                 for (int j=0;j<NDIM;j++) {
    939                                                         tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    940                                                         if ((fabs(tmp)) > BondDistance) {
    941                                                                 flag = false;
    942                                                                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
    943                                                                 if (tmp > 0)
    944                                                                         Translationvector.x[j] -= 1.;
    945                                                                 else
    946                                                                         Translationvector.x[j] += 1.;
    947                                                         }
    948                                                 }
    949                                 }
    950                                 Testvector.AddVector(&Translationvector);
    951                                 Testvector.MatrixMultiplication(matrix);
    952                                 Center.AddVector(&Testvector);
    953                                 cout << Verbose(1) << "vector is: ";
    954                                 Testvector.Output((ofstream *)&cout);
    955                                 cout << endl;
     932        Testvector.CopyVector(&Walker->x);
     933        Testvector.InverseMatrixMultiplication(matrix);
     934        Translationvector.Zero();
     935        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     936          Binder = ListOfBondsPerAtom[Walker->nr][i];
     937          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     938            for (int j=0;j<NDIM;j++) {
     939              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     940              if ((fabs(tmp)) > BondDistance) {
     941                flag = false;
     942                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     943                if (tmp > 0)
     944                  Translationvector.x[j] -= 1.;
     945                else
     946                  Translationvector.x[j] += 1.;
     947              }
     948            }
     949        }
     950        Testvector.AddVector(&Translationvector);
     951        Testvector.MatrixMultiplication(matrix);
     952        Center.AddVector(&Testvector);
     953        cout << Verbose(1) << "vector is: ";
     954        Testvector.Output((ofstream *)&cout);
     955        cout << endl;
    956956#ifdef ADDHYDROGEN
    957                                 // now also change all hydrogens
    958                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    959                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    960                                         if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    961                                                 Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
    962                                                 Testvector.InverseMatrixMultiplication(matrix);
    963                                                 Testvector.AddVector(&Translationvector);
    964                                                 Testvector.MatrixMultiplication(matrix);
    965                                                 Center.AddVector(&Testvector);
    966                                                 cout << Verbose(1) << "Hydrogen vector is: ";
    967                                                 Testvector.Output((ofstream *)&cout);
    968                                                 cout << endl;
    969                                         }
    970                                 }
    971                         }
     957        // now also change all hydrogens
     958        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     959          Binder = ListOfBondsPerAtom[Walker->nr][i];
     960          if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
     961            Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     962            Testvector.InverseMatrixMultiplication(matrix);
     963            Testvector.AddVector(&Translationvector);
     964            Testvector.MatrixMultiplication(matrix);
     965            Center.AddVector(&Testvector);
     966            cout << Verbose(1) << "Hydrogen vector is: ";
     967            Testvector.Output((ofstream *)&cout);
     968            cout << endl;
     969          }
     970        }
     971      }
    972972#endif
    973                 }
    974         } while (!flag);
    975         Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
    976         Center.Scale(1./(double)AtomCount);
     973    }
     974  } while (!flag);
     975  Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
     976  Center.Scale(1./(double)AtomCount);
    977977};
    978978
     
    983983void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate)
    984984{
    985         atom *ptr = start;      // start at first in list
    986         double InertiaTensor[NDIM*NDIM];
    987         Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    988 
    989         CenterGravity(out, CenterOfGravity);
    990 
    991         // reset inertia tensor
    992         for(int i=0;i<NDIM*NDIM;i++)
    993                 InertiaTensor[i] = 0.;
    994 
    995         // sum up inertia tensor
    996         while (ptr->next != end) {
    997                 ptr = ptr->next;
    998                 Vector x;
    999                 x.CopyVector(&ptr->x);
    1000                 //x.SubtractVector(CenterOfGravity);
    1001                 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    1002                 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    1003                 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    1004                 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    1005                 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    1006                 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    1007                 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    1008                 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    1009                 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    1010         }
    1011         // print InertiaTensor for debugging
    1012         *out << "The inertia tensor is:" << endl;
    1013         for(int i=0;i<NDIM;i++) {
    1014                 for(int j=0;j<NDIM;j++)
    1015                         *out << InertiaTensor[i*NDIM+j] << " ";
    1016                 *out << endl;
    1017         }
    1018         *out << endl;
    1019 
    1020         // diagonalize to determine principal axis system
    1021         gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
    1022         gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
    1023         gsl_vector *eval = gsl_vector_alloc(NDIM);
    1024         gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
    1025         gsl_eigen_symmv(&m.matrix, eval, evec, T);
    1026         gsl_eigen_symmv_free(T);
    1027         gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    1028 
    1029         for(int i=0;i<NDIM;i++) {
    1030                 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    1031                 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    1032         }
    1033 
    1034         // check whether we rotate or not
    1035         if (DoRotate) {
    1036                 *out << Verbose(1) << "Transforming molecule into PAS ... ";
    1037                 // the eigenvectors specify the transformation matrix
    1038                 ptr = start;
    1039                 while (ptr->next != end) {
    1040                         ptr = ptr->next;
    1041                         for (int j=0;j<MDSteps;j++)
    1042                                 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
    1043                         ptr->x.MatrixMultiplication(evec->data);
    1044                 }
    1045                 *out << "done." << endl;
    1046 
    1047                 // summing anew for debugging (resulting matrix has to be diagonal!)
    1048                 // reset inertia tensor
    1049                 for(int i=0;i<NDIM*NDIM;i++)
    1050                         InertiaTensor[i] = 0.;
    1051 
    1052                 // sum up inertia tensor
    1053                 ptr = start;
    1054                 while (ptr->next != end) {
    1055                         ptr = ptr->next;
    1056                         Vector x;
    1057                         x.CopyVector(&ptr->x);
    1058                         //x.SubtractVector(CenterOfGravity);
    1059                         InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    1060                         InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    1061                         InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    1062                         InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    1063                         InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    1064                         InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    1065                         InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    1066                         InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    1067                         InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    1068                 }
    1069                 // print InertiaTensor for debugging
    1070                 *out << "The inertia tensor is:" << endl;
    1071                 for(int i=0;i<NDIM;i++) {
    1072                         for(int j=0;j<NDIM;j++)
    1073                                 *out << InertiaTensor[i*NDIM+j] << " ";
    1074                         *out << endl;
    1075                 }
    1076                 *out << endl;
    1077         }
    1078 
    1079         // free everything
    1080         delete(CenterOfGravity);
    1081         gsl_vector_free(eval);
    1082         gsl_matrix_free(evec);
     985  atom *ptr = start;  // start at first in list
     986  double InertiaTensor[NDIM*NDIM];
     987  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
     988
     989  CenterGravity(out, CenterOfGravity);
     990
     991  // reset inertia tensor
     992  for(int i=0;i<NDIM*NDIM;i++)
     993    InertiaTensor[i] = 0.;
     994
     995  // sum up inertia tensor
     996  while (ptr->next != end) {
     997    ptr = ptr->next;
     998    Vector x;
     999    x.CopyVector(&ptr->x);
     1000    //x.SubtractVector(CenterOfGravity);
     1001    InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     1002    InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     1003    InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     1004    InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     1005    InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     1006    InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     1007    InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     1008    InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     1009    InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     1010  }
     1011  // print InertiaTensor for debugging
     1012  *out << "The inertia tensor is:" << endl;
     1013  for(int i=0;i<NDIM;i++) {
     1014    for(int j=0;j<NDIM;j++)
     1015      *out << InertiaTensor[i*NDIM+j] << " ";
     1016    *out << endl;
     1017  }
     1018  *out << endl;
     1019
     1020  // diagonalize to determine principal axis system
     1021  gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     1022  gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
     1023  gsl_vector *eval = gsl_vector_alloc(NDIM);
     1024  gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
     1025  gsl_eigen_symmv(&m.matrix, eval, evec, T);
     1026  gsl_eigen_symmv_free(T);
     1027  gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
     1028
     1029  for(int i=0;i<NDIM;i++) {
     1030    *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
     1031    *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
     1032  }
     1033
     1034  // check whether we rotate or not
     1035  if (DoRotate) {
     1036    *out << Verbose(1) << "Transforming molecule into PAS ... ";
     1037    // the eigenvectors specify the transformation matrix
     1038    ptr = start;
     1039    while (ptr->next != end) {
     1040      ptr = ptr->next;
     1041      for (int j=0;j<MDSteps;j++)
     1042        Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
     1043      ptr->x.MatrixMultiplication(evec->data);
     1044    }
     1045    *out << "done." << endl;
     1046
     1047    // summing anew for debugging (resulting matrix has to be diagonal!)
     1048    // reset inertia tensor
     1049    for(int i=0;i<NDIM*NDIM;i++)
     1050      InertiaTensor[i] = 0.;
     1051
     1052    // sum up inertia tensor
     1053    ptr = start;
     1054    while (ptr->next != end) {
     1055      ptr = ptr->next;
     1056      Vector x;
     1057      x.CopyVector(&ptr->x);
     1058      //x.SubtractVector(CenterOfGravity);
     1059      InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     1060      InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     1061      InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     1062      InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     1063      InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     1064      InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     1065      InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     1066      InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     1067      InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     1068    }
     1069    // print InertiaTensor for debugging
     1070    *out << "The inertia tensor is:" << endl;
     1071    for(int i=0;i<NDIM;i++) {
     1072      for(int j=0;j<NDIM;j++)
     1073        *out << InertiaTensor[i*NDIM+j] << " ";
     1074      *out << endl;
     1075    }
     1076    *out << endl;
     1077  }
     1078
     1079  // free everything
     1080  delete(CenterOfGravity);
     1081  gsl_vector_free(eval);
     1082  gsl_matrix_free(evec);
    10831083};
    10841084
     
    10941094bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
    10951095{
    1096         element *runner = elemente->start;
    1097         atom *walker = NULL;
    1098         int AtomNo;
    1099         ifstream input(file);
    1100         string token;
    1101         stringstream item;
    1102         double a, IonMass;
    1103         ForceMatrix Force;
    1104         Vector tmpvector;
    1105 
    1106         CountElements();        // make sure ElementsInMolecule is up to date
    1107 
    1108         // check file
    1109         if (input == NULL) {
    1110                 return false;
    1111         } else {
    1112                 // parse file into ForceMatrix
    1113                 if (!Force.ParseMatrix(file, 0,0,0)) {
    1114                         cerr << "Could not parse Force Matrix file " << file << "." << endl;
    1115                         return false;
    1116                 }
    1117                 if (Force.RowCounter[0] != AtomCount) {
    1118                         cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
    1119                         return false;
    1120                 }
    1121                 // correct Forces
    1122 //              for(int d=0;d<NDIM;d++)
    1123 //                      tmpvector.x[d] = 0.;
    1124 //              for(int i=0;i<AtomCount;i++)
    1125 //                      for(int d=0;d<NDIM;d++) {
    1126 //                              tmpvector.x[d] += Force.Matrix[0][i][d+5];
    1127 //                      }
    1128 //              for(int i=0;i<AtomCount;i++)
    1129 //                      for(int d=0;d<NDIM;d++) {
    1130 //                              Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
    1131 //                      }
    1132                 // and perform Verlet integration for each atom with position, velocity and force vector
    1133                 runner = elemente->start;
    1134                 while (runner->next != elemente->end) { // go through every element
    1135                         runner = runner->next;
    1136                         IonMass = runner->mass;
    1137                         a = delta_t*0.5/IonMass;                                // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1138                         if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1139                                 AtomNo = 0;
    1140                                 walker = start;
    1141                                 while (walker->next != end) { // go through every atom of this element
    1142                                         walker = walker->next;
    1143                                         if (walker->type == runner) { // if this atom fits to element
    1144                                                 // check size of vectors
    1145                                                 if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1146                                                         //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1147                                                         Trajectories[walker].R.resize(MDSteps+10);
    1148                                                         Trajectories[walker].U.resize(MDSteps+10);
    1149                                                         Trajectories[walker].F.resize(MDSteps+10);
    1150                                                 }
    1151                                                 // 1. calculate x(t+\delta t)
    1152                                                 for (int d=0; d<NDIM; d++) {
    1153                                                         Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
    1154                                                         Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1155                                                         Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
    1156                                                         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
    1157                                                 }
    1158                                                 // 2. Calculate v(t+\delta t)
    1159                                                 for (int d=0; d<NDIM; d++) {
    1160                                                         Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1161                                                         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;
    1162                                                 }
    1163 //                                              cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1164 //                                              for (int d=0;d<NDIM;d++)
    1165 //                                                      cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";                                 // next step
    1166 //                                              cout << ")\t(";
    1167 //                                              for (int d=0;d<NDIM;d++)
    1168 //                                                      cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";                                 // next step
    1169 //                                              cout << ")" << endl;
    1170                                                 // next atom
    1171                                                 AtomNo++;
    1172                                         }
    1173                                 }
    1174                         }
    1175                 }
    1176         }
    1177 //      // correct velocities (rather momenta) so that center of mass remains motionless
    1178 //      tmpvector.zero()
    1179 //      IonMass = 0.;
    1180 //      walker = start;
    1181 //      while (walker->next != end) { // go through every atom
    1182 //              walker = walker->next;
    1183 //              IonMass += walker->type->mass;  // sum up total mass
    1184 //              for(int d=0;d<NDIM;d++) {
    1185 //                      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1186 //              }
    1187 //      }
    1188 //      walker = start;
    1189 //      while (walker->next != end) { // go through every atom of this element
    1190 //              walker = walker->next;
    1191 //              for(int d=0;d<NDIM;d++) {
    1192 //                      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
    1193 //              }
    1194 //      }
    1195         MDSteps++;
    1196 
    1197 
    1198         // exit
    1199         return true;
     1096  element *runner = elemente->start;
     1097  atom *walker = NULL;
     1098  int AtomNo;
     1099  ifstream input(file);
     1100  string token;
     1101  stringstream item;
     1102  double a, IonMass;
     1103  ForceMatrix Force;
     1104  Vector tmpvector;
     1105
     1106  CountElements();  // make sure ElementsInMolecule is up to date
     1107
     1108  // check file
     1109  if (input == NULL) {
     1110    return false;
     1111  } else {
     1112    // parse file into ForceMatrix
     1113    if (!Force.ParseMatrix(file, 0,0,0)) {
     1114      cerr << "Could not parse Force Matrix file " << file << "." << endl;
     1115      return false;
     1116    }
     1117    if (Force.RowCounter[0] != AtomCount) {
     1118      cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
     1119      return false;
     1120    }
     1121    // correct Forces
     1122//    for(int d=0;d<NDIM;d++)
     1123//      tmpvector.x[d] = 0.;
     1124//    for(int i=0;i<AtomCount;i++)
     1125//      for(int d=0;d<NDIM;d++) {
     1126//        tmpvector.x[d] += Force.Matrix[0][i][d+5];
     1127//      }
     1128//    for(int i=0;i<AtomCount;i++)
     1129//      for(int d=0;d<NDIM;d++) {
     1130//        Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
     1131//      }
     1132    // and perform Verlet integration for each atom with position, velocity and force vector
     1133    runner = elemente->start;
     1134    while (runner->next != elemente->end) { // go through every element
     1135      runner = runner->next;
     1136      IonMass = runner->mass;
     1137      a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1138      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1139        AtomNo = 0;
     1140        walker = start;
     1141        while (walker->next != end) { // go through every atom of this element
     1142          walker = walker->next;
     1143          if (walker->type == runner) { // if this atom fits to element
     1144            // check size of vectors
     1145            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1146              //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1147              Trajectories[walker].R.resize(MDSteps+10);
     1148              Trajectories[walker].U.resize(MDSteps+10);
     1149              Trajectories[walker].F.resize(MDSteps+10);
     1150            }
     1151            // 1. calculate x(t+\delta t)
     1152            for (int d=0; d<NDIM; d++) {
     1153              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
     1154              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1155              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1156              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
     1157            }
     1158            // 2. Calculate v(t+\delta t)
     1159            for (int d=0; d<NDIM; d++) {
     1160              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1161              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;
     1162            }
     1163//            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1164//            for (int d=0;d<NDIM;d++)
     1165//              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1166//            cout << ")\t(";
     1167//            for (int d=0;d<NDIM;d++)
     1168//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1169//            cout << ")" << endl;
     1170            // next atom
     1171            AtomNo++;
     1172          }
     1173        }
     1174      }
     1175    }
     1176  }
     1177//  // correct velocities (rather momenta) so that center of mass remains motionless
     1178//  tmpvector.zero()
     1179//  IonMass = 0.;
     1180//  walker = start;
     1181//  while (walker->next != end) { // go through every atom
     1182//    walker = walker->next;
     1183//    IonMass += walker->type->mass;  // sum up total mass
     1184//    for(int d=0;d<NDIM;d++) {
     1185//      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1186//    }
     1187//  }
     1188//  walker = start;
     1189//  while (walker->next != end) { // go through every atom of this element
     1190//    walker = walker->next;
     1191//    for(int d=0;d<NDIM;d++) {
     1192//      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
     1193//    }
     1194//  }
     1195  MDSteps++;
     1196
     1197
     1198  // exit
     1199  return true;
    12001200};
    12011201
     
    12051205void molecule::Align(Vector *n)
    12061206{
    1207         atom *ptr = start;
    1208         double alpha, tmp;
    1209         Vector z_axis;
    1210         z_axis.x[0] = 0.;
    1211         z_axis.x[1] = 0.;
    1212         z_axis.x[2] = 1.;
    1213 
    1214         // rotate on z-x plane
    1215         cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
    1216         alpha = atan(-n->x[0]/n->x[2]);
    1217         cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
    1218         while (ptr->next != end) {
    1219                 ptr = ptr->next;
    1220                 tmp = ptr->x.x[0];
    1221                 ptr->x.x[0] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1222                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1223                 for (int j=0;j<MDSteps;j++) {
    1224                         tmp = Trajectories[ptr].R.at(j).x[0];
    1225                         Trajectories[ptr].R.at(j).x[0] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1226                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1227                 }
    1228         }
    1229         // rotate n vector
    1230         tmp = n->x[0];
    1231         n->x[0] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1232         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1233         cout << Verbose(1) << "alignment vector after first rotation: ";
    1234         n->Output((ofstream *)&cout);
    1235         cout << endl;
    1236 
    1237         // rotate on z-y plane
    1238         ptr = start;
    1239         alpha = atan(-n->x[1]/n->x[2]);
    1240         cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
    1241         while (ptr->next != end) {
    1242                 ptr = ptr->next;
    1243                 tmp = ptr->x.x[1];
    1244                 ptr->x.x[1] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1245                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1246                 for (int j=0;j<MDSteps;j++) {
    1247                         tmp = Trajectories[ptr].R.at(j).x[1];
    1248                         Trajectories[ptr].R.at(j).x[1] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1249                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1250                 }
    1251         }
    1252         // rotate n vector (for consistency check)
    1253         tmp = n->x[1];
    1254         n->x[1] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1255         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1256 
    1257         cout << Verbose(1) << "alignment vector after second rotation: ";
    1258         n->Output((ofstream *)&cout);
    1259         cout << Verbose(1) << endl;
    1260         cout << Verbose(0) << "End of Aligning all atoms." << endl;
     1207  atom *ptr = start;
     1208  double alpha, tmp;
     1209  Vector z_axis;
     1210  z_axis.x[0] = 0.;
     1211  z_axis.x[1] = 0.;
     1212  z_axis.x[2] = 1.;
     1213
     1214  // rotate on z-x plane
     1215  cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
     1216  alpha = atan(-n->x[0]/n->x[2]);
     1217  cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
     1218  while (ptr->next != end) {
     1219    ptr = ptr->next;
     1220    tmp = ptr->x.x[0];
     1221    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1222    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1223    for (int j=0;j<MDSteps;j++) {
     1224      tmp = Trajectories[ptr].R.at(j).x[0];
     1225      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1226      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1227    }
     1228  }
     1229  // rotate n vector
     1230  tmp = n->x[0];
     1231  n->x[0] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1232  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1233  cout << Verbose(1) << "alignment vector after first rotation: ";
     1234  n->Output((ofstream *)&cout);
     1235  cout << endl;
     1236
     1237  // rotate on z-y plane
     1238  ptr = start;
     1239  alpha = atan(-n->x[1]/n->x[2]);
     1240  cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
     1241  while (ptr->next != end) {
     1242    ptr = ptr->next;
     1243    tmp = ptr->x.x[1];
     1244    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1245    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1246    for (int j=0;j<MDSteps;j++) {
     1247      tmp = Trajectories[ptr].R.at(j).x[1];
     1248      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1249      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1250    }
     1251  }
     1252  // rotate n vector (for consistency check)
     1253  tmp = n->x[1];
     1254  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1255  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1256
     1257  cout << Verbose(1) << "alignment vector after second rotation: ";
     1258  n->Output((ofstream *)&cout);
     1259  cout << Verbose(1) << endl;
     1260  cout << Verbose(0) << "End of Aligning all atoms." << endl;
    12611261};
    12621262
     
    12671267bool molecule::RemoveAtom(atom *pointer)
    12681268{
    1269         if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    1270                 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element
    1271         else
    1272                 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    1273         if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    1274                 ElementCount--;
    1275         Trajectories.erase(pointer);
    1276         return remove(pointer, start, end);
     1269  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1270    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
     1271  else
     1272    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1273  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     1274    ElementCount--;
     1275  Trajectories.erase(pointer);
     1276  return remove(pointer, start, end);
    12771277};
    12781278
     
    13011301bool molecule::CleanupMolecule()
    13021302{
    1303         return (cleanup(start,end) && cleanup(first,last));
     1303  return (cleanup(start,end) && cleanup(first,last));
    13041304};
    13051305
     
    13081308 * \return pointer to atom or NULL
    13091309 */
    1310 atom * molecule::FindAtom(int Nr)       const{
    1311         atom * walker = find(&Nr, start,end);
    1312         if (walker != NULL) {
    1313                 //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
    1314                 return walker;
    1315         } else {
    1316                 cout << Verbose(0) << "Atom not found in list." << endl;
    1317                 return NULL;
    1318         }
     1310atom * molecule::FindAtom(int Nr)  const{
     1311  atom * walker = find(&Nr, start,end);
     1312  if (walker != NULL) {
     1313    //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
     1314    return walker;
     1315  } else {
     1316    cout << Verbose(0) << "Atom not found in list." << endl;
     1317    return NULL;
     1318  }
    13191319};
    13201320
     
    13241324atom * molecule::AskAtom(string text)
    13251325{
    1326         int No;
    1327         atom *ion = NULL;
    1328         do {
    1329                 //cout << Verbose(0) << "============Atom list==========================" << endl;
    1330                 //mol->Output((ofstream *)&cout);
    1331                 //cout << Verbose(0) << "===============================================" << endl;
    1332                 cout << Verbose(0) << text;
    1333                 cin >> No;
    1334                 ion = this->FindAtom(No);
    1335         } while (ion == NULL);
    1336         return ion;
     1326  int No;
     1327  atom *ion = NULL;
     1328  do {
     1329    //cout << Verbose(0) << "============Atom list==========================" << endl;
     1330    //mol->Output((ofstream *)&cout);
     1331    //cout << Verbose(0) << "===============================================" << endl;
     1332    cout << Verbose(0) << text;
     1333    cin >> No;
     1334    ion = this->FindAtom(No);
     1335  } while (ion == NULL);
     1336  return ion;
    13371337};
    13381338
     
    13431343bool molecule::CheckBounds(const Vector *x) const
    13441344{
    1345         bool result = true;
    1346         int j =-1;
    1347         for (int i=0;i<NDIM;i++) {
    1348                 j += i+1;
    1349                 result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
    1350         }
    1351         //return result;
    1352         return true; /// probably not gonna use the check no more
     1345  bool result = true;
     1346  int j =-1;
     1347  for (int i=0;i<NDIM;i++) {
     1348    j += i+1;
     1349    result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
     1350  }
     1351  //return result;
     1352  return true; /// probably not gonna use the check no more
    13531353};
    13541354
     
    13601360double LeastSquareDistance (const gsl_vector * x, void * params)
    13611361{
    1362         double res = 0, t;
    1363         Vector a,b,c,d;
    1364         struct lsq_params *par = (struct lsq_params *)params;
    1365         atom *ptr = par->mol->start;
    1366 
    1367         // initialize vectors
    1368         a.x[0] = gsl_vector_get(x,0);
    1369         a.x[1] = gsl_vector_get(x,1);
    1370         a.x[2] = gsl_vector_get(x,2);
    1371         b.x[0] = gsl_vector_get(x,3);
    1372         b.x[1] = gsl_vector_get(x,4);
    1373         b.x[2] = gsl_vector_get(x,5);
    1374         // go through all atoms
    1375         while (ptr != par->mol->end) {
    1376                 ptr = ptr->next;
    1377                 if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
    1378                         c.CopyVector(&ptr->x);  // copy vector to temporary one
    1379                         c.SubtractVector(&a);    // subtract offset vector
    1380                         t = c.ScalarProduct(&b);                                        // get direction parameter
    1381                         d.CopyVector(&b);                        // and create vector
    1382                         d.Scale(&t);
    1383                         c.SubtractVector(&d);    // ... yielding distance vector
    1384                         res += d.ScalarProduct((const Vector *)&d);                             // add squared distance
    1385                 }
    1386         }
    1387         return res;
     1362  double res = 0, t;
     1363  Vector a,b,c,d;
     1364  struct lsq_params *par = (struct lsq_params *)params;
     1365  atom *ptr = par->mol->start;
     1366
     1367  // initialize vectors
     1368  a.x[0] = gsl_vector_get(x,0);
     1369  a.x[1] = gsl_vector_get(x,1);
     1370  a.x[2] = gsl_vector_get(x,2);
     1371  b.x[0] = gsl_vector_get(x,3);
     1372  b.x[1] = gsl_vector_get(x,4);
     1373  b.x[2] = gsl_vector_get(x,5);
     1374  // go through all atoms
     1375  while (ptr != par->mol->end) {
     1376    ptr = ptr->next;
     1377    if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
     1378      c.CopyVector(&ptr->x);  // copy vector to temporary one
     1379      c.SubtractVector(&a);  // subtract offset vector
     1380      t = c.ScalarProduct(&b);          // get direction parameter
     1381      d.CopyVector(&b);      // and create vector
     1382      d.Scale(&t);
     1383      c.SubtractVector(&d);  // ... yielding distance vector
     1384      res += d.ScalarProduct((const Vector *)&d);        // add squared distance
     1385    }
     1386  }
     1387  return res;
    13881388};
    13891389
     
    13931393void molecule::GetAlignvector(struct lsq_params * par) const
    13941394{
    1395                 int np = 6;
    1396 
    1397         const gsl_multimin_fminimizer_type *T =
    1398                 gsl_multimin_fminimizer_nmsimplex;
    1399         gsl_multimin_fminimizer *s = NULL;
    1400         gsl_vector *ss;
    1401         gsl_multimin_function minex_func;
    1402 
    1403         size_t iter = 0, i;
    1404         int status;
    1405         double size;
    1406 
    1407         /* Initial vertex size vector */
    1408         ss = gsl_vector_alloc (np);
    1409 
    1410         /* Set all step sizes to 1 */
    1411         gsl_vector_set_all (ss, 1.0);
    1412 
    1413         /* Starting point */
    1414         par->x = gsl_vector_alloc (np);
    1415         par->mol = this;
    1416 
    1417          gsl_vector_set (par->x, 0, 0.0);       // offset
    1418         gsl_vector_set (par->x, 1, 0.0);
    1419         gsl_vector_set (par->x, 2, 0.0);
    1420          gsl_vector_set (par->x, 3, 0.0);       // direction
    1421         gsl_vector_set (par->x, 4, 0.0);
    1422         gsl_vector_set (par->x, 5, 1.0);
    1423 
    1424         /* Initialize method and iterate */
    1425         minex_func.f = &LeastSquareDistance;
    1426         minex_func.n = np;
    1427         minex_func.params = (void *)par;
    1428 
    1429         s = gsl_multimin_fminimizer_alloc (T, np);
    1430         gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1431 
    1432         do
    1433                 {
    1434                         iter++;
    1435                         status = gsl_multimin_fminimizer_iterate(s);
    1436 
    1437                         if (status)
    1438                                 break;
    1439 
    1440                         size = gsl_multimin_fminimizer_size (s);
    1441                         status = gsl_multimin_test_size (size, 1e-2);
    1442 
    1443                         if (status == GSL_SUCCESS)
    1444                                 {
    1445                                         printf ("converged to minimum at\n");
    1446                                 }
    1447 
    1448                         printf ("%5d ", (int)iter);
    1449                         for (i = 0; i < (size_t)np; i++)
    1450                                 {
    1451                                         printf ("%10.3e ", gsl_vector_get (s->x, i));
    1452                                 }
    1453                         printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    1454                 }
    1455         while (status == GSL_CONTINUE && iter < 100);
    1456 
    1457         for (i=0;i<(size_t)np;i++)
    1458                 gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
    1459         //gsl_vector_free(par->x);
    1460         gsl_vector_free(ss);
    1461         gsl_multimin_fminimizer_free (s);
     1395    int np = 6;
     1396
     1397  const gsl_multimin_fminimizer_type *T =
     1398    gsl_multimin_fminimizer_nmsimplex;
     1399  gsl_multimin_fminimizer *s = NULL;
     1400  gsl_vector *ss;
     1401  gsl_multimin_function minex_func;
     1402
     1403  size_t iter = 0, i;
     1404  int status;
     1405  double size;
     1406
     1407  /* Initial vertex size vector */
     1408  ss = gsl_vector_alloc (np);
     1409
     1410  /* Set all step sizes to 1 */
     1411  gsl_vector_set_all (ss, 1.0);
     1412
     1413  /* Starting point */
     1414  par->x = gsl_vector_alloc (np);
     1415  par->mol = this;
     1416
     1417   gsl_vector_set (par->x, 0, 0.0);  // offset
     1418  gsl_vector_set (par->x, 1, 0.0);
     1419  gsl_vector_set (par->x, 2, 0.0);
     1420   gsl_vector_set (par->x, 3, 0.0);  // direction
     1421  gsl_vector_set (par->x, 4, 0.0);
     1422  gsl_vector_set (par->x, 5, 1.0);
     1423
     1424  /* Initialize method and iterate */
     1425  minex_func.f = &LeastSquareDistance;
     1426  minex_func.n = np;
     1427  minex_func.params = (void *)par;
     1428
     1429  s = gsl_multimin_fminimizer_alloc (T, np);
     1430  gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
     1431
     1432  do
     1433    {
     1434      iter++;
     1435      status = gsl_multimin_fminimizer_iterate(s);
     1436
     1437      if (status)
     1438        break;
     1439
     1440      size = gsl_multimin_fminimizer_size (s);
     1441      status = gsl_multimin_test_size (size, 1e-2);
     1442
     1443      if (status == GSL_SUCCESS)
     1444        {
     1445          printf ("converged to minimum at\n");
     1446        }
     1447
     1448      printf ("%5d ", (int)iter);
     1449      for (i = 0; i < (size_t)np; i++)
     1450        {
     1451          printf ("%10.3e ", gsl_vector_get (s->x, i));
     1452        }
     1453      printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     1454    }
     1455  while (status == GSL_CONTINUE && iter < 100);
     1456
     1457  for (i=0;i<(size_t)np;i++)
     1458    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     1459  //gsl_vector_free(par->x);
     1460  gsl_vector_free(ss);
     1461  gsl_multimin_fminimizer_free (s);
    14621462};
    14631463
     
    14671467bool molecule::Output(ofstream *out)
    14681468{
    1469         atom *walker = NULL;
    1470         int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
    1471         CountElements();
    1472 
    1473         for (int i=0;i<MAX_ELEMENTS;++i) {
    1474           AtomNo[i] = 0;
    1475           ElementNo[i] = 0;
    1476         }
    1477         if (out == NULL) {
    1478                 return false;
    1479         } else {
    1480                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1469  atom *walker = NULL;
     1470  int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
     1471  CountElements();
     1472
     1473  for (int i=0;i<MAX_ELEMENTS;++i) {
     1474    AtomNo[i] = 0;
     1475    ElementNo[i] = 0;
     1476  }
     1477  if (out == NULL) {
     1478    return false;
     1479  } else {
     1480    *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
    14811481    walker = start;
    14821482    while (walker->next != end) { // go through every atom of this element
     
    14951495      walker->Output(ElementNo[walker->type->Z], AtomNo[walker->type->Z], out); // removed due to trajectories
    14961496    }
    1497                 return true;
    1498         }
     1497    return true;
     1498  }
    14991499};
    15001500
     
    15041504bool molecule::OutputTrajectories(ofstream *out)
    15051505{
    1506         atom *walker = NULL;
     1506  atom *walker = NULL;
    15071507  int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
    1508         CountElements();
    1509 
    1510         if (out == NULL) {
    1511                 return false;
    1512         } else {
    1513                 for (int step = 0; step < MDSteps; step++) {
    1514                         if (step == 0) {
    1515                                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1516                         } else {
    1517                                 *out << "# ====== MD step " << step << " =========" << endl;
    1518                         }
    1519                   for (int i=0;i<MAX_ELEMENTS;++i) {
    1520                     AtomNo[i] = 0;
    1521                     ElementNo[i] = 0;
    1522                   }
     1508  CountElements();
     1509
     1510  if (out == NULL) {
     1511    return false;
     1512  } else {
     1513    for (int step = 0; step < MDSteps; step++) {
     1514      if (step == 0) {
     1515        *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1516      } else {
     1517        *out << "# ====== MD step " << step << " =========" << endl;
     1518      }
     1519      for (int i=0;i<MAX_ELEMENTS;++i) {
     1520        AtomNo[i] = 0;
     1521        ElementNo[i] = 0;
     1522      }
    15231523    walker = start;
    15241524    while (walker->next != end) { // go through every atom of this element
     
    15351535        walker = walker->next;
    15361536        AtomNo[walker->type->Z]++;
    1537         *out << "Ion_Type" << ElementNo[walker->type->Z] << "_" << AtomNo[walker->type->Z] << "\t"      << fixed << setprecision(9) << showpoint;
     1537        *out << "Ion_Type" << ElementNo[walker->type->Z] << "_" << AtomNo[walker->type->Z] << "\t"  << fixed << setprecision(9) << showpoint;
    15381538        *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
    15391539        *out << "\t" << walker->FixedIon;
     
    15441544        *out << "\t# Number in molecule " << walker->nr << endl;
    15451545      }
    1546                 }
    1547                 return true;
    1548         }
     1546    }
     1547    return true;
     1548  }
    15491549};
    15501550
     
    15541554void molecule::OutputListOfBonds(ofstream *out) const
    15551555{
    1556         *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    1557         atom *Walker = start;
    1558         while (Walker->next != end) {
    1559                 Walker = Walker->next;
     1556  *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
     1557  atom *Walker = start;
     1558  while (Walker->next != end) {
     1559    Walker = Walker->next;
    15601560#ifdef ADDHYDROGEN
    1561                 if (Walker->type->Z != 1) {      // regard only non-hydrogen
     1561    if (Walker->type->Z != 1) {  // regard only non-hydrogen
    15621562#endif
    1563                         *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
    1564                         for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    1565                                 *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
    1566                         }
     1563      *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
     1564      for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     1565        *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
     1566      }
    15671567#ifdef ADDHYDROGEN
    1568                 }
     1568    }
    15691569#endif
    1570         }
    1571         *out << endl;
     1570  }
     1571  *out << endl;
    15721572};
    15731573
     
    15751575 * \param *out stream pointer
    15761576 */
    1577 bool molecule::Checkout(ofstream *out)  const
    1578 {
    1579         return elemente->Checkout(out, ElementsInMolecule);
     1577bool molecule::Checkout(ofstream *out)  const
     1578{
     1579  return elemente->Checkout(out, ElementsInMolecule);
    15801580};
    15811581
     
    15851585bool molecule::OutputTrajectoriesXYZ(ofstream *out)
    15861586{
    1587         atom *walker = NULL;
    1588         int No = 0;
    1589         time_t now;
    1590 
    1591         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1592         walker = start;
    1593         while (walker->next != end) { // go through every atom and count
    1594                 walker = walker->next;
    1595                 No++;
    1596         }
    1597         if (out != NULL) {
    1598                 for (int step=0;step<MDSteps;step++) {
    1599                         *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
    1600                         walker = start;
    1601                         while (walker->next != end) { // go through every atom of this element
    1602                                 walker = walker->next;
    1603                                 *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;
    1604                         }
    1605                 }
    1606                 return true;
    1607         } else
    1608                 return false;
     1587  atom *walker = NULL;
     1588  int No = 0;
     1589  time_t now;
     1590
     1591  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1592  walker = start;
     1593  while (walker->next != end) { // go through every atom and count
     1594    walker = walker->next;
     1595    No++;
     1596  }
     1597  if (out != NULL) {
     1598    for (int step=0;step<MDSteps;step++) {
     1599      *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     1600      walker = start;
     1601      while (walker->next != end) { // go through every atom of this element
     1602        walker = walker->next;
     1603        *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;
     1604      }
     1605    }
     1606    return true;
     1607  } else
     1608    return false;
    16091609};
    16101610
     
    16141614bool molecule::OutputXYZ(ofstream *out) const
    16151615{
    1616         atom *walker = NULL;
    1617         int AtomNo = 0;
    1618         time_t now;
    1619 
    1620         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1621         walker = start;
    1622         while (walker->next != end) { // go through every atom and count
    1623                 walker = walker->next;
    1624                 AtomNo++;
    1625         }
    1626         if (out != NULL) {
    1627                 *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
     1616  atom *walker = NULL;
     1617  int AtomNo = 0;
     1618  time_t now;
     1619
     1620  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1621  walker = start;
     1622  while (walker->next != end) { // go through every atom and count
     1623    walker = walker->next;
     1624    AtomNo++;
     1625  }
     1626  if (out != NULL) {
     1627    *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    16281628    walker = start;
    16291629    while (walker->next != end) { // go through every atom of this element
     
    16311631      walker->OutputXYZLine(out);
    16321632    }
    1633                 return true;
    1634         } else
    1635                 return false;
     1633    return true;
     1634  } else
     1635    return false;
    16361636};
    16371637
     
    16411641void molecule::CountAtoms(ofstream *out)
    16421642{
    1643         int i = 0;
    1644         atom *Walker = start;
    1645         while (Walker->next != end) {
    1646                 Walker = Walker->next;
    1647                 i++;
    1648         }
    1649         if ((AtomCount == 0) || (i != AtomCount)) {
    1650                 *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
    1651                 AtomCount = i;
    1652 
    1653                 // count NonHydrogen atoms and give each atom a unique name
    1654                 if (AtomCount != 0) {
    1655                         i=0;
    1656                         NoNonHydrogen = 0;
    1657                         Walker = start;
    1658                         while (Walker->next != end) {
    1659                                 Walker = Walker->next;
    1660                                 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron)
    1661                                 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1662                                         NoNonHydrogen++;
    1663                                 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    1664                                 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
    1665                                 sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
    1666                                 *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
    1667                                 i++;
    1668                         }
    1669                 } else
    1670                         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    1671         }
     1643  int i = 0;
     1644  atom *Walker = start;
     1645  while (Walker->next != end) {
     1646    Walker = Walker->next;
     1647    i++;
     1648  }
     1649  if ((AtomCount == 0) || (i != AtomCount)) {
     1650    *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
     1651    AtomCount = i;
     1652
     1653    // count NonHydrogen atoms and give each atom a unique name
     1654    if (AtomCount != 0) {
     1655      i=0;
     1656      NoNonHydrogen = 0;
     1657      Walker = start;
     1658      while (Walker->next != end) {
     1659        Walker = Walker->next;
     1660        Walker->nr = i;  // update number in molecule (for easier referencing in FragmentMolecule lateron)
     1661        if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
     1662          NoNonHydrogen++;
     1663        Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
     1664        Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     1665        sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
     1666        *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
     1667        i++;
     1668      }
     1669    } else
     1670      *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     1671  }
    16721672};
    16731673
     
    16761676void molecule::CountElements()
    16771677{
    1678         int i = 0;
    1679         for(i=MAX_ELEMENTS;i--;)
    1680                 ElementsInMolecule[i] = 0;
    1681         ElementCount = 0;
    1682 
    1683         atom *walker = start;
    1684         while (walker->next != end) {
    1685                 walker = walker->next;
    1686                 ElementsInMolecule[walker->type->Z]++;
    1687                 i++;
    1688         }
    1689         for(i=MAX_ELEMENTS;i--;)
    1690                 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
     1678  int i = 0;
     1679  for(i=MAX_ELEMENTS;i--;)
     1680    ElementsInMolecule[i] = 0;
     1681  ElementCount = 0;
     1682
     1683  atom *walker = start;
     1684  while (walker->next != end) {
     1685    walker = walker->next;
     1686    ElementsInMolecule[walker->type->Z]++;
     1687    i++;
     1688  }
     1689  for(i=MAX_ELEMENTS;i--;)
     1690    ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
    16911691};
    16921692
     
    16981698int molecule::CountCyclicBonds(ofstream *out)
    16991699{
    1700         int No = 0;
    1701         int *MinimumRingSize = NULL;
    1702         MoleculeLeafClass *Subgraphs = NULL;
    1703         class StackClass<bond *> *BackEdgeStack = NULL;
    1704         bond *Binder = first;
    1705         if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
    1706                 *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
    1707                 Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    1708                 while (Subgraphs->next != NULL) {
    1709                         Subgraphs = Subgraphs->next;
    1710                         delete(Subgraphs->previous);
    1711                 }
    1712                 delete(Subgraphs);
    1713                 delete[](MinimumRingSize);
    1714         }
    1715         while(Binder->next != last) {
    1716                 Binder = Binder->next;
    1717                 if (Binder->Cyclic)
    1718                         No++;
    1719         }
    1720         delete(BackEdgeStack);
    1721         return No;
     1700  int No = 0;
     1701  int *MinimumRingSize = NULL;
     1702  MoleculeLeafClass *Subgraphs = NULL;
     1703  class StackClass<bond *> *BackEdgeStack = NULL;
     1704  bond *Binder = first;
     1705  if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
     1706    *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
     1707    Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     1708    while (Subgraphs->next != NULL) {
     1709      Subgraphs = Subgraphs->next;
     1710      delete(Subgraphs->previous);
     1711    }
     1712    delete(Subgraphs);
     1713    delete[](MinimumRingSize);
     1714  }
     1715  while(Binder->next != last) {
     1716    Binder = Binder->next;
     1717    if (Binder->Cyclic)
     1718      No++;
     1719  }
     1720  delete(BackEdgeStack);
     1721  return No;
    17221722};
    17231723/** Returns Shading as a char string.
     
    17271727string molecule::GetColor(enum Shading color)
    17281728{
    1729         switch(color) {
    1730                 case white:
    1731                         return "white";
    1732                         break;
    1733                 case lightgray:
    1734                         return "lightgray";
    1735                         break;
    1736                 case darkgray:
    1737                         return "darkgray";
    1738                         break;
    1739                 case black:
    1740                         return "black";
    1741                         break;
    1742                 default:
    1743                         return "uncolored";
    1744                         break;
    1745         };
     1729  switch(color) {
     1730    case white:
     1731      return "white";
     1732      break;
     1733    case lightgray:
     1734      return "lightgray";
     1735      break;
     1736    case darkgray:
     1737      return "darkgray";
     1738      break;
     1739    case black:
     1740      return "black";
     1741      break;
     1742    default:
     1743      return "uncolored";
     1744      break;
     1745  };
    17461746};
    17471747
     
    17521752void molecule::CalculateOrbitals(class config &configuration)
    17531753{
    1754         configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
    1755         for(int i=MAX_ELEMENTS;i--;) {
    1756                 if (ElementsInMolecule[i] != 0) {
    1757                         //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
    1758                         configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
    1759                 }
    1760         }
    1761         configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
    1762         configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
    1763         configuration.MaxPsiDouble /= 2;
    1764         configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
    1765         if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
    1766                 configuration.ProcPEGamma /= 2;
    1767                 configuration.ProcPEPsi *= 2;
    1768         } else {
    1769                 configuration.ProcPEGamma *= configuration.ProcPEPsi;
    1770                 configuration.ProcPEPsi = 1;
    1771         }
    1772         configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
     1754  configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
     1755  for(int i=MAX_ELEMENTS;i--;) {
     1756    if (ElementsInMolecule[i] != 0) {
     1757      //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
     1758      configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
     1759    }
     1760  }
     1761  configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
     1762  configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
     1763  configuration.MaxPsiDouble /= 2;
     1764  configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
     1765  if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
     1766    configuration.ProcPEGamma /= 2;
     1767    configuration.ProcPEPsi *= 2;
     1768  } else {
     1769    configuration.ProcPEGamma *= configuration.ProcPEPsi;
     1770    configuration.ProcPEPsi = 1;
     1771  }
     1772  configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
    17731773};
    17741774
     
    17791779{
    17801780
    1781         // 1 We will parse bonds out of the dbond file created by tremolo.
    1782                         int atom1, atom2, temp;
    1783                         atom *Walker, *OtherWalker;
    1784 
    1785                                         if (!input)
    1786                                         {
    1787                                                 cout << Verbose(1) << "Opening silica failed \n";
    1788                                         };
    1789 
    1790                         *input >> ws >> atom1;
    1791                         *input >> ws >> atom2;
    1792                                         cout << Verbose(1) << "Scanning file\n";
    1793                                         while (!input->eof()) // Check whether we read everything already
    1794                                         {
    1795                                 *input >> ws >> atom1;
    1796                                 *input >> ws >> atom2;
    1797                                                 if(atom2<atom1) //Sort indices of atoms in order
    1798                                                 {
    1799                                                         temp=atom1;
    1800                                                         atom1=atom2;
    1801                                                         atom2=temp;
    1802                                                 };
    1803 
    1804                                                 Walker=start;
    1805                                                 while(Walker-> nr != atom1) // Find atom corresponding to first index
    1806                                                 {
    1807                                                         Walker = Walker->next;
    1808                                                 };
    1809                                                 OtherWalker = Walker->next;
    1810                                                 while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    1811                                                 {
    1812                                                         OtherWalker= OtherWalker->next;
    1813                                                 };
    1814                                                 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1815 
    1816                                         }
    1817 
    1818                                         CreateListOfBondsPerAtom(out);
     1781  // 1 We will parse bonds out of the dbond file created by tremolo.
     1782      int atom1, atom2, temp;
     1783      atom *Walker, *OtherWalker;
     1784
     1785          if (!input)
     1786          {
     1787            cout << Verbose(1) << "Opening silica failed \n";
     1788          };
     1789
     1790      *input >> ws >> atom1;
     1791      *input >> ws >> atom2;
     1792          cout << Verbose(1) << "Scanning file\n";
     1793          while (!input->eof()) // Check whether we read everything already
     1794          {
     1795        *input >> ws >> atom1;
     1796        *input >> ws >> atom2;
     1797            if(atom2<atom1) //Sort indices of atoms in order
     1798            {
     1799              temp=atom1;
     1800              atom1=atom2;
     1801              atom2=temp;
     1802            };
     1803
     1804            Walker=start;
     1805            while(Walker-> nr != atom1) // Find atom corresponding to first index
     1806            {
     1807              Walker = Walker->next;
     1808            };
     1809            OtherWalker = Walker->next;
     1810            while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     1811            {
     1812              OtherWalker= OtherWalker->next;
     1813            };
     1814            AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     1815
     1816          }
     1817
     1818          CreateListOfBondsPerAtom(out);
    18191819
    18201820};
     
    18271827 * To make it O(N log N) the function uses the linked-cell technique as follows:
    18281828 * The procedure is step-wise:
    1829  *      -# Remove every bond in list
    1830  *      -# Count the atoms in the molecule with CountAtoms()
    1831  *      -# partition cell into smaller linked cells of size \a bonddistance
    1832  *      -# put each atom into its corresponding cell
    1833  *      -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    1834  *      -# create the list of bonds via CreateListOfBondsPerAtom()
    1835  *      -# correct the bond degree iteratively (single->double->triple bond)
    1836  *      -# finally print the bond list to \a *out if desired
     1829 *  -# Remove every bond in list
     1830 *  -# Count the atoms in the molecule with CountAtoms()
     1831 *  -# partition cell into smaller linked cells of size \a bonddistance
     1832 *  -# put each atom into its corresponding cell
     1833 *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
     1834 *  -# create the list of bonds via CreateListOfBondsPerAtom()
     1835 *  -# correct the bond degree iteratively (single->double->triple bond)
     1836 *  -# finally print the bond list to \a *out if desired
    18371837 * \param *out out stream for printing the matrix, NULL if no output
    18381838 * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
     
    18421842{
    18431843
    1844         atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    1845         int No, NoBonds, CandidateBondNo;
    1846         int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
    1847         molecule **CellList;
    1848         double distance, MinDistance, MaxDistance;
    1849         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    1850         Vector x;
    1851         int FalseBondDegree = 0;
    1852 
    1853         BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    1854         *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
    1855         // remove every bond from the list
    1856         if ((first->next != last) && (last->previous != first)) {       // there are bonds present
    1857                 cleanup(first,last);
    1858         }
    1859 
    1860         // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    1861         CountAtoms(out);
    1862         *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
    1863 
    1864         if (AtomCount != 0) {
    1865                 // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
    1866                 j=-1;
    1867                 for (int i=0;i<NDIM;i++) {
    1868                         j += i+1;
    1869                         divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    1870                         //*out << Verbose(1) << "divisor[" << i << "]   = " << divisor[i] << "." << endl;
    1871                 }
    1872                 // 2a. allocate memory for the cell list
    1873                 NumberCells = divisor[0]*divisor[1]*divisor[2];
    1874                 *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
    1875                 CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
    1876                 for (int i=NumberCells;i--;)
    1877                         CellList[i] = NULL;
    1878 
    1879                 // 2b. put all atoms into its corresponding list
    1880                 Walker = start;
    1881                 while(Walker->next != end) {
    1882                         Walker = Walker->next;
    1883                         //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
    1884                         //Walker->x.Output(out);
    1885                         //*out << "." << endl;
    1886                         // compute the cell by the atom's coordinates
    1887                         j=-1;
    1888                         for (int i=0;i<NDIM;i++) {
    1889                                 j += i+1;
    1890                                 x.CopyVector(&(Walker->x));
    1891                                 x.KeepPeriodic(out, matrix);
    1892                                 n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
    1893                         }
    1894                         index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    1895                         //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    1896                         // add copy atom to this cell
    1897                         if (CellList[index] == NULL)    // allocate molecule if not done
    1898                                 CellList[index] = new molecule(elemente);
    1899                         OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    1900                         //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    1901                 }
    1902                 //for (int i=0;i<NumberCells;i++)
    1903                         //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1904 
    1905 
    1906                 // 3a. go through every cell
    1907                 for (N[0]=divisor[0];N[0]--;)
    1908                         for (N[1]=divisor[1];N[1]--;)
    1909                                 for (N[2]=divisor[2];N[2]--;) {
    1910                                         Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
    1911                                         if (CellList[Index] != NULL) { // if there atoms in this cell
    1912                                                 //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
    1913                                                 // 3b. for every atom therein
    1914                                                 Walker = CellList[Index]->start;
    1915                                                 while (Walker->next != CellList[Index]->end) {  // go through every atom
    1916                                                         Walker = Walker->next;
    1917                                                         //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1918                                                         // 3c. check for possible bond between each atom in this and every one in the 27 cells
    1919                                                         for (n[0]=-1;n[0]<=1;n[0]++)
    1920                                                                 for (n[1]=-1;n[1]<=1;n[1]++)
    1921                                                                         for (n[2]=-1;n[2]<=1;n[2]++) {
    1922                                                                                 // compute the index of this comparison cell and make it periodic
    1923                                                                                 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];
    1924                                                                                 //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
    1925                                                                                 if (CellList[index] != NULL) {  // if there are any atoms in this cell
    1926                                                                                         OtherWalker = CellList[index]->start;
    1927                                                                                         while(OtherWalker->next != CellList[index]->end) {      // go through every atom in this cell
    1928                                                                                                 OtherWalker = OtherWalker->next;
    1929                                                                                                 //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    1930                                                                                                 /// \todo periodic check is missing here!
    1931                                                                                                 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    1932                                                                                                 MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    1933                                                                                                 MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    1934                                                                                                 MaxDistance = MinDistance + BONDTHRESHOLD;
    1935                                                                                                 MinDistance -= BONDTHRESHOLD;
    1936                                                                                                 distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
    1937                                                                                                 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    1938                                                                                                         //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    1939                                                                                                         AddBond(Walker->father, OtherWalker->father, 1);        // also increases molecule::BondCount
    1940                                                                                                 } else {
    1941                                                                                                         //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
    1942                                                                                                 }
    1943                                                                                         }
    1944                                                                                 }
    1945                                                                         }
    1946                                                 }
    1947                                         }
    1948                                 }
    1949 
    1950 
    1951 
    1952                 // 4. free the cell again
    1953                 for (int i=NumberCells;i--;)
    1954                         if (CellList[i] != NULL) {
    1955                                 delete(CellList[i]);
    1956                         }
    1957                 Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1958 
    1959                 // create the adjacency list per atom
    1960                 CreateListOfBondsPerAtom(out);
    1961 
    1962                 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    1963                 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    1964                 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    1965                 // double bonds as was expected.
    1966                 if (BondCount != 0) {
    1967                         NoCyclicBonds = 0;
    1968                         *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    1969                         do {
    1970                                 No = 0; // No acts as breakup flag (if 1 we still continue)
    1971                                 Walker = start;
    1972                                 while (Walker->next != end) { // go through every atom
    1973                                         Walker = Walker->next;
    1974                                         // count valence of first partner
    1975                                         NoBonds = 0;
    1976                                         for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
    1977                                                 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    1978                                         *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1979                                         if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    1980                                                 Candidate = NULL;
    1981                                                 CandidateBondNo = -1;
    1982                                                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    1983                                                         OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    1984                                                         // count valence of second partner
    1985                                                         NoBonds = 0;
    1986                                                         for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    1987                                                                 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    1988                                                         *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1989                                                         if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    1990                                                                 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    1991                                                                         Candidate = OtherWalker;
    1992                                                                         CandidateBondNo = i;
    1993                                                                         *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    1994                                                                 }
    1995                                                         }
    1996                                                 }
    1997                                                 if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    1998                                                         ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    1999                                                         *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    2000                                                 } else
    2001                                                         *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    2002                                                         FalseBondDegree++;
    2003                                         }
    2004                                 }
    2005                         } while (No);
    2006                 *out << " done." << endl;
    2007                 } else
    2008                         *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    2009                 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    2010 
    2011                 // output bonds for debugging (if bond chain list was correctly installed)
    2012                 *out << Verbose(1) << endl << "From contents of bond chain list:";
    2013                 bond *Binder = first;
    2014                 while(Binder->next != last) {
    2015                         Binder = Binder->next;
    2016                         *out << *Binder << "\t" << endl;
    2017                 }
    2018                 *out << endl;
    2019         } else
    2020                 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    2021         *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    2022         Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
     1844  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
     1845  int No, NoBonds, CandidateBondNo;
     1846  int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
     1847  molecule **CellList;
     1848  double distance, MinDistance, MaxDistance;
     1849  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     1850  Vector x;
     1851  int FalseBondDegree = 0;
     1852
     1853  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
     1854  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     1855  // remove every bond from the list
     1856  if ((first->next != last) && (last->previous != first)) {  // there are bonds present
     1857    cleanup(first,last);
     1858  }
     1859
     1860  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
     1861  CountAtoms(out);
     1862  *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
     1863
     1864  if (AtomCount != 0) {
     1865    // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
     1866    j=-1;
     1867    for (int i=0;i<NDIM;i++) {
     1868      j += i+1;
     1869      divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
     1870      //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
     1871    }
     1872    // 2a. allocate memory for the cell list
     1873    NumberCells = divisor[0]*divisor[1]*divisor[2];
     1874    *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
     1875    CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
     1876    for (int i=NumberCells;i--;)
     1877      CellList[i] = NULL;
     1878
     1879    // 2b. put all atoms into its corresponding list
     1880    Walker = start;
     1881    while(Walker->next != end) {
     1882      Walker = Walker->next;
     1883      //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
     1884      //Walker->x.Output(out);
     1885      //*out << "." << endl;
     1886      // compute the cell by the atom's coordinates
     1887      j=-1;
     1888      for (int i=0;i<NDIM;i++) {
     1889        j += i+1;
     1890        x.CopyVector(&(Walker->x));
     1891        x.KeepPeriodic(out, matrix);
     1892        n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
     1893      }
     1894      index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
     1895      //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
     1896      // add copy atom to this cell
     1897      if (CellList[index] == NULL)  // allocate molecule if not done
     1898        CellList[index] = new molecule(elemente);
     1899      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
     1900      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     1901    }
     1902    //for (int i=0;i<NumberCells;i++)
     1903      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
     1904
     1905
     1906    // 3a. go through every cell
     1907    for (N[0]=divisor[0];N[0]--;)
     1908      for (N[1]=divisor[1];N[1]--;)
     1909        for (N[2]=divisor[2];N[2]--;) {
     1910          Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
     1911          if (CellList[Index] != NULL) { // if there atoms in this cell
     1912            //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
     1913            // 3b. for every atom therein
     1914            Walker = CellList[Index]->start;
     1915            while (Walker->next != CellList[Index]->end) {  // go through every atom
     1916              Walker = Walker->next;
     1917              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
     1918              // 3c. check for possible bond between each atom in this and every one in the 27 cells
     1919              for (n[0]=-1;n[0]<=1;n[0]++)
     1920                for (n[1]=-1;n[1]<=1;n[1]++)
     1921                  for (n[2]=-1;n[2]<=1;n[2]++) {
     1922                    // compute the index of this comparison cell and make it periodic
     1923                    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];
     1924                    //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
     1925                    if (CellList[index] != NULL) {  // if there are any atoms in this cell
     1926                      OtherWalker = CellList[index]->start;
     1927                      while(OtherWalker->next != CellList[index]->end) {  // go through every atom in this cell
     1928                        OtherWalker = OtherWalker->next;
     1929                        //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
     1930                        /// \todo periodic check is missing here!
     1931                        //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     1932                        MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
     1933                        MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
     1934                        MaxDistance = MinDistance + BONDTHRESHOLD;
     1935                        MinDistance -= BONDTHRESHOLD;
     1936                        distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
     1937                        if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
     1938                          //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
     1939                          AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
     1940                        } else {
     1941                          //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     1942                        }
     1943                      }
     1944                    }
     1945                  }
     1946            }
     1947          }
     1948        }
     1949
     1950
     1951
     1952    // 4. free the cell again
     1953    for (int i=NumberCells;i--;)
     1954      if (CellList[i] != NULL) {
     1955        delete(CellList[i]);
     1956      }
     1957    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
     1958
     1959    // create the adjacency list per atom
     1960    CreateListOfBondsPerAtom(out);
     1961
     1962    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
     1963    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     1964    // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
     1965    // double bonds as was expected.
     1966    if (BondCount != 0) {
     1967      NoCyclicBonds = 0;
     1968      *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     1969      do {
     1970        No = 0; // No acts as breakup flag (if 1 we still continue)
     1971        Walker = start;
     1972        while (Walker->next != end) { // go through every atom
     1973          Walker = Walker->next;
     1974          // count valence of first partner
     1975          NoBonds = 0;
     1976          for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
     1977            NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     1978          *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1979          if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
     1980            Candidate = NULL;
     1981            CandidateBondNo = -1;
     1982            for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
     1983              OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1984              // count valence of second partner
     1985              NoBonds = 0;
     1986              for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
     1987                NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
     1988              *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1989              if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     1990                if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
     1991                  Candidate = OtherWalker;
     1992                  CandidateBondNo = i;
     1993                  *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
     1994                }
     1995              }
     1996            }
     1997            if ((Candidate != NULL) && (CandidateBondNo != -1)) {
     1998              ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
     1999              *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
     2000            } else
     2001              *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
     2002              FalseBondDegree++;
     2003          }
     2004        }
     2005      } while (No);
     2006    *out << " done." << endl;
     2007    } else
     2008      *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
     2009    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     2010
     2011    // output bonds for debugging (if bond chain list was correctly installed)
     2012    *out << Verbose(1) << endl << "From contents of bond chain list:";
     2013    bond *Binder = first;
     2014    while(Binder->next != last) {
     2015      Binder = Binder->next;
     2016      *out << *Binder << "\t" << endl;
     2017    }
     2018    *out << endl;
     2019  } else
     2020    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     2021  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
     2022  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    20232023
    20242024};
     
    20362036MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
    20372037{
    2038         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    2039         BackEdgeStack = new StackClass<bond *> (BondCount);
    2040         MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    2041         MoleculeLeafClass *LeafWalker = SubGraphs;
    2042         int CurrentGraphNr = 0, OldGraphNr;
    2043         int ComponentNumber = 0;
    2044         atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
    2045         bond *Binder = NULL;
    2046         bool BackStepping = false;
    2047 
    2048         *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2049 
    2050         ResetAllBondsToUnused();
    2051         ResetAllAtomNumbers();
    2052         InitComponentNumbers();
    2053         BackEdgeStack->ClearStack();
    2054         while (Root != end) { // if there any atoms at all
    2055                 // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
    2056                 AtomStack->ClearStack();
    2057 
    2058                 // put into new subgraph molecule and add this to list of subgraphs
    2059                 LeafWalker = new MoleculeLeafClass(LeafWalker);
    2060                 LeafWalker->Leaf = new molecule(elemente);
    2061                 LeafWalker->Leaf->AddCopyAtom(Root);
    2062 
    2063                 OldGraphNr = CurrentGraphNr;
    2064                 Walker = Root;
    2065                 do { // (10)
    2066                         do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
    2067                                 if (!BackStepping) { // if we don't just return from (8)
    2068                                         Walker->GraphNr = CurrentGraphNr;
    2069                                         Walker->LowpointNr = CurrentGraphNr;
    2070                                         *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
    2071                                         AtomStack->Push(Walker);
    2072                                         CurrentGraphNr++;
    2073                                 }
    2074                                 do { // (3) if Walker has no unused egdes, go to (5)
    2075                                         BackStepping = false; // reset backstepping flag for (8)
    2076                                         if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
    2077                                                 Binder = FindNextUnused(Walker);
    2078                                         if (Binder == NULL)
    2079                                                 break;
    2080                                         *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
    2081                                         // (4) Mark Binder used, ...
    2082                                         Binder->MarkUsed(black);
    2083                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2084                                         *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
    2085                                         if (OtherAtom->GraphNr != -1) {
    2086                                                 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
    2087                                                 Binder->Type = BackEdge;
    2088                                                 BackEdgeStack->Push(Binder);
    2089                                                 Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
    2090                                                 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
    2091                                         } else {
    2092                                                 // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
    2093                                                 Binder->Type = TreeEdge;
    2094                                                 OtherAtom->Ancestor = Walker;
    2095                                                 Walker = OtherAtom;
    2096                                                 *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
    2097                                                 break;
    2098                                         }
    2099                                         Binder = NULL;
    2100                                 } while (1);    // (3)
    2101                                 if (Binder == NULL) {
    2102                                         *out << Verbose(2) << "No more Unused Bonds." << endl;
    2103                                         break;
    2104                                 } else
    2105                                         Binder = NULL;
    2106                         } while (1);    // (2)
    2107 
    2108                         // 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!
    2109                         if ((Walker == Root) && (Binder == NULL))
    2110                                 break;
    2111 
    2112                         // (5) if Ancestor of Walker is ...
    2113                         *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    2114                         if (Walker->Ancestor->GraphNr != Root->GraphNr) {
    2115                                 // (6)  (Ancestor of Walker is not Root)
    2116                                 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
    2117                                         // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
    2118                                         Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
    2119                                         *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
    2120                                 } else {
    2121                                         // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
    2122                                         Walker->Ancestor->SeparationVertex = true;
    2123                                         *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
    2124                                         SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
    2125                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
    2126                                         SetNextComponentNumber(Walker, ComponentNumber);
    2127                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2128                                         do {
    2129                                                 OtherAtom = AtomStack->PopLast();
    2130                                                 LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2131                                                 SetNextComponentNumber(OtherAtom, ComponentNumber);
    2132                                                 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2133                                         } while (OtherAtom != Walker);
    2134                                         ComponentNumber++;
    2135                                 }
    2136                                 // (8) Walker becomes its Ancestor, go to (3)
    2137                                 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
    2138                                 Walker = Walker->Ancestor;
    2139                                 BackStepping = true;
    2140                         }
    2141                         if (!BackStepping) {    // coming from (8) want to go to (3)
    2142                                 // (9) remove all from stack till Walker (including), these and Root form a component
    2143                                 AtomStack->Output(out);
    2144                                 SetNextComponentNumber(Root, ComponentNumber);
    2145                                 *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2146                                 SetNextComponentNumber(Walker, ComponentNumber);
    2147                                 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2148                                 do {
    2149                                         OtherAtom = AtomStack->PopLast();
    2150                                         LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2151                                         SetNextComponentNumber(OtherAtom, ComponentNumber);
    2152                                         *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2153                                 } while (OtherAtom != Walker);
    2154                                 ComponentNumber++;
    2155 
    2156                                 // (11) Root is separation vertex,      set Walker to Root and go to (4)
    2157                                 Walker = Root;
    2158                                 Binder = FindNextUnused(Walker);
    2159                                 *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
    2160                                 if (Binder != NULL) { // Root is separation vertex
    2161                                         *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
    2162                                         Walker->SeparationVertex = true;
    2163                                 }
    2164                         }
    2165                 } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
    2166 
    2167                 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2168                 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    2169                 LeafWalker->Leaf->Output(out);
    2170                 *out << endl;
    2171 
    2172                 // step on to next root
    2173                 while ((Root != end) && (Root->GraphNr != -1)) {
    2174                         //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    2175                         if (Root->GraphNr != -1) // if already discovered, step on
    2176                                 Root = Root->next;
    2177                 }
    2178         }
    2179         // set cyclic bond criterium on "same LP" basis
    2180         Binder = first;
    2181         while(Binder->next != last) {
    2182                 Binder = Binder->next;
    2183                 if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
    2184                         Binder->Cyclic = true;
    2185                         NoCyclicBonds++;
    2186                 }
    2187         }
    2188 
    2189 
    2190         *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    2191         Walker = start;
    2192         while (Walker->next != end) {
    2193                 Walker = Walker->next;
    2194                 *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    2195                 OutputComponentNumber(out, Walker);
    2196                 *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    2197         }
    2198 
    2199         *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    2200         Binder = first;
    2201         while(Binder->next != last) {
    2202                 Binder = Binder->next;
    2203                 *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    2204                 *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    2205                 OutputComponentNumber(out, Binder->leftatom);
    2206                 *out << " ===   ";
    2207                 *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    2208                 OutputComponentNumber(out, Binder->rightatom);
    2209                 *out << ">." << endl;
    2210                 if (Binder->Cyclic) // cyclic ??
    2211                         *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    2212         }
    2213 
    2214         // free all and exit
    2215         delete(AtomStack);
    2216         *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    2217         return SubGraphs;
     2038  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     2039  BackEdgeStack = new StackClass<bond *> (BondCount);
     2040  MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
     2041  MoleculeLeafClass *LeafWalker = SubGraphs;
     2042  int CurrentGraphNr = 0, OldGraphNr;
     2043  int ComponentNumber = 0;
     2044  atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
     2045  bond *Binder = NULL;
     2046  bool BackStepping = false;
     2047
     2048  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
     2049
     2050  ResetAllBondsToUnused();
     2051  ResetAllAtomNumbers();
     2052  InitComponentNumbers();
     2053  BackEdgeStack->ClearStack();
     2054  while (Root != end) { // if there any atoms at all
     2055    // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
     2056    AtomStack->ClearStack();
     2057
     2058    // put into new subgraph molecule and add this to list of subgraphs
     2059    LeafWalker = new MoleculeLeafClass(LeafWalker);
     2060    LeafWalker->Leaf = new molecule(elemente);
     2061    LeafWalker->Leaf->AddCopyAtom(Root);
     2062
     2063    OldGraphNr = CurrentGraphNr;
     2064    Walker = Root;
     2065    do { // (10)
     2066      do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
     2067        if (!BackStepping) { // if we don't just return from (8)
     2068          Walker->GraphNr = CurrentGraphNr;
     2069          Walker->LowpointNr = CurrentGraphNr;
     2070          *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
     2071          AtomStack->Push(Walker);
     2072          CurrentGraphNr++;
     2073        }
     2074        do { // (3) if Walker has no unused egdes, go to (5)
     2075          BackStepping = false; // reset backstepping flag for (8)
     2076          if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
     2077            Binder = FindNextUnused(Walker);
     2078          if (Binder == NULL)
     2079            break;
     2080          *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
     2081          // (4) Mark Binder used, ...
     2082          Binder->MarkUsed(black);
     2083          OtherAtom = Binder->GetOtherAtom(Walker);
     2084          *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
     2085          if (OtherAtom->GraphNr != -1) {
     2086            // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
     2087            Binder->Type = BackEdge;
     2088            BackEdgeStack->Push(Binder);
     2089            Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
     2090            *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
     2091          } else {
     2092            // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
     2093            Binder->Type = TreeEdge;
     2094            OtherAtom->Ancestor = Walker;
     2095            Walker = OtherAtom;
     2096            *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
     2097            break;
     2098          }
     2099          Binder = NULL;
     2100        } while (1);  // (3)
     2101        if (Binder == NULL) {
     2102          *out << Verbose(2) << "No more Unused Bonds." << endl;
     2103          break;
     2104        } else
     2105          Binder = NULL;
     2106      } while (1);  // (2)
     2107
     2108      // 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!
     2109      if ((Walker == Root) && (Binder == NULL))
     2110        break;
     2111
     2112      // (5) if Ancestor of Walker is ...
     2113      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
     2114      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     2115        // (6)  (Ancestor of Walker is not Root)
     2116        if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
     2117          // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
     2118          Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
     2119          *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
     2120        } else {
     2121          // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
     2122          Walker->Ancestor->SeparationVertex = true;
     2123          *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
     2124          SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
     2125          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
     2126          SetNextComponentNumber(Walker, ComponentNumber);
     2127          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2128          do {
     2129            OtherAtom = AtomStack->PopLast();
     2130            LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2131            SetNextComponentNumber(OtherAtom, ComponentNumber);
     2132            *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2133          } while (OtherAtom != Walker);
     2134          ComponentNumber++;
     2135        }
     2136        // (8) Walker becomes its Ancestor, go to (3)
     2137        *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
     2138        Walker = Walker->Ancestor;
     2139        BackStepping = true;
     2140      }
     2141      if (!BackStepping) {  // coming from (8) want to go to (3)
     2142        // (9) remove all from stack till Walker (including), these and Root form a component
     2143        AtomStack->Output(out);
     2144        SetNextComponentNumber(Root, ComponentNumber);
     2145        *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2146        SetNextComponentNumber(Walker, ComponentNumber);
     2147        *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2148        do {
     2149          OtherAtom = AtomStack->PopLast();
     2150          LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2151          SetNextComponentNumber(OtherAtom, ComponentNumber);
     2152          *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2153        } while (OtherAtom != Walker);
     2154        ComponentNumber++;
     2155
     2156        // (11) Root is separation vertex,  set Walker to Root and go to (4)
     2157        Walker = Root;
     2158        Binder = FindNextUnused(Walker);
     2159        *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
     2160        if (Binder != NULL) { // Root is separation vertex
     2161          *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
     2162          Walker->SeparationVertex = true;
     2163        }
     2164      }
     2165    } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
     2166
     2167    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
     2168    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2169    LeafWalker->Leaf->Output(out);
     2170    *out << endl;
     2171
     2172    // step on to next root
     2173    while ((Root != end) && (Root->GraphNr != -1)) {
     2174      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
     2175      if (Root->GraphNr != -1) // if already discovered, step on
     2176        Root = Root->next;
     2177    }
     2178  }
     2179  // set cyclic bond criterium on "same LP" basis
     2180  Binder = first;
     2181  while(Binder->next != last) {
     2182    Binder = Binder->next;
     2183    if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
     2184      Binder->Cyclic = true;
     2185      NoCyclicBonds++;
     2186    }
     2187  }
     2188
     2189
     2190  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
     2191  Walker = start;
     2192  while (Walker->next != end) {
     2193    Walker = Walker->next;
     2194    *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
     2195    OutputComponentNumber(out, Walker);
     2196    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
     2197  }
     2198
     2199  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
     2200  Binder = first;
     2201  while(Binder->next != last) {
     2202    Binder = Binder->next;
     2203    *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
     2204    *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
     2205    OutputComponentNumber(out, Binder->leftatom);
     2206    *out << " ===  ";
     2207    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
     2208    OutputComponentNumber(out, Binder->rightatom);
     2209    *out << ">." << endl;
     2210    if (Binder->Cyclic) // cyclic ??
     2211      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     2212  }
     2213
     2214  // free all and exit
     2215  delete(AtomStack);
     2216  *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     2217  return SubGraphs;
    22182218};
    22192219
     
    22282228 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
    22292229 */
    2230 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *        BackEdgeStack, int *&MinimumRingSize)
    2231 {
    2232         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2233         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    2234         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2235         class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);        // will hold the current ring
    2236         class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);    // contains all "touched" atoms (that need to be reset after BFS loop)
    2237         atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
    2238         bond *Binder = NULL, *BackEdge = NULL;
    2239         int RingSize, NumCycles, MinRingSize = -1;
    2240 
    2241         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    2242         for (int i=AtomCount;i--;) {
    2243                 PredecessorList[i] = NULL;
    2244                 ShortestPathList[i] = -1;
    2245                 ColorList[i] = white;
    2246         }
    2247 
    2248         *out << Verbose(1) << "Back edge list - ";
    2249         BackEdgeStack->Output(out);
    2250 
    2251         *out << Verbose(1) << "Analysing cycles ... " << endl;
    2252         NumCycles = 0;
    2253         while (!BackEdgeStack->IsEmpty()) {
    2254                 BackEdge = BackEdgeStack->PopFirst();
    2255                 // this is the target
    2256                 Root = BackEdge->leftatom;
    2257                 // this is the source point
    2258                 Walker = BackEdge->rightatom;
    2259                 ShortestPathList[Walker->nr] = 0;
    2260                 BFSStack->ClearStack(); // start with empty BFS stack
    2261                 BFSStack->Push(Walker);
    2262                 TouchedStack->Push(Walker);
    2263                 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2264                 OtherAtom = NULL;
    2265                 do {    // look for Root
    2266                         Walker = BFSStack->PopFirst();
    2267                         *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2268                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2269                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2270                                 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    2271                                         OtherAtom = Binder->GetOtherAtom(Walker);
     2230void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *  BackEdgeStack, int *&MinimumRingSize)
     2231{
     2232  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2233  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
     2234  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
     2235  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);  // will hold the current ring
     2236  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);  // contains all "touched" atoms (that need to be reset after BFS loop)
     2237  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     2238  bond *Binder = NULL, *BackEdge = NULL;
     2239  int RingSize, NumCycles, MinRingSize = -1;
     2240
     2241  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     2242  for (int i=AtomCount;i--;) {
     2243    PredecessorList[i] = NULL;
     2244    ShortestPathList[i] = -1;
     2245    ColorList[i] = white;
     2246  }
     2247
     2248  *out << Verbose(1) << "Back edge list - ";
     2249  BackEdgeStack->Output(out);
     2250
     2251  *out << Verbose(1) << "Analysing cycles ... " << endl;
     2252  NumCycles = 0;
     2253  while (!BackEdgeStack->IsEmpty()) {
     2254    BackEdge = BackEdgeStack->PopFirst();
     2255    // this is the target
     2256    Root = BackEdge->leftatom;
     2257    // this is the source point
     2258    Walker = BackEdge->rightatom;
     2259    ShortestPathList[Walker->nr] = 0;
     2260    BFSStack->ClearStack();  // start with empty BFS stack
     2261    BFSStack->Push(Walker);
     2262    TouchedStack->Push(Walker);
     2263    *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2264    OtherAtom = NULL;
     2265    do {  // look for Root
     2266      Walker = BFSStack->PopFirst();
     2267      *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2268      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2269        Binder = ListOfBondsPerAtom[Walker->nr][i];
     2270        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     2271          OtherAtom = Binder->GetOtherAtom(Walker);
    22722272#ifdef ADDHYDROGEN
    2273                                         if (OtherAtom->type->Z != 1) {
     2273          if (OtherAtom->type->Z != 1) {
    22742274#endif
    2275                                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2276                                                 if (ColorList[OtherAtom->nr] == white) {
    2277                                                         TouchedStack->Push(OtherAtom);
    2278                                                         ColorList[OtherAtom->nr] = lightgray;
    2279                                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2280                                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2281                                                         *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;
    2282                                                         //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    2283                                                                 *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
    2284                                                                 BFSStack->Push(OtherAtom);
    2285                                                         //}
    2286                                                 } else {
    2287                                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2288                                                 }
    2289                                                 if (OtherAtom == Root)
    2290                                                         break;
     2275            *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2276            if (ColorList[OtherAtom->nr] == white) {
     2277              TouchedStack->Push(OtherAtom);
     2278              ColorList[OtherAtom->nr] = lightgray;
     2279              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2280              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2281              *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;
     2282              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
     2283                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     2284                BFSStack->Push(OtherAtom);
     2285              //}
     2286            } else {
     2287              *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2288            }
     2289            if (OtherAtom == Root)
     2290              break;
    22912291#ifdef ADDHYDROGEN
    2292                                         } else {
    2293                                                 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
    2294                                                 ColorList[OtherAtom->nr] = black;
    2295                                         }
     2292          } else {
     2293            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     2294            ColorList[OtherAtom->nr] = black;
     2295          }
    22962296#endif
    2297                                 } else {
    2298                                         *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
    2299                                 }
    2300                         }
    2301                         ColorList[Walker->nr] = black;
    2302                         *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2303                         if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
    2304                                 // step through predecessor list
    2305                                 while (OtherAtom != BackEdge->rightatom) {
    2306                                         if (!OtherAtom->GetTrueFather()->IsCyclic)      // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
    2307                                                 break;
    2308                                         else
    2309                                                 OtherAtom = PredecessorList[OtherAtom->nr];
    2310                                 }
    2311                                 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
    2312                                         *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
    2313                                         do {
    2314                                                 OtherAtom = TouchedStack->PopLast();
    2315                                                 if (PredecessorList[OtherAtom->nr] == Walker) {
    2316                                                         *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
    2317                                                         PredecessorList[OtherAtom->nr] = NULL;
    2318                                                         ShortestPathList[OtherAtom->nr] = -1;
    2319                                                         ColorList[OtherAtom->nr] = white;
    2320                                                         BFSStack->RemoveItem(OtherAtom);
    2321                                                 }
    2322                                         } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
    2323                                         TouchedStack->Push(OtherAtom);  // last was wrongly popped
    2324                                         OtherAtom = BackEdge->rightatom; // set to not Root
    2325                                 } else
    2326                                         OtherAtom = Root;
    2327                         }
    2328                 } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2329 
    2330                 if (OtherAtom == Root) {
    2331                         // now climb back the predecessor list and thus find the cycle members
    2332                         NumCycles++;
    2333                         RingSize = 1;
    2334                         Root->GetTrueFather()->IsCyclic = true;
    2335                         *out << Verbose(1) << "Found ring contains: ";
    2336                         Walker = Root;
    2337                         while (Walker != BackEdge->rightatom) {
    2338                                 *out << Walker->Name << " <-> ";
    2339                                 Walker = PredecessorList[Walker->nr];
    2340                                 Walker->GetTrueFather()->IsCyclic = true;
    2341                                 RingSize++;
    2342                         }
    2343                         *out << Walker->Name << "       with a length of " << RingSize << "." << endl << endl;
    2344                         // walk through all and set MinimumRingSize
    2345                         Walker = Root;
    2346                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2347                         while (Walker != BackEdge->rightatom) {
    2348                                 Walker = PredecessorList[Walker->nr];
    2349                                 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
    2350                                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2351                         }
    2352                         if ((RingSize < MinRingSize) || (MinRingSize == -1))
    2353                                 MinRingSize = RingSize;
    2354                 } else {
    2355                         *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    2356                 }
    2357 
    2358                 // now clean the lists
    2359                 while (!TouchedStack->IsEmpty()){
    2360                         Walker = TouchedStack->PopFirst();
    2361                         PredecessorList[Walker->nr] = NULL;
    2362                         ShortestPathList[Walker->nr] = -1;
    2363                         ColorList[Walker->nr] = white;
    2364                 }
    2365         }
    2366         if (MinRingSize != -1) {
    2367                 // go over all atoms
    2368                 Root = start;
    2369                 while(Root->next != end) {
    2370                         Root = Root->next;
    2371 
    2372                         if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    2373                                 Walker = Root;
    2374                                 ShortestPathList[Walker->nr] = 0;
    2375                                 BFSStack->ClearStack(); // start with empty BFS stack
    2376                                 BFSStack->Push(Walker);
    2377                                 TouchedStack->Push(Walker);
    2378                                 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2379                                 OtherAtom = Walker;
    2380                                 while (OtherAtom != NULL) {     // look for Root
    2381                                         Walker = BFSStack->PopFirst();
    2382                                         //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2383                                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2384                                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2385                                                 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
    2386                                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2387                                                         //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2388                                                         if (ColorList[OtherAtom->nr] == white) {
    2389                                                                 TouchedStack->Push(OtherAtom);
    2390                                                                 ColorList[OtherAtom->nr] = lightgray;
    2391                                                                 PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2392                                                                 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2393                                                                 //*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;
    2394                                                                 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
    2395                                                                         MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
    2396                                                                         OtherAtom = NULL; //break;
    2397                                                                         break;
    2398                                                                 } else
    2399                                                                         BFSStack->Push(OtherAtom);
    2400                                                         } else {
    2401                                                                 //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2402                                                         }
    2403                                                 } else {
    2404                                                         //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
    2405                                                 }
    2406                                         }
    2407                                         ColorList[Walker->nr] = black;
    2408                                         //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2409                                 }
    2410 
    2411                                 // now clean the lists
    2412                                 while (!TouchedStack->IsEmpty()){
    2413                                         Walker = TouchedStack->PopFirst();
    2414                                         PredecessorList[Walker->nr] = NULL;
    2415                                         ShortestPathList[Walker->nr] = -1;
    2416                                         ColorList[Walker->nr] = white;
    2417                                 }
    2418                         }
    2419                         *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
    2420                 }
    2421                 *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
    2422         } else
    2423                 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
    2424 
    2425         Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2426         Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
    2427         Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
    2428         delete(BFSStack);
     2297        } else {
     2298          *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
     2299        }
     2300      }
     2301      ColorList[Walker->nr] = black;
     2302      *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2303      if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
     2304        // step through predecessor list
     2305        while (OtherAtom != BackEdge->rightatom) {
     2306          if (!OtherAtom->GetTrueFather()->IsCyclic)  // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
     2307            break;
     2308          else
     2309            OtherAtom = PredecessorList[OtherAtom->nr];
     2310        }
     2311        if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
     2312          *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
     2313          do {
     2314            OtherAtom = TouchedStack->PopLast();
     2315            if (PredecessorList[OtherAtom->nr] == Walker) {
     2316              *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
     2317              PredecessorList[OtherAtom->nr] = NULL;
     2318              ShortestPathList[OtherAtom->nr] = -1;
     2319              ColorList[OtherAtom->nr] = white;
     2320              BFSStack->RemoveItem(OtherAtom);
     2321            }
     2322          } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
     2323          TouchedStack->Push(OtherAtom);  // last was wrongly popped
     2324          OtherAtom = BackEdge->rightatom; // set to not Root
     2325        } else
     2326          OtherAtom = Root;
     2327      }
     2328    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
     2329
     2330    if (OtherAtom == Root) {
     2331      // now climb back the predecessor list and thus find the cycle members
     2332      NumCycles++;
     2333      RingSize = 1;
     2334      Root->GetTrueFather()->IsCyclic = true;
     2335      *out << Verbose(1) << "Found ring contains: ";
     2336      Walker = Root;
     2337      while (Walker != BackEdge->rightatom) {
     2338        *out << Walker->Name << " <-> ";
     2339        Walker = PredecessorList[Walker->nr];
     2340        Walker->GetTrueFather()->IsCyclic = true;
     2341        RingSize++;
     2342      }
     2343      *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
     2344      // walk through all and set MinimumRingSize
     2345      Walker = Root;
     2346      MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2347      while (Walker != BackEdge->rightatom) {
     2348        Walker = PredecessorList[Walker->nr];
     2349        if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
     2350          MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2351      }
     2352      if ((RingSize < MinRingSize) || (MinRingSize == -1))
     2353        MinRingSize = RingSize;
     2354    } else {
     2355      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
     2356    }
     2357
     2358    // now clean the lists
     2359    while (!TouchedStack->IsEmpty()){
     2360      Walker = TouchedStack->PopFirst();
     2361      PredecessorList[Walker->nr] = NULL;
     2362      ShortestPathList[Walker->nr] = -1;
     2363      ColorList[Walker->nr] = white;
     2364    }
     2365  }
     2366  if (MinRingSize != -1) {
     2367    // go over all atoms
     2368    Root = start;
     2369    while(Root->next != end) {
     2370      Root = Root->next;
     2371
     2372      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
     2373        Walker = Root;
     2374        ShortestPathList[Walker->nr] = 0;
     2375        BFSStack->ClearStack();  // start with empty BFS stack
     2376        BFSStack->Push(Walker);
     2377        TouchedStack->Push(Walker);
     2378        //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2379        OtherAtom = Walker;
     2380        while (OtherAtom != NULL) {  // look for Root
     2381          Walker = BFSStack->PopFirst();
     2382          //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2383          for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2384            Binder = ListOfBondsPerAtom[Walker->nr][i];
     2385            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
     2386              OtherAtom = Binder->GetOtherAtom(Walker);
     2387              //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2388              if (ColorList[OtherAtom->nr] == white) {
     2389                TouchedStack->Push(OtherAtom);
     2390                ColorList[OtherAtom->nr] = lightgray;
     2391                PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2392                ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2393                //*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;
     2394                if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
     2395                  MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
     2396                  OtherAtom = NULL; //break;
     2397                  break;
     2398                } else
     2399                  BFSStack->Push(OtherAtom);
     2400              } else {
     2401                //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2402              }
     2403            } else {
     2404              //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
     2405            }
     2406          }
     2407          ColorList[Walker->nr] = black;
     2408          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2409        }
     2410
     2411        // now clean the lists
     2412        while (!TouchedStack->IsEmpty()){
     2413          Walker = TouchedStack->PopFirst();
     2414          PredecessorList[Walker->nr] = NULL;
     2415          ShortestPathList[Walker->nr] = -1;
     2416          ColorList[Walker->nr] = white;
     2417        }
     2418      }
     2419      *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
     2420    }
     2421    *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
     2422  } else
     2423    *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
     2424
     2425  Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2426  Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
     2427  Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
     2428  delete(BFSStack);
    24292429};
    24302430
     
    24362436void molecule::SetNextComponentNumber(atom *vertex, int nr)
    24372437{
    2438         int i=0;
    2439         if (vertex != NULL) {
    2440                 for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
    2441                         if (vertex->ComponentNr[i] == -1) {      // check if not yet used
    2442                                 vertex->ComponentNr[i] = nr;
    2443                                 break;
    2444                         }
    2445                         else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
    2446                                 break;  // breaking here will not cause error!
    2447                 }
    2448                 if (i == NumberOfBondsPerAtom[vertex->nr])
    2449                         cerr << "Error: All Component entries are already occupied!" << endl;
    2450         } else
    2451                         cerr << "Error: Given vertex is NULL!" << endl;
     2438  int i=0;
     2439  if (vertex != NULL) {
     2440    for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
     2441      if (vertex->ComponentNr[i] == -1) {  // check if not yet used
     2442        vertex->ComponentNr[i] = nr;
     2443        break;
     2444      }
     2445      else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
     2446        break;  // breaking here will not cause error!
     2447    }
     2448    if (i == NumberOfBondsPerAtom[vertex->nr])
     2449      cerr << "Error: All Component entries are already occupied!" << endl;
     2450  } else
     2451      cerr << "Error: Given vertex is NULL!" << endl;
    24522452};
    24532453
     
    24572457void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    24582458{
    2459         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2460                 *out << vertex->ComponentNr[i] << "     ";
     2459  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2460    *out << vertex->ComponentNr[i] << "  ";
    24612461};
    24622462
     
    24652465void molecule::InitComponentNumbers()
    24662466{
    2467         atom *Walker = start;
    2468         while(Walker->next != end) {
    2469                 Walker = Walker->next;
    2470                 if (Walker->ComponentNr != NULL)
    2471                         Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
    2472                 Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    2473                 for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
    2474                         Walker->ComponentNr[i] = -1;
    2475         }
     2467  atom *Walker = start;
     2468  while(Walker->next != end) {
     2469    Walker = Walker->next;
     2470    if (Walker->ComponentNr != NULL)
     2471      Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
     2472    Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
     2473    for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
     2474      Walker->ComponentNr[i] = -1;
     2475  }
    24762476};
    24772477
     
    24822482bond * molecule::FindNextUnused(atom *vertex)
    24832483{
    2484         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2485                 if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    2486                         return(ListOfBondsPerAtom[vertex->nr][i]);
    2487         return NULL;
     2484  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2485    if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
     2486      return(ListOfBondsPerAtom[vertex->nr][i]);
     2487  return NULL;
    24882488};
    24892489
     
    24932493void molecule::ResetAllBondsToUnused()
    24942494{
    2495         bond *Binder = first;
    2496         while (Binder->next != last) {
    2497                 Binder = Binder->next;
    2498                 Binder->ResetUsed();
    2499         }
     2495  bond *Binder = first;
     2496  while (Binder->next != last) {
     2497    Binder = Binder->next;
     2498    Binder->ResetUsed();
     2499  }
    25002500};
    25012501
     
    25042504void molecule::ResetAllAtomNumbers()
    25052505{
    2506         atom *Walker = start;
    2507         while (Walker->next != end) {
    2508                 Walker = Walker->next;
    2509                 Walker->GraphNr = -1;
    2510         }
     2506  atom *Walker = start;
     2507  while (Walker->next != end) {
     2508    Walker = Walker->next;
     2509    Walker->GraphNr  = -1;
     2510  }
    25112511};
    25122512
     
    25172517void OutputAlreadyVisited(ofstream *out, int *list)
    25182518{
    2519         *out << Verbose(4) << "Already Visited Bonds:\t";
    2520         for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
    2521         *out << endl;
     2519  *out << Verbose(4) << "Already Visited Bonds:\t";
     2520  for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
     2521  *out << endl;
    25222522};
    25232523
     
    25252525 * The upper limit is
    25262526 * \f[
    2527  *      n = N \cdot C^k
     2527 *  n = N \cdot C^k
    25282528 * \f]
    25292529 * where \f$C=2^c\f$ and c is the maximum bond degree over N number of atoms.
     
    25342534int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    25352535{
    2536         int c = 0;
    2537         int FragmentCount;
    2538         // get maximum bond degree
    2539         atom *Walker = start;
    2540         while (Walker->next != end) {
    2541                 Walker = Walker->next;
    2542                 c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
    2543         }
    2544         FragmentCount = NoNonHydrogen*(1 << (c*order));
    2545         *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    2546         return FragmentCount;
     2536  int c = 0;
     2537  int FragmentCount;
     2538  // get maximum bond degree
     2539  atom *Walker = start;
     2540  while (Walker->next != end) {
     2541    Walker = Walker->next;
     2542    c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     2543  }
     2544  FragmentCount = NoNonHydrogen*(1 << (c*order));
     2545  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
     2546  return FragmentCount;
    25472547};
    25482548
     
    25552555bool molecule::ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet)
    25562556{
    2557         stringstream line;
    2558         int AtomNr;
    2559         int status = 0;
    2560 
    2561         line.str(buffer);
    2562         while (!line.eof()) {
    2563                 line >> AtomNr;
    2564                 if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2565                         CurrentSet.insert(AtomNr);      // insert at end, hence in same order as in file!
    2566                         status++;
    2567                 } // else it's "-1" or else and thus must not be added
    2568         }
    2569         *out << Verbose(1) << "The scanned KeySet is ";
    2570         for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
    2571                 *out << (*runner) << "\t";
    2572         }
    2573         *out << endl;
    2574         return (status != 0);
     2557  stringstream line;
     2558  int AtomNr;
     2559  int status = 0;
     2560
     2561  line.str(buffer);
     2562  while (!line.eof()) {
     2563    line >> AtomNr;
     2564    if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2565      CurrentSet.insert(AtomNr);  // insert at end, hence in same order as in file!
     2566      status++;
     2567    } // else it's "-1" or else and thus must not be added
     2568  }
     2569  *out << Verbose(1) << "The scanned KeySet is ";
     2570  for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
     2571    *out << (*runner) << "\t";
     2572  }
     2573  *out << endl;
     2574  return (status != 0);
    25752575};
    25762576
     
    25872587bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList)
    25882588{
    2589         bool status = true;
    2590         ifstream InputFile;
    2591         stringstream line;
    2592         GraphTestPair testGraphInsert;
    2593         int NumberOfFragments = 0;
    2594         double TEFactor;
    2595         char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2596 
    2597         if (FragmentList == NULL) { // check list pointer
    2598                 FragmentList = new Graph;
    2599         }
    2600 
    2601         // 1st pass: open file and read
    2602         *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
    2603         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
    2604         InputFile.open(filename);
    2605         if (InputFile != NULL) {
    2606                 // each line represents a new fragment
    2607                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
    2608                 // 1. parse keysets and insert into temp. graph
    2609                 while (!InputFile.eof()) {
    2610                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2611                         KeySet CurrentSet;
    2612                         if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
    2613                                 testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
    2614                                 if (!testGraphInsert.second) {
    2615                                         cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    2616                                 }
    2617                         }
    2618                 }
    2619                 // 2. Free and done
    2620                 InputFile.close();
    2621                 InputFile.clear();
    2622                 Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
    2623                 *out << Verbose(1) << "done." << endl;
    2624         } else {
    2625                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2626                 status = false;
    2627         }
    2628 
    2629         // 2nd pass: open TEFactors file and read
    2630         *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
    2631         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
    2632         InputFile.open(filename);
    2633         if (InputFile != NULL) {
    2634                 // 3. add found TEFactors to each keyset
    2635                 NumberOfFragments = 0;
    2636                 for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
    2637                         if (!InputFile.eof()) {
    2638                                 InputFile >> TEFactor;
    2639                                 (*runner).second.second = TEFactor;
    2640                                 *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    2641                         } else {
    2642                                 status = false;
    2643                                 break;
    2644                         }
    2645                 }
    2646                 // 4. Free and done
    2647                 InputFile.close();
    2648                 *out << Verbose(1) << "done." << endl;
    2649         } else {
    2650                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2651                 status = false;
    2652         }
    2653 
    2654         // free memory
    2655         Free((void **)&filename, "molecule::ParseKeySetFile - filename");
    2656 
    2657         return status;
     2589  bool status = true;
     2590  ifstream InputFile;
     2591  stringstream line;
     2592  GraphTestPair testGraphInsert;
     2593  int NumberOfFragments = 0;
     2594  double TEFactor;
     2595  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
     2596
     2597  if (FragmentList == NULL) { // check list pointer
     2598    FragmentList = new Graph;
     2599  }
     2600
     2601  // 1st pass: open file and read
     2602  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     2603  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
     2604  InputFile.open(filename);
     2605  if (InputFile != NULL) {
     2606    // each line represents a new fragment
     2607    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
     2608    // 1. parse keysets and insert into temp. graph
     2609    while (!InputFile.eof()) {
     2610      InputFile.getline(buffer, MAXSTRINGSIZE);
     2611      KeySet CurrentSet;
     2612      if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
     2613        testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1)));  // store fragment number and current factor
     2614        if (!testGraphInsert.second) {
     2615          cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
     2616        }
     2617      }
     2618    }
     2619    // 2. Free and done
     2620    InputFile.close();
     2621    InputFile.clear();
     2622    Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
     2623    *out << Verbose(1) << "done." << endl;
     2624  } else {
     2625    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2626    status = false;
     2627  }
     2628
     2629  // 2nd pass: open TEFactors file and read
     2630  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     2631  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
     2632  InputFile.open(filename);
     2633  if (InputFile != NULL) {
     2634    // 3. add found TEFactors to each keyset
     2635    NumberOfFragments = 0;
     2636    for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
     2637      if (!InputFile.eof()) {
     2638        InputFile >> TEFactor;
     2639        (*runner).second.second = TEFactor;
     2640        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2641      } else {
     2642        status = false;
     2643        break;
     2644      }
     2645    }
     2646    // 4. Free and done
     2647    InputFile.close();
     2648    *out << Verbose(1) << "done." << endl;
     2649  } else {
     2650    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2651    status = false;
     2652  }
     2653
     2654  // free memory
     2655  Free((void **)&filename, "molecule::ParseKeySetFile - filename");
     2656
     2657  return status;
    26582658};
    26592659
     
    26662666bool molecule::StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path)
    26672667{
    2668         ofstream output;
    2669         bool status =   true;
    2670         string line;
    2671 
    2672         // open KeySet file
    2673         line = path;
    2674         line.append("/");
    2675         line += FRAGMENTPREFIX;
    2676         line += KEYSETFILE;
    2677         output.open(line.c_str(), ios::out);
    2678         *out << Verbose(1) << "Saving key sets of the total graph ... ";
    2679         if(output != NULL) {
    2680                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2681                         for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    2682                                 if (sprinter != (*runner).first.begin())
    2683                                         output << "\t";
    2684                                 output << *sprinter;
    2685                         }
    2686                         output << endl;
    2687                 }
    2688                 *out << "done." << endl;
    2689         } else {
    2690                 cerr << "Unable to open " << line << " for writing keysets!" << endl;
    2691                 status = false;
    2692         }
    2693         output.close();
    2694         output.clear();
    2695 
    2696         // open TEFactors file
    2697         line = path;
    2698         line.append("/");
    2699         line += FRAGMENTPREFIX;
    2700         line += TEFACTORSFILE;
    2701         output.open(line.c_str(), ios::out);
    2702         *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
    2703         if(output != NULL) {
    2704                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
    2705                         output << (*runner).second.second << endl;
    2706                 *out << Verbose(1) << "done." << endl;
    2707         } else {
    2708                 *out << Verbose(1) << "failed to open " << line << "." << endl;
    2709                 status = false;
    2710         }
    2711         output.close();
    2712 
    2713         return status;
     2668  ofstream output;
     2669  bool status =  true;
     2670  string line;
     2671
     2672  // open KeySet file
     2673  line = path;
     2674  line.append("/");
     2675  line += FRAGMENTPREFIX;
     2676  line += KEYSETFILE;
     2677  output.open(line.c_str(), ios::out);
     2678  *out << Verbose(1) << "Saving key sets of the total graph ... ";
     2679  if(output != NULL) {
     2680    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
     2681      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     2682        if (sprinter != (*runner).first.begin())
     2683          output << "\t";
     2684        output << *sprinter;
     2685      }
     2686      output << endl;
     2687    }
     2688    *out << "done." << endl;
     2689  } else {
     2690    cerr << "Unable to open " << line << " for writing keysets!" << endl;
     2691    status = false;
     2692  }
     2693  output.close();
     2694  output.clear();
     2695
     2696  // open TEFactors file
     2697  line = path;
     2698  line.append("/");
     2699  line += FRAGMENTPREFIX;
     2700  line += TEFACTORSFILE;
     2701  output.open(line.c_str(), ios::out);
     2702  *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
     2703  if(output != NULL) {
     2704    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
     2705      output << (*runner).second.second << endl;
     2706    *out << Verbose(1) << "done." << endl;
     2707  } else {
     2708    *out << Verbose(1) << "failed to open " << line << "." << endl;
     2709    status = false;
     2710  }
     2711  output.close();
     2712
     2713  return status;
    27142714};
    27152715
     
    27222722bool molecule::StoreAdjacencyToFile(ofstream *out, char *path)
    27232723{
    2724         ofstream AdjacencyFile;
    2725         atom *Walker = NULL;
    2726         stringstream line;
    2727         bool status = true;
    2728 
    2729         line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2730         AdjacencyFile.open(line.str().c_str(), ios::out);
    2731         *out << Verbose(1) << "Saving adjacency list ... ";
    2732         if (AdjacencyFile != NULL) {
    2733                 Walker = start;
    2734                 while(Walker->next != end) {
    2735                         Walker = Walker->next;
    2736                         AdjacencyFile << Walker->nr << "\t";
    2737                         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    2738                                 AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    2739                         AdjacencyFile << endl;
    2740                 }
    2741                 AdjacencyFile.close();
    2742                 *out << Verbose(1) << "done." << endl;
    2743         } else {
    2744                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    2745                 status = false;
    2746         }
    2747 
    2748         return status;
     2724  ofstream AdjacencyFile;
     2725  atom *Walker = NULL;
     2726  stringstream line;
     2727  bool status = true;
     2728
     2729  line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2730  AdjacencyFile.open(line.str().c_str(), ios::out);
     2731  *out << Verbose(1) << "Saving adjacency list ... ";
     2732  if (AdjacencyFile != NULL) {
     2733    Walker = start;
     2734    while(Walker->next != end) {
     2735      Walker = Walker->next;
     2736      AdjacencyFile << Walker->nr << "\t";
     2737      for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
     2738        AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
     2739      AdjacencyFile << endl;
     2740    }
     2741    AdjacencyFile.close();
     2742    *out << Verbose(1) << "done." << endl;
     2743  } else {
     2744    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     2745    status = false;
     2746  }
     2747
     2748  return status;
    27492749};
    27502750
     
    27572757bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    27582758{
    2759         ifstream File;
    2760         stringstream filename;
    2761         bool status = true;
    2762         char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2763 
    2764         filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2765         File.open(filename.str().c_str(), ios::out);
    2766         *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
    2767         if (File != NULL) {
    2768                 // allocate storage structure
    2769                 int NonMatchNumber = 0; // will number of atoms with differing bond structure
    2770                 int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    2771                 int CurrentBondsOfAtom;
    2772 
    2773                 // Parse the file line by line and count the bonds
    2774                 while (!File.eof()) {
    2775                         File.getline(buffer, MAXSTRINGSIZE);
    2776                         stringstream line;
    2777                         line.str(buffer);
    2778                         int AtomNr = -1;
    2779                         line >> AtomNr;
    2780                         CurrentBondsOfAtom = -1; // we count one too far due to line end
    2781                         // parse into structure
    2782                         if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2783                                 while (!line.eof())
    2784                                         line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    2785                                 // compare against present bonds
    2786                                 //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    2787                                 if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    2788                                         for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    2789                                                 int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    2790                                                 int j = 0;
    2791                                                 for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    2792                                                 if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
    2793                                                         ListOfAtoms[AtomNr] = NULL;
    2794                                                         NonMatchNumber++;
    2795                                                         status = false;
    2796                                                         //out << "[" << id << "]\t";
    2797                                                 } else {
    2798                                                         //out << id << "\t";
    2799                                                 }
    2800                                         }
    2801                                         //out << endl;
    2802                                 } else {
    2803                                         *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
    2804                                         status = false;
    2805                                 }
    2806                         }
    2807                 }
    2808                 File.close();
    2809                 File.clear();
    2810                 if (status) { // if equal we parse the KeySetFile
    2811                         *out << Verbose(1) << "done: Equal." << endl;
    2812                         status = true;
    2813                 } else
    2814                         *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    2815                 Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
    2816         } else {
    2817                 *out << Verbose(1) << "Adjacency file not found." << endl;
    2818                 status = false;
    2819         }
    2820         *out << endl;
    2821         Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2822 
    2823         return status;
     2759  ifstream File;
     2760  stringstream filename;
     2761  bool status = true;
     2762  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2763
     2764  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2765  File.open(filename.str().c_str(), ios::out);
     2766  *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
     2767  if (File != NULL) {
     2768    // allocate storage structure
     2769    int NonMatchNumber = 0;  // will number of atoms with differing bond structure
     2770    int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
     2771    int CurrentBondsOfAtom;
     2772
     2773    // Parse the file line by line and count the bonds
     2774    while (!File.eof()) {
     2775      File.getline(buffer, MAXSTRINGSIZE);
     2776      stringstream line;
     2777      line.str(buffer);
     2778      int AtomNr = -1;
     2779      line >> AtomNr;
     2780      CurrentBondsOfAtom = -1; // we count one too far due to line end
     2781      // parse into structure
     2782      if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2783        while (!line.eof())
     2784          line >> CurrentBonds[ ++CurrentBondsOfAtom ];
     2785        // compare against present bonds
     2786        //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
     2787        if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
     2788          for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
     2789            int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
     2790            int j = 0;
     2791            for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
     2792            if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
     2793              ListOfAtoms[AtomNr] = NULL;
     2794              NonMatchNumber++;
     2795              status = false;
     2796              //out << "[" << id << "]\t";
     2797            } else {
     2798              //out << id << "\t";
     2799            }
     2800          }
     2801          //out << endl;
     2802        } else {
     2803          *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
     2804          status = false;
     2805        }
     2806      }
     2807    }
     2808    File.close();
     2809    File.clear();
     2810    if (status) { // if equal we parse the KeySetFile
     2811      *out << Verbose(1) << "done: Equal." << endl;
     2812      status = true;
     2813    } else
     2814      *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
     2815    Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
     2816  } else {
     2817    *out << Verbose(1) << "Adjacency file not found." << endl;
     2818    status = false;
     2819  }
     2820  *out << endl;
     2821  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2822
     2823  return status;
    28242824};
    28252825
     
    28352835bool molecule::CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path)
    28362836{
    2837         atom *Walker = start;
    2838         bool status = false;
    2839         ifstream InputFile;
    2840 
    2841         // initialize mask list
    2842         for(int i=AtomCount;i--;)
    2843                 AtomMask[i] = false;
    2844 
    2845         if (Order < 0) { // adaptive increase of BondOrder per site
    2846                 if (AtomMask[AtomCount] == true)        // break after one step
    2847                         return false;
    2848                 // parse the EnergyPerFragment file
    2849                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
    2850                 sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
    2851                 InputFile.open(buffer, ios::in);
    2852                 if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
    2853                         // transmorph graph keyset list into indexed KeySetList
    2854                         map<int,KeySet> IndexKeySetList;
    2855                         for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
    2856                                 IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
    2857                         }
    2858                         int lines = 0;
    2859                         // count the number of lines, i.e. the number of fragments
    2860                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2861                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2862                         while(!InputFile.eof()) {
    2863                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2864                                 lines++;
    2865                         }
    2866                         //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;      // one endline too much
    2867                         InputFile.clear();
    2868                         InputFile.seekg(ios::beg);
    2869                         map<int, pair<double,int> > AdaptiveCriteriaList;       // (Root No., (Value, Order)) !
    2870                         int No, FragOrder;
    2871                         double Value;
    2872                         // each line represents a fragment root (Atom::nr) id and its energy contribution
    2873                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2874                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2875                         while(!InputFile.eof()) {
    2876                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2877                                 if (strlen(buffer) > 2) {
    2878                                         //*out << Verbose(2) << "Scanning: " << buffer << endl;
    2879                                         stringstream line(buffer);
    2880                                         line >> FragOrder;
    2881                                         line >> ws >> No;
    2882                                         line >> ws >> Value; // skip time entry
    2883                                         line >> ws >> Value;
    2884                                         No -= 1;        // indices start at 1 in file, not 0
    2885                                         //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    2886 
    2887                                         // clean the list of those entries that have been superceded by higher order terms already
    2888                                         map<int,KeySet>::iterator marker = IndexKeySetList.find(No);            // find keyset to Frag No.
    2889                                         if (marker != IndexKeySetList.end()) {  // if found
    2890                                                 Value *= 1 + MYEPSILON*(*((*marker).second.begin()));            // in case of equal energies this makes em not equal without changing anything actually
    2891                                                 // 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
    2892                                                 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2893                                                 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    2894                                                 if (!InsertedElement.second) { // this root is already present
    2895                                                         if ((*PresentItem).second.second < FragOrder)   // if order there is lower, update entry with higher-order term
    2896                                                                 //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)
    2897                                                                 {       // if value is smaller, update value and order
    2898                                                                 (*PresentItem).second.first = fabs(Value);
    2899                                                                 (*PresentItem).second.second = FragOrder;
    2900                                                                 *out << Verbose(2) << "Updated element (" <<    (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2901                                                         } else {
    2902                                                                 *out << Verbose(2) << "Did not update element " <<      (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
    2903                                                         }
    2904                                                 } else {
    2905                                                         *out << Verbose(2) << "Inserted element (" <<   (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2906                                                 }
    2907                                         } else {
    2908                                                 *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
    2909                                         }
    2910                                 }
    2911                         }
    2912                         // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
    2913                         map<double, pair<int,int> > FinalRootCandidates;
    2914                         *out << Verbose(1) << "Root candidate list is: " << endl;
    2915                         for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
    2916                                 Walker = FindAtom((*runner).first);
    2917                                 if (Walker != NULL) {
    2918                                         //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
    2919                                         if (!Walker->MaxOrder) {
    2920                                                 *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
    2921                                                 FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
    2922                                         } else {
    2923                                                 *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
    2924                                         }
    2925                                 } else {
    2926                                         cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
    2927                                 }
    2928                         }
    2929                         // pick the ones still below threshold and mark as to be adaptively updated
    2930                         for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
    2931                                 No = (*runner).second.first;
    2932                                 Walker = FindAtom(No);
    2933                                 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2934                                         *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    2935                                         AtomMask[No] = true;
    2936                                         status = true;
    2937                                 //} else
    2938                                         //*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;
    2939                         }
    2940                         // close and done
    2941                         InputFile.close();
    2942                         InputFile.clear();
    2943                 } else {
    2944                         cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
    2945                         while (Walker->next != end) {
    2946                                 Walker = Walker->next;
    2947                 #ifdef ADDHYDROGEN
    2948                                 if (Walker->type->Z != 1) // skip hydrogen
    2949                 #endif
    2950                                 {
    2951                                         AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2952                                         status = true;
    2953                                 }
    2954                         }
    2955                 }
    2956                 Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
    2957                 // pick a given number of highest values and set AtomMask
    2958         } else { // global increase of Bond Order
    2959                 while (Walker->next != end) {
    2960                         Walker = Walker->next;
    2961         #ifdef ADDHYDROGEN
    2962                         if (Walker->type->Z != 1) // skip hydrogen
    2963         #endif
    2964                         {
    2965                                 AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2966                                 if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
    2967                                         status = true;
    2968                         }
    2969                 }
    2970                 if ((Order == 0) && (AtomMask[AtomCount] == false))     // single stepping, just check
    2971                         status = true;
    2972 
    2973                 if (!status) {
    2974                         if (Order == 0)
    2975                                 *out << Verbose(1) << "Single stepping done." << endl;
    2976                         else
    2977                                 *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
    2978                 }
    2979         }
    2980 
    2981         // print atom mask for debugging
    2982         *out << "                                                       ";
    2983         for(int i=0;i<AtomCount;i++)
    2984                 *out << (i % 10);
    2985         *out << endl << "Atom mask is: ";
    2986         for(int i=0;i<AtomCount;i++)
    2987                 *out << (AtomMask[i] ? "t" : "f");
    2988         *out << endl;
    2989 
    2990         return status;
     2837  atom *Walker = start;
     2838  bool status = false;
     2839  ifstream InputFile;
     2840
     2841  // initialize mask list
     2842  for(int i=AtomCount;i--;)
     2843    AtomMask[i] = false;
     2844
     2845  if (Order < 0) { // adaptive increase of BondOrder per site
     2846    if (AtomMask[AtomCount] == true)  // break after one step
     2847      return false;
     2848    // parse the EnergyPerFragment file
     2849    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
     2850    sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
     2851    InputFile.open(buffer, ios::in);
     2852    if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
     2853      // transmorph graph keyset list into indexed KeySetList
     2854      map<int,KeySet> IndexKeySetList;
     2855      for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
     2856        IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
     2857      }
     2858      int lines = 0;
     2859      // count the number of lines, i.e. the number of fragments
     2860      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2861      InputFile.getline(buffer, MAXSTRINGSIZE);
     2862      while(!InputFile.eof()) {
     2863        InputFile.getline(buffer, MAXSTRINGSIZE);
     2864        lines++;
     2865      }
     2866      //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;  // one endline too much
     2867      InputFile.clear();
     2868      InputFile.seekg(ios::beg);
     2869      map<int, pair<double,int> > AdaptiveCriteriaList;  // (Root No., (Value, Order)) !
     2870      int No, FragOrder;
     2871      double Value;
     2872      // each line represents a fragment root (Atom::nr) id and its energy contribution
     2873      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2874      InputFile.getline(buffer, MAXSTRINGSIZE);
     2875      while(!InputFile.eof()) {
     2876        InputFile.getline(buffer, MAXSTRINGSIZE);
     2877        if (strlen(buffer) > 2) {
     2878          //*out << Verbose(2) << "Scanning: " << buffer << endl;
     2879          stringstream line(buffer);
     2880          line >> FragOrder;
     2881          line >> ws >> No;
     2882          line >> ws >> Value; // skip time entry
     2883          line >> ws >> Value;
     2884          No -= 1;  // indices start at 1 in file, not 0
     2885          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
     2886
     2887          // clean the list of those entries that have been superceded by higher order terms already
     2888          map<int,KeySet>::iterator marker = IndexKeySetList.find(No);    // find keyset to Frag No.
     2889          if (marker != IndexKeySetList.end()) {  // if found
     2890            Value *= 1 + MYEPSILON*(*((*marker).second.begin()));    // in case of equal energies this makes em not equal without changing anything actually
     2891            // 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
     2892            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
     2893            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     2894            if (!InsertedElement.second) { // this root is already present
     2895              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
     2896                //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)
     2897                {  // if value is smaller, update value and order
     2898                (*PresentItem).second.first = fabs(Value);
     2899                (*PresentItem).second.second = FragOrder;
     2900                *out << Verbose(2) << "Updated element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2901              } else {
     2902                *out << Verbose(2) << "Did not update element " <<  (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
     2903              }
     2904            } else {
     2905              *out << Verbose(2) << "Inserted element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2906            }
     2907          } else {
     2908            *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
     2909          }
     2910        }
     2911      }
     2912      // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
     2913      map<double, pair<int,int> > FinalRootCandidates;
     2914      *out << Verbose(1) << "Root candidate list is: " << endl;
     2915      for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
     2916        Walker = FindAtom((*runner).first);
     2917        if (Walker != NULL) {
     2918          //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2919          if (!Walker->MaxOrder) {
     2920            *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
     2921            FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
     2922          } else {
     2923            *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
     2924          }
     2925        } else {
     2926          cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
     2927        }
     2928      }
     2929      // pick the ones still below threshold and mark as to be adaptively updated
     2930      for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
     2931        No = (*runner).second.first;
     2932        Walker = FindAtom(No);
     2933        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
     2934          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     2935          AtomMask[No] = true;
     2936          status = true;
     2937        //} else
     2938          //*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;
     2939      }
     2940      // close and done
     2941      InputFile.close();
     2942      InputFile.clear();
     2943    } else {
     2944      cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
     2945      while (Walker->next != end) {
     2946        Walker = Walker->next;
     2947    #ifdef ADDHYDROGEN
     2948        if (Walker->type->Z != 1) // skip hydrogen
     2949    #endif
     2950        {
     2951          AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2952          status = true;
     2953        }
     2954      }
     2955    }
     2956    Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
     2957    // pick a given number of highest values and set AtomMask
     2958  } else { // global increase of Bond Order
     2959    while (Walker->next != end) {
     2960      Walker = Walker->next;
     2961  #ifdef ADDHYDROGEN
     2962      if (Walker->type->Z != 1) // skip hydrogen
     2963  #endif
     2964      {
     2965        AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2966        if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
     2967          status = true;
     2968      }
     2969    }
     2970    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
     2971      status = true;
     2972
     2973    if (!status) {
     2974      if (Order == 0)
     2975        *out << Verbose(1) << "Single stepping done." << endl;
     2976      else
     2977        *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2978    }
     2979  }
     2980
     2981  // print atom mask for debugging
     2982  *out << "              ";
     2983  for(int i=0;i<AtomCount;i++)
     2984    *out << (i % 10);
     2985  *out << endl << "Atom mask is: ";
     2986  for(int i=0;i<AtomCount;i++)
     2987    *out << (AtomMask[i] ? "t" : "f");
     2988  *out << endl;
     2989
     2990  return status;
    29912991};
    29922992
     
    29982998bool molecule::CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex)
    29992999{
    3000         element *runner = elemente->start;
    3001         int AtomNo = 0;
    3002         atom *Walker = NULL;
    3003 
    3004         if (SortIndex != NULL) {
    3005                 *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
    3006                 return false;
    3007         }
    3008         SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
    3009         for(int i=AtomCount;i--;)
    3010                 SortIndex[i] = -1;
    3011         while (runner->next != elemente->end) { // go through every element
    3012                 runner = runner->next;
    3013                 if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    3014                         Walker = start;
    3015                         while (Walker->next != end) { // go through every atom of this element
    3016                                 Walker = Walker->next;
    3017                                 if (Walker->type->Z == runner->Z) // if this atom fits to element
    3018                                         SortIndex[Walker->nr] = AtomNo++;
    3019                         }
    3020                 }
    3021         }
    3022         return true;
     3000  element *runner = elemente->start;
     3001  int AtomNo = 0;
     3002  atom *Walker = NULL;
     3003
     3004  if (SortIndex != NULL) {
     3005    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     3006    return false;
     3007  }
     3008  SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
     3009  for(int i=AtomCount;i--;)
     3010    SortIndex[i] = -1;
     3011  while (runner->next != elemente->end) { // go through every element
     3012    runner = runner->next;
     3013    if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     3014      Walker = start;
     3015      while (Walker->next != end) { // go through every atom of this element
     3016        Walker = Walker->next;
     3017        if (Walker->type->Z == runner->Z) // if this atom fits to element
     3018          SortIndex[Walker->nr] = AtomNo++;
     3019      }
     3020    }
     3021  }
     3022  return true;
    30233023};
    30243024
     
    30293029y contribution", and that's why this consciously not done in the following loop)
    30303030 * -# in a loop over all subgraphs
    3031  *      -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
    3032  *      -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
     3031 *  -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
     3032 *  -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
    30333033 * -# combines the generated molecule lists from all subgraphs
    30343034 * -# saves to disk: fragment configs, adjacency, orderatsite, keyset files
     
    30433043int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
    30443044{
    3045         MoleculeListClass *BondFragments = NULL;
    3046         int *SortIndex = NULL;
    3047         int *MinimumRingSize = new int[AtomCount];
    3048         int FragmentCounter;
    3049         MoleculeLeafClass *MolecularWalker = NULL;
    3050         MoleculeLeafClass *Subgraphs = NULL;                    // list of subgraphs from DFS analysis
    3051         fstream File;
    3052         bool FragmentationToDo = true;
    3053         class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
    3054         bool CheckOrder = false;
    3055         Graph **FragmentList = NULL;
    3056         Graph *ParsedFragmentList = NULL;
    3057         Graph TotalGraph;                // graph with all keysets however local numbers
    3058         int TotalNumberOfKeySets = 0;
    3059         atom **ListOfAtoms = NULL;
    3060         atom ***ListOfLocalAtoms = NULL;
    3061         bool *AtomMask = NULL;
    3062 
    3063         *out << endl;
     3045  MoleculeListClass *BondFragments = NULL;
     3046  int *SortIndex = NULL;
     3047  int *MinimumRingSize = new int[AtomCount];
     3048  int FragmentCounter;
     3049  MoleculeLeafClass *MolecularWalker = NULL;
     3050  MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     3051  fstream File;
     3052  bool FragmentationToDo = true;
     3053  class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
     3054  bool CheckOrder = false;
     3055  Graph **FragmentList = NULL;
     3056  Graph *ParsedFragmentList = NULL;
     3057  Graph TotalGraph;    // graph with all keysets however local numbers
     3058  int TotalNumberOfKeySets = 0;
     3059  atom **ListOfAtoms = NULL;
     3060  atom ***ListOfLocalAtoms = NULL;
     3061  bool *AtomMask = NULL;
     3062
     3063  *out << endl;
    30643064#ifdef ADDHYDROGEN
    3065         *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
     3065  *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
    30663066#else
    3067         *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
     3067  *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
    30683068#endif
    30693069
    3070         // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3071 
    3072         // ===== 1. Check whether bond structure is same as stored in files ====
    3073 
    3074         // fill the adjacency list
    3075         CreateListOfBondsPerAtom(out);
    3076 
    3077         // create lookup table for Atom::nr
    3078         FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3079 
    3080         // === compare it with adjacency file ===
    3081         FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    3082         Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    3083 
    3084         // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    3085         Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    3086         // fill the bond structure of the individually stored subgraphs
    3087         Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);     // we want to keep the created ListOfLocalAtoms
    3088         // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
    3089         for(int i=AtomCount;i--;)
    3090                 MinimumRingSize[i] = AtomCount;
    3091         MolecularWalker = Subgraphs;
    3092         FragmentCounter = 0;
    3093         while (MolecularWalker->next != NULL) {
    3094                 MolecularWalker = MolecularWalker->next;
    3095                 LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    3096 //              // check the list of local atoms for debugging
    3097 //              *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
    3098 //              for (int i=0;i<AtomCount;i++)
    3099 //                      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
    3100 //                              *out << "\tNULL";
    3101 //                      else
    3102 //                              *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3103                 *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3104                 MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3105                 *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3106                 MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3107                 *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3108                 delete(LocalBackEdgeStack);
    3109         }
    3110 
    3111         // ===== 3. if structure still valid, parse key set file and others =====
    3112         FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
    3113 
    3114         // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    3115         FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3116 
    3117         // =================================== Begin of FRAGMENTATION ===============================
    3118         // ===== 6a. assign each keyset to its respective subgraph =====
    3119         Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    3120 
    3121         // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
    3122         KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
    3123         AtomMask = new bool[AtomCount+1];
    3124         AtomMask[AtomCount] = false;
    3125         FragmentationToDo = false;      // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
    3126         while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
    3127                 FragmentationToDo = FragmentationToDo || CheckOrder;
    3128                 AtomMask[AtomCount] = true;      // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3129                 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    3130                 Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    3131 
    3132                 // ===== 7. fill the bond fragment list =====
    3133                 FragmentCounter = 0;
    3134                 MolecularWalker = Subgraphs;
    3135                 while (MolecularWalker->next != NULL) {
    3136                         MolecularWalker = MolecularWalker->next;
    3137                         *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3138                         //MolecularWalker->Leaf->OutputListOfBonds(out);        // output ListOfBondsPerAtom for debugging
    3139                         if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3140                                 // call BOSSANOVA method
    3141                                 *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
    3142                                 MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
    3143                         } else {
    3144                                 cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
    3145                         }
    3146                         FragmentCounter++;      // next fragment list
    3147                 }
    3148         }
    3149         delete[](RootStack);
    3150         delete[](AtomMask);
    3151         delete(ParsedFragmentList);
    3152         delete[](MinimumRingSize);
    3153 
    3154 
    3155         // ==================================== End of FRAGMENTATION ============================================
    3156 
    3157         // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    3158         Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3159 
    3160         // free subgraph memory again
    3161         FragmentCounter = 0;
    3162         if (Subgraphs != NULL) {
    3163                 while (Subgraphs->next != NULL) {
    3164                         Subgraphs = Subgraphs->next;
    3165                         delete(FragmentList[FragmentCounter++]);
    3166                         delete(Subgraphs->previous);
    3167                 }
    3168                 delete(Subgraphs);
    3169         }
    3170         Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
    3171 
    3172         // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    3173         //if (FragmentationToDo) {              // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    3174                 // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3175                 BondFragments = new MoleculeListClass();
    3176                 int k=0;
    3177                 for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    3178                         KeySet test = (*runner).first;
    3179                         *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    3180                         BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
    3181                         k++;
    3182                 }
    3183                 *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    3184 
    3185                 // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3186                 if (BondFragments->ListOfMolecules.size() != 0) {
    3187                         // create the SortIndex from BFS labels to order in the config file
    3188                         CreateMappingLabelsToConfigSequence(out, SortIndex);
    3189 
    3190                         *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
    3191                         if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    3192                                 *out << Verbose(1) << "All configs written." << endl;
    3193                         else
    3194                                 *out << Verbose(1) << "Some config writing failed." << endl;
    3195 
    3196                         // store force index reference file
    3197                         BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3198 
    3199                         // store keysets file
    3200                         StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3201 
    3202                         // store Adjacency file
    3203                         StoreAdjacencyToFile(out, configuration->configpath);
    3204 
    3205                         // store Hydrogen saturation correction file
    3206                         BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3207 
    3208                         // store adaptive orders into file
    3209                         StoreOrderAtSiteFile(out, configuration->configpath);
    3210 
    3211                         // restore orbital and Stop values
    3212                         CalculateOrbitals(*configuration);
    3213 
    3214                         // free memory for bond part
    3215                         *out << Verbose(1) << "Freeing bond memory" << endl;
    3216                         delete(FragmentList); // remove bond molecule from memory
    3217                         Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    3218                 } else
    3219                         *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3220         //} else
    3221         //      *out << Verbose(1) << "No fragments to store." << endl;
    3222         *out << Verbose(0) << "End of bond fragmentation." << endl;
    3223 
    3224         return ((int)(!FragmentationToDo)+1);           // 1 - continue, 2 - stop (no fragmentation occured)
     3070  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
     3071
     3072  // ===== 1. Check whether bond structure is same as stored in files ====
     3073
     3074  // fill the adjacency list
     3075  CreateListOfBondsPerAtom(out);
     3076
     3077  // create lookup table for Atom::nr
     3078  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
     3079
     3080  // === compare it with adjacency file ===
     3081  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     3082  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
     3083
     3084  // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
     3085  Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     3086  // fill the bond structure of the individually stored subgraphs
     3087  Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     3088  // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
     3089  for(int i=AtomCount;i--;)
     3090    MinimumRingSize[i] = AtomCount;
     3091  MolecularWalker = Subgraphs;
     3092  FragmentCounter = 0;
     3093  while (MolecularWalker->next != NULL) {
     3094    MolecularWalker = MolecularWalker->next;
     3095    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     3096//    // check the list of local atoms for debugging
     3097//    *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
     3098//    for (int i=0;i<AtomCount;i++)
     3099//      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
     3100//        *out << "\tNULL";
     3101//      else
     3102//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3103    *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3104    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3105    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3106    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3107    *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3108    delete(LocalBackEdgeStack);
     3109  }
     3110
     3111  // ===== 3. if structure still valid, parse key set file and others =====
     3112  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     3113
     3114  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
     3115  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
     3116
     3117  // =================================== Begin of FRAGMENTATION ===============================
     3118  // ===== 6a. assign each keyset to its respective subgraph =====
     3119  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
     3120
     3121  // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
     3122  KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
     3123  AtomMask = new bool[AtomCount+1];
     3124  AtomMask[AtomCount] = false;
     3125  FragmentationToDo = false;  // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
     3126  while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
     3127    FragmentationToDo = FragmentationToDo || CheckOrder;
     3128    AtomMask[AtomCount] = true;  // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
     3129    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3130    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
     3131
     3132    // ===== 7. fill the bond fragment list =====
     3133    FragmentCounter = 0;
     3134    MolecularWalker = Subgraphs;
     3135    while (MolecularWalker->next != NULL) {
     3136      MolecularWalker = MolecularWalker->next;
     3137      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
     3138      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     3139      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3140        // call BOSSANOVA method
     3141        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     3142        MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
     3143      } else {
     3144        cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
     3145      }
     3146      FragmentCounter++;  // next fragment list
     3147    }
     3148  }
     3149  delete[](RootStack);
     3150  delete[](AtomMask);
     3151  delete(ParsedFragmentList);
     3152  delete[](MinimumRingSize);
     3153
     3154
     3155  // ==================================== End of FRAGMENTATION ============================================
     3156
     3157  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
     3158  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
     3159
     3160  // free subgraph memory again
     3161  FragmentCounter = 0;
     3162  if (Subgraphs != NULL) {
     3163    while (Subgraphs->next != NULL) {
     3164      Subgraphs = Subgraphs->next;
     3165      delete(FragmentList[FragmentCounter++]);
     3166      delete(Subgraphs->previous);
     3167    }
     3168    delete(Subgraphs);
     3169  }
     3170  Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
     3171
     3172  // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
     3173  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
     3174    // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     3175    BondFragments = new MoleculeListClass();
     3176    int k=0;
     3177    for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     3178      KeySet test = (*runner).first;
     3179      *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     3180      BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
     3181      k++;
     3182    }
     3183    *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
     3184
     3185    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     3186    if (BondFragments->ListOfMolecules.size() != 0) {
     3187      // create the SortIndex from BFS labels to order in the config file
     3188      CreateMappingLabelsToConfigSequence(out, SortIndex);
     3189
     3190      *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
     3191      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     3192        *out << Verbose(1) << "All configs written." << endl;
     3193      else
     3194        *out << Verbose(1) << "Some config writing failed." << endl;
     3195
     3196      // store force index reference file
     3197      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     3198
     3199      // store keysets file
     3200      StoreKeySetFile(out, TotalGraph, configuration->configpath);
     3201
     3202      // store Adjacency file
     3203      StoreAdjacencyToFile(out, configuration->configpath);
     3204
     3205      // store Hydrogen saturation correction file
     3206      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     3207
     3208      // store adaptive orders into file
     3209      StoreOrderAtSiteFile(out, configuration->configpath);
     3210
     3211      // restore orbital and Stop values
     3212      CalculateOrbitals(*configuration);
     3213
     3214      // free memory for bond part
     3215      *out << Verbose(1) << "Freeing bond memory" << endl;
     3216      delete(FragmentList); // remove bond molecule from memory
     3217      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3218    } else
     3219      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     3220  //} else
     3221  //  *out << Verbose(1) << "No fragments to store." << endl;
     3222  *out << Verbose(0) << "End of bond fragmentation." << endl;
     3223
     3224  return ((int)(!FragmentationToDo)+1);    // 1 - continue, 2 - stop (no fragmentation occured)
    32253225};
    32263226
     
    32353235bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
    32363236{
    3237         bool status = true;
    3238         if (ReferenceStack->IsEmpty()) {
    3239                 cerr << "ReferenceStack is empty!" << endl;
    3240                 return false;
    3241         }
    3242         bond *Binder = ReferenceStack->PopFirst();
    3243         bond *FirstBond = Binder;        // mark the first bond, so that we don't loop through the stack indefinitely
    3244         atom *Walker = NULL, *OtherAtom = NULL;
    3245         ReferenceStack->Push(Binder);
    3246 
    3247         do {    // go through all bonds and push local ones
    3248                 Walker = ListOfLocalAtoms[Binder->leftatom->nr];        // get one atom in the reference molecule
    3249                 if (Walker != NULL) // if this Walker exists in the subgraph ...
    3250                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {           // go through the local list of bonds
    3251                                 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3252                                 if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3253                                         LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3254                                         *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3255                                         break;
    3256                                 }
    3257                         }
    3258                 Binder = ReferenceStack->PopFirst();    // loop the stack for next item
    3259                 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    3260                 ReferenceStack->Push(Binder);
    3261         } while (FirstBond != Binder);
    3262 
    3263         return status;
     3237  bool status = true;
     3238  if (ReferenceStack->IsEmpty()) {
     3239    cerr << "ReferenceStack is empty!" << endl;
     3240    return false;
     3241  }
     3242  bond *Binder = ReferenceStack->PopFirst();
     3243  bond *FirstBond = Binder;  // mark the first bond, so that we don't loop through the stack indefinitely
     3244  atom *Walker = NULL, *OtherAtom = NULL;
     3245  ReferenceStack->Push(Binder);
     3246
     3247  do {  // go through all bonds and push local ones
     3248    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     3249    if (Walker != NULL) // if this Walker exists in the subgraph ...
     3250      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3251        OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3252        if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3253          LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3254          *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
     3255          break;
     3256        }
     3257      }
     3258    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3259    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
     3260    ReferenceStack->Push(Binder);
     3261  } while (FirstBond != Binder);
     3262
     3263  return status;
    32643264};
    32653265
     
    32723272bool molecule::StoreOrderAtSiteFile(ofstream *out, char *path)
    32733273{
    3274         stringstream line;
    3275         ofstream file;
    3276 
    3277         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3278         file.open(line.str().c_str());
    3279         *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
    3280         if (file != NULL) {
    3281                 atom *Walker = start;
    3282                 while (Walker->next != end) {
    3283                         Walker = Walker->next;
    3284                         file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
    3285                         *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    3286                 }
    3287                 file.close();
    3288                 *out << Verbose(1) << "done." << endl;
    3289                 return true;
    3290         } else {
    3291                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3292                 return false;
    3293         }
     3274  stringstream line;
     3275  ofstream file;
     3276
     3277  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3278  file.open(line.str().c_str());
     3279  *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
     3280  if (file != NULL) {
     3281    atom *Walker = start;
     3282    while (Walker->next != end) {
     3283      Walker = Walker->next;
     3284      file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
     3285      *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
     3286    }
     3287    file.close();
     3288    *out << Verbose(1) << "done." << endl;
     3289    return true;
     3290  } else {
     3291    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3292    return false;
     3293  }
    32943294};
    32953295
     
    33033303bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path)
    33043304{
    3305         unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3306         bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3307         bool status;
    3308         int AtomNr, value;
    3309         stringstream line;
    3310         ifstream file;
    3311 
    3312         *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
    3313         for(int i=AtomCount;i--;)
    3314                 OrderArray[i] = 0;
    3315         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3316         file.open(line.str().c_str());
    3317         if (file != NULL) {
    3318                 for (int i=AtomCount;i--;) { // initialise with 0
    3319                         OrderArray[i] = 0;
    3320                         MaxArray[i] = 0;
    3321                 }
    3322                 while (!file.eof()) { // parse from file
    3323                         AtomNr = -1;
    3324                         file >> AtomNr;
    3325                         if (AtomNr != -1) {      // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
    3326                                 file >> value;
    3327                                 OrderArray[AtomNr] = value;
    3328                                 file >> value;
    3329                                 MaxArray[AtomNr] = value;
    3330                                 //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
    3331                         }
    3332                 }
    3333                 atom *Walker = start;
    3334                 while (Walker->next != end) { // fill into atom classes
    3335                         Walker = Walker->next;
    3336                         Walker->AdaptiveOrder = OrderArray[Walker->nr];
    3337                         Walker->MaxOrder = MaxArray[Walker->nr];
    3338                         *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    3339                 }
    3340                 file.close();
    3341                 *out << Verbose(1) << "done." << endl;
    3342                 status = true;
    3343         } else {
    3344                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3345                 status = false;
    3346         }
    3347         Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3348         Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3349 
    3350         *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    3351         return status;
     3305  unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3306  bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3307  bool status;
     3308  int AtomNr, value;
     3309  stringstream line;
     3310  ifstream file;
     3311
     3312  *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
     3313  for(int i=AtomCount;i--;)
     3314    OrderArray[i] = 0;
     3315  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3316  file.open(line.str().c_str());
     3317  if (file != NULL) {
     3318    for (int i=AtomCount;i--;) { // initialise with 0
     3319      OrderArray[i] = 0;
     3320      MaxArray[i] = 0;
     3321    }
     3322    while (!file.eof()) { // parse from file
     3323      AtomNr = -1;
     3324      file >> AtomNr;
     3325      if (AtomNr != -1) {  // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
     3326        file >> value;
     3327        OrderArray[AtomNr] = value;
     3328        file >> value;
     3329        MaxArray[AtomNr] = value;
     3330        //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
     3331      }
     3332    }
     3333    atom *Walker = start;
     3334    while (Walker->next != end) { // fill into atom classes
     3335      Walker = Walker->next;
     3336      Walker->AdaptiveOrder = OrderArray[Walker->nr];
     3337      Walker->MaxOrder = MaxArray[Walker->nr];
     3338      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3339    }
     3340    file.close();
     3341    *out << Verbose(1) << "done." << endl;
     3342    status = true;
     3343  } else {
     3344    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3345    status = false;
     3346  }
     3347  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3348  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3349
     3350  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
     3351  return status;
    33523352};
    33533353
     
    33603360void molecule::CreateListOfBondsPerAtom(ofstream *out)
    33613361{
    3362         bond *Binder = NULL;
    3363         atom *Walker = NULL;
    3364         int TotalDegree;
    3365         *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    3366 
    3367         // re-allocate memory
    3368         *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    3369         if (ListOfBondsPerAtom != NULL) {
    3370                 for(int i=AtomCount;i--;)
    3371                         Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
    3372                 Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
    3373         }
    3374         if (NumberOfBondsPerAtom != NULL)
    3375                 Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
    3376         ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    3377         NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    3378 
    3379         // reset bond counts per atom
    3380         for(int i=AtomCount;i--;)
    3381                 NumberOfBondsPerAtom[i] = 0;
    3382         // count bonds per atom
    3383         Binder = first;
    3384         while (Binder->next != last) {
    3385                 Binder = Binder->next;
    3386                 NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    3387                 NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    3388         }
    3389         for(int i=AtomCount;i--;) {
    3390                 // allocate list of bonds per atom
    3391                 ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    3392                 // clear the list again, now each NumberOfBondsPerAtom marks current free field
    3393                 NumberOfBondsPerAtom[i] = 0;
    3394         }
    3395         // fill the list
    3396         Binder = first;
    3397         while (Binder->next != last) {
    3398                 Binder = Binder->next;
    3399                 ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    3400                 ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    3401         }
    3402 
    3403         // output list for debugging
    3404         *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    3405         Walker = start;
    3406         while (Walker->next != end) {
    3407                 Walker = Walker->next;
    3408                 *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    3409                 TotalDegree = 0;
    3410                 for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    3411                         *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
    3412                         TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    3413                 }
    3414                 *out << " -- TotalDegree: " << TotalDegree << endl;
    3415         }
    3416         *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
     3362  bond *Binder = NULL;
     3363  atom *Walker = NULL;
     3364  int TotalDegree;
     3365  *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
     3366
     3367  // re-allocate memory
     3368  *out << Verbose(2) << "(Re-)Allocating memory." << endl;
     3369  if (ListOfBondsPerAtom != NULL) {
     3370    for(int i=AtomCount;i--;)
     3371      Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
     3372    Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
     3373  }
     3374  if (NumberOfBondsPerAtom != NULL)
     3375    Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
     3376  ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
     3377  NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
     3378
     3379  // reset bond counts per atom
     3380  for(int i=AtomCount;i--;)
     3381    NumberOfBondsPerAtom[i] = 0;
     3382  // count bonds per atom
     3383  Binder = first;
     3384  while (Binder->next != last) {
     3385    Binder = Binder->next;
     3386    NumberOfBondsPerAtom[Binder->leftatom->nr]++;
     3387    NumberOfBondsPerAtom[Binder->rightatom->nr]++;
     3388  }
     3389  for(int i=AtomCount;i--;) {
     3390    // allocate list of bonds per atom
     3391    ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
     3392    // clear the list again, now each NumberOfBondsPerAtom marks current free field
     3393    NumberOfBondsPerAtom[i] = 0;
     3394  }
     3395  // fill the list
     3396  Binder = first;
     3397  while (Binder->next != last) {
     3398    Binder = Binder->next;
     3399    ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
     3400    ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
     3401  }
     3402
     3403  // output list for debugging
     3404  *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
     3405  Walker = start;
     3406  while (Walker->next != end) {
     3407    Walker = Walker->next;
     3408    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
     3409    TotalDegree = 0;
     3410    for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     3411      *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
     3412      TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     3413    }
     3414    *out << " -- TotalDegree: " << TotalDegree << endl;
     3415  }
     3416  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    34173417};
    34183418
     
    34313431void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    34323432{
    3433         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3434         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
    3435         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
    3436         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    3437         atom *Walker = NULL, *OtherAtom = NULL;
    3438         bond *Binder = NULL;
    3439 
    3440         // add Root if not done yet
    3441         AtomStack->ClearStack();
    3442         if (AddedAtomList[Root->nr] == NULL)    // add Root if not yet present
    3443                 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
    3444         AtomStack->Push(Root);
    3445 
    3446         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    3447         for (int i=AtomCount;i--;) {
    3448                 PredecessorList[i] = NULL;
    3449                 ShortestPathList[i] = -1;
    3450                 if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
    3451                         ColorList[i] = lightgray;
    3452                 else
    3453                         ColorList[i] = white;
    3454         }
    3455         ShortestPathList[Root->nr] = 0;
    3456 
    3457         // and go on ... Queue always contains all lightgray vertices
    3458         while (!AtomStack->IsEmpty()) {
    3459                 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
    3460                 // 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
    3461                 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
    3462                 // followed by n+1 till top of stack.
    3463                 Walker = AtomStack->PopFirst(); // pop oldest added
    3464                 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    3465                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    3466                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    3467                         if (Binder != NULL) { // don't look at bond equal NULL
    3468                                 OtherAtom = Binder->GetOtherAtom(Walker);
    3469                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    3470                                 if (ColorList[OtherAtom->nr] == white) {
    3471                                         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)
    3472                                                 ColorList[OtherAtom->nr] = lightgray;
    3473                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    3474                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3475                                         *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;
    3476                                         if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    3477                                                 *out << Verbose(3);
    3478                                                 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    3479                                                         AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    3480                                                         *out << "Added OtherAtom " << OtherAtom->Name;
    3481                                                         AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3482                                                         AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3483                                                         AddedBondList[Binder->nr]->Type = Binder->Type;
    3484                                                         *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
    3485                                                 } 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)
    3486                                                         *out << "Not adding OtherAtom " << OtherAtom->Name;
    3487                                                         if (AddedBondList[Binder->nr] == NULL) {
    3488                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3489                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3490                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3491                                                                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
    3492                                                         } else
    3493                                                                 *out << ", not added Bond ";
    3494                                                 }
    3495                                                 *out << ", putting OtherAtom into queue." << endl;
    3496                                                 AtomStack->Push(OtherAtom);
    3497                                         } else { // out of bond order, then replace
    3498                                                 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
    3499                                                         ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    3500                                                 if (Binder == Bond)
    3501                                                         *out << Verbose(3) << "Not Queueing, is the Root bond";
    3502                                                 else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    3503                                                         *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    3504                                                 if (!Binder->Cyclic)
    3505                                                         *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    3506                                                 if (AddedBondList[Binder->nr] == NULL) {
    3507                                                         if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    3508                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3509                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3510                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3511                                                         } else {
     3433  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3434  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
     3435  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
     3436  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     3437  atom *Walker = NULL, *OtherAtom = NULL;
     3438  bond *Binder = NULL;
     3439
     3440  // add Root if not done yet
     3441  AtomStack->ClearStack();
     3442  if (AddedAtomList[Root->nr] == NULL)  // add Root if not yet present
     3443    AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
     3444  AtomStack->Push(Root);
     3445
     3446  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     3447  for (int i=AtomCount;i--;) {
     3448    PredecessorList[i] = NULL;
     3449    ShortestPathList[i] = -1;
     3450    if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
     3451      ColorList[i] = lightgray;
     3452    else
     3453      ColorList[i] = white;
     3454  }
     3455  ShortestPathList[Root->nr] = 0;
     3456
     3457  // and go on ... Queue always contains all lightgray vertices
     3458  while (!AtomStack->IsEmpty()) {
     3459    // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
     3460    // 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
     3461    // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
     3462    // followed by n+1 till top of stack.
     3463    Walker = AtomStack->PopFirst(); // pop oldest added
     3464    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3465    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     3466      Binder = ListOfBondsPerAtom[Walker->nr][i];
     3467      if (Binder != NULL) { // don't look at bond equal NULL
     3468        OtherAtom = Binder->GetOtherAtom(Walker);
     3469        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     3470        if (ColorList[OtherAtom->nr] == white) {
     3471          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)
     3472            ColorList[OtherAtom->nr] = lightgray;
     3473          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     3474          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     3475          *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;
     3476          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
     3477            *out << Verbose(3);
     3478            if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
     3479              AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
     3480              *out << "Added OtherAtom " << OtherAtom->Name;
     3481              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3482              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3483              AddedBondList[Binder->nr]->Type = Binder->Type;
     3484              *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     3485            } 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)
     3486              *out << "Not adding OtherAtom " << OtherAtom->Name;
     3487              if (AddedBondList[Binder->nr] == NULL) {
     3488                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3489                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3490                AddedBondList[Binder->nr]->Type = Binder->Type;
     3491                *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     3492              } else
     3493                *out << ", not added Bond ";
     3494            }
     3495            *out << ", putting OtherAtom into queue." << endl;
     3496            AtomStack->Push(OtherAtom);
     3497          } else { // out of bond order, then replace
     3498            if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     3499              ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
     3500            if (Binder == Bond)
     3501              *out << Verbose(3) << "Not Queueing, is the Root bond";
     3502            else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
     3503              *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
     3504            if (!Binder->Cyclic)
     3505              *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
     3506            if (AddedBondList[Binder->nr] == NULL) {
     3507              if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
     3508                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3509                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3510                AddedBondList[Binder->nr]->Type = Binder->Type;
     3511              } else {
    35123512#ifdef ADDHYDROGEN
    3513                                                                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3514                                                                         exit(1);
     3513                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3514                  exit(1);
    35153515#endif
    3516                                                         }
    3517                                                 }
    3518                                         }
    3519                                 } else {
    3520                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    3521                                         // This has to be a cyclic bond, check whether it's present ...
    3522                                         if (AddedBondList[Binder->nr] == NULL) {
    3523                                                 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    3524                                                         AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3525                                                         AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3526                                                         AddedBondList[Binder->nr]->Type = Binder->Type;
    3527                                                 } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
     3516              }
     3517            }
     3518          }
     3519        } else {
     3520          *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     3521          // This has to be a cyclic bond, check whether it's present ...
     3522          if (AddedBondList[Binder->nr] == NULL) {
     3523            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     3524              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3525              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3526              AddedBondList[Binder->nr]->Type = Binder->Type;
     3527            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    35283528#ifdef ADDHYDROGEN
    3529                                                         if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3530                                                                 exit(1);
     3529              if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3530                exit(1);
    35313531#endif
    3532                                                 }
    3533                                         }
    3534                                 }
    3535                         }
    3536                 }
    3537                 ColorList[Walker->nr] = black;
    3538                 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    3539         }
    3540         Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3541         Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
    3542         Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
    3543         delete(AtomStack);
     3532            }
     3533          }
     3534        }
     3535      }
     3536    }
     3537    ColorList[Walker->nr] = black;
     3538    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3539  }
     3540  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3541  Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
     3542  Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
     3543  delete(AtomStack);
    35443544};
    35453545
     
    35553555bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
    35563556{
    3557         atom *Walker = NULL, *OtherAtom = NULL;
    3558         bool status = true;
    3559         atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
    3560 
    3561         *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3562 
    3563         // reset parent list
    3564         *out << Verbose(3) << "Resetting ParentList." << endl;
    3565         for (int i=Father->AtomCount;i--;)
    3566                 ParentList[i] = NULL;
    3567 
    3568         // fill parent list with sons
    3569         *out << Verbose(3) << "Filling Parent List." << endl;
    3570         Walker = start;
    3571         while (Walker->next != end) {
    3572                 Walker = Walker->next;
    3573                 ParentList[Walker->father->nr] = Walker;
    3574                 // Outputting List for debugging
    3575                 *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<        " is " << ParentList[Walker->father->nr] << "." << endl;
    3576         }
    3577 
    3578         // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
    3579         *out << Verbose(3) << "Creating bonds." << endl;
    3580         Walker = Father->start;
    3581         while (Walker->next != Father->end) {
    3582                 Walker = Walker->next;
    3583                 if (ParentList[Walker->nr] != NULL) {
    3584                         if (ParentList[Walker->nr]->father != Walker) {
    3585                                 status = false;
    3586                         } else {
    3587                                 for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    3588                                         OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3589                                         if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    3590                                                 *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    3591                                                 AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
    3592                                         }
    3593                                 }
    3594                         }
    3595                 }
    3596         }
    3597 
    3598         Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
    3599         *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
    3600         return status;
     3557  atom *Walker = NULL, *OtherAtom = NULL;
     3558  bool status = true;
     3559  atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
     3560
     3561  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
     3562
     3563  // reset parent list
     3564  *out << Verbose(3) << "Resetting ParentList." << endl;
     3565  for (int i=Father->AtomCount;i--;)
     3566    ParentList[i] = NULL;
     3567
     3568  // fill parent list with sons
     3569  *out << Verbose(3) << "Filling Parent List." << endl;
     3570  Walker = start;
     3571  while (Walker->next != end) {
     3572    Walker = Walker->next;
     3573    ParentList[Walker->father->nr] = Walker;
     3574    // Outputting List for debugging
     3575    *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<  " is " << ParentList[Walker->father->nr] << "." << endl;
     3576  }
     3577
     3578  // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
     3579  *out << Verbose(3) << "Creating bonds." << endl;
     3580  Walker = Father->start;
     3581  while (Walker->next != Father->end) {
     3582    Walker = Walker->next;
     3583    if (ParentList[Walker->nr] != NULL) {
     3584      if (ParentList[Walker->nr]->father != Walker) {
     3585        status = false;
     3586      } else {
     3587        for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
     3588          OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3589          if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
     3590            *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     3591            AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     3592          }
     3593        }
     3594      }
     3595    }
     3596  }
     3597
     3598  Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
     3599  *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
     3600  return status;
    36013601};
    36023602
     
    36103610int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
    36113611{
    3612         atom *Runner = NULL;
    3613         int SP, Removal;
    3614 
    3615         *out << Verbose(2) << "Looking for removal candidate." << endl;
    3616         SP = -1; //0;   // not -1, so that Root is never removed
    3617         Removal = -1;
    3618         for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
    3619                 Runner = FindAtom((*runner));
    3620                 if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
    3621                         if (ShortestPathList[(*runner)] > SP) { // remove the oldest one with longest shortest path
    3622                                 SP = ShortestPathList[(*runner)];
    3623                                 Removal = (*runner);
    3624                         }
    3625                 }
    3626         }
    3627         return Removal;
     3612  atom *Runner = NULL;
     3613  int SP, Removal;
     3614
     3615  *out << Verbose(2) << "Looking for removal candidate." << endl;
     3616  SP = -1; //0;  // not -1, so that Root is never removed
     3617  Removal = -1;
     3618  for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
     3619    Runner = FindAtom((*runner));
     3620    if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
     3621      if (ShortestPathList[(*runner)] > SP) {  // remove the oldest one with longest shortest path
     3622        SP = ShortestPathList[(*runner)];
     3623        Removal = (*runner);
     3624      }
     3625    }
     3626  }
     3627  return Removal;
    36283628};
    36293629
     
    36383638molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem)
    36393639{
    3640         atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
    3641         atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
    3642         molecule *Leaf = new molecule(elemente);
    3643         bool LonelyFlag = false;
    3644         int size;
    3645 
    3646 //      *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3647 
    3648         Leaf->BondDistance = BondDistance;
    3649         for(int i=NDIM*2;i--;)
    3650                 Leaf->cell_size[i] = cell_size[i];
    3651 
    3652         // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
    3653         for(int i=AtomCount;i--;)
    3654                 SonList[i] = NULL;
    3655 
    3656         // first create the minimal set of atoms from the KeySet
    3657         size = 0;
    3658         for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
    3659                 FatherOfRunner = FindAtom((*runner));   // find the id
    3660                 SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
    3661                 size++;
    3662         }
    3663 
    3664         // create the bonds between all: Make it an induced subgraph and add hydrogen
    3665 //      *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
    3666         Runner = Leaf->start;
    3667         while (Runner->next != Leaf->end) {
    3668                 Runner = Runner->next;
    3669                 LonelyFlag = true;
    3670                 FatherOfRunner = Runner->father;
    3671                 if (SonList[FatherOfRunner->nr] != NULL)        {       // check if this, our father, is present in list
    3672                         // create all bonds
    3673                         for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    3674                                 OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    3675 //                              *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    3676                                 if (SonList[OtherFather->nr] != NULL) {
    3677 //                                      *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    3678                                         if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    3679 //                                              *out << Verbose(3) << "Adding Bond: ";
    3680 //                                              *out <<
    3681                                                 Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    3682 //                                              *out << "." << endl;
    3683                                                 //NumBonds[Runner->nr]++;
    3684                                         } else {
    3685 //                                              *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    3686                                         }
    3687                                         LonelyFlag = false;
    3688                                 } else {
    3689 //                                      *out << ", who has no son in this fragment molecule." << endl;
     3640  atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
     3641  atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
     3642  molecule *Leaf = new molecule(elemente);
     3643  bool LonelyFlag = false;
     3644  int size;
     3645
     3646//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
     3647
     3648  Leaf->BondDistance = BondDistance;
     3649  for(int i=NDIM*2;i--;)
     3650    Leaf->cell_size[i] = cell_size[i];
     3651
     3652  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     3653  for(int i=AtomCount;i--;)
     3654    SonList[i] = NULL;
     3655
     3656  // first create the minimal set of atoms from the KeySet
     3657  size = 0;
     3658  for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
     3659    FatherOfRunner = FindAtom((*runner));  // find the id
     3660    SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
     3661    size++;
     3662  }
     3663
     3664  // create the bonds between all: Make it an induced subgraph and add hydrogen
     3665//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     3666  Runner = Leaf->start;
     3667  while (Runner->next != Leaf->end) {
     3668    Runner = Runner->next;
     3669    LonelyFlag = true;
     3670    FatherOfRunner = Runner->father;
     3671    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
     3672      // create all bonds
     3673      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3674        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     3675//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
     3676        if (SonList[OtherFather->nr] != NULL) {
     3677//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     3678          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
     3679//            *out << Verbose(3) << "Adding Bond: ";
     3680//            *out <<
     3681            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     3682//            *out << "." << endl;
     3683            //NumBonds[Runner->nr]++;
     3684          } else {
     3685//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
     3686          }
     3687          LonelyFlag = false;
     3688        } else {
     3689//          *out << ", who has no son in this fragment molecule." << endl;
    36903690#ifdef ADDHYDROGEN
    3691                                         //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    3692                                         if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    3693                                                 exit(1);
     3691          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
     3692          if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     3693            exit(1);
    36943694#endif
    3695                                         //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
    3696                                 }
    3697                         }
    3698                 } else {
    3699                         *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
    3700                 }
    3701                 if ((LonelyFlag) && (size > 1)) {
    3702                         *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
    3703                 }
     3695          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     3696        }
     3697      }
     3698    } else {
     3699      *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
     3700    }
     3701    if ((LonelyFlag) && (size > 1)) {
     3702      *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
     3703    }
    37043704#ifdef ADDHYDROGEN
    3705                 while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    3706                         Runner = Runner->next;
     3705    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
     3706      Runner = Runner->next;
    37073707#endif
    3708         }
    3709         Leaf->CreateListOfBondsPerAtom(out);
    3710         //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    3711         Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
    3712 //      *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
    3713         return Leaf;
     3708  }
     3709  Leaf->CreateListOfBondsPerAtom(out);
     3710  //Leaflet->Leaf->ScanForPeriodicCorrection(out);
     3711  Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
     3712//  *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
     3713  return Leaf;
    37143714};
    37153715
     
    37173717 */
    37183718struct UniqueFragments {
    3719         config *configuration;
    3720         atom *Root;
    3721         Graph *Leaflet;
    3722         KeySet *FragmentSet;
    3723         int ANOVAOrder;
    3724         int FragmentCounter;
    3725         int CurrentIndex;
    3726         double TEFactor;
    3727         int *ShortestPathList;
    3728         bool **UsedList;
    3729         bond **BondsPerSPList;
    3730         int *BondsPerSPCount;
     3719  config *configuration;
     3720  atom *Root;
     3721  Graph *Leaflet;
     3722  KeySet *FragmentSet;
     3723  int ANOVAOrder;
     3724  int FragmentCounter;
     3725  int CurrentIndex;
     3726  double TEFactor;
     3727  int *ShortestPathList;
     3728  bool **UsedList;
     3729  bond **BondsPerSPList;
     3730  int *BondsPerSPCount;
    37313731};
    37323732
    37333733/** From a given set of Bond sorted by Shortest Path distance, create all possible fragments of size \a SetDimension.
    37343734 * -# loops over every possible combination (2^dimension of edge set)
    3735  *      -# inserts current set, if there's still space left
    3736  *              -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
     3735 *  -# inserts current set, if there's still space left
     3736 *    -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
    37373737ance+1
    3738  *              -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
    3739  *      -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
     3738 *    -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
     3739 *  -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
    37403740distance) and current set
    37413741 * \param *out output stream for debugging
     
    37473747void molecule::SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder)
    37483748{
    3749         atom *OtherWalker = NULL;
    3750         int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
    3751         int NumCombinations;
    3752         bool bit;
    3753         int bits, TouchedIndex, SubSetDimension, SP, Added;
    3754         int Removal;
    3755         int SpaceLeft;
    3756         int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
    3757         bond *Binder = NULL;
    3758         bond **BondsList = NULL;
    3759         KeySetTestPair TestKeySetInsert;
    3760 
    3761         NumCombinations = 1 << SetDimension;
    3762 
    3763         // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    3764         // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    3765         // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3766 
    3767         *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    3768         *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;
    3769 
    3770         // initialised touched list (stores added atoms on this level)
    3771         *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    3772         for (TouchedIndex=SubOrder+1;TouchedIndex--;)   // empty touched list
    3773                 TouchedList[TouchedIndex] = -1;
    3774         TouchedIndex = 0;
    3775 
    3776         // create every possible combination of the endpieces
    3777         *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
    3778         for (int i=1;i<NumCombinations;i++) {   // sweep through all power set combinations (skip empty set!)
    3779                 // count the set bit of i
    3780                 bits = 0;
    3781                 for (int j=SetDimension;j--;)
    3782                         bits += (i & (1 << j)) >> j;
    3783 
    3784                 *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    3785                 if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
    3786                         // --1-- add this set of the power set of bond partners to the snake stack
    3787                         Added = 0;
    3788                         for (int j=0;j<SetDimension;j++) {      // pull out every bit by shifting
    3789                                 bit = ((i & (1 << j)) != 0);    // mask the bit for the j-th bond
    3790                                 if (bit) {      // if bit is set, we add this bond partner
    3791                                         OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    3792                                         //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    3793                                         *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3794                                         TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    3795                                         if (TestKeySetInsert.second) {
    3796                                                 TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
    3797                                                 Added++;
    3798                                         } else {
    3799                                                 *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
    3800                                         }
    3801                                                 //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
    3802                                         //}
    3803                                 } else {
    3804                                         *out << Verbose(2+verbosity) << "Not adding." << endl;
    3805                                 }
    3806                         }
    3807 
    3808                         SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    3809                         if (SpaceLeft > 0) {
    3810                                 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
    3811                                 if (SubOrder > 1) {             // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
    3812                                         // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
    3813                                         SP = RootDistance+1;    // this is the next level
    3814                                         // first count the members in the subset
    3815                                         SubSetDimension = 0;
    3816                                         Binder = FragmentSearch->BondsPerSPList[2*SP];          // start node for this level
    3817                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {                // compare to end node of this level
    3818                                                 Binder = Binder->next;
    3819                                                 for (int k=TouchedIndex;k--;) {
    3820                                                         if (Binder->Contains(TouchedList[k]))    // if we added this very endpiece
    3821                                                                 SubSetDimension++;
    3822                                                 }
    3823                                         }
    3824                                         // then allocate and fill the list
    3825                                         BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
    3826                                         SubSetDimension = 0;
    3827                                         Binder = FragmentSearch->BondsPerSPList[2*SP];
    3828                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
    3829                                                 Binder = Binder->next;
    3830                                                 for (int k=0;k<TouchedIndex;k++) {
    3831                                                         if (Binder->leftatom->nr == TouchedList[k])      // leftatom is always the close one
    3832                                                                 BondsList[SubSetDimension++] = Binder;
    3833                                                 }
    3834                                         }
    3835                                         *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3836                                         SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    3837                                         Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    3838                                 }
    3839                         } else {
    3840                                 // --2-- otherwise store the complete fragment
    3841                                 *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
    3842                                 // store fragment as a KeySet
    3843                                 *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    3844                                 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3845                                         *out << (*runner) << " ";
    3846                                 *out << endl;
    3847                                 //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
    3848                                         //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
    3849                                 InsertFragmentIntoGraph(out, FragmentSearch);
    3850                                 //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
    3851                                 //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    3852                         }
    3853 
    3854                         // --3-- remove all added items in this level from snake stack
    3855                         *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
    3856                         for(int j=0;j<TouchedIndex;j++) {
    3857                                 Removal = TouchedList[j];
    3858                                 *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
    3859                                 FragmentSearch->FragmentSet->erase(Removal);
    3860                                 TouchedList[j] = -1;
    3861                         }
    3862                         *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    3863                         for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3864                                 *out << (*runner) << " ";
    3865                         *out << endl;
    3866                         TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
    3867                 } else {
    3868                         *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
    3869                 }
    3870         }
    3871         Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    3872         *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
     3749  atom *OtherWalker = NULL;
     3750  int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
     3751  int NumCombinations;
     3752  bool bit;
     3753  int bits, TouchedIndex, SubSetDimension, SP, Added;
     3754  int Removal;
     3755  int SpaceLeft;
     3756  int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
     3757  bond *Binder = NULL;
     3758  bond **BondsList = NULL;
     3759  KeySetTestPair TestKeySetInsert;
     3760
     3761  NumCombinations = 1 << SetDimension;
     3762
     3763  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
     3764  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
     3765  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
     3766
     3767  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     3768  *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;
     3769
     3770  // initialised touched list (stores added atoms on this level)
     3771  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
     3772  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
     3773    TouchedList[TouchedIndex] = -1;
     3774  TouchedIndex = 0;
     3775
     3776  // create every possible combination of the endpieces
     3777  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     3778  for (int i=1;i<NumCombinations;i++) {  // sweep through all power set combinations (skip empty set!)
     3779    // count the set bit of i
     3780    bits = 0;
     3781    for (int j=SetDimension;j--;)
     3782      bits += (i & (1 << j)) >> j;
     3783
     3784    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
     3785    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     3786      // --1-- add this set of the power set of bond partners to the snake stack
     3787      Added = 0;
     3788      for (int j=0;j<SetDimension;j++) {  // pull out every bit by shifting
     3789        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
     3790        if (bit) {  // if bit is set, we add this bond partner
     3791          OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
     3792          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
     3793          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
     3794          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     3795          if (TestKeySetInsert.second) {
     3796            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     3797            Added++;
     3798          } else {
     3799            *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
     3800          }
     3801            //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
     3802          //}
     3803        } else {
     3804          *out << Verbose(2+verbosity) << "Not adding." << endl;
     3805        }
     3806      }
     3807
     3808      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     3809      if (SpaceLeft > 0) {
     3810        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     3811        if (SubOrder > 1) {    // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
     3812          // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
     3813          SP = RootDistance+1;  // this is the next level
     3814          // first count the members in the subset
     3815          SubSetDimension = 0;
     3816          Binder = FragmentSearch->BondsPerSPList[2*SP];    // start node for this level
     3817          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {    // compare to end node of this level
     3818            Binder = Binder->next;
     3819            for (int k=TouchedIndex;k--;) {
     3820              if (Binder->Contains(TouchedList[k]))  // if we added this very endpiece
     3821                SubSetDimension++;
     3822            }
     3823          }
     3824          // then allocate and fill the list
     3825          BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
     3826          SubSetDimension = 0;
     3827          Binder = FragmentSearch->BondsPerSPList[2*SP];
     3828          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
     3829            Binder = Binder->next;
     3830            for (int k=0;k<TouchedIndex;k++) {
     3831              if (Binder->leftatom->nr == TouchedList[k])  // leftatom is always the close one
     3832                BondsList[SubSetDimension++] = Binder;
     3833            }
     3834          }
     3835          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
     3836          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     3837          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
     3838        }
     3839      } else {
     3840        // --2-- otherwise store the complete fragment
     3841        *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
     3842        // store fragment as a KeySet
     3843        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
     3844        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3845          *out << (*runner) << " ";
     3846        *out << endl;
     3847        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     3848          //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
     3849        InsertFragmentIntoGraph(out, FragmentSearch);
     3850        //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
     3851        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
     3852      }
     3853
     3854      // --3-- remove all added items in this level from snake stack
     3855      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     3856      for(int j=0;j<TouchedIndex;j++) {
     3857        Removal = TouchedList[j];
     3858        *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
     3859        FragmentSearch->FragmentSet->erase(Removal);
     3860        TouchedList[j] = -1;
     3861      }
     3862      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
     3863      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3864        *out << (*runner) << " ";
     3865      *out << endl;
     3866      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     3867    } else {
     3868      *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
     3869    }
     3870  }
     3871  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     3872  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    38733873};
    38743874
     
    38813881bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    38823882{
    3883         atom *Walker = NULL, *Walker2 = NULL;
    3884         bool BondStatus = false;
    3885         int size;
    3886 
    3887         *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    3888         *out << Verbose(2) << "Disconnected atom: ";
    3889 
    3890         // count number of atoms in graph
    3891         size = 0;
    3892         for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
    3893                 size++;
    3894         if (size > 1)
    3895                 for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
    3896                         Walker = FindAtom(*runner);
    3897                         BondStatus = false;
    3898                         for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    3899                                 Walker2 = FindAtom(*runners);
    3900                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    3901                                         if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
    3902                                                 BondStatus = true;
    3903                                                 break;
    3904                                         }
    3905                                         if (BondStatus)
    3906                                                 break;
    3907                                 }
    3908                         }
    3909                         if (!BondStatus) {
    3910                                 *out << (*Walker) << endl;
    3911                                 return false;
    3912                         }
    3913                 }
    3914         else {
    3915                 *out << "none." << endl;
    3916                 return true;
    3917         }
    3918         *out << "none." << endl;
    3919 
    3920         *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
    3921 
    3922         return true;
     3883  atom *Walker = NULL, *Walker2 = NULL;
     3884  bool BondStatus = false;
     3885  int size;
     3886
     3887  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
     3888  *out << Verbose(2) << "Disconnected atom: ";
     3889
     3890  // count number of atoms in graph
     3891  size = 0;
     3892  for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
     3893    size++;
     3894  if (size > 1)
     3895    for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
     3896      Walker = FindAtom(*runner);
     3897      BondStatus = false;
     3898      for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
     3899        Walker2 = FindAtom(*runners);
     3900        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     3901          if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     3902            BondStatus = true;
     3903            break;
     3904          }
     3905          if (BondStatus)
     3906            break;
     3907        }
     3908      }
     3909      if (!BondStatus) {
     3910        *out << (*Walker) << endl;
     3911        return false;
     3912      }
     3913    }
     3914  else {
     3915    *out << "none." << endl;
     3916    return true;
     3917  }
     3918  *out << "none." << endl;
     3919
     3920  *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
     3921
     3922  return true;
    39233923}
    39243924
     
    39403940int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    39413941{
    3942         int SP, AtomKeyNr;
    3943         atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
    3944         bond *Binder = NULL;
    3945         bond *CurrentEdge = NULL;
    3946         bond **BondsList = NULL;
    3947         int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    3948         int Counter = FragmentSearch.FragmentCounter;
    3949         int RemainingWalkers;
    3950 
    3951         *out << endl;
    3952         *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
    3953 
    3954         // prepare Label and SP arrays of the BFS search
    3955         FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
    3956 
    3957         // prepare root level (SP = 0) and a loop bond denoting Root
    3958         for (int i=1;i<Order;i++)
    3959                 FragmentSearch.BondsPerSPCount[i] = 0;
    3960         FragmentSearch.BondsPerSPCount[0] = 1;
    3961         Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    3962         add(Binder, FragmentSearch.BondsPerSPList[1]);
    3963 
    3964         // do a BFS search to fill the SP lists and label the found vertices
    3965         // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    3966         // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    3967         // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    3968         // (EdgeinSPLevel) of this tree ...
    3969         // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    3970         // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
    3971         *out << endl;
    3972         *out << Verbose(0) << "Starting BFS analysis ..." << endl;
    3973         for (SP = 0; SP < (Order-1); SP++) {
    3974                 *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
    3975                 if (SP > 0) {
    3976                         *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
    3977                         FragmentSearch.BondsPerSPCount[SP] = 0;
    3978                 } else
    3979                         *out << "." << endl;
    3980 
    3981                 RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
    3982                 CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];              /// start of this SP level's list
    3983                 while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {            /// end of this SP level's list
    3984                         CurrentEdge = CurrentEdge->next;
    3985                         RemainingWalkers--;
    3986                         Walker = CurrentEdge->rightatom;                // rightatom is always the one more distant
    3987                         Predecessor = CurrentEdge->leftatom;            // ... and leftatom is predecessor
    3988                         AtomKeyNr = Walker->nr;
    3989                         *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
    3990                         // check for new sp level
    3991                         // go through all its bonds
    3992                         *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    3993                         for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
    3994                                 Binder = ListOfBondsPerAtom[AtomKeyNr][i];
    3995                                 OtherWalker = Binder->GetOtherAtom(Walker);
    3996                                 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    3997         #ifdef ADDHYDROGEN
    3998                                 && (OtherWalker->type->Z != 1)
    3999         #endif
    4000                                                                                                                                                                                                                                                         ) {     // skip hydrogens and restrict to fragment
    4001                                         *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
    4002                                         // set the label if not set (and push on root stack as well)
    4003                                         if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
    4004                                                 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
    4005                                                 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
    4006                                                 // add the bond in between to the SP list
    4007                                                 Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
    4008                                                 add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
    4009                                                 FragmentSearch.BondsPerSPCount[SP+1]++;
    4010                                                 *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
    4011                                         } else {
    4012                                                 if (OtherWalker != Predecessor)
    4013                                                         *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
    4014                                                 else
    4015                                                         *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
    4016                                         }
    4017                                 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
    4018                         }
    4019                 }
    4020         }
    4021 
    4022         // outputting all list for debugging
    4023         *out << Verbose(0) << "Printing all found lists." << endl;
    4024         for(int i=1;i<Order;i++) {              // skip the root edge in the printing
    4025                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4026                 *out << Verbose(1) << "Current SP level is " << i << "." << endl;
    4027                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4028                         Binder = Binder->next;
    4029                         *out << Verbose(2) << *Binder << endl;
    4030                 }
    4031         }
    4032 
    4033         // creating fragments with the found edge sets  (may be done in reverse order, faster)
    4034         SP = -1;        // the Root <-> Root edge must be subtracted!
    4035         for(int i=Order;i--;) { // sum up all found edges
    4036                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4037                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4038                         Binder = Binder->next;
    4039                         SP ++;
    4040                 }
    4041         }
    4042         *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
    4043         if (SP >= (Order-1)) {
    4044                 // start with root (push on fragment stack)
    4045                 *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4046                 FragmentSearch.FragmentSet->clear();
    4047                 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    4048                 // prepare the subset and call the generator
    4049                 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    4050                 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4051 
    4052                 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4053 
    4054                 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    4055         } else {
    4056                 *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
    4057         }
    4058 
    4059         // as FragmentSearch structure is used only once, we don't have to clean it anymore
    4060         // remove root from stack
    4061         *out << Verbose(0) << "Removing root again from stack." << endl;
    4062         FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    4063 
    4064         // free'ing the bonds lists
    4065         *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
    4066         for(int i=Order;i--;) {
    4067                 *out << Verbose(1) << "Current SP level is " << i << ": ";
    4068                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4069                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4070                         Binder = Binder->next;
    4071                         // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
    4072                         FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
    4073                         FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
    4074                 }
    4075                 // delete added bonds
    4076                 cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
    4077                 // also start and end node
    4078                 *out << "cleaned." << endl;
    4079         }
    4080 
    4081         // return list
    4082         *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    4083         return (FragmentSearch.FragmentCounter - Counter);
     3942  int SP, AtomKeyNr;
     3943  atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
     3944  bond *Binder = NULL;
     3945  bond *CurrentEdge = NULL;
     3946  bond **BondsList = NULL;
     3947  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
     3948  int Counter = FragmentSearch.FragmentCounter;
     3949  int RemainingWalkers;
     3950
     3951  *out << endl;
     3952  *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
     3953
     3954  // prepare Label and SP arrays of the BFS search
     3955  FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
     3956
     3957  // prepare root level (SP = 0) and a loop bond denoting Root
     3958  for (int i=1;i<Order;i++)
     3959    FragmentSearch.BondsPerSPCount[i] = 0;
     3960  FragmentSearch.BondsPerSPCount[0] = 1;
     3961  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     3962  add(Binder, FragmentSearch.BondsPerSPList[1]);
     3963
     3964  // do a BFS search to fill the SP lists and label the found vertices
     3965  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
     3966  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
     3967  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
     3968  // (EdgeinSPLevel) of this tree ...
     3969  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
     3970  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     3971  *out << endl;
     3972  *out << Verbose(0) << "Starting BFS analysis ..." << endl;
     3973  for (SP = 0; SP < (Order-1); SP++) {
     3974    *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
     3975    if (SP > 0) {
     3976      *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
     3977      FragmentSearch.BondsPerSPCount[SP] = 0;
     3978    } else
     3979      *out << "." << endl;
     3980
     3981    RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
     3982    CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];    /// start of this SP level's list
     3983    while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {    /// end of this SP level's list
     3984      CurrentEdge = CurrentEdge->next;
     3985      RemainingWalkers--;
     3986      Walker = CurrentEdge->rightatom;    // rightatom is always the one more distant
     3987      Predecessor = CurrentEdge->leftatom;    // ... and leftatom is predecessor
     3988      AtomKeyNr = Walker->nr;
     3989      *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
     3990      // check for new sp level
     3991      // go through all its bonds
     3992      *out << Verbose(1) << "Going through all bonds of Walker." << endl;
     3993      for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
     3994        Binder = ListOfBondsPerAtom[AtomKeyNr][i];
     3995        OtherWalker = Binder->GetOtherAtom(Walker);
     3996        if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
     3997  #ifdef ADDHYDROGEN
     3998        && (OtherWalker->type->Z != 1)
     3999  #endif
     4000                                                              ) {  // skip hydrogens and restrict to fragment
     4001          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     4002          // set the label if not set (and push on root stack as well)
     4003          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     4004            FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
     4005            *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
     4006            // add the bond in between to the SP list
     4007            Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
     4008            add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
     4009            FragmentSearch.BondsPerSPCount[SP+1]++;
     4010            *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
     4011          } else {
     4012            if (OtherWalker != Predecessor)
     4013              *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
     4014            else
     4015              *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
     4016          }
     4017        } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
     4018      }
     4019    }
     4020  }
     4021
     4022  // outputting all list for debugging
     4023  *out << Verbose(0) << "Printing all found lists." << endl;
     4024  for(int i=1;i<Order;i++) {    // skip the root edge in the printing
     4025    Binder = FragmentSearch.BondsPerSPList[2*i];
     4026    *out << Verbose(1) << "Current SP level is " << i << "." << endl;
     4027    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4028      Binder = Binder->next;
     4029      *out << Verbose(2) << *Binder << endl;
     4030    }
     4031  }
     4032
     4033  // creating fragments with the found edge sets  (may be done in reverse order, faster)
     4034  SP = -1;  // the Root <-> Root edge must be subtracted!
     4035  for(int i=Order;i--;) { // sum up all found edges
     4036    Binder = FragmentSearch.BondsPerSPList[2*i];
     4037    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4038      Binder = Binder->next;
     4039      SP ++;
     4040    }
     4041  }
     4042  *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
     4043  if (SP >= (Order-1)) {
     4044    // start with root (push on fragment stack)
     4045    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
     4046    FragmentSearch.FragmentSet->clear();
     4047    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
     4048    // prepare the subset and call the generator
     4049    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
     4050    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
     4051
     4052    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
     4053
     4054    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
     4055  } else {
     4056    *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
     4057  }
     4058
     4059  // as FragmentSearch structure is used only once, we don't have to clean it anymore
     4060  // remove root from stack
     4061  *out << Verbose(0) << "Removing root again from stack." << endl;
     4062  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4063
     4064  // free'ing the bonds lists
     4065  *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
     4066  for(int i=Order;i--;) {
     4067    *out << Verbose(1) << "Current SP level is " << i << ": ";
     4068    Binder = FragmentSearch.BondsPerSPList[2*i];
     4069    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4070      Binder = Binder->next;
     4071      // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
     4072      FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
     4073      FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
     4074    }
     4075    // delete added bonds
     4076    cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
     4077    // also start and end node
     4078    *out << "cleaned." << endl;
     4079  }
     4080
     4081  // return list
     4082  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
     4083  return (FragmentSearch.FragmentCounter - Counter);
    40844084};
    40854085
     
    40924092void molecule::ScanForPeriodicCorrection(ofstream *out)
    40934093{
    4094         bond *Binder = NULL;
    4095         bond *OtherBinder = NULL;
    4096         atom *Walker = NULL;
    4097         atom *OtherWalker = NULL;
    4098         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    4099         enum Shading *ColorList = NULL;
    4100         double tmp;
    4101         Vector Translationvector;
    4102         //class StackClass<atom *> *CompStack = NULL;
    4103         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    4104         bool flag = true;
    4105 
    4106         *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
    4107 
    4108         ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
    4109         while (flag) {
    4110                 // remove bonds that are beyond bonddistance
    4111                 for(int i=NDIM;i--;)
    4112                         Translationvector.x[i] = 0.;
    4113                 // scan all bonds
    4114                 Binder = first;
    4115                 flag = false;
    4116                 while ((!flag) && (Binder->next != last)) {
    4117                         Binder = Binder->next;
    4118                         for (int i=NDIM;i--;) {
    4119                                 tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
    4120                                 //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
    4121                                 if (tmp > BondDistance) {
    4122                                         OtherBinder = Binder->next; // note down binding partner for later re-insertion
    4123                                         unlink(Binder); // unlink bond
    4124                                         *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
    4125                                         flag = true;
    4126                                         break;
    4127                                 }
    4128                         }
    4129                 }
    4130                 if (flag) {
    4131                         // create translation vector from their periodically modified distance
    4132                         for (int i=NDIM;i--;) {
    4133                                 tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
    4134                                 if (fabs(tmp) > BondDistance)
    4135                                         Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
    4136                         }
    4137                         Translationvector.MatrixMultiplication(matrix);
    4138                         //*out << Verbose(3) << "Translation vector is ";
    4139                         Translationvector.Output(out);
    4140                         *out << endl;
    4141                         // apply to all atoms of first component via BFS
    4142                         for (int i=AtomCount;i--;)
    4143                                 ColorList[i] = white;
    4144                         AtomStack->Push(Binder->leftatom);
    4145                         while (!AtomStack->IsEmpty()) {
    4146                                 Walker = AtomStack->PopFirst();
    4147                                 //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
    4148                                 ColorList[Walker->nr] = black;          // mark as explored
    4149                                 Walker->x.AddVector(&Translationvector); // translate
    4150                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    4151                                         if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    4152                                                 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    4153                                                 if (ColorList[OtherWalker->nr] == white) {
    4154                                                         AtomStack->Push(OtherWalker); // push if yet unexplored
    4155                                                 }
    4156                                         }
    4157                                 }
    4158                         }
    4159                         // re-add bond
    4160                         link(Binder, OtherBinder);
    4161                 } else {
    4162                         *out << Verbose(3) << "No corrections for this fragment." << endl;
    4163                 }
    4164                 //delete(CompStack);
    4165         }
    4166 
    4167         // free allocated space from ReturnFullMatrixforSymmetric()
    4168         delete(AtomStack);
    4169         Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
    4170         Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
    4171         *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
     4094  bond *Binder = NULL;
     4095  bond *OtherBinder = NULL;
     4096  atom *Walker = NULL;
     4097  atom *OtherWalker = NULL;
     4098  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     4099  enum Shading *ColorList = NULL;
     4100  double tmp;
     4101  Vector Translationvector;
     4102  //class StackClass<atom *> *CompStack = NULL;
     4103  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     4104  bool flag = true;
     4105
     4106  *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
     4107
     4108  ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
     4109  while (flag) {
     4110    // remove bonds that are beyond bonddistance
     4111    for(int i=NDIM;i--;)
     4112      Translationvector.x[i] = 0.;
     4113    // scan all bonds
     4114    Binder = first;
     4115    flag = false;
     4116    while ((!flag) && (Binder->next != last)) {
     4117      Binder = Binder->next;
     4118      for (int i=NDIM;i--;) {
     4119        tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
     4120        //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
     4121        if (tmp > BondDistance) {
     4122          OtherBinder = Binder->next; // note down binding partner for later re-insertion
     4123          unlink(Binder);  // unlink bond
     4124          *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
     4125          flag = true;
     4126          break;
     4127        }
     4128      }
     4129    }
     4130    if (flag) {
     4131      // create translation vector from their periodically modified distance
     4132      for (int i=NDIM;i--;) {
     4133        tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
     4134        if (fabs(tmp) > BondDistance)
     4135          Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
     4136      }
     4137      Translationvector.MatrixMultiplication(matrix);
     4138      //*out << Verbose(3) << "Translation vector is ";
     4139      Translationvector.Output(out);
     4140      *out << endl;
     4141      // apply to all atoms of first component via BFS
     4142      for (int i=AtomCount;i--;)
     4143        ColorList[i] = white;
     4144      AtomStack->Push(Binder->leftatom);
     4145      while (!AtomStack->IsEmpty()) {
     4146        Walker = AtomStack->PopFirst();
     4147        //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
     4148        ColorList[Walker->nr] = black;    // mark as explored
     4149        Walker->x.AddVector(&Translationvector); // translate
     4150        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
     4151          if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
     4152            OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     4153            if (ColorList[OtherWalker->nr] == white) {
     4154              AtomStack->Push(OtherWalker); // push if yet unexplored
     4155            }
     4156          }
     4157        }
     4158      }
     4159      // re-add bond
     4160      link(Binder, OtherBinder);
     4161    } else {
     4162      *out << Verbose(3) << "No corrections for this fragment." << endl;
     4163    }
     4164    //delete(CompStack);
     4165  }
     4166
     4167  // free allocated space from ReturnFullMatrixforSymmetric()
     4168  delete(AtomStack);
     4169  Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
     4170  Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
     4171  *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
    41724172};
    41734173
     
    41784178double * molecule::ReturnFullMatrixforSymmetric(double *symm)
    41794179{
    4180         double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
    4181         matrix[0] = symm[0];
    4182         matrix[1] = symm[1];
    4183         matrix[2] = symm[2];
    4184         matrix[3] = symm[1];
    4185         matrix[4] = symm[3];
    4186         matrix[5] = symm[4];
    4187         matrix[6] = symm[2];
    4188         matrix[7] = symm[4];
    4189         matrix[8] = symm[5];
    4190         return matrix;
     4180  double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
     4181  matrix[0] = symm[0];
     4182  matrix[1] = symm[1];
     4183  matrix[2] = symm[2];
     4184  matrix[3] = symm[1];
     4185  matrix[4] = symm[3];
     4186  matrix[5] = symm[4];
     4187  matrix[6] = symm[2];
     4188  matrix[7] = symm[4];
     4189  matrix[8] = symm[5];
     4190  return matrix;
    41914191};
    41924192
    41934193bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
    41944194{
    4195         //cout << "my check is used." << endl;
    4196         if (SubgraphA.size() < SubgraphB.size()) {
    4197                 return true;
    4198         } else {
    4199                 if (SubgraphA.size() > SubgraphB.size()) {
    4200                         return false;
    4201                 } else {
    4202                         KeySet::iterator IteratorA = SubgraphA.begin();
    4203                         KeySet::iterator IteratorB = SubgraphB.begin();
    4204                         while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
    4205                                 if ((*IteratorA) <      (*IteratorB))
    4206                                         return true;
    4207                                 else if ((*IteratorA) > (*IteratorB)) {
    4208                                                 return false;
    4209                                         } // else, go on to next index
    4210                                 IteratorA++;
    4211                                 IteratorB++;
    4212                         } // end of while loop
    4213                 }// end of check in case of equal sizes
    4214         }
    4215         return false; // if we reach this point, they are equal
     4195  //cout << "my check is used." << endl;
     4196  if (SubgraphA.size() < SubgraphB.size()) {
     4197    return true;
     4198  } else {
     4199    if (SubgraphA.size() > SubgraphB.size()) {
     4200      return false;
     4201    } else {
     4202      KeySet::iterator IteratorA = SubgraphA.begin();
     4203      KeySet::iterator IteratorB = SubgraphB.begin();
     4204      while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
     4205        if ((*IteratorA) <  (*IteratorB))
     4206          return true;
     4207        else if ((*IteratorA) > (*IteratorB)) {
     4208            return false;
     4209          } // else, go on to next index
     4210        IteratorA++;
     4211        IteratorB++;
     4212      } // end of while loop
     4213    }// end of check in case of equal sizes
     4214  }
     4215  return false; // if we reach this point, they are equal
    42164216};
    42174217
    42184218//bool operator < (KeySet SubgraphA, KeySet SubgraphB)
    42194219//{
    4220 //      return KeyCompare(SubgraphA, SubgraphB);
     4220//  return KeyCompare(SubgraphA, SubgraphB);
    42214221//};
    42224222
     
    42304230inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment)
    42314231{
    4232         GraphTestPair testGraphInsert;
    4233 
    4234         testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor))); // store fragment number and current factor
    4235         if (testGraphInsert.second) {
    4236                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
    4237                 Fragment->FragmentCounter++;
    4238         } else {
    4239                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4240                 ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;       // increase the "created" counter
    4241                 *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
    4242         }
     4232  GraphTestPair testGraphInsert;
     4233
     4234  testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor)));  // store fragment number and current factor
     4235  if (testGraphInsert.second) {
     4236    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
     4237    Fragment->FragmentCounter++;
     4238  } else {
     4239    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4240    ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;  // increase the "created" counter
     4241    *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
     4242  }
    42434243};
    42444244//void inline InsertIntoGraph(ofstream *out, KeyStack &stack, Graph &graph, int *counter, double factor)
    42454245//{
    4246 //      // copy stack contents to set and call overloaded function again
    4247 //      KeySet set;
    4248 //      for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
    4249 //              set.insert((*runner));
    4250 //      InsertIntoGraph(out, set, graph, counter, factor);
     4246//  // copy stack contents to set and call overloaded function again
     4247//  KeySet set;
     4248//  for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
     4249//    set.insert((*runner));
     4250//  InsertIntoGraph(out, set, graph, counter, factor);
    42514251//};
    42524252
     
    42594259inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
    42604260{
    4261         GraphTestPair testGraphInsert;
    4262 
    4263         for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
    4264                 testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
    4265                 if (testGraphInsert.second) {
    4266                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
    4267                 } else {
    4268                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4269                         ((*(testGraphInsert.first)).second).second += (*runner).second.second;
    4270                         *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
    4271                 }
    4272         }
     4261  GraphTestPair testGraphInsert;
     4262
     4263  for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
     4264    testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
     4265    if (testGraphInsert.second) {
     4266      *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
     4267    } else {
     4268      *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4269      ((*(testGraphInsert.first)).second).second += (*runner).second.second;
     4270      *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
     4271    }
     4272  }
    42734273};
    42744274
     
    42774277 * -# constructs a complete keyset of the molecule
    42784278 * -# In a loop over all possible roots from the given rootstack
    4279  *      -# increases order of root site
    4280  *      -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
    4281  *      -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
     4279 *  -# increases order of root site
     4280 *  -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
     4281 *  -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
    42824282as the restricted one and each site in the set as the root)
    4283  *      -# these are merged into a fragment list of keysets
     4283 *  -# these are merged into a fragment list of keysets
    42844284 * -# All fragment lists (for all orders, i.e. from all destination fields) are merged into one list for return
    42854285 * Important only is that we create all fragments, it is not important if we create them more than once
     
    42934293void molecule::FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize)
    42944294{
    4295         Graph ***FragmentLowerOrdersList = NULL;
    4296         int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
    4297         int counter = 0, Order;
    4298         int UpgradeCount = RootStack.size();
    4299         KeyStack FragmentRootStack;
    4300         int RootKeyNr, RootNr;
    4301         struct UniqueFragments FragmentSearch;
    4302 
    4303         *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    4304 
    4305         // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
    4306         // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
    4307         NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4308         FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4309 
    4310         // initialise the fragments structure
    4311         FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    4312         FragmentSearch.FragmentCounter = 0;
    4313         FragmentSearch.FragmentSet = new KeySet;
    4314         FragmentSearch.Root = FindAtom(RootKeyNr);
    4315         for (int i=AtomCount;i--;) {
    4316                 FragmentSearch.ShortestPathList[i] = -1;
    4317         }
    4318 
    4319         // Construct the complete KeySet which we need for topmost level only (but for all Roots)
    4320         atom *Walker = start;
    4321         KeySet CompleteMolecule;
    4322         while (Walker->next != end) {
    4323                 Walker = Walker->next;
    4324                 CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4325         }
    4326 
    4327         // 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
    4328         // 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),
    4329         // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
    4330         // 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)
    4331         RootNr = 0;      // counts through the roots in RootStack
    4332         while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
    4333                 RootKeyNr = RootStack.front();
    4334                 RootStack.pop_front();
    4335                 Walker = FindAtom(RootKeyNr);
    4336                 // check cyclic lengths
    4337                 //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    4338                 //      *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;
    4339                 //} else
    4340                 {
    4341                         // increase adaptive order by one
    4342                         Walker->GetTrueFather()->AdaptiveOrder++;
    4343                         Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4344 
    4345                         // initialise Order-dependent entries of UniqueFragments structure
    4346                         FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4347                         FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4348                         for (int i=Order;i--;) {
    4349                                 FragmentSearch.BondsPerSPList[2*i] = new bond();                // start node
    4350                                 FragmentSearch.BondsPerSPList[2*i+1] = new bond();      // end node
    4351                                 FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];                // intertwine these two
    4352                                 FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    4353                                 FragmentSearch.BondsPerSPCount[i] = 0;
    4354                         }
    4355 
    4356                         // allocate memory for all lower level orders in this 1D-array of ptrs
    4357                         NumLevels = 1 << (Order-1); // (int)pow(2,Order);
    4358                         FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4359                         for (int i=0;i<NumLevels;i++)
    4360                                 FragmentLowerOrdersList[RootNr][i] = NULL;
    4361 
    4362                         // create top order where nothing is reduced
    4363                         *out << Verbose(0) << "==============================================================================================================" << endl;
    4364                         *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4365 
    4366                         // Create list of Graphs of current Bond Order (i.e. F_{ij})
    4367                         FragmentLowerOrdersList[RootNr][0] =    new Graph;
    4368                         FragmentSearch.TEFactor = 1.;
    4369                         FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];                    // set to insertion graph
    4370                         FragmentSearch.Root = Walker;
    4371                         NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
    4372                         *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4373                         if (NumMoleculesOfOrder[RootNr] != 0) {
    4374                                 NumMolecules = 0;
    4375 
    4376                                 // we don't have to dive into suborders! These keysets are all already created on lower orders!
    4377                                 // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4378 
    4379 //                              if ((NumLevels >> 1) > 0) {
    4380 //                                      // create lower order fragments
    4381 //                                      *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
    4382 //                                      Order = Walker->AdaptiveOrder;
    4383 //                                      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)
    4384 //                                              // step down to next order at (virtual) boundary of powers of 2 in array
    4385 //                                              while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    4386 //                                                      Order--;
    4387 //                                              *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
    4388 //                                              for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
    4389 //                                                      int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
    4390 //                                                      *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    4391 //                                                      *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
     4295  Graph ***FragmentLowerOrdersList = NULL;
     4296  int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
     4297  int counter = 0, Order;
     4298  int UpgradeCount = RootStack.size();
     4299  KeyStack FragmentRootStack;
     4300  int RootKeyNr, RootNr;
     4301  struct UniqueFragments FragmentSearch;
     4302
     4303  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
     4304
     4305  // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
     4306  // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
     4307  NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4308  FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4309
     4310  // initialise the fragments structure
     4311  FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
     4312  FragmentSearch.FragmentCounter = 0;
     4313  FragmentSearch.FragmentSet = new KeySet;
     4314  FragmentSearch.Root = FindAtom(RootKeyNr);
     4315  for (int i=AtomCount;i--;) {
     4316    FragmentSearch.ShortestPathList[i] = -1;
     4317  }
     4318
     4319  // Construct the complete KeySet which we need for topmost level only (but for all Roots)
     4320  atom *Walker = start;
     4321  KeySet CompleteMolecule;
     4322  while (Walker->next != end) {
     4323    Walker = Walker->next;
     4324    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
     4325  }
     4326
     4327  // 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
     4328  // 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),
     4329  // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
     4330  // 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)
     4331  RootNr = 0;  // counts through the roots in RootStack
     4332  while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
     4333    RootKeyNr = RootStack.front();
     4334    RootStack.pop_front();
     4335    Walker = FindAtom(RootKeyNr);
     4336    // check cyclic lengths
     4337    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
     4338    //  *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;
     4339    //} else
     4340    {
     4341      // increase adaptive order by one
     4342      Walker->GetTrueFather()->AdaptiveOrder++;
     4343      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
     4344
     4345      // initialise Order-dependent entries of UniqueFragments structure
     4346      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4347      FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4348      for (int i=Order;i--;) {
     4349        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
     4350        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
     4351        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];    // intertwine these two
     4352        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
     4353        FragmentSearch.BondsPerSPCount[i] = 0;
     4354      }
     4355
     4356      // allocate memory for all lower level orders in this 1D-array of ptrs
     4357      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     4358      FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4359      for (int i=0;i<NumLevels;i++)
     4360        FragmentLowerOrdersList[RootNr][i] = NULL;
     4361
     4362      // create top order where nothing is reduced
     4363      *out << Verbose(0) << "==============================================================================================================" << endl;
     4364      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
     4365
     4366      // Create list of Graphs of current Bond Order (i.e. F_{ij})
     4367      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     4368      FragmentSearch.TEFactor = 1.;
     4369      FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];      // set to insertion graph
     4370      FragmentSearch.Root = Walker;
     4371      NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
     4372      *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4373      if (NumMoleculesOfOrder[RootNr] != 0) {
     4374        NumMolecules = 0;
     4375
     4376        // we don't have to dive into suborders! These keysets are all already created on lower orders!
     4377        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
     4378
     4379//        if ((NumLevels >> 1) > 0) {
     4380//          // create lower order fragments
     4381//          *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
     4382//          Order = Walker->AdaptiveOrder;
     4383//          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)
     4384//            // step down to next order at (virtual) boundary of powers of 2 in array
     4385//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4386//              Order--;
     4387//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     4388//            for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
     4389//              int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
     4390//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
     4391//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    43924392//
    4393 //                                                      // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    4394 //                                                      //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
    4395 //                                                      //NumMolecules = 0;
    4396 //                                                      FragmentLowerOrdersList[RootNr][dest] = new Graph;
    4397 //                                                      for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
    4398 //                                                              for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    4399 //                                                                      Graph TempFragmentList;
    4400 //                                                                      FragmentSearch.TEFactor = -(*runner).second.second;
    4401 //                                                                      FragmentSearch.Leaflet = &TempFragmentList;                     // set to insertion graph
    4402 //                                                                      FragmentSearch.Root = FindAtom(*sprinter);
    4403 //                                                                      NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
    4404 //                                                                      // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
    4405 //                                                                      *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
    4406 //                                                                      InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
    4407 //                                                              }
    4408 //                                                      }
    4409 //                                                      *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
    4410 //                                              }
    4411 //                                      }
    4412 //                              }
    4413                         } else {
    4414                                 Walker->GetTrueFather()->MaxOrder = true;
    4415 //                              *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
    4416                         }
    4417                         // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
    4418                         //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
    4419                         TotalNumMolecules += NumMoleculesOfOrder[RootNr];
    4420 //                      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4421                         RootStack.push_back(RootKeyNr); // put back on stack
    4422                         RootNr++;
    4423 
    4424                         // free Order-dependent entries of UniqueFragments structure for next loop cycle
    4425                         Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4426                         for (int i=Order;i--;) {
    4427                                 delete(FragmentSearch.BondsPerSPList[2*i]);
    4428                                 delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4429                         }
    4430                         Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4431                 }
    4432         }
    4433         *out << Verbose(0) << "==============================================================================================================" << endl;
    4434         *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
    4435         *out << Verbose(0) << "==============================================================================================================" << endl;
    4436 
    4437         // cleanup FragmentSearch structure
    4438         Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    4439         delete(FragmentSearch.FragmentSet);
    4440 
    4441         // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    4442         // 5433222211111111
    4443         // 43221111
    4444         // 3211
    4445         // 21
    4446         // 1
    4447 
    4448         // Subsequently, we combine all into a single list (FragmentList)
    4449 
    4450         *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
    4451         if (FragmentList == NULL) {
    4452                 FragmentList = new Graph;
    4453                 counter = 0;
    4454         } else {
    4455                 counter = FragmentList->size();
    4456         }
    4457         RootNr = 0;
    4458         while (!RootStack.empty()) {
    4459                 RootKeyNr = RootStack.front();
    4460                 RootStack.pop_front();
    4461                 Walker = FindAtom(RootKeyNr);
    4462                 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    4463                 for(int i=0;i<NumLevels;i++) {
    4464                         if (FragmentLowerOrdersList[RootNr][i] != NULL) {
    4465                                 InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
    4466                                 delete(FragmentLowerOrdersList[RootNr][i]);
    4467                         }
    4468                 }
    4469                 Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4470                 RootNr++;
    4471         }
    4472         Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4473         Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4474 
    4475         *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
     4393//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
     4394//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     4395//              //NumMolecules = 0;
     4396//              FragmentLowerOrdersList[RootNr][dest] = new Graph;
     4397//              for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
     4398//                for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     4399//                  Graph TempFragmentList;
     4400//                  FragmentSearch.TEFactor = -(*runner).second.second;
     4401//                  FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
     4402//                  FragmentSearch.Root = FindAtom(*sprinter);
     4403//                  NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
     4404//                  // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
     4405//                  *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
     4406//                  InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
     4407//                }
     4408//              }
     4409//              *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
     4410//            }
     4411//          }
     4412//        }
     4413      } else {
     4414        Walker->GetTrueFather()->MaxOrder = true;
     4415//        *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
     4416      }
     4417      // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
     4418      //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
     4419      TotalNumMolecules += NumMoleculesOfOrder[RootNr];
     4420//      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4421      RootStack.push_back(RootKeyNr); // put back on stack
     4422      RootNr++;
     4423
     4424      // free Order-dependent entries of UniqueFragments structure for next loop cycle
     4425      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4426      for (int i=Order;i--;) {
     4427        delete(FragmentSearch.BondsPerSPList[2*i]);
     4428        delete(FragmentSearch.BondsPerSPList[2*i+1]);
     4429      }
     4430      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4431    }
     4432  }
     4433  *out << Verbose(0) << "==============================================================================================================" << endl;
     4434  *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
     4435  *out << Verbose(0) << "==============================================================================================================" << endl;
     4436
     4437  // cleanup FragmentSearch structure
     4438  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
     4439  delete(FragmentSearch.FragmentSet);
     4440
     4441  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4442  // 5433222211111111
     4443  // 43221111
     4444  // 3211
     4445  // 21
     4446  // 1
     4447
     4448  // Subsequently, we combine all into a single list (FragmentList)
     4449
     4450  *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
     4451  if (FragmentList == NULL) {
     4452    FragmentList = new Graph;
     4453    counter = 0;
     4454  } else {
     4455    counter = FragmentList->size();
     4456  }
     4457  RootNr = 0;
     4458  while (!RootStack.empty()) {
     4459    RootKeyNr = RootStack.front();
     4460    RootStack.pop_front();
     4461    Walker = FindAtom(RootKeyNr);
     4462    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
     4463    for(int i=0;i<NumLevels;i++) {
     4464      if (FragmentLowerOrdersList[RootNr][i] != NULL) {
     4465        InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
     4466        delete(FragmentLowerOrdersList[RootNr][i]);
     4467      }
     4468    }
     4469    Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4470    RootNr++;
     4471  }
     4472  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4473  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4474
     4475  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    44764476};
    44774477
     
    44834483inline int CompareDoubles (const void * a, const void * b)
    44844484{
    4485         if (*(double *)a > *(double *)b)
    4486                 return -1;
    4487         else if (*(double *)a < *(double *)b)
    4488                 return 1;
    4489         else
    4490                 return 0;
     4485  if (*(double *)a > *(double *)b)
     4486    return -1;
     4487  else if (*(double *)a < *(double *)b)
     4488    return 1;
     4489  else
     4490    return 0;
    44914491};
    44924492
     
    44994499int * molecule::IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold)
    45004500{
    4501         int flag;
    4502         double *Distances = NULL, *OtherDistances = NULL;
    4503         Vector CenterOfGravity, OtherCenterOfGravity;
    4504         size_t *PermMap = NULL, *OtherPermMap = NULL;
    4505         int *PermutationMap = NULL;
    4506         atom *Walker = NULL;
    4507         bool result = true; // status of comparison
    4508 
    4509         *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    4510         /// first count both their atoms and elements and update lists thereby ...
    4511         //*out << Verbose(0) << "Counting atoms, updating list" << endl;
    4512         CountAtoms(out);
    4513         OtherMolecule->CountAtoms(out);
    4514         CountElements();
    4515         OtherMolecule->CountElements();
    4516 
    4517         /// ... and compare:
    4518         /// -# AtomCount
    4519         if (result) {
    4520                 if (AtomCount != OtherMolecule->AtomCount) {
    4521                         *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4522                         result = false;
    4523                 } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4524         }
    4525         /// -# ElementCount
    4526         if (result) {
    4527                 if (ElementCount != OtherMolecule->ElementCount) {
    4528                         *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4529                         result = false;
    4530                 } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4531         }
    4532         /// -# ElementsInMolecule
    4533         if (result) {
    4534                 for (flag=MAX_ELEMENTS;flag--;) {
    4535                         //*out << Verbose(5) << "Element " <<   flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
    4536                         if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
    4537                                 break;
    4538                 }
    4539                 if (flag < MAX_ELEMENTS) {
    4540                         *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
    4541                         result = false;
    4542                 } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
    4543         }
    4544         /// then determine and compare center of gravity for each molecule ...
    4545         if (result) {
    4546                 *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    4547                 DetermineCenter(CenterOfGravity);
    4548                 OtherMolecule->DetermineCenter(OtherCenterOfGravity);
    4549                 *out << Verbose(5) << "Center of Gravity: ";
    4550                 CenterOfGravity.Output(out);
    4551                 *out << endl << Verbose(5) << "Other Center of Gravity: ";
    4552                 OtherCenterOfGravity.Output(out);
    4553                 *out << endl;
    4554                 if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
    4555                         *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4556                         result = false;
    4557                 }
    4558         }
    4559 
    4560         /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    4561         if (result) {
    4562                 *out << Verbose(5) << "Calculating distances" << endl;
    4563                 Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    4564                 OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4565                 Walker = start;
    4566                 while (Walker->next != end) {
    4567                         Walker = Walker->next;
    4568                         Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
    4569                 }
    4570                 Walker = OtherMolecule->start;
    4571                 while (Walker->next != OtherMolecule->end) {
    4572                         Walker = Walker->next;
    4573                         OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
    4574                 }
    4575 
    4576                 /// ... sort each list (using heapsort (o(N log N)) from GSL)
    4577                 *out << Verbose(5) << "Sorting distances" << endl;
    4578                 PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    4579                 OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4580                 gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    4581                 gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    4582                 PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4583                 *out << Verbose(5) << "Combining Permutation Maps" << endl;
    4584                 for(int i=AtomCount;i--;)
    4585                         PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4586 
    4587                 /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    4588                 *out << Verbose(4) << "Comparing distances" << endl;
    4589                 flag = 0;
    4590                 for (int i=0;i<AtomCount;i++) {
    4591                         *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<      threshold << endl;
    4592                         if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
    4593                                 flag = 1;
    4594                 }
    4595                 Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    4596                 Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4597 
    4598                 /// free memory
    4599                 Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
    4600                 Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4601                 if (flag) { // if not equal
    4602                         Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4603                         result = false;
    4604                 }
    4605         }
    4606         /// return pointer to map if all distances were below \a threshold
    4607         *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
    4608         if (result) {
    4609                 *out << Verbose(3) << "Result: Equal." << endl;
    4610                 return PermutationMap;
    4611         } else {
    4612                 *out << Verbose(3) << "Result: Not equal." << endl;
    4613                 return NULL;
    4614         }
     4501  int flag;
     4502  double *Distances = NULL, *OtherDistances = NULL;
     4503  Vector CenterOfGravity, OtherCenterOfGravity;
     4504  size_t *PermMap = NULL, *OtherPermMap = NULL;
     4505  int *PermutationMap = NULL;
     4506  atom *Walker = NULL;
     4507  bool result = true; // status of comparison
     4508
     4509  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     4510  /// first count both their atoms and elements and update lists thereby ...
     4511  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     4512  CountAtoms(out);
     4513  OtherMolecule->CountAtoms(out);
     4514  CountElements();
     4515  OtherMolecule->CountElements();
     4516
     4517  /// ... and compare:
     4518  /// -# AtomCount
     4519  if (result) {
     4520    if (AtomCount != OtherMolecule->AtomCount) {
     4521      *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4522      result = false;
     4523    } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4524  }
     4525  /// -# ElementCount
     4526  if (result) {
     4527    if (ElementCount != OtherMolecule->ElementCount) {
     4528      *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4529      result = false;
     4530    } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4531  }
     4532  /// -# ElementsInMolecule
     4533  if (result) {
     4534    for (flag=MAX_ELEMENTS;flag--;) {
     4535      //*out << Verbose(5) << "Element " <<  flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
     4536      if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
     4537        break;
     4538    }
     4539    if (flag < MAX_ELEMENTS) {
     4540      *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
     4541      result = false;
     4542    } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
     4543  }
     4544  /// then determine and compare center of gravity for each molecule ...
     4545  if (result) {
     4546    *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
     4547    DetermineCenter(CenterOfGravity);
     4548    OtherMolecule->DetermineCenter(OtherCenterOfGravity);
     4549    *out << Verbose(5) << "Center of Gravity: ";
     4550    CenterOfGravity.Output(out);
     4551    *out << endl << Verbose(5) << "Other Center of Gravity: ";
     4552    OtherCenterOfGravity.Output(out);
     4553    *out << endl;
     4554    if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
     4555      *out << Verbose(4) << "Centers of gravity don't match." << endl;
     4556      result = false;
     4557    }
     4558  }
     4559
     4560  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
     4561  if (result) {
     4562    *out << Verbose(5) << "Calculating distances" << endl;
     4563    Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
     4564    OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4565    Walker = start;
     4566    while (Walker->next != end) {
     4567      Walker = Walker->next;
     4568      Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
     4569    }
     4570    Walker = OtherMolecule->start;
     4571    while (Walker->next != OtherMolecule->end) {
     4572      Walker = Walker->next;
     4573      OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
     4574    }
     4575
     4576    /// ... sort each list (using heapsort (o(N log N)) from GSL)
     4577    *out << Verbose(5) << "Sorting distances" << endl;
     4578    PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
     4579    OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4580    gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
     4581    gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
     4582    PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4583    *out << Verbose(5) << "Combining Permutation Maps" << endl;
     4584    for(int i=AtomCount;i--;)
     4585      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
     4586
     4587    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
     4588    *out << Verbose(4) << "Comparing distances" << endl;
     4589    flag = 0;
     4590    for (int i=0;i<AtomCount;i++) {
     4591      *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
     4592      if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
     4593        flag = 1;
     4594    }
     4595    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
     4596    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4597
     4598    /// free memory
     4599    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     4600    Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4601    if (flag) { // if not equal
     4602      Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4603      result = false;
     4604    }
     4605  }
     4606  /// return pointer to map if all distances were below \a threshold
     4607  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     4608  if (result) {
     4609    *out << Verbose(3) << "Result: Equal." << endl;
     4610    return PermutationMap;
     4611  } else {
     4612    *out << Verbose(3) << "Result: Not equal." << endl;
     4613    return NULL;
     4614  }
    46154615};
    46164616
     
    46244624int * molecule::GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule)
    46254625{
    4626         atom *Walker = NULL, *OtherWalker = NULL;
    4627         *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
    4628         int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");   //Calloc
    4629         for (int i=AtomCount;i--;)
    4630                 AtomicMap[i] = -1;
    4631         if (OtherMolecule == this) {    // same molecule
    4632                 for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
    4633                         AtomicMap[i] = i;
    4634                 *out << Verbose(4) << "Map is trivial." << endl;
    4635         } else {
    4636                 *out << Verbose(4) << "Map is ";
    4637                 Walker = start;
    4638                 while (Walker->next != end) {
    4639                         Walker = Walker->next;
    4640                         if (Walker->father == NULL) {
    4641                                 AtomicMap[Walker->nr] = -2;
    4642                         } else {
    4643                                 OtherWalker = OtherMolecule->start;
    4644                                 while (OtherWalker->next != OtherMolecule->end) {
    4645                                         OtherWalker = OtherWalker->next;
    4646                         //for (int i=0;i<AtomCount;i++) { // search atom
    4647                                 //for (int j=0;j<OtherMolecule->AtomCount;j++) {
    4648                                         //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
    4649                                         if (Walker->father == OtherWalker)
    4650                                                 AtomicMap[Walker->nr] = OtherWalker->nr;
    4651                                 }
    4652                         }
    4653                         *out << AtomicMap[Walker->nr] << "\t";
    4654                 }
    4655                 *out << endl;
    4656         }
    4657         *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
    4658         return AtomicMap;
     4626  atom *Walker = NULL, *OtherWalker = NULL;
     4627  *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
     4628  int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");  //Calloc
     4629  for (int i=AtomCount;i--;)
     4630    AtomicMap[i] = -1;
     4631  if (OtherMolecule == this) {  // same molecule
     4632    for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
     4633      AtomicMap[i] = i;
     4634    *out << Verbose(4) << "Map is trivial." << endl;
     4635  } else {
     4636    *out << Verbose(4) << "Map is ";
     4637    Walker = start;
     4638    while (Walker->next != end) {
     4639      Walker = Walker->next;
     4640      if (Walker->father == NULL) {
     4641        AtomicMap[Walker->nr] = -2;
     4642      } else {
     4643        OtherWalker = OtherMolecule->start;
     4644        while (OtherWalker->next != OtherMolecule->end) {
     4645          OtherWalker = OtherWalker->next;
     4646      //for (int i=0;i<AtomCount;i++) { // search atom
     4647        //for (int j=0;j<OtherMolecule->AtomCount;j++) {
     4648          //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
     4649          if (Walker->father == OtherWalker)
     4650            AtomicMap[Walker->nr] = OtherWalker->nr;
     4651        }
     4652      }
     4653      *out << AtomicMap[Walker->nr] << "\t";
     4654    }
     4655    *out << endl;
     4656  }
     4657  *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
     4658  return AtomicMap;
    46594659};
    46604660
     
    46704670bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    46714671{
    4672         double temperature;
    4673         atom *Walker = NULL;
    4674         // test stream
    4675         if (output == NULL)
    4676                 return false;
    4677         else
    4678                 *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    4679         for (int step=startstep;step < endstep; step++) { // loop over all time steps
    4680                 temperature = 0.;
    4681                 Walker = start;
    4682                 while (Walker->next != end) {
    4683                         Walker = Walker->next;
    4684                         for (int i=NDIM;i--;)
    4685                                 temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
    4686                 }
    4687                 *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
    4688         }
    4689         return true;
    4690 };
     4672  double temperature;
     4673  atom *Walker = NULL;
     4674  // test stream
     4675  if (output == NULL)
     4676    return false;
     4677  else
     4678    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
     4679  for (int step=startstep;step < endstep; step++) { // loop over all time steps
     4680    temperature = 0.;
     4681    Walker = start;
     4682    while (Walker->next != end) {
     4683      Walker = Walker->next;
     4684      for (int i=NDIM;i--;)
     4685        temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
     4686    }
     4687    *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
     4688  }
     4689  return true;
     4690};
Note: See TracChangeset for help on using the changeset viewer.