Ignore:
Timestamp:
Jul 23, 2009, 12:14:13 PM (16 years ago)
Author:
Frederik Heber <heber@…>
Children:
f39735
Parents:
a41b50
Message:

Fix indentation from tab to two spaces.

The trouble was caused at the merge e08f45e4539ffcc30e039dec5606cf06b45ab6be. Seemingly, I thought eclipse had pulled some shit which i didn't

File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/molecules.cpp

    ra41b50 r1b2aa1  
    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");
    65         IndexNr  = -1;
    66         ActiveFlag = false;
     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");
     65  IndexNr  = -1;
     66  ActiveFlag = false;
    6767};
    6868
     
    7272molecule::~molecule()
    7373{
    74         if (ListOfBondsPerAtom != NULL)
    75                 for(int i=AtomCount;i--;)
    76                         Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
    77         Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
    78         Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
    79         CleanupMolecule();
    80         delete(first);
    81         delete(last);
    82         delete(end);
    83         delete(start);
     74  if (ListOfBondsPerAtom != NULL)
     75    for(int i=AtomCount;i--;)
     76      Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
     77  Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
     78  Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
     79  CleanupMolecule();
     80  delete(first);
     81  delete(last);
     82  delete(end);
     83  delete(start);
    8484};
    8585
     
    9191bool molecule::AddAtom(atom *pointer)
    9292{
    93         if (pointer != NULL) {
    94                 pointer->sort = &pointer->nr;
    95                 pointer->nr = last_atom++;      // increase number within molecule
    96                 AtomCount++;
    97                 if (pointer->type != NULL) {
    98                         if (ElementsInMolecule[pointer->type->Z] == 0)
    99                                 ElementCount++;
    100                         ElementsInMolecule[pointer->type->Z]++; // increase number of elements
    101                         if (pointer->type->Z != 1)
    102                                 NoNonHydrogen++;
    103                         if (pointer->Name == NULL) {
    104                                 Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
    105                                 pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
    106                                 sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
    107                         }
    108                 }
    109                 return add(pointer, end);
    110         } else
    111                 return false;
     93  if (pointer != NULL) {
     94    pointer->sort = &pointer->nr;
     95    pointer->nr = last_atom++;  // increase number within molecule
     96    AtomCount++;
     97    if (pointer->type != NULL) {
     98      if (ElementsInMolecule[pointer->type->Z] == 0)
     99        ElementCount++;
     100      ElementsInMolecule[pointer->type->Z]++; // increase number of elements
     101      if (pointer->type->Z != 1)
     102        NoNonHydrogen++;
     103      if (pointer->Name == NULL) {
     104        Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
     105        pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
     106        sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
     107      }
     108    }
     109    return add(pointer, end);
     110  } else
     111    return false;
    112112};
    113113
     
    119119atom * molecule::AddCopyAtom(atom *pointer)
    120120{
    121         if (pointer != NULL) {
    122                 atom *walker = new atom();
    123                 walker->type = pointer->type;   // copy element of atom
    124                 walker->x.CopyVector(&pointer->x); // copy coordination
    125                 walker->v.CopyVector(&pointer->v); // copy velocity
    126                 walker->FixedIon = pointer->FixedIon;
    127                 walker->sort = &walker->nr;
    128                 walker->nr = last_atom++;       // increase number within molecule
    129                 walker->father = pointer; //->GetTrueFather();
    130                 walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
    131                 strcpy (walker->Name, pointer->Name);
    132                 add(walker, end);
    133                 if ((pointer->type != NULL) && (pointer->type->Z != 1))
    134                         NoNonHydrogen++;
    135                 AtomCount++;
    136                 return walker;
    137         } else
    138                 return NULL;
     121  if (pointer != NULL) {
     122    atom *walker = new atom();
     123    walker->type = pointer->type;  // copy element of atom
     124    walker->x.CopyVector(&pointer->x); // copy coordination
     125    walker->v.CopyVector(&pointer->v); // copy velocity
     126    walker->FixedIon = pointer->FixedIon;
     127    walker->sort = &walker->nr;
     128    walker->nr = last_atom++;  // increase number within molecule
     129    walker->father = pointer; //->GetTrueFather();
     130    walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
     131    strcpy (walker->Name, pointer->Name);
     132    add(walker, end);
     133    if ((pointer->type != NULL) && (pointer->type->Z != 1))
     134      NoNonHydrogen++;
     135    AtomCount++;
     136    return walker;
     137  } else
     138    return NULL;
    139139};
    140140
     
    144144 * -# Single Bond: Simply add new atom with bond distance rescaled to typical hydrogen one
    145145 * -# Double Bond: Here, we need the **BondList of the \a *origin atom, by scanning for the other bonds instead of
    146  *              *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
    147  *              The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
    148  *              replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
    149  *              element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
    150  *              hydrogens forming this angle with *origin.
     146 *    *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
     147 *    The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
     148 *    replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
     149 *    element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
     150 *    hydrogens forming this angle with *origin.
    151151 * -# 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
    152  *              triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
    153  *              determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
    154  *              We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
    155  *              \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 )}}
    156  *              \f]
    157  *              vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
    158  *              the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
    159  *              The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    160  *              the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    161  *              \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
    162  *              \f]
    163  *              as the coordination of all three atoms in the coordinate system of these three vectors:
    164  *              \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$.
     152 *    triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
     153 *    determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
     154 *    We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
     155 *    \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 )}}
     156 *    \f]
     157 *    vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
     158 *    the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
     159 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
     160 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
     161 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     162 *    \f]
     163 *    as the coordination of all three atoms in the coordinate system of these three vectors:
     164 *    \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$.
    165165 *
    166166 * \param *out output stream for debugging
     
    170170 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    171171 * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    172  * \param NumBond       number of bonds in \a **BondList
     172 * \param NumBond  number of bonds in \a **BondList
    173173 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    174174 * \return number of atoms added, if < bond::BondDegree then something went wrong
     
    177177bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
    178178{
    179         double bondlength;      // bond length of the bond to be replaced/cut
    180         double bondangle;       // bond angle of the bond to be replaced/cut
    181         double BondRescale;      // rescale value for the hydrogen bond length
    182         bool AllWentWell = true;                // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
    183         bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
    184         atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
    185         double b,l,d,f,g, alpha, factors[NDIM];         // hold temporary values in triple bond case for coordination determination
    186         Vector Orthovector1, Orthovector2;      // temporary vectors in coordination construction
    187         Vector InBondvector;            // vector in direction of *Bond
    188         bond *Binder = NULL;
    189         double *matrix;
    190 
    191 //      *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
    192         // create vector in direction of bond
    193         InBondvector.CopyVector(&TopReplacement->x);
    194         InBondvector.SubtractVector(&TopOrigin->x);
    195         bondlength = InBondvector.Norm();
    196 
    197         // is greater than typical bond distance? Then we have to correct periodically
    198         // the problem is not the H being out of the box, but InBondvector have the wrong direction
    199         // due to TopReplacement or Origin being on the wrong side!
    200         if (bondlength > BondDistance) {
    201 //              *out << Verbose(4) << "InBondvector is: ";
    202 //              InBondvector.Output(out);
    203 //              *out << endl;
    204                 Orthovector1.Zero();
    205                 for (int i=NDIM;i--;) {
    206                         l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
    207                         if (fabs(l) > BondDistance) { // is component greater than bond distance
    208                                 Orthovector1.x[i] = (l < 0) ? -1. : +1.;
    209                         } // (signs are correct, was tested!)
    210                 }
    211                 matrix = ReturnFullMatrixforSymmetric(cell_size);
    212                 Orthovector1.MatrixMultiplication(matrix);
    213                 InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
    214                 Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
    215                 bondlength = InBondvector.Norm();
    216 //              *out << Verbose(4) << "Corrected InBondvector is now: ";
    217 //              InBondvector.Output(out);
    218 //              *out << endl;
    219         } // periodic correction finished
    220 
    221         InBondvector.Normalize();
    222         // get typical bond length and store as scale factor for later
    223         BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    224         if (BondRescale == -1) {
    225                 cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    226                 return false;
    227                 BondRescale = bondlength;
    228         } else {
    229                 if (!IsAngstroem)
    230                         BondRescale /= (1.*AtomicLengthToAngstroem);
    231         }
    232 
    233         // discern single, double and triple bonds
    234         switch(TopBond->BondDegree) {
    235                 case 1:
    236                         FirstOtherAtom = new atom();            // new atom
    237                         FirstOtherAtom->type = elemente->FindElement(1);        // element is Hydrogen
    238                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    239                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    240                         if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
    241                                 FirstOtherAtom->father = TopReplacement;
    242                                 BondRescale = bondlength;
    243                         } else {
    244                                 FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
    245                         }
    246                         InBondvector.Scale(&BondRescale);        // rescale the distance vector to Hydrogen bond length
    247                         FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
    248                         FirstOtherAtom->x.AddVector(&InBondvector);     // ... and add distance vector to replacement atom
    249                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    250 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    251 //                      FirstOtherAtom->x.Output(out);
    252 //                      *out << endl;
    253                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    254                         Binder->Cyclic = false;
    255                         Binder->Type = TreeEdge;
    256                         break;
    257                 case 2:
    258                         // determine two other bonds (warning if there are more than two other) plus valence sanity check
    259                         for (int i=0;i<NumBond;i++) {
    260                                 if (BondList[i] != TopBond) {
    261                                         if (FirstBond == NULL) {
    262                                                 FirstBond = BondList[i];
    263                                                 FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    264                                         } else if (SecondBond == NULL) {
    265                                                 SecondBond = BondList[i];
    266                                                 SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    267                                         } else {
    268                                                 *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
    269                                         }
    270                                 }
    271                         }
    272                         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)
    273                                 SecondBond = TopBond;
    274                                 SecondOtherAtom = TopReplacement;
    275                         }
    276                         if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    277 //                              *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;
    278 
    279                                 // determine the plane of these two with the *origin
    280                                 AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
    281                         } else {
    282                                 Orthovector1.GetOneNormalVector(&InBondvector);
    283                         }
    284                         //*out << Verbose(3)<< "Orthovector1: ";
    285                         //Orthovector1.Output(out);
    286                         //*out << endl;
    287                         // orthogonal vector and bond vector between origin and replacement form the new plane
    288                         Orthovector1.MakeNormalVector(&InBondvector);
    289                         Orthovector1.Normalize();
    290                         //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    291 
    292                         // create the two Hydrogens ...
    293                         FirstOtherAtom = new atom();
    294                         SecondOtherAtom = new atom();
    295                         FirstOtherAtom->type = elemente->FindElement(1);
    296                         SecondOtherAtom->type = elemente->FindElement(1);
    297                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    298                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    299                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    300                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    301                         FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
    302                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    303                         bondangle = TopOrigin->type->HBondAngle[1];
    304                         if (bondangle == -1) {
    305                                 *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    306                                 return false;
    307                                 bondangle = 0;
    308                         }
    309                         bondangle *= M_PI/180./2.;
    310 //                      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
    311 //                      InBondvector.Output(out);
    312 //                      *out << endl;
    313 //                      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
    314 //                      Orthovector1.Output(out);
    315 //                      *out << endl;
    316 //                      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
    317                         FirstOtherAtom->x.Zero();
    318                         SecondOtherAtom->x.Zero();
    319                         for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
    320                                 FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
    321                                 SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    322                         }
    323                         FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    324                         SecondOtherAtom->x.Scale(&BondRescale);
    325                         //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    326                         for(int i=NDIM;i--;) { // and make relative to origin atom
    327                                 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    328                                 SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    329                         }
    330                         // ... and add to molecule
    331                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    332                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    333 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    334 //                      FirstOtherAtom->x.Output(out);
    335 //                      *out << endl;
    336 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    337 //                      SecondOtherAtom->x.Output(out);
    338 //                      *out << endl;
    339                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    340                         Binder->Cyclic = false;
    341                         Binder->Type = TreeEdge;
    342                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    343                         Binder->Cyclic = false;
    344                         Binder->Type = TreeEdge;
    345                         break;
    346                 case 3:
    347                         // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
    348                         FirstOtherAtom = new atom();
    349                         SecondOtherAtom = new atom();
    350                         ThirdOtherAtom = new atom();
    351                         FirstOtherAtom->type = elemente->FindElement(1);
    352                         SecondOtherAtom->type = elemente->FindElement(1);
    353                         ThirdOtherAtom->type = elemente->FindElement(1);
    354                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    355                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    356                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    357                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    358                         ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    359                         ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
    360                         FirstOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    361                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    362                         ThirdOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    363 
    364                         // we need to vectors orthonormal the InBondvector
    365                         AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
    366 //                      *out << Verbose(3) << "Orthovector1: ";
    367 //                      Orthovector1.Output(out);
    368 //                      *out << endl;
    369                         AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    370 //                      *out << Verbose(3) << "Orthovector2: ";
    371 //                      Orthovector2.Output(out);
    372 //                      *out << endl;
    373 
    374                         // create correct coordination for the three atoms
    375                         alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
    376                         l = BondRescale;                                // desired bond length
    377                         b = 2.*l*sin(alpha);            // base length of isosceles triangle
    378                         d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);    // length for InBondvector
    379                         f = b/sqrt(3.); // length for Orthvector1
    380                         g = b/2.;                                // length for Orthvector2
    381 //                      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
    382 //                      *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;
    383                         factors[0] = d;
    384                         factors[1] = f;
    385                         factors[2] = 0.;
    386                         FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387                         factors[1] = -0.5*f;
    388                         factors[2] = g;
    389                         SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    390                         factors[2] = -g;
    391                         ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    392 
    393                         // rescale each to correct BondDistance
    394 //                      FirstOtherAtom->x.Scale(&BondRescale);
    395 //                      SecondOtherAtom->x.Scale(&BondRescale);
    396 //                      ThirdOtherAtom->x.Scale(&BondRescale);
    397 
    398                         // and relative to *origin atom
    399                         FirstOtherAtom->x.AddVector(&TopOrigin->x);
    400                         SecondOtherAtom->x.AddVector(&TopOrigin->x);
    401                         ThirdOtherAtom->x.AddVector(&TopOrigin->x);
    402 
    403                         // ... and add to molecule
    404                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    405                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    406                         AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
    407 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    408 //                      FirstOtherAtom->x.Output(out);
    409 //                      *out << endl;
    410 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    411 //                      SecondOtherAtom->x.Output(out);
    412 //                      *out << endl;
    413 //                      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
    414 //                      ThirdOtherAtom->x.Output(out);
    415 //                      *out << endl;
    416                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    417                         Binder->Cyclic = false;
    418                         Binder->Type = TreeEdge;
    419                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    420                         Binder->Cyclic = false;
    421                         Binder->Type = TreeEdge;
    422                         Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
    423                         Binder->Cyclic = false;
    424                         Binder->Type = TreeEdge;
    425                         break;
    426                 default:
    427                         cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
    428                         AllWentWell = false;
    429                         break;
    430         }
    431 
    432 //      *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
    433         return AllWentWell;
     179  double bondlength;  // bond length of the bond to be replaced/cut
     180  double bondangle;  // bond angle of the bond to be replaced/cut
     181  double BondRescale;  // rescale value for the hydrogen bond length
     182  bool AllWentWell = true;    // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
     183  bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
     184  atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
     185  double b,l,d,f,g, alpha, factors[NDIM];    // hold temporary values in triple bond case for coordination determination
     186  Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
     187  Vector InBondvector;    // vector in direction of *Bond
     188  bond *Binder = NULL;
     189  double *matrix;
     190
     191//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     192  // create vector in direction of bond
     193  InBondvector.CopyVector(&TopReplacement->x);
     194  InBondvector.SubtractVector(&TopOrigin->x);
     195  bondlength = InBondvector.Norm();
     196
     197  // is greater than typical bond distance? Then we have to correct periodically
     198  // the problem is not the H being out of the box, but InBondvector have the wrong direction
     199  // due to TopReplacement or Origin being on the wrong side!
     200  if (bondlength > BondDistance) {
     201//    *out << Verbose(4) << "InBondvector is: ";
     202//    InBondvector.Output(out);
     203//    *out << endl;
     204    Orthovector1.Zero();
     205    for (int i=NDIM;i--;) {
     206      l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
     207      if (fabs(l) > BondDistance) { // is component greater than bond distance
     208        Orthovector1.x[i] = (l < 0) ? -1. : +1.;
     209      } // (signs are correct, was tested!)
     210    }
     211    matrix = ReturnFullMatrixforSymmetric(cell_size);
     212    Orthovector1.MatrixMultiplication(matrix);
     213    InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
     214    Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
     215    bondlength = InBondvector.Norm();
     216//    *out << Verbose(4) << "Corrected InBondvector is now: ";
     217//    InBondvector.Output(out);
     218//    *out << endl;
     219  } // periodic correction finished
     220
     221  InBondvector.Normalize();
     222  // get typical bond length and store as scale factor for later
     223  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
     224  if (BondRescale == -1) {
     225    cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     226    return false;
     227    BondRescale = bondlength;
     228  } else {
     229    if (!IsAngstroem)
     230      BondRescale /= (1.*AtomicLengthToAngstroem);
     231  }
     232
     233  // discern single, double and triple bonds
     234  switch(TopBond->BondDegree) {
     235    case 1:
     236      FirstOtherAtom = new atom();    // new atom
     237      FirstOtherAtom->type = elemente->FindElement(1);  // element is Hydrogen
     238      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     239      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     240      if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
     241        FirstOtherAtom->father = TopReplacement;
     242        BondRescale = bondlength;
     243      } else {
     244        FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
     245      }
     246      InBondvector.Scale(&BondRescale);  // rescale the distance vector to Hydrogen bond length
     247      FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
     248      FirstOtherAtom->x.AddVector(&InBondvector);  // ... and add distance vector to replacement atom
     249      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     250//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     251//      FirstOtherAtom->x.Output(out);
     252//      *out << endl;
     253      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     254      Binder->Cyclic = false;
     255      Binder->Type = TreeEdge;
     256      break;
     257    case 2:
     258      // determine two other bonds (warning if there are more than two other) plus valence sanity check
     259      for (int i=0;i<NumBond;i++) {
     260        if (BondList[i] != TopBond) {
     261          if (FirstBond == NULL) {
     262            FirstBond = BondList[i];
     263            FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     264          } else if (SecondBond == NULL) {
     265            SecondBond = BondList[i];
     266            SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     267          } else {
     268            *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     269          }
     270        }
     271      }
     272      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)
     273        SecondBond = TopBond;
     274        SecondOtherAtom = TopReplacement;
     275      }
     276      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
     277//        *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;
     278
     279        // determine the plane of these two with the *origin
     280        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     281      } else {
     282        Orthovector1.GetOneNormalVector(&InBondvector);
     283      }
     284      //*out << Verbose(3)<< "Orthovector1: ";
     285      //Orthovector1.Output(out);
     286      //*out << endl;
     287      // orthogonal vector and bond vector between origin and replacement form the new plane
     288      Orthovector1.MakeNormalVector(&InBondvector);
     289      Orthovector1.Normalize();
     290      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
     291
     292      // create the two Hydrogens ...
     293      FirstOtherAtom = new atom();
     294      SecondOtherAtom = new atom();
     295      FirstOtherAtom->type = elemente->FindElement(1);
     296      SecondOtherAtom->type = elemente->FindElement(1);
     297      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     298      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     299      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     300      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     301      FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
     302      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     303      bondangle = TopOrigin->type->HBondAngle[1];
     304      if (bondangle == -1) {
     305        *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     306        return false;
     307        bondangle = 0;
     308      }
     309      bondangle *= M_PI/180./2.;
     310//      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
     311//      InBondvector.Output(out);
     312//      *out << endl;
     313//      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
     314//      Orthovector1.Output(out);
     315//      *out << endl;
     316//      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
     317      FirstOtherAtom->x.Zero();
     318      SecondOtherAtom->x.Zero();
     319      for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
     320        FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
     321        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
     322      }
     323      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     324      SecondOtherAtom->x.Scale(&BondRescale);
     325      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
     326      for(int i=NDIM;i--;) { // and make relative to origin atom
     327        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     328        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
     329      }
     330      // ... and add to molecule
     331      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     332      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     333//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     334//      FirstOtherAtom->x.Output(out);
     335//      *out << endl;
     336//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     337//      SecondOtherAtom->x.Output(out);
     338//      *out << endl;
     339      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     340      Binder->Cyclic = false;
     341      Binder->Type = TreeEdge;
     342      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     343      Binder->Cyclic = false;
     344      Binder->Type = TreeEdge;
     345      break;
     346    case 3:
     347      // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
     348      FirstOtherAtom = new atom();
     349      SecondOtherAtom = new atom();
     350      ThirdOtherAtom = new atom();
     351      FirstOtherAtom->type = elemente->FindElement(1);
     352      SecondOtherAtom->type = elemente->FindElement(1);
     353      ThirdOtherAtom->type = elemente->FindElement(1);
     354      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     355      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     356      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     357      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     358      ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     359      ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
     360      FirstOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     361      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     362      ThirdOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     363
     364      // we need to vectors orthonormal the InBondvector
     365      AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
     366//      *out << Verbose(3) << "Orthovector1: ";
     367//      Orthovector1.Output(out);
     368//      *out << endl;
     369      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
     370//      *out << Verbose(3) << "Orthovector2: ";
     371//      Orthovector2.Output(out);
     372//      *out << endl;
     373
     374      // create correct coordination for the three atoms
     375      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     376      l = BondRescale;        // desired bond length
     377      b = 2.*l*sin(alpha);    // base length of isosceles triangle
     378      d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);  // length for InBondvector
     379      f = b/sqrt(3.);  // length for Orthvector1
     380      g = b/2.;        // length for Orthvector2
     381//      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
     382//      *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;
     383      factors[0] = d;
     384      factors[1] = f;
     385      factors[2] = 0.;
     386      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     387      factors[1] = -0.5*f;
     388      factors[2] = g;
     389      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     390      factors[2] = -g;
     391      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     392
     393      // rescale each to correct BondDistance
     394//      FirstOtherAtom->x.Scale(&BondRescale);
     395//      SecondOtherAtom->x.Scale(&BondRescale);
     396//      ThirdOtherAtom->x.Scale(&BondRescale);
     397
     398      // and relative to *origin atom
     399      FirstOtherAtom->x.AddVector(&TopOrigin->x);
     400      SecondOtherAtom->x.AddVector(&TopOrigin->x);
     401      ThirdOtherAtom->x.AddVector(&TopOrigin->x);
     402
     403      // ... and add to molecule
     404      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     405      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     406      AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
     407//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     408//      FirstOtherAtom->x.Output(out);
     409//      *out << endl;
     410//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     411//      SecondOtherAtom->x.Output(out);
     412//      *out << endl;
     413//      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
     414//      ThirdOtherAtom->x.Output(out);
     415//      *out << endl;
     416      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     417      Binder->Cyclic = false;
     418      Binder->Type = TreeEdge;
     419      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     420      Binder->Cyclic = false;
     421      Binder->Type = TreeEdge;
     422      Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
     423      Binder->Cyclic = false;
     424      Binder->Type = TreeEdge;
     425      break;
     426    default:
     427      cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
     428      AllWentWell = false;
     429      break;
     430  }
     431
     432//  *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
     433  return AllWentWell;
    434434};
    435435
     
    441441bool molecule::AddXYZFile(string filename)
    442442{
    443         istringstream *input = NULL;
    444         int NumberOfAtoms = 0; // atom number in xyz read
    445         int i, j; // loop variables
    446         atom *Walker = NULL;    // pointer to added atom
    447         char shorthand[3];      // shorthand for atom name
    448         ifstream xyzfile;        // xyz file
    449         string line;            // currently parsed line
    450         double x[3];            // atom coordinates
    451 
    452         xyzfile.open(filename.c_str());
    453         if (!xyzfile)
    454                 return false;
    455 
    456         getline(xyzfile,line,'\n'); // Read numer of atoms in file
    457         input = new istringstream(line);
    458         *input >> NumberOfAtoms;
    459         cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    460         getline(xyzfile,line,'\n'); // Read comment
    461         cout << Verbose(1) << "Comment: " << line << endl;
    462 
    463         if (MDSteps == 0) // no atoms yet present
    464                 MDSteps++;
    465         for(i=0;i<NumberOfAtoms;i++){
    466                 Walker = new atom;
    467                 getline(xyzfile,line,'\n');
    468                 istringstream *item = new istringstream(line);
    469                 //istringstream input(line);
    470                 //cout << Verbose(1) << "Reading: " << line << endl;
    471                 *item >> shorthand;
    472                 *item >> x[0];
    473                 *item >> x[1];
    474                 *item >> x[2];
    475                 Walker->type = elemente->FindElement(shorthand);
    476                 if (Walker->type == NULL) {
    477                         cerr << "Could not parse the element at line: '" << line << "', setting to H.";
    478                         Walker->type = elemente->FindElement(1);
    479                 }
    480                 if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
    481                         Trajectories[Walker].R.resize(MDSteps+10);
    482                         Trajectories[Walker].U.resize(MDSteps+10);
    483                         Trajectories[Walker].F.resize(MDSteps+10);
    484                 }
    485                 for(j=NDIM;j--;) {
    486                         Walker->x.x[j] = x[j];
    487                         Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
    488                         Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
    489                         Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
    490                 }
    491                 AddAtom(Walker);        // add to molecule
    492                 delete(item);
    493         }
    494         xyzfile.close();
    495         delete(input);
    496         return true;
     443  istringstream *input = NULL;
     444  int NumberOfAtoms = 0; // atom number in xyz read
     445  int i, j; // loop variables
     446  atom *Walker = NULL;  // pointer to added atom
     447  char shorthand[3];  // shorthand for atom name
     448  ifstream xyzfile;  // xyz file
     449  string line;    // currently parsed line
     450  double x[3];    // atom coordinates
     451
     452  xyzfile.open(filename.c_str());
     453  if (!xyzfile)
     454    return false;
     455
     456  getline(xyzfile,line,'\n'); // Read numer of atoms in file
     457  input = new istringstream(line);
     458  *input >> NumberOfAtoms;
     459  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     460  getline(xyzfile,line,'\n'); // Read comment
     461  cout << Verbose(1) << "Comment: " << line << endl;
     462
     463  if (MDSteps == 0) // no atoms yet present
     464    MDSteps++;
     465  for(i=0;i<NumberOfAtoms;i++){
     466    Walker = new atom;
     467    getline(xyzfile,line,'\n');
     468    istringstream *item = new istringstream(line);
     469    //istringstream input(line);
     470    //cout << Verbose(1) << "Reading: " << line << endl;
     471    *item >> shorthand;
     472    *item >> x[0];
     473    *item >> x[1];
     474    *item >> x[2];
     475    Walker->type = elemente->FindElement(shorthand);
     476    if (Walker->type == NULL) {
     477      cerr << "Could not parse the element at line: '" << line << "', setting to H.";
     478      Walker->type = elemente->FindElement(1);
     479    }
     480    if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
     481      Trajectories[Walker].R.resize(MDSteps+10);
     482      Trajectories[Walker].U.resize(MDSteps+10);
     483      Trajectories[Walker].F.resize(MDSteps+10);
     484    }
     485    for(j=NDIM;j--;) {
     486      Walker->x.x[j] = x[j];
     487      Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
     488      Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
     489      Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
     490    }
     491    AddAtom(Walker);  // add to molecule
     492    delete(item);
     493  }
     494  xyzfile.close();
     495  delete(input);
     496  return true;
    497497};
    498498
     
    502502molecule *molecule::CopyMolecule()
    503503{
    504         molecule *copy = new molecule(elemente);
    505         atom *CurrentAtom = NULL;
    506         atom *LeftAtom = NULL, *RightAtom = NULL;
    507         atom *Walker = NULL;
    508 
    509         // copy all atoms
    510         Walker = start;
    511         while(Walker->next != end) {
    512                 Walker = Walker->next;
    513                 CurrentAtom = copy->AddCopyAtom(Walker);
    514         }
    515 
    516         // copy all bonds
    517         bond *Binder = first;
    518         bond *NewBond = NULL;
    519         while(Binder->next != last) {
    520                 Binder = Binder->next;
    521                 // get the pendant atoms of current bond in the copy molecule
    522                 LeftAtom = copy->start;
    523                 while (LeftAtom->next != copy->end) {
    524                         LeftAtom = LeftAtom->next;
    525                         if (LeftAtom->father == Binder->leftatom)
    526                                 break;
    527                 }
    528                 RightAtom = copy->start;
    529                 while (RightAtom->next != copy->end) {
    530                         RightAtom = RightAtom->next;
    531                         if (RightAtom->father == Binder->rightatom)
    532                                 break;
    533                 }
    534                 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
    535                 NewBond->Cyclic = Binder->Cyclic;
    536                 if (Binder->Cyclic)
    537                         copy->NoCyclicBonds++;
    538                 NewBond->Type = Binder->Type;
    539         }
    540         // correct fathers
    541         Walker = copy->start;
    542         while(Walker->next != copy->end) {
    543                 Walker = Walker->next;
    544                 if (Walker->father->father == Walker->father)    // same atom in copy's father points to itself
    545                         Walker->father = Walker;        // set father to itself (copy of a whole molecule)
    546                 else
    547                  Walker->father = Walker->father->father;       // set father to original's father
    548         }
    549         // copy values
    550         copy->CountAtoms((ofstream *)&cout);
    551         copy->CountElements();
    552         if (first->next != last) {      // if adjaceny list is present
    553                 copy->BondDistance = BondDistance;
    554                 copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    555         }
    556 
    557         return copy;
     504  molecule *copy = new molecule(elemente);
     505  atom *CurrentAtom = NULL;
     506  atom *LeftAtom = NULL, *RightAtom = NULL;
     507  atom *Walker = NULL;
     508
     509  // copy all atoms
     510  Walker = start;
     511  while(Walker->next != end) {
     512    Walker = Walker->next;
     513    CurrentAtom = copy->AddCopyAtom(Walker);
     514  }
     515
     516  // copy all bonds
     517  bond *Binder = first;
     518  bond *NewBond = NULL;
     519  while(Binder->next != last) {
     520    Binder = Binder->next;
     521    // get the pendant atoms of current bond in the copy molecule
     522    LeftAtom = copy->start;
     523    while (LeftAtom->next != copy->end) {
     524      LeftAtom = LeftAtom->next;
     525      if (LeftAtom->father == Binder->leftatom)
     526        break;
     527    }
     528    RightAtom = copy->start;
     529    while (RightAtom->next != copy->end) {
     530      RightAtom = RightAtom->next;
     531      if (RightAtom->father == Binder->rightatom)
     532        break;
     533    }
     534    NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
     535    NewBond->Cyclic = Binder->Cyclic;
     536    if (Binder->Cyclic)
     537      copy->NoCyclicBonds++;
     538    NewBond->Type = Binder->Type;
     539  }
     540  // correct fathers
     541  Walker = copy->start;
     542  while(Walker->next != copy->end) {
     543    Walker = Walker->next;
     544    if (Walker->father->father == Walker->father)  // same atom in copy's father points to itself
     545      Walker->father = Walker;  // set father to itself (copy of a whole molecule)
     546    else
     547     Walker->father = Walker->father->father;  // set father to original's father
     548  }
     549  // copy values
     550  copy->CountAtoms((ofstream *)&cout);
     551  copy->CountElements();
     552  if (first->next != last) {  // if adjaceny list is present
     553    copy->BondDistance = BondDistance;
     554    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
     555  }
     556
     557  return copy;
    558558};
    559559
     
    566566bond * molecule::AddBond(atom *atom1, atom *atom2, int degree=1)
    567567{
    568         bond *Binder = NULL;
    569         if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    570                 Binder = new bond(atom1, atom2, degree, BondCount++);
    571                 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    572                         NoNonBonds++;
    573                 add(Binder, last);
    574         } else {
    575                 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;
    576         }
    577         return Binder;
     568  bond *Binder = NULL;
     569  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
     570    Binder = new bond(atom1, atom2, degree, BondCount++);
     571    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
     572      NoNonBonds++;
     573    add(Binder, last);
     574  } else {
     575    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;
     576  }
     577  return Binder;
    578578};
    579579
     
    585585bool molecule::RemoveBond(bond *pointer)
    586586{
    587         //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    588         removewithoutcheck(pointer);
    589         return true;
     587  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     588  removewithoutcheck(pointer);
     589  return true;
    590590};
    591591
     
    597597bool molecule::RemoveBonds(atom *BondPartner)
    598598{
    599         cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    600         return false;
     599  cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     600  return false;
    601601};
    602602
     
    622622void molecule::SetBoxDimension(Vector *dim)
    623623{
    624         cell_size[0] = dim->x[0];
    625         cell_size[1] = 0.;
    626         cell_size[2] = dim->x[1];
    627         cell_size[3] = 0.;
    628         cell_size[4] = 0.;
    629         cell_size[5] = dim->x[2];
     624  cell_size[0] = dim->x[0];
     625  cell_size[1] = 0.;
     626  cell_size[2] = dim->x[1];
     627  cell_size[3] = 0.;
     628  cell_size[4] = 0.;
     629  cell_size[5] = dim->x[2];
    630630};
    631631
     
    636636bool molecule::CenterInBox(ofstream *out, Vector *BoxLengths)
    637637{
    638         bool status = true;
    639         atom *ptr = NULL;
    640         Vector *min = new Vector;
    641         Vector *max = new Vector;
    642 
    643         // gather min and max for each axis
    644         ptr = start->next;      // start at first in list
    645         if (ptr != end) {        //list not empty?
    646                 for (int i=NDIM;i--;) {
    647                         max->x[i] = ptr->x.x[i];
    648                         min->x[i] = ptr->x.x[i];
    649                 }
    650                 while (ptr->next != end) {      // continue with second if present
    651                         ptr = ptr->next;
    652                         //ptr->Output(1,1,out);
    653                         for (int i=NDIM;i--;) {
    654                                 max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    655                                 min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    656                         }
    657                 }
    658         }
    659         // sanity check
    660         for(int i=NDIM;i--;) {
    661                 if (max->x[i] - min->x[i] > BoxLengths->x[i])
    662                         status = false;
    663         }
    664         // warn if check failed
    665         if (!status)
    666                 *out << "WARNING: molecule is bigger than defined box!" << endl;
    667         else {  // else center in box
    668                 max->AddVector(min);
    669                 max->Scale(-1.);
    670                 max->AddVector(BoxLengths);
    671                 max->Scale(0.5);
     638  bool status = true;
     639  atom *ptr = NULL;
     640  Vector *min = new Vector;
     641  Vector *max = new Vector;
     642
     643  // gather min and max for each axis
     644  ptr = start->next;  // start at first in list
     645  if (ptr != end) {  //list not empty?
     646    for (int i=NDIM;i--;) {
     647      max->x[i] = ptr->x.x[i];
     648      min->x[i] = ptr->x.x[i];
     649    }
     650    while (ptr->next != end) {  // continue with second if present
     651      ptr = ptr->next;
     652      //ptr->Output(1,1,out);
     653      for (int i=NDIM;i--;) {
     654        max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     655        min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     656      }
     657    }
     658  }
     659  // sanity check
     660  for(int i=NDIM;i--;) {
     661    if (max->x[i] - min->x[i] > BoxLengths->x[i])
     662      status = false;
     663  }
     664  // warn if check failed
     665  if (!status)
     666    *out << "WARNING: molecule is bigger than defined box!" << endl;
     667  else {  // else center in box
     668    max->AddVector(min);
     669    max->Scale(-1.);
     670    max->AddVector(BoxLengths);
     671    max->Scale(0.5);
    672672    Translate(max);
    673673    Center.Zero();
    674         }
    675 
    676         // free and exit
    677         delete(min);
    678         delete(max);
    679         return status;
     674  }
     675
     676  // free and exit
     677  delete(min);
     678  delete(max);
     679  return status;
    680680};
    681681
     
    686686void molecule::CenterEdge(ofstream *out, Vector *max)
    687687{
    688         Vector *min = new Vector;
    689 
    690 //      *out << Verbose(3) << "Begin of CenterEdge." << endl;
    691         atom *ptr = start->next;        // start at first in list
    692         if (ptr != end) {        //list not empty?
    693                 for (int i=NDIM;i--;) {
    694                         max->x[i] = ptr->x.x[i];
    695                         min->x[i] = ptr->x.x[i];
    696                 }
    697                 while (ptr->next != end) {      // continue with second if present
    698                         ptr = ptr->next;
    699                         //ptr->Output(1,1,out);
    700                         for (int i=NDIM;i--;) {
    701                                 max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    702                                 min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    703                         }
    704                 }
    705 //              *out << Verbose(4) << "Maximum is ";
    706 //              max->Output(out);
    707 //              *out << ", Minimum is ";
    708 //              min->Output(out);
    709 //              *out << endl;
    710                 min->Scale(-1.);
    711                 max->AddVector(min);
    712                 Translate(min);
    713                 Center.Zero();
    714         }
    715         delete(min);
    716 //      *out << Verbose(3) << "End of CenterEdge." << endl;
     688  Vector *min = new Vector;
     689
     690//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
     691  atom *ptr = start->next;  // start at first in list
     692  if (ptr != end) {  //list not empty?
     693    for (int i=NDIM;i--;) {
     694      max->x[i] = ptr->x.x[i];
     695      min->x[i] = ptr->x.x[i];
     696    }
     697    while (ptr->next != end) {  // continue with second if present
     698      ptr = ptr->next;
     699      //ptr->Output(1,1,out);
     700      for (int i=NDIM;i--;) {
     701        max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     702        min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     703      }
     704    }
     705//    *out << Verbose(4) << "Maximum is ";
     706//    max->Output(out);
     707//    *out << ", Minimum is ";
     708//    min->Output(out);
     709//    *out << endl;
     710    min->Scale(-1.);
     711    max->AddVector(min);
     712    Translate(min);
     713    Center.Zero();
     714  }
     715  delete(min);
     716//  *out << Verbose(3) << "End of CenterEdge." << endl;
    717717};
    718718
     
    723723void molecule::CenterOrigin(ofstream *out)
    724724{
    725         int Num = 0;
    726         atom *ptr = start->next;        // start at first in list
    727 
    728         Center.Zero();
    729 
    730         if (ptr != end) {        //list not empty?
    731                 while (ptr->next != end) {      // continue with second if present
    732                         ptr = ptr->next;
    733                         Num++;
    734                         Center.AddVector(&ptr->x);
    735                 }
    736                 Center.Scale(-1./Num); // divide through total number (and sign for direction)
    737           Translate(&Center);
    738           Center.Zero();
    739         }
     725  int Num = 0;
     726  atom *ptr = start->next;  // start at first in list
     727
     728  Center.Zero();
     729
     730  if (ptr != end) {  //list not empty?
     731    while (ptr->next != end) {  // continue with second if present
     732      ptr = ptr->next;
     733      Num++;
     734      Center.AddVector(&ptr->x);
     735    }
     736    Center.Scale(-1./Num); // divide through total number (and sign for direction)
     737    Translate(&Center);
     738    Center.Zero();
     739  }
    740740};
    741741
     
    746746Vector * molecule::DetermineCenterOfAll(ofstream *out)
    747747{
    748         atom *ptr = start->next;        // start at first in list
    749         Vector *a = new Vector();
    750         Vector tmp;
    751         double Num = 0;
    752 
    753         a->Zero();
    754 
    755         if (ptr != end) {        //list not empty?
    756                 while (ptr->next != end) {      // continue with second if present
    757                         ptr = ptr->next;
    758                         Num += 1.;
    759                         tmp.CopyVector(&ptr->x);
    760                         a->AddVector(&tmp);
    761                 }
    762                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    763         }
    764         //cout << Verbose(1) << "Resulting center of gravity: ";
    765         //a->Output(out);
    766         //cout << endl;
    767         return a;
     748  atom *ptr = start->next;  // start at first in list
     749  Vector *a = new Vector();
     750  Vector tmp;
     751  double Num = 0;
     752
     753  a->Zero();
     754
     755  if (ptr != end) {  //list not empty?
     756    while (ptr->next != end) {  // continue with second if present
     757      ptr = ptr->next;
     758      Num += 1.;
     759      tmp.CopyVector(&ptr->x);
     760      a->AddVector(&tmp);
     761    }
     762    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     763  }
     764  //cout << Verbose(1) << "Resulting center of gravity: ";
     765  //a->Output(out);
     766  //cout << endl;
     767  return a;
    768768};
    769769
     
    774774Vector * molecule::DetermineCenterOfGravity(ofstream *out)
    775775{
    776         atom *ptr = start->next;        // start at first in list
    777         Vector *a = new Vector();
    778         Vector tmp;
    779         double Num = 0;
    780 
    781         a->Zero();
    782 
    783         if (ptr != end) {        //list not empty?
    784                 while (ptr->next != end) {      // continue with second if present
    785                         ptr = ptr->next;
    786                         Num += ptr->type->mass;
    787                         tmp.CopyVector(&ptr->x);
    788                         tmp.Scale(ptr->type->mass);     // scale by mass
    789                         a->AddVector(&tmp);
    790                 }
    791                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    792         }
    793 //      *out << Verbose(1) << "Resulting center of gravity: ";
    794 //      a->Output(out);
    795 //      *out << endl;
    796         return a;
     776  atom *ptr = start->next;  // start at first in list
     777  Vector *a = new Vector();
     778  Vector tmp;
     779  double Num = 0;
     780
     781  a->Zero();
     782
     783  if (ptr != end) {  //list not empty?
     784    while (ptr->next != end) {  // continue with second if present
     785      ptr = ptr->next;
     786      Num += ptr->type->mass;
     787      tmp.CopyVector(&ptr->x);
     788      tmp.Scale(ptr->type->mass);  // scale by mass
     789      a->AddVector(&tmp);
     790    }
     791    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     792  }
     793//  *out << Verbose(1) << "Resulting center of gravity: ";
     794//  a->Output(out);
     795//  *out << endl;
     796  return a;
    797797};
    798798
     
    803803void molecule::CenterPeriodic(ofstream *out)
    804804{
    805         DeterminePeriodicCenter(Center);
     805  DeterminePeriodicCenter(Center);
    806806};
    807807
     
    820820void molecule::Scale(double **factor)
    821821{
    822         atom *ptr = start;
    823 
    824         while (ptr->next != end) {
    825                 ptr = ptr->next;
    826                 for (int j=0;j<MDSteps;j++)
    827                         Trajectories[ptr].R.at(j).Scale(factor);
    828                 ptr->x.Scale(factor);
    829         }
     822  atom *ptr = start;
     823
     824  while (ptr->next != end) {
     825    ptr = ptr->next;
     826    for (int j=0;j<MDSteps;j++)
     827      Trajectories[ptr].R.at(j).Scale(factor);
     828    ptr->x.Scale(factor);
     829  }
    830830};
    831831
     
    835835void molecule::Translate(const Vector *trans)
    836836{
    837         atom *ptr = start;
    838 
    839         while (ptr->next != end) {
    840                 ptr = ptr->next;
    841                 for (int j=0;j<MDSteps;j++)
    842                         Trajectories[ptr].R.at(j).Translate(trans);
    843                 ptr->x.Translate(trans);
    844         }
     837  atom *ptr = start;
     838
     839  while (ptr->next != end) {
     840    ptr = ptr->next;
     841    for (int j=0;j<MDSteps;j++)
     842      Trajectories[ptr].R.at(j).Translate(trans);
     843    ptr->x.Translate(trans);
     844  }
    845845};
    846846
     
    850850void molecule::Mirror(const Vector *n)
    851851{
    852         atom *ptr = start;
    853 
    854         while (ptr->next != end) {
    855                 ptr = ptr->next;
    856                 for (int j=0;j<MDSteps;j++)
    857                         Trajectories[ptr].R.at(j).Mirror(n);
    858                 ptr->x.Mirror(n);
    859         }
     852  atom *ptr = start;
     853
     854  while (ptr->next != end) {
     855    ptr = ptr->next;
     856    for (int j=0;j<MDSteps;j++)
     857      Trajectories[ptr].R.at(j).Mirror(n);
     858    ptr->x.Mirror(n);
     859  }
    860860};
    861861
     
    865865void molecule::DeterminePeriodicCenter(Vector &center)
    866866{
    867         atom *Walker = start;
    868         bond *Binder = NULL;
    869         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    870         double tmp;
    871         bool flag;
    872         Vector Testvector, Translationvector;
    873 
    874         do {
    875                 center.Zero();
    876                 flag = true;
    877                 while (Walker->next != end) {
    878                         Walker = Walker->next;
     867  atom *Walker = start;
     868  bond *Binder = NULL;
     869  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     870  double tmp;
     871  bool flag;
     872  Vector Testvector, Translationvector;
     873
     874  do {
     875    center.Zero();
     876    flag = true;
     877    while (Walker->next != end) {
     878      Walker = Walker->next;
    879879#ifdef ADDHYDROGEN
    880                         if (Walker->type->Z != 1) {
     880      if (Walker->type->Z != 1) {
    881881#endif
    882                                 Testvector.CopyVector(&Walker->x);
    883                                 Testvector.InverseMatrixMultiplication(matrix);
    884                                 Translationvector.Zero();
    885                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    886                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    887                                         if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    888                                                 for (int j=0;j<NDIM;j++) {
    889                                                         tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    890                                                         if ((fabs(tmp)) > BondDistance) {
    891                                                                 flag = false;
    892                                                                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
    893                                                                 if (tmp > 0)
    894                                                                         Translationvector.x[j] -= 1.;
    895                                                                 else
    896                                                                         Translationvector.x[j] += 1.;
    897                                                         }
    898                                                 }
    899                                 }
    900                                 Testvector.AddVector(&Translationvector);
    901                                 Testvector.MatrixMultiplication(matrix);
    902                                 center.AddVector(&Testvector);
    903                                 cout << Verbose(1) << "vector is: ";
    904                                 Testvector.Output((ofstream *)&cout);
    905                                 cout << endl;
     882        Testvector.CopyVector(&Walker->x);
     883        Testvector.InverseMatrixMultiplication(matrix);
     884        Translationvector.Zero();
     885        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     886          Binder = ListOfBondsPerAtom[Walker->nr][i];
     887          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     888            for (int j=0;j<NDIM;j++) {
     889              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     890              if ((fabs(tmp)) > BondDistance) {
     891                flag = false;
     892                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     893                if (tmp > 0)
     894                  Translationvector.x[j] -= 1.;
     895                else
     896                  Translationvector.x[j] += 1.;
     897              }
     898            }
     899        }
     900        Testvector.AddVector(&Translationvector);
     901        Testvector.MatrixMultiplication(matrix);
     902        center.AddVector(&Testvector);
     903        cout << Verbose(1) << "vector is: ";
     904        Testvector.Output((ofstream *)&cout);
     905        cout << endl;
    906906#ifdef ADDHYDROGEN
    907                                 // now also change all hydrogens
    908                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    909                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    910                                         if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    911                                                 Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
    912                                                 Testvector.InverseMatrixMultiplication(matrix);
    913                                                 Testvector.AddVector(&Translationvector);
    914                                                 Testvector.MatrixMultiplication(matrix);
    915                                                 center.AddVector(&Testvector);
    916                                                 cout << Verbose(1) << "Hydrogen vector is: ";
    917                                                 Testvector.Output((ofstream *)&cout);
    918                                                 cout << endl;
    919                                         }
    920                                 }
    921                         }
     907        // now also change all hydrogens
     908        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     909          Binder = ListOfBondsPerAtom[Walker->nr][i];
     910          if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
     911            Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     912            Testvector.InverseMatrixMultiplication(matrix);
     913            Testvector.AddVector(&Translationvector);
     914            Testvector.MatrixMultiplication(matrix);
     915            center.AddVector(&Testvector);
     916            cout << Verbose(1) << "Hydrogen vector is: ";
     917            Testvector.Output((ofstream *)&cout);
     918            cout << endl;
     919          }
     920        }
     921      }
    922922#endif
    923                 }
    924         } while (!flag);
    925         Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
    926         center.Scale(1./(double)AtomCount);
     923    }
     924  } while (!flag);
     925  Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
     926  center.Scale(1./(double)AtomCount);
    927927};
    928928
     
    933933void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate)
    934934{
    935         atom *ptr = start;      // start at first in list
    936         double InertiaTensor[NDIM*NDIM];
    937         Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    938 
    939         CenterAtVector(out, CenterOfGravity);
    940 
    941         // reset inertia tensor
    942         for(int i=0;i<NDIM*NDIM;i++)
    943                 InertiaTensor[i] = 0.;
    944 
    945         // sum up inertia tensor
    946         while (ptr->next != end) {
    947                 ptr = ptr->next;
    948                 Vector x;
    949                 x.CopyVector(&ptr->x);
    950                 //x.SubtractVector(CenterOfGravity);
    951                 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    952                 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    953                 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    954                 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    955                 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    956                 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    957                 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    958                 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    959                 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    960         }
    961         // print InertiaTensor for debugging
    962         *out << "The inertia tensor is:" << endl;
    963         for(int i=0;i<NDIM;i++) {
    964                 for(int j=0;j<NDIM;j++)
    965                         *out << InertiaTensor[i*NDIM+j] << " ";
    966                 *out << endl;
    967         }
    968         *out << endl;
    969 
    970         // diagonalize to determine principal axis system
    971         gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
    972         gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
    973         gsl_vector *eval = gsl_vector_alloc(NDIM);
    974         gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
    975         gsl_eigen_symmv(&m.matrix, eval, evec, T);
    976         gsl_eigen_symmv_free(T);
    977         gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    978 
    979         for(int i=0;i<NDIM;i++) {
    980                 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    981                 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    982         }
    983 
    984         // check whether we rotate or not
    985         if (DoRotate) {
    986                 *out << Verbose(1) << "Transforming molecule into PAS ... ";
    987                 // the eigenvectors specify the transformation matrix
    988                 ptr = start;
    989                 while (ptr->next != end) {
    990                         ptr = ptr->next;
    991                         for (int j=0;j<MDSteps;j++)
    992                                 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
    993                         ptr->x.MatrixMultiplication(evec->data);
    994                 }
    995                 *out << "done." << endl;
    996 
    997                 // summing anew for debugging (resulting matrix has to be diagonal!)
    998                 // reset inertia tensor
    999                 for(int i=0;i<NDIM*NDIM;i++)
    1000                         InertiaTensor[i] = 0.;
    1001 
    1002                 // sum up inertia tensor
    1003                 ptr = start;
    1004                 while (ptr->next != end) {
    1005                         ptr = ptr->next;
    1006                         Vector x;
    1007                         x.CopyVector(&ptr->x);
    1008                         //x.SubtractVector(CenterOfGravity);
    1009                         InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    1010                         InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    1011                         InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    1012                         InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    1013                         InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    1014                         InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    1015                         InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    1016                         InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    1017                         InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    1018                 }
    1019                 // print InertiaTensor for debugging
    1020                 *out << "The inertia tensor is:" << endl;
    1021                 for(int i=0;i<NDIM;i++) {
    1022                         for(int j=0;j<NDIM;j++)
    1023                                 *out << InertiaTensor[i*NDIM+j] << " ";
    1024                         *out << endl;
    1025                 }
    1026                 *out << endl;
    1027         }
    1028 
    1029         // free everything
    1030         delete(CenterOfGravity);
    1031         gsl_vector_free(eval);
    1032         gsl_matrix_free(evec);
     935  atom *ptr = start;  // start at first in list
     936  double InertiaTensor[NDIM*NDIM];
     937  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
     938
     939  CenterAtVector(out, CenterOfGravity);
     940
     941  // reset inertia tensor
     942  for(int i=0;i<NDIM*NDIM;i++)
     943    InertiaTensor[i] = 0.;
     944
     945  // sum up inertia tensor
     946  while (ptr->next != end) {
     947    ptr = ptr->next;
     948    Vector x;
     949    x.CopyVector(&ptr->x);
     950    //x.SubtractVector(CenterOfGravity);
     951    InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     952    InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     953    InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     954    InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     955    InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     956    InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     957    InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     958    InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     959    InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     960  }
     961  // print InertiaTensor for debugging
     962  *out << "The inertia tensor is:" << endl;
     963  for(int i=0;i<NDIM;i++) {
     964    for(int j=0;j<NDIM;j++)
     965      *out << InertiaTensor[i*NDIM+j] << " ";
     966    *out << endl;
     967  }
     968  *out << endl;
     969
     970  // diagonalize to determine principal axis system
     971  gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     972  gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
     973  gsl_vector *eval = gsl_vector_alloc(NDIM);
     974  gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
     975  gsl_eigen_symmv(&m.matrix, eval, evec, T);
     976  gsl_eigen_symmv_free(T);
     977  gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
     978
     979  for(int i=0;i<NDIM;i++) {
     980    *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
     981    *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
     982  }
     983
     984  // check whether we rotate or not
     985  if (DoRotate) {
     986    *out << Verbose(1) << "Transforming molecule into PAS ... ";
     987    // the eigenvectors specify the transformation matrix
     988    ptr = start;
     989    while (ptr->next != end) {
     990      ptr = ptr->next;
     991      for (int j=0;j<MDSteps;j++)
     992        Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
     993      ptr->x.MatrixMultiplication(evec->data);
     994    }
     995    *out << "done." << endl;
     996
     997    // summing anew for debugging (resulting matrix has to be diagonal!)
     998    // reset inertia tensor
     999    for(int i=0;i<NDIM*NDIM;i++)
     1000      InertiaTensor[i] = 0.;
     1001
     1002    // sum up inertia tensor
     1003    ptr = start;
     1004    while (ptr->next != end) {
     1005      ptr = ptr->next;
     1006      Vector x;
     1007      x.CopyVector(&ptr->x);
     1008      //x.SubtractVector(CenterOfGravity);
     1009      InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     1010      InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     1011      InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     1012      InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     1013      InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     1014      InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     1015      InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     1016      InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     1017      InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     1018    }
     1019    // print InertiaTensor for debugging
     1020    *out << "The inertia tensor is:" << endl;
     1021    for(int i=0;i<NDIM;i++) {
     1022      for(int j=0;j<NDIM;j++)
     1023        *out << InertiaTensor[i*NDIM+j] << " ";
     1024      *out << endl;
     1025    }
     1026    *out << endl;
     1027  }
     1028
     1029  // free everything
     1030  delete(CenterOfGravity);
     1031  gsl_vector_free(eval);
     1032  gsl_matrix_free(evec);
    10331033};
    10341034
     
    10441044bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
    10451045{
    1046         element *runner = elemente->start;
    1047         atom *walker = NULL;
    1048         int AtomNo;
    1049         ifstream input(file);
    1050         string token;
    1051         stringstream item;
    1052         double a, IonMass;
    1053         ForceMatrix Force;
    1054         Vector tmpvector;
    1055 
    1056         CountElements();        // make sure ElementsInMolecule is up to date
    1057 
    1058         // check file
    1059         if (input == NULL) {
    1060                 return false;
    1061         } else {
    1062                 // parse file into ForceMatrix
    1063                 if (!Force.ParseMatrix(file, 0,0,0)) {
    1064                         cerr << "Could not parse Force Matrix file " << file << "." << endl;
    1065                         return false;
    1066                 }
    1067                 if (Force.RowCounter[0] != AtomCount) {
    1068                         cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
    1069                         return false;
    1070                 }
    1071                 // correct Forces
    1072 //              for(int d=0;d<NDIM;d++)
    1073 //                      tmpvector.x[d] = 0.;
    1074 //              for(int i=0;i<AtomCount;i++)
    1075 //                      for(int d=0;d<NDIM;d++) {
    1076 //                              tmpvector.x[d] += Force.Matrix[0][i][d+5];
    1077 //                      }
    1078 //              for(int i=0;i<AtomCount;i++)
    1079 //                      for(int d=0;d<NDIM;d++) {
    1080 //                              Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
    1081 //                      }
    1082                 // and perform Verlet integration for each atom with position, velocity and force vector
    1083                 runner = elemente->start;
    1084                 while (runner->next != elemente->end) { // go through every element
    1085                         runner = runner->next;
    1086                         IonMass = runner->mass;
    1087                         a = delta_t*0.5/IonMass;                                // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1088                         if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1089                                 AtomNo = 0;
    1090                                 walker = start;
    1091                                 while (walker->next != end) { // go through every atom of this element
    1092                                         walker = walker->next;
    1093                                         if (walker->type == runner) { // if this atom fits to element
    1094                                                 // check size of vectors
    1095                                                 if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1096                                                         //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1097                                                         Trajectories[walker].R.resize(MDSteps+10);
    1098                                                         Trajectories[walker].U.resize(MDSteps+10);
    1099                                                         Trajectories[walker].F.resize(MDSteps+10);
    1100                                                 }
    1101                                                 // 1. calculate x(t+\delta t)
    1102                                                 for (int d=0; d<NDIM; d++) {
    1103                                                         Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
    1104                                                         Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1105                                                         Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
    1106                                                         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
    1107                                                 }
    1108                                                 // 2. Calculate v(t+\delta t)
    1109                                                 for (int d=0; d<NDIM; d++) {
    1110                                                         Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1111                                                         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;
    1112                                                 }
    1113 //                                              cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1114 //                                              for (int d=0;d<NDIM;d++)
    1115 //                                                      cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";                                 // next step
    1116 //                                              cout << ")\t(";
    1117 //                                              for (int d=0;d<NDIM;d++)
    1118 //                                                      cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";                                 // next step
    1119 //                                              cout << ")" << endl;
    1120                                                 // next atom
    1121                                                 AtomNo++;
    1122                                         }
    1123                                 }
    1124                         }
    1125                 }
    1126         }
    1127 //      // correct velocities (rather momenta) so that center of mass remains motionless
    1128 //      tmpvector.zero()
    1129 //      IonMass = 0.;
    1130 //      walker = start;
    1131 //      while (walker->next != end) { // go through every atom
    1132 //              walker = walker->next;
    1133 //              IonMass += walker->type->mass;  // sum up total mass
    1134 //              for(int d=0;d<NDIM;d++) {
    1135 //                      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1136 //              }
    1137 //      }
    1138 //      walker = start;
    1139 //      while (walker->next != end) { // go through every atom of this element
    1140 //              walker = walker->next;
    1141 //              for(int d=0;d<NDIM;d++) {
    1142 //                      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
    1143 //              }
    1144 //      }
    1145         MDSteps++;
    1146 
    1147 
    1148         // exit
    1149         return true;
     1046  element *runner = elemente->start;
     1047  atom *walker = NULL;
     1048  int AtomNo;
     1049  ifstream input(file);
     1050  string token;
     1051  stringstream item;
     1052  double a, IonMass;
     1053  ForceMatrix Force;
     1054  Vector tmpvector;
     1055
     1056  CountElements();  // make sure ElementsInMolecule is up to date
     1057
     1058  // check file
     1059  if (input == NULL) {
     1060    return false;
     1061  } else {
     1062    // parse file into ForceMatrix
     1063    if (!Force.ParseMatrix(file, 0,0,0)) {
     1064      cerr << "Could not parse Force Matrix file " << file << "." << endl;
     1065      return false;
     1066    }
     1067    if (Force.RowCounter[0] != AtomCount) {
     1068      cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
     1069      return false;
     1070    }
     1071    // correct Forces
     1072//    for(int d=0;d<NDIM;d++)
     1073//      tmpvector.x[d] = 0.;
     1074//    for(int i=0;i<AtomCount;i++)
     1075//      for(int d=0;d<NDIM;d++) {
     1076//        tmpvector.x[d] += Force.Matrix[0][i][d+5];
     1077//      }
     1078//    for(int i=0;i<AtomCount;i++)
     1079//      for(int d=0;d<NDIM;d++) {
     1080//        Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
     1081//      }
     1082    // and perform Verlet integration for each atom with position, velocity and force vector
     1083    runner = elemente->start;
     1084    while (runner->next != elemente->end) { // go through every element
     1085      runner = runner->next;
     1086      IonMass = runner->mass;
     1087      a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1088      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1089        AtomNo = 0;
     1090        walker = start;
     1091        while (walker->next != end) { // go through every atom of this element
     1092          walker = walker->next;
     1093          if (walker->type == runner) { // if this atom fits to element
     1094            // check size of vectors
     1095            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1096              //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1097              Trajectories[walker].R.resize(MDSteps+10);
     1098              Trajectories[walker].U.resize(MDSteps+10);
     1099              Trajectories[walker].F.resize(MDSteps+10);
     1100            }
     1101            // 1. calculate x(t+\delta t)
     1102            for (int d=0; d<NDIM; d++) {
     1103              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
     1104              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1105              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1106              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
     1107            }
     1108            // 2. Calculate v(t+\delta t)
     1109            for (int d=0; d<NDIM; d++) {
     1110              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1111              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;
     1112            }
     1113//            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1114//            for (int d=0;d<NDIM;d++)
     1115//              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1116//            cout << ")\t(";
     1117//            for (int d=0;d<NDIM;d++)
     1118//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1119//            cout << ")" << endl;
     1120            // next atom
     1121            AtomNo++;
     1122          }
     1123        }
     1124      }
     1125    }
     1126  }
     1127//  // correct velocities (rather momenta) so that center of mass remains motionless
     1128//  tmpvector.zero()
     1129//  IonMass = 0.;
     1130//  walker = start;
     1131//  while (walker->next != end) { // go through every atom
     1132//    walker = walker->next;
     1133//    IonMass += walker->type->mass;  // sum up total mass
     1134//    for(int d=0;d<NDIM;d++) {
     1135//      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1136//    }
     1137//  }
     1138//  walker = start;
     1139//  while (walker->next != end) { // go through every atom of this element
     1140//    walker = walker->next;
     1141//    for(int d=0;d<NDIM;d++) {
     1142//      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
     1143//    }
     1144//  }
     1145  MDSteps++;
     1146
     1147
     1148  // exit
     1149  return true;
    11501150};
    11511151
     
    11551155void molecule::Align(Vector *n)
    11561156{
    1157         atom *ptr = start;
    1158         double alpha, tmp;
    1159         Vector z_axis;
    1160         z_axis.x[0] = 0.;
    1161         z_axis.x[1] = 0.;
    1162         z_axis.x[2] = 1.;
    1163 
    1164         // rotate on z-x plane
    1165         cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
    1166         alpha = atan(-n->x[0]/n->x[2]);
    1167         cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
    1168         while (ptr->next != end) {
    1169                 ptr = ptr->next;
    1170                 tmp = ptr->x.x[0];
    1171                 ptr->x.x[0] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1172                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1173                 for (int j=0;j<MDSteps;j++) {
    1174                         tmp = Trajectories[ptr].R.at(j).x[0];
    1175                         Trajectories[ptr].R.at(j).x[0] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1176                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1177                 }
    1178         }
    1179         // rotate n vector
    1180         tmp = n->x[0];
    1181         n->x[0] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1182         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1183         cout << Verbose(1) << "alignment vector after first rotation: ";
    1184         n->Output((ofstream *)&cout);
    1185         cout << endl;
    1186 
    1187         // rotate on z-y plane
    1188         ptr = start;
    1189         alpha = atan(-n->x[1]/n->x[2]);
    1190         cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
    1191         while (ptr->next != end) {
    1192                 ptr = ptr->next;
    1193                 tmp = ptr->x.x[1];
    1194                 ptr->x.x[1] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1195                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1196                 for (int j=0;j<MDSteps;j++) {
    1197                         tmp = Trajectories[ptr].R.at(j).x[1];
    1198                         Trajectories[ptr].R.at(j).x[1] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1199                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1200                 }
    1201         }
    1202         // rotate n vector (for consistency check)
    1203         tmp = n->x[1];
    1204         n->x[1] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1205         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1206 
    1207         cout << Verbose(1) << "alignment vector after second rotation: ";
    1208         n->Output((ofstream *)&cout);
    1209         cout << Verbose(1) << endl;
    1210         cout << Verbose(0) << "End of Aligning all atoms." << endl;
     1157  atom *ptr = start;
     1158  double alpha, tmp;
     1159  Vector z_axis;
     1160  z_axis.x[0] = 0.;
     1161  z_axis.x[1] = 0.;
     1162  z_axis.x[2] = 1.;
     1163
     1164  // rotate on z-x plane
     1165  cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
     1166  alpha = atan(-n->x[0]/n->x[2]);
     1167  cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
     1168  while (ptr->next != end) {
     1169    ptr = ptr->next;
     1170    tmp = ptr->x.x[0];
     1171    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1172    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1173    for (int j=0;j<MDSteps;j++) {
     1174      tmp = Trajectories[ptr].R.at(j).x[0];
     1175      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1176      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1177    }
     1178  }
     1179  // rotate n vector
     1180  tmp = n->x[0];
     1181  n->x[0] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1182  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1183  cout << Verbose(1) << "alignment vector after first rotation: ";
     1184  n->Output((ofstream *)&cout);
     1185  cout << endl;
     1186
     1187  // rotate on z-y plane
     1188  ptr = start;
     1189  alpha = atan(-n->x[1]/n->x[2]);
     1190  cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
     1191  while (ptr->next != end) {
     1192    ptr = ptr->next;
     1193    tmp = ptr->x.x[1];
     1194    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1195    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1196    for (int j=0;j<MDSteps;j++) {
     1197      tmp = Trajectories[ptr].R.at(j).x[1];
     1198      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1199      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1200    }
     1201  }
     1202  // rotate n vector (for consistency check)
     1203  tmp = n->x[1];
     1204  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1205  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1206
     1207  cout << Verbose(1) << "alignment vector after second rotation: ";
     1208  n->Output((ofstream *)&cout);
     1209  cout << Verbose(1) << endl;
     1210  cout << Verbose(0) << "End of Aligning all atoms." << endl;
    12111211};
    12121212
     
    12171217bool molecule::RemoveAtom(atom *pointer)
    12181218{
    1219         if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    1220                 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element
    1221         else
    1222                 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    1223         if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    1224                 ElementCount--;
    1225         Trajectories.erase(pointer);
    1226         return remove(pointer, start, end);
     1219  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1220    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
     1221  else
     1222    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1223  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     1224    ElementCount--;
     1225  Trajectories.erase(pointer);
     1226  return remove(pointer, start, end);
    12271227};
    12281228
     
    12511251bool molecule::CleanupMolecule()
    12521252{
    1253         return (cleanup(start,end) && cleanup(first,last));
     1253  return (cleanup(start,end) && cleanup(first,last));
    12541254};
    12551255
     
    12581258 * \return pointer to atom or NULL
    12591259 */
    1260 atom * molecule::FindAtom(int Nr)       const{
    1261         atom * walker = find(&Nr, start,end);
    1262         if (walker != NULL) {
    1263                 //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
    1264                 return walker;
    1265         } else {
    1266                 cout << Verbose(0) << "Atom not found in list." << endl;
    1267                 return NULL;
    1268         }
     1260atom * molecule::FindAtom(int Nr)  const{
     1261  atom * walker = find(&Nr, start,end);
     1262  if (walker != NULL) {
     1263    //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
     1264    return walker;
     1265  } else {
     1266    cout << Verbose(0) << "Atom not found in list." << endl;
     1267    return NULL;
     1268  }
    12691269};
    12701270
     
    12741274atom * molecule::AskAtom(string text)
    12751275{
    1276         int No;
    1277         atom *ion = NULL;
    1278         do {
    1279                 //cout << Verbose(0) << "============Atom list==========================" << endl;
    1280                 //mol->Output((ofstream *)&cout);
    1281                 //cout << Verbose(0) << "===============================================" << endl;
    1282                 cout << Verbose(0) << text;
    1283                 cin >> No;
    1284                 ion = this->FindAtom(No);
    1285         } while (ion == NULL);
    1286         return ion;
     1276  int No;
     1277  atom *ion = NULL;
     1278  do {
     1279    //cout << Verbose(0) << "============Atom list==========================" << endl;
     1280    //mol->Output((ofstream *)&cout);
     1281    //cout << Verbose(0) << "===============================================" << endl;
     1282    cout << Verbose(0) << text;
     1283    cin >> No;
     1284    ion = this->FindAtom(No);
     1285  } while (ion == NULL);
     1286  return ion;
    12871287};
    12881288
     
    12931293bool molecule::CheckBounds(const Vector *x) const
    12941294{
    1295         bool result = true;
    1296         int j =-1;
    1297         for (int i=0;i<NDIM;i++) {
    1298                 j += i+1;
    1299                 result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
    1300         }
    1301         //return result;
    1302         return true; /// probably not gonna use the check no more
     1295  bool result = true;
     1296  int j =-1;
     1297  for (int i=0;i<NDIM;i++) {
     1298    j += i+1;
     1299    result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
     1300  }
     1301  //return result;
     1302  return true; /// probably not gonna use the check no more
    13031303};
    13041304
     
    13101310double LeastSquareDistance (const gsl_vector * x, void * params)
    13111311{
    1312         double res = 0, t;
    1313         Vector a,b,c,d;
    1314         struct lsq_params *par = (struct lsq_params *)params;
    1315         atom *ptr = par->mol->start;
    1316 
    1317         // initialize vectors
    1318         a.x[0] = gsl_vector_get(x,0);
    1319         a.x[1] = gsl_vector_get(x,1);
    1320         a.x[2] = gsl_vector_get(x,2);
    1321         b.x[0] = gsl_vector_get(x,3);
    1322         b.x[1] = gsl_vector_get(x,4);
    1323         b.x[2] = gsl_vector_get(x,5);
    1324         // go through all atoms
    1325         while (ptr != par->mol->end) {
    1326                 ptr = ptr->next;
    1327                 if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
    1328                         c.CopyVector(&ptr->x);  // copy vector to temporary one
    1329                         c.SubtractVector(&a);    // subtract offset vector
    1330                         t = c.ScalarProduct(&b);                                        // get direction parameter
    1331                         d.CopyVector(&b);                        // and create vector
    1332                         d.Scale(&t);
    1333                         c.SubtractVector(&d);    // ... yielding distance vector
    1334                         res += d.ScalarProduct((const Vector *)&d);                             // add squared distance
    1335                 }
    1336         }
    1337         return res;
     1312  double res = 0, t;
     1313  Vector a,b,c,d;
     1314  struct lsq_params *par = (struct lsq_params *)params;
     1315  atom *ptr = par->mol->start;
     1316
     1317  // initialize vectors
     1318  a.x[0] = gsl_vector_get(x,0);
     1319  a.x[1] = gsl_vector_get(x,1);
     1320  a.x[2] = gsl_vector_get(x,2);
     1321  b.x[0] = gsl_vector_get(x,3);
     1322  b.x[1] = gsl_vector_get(x,4);
     1323  b.x[2] = gsl_vector_get(x,5);
     1324  // go through all atoms
     1325  while (ptr != par->mol->end) {
     1326    ptr = ptr->next;
     1327    if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
     1328      c.CopyVector(&ptr->x);  // copy vector to temporary one
     1329      c.SubtractVector(&a);  // subtract offset vector
     1330      t = c.ScalarProduct(&b);          // get direction parameter
     1331      d.CopyVector(&b);      // and create vector
     1332      d.Scale(&t);
     1333      c.SubtractVector(&d);  // ... yielding distance vector
     1334      res += d.ScalarProduct((const Vector *)&d);        // add squared distance
     1335    }
     1336  }
     1337  return res;
    13381338};
    13391339
     
    13431343void molecule::GetAlignvector(struct lsq_params * par) const
    13441344{
    1345                 int np = 6;
    1346 
    1347         const gsl_multimin_fminimizer_type *T =
    1348                 gsl_multimin_fminimizer_nmsimplex;
    1349         gsl_multimin_fminimizer *s = NULL;
    1350         gsl_vector *ss;
    1351         gsl_multimin_function minex_func;
    1352 
    1353         size_t iter = 0, i;
    1354         int status;
    1355         double size;
    1356 
    1357         /* Initial vertex size vector */
    1358         ss = gsl_vector_alloc (np);
    1359 
    1360         /* Set all step sizes to 1 */
    1361         gsl_vector_set_all (ss, 1.0);
    1362 
    1363         /* Starting point */
    1364         par->x = gsl_vector_alloc (np);
    1365         par->mol = this;
    1366 
    1367          gsl_vector_set (par->x, 0, 0.0);       // offset
    1368         gsl_vector_set (par->x, 1, 0.0);
    1369         gsl_vector_set (par->x, 2, 0.0);
    1370          gsl_vector_set (par->x, 3, 0.0);       // direction
    1371         gsl_vector_set (par->x, 4, 0.0);
    1372         gsl_vector_set (par->x, 5, 1.0);
    1373 
    1374         /* Initialize method and iterate */
    1375         minex_func.f = &LeastSquareDistance;
    1376         minex_func.n = np;
    1377         minex_func.params = (void *)par;
    1378 
    1379         s = gsl_multimin_fminimizer_alloc (T, np);
    1380         gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1381 
    1382         do
    1383                 {
    1384                         iter++;
    1385                         status = gsl_multimin_fminimizer_iterate(s);
    1386 
    1387                         if (status)
    1388                                 break;
    1389 
    1390                         size = gsl_multimin_fminimizer_size (s);
    1391                         status = gsl_multimin_test_size (size, 1e-2);
    1392 
    1393                         if (status == GSL_SUCCESS)
    1394                                 {
    1395                                         printf ("converged to minimum at\n");
    1396                                 }
    1397 
    1398                         printf ("%5d ", (int)iter);
    1399                         for (i = 0; i < (size_t)np; i++)
    1400                                 {
    1401                                         printf ("%10.3e ", gsl_vector_get (s->x, i));
    1402                                 }
    1403                         printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    1404                 }
    1405         while (status == GSL_CONTINUE && iter < 100);
    1406 
    1407         for (i=0;i<(size_t)np;i++)
    1408                 gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
    1409         //gsl_vector_free(par->x);
    1410         gsl_vector_free(ss);
    1411         gsl_multimin_fminimizer_free (s);
     1345    int np = 6;
     1346
     1347  const gsl_multimin_fminimizer_type *T =
     1348    gsl_multimin_fminimizer_nmsimplex;
     1349  gsl_multimin_fminimizer *s = NULL;
     1350  gsl_vector *ss;
     1351  gsl_multimin_function minex_func;
     1352
     1353  size_t iter = 0, i;
     1354  int status;
     1355  double size;
     1356
     1357  /* Initial vertex size vector */
     1358  ss = gsl_vector_alloc (np);
     1359
     1360  /* Set all step sizes to 1 */
     1361  gsl_vector_set_all (ss, 1.0);
     1362
     1363  /* Starting point */
     1364  par->x = gsl_vector_alloc (np);
     1365  par->mol = this;
     1366
     1367   gsl_vector_set (par->x, 0, 0.0);  // offset
     1368  gsl_vector_set (par->x, 1, 0.0);
     1369  gsl_vector_set (par->x, 2, 0.0);
     1370   gsl_vector_set (par->x, 3, 0.0);  // direction
     1371  gsl_vector_set (par->x, 4, 0.0);
     1372  gsl_vector_set (par->x, 5, 1.0);
     1373
     1374  /* Initialize method and iterate */
     1375  minex_func.f = &LeastSquareDistance;
     1376  minex_func.n = np;
     1377  minex_func.params = (void *)par;
     1378
     1379  s = gsl_multimin_fminimizer_alloc (T, np);
     1380  gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
     1381
     1382  do
     1383    {
     1384      iter++;
     1385      status = gsl_multimin_fminimizer_iterate(s);
     1386
     1387      if (status)
     1388        break;
     1389
     1390      size = gsl_multimin_fminimizer_size (s);
     1391      status = gsl_multimin_test_size (size, 1e-2);
     1392
     1393      if (status == GSL_SUCCESS)
     1394        {
     1395          printf ("converged to minimum at\n");
     1396        }
     1397
     1398      printf ("%5d ", (int)iter);
     1399      for (i = 0; i < (size_t)np; i++)
     1400        {
     1401          printf ("%10.3e ", gsl_vector_get (s->x, i));
     1402        }
     1403      printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     1404    }
     1405  while (status == GSL_CONTINUE && iter < 100);
     1406
     1407  for (i=0;i<(size_t)np;i++)
     1408    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     1409  //gsl_vector_free(par->x);
     1410  gsl_vector_free(ss);
     1411  gsl_multimin_fminimizer_free (s);
    14121412};
    14131413
     
    14171417bool molecule::Output(ofstream *out)
    14181418{
    1419         element *runner;
    1420         atom *walker = NULL;
    1421         int ElementNo, AtomNo;
    1422         CountElements();
    1423 
    1424         if (out == NULL) {
    1425                 return false;
    1426         } else {
    1427                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1428                 ElementNo = 0;
    1429                 runner = elemente->start;
    1430                 while (runner->next != elemente->end) { // go through every element
    1431                         runner = runner->next;
    1432                         if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1433                                 ElementNo++;
    1434                                 AtomNo = 0;
    1435                                 walker = start;
    1436                                 while (walker->next != end) { // go through every atom of this element
    1437                                         walker = walker->next;
    1438                                         if (walker->type == runner) { // if this atom fits to element
    1439                                                 AtomNo++;
    1440                                                 walker->Output(ElementNo, AtomNo, out); // removed due to trajectories
    1441                                         }
    1442                                 }
    1443                         }
    1444                 }
    1445                 return true;
    1446         }
     1419  element *runner;
     1420  atom *walker = NULL;
     1421  int ElementNo, AtomNo;
     1422  CountElements();
     1423
     1424  if (out == NULL) {
     1425    return false;
     1426  } else {
     1427    *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1428    ElementNo = 0;
     1429    runner = elemente->start;
     1430    while (runner->next != elemente->end) { // go through every element
     1431      runner = runner->next;
     1432      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1433        ElementNo++;
     1434        AtomNo = 0;
     1435        walker = start;
     1436        while (walker->next != end) { // go through every atom of this element
     1437          walker = walker->next;
     1438          if (walker->type == runner) { // if this atom fits to element
     1439            AtomNo++;
     1440            walker->Output(ElementNo, AtomNo, out); // removed due to trajectories
     1441          }
     1442        }
     1443      }
     1444    }
     1445    return true;
     1446  }
    14471447};
    14481448
     
    14521452bool molecule::OutputTrajectories(ofstream *out)
    14531453{
    1454         element *runner = NULL;
    1455         atom *walker = NULL;
    1456         int ElementNo, AtomNo;
    1457         CountElements();
    1458 
    1459         if (out == NULL) {
    1460                 return false;
    1461         } else {
    1462                 for (int step = 0; step < MDSteps; step++) {
    1463                         if (step == 0) {
    1464                                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1465                         } else {
    1466                                 *out << "# ====== MD step " << step << " =========" << endl;
    1467                         }
    1468                         ElementNo = 0;
    1469                         runner = elemente->start;
    1470                         while (runner->next != elemente->end) { // go through every element
    1471                                 runner = runner->next;
    1472                                 if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1473                                         ElementNo++;
    1474                                         AtomNo = 0;
    1475                                         walker = start;
    1476                                         while (walker->next != end) { // go through every atom of this element
    1477                                                 walker = walker->next;
    1478                                                 if (walker->type == runner) { // if this atom fits to element
    1479                                                         AtomNo++;
    1480                                                         *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"        << fixed << setprecision(9) << showpoint;
    1481                                                         *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
    1482                                                         *out << "\t" << walker->FixedIon;
    1483                                                         if (Trajectories[walker].U.at(step).Norm() > MYEPSILON)
    1484                                                                 *out << "\t" << scientific << setprecision(6) << Trajectories[walker].U.at(step).x[0] << "\t" << Trajectories[walker].U.at(step).x[1] << "\t" << Trajectories[walker].U.at(step).x[2] << "\t";
    1485                                                         if (Trajectories[walker].F.at(step).Norm() > MYEPSILON)
    1486                                                                 *out << "\t" << scientific << setprecision(6) << Trajectories[walker].F.at(step).x[0] << "\t" << Trajectories[walker].F.at(step).x[1] << "\t" << Trajectories[walker].F.at(step).x[2] << "\t";
    1487                                                         *out << "\t# Number in molecule " << walker->nr << endl;
    1488                                                 }
    1489                                         }
    1490                                 }
    1491                         }
    1492                 }
    1493                 return true;
    1494         }
     1454  element *runner = NULL;
     1455  atom *walker = NULL;
     1456  int ElementNo, AtomNo;
     1457  CountElements();
     1458
     1459  if (out == NULL) {
     1460    return false;
     1461  } else {
     1462    for (int step = 0; step < MDSteps; step++) {
     1463      if (step == 0) {
     1464        *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1465      } else {
     1466        *out << "# ====== MD step " << step << " =========" << endl;
     1467      }
     1468      ElementNo = 0;
     1469      runner = elemente->start;
     1470      while (runner->next != elemente->end) { // go through every element
     1471        runner = runner->next;
     1472        if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1473          ElementNo++;
     1474          AtomNo = 0;
     1475          walker = start;
     1476          while (walker->next != end) { // go through every atom of this element
     1477            walker = walker->next;
     1478            if (walker->type == runner) { // if this atom fits to element
     1479              AtomNo++;
     1480              *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"  << fixed << setprecision(9) << showpoint;
     1481              *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
     1482              *out << "\t" << walker->FixedIon;
     1483              if (Trajectories[walker].U.at(step).Norm() > MYEPSILON)
     1484                *out << "\t" << scientific << setprecision(6) << Trajectories[walker].U.at(step).x[0] << "\t" << Trajectories[walker].U.at(step).x[1] << "\t" << Trajectories[walker].U.at(step).x[2] << "\t";
     1485              if (Trajectories[walker].F.at(step).Norm() > MYEPSILON)
     1486                *out << "\t" << scientific << setprecision(6) << Trajectories[walker].F.at(step).x[0] << "\t" << Trajectories[walker].F.at(step).x[1] << "\t" << Trajectories[walker].F.at(step).x[2] << "\t";
     1487              *out << "\t# Number in molecule " << walker->nr << endl;
     1488            }
     1489          }
     1490        }
     1491      }
     1492    }
     1493    return true;
     1494  }
    14951495};
    14961496
     
    15001500void molecule::OutputListOfBonds(ofstream *out) const
    15011501{
    1502         *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    1503         atom *Walker = start;
    1504         while (Walker->next != end) {
    1505                 Walker = Walker->next;
     1502  *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
     1503  atom *Walker = start;
     1504  while (Walker->next != end) {
     1505    Walker = Walker->next;
    15061506#ifdef ADDHYDROGEN
    1507                 if (Walker->type->Z != 1) {      // regard only non-hydrogen
     1507    if (Walker->type->Z != 1) {  // regard only non-hydrogen
    15081508#endif
    1509                         *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
    1510                         for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    1511                                 *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
    1512                         }
     1509      *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
     1510      for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     1511        *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
     1512      }
    15131513#ifdef ADDHYDROGEN
    1514                 }
     1514    }
    15151515#endif
    1516         }
    1517         *out << endl;
     1516  }
     1517  *out << endl;
    15181518};
    15191519
     
    15211521 * \param *out stream pointer
    15221522 */
    1523 bool molecule::Checkout(ofstream *out)  const
    1524 {
    1525         return elemente->Checkout(out, ElementsInMolecule);
     1523bool molecule::Checkout(ofstream *out)  const
     1524{
     1525  return elemente->Checkout(out, ElementsInMolecule);
    15261526};
    15271527
     
    15311531bool molecule::OutputTrajectoriesXYZ(ofstream *out)
    15321532{
    1533         atom *walker = NULL;
    1534         int No = 0;
    1535         time_t now;
    1536 
    1537         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1538         walker = start;
    1539         while (walker->next != end) { // go through every atom and count
    1540                 walker = walker->next;
    1541                 No++;
    1542         }
    1543         if (out != NULL) {
    1544                 for (int step=0;step<MDSteps;step++) {
    1545                         *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
    1546                         walker = start;
    1547                         while (walker->next != end) { // go through every atom of this element
    1548                                 walker = walker->next;
    1549                                 *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;
    1550                         }
    1551                 }
    1552                 return true;
    1553         } else
    1554                 return false;
     1533  atom *walker = NULL;
     1534  int No = 0;
     1535  time_t now;
     1536
     1537  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1538  walker = start;
     1539  while (walker->next != end) { // go through every atom and count
     1540    walker = walker->next;
     1541    No++;
     1542  }
     1543  if (out != NULL) {
     1544    for (int step=0;step<MDSteps;step++) {
     1545      *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     1546      walker = start;
     1547      while (walker->next != end) { // go through every atom of this element
     1548        walker = walker->next;
     1549        *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;
     1550      }
     1551    }
     1552    return true;
     1553  } else
     1554    return false;
    15551555};
    15561556
     
    15601560bool molecule::OutputXYZ(ofstream *out) const
    15611561{
    1562         atom *walker = NULL;
    1563         int AtomNo = 0, ElementNo;
    1564         time_t now;
    1565         element *runner = NULL;
    1566 
    1567         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1568         walker = start;
    1569         while (walker->next != end) { // go through every atom and count
    1570                 walker = walker->next;
    1571                 AtomNo++;
    1572         }
    1573         if (out != NULL) {
    1574                 *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    1575                 ElementNo = 0;
    1576                 runner = elemente->start;
    1577                 while (runner->next != elemente->end) { // go through every element
    1578                         runner = runner->next;
    1579                         if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1580                                 ElementNo++;
    1581                                 walker = start;
    1582                                 while (walker->next != end) { // go through every atom of this element
    1583                                         walker = walker->next;
    1584                                         if (walker->type == runner) { // if this atom fits to element
    1585                                                 walker->OutputXYZLine(out);
    1586                                         }
    1587                                 }
    1588                         }
    1589                 }
    1590                 return true;
    1591         } else
    1592                 return false;
     1562  atom *walker = NULL;
     1563  int AtomNo = 0, ElementNo;
     1564  time_t now;
     1565  element *runner = NULL;
     1566
     1567  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1568  walker = start;
     1569  while (walker->next != end) { // go through every atom and count
     1570    walker = walker->next;
     1571    AtomNo++;
     1572  }
     1573  if (out != NULL) {
     1574    *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
     1575    ElementNo = 0;
     1576    runner = elemente->start;
     1577    while (runner->next != elemente->end) { // go through every element
     1578      runner = runner->next;
     1579      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1580        ElementNo++;
     1581        walker = start;
     1582        while (walker->next != end) { // go through every atom of this element
     1583          walker = walker->next;
     1584          if (walker->type == runner) { // if this atom fits to element
     1585            walker->OutputXYZLine(out);
     1586          }
     1587        }
     1588      }
     1589    }
     1590    return true;
     1591  } else
     1592    return false;
    15931593};
    15941594
     
    15981598void molecule::CountAtoms(ofstream *out)
    15991599{
    1600         int i = 0;
    1601         atom *Walker = start;
    1602         while (Walker->next != end) {
    1603                 Walker = Walker->next;
    1604                 i++;
    1605         }
    1606         if ((AtomCount == 0) || (i != AtomCount)) {
    1607                 *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
    1608                 AtomCount = i;
    1609 
    1610                 // count NonHydrogen atoms and give each atom a unique name
    1611                 if (AtomCount != 0) {
    1612                         i=0;
    1613                         NoNonHydrogen = 0;
    1614                         Walker = start;
    1615                         while (Walker->next != end) {
    1616                                 Walker = Walker->next;
    1617                                 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron)
    1618                                 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1619                                         NoNonHydrogen++;
    1620                                 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    1621                                 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
    1622                                 sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
    1623                                 *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
    1624                                 i++;
    1625                         }
    1626                 } else
    1627                         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    1628         }
     1600  int i = 0;
     1601  atom *Walker = start;
     1602  while (Walker->next != end) {
     1603    Walker = Walker->next;
     1604    i++;
     1605  }
     1606  if ((AtomCount == 0) || (i != AtomCount)) {
     1607    *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
     1608    AtomCount = i;
     1609
     1610    // count NonHydrogen atoms and give each atom a unique name
     1611    if (AtomCount != 0) {
     1612      i=0;
     1613      NoNonHydrogen = 0;
     1614      Walker = start;
     1615      while (Walker->next != end) {
     1616        Walker = Walker->next;
     1617        Walker->nr = i;  // update number in molecule (for easier referencing in FragmentMolecule lateron)
     1618        if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
     1619          NoNonHydrogen++;
     1620        Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
     1621        Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     1622        sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
     1623        *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
     1624        i++;
     1625      }
     1626    } else
     1627      *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     1628  }
    16291629};
    16301630
     
    16331633void molecule::CountElements()
    16341634{
    1635         int i = 0;
    1636         for(i=MAX_ELEMENTS;i--;)
    1637                 ElementsInMolecule[i] = 0;
    1638         ElementCount = 0;
    1639 
    1640         atom *walker = start;
    1641         while (walker->next != end) {
    1642                 walker = walker->next;
    1643                 ElementsInMolecule[walker->type->Z]++;
    1644                 i++;
    1645         }
    1646         for(i=MAX_ELEMENTS;i--;)
    1647                 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
     1635  int i = 0;
     1636  for(i=MAX_ELEMENTS;i--;)
     1637    ElementsInMolecule[i] = 0;
     1638  ElementCount = 0;
     1639
     1640  atom *walker = start;
     1641  while (walker->next != end) {
     1642    walker = walker->next;
     1643    ElementsInMolecule[walker->type->Z]++;
     1644    i++;
     1645  }
     1646  for(i=MAX_ELEMENTS;i--;)
     1647    ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
    16481648};
    16491649
     
    16551655int molecule::CountCyclicBonds(ofstream *out)
    16561656{
    1657         int No = 0;
    1658         int *MinimumRingSize = NULL;
    1659         MoleculeLeafClass *Subgraphs = NULL;
    1660         class StackClass<bond *> *BackEdgeStack = NULL;
    1661         bond *Binder = first;
    1662         if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
    1663                 *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
    1664                 Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    1665                 while (Subgraphs->next != NULL) {
    1666                         Subgraphs = Subgraphs->next;
    1667                         delete(Subgraphs->previous);
    1668                 }
    1669                 delete(Subgraphs);
    1670                 delete[](MinimumRingSize);
    1671         }
    1672         while(Binder->next != last) {
    1673                 Binder = Binder->next;
    1674                 if (Binder->Cyclic)
    1675                         No++;
    1676         }
    1677         delete(BackEdgeStack);
    1678         return No;
     1657  int No = 0;
     1658  int *MinimumRingSize = NULL;
     1659  MoleculeLeafClass *Subgraphs = NULL;
     1660  class StackClass<bond *> *BackEdgeStack = NULL;
     1661  bond *Binder = first;
     1662  if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
     1663    *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
     1664    Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     1665    while (Subgraphs->next != NULL) {
     1666      Subgraphs = Subgraphs->next;
     1667      delete(Subgraphs->previous);
     1668    }
     1669    delete(Subgraphs);
     1670    delete[](MinimumRingSize);
     1671  }
     1672  while(Binder->next != last) {
     1673    Binder = Binder->next;
     1674    if (Binder->Cyclic)
     1675      No++;
     1676  }
     1677  delete(BackEdgeStack);
     1678  return No;
    16791679};
    16801680/** Returns Shading as a char string.
     
    16841684string molecule::GetColor(enum Shading color)
    16851685{
    1686         switch(color) {
    1687                 case white:
    1688                         return "white";
    1689                         break;
    1690                 case lightgray:
    1691                         return "lightgray";
    1692                         break;
    1693                 case darkgray:
    1694                         return "darkgray";
    1695                         break;
    1696                 case black:
    1697                         return "black";
    1698                         break;
    1699                 default:
    1700                         return "uncolored";
    1701                         break;
    1702         };
     1686  switch(color) {
     1687    case white:
     1688      return "white";
     1689      break;
     1690    case lightgray:
     1691      return "lightgray";
     1692      break;
     1693    case darkgray:
     1694      return "darkgray";
     1695      break;
     1696    case black:
     1697      return "black";
     1698      break;
     1699    default:
     1700      return "uncolored";
     1701      break;
     1702  };
    17031703};
    17041704
     
    17091709void molecule::CalculateOrbitals(class config &configuration)
    17101710{
    1711         configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
    1712         for(int i=MAX_ELEMENTS;i--;) {
    1713                 if (ElementsInMolecule[i] != 0) {
    1714                         //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
    1715                         configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
    1716                 }
    1717         }
    1718         configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
    1719         configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
    1720         configuration.MaxPsiDouble /= 2;
    1721         configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
    1722         if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
    1723                 configuration.ProcPEGamma /= 2;
    1724                 configuration.ProcPEPsi *= 2;
    1725         } else {
    1726                 configuration.ProcPEGamma *= configuration.ProcPEPsi;
    1727                 configuration.ProcPEPsi = 1;
    1728         }
    1729         configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
     1711  configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
     1712  for(int i=MAX_ELEMENTS;i--;) {
     1713    if (ElementsInMolecule[i] != 0) {
     1714      //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
     1715      configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
     1716    }
     1717  }
     1718  configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
     1719  configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
     1720  configuration.MaxPsiDouble /= 2;
     1721  configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
     1722  if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
     1723    configuration.ProcPEGamma /= 2;
     1724    configuration.ProcPEPsi *= 2;
     1725  } else {
     1726    configuration.ProcPEGamma *= configuration.ProcPEPsi;
     1727    configuration.ProcPEPsi = 1;
     1728  }
     1729  configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
    17301730};
    17311731
     
    17361736{
    17371737
    1738         // 1 We will parse bonds out of the dbond file created by tremolo.
    1739                         int atom1, atom2, temp;
    1740                         atom *Walker, *OtherWalker;
    1741 
    1742                                         if (!input)
    1743                                         {
    1744                                                 cout << Verbose(1) << "Opening silica failed \n";
    1745                                         };
    1746 
    1747                         *input >> ws >> atom1;
    1748                         *input >> ws >> atom2;
    1749                                         cout << Verbose(1) << "Scanning file\n";
    1750                                         while (!input->eof()) // Check whether we read everything already
    1751                                         {
    1752                                 *input >> ws >> atom1;
    1753                                 *input >> ws >> atom2;
    1754                                                 if(atom2<atom1) //Sort indices of atoms in order
    1755                                                 {
    1756                                                         temp=atom1;
    1757                                                         atom1=atom2;
    1758                                                         atom2=temp;
    1759                                                 };
    1760 
    1761                                                 Walker=start;
    1762                                                 while(Walker-> nr != atom1) // Find atom corresponding to first index
    1763                                                 {
    1764                                                         Walker = Walker->next;
    1765                                                 };
    1766                                                 OtherWalker = Walker->next;
    1767                                                 while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    1768                                                 {
    1769                                                         OtherWalker= OtherWalker->next;
    1770                                                 };
    1771                                                 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1772 
    1773                                         }
    1774 
    1775                                         CreateListOfBondsPerAtom(out);
     1738  // 1 We will parse bonds out of the dbond file created by tremolo.
     1739      int atom1, atom2, temp;
     1740      atom *Walker, *OtherWalker;
     1741
     1742          if (!input)
     1743          {
     1744            cout << Verbose(1) << "Opening silica failed \n";
     1745          };
     1746
     1747      *input >> ws >> atom1;
     1748      *input >> ws >> atom2;
     1749          cout << Verbose(1) << "Scanning file\n";
     1750          while (!input->eof()) // Check whether we read everything already
     1751          {
     1752        *input >> ws >> atom1;
     1753        *input >> ws >> atom2;
     1754            if(atom2<atom1) //Sort indices of atoms in order
     1755            {
     1756              temp=atom1;
     1757              atom1=atom2;
     1758              atom2=temp;
     1759            };
     1760
     1761            Walker=start;
     1762            while(Walker-> nr != atom1) // Find atom corresponding to first index
     1763            {
     1764              Walker = Walker->next;
     1765            };
     1766            OtherWalker = Walker->next;
     1767            while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     1768            {
     1769              OtherWalker= OtherWalker->next;
     1770            };
     1771            AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     1772
     1773          }
     1774
     1775          CreateListOfBondsPerAtom(out);
    17761776
    17771777};
     
    17841784 * To make it O(N log N) the function uses the linked-cell technique as follows:
    17851785 * The procedure is step-wise:
    1786  *      -# Remove every bond in list
    1787  *      -# Count the atoms in the molecule with CountAtoms()
    1788  *      -# partition cell into smaller linked cells of size \a bonddistance
    1789  *      -# put each atom into its corresponding cell
    1790  *      -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    1791  *      -# create the list of bonds via CreateListOfBondsPerAtom()
    1792  *      -# correct the bond degree iteratively (single->double->triple bond)
    1793  *      -# finally print the bond list to \a *out if desired
     1786 *  -# Remove every bond in list
     1787 *  -# Count the atoms in the molecule with CountAtoms()
     1788 *  -# partition cell into smaller linked cells of size \a bonddistance
     1789 *  -# put each atom into its corresponding cell
     1790 *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
     1791 *  -# create the list of bonds via CreateListOfBondsPerAtom()
     1792 *  -# correct the bond degree iteratively (single->double->triple bond)
     1793 *  -# finally print the bond list to \a *out if desired
    17941794 * \param *out out stream for printing the matrix, NULL if no output
    17951795 * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
     
    17991799{
    18001800
    1801         atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    1802         int No, NoBonds, CandidateBondNo;
    1803         int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
    1804         molecule **CellList;
    1805         double distance, MinDistance, MaxDistance;
    1806         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    1807         Vector x;
    1808         int FalseBondDegree = 0;
    1809 
    1810         BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    1811         *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
    1812         // remove every bond from the list
    1813         if ((first->next != last) && (last->previous != first)) {       // there are bonds present
    1814                 cleanup(first,last);
    1815         }
    1816 
    1817         // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    1818         CountAtoms(out);
    1819         *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
    1820 
    1821         if (AtomCount != 0) {
    1822                 // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
    1823                 j=-1;
    1824                 for (int i=0;i<NDIM;i++) {
    1825                         j += i+1;
    1826                         divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    1827                         //*out << Verbose(1) << "divisor[" << i << "]   = " << divisor[i] << "." << endl;
    1828                 }
    1829                 // 2a. allocate memory for the cell list
    1830                 NumberCells = divisor[0]*divisor[1]*divisor[2];
    1831                 *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
    1832                 CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
    1833                 for (int i=NumberCells;i--;)
    1834                         CellList[i] = NULL;
    1835 
    1836                 // 2b. put all atoms into its corresponding list
    1837                 Walker = start;
    1838                 while(Walker->next != end) {
    1839                         Walker = Walker->next;
    1840                         //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
    1841                         //Walker->x.Output(out);
    1842                         //*out << "." << endl;
    1843                         // compute the cell by the atom's coordinates
    1844                         j=-1;
    1845                         for (int i=0;i<NDIM;i++) {
    1846                                 j += i+1;
    1847                                 x.CopyVector(&(Walker->x));
    1848                                 x.KeepPeriodic(out, matrix);
    1849                                 n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
    1850                         }
    1851                         index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    1852                         //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    1853                         // add copy atom to this cell
    1854                         if (CellList[index] == NULL)    // allocate molecule if not done
    1855                                 CellList[index] = new molecule(elemente);
    1856                         OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    1857                         //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    1858                 }
    1859                 //for (int i=0;i<NumberCells;i++)
    1860                         //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1861 
    1862 
    1863                 // 3a. go through every cell
    1864                 for (N[0]=divisor[0];N[0]--;)
    1865                         for (N[1]=divisor[1];N[1]--;)
    1866                                 for (N[2]=divisor[2];N[2]--;) {
    1867                                         Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
    1868                                         if (CellList[Index] != NULL) { // if there atoms in this cell
    1869                                                 //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
    1870                                                 // 3b. for every atom therein
    1871                                                 Walker = CellList[Index]->start;
    1872                                                 while (Walker->next != CellList[Index]->end) {  // go through every atom
    1873                                                         Walker = Walker->next;
    1874                                                         //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1875                                                         // 3c. check for possible bond between each atom in this and every one in the 27 cells
    1876                                                         for (n[0]=-1;n[0]<=1;n[0]++)
    1877                                                                 for (n[1]=-1;n[1]<=1;n[1]++)
    1878                                                                         for (n[2]=-1;n[2]<=1;n[2]++) {
    1879                                                                                 // compute the index of this comparison cell and make it periodic
    1880                                                                                 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];
    1881                                                                                 //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
    1882                                                                                 if (CellList[index] != NULL) {  // if there are any atoms in this cell
    1883                                                                                         OtherWalker = CellList[index]->start;
    1884                                                                                         while(OtherWalker->next != CellList[index]->end) {      // go through every atom in this cell
    1885                                                                                                 OtherWalker = OtherWalker->next;
    1886                                                                                                 //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    1887                                                                                                 /// \todo periodic check is missing here!
    1888                                                                                                 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    1889                                                                                                 MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    1890                                                                                                 MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    1891                                                                                                 MaxDistance = MinDistance + BONDTHRESHOLD;
    1892                                                                                                 MinDistance -= BONDTHRESHOLD;
    1893                                                                                                 distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
    1894                                                                                                 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    1895                                                                                                         //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    1896                                                                                                         AddBond(Walker->father, OtherWalker->father, 1);        // also increases molecule::BondCount
    1897                                                                                                 } else {
    1898                                                                                                         //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
    1899                                                                                                 }
    1900                                                                                         }
    1901                                                                                 }
    1902                                                                         }
    1903                                                 }
    1904                                         }
    1905                                 }
    1906 
    1907 
    1908 
    1909                 // 4. free the cell again
    1910                 for (int i=NumberCells;i--;)
    1911                         if (CellList[i] != NULL) {
    1912                                 delete(CellList[i]);
    1913                         }
    1914                 Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1915 
    1916                 // create the adjacency list per atom
    1917                 CreateListOfBondsPerAtom(out);
    1918 
    1919                 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    1920                 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    1921                 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    1922                 // double bonds as was expected.
    1923                 if (BondCount != 0) {
    1924                         NoCyclicBonds = 0;
    1925                         *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    1926                         do {
    1927                                 No = 0; // No acts as breakup flag (if 1 we still continue)
    1928                                 Walker = start;
    1929                                 while (Walker->next != end) { // go through every atom
    1930                                         Walker = Walker->next;
    1931                                         // count valence of first partner
    1932                                         NoBonds = 0;
    1933                                         for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
    1934                                                 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    1935                                         *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1936                                         if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    1937                                                 Candidate = NULL;
    1938                                                 CandidateBondNo = -1;
    1939                                                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    1940                                                         OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    1941                                                         // count valence of second partner
    1942                                                         NoBonds = 0;
    1943                                                         for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    1944                                                                 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    1945                                                         *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1946                                                         if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    1947                                                                 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    1948                                                                         Candidate = OtherWalker;
    1949                                                                         CandidateBondNo = i;
    1950                                                                         *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    1951                                                                 }
    1952                                                         }
    1953                                                 }
    1954                                                 if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    1955                                                         ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    1956                                                         *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    1957                                                 } else
    1958                                                         *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    1959                                                         FalseBondDegree++;
    1960                                         }
    1961                                 }
    1962                         } while (No);
    1963                 *out << " done." << endl;
    1964                 } else
    1965                         *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    1966                 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    1967 
    1968                 // output bonds for debugging (if bond chain list was correctly installed)
    1969                 *out << Verbose(1) << endl << "From contents of bond chain list:";
    1970                 bond *Binder = first;
    1971                 while(Binder->next != last) {
    1972                         Binder = Binder->next;
    1973                         *out << *Binder << "\t" << endl;
    1974                 }
    1975                 *out << endl;
    1976         } else
    1977                 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    1978         *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    1979         Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
     1801  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
     1802  int No, NoBonds, CandidateBondNo;
     1803  int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
     1804  molecule **CellList;
     1805  double distance, MinDistance, MaxDistance;
     1806  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     1807  Vector x;
     1808  int FalseBondDegree = 0;
     1809
     1810  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
     1811  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     1812  // remove every bond from the list
     1813  if ((first->next != last) && (last->previous != first)) {  // there are bonds present
     1814    cleanup(first,last);
     1815  }
     1816
     1817  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
     1818  CountAtoms(out);
     1819  *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
     1820
     1821  if (AtomCount != 0) {
     1822    // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
     1823    j=-1;
     1824    for (int i=0;i<NDIM;i++) {
     1825      j += i+1;
     1826      divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
     1827      //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
     1828    }
     1829    // 2a. allocate memory for the cell list
     1830    NumberCells = divisor[0]*divisor[1]*divisor[2];
     1831    *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
     1832    CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
     1833    for (int i=NumberCells;i--;)
     1834      CellList[i] = NULL;
     1835
     1836    // 2b. put all atoms into its corresponding list
     1837    Walker = start;
     1838    while(Walker->next != end) {
     1839      Walker = Walker->next;
     1840      //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
     1841      //Walker->x.Output(out);
     1842      //*out << "." << endl;
     1843      // compute the cell by the atom's coordinates
     1844      j=-1;
     1845      for (int i=0;i<NDIM;i++) {
     1846        j += i+1;
     1847        x.CopyVector(&(Walker->x));
     1848        x.KeepPeriodic(out, matrix);
     1849        n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
     1850      }
     1851      index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
     1852      //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
     1853      // add copy atom to this cell
     1854      if (CellList[index] == NULL)  // allocate molecule if not done
     1855        CellList[index] = new molecule(elemente);
     1856      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
     1857      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     1858    }
     1859    //for (int i=0;i<NumberCells;i++)
     1860      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
     1861
     1862
     1863    // 3a. go through every cell
     1864    for (N[0]=divisor[0];N[0]--;)
     1865      for (N[1]=divisor[1];N[1]--;)
     1866        for (N[2]=divisor[2];N[2]--;) {
     1867          Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
     1868          if (CellList[Index] != NULL) { // if there atoms in this cell
     1869            //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
     1870            // 3b. for every atom therein
     1871            Walker = CellList[Index]->start;
     1872            while (Walker->next != CellList[Index]->end) {  // go through every atom
     1873              Walker = Walker->next;
     1874              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
     1875              // 3c. check for possible bond between each atom in this and every one in the 27 cells
     1876              for (n[0]=-1;n[0]<=1;n[0]++)
     1877                for (n[1]=-1;n[1]<=1;n[1]++)
     1878                  for (n[2]=-1;n[2]<=1;n[2]++) {
     1879                    // compute the index of this comparison cell and make it periodic
     1880                    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];
     1881                    //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
     1882                    if (CellList[index] != NULL) {  // if there are any atoms in this cell
     1883                      OtherWalker = CellList[index]->start;
     1884                      while(OtherWalker->next != CellList[index]->end) {  // go through every atom in this cell
     1885                        OtherWalker = OtherWalker->next;
     1886                        //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
     1887                        /// \todo periodic check is missing here!
     1888                        //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     1889                        MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
     1890                        MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
     1891                        MaxDistance = MinDistance + BONDTHRESHOLD;
     1892                        MinDistance -= BONDTHRESHOLD;
     1893                        distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
     1894                        if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
     1895                          //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
     1896                          AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
     1897                        } else {
     1898                          //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     1899                        }
     1900                      }
     1901                    }
     1902                  }
     1903            }
     1904          }
     1905        }
     1906
     1907
     1908
     1909    // 4. free the cell again
     1910    for (int i=NumberCells;i--;)
     1911      if (CellList[i] != NULL) {
     1912        delete(CellList[i]);
     1913      }
     1914    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
     1915
     1916    // create the adjacency list per atom
     1917    CreateListOfBondsPerAtom(out);
     1918
     1919    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
     1920    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     1921    // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
     1922    // double bonds as was expected.
     1923    if (BondCount != 0) {
     1924      NoCyclicBonds = 0;
     1925      *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     1926      do {
     1927        No = 0; // No acts as breakup flag (if 1 we still continue)
     1928        Walker = start;
     1929        while (Walker->next != end) { // go through every atom
     1930          Walker = Walker->next;
     1931          // count valence of first partner
     1932          NoBonds = 0;
     1933          for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
     1934            NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     1935          *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1936          if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
     1937            Candidate = NULL;
     1938            CandidateBondNo = -1;
     1939            for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
     1940              OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1941              // count valence of second partner
     1942              NoBonds = 0;
     1943              for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
     1944                NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
     1945              *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1946              if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     1947                if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
     1948                  Candidate = OtherWalker;
     1949                  CandidateBondNo = i;
     1950                  *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
     1951                }
     1952              }
     1953            }
     1954            if ((Candidate != NULL) && (CandidateBondNo != -1)) {
     1955              ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
     1956              *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
     1957            } else
     1958              *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
     1959              FalseBondDegree++;
     1960          }
     1961        }
     1962      } while (No);
     1963    *out << " done." << endl;
     1964    } else
     1965      *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
     1966    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     1967
     1968    // output bonds for debugging (if bond chain list was correctly installed)
     1969    *out << Verbose(1) << endl << "From contents of bond chain list:";
     1970    bond *Binder = first;
     1971    while(Binder->next != last) {
     1972      Binder = Binder->next;
     1973      *out << *Binder << "\t" << endl;
     1974    }
     1975    *out << endl;
     1976  } else
     1977    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     1978  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
     1979  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    19801980
    19811981};
     
    19931993MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
    19941994{
    1995         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    1996         BackEdgeStack = new StackClass<bond *> (BondCount);
    1997         MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    1998         MoleculeLeafClass *LeafWalker = SubGraphs;
    1999         int CurrentGraphNr = 0, OldGraphNr;
    2000         int ComponentNumber = 0;
    2001         atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
    2002         bond *Binder = NULL;
    2003         bool BackStepping = false;
    2004 
    2005         *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2006 
    2007         ResetAllBondsToUnused();
    2008         ResetAllAtomNumbers();
    2009         InitComponentNumbers();
    2010         BackEdgeStack->ClearStack();
    2011         while (Root != end) { // if there any atoms at all
    2012                 // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
    2013                 AtomStack->ClearStack();
    2014 
    2015                 // put into new subgraph molecule and add this to list of subgraphs
    2016                 LeafWalker = new MoleculeLeafClass(LeafWalker);
    2017                 LeafWalker->Leaf = new molecule(elemente);
    2018                 LeafWalker->Leaf->AddCopyAtom(Root);
    2019 
    2020                 OldGraphNr = CurrentGraphNr;
    2021                 Walker = Root;
    2022                 do { // (10)
    2023                         do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
    2024                                 if (!BackStepping) { // if we don't just return from (8)
    2025                                         Walker->GraphNr = CurrentGraphNr;
    2026                                         Walker->LowpointNr = CurrentGraphNr;
    2027                                         *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
    2028                                         AtomStack->Push(Walker);
    2029                                         CurrentGraphNr++;
    2030                                 }
    2031                                 do { // (3) if Walker has no unused egdes, go to (5)
    2032                                         BackStepping = false; // reset backstepping flag for (8)
    2033                                         if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
    2034                                                 Binder = FindNextUnused(Walker);
    2035                                         if (Binder == NULL)
    2036                                                 break;
    2037                                         *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
    2038                                         // (4) Mark Binder used, ...
    2039                                         Binder->MarkUsed(black);
    2040                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2041                                         *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
    2042                                         if (OtherAtom->GraphNr != -1) {
    2043                                                 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
    2044                                                 Binder->Type = BackEdge;
    2045                                                 BackEdgeStack->Push(Binder);
    2046                                                 Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
    2047                                                 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
    2048                                         } else {
    2049                                                 // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
    2050                                                 Binder->Type = TreeEdge;
    2051                                                 OtherAtom->Ancestor = Walker;
    2052                                                 Walker = OtherAtom;
    2053                                                 *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
    2054                                                 break;
    2055                                         }
    2056                                         Binder = NULL;
    2057                                 } while (1);    // (3)
    2058                                 if (Binder == NULL) {
    2059                                         *out << Verbose(2) << "No more Unused Bonds." << endl;
    2060                                         break;
    2061                                 } else
    2062                                         Binder = NULL;
    2063                         } while (1);    // (2)
    2064 
    2065                         // 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!
    2066                         if ((Walker == Root) && (Binder == NULL))
    2067                                 break;
    2068 
    2069                         // (5) if Ancestor of Walker is ...
    2070                         *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    2071                         if (Walker->Ancestor->GraphNr != Root->GraphNr) {
    2072                                 // (6)  (Ancestor of Walker is not Root)
    2073                                 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
    2074                                         // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
    2075                                         Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
    2076                                         *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
    2077                                 } else {
    2078                                         // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
    2079                                         Walker->Ancestor->SeparationVertex = true;
    2080                                         *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
    2081                                         SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
    2082                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
    2083                                         SetNextComponentNumber(Walker, ComponentNumber);
    2084                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2085                                         do {
    2086                                                 OtherAtom = AtomStack->PopLast();
    2087                                                 LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2088                                                 SetNextComponentNumber(OtherAtom, ComponentNumber);
    2089                                                 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2090                                         } while (OtherAtom != Walker);
    2091                                         ComponentNumber++;
    2092                                 }
    2093                                 // (8) Walker becomes its Ancestor, go to (3)
    2094                                 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
    2095                                 Walker = Walker->Ancestor;
    2096                                 BackStepping = true;
    2097                         }
    2098                         if (!BackStepping) {    // coming from (8) want to go to (3)
    2099                                 // (9) remove all from stack till Walker (including), these and Root form a component
    2100                                 AtomStack->Output(out);
    2101                                 SetNextComponentNumber(Root, ComponentNumber);
    2102                                 *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2103                                 SetNextComponentNumber(Walker, ComponentNumber);
    2104                                 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2105                                 do {
    2106                                         OtherAtom = AtomStack->PopLast();
    2107                                         LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2108                                         SetNextComponentNumber(OtherAtom, ComponentNumber);
    2109                                         *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2110                                 } while (OtherAtom != Walker);
    2111                                 ComponentNumber++;
    2112 
    2113                                 // (11) Root is separation vertex,      set Walker to Root and go to (4)
    2114                                 Walker = Root;
    2115                                 Binder = FindNextUnused(Walker);
    2116                                 *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
    2117                                 if (Binder != NULL) { // Root is separation vertex
    2118                                         *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
    2119                                         Walker->SeparationVertex = true;
    2120                                 }
    2121                         }
    2122                 } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
    2123 
    2124                 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2125                 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    2126                 LeafWalker->Leaf->Output(out);
    2127                 *out << endl;
    2128 
    2129                 // step on to next root
    2130                 while ((Root != end) && (Root->GraphNr != -1)) {
    2131                         //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    2132                         if (Root->GraphNr != -1) // if already discovered, step on
    2133                                 Root = Root->next;
    2134                 }
    2135         }
    2136         // set cyclic bond criterium on "same LP" basis
    2137         Binder = first;
    2138         while(Binder->next != last) {
    2139                 Binder = Binder->next;
    2140                 if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
    2141                         Binder->Cyclic = true;
    2142                         NoCyclicBonds++;
    2143                 }
    2144         }
    2145 
    2146 
    2147         *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    2148         Walker = start;
    2149         while (Walker->next != end) {
    2150                 Walker = Walker->next;
    2151                 *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    2152                 OutputComponentNumber(out, Walker);
    2153                 *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    2154         }
    2155 
    2156         *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    2157         Binder = first;
    2158         while(Binder->next != last) {
    2159                 Binder = Binder->next;
    2160                 *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    2161                 *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    2162                 OutputComponentNumber(out, Binder->leftatom);
    2163                 *out << " ===   ";
    2164                 *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    2165                 OutputComponentNumber(out, Binder->rightatom);
    2166                 *out << ">." << endl;
    2167                 if (Binder->Cyclic) // cyclic ??
    2168                         *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    2169         }
    2170 
    2171         // free all and exit
    2172         delete(AtomStack);
    2173         *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    2174         return SubGraphs;
     1995  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     1996  BackEdgeStack = new StackClass<bond *> (BondCount);
     1997  MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
     1998  MoleculeLeafClass *LeafWalker = SubGraphs;
     1999  int CurrentGraphNr = 0, OldGraphNr;
     2000  int ComponentNumber = 0;
     2001  atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
     2002  bond *Binder = NULL;
     2003  bool BackStepping = false;
     2004
     2005  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
     2006
     2007  ResetAllBondsToUnused();
     2008  ResetAllAtomNumbers();
     2009  InitComponentNumbers();
     2010  BackEdgeStack->ClearStack();
     2011  while (Root != end) { // if there any atoms at all
     2012    // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
     2013    AtomStack->ClearStack();
     2014
     2015    // put into new subgraph molecule and add this to list of subgraphs
     2016    LeafWalker = new MoleculeLeafClass(LeafWalker);
     2017    LeafWalker->Leaf = new molecule(elemente);
     2018    LeafWalker->Leaf->AddCopyAtom(Root);
     2019
     2020    OldGraphNr = CurrentGraphNr;
     2021    Walker = Root;
     2022    do { // (10)
     2023      do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
     2024        if (!BackStepping) { // if we don't just return from (8)
     2025          Walker->GraphNr = CurrentGraphNr;
     2026          Walker->LowpointNr = CurrentGraphNr;
     2027          *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
     2028          AtomStack->Push(Walker);
     2029          CurrentGraphNr++;
     2030        }
     2031        do { // (3) if Walker has no unused egdes, go to (5)
     2032          BackStepping = false; // reset backstepping flag for (8)
     2033          if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
     2034            Binder = FindNextUnused(Walker);
     2035          if (Binder == NULL)
     2036            break;
     2037          *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
     2038          // (4) Mark Binder used, ...
     2039          Binder->MarkUsed(black);
     2040          OtherAtom = Binder->GetOtherAtom(Walker);
     2041          *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
     2042          if (OtherAtom->GraphNr != -1) {
     2043            // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
     2044            Binder->Type = BackEdge;
     2045            BackEdgeStack->Push(Binder);
     2046            Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
     2047            *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
     2048          } else {
     2049            // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
     2050            Binder->Type = TreeEdge;
     2051            OtherAtom->Ancestor = Walker;
     2052            Walker = OtherAtom;
     2053            *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
     2054            break;
     2055          }
     2056          Binder = NULL;
     2057        } while (1);  // (3)
     2058        if (Binder == NULL) {
     2059          *out << Verbose(2) << "No more Unused Bonds." << endl;
     2060          break;
     2061        } else
     2062          Binder = NULL;
     2063      } while (1);  // (2)
     2064
     2065      // 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!
     2066      if ((Walker == Root) && (Binder == NULL))
     2067        break;
     2068
     2069      // (5) if Ancestor of Walker is ...
     2070      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
     2071      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     2072        // (6)  (Ancestor of Walker is not Root)
     2073        if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
     2074          // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
     2075          Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
     2076          *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
     2077        } else {
     2078          // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
     2079          Walker->Ancestor->SeparationVertex = true;
     2080          *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
     2081          SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
     2082          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
     2083          SetNextComponentNumber(Walker, ComponentNumber);
     2084          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2085          do {
     2086            OtherAtom = AtomStack->PopLast();
     2087            LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2088            SetNextComponentNumber(OtherAtom, ComponentNumber);
     2089            *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2090          } while (OtherAtom != Walker);
     2091          ComponentNumber++;
     2092        }
     2093        // (8) Walker becomes its Ancestor, go to (3)
     2094        *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
     2095        Walker = Walker->Ancestor;
     2096        BackStepping = true;
     2097      }
     2098      if (!BackStepping) {  // coming from (8) want to go to (3)
     2099        // (9) remove all from stack till Walker (including), these and Root form a component
     2100        AtomStack->Output(out);
     2101        SetNextComponentNumber(Root, ComponentNumber);
     2102        *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2103        SetNextComponentNumber(Walker, ComponentNumber);
     2104        *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2105        do {
     2106          OtherAtom = AtomStack->PopLast();
     2107          LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2108          SetNextComponentNumber(OtherAtom, ComponentNumber);
     2109          *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2110        } while (OtherAtom != Walker);
     2111        ComponentNumber++;
     2112
     2113        // (11) Root is separation vertex,  set Walker to Root and go to (4)
     2114        Walker = Root;
     2115        Binder = FindNextUnused(Walker);
     2116        *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
     2117        if (Binder != NULL) { // Root is separation vertex
     2118          *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
     2119          Walker->SeparationVertex = true;
     2120        }
     2121      }
     2122    } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
     2123
     2124    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
     2125    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2126    LeafWalker->Leaf->Output(out);
     2127    *out << endl;
     2128
     2129    // step on to next root
     2130    while ((Root != end) && (Root->GraphNr != -1)) {
     2131      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
     2132      if (Root->GraphNr != -1) // if already discovered, step on
     2133        Root = Root->next;
     2134    }
     2135  }
     2136  // set cyclic bond criterium on "same LP" basis
     2137  Binder = first;
     2138  while(Binder->next != last) {
     2139    Binder = Binder->next;
     2140    if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
     2141      Binder->Cyclic = true;
     2142      NoCyclicBonds++;
     2143    }
     2144  }
     2145
     2146
     2147  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
     2148  Walker = start;
     2149  while (Walker->next != end) {
     2150    Walker = Walker->next;
     2151    *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
     2152    OutputComponentNumber(out, Walker);
     2153    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
     2154  }
     2155
     2156  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
     2157  Binder = first;
     2158  while(Binder->next != last) {
     2159    Binder = Binder->next;
     2160    *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
     2161    *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
     2162    OutputComponentNumber(out, Binder->leftatom);
     2163    *out << " ===  ";
     2164    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
     2165    OutputComponentNumber(out, Binder->rightatom);
     2166    *out << ">." << endl;
     2167    if (Binder->Cyclic) // cyclic ??
     2168      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     2169  }
     2170
     2171  // free all and exit
     2172  delete(AtomStack);
     2173  *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     2174  return SubGraphs;
    21752175};
    21762176
     
    21852185 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
    21862186 */
    2187 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *        BackEdgeStack, int *&MinimumRingSize)
    2188 {
    2189         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2190         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    2191         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2192         class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);        // will hold the current ring
    2193         class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);    // contains all "touched" atoms (that need to be reset after BFS loop)
    2194         atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
    2195         bond *Binder = NULL, *BackEdge = NULL;
    2196         int RingSize, NumCycles, MinRingSize = -1;
    2197 
    2198         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    2199         for (int i=AtomCount;i--;) {
    2200                 PredecessorList[i] = NULL;
    2201                 ShortestPathList[i] = -1;
    2202                 ColorList[i] = white;
    2203         }
    2204 
    2205         *out << Verbose(1) << "Back edge list - ";
    2206         BackEdgeStack->Output(out);
    2207 
    2208         *out << Verbose(1) << "Analysing cycles ... " << endl;
    2209         NumCycles = 0;
    2210         while (!BackEdgeStack->IsEmpty()) {
    2211                 BackEdge = BackEdgeStack->PopFirst();
    2212                 // this is the target
    2213                 Root = BackEdge->leftatom;
    2214                 // this is the source point
    2215                 Walker = BackEdge->rightatom;
    2216                 ShortestPathList[Walker->nr] = 0;
    2217                 BFSStack->ClearStack(); // start with empty BFS stack
    2218                 BFSStack->Push(Walker);
    2219                 TouchedStack->Push(Walker);
    2220                 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2221                 OtherAtom = NULL;
    2222                 do {    // look for Root
    2223                         Walker = BFSStack->PopFirst();
    2224                         *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2225                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2226                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2227                                 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    2228                                         OtherAtom = Binder->GetOtherAtom(Walker);
     2187void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *  BackEdgeStack, int *&MinimumRingSize)
     2188{
     2189  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2190  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
     2191  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
     2192  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);  // will hold the current ring
     2193  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);  // contains all "touched" atoms (that need to be reset after BFS loop)
     2194  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     2195  bond *Binder = NULL, *BackEdge = NULL;
     2196  int RingSize, NumCycles, MinRingSize = -1;
     2197
     2198  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     2199  for (int i=AtomCount;i--;) {
     2200    PredecessorList[i] = NULL;
     2201    ShortestPathList[i] = -1;
     2202    ColorList[i] = white;
     2203  }
     2204
     2205  *out << Verbose(1) << "Back edge list - ";
     2206  BackEdgeStack->Output(out);
     2207
     2208  *out << Verbose(1) << "Analysing cycles ... " << endl;
     2209  NumCycles = 0;
     2210  while (!BackEdgeStack->IsEmpty()) {
     2211    BackEdge = BackEdgeStack->PopFirst();
     2212    // this is the target
     2213    Root = BackEdge->leftatom;
     2214    // this is the source point
     2215    Walker = BackEdge->rightatom;
     2216    ShortestPathList[Walker->nr] = 0;
     2217    BFSStack->ClearStack();  // start with empty BFS stack
     2218    BFSStack->Push(Walker);
     2219    TouchedStack->Push(Walker);
     2220    *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2221    OtherAtom = NULL;
     2222    do {  // look for Root
     2223      Walker = BFSStack->PopFirst();
     2224      *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2225      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2226        Binder = ListOfBondsPerAtom[Walker->nr][i];
     2227        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     2228          OtherAtom = Binder->GetOtherAtom(Walker);
    22292229#ifdef ADDHYDROGEN
    2230                                         if (OtherAtom->type->Z != 1) {
     2230          if (OtherAtom->type->Z != 1) {
    22312231#endif
    2232                                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2233                                                 if (ColorList[OtherAtom->nr] == white) {
    2234                                                         TouchedStack->Push(OtherAtom);
    2235                                                         ColorList[OtherAtom->nr] = lightgray;
    2236                                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2237                                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2238                                                         *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;
    2239                                                         //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    2240                                                                 *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
    2241                                                                 BFSStack->Push(OtherAtom);
    2242                                                         //}
    2243                                                 } else {
    2244                                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2245                                                 }
    2246                                                 if (OtherAtom == Root)
    2247                                                         break;
     2232            *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2233            if (ColorList[OtherAtom->nr] == white) {
     2234              TouchedStack->Push(OtherAtom);
     2235              ColorList[OtherAtom->nr] = lightgray;
     2236              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2237              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2238              *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;
     2239              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
     2240                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     2241                BFSStack->Push(OtherAtom);
     2242              //}
     2243            } else {
     2244              *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2245            }
     2246            if (OtherAtom == Root)
     2247              break;
    22482248#ifdef ADDHYDROGEN
    2249                                         } else {
    2250                                                 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
    2251                                                 ColorList[OtherAtom->nr] = black;
    2252                                         }
     2249          } else {
     2250            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     2251            ColorList[OtherAtom->nr] = black;
     2252          }
    22532253#endif
    2254                                 } else {
    2255                                         *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
    2256                                 }
    2257                         }
    2258                         ColorList[Walker->nr] = black;
    2259                         *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2260                         if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
    2261                                 // step through predecessor list
    2262                                 while (OtherAtom != BackEdge->rightatom) {
    2263                                         if (!OtherAtom->GetTrueFather()->IsCyclic)      // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
    2264                                                 break;
    2265                                         else
    2266                                                 OtherAtom = PredecessorList[OtherAtom->nr];
    2267                                 }
    2268                                 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
    2269                                         *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
    2270                                         do {
    2271                                                 OtherAtom = TouchedStack->PopLast();
    2272                                                 if (PredecessorList[OtherAtom->nr] == Walker) {
    2273                                                         *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
    2274                                                         PredecessorList[OtherAtom->nr] = NULL;
    2275                                                         ShortestPathList[OtherAtom->nr] = -1;
    2276                                                         ColorList[OtherAtom->nr] = white;
    2277                                                         BFSStack->RemoveItem(OtherAtom);
    2278                                                 }
    2279                                         } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
    2280                                         TouchedStack->Push(OtherAtom);  // last was wrongly popped
    2281                                         OtherAtom = BackEdge->rightatom; // set to not Root
    2282                                 } else
    2283                                         OtherAtom = Root;
    2284                         }
    2285                 } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2286 
    2287                 if (OtherAtom == Root) {
    2288                         // now climb back the predecessor list and thus find the cycle members
    2289                         NumCycles++;
    2290                         RingSize = 1;
    2291                         Root->GetTrueFather()->IsCyclic = true;
    2292                         *out << Verbose(1) << "Found ring contains: ";
    2293                         Walker = Root;
    2294                         while (Walker != BackEdge->rightatom) {
    2295                                 *out << Walker->Name << " <-> ";
    2296                                 Walker = PredecessorList[Walker->nr];
    2297                                 Walker->GetTrueFather()->IsCyclic = true;
    2298                                 RingSize++;
    2299                         }
    2300                         *out << Walker->Name << "       with a length of " << RingSize << "." << endl << endl;
    2301                         // walk through all and set MinimumRingSize
    2302                         Walker = Root;
    2303                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2304                         while (Walker != BackEdge->rightatom) {
    2305                                 Walker = PredecessorList[Walker->nr];
    2306                                 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
    2307                                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2308                         }
    2309                         if ((RingSize < MinRingSize) || (MinRingSize == -1))
    2310                                 MinRingSize = RingSize;
    2311                 } else {
    2312                         *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    2313                 }
    2314 
    2315                 // now clean the lists
    2316                 while (!TouchedStack->IsEmpty()){
    2317                         Walker = TouchedStack->PopFirst();
    2318                         PredecessorList[Walker->nr] = NULL;
    2319                         ShortestPathList[Walker->nr] = -1;
    2320                         ColorList[Walker->nr] = white;
    2321                 }
    2322         }
    2323         if (MinRingSize != -1) {
    2324                 // go over all atoms
    2325                 Root = start;
    2326                 while(Root->next != end) {
    2327                         Root = Root->next;
    2328 
    2329                         if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    2330                                 Walker = Root;
    2331                                 ShortestPathList[Walker->nr] = 0;
    2332                                 BFSStack->ClearStack(); // start with empty BFS stack
    2333                                 BFSStack->Push(Walker);
    2334                                 TouchedStack->Push(Walker);
    2335                                 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2336                                 OtherAtom = Walker;
    2337                                 while (OtherAtom != NULL) {     // look for Root
    2338                                         Walker = BFSStack->PopFirst();
    2339                                         //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2340                                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2341                                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2342                                                 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
    2343                                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2344                                                         //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2345                                                         if (ColorList[OtherAtom->nr] == white) {
    2346                                                                 TouchedStack->Push(OtherAtom);
    2347                                                                 ColorList[OtherAtom->nr] = lightgray;
    2348                                                                 PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2349                                                                 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2350                                                                 //*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;
    2351                                                                 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
    2352                                                                         MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
    2353                                                                         OtherAtom = NULL; //break;
    2354                                                                         break;
    2355                                                                 } else
    2356                                                                         BFSStack->Push(OtherAtom);
    2357                                                         } else {
    2358                                                                 //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2359                                                         }
    2360                                                 } else {
    2361                                                         //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
    2362                                                 }
    2363                                         }
    2364                                         ColorList[Walker->nr] = black;
    2365                                         //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2366                                 }
    2367 
    2368                                 // now clean the lists
    2369                                 while (!TouchedStack->IsEmpty()){
    2370                                         Walker = TouchedStack->PopFirst();
    2371                                         PredecessorList[Walker->nr] = NULL;
    2372                                         ShortestPathList[Walker->nr] = -1;
    2373                                         ColorList[Walker->nr] = white;
    2374                                 }
    2375                         }
    2376                         *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
    2377                 }
    2378                 *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
    2379         } else
    2380                 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
    2381 
    2382         Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2383         Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
    2384         Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
    2385         delete(BFSStack);
     2254        } else {
     2255          *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
     2256        }
     2257      }
     2258      ColorList[Walker->nr] = black;
     2259      *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2260      if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
     2261        // step through predecessor list
     2262        while (OtherAtom != BackEdge->rightatom) {
     2263          if (!OtherAtom->GetTrueFather()->IsCyclic)  // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
     2264            break;
     2265          else
     2266            OtherAtom = PredecessorList[OtherAtom->nr];
     2267        }
     2268        if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
     2269          *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
     2270          do {
     2271            OtherAtom = TouchedStack->PopLast();
     2272            if (PredecessorList[OtherAtom->nr] == Walker) {
     2273              *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
     2274              PredecessorList[OtherAtom->nr] = NULL;
     2275              ShortestPathList[OtherAtom->nr] = -1;
     2276              ColorList[OtherAtom->nr] = white;
     2277              BFSStack->RemoveItem(OtherAtom);
     2278            }
     2279          } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
     2280          TouchedStack->Push(OtherAtom);  // last was wrongly popped
     2281          OtherAtom = BackEdge->rightatom; // set to not Root
     2282        } else
     2283          OtherAtom = Root;
     2284      }
     2285    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
     2286
     2287    if (OtherAtom == Root) {
     2288      // now climb back the predecessor list and thus find the cycle members
     2289      NumCycles++;
     2290      RingSize = 1;
     2291      Root->GetTrueFather()->IsCyclic = true;
     2292      *out << Verbose(1) << "Found ring contains: ";
     2293      Walker = Root;
     2294      while (Walker != BackEdge->rightatom) {
     2295        *out << Walker->Name << " <-> ";
     2296        Walker = PredecessorList[Walker->nr];
     2297        Walker->GetTrueFather()->IsCyclic = true;
     2298        RingSize++;
     2299      }
     2300      *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
     2301      // walk through all and set MinimumRingSize
     2302      Walker = Root;
     2303      MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2304      while (Walker != BackEdge->rightatom) {
     2305        Walker = PredecessorList[Walker->nr];
     2306        if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
     2307          MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2308      }
     2309      if ((RingSize < MinRingSize) || (MinRingSize == -1))
     2310        MinRingSize = RingSize;
     2311    } else {
     2312      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
     2313    }
     2314
     2315    // now clean the lists
     2316    while (!TouchedStack->IsEmpty()){
     2317      Walker = TouchedStack->PopFirst();
     2318      PredecessorList[Walker->nr] = NULL;
     2319      ShortestPathList[Walker->nr] = -1;
     2320      ColorList[Walker->nr] = white;
     2321    }
     2322  }
     2323  if (MinRingSize != -1) {
     2324    // go over all atoms
     2325    Root = start;
     2326    while(Root->next != end) {
     2327      Root = Root->next;
     2328
     2329      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
     2330        Walker = Root;
     2331        ShortestPathList[Walker->nr] = 0;
     2332        BFSStack->ClearStack();  // start with empty BFS stack
     2333        BFSStack->Push(Walker);
     2334        TouchedStack->Push(Walker);
     2335        //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2336        OtherAtom = Walker;
     2337        while (OtherAtom != NULL) {  // look for Root
     2338          Walker = BFSStack->PopFirst();
     2339          //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2340          for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2341            Binder = ListOfBondsPerAtom[Walker->nr][i];
     2342            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
     2343              OtherAtom = Binder->GetOtherAtom(Walker);
     2344              //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2345              if (ColorList[OtherAtom->nr] == white) {
     2346                TouchedStack->Push(OtherAtom);
     2347                ColorList[OtherAtom->nr] = lightgray;
     2348                PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2349                ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2350                //*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;
     2351                if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
     2352                  MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
     2353                  OtherAtom = NULL; //break;
     2354                  break;
     2355                } else
     2356                  BFSStack->Push(OtherAtom);
     2357              } else {
     2358                //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2359              }
     2360            } else {
     2361              //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
     2362            }
     2363          }
     2364          ColorList[Walker->nr] = black;
     2365          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2366        }
     2367
     2368        // now clean the lists
     2369        while (!TouchedStack->IsEmpty()){
     2370          Walker = TouchedStack->PopFirst();
     2371          PredecessorList[Walker->nr] = NULL;
     2372          ShortestPathList[Walker->nr] = -1;
     2373          ColorList[Walker->nr] = white;
     2374        }
     2375      }
     2376      *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
     2377    }
     2378    *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
     2379  } else
     2380    *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
     2381
     2382  Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2383  Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
     2384  Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
     2385  delete(BFSStack);
    23862386};
    23872387
     
    23932393void molecule::SetNextComponentNumber(atom *vertex, int nr)
    23942394{
    2395         int i=0;
    2396         if (vertex != NULL) {
    2397                 for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
    2398                         if (vertex->ComponentNr[i] == -1) {      // check if not yet used
    2399                                 vertex->ComponentNr[i] = nr;
    2400                                 break;
    2401                         }
    2402                         else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
    2403                                 break;  // breaking here will not cause error!
    2404                 }
    2405                 if (i == NumberOfBondsPerAtom[vertex->nr])
    2406                         cerr << "Error: All Component entries are already occupied!" << endl;
    2407         } else
    2408                         cerr << "Error: Given vertex is NULL!" << endl;
     2395  int i=0;
     2396  if (vertex != NULL) {
     2397    for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
     2398      if (vertex->ComponentNr[i] == -1) {  // check if not yet used
     2399        vertex->ComponentNr[i] = nr;
     2400        break;
     2401      }
     2402      else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
     2403        break;  // breaking here will not cause error!
     2404    }
     2405    if (i == NumberOfBondsPerAtom[vertex->nr])
     2406      cerr << "Error: All Component entries are already occupied!" << endl;
     2407  } else
     2408      cerr << "Error: Given vertex is NULL!" << endl;
    24092409};
    24102410
     
    24142414void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    24152415{
    2416         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2417                 *out << vertex->ComponentNr[i] << "     ";
     2416  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2417    *out << vertex->ComponentNr[i] << "  ";
    24182418};
    24192419
     
    24222422void molecule::InitComponentNumbers()
    24232423{
    2424         atom *Walker = start;
    2425         while(Walker->next != end) {
    2426                 Walker = Walker->next;
    2427                 if (Walker->ComponentNr != NULL)
    2428                         Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
    2429                 Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    2430                 for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
    2431                         Walker->ComponentNr[i] = -1;
    2432         }
     2424  atom *Walker = start;
     2425  while(Walker->next != end) {
     2426    Walker = Walker->next;
     2427    if (Walker->ComponentNr != NULL)
     2428      Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
     2429    Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
     2430    for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
     2431      Walker->ComponentNr[i] = -1;
     2432  }
    24332433};
    24342434
     
    24392439bond * molecule::FindNextUnused(atom *vertex)
    24402440{
    2441         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2442                 if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    2443                         return(ListOfBondsPerAtom[vertex->nr][i]);
    2444         return NULL;
     2441  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2442    if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
     2443      return(ListOfBondsPerAtom[vertex->nr][i]);
     2444  return NULL;
    24452445};
    24462446
     
    24502450void molecule::ResetAllBondsToUnused()
    24512451{
    2452         bond *Binder = first;
    2453         while (Binder->next != last) {
    2454                 Binder = Binder->next;
    2455                 Binder->ResetUsed();
    2456         }
     2452  bond *Binder = first;
     2453  while (Binder->next != last) {
     2454    Binder = Binder->next;
     2455    Binder->ResetUsed();
     2456  }
    24572457};
    24582458
     
    24612461void molecule::ResetAllAtomNumbers()
    24622462{
    2463         atom *Walker = start;
    2464         while (Walker->next != end) {
    2465                 Walker = Walker->next;
    2466                 Walker->GraphNr = -1;
    2467         }
     2463  atom *Walker = start;
     2464  while (Walker->next != end) {
     2465    Walker = Walker->next;
     2466    Walker->GraphNr  = -1;
     2467  }
    24682468};
    24692469
     
    24742474void OutputAlreadyVisited(ofstream *out, int *list)
    24752475{
    2476         *out << Verbose(4) << "Already Visited Bonds:\t";
    2477         for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
    2478         *out << endl;
     2476  *out << Verbose(4) << "Already Visited Bonds:\t";
     2477  for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
     2478  *out << endl;
    24792479};
    24802480
     
    24822482 * The upper limit is
    24832483 * \f[
    2484  *      n = N \cdot C^k
     2484 *  n = N \cdot C^k
    24852485 * \f]
    24862486 * where \f$C=2^c\f$ and c is the maximum bond degree over N number of atoms.
     
    24912491int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    24922492{
    2493         int c = 0;
    2494         int FragmentCount;
    2495         // get maximum bond degree
    2496         atom *Walker = start;
    2497         while (Walker->next != end) {
    2498                 Walker = Walker->next;
    2499                 c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
    2500         }
    2501         FragmentCount = NoNonHydrogen*(1 << (c*order));
    2502         *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    2503         return FragmentCount;
     2493  int c = 0;
     2494  int FragmentCount;
     2495  // get maximum bond degree
     2496  atom *Walker = start;
     2497  while (Walker->next != end) {
     2498    Walker = Walker->next;
     2499    c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     2500  }
     2501  FragmentCount = NoNonHydrogen*(1 << (c*order));
     2502  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
     2503  return FragmentCount;
    25042504};
    25052505
     
    25122512bool molecule::ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet)
    25132513{
    2514         stringstream line;
    2515         int AtomNr;
    2516         int status = 0;
    2517 
    2518         line.str(buffer);
    2519         while (!line.eof()) {
    2520                 line >> AtomNr;
    2521                 if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2522                         CurrentSet.insert(AtomNr);      // insert at end, hence in same order as in file!
    2523                         status++;
    2524                 } // else it's "-1" or else and thus must not be added
    2525         }
    2526         *out << Verbose(1) << "The scanned KeySet is ";
    2527         for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
    2528                 *out << (*runner) << "\t";
    2529         }
    2530         *out << endl;
    2531         return (status != 0);
     2514  stringstream line;
     2515  int AtomNr;
     2516  int status = 0;
     2517
     2518  line.str(buffer);
     2519  while (!line.eof()) {
     2520    line >> AtomNr;
     2521    if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2522      CurrentSet.insert(AtomNr);  // insert at end, hence in same order as in file!
     2523      status++;
     2524    } // else it's "-1" or else and thus must not be added
     2525  }
     2526  *out << Verbose(1) << "The scanned KeySet is ";
     2527  for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
     2528    *out << (*runner) << "\t";
     2529  }
     2530  *out << endl;
     2531  return (status != 0);
    25322532};
    25332533
     
    25442544bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList)
    25452545{
    2546         bool status = true;
    2547         ifstream InputFile;
    2548         stringstream line;
    2549         GraphTestPair testGraphInsert;
    2550         int NumberOfFragments = 0;
    2551         double TEFactor;
    2552         char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2553 
    2554         if (FragmentList == NULL) { // check list pointer
    2555                 FragmentList = new Graph;
    2556         }
    2557 
    2558         // 1st pass: open file and read
    2559         *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
    2560         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
    2561         InputFile.open(filename);
    2562         if (InputFile != NULL) {
    2563                 // each line represents a new fragment
    2564                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
    2565                 // 1. parse keysets and insert into temp. graph
    2566                 while (!InputFile.eof()) {
    2567                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2568                         KeySet CurrentSet;
    2569                         if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
    2570                                 testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
    2571                                 if (!testGraphInsert.second) {
    2572                                         cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    2573                                 }
    2574                         }
    2575                 }
    2576                 // 2. Free and done
    2577                 InputFile.close();
    2578                 InputFile.clear();
    2579                 Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
    2580                 *out << Verbose(1) << "done." << endl;
    2581         } else {
    2582                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2583                 status = false;
    2584         }
    2585 
    2586         // 2nd pass: open TEFactors file and read
    2587         *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
    2588         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
    2589         InputFile.open(filename);
    2590         if (InputFile != NULL) {
    2591                 // 3. add found TEFactors to each keyset
    2592                 NumberOfFragments = 0;
    2593                 for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
    2594                         if (!InputFile.eof()) {
    2595                                 InputFile >> TEFactor;
    2596                                 (*runner).second.second = TEFactor;
    2597                                 *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    2598                         } else {
    2599                                 status = false;
    2600                                 break;
    2601                         }
    2602                 }
    2603                 // 4. Free and done
    2604                 InputFile.close();
    2605                 *out << Verbose(1) << "done." << endl;
    2606         } else {
    2607                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2608                 status = false;
    2609         }
    2610 
    2611         // free memory
    2612         Free((void **)&filename, "molecule::ParseKeySetFile - filename");
    2613 
    2614         return status;
     2546  bool status = true;
     2547  ifstream InputFile;
     2548  stringstream line;
     2549  GraphTestPair testGraphInsert;
     2550  int NumberOfFragments = 0;
     2551  double TEFactor;
     2552  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
     2553
     2554  if (FragmentList == NULL) { // check list pointer
     2555    FragmentList = new Graph;
     2556  }
     2557
     2558  // 1st pass: open file and read
     2559  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     2560  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
     2561  InputFile.open(filename);
     2562  if (InputFile != NULL) {
     2563    // each line represents a new fragment
     2564    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
     2565    // 1. parse keysets and insert into temp. graph
     2566    while (!InputFile.eof()) {
     2567      InputFile.getline(buffer, MAXSTRINGSIZE);
     2568      KeySet CurrentSet;
     2569      if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
     2570        testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1)));  // store fragment number and current factor
     2571        if (!testGraphInsert.second) {
     2572          cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
     2573        }
     2574      }
     2575    }
     2576    // 2. Free and done
     2577    InputFile.close();
     2578    InputFile.clear();
     2579    Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
     2580    *out << Verbose(1) << "done." << endl;
     2581  } else {
     2582    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2583    status = false;
     2584  }
     2585
     2586  // 2nd pass: open TEFactors file and read
     2587  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     2588  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
     2589  InputFile.open(filename);
     2590  if (InputFile != NULL) {
     2591    // 3. add found TEFactors to each keyset
     2592    NumberOfFragments = 0;
     2593    for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
     2594      if (!InputFile.eof()) {
     2595        InputFile >> TEFactor;
     2596        (*runner).second.second = TEFactor;
     2597        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2598      } else {
     2599        status = false;
     2600        break;
     2601      }
     2602    }
     2603    // 4. Free and done
     2604    InputFile.close();
     2605    *out << Verbose(1) << "done." << endl;
     2606  } else {
     2607    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2608    status = false;
     2609  }
     2610
     2611  // free memory
     2612  Free((void **)&filename, "molecule::ParseKeySetFile - filename");
     2613
     2614  return status;
    26152615};
    26162616
     
    26232623bool molecule::StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path)
    26242624{
    2625         ofstream output;
    2626         bool status =   true;
    2627         string line;
    2628 
    2629         // open KeySet file
    2630         line = path;
    2631         line.append("/");
    2632         line += FRAGMENTPREFIX;
    2633         line += KEYSETFILE;
    2634         output.open(line.c_str(), ios::out);
    2635         *out << Verbose(1) << "Saving key sets of the total graph ... ";
    2636         if(output != NULL) {
    2637                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2638                         for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    2639                                 if (sprinter != (*runner).first.begin())
    2640                                         output << "\t";
    2641                                 output << *sprinter;
    2642                         }
    2643                         output << endl;
    2644                 }
    2645                 *out << "done." << endl;
    2646         } else {
    2647                 cerr << "Unable to open " << line << " for writing keysets!" << endl;
    2648                 status = false;
    2649         }
    2650         output.close();
    2651         output.clear();
    2652 
    2653         // open TEFactors file
    2654         line = path;
    2655         line.append("/");
    2656         line += FRAGMENTPREFIX;
    2657         line += TEFACTORSFILE;
    2658         output.open(line.c_str(), ios::out);
    2659         *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
    2660         if(output != NULL) {
    2661                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
    2662                         output << (*runner).second.second << endl;
    2663                 *out << Verbose(1) << "done." << endl;
    2664         } else {
    2665                 *out << Verbose(1) << "failed to open " << line << "." << endl;
    2666                 status = false;
    2667         }
    2668         output.close();
    2669 
    2670         return status;
     2625  ofstream output;
     2626  bool status =  true;
     2627  string line;
     2628
     2629  // open KeySet file
     2630  line = path;
     2631  line.append("/");
     2632  line += FRAGMENTPREFIX;
     2633  line += KEYSETFILE;
     2634  output.open(line.c_str(), ios::out);
     2635  *out << Verbose(1) << "Saving key sets of the total graph ... ";
     2636  if(output != NULL) {
     2637    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
     2638      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     2639        if (sprinter != (*runner).first.begin())
     2640          output << "\t";
     2641        output << *sprinter;
     2642      }
     2643      output << endl;
     2644    }
     2645    *out << "done." << endl;
     2646  } else {
     2647    cerr << "Unable to open " << line << " for writing keysets!" << endl;
     2648    status = false;
     2649  }
     2650  output.close();
     2651  output.clear();
     2652
     2653  // open TEFactors file
     2654  line = path;
     2655  line.append("/");
     2656  line += FRAGMENTPREFIX;
     2657  line += TEFACTORSFILE;
     2658  output.open(line.c_str(), ios::out);
     2659  *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
     2660  if(output != NULL) {
     2661    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
     2662      output << (*runner).second.second << endl;
     2663    *out << Verbose(1) << "done." << endl;
     2664  } else {
     2665    *out << Verbose(1) << "failed to open " << line << "." << endl;
     2666    status = false;
     2667  }
     2668  output.close();
     2669
     2670  return status;
    26712671};
    26722672
     
    26792679bool molecule::StoreAdjacencyToFile(ofstream *out, char *path)
    26802680{
    2681         ofstream AdjacencyFile;
    2682         atom *Walker = NULL;
    2683         stringstream line;
    2684         bool status = true;
    2685 
    2686         line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2687         AdjacencyFile.open(line.str().c_str(), ios::out);
    2688         *out << Verbose(1) << "Saving adjacency list ... ";
    2689         if (AdjacencyFile != NULL) {
    2690                 Walker = start;
    2691                 while(Walker->next != end) {
    2692                         Walker = Walker->next;
    2693                         AdjacencyFile << Walker->nr << "\t";
    2694                         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    2695                                 AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    2696                         AdjacencyFile << endl;
    2697                 }
    2698                 AdjacencyFile.close();
    2699                 *out << Verbose(1) << "done." << endl;
    2700         } else {
    2701                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    2702                 status = false;
    2703         }
    2704 
    2705         return status;
     2681  ofstream AdjacencyFile;
     2682  atom *Walker = NULL;
     2683  stringstream line;
     2684  bool status = true;
     2685
     2686  line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2687  AdjacencyFile.open(line.str().c_str(), ios::out);
     2688  *out << Verbose(1) << "Saving adjacency list ... ";
     2689  if (AdjacencyFile != NULL) {
     2690    Walker = start;
     2691    while(Walker->next != end) {
     2692      Walker = Walker->next;
     2693      AdjacencyFile << Walker->nr << "\t";
     2694      for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
     2695        AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
     2696      AdjacencyFile << endl;
     2697    }
     2698    AdjacencyFile.close();
     2699    *out << Verbose(1) << "done." << endl;
     2700  } else {
     2701    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     2702    status = false;
     2703  }
     2704
     2705  return status;
    27062706};
    27072707
     
    27142714bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    27152715{
    2716         ifstream File;
    2717         stringstream filename;
    2718         bool status = true;
    2719         char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2720 
    2721         filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2722         File.open(filename.str().c_str(), ios::out);
    2723         *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
    2724         if (File != NULL) {
    2725                 // allocate storage structure
    2726                 int NonMatchNumber = 0; // will number of atoms with differing bond structure
    2727                 int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    2728                 int CurrentBondsOfAtom;
    2729 
    2730                 // Parse the file line by line and count the bonds
    2731                 while (!File.eof()) {
    2732                         File.getline(buffer, MAXSTRINGSIZE);
    2733                         stringstream line;
    2734                         line.str(buffer);
    2735                         int AtomNr = -1;
    2736                         line >> AtomNr;
    2737                         CurrentBondsOfAtom = -1; // we count one too far due to line end
    2738                         // parse into structure
    2739                         if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2740                                 while (!line.eof())
    2741                                         line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    2742                                 // compare against present bonds
    2743                                 //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    2744                                 if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    2745                                         for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    2746                                                 int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    2747                                                 int j = 0;
    2748                                                 for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    2749                                                 if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
    2750                                                         ListOfAtoms[AtomNr] = NULL;
    2751                                                         NonMatchNumber++;
    2752                                                         status = false;
    2753                                                         //out << "[" << id << "]\t";
    2754                                                 } else {
    2755                                                         //out << id << "\t";
    2756                                                 }
    2757                                         }
    2758                                         //out << endl;
    2759                                 } else {
    2760                                         *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
    2761                                         status = false;
    2762                                 }
    2763                         }
    2764                 }
    2765                 File.close();
    2766                 File.clear();
    2767                 if (status) { // if equal we parse the KeySetFile
    2768                         *out << Verbose(1) << "done: Equal." << endl;
    2769                         status = true;
    2770                 } else
    2771                         *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    2772                 Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
    2773         } else {
    2774                 *out << Verbose(1) << "Adjacency file not found." << endl;
    2775                 status = false;
    2776         }
    2777         *out << endl;
    2778         Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2779 
    2780         return status;
     2716  ifstream File;
     2717  stringstream filename;
     2718  bool status = true;
     2719  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2720
     2721  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2722  File.open(filename.str().c_str(), ios::out);
     2723  *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
     2724  if (File != NULL) {
     2725    // allocate storage structure
     2726    int NonMatchNumber = 0;  // will number of atoms with differing bond structure
     2727    int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
     2728    int CurrentBondsOfAtom;
     2729
     2730    // Parse the file line by line and count the bonds
     2731    while (!File.eof()) {
     2732      File.getline(buffer, MAXSTRINGSIZE);
     2733      stringstream line;
     2734      line.str(buffer);
     2735      int AtomNr = -1;
     2736      line >> AtomNr;
     2737      CurrentBondsOfAtom = -1; // we count one too far due to line end
     2738      // parse into structure
     2739      if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2740        while (!line.eof())
     2741          line >> CurrentBonds[ ++CurrentBondsOfAtom ];
     2742        // compare against present bonds
     2743        //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
     2744        if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
     2745          for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
     2746            int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
     2747            int j = 0;
     2748            for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
     2749            if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
     2750              ListOfAtoms[AtomNr] = NULL;
     2751              NonMatchNumber++;
     2752              status = false;
     2753              //out << "[" << id << "]\t";
     2754            } else {
     2755              //out << id << "\t";
     2756            }
     2757          }
     2758          //out << endl;
     2759        } else {
     2760          *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
     2761          status = false;
     2762        }
     2763      }
     2764    }
     2765    File.close();
     2766    File.clear();
     2767    if (status) { // if equal we parse the KeySetFile
     2768      *out << Verbose(1) << "done: Equal." << endl;
     2769      status = true;
     2770    } else
     2771      *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
     2772    Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
     2773  } else {
     2774    *out << Verbose(1) << "Adjacency file not found." << endl;
     2775    status = false;
     2776  }
     2777  *out << endl;
     2778  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2779
     2780  return status;
    27812781};
    27822782
     
    27922792bool molecule::CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path)
    27932793{
    2794         atom *Walker = start;
    2795         bool status = false;
    2796         ifstream InputFile;
    2797 
    2798         // initialize mask list
    2799         for(int i=AtomCount;i--;)
    2800                 AtomMask[i] = false;
    2801 
    2802         if (Order < 0) { // adaptive increase of BondOrder per site
    2803                 if (AtomMask[AtomCount] == true)        // break after one step
    2804                         return false;
    2805                 // parse the EnergyPerFragment file
    2806                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
    2807                 sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
    2808                 InputFile.open(buffer, ios::in);
    2809                 if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
    2810                         // transmorph graph keyset list into indexed KeySetList
    2811                         map<int,KeySet> IndexKeySetList;
    2812                         for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
    2813                                 IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
    2814                         }
    2815                         int lines = 0;
    2816                         // count the number of lines, i.e. the number of fragments
    2817                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2818                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2819                         while(!InputFile.eof()) {
    2820                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2821                                 lines++;
    2822                         }
    2823                         //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;      // one endline too much
    2824                         InputFile.clear();
    2825                         InputFile.seekg(ios::beg);
    2826                         map<int, pair<double,int> > AdaptiveCriteriaList;       // (Root No., (Value, Order)) !
    2827                         int No, FragOrder;
    2828                         double Value;
    2829                         // each line represents a fragment root (Atom::nr) id and its energy contribution
    2830                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2831                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2832                         while(!InputFile.eof()) {
    2833                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2834                                 if (strlen(buffer) > 2) {
    2835                                         //*out << Verbose(2) << "Scanning: " << buffer << endl;
    2836                                         stringstream line(buffer);
    2837                                         line >> FragOrder;
    2838                                         line >> ws >> No;
    2839                                         line >> ws >> Value; // skip time entry
    2840                                         line >> ws >> Value;
    2841                                         No -= 1;        // indices start at 1 in file, not 0
    2842                                         //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    2843 
    2844                                         // clean the list of those entries that have been superceded by higher order terms already
    2845                                         map<int,KeySet>::iterator marker = IndexKeySetList.find(No);            // find keyset to Frag No.
    2846                                         if (marker != IndexKeySetList.end()) {  // if found
    2847                                                 Value *= 1 + MYEPSILON*(*((*marker).second.begin()));            // in case of equal energies this makes em not equal without changing anything actually
    2848                                                 // 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
    2849                                                 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2850                                                 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    2851                                                 if (!InsertedElement.second) { // this root is already present
    2852                                                         if ((*PresentItem).second.second < FragOrder)   // if order there is lower, update entry with higher-order term
    2853                                                                 //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)
    2854                                                                 {       // if value is smaller, update value and order
    2855                                                                 (*PresentItem).second.first = fabs(Value);
    2856                                                                 (*PresentItem).second.second = FragOrder;
    2857                                                                 *out << Verbose(2) << "Updated element (" <<    (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2858                                                         } else {
    2859                                                                 *out << Verbose(2) << "Did not update element " <<      (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
    2860                                                         }
    2861                                                 } else {
    2862                                                         *out << Verbose(2) << "Inserted element (" <<   (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2863                                                 }
    2864                                         } else {
    2865                                                 *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
    2866                                         }
    2867                                 }
    2868                         }
    2869                         // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
    2870                         map<double, pair<int,int> > FinalRootCandidates;
    2871                         *out << Verbose(1) << "Root candidate list is: " << endl;
    2872                         for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
    2873                                 Walker = FindAtom((*runner).first);
    2874                                 if (Walker != NULL) {
    2875                                         //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
    2876                                         if (!Walker->MaxOrder) {
    2877                                                 *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
    2878                                                 FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
    2879                                         } else {
    2880                                                 *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
    2881                                         }
    2882                                 } else {
    2883                                         cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
    2884                                 }
    2885                         }
    2886                         // pick the ones still below threshold and mark as to be adaptively updated
    2887                         for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
    2888                                 No = (*runner).second.first;
    2889                                 Walker = FindAtom(No);
    2890                                 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2891                                         *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    2892                                         AtomMask[No] = true;
    2893                                         status = true;
    2894                                 //} else
    2895                                         //*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;
    2896                         }
    2897                         // close and done
    2898                         InputFile.close();
    2899                         InputFile.clear();
    2900                 } else {
    2901                         cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
    2902                         while (Walker->next != end) {
    2903                                 Walker = Walker->next;
    2904                 #ifdef ADDHYDROGEN
    2905                                 if (Walker->type->Z != 1) // skip hydrogen
    2906                 #endif
    2907                                 {
    2908                                         AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2909                                         status = true;
    2910                                 }
    2911                         }
    2912                 }
    2913                 Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
    2914                 // pick a given number of highest values and set AtomMask
    2915         } else { // global increase of Bond Order
    2916                 while (Walker->next != end) {
    2917                         Walker = Walker->next;
    2918         #ifdef ADDHYDROGEN
    2919                         if (Walker->type->Z != 1) // skip hydrogen
    2920         #endif
    2921                         {
    2922                                 AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2923                                 if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
    2924                                         status = true;
    2925                         }
    2926                 }
    2927                 if ((Order == 0) && (AtomMask[AtomCount] == false))     // single stepping, just check
    2928                         status = true;
    2929 
    2930                 if (!status) {
    2931                         if (Order == 0)
    2932                                 *out << Verbose(1) << "Single stepping done." << endl;
    2933                         else
    2934                                 *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
    2935                 }
    2936         }
    2937 
    2938         // print atom mask for debugging
    2939         *out << "                                                       ";
    2940         for(int i=0;i<AtomCount;i++)
    2941                 *out << (i % 10);
    2942         *out << endl << "Atom mask is: ";
    2943         for(int i=0;i<AtomCount;i++)
    2944                 *out << (AtomMask[i] ? "t" : "f");
    2945         *out << endl;
    2946 
    2947         return status;
     2794  atom *Walker = start;
     2795  bool status = false;
     2796  ifstream InputFile;
     2797
     2798  // initialize mask list
     2799  for(int i=AtomCount;i--;)
     2800    AtomMask[i] = false;
     2801
     2802  if (Order < 0) { // adaptive increase of BondOrder per site
     2803    if (AtomMask[AtomCount] == true)  // break after one step
     2804      return false;
     2805    // parse the EnergyPerFragment file
     2806    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
     2807    sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
     2808    InputFile.open(buffer, ios::in);
     2809    if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
     2810      // transmorph graph keyset list into indexed KeySetList
     2811      map<int,KeySet> IndexKeySetList;
     2812      for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
     2813        IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
     2814      }
     2815      int lines = 0;
     2816      // count the number of lines, i.e. the number of fragments
     2817      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2818      InputFile.getline(buffer, MAXSTRINGSIZE);
     2819      while(!InputFile.eof()) {
     2820        InputFile.getline(buffer, MAXSTRINGSIZE);
     2821        lines++;
     2822      }
     2823      //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;  // one endline too much
     2824      InputFile.clear();
     2825      InputFile.seekg(ios::beg);
     2826      map<int, pair<double,int> > AdaptiveCriteriaList;  // (Root No., (Value, Order)) !
     2827      int No, FragOrder;
     2828      double Value;
     2829      // each line represents a fragment root (Atom::nr) id and its energy contribution
     2830      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2831      InputFile.getline(buffer, MAXSTRINGSIZE);
     2832      while(!InputFile.eof()) {
     2833        InputFile.getline(buffer, MAXSTRINGSIZE);
     2834        if (strlen(buffer) > 2) {
     2835          //*out << Verbose(2) << "Scanning: " << buffer << endl;
     2836          stringstream line(buffer);
     2837          line >> FragOrder;
     2838          line >> ws >> No;
     2839          line >> ws >> Value; // skip time entry
     2840          line >> ws >> Value;
     2841          No -= 1;  // indices start at 1 in file, not 0
     2842          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
     2843
     2844          // clean the list of those entries that have been superceded by higher order terms already
     2845          map<int,KeySet>::iterator marker = IndexKeySetList.find(No);    // find keyset to Frag No.
     2846          if (marker != IndexKeySetList.end()) {  // if found
     2847            Value *= 1 + MYEPSILON*(*((*marker).second.begin()));    // in case of equal energies this makes em not equal without changing anything actually
     2848            // 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
     2849            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
     2850            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     2851            if (!InsertedElement.second) { // this root is already present
     2852              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
     2853                //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)
     2854                {  // if value is smaller, update value and order
     2855                (*PresentItem).second.first = fabs(Value);
     2856                (*PresentItem).second.second = FragOrder;
     2857                *out << Verbose(2) << "Updated element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2858              } else {
     2859                *out << Verbose(2) << "Did not update element " <<  (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
     2860              }
     2861            } else {
     2862              *out << Verbose(2) << "Inserted element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2863            }
     2864          } else {
     2865            *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
     2866          }
     2867        }
     2868      }
     2869      // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
     2870      map<double, pair<int,int> > FinalRootCandidates;
     2871      *out << Verbose(1) << "Root candidate list is: " << endl;
     2872      for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
     2873        Walker = FindAtom((*runner).first);
     2874        if (Walker != NULL) {
     2875          //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2876          if (!Walker->MaxOrder) {
     2877            *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
     2878            FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
     2879          } else {
     2880            *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
     2881          }
     2882        } else {
     2883          cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
     2884        }
     2885      }
     2886      // pick the ones still below threshold and mark as to be adaptively updated
     2887      for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
     2888        No = (*runner).second.first;
     2889        Walker = FindAtom(No);
     2890        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
     2891          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     2892          AtomMask[No] = true;
     2893          status = true;
     2894        //} else
     2895          //*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;
     2896      }
     2897      // close and done
     2898      InputFile.close();
     2899      InputFile.clear();
     2900    } else {
     2901      cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
     2902      while (Walker->next != end) {
     2903        Walker = Walker->next;
     2904    #ifdef ADDHYDROGEN
     2905        if (Walker->type->Z != 1) // skip hydrogen
     2906    #endif
     2907        {
     2908          AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2909          status = true;
     2910        }
     2911      }
     2912    }
     2913    Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
     2914    // pick a given number of highest values and set AtomMask
     2915  } else { // global increase of Bond Order
     2916    while (Walker->next != end) {
     2917      Walker = Walker->next;
     2918  #ifdef ADDHYDROGEN
     2919      if (Walker->type->Z != 1) // skip hydrogen
     2920  #endif
     2921      {
     2922        AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2923        if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
     2924          status = true;
     2925      }
     2926    }
     2927    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
     2928      status = true;
     2929
     2930    if (!status) {
     2931      if (Order == 0)
     2932        *out << Verbose(1) << "Single stepping done." << endl;
     2933      else
     2934        *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2935    }
     2936  }
     2937
     2938  // print atom mask for debugging
     2939  *out << "              ";
     2940  for(int i=0;i<AtomCount;i++)
     2941    *out << (i % 10);
     2942  *out << endl << "Atom mask is: ";
     2943  for(int i=0;i<AtomCount;i++)
     2944    *out << (AtomMask[i] ? "t" : "f");
     2945  *out << endl;
     2946
     2947  return status;
    29482948};
    29492949
     
    29552955bool molecule::CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex)
    29562956{
    2957         element *runner = elemente->start;
    2958         int AtomNo = 0;
    2959         atom *Walker = NULL;
    2960 
    2961         if (SortIndex != NULL) {
    2962                 *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
    2963                 return false;
    2964         }
    2965         SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
    2966         for(int i=AtomCount;i--;)
    2967                 SortIndex[i] = -1;
    2968         while (runner->next != elemente->end) { // go through every element
    2969                 runner = runner->next;
    2970                 if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    2971                         Walker = start;
    2972                         while (Walker->next != end) { // go through every atom of this element
    2973                                 Walker = Walker->next;
    2974                                 if (Walker->type->Z == runner->Z) // if this atom fits to element
    2975                                         SortIndex[Walker->nr] = AtomNo++;
    2976                         }
    2977                 }
    2978         }
    2979         return true;
     2957  element *runner = elemente->start;
     2958  int AtomNo = 0;
     2959  atom *Walker = NULL;
     2960
     2961  if (SortIndex != NULL) {
     2962    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     2963    return false;
     2964  }
     2965  SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
     2966  for(int i=AtomCount;i--;)
     2967    SortIndex[i] = -1;
     2968  while (runner->next != elemente->end) { // go through every element
     2969    runner = runner->next;
     2970    if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     2971      Walker = start;
     2972      while (Walker->next != end) { // go through every atom of this element
     2973        Walker = Walker->next;
     2974        if (Walker->type->Z == runner->Z) // if this atom fits to element
     2975          SortIndex[Walker->nr] = AtomNo++;
     2976      }
     2977    }
     2978  }
     2979  return true;
    29802980};
    29812981
     
    29862986y contribution", and that's why this consciously not done in the following loop)
    29872987 * -# in a loop over all subgraphs
    2988  *      -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
    2989  *      -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
     2988 *  -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
     2989 *  -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
    29902990 * -# combines the generated molecule lists from all subgraphs
    29912991 * -# saves to disk: fragment configs, adjacency, orderatsite, keyset files
     
    30003000int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
    30013001{
    3002         MoleculeListClass *BondFragments = NULL;
    3003         int *SortIndex = NULL;
    3004         int *MinimumRingSize = new int[AtomCount];
    3005         int FragmentCounter;
    3006         MoleculeLeafClass *MolecularWalker = NULL;
    3007         MoleculeLeafClass *Subgraphs = NULL;                    // list of subgraphs from DFS analysis
    3008         fstream File;
    3009         bool FragmentationToDo = true;
    3010         class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
    3011         bool CheckOrder = false;
    3012         Graph **FragmentList = NULL;
    3013         Graph *ParsedFragmentList = NULL;
    3014         Graph TotalGraph;                // graph with all keysets however local numbers
    3015         int TotalNumberOfKeySets = 0;
    3016         atom **ListOfAtoms = NULL;
    3017         atom ***ListOfLocalAtoms = NULL;
    3018         bool *AtomMask = NULL;
    3019 
    3020         *out << endl;
     3002  MoleculeListClass *BondFragments = NULL;
     3003  int *SortIndex = NULL;
     3004  int *MinimumRingSize = new int[AtomCount];
     3005  int FragmentCounter;
     3006  MoleculeLeafClass *MolecularWalker = NULL;
     3007  MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     3008  fstream File;
     3009  bool FragmentationToDo = true;
     3010  class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
     3011  bool CheckOrder = false;
     3012  Graph **FragmentList = NULL;
     3013  Graph *ParsedFragmentList = NULL;
     3014  Graph TotalGraph;    // graph with all keysets however local numbers
     3015  int TotalNumberOfKeySets = 0;
     3016  atom **ListOfAtoms = NULL;
     3017  atom ***ListOfLocalAtoms = NULL;
     3018  bool *AtomMask = NULL;
     3019
     3020  *out << endl;
    30213021#ifdef ADDHYDROGEN
    3022         *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
     3022  *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
    30233023#else
    3024         *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
     3024  *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
    30253025#endif
    30263026
    3027         // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3028 
    3029         // ===== 1. Check whether bond structure is same as stored in files ====
    3030 
    3031         // fill the adjacency list
    3032         CreateListOfBondsPerAtom(out);
    3033 
    3034         // create lookup table for Atom::nr
    3035         FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3036 
    3037         // === compare it with adjacency file ===
    3038         FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    3039         Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    3040 
    3041         // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    3042         Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    3043         // fill the bond structure of the individually stored subgraphs
    3044         Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);     // we want to keep the created ListOfLocalAtoms
    3045         // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
    3046         for(int i=AtomCount;i--;)
    3047                 MinimumRingSize[i] = AtomCount;
    3048         MolecularWalker = Subgraphs;
    3049         FragmentCounter = 0;
    3050         while (MolecularWalker->next != NULL) {
    3051                 MolecularWalker = MolecularWalker->next;
    3052                 LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    3053 //              // check the list of local atoms for debugging
    3054 //              *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
    3055 //              for (int i=0;i<AtomCount;i++)
    3056 //                      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
    3057 //                              *out << "\tNULL";
    3058 //                      else
    3059 //                              *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3060                 *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3061                 MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3062                 *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3063                 MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3064                 *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3065                 delete(LocalBackEdgeStack);
    3066         }
    3067 
    3068         // ===== 3. if structure still valid, parse key set file and others =====
    3069         FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
    3070 
    3071         // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    3072         FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3073 
    3074         // =================================== Begin of FRAGMENTATION ===============================
    3075         // ===== 6a. assign each keyset to its respective subgraph =====
    3076         Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    3077 
    3078         // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
    3079         KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
    3080         AtomMask = new bool[AtomCount+1];
    3081         AtomMask[AtomCount] = false;
    3082         FragmentationToDo = false;      // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
    3083         while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
    3084                 FragmentationToDo = FragmentationToDo || CheckOrder;
    3085                 AtomMask[AtomCount] = true;      // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3086                 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    3087                 Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    3088 
    3089                 // ===== 7. fill the bond fragment list =====
    3090                 FragmentCounter = 0;
    3091                 MolecularWalker = Subgraphs;
    3092                 while (MolecularWalker->next != NULL) {
    3093                         MolecularWalker = MolecularWalker->next;
    3094                         *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3095                         //MolecularWalker->Leaf->OutputListOfBonds(out);        // output ListOfBondsPerAtom for debugging
    3096                         if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3097                                 // call BOSSANOVA method
    3098                                 *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
    3099                                 MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
    3100                         } else {
    3101                                 cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
    3102                         }
    3103                         FragmentCounter++;      // next fragment list
    3104                 }
    3105         }
    3106         delete[](RootStack);
    3107         delete[](AtomMask);
    3108         delete(ParsedFragmentList);
    3109         delete[](MinimumRingSize);
    3110 
    3111 
    3112         // ==================================== End of FRAGMENTATION ============================================
    3113 
    3114         // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    3115         Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3116 
    3117         // free subgraph memory again
    3118         FragmentCounter = 0;
    3119         if (Subgraphs != NULL) {
    3120                 while (Subgraphs->next != NULL) {
    3121                         Subgraphs = Subgraphs->next;
    3122                         delete(FragmentList[FragmentCounter++]);
    3123                         delete(Subgraphs->previous);
    3124                 }
    3125                 delete(Subgraphs);
    3126         }
    3127         Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
    3128 
    3129         // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    3130         //if (FragmentationToDo) {              // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    3131                 // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3132                 BondFragments = new MoleculeListClass();
    3133                 int k=0;
    3134                 for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    3135                         KeySet test = (*runner).first;
    3136                         *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    3137                         BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
    3138                         k++;
    3139                 }
    3140                 *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    3141 
    3142                 // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3143                 if (BondFragments->ListOfMolecules.size() != 0) {
    3144                         // create the SortIndex from BFS labels to order in the config file
    3145                         CreateMappingLabelsToConfigSequence(out, SortIndex);
    3146 
    3147                         *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
    3148                         if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    3149                                 *out << Verbose(1) << "All configs written." << endl;
    3150                         else
    3151                                 *out << Verbose(1) << "Some config writing failed." << endl;
    3152 
    3153                         // store force index reference file
    3154                         BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3155 
    3156                         // store keysets file
    3157                         StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3158 
    3159                         // store Adjacency file
    3160                         StoreAdjacencyToFile(out, configuration->configpath);
    3161 
    3162                         // store Hydrogen saturation correction file
    3163                         BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3164 
    3165                         // store adaptive orders into file
    3166                         StoreOrderAtSiteFile(out, configuration->configpath);
    3167 
    3168                         // restore orbital and Stop values
    3169                         CalculateOrbitals(*configuration);
    3170 
    3171                         // free memory for bond part
    3172                         *out << Verbose(1) << "Freeing bond memory" << endl;
    3173                         delete(FragmentList); // remove bond molecule from memory
    3174                         Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    3175                 } else
    3176                         *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3177         //} else
    3178         //      *out << Verbose(1) << "No fragments to store." << endl;
    3179         *out << Verbose(0) << "End of bond fragmentation." << endl;
    3180 
    3181         return ((int)(!FragmentationToDo)+1);           // 1 - continue, 2 - stop (no fragmentation occured)
     3027  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
     3028
     3029  // ===== 1. Check whether bond structure is same as stored in files ====
     3030
     3031  // fill the adjacency list
     3032  CreateListOfBondsPerAtom(out);
     3033
     3034  // create lookup table for Atom::nr
     3035  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
     3036
     3037  // === compare it with adjacency file ===
     3038  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     3039  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
     3040
     3041  // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
     3042  Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     3043  // fill the bond structure of the individually stored subgraphs
     3044  Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     3045  // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
     3046  for(int i=AtomCount;i--;)
     3047    MinimumRingSize[i] = AtomCount;
     3048  MolecularWalker = Subgraphs;
     3049  FragmentCounter = 0;
     3050  while (MolecularWalker->next != NULL) {
     3051    MolecularWalker = MolecularWalker->next;
     3052    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     3053//    // check the list of local atoms for debugging
     3054//    *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
     3055//    for (int i=0;i<AtomCount;i++)
     3056//      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
     3057//        *out << "\tNULL";
     3058//      else
     3059//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3060    *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3061    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3062    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3063    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3064    *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3065    delete(LocalBackEdgeStack);
     3066  }
     3067
     3068  // ===== 3. if structure still valid, parse key set file and others =====
     3069  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     3070
     3071  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
     3072  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
     3073
     3074  // =================================== Begin of FRAGMENTATION ===============================
     3075  // ===== 6a. assign each keyset to its respective subgraph =====
     3076  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
     3077
     3078  // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
     3079  KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
     3080  AtomMask = new bool[AtomCount+1];
     3081  AtomMask[AtomCount] = false;
     3082  FragmentationToDo = false;  // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
     3083  while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
     3084    FragmentationToDo = FragmentationToDo || CheckOrder;
     3085    AtomMask[AtomCount] = true;  // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
     3086    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3087    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
     3088
     3089    // ===== 7. fill the bond fragment list =====
     3090    FragmentCounter = 0;
     3091    MolecularWalker = Subgraphs;
     3092    while (MolecularWalker->next != NULL) {
     3093      MolecularWalker = MolecularWalker->next;
     3094      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
     3095      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     3096      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3097        // call BOSSANOVA method
     3098        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     3099        MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
     3100      } else {
     3101        cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
     3102      }
     3103      FragmentCounter++;  // next fragment list
     3104    }
     3105  }
     3106  delete[](RootStack);
     3107  delete[](AtomMask);
     3108  delete(ParsedFragmentList);
     3109  delete[](MinimumRingSize);
     3110
     3111
     3112  // ==================================== End of FRAGMENTATION ============================================
     3113
     3114  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
     3115  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
     3116
     3117  // free subgraph memory again
     3118  FragmentCounter = 0;
     3119  if (Subgraphs != NULL) {
     3120    while (Subgraphs->next != NULL) {
     3121      Subgraphs = Subgraphs->next;
     3122      delete(FragmentList[FragmentCounter++]);
     3123      delete(Subgraphs->previous);
     3124    }
     3125    delete(Subgraphs);
     3126  }
     3127  Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
     3128
     3129  // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
     3130  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
     3131    // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     3132    BondFragments = new MoleculeListClass();
     3133    int k=0;
     3134    for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     3135      KeySet test = (*runner).first;
     3136      *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     3137      BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
     3138      k++;
     3139    }
     3140    *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
     3141
     3142    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     3143    if (BondFragments->ListOfMolecules.size() != 0) {
     3144      // create the SortIndex from BFS labels to order in the config file
     3145      CreateMappingLabelsToConfigSequence(out, SortIndex);
     3146
     3147      *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
     3148      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     3149        *out << Verbose(1) << "All configs written." << endl;
     3150      else
     3151        *out << Verbose(1) << "Some config writing failed." << endl;
     3152
     3153      // store force index reference file
     3154      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     3155
     3156      // store keysets file
     3157      StoreKeySetFile(out, TotalGraph, configuration->configpath);
     3158
     3159      // store Adjacency file
     3160      StoreAdjacencyToFile(out, configuration->configpath);
     3161
     3162      // store Hydrogen saturation correction file
     3163      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     3164
     3165      // store adaptive orders into file
     3166      StoreOrderAtSiteFile(out, configuration->configpath);
     3167
     3168      // restore orbital and Stop values
     3169      CalculateOrbitals(*configuration);
     3170
     3171      // free memory for bond part
     3172      *out << Verbose(1) << "Freeing bond memory" << endl;
     3173      delete(FragmentList); // remove bond molecule from memory
     3174      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3175    } else
     3176      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     3177  //} else
     3178  //  *out << Verbose(1) << "No fragments to store." << endl;
     3179  *out << Verbose(0) << "End of bond fragmentation." << endl;
     3180
     3181  return ((int)(!FragmentationToDo)+1);    // 1 - continue, 2 - stop (no fragmentation occured)
    31823182};
    31833183
     
    31923192bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
    31933193{
    3194         bool status = true;
    3195         if (ReferenceStack->IsEmpty()) {
    3196                 cerr << "ReferenceStack is empty!" << endl;
    3197                 return false;
    3198         }
    3199         bond *Binder = ReferenceStack->PopFirst();
    3200         bond *FirstBond = Binder;        // mark the first bond, so that we don't loop through the stack indefinitely
    3201         atom *Walker = NULL, *OtherAtom = NULL;
    3202         ReferenceStack->Push(Binder);
    3203 
    3204         do {    // go through all bonds and push local ones
    3205                 Walker = ListOfLocalAtoms[Binder->leftatom->nr];        // get one atom in the reference molecule
    3206                 if (Walker != NULL) // if this Walker exists in the subgraph ...
    3207                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {           // go through the local list of bonds
    3208                                 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3209                                 if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3210                                         LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3211                                         *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3212                                         break;
    3213                                 }
    3214                         }
    3215                 Binder = ReferenceStack->PopFirst();    // loop the stack for next item
    3216                 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    3217                 ReferenceStack->Push(Binder);
    3218         } while (FirstBond != Binder);
    3219 
    3220         return status;
     3194  bool status = true;
     3195  if (ReferenceStack->IsEmpty()) {
     3196    cerr << "ReferenceStack is empty!" << endl;
     3197    return false;
     3198  }
     3199  bond *Binder = ReferenceStack->PopFirst();
     3200  bond *FirstBond = Binder;  // mark the first bond, so that we don't loop through the stack indefinitely
     3201  atom *Walker = NULL, *OtherAtom = NULL;
     3202  ReferenceStack->Push(Binder);
     3203
     3204  do {  // go through all bonds and push local ones
     3205    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     3206    if (Walker != NULL) // if this Walker exists in the subgraph ...
     3207      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3208        OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3209        if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3210          LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3211          *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
     3212          break;
     3213        }
     3214      }
     3215    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3216    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
     3217    ReferenceStack->Push(Binder);
     3218  } while (FirstBond != Binder);
     3219
     3220  return status;
    32213221};
    32223222
     
    32293229bool molecule::StoreOrderAtSiteFile(ofstream *out, char *path)
    32303230{
    3231         stringstream line;
    3232         ofstream file;
    3233 
    3234         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3235         file.open(line.str().c_str());
    3236         *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
    3237         if (file != NULL) {
    3238                 atom *Walker = start;
    3239                 while (Walker->next != end) {
    3240                         Walker = Walker->next;
    3241                         file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
    3242                         *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    3243                 }
    3244                 file.close();
    3245                 *out << Verbose(1) << "done." << endl;
    3246                 return true;
    3247         } else {
    3248                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3249                 return false;
    3250         }
     3231  stringstream line;
     3232  ofstream file;
     3233
     3234  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3235  file.open(line.str().c_str());
     3236  *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
     3237  if (file != NULL) {
     3238    atom *Walker = start;
     3239    while (Walker->next != end) {
     3240      Walker = Walker->next;
     3241      file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
     3242      *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
     3243    }
     3244    file.close();
     3245    *out << Verbose(1) << "done." << endl;
     3246    return true;
     3247  } else {
     3248    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3249    return false;
     3250  }
    32513251};
    32523252
     
    32603260bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path)
    32613261{
    3262         unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3263         bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3264         bool status;
    3265         int AtomNr, value;
    3266         stringstream line;
    3267         ifstream file;
    3268 
    3269         *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
    3270         for(int i=AtomCount;i--;)
    3271                 OrderArray[i] = 0;
    3272         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3273         file.open(line.str().c_str());
    3274         if (file != NULL) {
    3275                 for (int i=AtomCount;i--;) { // initialise with 0
    3276                         OrderArray[i] = 0;
    3277                         MaxArray[i] = 0;
    3278                 }
    3279                 while (!file.eof()) { // parse from file
    3280                         AtomNr = -1;
    3281                         file >> AtomNr;
    3282                         if (AtomNr != -1) {      // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
    3283                                 file >> value;
    3284                                 OrderArray[AtomNr] = value;
    3285                                 file >> value;
    3286                                 MaxArray[AtomNr] = value;
    3287                                 //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
    3288                         }
    3289                 }
    3290                 atom *Walker = start;
    3291                 while (Walker->next != end) { // fill into atom classes
    3292                         Walker = Walker->next;
    3293                         Walker->AdaptiveOrder = OrderArray[Walker->nr];
    3294                         Walker->MaxOrder = MaxArray[Walker->nr];
    3295                         *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    3296                 }
    3297                 file.close();
    3298                 *out << Verbose(1) << "done." << endl;
    3299                 status = true;
    3300         } else {
    3301                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3302                 status = false;
    3303         }
    3304         Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3305         Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3306 
    3307         *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    3308         return status;
     3262  unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3263  bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3264  bool status;
     3265  int AtomNr, value;
     3266  stringstream line;
     3267  ifstream file;
     3268
     3269  *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
     3270  for(int i=AtomCount;i--;)
     3271    OrderArray[i] = 0;
     3272  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3273  file.open(line.str().c_str());
     3274  if (file != NULL) {
     3275    for (int i=AtomCount;i--;) { // initialise with 0
     3276      OrderArray[i] = 0;
     3277      MaxArray[i] = 0;
     3278    }
     3279    while (!file.eof()) { // parse from file
     3280      AtomNr = -1;
     3281      file >> AtomNr;
     3282      if (AtomNr != -1) {  // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
     3283        file >> value;
     3284        OrderArray[AtomNr] = value;
     3285        file >> value;
     3286        MaxArray[AtomNr] = value;
     3287        //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
     3288      }
     3289    }
     3290    atom *Walker = start;
     3291    while (Walker->next != end) { // fill into atom classes
     3292      Walker = Walker->next;
     3293      Walker->AdaptiveOrder = OrderArray[Walker->nr];
     3294      Walker->MaxOrder = MaxArray[Walker->nr];
     3295      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3296    }
     3297    file.close();
     3298    *out << Verbose(1) << "done." << endl;
     3299    status = true;
     3300  } else {
     3301    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3302    status = false;
     3303  }
     3304  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3305  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3306
     3307  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
     3308  return status;
    33093309};
    33103310
     
    33173317void molecule::CreateListOfBondsPerAtom(ofstream *out)
    33183318{
    3319         bond *Binder = NULL;
    3320         atom *Walker = NULL;
    3321         int TotalDegree;
    3322         *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    3323 
    3324         // re-allocate memory
    3325         *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    3326         if (ListOfBondsPerAtom != NULL) {
    3327                 for(int i=AtomCount;i--;)
    3328                         Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
    3329                 Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
    3330         }
    3331         if (NumberOfBondsPerAtom != NULL)
    3332                 Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
    3333         ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    3334         NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    3335 
    3336         // reset bond counts per atom
    3337         for(int i=AtomCount;i--;)
    3338                 NumberOfBondsPerAtom[i] = 0;
    3339         // count bonds per atom
    3340         Binder = first;
    3341         while (Binder->next != last) {
    3342                 Binder = Binder->next;
    3343                 NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    3344                 NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    3345         }
    3346         for(int i=AtomCount;i--;) {
    3347                 // allocate list of bonds per atom
    3348                 ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    3349                 // clear the list again, now each NumberOfBondsPerAtom marks current free field
    3350                 NumberOfBondsPerAtom[i] = 0;
    3351         }
    3352         // fill the list
    3353         Binder = first;
    3354         while (Binder->next != last) {
    3355                 Binder = Binder->next;
    3356                 ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    3357                 ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    3358         }
    3359 
    3360         // output list for debugging
    3361         *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    3362         Walker = start;
    3363         while (Walker->next != end) {
    3364                 Walker = Walker->next;
    3365                 *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    3366                 TotalDegree = 0;
    3367                 for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    3368                         *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
    3369                         TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    3370                 }
    3371                 *out << " -- TotalDegree: " << TotalDegree << endl;
    3372         }
    3373         *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
     3319  bond *Binder = NULL;
     3320  atom *Walker = NULL;
     3321  int TotalDegree;
     3322  *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
     3323
     3324  // re-allocate memory
     3325  *out << Verbose(2) << "(Re-)Allocating memory." << endl;
     3326  if (ListOfBondsPerAtom != NULL) {
     3327    for(int i=AtomCount;i--;)
     3328      Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
     3329    Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
     3330  }
     3331  if (NumberOfBondsPerAtom != NULL)
     3332    Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
     3333  ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
     3334  NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
     3335
     3336  // reset bond counts per atom
     3337  for(int i=AtomCount;i--;)
     3338    NumberOfBondsPerAtom[i] = 0;
     3339  // count bonds per atom
     3340  Binder = first;
     3341  while (Binder->next != last) {
     3342    Binder = Binder->next;
     3343    NumberOfBondsPerAtom[Binder->leftatom->nr]++;
     3344    NumberOfBondsPerAtom[Binder->rightatom->nr]++;
     3345  }
     3346  for(int i=AtomCount;i--;) {
     3347    // allocate list of bonds per atom
     3348    ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
     3349    // clear the list again, now each NumberOfBondsPerAtom marks current free field
     3350    NumberOfBondsPerAtom[i] = 0;
     3351  }
     3352  // fill the list
     3353  Binder = first;
     3354  while (Binder->next != last) {
     3355    Binder = Binder->next;
     3356    ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
     3357    ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
     3358  }
     3359
     3360  // output list for debugging
     3361  *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
     3362  Walker = start;
     3363  while (Walker->next != end) {
     3364    Walker = Walker->next;
     3365    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
     3366    TotalDegree = 0;
     3367    for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     3368      *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
     3369      TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     3370    }
     3371    *out << " -- TotalDegree: " << TotalDegree << endl;
     3372  }
     3373  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    33743374};
    33753375
     
    33883388void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    33893389{
    3390         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3391         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
    3392         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
    3393         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    3394         atom *Walker = NULL, *OtherAtom = NULL;
    3395         bond *Binder = NULL;
    3396 
    3397         // add Root if not done yet
    3398         AtomStack->ClearStack();
    3399         if (AddedAtomList[Root->nr] == NULL)    // add Root if not yet present
    3400                 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
    3401         AtomStack->Push(Root);
    3402 
    3403         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    3404         for (int i=AtomCount;i--;) {
    3405                 PredecessorList[i] = NULL;
    3406                 ShortestPathList[i] = -1;
    3407                 if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
    3408                         ColorList[i] = lightgray;
    3409                 else
    3410                         ColorList[i] = white;
    3411         }
    3412         ShortestPathList[Root->nr] = 0;
    3413 
    3414         // and go on ... Queue always contains all lightgray vertices
    3415         while (!AtomStack->IsEmpty()) {
    3416                 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
    3417                 // 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
    3418                 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
    3419                 // followed by n+1 till top of stack.
    3420                 Walker = AtomStack->PopFirst(); // pop oldest added
    3421                 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    3422                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    3423                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    3424                         if (Binder != NULL) { // don't look at bond equal NULL
    3425                                 OtherAtom = Binder->GetOtherAtom(Walker);
    3426                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    3427                                 if (ColorList[OtherAtom->nr] == white) {
    3428                                         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)
    3429                                                 ColorList[OtherAtom->nr] = lightgray;
    3430                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    3431                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3432                                         *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;
    3433                                         if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    3434                                                 *out << Verbose(3);
    3435                                                 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    3436                                                         AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    3437                                                         *out << "Added OtherAtom " << OtherAtom->Name;
    3438                                                         AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3439                                                         AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3440                                                         AddedBondList[Binder->nr]->Type = Binder->Type;
    3441                                                         *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
    3442                                                 } 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)
    3443                                                         *out << "Not adding OtherAtom " << OtherAtom->Name;
    3444                                                         if (AddedBondList[Binder->nr] == NULL) {
    3445                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3446                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3447                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3448                                                                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
    3449                                                         } else
    3450                                                                 *out << ", not added Bond ";
    3451                                                 }
    3452                                                 *out << ", putting OtherAtom into queue." << endl;
    3453                                                 AtomStack->Push(OtherAtom);
    3454                                         } else { // out of bond order, then replace
    3455                                                 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
    3456                                                         ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    3457                                                 if (Binder == Bond)
    3458                                                         *out << Verbose(3) << "Not Queueing, is the Root bond";
    3459                                                 else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    3460                                                         *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    3461                                                 if (!Binder->Cyclic)
    3462                                                         *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    3463                                                 if (AddedBondList[Binder->nr] == NULL) {
    3464                                                         if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    3465                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3466                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3467                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3468                                                         } else {
     3390  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3391  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
     3392  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
     3393  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     3394  atom *Walker = NULL, *OtherAtom = NULL;
     3395  bond *Binder = NULL;
     3396
     3397  // add Root if not done yet
     3398  AtomStack->ClearStack();
     3399  if (AddedAtomList[Root->nr] == NULL)  // add Root if not yet present
     3400    AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
     3401  AtomStack->Push(Root);
     3402
     3403  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     3404  for (int i=AtomCount;i--;) {
     3405    PredecessorList[i] = NULL;
     3406    ShortestPathList[i] = -1;
     3407    if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
     3408      ColorList[i] = lightgray;
     3409    else
     3410      ColorList[i] = white;
     3411  }
     3412  ShortestPathList[Root->nr] = 0;
     3413
     3414  // and go on ... Queue always contains all lightgray vertices
     3415  while (!AtomStack->IsEmpty()) {
     3416    // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
     3417    // 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
     3418    // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
     3419    // followed by n+1 till top of stack.
     3420    Walker = AtomStack->PopFirst(); // pop oldest added
     3421    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3422    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     3423      Binder = ListOfBondsPerAtom[Walker->nr][i];
     3424      if (Binder != NULL) { // don't look at bond equal NULL
     3425        OtherAtom = Binder->GetOtherAtom(Walker);
     3426        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     3427        if (ColorList[OtherAtom->nr] == white) {
     3428          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)
     3429            ColorList[OtherAtom->nr] = lightgray;
     3430          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     3431          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     3432          *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;
     3433          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
     3434            *out << Verbose(3);
     3435            if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
     3436              AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
     3437              *out << "Added OtherAtom " << OtherAtom->Name;
     3438              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3439              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3440              AddedBondList[Binder->nr]->Type = Binder->Type;
     3441              *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     3442            } 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)
     3443              *out << "Not adding OtherAtom " << OtherAtom->Name;
     3444              if (AddedBondList[Binder->nr] == NULL) {
     3445                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3446                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3447                AddedBondList[Binder->nr]->Type = Binder->Type;
     3448                *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     3449              } else
     3450                *out << ", not added Bond ";
     3451            }
     3452            *out << ", putting OtherAtom into queue." << endl;
     3453            AtomStack->Push(OtherAtom);
     3454          } else { // out of bond order, then replace
     3455            if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     3456              ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
     3457            if (Binder == Bond)
     3458              *out << Verbose(3) << "Not Queueing, is the Root bond";
     3459            else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
     3460              *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
     3461            if (!Binder->Cyclic)
     3462              *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
     3463            if (AddedBondList[Binder->nr] == NULL) {
     3464              if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
     3465                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3466                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3467                AddedBondList[Binder->nr]->Type = Binder->Type;
     3468              } else {
    34693469#ifdef ADDHYDROGEN
    3470                                                                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3471                                                                         exit(1);
     3470                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3471                  exit(1);
    34723472#endif
    3473                                                         }
    3474                                                 }
    3475                                         }
    3476                                 } else {
    3477                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    3478                                         // This has to be a cyclic bond, check whether it's present ...
    3479                                         if (AddedBondList[Binder->nr] == NULL) {
    3480                                                 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    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                                                 } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
     3473              }
     3474            }
     3475          }
     3476        } else {
     3477          *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     3478          // This has to be a cyclic bond, check whether it's present ...
     3479          if (AddedBondList[Binder->nr] == NULL) {
     3480            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     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            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    34853485#ifdef ADDHYDROGEN
    3486                                                         if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3487                                                                 exit(1);
     3486              if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3487                exit(1);
    34883488#endif
    3489                                                 }
    3490                                         }
    3491                                 }
    3492                         }
    3493                 }
    3494                 ColorList[Walker->nr] = black;
    3495                 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    3496         }
    3497         Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3498         Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
    3499         Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
    3500         delete(AtomStack);
     3489            }
     3490          }
     3491        }
     3492      }
     3493    }
     3494    ColorList[Walker->nr] = black;
     3495    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3496  }
     3497  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3498  Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
     3499  Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
     3500  delete(AtomStack);
    35013501};
    35023502
     
    35123512bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
    35133513{
    3514         atom *Walker = NULL, *OtherAtom = NULL;
    3515         bool status = true;
    3516         atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
    3517 
    3518         *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3519 
    3520         // reset parent list
    3521         *out << Verbose(3) << "Resetting ParentList." << endl;
    3522         for (int i=Father->AtomCount;i--;)
    3523                 ParentList[i] = NULL;
    3524 
    3525         // fill parent list with sons
    3526         *out << Verbose(3) << "Filling Parent List." << endl;
    3527         Walker = start;
    3528         while (Walker->next != end) {
    3529                 Walker = Walker->next;
    3530                 ParentList[Walker->father->nr] = Walker;
    3531                 // Outputting List for debugging
    3532                 *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<        " is " << ParentList[Walker->father->nr] << "." << endl;
    3533         }
    3534 
    3535         // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
    3536         *out << Verbose(3) << "Creating bonds." << endl;
    3537         Walker = Father->start;
    3538         while (Walker->next != Father->end) {
    3539                 Walker = Walker->next;
    3540                 if (ParentList[Walker->nr] != NULL) {
    3541                         if (ParentList[Walker->nr]->father != Walker) {
    3542                                 status = false;
    3543                         } else {
    3544                                 for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    3545                                         OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3546                                         if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    3547                                                 *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    3548                                                 AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
    3549                                         }
    3550                                 }
    3551                         }
    3552                 }
    3553         }
    3554 
    3555         Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
    3556         *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
    3557         return status;
     3514  atom *Walker = NULL, *OtherAtom = NULL;
     3515  bool status = true;
     3516  atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
     3517
     3518  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
     3519
     3520  // reset parent list
     3521  *out << Verbose(3) << "Resetting ParentList." << endl;
     3522  for (int i=Father->AtomCount;i--;)
     3523    ParentList[i] = NULL;
     3524
     3525  // fill parent list with sons
     3526  *out << Verbose(3) << "Filling Parent List." << endl;
     3527  Walker = start;
     3528  while (Walker->next != end) {
     3529    Walker = Walker->next;
     3530    ParentList[Walker->father->nr] = Walker;
     3531    // Outputting List for debugging
     3532    *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<  " is " << ParentList[Walker->father->nr] << "." << endl;
     3533  }
     3534
     3535  // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
     3536  *out << Verbose(3) << "Creating bonds." << endl;
     3537  Walker = Father->start;
     3538  while (Walker->next != Father->end) {
     3539    Walker = Walker->next;
     3540    if (ParentList[Walker->nr] != NULL) {
     3541      if (ParentList[Walker->nr]->father != Walker) {
     3542        status = false;
     3543      } else {
     3544        for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
     3545          OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3546          if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
     3547            *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     3548            AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     3549          }
     3550        }
     3551      }
     3552    }
     3553  }
     3554
     3555  Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
     3556  *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
     3557  return status;
    35583558};
    35593559
     
    35673567int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
    35683568{
    3569         atom *Runner = NULL;
    3570         int SP, Removal;
    3571 
    3572         *out << Verbose(2) << "Looking for removal candidate." << endl;
    3573         SP = -1; //0;   // not -1, so that Root is never removed
    3574         Removal = -1;
    3575         for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
    3576                 Runner = FindAtom((*runner));
    3577                 if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
    3578                         if (ShortestPathList[(*runner)] > SP) { // remove the oldest one with longest shortest path
    3579                                 SP = ShortestPathList[(*runner)];
    3580                                 Removal = (*runner);
    3581                         }
    3582                 }
    3583         }
    3584         return Removal;
     3569  atom *Runner = NULL;
     3570  int SP, Removal;
     3571
     3572  *out << Verbose(2) << "Looking for removal candidate." << endl;
     3573  SP = -1; //0;  // not -1, so that Root is never removed
     3574  Removal = -1;
     3575  for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
     3576    Runner = FindAtom((*runner));
     3577    if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
     3578      if (ShortestPathList[(*runner)] > SP) {  // remove the oldest one with longest shortest path
     3579        SP = ShortestPathList[(*runner)];
     3580        Removal = (*runner);
     3581      }
     3582    }
     3583  }
     3584  return Removal;
    35853585};
    35863586
     
    35953595molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem)
    35963596{
    3597         atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
    3598         atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
    3599         molecule *Leaf = new molecule(elemente);
    3600         bool LonelyFlag = false;
    3601         int size;
    3602 
    3603 //      *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3604 
    3605         Leaf->BondDistance = BondDistance;
    3606         for(int i=NDIM*2;i--;)
    3607                 Leaf->cell_size[i] = cell_size[i];
    3608 
    3609         // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
    3610         for(int i=AtomCount;i--;)
    3611                 SonList[i] = NULL;
    3612 
    3613         // first create the minimal set of atoms from the KeySet
    3614         size = 0;
    3615         for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
    3616                 FatherOfRunner = FindAtom((*runner));   // find the id
    3617                 SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
    3618                 size++;
    3619         }
    3620 
    3621         // create the bonds between all: Make it an induced subgraph and add hydrogen
    3622 //      *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
    3623         Runner = Leaf->start;
    3624         while (Runner->next != Leaf->end) {
    3625                 Runner = Runner->next;
    3626                 LonelyFlag = true;
    3627                 FatherOfRunner = Runner->father;
    3628                 if (SonList[FatherOfRunner->nr] != NULL)        {       // check if this, our father, is present in list
    3629                         // create all bonds
    3630                         for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    3631                                 OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    3632 //                              *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    3633                                 if (SonList[OtherFather->nr] != NULL) {
    3634 //                                      *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    3635                                         if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    3636 //                                              *out << Verbose(3) << "Adding Bond: ";
    3637 //                                              *out <<
    3638                                                 Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    3639 //                                              *out << "." << endl;
    3640                                                 //NumBonds[Runner->nr]++;
    3641                                         } else {
    3642 //                                              *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    3643                                         }
    3644                                         LonelyFlag = false;
    3645                                 } else {
    3646 //                                      *out << ", who has no son in this fragment molecule." << endl;
     3597  atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
     3598  atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
     3599  molecule *Leaf = new molecule(elemente);
     3600  bool LonelyFlag = false;
     3601  int size;
     3602
     3603//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
     3604
     3605  Leaf->BondDistance = BondDistance;
     3606  for(int i=NDIM*2;i--;)
     3607    Leaf->cell_size[i] = cell_size[i];
     3608
     3609  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     3610  for(int i=AtomCount;i--;)
     3611    SonList[i] = NULL;
     3612
     3613  // first create the minimal set of atoms from the KeySet
     3614  size = 0;
     3615  for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
     3616    FatherOfRunner = FindAtom((*runner));  // find the id
     3617    SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
     3618    size++;
     3619  }
     3620
     3621  // create the bonds between all: Make it an induced subgraph and add hydrogen
     3622//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     3623  Runner = Leaf->start;
     3624  while (Runner->next != Leaf->end) {
     3625    Runner = Runner->next;
     3626    LonelyFlag = true;
     3627    FatherOfRunner = Runner->father;
     3628    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
     3629      // create all bonds
     3630      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3631        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     3632//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
     3633        if (SonList[OtherFather->nr] != NULL) {
     3634//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     3635          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
     3636//            *out << Verbose(3) << "Adding Bond: ";
     3637//            *out <<
     3638            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     3639//            *out << "." << endl;
     3640            //NumBonds[Runner->nr]++;
     3641          } else {
     3642//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
     3643          }
     3644          LonelyFlag = false;
     3645        } else {
     3646//          *out << ", who has no son in this fragment molecule." << endl;
    36473647#ifdef ADDHYDROGEN
    3648                                         //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    3649                                         if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    3650                                                 exit(1);
     3648          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
     3649          if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     3650            exit(1);
    36513651#endif
    3652                                         //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
    3653                                 }
    3654                         }
    3655                 } else {
    3656                         *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
    3657                 }
    3658                 if ((LonelyFlag) && (size > 1)) {
    3659                         *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
    3660                 }
     3652          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     3653        }
     3654      }
     3655    } else {
     3656      *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
     3657    }
     3658    if ((LonelyFlag) && (size > 1)) {
     3659      *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
     3660    }
    36613661#ifdef ADDHYDROGEN
    3662                 while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    3663                         Runner = Runner->next;
     3662    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
     3663      Runner = Runner->next;
    36643664#endif
    3665         }
    3666         Leaf->CreateListOfBondsPerAtom(out);
    3667         //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    3668         Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
    3669 //      *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
    3670         return Leaf;
     3665  }
     3666  Leaf->CreateListOfBondsPerAtom(out);
     3667  //Leaflet->Leaf->ScanForPeriodicCorrection(out);
     3668  Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
     3669//  *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
     3670  return Leaf;
    36713671};
    36723672
     
    36743674 */
    36753675struct UniqueFragments {
    3676         config *configuration;
    3677         atom *Root;
    3678         Graph *Leaflet;
    3679         KeySet *FragmentSet;
    3680         int ANOVAOrder;
    3681         int FragmentCounter;
    3682         int CurrentIndex;
    3683         double TEFactor;
    3684         int *ShortestPathList;
    3685         bool **UsedList;
    3686         bond **BondsPerSPList;
    3687         int *BondsPerSPCount;
     3676  config *configuration;
     3677  atom *Root;
     3678  Graph *Leaflet;
     3679  KeySet *FragmentSet;
     3680  int ANOVAOrder;
     3681  int FragmentCounter;
     3682  int CurrentIndex;
     3683  double TEFactor;
     3684  int *ShortestPathList;
     3685  bool **UsedList;
     3686  bond **BondsPerSPList;
     3687  int *BondsPerSPCount;
    36883688};
    36893689
    36903690/** From a given set of Bond sorted by Shortest Path distance, create all possible fragments of size \a SetDimension.
    36913691 * -# loops over every possible combination (2^dimension of edge set)
    3692  *      -# inserts current set, if there's still space left
    3693  *              -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
     3692 *  -# inserts current set, if there's still space left
     3693 *    -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
    36943694ance+1
    3695  *              -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
    3696  *      -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
     3695 *    -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
     3696 *  -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
    36973697distance) and current set
    36983698 * \param *out output stream for debugging
     
    37043704void molecule::SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder)
    37053705{
    3706         atom *OtherWalker = NULL;
    3707         int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
    3708         int NumCombinations;
    3709         bool bit;
    3710         int bits, TouchedIndex, SubSetDimension, SP, Added;
    3711         int Removal;
    3712         int SpaceLeft;
    3713         int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
    3714         bond *Binder = NULL;
    3715         bond **BondsList = NULL;
    3716         KeySetTestPair TestKeySetInsert;
    3717 
    3718         NumCombinations = 1 << SetDimension;
    3719 
    3720         // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    3721         // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    3722         // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3723 
    3724         *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    3725         *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;
    3726 
    3727         // initialised touched list (stores added atoms on this level)
    3728         *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    3729         for (TouchedIndex=SubOrder+1;TouchedIndex--;)   // empty touched list
    3730                 TouchedList[TouchedIndex] = -1;
    3731         TouchedIndex = 0;
    3732 
    3733         // create every possible combination of the endpieces
    3734         *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
    3735         for (int i=1;i<NumCombinations;i++) {   // sweep through all power set combinations (skip empty set!)
    3736                 // count the set bit of i
    3737                 bits = 0;
    3738                 for (int j=SetDimension;j--;)
    3739                         bits += (i & (1 << j)) >> j;
    3740 
    3741                 *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    3742                 if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
    3743                         // --1-- add this set of the power set of bond partners to the snake stack
    3744                         Added = 0;
    3745                         for (int j=0;j<SetDimension;j++) {      // pull out every bit by shifting
    3746                                 bit = ((i & (1 << j)) != 0);    // mask the bit for the j-th bond
    3747                                 if (bit) {      // if bit is set, we add this bond partner
    3748                                         OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    3749                                         //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    3750                                         *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3751                                         TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    3752                                         if (TestKeySetInsert.second) {
    3753                                                 TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
    3754                                                 Added++;
    3755                                         } else {
    3756                                                 *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
    3757                                         }
    3758                                                 //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
    3759                                         //}
    3760                                 } else {
    3761                                         *out << Verbose(2+verbosity) << "Not adding." << endl;
    3762                                 }
    3763                         }
    3764 
    3765                         SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    3766                         if (SpaceLeft > 0) {
    3767                                 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
    3768                                 if (SubOrder > 1) {             // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
    3769                                         // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
    3770                                         SP = RootDistance+1;    // this is the next level
    3771                                         // first count the members in the subset
    3772                                         SubSetDimension = 0;
    3773                                         Binder = FragmentSearch->BondsPerSPList[2*SP];          // start node for this level
    3774                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {                // compare to end node of this level
    3775                                                 Binder = Binder->next;
    3776                                                 for (int k=TouchedIndex;k--;) {
    3777                                                         if (Binder->Contains(TouchedList[k]))    // if we added this very endpiece
    3778                                                                 SubSetDimension++;
    3779                                                 }
    3780                                         }
    3781                                         // then allocate and fill the list
    3782                                         BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
    3783                                         SubSetDimension = 0;
    3784                                         Binder = FragmentSearch->BondsPerSPList[2*SP];
    3785                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
    3786                                                 Binder = Binder->next;
    3787                                                 for (int k=0;k<TouchedIndex;k++) {
    3788                                                         if (Binder->leftatom->nr == TouchedList[k])      // leftatom is always the close one
    3789                                                                 BondsList[SubSetDimension++] = Binder;
    3790                                                 }
    3791                                         }
    3792                                         *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3793                                         SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    3794                                         Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    3795                                 }
    3796                         } else {
    3797                                 // --2-- otherwise store the complete fragment
    3798                                 *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
    3799                                 // store fragment as a KeySet
    3800                                 *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    3801                                 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3802                                         *out << (*runner) << " ";
    3803                                 *out << endl;
    3804                                 //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
    3805                                         //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
    3806                                 InsertFragmentIntoGraph(out, FragmentSearch);
    3807                                 //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
    3808                                 //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    3809                         }
    3810 
    3811                         // --3-- remove all added items in this level from snake stack
    3812                         *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
    3813                         for(int j=0;j<TouchedIndex;j++) {
    3814                                 Removal = TouchedList[j];
    3815                                 *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
    3816                                 FragmentSearch->FragmentSet->erase(Removal);
    3817                                 TouchedList[j] = -1;
    3818                         }
    3819                         *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    3820                         for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3821                                 *out << (*runner) << " ";
    3822                         *out << endl;
    3823                         TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
    3824                 } else {
    3825                         *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
    3826                 }
    3827         }
    3828         Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    3829         *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
     3706  atom *OtherWalker = NULL;
     3707  int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
     3708  int NumCombinations;
     3709  bool bit;
     3710  int bits, TouchedIndex, SubSetDimension, SP, Added;
     3711  int Removal;
     3712  int SpaceLeft;
     3713  int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
     3714  bond *Binder = NULL;
     3715  bond **BondsList = NULL;
     3716  KeySetTestPair TestKeySetInsert;
     3717
     3718  NumCombinations = 1 << SetDimension;
     3719
     3720  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
     3721  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
     3722  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
     3723
     3724  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     3725  *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;
     3726
     3727  // initialised touched list (stores added atoms on this level)
     3728  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
     3729  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
     3730    TouchedList[TouchedIndex] = -1;
     3731  TouchedIndex = 0;
     3732
     3733  // create every possible combination of the endpieces
     3734  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     3735  for (int i=1;i<NumCombinations;i++) {  // sweep through all power set combinations (skip empty set!)
     3736    // count the set bit of i
     3737    bits = 0;
     3738    for (int j=SetDimension;j--;)
     3739      bits += (i & (1 << j)) >> j;
     3740
     3741    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
     3742    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     3743      // --1-- add this set of the power set of bond partners to the snake stack
     3744      Added = 0;
     3745      for (int j=0;j<SetDimension;j++) {  // pull out every bit by shifting
     3746        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
     3747        if (bit) {  // if bit is set, we add this bond partner
     3748          OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
     3749          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
     3750          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
     3751          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     3752          if (TestKeySetInsert.second) {
     3753            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     3754            Added++;
     3755          } else {
     3756            *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
     3757          }
     3758            //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
     3759          //}
     3760        } else {
     3761          *out << Verbose(2+verbosity) << "Not adding." << endl;
     3762        }
     3763      }
     3764
     3765      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     3766      if (SpaceLeft > 0) {
     3767        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     3768        if (SubOrder > 1) {    // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
     3769          // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
     3770          SP = RootDistance+1;  // this is the next level
     3771          // first count the members in the subset
     3772          SubSetDimension = 0;
     3773          Binder = FragmentSearch->BondsPerSPList[2*SP];    // start node for this level
     3774          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {    // compare to end node of this level
     3775            Binder = Binder->next;
     3776            for (int k=TouchedIndex;k--;) {
     3777              if (Binder->Contains(TouchedList[k]))  // if we added this very endpiece
     3778                SubSetDimension++;
     3779            }
     3780          }
     3781          // then allocate and fill the list
     3782          BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
     3783          SubSetDimension = 0;
     3784          Binder = FragmentSearch->BondsPerSPList[2*SP];
     3785          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
     3786            Binder = Binder->next;
     3787            for (int k=0;k<TouchedIndex;k++) {
     3788              if (Binder->leftatom->nr == TouchedList[k])  // leftatom is always the close one
     3789                BondsList[SubSetDimension++] = Binder;
     3790            }
     3791          }
     3792          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
     3793          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     3794          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
     3795        }
     3796      } else {
     3797        // --2-- otherwise store the complete fragment
     3798        *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
     3799        // store fragment as a KeySet
     3800        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
     3801        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3802          *out << (*runner) << " ";
     3803        *out << endl;
     3804        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     3805          //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
     3806        InsertFragmentIntoGraph(out, FragmentSearch);
     3807        //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
     3808        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
     3809      }
     3810
     3811      // --3-- remove all added items in this level from snake stack
     3812      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     3813      for(int j=0;j<TouchedIndex;j++) {
     3814        Removal = TouchedList[j];
     3815        *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
     3816        FragmentSearch->FragmentSet->erase(Removal);
     3817        TouchedList[j] = -1;
     3818      }
     3819      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
     3820      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3821        *out << (*runner) << " ";
     3822      *out << endl;
     3823      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     3824    } else {
     3825      *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
     3826    }
     3827  }
     3828  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     3829  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    38303830};
    38313831
     
    38383838bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    38393839{
    3840         atom *Walker = NULL, *Walker2 = NULL;
    3841         bool BondStatus = false;
    3842         int size;
    3843 
    3844         *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    3845         *out << Verbose(2) << "Disconnected atom: ";
    3846 
    3847         // count number of atoms in graph
    3848         size = 0;
    3849         for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
    3850                 size++;
    3851         if (size > 1)
    3852                 for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
    3853                         Walker = FindAtom(*runner);
    3854                         BondStatus = false;
    3855                         for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    3856                                 Walker2 = FindAtom(*runners);
    3857                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    3858                                         if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
    3859                                                 BondStatus = true;
    3860                                                 break;
    3861                                         }
    3862                                         if (BondStatus)
    3863                                                 break;
    3864                                 }
    3865                         }
    3866                         if (!BondStatus) {
    3867                                 *out << (*Walker) << endl;
    3868                                 return false;
    3869                         }
    3870                 }
    3871         else {
    3872                 *out << "none." << endl;
    3873                 return true;
    3874         }
    3875         *out << "none." << endl;
    3876 
    3877         *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
    3878 
    3879         return true;
     3840  atom *Walker = NULL, *Walker2 = NULL;
     3841  bool BondStatus = false;
     3842  int size;
     3843
     3844  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
     3845  *out << Verbose(2) << "Disconnected atom: ";
     3846
     3847  // count number of atoms in graph
     3848  size = 0;
     3849  for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
     3850    size++;
     3851  if (size > 1)
     3852    for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
     3853      Walker = FindAtom(*runner);
     3854      BondStatus = false;
     3855      for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
     3856        Walker2 = FindAtom(*runners);
     3857        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     3858          if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     3859            BondStatus = true;
     3860            break;
     3861          }
     3862          if (BondStatus)
     3863            break;
     3864        }
     3865      }
     3866      if (!BondStatus) {
     3867        *out << (*Walker) << endl;
     3868        return false;
     3869      }
     3870    }
     3871  else {
     3872    *out << "none." << endl;
     3873    return true;
     3874  }
     3875  *out << "none." << endl;
     3876
     3877  *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
     3878
     3879  return true;
    38803880}
    38813881
     
    38973897int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    38983898{
    3899         int SP, AtomKeyNr;
    3900         atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
    3901         bond *Binder = NULL;
    3902         bond *CurrentEdge = NULL;
    3903         bond **BondsList = NULL;
    3904         int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    3905         int Counter = FragmentSearch.FragmentCounter;
    3906         int RemainingWalkers;
    3907 
    3908         *out << endl;
    3909         *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
    3910 
    3911         // prepare Label and SP arrays of the BFS search
    3912         FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
    3913 
    3914         // prepare root level (SP = 0) and a loop bond denoting Root
    3915         for (int i=1;i<Order;i++)
    3916                 FragmentSearch.BondsPerSPCount[i] = 0;
    3917         FragmentSearch.BondsPerSPCount[0] = 1;
    3918         Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    3919         add(Binder, FragmentSearch.BondsPerSPList[1]);
    3920 
    3921         // do a BFS search to fill the SP lists and label the found vertices
    3922         // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    3923         // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    3924         // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    3925         // (EdgeinSPLevel) of this tree ...
    3926         // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    3927         // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
    3928         *out << endl;
    3929         *out << Verbose(0) << "Starting BFS analysis ..." << endl;
    3930         for (SP = 0; SP < (Order-1); SP++) {
    3931                 *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
    3932                 if (SP > 0) {
    3933                         *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
    3934                         FragmentSearch.BondsPerSPCount[SP] = 0;
    3935                 } else
    3936                         *out << "." << endl;
    3937 
    3938                 RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
    3939                 CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];              /// start of this SP level's list
    3940                 while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {            /// end of this SP level's list
    3941                         CurrentEdge = CurrentEdge->next;
    3942                         RemainingWalkers--;
    3943                         Walker = CurrentEdge->rightatom;                // rightatom is always the one more distant
    3944                         Predecessor = CurrentEdge->leftatom;            // ... and leftatom is predecessor
    3945                         AtomKeyNr = Walker->nr;
    3946                         *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
    3947                         // check for new sp level
    3948                         // go through all its bonds
    3949                         *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    3950                         for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
    3951                                 Binder = ListOfBondsPerAtom[AtomKeyNr][i];
    3952                                 OtherWalker = Binder->GetOtherAtom(Walker);
    3953                                 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    3954         #ifdef ADDHYDROGEN
    3955                                 && (OtherWalker->type->Z != 1)
    3956         #endif
    3957                                                                                                                                                                                                                                                         ) {     // skip hydrogens and restrict to fragment
    3958                                         *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
    3959                                         // set the label if not set (and push on root stack as well)
    3960                                         if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
    3961                                                 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
    3962                                                 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
    3963                                                 // add the bond in between to the SP list
    3964                                                 Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
    3965                                                 add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
    3966                                                 FragmentSearch.BondsPerSPCount[SP+1]++;
    3967                                                 *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
    3968                                         } else {
    3969                                                 if (OtherWalker != Predecessor)
    3970                                                         *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
    3971                                                 else
    3972                                                         *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
    3973                                         }
    3974                                 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
    3975                         }
    3976                 }
    3977         }
    3978 
    3979         // outputting all list for debugging
    3980         *out << Verbose(0) << "Printing all found lists." << endl;
    3981         for(int i=1;i<Order;i++) {              // skip the root edge in the printing
    3982                 Binder = FragmentSearch.BondsPerSPList[2*i];
    3983                 *out << Verbose(1) << "Current SP level is " << i << "." << endl;
    3984                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    3985                         Binder = Binder->next;
    3986                         *out << Verbose(2) << *Binder << endl;
    3987                 }
    3988         }
    3989 
    3990         // creating fragments with the found edge sets  (may be done in reverse order, faster)
    3991         SP = -1;        // the Root <-> Root edge must be subtracted!
    3992         for(int i=Order;i--;) { // sum up all found edges
    3993                 Binder = FragmentSearch.BondsPerSPList[2*i];
    3994                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    3995                         Binder = Binder->next;
    3996                         SP ++;
    3997                 }
    3998         }
    3999         *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
    4000         if (SP >= (Order-1)) {
    4001                 // start with root (push on fragment stack)
    4002                 *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4003                 FragmentSearch.FragmentSet->clear();
    4004                 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    4005                 // prepare the subset and call the generator
    4006                 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    4007                 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4008 
    4009                 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4010 
    4011                 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    4012         } else {
    4013                 *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
    4014         }
    4015 
    4016         // as FragmentSearch structure is used only once, we don't have to clean it anymore
    4017         // remove root from stack
    4018         *out << Verbose(0) << "Removing root again from stack." << endl;
    4019         FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    4020 
    4021         // free'ing the bonds lists
    4022         *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
    4023         for(int i=Order;i--;) {
    4024                 *out << Verbose(1) << "Current SP level is " << i << ": ";
    4025                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4026                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4027                         Binder = Binder->next;
    4028                         // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
    4029                         FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
    4030                         FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
    4031                 }
    4032                 // delete added bonds
    4033                 cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
    4034                 // also start and end node
    4035                 *out << "cleaned." << endl;
    4036         }
    4037 
    4038         // return list
    4039         *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    4040         return (FragmentSearch.FragmentCounter - Counter);
     3899  int SP, AtomKeyNr;
     3900  atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
     3901  bond *Binder = NULL;
     3902  bond *CurrentEdge = NULL;
     3903  bond **BondsList = NULL;
     3904  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
     3905  int Counter = FragmentSearch.FragmentCounter;
     3906  int RemainingWalkers;
     3907
     3908  *out << endl;
     3909  *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
     3910
     3911  // prepare Label and SP arrays of the BFS search
     3912  FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
     3913
     3914  // prepare root level (SP = 0) and a loop bond denoting Root
     3915  for (int i=1;i<Order;i++)
     3916    FragmentSearch.BondsPerSPCount[i] = 0;
     3917  FragmentSearch.BondsPerSPCount[0] = 1;
     3918  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     3919  add(Binder, FragmentSearch.BondsPerSPList[1]);
     3920
     3921  // do a BFS search to fill the SP lists and label the found vertices
     3922  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
     3923  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
     3924  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
     3925  // (EdgeinSPLevel) of this tree ...
     3926  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
     3927  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     3928  *out << endl;
     3929  *out << Verbose(0) << "Starting BFS analysis ..." << endl;
     3930  for (SP = 0; SP < (Order-1); SP++) {
     3931    *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
     3932    if (SP > 0) {
     3933      *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
     3934      FragmentSearch.BondsPerSPCount[SP] = 0;
     3935    } else
     3936      *out << "." << endl;
     3937
     3938    RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
     3939    CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];    /// start of this SP level's list
     3940    while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {    /// end of this SP level's list
     3941      CurrentEdge = CurrentEdge->next;
     3942      RemainingWalkers--;
     3943      Walker = CurrentEdge->rightatom;    // rightatom is always the one more distant
     3944      Predecessor = CurrentEdge->leftatom;    // ... and leftatom is predecessor
     3945      AtomKeyNr = Walker->nr;
     3946      *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
     3947      // check for new sp level
     3948      // go through all its bonds
     3949      *out << Verbose(1) << "Going through all bonds of Walker." << endl;
     3950      for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
     3951        Binder = ListOfBondsPerAtom[AtomKeyNr][i];
     3952        OtherWalker = Binder->GetOtherAtom(Walker);
     3953        if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
     3954  #ifdef ADDHYDROGEN
     3955        && (OtherWalker->type->Z != 1)
     3956  #endif
     3957                                                              ) {  // skip hydrogens and restrict to fragment
     3958          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     3959          // set the label if not set (and push on root stack as well)
     3960          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     3961            FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
     3962            *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
     3963            // add the bond in between to the SP list
     3964            Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
     3965            add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
     3966            FragmentSearch.BondsPerSPCount[SP+1]++;
     3967            *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
     3968          } else {
     3969            if (OtherWalker != Predecessor)
     3970              *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
     3971            else
     3972              *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
     3973          }
     3974        } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
     3975      }
     3976    }
     3977  }
     3978
     3979  // outputting all list for debugging
     3980  *out << Verbose(0) << "Printing all found lists." << endl;
     3981  for(int i=1;i<Order;i++) {    // skip the root edge in the printing
     3982    Binder = FragmentSearch.BondsPerSPList[2*i];
     3983    *out << Verbose(1) << "Current SP level is " << i << "." << endl;
     3984    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     3985      Binder = Binder->next;
     3986      *out << Verbose(2) << *Binder << endl;
     3987    }
     3988  }
     3989
     3990  // creating fragments with the found edge sets  (may be done in reverse order, faster)
     3991  SP = -1;  // the Root <-> Root edge must be subtracted!
     3992  for(int i=Order;i--;) { // sum up all found edges
     3993    Binder = FragmentSearch.BondsPerSPList[2*i];
     3994    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     3995      Binder = Binder->next;
     3996      SP ++;
     3997    }
     3998  }
     3999  *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
     4000  if (SP >= (Order-1)) {
     4001    // start with root (push on fragment stack)
     4002    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
     4003    FragmentSearch.FragmentSet->clear();
     4004    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
     4005    // prepare the subset and call the generator
     4006    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
     4007    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
     4008
     4009    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
     4010
     4011    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
     4012  } else {
     4013    *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
     4014  }
     4015
     4016  // as FragmentSearch structure is used only once, we don't have to clean it anymore
     4017  // remove root from stack
     4018  *out << Verbose(0) << "Removing root again from stack." << endl;
     4019  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4020
     4021  // free'ing the bonds lists
     4022  *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
     4023  for(int i=Order;i--;) {
     4024    *out << Verbose(1) << "Current SP level is " << i << ": ";
     4025    Binder = FragmentSearch.BondsPerSPList[2*i];
     4026    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4027      Binder = Binder->next;
     4028      // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
     4029      FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
     4030      FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
     4031    }
     4032    // delete added bonds
     4033    cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
     4034    // also start and end node
     4035    *out << "cleaned." << endl;
     4036  }
     4037
     4038  // return list
     4039  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
     4040  return (FragmentSearch.FragmentCounter - Counter);
    40414041};
    40424042
     
    40494049void molecule::ScanForPeriodicCorrection(ofstream *out)
    40504050{
    4051         bond *Binder = NULL;
    4052         bond *OtherBinder = NULL;
    4053         atom *Walker = NULL;
    4054         atom *OtherWalker = NULL;
    4055         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    4056         enum Shading *ColorList = NULL;
    4057         double tmp;
    4058         Vector Translationvector;
    4059         //class StackClass<atom *> *CompStack = NULL;
    4060         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    4061         bool flag = true;
    4062 
    4063         *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
    4064 
    4065         ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
    4066         while (flag) {
    4067                 // remove bonds that are beyond bonddistance
    4068                 for(int i=NDIM;i--;)
    4069                         Translationvector.x[i] = 0.;
    4070                 // scan all bonds
    4071                 Binder = first;
    4072                 flag = false;
    4073                 while ((!flag) && (Binder->next != last)) {
    4074                         Binder = Binder->next;
    4075                         for (int i=NDIM;i--;) {
    4076                                 tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
    4077                                 //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
    4078                                 if (tmp > BondDistance) {
    4079                                         OtherBinder = Binder->next; // note down binding partner for later re-insertion
    4080                                         unlink(Binder); // unlink bond
    4081                                         *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
    4082                                         flag = true;
    4083                                         break;
    4084                                 }
    4085                         }
    4086                 }
    4087                 if (flag) {
    4088                         // create translation vector from their periodically modified distance
    4089                         for (int i=NDIM;i--;) {
    4090                                 tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
    4091                                 if (fabs(tmp) > BondDistance)
    4092                                         Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
    4093                         }
    4094                         Translationvector.MatrixMultiplication(matrix);
    4095                         //*out << Verbose(3) << "Translation vector is ";
    4096                         Translationvector.Output(out);
    4097                         *out << endl;
    4098                         // apply to all atoms of first component via BFS
    4099                         for (int i=AtomCount;i--;)
    4100                                 ColorList[i] = white;
    4101                         AtomStack->Push(Binder->leftatom);
    4102                         while (!AtomStack->IsEmpty()) {
    4103                                 Walker = AtomStack->PopFirst();
    4104                                 //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
    4105                                 ColorList[Walker->nr] = black;          // mark as explored
    4106                                 Walker->x.AddVector(&Translationvector); // translate
    4107                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    4108                                         if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    4109                                                 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    4110                                                 if (ColorList[OtherWalker->nr] == white) {
    4111                                                         AtomStack->Push(OtherWalker); // push if yet unexplored
    4112                                                 }
    4113                                         }
    4114                                 }
    4115                         }
    4116                         // re-add bond
    4117                         link(Binder, OtherBinder);
    4118                 } else {
    4119                         *out << Verbose(3) << "No corrections for this fragment." << endl;
    4120                 }
    4121                 //delete(CompStack);
    4122         }
    4123 
    4124         // free allocated space from ReturnFullMatrixforSymmetric()
    4125         delete(AtomStack);
    4126         Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
    4127         Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
    4128         *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
     4051  bond *Binder = NULL;
     4052  bond *OtherBinder = NULL;
     4053  atom *Walker = NULL;
     4054  atom *OtherWalker = NULL;
     4055  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     4056  enum Shading *ColorList = NULL;
     4057  double tmp;
     4058  Vector Translationvector;
     4059  //class StackClass<atom *> *CompStack = NULL;
     4060  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     4061  bool flag = true;
     4062
     4063  *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
     4064
     4065  ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
     4066  while (flag) {
     4067    // remove bonds that are beyond bonddistance
     4068    for(int i=NDIM;i--;)
     4069      Translationvector.x[i] = 0.;
     4070    // scan all bonds
     4071    Binder = first;
     4072    flag = false;
     4073    while ((!flag) && (Binder->next != last)) {
     4074      Binder = Binder->next;
     4075      for (int i=NDIM;i--;) {
     4076        tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
     4077        //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
     4078        if (tmp > BondDistance) {
     4079          OtherBinder = Binder->next; // note down binding partner for later re-insertion
     4080          unlink(Binder);  // unlink bond
     4081          *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
     4082          flag = true;
     4083          break;
     4084        }
     4085      }
     4086    }
     4087    if (flag) {
     4088      // create translation vector from their periodically modified distance
     4089      for (int i=NDIM;i--;) {
     4090        tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
     4091        if (fabs(tmp) > BondDistance)
     4092          Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
     4093      }
     4094      Translationvector.MatrixMultiplication(matrix);
     4095      //*out << Verbose(3) << "Translation vector is ";
     4096      Translationvector.Output(out);
     4097      *out << endl;
     4098      // apply to all atoms of first component via BFS
     4099      for (int i=AtomCount;i--;)
     4100        ColorList[i] = white;
     4101      AtomStack->Push(Binder->leftatom);
     4102      while (!AtomStack->IsEmpty()) {
     4103        Walker = AtomStack->PopFirst();
     4104        //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
     4105        ColorList[Walker->nr] = black;    // mark as explored
     4106        Walker->x.AddVector(&Translationvector); // translate
     4107        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
     4108          if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
     4109            OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     4110            if (ColorList[OtherWalker->nr] == white) {
     4111              AtomStack->Push(OtherWalker); // push if yet unexplored
     4112            }
     4113          }
     4114        }
     4115      }
     4116      // re-add bond
     4117      link(Binder, OtherBinder);
     4118    } else {
     4119      *out << Verbose(3) << "No corrections for this fragment." << endl;
     4120    }
     4121    //delete(CompStack);
     4122  }
     4123
     4124  // free allocated space from ReturnFullMatrixforSymmetric()
     4125  delete(AtomStack);
     4126  Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
     4127  Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
     4128  *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
    41294129};
    41304130
     
    41354135double * molecule::ReturnFullMatrixforSymmetric(double *symm)
    41364136{
    4137         double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
    4138         matrix[0] = symm[0];
    4139         matrix[1] = symm[1];
    4140         matrix[2] = symm[3];
    4141         matrix[3] = symm[1];
    4142         matrix[4] = symm[2];
    4143         matrix[5] = symm[4];
    4144         matrix[6] = symm[3];
    4145         matrix[7] = symm[4];
    4146         matrix[8] = symm[5];
    4147         return matrix;
     4137  double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
     4138  matrix[0] = symm[0];
     4139  matrix[1] = symm[1];
     4140  matrix[2] = symm[3];
     4141  matrix[3] = symm[1];
     4142  matrix[4] = symm[2];
     4143  matrix[5] = symm[4];
     4144  matrix[6] = symm[3];
     4145  matrix[7] = symm[4];
     4146  matrix[8] = symm[5];
     4147  return matrix;
    41484148};
    41494149
    41504150bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
    41514151{
    4152         //cout << "my check is used." << endl;
    4153         if (SubgraphA.size() < SubgraphB.size()) {
    4154                 return true;
    4155         } else {
    4156                 if (SubgraphA.size() > SubgraphB.size()) {
    4157                         return false;
    4158                 } else {
    4159                         KeySet::iterator IteratorA = SubgraphA.begin();
    4160                         KeySet::iterator IteratorB = SubgraphB.begin();
    4161                         while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
    4162                                 if ((*IteratorA) <      (*IteratorB))
    4163                                         return true;
    4164                                 else if ((*IteratorA) > (*IteratorB)) {
    4165                                                 return false;
    4166                                         } // else, go on to next index
    4167                                 IteratorA++;
    4168                                 IteratorB++;
    4169                         } // end of while loop
    4170                 }// end of check in case of equal sizes
    4171         }
    4172         return false; // if we reach this point, they are equal
     4152  //cout << "my check is used." << endl;
     4153  if (SubgraphA.size() < SubgraphB.size()) {
     4154    return true;
     4155  } else {
     4156    if (SubgraphA.size() > SubgraphB.size()) {
     4157      return false;
     4158    } else {
     4159      KeySet::iterator IteratorA = SubgraphA.begin();
     4160      KeySet::iterator IteratorB = SubgraphB.begin();
     4161      while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
     4162        if ((*IteratorA) <  (*IteratorB))
     4163          return true;
     4164        else if ((*IteratorA) > (*IteratorB)) {
     4165            return false;
     4166          } // else, go on to next index
     4167        IteratorA++;
     4168        IteratorB++;
     4169      } // end of while loop
     4170    }// end of check in case of equal sizes
     4171  }
     4172  return false; // if we reach this point, they are equal
    41734173};
    41744174
    41754175//bool operator < (KeySet SubgraphA, KeySet SubgraphB)
    41764176//{
    4177 //      return KeyCompare(SubgraphA, SubgraphB);
     4177//  return KeyCompare(SubgraphA, SubgraphB);
    41784178//};
    41794179
     
    41874187inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment)
    41884188{
    4189         GraphTestPair testGraphInsert;
    4190 
    4191         testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor))); // store fragment number and current factor
    4192         if (testGraphInsert.second) {
    4193                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
    4194                 Fragment->FragmentCounter++;
    4195         } else {
    4196                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4197                 ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;       // increase the "created" counter
    4198                 *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
    4199         }
     4189  GraphTestPair testGraphInsert;
     4190
     4191  testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor)));  // store fragment number and current factor
     4192  if (testGraphInsert.second) {
     4193    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
     4194    Fragment->FragmentCounter++;
     4195  } else {
     4196    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4197    ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;  // increase the "created" counter
     4198    *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
     4199  }
    42004200};
    42014201//void inline InsertIntoGraph(ofstream *out, KeyStack &stack, Graph &graph, int *counter, double factor)
    42024202//{
    4203 //      // copy stack contents to set and call overloaded function again
    4204 //      KeySet set;
    4205 //      for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
    4206 //              set.insert((*runner));
    4207 //      InsertIntoGraph(out, set, graph, counter, factor);
     4203//  // copy stack contents to set and call overloaded function again
     4204//  KeySet set;
     4205//  for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
     4206//    set.insert((*runner));
     4207//  InsertIntoGraph(out, set, graph, counter, factor);
    42084208//};
    42094209
     
    42164216inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
    42174217{
    4218         GraphTestPair testGraphInsert;
    4219 
    4220         for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
    4221                 testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
    4222                 if (testGraphInsert.second) {
    4223                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
    4224                 } else {
    4225                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4226                         ((*(testGraphInsert.first)).second).second += (*runner).second.second;
    4227                         *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
    4228                 }
    4229         }
     4218  GraphTestPair testGraphInsert;
     4219
     4220  for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
     4221    testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
     4222    if (testGraphInsert.second) {
     4223      *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
     4224    } else {
     4225      *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4226      ((*(testGraphInsert.first)).second).second += (*runner).second.second;
     4227      *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
     4228    }
     4229  }
    42304230};
    42314231
     
    42344234 * -# constructs a complete keyset of the molecule
    42354235 * -# In a loop over all possible roots from the given rootstack
    4236  *      -# increases order of root site
    4237  *      -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
    4238  *      -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
     4236 *  -# increases order of root site
     4237 *  -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
     4238 *  -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
    42394239as the restricted one and each site in the set as the root)
    4240  *      -# these are merged into a fragment list of keysets
     4240 *  -# these are merged into a fragment list of keysets
    42414241 * -# All fragment lists (for all orders, i.e. from all destination fields) are merged into one list for return
    42424242 * Important only is that we create all fragments, it is not important if we create them more than once
     
    42504250void molecule::FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize)
    42514251{
    4252         Graph ***FragmentLowerOrdersList = NULL;
    4253         int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
    4254         int counter = 0, Order;
    4255         int UpgradeCount = RootStack.size();
    4256         KeyStack FragmentRootStack;
    4257         int RootKeyNr, RootNr;
    4258         struct UniqueFragments FragmentSearch;
    4259 
    4260         *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    4261 
    4262         // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
    4263         // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
    4264         NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4265         FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4266 
    4267         // initialise the fragments structure
    4268         FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    4269         FragmentSearch.FragmentCounter = 0;
    4270         FragmentSearch.FragmentSet = new KeySet;
    4271         FragmentSearch.Root = FindAtom(RootKeyNr);
    4272         for (int i=AtomCount;i--;) {
    4273                 FragmentSearch.ShortestPathList[i] = -1;
    4274         }
    4275 
    4276         // Construct the complete KeySet which we need for topmost level only (but for all Roots)
    4277         atom *Walker = start;
    4278         KeySet CompleteMolecule;
    4279         while (Walker->next != end) {
    4280                 Walker = Walker->next;
    4281                 CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4282         }
    4283 
    4284         // 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
    4285         // 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),
    4286         // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
    4287         // 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)
    4288         RootNr = 0;      // counts through the roots in RootStack
    4289         while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
    4290                 RootKeyNr = RootStack.front();
    4291                 RootStack.pop_front();
    4292                 Walker = FindAtom(RootKeyNr);
    4293                 // check cyclic lengths
    4294                 //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    4295                 //      *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;
    4296                 //} else
    4297                 {
    4298                         // increase adaptive order by one
    4299                         Walker->GetTrueFather()->AdaptiveOrder++;
    4300                         Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4301 
    4302                         // initialise Order-dependent entries of UniqueFragments structure
    4303                         FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4304                         FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4305                         for (int i=Order;i--;) {
    4306                                 FragmentSearch.BondsPerSPList[2*i] = new bond();                // start node
    4307                                 FragmentSearch.BondsPerSPList[2*i+1] = new bond();      // end node
    4308                                 FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];                // intertwine these two
    4309                                 FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    4310                                 FragmentSearch.BondsPerSPCount[i] = 0;
    4311                         }
    4312 
    4313                         // allocate memory for all lower level orders in this 1D-array of ptrs
    4314                         NumLevels = 1 << (Order-1); // (int)pow(2,Order);
    4315                         FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4316                         for (int i=0;i<NumLevels;i++)
    4317                                 FragmentLowerOrdersList[RootNr][i] = NULL;
    4318 
    4319                         // create top order where nothing is reduced
    4320                         *out << Verbose(0) << "==============================================================================================================" << endl;
    4321                         *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4322 
    4323                         // Create list of Graphs of current Bond Order (i.e. F_{ij})
    4324                         FragmentLowerOrdersList[RootNr][0] =    new Graph;
    4325                         FragmentSearch.TEFactor = 1.;
    4326                         FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];                    // set to insertion graph
    4327                         FragmentSearch.Root = Walker;
    4328                         NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
    4329                         *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4330                         if (NumMoleculesOfOrder[RootNr] != 0) {
    4331                                 NumMolecules = 0;
    4332 
    4333                                 // we don't have to dive into suborders! These keysets are all already created on lower orders!
    4334                                 // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4335 
    4336 //                              if ((NumLevels >> 1) > 0) {
    4337 //                                      // create lower order fragments
    4338 //                                      *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
    4339 //                                      Order = Walker->AdaptiveOrder;
    4340 //                                      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)
    4341 //                                              // step down to next order at (virtual) boundary of powers of 2 in array
    4342 //                                              while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    4343 //                                                      Order--;
    4344 //                                              *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
    4345 //                                              for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
    4346 //                                                      int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
    4347 //                                                      *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    4348 //                                                      *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
     4252  Graph ***FragmentLowerOrdersList = NULL;
     4253  int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
     4254  int counter = 0, Order;
     4255  int UpgradeCount = RootStack.size();
     4256  KeyStack FragmentRootStack;
     4257  int RootKeyNr, RootNr;
     4258  struct UniqueFragments FragmentSearch;
     4259
     4260  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
     4261
     4262  // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
     4263  // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
     4264  NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4265  FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4266
     4267  // initialise the fragments structure
     4268  FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
     4269  FragmentSearch.FragmentCounter = 0;
     4270  FragmentSearch.FragmentSet = new KeySet;
     4271  FragmentSearch.Root = FindAtom(RootKeyNr);
     4272  for (int i=AtomCount;i--;) {
     4273    FragmentSearch.ShortestPathList[i] = -1;
     4274  }
     4275
     4276  // Construct the complete KeySet which we need for topmost level only (but for all Roots)
     4277  atom *Walker = start;
     4278  KeySet CompleteMolecule;
     4279  while (Walker->next != end) {
     4280    Walker = Walker->next;
     4281    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
     4282  }
     4283
     4284  // 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
     4285  // 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),
     4286  // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
     4287  // 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)
     4288  RootNr = 0;  // counts through the roots in RootStack
     4289  while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
     4290    RootKeyNr = RootStack.front();
     4291    RootStack.pop_front();
     4292    Walker = FindAtom(RootKeyNr);
     4293    // check cyclic lengths
     4294    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
     4295    //  *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;
     4296    //} else
     4297    {
     4298      // increase adaptive order by one
     4299      Walker->GetTrueFather()->AdaptiveOrder++;
     4300      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
     4301
     4302      // initialise Order-dependent entries of UniqueFragments structure
     4303      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4304      FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4305      for (int i=Order;i--;) {
     4306        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
     4307        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
     4308        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];    // intertwine these two
     4309        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
     4310        FragmentSearch.BondsPerSPCount[i] = 0;
     4311      }
     4312
     4313      // allocate memory for all lower level orders in this 1D-array of ptrs
     4314      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     4315      FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4316      for (int i=0;i<NumLevels;i++)
     4317        FragmentLowerOrdersList[RootNr][i] = NULL;
     4318
     4319      // create top order where nothing is reduced
     4320      *out << Verbose(0) << "==============================================================================================================" << endl;
     4321      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
     4322
     4323      // Create list of Graphs of current Bond Order (i.e. F_{ij})
     4324      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     4325      FragmentSearch.TEFactor = 1.;
     4326      FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];      // set to insertion graph
     4327      FragmentSearch.Root = Walker;
     4328      NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
     4329      *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4330      if (NumMoleculesOfOrder[RootNr] != 0) {
     4331        NumMolecules = 0;
     4332
     4333        // we don't have to dive into suborders! These keysets are all already created on lower orders!
     4334        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
     4335
     4336//        if ((NumLevels >> 1) > 0) {
     4337//          // create lower order fragments
     4338//          *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
     4339//          Order = Walker->AdaptiveOrder;
     4340//          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)
     4341//            // step down to next order at (virtual) boundary of powers of 2 in array
     4342//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4343//              Order--;
     4344//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     4345//            for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
     4346//              int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
     4347//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
     4348//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    43494349//
    4350 //                                                      // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    4351 //                                                      //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
    4352 //                                                      //NumMolecules = 0;
    4353 //                                                      FragmentLowerOrdersList[RootNr][dest] = new Graph;
    4354 //                                                      for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
    4355 //                                                              for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    4356 //                                                                      Graph TempFragmentList;
    4357 //                                                                      FragmentSearch.TEFactor = -(*runner).second.second;
    4358 //                                                                      FragmentSearch.Leaflet = &TempFragmentList;                     // set to insertion graph
    4359 //                                                                      FragmentSearch.Root = FindAtom(*sprinter);
    4360 //                                                                      NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
    4361 //                                                                      // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
    4362 //                                                                      *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
    4363 //                                                                      InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
    4364 //                                                              }
    4365 //                                                      }
    4366 //                                                      *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
    4367 //                                              }
    4368 //                                      }
    4369 //                              }
    4370                         } else {
    4371                                 Walker->GetTrueFather()->MaxOrder = true;
    4372 //                              *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
    4373                         }
    4374                         // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
    4375                         //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
    4376                         TotalNumMolecules += NumMoleculesOfOrder[RootNr];
    4377 //                      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4378                         RootStack.push_back(RootKeyNr); // put back on stack
    4379                         RootNr++;
    4380 
    4381                         // free Order-dependent entries of UniqueFragments structure for next loop cycle
    4382                         Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4383                         for (int i=Order;i--;) {
    4384                                 delete(FragmentSearch.BondsPerSPList[2*i]);
    4385                                 delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4386                         }
    4387                         Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4388                 }
    4389         }
    4390         *out << Verbose(0) << "==============================================================================================================" << endl;
    4391         *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
    4392         *out << Verbose(0) << "==============================================================================================================" << endl;
    4393 
    4394         // cleanup FragmentSearch structure
    4395         Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    4396         delete(FragmentSearch.FragmentSet);
    4397 
    4398         // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    4399         // 5433222211111111
    4400         // 43221111
    4401         // 3211
    4402         // 21
    4403         // 1
    4404 
    4405         // Subsequently, we combine all into a single list (FragmentList)
    4406 
    4407         *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
    4408         if (FragmentList == NULL) {
    4409                 FragmentList = new Graph;
    4410                 counter = 0;
    4411         } else {
    4412                 counter = FragmentList->size();
    4413         }
    4414         RootNr = 0;
    4415         while (!RootStack.empty()) {
    4416                 RootKeyNr = RootStack.front();
    4417                 RootStack.pop_front();
    4418                 Walker = FindAtom(RootKeyNr);
    4419                 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    4420                 for(int i=0;i<NumLevels;i++) {
    4421                         if (FragmentLowerOrdersList[RootNr][i] != NULL) {
    4422                                 InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
    4423                                 delete(FragmentLowerOrdersList[RootNr][i]);
    4424                         }
    4425                 }
    4426                 Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4427                 RootNr++;
    4428         }
    4429         Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4430         Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4431 
    4432         *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
     4350//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
     4351//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     4352//              //NumMolecules = 0;
     4353//              FragmentLowerOrdersList[RootNr][dest] = new Graph;
     4354//              for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
     4355//                for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     4356//                  Graph TempFragmentList;
     4357//                  FragmentSearch.TEFactor = -(*runner).second.second;
     4358//                  FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
     4359//                  FragmentSearch.Root = FindAtom(*sprinter);
     4360//                  NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
     4361//                  // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
     4362//                  *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
     4363//                  InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
     4364//                }
     4365//              }
     4366//              *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
     4367//            }
     4368//          }
     4369//        }
     4370      } else {
     4371        Walker->GetTrueFather()->MaxOrder = true;
     4372//        *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
     4373      }
     4374      // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
     4375      //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
     4376      TotalNumMolecules += NumMoleculesOfOrder[RootNr];
     4377//      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4378      RootStack.push_back(RootKeyNr); // put back on stack
     4379      RootNr++;
     4380
     4381      // free Order-dependent entries of UniqueFragments structure for next loop cycle
     4382      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4383      for (int i=Order;i--;) {
     4384        delete(FragmentSearch.BondsPerSPList[2*i]);
     4385        delete(FragmentSearch.BondsPerSPList[2*i+1]);
     4386      }
     4387      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4388    }
     4389  }
     4390  *out << Verbose(0) << "==============================================================================================================" << endl;
     4391  *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
     4392  *out << Verbose(0) << "==============================================================================================================" << endl;
     4393
     4394  // cleanup FragmentSearch structure
     4395  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
     4396  delete(FragmentSearch.FragmentSet);
     4397
     4398  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4399  // 5433222211111111
     4400  // 43221111
     4401  // 3211
     4402  // 21
     4403  // 1
     4404
     4405  // Subsequently, we combine all into a single list (FragmentList)
     4406
     4407  *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
     4408  if (FragmentList == NULL) {
     4409    FragmentList = new Graph;
     4410    counter = 0;
     4411  } else {
     4412    counter = FragmentList->size();
     4413  }
     4414  RootNr = 0;
     4415  while (!RootStack.empty()) {
     4416    RootKeyNr = RootStack.front();
     4417    RootStack.pop_front();
     4418    Walker = FindAtom(RootKeyNr);
     4419    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
     4420    for(int i=0;i<NumLevels;i++) {
     4421      if (FragmentLowerOrdersList[RootNr][i] != NULL) {
     4422        InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
     4423        delete(FragmentLowerOrdersList[RootNr][i]);
     4424      }
     4425    }
     4426    Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4427    RootNr++;
     4428  }
     4429  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4430  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4431
     4432  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    44334433};
    44344434
     
    44404440inline int CompareDoubles (const void * a, const void * b)
    44414441{
    4442         if (*(double *)a > *(double *)b)
    4443                 return -1;
    4444         else if (*(double *)a < *(double *)b)
    4445                 return 1;
    4446         else
    4447                 return 0;
     4442  if (*(double *)a > *(double *)b)
     4443    return -1;
     4444  else if (*(double *)a < *(double *)b)
     4445    return 1;
     4446  else
     4447    return 0;
    44484448};
    44494449
     
    44564456int * molecule::IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold)
    44574457{
    4458         int flag;
    4459         double *Distances = NULL, *OtherDistances = NULL;
    4460         Vector CenterOfGravity, OtherCenterOfGravity;
    4461         size_t *PermMap = NULL, *OtherPermMap = NULL;
    4462         int *PermutationMap = NULL;
    4463         atom *Walker = NULL;
    4464         bool result = true; // status of comparison
    4465 
    4466         *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    4467         /// first count both their atoms and elements and update lists thereby ...
    4468         //*out << Verbose(0) << "Counting atoms, updating list" << endl;
    4469         CountAtoms(out);
    4470         OtherMolecule->CountAtoms(out);
    4471         CountElements();
    4472         OtherMolecule->CountElements();
    4473 
    4474         /// ... and compare:
    4475         /// -# AtomCount
    4476         if (result) {
    4477                 if (AtomCount != OtherMolecule->AtomCount) {
    4478                         *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4479                         result = false;
    4480                 } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4481         }
    4482         /// -# ElementCount
    4483         if (result) {
    4484                 if (ElementCount != OtherMolecule->ElementCount) {
    4485                         *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4486                         result = false;
    4487                 } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4488         }
    4489         /// -# ElementsInMolecule
    4490         if (result) {
    4491                 for (flag=MAX_ELEMENTS;flag--;) {
    4492                         //*out << Verbose(5) << "Element " <<   flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
    4493                         if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
    4494                                 break;
    4495                 }
    4496                 if (flag < MAX_ELEMENTS) {
    4497                         *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
    4498                         result = false;
    4499                 } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
    4500         }
    4501         /// then determine and compare center of gravity for each molecule ...
    4502         if (result) {
    4503                 *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    4504                 DeterminePeriodicCenter(CenterOfGravity);
    4505                 OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);
    4506                 *out << Verbose(5) << "Center of Gravity: ";
    4507                 CenterOfGravity.Output(out);
    4508                 *out << endl << Verbose(5) << "Other Center of Gravity: ";
    4509                 OtherCenterOfGravity.Output(out);
    4510                 *out << endl;
    4511                 if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
    4512                         *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4513                         result = false;
    4514                 }
    4515         }
    4516 
    4517         /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    4518         if (result) {
    4519                 *out << Verbose(5) << "Calculating distances" << endl;
    4520                 Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    4521                 OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4522                 Walker = start;
    4523                 while (Walker->next != end) {
    4524                         Walker = Walker->next;
    4525                         Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
    4526                 }
    4527                 Walker = OtherMolecule->start;
    4528                 while (Walker->next != OtherMolecule->end) {
    4529                         Walker = Walker->next;
    4530                         OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
    4531                 }
    4532 
    4533                 /// ... sort each list (using heapsort (o(N log N)) from GSL)
    4534                 *out << Verbose(5) << "Sorting distances" << endl;
    4535                 PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    4536                 OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4537                 gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    4538                 gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    4539                 PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4540                 *out << Verbose(5) << "Combining Permutation Maps" << endl;
    4541                 for(int i=AtomCount;i--;)
    4542                         PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4543 
    4544                 /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    4545                 *out << Verbose(4) << "Comparing distances" << endl;
    4546                 flag = 0;
    4547                 for (int i=0;i<AtomCount;i++) {
    4548                         *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<      threshold << endl;
    4549                         if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
    4550                                 flag = 1;
    4551                 }
    4552                 Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    4553                 Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4554 
    4555                 /// free memory
    4556                 Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
    4557                 Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4558                 if (flag) { // if not equal
    4559                         Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4560                         result = false;
    4561                 }
    4562         }
    4563         /// return pointer to map if all distances were below \a threshold
    4564         *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
    4565         if (result) {
    4566                 *out << Verbose(3) << "Result: Equal." << endl;
    4567                 return PermutationMap;
    4568         } else {
    4569                 *out << Verbose(3) << "Result: Not equal." << endl;
    4570                 return NULL;
    4571         }
     4458  int flag;
     4459  double *Distances = NULL, *OtherDistances = NULL;
     4460  Vector CenterOfGravity, OtherCenterOfGravity;
     4461  size_t *PermMap = NULL, *OtherPermMap = NULL;
     4462  int *PermutationMap = NULL;
     4463  atom *Walker = NULL;
     4464  bool result = true; // status of comparison
     4465
     4466  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     4467  /// first count both their atoms and elements and update lists thereby ...
     4468  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     4469  CountAtoms(out);
     4470  OtherMolecule->CountAtoms(out);
     4471  CountElements();
     4472  OtherMolecule->CountElements();
     4473
     4474  /// ... and compare:
     4475  /// -# AtomCount
     4476  if (result) {
     4477    if (AtomCount != OtherMolecule->AtomCount) {
     4478      *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4479      result = false;
     4480    } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4481  }
     4482  /// -# ElementCount
     4483  if (result) {
     4484    if (ElementCount != OtherMolecule->ElementCount) {
     4485      *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4486      result = false;
     4487    } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4488  }
     4489  /// -# ElementsInMolecule
     4490  if (result) {
     4491    for (flag=MAX_ELEMENTS;flag--;) {
     4492      //*out << Verbose(5) << "Element " <<  flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
     4493      if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
     4494        break;
     4495    }
     4496    if (flag < MAX_ELEMENTS) {
     4497      *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
     4498      result = false;
     4499    } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
     4500  }
     4501  /// then determine and compare center of gravity for each molecule ...
     4502  if (result) {
     4503    *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
     4504    DeterminePeriodicCenter(CenterOfGravity);
     4505    OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);
     4506    *out << Verbose(5) << "Center of Gravity: ";
     4507    CenterOfGravity.Output(out);
     4508    *out << endl << Verbose(5) << "Other Center of Gravity: ";
     4509    OtherCenterOfGravity.Output(out);
     4510    *out << endl;
     4511    if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
     4512      *out << Verbose(4) << "Centers of gravity don't match." << endl;
     4513      result = false;
     4514    }
     4515  }
     4516
     4517  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
     4518  if (result) {
     4519    *out << Verbose(5) << "Calculating distances" << endl;
     4520    Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
     4521    OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4522    Walker = start;
     4523    while (Walker->next != end) {
     4524      Walker = Walker->next;
     4525      Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
     4526    }
     4527    Walker = OtherMolecule->start;
     4528    while (Walker->next != OtherMolecule->end) {
     4529      Walker = Walker->next;
     4530      OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
     4531    }
     4532
     4533    /// ... sort each list (using heapsort (o(N log N)) from GSL)
     4534    *out << Verbose(5) << "Sorting distances" << endl;
     4535    PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
     4536    OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4537    gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
     4538    gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
     4539    PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4540    *out << Verbose(5) << "Combining Permutation Maps" << endl;
     4541    for(int i=AtomCount;i--;)
     4542      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
     4543
     4544    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
     4545    *out << Verbose(4) << "Comparing distances" << endl;
     4546    flag = 0;
     4547    for (int i=0;i<AtomCount;i++) {
     4548      *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
     4549      if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
     4550        flag = 1;
     4551    }
     4552    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
     4553    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4554
     4555    /// free memory
     4556    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     4557    Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4558    if (flag) { // if not equal
     4559      Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4560      result = false;
     4561    }
     4562  }
     4563  /// return pointer to map if all distances were below \a threshold
     4564  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     4565  if (result) {
     4566    *out << Verbose(3) << "Result: Equal." << endl;
     4567    return PermutationMap;
     4568  } else {
     4569    *out << Verbose(3) << "Result: Not equal." << endl;
     4570    return NULL;
     4571  }
    45724572};
    45734573
     
    45814581int * molecule::GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule)
    45824582{
    4583         atom *Walker = NULL, *OtherWalker = NULL;
    4584         *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
    4585         int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");   //Calloc
    4586         for (int i=AtomCount;i--;)
    4587                 AtomicMap[i] = -1;
    4588         if (OtherMolecule == this) {    // same molecule
    4589                 for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
    4590                         AtomicMap[i] = i;
    4591                 *out << Verbose(4) << "Map is trivial." << endl;
    4592         } else {
    4593                 *out << Verbose(4) << "Map is ";
    4594                 Walker = start;
    4595                 while (Walker->next != end) {
    4596                         Walker = Walker->next;
    4597                         if (Walker->father == NULL) {
    4598                                 AtomicMap[Walker->nr] = -2;
    4599                         } else {
    4600                                 OtherWalker = OtherMolecule->start;
    4601                                 while (OtherWalker->next != OtherMolecule->end) {
    4602                                         OtherWalker = OtherWalker->next;
    4603                         //for (int i=0;i<AtomCount;i++) { // search atom
    4604                                 //for (int j=0;j<OtherMolecule->AtomCount;j++) {
    4605                                         //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
    4606                                         if (Walker->father == OtherWalker)
    4607                                                 AtomicMap[Walker->nr] = OtherWalker->nr;
    4608                                 }
    4609                         }
    4610                         *out << AtomicMap[Walker->nr] << "\t";
    4611                 }
    4612                 *out << endl;
    4613         }
    4614         *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
    4615         return AtomicMap;
     4583  atom *Walker = NULL, *OtherWalker = NULL;
     4584  *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
     4585  int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");  //Calloc
     4586  for (int i=AtomCount;i--;)
     4587    AtomicMap[i] = -1;
     4588  if (OtherMolecule == this) {  // same molecule
     4589    for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
     4590      AtomicMap[i] = i;
     4591    *out << Verbose(4) << "Map is trivial." << endl;
     4592  } else {
     4593    *out << Verbose(4) << "Map is ";
     4594    Walker = start;
     4595    while (Walker->next != end) {
     4596      Walker = Walker->next;
     4597      if (Walker->father == NULL) {
     4598        AtomicMap[Walker->nr] = -2;
     4599      } else {
     4600        OtherWalker = OtherMolecule->start;
     4601        while (OtherWalker->next != OtherMolecule->end) {
     4602          OtherWalker = OtherWalker->next;
     4603      //for (int i=0;i<AtomCount;i++) { // search atom
     4604        //for (int j=0;j<OtherMolecule->AtomCount;j++) {
     4605          //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
     4606          if (Walker->father == OtherWalker)
     4607            AtomicMap[Walker->nr] = OtherWalker->nr;
     4608        }
     4609      }
     4610      *out << AtomicMap[Walker->nr] << "\t";
     4611    }
     4612    *out << endl;
     4613  }
     4614  *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
     4615  return AtomicMap;
    46164616};
    46174617
     
    46274627bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    46284628{
    4629         double temperature;
    4630         atom *Walker = NULL;
    4631         // test stream
    4632         if (output == NULL)
    4633                 return false;
    4634         else
    4635                 *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    4636         for (int step=startstep;step < endstep; step++) { // loop over all time steps
    4637                 temperature = 0.;
    4638                 Walker = start;
    4639                 while (Walker->next != end) {
    4640                         Walker = Walker->next;
    4641                         for (int i=NDIM;i--;)
    4642                                 temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
    4643                 }
    4644                 *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
    4645         }
    4646         return true;
    4647 };
     4629  double temperature;
     4630  atom *Walker = NULL;
     4631  // test stream
     4632  if (output == NULL)
     4633    return false;
     4634  else
     4635    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
     4636  for (int step=startstep;step < endstep; step++) { // loop over all time steps
     4637    temperature = 0.;
     4638    Walker = start;
     4639    while (Walker->next != end) {
     4640      Walker = Walker->next;
     4641      for (int i=NDIM;i--;)
     4642        temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
     4643    }
     4644    *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
     4645  }
     4646  return true;
     4647};
Note: See TracChangeset for help on using the changeset viewer.