Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecules.cpp

    • Property mode changed from 100755 to 100644
    rcc2ee5 r4158ba  
    11/** \file molecules.cpp
    2  *
     2 * 
    33 * Functions for the class molecule.
    4  *
     4 * 
    55 */
    66
     
    2525      sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
    2626  }
    27 
     27 
    2828  return sum;
    2929};
     
    3434 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    3535 */
    36 molecule::molecule(periodentafel *teil)
    37 {
     36molecule::molecule(periodentafel *teil) 
     37{ 
    3838  // init atom chain list
    39   start = new atom;
     39  start = new atom; 
    4040  end = new atom;
    41   start->father = NULL;
     41  start->father = NULL; 
    4242  end->father = NULL;
    4343  link(start,end);
     
    4646  last = new bond(start, end, 1, -1);
    4747  link(first,last);
    48   // other stuff
     48  // other stuff 
    4949  MDSteps = 0;
    50   last_atom = 0;
     50  last_atom = 0; 
    5151  elemente = teil;
    5252  AtomCount = 0;
     
    6767 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    6868 */
    69 molecule::~molecule()
     69molecule::~molecule() 
    7070{
    7171  if (ListOfBondsPerAtom != NULL)
     
    7878  delete(last);
    7979  delete(end);
    80   delete(start);
     80  delete(start); 
    8181};
    8282
    8383/** Adds given atom \a *pointer from molecule list.
    84  * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount
     84 * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount 
    8585 * \param *pointer allocated and set atom
    8686 * \return true - succeeded, false - atom not found in list
    8787 */
    8888bool molecule::AddAtom(atom *pointer)
    89 {
     89{ 
    9090  if (pointer != NULL) {
    91     pointer->sort = &pointer->nr;
     91    pointer->sort = &pointer->nr; 
    9292    pointer->nr = last_atom++;  // increase number within molecule
    9393    AtomCount++;
     
    106106    return add(pointer, end);
    107107  } else
    108     return false;
     108    return false; 
    109109};
    110110
     
    115115 */
    116116atom * molecule::AddCopyAtom(atom *pointer)
    117 {
     117{ 
    118118  if (pointer != NULL) {
    119119        atom *walker = new atom();
     
    122122    walker->v.CopyVector(&pointer->v); // copy velocity
    123123    walker->FixedIon = pointer->FixedIon;
    124     walker->sort = &walker->nr;
     124    walker->sort = &walker->nr; 
    125125    walker->nr = last_atom++;  // increase number within molecule
    126126    walker->father = pointer; //->GetTrueFather();
     
    133133    return walker;
    134134  } else
    135     return NULL;
     135    return NULL; 
    136136};
    137137
     
    156156 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    157157 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    158  *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     158 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2} 
    159159 *    \f]
    160  *    as the coordination of all three atoms in the coordinate system of these three vectors:
     160 *    as the coordination of all three atoms in the coordinate system of these three vectors: 
    161161 *    \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$.
    162  *
     162 * 
    163163 * \param *out output stream for debugging
    164  * \param *Bond pointer to bond between \a *origin and \a *replacement
    165  * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin)
     164 * \param *Bond pointer to bond between \a *origin and \a *replacement 
     165 * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin) 
    166166 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length
    167167 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
     
    191191  InBondvector.SubtractVector(&TopOrigin->x);
    192192  bondlength = InBondvector.Norm();
    193 
     193   
    194194   // is greater than typical bond distance? Then we have to correct periodically
    195195   // the problem is not the H being out of the box, but InBondvector have the wrong direction
    196    // due to TopReplacement or Origin being on the wrong side!
    197   if (bondlength > BondDistance) {
     196   // due to TopReplacement or Origin being on the wrong side! 
     197  if (bondlength > BondDistance) { 
    198198//    *out << Verbose(4) << "InBondvector is: ";
    199199//    InBondvector.Output(out);
     
    215215//    *out << endl;
    216216  } // periodic correction finished
    217 
     217 
    218218  InBondvector.Normalize();
    219219  // get typical bond length and store as scale factor for later
    220220  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    221221  if (BondRescale == -1) {
    222     cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223     return false;
    224     BondRescale = bondlength;
     222    cerr << Verbose(3) << "WARNING: There is no typical bond distance for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     223    BondRescale = bondlength;
    225224  } else {
    226225    if (!IsAngstroem)
     
    273272      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    274273//        *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
    275 
     274       
    276275        // determine the plane of these two with the *origin
    277276        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     
    286285      Orthovector1.Normalize();
    287286      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    288 
     287     
    289288      // create the two Hydrogens ...
    290289      FirstOtherAtom = new atom();
     
    300299      bondangle = TopOrigin->type->HBondAngle[1];
    301300      if (bondangle == -1) {
    302         *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    303         return false;
     301        *out << Verbose(3) << "WARNING: There is no typical bond angle for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    304302        bondangle = 0;
    305303      }
     
    318316        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    319317      }
    320       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     318      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance 
    321319      SecondOtherAtom->x.Scale(&BondRescale);
    322320      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    323321      for(int i=NDIM;i--;) { // and make relative to origin atom
    324         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     322        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 
    325323        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326324      }
     
    365363//      *out << endl;
    366364      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    367 //      *out << Verbose(3) << "Orthovector2: ";
     365//      *out << Verbose(3) << "Orthovector2: "; 
    368366//      Orthovector2.Output(out);
    369367//      *out << endl;
    370 
     368     
    371369      // create correct coordination for the three atoms
    372370      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     
    380378      factors[0] = d;
    381379      factors[1] = f;
    382       factors[2] = 0.;
     380      factors[2] = 0.; 
    383381      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    384382      factors[1] = -0.5*f;
    385       factors[2] = g;
     383      factors[2] = g; 
    386384      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387       factors[2] = -g;
     385      factors[2] = -g; 
    388386      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    389387
     
    437435 */
    438436bool molecule::AddXYZFile(string filename)
    439 {
     437{ 
    440438  istringstream *input = NULL;
    441439  int NumberOfAtoms = 0; // atom number in xyz read
     
    446444  string line;    // currently parsed line
    447445  double x[3];    // atom coordinates
    448 
     446 
    449447  xyzfile.open(filename.c_str());
    450448  if (!xyzfile)
     
    454452  input = new istringstream(line);
    455453  *input >> NumberOfAtoms;
    456   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     454  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 
    457455  getline(xyzfile,line,'\n'); // Read comment
    458456  cout << Verbose(1) << "Comment: " << line << endl;
    459 
     457 
    460458  if (MDSteps == 0) // no atoms yet present
    461459    MDSteps++;
     
    491489  xyzfile.close();
    492490  delete(input);
    493   return true;
     491  return true; 
    494492};
    495493
     
    503501  atom *LeftAtom = NULL, *RightAtom = NULL;
    504502  atom *Walker = NULL;
    505 
     503 
    506504  // copy all atoms
    507505  Walker = start;
     
    510508    CurrentAtom = copy->AddCopyAtom(Walker);
    511509  }
    512 
     510 
    513511  // copy all bonds
    514512  bond *Binder = first;
     
    534532      copy->NoCyclicBonds++;
    535533    NewBond->Type = Binder->Type;
    536   }
     534  } 
    537535  // correct fathers
    538536  Walker = copy->start;
     
    551549    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    552550  }
    553 
     551 
    554552  return copy;
    555553};
     
    576574
    577575/** Remove bond from bond chain list.
    578  * \todo Function not implemented yet
     576 * \todo Function not implemented yet 
    579577 * \param *pointer bond pointer
    580578 * \return true - bound found and removed, false - bond not found/removed
     
    588586
    589587/** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of.
    590  * \todo Function not implemented yet
     588 * \todo Function not implemented yet 
    591589 * \param *BondPartner atom to be removed
    592590 * \return true - bounds found and removed, false - bonds not found/removed
     
    621619  Vector *min = new Vector;
    622620  Vector *max = new Vector;
    623 
     621 
    624622  // gather min and max for each axis
    625623  ptr = start->next;  // start at first in list
     
    667665{
    668666  Vector *min = new Vector;
    669 
     667 
    670668//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    671669  atom *ptr = start->next;  // start at first in list
     
    683681      }
    684682    }
    685 //    *out << Verbose(4) << "Maximum is ";
     683//    *out << Verbose(4) << "Maximum is "; 
    686684//    max->Output(out);
    687685//    *out << ", Minimum is ";
     
    691689    max->AddVector(min);
    692690    Translate(min);
    693   }
     691  } 
    694692  delete(min);
    695693//  *out << Verbose(3) << "End of CenterEdge." << endl;
    696 };
     694}; 
    697695
    698696/** Centers the center of the atoms at (0,0,0).
     
    704702  int Num = 0;
    705703  atom *ptr = start->next;  // start at first in list
    706 
     704 
    707705  for(int i=NDIM;i--;) // zero center vector
    708706    center->x[i] = 0.;
    709 
     707   
    710708  if (ptr != end) {   //list not empty?
    711709    while (ptr->next != end) {  // continue with second if present
    712710      ptr = ptr->next;
    713711      Num++;
    714       center->AddVector(&ptr->x);
     712      center->AddVector(&ptr->x);       
    715713    }
    716714    center->Scale(-1./Num); // divide through total number (and sign for direction)
    717715    Translate(center);
    718716  }
    719 };
     717}; 
    720718
    721719/** Returns vector pointing to center of gravity.
     
    729727  Vector tmp;
    730728  double Num = 0;
    731 
     729 
    732730  a->Zero();
    733731
     
    737735      Num += 1.;
    738736      tmp.CopyVector(&ptr->x);
    739       a->AddVector(&tmp);
     737      a->AddVector(&tmp);       
    740738    }
    741739    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    757755        Vector tmp;
    758756  double Num = 0;
    759 
     757       
    760758        a->Zero();
    761759
     
    766764      tmp.CopyVector(&ptr->x);
    767765      tmp.Scale(ptr->type->mass);  // scale by mass
    768       a->AddVector(&tmp);
     766      a->AddVector(&tmp);       
    769767    }
    770768    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    789787    Translate(center);
    790788  }
    791 };
     789}; 
    792790
    793791/** Scales all atoms by \a *factor.
     
    803801      Trajectories[ptr].R.at(j).Scale(factor);
    804802    ptr->x.Scale(factor);
    805   }
    806 };
    807 
    808 /** Translate all atoms by given vector.
     803  }     
     804};
     805
     806/** Translate all atoms by given vector. 
    809807 * \param trans[] translation vector.
    810808 */
     
    818816      Trajectories[ptr].R.at(j).Translate(trans);
    819817    ptr->x.Translate(trans);
    820   }
    821 };
    822 
    823 /** Mirrors all atoms against a given plane.
     818  }     
     819};
     820
     821/** Mirrors all atoms against a given plane. 
    824822 * \param n[] normal vector of mirror plane.
    825823 */
     
    833831      Trajectories[ptr].R.at(j).Mirror(n);
    834832    ptr->x.Mirror(n);
    835   }
     833  }     
    836834};
    837835
     
    847845  bool flag;
    848846  Vector Testvector, Translationvector;
    849 
     847 
    850848  do {
    851849    Center.Zero();
     
    863861          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    864862            for (int j=0;j<NDIM;j++) {
    865               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     863              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 
    866864              if ((fabs(tmp)) > BondDistance) {
    867865                flag = false;
     
    879877        cout << Verbose(1) << "vector is: ";
    880878        Testvector.Output((ofstream *)&cout);
    881         cout << endl;
     879        cout << endl;     
    882880#ifdef ADDHYDROGEN
    883881        // now also change all hydrogens
     
    892890            cout << Verbose(1) << "Hydrogen vector is: ";
    893891            Testvector.Output((ofstream *)&cout);
    894             cout << endl;
     892            cout << endl;     
    895893          }
    896894        }
     
    914912
    915913        CenterGravity(out, CenterOfGravity);
    916 
    917         // reset inertia tensor
     914       
     915        // reset inertia tensor 
    918916        for(int i=0;i<NDIM*NDIM;i++)
    919917                InertiaTensor[i] = 0.;
    920 
     918       
    921919        // sum up inertia tensor
    922920        while (ptr->next != end) {
     
    943941        }
    944942        *out << endl;
    945 
     943       
    946944        // diagonalize to determine principal axis system
    947945        gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     
    952950        gsl_eigen_symmv_free(T);
    953951        gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    954 
     952       
    955953        for(int i=0;i<NDIM;i++) {
    956954                *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    957955                *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    958956        }
    959 
     957       
    960958        // check whether we rotate or not
    961959        if (DoRotate) {
    962           *out << Verbose(1) << "Transforming molecule into PAS ... ";
     960          *out << Verbose(1) << "Transforming molecule into PAS ... "; 
    963961          // the eigenvectors specify the transformation matrix
    964962          ptr = start;
     
    972970
    973971          // summing anew for debugging (resulting matrix has to be diagonal!)
    974           // reset inertia tensor
     972          // reset inertia tensor 
    975973    for(int i=0;i<NDIM*NDIM;i++)
    976974      InertiaTensor[i] = 0.;
    977 
     975   
    978976    // sum up inertia tensor
    979977    ptr = start;
     
    10021000    *out << endl;
    10031001        }
    1004 
     1002       
    10051003        // free everything
    10061004        delete(CenterOfGravity);
     
    10091007};
    10101008
     1009/** Evaluates the potential energy used for constrained molecular dynamics.
     1010 * \f$V_i^{con} = c^{bond} \cdot | r_{P(i)} - R_i | + sum_{i \neq j} C^{min} \cdot \frac{1}{C_{ij}} + C^{inj} \Bigl (1 - \theta \bigl (\prod_{i \neq j} (P(i) - P(j)) \bigr ) \Bigr )\f$
     1011 *     where the first term points to the target in minimum distance, the second is a penalty for trajectories lying too close to each other (\f$C_{ij}$ is minimum distance between
     1012 *     trajectories i and j) and the third term is a penalty for two atoms trying to each the same target point.
     1013 * Note that for the second term we have to solve the following linear system:
     1014 * \f$-c_1 \cdot n_1 + c_2 \cdot n_2 + C \cdot n_3 = - p_2 + p_1\f$, where \f$c_1\f$, \f$c_2\f$ and \f$C\f$ are constants,
     1015 * offset vector \f$p_1\f$ in direction \f$n_1\f$, offset vector \f$p_2\f$ in direction \f$n_2\f$,
     1016 * \f$n_3\f$ is the normal vector to both directions. \f$C\f$ would be the minimum distance between the two lines.
     1017 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration()
     1018 * \param *out output stream for debugging
     1019 * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$V^{con}(x)\f$)
     1020 * \param startstep start configuration (MDStep in molecule::trajectories)
     1021 * \param endstep end configuration (MDStep in molecule::trajectories)
     1022 * \param *constants constant in front of each term
     1023 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1024 * \return potential energy
     1025 * \note This routine is scaling quadratically which is not optimal.
     1026 * \todo There's a bit double counting going on for the first time, bu nothing to worry really about.
     1027 */
     1028double molecule::ConstrainedPotential(ofstream *out, atom **PermutationMap, int startstep, int endstep, double *constants, bool IsAngstroem)
     1029{
     1030  double result = 0., tmp, Norm1, Norm2;
     1031  atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL;
     1032  Vector trajectory1, trajectory2, normal, TestVector;
     1033  gsl_matrix *A = gsl_matrix_alloc(NDIM,NDIM);
     1034  gsl_vector *x = gsl_vector_alloc(NDIM);
     1035
     1036  // go through every atom
     1037  Walker = start;
     1038  while (Walker->next != end) {
     1039    Walker = Walker->next;
     1040    // first term: distance to target
     1041    Runner = PermutationMap[Walker->nr];   // find target point
     1042    tmp = (Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)));
     1043    tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem;
     1044    result += constants[0] * tmp;
     1045    //*out << Verbose(4) << "Adding " << tmp*constants[0] << "." << endl;
     1046   
     1047    // second term: sum of distances to other trajectories
     1048    Runner = start;
     1049    while (Runner->next != end) {
     1050      Runner = Runner->next;
     1051      if (Runner == Walker) // hence, we only go up to the Walker, not beyond (similar to i=0; i<j; i++)
     1052        break;
     1053      // determine normalized trajectories direction vector (n1, n2)
     1054      Sprinter = PermutationMap[Walker->nr];   // find first target point
     1055      trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep));
     1056      trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep));
     1057      trajectory1.Normalize();
     1058      Norm1 = trajectory1.Norm();
     1059      Sprinter = PermutationMap[Runner->nr];   // find second target point
     1060      trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep));
     1061      trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep));
     1062      trajectory2.Normalize();
     1063      Norm2 = trajectory1.Norm();
     1064      // check whether either is zero()
     1065      if ((Norm1 < MYEPSILON) && (Norm2 < MYEPSILON)) {
     1066        tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep));
     1067      } else if (Norm1 < MYEPSILON) {
     1068        Sprinter = PermutationMap[Walker->nr];   // find first target point
     1069        trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep));  // copy first offset
     1070        trajectory1.SubtractVector(&Trajectories[Runner].R.at(startstep));  // subtract second offset
     1071        trajectory2.Scale( trajectory1.ScalarProduct(&trajectory2) ); // trajectory2 is scaled to unity, hence we don't need to divide by anything
     1072        trajectory1.SubtractVector(&trajectory2);   // project the part in norm direction away
     1073        tmp = trajectory1.Norm();  // remaining norm is distance
     1074      } else if (Norm2 < MYEPSILON) {
     1075        Sprinter = PermutationMap[Runner->nr];   // find second target point
     1076        trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep));  // copy second offset
     1077        trajectory2.SubtractVector(&Trajectories[Walker].R.at(startstep));  // subtract first offset
     1078        trajectory1.Scale( trajectory2.ScalarProduct(&trajectory1) ); // trajectory1 is scaled to unity, hence we don't need to divide by anything
     1079        trajectory2.SubtractVector(&trajectory1);   // project the part in norm direction away
     1080        tmp = trajectory2.Norm();  // remaining norm is distance
     1081      } else if ((fabs(trajectory1.ScalarProduct(&trajectory2)/Norm1/Norm2) - 1.) < MYEPSILON) { // check whether they're linear dependent
     1082//        *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: ";
     1083//        *out << trajectory1;
     1084//        *out << " and ";
     1085//        *out << trajectory2;
     1086        tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep));
     1087//        *out << " with distance " << tmp << "." << endl;
     1088      } else { // determine distance by finding minimum distance
     1089//        *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent ";
     1090//        *out << endl;
     1091//        *out << "First Trajectory: ";
     1092//        *out << trajectory1 << endl;
     1093//        *out << "Second Trajectory: ";
     1094//        *out << trajectory2 << endl;
     1095        // determine normal vector for both
     1096        normal.MakeNormalVector(&trajectory1, &trajectory2);
     1097        // print all vectors for debugging
     1098//        *out << "Normal vector in between: ";
     1099//        *out << normal << endl;
     1100        // setup matrix
     1101        for (int i=NDIM;i--;) {
     1102          gsl_matrix_set(A, 0, i, trajectory1.x[i]);
     1103          gsl_matrix_set(A, 1, i, trajectory2.x[i]);
     1104          gsl_matrix_set(A, 2, i, normal.x[i]);
     1105          gsl_vector_set(x,i, (Trajectories[Walker].R.at(startstep).x[i] - Trajectories[Runner].R.at(startstep).x[i]));
     1106        }
     1107        // solve the linear system by Householder transformations
     1108        gsl_linalg_HH_svx(A, x);
     1109        // distance from last component
     1110        tmp = gsl_vector_get(x,2);
     1111//        *out << " with distance " << tmp << "." << endl;
     1112        // test whether we really have the intersection (by checking on c_1 and c_2)
     1113        TestVector.CopyVector(&Trajectories[Runner].R.at(startstep));
     1114        trajectory2.Scale(gsl_vector_get(x,1));
     1115        TestVector.AddVector(&trajectory2);
     1116        normal.Scale(gsl_vector_get(x,2));
     1117        TestVector.AddVector(&normal);
     1118        TestVector.SubtractVector(&Trajectories[Walker].R.at(startstep));
     1119        trajectory1.Scale(gsl_vector_get(x,0));
     1120        TestVector.SubtractVector(&trajectory1);
     1121        if (TestVector.Norm() < MYEPSILON) {
     1122//          *out << Verbose(2) << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 
     1123        } else {
     1124//          *out << Verbose(2) << "Test: failed.\tIntersection is off by ";
     1125//          *out << TestVector;
     1126//          *out << "." << endl; 
     1127        }
     1128      }
     1129      // add up
     1130      tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem;
     1131      if (fabs(tmp) > MYEPSILON) {
     1132        result += constants[1] * 1./tmp;
     1133        //*out << Verbose(4) << "Adding " << 1./tmp*constants[1] << "." << endl;
     1134      }
     1135    }
     1136     
     1137    // third term: penalty for equal targets
     1138    Runner = start;
     1139    while (Runner->next != end) {
     1140      Runner = Runner->next;
     1141      if ((PermutationMap[Walker->nr] == PermutationMap[Runner->nr]) && (Walker->nr < Runner->nr)) {
     1142        Sprinter = PermutationMap[Walker->nr];
     1143//        *out << *Walker << " and " << *Runner << " are heading to the same target at ";
     1144//        *out << Trajectories[Sprinter].R.at(endstep);
     1145//        *out << ", penalting." << endl;
     1146        result += constants[2];
     1147        //*out << Verbose(4) << "Adding " << constants[2] << "." << endl;
     1148      }
     1149    }
     1150  }
     1151 
     1152  return result;
     1153};
     1154
     1155void PrintPermutationMap(ofstream *out, atom **PermutationMap, int Nr)
     1156{
     1157  stringstream zeile1, zeile2;
     1158  int *DoubleList = (int *) Malloc(Nr*sizeof(int), "PrintPermutationMap: *DoubleList");
     1159  int doubles = 0;
     1160  for (int i=0;i<Nr;i++)
     1161    DoubleList[i] = 0;
     1162  zeile1 << "PermutationMap: ";
     1163  zeile2 << "                ";
     1164  for (int i=0;i<Nr;i++) {
     1165    DoubleList[PermutationMap[i]->nr]++;
     1166    zeile1 << i << " ";
     1167    zeile2 << PermutationMap[i]->nr << " ";
     1168  }
     1169  for (int i=0;i<Nr;i++)
     1170    if (DoubleList[i] > 1)
     1171    doubles++;
     1172 // *out << "Found " << doubles << " Doubles." << endl;
     1173  Free((void **)&DoubleList, "PrintPermutationMap: *DoubleList");
     1174//  *out << zeile1.str() << endl << zeile2.str() << endl;
     1175};
     1176
     1177/** Minimises the extra potential for constrained molecular dynamics and gives forces and the constrained potential energy.
     1178 * We do the following:
     1179 *  -# Generate a distance list from all source to all target points
     1180 *  -# Sort this per source point
     1181 *  -# Take for each source point the target point with minimum distance, use this as initial permutation
     1182 *  -# check whether molecule::ConstrainedPotential() is greater than injective penalty
     1183 *     -# If so, we go through each source point, stepping down in the sorted target point distance list and re-checking potential.
     1184 *  -# Next, we only apply transformations that keep the injectivity of the permutations list.
     1185 *  -# Hence, for one source point we step down the ladder and seek the corresponding owner of this new target
     1186 *     point and try to change it for one with lesser distance, or for the next one with greater distance, but only
     1187 *     if this decreases the conditional potential.
     1188 *  -# finished.
     1189 *  -# Then, we calculate the forces by taking the spatial derivative, where we scale the potential to such a degree,
     1190 *     that the total force is always pointing in direction of the constraint force (ensuring that we move in the
     1191 *     right direction).
     1192 *  -# Finally, we calculate the potential energy and return.
     1193 * \param *out output stream for debugging
     1194 * \param **PermutationMap on return: mapping between the atom label of the initial and the final configuration
     1195 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated)
     1196 * \param endstep step giving final position in constrained MD
     1197 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1198 * \sa molecule::VerletForceIntegration()
     1199 * \return potential energy (and allocated **PermutationMap (array of molecule::AtomCount ^2)
     1200 * \todo The constrained potential's constants are set to fixed values right now, but they should scale based on checks of the system in order
     1201 *       to ensure they're properties (e.g. constants[2] always greater than the energy of the system).
     1202 * \bug this all is not O(N log N) but O(N^2)
     1203 */
     1204double molecule::MinimiseConstrainedPotential(ofstream *out, atom **&PermutationMap, int startstep, int endstep, bool IsAngstroem)
     1205{
     1206  double Potential, OldPotential, OlderPotential;
     1207  PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential: **PermutationMap");
     1208  DistanceMap **DistanceList = (DistanceMap **) Malloc(AtomCount*sizeof(DistanceMap *), "molecule::MinimiseConstrainedPotential: **DistanceList");
     1209  DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators");
     1210  int *DoubleList = (int *) Malloc(AtomCount*sizeof(int), "molecule::MinimiseConstrainedPotential: *DoubleList");
     1211  DistanceMap::iterator *StepList = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *StepList");
     1212  double constants[3];
     1213  int round;
     1214  atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL;
     1215  DistanceMap::iterator Rider, Strider;
     1216 
     1217  /// Minimise the potential
     1218  // set Lagrange multiplier constants
     1219  constants[0] = 10.;
     1220  constants[1] = 1.;
     1221  constants[2] = 1e+7;    // just a huge penalty
     1222  // generate the distance list
     1223  *out << Verbose(1) << "Creating the distance list ... " << endl;
     1224  for (int i=AtomCount; i--;) {
     1225    DoubleList[i] = 0;  // stores for how many atoms in startstep this atom is a target in endstep
     1226    DistanceList[i] = new DistanceMap;    // is the distance sorted target list per atom
     1227    DistanceList[i]->clear();
     1228  }
     1229  *out << Verbose(1) << "Filling the distance list ... " << endl;
     1230  Walker = start;
     1231  while (Walker->next != end) {
     1232    Walker = Walker->next;
     1233    Runner = start;
     1234    while(Runner->next != end) {
     1235      Runner = Runner->next;
     1236      DistanceList[Walker->nr]->insert( DistancePair(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)), Runner) );
     1237    }
     1238  }
     1239  // create the initial PermutationMap (source -> target)
     1240  Walker = start;
     1241  while (Walker->next != end) {
     1242    Walker = Walker->next;
     1243    StepList[Walker->nr] = DistanceList[Walker->nr]->begin();    // stores the step to the next iterator that could be a possible next target
     1244    PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second;   // always pick target with the smallest distance
     1245    DoubleList[DistanceList[Walker->nr]->begin()->second->nr]++;            // increase this target's source count (>1? not injective)
     1246    DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin();    // and remember which one we picked
     1247    *out << *Walker << " starts with distance " << DistanceList[Walker->nr]->begin()->first << "." << endl;
     1248  }
     1249  *out << Verbose(1) << "done." << endl;
     1250  // make the PermutationMap injective by checking whether we have a non-zero constants[2] term in it
     1251  *out << Verbose(1) << "Making the PermutationMap injective ... " << endl;
     1252  Walker = start;
     1253  DistanceMap::iterator NewBase;
     1254  OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem));
     1255  while ((OldPotential) > constants[2]) {
     1256    PrintPermutationMap(out, PermutationMap, AtomCount);
     1257    Walker = Walker->next;
     1258    if (Walker == end) // round-robin at the end
     1259      Walker = start->next;
     1260    if (DoubleList[DistanceIterators[Walker->nr]->second->nr] <= 1)  // no need to make those injective that aren't
     1261      continue;
     1262    // now, try finding a new one
     1263    NewBase = DistanceIterators[Walker->nr];  // store old base
     1264    do {
     1265      NewBase++;  // take next further distance in distance to targets list that's a target of no one
     1266    } while ((DoubleList[NewBase->second->nr] != 0) && (NewBase != DistanceList[Walker->nr]->end()));
     1267    if (NewBase != DistanceList[Walker->nr]->end()) {
     1268      PermutationMap[Walker->nr] = NewBase->second;
     1269      Potential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem));
     1270      if (Potential > OldPotential) { // undo
     1271        PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second;
     1272      } else {  // do
     1273        DoubleList[DistanceIterators[Walker->nr]->second->nr]--;  // decrease the old entry in the doubles list
     1274        DoubleList[NewBase->second->nr]++;    // increase the old entry in the doubles list
     1275        DistanceIterators[Walker->nr] = NewBase;
     1276        OldPotential = Potential;
     1277        *out << Verbose(3) << "Found a new permutation, new potential is " << OldPotential << "." << endl;
     1278      }
     1279    }
     1280  }
     1281  for (int i=AtomCount; i--;) // now each single entry in the DoubleList should be <=1
     1282    if (DoubleList[i] > 1) {
     1283      cerr << "Failed to create an injective PermutationMap!" << endl;
     1284      exit(1);
     1285    }
     1286  *out << Verbose(1) << "done." << endl;
     1287  Free((void **)&DoubleList, "molecule::MinimiseConstrainedPotential: *DoubleList");
     1288  // argument minimise the constrained potential in this injective PermutationMap
     1289  *out << Verbose(1) << "Argument minimising the PermutationMap, at current potential " << OldPotential << " ... " << endl;
     1290  OldPotential = 1e+10;
     1291  round = 0;
     1292  do {
     1293    *out << "Starting round " << ++round << " ... " << endl;
     1294    OlderPotential = OldPotential;
     1295    do {
     1296      Walker = start;
     1297      while (Walker->next != end) { // pick one
     1298        Walker = Walker->next;
     1299        PrintPermutationMap(out, PermutationMap, AtomCount);
     1300        Sprinter = DistanceIterators[Walker->nr]->second;   // store initial partner
     1301        Strider = DistanceIterators[Walker->nr];  //remember old iterator
     1302        DistanceIterators[Walker->nr] = StepList[Walker->nr]; 
     1303        if (DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->end()) {// stop, before we run through the list and still on
     1304          DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->begin();
     1305          break;
     1306        }
     1307        //*out << Verbose(2) << "Current Walker: " << *Walker << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[Walker->nr]->second << "." << endl;
     1308        // find source of the new target
     1309        Runner = start->next;
     1310        while(Runner != end) { // find the source whose toes we might be stepping on (Walker's new target should be in use by another already)
     1311          if (PermutationMap[Runner->nr] == DistanceIterators[Walker->nr]->second) {
     1312            //*out << Verbose(2) << "Found the corresponding owner " << *Runner << " to " << *PermutationMap[Runner->nr] << "." << endl;
     1313            break;
     1314          }
     1315          Runner = Runner->next;
     1316        }
     1317        if (Runner != end) { // we found the other source
     1318          // then look in its distance list for Sprinter
     1319          Rider = DistanceList[Runner->nr]->begin();
     1320          for (; Rider != DistanceList[Runner->nr]->end(); Rider++)
     1321            if (Rider->second == Sprinter)
     1322              break;
     1323          if (Rider != DistanceList[Runner->nr]->end()) { // if we have found one
     1324            //*out << Verbose(2) << "Current Other: " << *Runner << " with old/next candidate " << *PermutationMap[Runner->nr] << "/" << *Rider->second << "." << endl;
     1325            // exchange both
     1326            PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // put next farther distance into PermutationMap
     1327            PermutationMap[Runner->nr] = Sprinter;  // and hand the old target to its respective owner
     1328            PrintPermutationMap(out, PermutationMap, AtomCount);
     1329            // calculate the new potential
     1330            //*out << Verbose(2) << "Checking new potential ..." << endl;
     1331            Potential = ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem);
     1332            if (Potential > OldPotential) { // we made everything worse! Undo ...
     1333              //*out << Verbose(3) << "Nay, made the potential worse: " << Potential << " vs. " << OldPotential << "!" << endl;
     1334              //*out << Verbose(3) << "Setting " << *Runner << "'s source to " << *DistanceIterators[Runner->nr]->second << "." << endl;
     1335              // Undo for Runner (note, we haven't moved the iteration yet, we may use this)
     1336              PermutationMap[Runner->nr] = DistanceIterators[Runner->nr]->second;
     1337              // Undo for Walker
     1338              DistanceIterators[Walker->nr] = Strider;  // take next farther distance target
     1339              //*out << Verbose(3) << "Setting " << *Walker << "'s source to " << *DistanceIterators[Walker->nr]->second << "." << endl;
     1340              PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second;
     1341            } else {
     1342              DistanceIterators[Runner->nr] = Rider;  // if successful also move the pointer in the iterator list
     1343              *out << Verbose(3) << "Found a better permutation, new potential is " << Potential << " vs." << OldPotential << "." << endl;
     1344              OldPotential = Potential;
     1345            }
     1346            if (Potential > constants[2]) {
     1347              cerr << "ERROR: The two-step permutation procedure did not maintain injectivity!" << endl;
     1348              exit(255);
     1349            }
     1350            //*out << endl;
     1351          } else {
     1352            cerr << "ERROR: " << *Runner << " was not the owner of " << *Sprinter << "!" << endl;
     1353            exit(255);
     1354          }
     1355        } else {
     1356          PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // new target has no source!
     1357        }
     1358        StepList[Walker->nr]++; // take next farther distance target
     1359      }
     1360    } while (Walker->next != end);
     1361  } while ((OlderPotential - OldPotential) > 1e-3);
     1362  *out << Verbose(1) << "done." << endl;
     1363
     1364 
     1365  /// free memory and return with evaluated potential
     1366  for (int i=AtomCount; i--;)
     1367    DistanceList[i]->clear();
     1368  Free((void **)&DistanceList, "molecule::MinimiseConstrainedPotential: **DistanceList");
     1369  Free((void **)&DistanceIterators, "molecule::MinimiseConstrainedPotential: *DistanceIterators");
     1370  return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem);
     1371};
     1372
     1373/** Evaluates the (distance-related part) of the constrained potential for the constrained forces.
     1374 * \param *out output stream for debugging
     1375 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated)
     1376 * \param endstep step giving final position in constrained MD
     1377 * \param **PermutationMap mapping between the atom label of the initial and the final configuration
     1378 * \param *Force ForceMatrix containing force vectors from the external energy functional minimisation.
     1379 * \todo the constant for the constrained potential distance part is hard-coded independently of the hard-coded value in MinimiseConstrainedPotential()
     1380 */
     1381void molecule::EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
     1382{
     1383  double constant = 10.;
     1384  atom *Walker = NULL, *Sprinter = NULL;
     1385 
     1386  /// evaluate forces (only the distance to target dependent part) with the final PermutationMap
     1387  *out << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl;
     1388  Walker = start;
     1389  while (Walker->next != NULL) {
     1390    Walker = Walker->next;
     1391    Sprinter = PermutationMap[Walker->nr];
     1392    // set forces
     1393    for (int i=NDIM;i++;)
     1394      Force->Matrix[0][Walker->nr][5+i] += 2.*constant*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep)));
     1395  } 
     1396  *out << Verbose(1) << "done." << endl;
     1397};
     1398
     1399/** Performs a linear interpolation between two desired atomic configurations with a given number of steps.
     1400 * Note, step number is config::MaxOuterStep
     1401 * \param *out output stream for debugging
     1402 * \param startstep stating initial configuration in molecule::Trajectories
     1403 * \param endstep stating final configuration in molecule::Trajectories
     1404 * \param &config configuration structure
     1405 * \return true - success in writing step files, false - error writing files or only one step in molecule::Trajectories
     1406 */
     1407bool molecule::LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration)
     1408{
     1409  bool status = true;
     1410  int MaxSteps = configuration.MaxOuterStep;
     1411  MoleculeListClass *MoleculePerStep = new MoleculeListClass(MaxSteps+1, AtomCount);
     1412  // Get the Permutation Map by MinimiseConstrainedPotential
     1413  atom **PermutationMap = NULL;
     1414  atom *Walker = NULL, *Sprinter = NULL;
     1415  MinimiseConstrainedPotential(out, PermutationMap, startstep, endstep, configuration.GetIsAngstroem());
     1416
     1417  // check whether we have sufficient space in Trajectories for each atom
     1418  Walker = start;
     1419  while (Walker->next != end) {
     1420    Walker = Walker->next;
     1421    if (Trajectories[Walker].R.size() <= (unsigned int)(MaxSteps)) {
     1422      //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
     1423      Trajectories[Walker].R.resize(MaxSteps+1);
     1424      Trajectories[Walker].U.resize(MaxSteps+1);
     1425      Trajectories[Walker].F.resize(MaxSteps+1);
     1426    }
     1427  }
     1428  // push endstep to last one
     1429  Walker = start;
     1430  while (Walker->next != end) { // remove the endstep (is now the very last one)
     1431    Walker = Walker->next;
     1432    for (int n=NDIM;n--;) {
     1433      Trajectories[Walker].R.at(MaxSteps).x[n] = Trajectories[Walker].R.at(endstep).x[n];
     1434      Trajectories[Walker].U.at(MaxSteps).x[n] = Trajectories[Walker].U.at(endstep).x[n];
     1435      Trajectories[Walker].F.at(MaxSteps).x[n] = Trajectories[Walker].F.at(endstep).x[n];
     1436    }
     1437  }
     1438  endstep = MaxSteps;
     1439 
     1440  // go through all steps and add the molecular configuration to the list and to the Trajectories of \a this molecule
     1441  *out << Verbose(1) << "Filling intermediate " << MaxSteps << " steps with MDSteps of " << MDSteps << "." << endl;
     1442  for (int step = 0; step <= MaxSteps; step++) {
     1443    MoleculePerStep->ListOfMolecules[step] = new molecule(elemente);
     1444    Walker = start;
     1445    while (Walker->next != end) {
     1446      Walker = Walker->next;
     1447      // add to molecule list
     1448      Sprinter = MoleculePerStep->ListOfMolecules[step]->AddCopyAtom(Walker);
     1449      for (int n=NDIM;n--;) {
     1450        Sprinter->x.x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps);
     1451        // add to Trajectories
     1452        //*out << Verbose(3) << step << ">=" << MDSteps-1 << endl;
     1453        if (step < MaxSteps) {
     1454          Trajectories[Walker].R.at(step).x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps);
     1455          Trajectories[Walker].U.at(step).x[n] = 0.;
     1456          Trajectories[Walker].F.at(step).x[n] = 0.;
     1457        }
     1458      }
     1459    }
     1460  }
     1461  MDSteps = MaxSteps+1;   // otherwise new Trajectories' points aren't stored on save&exit
     1462 
     1463  // store the list to single step files
     1464  int *SortIndex = (int *) Malloc(AtomCount*sizeof(int), "molecule::LinearInterpolationBetweenConfiguration: *SortIndex");
     1465  for (int i=AtomCount; i--; )
     1466    SortIndex[i] = i;
     1467  status = MoleculePerStep->OutputConfigForListOfFragments(out, "ConstrainedStep", &configuration, SortIndex, false, false);
     1468 
     1469  // free and return
     1470  Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
     1471  delete(MoleculePerStep);
     1472  return status;
     1473};
     1474
    10111475/** Parses nuclear forces from file and performs Verlet integration.
    10121476 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
    10131477 * have to transform them).
    10141478 * This adds a new MD step to the config file.
     1479 * \param *out output stream for debugging
    10151480 * \param *file filename
    10161481 * \param delta_t time step width in atomic units
    10171482 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1483 * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential()
    10181484 * \return true - file found and parsed, false - file not found or imparsable
    1019  */
    1020 bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
     1485 * \todo This is not yet checked if it is correctly working with DoConstrained set to true.
     1486 */
     1487bool molecule::VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained)
    10211488{
    10221489  element *runner = elemente->start;
     
    10261493  string token;
    10271494  stringstream item;
    1028   double a, IonMass;
     1495  double a, IonMass, Vector[NDIM], ConstrainedPotentialEnergy;
    10291496  ForceMatrix Force;
    1030   Vector tmpvector;
    10311497
    10321498  CountElements();  // make sure ElementsInMolecule is up to date
    1033 
     1499 
    10341500  // check file
    10351501  if (input == NULL) {
     
    10461512    }
    10471513    // correct Forces
    1048 //    for(int d=0;d<NDIM;d++)
    1049 //      tmpvector.x[d] = 0.;
    1050 //    for(int i=0;i<AtomCount;i++)
    1051 //      for(int d=0;d<NDIM;d++) {
    1052 //        tmpvector.x[d] += Force.Matrix[0][i][d+5];
    1053 //      }
    1054 //    for(int i=0;i<AtomCount;i++)
    1055 //      for(int d=0;d<NDIM;d++) {
    1056 //        Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
    1057 //      }
     1514    for(int d=0;d<NDIM;d++)
     1515      Vector[d] = 0.;
     1516    for(int i=0;i<AtomCount;i++)
     1517      for(int d=0;d<NDIM;d++) {
     1518        Vector[d] += Force.Matrix[0][i][d+5];
     1519      }
     1520    for(int i=0;i<AtomCount;i++)
     1521      for(int d=0;d<NDIM;d++) {
     1522        Force.Matrix[0][i][d+5] -= Vector[d]/(double)AtomCount;
     1523      }
     1524    // solve a constrained potential if we are meant to
     1525    if (DoConstrained) {
     1526      // calculate forces and potential
     1527      atom **PermutationMap = NULL;
     1528      ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap, DoConstrained, 0, IsAngstroem);
     1529      EvaluateConstrainedForces(out, DoConstrained, 0, PermutationMap, &Force);
     1530      Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
     1531    }
     1532   
    10581533    // and perform Verlet integration for each atom with position, velocity and force vector
    10591534    runner = elemente->start;
     
    10701545            // check size of vectors
    10711546            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1072               //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1547              //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    10731548              Trajectories[walker].R.resize(MDSteps+10);
    10741549              Trajectories[walker].U.resize(MDSteps+10);
    10751550              Trajectories[walker].F.resize(MDSteps+10);
    10761551            }
    1077             // 1. calculate x(t+\delta t)
     1552           
     1553            // Update R (and F)
    10781554            for (int d=0; d<NDIM; d++) {
    1079               Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
     1555              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5]*(IsAngstroem ? AtomicLengthToAngstroem : 1.);
    10801556              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    10811557              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
    1082               Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass;     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
     1558              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*a*(Trajectories[walker].F.at(MDSteps).x[d]);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    10831559            }
    1084             // 2. Calculate v(t+\delta t)
     1560            // Update U
    10851561            for (int d=0; d<NDIM; d++) {
    1086               Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1087               Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
     1562              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d]; 
     1563              Trajectories[walker].U.at(MDSteps).x[d] += a * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]);
    10881564            }
    1089 //            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1565//            out << "Integrated position&velocity of step " << (MDSteps) << ": (";
    10901566//            for (int d=0;d<NDIM;d++)
    1091 //              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
    1092 //            cout << ")\t(";
     1567//              out << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1568//            out << ")\t(";
    10931569//            for (int d=0;d<NDIM;d++)
    10941570//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
    1095 //            cout << ")" << endl;
     1571//            out << ")" << endl;
    10961572            // next atom
    10971573            AtomNo++;
     
    11021578  }
    11031579//  // correct velocities (rather momenta) so that center of mass remains motionless
    1104 //  tmpvector.zero()
     1580//  for(int d=0;d<NDIM;d++)
     1581//    Vector[d] = 0.;
    11051582//  IonMass = 0.;
    11061583//  walker = start;
     
    11091586//    IonMass += walker->type->mass;  // sum up total mass
    11101587//    for(int d=0;d<NDIM;d++) {
    1111 //      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1588//      Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    11121589//    }
    11131590//  }
     
    11161593//    walker = walker->next;
    11171594//    for(int d=0;d<NDIM;d++) {
    1118 //      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
     1595//      Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d]*walker->type->mass/IonMass;
    11191596//    }
    11201597//  }
    11211598  MDSteps++;
    11221599
    1123 
     1600 
    11241601  // exit
    11251602  return true;
    11261603};
    11271604
    1128 /** Align all atoms in such a manner that given vector \a *n is along z axis.
     1605/** Align all atoms in such a manner that given vector \a *n is along z axis. 
    11291606 * \param n[] alignment vector.
    11301607 */
     
    11451622    ptr = ptr->next;
    11461623    tmp = ptr->x.x[0];
    1147     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1624    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
    11481625    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    11491626    for (int j=0;j<MDSteps;j++) {
    11501627      tmp = Trajectories[ptr].R.at(j).x[0];
    1151       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1628      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
    11521629      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    11531630    }
    1154   }
     1631  }     
    11551632  // rotate n vector
    11561633  tmp = n->x[0];
     
    11601637  n->Output((ofstream *)&cout);
    11611638  cout << endl;
    1162 
     1639 
    11631640  // rotate on z-y plane
    11641641  ptr = start;
     
    11681645    ptr = ptr->next;
    11691646    tmp = ptr->x.x[1];
    1170     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1647    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
    11711648    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    11721649    for (int j=0;j<MDSteps;j++) {
    11731650      tmp = Trajectories[ptr].R.at(j).x[1];
    1174       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1651      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
    11751652      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    11761653    }
    1177   }
     1654  }     
    11781655  // rotate n vector (for consistency check)
    11791656  tmp = n->x[1];
    11801657  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    11811658  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1182 
     1659 
    11831660  cout << Verbose(1) << "alignment vector after second rotation: ";
    11841661  n->Output((ofstream *)&cout);
     
    11911668 * \return true - succeeded, false - atom not found in list
    11921669 */
    1193 bool molecule::RemoveAtom(atom *pointer)
    1194 {
     1670bool molecule::RemoveAtom(atom *pointer) 
     1671{ 
    11951672  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    11961673    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    11971674  else
    1198     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1675    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 
    11991676  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    12001677    ElementCount--;
     
    12061683 * \return true - succeeded, false - atom not found in list
    12071684 */
    1208 bool molecule::CleanupMolecule()
    1209 {
    1210   return (cleanup(start,end) && cleanup(first,last));
     1685bool molecule::CleanupMolecule() 
     1686{ 
     1687  return (cleanup(start,end) && cleanup(first,last)); 
    12111688};
    12121689
     
    12221699  } else {
    12231700    cout << Verbose(0) << "Atom not found in list." << endl;
    1224     return NULL;
     1701    return NULL; 
    12251702  }
    12261703};
     
    12711748  struct lsq_params *par = (struct lsq_params *)params;
    12721749  atom *ptr = par->mol->start;
    1273 
     1750 
    12741751  // initialize vectors
    12751752  a.x[0] = gsl_vector_get(x,0);
     
    13011778{
    13021779    int np = 6;
    1303 
     1780   
    13041781   const gsl_multimin_fminimizer_type *T =
    13051782     gsl_multimin_fminimizer_nmsimplex;
     
    13071784   gsl_vector *ss;
    13081785   gsl_multimin_function minex_func;
    1309 
     1786 
    13101787   size_t iter = 0, i;
    13111788   int status;
    13121789   double size;
    1313 
     1790 
    13141791   /* Initial vertex size vector */
    13151792   ss = gsl_vector_alloc (np);
    1316 
     1793 
    13171794   /* Set all step sizes to 1 */
    13181795   gsl_vector_set_all (ss, 1.0);
    1319 
     1796 
    13201797   /* Starting point */
    13211798   par->x = gsl_vector_alloc (np);
    13221799   par->mol = this;
    1323 
     1800 
    13241801   gsl_vector_set (par->x, 0, 0.0);  // offset
    13251802   gsl_vector_set (par->x, 1, 0.0);
     
    13281805   gsl_vector_set (par->x, 4, 0.0);
    13291806   gsl_vector_set (par->x, 5, 1.0);
    1330 
     1807 
    13311808   /* Initialize method and iterate */
    13321809   minex_func.f = &LeastSquareDistance;
    13331810   minex_func.n = np;
    13341811   minex_func.params = (void *)par;
    1335 
     1812 
    13361813   s = gsl_multimin_fminimizer_alloc (T, np);
    13371814   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1338 
     1815 
    13391816   do
    13401817     {
    13411818       iter++;
    13421819       status = gsl_multimin_fminimizer_iterate(s);
    1343 
     1820 
    13441821       if (status)
    13451822         break;
    1346 
     1823 
    13471824       size = gsl_multimin_fminimizer_size (s);
    13481825       status = gsl_multimin_test_size (size, 1e-2);
    1349 
     1826 
    13501827       if (status == GSL_SUCCESS)
    13511828         {
    13521829           printf ("converged to minimum at\n");
    13531830         }
    1354 
     1831 
    13551832       printf ("%5d ", (int)iter);
    13561833       for (i = 0; i < (size_t)np; i++)
     
    13611838     }
    13621839   while (status == GSL_CONTINUE && iter < 100);
    1363 
     1840 
    13641841  for (i=0;i<(size_t)np;i++)
    13651842    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     
    13781855  int ElementNo, AtomNo;
    13791856  CountElements();
    1380 
     1857 
    13811858  if (out == NULL) {
    13821859    return false;
     
    14131890  int ElementNo, AtomNo;
    14141891  CountElements();
    1415 
     1892 
    14161893  if (out == NULL) {
    14171894    return false;
     
    14601937  atom *Walker = start;
    14611938  while (Walker->next != end) {
    1462     Walker = Walker->next;
     1939    Walker = Walker->next; 
    14631940#ifdef ADDHYDROGEN
    14641941    if (Walker->type->Z != 1) {   // regard only non-hydrogen
     
    14911968  int No = 0;
    14921969  time_t now;
    1493 
     1970 
    14941971  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    14951972  walker = start;
     
    15181995{
    15191996  atom *walker = NULL;
    1520   int AtomNo = 0, ElementNo;
     1997  int No = 0;
    15211998  time_t now;
    1522   element *runner = NULL;
    1523 
     1999 
    15242000  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    15252001  walker = start;
    15262002  while (walker->next != end) { // go through every atom and count
    15272003    walker = walker->next;
    1528     AtomNo++;
     2004    No++;
    15292005  }
    15302006  if (out != NULL) {
    1531     *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    1532     ElementNo = 0;
    1533     runner = elemente->start;
    1534     while (runner->next != elemente->end) { // go through every element
    1535                 runner = runner->next;
    1536       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1537         ElementNo++;
    1538         walker = start;
    1539         while (walker->next != end) { // go through every atom of this element
    1540           walker = walker->next;
    1541           if (walker->type == runner) { // if this atom fits to element
    1542             walker->OutputXYZLine(out);
    1543           }
    1544         }
    1545       }
     2007    *out << No << "\n\tCreated by molecuilder on " << ctime(&now);
     2008    walker = start;
     2009    while (walker->next != end) { // go through every atom of this element
     2010      walker = walker->next;
     2011      walker->OutputXYZLine(out);
    15462012    }
    15472013    return true;
     
    15742040              Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    15752041              if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1576                 NoNonHydrogen++;
     2042                NoNonHydrogen++; 
    15772043              Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    15782044              Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     
    15822048            }
    15832049    } else
    1584         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     2050        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 
    15852051  }
    15862052};
     
    15942060        ElementsInMolecule[i] = 0;
    15952061        ElementCount = 0;
    1596 
     2062       
    15972063  atom *walker = start;
    15982064  while (walker->next != end) {
     
    16302096    Binder = Binder->next;
    16312097    if (Binder->Cyclic)
    1632       No++;
     2098      No++;   
    16332099  }
    16342100  delete(BackEdgeStack);
     
    16882154
    16892155/** Creates an adjacency list of the molecule.
    1690  * We obtain an outside file with the indices of atoms which are bondmembers.
    1691  */
    1692 void molecule::CreateAdjacencyList2(ofstream *out, ifstream *input)
    1693 {
    1694 
    1695         // 1 We will parse bonds out of the dbond file created by tremolo.
    1696                         int atom1, atom2, temp;
    1697                         atom *Walker, *OtherWalker;
    1698 
    1699                 if (!input)
    1700                 {
    1701                         cout << Verbose(1) << "Opening silica failed \n";
    1702                 };
    1703 
    1704                         *input >> ws >> atom1;
    1705                         *input >> ws >> atom2;
    1706                 cout << Verbose(1) << "Scanning file\n";
    1707                 while (!input->eof()) // Check whether we read everything already
    1708                 {
    1709                                 *input >> ws >> atom1;
    1710                                 *input >> ws >> atom2;
    1711                         if(atom2<atom1) //Sort indices of atoms in order
    1712                         {
    1713                                 temp=atom1;
    1714                                 atom1=atom2;
    1715                                 atom2=temp;
    1716                         };
    1717 
    1718                         Walker=start;
    1719                         while(Walker-> nr != atom1) // Find atom corresponding to first index
    1720                         {
    1721                                 Walker = Walker->next;
    1722                         };
    1723                         OtherWalker = Walker->next;
    1724                         while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    1725                         {
    1726                                 OtherWalker= OtherWalker->next;
    1727                         };
    1728                         AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1729                        
    1730                 }
    1731 
    1732                 CreateListOfBondsPerAtom(out);
    1733 
    1734 };
    1735 
    1736 
    1737 /** Creates an adjacency list of the molecule.
    17382156 * Generally, we use the CSD approach to bond recognition, that is the the distance
    17392157 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    1740  * a threshold t = 0.4 Angstroem.
     2158 * a threshold t = 0.4 Angstroem. 
    17412159 * To make it O(N log N) the function uses the linked-cell technique as follows:
    17422160 * The procedure is step-wise:
     
    17552173void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    17562174{
    1757 
    17582175  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    17592176  int No, NoBonds, CandidateBondNo;
     
    17642181  Vector x;
    17652182  int FalseBondDegree = 0;
    1766 
     2183 
    17672184  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    17682185  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     
    17712188    cleanup(first,last);
    17722189  }
    1773 
     2190       
    17742191  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    17752192  CountAtoms(out);
     
    17902207    for (int i=NumberCells;i--;)
    17912208      CellList[i] = NULL;
    1792 
     2209 
    17932210    // 2b. put all atoms into its corresponding list
    17942211    Walker = start;
     
    18112228      if (CellList[index] == NULL)  // allocate molecule if not done
    18122229        CellList[index] = new molecule(elemente);
    1813       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    1814       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     2230      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 
     2231      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 
    18152232    }
    18162233    //for (int i=0;i<NumberCells;i++)
    18172234      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1818 
    1819 
     2235     
    18202236    // 3a. go through every cell
    18212237    for (N[0]=divisor[0];N[0]--;)
     
    18302246              Walker = Walker->next;
    18312247              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1832               // 3c. check for possible bond between each atom in this and every one in the 27 cells
     2248              // 3c. check for possible bond between each atom in this and every one in the 27 cells 
    18332249              for (n[0]=-1;n[0]<=1;n[0]++)
    18342250                for (n[1]=-1;n[1]<=1;n[1]++)
     
    18622278          }
    18632279        }
    1864 
    1865 
    1866 
    18672280    // 4. free the cell again
    18682281    for (int i=NumberCells;i--;)
     
    18712284      }
    18722285    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1873 
     2286   
    18742287    // create the adjacency list per atom
    18752288    CreateListOfBondsPerAtom(out);
    1876 
     2289               
    18772290    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    18782291    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     
    19232336                        *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    19242337          *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    1925 
     2338               
    19262339          // output bonds for debugging (if bond chain list was correctly installed)
    19272340          *out << Verbose(1) << endl << "From contents of bond chain list:";
     
    19332346    *out << endl;
    19342347  } else
    1935         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     2348        *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 
    19362349  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    19372350  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    1938 
    1939 };
    1940 
    1941 
     2351};
    19422352
    19432353/** Performs a Depth-First search on this molecule.
     
    19602370  bond *Binder = NULL;
    19612371  bool BackStepping = false;
    1962 
     2372 
    19632373  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    1964 
     2374 
    19652375  ResetAllBondsToUnused();
    19662376  ResetAllAtomNumbers();
     
    19752385    LeafWalker->Leaf = new molecule(elemente);
    19762386    LeafWalker->Leaf->AddCopyAtom(Root);
    1977 
     2387   
    19782388    OldGraphNr = CurrentGraphNr;
    19792389    Walker = Root;
     
    19862396          AtomStack->Push(Walker);
    19872397          CurrentGraphNr++;
    1988         }
     2398        }     
    19892399        do { // (3) if Walker has no unused egdes, go to (5)
    19902400          BackStepping = false; // reset backstepping flag for (8)
     
    20202430          Binder = NULL;
    20212431      } while (1);  // (2)
    2022 
     2432     
    20232433      // 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!
    20242434      if ((Walker == Root) && (Binder == NULL))
    20252435        break;
    2026 
    2027       // (5) if Ancestor of Walker is ...
     2436       
     2437      // (5) if Ancestor of Walker is ... 
    20282438      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    20292439      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     
    20682478        } while (OtherAtom != Walker);
    20692479        ComponentNumber++;
    2070 
     2480   
    20712481        // (11) Root is separation vertex,  set Walker to Root and go to (4)
    20722482        Walker = Root;
     
    20812491
    20822492    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2083     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2493    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;   
    20842494    LeafWalker->Leaf->Output(out);
    20852495    *out << endl;
     
    20892499      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    20902500      if (Root->GraphNr != -1) // if already discovered, step on
    2091         Root = Root->next;
     2501        Root = Root->next; 
    20922502    }
    20932503  }
     
    21112521    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    21122522  }
    2113 
     2523 
    21142524  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    21152525  Binder = first;
     
    21222532    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    21232533    OutputComponentNumber(out, Binder->rightatom);
    2124     *out << ">." << endl;
     2534    *out << ">." << endl; 
    21252535    if (Binder->Cyclic) // cyclic ??
    21262536      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     
    21372547 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as
    21382548 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds
    2139  * as cyclic and print out the cycles.
     2549 * as cyclic and print out the cycles. 
    21402550 * \param *out output stream for debugging
    21412551 * \param *BackEdgeStack stack with all back edges found during DFS scan. Beware: This stack contains the bonds from the total molecule, not from the subgraph!
     
    21482558  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    21492559  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2150   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
     2560  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring 
    21512561  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    21522562  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     
    21602570    ColorList[i] = white;
    21612571  }
    2162 
     2572 
    21632573  *out << Verbose(1) << "Back edge list - ";
    21642574  BackEdgeStack->Output(out);
    2165 
     2575 
    21662576  *out << Verbose(1) << "Analysing cycles ... " << endl;
    21672577  NumCycles = 0;
     
    21692579    BackEdge = BackEdgeStack->PopFirst();
    21702580    // this is the target
    2171     Root = BackEdge->leftatom;
     2581    Root = BackEdge->leftatom; 
    21722582    // this is the source point
    2173     Walker = BackEdge->rightatom;
     2583    Walker = BackEdge->rightatom; 
    21742584    ShortestPathList[Walker->nr] = 0;
    21752585    BFSStack->ClearStack();  // start with empty BFS stack
     
    21852595        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    21862596          OtherAtom = Binder->GetOtherAtom(Walker);
    2187 #ifdef ADDHYDROGEN
     2597#ifdef ADDHYDROGEN         
    21882598          if (OtherAtom->type->Z != 1) {
    21892599#endif
     
    21942604              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    21952605              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2196               *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     2606              *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; 
    21972607              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    21982608                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     
    22042614            if (OtherAtom == Root)
    22052615              break;
    2206 #ifdef ADDHYDROGEN
     2616#ifdef ADDHYDROGEN         
    22072617          } else {
    22082618            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     
    22422652      }
    22432653    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2244 
     2654   
    22452655    if (OtherAtom == Root) {
    22462656      // now climb back the predecessor list and thus find the cycle members
     
    22702680      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    22712681    }
    2272 
     2682   
    22732683    // now clean the lists
    22742684    while (!TouchedStack->IsEmpty()){
     
    22802690  }
    22812691  if (MinRingSize != -1) {
    2282     // go over all atoms
     2692    // go over all atoms 
    22832693    Root = start;
    22842694    while(Root->next != end) {
    22852695      Root = Root->next;
    2286 
     2696     
    22872697      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    22882698        Walker = Root;
     
    23212731          }
    23222732          ColorList[Walker->nr] = black;
    2323           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2733          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
    23242734        }
    2325 
     2735   
    23262736        // now clean the lists
    23272737        while (!TouchedStack->IsEmpty()){
     
    23722782void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    23732783{
    2374   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2784  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 
    23752785    *out << vertex->ComponentNr[i] << "  ";
    23762786};
     
    24502860{
    24512861  int c = 0;
    2452   int FragmentCount;
     2862  int FragmentCount; 
    24532863  // get maximum bond degree
    24542864  atom *Walker = start;
     
    24602870  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    24612871  return FragmentCount;
    2462 };
     2872}; 
    24632873
    24642874/** Scans a single line for number and puts them into \a KeySet.
    24652875 * \param *out output stream for debugging
    24662876 * \param *buffer buffer to scan
    2467  * \param &CurrentSet filled KeySet on return
     2877 * \param &CurrentSet filled KeySet on return 
    24682878 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
    24692879 */
     
    24732883  int AtomNr;
    24742884  int status = 0;
    2475 
     2885 
    24762886  line.str(buffer);
    24772887  while (!line.eof()) {
     
    25092919  double TEFactor;
    25102920  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2511 
     2921 
    25122922  if (FragmentList == NULL) { // check list pointer
    25132923    FragmentList = new Graph;
    25142924  }
    2515 
     2925 
    25162926  // 1st pass: open file and read
    25172927  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     
    25422952    status = false;
    25432953  }
    2544 
     2954 
    25452955  // 2nd pass: open TEFactors file and read
    25462956  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     
    25542964        InputFile >> TEFactor;
    25552965        (*runner).second.second = TEFactor;
    2556         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2966        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 
    25572967      } else {
    25582968        status = false;
     
    25953005  if(output != NULL) {
    25963006    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2597       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     3007      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 
    25983008        if (sprinter != (*runner).first.begin())
    25993009          output << "\t";
     
    26613071    status = false;
    26623072  }
    2663 
     3073 
    26643074  return status;
    26653075};
     
    26703080 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom
    26713081 * \return true - structure is equal, false - not equivalence
    2672  */
     3082 */ 
    26733083bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    26743084{
     
    26773087  bool status = true;
    26783088  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2679 
     3089 
    26803090  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    26813091  File.open(filename.str().c_str(), ios::out);
     
    27363146  *out << endl;
    27373147  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2738 
     3148 
    27393149  return status;
    27403150};
     
    27583168  for(int i=AtomCount;i--;)
    27593169    AtomMask[i] = false;
    2760 
     3170 
    27613171  if (Order < 0) { // adaptive increase of BondOrder per site
    27623172    if (AtomMask[AtomCount] == true)  // break after one step
     
    27983208          line >> ws >> Value; // skip time entry
    27993209          line >> ws >> Value;
    2800           No -= 1;  // indices start at 1 in file, not 0
     3210          No -= 1;  // indices start at 1 in file, not 0 
    28013211          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    28023212
     
    28073217            // 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
    28083218            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2809             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     3219            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 
    28103220            if (!InsertedElement.second) { // this root is already present
    2811               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
    2812                 //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
     3221              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term 
     3222                //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) 
    28133223                {  // if value is smaller, update value and order
    28143224                (*PresentItem).second.first = fabs(Value);
     
    28483258        Walker = FindAtom(No);
    28493259        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2850           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     3260          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 
    28513261          AtomMask[No] = true;
    28523262          status = true;
    28533263        //} else
    2854           //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl;
     3264          //*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; 
    28553265      }
    28563266      // close and done
     
    28863296    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    28873297      status = true;
    2888 
     3298     
    28893299    if (!status) {
    28903300      if (Order == 0)
     
    28943304    }
    28953305  }
    2896 
     3306 
    28973307  // print atom mask for debugging
    28983308  *out << "              ";
     
    29033313    *out << (AtomMask[i] ? "t" : "f");
    29043314  *out << endl;
    2905 
     3315 
    29063316  return status;
    29073317};
     
    29173327  int AtomNo = 0;
    29183328  atom *Walker = NULL;
    2919 
     3329 
    29203330  if (SortIndex != NULL) {
    29213331    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     
    29753385  atom **ListOfAtoms = NULL;
    29763386  atom ***ListOfLocalAtoms = NULL;
    2977   bool *AtomMask = NULL;
    2978 
     3387  bool *AtomMask = NULL; 
     3388 
    29793389  *out << endl;
    29803390#ifdef ADDHYDROGEN
     
    29853395
    29863396  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    2987 
     3397 
    29883398  // ===== 1. Check whether bond structure is same as stored in files ====
    2989 
     3399 
    29903400  // fill the adjacency list
    29913401  CreateListOfBondsPerAtom(out);
     
    29933403  // create lookup table for Atom::nr
    29943404  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    2995 
     3405 
    29963406  // === compare it with adjacency file ===
    2997   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     3407  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 
    29983408  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    29993409
     
    30093419  while (MolecularWalker->next != NULL) {
    30103420    MolecularWalker = MolecularWalker->next;
     3421    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    30113422    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    30123423//    // check the list of local atoms for debugging
     
    30173428//      else
    30183429//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3019     *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    30203430    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3021     *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    30223431    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3023     *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    30243432    delete(LocalBackEdgeStack);
    30253433  }
    3026 
     3434 
    30273435  // ===== 3. if structure still valid, parse key set file and others =====
    30283436  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     
    30303438  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    30313439  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3032 
    3033   // =================================== Begin of FRAGMENTATION ===============================
    3034   // ===== 6a. assign each keyset to its respective subgraph =====
     3440 
     3441  // =================================== Begin of FRAGMENTATION =============================== 
     3442  // ===== 6a. assign each keyset to its respective subgraph ===== 
    30353443  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    30363444
     
    30433451    FragmentationToDo = FragmentationToDo || CheckOrder;
    30443452    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3045     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3453    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 
    30463454    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    30473455
     
    30523460      MolecularWalker = MolecularWalker->next;
    30533461      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3054       //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     3462      // output ListOfBondsPerAtom for debugging
     3463      MolecularWalker->Leaf->OutputListOfBonds(out);
    30553464      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3465     
    30563466        // call BOSSANOVA method
    30573467        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     
    30673477  delete(ParsedFragmentList);
    30683478  delete[](MinimumRingSize);
    3069 
     3479 
    30703480
    30713481  // ==================================== End of FRAGMENTATION ============================================
     
    30733483  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    30743484  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3075 
     3485 
    30763486  // free subgraph memory again
    30773487  FragmentCounter = 0;
     
    30983508    }
    30993509    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3100 
     3510   
    31013511    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    31023512    if (BondFragments->NumberOfMolecules != 0) {
    31033513      // create the SortIndex from BFS labels to order in the config file
    31043514      CreateMappingLabelsToConfigSequence(out, SortIndex);
    3105 
     3515     
    31063516      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    3107       if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     3517      if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true))
    31083518        *out << Verbose(1) << "All configs written." << endl;
    31093519      else
    31103520        *out << Verbose(1) << "Some config writing failed." << endl;
    3111 
     3521 
    31123522      // store force index reference file
    31133523      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3114 
    3115       // store keysets file
     3524     
     3525      // store keysets file 
    31163526      StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3117 
    3118       // store Adjacency file
     3527 
     3528      // store Adjacency file 
    31193529      StoreAdjacencyToFile(out, configuration->configpath);
    3120 
     3530 
    31213531      // store Hydrogen saturation correction file
    31223532      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3123 
     3533     
    31243534      // store adaptive orders into file
    31253535      StoreOrderAtSiteFile(out, configuration->configpath);
    3126 
     3536     
    31273537      // restore orbital and Stop values
    31283538      CalculateOrbitals(*configuration);
    3129 
     3539     
    31303540      // free memory for bond part
    31313541      *out << Verbose(1) << "Freeing bond memory" << endl;
    31323542      delete(FragmentList); // remove bond molecule from memory
    3133       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3543      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 
    31343544    } else
    31353545      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3136   //} else
     3546  //} else 
    31373547  //  *out << Verbose(1) << "No fragments to store." << endl;
    31383548  *out << Verbose(0) << "End of bond fragmentation." << endl;
     
    31603570  atom *Walker = NULL, *OtherAtom = NULL;
    31613571  ReferenceStack->Push(Binder);
    3162 
     3572 
    31633573  do {  // go through all bonds and push local ones
    31643574    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3165     if (Walker != NULL) // if this Walker exists in the subgraph ...
    3166         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3167         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3168               if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3169               LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3170                                         *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3171                 break;
    3172             }
    3173         }
     3575    if (Walker == NULL) // if this Walker exists in the subgraph ...
     3576      continue;
     3577    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3578      OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3579      if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3580        LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3581        break;
     3582      }
     3583    }
    31743584    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
    3175                 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    31763585    ReferenceStack->Push(Binder);
    31773586  } while (FirstBond != Binder);
    3178 
     3587 
    31793588  return status;
    31803589};
     
    32523661      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    32533662      Walker->MaxOrder = MaxArray[Walker->nr];
    3254       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3663      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 
    32553664    }
    32563665    file.close();
     
    32633672  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    32643673  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3265 
     3674 
    32663675  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    32673676  return status;
     
    33213730  Walker = start;
    33223731  while (Walker->next != end) {
    3323     Walker = Walker->next;
     3732    Walker = Walker->next; 
    33243733    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    33253734    TotalDegree = 0;
     
    33293738    }
    33303739    *out << " -- TotalDegree: " << TotalDegree << endl;
    3331   }
     3740  }     
    33323741  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    33333742};
     
    33353744/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
    33363745 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was
    3337  * white and putting into queue.
     3746 * white and putting into queue. 
    33383747 * \param *out output stream for debugging
    33393748 * \param *Mol Molecule class to add atoms to
     
    33443753 * \param BondOrder maximum distance for vertices to add
    33453754 * \param IsAngstroem lengths are in angstroem or bohrradii
    3346  */
     3755 */ 
    33473756void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    33483757{
     
    33703779  }
    33713780  ShortestPathList[Root->nr] = 0;
    3372 
     3781 
    33733782  // and go on ... Queue always contains all lightgray vertices
    33743783  while (!AtomStack->IsEmpty()) {
     
    33783787    // followed by n+1 till top of stack.
    33793788    Walker = AtomStack->PopFirst(); // pop oldest added
    3380     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3789    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 
    33813790    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    33823791      Binder = ListOfBondsPerAtom[Walker->nr][i];
     
    33853794        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    33863795        if (ColorList[OtherAtom->nr] == white) {
    3387           if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem)
     3796          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) 
    33883797            ColorList[OtherAtom->nr] = lightgray;
    33893798          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    33903799          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3391           *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     3800          *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; 
    33923801          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    33933802            *out << Verbose(3);
     
    34273836              } else {
    34283837#ifdef ADDHYDROGEN
    3429                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3430                   exit(1);
     3838                Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
    34313839#endif
    34323840              }
     
    34373845          // This has to be a cyclic bond, check whether it's present ...
    34383846          if (AddedBondList[Binder->nr] == NULL) {
    3439             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     3847            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 
    34403848              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    34413849              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     
    34433851            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    34443852#ifdef ADDHYDROGEN
    3445               if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3446                 exit(1);
     3853              Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
    34473854#endif
    34483855            }
     
    34523859    }
    34533860    ColorList[Walker->nr] = black;
    3454     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3861    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
    34553862  }
    34563863  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     
    34763883
    34773884  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3478 
     3885 
    34793886  // reset parent list
    34803887  *out << Verbose(3) << "Resetting ParentList." << endl;
    34813888  for (int i=Father->AtomCount;i--;)
    34823889    ParentList[i] = NULL;
    3483 
     3890 
    34843891  // fill parent list with sons
    34853892  *out << Verbose(3) << "Filling Parent List." << endl;
     
    35223929 * \param *&Leaf KeySet to look through
    35233930 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end
    3524  * \param index of the atom suggested for removal
     3931 * \param index of the atom suggested for removal 
    35253932 */
    35263933int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
     
    35283935  atom *Runner = NULL;
    35293936  int SP, Removal;
    3530 
     3937 
    35313938  *out << Verbose(2) << "Looking for removal candidate." << endl;
    35323939  SP = -1; //0;  // not -1, so that Root is never removed
     
    35463953/** Stores a fragment from \a KeySet into \a molecule.
    35473954 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
    3548  * molecule and adds missing hydrogen where bonds were cut.
     3955 * molecule and adds missing hydrogen where bonds were cut. 
    35493956 * \param *out output stream for debugging messages
    3550  * \param &Leaflet pointer to KeySet structure
     3957 * \param &Leaflet pointer to KeySet structure 
    35513958 * \param IsAngstroem whether we have Ansgtroem or bohrradius
    35523959 * \return pointer to constructed molecule
     
    35593966  bool LonelyFlag = false;
    35603967  int size;
    3561 
     3968 
    35623969//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3563 
     3970 
    35643971  Leaf->BondDistance = BondDistance;
    35653972  for(int i=NDIM*2;i--;)
    3566     Leaf->cell_size[i] = cell_size[i];
     3973    Leaf->cell_size[i] = cell_size[i]; 
    35673974
    35683975  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     
    35773984    size++;
    35783985  }
    3579 
     3986 
    35803987  // create the bonds between all: Make it an induced subgraph and add hydrogen
    35813988//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     
    35873994    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    35883995      // create all bonds
    3589       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3996      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 
    35903997        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    35913998//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    35923999        if (SonList[OtherFather->nr] != NULL) {
    3593 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     4000//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 
    35944001          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    35954002//            *out << Verbose(3) << "Adding Bond: ";
    3596 //            *out <<
     4003//            *out << 
    35974004            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    35984005//            *out << "." << endl;
    35994006            //NumBonds[Runner->nr]++;
    3600           } else {
     4007          } else { 
    36014008//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    36024009          }
    36034010          LonelyFlag = false;
    36044011        } else {
    3605 //          *out << ", who has no son in this fragment molecule." << endl;
     4012//          *out << ", who has no son in this fragment molecule." << endl; 
    36064013#ifdef ADDHYDROGEN
    36074014          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    3608           if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    3609             exit(1);
     4015          Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem);
    36104016#endif
    36114017          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     
    36214027    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    36224028      Runner = Runner->next;
    3623 #endif
     4029#endif       
    36244030  }
    36254031  Leaf->CreateListOfBondsPerAtom(out);
     
    36544060  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    36554061  StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack!
    3656   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
     4062  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 
    36574063  MoleculeListClass *FragmentList = NULL;
    36584064  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     
    37044110                // clear snake stack
    37054111          SnakeStack->ClearStack();
    3706     //SnakeStack->TestImplementation(out, start->next);
     4112    //SnakeStack->TestImplementation(out, start->next);   
    37074113
    37084114    ///// INNER LOOP ////////////
     
    37254131        }
    37264132        if (ShortestPathList[Walker->nr] == -1) {
    3727           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
     4133          ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 
    37284134          TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    37294135        }
     
    37634169                                OtherAtom = Binder->GetOtherAtom(Walker);
    37644170            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    3765               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
     4171              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 
    37664172              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    37674173            } else { // otherwise check its colour and element
    37684174                                if (
    37694175#ifdef ADDHYDROGEN
    3770               (OtherAtom->type->Z != 1) &&
     4176              (OtherAtom->type->Z != 1) && 
    37714177#endif
    37724178                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     
    37784184                //} else {
    37794185                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    3780                 //}
     4186                //} 
    37814187                Walker = OtherAtom;
    37824188                break;
    37834189              } else {
    3784                 if (OtherAtom->type->Z == 1)
     4190                if (OtherAtom->type->Z == 1) 
    37854191                  *out << "Links to a hydrogen atom." << endl;
    3786                 else
     4192                else                 
    37874193                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    37884194              }
     
    37944200          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    37954201        }
    3796                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
     4202                        if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black 
    37974203          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    37984204                                ColorVertexList[Walker->nr] = black;
     
    38014207      }
    38024208        } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    3803     *out << Verbose(2) << "Inner Looping is finished." << endl;
     4209    *out << Verbose(2) << "Inner Looping is finished." << endl;   
    38044210
    38054211    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     
    38174223    }
    38184224  }
    3819   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
     4225  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 
    38204226
    38214227  // copy together
    3822   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
     4228  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 
    38234229  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    38244230  RunningIndex = 0;
     
    38914297
    38924298  NumCombinations = 1 << SetDimension;
    3893 
     4299 
    38944300  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    38954301  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    38964302  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3897 
     4303 
    38984304  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    38994305  *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;
    39004306
    3901   // initialised touched list (stores added atoms on this level)
     4307  // initialised touched list (stores added atoms on this level) 
    39024308  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    39034309  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    39044310    TouchedList[TouchedIndex] = -1;
    39054311  TouchedIndex = 0;
    3906 
     4312 
    39074313  // create every possible combination of the endpieces
    39084314  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     
    39124318    for (int j=SetDimension;j--;)
    39134319      bits += (i & (1 << j)) >> j;
    3914 
     4320     
    39154321    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    39164322    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     
    39204326        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    39214327        if (bit) {  // if bit is set, we add this bond partner
    3922                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
     4328                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add 
    39234329          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    39244330          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3925           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     4331          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 
    39264332          if (TestKeySetInsert.second) {
    39274333            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     
    39364342        }
    39374343      }
    3938 
    3939       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     4344     
     4345      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 
    39404346      if (SpaceLeft > 0) {
    39414347        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     
    39654371          }
    39664372          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3967           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     4373          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 
    39684374          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    39694375        }
     
    39744380        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    39754381        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3976           *out << (*runner) << " ";
     4382          *out << (*runner) << " "; 
    39774383        *out << endl;
    39784384        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     
    39824388        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    39834389      }
    3984 
     4390     
    39854391      // --3-- remove all added items in this level from snake stack
    39864392      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     
    39934399      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    39944400      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3995         *out << (*runner) << " ";
     4401        *out << (*runner) << " "; 
    39964402      *out << endl;
    39974403      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     
    40004406    }
    40014407  }
    4002   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     4408  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 
    40034409  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    40044410};
     
    40094415 * \return true - connected, false - disconnected
    40104416 * \note this is O(n^2) for it's just a bug checker not meant for permanent use!
    4011  */
     4417 */ 
    40124418bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    40134419{
     
    40154421  bool BondStatus = false;
    40164422  int size;
    4017 
     4423 
    40184424  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    40194425  *out << Verbose(2) << "Disconnected atom: ";
    4020 
     4426 
    40214427  // count number of atoms in graph
    40224428  size = 0;
     
    40644470 * \param *out output stream for debugging
    40654471 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation
    4066  * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on
     4472 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 
    40674473 * \param RestrictedKeySet Restricted vertex set to use in context of molecule
    40684474 * \return number of inserted fragments
    40694475 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore
    40704476 */
    4071 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
     4477int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 
    40724478{
    40734479  int SP, AtomKeyNr;
     
    40904496    FragmentSearch.BondsPerSPCount[i] = 0;
    40914497  FragmentSearch.BondsPerSPCount[0] = 1;
    4092   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     4498  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 
    40934499  add(Binder, FragmentSearch.BondsPerSPList[1]);
    4094 
     4500 
    40954501  // do a BFS search to fill the SP lists and label the found vertices
    40964502  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    40974503  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    40984504  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4099   // (EdgeinSPLevel) of this tree ...
     4505  // (EdgeinSPLevel) of this tree ... 
    41004506  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    41014507  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     
    41504556    }
    41514557  }
    4152 
     4558 
    41534559  // outputting all list for debugging
    41544560  *out << Verbose(0) << "Printing all found lists." << endl;
     
    41594565      Binder = Binder->next;
    41604566      *out << Verbose(2) << *Binder << endl;
    4161     }
    4162   }
    4163 
     4567    } 
     4568  }
     4569 
    41644570  // creating fragments with the found edge sets  (may be done in reverse order, faster)
    41654571  SP = -1;  // the Root <-> Root edge must be subtracted!
     
    41684574    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    41694575      Binder = Binder->next;
    4170       SP ++;
     4576      SP ++; 
    41714577    }
    41724578  }
     
    41754581    // start with root (push on fragment stack)
    41764582    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4177     FragmentSearch.FragmentSet->clear();
     4583    FragmentSearch.FragmentSet->clear(); 
    41784584    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    41794585    // prepare the subset and call the generator
    41804586    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    41814587    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4182 
     4588   
    41834589    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4184 
     4590   
    41854591    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    41864592  } else {
     
    41914597  // remove root from stack
    41924598  *out << Verbose(0) << "Removing root again from stack." << endl;
    4193   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4599  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);   
    41944600
    41954601  // free'ing the bonds lists
     
    42104616  }
    42114617
    4212   // return list
     4618  // return list 
    42134619  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    42144620  return (FragmentSearch.FragmentCounter - Counter);
     
    42414647    // remove bonds that are beyond bonddistance
    42424648    for(int i=NDIM;i--;)
    4243       Translationvector.x[i] = 0.;
     4649      Translationvector.x[i] = 0.; 
    42444650    // scan all bonds
    42454651    Binder = first;
     
    42884694        }
    42894695      }
    4290       // re-add bond
     4696      // re-add bond   
    42914697      link(Binder, OtherBinder);
    42924698    } else {
     
    43424748        IteratorB++;
    43434749      } // end of while loop
    4344     }// end of check in case of equal sizes
     4750    }// end of check in case of equal sizes 
    43454751  }
    43464752  return false; // if we reach this point, they are equal
     
    43864792 * \param graph1 first (dest) graph
    43874793 * \param graph2 second (source) graph
    4388  * \param *counter keyset counter that gets increased
     4794 * \param *counter keyset counter that gets increased 
    43894795 */
    43904796inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
     
    44314837  int RootKeyNr, RootNr;
    44324838  struct UniqueFragments FragmentSearch;
    4433 
     4839 
    44344840  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    44354841
     
    44544860    Walker = Walker->next;
    44554861    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4456   }
     4862  } 
    44574863
    44584864  // 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
     
    44684874    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    44694875    //  *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl;
    4470     //} else
     4876    //} else 
    44714877    {
    44724878      // increase adaptive order by one
    44734879      Walker->GetTrueFather()->AdaptiveOrder++;
    44744880      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4475 
     4881 
    44764882      // initialise Order-dependent entries of UniqueFragments structure
    44774883      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     
    44804886        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    44814887        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    4482         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two
     4888        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two 
    44834889        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    44844890        FragmentSearch.BondsPerSPCount[i] = 0;
    4485       }
    4486 
     4891      } 
     4892 
    44874893      // allocate memory for all lower level orders in this 1D-array of ptrs
    44884894      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     
    44904896      for (int i=0;i<NumLevels;i++)
    44914897        FragmentLowerOrdersList[RootNr][i] = NULL;
    4492 
     4898     
    44934899      // create top order where nothing is reduced
    44944900      *out << Verbose(0) << "==============================================================================================================" << endl;
    44954901      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4496 
     4902 
    44974903      // Create list of Graphs of current Bond Order (i.e. F_{ij})
    44984904      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     
    45074913        // we don't have to dive into suborders! These keysets are all already created on lower orders!
    45084914        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4509 
     4915       
    45104916//        if ((NumLevels >> 1) > 0) {
    45114917//          // create lower order fragments
     
    45144920//          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)
    45154921//            // step down to next order at (virtual) boundary of powers of 2 in array
    4516 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4922//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
    45174923//              Order--;
    45184924//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     
    45214927//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    45224928//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    4523 //
     4929//       
    45244930//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    45254931//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     
    45524958      RootStack.push_back(RootKeyNr); // put back on stack
    45534959      RootNr++;
    4554 
     4960 
    45554961      // free Order-dependent entries of UniqueFragments structure for next loop cycle
    45564962      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     
    45584964        delete(FragmentSearch.BondsPerSPList[2*i]);
    45594965        delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4560       }
     4966      } 
    45614967      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    45624968    }
     
    45694975  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    45704976  delete(FragmentSearch.FragmentSet);
    4571 
    4572   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4977 
     4978  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 
    45734979  // 5433222211111111
    45744980  // 43221111
     
    45904996    RootKeyNr = RootStack.front();
    45914997    RootStack.pop_front();
    4592     Walker = FindAtom(RootKeyNr);
     4998    Walker = FindAtom(RootKeyNr); 
    45934999    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    45945000    for(int i=0;i<NumLevels;i++) {
     
    46035009  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    46045010  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4605 
     5011 
    46065012  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    46075013};
     
    46375043  atom *Walker = NULL;
    46385044  bool result = true; // status of comparison
    4639 
    4640   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     5045 
     5046  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 
    46415047  /// first count both their atoms and elements and update lists thereby ...
    46425048  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     
    46855091    if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    46865092      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4687       result = false;
    4688     }
    4689   }
    4690 
     5093      result = false; 
     5094    }
     5095  }
     5096 
    46915097  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    46925098  if (result) {
     
    47045110      OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    47055111    }
    4706 
     5112 
    47075113    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    47085114    *out << Verbose(5) << "Sorting distances" << endl;
     
    47155121    for(int i=AtomCount;i--;)
    47165122      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4717 
     5123   
    47185124    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    47195125    *out << Verbose(4) << "Comparing distances" << endl;
     
    47265132    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    47275133    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4728 
     5134     
    47295135    /// free memory
    47305136    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     
    47345140      result = false;
    47355141    }
    4736   }
     5142  } 
    47375143  /// return pointer to map if all distances were below \a threshold
    47385144  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     
    47435149    *out << Verbose(3) << "Result: Not equal." << endl;
    47445150    return NULL;
    4745   }
     5151  } 
    47465152};
    47475153
     
    47985204 * \param *output output stream of temperature file
    47995205 * \return file written (true), failure on writing file (false)
    4800  */
     5206 */ 
    48015207bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    48025208{
     
    48065212  if (output == NULL)
    48075213    return false;
    4808   else
     5214  else 
    48095215    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    48105216  for (int step=startstep;step < endstep; step++) { // loop over all time steps
Note: See TracChangeset for help on using the changeset viewer.