Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/molecules.cpp

    • Property mode changed from 100644 to 100755
    rd01f4d r848729  
    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) << "WARNING: There is no typical bond distance for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223     BondRescale = bondlength;
     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;
    224225  } else {
    225226    if (!IsAngstroem)
     
    272273      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    273274//        *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;
    274        
     275
    275276        // determine the plane of these two with the *origin
    276277        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     
    285286      Orthovector1.Normalize();
    286287      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    287      
     288
    288289      // create the two Hydrogens ...
    289290      FirstOtherAtom = new atom();
     
    299300      bondangle = TopOrigin->type->HBondAngle[1];
    300301      if (bondangle == -1) {
    301         *out << Verbose(3) << "WARNING: There is no typical bond angle for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     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;
    302304        bondangle = 0;
    303305      }
     
    316318        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    317319      }
    318       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance 
     320      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    319321      SecondOtherAtom->x.Scale(&BondRescale);
    320322      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    321323      for(int i=NDIM;i--;) { // and make relative to origin atom
    322         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 
     324        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    323325        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    324326      }
     
    363365//      *out << endl;
    364366      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    365 //      *out << Verbose(3) << "Orthovector2: "; 
     367//      *out << Verbose(3) << "Orthovector2: ";
    366368//      Orthovector2.Output(out);
    367369//      *out << endl;
    368      
     370
    369371      // create correct coordination for the three atoms
    370372      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     
    378380      factors[0] = d;
    379381      factors[1] = f;
    380       factors[2] = 0.; 
     382      factors[2] = 0.;
    381383      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    382384      factors[1] = -0.5*f;
    383       factors[2] = g; 
     385      factors[2] = g;
    384386      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    385       factors[2] = -g; 
     387      factors[2] = -g;
    386388      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387389
     
    435437 */
    436438bool molecule::AddXYZFile(string filename)
    437 { 
     439{
    438440  istringstream *input = NULL;
    439441  int NumberOfAtoms = 0; // atom number in xyz read
     
    444446  string line;    // currently parsed line
    445447  double x[3];    // atom coordinates
    446  
     448
    447449  xyzfile.open(filename.c_str());
    448450  if (!xyzfile)
     
    452454  input = new istringstream(line);
    453455  *input >> NumberOfAtoms;
    454   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 
     456  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    455457  getline(xyzfile,line,'\n'); // Read comment
    456458  cout << Verbose(1) << "Comment: " << line << endl;
    457  
     459
    458460  if (MDSteps == 0) // no atoms yet present
    459461    MDSteps++;
     
    489491  xyzfile.close();
    490492  delete(input);
    491   return true; 
     493  return true;
    492494};
    493495
     
    501503  atom *LeftAtom = NULL, *RightAtom = NULL;
    502504  atom *Walker = NULL;
    503  
     505
    504506  // copy all atoms
    505507  Walker = start;
     
    508510    CurrentAtom = copy->AddCopyAtom(Walker);
    509511  }
    510  
     512
    511513  // copy all bonds
    512514  bond *Binder = first;
     
    532534      copy->NoCyclicBonds++;
    533535    NewBond->Type = Binder->Type;
    534   } 
     536  }
    535537  // correct fathers
    536538  Walker = copy->start;
     
    549551    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    550552  }
    551  
     553
    552554  return copy;
    553555};
     
    574576
    575577/** Remove bond from bond chain list.
    576  * \todo Function not implemented yet 
     578 * \todo Function not implemented yet
    577579 * \param *pointer bond pointer
    578580 * \return true - bound found and removed, false - bond not found/removed
     
    586588
    587589/** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of.
    588  * \todo Function not implemented yet 
     590 * \todo Function not implemented yet
    589591 * \param *BondPartner atom to be removed
    590592 * \return true - bounds found and removed, false - bonds not found/removed
     
    619621  Vector *min = new Vector;
    620622  Vector *max = new Vector;
    621  
     623
    622624  // gather min and max for each axis
    623625  ptr = start->next;  // start at first in list
     
    665667{
    666668  Vector *min = new Vector;
    667  
     669
    668670//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    669671  atom *ptr = start->next;  // start at first in list
     
    681683      }
    682684    }
    683 //    *out << Verbose(4) << "Maximum is "; 
     685//    *out << Verbose(4) << "Maximum is ";
    684686//    max->Output(out);
    685687//    *out << ", Minimum is ";
     
    689691    max->AddVector(min);
    690692    Translate(min);
    691   } 
     693  }
    692694  delete(min);
    693695//  *out << Verbose(3) << "End of CenterEdge." << endl;
    694 }; 
     696};
    695697
    696698/** Centers the center of the atoms at (0,0,0).
     
    702704  int Num = 0;
    703705  atom *ptr = start->next;  // start at first in list
    704  
     706
    705707  for(int i=NDIM;i--;) // zero center vector
    706708    center->x[i] = 0.;
    707    
     709
    708710  if (ptr != end) {   //list not empty?
    709711    while (ptr->next != end) {  // continue with second if present
    710712      ptr = ptr->next;
    711713      Num++;
    712       center->AddVector(&ptr->x);       
     714      center->AddVector(&ptr->x);
    713715    }
    714716    center->Scale(-1./Num); // divide through total number (and sign for direction)
    715717    Translate(center);
    716718  }
    717 }; 
     719};
    718720
    719721/** Returns vector pointing to center of gravity.
     
    727729  Vector tmp;
    728730  double Num = 0;
    729  
     731
    730732  a->Zero();
    731733
     
    735737      Num += 1.;
    736738      tmp.CopyVector(&ptr->x);
    737       a->AddVector(&tmp);       
     739      a->AddVector(&tmp);
    738740    }
    739741    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    755757        Vector tmp;
    756758  double Num = 0;
    757        
     759
    758760        a->Zero();
    759761
     
    764766      tmp.CopyVector(&ptr->x);
    765767      tmp.Scale(ptr->type->mass);  // scale by mass
    766       a->AddVector(&tmp);       
     768      a->AddVector(&tmp);
    767769    }
    768770    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    787789    Translate(center);
    788790  }
    789 }; 
     791};
    790792
    791793/** Scales all atoms by \a *factor.
     
    801803      Trajectories[ptr].R.at(j).Scale(factor);
    802804    ptr->x.Scale(factor);
    803   }     
    804 };
    805 
    806 /** Translate all atoms by given vector. 
     805  }
     806};
     807
     808/** Translate all atoms by given vector.
    807809 * \param trans[] translation vector.
    808810 */
     
    816818      Trajectories[ptr].R.at(j).Translate(trans);
    817819    ptr->x.Translate(trans);
    818   }     
    819 };
    820 
    821 /** Mirrors all atoms against a given plane. 
     820  }
     821};
     822
     823/** Mirrors all atoms against a given plane.
    822824 * \param n[] normal vector of mirror plane.
    823825 */
     
    831833      Trajectories[ptr].R.at(j).Mirror(n);
    832834    ptr->x.Mirror(n);
    833   }     
     835  }
    834836};
    835837
     
    845847  bool flag;
    846848  Vector Testvector, Translationvector;
    847  
     849
    848850  do {
    849851    Center.Zero();
     
    861863          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    862864            for (int j=0;j<NDIM;j++) {
    863               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 
     865              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    864866              if ((fabs(tmp)) > BondDistance) {
    865867                flag = false;
     
    877879        cout << Verbose(1) << "vector is: ";
    878880        Testvector.Output((ofstream *)&cout);
    879         cout << endl;     
     881        cout << endl;
    880882#ifdef ADDHYDROGEN
    881883        // now also change all hydrogens
     
    890892            cout << Verbose(1) << "Hydrogen vector is: ";
    891893            Testvector.Output((ofstream *)&cout);
    892             cout << endl;     
     894            cout << endl;
    893895          }
    894896        }
     
    912914
    913915        CenterGravity(out, CenterOfGravity);
    914        
    915         // reset inertia tensor 
     916
     917        // reset inertia tensor
    916918        for(int i=0;i<NDIM*NDIM;i++)
    917919                InertiaTensor[i] = 0.;
    918        
     920
    919921        // sum up inertia tensor
    920922        while (ptr->next != end) {
     
    941943        }
    942944        *out << endl;
    943        
     945
    944946        // diagonalize to determine principal axis system
    945947        gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     
    950952        gsl_eigen_symmv_free(T);
    951953        gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    952        
     954
    953955        for(int i=0;i<NDIM;i++) {
    954956                *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    955957                *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    956958        }
    957        
     959
    958960        // check whether we rotate or not
    959961        if (DoRotate) {
    960           *out << Verbose(1) << "Transforming molecule into PAS ... "; 
     962          *out << Verbose(1) << "Transforming molecule into PAS ... ";
    961963          // the eigenvectors specify the transformation matrix
    962964          ptr = start;
     
    970972
    971973          // summing anew for debugging (resulting matrix has to be diagonal!)
    972           // reset inertia tensor 
     974          // reset inertia tensor
    973975    for(int i=0;i<NDIM*NDIM;i++)
    974976      InertiaTensor[i] = 0.;
    975    
     977
    976978    // sum up inertia tensor
    977979    ptr = start;
     
    10001002    *out << endl;
    10011003        }
    1002        
     1004
    10031005        // free everything
    10041006        delete(CenterOfGravity);
     
    10071009};
    10081010
    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  */
    1028 double 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 
    1155 void 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  */
    1204 double 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  */
    1381 void 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  */
    1407 bool 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 
    14751011/** Parses nuclear forces from file and performs Verlet integration.
    14761012 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
    14771013 * have to transform them).
    14781014 * This adds a new MD step to the config file.
    1479  * \param *out output stream for debugging
    14801015 * \param *file filename
    1481  * \param config structure with config::Deltat, config::IsAngstroem, config::DoConstrained
    14821016 * \param delta_t time step width in atomic units
    14831017 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
    1484  * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential()
    14851018 * \return true - file found and parsed, false - file not found or imparsable
    1486  * \todo This is not yet checked if it is correctly working with DoConstrained set to true.
    1487  */
    1488 bool molecule::VerletForceIntegration(ofstream *out, char *file, config &configuration)
    1489 {
     1019 */
     1020bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
     1021{
     1022  element *runner = elemente->start;
    14901023  atom *walker = NULL;
    14911024  int AtomNo;
     
    14931026  string token;
    14941027  stringstream item;
    1495   double a, IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp;
     1028  double a, IonMass;
    14961029  ForceMatrix Force;
     1030  Vector tmpvector;
    14971031
    14981032  CountElements();  // make sure ElementsInMolecule is up to date
    1499  
     1033
    15001034  // check file
    15011035  if (input == NULL) {
     
    15121046    }
    15131047    // correct Forces
    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 (configuration.DoConstrainedMD) {
    1526       // calculate forces and potential
    1527       atom **PermutationMap = NULL;
    1528       ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap,configuration.DoConstrainedMD, 0, configuration.GetIsAngstroem());
    1529       EvaluateConstrainedForces(out, configuration.DoConstrainedMD, 0, PermutationMap, &Force);
    1530       Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
    1531     }
    1532    
     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//      }
    15331058    // and perform Verlet integration for each atom with position, velocity and force vector
    1534     walker = start;
    1535     while (walker->next != end) { // go through every atom of this element
    1536       walker = walker->next;
    1537       //a = configuration.Deltat*0.5/walker->type->mass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1538       // check size of vectors
    1539       if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1540         //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1541         Trajectories[walker].R.resize(MDSteps+10);
    1542         Trajectories[walker].U.resize(MDSteps+10);
    1543         Trajectories[walker].F.resize(MDSteps+10);
    1544       }
    1545      
    1546       // Update R (and F)
    1547       for (int d=0; d<NDIM; d++) {
    1548         Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][walker->nr][d+5]*(configuration.GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
    1549         Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1550         Trajectories[walker].R.at(MDSteps).x[d] += configuration.Deltat*(Trajectories[walker].U.at(MDSteps-1).x[d]);     // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
    1551         Trajectories[walker].R.at(MDSteps).x[d] += 0.5*configuration.Deltat*configuration.Deltat*(Trajectories[walker].F.at(MDSteps).x[d]/walker->type->mass);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    1552       }
    1553       // Update U
    1554       for (int d=0; d<NDIM; d++) {
    1555         Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1556         Trajectories[walker].U.at(MDSteps).x[d] += configuration.Deltat * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]/walker->type->mass); // v = F/m * t
    1557       }
    1558 //      out << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1559 //      for (int d=0;d<NDIM;d++)
    1560 //        out << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
    1561 //      out << ")\t(";
    1562 //      for (int d=0;d<NDIM;d++)
    1563 //        cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
    1564 //      out << ")" << endl;
    1565             // next atom
    1566     }
    1567   }
    1568   // correct velocities (rather momenta) so that center of mass remains motionless
    1569   for(int d=0;d<NDIM;d++)
    1570     Vector[d] = 0.;
    1571   IonMass = 0.;
    1572   walker = start;
    1573   while (walker->next != end) { // go through every atom
    1574     walker = walker->next;
    1575     IonMass += walker->type->mass;  // sum up total mass
    1576     for(int d=0;d<NDIM;d++) {
    1577       Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1578     }
    1579   }
    1580   for(int d=0;d<NDIM;d++)
    1581     Vector[d] /= IonMass;
    1582   ActualTemp = 0.;
    1583   walker = start;
    1584   while (walker->next != end) { // go through every atom of this element
    1585     walker = walker->next;
    1586     for(int d=0;d<NDIM;d++) {
    1587       Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d];
    1588       ActualTemp += 0.5 * walker->type->mass * Trajectories[walker].U.at(MDSteps).x[d] * Trajectories[walker].U.at(MDSteps).x[d];
    1589     }
    1590   }
    1591   Thermostats(configuration, ActualTemp, Berendsen);
    1592   MDSteps++;
    1593 
    1594  
    1595   // exit
    1596   return true;
    1597 };
    1598 
    1599 
    1600 /** Implementation of various thermostats.
    1601  * All these thermostats apply an additional force which has the following forms:
    1602  * -# Woodcock
    1603  *  \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$
    1604  * -# Gaussian
    1605  *  \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$
    1606  * -# Langevin
    1607  *  \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$ 
    1608  * -# Berendsen
    1609  *  \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$
    1610  * -# Nose-Hoover
    1611  *  \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$
    1612  * These Thermostats either simply rescale the velocities, thus this function should be called after ion velocities have been updated, and/or
    1613  * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified
    1614  * belatedly and the constraint force set.
    1615  * \param *P Problem at hand
    1616  * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover
    1617  * \sa InitThermostat()
    1618  */
    1619 void molecule::Thermostats(config &configuration, double ActualTemp, int Thermostat)
    1620 {
    1621   double ekin = 0.;
    1622   double E = 0., G = 0.;
    1623   double delta_alpha = 0.;
    1624   double ScaleTempFactor;
    1625   double sigma;
    1626   double IonMass;
    1627   int d;
    1628   gsl_rng * r;
    1629   const gsl_rng_type * T;
    1630   double *U = NULL, *F = NULL, FConstraint[NDIM];
    1631   atom *walker = NULL;
    1632  
    1633   // calculate scale configuration
    1634   ScaleTempFactor = configuration.TargetTemp/ActualTemp;
    1635    
    1636   // differentating between the various thermostats
    1637   switch(Thermostat) {
    1638      case None:
    1639       cout << Verbose(2) <<  "Applying no thermostat..." << endl;
    1640       break;
    1641      case Woodcock:
    1642       if ((configuration.ScaleTempStep > 0) && ((MDSteps-1) % configuration.ScaleTempStep == 0)) {
    1643         cout << Verbose(2) <<  "Applying Woodcock thermostat..." << endl;
     1059    runner = elemente->start;
     1060    while (runner->next != elemente->end) { // go through every element
     1061      runner = runner->next;
     1062      IonMass = runner->mass;
     1063      a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1064      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1065        AtomNo = 0;
    16441066        walker = start;
    16451067        while (walker->next != end) { // go through every atom of this element
    16461068          walker = walker->next;
    1647           IonMass = walker->type->mass;
    1648           U = Trajectories[walker].U.at(MDSteps).x;
    1649           if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1650             for (d=0; d<NDIM; d++) {
    1651               U[d] *= sqrt(ScaleTempFactor);
    1652               ekin += 0.5*IonMass * U[d]*U[d];
     1069          if (walker->type == runner) { // if this atom fits to element
     1070            // check size of vectors
     1071            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1072              //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1073              Trajectories[walker].R.resize(MDSteps+10);
     1074              Trajectories[walker].U.resize(MDSteps+10);
     1075              Trajectories[walker].F.resize(MDSteps+10);
    16531076            }
    1654         }
    1655       }
    1656       break;
    1657      case Gaussian:
    1658       cout << Verbose(2) <<  "Applying Gaussian thermostat..." << endl;
    1659       walker = start;
    1660       while (walker->next != end) { // go through every atom of this element
    1661         walker = walker->next;
    1662         IonMass = walker->type->mass;
    1663         U = Trajectories[walker].U.at(MDSteps).x;
    1664         F = Trajectories[walker].F.at(MDSteps).x;
    1665         if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1666           for (d=0; d<NDIM; d++) {
    1667             G += U[d] * F[d];
    1668             E += U[d]*U[d]*IonMass;
    1669           }
    1670       }
    1671       cout << Verbose(1) << "Gaussian Least Constraint constant is " << G/E << "." << endl;
    1672       walker = start;
    1673       while (walker->next != end) { // go through every atom of this element
    1674         walker = walker->next;
    1675         IonMass = walker->type->mass;
    1676         U = Trajectories[walker].U.at(MDSteps).x;
    1677         F = Trajectories[walker].F.at(MDSteps).x;
    1678         if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1679           for (d=0; d<NDIM; d++) {
    1680             FConstraint[d] = (G/E) * (U[d]*IonMass);
    1681             U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
    1682             ekin += IonMass * U[d]*U[d];
    1683           }
    1684       }
    1685       break;
    1686      case Langevin:
    1687       cout << Verbose(2) <<  "Applying Langevin thermostat..." << endl;
    1688       // init random number generator
    1689       gsl_rng_env_setup();
    1690       T = gsl_rng_default;
    1691       r = gsl_rng_alloc (T);
    1692       // Go through each ion
    1693       walker = start;
    1694       while (walker->next != end) { // go through every atom of this element
    1695         walker = walker->next;
    1696         IonMass = walker->type->mass;
    1697         sigma  = sqrt(configuration.TargetTemp/IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
    1698         U = Trajectories[walker].U.at(MDSteps).x;
    1699         F = Trajectories[walker].F.at(MDSteps).x;
    1700         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1701           // throw a dice to determine whether it gets hit by a heat bath particle
    1702           if (((((rand()/(double)RAND_MAX))*configuration.TempFrequency) < 1.)) { 
    1703             cout << Verbose(3) << "Particle " << *walker << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
    1704             // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
    1705             for (d=0; d<NDIM; d++) {
    1706               U[d] = gsl_ran_gaussian (r, sigma);
     1077            // 1. calculate x(t+\delta t)
     1078            for (int d=0; d<NDIM; d++) {
     1079              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
     1080              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1081              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1082              Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass;     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    17071083            }
    1708             cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
    1709           }
    1710           for (d=0; d<NDIM; d++)
    1711             ekin += 0.5*IonMass * U[d]*U[d];
    1712         }
    1713       }
    1714       break;
    1715      case Berendsen:
    1716       cout << Verbose(2) <<  "Applying Berendsen-VanGunsteren thermostat..." << endl;
    1717       walker = start;
    1718       while (walker->next != end) { // go through every atom of this element
    1719         walker = walker->next;
    1720         IonMass = walker->type->mass;
    1721         U = Trajectories[walker].U.at(MDSteps).x;
    1722         F = Trajectories[walker].F.at(MDSteps).x;
    1723         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1724           for (d=0; d<NDIM; d++) {
    1725             U[d] *= sqrt(1+(configuration.Deltat/configuration.TempFrequency)*(ScaleTempFactor-1));
    1726             ekin += 0.5*IonMass * U[d]*U[d];
     1084            // 2. Calculate v(t+\delta t)
     1085            for (int d=0; d<NDIM; d++) {
     1086              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1087              Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
     1088            }
     1089//            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1090//            for (int d=0;d<NDIM;d++)
     1091//              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1092//            cout << ")\t(";
     1093//            for (int d=0;d<NDIM;d++)
     1094//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1095//            cout << ")" << endl;
     1096            // next atom
     1097            AtomNo++;
    17271098          }
    17281099        }
    17291100      }
    1730       break;
    1731      case NoseHoover:
    1732       cout << Verbose(2) <<  "Applying Nose-Hoover thermostat..." << endl;
    1733       // dynamically evolve alpha (the additional degree of freedom)
    1734       delta_alpha = 0.;
    1735       walker = start;
    1736       while (walker->next != end) { // go through every atom of this element
    1737         walker = walker->next;
    1738         IonMass = walker->type->mass;
    1739         U = Trajectories[walker].U.at(MDSteps).x;
    1740         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1741           for (d=0; d<NDIM; d++) {
    1742             delta_alpha += U[d]*U[d]*IonMass;
    1743           }
    1744         }
    1745       }
    1746       delta_alpha = (delta_alpha - (3.*AtomCount+1.) * configuration.TargetTemp)/(configuration.HooverMass*Units2Electronmass);
    1747       configuration.alpha += delta_alpha*configuration.Deltat;
    1748       cout << Verbose(3) << "alpha = " << delta_alpha << " * " << configuration.Deltat << " = " << configuration.alpha << "." << endl;
    1749       // apply updated alpha as additional force
    1750       walker = start;
    1751       while (walker->next != end) { // go through every atom of this element
    1752         walker = walker->next;
    1753         IonMass = walker->type->mass;
    1754         U = Trajectories[walker].U.at(MDSteps).x;
    1755         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1756           for (d=0; d<NDIM; d++) {
    1757               FConstraint[d] = - configuration.alpha * (U[d] * IonMass);
    1758               U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
    1759               ekin += (0.5*IonMass) * U[d]*U[d];
    1760             }
    1761         }
    1762       }
    1763       break;
    1764   }   
    1765   cout << Verbose(1) << "Kinetic energy is " << ekin << "." << endl;
    1766 };
    1767 
    1768 /** Align all atoms in such a manner that given vector \a *n is along z axis.
     1101    }
     1102  }
     1103//  // correct velocities (rather momenta) so that center of mass remains motionless
     1104//  tmpvector.zero()
     1105//  IonMass = 0.;
     1106//  walker = start;
     1107//  while (walker->next != end) { // go through every atom
     1108//    walker = walker->next;
     1109//    IonMass += walker->type->mass;  // sum up total mass
     1110//    for(int d=0;d<NDIM;d++) {
     1111//      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1112//    }
     1113//  }
     1114//  walker = start;
     1115//  while (walker->next != end) { // go through every atom of this element
     1116//    walker = walker->next;
     1117//    for(int d=0;d<NDIM;d++) {
     1118//      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
     1119//    }
     1120//  }
     1121  MDSteps++;
     1122
     1123
     1124  // exit
     1125  return true;
     1126};
     1127
     1128/** Align all atoms in such a manner that given vector \a *n is along z axis.
    17691129 * \param n[] alignment vector.
    17701130 */
     
    17851145    ptr = ptr->next;
    17861146    tmp = ptr->x.x[0];
    1787     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1147    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    17881148    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    17891149    for (int j=0;j<MDSteps;j++) {
    17901150      tmp = Trajectories[ptr].R.at(j).x[0];
    1791       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1151      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    17921152      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    17931153    }
    1794   }     
     1154  }
    17951155  // rotate n vector
    17961156  tmp = n->x[0];
     
    18001160  n->Output((ofstream *)&cout);
    18011161  cout << endl;
    1802  
     1162
    18031163  // rotate on z-y plane
    18041164  ptr = start;
     
    18081168    ptr = ptr->next;
    18091169    tmp = ptr->x.x[1];
    1810     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1170    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    18111171    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    18121172    for (int j=0;j<MDSteps;j++) {
    18131173      tmp = Trajectories[ptr].R.at(j).x[1];
    1814       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1174      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    18151175      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    18161176    }
    1817   }     
     1177  }
    18181178  // rotate n vector (for consistency check)
    18191179  tmp = n->x[1];
    18201180  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    18211181  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1822  
     1182
    18231183  cout << Verbose(1) << "alignment vector after second rotation: ";
    18241184  n->Output((ofstream *)&cout);
     
    18311191 * \return true - succeeded, false - atom not found in list
    18321192 */
    1833 bool molecule::RemoveAtom(atom *pointer) 
    1834 { 
     1193bool molecule::RemoveAtom(atom *pointer)
     1194{
    18351195  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    18361196    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    18371197  else
    1838     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 
     1198    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    18391199  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    18401200    ElementCount--;
     
    18461206 * \return true - succeeded, false - atom not found in list
    18471207 */
    1848 bool molecule::CleanupMolecule() 
    1849 { 
    1850   return (cleanup(start,end) && cleanup(first,last)); 
     1208bool molecule::CleanupMolecule()
     1209{
     1210  return (cleanup(start,end) && cleanup(first,last));
    18511211};
    18521212
     
    18621222  } else {
    18631223    cout << Verbose(0) << "Atom not found in list." << endl;
    1864     return NULL; 
     1224    return NULL;
    18651225  }
    18661226};
     
    19111271  struct lsq_params *par = (struct lsq_params *)params;
    19121272  atom *ptr = par->mol->start;
    1913  
     1273
    19141274  // initialize vectors
    19151275  a.x[0] = gsl_vector_get(x,0);
     
    19411301{
    19421302    int np = 6;
    1943    
     1303
    19441304   const gsl_multimin_fminimizer_type *T =
    19451305     gsl_multimin_fminimizer_nmsimplex;
     
    19471307   gsl_vector *ss;
    19481308   gsl_multimin_function minex_func;
    1949  
     1309
    19501310   size_t iter = 0, i;
    19511311   int status;
    19521312   double size;
    1953  
     1313
    19541314   /* Initial vertex size vector */
    19551315   ss = gsl_vector_alloc (np);
    1956  
     1316
    19571317   /* Set all step sizes to 1 */
    19581318   gsl_vector_set_all (ss, 1.0);
    1959  
     1319
    19601320   /* Starting point */
    19611321   par->x = gsl_vector_alloc (np);
    19621322   par->mol = this;
    1963  
     1323
    19641324   gsl_vector_set (par->x, 0, 0.0);  // offset
    19651325   gsl_vector_set (par->x, 1, 0.0);
     
    19681328   gsl_vector_set (par->x, 4, 0.0);
    19691329   gsl_vector_set (par->x, 5, 1.0);
    1970  
     1330
    19711331   /* Initialize method and iterate */
    19721332   minex_func.f = &LeastSquareDistance;
    19731333   minex_func.n = np;
    19741334   minex_func.params = (void *)par;
    1975  
     1335
    19761336   s = gsl_multimin_fminimizer_alloc (T, np);
    19771337   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1978  
     1338
    19791339   do
    19801340     {
    19811341       iter++;
    19821342       status = gsl_multimin_fminimizer_iterate(s);
    1983  
     1343
    19841344       if (status)
    19851345         break;
    1986  
     1346
    19871347       size = gsl_multimin_fminimizer_size (s);
    19881348       status = gsl_multimin_test_size (size, 1e-2);
    1989  
     1349
    19901350       if (status == GSL_SUCCESS)
    19911351         {
    19921352           printf ("converged to minimum at\n");
    19931353         }
    1994  
     1354
    19951355       printf ("%5d ", (int)iter);
    19961356       for (i = 0; i < (size_t)np; i++)
     
    20011361     }
    20021362   while (status == GSL_CONTINUE && iter < 100);
    2003  
     1363
    20041364  for (i=0;i<(size_t)np;i++)
    20051365    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     
    20181378  int ElementNo, AtomNo;
    20191379  CountElements();
    2020  
     1380
    20211381  if (out == NULL) {
    20221382    return false;
     
    20531413  int ElementNo, AtomNo;
    20541414  CountElements();
    2055  
     1415
    20561416  if (out == NULL) {
    20571417    return false;
     
    21001460  atom *Walker = start;
    21011461  while (Walker->next != end) {
    2102     Walker = Walker->next; 
     1462    Walker = Walker->next;
    21031463#ifdef ADDHYDROGEN
    21041464    if (Walker->type->Z != 1) {   // regard only non-hydrogen
     
    21311491  int No = 0;
    21321492  time_t now;
    2133  
     1493
    21341494  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21351495  walker = start;
     
    21581518{
    21591519  atom *walker = NULL;
    2160   int No = 0;
     1520  int AtomNo = 0, ElementNo;
    21611521  time_t now;
    2162  
     1522  element *runner = NULL;
     1523
    21631524  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21641525  walker = start;
    21651526  while (walker->next != end) { // go through every atom and count
    21661527    walker = walker->next;
    2167     No++;
     1528    AtomNo++;
    21681529  }
    21691530  if (out != NULL) {
    2170     *out << No << "\n\tCreated by molecuilder on " << ctime(&now);
    2171     walker = start;
    2172     while (walker->next != end) { // go through every atom of this element
    2173       walker = walker->next;
    2174       walker->OutputXYZLine(out);
     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      }
    21751546    }
    21761547    return true;
     
    22031574              Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    22041575              if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    2205                 NoNonHydrogen++; 
     1576                NoNonHydrogen++;
    22061577              Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    22071578              Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     
    22111582            }
    22121583    } else
    2213         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 
     1584        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    22141585  }
    22151586};
     
    22231594        ElementsInMolecule[i] = 0;
    22241595        ElementCount = 0;
    2225        
     1596
    22261597  atom *walker = start;
    22271598  while (walker->next != end) {
     
    22591630    Binder = Binder->next;
    22601631    if (Binder->Cyclic)
    2261       No++;   
     1632      No++;
    22621633  }
    22631634  delete(BackEdgeStack);
     
    23171688
    23181689/** Creates an adjacency list of the molecule.
     1690 * We obtain an outside file with the indices of atoms which are bondmembers.
     1691 */
     1692void 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.
    23191738 * Generally, we use the CSD approach to bond recognition, that is the the distance
    23201739 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    2321  * a threshold t = 0.4 Angstroem. 
     1740 * a threshold t = 0.4 Angstroem.
    23221741 * To make it O(N log N) the function uses the linked-cell technique as follows:
    23231742 * The procedure is step-wise:
     
    23361755void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    23371756{
     1757
    23381758  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    23391759  int No, NoBonds, CandidateBondNo;
     
    23441764  Vector x;
    23451765  int FalseBondDegree = 0;
    2346  
     1766
    23471767  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    23481768  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     
    23511771    cleanup(first,last);
    23521772  }
    2353        
     1773
    23541774  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    23551775  CountAtoms(out);
     
    23701790    for (int i=NumberCells;i--;)
    23711791      CellList[i] = NULL;
    2372  
     1792
    23731793    // 2b. put all atoms into its corresponding list
    23741794    Walker = start;
     
    23911811      if (CellList[index] == NULL)  // allocate molecule if not done
    23921812        CellList[index] = new molecule(elemente);
    2393       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 
    2394       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 
     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;
    23951815    }
    23961816    //for (int i=0;i<NumberCells;i++)
    23971817      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    2398      
     1818
     1819
    23991820    // 3a. go through every cell
    24001821    for (N[0]=divisor[0];N[0]--;)
     
    24091830              Walker = Walker->next;
    24101831              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    2411               // 3c. check for possible bond between each atom in this and every one in the 27 cells 
     1832              // 3c. check for possible bond between each atom in this and every one in the 27 cells
    24121833              for (n[0]=-1;n[0]<=1;n[0]++)
    24131834                for (n[1]=-1;n[1]<=1;n[1]++)
     
    24411862          }
    24421863        }
     1864
     1865
     1866
    24431867    // 4. free the cell again
    24441868    for (int i=NumberCells;i--;)
     
    24471871      }
    24481872    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    2449    
     1873
    24501874    // create the adjacency list per atom
    24511875    CreateListOfBondsPerAtom(out);
    2452                
     1876
    24531877    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    24541878    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     
    24991923                        *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    25001924          *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    2501                
     1925
    25021926          // output bonds for debugging (if bond chain list was correctly installed)
    25031927          *out << Verbose(1) << endl << "From contents of bond chain list:";
     
    25091933    *out << endl;
    25101934  } else
    2511         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 
     1935        *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    25121936  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    25131937  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    2514 };
     1938
     1939};
     1940
     1941
    25151942
    25161943/** Performs a Depth-First search on this molecule.
     
    25331960  bond *Binder = NULL;
    25341961  bool BackStepping = false;
    2535  
     1962
    25361963  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2537  
     1964
    25381965  ResetAllBondsToUnused();
    25391966  ResetAllAtomNumbers();
     
    25481975    LeafWalker->Leaf = new molecule(elemente);
    25491976    LeafWalker->Leaf->AddCopyAtom(Root);
    2550    
     1977
    25511978    OldGraphNr = CurrentGraphNr;
    25521979    Walker = Root;
     
    25591986          AtomStack->Push(Walker);
    25601987          CurrentGraphNr++;
    2561         }     
     1988        }
    25621989        do { // (3) if Walker has no unused egdes, go to (5)
    25631990          BackStepping = false; // reset backstepping flag for (8)
     
    25932020          Binder = NULL;
    25942021      } while (1);  // (2)
    2595      
     2022
    25962023      // 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!
    25972024      if ((Walker == Root) && (Binder == NULL))
    25982025        break;
    2599        
    2600       // (5) if Ancestor of Walker is ... 
     2026
     2027      // (5) if Ancestor of Walker is ...
    26012028      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    26022029      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     
    26412068        } while (OtherAtom != Walker);
    26422069        ComponentNumber++;
    2643    
     2070
    26442071        // (11) Root is separation vertex,  set Walker to Root and go to (4)
    26452072        Walker = Root;
     
    26542081
    26552082    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2656     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;   
     2083    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    26572084    LeafWalker->Leaf->Output(out);
    26582085    *out << endl;
     
    26622089      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    26632090      if (Root->GraphNr != -1) // if already discovered, step on
    2664         Root = Root->next; 
     2091        Root = Root->next;
    26652092    }
    26662093  }
     
    26842111    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    26852112  }
    2686  
     2113
    26872114  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    26882115  Binder = first;
     
    26952122    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    26962123    OutputComponentNumber(out, Binder->rightatom);
    2697     *out << ">." << endl; 
     2124    *out << ">." << endl;
    26982125    if (Binder->Cyclic) // cyclic ??
    26992126      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     
    27102137 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as
    27112138 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds
    2712  * as cyclic and print out the cycles. 
     2139 * as cyclic and print out the cycles.
    27132140 * \param *out output stream for debugging
    27142141 * \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!
     
    27212148  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    27222149  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2723   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring 
     2150  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
    27242151  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    27252152  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     
    27332160    ColorList[i] = white;
    27342161  }
    2735  
     2162
    27362163  *out << Verbose(1) << "Back edge list - ";
    27372164  BackEdgeStack->Output(out);
    2738  
     2165
    27392166  *out << Verbose(1) << "Analysing cycles ... " << endl;
    27402167  NumCycles = 0;
     
    27422169    BackEdge = BackEdgeStack->PopFirst();
    27432170    // this is the target
    2744     Root = BackEdge->leftatom; 
     2171    Root = BackEdge->leftatom;
    27452172    // this is the source point
    2746     Walker = BackEdge->rightatom; 
     2173    Walker = BackEdge->rightatom;
    27472174    ShortestPathList[Walker->nr] = 0;
    27482175    BFSStack->ClearStack();  // start with empty BFS stack
     
    27582185        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    27592186          OtherAtom = Binder->GetOtherAtom(Walker);
    2760 #ifdef ADDHYDROGEN         
     2187#ifdef ADDHYDROGEN
    27612188          if (OtherAtom->type->Z != 1) {
    27622189#endif
     
    27672194              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    27682195              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2769               *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 
     2196              *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;
    27702197              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    27712198                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     
    27772204            if (OtherAtom == Root)
    27782205              break;
    2779 #ifdef ADDHYDROGEN         
     2206#ifdef ADDHYDROGEN
    27802207          } else {
    27812208            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     
    28152242      }
    28162243    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2817    
     2244
    28182245    if (OtherAtom == Root) {
    28192246      // now climb back the predecessor list and thus find the cycle members
     
    28432270      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    28442271    }
    2845    
     2272
    28462273    // now clean the lists
    28472274    while (!TouchedStack->IsEmpty()){
     
    28532280  }
    28542281  if (MinRingSize != -1) {
    2855     // go over all atoms 
     2282    // go over all atoms
    28562283    Root = start;
    28572284    while(Root->next != end) {
    28582285      Root = Root->next;
    2859      
     2286
    28602287      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    28612288        Walker = Root;
     
    28942321          }
    28952322          ColorList[Walker->nr] = black;
    2896           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     2323          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    28972324        }
    2898    
     2325
    28992326        // now clean the lists
    29002327        while (!TouchedStack->IsEmpty()){
     
    29452372void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    29462373{
    2947   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 
     2374  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    29482375    *out << vertex->ComponentNr[i] << "  ";
    29492376};
     
    30232450{
    30242451  int c = 0;
    3025   int FragmentCount; 
     2452  int FragmentCount;
    30262453  // get maximum bond degree
    30272454  atom *Walker = start;
     
    30332460  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    30342461  return FragmentCount;
    3035 }; 
     2462};
    30362463
    30372464/** Scans a single line for number and puts them into \a KeySet.
    30382465 * \param *out output stream for debugging
    30392466 * \param *buffer buffer to scan
    3040  * \param &CurrentSet filled KeySet on return 
     2467 * \param &CurrentSet filled KeySet on return
    30412468 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
    30422469 */
     
    30462473  int AtomNr;
    30472474  int status = 0;
    3048  
     2475
    30492476  line.str(buffer);
    30502477  while (!line.eof()) {
     
    30822509  double TEFactor;
    30832510  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    3084  
     2511
    30852512  if (FragmentList == NULL) { // check list pointer
    30862513    FragmentList = new Graph;
    30872514  }
    3088  
     2515
    30892516  // 1st pass: open file and read
    30902517  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     
    31152542    status = false;
    31162543  }
    3117  
     2544
    31182545  // 2nd pass: open TEFactors file and read
    31192546  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     
    31272554        InputFile >> TEFactor;
    31282555        (*runner).second.second = TEFactor;
    3129         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 
     2556        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    31302557      } else {
    31312558        status = false;
     
    31682595  if(output != NULL) {
    31692596    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    3170       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 
     2597      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    31712598        if (sprinter != (*runner).first.begin())
    31722599          output << "\t";
     
    32342661    status = false;
    32352662  }
    3236  
     2663
    32372664  return status;
    32382665};
     
    32432670 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom
    32442671 * \return true - structure is equal, false - not equivalence
    3245  */ 
     2672 */
    32462673bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    32472674{
     
    32502677  bool status = true;
    32512678  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3252  
     2679
    32532680  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    32542681  File.open(filename.str().c_str(), ios::out);
     
    33092736  *out << endl;
    33102737  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3311  
     2738
    33122739  return status;
    33132740};
     
    33312758  for(int i=AtomCount;i--;)
    33322759    AtomMask[i] = false;
    3333  
     2760
    33342761  if (Order < 0) { // adaptive increase of BondOrder per site
    33352762    if (AtomMask[AtomCount] == true)  // break after one step
     
    33712798          line >> ws >> Value; // skip time entry
    33722799          line >> ws >> Value;
    3373           No -= 1;  // indices start at 1 in file, not 0 
     2800          No -= 1;  // indices start at 1 in file, not 0
    33742801          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    33752802
     
    33802807            // 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
    33812808            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    3382             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 
     2809            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    33832810            if (!InsertedElement.second) { // this root is already present
    3384               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term 
    3385                 //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) 
     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)
    33862813                {  // if value is smaller, update value and order
    33872814                (*PresentItem).second.first = fabs(Value);
     
    34212848        Walker = FindAtom(No);
    34222849        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    3423           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 
     2850          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    34242851          AtomMask[No] = true;
    34252852          status = true;
    34262853        //} else
    3427           //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl; 
     2854          //*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;
    34282855      }
    34292856      // close and done
     
    34592886    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    34602887      status = true;
    3461      
     2888
    34622889    if (!status) {
    34632890      if (Order == 0)
     
    34672894    }
    34682895  }
    3469  
     2896
    34702897  // print atom mask for debugging
    34712898  *out << "              ";
     
    34762903    *out << (AtomMask[i] ? "t" : "f");
    34772904  *out << endl;
    3478  
     2905
    34792906  return status;
    34802907};
     
    34902917  int AtomNo = 0;
    34912918  atom *Walker = NULL;
    3492  
     2919
    34932920  if (SortIndex != NULL) {
    34942921    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     
    35482975  atom **ListOfAtoms = NULL;
    35492976  atom ***ListOfLocalAtoms = NULL;
    3550   bool *AtomMask = NULL; 
    3551  
     2977  bool *AtomMask = NULL;
     2978
    35522979  *out << endl;
    35532980#ifdef ADDHYDROGEN
     
    35582985
    35592986  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3560  
     2987
    35612988  // ===== 1. Check whether bond structure is same as stored in files ====
    3562  
     2989
    35632990  // fill the adjacency list
    35642991  CreateListOfBondsPerAtom(out);
     
    35662993  // create lookup table for Atom::nr
    35672994  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3568  
     2995
    35692996  // === compare it with adjacency file ===
    3570   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 
     2997  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    35712998  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    35722999
     
    35823009  while (MolecularWalker->next != NULL) {
    35833010    MolecularWalker = MolecularWalker->next;
    3584     *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35853011    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    35863012//    // check the list of local atoms for debugging
     
    35913017//      else
    35923018//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3019    *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35933020    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3021    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35943022    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3023    *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35953024    delete(LocalBackEdgeStack);
    35963025  }
    3597  
     3026
    35983027  // ===== 3. if structure still valid, parse key set file and others =====
    35993028  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     
    36013030  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    36023031  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3603  
    3604   // =================================== Begin of FRAGMENTATION =============================== 
    3605   // ===== 6a. assign each keyset to its respective subgraph ===== 
     3032
     3033  // =================================== Begin of FRAGMENTATION ===============================
     3034  // ===== 6a. assign each keyset to its respective subgraph =====
    36063035  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    36073036
     
    36143043    FragmentationToDo = FragmentationToDo || CheckOrder;
    36153044    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3616     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 
     3045    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    36173046    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    36183047
     
    36233052      MolecularWalker = MolecularWalker->next;
    36243053      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3625       // output ListOfBondsPerAtom for debugging
    3626       MolecularWalker->Leaf->OutputListOfBonds(out);
     3054      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
    36273055      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3628      
    36293056        // call BOSSANOVA method
    36303057        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     
    36403067  delete(ParsedFragmentList);
    36413068  delete[](MinimumRingSize);
    3642  
     3069
    36433070
    36443071  // ==================================== End of FRAGMENTATION ============================================
     
    36463073  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    36473074  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3648  
     3075
    36493076  // free subgraph memory again
    36503077  FragmentCounter = 0;
     
    36713098    }
    36723099    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3673    
     3100
    36743101    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    36753102    if (BondFragments->NumberOfMolecules != 0) {
    36763103      // create the SortIndex from BFS labels to order in the config file
    36773104      CreateMappingLabelsToConfigSequence(out, SortIndex);
    3678      
     3105
    36793106      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    3680       if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true))
     3107      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    36813108        *out << Verbose(1) << "All configs written." << endl;
    36823109      else
    36833110        *out << Verbose(1) << "Some config writing failed." << endl;
    3684  
     3111
    36853112      // store force index reference file
    36863113      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3687      
    3688       // store keysets file 
     3114
     3115      // store keysets file
    36893116      StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3690  
    3691       // store Adjacency file 
     3117
     3118      // store Adjacency file
    36923119      StoreAdjacencyToFile(out, configuration->configpath);
    3693  
     3120
    36943121      // store Hydrogen saturation correction file
    36953122      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3696      
     3123
    36973124      // store adaptive orders into file
    36983125      StoreOrderAtSiteFile(out, configuration->configpath);
    3699      
     3126
    37003127      // restore orbital and Stop values
    37013128      CalculateOrbitals(*configuration);
    3702      
     3129
    37033130      // free memory for bond part
    37043131      *out << Verbose(1) << "Freeing bond memory" << endl;
    37053132      delete(FragmentList); // remove bond molecule from memory
    3706       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 
     3133      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    37073134    } else
    37083135      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3709   //} else 
     3136  //} else
    37103137  //  *out << Verbose(1) << "No fragments to store." << endl;
    37113138  *out << Verbose(0) << "End of bond fragmentation." << endl;
     
    37333160  atom *Walker = NULL, *OtherAtom = NULL;
    37343161  ReferenceStack->Push(Binder);
    3735  
     3162
    37363163  do {  // go through all bonds and push local ones
    37373164    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3738     if (Walker == NULL) // if this Walker exists in the subgraph ...
    3739       continue;
    3740     for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3741       OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3742       if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3743         LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3744         break;
    3745       }
    3746     }
     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        }
    37473174    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3175                *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    37483176    ReferenceStack->Push(Binder);
    37493177  } while (FirstBond != Binder);
    3750  
     3178
    37513179  return status;
    37523180};
     
    38243252      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    38253253      Walker->MaxOrder = MaxArray[Walker->nr];
    3826       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 
     3254      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    38273255    }
    38283256    file.close();
     
    38353263  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    38363264  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3837  
     3265
    38383266  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    38393267  return status;
     
    38933321  Walker = start;
    38943322  while (Walker->next != end) {
    3895     Walker = Walker->next; 
     3323    Walker = Walker->next;
    38963324    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    38973325    TotalDegree = 0;
     
    39013329    }
    39023330    *out << " -- TotalDegree: " << TotalDegree << endl;
    3903   }     
     3331  }
    39043332  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    39053333};
     
    39073335/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
    39083336 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was
    3909  * white and putting into queue. 
     3337 * white and putting into queue.
    39103338 * \param *out output stream for debugging
    39113339 * \param *Mol Molecule class to add atoms to
     
    39163344 * \param BondOrder maximum distance for vertices to add
    39173345 * \param IsAngstroem lengths are in angstroem or bohrradii
    3918  */ 
     3346 */
    39193347void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    39203348{
     
    39423370  }
    39433371  ShortestPathList[Root->nr] = 0;
    3944  
     3372
    39453373  // and go on ... Queue always contains all lightgray vertices
    39463374  while (!AtomStack->IsEmpty()) {
     
    39503378    // followed by n+1 till top of stack.
    39513379    Walker = AtomStack->PopFirst(); // pop oldest added
    3952     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 
     3380    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    39533381    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    39543382      Binder = ListOfBondsPerAtom[Walker->nr][i];
     
    39573385        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    39583386        if (ColorList[OtherAtom->nr] == white) {
    3959           if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 
     3387          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)
    39603388            ColorList[OtherAtom->nr] = lightgray;
    39613389          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    39623390          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3963           *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 
     3391          *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;
    39643392          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    39653393            *out << Verbose(3);
     
    39993427              } else {
    40003428#ifdef ADDHYDROGEN
    4001                 Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
     3429                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3430                  exit(1);
    40023431#endif
    40033432              }
     
    40083437          // This has to be a cyclic bond, check whether it's present ...
    40093438          if (AddedBondList[Binder->nr] == NULL) {
    4010             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 
     3439            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    40113440              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    40123441              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     
    40143443            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    40153444#ifdef ADDHYDROGEN
    4016               Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
     3445              if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3446                exit(1);
    40173447#endif
    40183448            }
     
    40223452    }
    40233453    ColorList[Walker->nr] = black;
    4024     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     3454    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    40253455  }
    40263456  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     
    40463476
    40473477  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    4048  
     3478
    40493479  // reset parent list
    40503480  *out << Verbose(3) << "Resetting ParentList." << endl;
    40513481  for (int i=Father->AtomCount;i--;)
    40523482    ParentList[i] = NULL;
    4053  
     3483
    40543484  // fill parent list with sons
    40553485  *out << Verbose(3) << "Filling Parent List." << endl;
     
    40923522 * \param *&Leaf KeySet to look through
    40933523 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end
    4094  * \param index of the atom suggested for removal 
     3524 * \param index of the atom suggested for removal
    40953525 */
    40963526int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
     
    40983528  atom *Runner = NULL;
    40993529  int SP, Removal;
    4100  
     3530
    41013531  *out << Verbose(2) << "Looking for removal candidate." << endl;
    41023532  SP = -1; //0;  // not -1, so that Root is never removed
     
    41163546/** Stores a fragment from \a KeySet into \a molecule.
    41173547 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
    4118  * molecule and adds missing hydrogen where bonds were cut. 
     3548 * molecule and adds missing hydrogen where bonds were cut.
    41193549 * \param *out output stream for debugging messages
    4120  * \param &Leaflet pointer to KeySet structure 
     3550 * \param &Leaflet pointer to KeySet structure
    41213551 * \param IsAngstroem whether we have Ansgtroem or bohrradius
    41223552 * \return pointer to constructed molecule
     
    41293559  bool LonelyFlag = false;
    41303560  int size;
    4131  
     3561
    41323562//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    4133  
     3563
    41343564  Leaf->BondDistance = BondDistance;
    41353565  for(int i=NDIM*2;i--;)
    4136     Leaf->cell_size[i] = cell_size[i]; 
     3566    Leaf->cell_size[i] = cell_size[i];
    41373567
    41383568  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     
    41473577    size++;
    41483578  }
    4149  
     3579
    41503580  // create the bonds between all: Make it an induced subgraph and add hydrogen
    41513581//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     
    41573587    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    41583588      // create all bonds
    4159       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 
     3589      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    41603590        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    41613591//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    41623592        if (SonList[OtherFather->nr] != NULL) {
    4163 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 
     3593//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    41643594          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    41653595//            *out << Verbose(3) << "Adding Bond: ";
    4166 //            *out << 
     3596//            *out <<
    41673597            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    41683598//            *out << "." << endl;
    41693599            //NumBonds[Runner->nr]++;
    4170           } else { 
     3600          } else {
    41713601//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    41723602          }
    41733603          LonelyFlag = false;
    41743604        } else {
    4175 //          *out << ", who has no son in this fragment molecule." << endl; 
     3605//          *out << ", who has no son in this fragment molecule." << endl;
    41763606#ifdef ADDHYDROGEN
    41773607          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    4178           Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem);
     3608          if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     3609            exit(1);
    41793610#endif
    41803611          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     
    41903621    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    41913622      Runner = Runner->next;
    4192 #endif       
     3623#endif
    41933624  }
    41943625  Leaf->CreateListOfBondsPerAtom(out);
     
    42233654  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    42243655  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!
    4225   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 
     3656  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
    42263657  MoleculeListClass *FragmentList = NULL;
    42273658  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     
    42733704                // clear snake stack
    42743705          SnakeStack->ClearStack();
    4275     //SnakeStack->TestImplementation(out, start->next);   
     3706    //SnakeStack->TestImplementation(out, start->next);
    42763707
    42773708    ///// INNER LOOP ////////////
     
    42943725        }
    42953726        if (ShortestPathList[Walker->nr] == -1) {
    4296           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 
     3727          ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
    42973728          TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    42983729        }
     
    43323763                                OtherAtom = Binder->GetOtherAtom(Walker);
    43333764            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    4334               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 
     3765              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    43353766              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    43363767            } else { // otherwise check its colour and element
    43373768                                if (
    43383769#ifdef ADDHYDROGEN
    4339               (OtherAtom->type->Z != 1) && 
     3770              (OtherAtom->type->Z != 1) &&
    43403771#endif
    43413772                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     
    43473778                //} else {
    43483779                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    4349                 //} 
     3780                //}
    43503781                Walker = OtherAtom;
    43513782                break;
    43523783              } else {
    4353                 if (OtherAtom->type->Z == 1) 
     3784                if (OtherAtom->type->Z == 1)
    43543785                  *out << "Links to a hydrogen atom." << endl;
    4355                 else                 
     3786                else
    43563787                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    43573788              }
     
    43633794          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    43643795        }
    4365                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black 
     3796                        if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
    43663797          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    43673798                                ColorVertexList[Walker->nr] = black;
     
    43703801      }
    43713802        } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    4372     *out << Verbose(2) << "Inner Looping is finished." << endl;   
     3803    *out << Verbose(2) << "Inner Looping is finished." << endl;
    43733804
    43743805    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     
    43863817    }
    43873818  }
    4388   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 
     3819  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
    43893820
    43903821  // copy together
    4391   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 
     3822  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
    43923823  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    43933824  RunningIndex = 0;
     
    44603891
    44613892  NumCombinations = 1 << SetDimension;
    4462  
     3893
    44633894  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    44643895  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    44653896  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    4466  
     3897
    44673898  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    44683899  *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;
    44693900
    4470   // initialised touched list (stores added atoms on this level) 
     3901  // initialised touched list (stores added atoms on this level)
    44713902  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    44723903  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    44733904    TouchedList[TouchedIndex] = -1;
    44743905  TouchedIndex = 0;
    4475  
     3906
    44763907  // create every possible combination of the endpieces
    44773908  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     
    44813912    for (int j=SetDimension;j--;)
    44823913      bits += (i & (1 << j)) >> j;
    4483      
     3914
    44843915    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    44853916    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     
    44893920        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    44903921        if (bit) {  // if bit is set, we add this bond partner
    4491                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add 
     3922                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    44923923          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    44933924          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    4494           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 
     3925          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    44953926          if (TestKeySetInsert.second) {
    44963927            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     
    45053936        }
    45063937      }
    4507      
    4508       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 
     3938
     3939      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    45093940      if (SpaceLeft > 0) {
    45103941        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     
    45343965          }
    45353966          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    4536           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 
     3967          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    45373968          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    45383969        }
     
    45433974        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    45443975        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4545           *out << (*runner) << " "; 
     3976          *out << (*runner) << " ";
    45463977        *out << endl;
    45473978        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     
    45513982        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    45523983      }
    4553      
     3984
    45543985      // --3-- remove all added items in this level from snake stack
    45553986      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     
    45623993      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    45633994      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4564         *out << (*runner) << " "; 
     3995        *out << (*runner) << " ";
    45653996      *out << endl;
    45663997      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     
    45694000    }
    45704001  }
    4571   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 
     4002  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    45724003  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    45734004};
     
    45784009 * \return true - connected, false - disconnected
    45794010 * \note this is O(n^2) for it's just a bug checker not meant for permanent use!
    4580  */ 
     4011 */
    45814012bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    45824013{
     
    45844015  bool BondStatus = false;
    45854016  int size;
    4586  
     4017
    45874018  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    45884019  *out << Verbose(2) << "Disconnected atom: ";
    4589  
     4020
    45904021  // count number of atoms in graph
    45914022  size = 0;
     
    46334064 * \param *out output stream for debugging
    46344065 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation
    4635  * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 
     4066 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on
    46364067 * \param RestrictedKeySet Restricted vertex set to use in context of molecule
    46374068 * \return number of inserted fragments
    46384069 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore
    46394070 */
    4640 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 
     4071int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    46414072{
    46424073  int SP, AtomKeyNr;
     
    46594090    FragmentSearch.BondsPerSPCount[i] = 0;
    46604091  FragmentSearch.BondsPerSPCount[0] = 1;
    4661   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 
     4092  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    46624093  add(Binder, FragmentSearch.BondsPerSPList[1]);
    4663  
     4094
    46644095  // do a BFS search to fill the SP lists and label the found vertices
    46654096  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    46664097  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    46674098  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4668   // (EdgeinSPLevel) of this tree ... 
     4099  // (EdgeinSPLevel) of this tree ...
    46694100  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    46704101  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     
    47194150    }
    47204151  }
    4721  
     4152
    47224153  // outputting all list for debugging
    47234154  *out << Verbose(0) << "Printing all found lists." << endl;
     
    47284159      Binder = Binder->next;
    47294160      *out << Verbose(2) << *Binder << endl;
    4730     } 
    4731   }
    4732  
     4161    }
     4162  }
     4163
    47334164  // creating fragments with the found edge sets  (may be done in reverse order, faster)
    47344165  SP = -1;  // the Root <-> Root edge must be subtracted!
     
    47374168    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    47384169      Binder = Binder->next;
    4739       SP ++; 
     4170      SP ++;
    47404171    }
    47414172  }
     
    47444175    // start with root (push on fragment stack)
    47454176    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4746     FragmentSearch.FragmentSet->clear(); 
     4177    FragmentSearch.FragmentSet->clear();
    47474178    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    47484179    // prepare the subset and call the generator
    47494180    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    47504181    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4751    
     4182
    47524183    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4753    
     4184
    47544185    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    47554186  } else {
     
    47604191  // remove root from stack
    47614192  *out << Verbose(0) << "Removing root again from stack." << endl;
    4762   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);   
     4193  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    47634194
    47644195  // free'ing the bonds lists
     
    47794210  }
    47804211
    4781   // return list 
     4212  // return list
    47824213  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    47834214  return (FragmentSearch.FragmentCounter - Counter);
     
    48104241    // remove bonds that are beyond bonddistance
    48114242    for(int i=NDIM;i--;)
    4812       Translationvector.x[i] = 0.; 
     4243      Translationvector.x[i] = 0.;
    48134244    // scan all bonds
    48144245    Binder = first;
     
    48574288        }
    48584289      }
    4859       // re-add bond   
     4290      // re-add bond
    48604291      link(Binder, OtherBinder);
    48614292    } else {
     
    49114342        IteratorB++;
    49124343      } // end of while loop
    4913     }// end of check in case of equal sizes 
     4344    }// end of check in case of equal sizes
    49144345  }
    49154346  return false; // if we reach this point, they are equal
     
    49554386 * \param graph1 first (dest) graph
    49564387 * \param graph2 second (source) graph
    4957  * \param *counter keyset counter that gets increased 
     4388 * \param *counter keyset counter that gets increased
    49584389 */
    49594390inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
     
    50004431  int RootKeyNr, RootNr;
    50014432  struct UniqueFragments FragmentSearch;
    5002  
     4433
    50034434  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    50044435
     
    50234454    Walker = Walker->next;
    50244455    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    5025   } 
     4456  }
    50264457
    50274458  // 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
     
    50374468    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    50384469    //  *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;
    5039     //} else 
     4470    //} else
    50404471    {
    50414472      // increase adaptive order by one
    50424473      Walker->GetTrueFather()->AdaptiveOrder++;
    50434474      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    5044  
     4475
    50454476      // initialise Order-dependent entries of UniqueFragments structure
    50464477      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     
    50494480        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    50504481        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    5051         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two 
     4482        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two
    50524483        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    50534484        FragmentSearch.BondsPerSPCount[i] = 0;
    5054       } 
    5055  
     4485      }
     4486
    50564487      // allocate memory for all lower level orders in this 1D-array of ptrs
    50574488      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     
    50594490      for (int i=0;i<NumLevels;i++)
    50604491        FragmentLowerOrdersList[RootNr][i] = NULL;
    5061      
     4492
    50624493      // create top order where nothing is reduced
    50634494      *out << Verbose(0) << "==============================================================================================================" << endl;
    50644495      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    5065  
     4496
    50664497      // Create list of Graphs of current Bond Order (i.e. F_{ij})
    50674498      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     
    50764507        // we don't have to dive into suborders! These keysets are all already created on lower orders!
    50774508        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    5078        
     4509
    50794510//        if ((NumLevels >> 1) > 0) {
    50804511//          // create lower order fragments
     
    50834514//          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)
    50844515//            // step down to next order at (virtual) boundary of powers of 2 in array
    5085 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
     4516//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    50864517//              Order--;
    50874518//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     
    50904521//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    50914522//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    5092 //       
     4523//
    50934524//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    50944525//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     
    51214552      RootStack.push_back(RootKeyNr); // put back on stack
    51224553      RootNr++;
    5123  
     4554
    51244555      // free Order-dependent entries of UniqueFragments structure for next loop cycle
    51254556      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     
    51274558        delete(FragmentSearch.BondsPerSPList[2*i]);
    51284559        delete(FragmentSearch.BondsPerSPList[2*i+1]);
    5129       } 
     4560      }
    51304561      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    51314562    }
     
    51384569  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    51394570  delete(FragmentSearch.FragmentSet);
    5140  
    5141   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 
     4571
     4572  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    51424573  // 5433222211111111
    51434574  // 43221111
     
    51594590    RootKeyNr = RootStack.front();
    51604591    RootStack.pop_front();
    5161     Walker = FindAtom(RootKeyNr); 
     4592    Walker = FindAtom(RootKeyNr);
    51624593    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    51634594    for(int i=0;i<NumLevels;i++) {
     
    51724603  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    51734604  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    5174  
     4605
    51754606  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    51764607};
     
    52064637  atom *Walker = NULL;
    52074638  bool result = true; // status of comparison
    5208  
    5209   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 
     4639
     4640  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    52104641  /// first count both their atoms and elements and update lists thereby ...
    52114642  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     
    52544685    if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    52554686      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    5256       result = false; 
    5257     }
    5258   }
    5259  
     4687      result = false;
     4688    }
     4689  }
     4690
    52604691  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    52614692  if (result) {
     
    52734704      OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    52744705    }
    5275  
     4706
    52764707    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    52774708    *out << Verbose(5) << "Sorting distances" << endl;
     
    52844715    for(int i=AtomCount;i--;)
    52854716      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    5286    
     4717
    52874718    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    52884719    *out << Verbose(4) << "Comparing distances" << endl;
     
    52954726    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    52964727    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    5297      
     4728
    52984729    /// free memory
    52994730    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     
    53034734      result = false;
    53044735    }
    5305   } 
     4736  }
    53064737  /// return pointer to map if all distances were below \a threshold
    53074738  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     
    53124743    *out << Verbose(3) << "Result: Not equal." << endl;
    53134744    return NULL;
    5314   } 
     4745  }
    53154746};
    53164747
     
    53674798 * \param *output output stream of temperature file
    53684799 * \return file written (true), failure on writing file (false)
    5369  */ 
     4800 */
    53704801bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    53714802{
     
    53754806  if (output == NULL)
    53764807    return false;
    5377   else 
     4808  else
    53784809    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    53794810  for (int step=startstep;step < endstep; step++) { // loop over all time steps
Note: See TracChangeset for help on using the changeset viewer.