Changes in / [06c7a3:7326b2]


Ignore:
Files:
25 added
1 deleted
52 edited

Legend:

Unmodified
Added
Removed
  • configure.ac

    r06c7a3 r7326b2  
    2727
    2828# Boost libraries
    29 AX_BOOST_BASE([1.33.1])
    30 AX_BOOST_PROGRAM_OPTIONS
     29#AX_BOOST_BASE([1.33.1])
     30#AX_BOOST_PROGRAM_OPTIONS
    3131#AX_BOOST_FOREACH
    3232#AX_BOOST_FILESYSTEM
  • src/Makefile.am

    r06c7a3 r7326b2  
    1 SOURCE = analysis_correlation.cpp atom.cpp bond.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp
    2 HEADER = analysis_correlation.hpp atom.hpp bond.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp
     1ATOMSOURCE = atom.cpp atom_atominfo.cpp atom_bondedparticle.cpp atom_bondedparticleinfo.cpp atom_graphnode.cpp atom_graphnodeinfo.cpp atom_particleinfo.cpp atom_trajectoryparticle.cpp atom_trajectoryparticleinfo.cpp
     2ATOMHEADER = atom.hpp atom_atominfo.hpp atom_bondedparticle.hpp atom_bondedparticleinfo.hpp atom_graphnode.hpp atom_graphnodeinfo.hpp atom_particleinfo.hpp atom_trajectoryparticle.hpp atom_trajectoryparticleinfo.hpp
     3
     4SOURCE = analysis_correlation.cpp ${ATOMSOURCE} bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorLogger.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp
     5HEADER = analysis_correlation.hpp ${ATOMHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorLogger.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp
    36
    47BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB)
  • src/analysis_correlation.cpp

    r06c7a3 r7326b2  
    1414#include "tesselationhelpers.hpp"
    1515#include "vector.hpp"
     16#include "verbose.hpp"
    1617
    1718
     
    1920 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
    2021 * \param *out output stream for debugging
    21  * \param *mol molecule with atoms
     22 * \param *molecules list of molecules structure
    2223 * \param *type1 first element or NULL (if any element)
    2324 * \param *type2 second element or NULL (if any element)
    2425 * \return Map of doubles with values the pair of the two atoms.
    2526 */
    26 PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 )
     27PairCorrelationMap *PairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2 )
    2728{
    2829  PairCorrelationMap *outmap = NULL;
    2930  double distance = 0.;
    3031
    31   if ((mol == NULL)) {
    32     cout << "No molecule given." << endl;
     32  if (molecules->ListOfMolecules.empty()) {
     33    cerr << Verbose(1) <<"No molecule given." << endl;
    3334    return outmap;
    3435  }
    3536  outmap = new PairCorrelationMap;
    36   atom *Walker = mol->start;
    37   while (Walker->next != mol->end) {
    38     Walker = Walker->next;
    39     if ((type1 == NULL) || (Walker->type == type1)) {
    40       atom *OtherWalker = mol->start;
    41       while (OtherWalker->next != mol->end) { // only go up to Walker
    42         OtherWalker = OtherWalker->next;
    43         if (Walker->nr < OtherWalker->nr)
    44           if ((type2 == NULL) || (OtherWalker->type == type2)) {
    45             distance = Walker->node->Distance(OtherWalker->node);
    46             //cout << "Inserting " << *Walker << " and " << *OtherWalker << endl;
    47             outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) );
     37  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     38    if ((*MolWalker)->ActiveFlag) {
     39      cerr << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     40      atom *Walker = (*MolWalker)->start;
     41      while (Walker->next != (*MolWalker)->end) {
     42        Walker = Walker->next;
     43        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     44        if ((type1 == NULL) || (Walker->type == type1)) {
     45          for (MoleculeList::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules->ListOfMolecules.end(); MolOtherWalker++)
     46            if ((*MolOtherWalker)->ActiveFlag) {
     47              *out << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl;
     48              atom *OtherWalker = (*MolOtherWalker)->start;
     49              while (OtherWalker->next != (*MolOtherWalker)->end) { // only go up to Walker
     50                OtherWalker = OtherWalker->next;
     51                *out << Verbose(3) << "Current otheratom is " << *OtherWalker << "." << endl;
     52                if (Walker->nr < OtherWalker->nr)
     53                  if ((type2 == NULL) || (OtherWalker->type == type2)) {
     54                    distance = Walker->node->PeriodicDistance(OtherWalker->node, (*MolWalker)->cell_size);
     55                    //*out << Verbose(1) <<"Inserting " << *Walker << " and " << *OtherWalker << endl;
     56                    outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) );
     57                  }
     58              }
    4859          }
    49       }
    50     }
    51   }
     60        }
     61      }
     62    }
     63
     64  return outmap;
     65};
     66
     67/** Calculates the pair correlation between given elements.
     68 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
     69 * \param *out output stream for debugging
     70 * \param *molecules list of molecules structure
     71 * \param *type1 first element or NULL (if any element)
     72 * \param *type2 second element or NULL (if any element)
     73 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
     74 * \return Map of doubles with values the pair of the two atoms.
     75 */
     76PairCorrelationMap *PeriodicPairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2, const int ranges[NDIM] )
     77{
     78  PairCorrelationMap *outmap = NULL;
     79  double distance = 0.;
     80  int n[NDIM];
     81  Vector checkX;
     82  Vector periodicX;
     83  int Othern[NDIM];
     84  Vector checkOtherX;
     85  Vector periodicOtherX;
     86
     87  if (molecules->ListOfMolecules.empty()) {
     88    cerr << Verbose(1) <<"No molecule given." << endl;
     89    return outmap;
     90  }
     91  outmap = new PairCorrelationMap;
     92  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     93    if ((*MolWalker)->ActiveFlag) {
     94      const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size);
     95      const double * const FullInverseMatrix = InverseMatrix(FullMatrix);
     96      cerr << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     97      atom *Walker = (*MolWalker)->start;
     98      while (Walker->next != (*MolWalker)->end) {
     99        Walker = Walker->next;
     100        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     101        if ((type1 == NULL) || (Walker->type == type1)) {
     102          periodicX.CopyVector(Walker->node);
     103          periodicX.MatrixMultiplication(FullInverseMatrix);  // x now in [0,1)^3
     104          // go through every range in xyz and get distance
     105          for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
     106            for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
     107              for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
     108                checkX.Init(n[0], n[1], n[2]);
     109                checkX.AddVector(&periodicX);
     110                checkX.MatrixMultiplication(FullMatrix);
     111                for (MoleculeList::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules->ListOfMolecules.end(); MolOtherWalker++)
     112                  if ((*MolOtherWalker)->ActiveFlag) {
     113                    *out << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl;
     114                    atom *OtherWalker = (*MolOtherWalker)->start;
     115                    while (OtherWalker->next != (*MolOtherWalker)->end) { // only go up to Walker
     116                      OtherWalker = OtherWalker->next;
     117                      *out << Verbose(3) << "Current otheratom is " << *OtherWalker << "." << endl;
     118                      if (Walker->nr < OtherWalker->nr)
     119                        if ((type2 == NULL) || (OtherWalker->type == type2)) {
     120                          periodicOtherX.CopyVector(OtherWalker->node);
     121                          periodicOtherX.MatrixMultiplication(FullInverseMatrix);  // x now in [0,1)^3
     122                          // go through every range in xyz and get distance
     123                          for (Othern[0]=-ranges[0]; Othern[0] <= ranges[0]; Othern[0]++)
     124                            for (Othern[1]=-ranges[1]; Othern[1] <= ranges[1]; Othern[1]++)
     125                              for (Othern[2]=-ranges[2]; Othern[2] <= ranges[2]; Othern[2]++) {
     126                                checkOtherX.Init(Othern[0], Othern[1], Othern[2]);
     127                                checkOtherX.AddVector(&periodicOtherX);
     128                                checkOtherX.MatrixMultiplication(FullMatrix);
     129                                distance = checkX.Distance(&checkOtherX);
     130                                //*out << Verbose(1) <<"Inserting " << *Walker << " and " << *OtherWalker << endl;
     131                                outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) );
     132                              }
     133                        }
     134                  }
     135              }
     136            }
     137        }
     138      }
     139    }
    52140
    53141  return outmap;
     
    56144/** Calculates the distance (pair) correlation between a given element and a point.
    57145 * \param *out output stream for debugging
    58  * \param *mol molecule with atoms
     146 * \param *molecules list of molecules structure
    59147 * \param *type element or NULL (if any element)
    60148 * \param *point vector to the correlation point
    61149 * \return Map of dobules with values as pairs of atom and the vector
    62150 */
    63 CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point )
     151CorrelationToPointMap *CorrelationToPoint(  ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point )
    64152{
    65153  CorrelationToPointMap *outmap = NULL;
    66154  double distance = 0.;
    67155
    68   if ((mol == NULL)) {
    69     cout << "No molecule given." << endl;
     156  if (molecules->ListOfMolecules.empty()) {
     157    *out << Verbose(1) <<"No molecule given." << endl;
    70158    return outmap;
    71159  }
    72160  outmap = new CorrelationToPointMap;
    73   atom *Walker = mol->start;
    74   while (Walker->next != mol->end) {
    75     Walker = Walker->next;
    76     if ((type == NULL) || (Walker->type == type)) {
    77       distance = Walker->node->Distance(point);
    78       outmap->insert ( pair<double, pair<atom *, Vector*> >(distance, pair<atom *, Vector*> (Walker, point) ) );
    79     }
    80   }
     161  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     162    if ((*MolWalker)->ActiveFlag) {
     163      *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     164      atom *Walker = (*MolWalker)->start;
     165      while (Walker->next != (*MolWalker)->end) {
     166        Walker = Walker->next;
     167        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     168        if ((type == NULL) || (Walker->type == type)) {
     169          distance = Walker->node->PeriodicDistance(point, (*MolWalker)->cell_size);
     170          *out << Verbose(4) << "Current distance is " << distance << "." << endl;
     171          outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> (Walker, point) ) );
     172        }
     173      }
     174    }
     175
     176  return outmap;
     177};
     178
     179/** Calculates the distance (pair) correlation between a given element, all its periodic images and a point.
     180 * \param *out output stream for debugging
     181 * \param *molecules list of molecules structure
     182 * \param *type element or NULL (if any element)
     183 * \param *point vector to the correlation point
     184 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
     185 * \return Map of dobules with values as pairs of atom and the vector
     186 */
     187CorrelationToPointMap *PeriodicCorrelationToPoint(  ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point, const int ranges[NDIM] )
     188{
     189  CorrelationToPointMap *outmap = NULL;
     190  double distance = 0.;
     191  int n[NDIM];
     192  Vector periodicX;
     193  Vector checkX;
     194
     195  if (molecules->ListOfMolecules.empty()) {
     196    *out << Verbose(1) <<"No molecule given." << endl;
     197    return outmap;
     198  }
     199  outmap = new CorrelationToPointMap;
     200  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     201    if ((*MolWalker)->ActiveFlag) {
     202      const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size);
     203      const double * const FullInverseMatrix = InverseMatrix(FullMatrix);
     204      *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     205      atom *Walker = (*MolWalker)->start;
     206      while (Walker->next != (*MolWalker)->end) {
     207        Walker = Walker->next;
     208        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     209        if ((type == NULL) || (Walker->type == type)) {
     210          periodicX.CopyVector(Walker->node);
     211          periodicX.MatrixMultiplication(FullInverseMatrix);  // x now in [0,1)^3
     212          // go through every range in xyz and get distance
     213          for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
     214            for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
     215              for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
     216                checkX.Init(n[0], n[1], n[2]);
     217                checkX.AddVector(&periodicX);
     218                checkX.MatrixMultiplication(FullMatrix);
     219                distance = checkX.Distance(point);
     220                *out << Verbose(4) << "Current distance is " << distance << "." << endl;
     221                outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> (Walker, point) ) );
     222              }
     223        }
     224      }
     225    }
    81226
    82227  return outmap;
     
    85230/** Calculates the distance (pair) correlation between a given element and a surface.
    86231 * \param *out output stream for debugging
    87  * \param *mol molecule with atoms
     232 * \param *molecules list of molecules structure
    88233 * \param *type element or NULL (if any element)
    89234 * \param *Surface pointer to Tesselation class surface
     
    91236 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
    92237 */
    93 CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC )
    94 {
    95 
     238CorrelationToSurfaceMap *CorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC )
     239{
    96240  CorrelationToSurfaceMap *outmap = NULL;
    97   double distance = 0.;
     241  double distance = 0;
    98242  class BoundaryTriangleSet *triangle = NULL;
    99243  Vector centroid;
    100244
    101   if ((Surface == NULL) || (LC == NULL) || (mol == NULL)) {
    102     cout << "No Tesselation, no LinkedCell or no molecule given." << endl;
     245  if ((Surface == NULL) || (LC == NULL) || (molecules->ListOfMolecules.empty())) {
     246    *out << Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl;
    103247    return outmap;
    104248  }
    105249  outmap = new CorrelationToSurfaceMap;
    106   atom *Walker = mol->start;
    107   while (Walker->next != mol->end) {
    108     Walker = Walker->next;
    109     if ((type == NULL) || (Walker->type == type)) {
    110       triangle = Surface->FindClosestTriangleToPoint(out, Walker->node, LC );
    111       if (triangle != NULL) {
    112         distance = DistanceToTrianglePlane(out, Walker->node, triangle);
    113         outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) );
    114       }
    115     }
    116   }
     250  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     251    if ((*MolWalker)->ActiveFlag) {
     252      *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     253      atom *Walker = (*MolWalker)->start;
     254      while (Walker->next != (*MolWalker)->end) {
     255        Walker = Walker->next;
     256        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     257        if ((type == NULL) || (Walker->type == type)) {
     258          triangle = Surface->FindClosestTriangleToPoint(out, Walker->node, LC );
     259          if (triangle != NULL) {
     260            distance = DistanceToTrianglePlane(out, Walker->node, triangle);
     261            outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) );
     262          }
     263        }
     264      }
     265    }
     266
     267  return outmap;
     268};
     269
     270/** Calculates the distance (pair) correlation between a given element, all its periodic images and and a surface.
     271 * Note that we also put all periodic images found in the cells given by [ -ranges[i], ranges[i] ] and i=0,...,NDIM-1.
     272 * I.e. We multiply the atom::node with the inverse of the domain matrix, i.e. transform it to \f$[0,0^3\f$, then add per
     273 * axis an integer from [ -ranges[i], ranges[i] ] onto it and multiply with the domain matrix to bring it back into
     274 * the real space. Then, we Tesselation::FindClosestTriangleToPoint() and DistanceToTrianglePlane().
     275 * \param *out output stream for debugging
     276 * \param *molecules list of molecules structure
     277 * \param *type element or NULL (if any element)
     278 * \param *Surface pointer to Tesselation class surface
     279 * \param *LC LinkedCell structure to quickly find neighbouring atoms
     280 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
     281 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
     282 */
     283CorrelationToSurfaceMap *PeriodicCorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC, const int ranges[NDIM] )
     284{
     285  CorrelationToSurfaceMap *outmap = NULL;
     286  double distance = 0;
     287  class BoundaryTriangleSet *triangle = NULL;
     288  Vector centroid;
     289  int n[NDIM];
     290  Vector periodicX;
     291  Vector checkX;
     292
     293  if ((Surface == NULL) || (LC == NULL) || (molecules->ListOfMolecules.empty())) {
     294    *out << Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl;
     295    return outmap;
     296  }
     297  outmap = new CorrelationToSurfaceMap;
     298  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++)
     299    if ((*MolWalker)->ActiveFlag) {
     300      const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size);
     301      const double * const FullInverseMatrix = InverseMatrix(FullMatrix);
     302      *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl;
     303      atom *Walker = (*MolWalker)->start;
     304      while (Walker->next != (*MolWalker)->end) {
     305        Walker = Walker->next;
     306        *out << Verbose(3) << "Current atom is " << *Walker << "." << endl;
     307        if ((type == NULL) || (Walker->type == type)) {
     308          periodicX.CopyVector(Walker->node);
     309          periodicX.MatrixMultiplication(FullInverseMatrix);  // x now in [0,1)^3
     310          // go through every range in xyz and get distance
     311          for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
     312            for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
     313              for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
     314                checkX.Init(n[0], n[1], n[2]);
     315                checkX.AddVector(&periodicX);
     316                checkX.MatrixMultiplication(FullMatrix);
     317                triangle = Surface->FindClosestTriangleToPoint(out, &checkX, LC );
     318                if (triangle != NULL) {
     319                  distance = DistanceToTrianglePlane(out, &checkX, triangle);
     320                  outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) );
     321                }
     322          }
     323        }
     324      }
     325    }
    117326
    118327  return outmap;
     
    124333 * \param BinStart first bin
    125334 */
    126 double GetBin ( double value, double BinWidth, double BinStart )
     335double GetBin ( const double value, const double BinWidth, const double BinStart )
    127336{
    128337  double bin =(double) (floor((value - BinStart)/BinWidth));
     
    135344 * \param *map map to write
    136345 */
    137 void OutputCorrelation( ofstream *file, BinPairMap *map )
     346void OutputCorrelation( ofstream * const file, const BinPairMap * const map )
    138347{
    139348  *file << "# BinStart\tCount" << endl;
    140   for (BinPairMap::iterator runner = map->begin(); runner != map->end(); ++runner) {
     349  for (BinPairMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
    141350    *file << runner->first << "\t" << runner->second << endl;
    142351  }
    143352};
     353
     354/** Prints correlation (double, (atom*,atom*) ) pairs to file.
     355 * \param *file file to write to
     356 * \param *map map to write
     357 */
     358void OutputPairCorrelation( ofstream * const file, const PairCorrelationMap * const map )
     359{
     360  *file << "# BinStart\tAtom1\tAtom2" << endl;
     361  for (PairCorrelationMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
     362    *file << runner->first << "\t" << *(runner->second.first) << "\t" << *(runner->second.second) << endl;
     363  }
     364};
     365
     366/** Prints correlation (double, int) pairs to file.
     367 * \param *file file to write to
     368 * \param *map map to write
     369 */
     370void OutputCorrelationToPoint( ofstream * const file, const CorrelationToPointMap * const map )
     371{
     372  *file << "# BinStart\tAtom::x[i]-point.x[i]" << endl;
     373  for (CorrelationToPointMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
     374    *file << runner->first;
     375    for (int i=0;i<NDIM;i++)
     376      *file << "\t" << (runner->second.first->node->x[i] - runner->second.second->x[i]);
     377    *file << endl;
     378  }
     379};
     380
     381/** Prints correlation (double, int) pairs to file.
     382 * \param *file file to write to
     383 * \param *map map to write
     384 */
     385void OutputCorrelationToSurface( ofstream * const file, const CorrelationToSurfaceMap * const map )
     386{
     387  *file << "# BinStart\tTriangle" << endl;
     388  for (CorrelationToSurfaceMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
     389    *file << runner->first << "\t" << *(runner->second.second) << endl;
     390  }
     391};
     392
  • src/analysis_correlation.hpp

    r06c7a3 r7326b2  
    3232class element;
    3333class LinkedCell;
    34 class molecule;
     34class MoleculeListClass;
    3535class Tesselation;
    3636class Vector;
     
    3939
    4040typedef multimap<double, pair<atom *, atom *> > PairCorrelationMap;
    41 typedef multimap<double, pair<atom *, Vector *> > CorrelationToPointMap;
     41typedef multimap<double, pair<atom *, const Vector *> > CorrelationToPointMap;
    4242typedef multimap<double, pair<atom *, BoundaryTriangleSet *> > CorrelationToSurfaceMap;
    4343typedef map<double, int> BinPairMap;
     
    4545/********************************************** declarations *******************************/
    4646
    47 PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 );
    48 CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point );
    49 CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC );
    50 double GetBin ( double value, double BinWidth, double BinStart );
    51 void OutputCorrelation( ofstream *file, BinPairMap *map );
     47PairCorrelationMap *PairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const  type2 );
     48CorrelationToPointMap *CorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point );
     49CorrelationToSurfaceMap *CorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC );
     50PairCorrelationMap *PeriodicPairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const  type2, const int ranges[NDIM] );
     51CorrelationToPointMap *PeriodicCorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point, const int ranges[NDIM] );
     52CorrelationToSurfaceMap *PeriodicCorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC, const int ranges[NDIM] );
     53double GetBin ( const double value, const double BinWidth, const double BinStart );
     54void OutputCorrelation( ofstream * const file, const BinPairMap * const map );
     55void OutputPairCorrelation( ofstream * const file, const BinPairMap * const map );
     56void OutputCorrelationToPoint( ofstream * const file, const BinPairMap * const map );
     57void OutputCorrelationToSurface( ofstream * const file, const BinPairMap * const map );
    5258
    5359
     
    6369  bool FirstMinFound = false;
    6470  bool FirstMaxFound = false;
     71
     72  if (map == NULL) {
     73    cerr << "Nothing to min/max, map is NULL!" << endl;
     74    return;
     75  }
    6576
    6677  for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) {
     
    8798 * \return Map of doubles (the bins) with counts as values
    8899 */
    89 template <typename T> BinPairMap *BinData ( ofstream *out,  T *map, double BinWidth, double BinStart, double BinEnd )
     100template <typename T> BinPairMap *BinData ( ofstream *out,  T *map, const double BinWidth, const double BinStart, const double BinEnd )
    90101{
    91102  BinPairMap *outmap = new BinPairMap;
     
    95106  pair <BinPairMap::iterator, bool > BinPairMapInserter;
    96107
     108  if (map == NULL) {
     109    cerr << "Nothing to bin, is NULL!" << endl;
     110    return outmap;
     111  }
     112
    97113  if (BinStart == BinEnd) { // if same, find range ourselves
    98114    GetMinMax( map, start, end);
     
    101117    end = BinEnd;
    102118    for (double runner = start; runner <= end; runner += BinWidth)
    103       outmap->insert( pair<double, int> (runner, 0.) );
     119      outmap->insert( pair<double, int> (runner, 0) );
    104120  }
    105121
  • src/analyzer.cpp

    r06c7a3 r7326b2  
    5959  bool NoTime = false;
    6060  bool NoHCorrection = true;
    61   int counter;
     61  int counter = 0;
    6262
    6363  cout << "ANOVA Analyzer" << endl;
  • src/atom.cpp

    r06c7a3 r7326b2  
    99#include "config.hpp"
    1010#include "element.hpp"
     11#include "lists.hpp"
    1112#include "memoryallocator.hpp"
    1213#include "parser.hpp"
     
    1516/************************************* Functions for class atom *************************************/
    1617
     18
    1719/** Constructor of class atom.
    1820 */
    19 atom::atom()
    20 {
    21   father = this;  // generally, father is itself
    22   previous = NULL;
    23   next = NULL;
    24   Ancestor = NULL;
    25   type = NULL;
    26   sort = NULL;
    27   FixedIon = 0;
    28   GraphNr = -1;
    29   ComponentNr = NULL;
    30   IsCyclic = false;
    31   SeparationVertex = false;
    32   LowpointNr = -1;
    33   AdaptiveOrder = 0;
    34   MaxOrder = false;
    35   // set LCNode::Vector to our Vector
    36   node = &x;
     21atom::atom() : previous(NULL), next(NULL), father(this), sort(&nr)
     22{
     23  node = &x;  // TesselPoint::x can only be referenced from here
    3724};
    3825
    3926/** Constructor of class atom.
    4027 */
    41 atom::atom(atom *pointer)
    42 {
    43   Name = NULL;
    44   previous = NULL;
    45   next = NULL;
    46   father = pointer;  // generally, father is itself
    47   Ancestor = NULL;
    48   GraphNr = -1;
    49   ComponentNr = NULL;
    50   IsCyclic = false;
    51   SeparationVertex = false;
    52   LowpointNr = -1;
    53   AdaptiveOrder = 0;
    54   MaxOrder = false;
     28atom::atom(atom *pointer) : previous(NULL), next(NULL), father(pointer), sort(&nr)
     29{
    5530  type = pointer->type;  // copy element of atom
    5631  x.CopyVector(&pointer->x); // copy coordination
    5732  v.CopyVector(&pointer->v); // copy velocity
    5833  FixedIon = pointer->FixedIon;
    59   nr = -1;
    60   sort = &nr;
    6134  node = &x;
    62 }
     35};
    6336
    6437
     
    6740atom::~atom()
    6841{
    69   Free<int>(&ComponentNr, "atom::~atom: *ComponentNr");
    70   Free<char>(&Name, "atom::~atom: *Name");
    71   Trajectory.R.clear();
    72   Trajectory.U.clear();
    73   Trajectory.F.clear();
     42  unlink(this);
    7443};
    7544
     
    10473 * \param **res return value (only set if atom::father is equal to \a *ptr)
    10574 */
    106 void atom::EqualsFather ( atom *ptr, atom **res )
     75void atom::EqualsFather ( const atom *ptr, const atom **res ) const
    10776{
    10877  if ( ptr == father )
     
    11584 * \return true - is inside, false - is not
    11685 */
    117 bool atom::IsInParallelepiped(Vector offset, double *parallelepiped)
     86bool atom::IsInParallelepiped(const Vector offset, const double *parallelepiped) const
    11887{
    11988  return (node->IsInParallelepiped(offset, parallelepiped));
    12089};
    12190
    122 /** Output of a single atom.
     91/** Counts the number of bonds weighted by bond::BondDegree.
     92 * \param bonds times bond::BondDegree
     93 */
     94int BondedParticle::CountBonds() const
     95{
     96  int NoBonds = 0;
     97  for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
     98    NoBonds += (*Runner)->BondDegree;
     99  return NoBonds;
     100};
     101
     102/** Output of a single atom with given numbering.
    123103 * \param ElementNo cardinal number of the element
    124104 * \param AtomNo cardinal number among these atoms of the same element
     
    127107  * \return true - \a *out present, false - \a *out is NULL
    128108 */
    129 bool atom::Output(ofstream *out, int ElementNo, int AtomNo, const char *comment) const
     109bool atom::OutputIndexed(ofstream *out, const int ElementNo, const int AtomNo, const char *comment) const
    130110{
    131111  if (out != NULL) {
     
    143123    return false;
    144124};
    145 bool atom::Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment)
     125
     126/** Output of a single atom with numbering from array according to atom::type.
     127 * \param *ElementNo cardinal number of the element
     128 * \param *AtomNo cardinal number among these atoms of the same element
     129 * \param *out stream to output to
     130 * \param *comment commentary after '#' sign
     131  * \return true - \a *out present, false - \a *out is NULL
     132 */
     133bool atom::OutputArrayIndexed(ofstream *out, const int *ElementNo, int *AtomNo, const char *comment) const
    146134{
    147135  AtomNo[type->Z]++;  // increment number
     
    181169  * \return true - \a *out present, false - \a *out is NULL
    182170 */
    183 bool atom::OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const
     171bool atom::OutputTrajectory(ofstream *out, const int *ElementNo, int *AtomNo, const int step) const
    184172{
    185173  AtomNo[type->Z]++;
     
    203191 * \return true - \a *out present, false - \a *out is NULL
    204192 */
    205 bool atom::OutputTrajectoryXYZ(ofstream *out, int step) const
     193bool atom::OutputTrajectoryXYZ(ofstream *out, const int step) const
    206194{
    207195  if (out != NULL) {
     
    215203};
    216204
    217 /** Prints all bonds of this atom from given global lists.
    218  * \param *out stream to output to
    219  * \param *NumberOfBondsPerAtom array with number of bonds per atomic index
    220  * \param ***ListOfBondsPerAtom array per atomic index of array with pointer to bond
    221  * \return true - \a *out present, false - \a *out is NULL
    222  */
    223 bool atom::OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const
    224 {
    225   if (out != NULL) {
    226 #ifdef ADDHYDROGEN
    227     if (type->Z != 1) {   // regard only non-hydrogen
    228 #endif
    229       *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << NumberOfBondsPerAtom[nr] << " bonds: ";
    230       int TotalDegree = 0;
    231       for (int j=0;j<NumberOfBondsPerAtom[nr];j++) {
    232         *out << *ListOfBondsPerAtom[nr][j] << "\t";
    233         TotalDegree += ListOfBondsPerAtom[nr][j]->BondDegree;
    234       }
    235       *out << " -- TotalDegree: " << TotalDegree << endl;
    236 #ifdef ADDHYDROGEN
    237     }
    238 #endif
    239     return true;
    240   } else
    241     return false;
    242 };
    243 
    244 ostream & operator << (ostream &ost, const atom &a)
    245 {
    246   ost << "[" << a.Name << "|" << &a << "]";
    247   return ost;
    248 };
    249 
    250 ostream & atom::operator << (ostream &ost)
    251 {
    252   ost << "[" << Name << "|" << this << "]";
    253   return ost;
     205/** Outputs the MPQC configuration line for this atom.
     206 * \param *out output stream
     207 * \param *center center of molecule subtracted from position
     208 * \param *AtomNo pointer to atom counter that is increased by one
     209 */
     210void atom::OutputMPQCLine(ofstream *out, const Vector *center, int *AtomNo = NULL) const
     211{
     212  *out << "\t\t" << type->symbol << " [ " << x.x[0]-center->x[0] << "\t" << x.x[1]-center->x[1] << "\t" << x.x[2]-center->x[2] << " ]" << endl;
     213  if (AtomNo != NULL)
     214    *AtomNo++;
    254215};
    255216
     
    258219 * \return true - this one's is smaller, false - not
    259220 */
    260 bool atom::Compare(const atom &ptr)
     221bool atom::Compare(const atom &ptr) const
    261222{
    262223  if (nr < ptr.nr)
     
    265226    return false;
    266227};
    267 
    268 /** Extends the trajectory STL vector to the new size.
    269  * Does nothing if \a MaxSteps is smaller than current size.
    270  * \param MaxSteps
    271  */
    272 void atom::ResizeTrajectory(int MaxSteps)
    273 {
    274   if (Trajectory.R.size() <= (unsigned int)(MaxSteps)) {
    275     //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
    276     Trajectory.R.resize(MaxSteps+1);
    277     Trajectory.U.resize(MaxSteps+1);
    278     Trajectory.F.resize(MaxSteps+1);
    279   }
    280 };
    281 
    282 /** Copies a given trajectory step \a src onto another \a dest
    283  * \param dest index of destination step
    284  * \param src index of source step
    285  */
    286 void atom::CopyStepOnStep(int dest, int src)
    287 {
    288   if (dest == src)  // self assignment check
    289     return;
    290 
    291   for (int n=NDIM;n--;) {
    292     Trajectory.R.at(dest).x[n] = Trajectory.R.at(src).x[n];
    293     Trajectory.U.at(dest).x[n] = Trajectory.U.at(src).x[n];
    294     Trajectory.F.at(dest).x[n] = Trajectory.F.at(src).x[n];
    295   }
    296 };
    297 
    298 /** Performs a velocity verlet update of the trajectory.
    299  * Parameters are according to those in configuration class.
    300  * \param NextStep index of sequential step to set
    301  * \param *configuration pointer to configuration with parameters
    302  * \param *Force matrix with forces
    303  */
    304 void atom::VelocityVerletUpdate(int NextStep, config *configuration, ForceMatrix *Force)
    305 {
    306   //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
    307   for (int d=0; d<NDIM; d++) {
    308     Trajectory.F.at(NextStep).x[d] = -Force->Matrix[0][nr][d+5]*(configuration->GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
    309     Trajectory.R.at(NextStep).x[d] = Trajectory.R.at(NextStep-1).x[d];
    310     Trajectory.R.at(NextStep).x[d] += configuration->Deltat*(Trajectory.U.at(NextStep-1).x[d]);     // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
    311     Trajectory.R.at(NextStep).x[d] += 0.5*configuration->Deltat*configuration->Deltat*(Trajectory.F.at(NextStep).x[d]/type->mass);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    312   }
    313   // Update U
    314   for (int d=0; d<NDIM; d++) {
    315     Trajectory.U.at(NextStep).x[d] = Trajectory.U.at(NextStep-1).x[d];
    316     Trajectory.U.at(NextStep).x[d] += configuration->Deltat * (Trajectory.F.at(NextStep).x[d]+Trajectory.F.at(NextStep-1).x[d]/type->mass); // v = F/m * t
    317   }
    318   // Update R (and F)
    319 //      out << "Integrated position&velocity of step " << (NextStep) << ": (";
    320 //      for (int d=0;d<NDIM;d++)
    321 //        out << Trajectory.R.at(NextStep).x[d] << " ";          // next step
    322 //      out << ")\t(";
    323 //      for (int d=0;d<NDIM;d++)
    324 //        cout << Trajectory.U.at(NextStep).x[d] << " ";          // next step
    325 //      out << ")" << endl;
    326 };
    327 
    328 /** Sums up mass and kinetics.
    329  * \param Step step to sum for
    330  * \param *TotalMass pointer to total mass sum
    331  * \param *TotalVelocity pointer to tota velocity sum
    332  */
    333 void atom::SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity )
    334 {
    335   *TotalMass += type->mass;  // sum up total mass
    336   for(int d=0;d<NDIM;d++) {
    337     TotalVelocity->x[d] += Trajectory.U.at(Step).x[d]*type->mass;
    338   }
    339 };
    340 
    341 /** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
    342  * \param *file output stream
    343  */
    344 void atom::OutputOrder(ofstream *file)
    345 {
    346   *file << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
    347   //cout << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    348 }
    349228
    350229/** Returns squared distance to a given vector.
     
    352231 * \return distance squared
    353232 */
    354 double atom::DistanceSquaredToVector(Vector &origin)
     233double atom::DistanceSquaredToVector(const Vector &origin) const
    355234{
    356235  return origin.DistanceSquared(&x);
    357 };
    358 
    359 /** Adds kinetic energy of this atom to given temperature value.
    360  * \param *temperature add on this value
    361  * \param step given step of trajectory to add
    362  */
    363 void atom::AddKineticToTemperature(double *temperature, int step) const
    364 {
    365   for (int i=NDIM;i--;)
    366     *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i];
    367236};
    368237
     
    371240 * \return distance
    372241 */
    373 double atom::DistanceToVector(Vector &origin)
     242double atom::DistanceToVector(const Vector &origin) const
    374243{
    375244  return origin.Distance(&x);
    376245};
    377246
     247/** Initialises the component number array.
     248 * Size is set to atom::ListOfBonds.size()+1 (last is th encode end by -1)
     249 */
     250void atom::InitComponentNr()
     251{
     252  if (ComponentNr != NULL)
     253    Free(&ComponentNr);
     254  ComponentNr = Malloc<int>(ListOfBonds.size()+1, "atom::InitComponentNumbers: *ComponentNr");
     255  for (int i=ListOfBonds.size()+1;i--;)
     256    ComponentNr[i] = -1;
     257};
     258
     259
    378260bool operator < (atom &a, atom &b)
    379261{
     
    381263};
    382264
    383 /** Evaluates some constraint potential if atom moves from \a startstep at once to \endstep in trajectory.
    384  * \param startstep trajectory begins at
    385  * \param endstep trajectory ends at
    386  * \param **PermutationMap if atom switches places with some other atom, there is no translation but a permutaton noted here (not in the trajectories of each).
    387  * \param *Force Force matrix to store result in
    388  */
    389 void atom::EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
    390 {
    391   double constant = 10.;
    392   atom *Sprinter = PermutationMap[nr];
    393   // set forces
    394   for (int i=NDIM;i++;)
    395     Force->Matrix[0][nr][5+i] += 2.*constant*sqrt(Trajectory.R.at(startstep).Distance(&Sprinter->Trajectory.R.at(endstep)));
    396 };
    397 
    398 /** Correct velocity against the summed \a CoGVelocity for \a step.
    399  * \param *ActualTemp sum up actual temperature meanwhile
    400  * \param Step MD step in atom::Tracjetory
    401  * \param *CoGVelocity remnant velocity (i.e. vector sum of all atom velocities)
    402  */
    403 void atom::CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity)
    404 {
    405   for(int d=0;d<NDIM;d++) {
    406     Trajectory.U.at(Step).x[d] -= CoGVelocity->x[d];
    407     *ActualTemp += 0.5 * type->mass * Trajectory.U.at(Step).x[d] * Trajectory.U.at(Step).x[d];
    408   }
    409 };
    410 
    411 /** Scales velocity of atom according to Woodcock thermostat.
    412  * \param ScaleTempFactor factor to scale the velocities with (i.e. sqrt of energy scale factor)
    413  * \param Step MD step to scale
    414  * \param *ekin sum of kinetic energy
    415  */
    416 void atom::Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin)
    417 {
    418   double *U = Trajectory.U.at(Step).x;
    419   if (FixedIon == 0) // even FixedIon moves, only not by other's forces
    420     for (int d=0; d<NDIM; d++) {
    421       U[d] *= ScaleTempFactor;
    422       *ekin += 0.5*type->mass * U[d]*U[d];
    423     }
    424 };
    425 
    426 /** Scales velocity of atom according to Gaussian thermostat.
    427  * \param Step MD step to scale
    428  * \param *G
    429  * \param *E
    430  */
    431 void atom::Thermostat_Gaussian_init(int Step, double *G, double *E)
    432 {
    433   double *U = Trajectory.U.at(Step).x;
    434   double *F = Trajectory.F.at(Step).x;
    435   if (FixedIon == 0) // even FixedIon moves, only not by other's forces
    436     for (int d=0; d<NDIM; d++) {
    437       *G += U[d] * F[d];
    438       *E += U[d]*U[d]*type->mass;
    439     }
    440 };
    441 
    442 /** Determines scale factors according to Gaussian thermostat.
    443  * \param Step MD step to scale
    444  * \param GE G over E ratio
    445  * \param *ekin sum of kinetic energy
    446  * \param *configuration configuration class with TempFrequency and TargetTemp
    447  */
    448 void atom::Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration)
    449 {
    450   double *U = Trajectory.U.at(Step).x;
    451   if (FixedIon == 0) // even FixedIon moves, only not by other's forces
    452     for (int d=0; d<NDIM; d++) {
    453       U[d] += configuration->Deltat/type->mass * ( (G_over_E) * (U[d]*type->mass) );
    454       *ekin += type->mass * U[d]*U[d];
    455     }
    456 };
    457 
    458 /** Scales velocity of atom according to Langevin thermostat.
    459  * \param Step MD step to scale
    460  * \param *r random number generator
    461  * \param *ekin sum of kinetic energy
    462  * \param *configuration configuration class with TempFrequency and TargetTemp
    463  */
    464 void atom::Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration)
    465 {
    466   double sigma  = sqrt(configuration->TargetTemp/type->mass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
    467   double *U = Trajectory.U.at(Step).x;
    468   if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
    469     // throw a dice to determine whether it gets hit by a heat bath particle
    470     if (((((rand()/(double)RAND_MAX))*configuration->TempFrequency) < 1.)) {
    471       cout << Verbose(3) << "Particle " << *this << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
    472       // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
    473       for (int d=0; d<NDIM; d++) {
    474         U[d] = gsl_ran_gaussian (r, sigma);
    475       }
    476       cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
    477     }
    478     for (int d=0; d<NDIM; d++)
    479       *ekin += 0.5*type->mass * U[d]*U[d];
    480   }
    481 };
    482 
    483 /** Scales velocity of atom according to Berendsen thermostat.
    484  * \param Step MD step to scale
    485  * \param ScaleTempFactor factor to scale energy (not velocity!) with
    486  * \param *ekin sum of kinetic energy
    487  * \param *configuration configuration class with TempFrequency and Deltat
    488  */
    489 void atom::Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration)
    490 {
    491   double *U = Trajectory.U.at(Step).x;
    492   if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
    493     for (int d=0; d<NDIM; d++) {
    494       U[d] *= sqrt(1+(configuration->Deltat/configuration->TempFrequency)*(ScaleTempFactor-1));
    495       *ekin += 0.5*type->mass * U[d]*U[d];
    496     }
    497   }
    498 };
    499 
    500 /** Initializes current run of NoseHoover thermostat.
    501  * \param Step MD step to scale
    502  * \param *delta_alpha additional sum of kinetic energy on return
    503  */
    504 void atom::Thermostat_NoseHoover_init(int Step, double *delta_alpha)
    505 {
    506   double *U = Trajectory.U.at(Step).x;
    507   if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
    508     for (int d=0; d<NDIM; d++) {
    509       *delta_alpha += U[d]*U[d]*type->mass;
    510     }
    511   }
    512 };
    513 
    514 /** Initializes current run of NoseHoover thermostat.
    515  * \param Step MD step to scale
    516  * \param *ekin sum of kinetic energy
    517  * \param *configuration configuration class with TempFrequency and Deltat
    518  */
    519 void atom::Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration)
    520 {
    521   double *U = Trajectory.U.at(Step).x;
    522   if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
    523     for (int d=0; d<NDIM; d++) {
    524         U[d] += configuration->Deltat/type->mass * (configuration->alpha * (U[d] * type->mass));
    525         *ekin += (0.5*type->mass) * U[d]*U[d];
    526       }
    527   }
    528 };
  • src/atom.hpp

    r06c7a3 r7326b2  
    1919
    2020#include <iostream>
     21#include <list>
    2122#include <vector>
    2223
    23 #include <gsl/gsl_randist.h>
    24 
     24#include "atom_atominfo.hpp"
     25#include "atom_bondedparticle.hpp"
     26#include "atom_graphnode.hpp"
     27#include "atom_particleinfo.hpp"
     28#include "atom_trajectoryparticle.hpp"
    2529#include "tesselation.hpp"
    2630
    2731/****************************************** forward declarations *****************************/
    2832
    29 class bond;
    30 class config;
    31 class element;
    32 class ForceMatrix;
    3333class Vector;
    3434
     
    3838 * Class incorporates position, type
    3939 */
    40 class atom : public TesselPoint {
     40class atom : public TesselPoint, public TrajectoryParticle, public GraphNode, public BondedParticle, public virtual ParticleInfo, public virtual AtomInfo {
    4141  public:
    42     struct
    43     {
    44       vector<Vector> R;  //!< position vector
    45       vector<Vector> U;  //!< velocity vector
    46       vector<Vector> F;  //!< last force vector
    47     } Trajectory;
    48 
    49     Vector x;       //!< coordinate vector of atom, giving last position within cell
    50     Vector v;       //!< velocity vector of atom, giving last velocity within cell
    51     Vector F;       //!< Force vector of atom, giving last force within cell
    52     element *type;  //!< pointing to element
    5342    atom *previous; //!< previous atom in molecule list
    5443    atom *next;     //!< next atom in molecule list
    5544    atom *father;   //!< In many-body bond order fragmentations points to originating atom
    56     atom *Ancestor; //!< "Father" in Depth-First-Search
    57     //char *Name;      //!< unique name used during many-body bond-order fragmentation, comes from TesselPoint
    58     int FixedIon;   //!< config variable that states whether forces act on the ion or not
    5945    int *sort;      //!< sort criteria
    60     //int nr;         //!< continuous, unique number, comes from TesselPoint
    61     int GraphNr;      //!< unique number, given in DepthFirstSearchAnalysis()
    62     int *ComponentNr;//!< belongs to this nonseparable components, given in DepthFirstSearchAnalysis() (if more than one, then is SeparationVertex)
    63     int LowpointNr; //!< needed in DepthFirstSearchAnalysis() to detect nonseparable components, is the lowest possible number of an atom to reach via tree edges only followed by at most one back edge.
    64     bool SeparationVertex; //!< whether this atom separates off subsets of atoms or not, determined in DepthFirstSearchAnalysis()
    65     bool IsCyclic;        //!< whether atom belong to as cycle or not, determined in DepthFirstSearchAnalysis()
    66     unsigned char AdaptiveOrder;  //!< current present bond order at site (0 means "not set")
    67     bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
    6846
    6947  atom();
     
    7149  virtual ~atom();
    7250
    73   bool Output(ofstream *out, int ElementNo, int AtomNo, const char *comment = NULL) const;
    74   bool Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment = NULL);
     51  bool OutputIndexed(ofstream *out, const int ElementNo, const int AtomNo, const char *comment = NULL) const;
     52  bool OutputArrayIndexed(ofstream *out, const int *ElementNo, int *AtomNo, const char *comment = NULL) const;
    7553  bool OutputXYZLine(ofstream *out) const;
    76   bool OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const;
    77   bool OutputTrajectoryXYZ(ofstream *out, int step) const;
    78   bool OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const;
     54  bool OutputTrajectory(ofstream *out, const int *ElementNo, int *AtomNo, const int step) const;
     55  bool OutputTrajectoryXYZ(ofstream *out, const int step) const;
     56  void OutputMPQCLine(ofstream *out, const Vector *center, int *AtomNo) const;
    7957
    80   void EqualsFather ( atom *ptr, atom **res );
     58  void InitComponentNr();
     59
     60  void EqualsFather ( const atom *ptr, const atom **res ) const;
    8161  void CorrectFather();
    8262  atom *GetTrueFather();
    83   bool Compare(const atom &ptr);
     63  bool Compare(const atom &ptr) const;
    8464
    85   // trajectory stuff
    86   void ResizeTrajectory(int MaxSteps);
    87   void CopyStepOnStep(int dest, int src);
    88   void VelocityVerletUpdate(int MDSteps, config *configuration, ForceMatrix *Force);
    89   void SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity );
    90 
    91   double DistanceToVector(Vector &origin);
    92   double DistanceSquaredToVector(Vector &origin);
    93 
    94   bool IsInParallelepiped(Vector offset, double *parallelepiped);
    95 
    96   // bond order stuff
    97   void OutputOrder(ofstream *file);
    98 
    99   // constraint potential and dynamics stuff
    100   void AddKineticToTemperature(double *temperature, int step) const;
    101   void EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force);
    102   void CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity);
    103 
    104   // thermostats
    105   void Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin);
    106   void Thermostat_Gaussian_init(int Step, double *G, double *E);
    107   void Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration);
    108   void Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration);
    109   void Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration);
    110   void Thermostat_NoseHoover_init(int Step, double *delta_alpha);
    111   void Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration);
    112 
    113 
    114   ostream & operator << (ostream &ost);
     65  double DistanceToVector(const Vector &origin) const;
     66  double DistanceSquaredToVector(const Vector &origin) const;
     67  bool IsInParallelepiped(const Vector offset, const double *parallelepiped) const;
    11568
    11669  private:
    11770};
    11871
    119 ostream & operator << (ostream &ost, const atom &a);
    120 
    12172#endif /* ATOM_HPP_ */
  • src/bond.cpp

    r06c7a3 r7326b2  
    1515/** Empty Constructor for class bond.
    1616 */
    17 bond::bond()
     17bond::bond() : leftatom(NULL), rightatom(NULL), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(0), nr(-1), Cyclic(false), Type(Undetermined), Used(white)
    1818{
    19   leftatom = NULL;
    20   rightatom = NULL;
    21   previous = NULL;
    22   next = NULL;
    23   nr = -1;
    24   HydrogenBond = 0;
    25   BondDegree = 0;
    26   Used = white;
    27   Cyclic = false;
    28   Type = Undetermined;
    2919};
    3020
     
    3525 * \param number increasing index
    3626 */
    37 bond::bond(atom *left, atom *right, int degree=1, int number=0)
     27bond::bond(atom *left, atom *right, const int degree, const int number) : leftatom(left), rightatom(right), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(degree), nr(number), Cyclic(false), Type(Undetermined), Used(white)
    3828{
    39   leftatom = left;
    40   rightatom = right;
    41   previous = NULL;
    42   next = NULL;
    43   HydrogenBond = 0;
    4429  if ((left != NULL) && (right != NULL)) {
    4530    if ((left->type != NULL) && (left->type->Z == 1))
     
    4833      HydrogenBond++;
    4934  }
    50   BondDegree = degree;
    51   nr = number;
    52   Used = white;
    53   Cyclic = false;
    54 };
    55 bond::bond(atom *left, atom *right)
    56 {
    57   leftatom = left;
    58   rightatom = right;
    59   previous = NULL;
    60   next = NULL;
    61   HydrogenBond = 0;
    62   if ((left != NULL) && (right != NULL)) {
    63     if ((left->type != NULL) && (left->type->Z == 1))
    64       HydrogenBond++;
    65     if ((right->type != NULL) && (right->type->Z == 1))
    66       HydrogenBond++;
    67   }
    68   BondDegree = 1;
    69   nr = 0;
    70   Used = white;
    71   Cyclic = false;
    7235};
    7336
     
    7740{
    7841  // remove this node from the list structure
    79   if (previous != NULL) {
    80     previous->next = next;
    81   }
    82   if (next != NULL) {
    83     next->previous = previous;
    84   }
     42  if (leftatom != NULL)
     43    leftatom->UnregisterBond(this);
     44  if (rightatom != NULL)
     45  rightatom->UnregisterBond(this);
     46  unlink(this);
    8547};
    8648
    87 ostream & operator << (ostream &ost, const bond &b) 
     49ostream & operator << (ostream &ost, const bond &b)
    8850{
    8951  ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]";
     
    9557 * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    9658 */
    97 atom * bond::GetOtherAtom(atom *Atom) const
     59atom * bond::GetOtherAtom(const ParticleInfo * const Atom) const
    9860{
    9961  if(leftatom == Atom)
     
    10567};
    10668
    107 /** Get the other atom in a bond if one is specified.
    108  * \param *Atom the pointer to the one atom
    109  * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    110  */
    111 bond * bond::GetFirstBond()
    112 {
    113   return GetFirst(this);
    114 };
    115 
    116 /** Get the other atom in a bond if one is specified.
    117  * \param *Atom the pointer to the one atom
    118  * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    119  */
    120 bond * bond::GetLastBond()
    121 {
    122   return GetLast(this);
    123 };
    12469
    12570/** Returns whether vertex was used in DFS.
     
    13580 * \return true if it is either bond::leftatom or bond::rightatom, false otherwise
    13681 */
    137 bool bond::Contains(const atom *ptr)
     82bool bond::Contains(const ParticleInfo * const ptr)
    13883{
    13984  return ((leftatom == ptr) || (rightatom == ptr));
     
    15297 * \return bond::Used, false if bond was already marked used
    15398 */
    154 bool bond::MarkUsed(enum Shading color) {
     99bool bond::MarkUsed(const enum Shading color) {
    155100  if (Used == black) {
    156101    cerr << "ERROR: Bond " << this << " was already marked black!." << endl;
  • src/bond.hpp

    r06c7a3 r7326b2  
    2121
    2222class atom;
     23class ParticleInfo;
    2324
    2425/********************************************** declarations *******************************/
    2526
    2627/** Bonds between atoms.
    27  * Class incorporates bonds between atoms in a molecule,
    28  * used to derive tge fragments in many-body bond order
    29  * calculations.
     28 * Class incorporates bonds between atoms in a molecule.
     29 * Note that we regard bond always as something in a molecule,
     30 * as it is the glue making up the connected subgrapgh and
     31 * hence the molecule. Thus, bonds belong globally to the molecule
     32 * (and are free'd there) and only locally to the atom classs.
    3033 */
    3134class bond {
     
    4144    enum EdgeType Type;//!< whether this is a tree or back edge
    4245
    43   atom * GetOtherAtom(atom *Atom) const;
    44   bond * GetFirstBond();
    45   bond * GetLastBond();
     46  atom * GetOtherAtom(const ParticleInfo * const Atom) const;
    4647
    47   bool MarkUsed(enum Shading color);
     48  bool MarkUsed(const enum Shading color);
    4849  enum Shading IsUsed();
    4950  void ResetUsed();
    50   bool Contains(const atom *ptr);
     51  bool Contains(const ParticleInfo * const ptr);
    5152  bool Contains(const int nr);
    5253
    5354  bond();
    54   bond(atom *left, atom *right);
    55   bond(atom *left, atom *right, int degree);
    56   bond(atom *left, atom *right, int degree, int number);
     55  bond(atom *left, atom *right, const int degree=1, const int number=0);
    5756  ~bond();
    5857
  • src/boundary.cpp

    r06c7a3 r7326b2  
    2626 * \param *BoundaryPoints NDIM set of boundary points defining the convex envelope on each projected plane
    2727 * \param *mol molecule structure representing the cluster
     28 * \param *&TesselStruct Tesselation structure with triangles
    2829 * \param IsAngstroem whether we have angstroem or atomic units
    2930 * \return NDIM array of the diameters
    3031 */
    31 double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
     32double *GetDiametersOfCluster(ofstream *out, const Boundaries *BoundaryPtr, const molecule *mol, Tesselation *&TesselStruct, const bool IsAngstroem)
    3233{
    3334  // get points on boundary of NULL was given as parameter
    3435  bool BoundaryFreeFlag = false;
    35   Boundaries *BoundaryPoints = BoundaryPtr;
    36   if (BoundaryPoints == NULL) {
     36  double OldComponent = 0.;
     37  double tmp = 0.;
     38  double w1 = 0.;
     39  double w2 = 0.;
     40  Vector DistanceVector;
     41  Vector OtherVector;
     42  int component = 0;
     43  int Othercomponent = 0;
     44  Boundaries::const_iterator Neighbour;
     45  Boundaries::const_iterator OtherNeighbour;
     46  double *GreatestDiameter = new double[NDIM];
     47
     48  const Boundaries *BoundaryPoints;
     49  if (BoundaryPtr == NULL) {
    3750    BoundaryFreeFlag = true;
    38     BoundaryPoints = GetBoundaryPoints(out, mol);
     51    BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct);
    3952  } else {
     53    BoundaryPoints = BoundaryPtr;
    4054    *out << Verbose(1) << "Using given boundary points set." << endl;
    4155  }
    4256  // determine biggest "diameter" of cluster for each axis
    43   Boundaries::iterator Neighbour, OtherNeighbour;
    44   double *GreatestDiameter = new double[NDIM];
    4557  for (int i = 0; i < NDIM; i++)
    4658    GreatestDiameter[i] = 0.;
    47   double OldComponent, tmp, w1, w2;
    48   Vector DistanceVector, OtherVector;
    49   int component, Othercomponent;
    5059  for (int axis = 0; axis < NDIM; axis++)
    5160    { // regard each projected plane
     
    5665          Othercomponent = (axis + 1 + ((j + 1) & 1)) % NDIM;
    5766          //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl;
    58           for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
    59               != BoundaryPoints[axis].end(); runner++)
    60             {
     67          for (Boundaries::const_iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    6168              //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl;
    6269              // seek for the neighbours pair where the Othercomponent sign flips
     
    6774              DistanceVector.CopyVector(&runner->second.second->x);
    6875              DistanceVector.SubtractVector(&Neighbour->second.second->x);
    69               do
    70                 { // seek for neighbour pair where it flips
     76              do { // seek for neighbour pair where it flips
    7177                  OldComponent = DistanceVector.x[Othercomponent];
    7278                  Neighbour++;
     
    7682                  DistanceVector.SubtractVector(&Neighbour->second.second->x);
    7783                  //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl;
    78                 }
    79               while ((runner != Neighbour) && (fabs(OldComponent / fabs(
     84                } while ((runner != Neighbour) && (fabs(OldComponent / fabs(
    8085                  OldComponent) - DistanceVector.x[Othercomponent] / fabs(
    8186                  DistanceVector.x[Othercomponent])) < MYEPSILON)); // as long as sign does not flip
    82               if (runner != Neighbour)
    83                 {
     87              if (runner != Neighbour) {
    8488                  OtherNeighbour = Neighbour;
    8589                  if (OtherNeighbour == BoundaryPoints[axis].begin()) // make it wrap around
     
    126130 * \param *out output stream for debugging
    127131 * \param *mol molecule structure representing the cluster
    128  */
    129 Boundaries *GetBoundaryPoints(ofstream *out, molecule *mol)
     132 * \param *&TesselStruct pointer to Tesselation structure
     133 */
     134Boundaries *GetBoundaryPoints(ofstream *out, const molecule *mol, Tesselation *&TesselStruct)
    130135{
    131136  atom *Walker = NULL;
     
    135140  Vector *MolCenter = mol->DetermineCenterOfAll(out);
    136141  Vector helper;
     142  BoundariesTestPair BoundaryTestPair;
     143  Vector AxisVector;
     144  Vector AngleReferenceVector;
     145  Vector AngleReferenceNormalVector;
     146  Vector ProjectedVector;
     147  Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)
     148  double angle = 0.;
    137149
    138150  *out << Verbose(1) << "Finding all boundary points." << endl;
    139   Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)
    140   BoundariesTestPair BoundaryTestPair;
    141   Vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;
    142   double radius, angle;
    143151  // 3a. Go through every axis
    144152  for (int axis = 0; axis < NDIM; axis++) {
     
    156164    while (Walker->next != mol->end) {
    157165      Walker = Walker->next;
    158       Vector ProjectedVector;
    159166      ProjectedVector.CopyVector(&Walker->x);
    160167      ProjectedVector.SubtractVector(MolCenter);
     
    162169
    163170      // correct for negative side
    164       radius = ProjectedVector.NormSquared();
     171      const double radius = ProjectedVector.NormSquared();
    165172      if (fabs(radius) > MYEPSILON)
    166173        angle = ProjectedVector.Angle(&AngleReferenceVector);
     
    178185        *out << Verbose(2) << "Present vector: " << *BoundaryTestPair.first->second.second << endl;
    179186        *out << Verbose(2) << "New vector: " << *Walker << endl;
    180         double tmp = ProjectedVector.NormSquared();
    181         if ((tmp - BoundaryTestPair.first->second.first) > MYEPSILON) {
    182           BoundaryTestPair.first->second.first = tmp;
     187        const double ProjectedVectorNorm = ProjectedVector.NormSquared();
     188        if ((ProjectedVectorNorm - BoundaryTestPair.first->second.first) > MYEPSILON) {
     189          BoundaryTestPair.first->second.first = ProjectedVectorNorm;
    183190          BoundaryTestPair.first->second.second = Walker;
    184           *out << Verbose(2) << "Keeping new vector due to larger projected distance " << tmp << "." << endl;
    185         } else if (fabs(tmp - BoundaryTestPair.first->second.first) < MYEPSILON) {
     191          *out << Verbose(2) << "Keeping new vector due to larger projected distance " << ProjectedVectorNorm << "." << endl;
     192        } else if (fabs(ProjectedVectorNorm - BoundaryTestPair.first->second.first) < MYEPSILON) {
    186193          helper.CopyVector(&Walker->x);
    187194          helper.SubtractVector(MolCenter);
    188           tmp = helper.NormSquared();
     195          const double oldhelperNorm = helper.NormSquared();
    189196          helper.CopyVector(&BoundaryTestPair.first->second.second->x);
    190197          helper.SubtractVector(MolCenter);
    191           if (helper.NormSquared() < tmp) {
     198          if (helper.NormSquared() < oldhelperNorm) {
    192199            BoundaryTestPair.first->second.second = Walker;
    193200            *out << Verbose(2) << "Keeping new vector due to larger distance to molecule center " << helper.NormSquared() << "." << endl;
    194201          } else {
    195             *out << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << tmp << "." << endl;
     202            *out << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << oldhelperNorm << "." << endl;
    196203          }
    197204        } else {
    198           *out << Verbose(2) << "Keeping present vector due to larger projected distance " << tmp << "." << endl;
     205          *out << Verbose(2) << "Keeping present vector due to larger projected distance " << ProjectedVectorNorm << "." << endl;
    199206        }
    200207      }
     
    267274
    268275          // calculate each length
    269           double a = SideA.Norm();
    270           //double b = SideB.Norm();
    271           //double c = SideC.Norm();
    272           double h = SideH.Norm();
     276          const double a = SideA.Norm();
     277          //const double b = SideB.Norm();
     278          //const double c = SideC.Norm();
     279          const double h = SideH.Norm();
    273280          // calculate the angles
    274           double alpha = SideA.Angle(&SideH);
    275           double beta = SideA.Angle(&SideC);
    276           double gamma = SideB.Angle(&SideH);
    277           double delta = SideC.Angle(&SideH);
    278           double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.);
     281          const double alpha = SideA.Angle(&SideH);
     282          const double beta = SideA.Angle(&SideC);
     283          const double gamma = SideB.Angle(&SideH);
     284          const double delta = SideC.Angle(&SideH);
     285          const double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.);
    279286          //*out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
    280287          *out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
     
    295302/** Tesselates the convex boundary by finding all boundary points.
    296303 * \param *out output stream for debugging
    297  * \param *mol molecule structure with Atom's and Bond's
     304 * \param *mol molecule structure with Atom's and Bond's.
    298305 * \param *TesselStruct Tesselation filled with points, lines and triangles on boundary on return
    299306 * \param *LCList atoms in LinkedCell list
     
    301308 * \return *TesselStruct is filled with convex boundary and tesselation is stored under \a *filename.
    302309 */
    303 void FindConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename)
     310void FindConvexBorder(ofstream *out, const molecule* mol, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename)
    304311{
    305312  bool BoundaryFreeFlag = false;
     
    308315  cout << Verbose(1) << "Begin of FindConvexBorder" << endl;
    309316
    310   if (mol->TesselStruct != NULL) // free if allocated
    311     delete(mol->TesselStruct);
    312   mol->TesselStruct = new class Tesselation;
     317  if (TesselStruct != NULL) // free if allocated
     318    delete(TesselStruct);
     319  TesselStruct = new class Tesselation;
    313320
    314321  // 1. Find all points on the boundary
    315322  if (BoundaryPoints == NULL) {
    316323      BoundaryFreeFlag = true;
    317       BoundaryPoints = GetBoundaryPoints(out, mol);
     324      BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct);
    318325  } else {
    319326      *out << Verbose(1) << "Using given boundary points set." << endl;
     
    338345  for (int axis = 0; axis < NDIM; axis++)
    339346    for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++)
    340         if (!mol->TesselStruct->AddBoundaryPoint(runner->second.second, 0))
     347        if (!TesselStruct->AddBoundaryPoint(runner->second.second, 0))
    341348          *out << Verbose(3) << "WARNING: Point " << *(runner->second.second) << " is already present!" << endl;
    342349
    343   *out << Verbose(2) << "I found " << mol->TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;
     350  *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;
    344351  // now we have the whole set of edge points in the BoundaryList
    345352
     
    352359
    353360  // 3a. guess starting triangle
    354   mol->TesselStruct->GuessStartingTriangle(out);
     361  TesselStruct->GuessStartingTriangle(out);
    355362
    356363  // 3b. go through all lines, that are not yet part of two triangles (only of one so far)
    357   mol->TesselStruct->TesselateOnBoundary(out, mol);
     364  TesselStruct->TesselateOnBoundary(out, mol);
    358365
    359366  // 3c. check whether all atoms lay inside the boundary, if not, add to boundary points, segment triangle into three with the new point
    360   if (!mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList))
     367  if (!TesselStruct->InsertStraddlingPoints(out, mol, LCList))
    361368    *out << Verbose(1) << "Insertion of straddling points failed!" << endl;
    362369
    363   *out << Verbose(2) << "I created " << mol->TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << mol->TesselStruct->LinesOnBoundary.size() << " lines and " << mol->TesselStruct->PointsOnBoundary.size() << " points." << endl;
     370  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl;
    364371
    365372  // 4. Store triangles in tecplot file
     
    370377      OutputName.append(TecplotSuffix);
    371378      ofstream *tecplot = new ofstream(OutputName.c_str());
    372       WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);
     379      WriteTecplotFile(out, tecplot, TesselStruct, mol, 0);
    373380      tecplot->close();
    374381      delete(tecplot);
     
    379386      OutputName.append(Raster3DSuffix);
    380387      ofstream *rasterplot = new ofstream(OutputName.c_str());
    381       WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);
     388      WriteRaster3dFile(out, rasterplot, TesselStruct, mol);
    382389      rasterplot->close();
    383390      delete(rasterplot);
     
    386393
    387394  // 3d. check all baselines whether the peaks of the two adjacent triangles with respect to center of baseline are convex, if not, make the baseline between the two peaks and baseline endpoints become the new peaks
    388   bool AllConvex;
     395  bool AllConvex = true;
    389396  class BoundaryLineSet *line = NULL;
    390397  do {
    391398    AllConvex = true;
    392     for (LineMap::iterator LineRunner = mol->TesselStruct->LinesOnBoundary.begin(); LineRunner != mol->TesselStruct->LinesOnBoundary.end(); LineRunner++) {
     399    for (LineMap::iterator LineRunner = TesselStruct->LinesOnBoundary.begin(); LineRunner != TesselStruct->LinesOnBoundary.end(); LineRunner++) {
    393400      line = LineRunner->second;
    394401      *out << Verbose(1) << "INFO: Current line is " << *line << "." << endl;
     
    397404
    398405        // flip the line
    399         if (mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)
     406        if (TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)
    400407          *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl;
    401408        else {
    402           mol->TesselStruct->FlipBaseline(out, line);
     409          TesselStruct->FlipBaseline(out, line);
    403410          *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl;
    404411        }
     
    408415
    409416  // 3e. we need another correction here, for TesselPoints that are below the surface (i.e. have an odd number of concave triangles surrounding it)
    410 //  if (!mol->TesselStruct->CorrectConcaveTesselPoints(out))
     417//  if (!TesselStruct->CorrectConcaveTesselPoints(out))
    411418//    *out << Verbose(1) << "Correction of concave tesselpoints failed!" << endl;
    412419
    413   *out << Verbose(2) << "I created " << mol->TesselStruct->TrianglesOnBoundary.size() << " triangles with " << mol->TesselStruct->LinesOnBoundary.size() << " lines and " << mol->TesselStruct->PointsOnBoundary.size() << " points." << endl;
     420  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl;
    414421
    415422  // 4. Store triangles in tecplot file
     
    419426      OutputName.append(TecplotSuffix);
    420427      ofstream *tecplot = new ofstream(OutputName.c_str());
    421       WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);
     428      WriteTecplotFile(out, tecplot, TesselStruct, mol, 0);
    422429      tecplot->close();
    423430      delete(tecplot);
     
    427434      OutputName.append(Raster3DSuffix);
    428435      ofstream *rasterplot = new ofstream(OutputName.c_str());
    429       WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);
     436      WriteRaster3dFile(out, rasterplot, TesselStruct, mol);
    430437      rasterplot->close();
    431438      delete(rasterplot);
     
    448455 * \return true - all removed, false - something went wrong
    449456 */
    450 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename)
     457bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename)
    451458{
    452459  int i=0;
     
    471478    // store envelope
    472479    sprintf(number, "-%04d", i++);
    473     StoreTrianglesinFile(out, mol, filename, number);
     480    StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, number);
    474481  }
    475482
     
    501508 * \return volume difference between the non- and the created convex envelope
    502509 */
    503 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename)
     510double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename)
    504511{
    505512  double volume = 0;
    506513  class BoundaryPointSet *point = NULL;
    507514  class BoundaryLineSet *line = NULL;
    508   bool Concavity;
     515  bool Concavity = false;
    509516  char dummy[MAXSTRINGSIZE];
    510   PointMap::iterator PointRunner, PointAdvance;
    511   LineMap::iterator LineRunner, LineAdvance;
    512   TriangleMap::iterator TriangleRunner, TriangleAdvance;
     517  PointMap::iterator PointRunner;
     518  PointMap::iterator PointAdvance;
     519  LineMap::iterator LineRunner;
     520  LineMap::iterator LineAdvance;
     521  TriangleMap::iterator TriangleRunner;
     522  TriangleMap::iterator TriangleAdvance;
     523  int run = 0;
    513524
    514525  *out << Verbose(0) << "Begin of ConvexizeNonconvexEnvelope" << endl;
     
    521532
    522533  // First step: RemovePointFromTesselatedSurface
    523   int run = 0;
    524   double tmp;
    525534  do {
    526535    Concavity = false;
    527536    sprintf(dummy, "-first-%d", run);
    528537    //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    529     StoreTrianglesinFile(out, mol, filename, dummy);
     538    StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy);
    530539
    531540    PointRunner = TesselStruct->PointsOnBoundary.begin();
     
    543552          volume += TesselStruct->RemovePointFromTesselatedSurface(out, point);
    544553          sprintf(dummy, "-first-%d", ++run);
    545           StoreTrianglesinFile(out, mol, filename, dummy);
     554          StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy);
    546555          Concavity = true;
    547556          break;
     
    553562    sprintf(dummy, "-second-%d", run);
    554563    //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    555     StoreTrianglesinFile(out, mol, filename, dummy);
     564    StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy);
    556565
    557566    // second step: PickFarthestofTwoBaselines
     
    564573      // take highest of both lines
    565574      if (TesselStruct->IsConvexRectangle(out, line) == NULL) {
    566         tmp = TesselStruct->PickFarthestofTwoBaselines(out, line);
     575        const double tmp = TesselStruct->PickFarthestofTwoBaselines(out, line);
    567576        volume += tmp;
    568         if (tmp != 0) {
    569           mol->TesselStruct->FlipBaseline(out, line);
     577        if (tmp != 0.) {
     578          TesselStruct->FlipBaseline(out, line);
    570579          Concavity = true;
    571580        }
     
    599608
    600609  CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    601   StoreTrianglesinFile(out, mol, filename, "");
     610  StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, "");
    602611
    603612  // end
     
    619628  bool IsAngstroem = configuration->GetIsAngstroem();
    620629  double volume = 0.;
    621   double PyramidVolume = 0.;
    622   double G, h;
    623   Vector x, y;
    624   double a, b, c;
     630  Vector x;
     631  Vector y;
    625632
    626633  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
     
    634641      y.CopyVector(runner->second->endpoints[0]->node->node);
    635642      y.SubtractVector(runner->second->endpoints[2]->node->node);
    636       a = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));
    637       b = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[2]->node->node));
    638       c = sqrt(runner->second->endpoints[2]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));
    639       G = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle
     643      const double a = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));
     644      const double b = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[2]->node->node));
     645      const double c = sqrt(runner->second->endpoints[2]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));
     646      const double G = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle
    640647      x.MakeNormalVector(runner->second->endpoints[0]->node->node, runner->second->endpoints[1]->node->node, runner->second->endpoints[2]->node->node);
    641648      x.Scale(runner->second->endpoints[1]->node->node->ScalarProduct(&x));
    642       h = x.Norm(); // distance of CoG to triangle
    643       PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    644       *out << Verbose(2) << "Area of triangle is " << G << " "
     649      const double h = x.Norm(); // distance of CoG to triangle
     650      const double PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
     651      *out << Verbose(2) << "Area of triangle is " << setprecision(10) << G << " "
    645652          << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is "
    646653          << h << " and the volume is " << PyramidVolume << " "
     
    648655      volume += PyramidVolume;
    649656    }
    650   *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10)
     657  *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(6)
    651658      << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3."
    652659      << endl;
     
    658665 * \param *out output stream for debugging
    659666 * \param *mol molecule with atoms and bonds
     667 * \param *&TesselStruct Tesselation with boundary triangles
    660668 * \param *filename prefix of filename
    661669 * \param *extraSuffix intermediate suffix
    662670 */
    663 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix)
     671void StoreTrianglesinFile(ofstream *out, const molecule * const mol, const Tesselation *&TesselStruct, const char *filename, const char *extraSuffix)
    664672{
    665673  // 4. Store triangles in tecplot file
     
    670678      OutputName.append(TecplotSuffix);
    671679      ofstream *tecplot = new ofstream(OutputName.c_str());
    672       WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);
     680      WriteTecplotFile(out, tecplot, TesselStruct, mol, 0);
    673681      tecplot->close();
    674682      delete(tecplot);
     
    679687      OutputName.append(Raster3DSuffix);
    680688      ofstream *rasterplot = new ofstream(OutputName.c_str());
    681       WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);
     689      WriteRaster3dFile(out, rasterplot, TesselStruct, mol);
    682690      rasterplot->close();
    683691      delete(rasterplot);
     
    691699 * \param *configuration needed for path to store convex envelope file
    692700 * \param *mol molecule structure representing the cluster
     701 * \param *&TesselStruct Tesselation structure with triangles on return
    693702 * \param ClusterVolume guesstimated cluster volume, if equal 0 we used VolumeOfConvexEnvelope() instead.
    694703 * \param celldensity desired average density in final cell
    695704 */
    696 void
    697 PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol,
    698     double ClusterVolume, double celldensity)
     705void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity)
    699706{
     707  bool IsAngstroem = true;
     708  double *GreatestDiameter = NULL;
     709  Boundaries *BoundaryPoints = NULL;
     710  class Tesselation *TesselStruct = NULL;
     711  Vector BoxLengths;
     712  int repetition[NDIM] = { 1, 1, 1 };
     713  int TotalNoClusters = 1;
     714  atom *Walker = NULL;
     715  double totalmass = 0.;
     716  double clustervolume = 0.;
     717  double cellvolume = 0.;
     718
    700719  // transform to PAS
    701720  mol->PrincipalAxisSystem(out, true);
    702721
     722  IsAngstroem = configuration->GetIsAngstroem();
     723  GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, TesselStruct, IsAngstroem);
     724  BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct);
     725  LinkedCell LCList(mol, 10.);
     726  FindConvexBorder(out, mol, TesselStruct, &LCList, NULL);
     727
    703728  // some preparations beforehand
    704   bool IsAngstroem = configuration->GetIsAngstroem();
    705   Boundaries *BoundaryPoints = GetBoundaryPoints(out, mol);
    706   class Tesselation *TesselStruct = NULL;
    707   LinkedCell LCList(mol, 10.);
    708   FindConvexBorder(out, mol, &LCList, NULL);
    709   double clustervolume;
    710729  if (ClusterVolume == 0)
    711730    clustervolume = VolumeOfConvexEnvelope(out, TesselStruct, configuration);
    712731  else
    713732    clustervolume = ClusterVolume;
    714   double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem);
    715   Vector BoxLengths;
    716   int repetition[NDIM] =
    717     { 1, 1, 1 };
    718   int TotalNoClusters = 1;
     733
    719734  for (int i = 0; i < NDIM; i++)
    720735    TotalNoClusters *= repetition[i];
    721736
    722737  // sum up the atomic masses
    723   double totalmass = 0.;
    724   atom *Walker = mol->start;
    725   while (Walker->next != mol->end)
    726     {
     738  Walker = mol->start;
     739  while (Walker->next != mol->end) {
    727740      Walker = Walker->next;
    728741      totalmass += Walker->type->mass;
    729     }
    730   *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10)
    731       << totalmass << " atomicmassunit." << endl;
    732 
    733   *out << Verbose(0) << "RESULT: The average density is " << setprecision(10)
    734       << totalmass / clustervolume << " atomicmassunit/"
    735       << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     742  }
     743  *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl;
     744  *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass / clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    736745
    737746  // solve cubic polynomial
    738   *out << Verbose(1) << "Solving equidistant suspension in water problem ..."
    739       << endl;
    740   double cellvolume;
     747  *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl;
    741748  if (IsAngstroem)
    742     cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass
    743         / clustervolume)) / (celldensity - 1);
     749    cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass / clustervolume)) / (celldensity - 1);
    744750  else
    745     cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass
    746         / clustervolume)) / (celldensity - 1);
    747   *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity
    748       << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom"
    749       : "atomiclength") << "^3." << endl;
    750 
    751   double minimumvolume = TotalNoClusters * (GreatestDiameter[0]
    752       * GreatestDiameter[1] * GreatestDiameter[2]);
    753   *out << Verbose(1)
    754       << "Minimum volume of the convex envelope contained in a rectangular box is "
    755       << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom"
    756       : "atomiclength") << "^3." << endl;
    757   if (minimumvolume > cellvolume)
    758     {
    759       cerr << Verbose(0)
    760           << "ERROR: the containing box already has a greater volume than the envisaged cell volume!"
    761           << endl;
    762       cout << Verbose(0)
    763           << "Setting Box dimensions to minimum possible, the greatest diameters."
    764           << endl;
    765       for (int i = 0; i < NDIM; i++)
    766         BoxLengths.x[i] = GreatestDiameter[i];
    767       mol->CenterEdge(out, &BoxLengths);
    768     }
    769   else
    770     {
    771       BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1]
    772           * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]);
    773       BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0]
    774           * GreatestDiameter[1] + repetition[0] * repetition[2]
    775           * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1]
    776           * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]);
    777       BoxLengths.x[2] = minimumvolume - cellvolume;
    778       double x0 = 0., x1 = 0., x2 = 0.;
    779       if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1],
    780           BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return
    781         *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0
    782             << " ." << endl;
    783       else
    784         {
    785           *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0
    786               << " and " << x1 << " and " << x2 << " ." << endl;
    787           x0 = x2; // sorted in ascending order
    788         }
    789 
    790       cellvolume = 1;
    791       for (int i = 0; i < NDIM; i++)
    792         {
    793           BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
    794           cellvolume *= BoxLengths.x[i];
    795         }
    796 
    797       // set new box dimensions
    798       *out << Verbose(0) << "Translating to box with these boundaries." << endl;
    799       mol->SetBoxDimension(&BoxLengths);
    800       mol->CenterInBox((ofstream *) &cout);
    801     }
     751    cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass / clustervolume)) / (celldensity - 1);
     752  *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     753
     754  double minimumvolume = TotalNoClusters * (GreatestDiameter[0] * GreatestDiameter[1] * GreatestDiameter[2]);
     755  *out << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     756  if (minimumvolume > cellvolume) {
     757    cerr << Verbose(0) << "ERROR: the containing box already has a greater volume than the envisaged cell volume!" << endl;
     758    cout << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl;
     759    for (int i = 0; i < NDIM; i++)
     760      BoxLengths.x[i] = GreatestDiameter[i];
     761    mol->CenterEdge(out, &BoxLengths);
     762  } else {
     763    BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1] * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]);
     764    BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0] * GreatestDiameter[1] + repetition[0] * repetition[2] * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1] * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]);
     765    BoxLengths.x[2] = minimumvolume - cellvolume;
     766    double x0 = 0.;
     767    double x1 = 0.;
     768    double x2 = 0.;
     769    if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1], BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return
     770      *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl;
     771    else {
     772      *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl;
     773      x0 = x2; // sorted in ascending order
     774    }
     775
     776    cellvolume = 1.;
     777    for (int i = 0; i < NDIM; i++) {
     778      BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
     779      cellvolume *= BoxLengths.x[i];
     780    }
     781
     782    // set new box dimensions
     783    *out << Verbose(0) << "Translating to box with these boundaries." << endl;
     784    mol->SetBoxDimension(&BoxLengths);
     785    mol->CenterInBox((ofstream *) &cout);
     786  }
    802787  // update Box of atoms by boundary
    803788  mol->SetBoxDimension(&BoxLengths);
    804   *out << Verbose(0) << "RESULT: The resulting cell dimensions are: "
    805       << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and "
    806       << BoxLengths.x[2] << " with total volume of " << cellvolume << " "
    807       << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    808 }
    809 ;
     789  *out << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     790};
    810791
    811792
     
    836817  atom *Walker = NULL;
    837818  bond *Binder = NULL;
    838   int i;
     819  int i = 0;
    839820  LinkedCell *LCList[List->ListOfMolecules.size()];
     821  double phi[NDIM];
     822  class Tesselation *TesselStruct[List->ListOfMolecules.size()];
    840823
    841824  *out << Verbose(0) << "Begin of FillBoxWithMolecule" << endl;
     
    845828    *out << Verbose(1) << "Pre-creating linked cell lists for molecule " << *ListRunner << "." << endl;
    846829    LCList[i] = new LinkedCell((*ListRunner), 5.); // get linked cell list
    847     if ((*ListRunner)->TesselStruct == NULL) {
     830    if (TesselStruct[i] == NULL) {
    848831      *out << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl;
    849       FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], 5., NULL);
     832      FindNonConvexBorder((ofstream *)&cout, (*ListRunner), TesselStruct[i], (const LinkedCell *&)LCList[i], 5., NULL);
    850833    }
    851834    i++;
     
    858841  filler->CountAtoms(out);
    859842  atom * CopyAtoms[filler->AtomCount];
    860   int nr = 0;
    861843
    862844  // calculate filler grid in [0,1]^3
     
    886868        for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) {
    887869          // get linked cell list
    888           if ((*ListRunner)->TesselStruct == NULL) {
     870          if (TesselStruct[i] == NULL) {
    889871            *out << Verbose(1) << "ERROR: TesselStruct of " << (*ListRunner) << " is NULL. Didn't we pre-create it?" << endl;
    890872            FillIt = false;
    891           } else
    892             FillIt = FillIt && (!(*ListRunner)->TesselStruct->IsInnerPoint(out, CurrentPosition, LCList[i++]));
     873          } else {
     874            FillIt = FillIt && (!TesselStruct[i]->IsInnerPoint(out, CurrentPosition, LCList[i]));
     875            i++;
     876          }
    893877        }
    894878
     
    903887
    904888          // go through all atoms
    905           nr=0;
    906889          Walker = filler->start;
    907890          while (Walker->next != filler->end) {
     
    916899            // ... and rotation matrix
    917900            if (DoRandomRotation) {
    918               double phi[NDIM];
    919901              for (int i=0;i<NDIM;i++) {
    920902                phi[i] = rand()/(RAND_MAX/(2.*M_PI));
     
    967949 * \param *out output stream for debugging
    968950 * \param *mol molecule structure with Atom's and Bond's
    969  * \param *Tess Tesselation filled with points, lines and triangles on boundary on return
    970  * \param *LCList atoms in LinkedCell list
     951 * \param *&TesselStruct Tesselation filled with points, lines and triangles on boundary on return
     952 * \param *&LCList atoms in LinkedCell list
    971953 * \param RADIUS radius of the virtual sphere
    972954 * \param *filename filename prefix for output of vertex data
    973955 */
    974 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const double RADIUS, const char *filename = NULL)
     956void FindNonConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *&LCList, const double RADIUS, const char *filename = NULL)
    975957{
    976958  bool freeLC = false;
    977 
    978   *out << Verbose(1) << "Entering search for non convex hull. " << endl;
    979   if (mol->TesselStruct == NULL) {
    980     *out << Verbose(1) << "Allocating Tesselation struct ..." << endl;
    981     mol->TesselStruct = new Tesselation;
    982   } else {
    983     delete(mol->TesselStruct);
    984     *out << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl;
    985     mol->TesselStruct = new Tesselation;
    986   }
    987959  LineMap::iterator baseline;
    988960  LineMap::iterator testline;
    989   *out << Verbose(0) << "Begin of FindNonConvexBorder\n";
    990961  bool OneLoopWithoutSuccessFlag = false;  // marks whether we went once through all baselines without finding any without two triangles
    991962  bool TesselationFailFlag = false;
     963
     964  *out << Verbose(1) << "Entering search for non convex hull. " << endl;
     965  if (TesselStruct == NULL) {
     966    *out << Verbose(1) << "Allocating Tesselation struct ..." << endl;
     967    TesselStruct= new Tesselation;
     968  } else {
     969    delete(TesselStruct);
     970    *out << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl;
     971    TesselStruct = new Tesselation;
     972  }
     973
     974  *out << Verbose(0) << "Begin of FindNonConvexBorder\n";
    992975
    993976  // initialise Linked Cell
     
    998981
    999982  // 1. get starting triangle
    1000   mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList);
     983  TesselStruct->FindStartingTriangle(out, RADIUS, LCList);
    1001984
    1002985  // 2. expand from there
    1003   baseline = mol->TesselStruct->LinesOnBoundary.begin();
     986  baseline = TesselStruct->LinesOnBoundary.begin();
    1004987  baseline++; // skip first line
    1005   while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) {
     988  while ((baseline != TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) {
    1006989    if (baseline->second->triangles.size() == 1) {
    1007990      // 3. find next triangle
    1008       TesselationFailFlag = mol->TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, LCList); //the line is there, so there is a triangle, but only one.
     991      TesselationFailFlag = TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, LCList); //the line is there, so there is a triangle, but only one.
    1009992      OneLoopWithoutSuccessFlag = OneLoopWithoutSuccessFlag || TesselationFailFlag;
    1010993      if (!TesselationFailFlag)
     
    1013996      // write temporary envelope
    1014997      if (filename != NULL) {
    1015         if ((DoSingleStepOutput && ((mol->TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration
    1016           mol->TesselStruct->Output(out, filename, mol);
     998        if ((DoSingleStepOutput && ((TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration
     999          TesselStruct->Output(out, filename, mol);
    10171000        }
    10181001      }
    1019       baseline = mol->TesselStruct->LinesOnBoundary.end();
     1002      baseline = TesselStruct->LinesOnBoundary.end();
    10201003      *out << Verbose(2) << "Baseline set to end." << endl;
    10211004    } else {
     
    10251008    }
    10261009
    1027     if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) {
    1028       baseline = mol->TesselStruct->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
     1010    if ((baseline == TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) {
     1011      baseline = TesselStruct->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
    10291012      OneLoopWithoutSuccessFlag = false;
    10301013    }
     
    10321015  }
    10331016  // check envelope for consistency
    1034   CheckListOfBaselines(out, mol->TesselStruct);
     1017  CheckListOfBaselines(out, TesselStruct);
    10351018
    10361019  // look whether all points are inside of the convex envelope, otherwise add them via degenerated triangles
    1037   //mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList);
     1020  //->InsertStraddlingPoints(out, mol, LCList);
    10381021//  mol->GoToFirst();
    10391022//  class TesselPoint *Runner = NULL;
     
    10411024//    Runner = mol->GetPoint();
    10421025//    *out << Verbose(1) << "Checking on " << Runner->Name << " ... " << endl;
    1043 //    if (!mol->TesselStruct->IsInnerPoint(out, Runner, LCList)) {
     1026//    if (!->IsInnerPoint(out, Runner, LCList)) {
    10441027//      *out << Verbose(2) << Runner->Name << " is outside of envelope, adding via degenerated triangles." << endl;
    1045 //      mol->TesselStruct->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList);
     1028//      ->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList);
    10461029//    } else {
    10471030//      *out << Verbose(2) << Runner->Name << " is inside of or on envelope." << endl;
     
    10511034
    10521035  // Purges surplus triangles.
    1053   mol->TesselStruct->RemoveDegeneratedTriangles();
     1036  TesselStruct->RemoveDegeneratedTriangles();
    10541037
    10551038  // check envelope for consistency
    1056   CheckListOfBaselines(out, mol->TesselStruct);
     1039  CheckListOfBaselines(out, TesselStruct);
    10571040
    10581041  // write final envelope
    1059   CalculateConcavityPerBoundaryPoint(out, mol->TesselStruct);
    1060   StoreTrianglesinFile(out, mol, filename, "");
     1042  CalculateConcavityPerBoundaryPoint(out, TesselStruct);
     1043  StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, "");
    10611044
    10621045  if (freeLC)
     
    10661049
    10671050
    1068 /** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it.
     1051/** Finds a hole of sufficient size in \a *mols to embed \a *srcmol into it.
    10691052 * \param *out output stream for debugging
    1070  * \param *srcmol molecule to embed into
     1053 * \param *mols molecules in the domain to embed in between
     1054 * \param *srcmol embedding molecule
    10711055 * \return *Vector new center of \a *srcmol for embedding relative to \a this
    10721056 */
    1073 Vector* molecule::FindEmbeddingHole(ofstream *out, molecule *srcmol)
     1057Vector* FindEmbeddingHole(ofstream *out, MoleculeListClass *mols, molecule *srcmol)
    10741058{
    10751059  Vector *Center = new Vector;
  • src/boundary.hpp

    r06c7a3 r7326b2  
    4848/********************************************** declarations *******************************/
    4949
     50double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename);
     51molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation);
     52void FindConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename);
     53Vector* FindEmbeddingHole(ofstream *out, MoleculeListClass *mols, molecule *srcmol);
     54void FindNextSuitablePoint(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC);
     55void FindNonConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *&LC, const double RADIUS, const char *tempbasename);
     56Boundaries *GetBoundaryPoints(ofstream *out, const molecule *mol, Tesselation *&TesselStruct);
     57double * GetDiametersOfCluster(ofstream *out, const Boundaries *BoundaryPtr, const molecule *mol, Tesselation *&TesselStruct, const bool IsAngstroem);
     58void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
     59bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename);
     60void StoreTrianglesinFile(ofstream *out, const molecule * const mol, const Tesselation *&TesselStruct, const char *filename, const char *extraSuffix);
    5061double VolumeOfConvexEnvelope(ofstream *out, class Tesselation *TesselStruct, class config *configuration);
    51 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    52 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
    53 molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation);
    54 void FindConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename);
    55 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LC, const double RADIUS, const char *tempbasename);
    56 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename);
    57 void FindNextSuitablePoint(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC);
    58 Boundaries *GetBoundaryPoints(ofstream *out, molecule *mol);
    59 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix);
    60 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename);
    6162
    6263
  • src/builder.cpp

    r06c7a3 r7326b2  
    5050using namespace std;
    5151
     52#include "analysis_correlation.hpp"
    5253#include "atom.hpp"
    5354#include "bond.hpp"
     55#include "bondgraph.hpp"
    5456#include "boundary.hpp"
    5557#include "config.hpp"
     
    253255        } while ((j != -1) && (i<128));
    254256        if (i >= 2) {
    255           first->x.LSQdistance(atoms, i);
     257          first->x.LSQdistance((const Vector **)atoms, i);
    256258
    257259          first->x.Output((ofstream *)&cout);
     
    591593      {
    592594        cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    593         LinkedCell LCList(mol, 10.);
    594595        class Tesselation *TesselStruct = NULL;
    595         FindConvexBorder((ofstream *)&cout, mol, &LCList, NULL);
     596        const LinkedCell *LCList = NULL;
     597        LCList = new LinkedCell(mol, 10.);
     598        FindConvexBorder((ofstream *)&cout, mol, TesselStruct, LCList, NULL);
    596599        double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, configuration);
    597         cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;
     600        cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;\
     601        delete(LCList);
    598602        delete(TesselStruct);
    599603      }
     
    719723       cin >> factor[2];
    720724       valid = true;
    721        mol->Scale(&factor);
     725       mol->Scale((const double ** const)&factor);
    722726       delete[](factor);
    723727      }
     
    837841          }
    838842          if (mol->first->next != mol->last) // if connect matrix is present already, redo it
    839             mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration->GetIsAngstroem());
     843            mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
    840844          // free memory
    841845          delete[](Elements);
     
    893897          cin >> bonddistance;
    894898          start = clock();
    895           mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem());
    896           mol->CreateListOfBondsPerAtom((ofstream *)&cout);
     899          mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
    897900          end = clock();
    898901          cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     
    12471250  // translate each to its center and merge all molecules in MoleculeListClass into this molecule
    12481251  int N = molecules->ListOfMolecules.size();
    1249   int *src = new int(N);
     1252  int *src = new int[N];
    12501253  N=0;
    12511254  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     
    12541257  }
    12551258  molecules->SimpleMultiAdd(mol, src, N);
    1256   delete(src);
     1259  delete[](src);
    12571260
    12581261  // ... and translate back
     
    13541357  int argptr;
    13551358  molecule *mol = NULL;
     1359  string BondGraphFileName("");
    13561360  strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1);
    13571361
     
    13751379            cout << "\t-B xx xy xz yy yz zz\tBound atoms by domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl;
    13761380            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
     1381            cout << "\t-C\tPair Correlation analysis." << endl;
    13771382            cout << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl;
    13781383            cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
     
    13801385            cout << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl;
    13811386            cout << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl;
     1387            cout << "\t-g <file>\tParses a bond length table from the given file." << endl;
    13821388            cout << "\t-h/-H/-?\tGive this help screen." << endl;
    13831389            cout << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl;
     
    14161422            }
    14171423            break;
     1424          case 'g':
     1425            if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1426              cerr << "Not enough or invalid arguments for specifying bond length table: -g <table file>" << endl;
     1427            } else {
     1428              BondGraphFileName = argv[argptr];
     1429              cout << "Using " << BondGraphFileName << " as bond length table." << endl;
     1430              argptr+=1;
     1431            }
     1432            break;
    14181433          case 'n':
    14191434            cout << "I won't parse trajectories." << endl;
     
    14281443    } while (argptr < argc);
    14291444
    1430     // 2. Parse the element database
     1445    // 3a. Parse the element database
    14311446    if (periode->LoadPeriodentafel(configuration.databasepath)) {
    14321447      cout << Verbose(0) << "Element list loaded successfully." << endl;
     
    14361451      return 1;
    14371452    }
    1438     // 3. Find config file name and parse if possible
     1453    // 3b. Find config file name and parse if possible, also BondGraphFileName
    14391454    if (argv[1][0] != '-') {
    14401455      // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
    1441       mol = new molecule(periode);
    1442       mol->ActiveFlag = true;
    1443       molecules->insert(mol);
    1444 
    14451456      cout << Verbose(0) << "Config file given." << endl;
    14461457      test.open(argv[1], ios::in);
     
    14611472        ConfigFileName = argv[1];
    14621473        cout << Verbose(1) << "Specified config file found, parsing ... ";
    1463         switch (configuration.TestSyntax(ConfigFileName, periode, mol)) {
     1474        switch (configuration.TestSyntax(ConfigFileName, periode)) {
    14641475          case 1:
    14651476            cout << "new syntax." << endl;
    1466             configuration.Load(ConfigFileName, periode, mol);
     1477            configuration.Load(ConfigFileName, BondGraphFileName, periode, molecules);
    14671478            configPresent = present;
    14681479            break;
    14691480          case 0:
    14701481            cout << "old syntax." << endl;
    1471             configuration.LoadOld(ConfigFileName, periode, mol);
     1482            configuration.LoadOld(ConfigFileName, BondGraphFileName, periode, molecules);
    14721483            configPresent = present;
    14731484            break;
     
    14791490    } else
    14801491      configPresent = absent;
     1492     // set mol to first active molecule
     1493     if (molecules->ListOfMolecules.size() != 0) {
     1494       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1495         if ((*ListRunner)->ActiveFlag) {
     1496           mol = *ListRunner;
     1497           break;
     1498         }
     1499     }
     1500     if (mol == NULL) {
     1501       mol = new molecule(periode);
     1502       mol->ActiveFlag = true;
     1503       molecules->insert(mol);
     1504     }
     1505
    14811506    // 4. parse again through options, now for those depending on elements db and config presence
    14821507    argptr = 1;
     
    15051530            case 'a':
    15061531              if (ExitFlag == 0) ExitFlag = 1;
    1507               if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1]))) {
     1532              if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3]))) {
    15081533                ExitFlag = 255;
    15091534                cerr << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
     
    15491574                int *MinimumRingSize = new int[mol->AtomCount];
    15501575                atom ***ListOfLocalAtoms = NULL;
    1551                 int FragmentCounter = 0;
    15521576                class StackClass<bond *> *BackEdgeStack = NULL;
    15531577                class StackClass<bond *> *LocalBackEdgeStack = NULL;
    1554                 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem());
    1555                 mol->CreateListOfBondsPerAtom((ofstream *)&cout);
     1578                mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
    15561579                Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
    15571580                if (Subgraphs != NULL) {
    1558                   Subgraphs->next->FillBondStructureFromReference((ofstream *)&cout, mol, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     1581                  int FragmentCounter = 0;
    15591582                  while (Subgraphs->next != NULL) {
    15601583                    Subgraphs = Subgraphs->next;
     1584                    Subgraphs->FillBondStructureFromReference((ofstream *)&cout, mol, FragmentCounter, ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
    15611585                    LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount);
    1562                     Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    1563                     Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, BackEdgeStack, MinimumRingSize);
     1586                    Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter], BackEdgeStack, LocalBackEdgeStack);
     1587                    Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, LocalBackEdgeStack, MinimumRingSize);
    15641588                    delete(LocalBackEdgeStack);
    15651589                    delete(Subgraphs->previous);
     1590                    FragmentCounter++;
    15661591                  }
    15671592                  delete(Subgraphs);
    15681593                  for (int i=0;i<FragmentCounter;i++)
    1569                     Free(&ListOfLocalAtoms[FragmentCounter]);
     1594                    Free(&ListOfLocalAtoms[i]);
    15701595                  Free(&ListOfLocalAtoms);
    15711596                }
     
    15741599              }
    15751600              //argptr+=1;
     1601              break;
     1602            case 'C':
     1603              if (ExitFlag == 0) ExitFlag = 1;
     1604              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-') || (argv[argptr+1][0] == '-') || (argv[argptr+2][0] == '-')) {
     1605                ExitFlag = 255;
     1606                cerr << "Not enough or invalid arguments given for pair correlation analysis: -C <Z> <output> <bin output>" << endl;
     1607              } else {
     1608                SaveFlag = false;
     1609                ofstream output(argv[argptr+1]);
     1610                ofstream binoutput(argv[argptr+2]);
     1611                const double radius = 5.;
     1612
     1613                // get the boundary
     1614                class molecule *Boundary = NULL;
     1615                class Tesselation *TesselStruct = NULL;
     1616                const LinkedCell *LCList = NULL;
     1617                // find biggest molecule
     1618                int counter  = 0;
     1619                for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) {
     1620                  if ((Boundary == NULL) || (Boundary->AtomCount < (*BigFinder)->AtomCount)) {
     1621                    Boundary = *BigFinder;
     1622                  }
     1623                  counter++;
     1624                }
     1625                bool *Actives = Malloc<bool>(counter, "ParseCommandLineOptions() - case C -- *Actives");
     1626                counter = 0;
     1627                for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) {
     1628                  Actives[counter] = (*BigFinder)->ActiveFlag;
     1629                  (*BigFinder)->ActiveFlag = (*BigFinder == Boundary) ? false : true;
     1630                }
     1631                LCList = new LinkedCell(Boundary, 2.*radius);
     1632                element *elemental = periode->FindElement((const int) atoi(argv[argptr]));
     1633                FindNonConvexBorder((ofstream *)&cout, Boundary, TesselStruct, LCList, radius, NULL);
     1634                int ranges[NDIM] = {1,1,1};
     1635                CorrelationToSurfaceMap *surfacemap = PeriodicCorrelationToSurface( (ofstream *)&cout, molecules, elemental, TesselStruct, LCList, ranges );
     1636                BinPairMap *binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. );
     1637                OutputCorrelation ( &binoutput, binmap );
     1638                output.close();
     1639                binoutput.close();
     1640                for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++)
     1641                  (*BigFinder)->ActiveFlag = Actives[counter];
     1642                Free(&Actives);
     1643                delete(LCList);
     1644                delete(TesselStruct);
     1645                argptr+=3;
     1646              }
    15761647              break;
    15771648            case 'E':
     
    16341705                cout << "Parsing bonds from " << argv[argptr] << "." << endl;
    16351706                ifstream *input = new ifstream(argv[argptr]);
    1636                 mol->CreateAdjacencyList2((ofstream *)&cout, input);
     1707                mol->CreateAdjacencyListFromDbondFile((ofstream *)&cout, input);
    16371708                input->close();
    16381709                argptr+=1;
     
    16451716                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
    16461717              } else {
    1647                 class Tesselation T;
     1718                class Tesselation *T = NULL;
     1719                const LinkedCell *LCList = NULL;
    16481720                string filename(argv[argptr+1]);
    16491721                filename.append(".csv");
     
    16511723                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
    16521724                start = clock();
    1653                 LinkedCell LCList(mol, atof(argv[argptr])*2.);
    1654                 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, atof(argv[argptr]), argv[argptr+1]);
    1655                 //FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str());
     1725                LCList = new LinkedCell(mol, atof(argv[argptr])*2.);
     1726                FindNonConvexBorder((ofstream *)&cout, mol, T, LCList, atof(argv[argptr]), argv[argptr+1]);
     1727                //FindDistributionOfEllipsoids((ofstream *)&cout, T, &LCList, N, number, filename.c_str());
    16561728                end = clock();
    16571729                cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     1730                delete(LCList);
    16581731                argptr+=2;
    16591732              }
     
    17351808            case 't':
    17361809              if (ExitFlag == 0) ExitFlag = 1;
    1737               if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
     1810              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    17381811                ExitFlag = 255;
    17391812                cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
     
    17501823            case 'T':
    17511824              if (ExitFlag == 0) ExitFlag = 1;
    1752               if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
     1825              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    17531826                ExitFlag = 255;
    17541827                cerr << "Not enough or invalid arguments given for periodic translation: -T <x> <y> <z>" << endl;
     
    17651838            case 's':
    17661839              if (ExitFlag == 0) ExitFlag = 1;
    1767               if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) {
     1840              if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    17681841                ExitFlag = 255;
    1769                 cerr << "Not enough or invalid arguments given for scaling: -s <factor/[factor_x]> [factor_y] [factor_z]" << endl;
     1842                cerr << "Not enough or invalid arguments given for scaling: -s <factor_x> [factor_y] [factor_z]" << endl;
    17701843              } else {
    17711844                SaveFlag = true;
     
    17741847                factor = new double[NDIM];
    17751848                factor[0] = atof(argv[argptr]);
    1776                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1777                   argptr++;
    1778                 factor[1] = atof(argv[argptr]);
    1779                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1780                   argptr++;
    1781                 factor[2] = atof(argv[argptr]);
    1782                 mol->Scale(&factor);
     1849                factor[1] = atof(argv[argptr+1]);
     1850                factor[2] = atof(argv[argptr+2]);
     1851                mol->Scale((const double ** const)&factor);
    17831852                for (int i=0;i<NDIM;i++) {
    17841853                  j += i+1;
     
    17871856                }
    17881857                delete[](factor);
    1789                 argptr+=1;
     1858                argptr+=3;
    17901859              }
    17911860              break;
     
    18791948                cout << Verbose(0) << "Creating connection matrix..." << endl;
    18801949                start = clock();
    1881                 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem());
     1950                mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
    18821951                cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    18831952                if (mol->first->next != mol->last) {
     
    19091978                cerr << "Not enough or invalid arguments given for convex envelope: -o <convex output file> <non-convex output file>" << endl;
    19101979              } else {
     1980                class Tesselation *TesselStruct = NULL;
     1981                const LinkedCell *LCList = NULL;
    19111982                cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    19121983                cout << Verbose(1) << "Storing tecplot convex data in " << argv[argptr] << "." << endl;
    19131984                cout << Verbose(1) << "Storing tecplot non-convex data in " << argv[argptr+1] << "." << endl;
    1914                 LinkedCell LCList(mol, 10.);
    1915                 //FindConvexBorder((ofstream *)&cout, mol, &LCList, argv[argptr]);
    1916                 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, 5., argv[argptr+1]);
    1917 //                RemoveAllBoundaryPoints((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]);
    1918                 double volumedifference = ConvexizeNonconvexEnvelope((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]);
    1919                 double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, mol->TesselStruct, &configuration);
     1985                LCList = new LinkedCell(mol, 10.);
     1986                //FindConvexBorder((ofstream *)&cout, mol, LCList, argv[argptr]);
     1987                FindNonConvexBorder((ofstream *)&cout, mol, TesselStruct, LCList, 5., argv[argptr+1]);
     1988//                RemoveAllBoundaryPoints((ofstream *)&cout, TesselStruct, mol, argv[argptr]);
     1989                double volumedifference = ConvexizeNonconvexEnvelope((ofstream *)&cout, TesselStruct, mol, argv[argptr]);
     1990                double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, &configuration);
    19201991                cout << Verbose(0) << "The tesselated volume area is " << clustervolume << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl;
    19211992                cout << Verbose(0) << "The non-convex tesselated volume area is " << clustervolume-volumedifference << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl;
     1993                delete(TesselStruct);
     1994                delete(LCList);
    19221995                argptr+=2;
    19231996              }
     
    20432116  MoleculeListClass *molecules = new MoleculeListClass;  // list of all molecules
    20442117  molecule *mol = NULL;
    2045   config configuration;
     2118  config *configuration = new config;
    20462119  char choice;  // menu choice char
    20472120  Vector x,y,z,n;  // coordinates for absolute point in cell volume
     
    20532126
    20542127  // =========================== PARSE COMMAND LINE OPTIONS ====================================
    2055   j = ParseCommandLineOptions(argc, argv, molecules, periode, configuration, ConfigFileName);
     2128  j = ParseCommandLineOptions(argc, argv, molecules, periode, *configuration, ConfigFileName);
    20562129  switch(j) {
    20572130    case 255:  // something went wrong
     2131    case 2:  // just for -f option
     2132    case 1:  // just for -v and -h options
    20582133      delete(molecules); // also free's all molecules contained
    20592134      delete(periode);
     2135      delete(configuration);
    20602136      cout << Verbose(0) <<  "Maximum of allocated memory: "
    20612137        << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
    20622138      cout << Verbose(0) <<  "Remaining non-freed memory: "
    20632139        << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
    2064      return j;
    2065       break;
    2066     case 1:  // just for -v and -h options
    2067       delete(molecules); // also free's all molecules contained
    2068       delete(periode);
    2069       cout << Verbose(0) <<  "Maximum of allocated memory: "
    2070         << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
    2071       cout << Verbose(0) <<  "Remaining non-freed memory: "
    2072         << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
    2073       return 0;
    2074       break;
    2075     case 2:  // just for -f option
    2076       delete(molecules); // also free's all molecules contained
    2077       delete(periode);
    2078       cout << Verbose(0) <<  "Maximum of allocated memory: "
    2079         << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
    2080       cout << Verbose(0) <<  "Remaining non-freed memory: "
    2081         << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
    2082       return 2;
    2083       break;
     2140      MemoryUsageObserver::getInstance()->purgeInstance();
     2141     return (j == 1 ? 0 : j);
    20842142    default:
    20852143      break;
     
    20962154      }
    20972155    }
     2156    mol->ActiveFlag = true;
    20982157    molecules->insert(mol);
    20992158  }
     
    21352194
    21362195      case 'c': // edit each field of the configuration
    2137        configuration.Edit();
     2196       configuration->Edit();
    21382197       break;
    21392198
     
    21432202
    21442203      case 'g': // manipulate molecules
    2145         ManipulateMolecules(periode, molecules, &configuration);
     2204        ManipulateMolecules(periode, molecules, configuration);
    21462205        break;
    21472206
     
    21512210
    21522211      case 'm': // manipulate atoms
    2153         ManipulateAtoms(periode, molecules, &configuration);
     2212        ManipulateAtoms(periode, molecules, configuration);
    21542213        break;
    21552214
     
    21582217
    21592218      case 's': // save to config file
    2160         SaveConfig(ConfigFileName, &configuration, periode, molecules);
     2219        SaveConfig(ConfigFileName, configuration, periode, molecules);
    21612220        break;
    21622221
     
    21712230
    21722231  // save element data base
    2173   if (periode->StorePeriodentafel(configuration.databasepath)) //ElementsFileName
     2232  if (periode->StorePeriodentafel(configuration->databasepath)) //ElementsFileName
    21742233    cout << Verbose(0) << "Saving of elements.db successful." << endl;
    21752234  else
     
    21782237  delete(molecules); // also free's all molecules contained
    21792238  delete(periode);
     2239  delete(configuration);
    21802240
    21812241  cout << Verbose(0) <<  "Maximum of allocated memory: "
     
    21832243  cout << Verbose(0) <<  "Remaining non-freed memory: "
    21842244    << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
     2245  MemoryUsageObserver::purgeInstance();
    21852246
    21862247  return (0);
  • src/config.cpp

    • Property mode changed from 100755 to 100644
    r06c7a3 r7326b2  
    88#include "config.hpp"
    99#include "element.hpp"
     10#include "helpers.hpp"
     11#include "lists.hpp"
     12#include "molecule.hpp"
    1013#include "memoryallocator.hpp"
    1114#include "molecule.hpp"
     
    5053/** Constructor for ConfigFileBuffer class.
    5154 */
    52 ConfigFileBuffer::ConfigFileBuffer()
     55ConfigFileBuffer::ConfigFileBuffer() : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0)
    5356{
    54   NoLines = 0;
    55   CurrentLine = 0;
    56   buffer = NULL;
    57   LineMapping = NULL;
    58 }
     57};
    5958
    6059/** Constructor for ConfigFileBuffer class with filename to be parsed.
    6160 * \param *filename file name
    6261 */
    63 ConfigFileBuffer::ConfigFileBuffer(char *filename)
     62ConfigFileBuffer::ConfigFileBuffer(const char * const filename) : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0)
    6463{
    65   NoLines = 0;
    66   CurrentLine = 0;
    67   buffer = NULL;
    68   LineMapping = NULL;
    6964  ifstream *file = NULL;
    7065  char line[MAXSTRINGSIZE];
     
    139134 * \param NoAtoms of subsequent lines to look at
    140135 */
    141 void ConfigFileBuffer::MapIonTypesInBuffer(int NoAtoms)
     136void ConfigFileBuffer::MapIonTypesInBuffer(const int NoAtoms)
    142137{
    143138  map<const char *, int, IonTypeCompare> LineList;
     
    166161/** Constructor for config file class.
    167162 */
    168 config::config()
    169 {
     163config::config() : BG(NULL), PsiType(0), MaxPsiDouble(0), PsiMaxNoUp(0), PsiMaxNoDown(0), MaxMinStopStep(1), InitMaxMinStopStep(1), ProcPEGamma(8), ProcPEPsi(1), configpath(NULL),
     164    configname(NULL), FastParsing(false), Deltat(0.01), basis(""), databasepath(NULL), DoConstrainedMD(0), MaxOuterStep(0), Thermostat(4), ThermostatImplemented(NULL),
     165    ThermostatNames(NULL), TempFrequency(2.5), alpha(0.), HooverMass(0.), TargetTemp(0.00095004455), ScaleTempStep(25),  mainname(NULL), defaultpath(NULL), pseudopotpath(NULL),
     166    DoOutVis(0), DoOutMes(1), DoOutNICS(0), DoOutOrbitals(0), DoOutCurrent(0), DoFullCurrent(0), DoPerturbation(0), DoWannier(0), CommonWannier(0), SawtoothStart(0.01),
     167    VectorPlane(0), VectorCut(0.), UseAddGramSch(1), Seed(1), OutVisStep(10), OutSrcStep(5), MaxPsiStep(0), EpsWannier(1e-7), MaxMinStep(100), RelEpsTotalEnergy(1e-7),
     168    RelEpsKineticEnergy(1e-5), MaxMinGapStopStep(0), MaxInitMinStep(100), InitRelEpsTotalEnergy(1e-5), InitRelEpsKineticEnergy(1e-4), InitMaxMinGapStopStep(0), ECut(128.),
     169    MaxLevel(5), RiemannTensor(0), LevRFactor(0), RiemannLevel(0), Lev0Factor(2), RTActualUse(0), AddPsis(0), RCut(20.), StructOpt(0), IsAngstroem(1), RelativeCoord(0),
     170    MaxTypes(0) {
    170171  mainname = Malloc<char>(MAXSTRINGSIZE,"config constructor: mainname");
    171172  defaultpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: defaultpath");
     
    174175  configpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: configpath");
    175176  configname = Malloc<char>(MAXSTRINGSIZE,"config constructor: configname");
    176   ThermostatImplemented = Malloc<int>(MaxThermostats, "config constructor: *ThermostatImplemented");
    177   ThermostatNames = Malloc<char*>(MaxThermostats, "config constructor: *ThermostatNames");
    178   for (int j=0;j<MaxThermostats;j++)
    179     ThermostatNames[j] = Malloc<char>(12, "config constructor: ThermostatNames[]");
    180   Thermostat = 4;
    181   alpha = 0.;
    182   ScaleTempStep = 25;
    183   TempFrequency = 2.5;
    184177  strcpy(mainname,"pcp");
    185178  strcpy(defaultpath,"not specified");
     
    189182  basis = "3-21G";
    190183
    191   strcpy(ThermostatNames[0],"None");
    192   ThermostatImplemented[0] = 1;
    193   strcpy(ThermostatNames[1],"Woodcock");
    194   ThermostatImplemented[1] = 1;
    195   strcpy(ThermostatNames[2],"Gaussian");
    196   ThermostatImplemented[2] = 1;
    197   strcpy(ThermostatNames[3],"Langevin");
    198   ThermostatImplemented[3] = 1;
    199   strcpy(ThermostatNames[4],"Berendsen");
    200   ThermostatImplemented[4] = 1;
    201   strcpy(ThermostatNames[5],"NoseHoover");
    202   ThermostatImplemented[5] = 1;
    203 
    204   FastParsing = false;
    205   ProcPEGamma=8;
    206   ProcPEPsi=1;
    207   DoOutVis=0;
    208   DoOutMes=1;
    209   DoOutNICS=0;
    210   DoOutOrbitals=0;
    211   DoOutCurrent=0;
    212   DoPerturbation=0;
    213   DoFullCurrent=0;
    214   DoWannier=0;
    215   DoConstrainedMD=0;
    216   CommonWannier=0;
    217   SawtoothStart=0.01;
    218   VectorPlane=0;
    219   VectorCut=0;
    220   UseAddGramSch=1;
    221   Seed=1;
    222 
    223   MaxOuterStep=0;
    224   Deltat=0.01;
    225   OutVisStep=10;
    226   OutSrcStep=5;
    227   TargetTemp=0.00095004455;
    228   ScaleTempStep=25;
    229   MaxPsiStep=0;
    230   EpsWannier=1e-7;
    231 
    232   MaxMinStep=100;
    233   RelEpsTotalEnergy=1e-7;
    234   RelEpsKineticEnergy=1e-5;
    235   MaxMinStopStep=1;
    236   MaxMinGapStopStep=0;
    237   MaxInitMinStep=100;
    238   InitRelEpsTotalEnergy=1e-5;
    239   InitRelEpsKineticEnergy=1e-4;
    240   InitMaxMinStopStep=1;
    241   InitMaxMinGapStopStep=0;
    242 
    243   //BoxLength[NDIM*NDIM];
    244 
    245   ECut=128.;
    246   MaxLevel=5;
    247   RiemannTensor=0;
    248   LevRFactor=0;
    249   RiemannLevel=0;
    250   Lev0Factor=2;
    251   RTActualUse=0;
    252   PsiType=0;
    253   MaxPsiDouble=0;
    254   PsiMaxNoUp=0;
    255   PsiMaxNoDown=0;
    256   AddPsis=0;
    257 
    258   RCut=20.;
    259   StructOpt=0;
    260   IsAngstroem=1;
    261   RelativeCoord=0;
    262   MaxTypes=0;
     184  InitThermostats();
    263185};
    264 
    265186
    266187/** Destructor for config file class.
     
    278199    Free(&ThermostatNames[j]);
    279200  Free(&ThermostatNames);
     201  if (BG != NULL)
     202    delete(BG);
     203};
     204
     205/** Initialises variables in class config for Thermostats.
     206 */
     207void config::InitThermostats()
     208{
     209  ThermostatImplemented = Malloc<int>(MaxThermostats, "config constructor: *ThermostatImplemented");
     210  ThermostatNames = Malloc<char*>(MaxThermostats, "config constructor: *ThermostatNames");
     211  for (int j=0;j<MaxThermostats;j++)
     212    ThermostatNames[j] = Malloc<char>(12, "config constructor: ThermostatNames[]");
     213
     214  strcpy(ThermostatNames[0],"None");
     215  ThermostatImplemented[0] = 1;
     216  strcpy(ThermostatNames[1],"Woodcock");
     217  ThermostatImplemented[1] = 1;
     218  strcpy(ThermostatNames[2],"Gaussian");
     219  ThermostatImplemented[2] = 1;
     220  strcpy(ThermostatNames[3],"Langevin");
     221  ThermostatImplemented[3] = 1;
     222  strcpy(ThermostatNames[4],"Berendsen");
     223  ThermostatImplemented[4] = 1;
     224  strcpy(ThermostatNames[5],"NoseHoover");
     225  ThermostatImplemented[5] = 1;
    280226};
    281227
     
    283229 * \param *fb file buffer containing the config file
    284230 */
    285 void config::InitThermostats(class ConfigFileBuffer *fb)
     231void config::ParseThermostats(class ConfigFileBuffer * const fb)
    286232{
    287   char *thermo = Malloc<char>(12, "IonsInitRead: thermo");
    288   int verbose = 0;
     233  char * const thermo = Malloc<char>(12, "IonsInitRead: thermo");
     234  const int verbose = 0;
    289235
    290236  // read desired Thermostat from file along with needed additional parameters
     
    352298    Thermostat = None;
    353299  }
    354   Free(&thermo);
     300  Free(thermo);
    355301};
    356302
     
    622568 * \param *filename filename of config file to be tested
    623569 * \param *periode pointer to a periodentafel class with all elements
    624  * \param *mol pointer to molecule containing all atoms of the molecule
    625570 * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax
    626571 */
    627 int config::TestSyntax(char *filename, periodentafel *periode, molecule *mol)
     572int config::TestSyntax(const char * const filename, const periodentafel * const periode) const
    628573{
    629574  int test;
     
    664609 * \return *defaultpath
    665610 */
    666 void config::SetDefaultPath(const char *path)
     611void config::SetDefaultPath(const char * const path)
    667612{
    668613  strcpy(defaultpath, path);
     
    672617 * \param filename config file string
    673618 */
    674 void config::RetrieveConfigPathAndName(string filename)
     619void config::RetrieveConfigPathAndName(const string filename)
    675620{
    676621  char *ptr = NULL;
     
    696641};
    697642
    698 
    699 /** Initializes config file structure by loading elements from a give file.
     643/** Initializes ConfigFileBuffer from a file.
    700644 * \param *file input file stream being the opened config file
    701  * \param *periode pointer to a periodentafel class with all elements
    702  * \param *mol pointer to molecule containing all atoms of the molecule
    703  */
    704 void config::Load(char *filename, periodentafel *periode, molecule *mol)
     645 * \param *FileBuffer pointer to FileBuffer on return, should point to NULL
     646 */
     647void PrepareFileBuffer(const char * const filename, struct ConfigFileBuffer *&FileBuffer)
    705648{
    706   ifstream *file = new ifstream(filename);
    707   if (file == NULL) {
    708     cerr << "ERROR: config file " << filename << " missing!" << endl;
    709     return;
    710   }
    711   file->close();
    712   delete(file);
    713   RetrieveConfigPathAndName(filename);
    714 
    715   // ParseParameterFile
    716   struct ConfigFileBuffer *FileBuffer = new ConfigFileBuffer(filename);
     649  if (FileBuffer != NULL) {
     650    cerr << Verbose(1) << "WARNING: deleting present FileBuffer in PrepareFileBuffer()." << endl;
     651    delete(FileBuffer);
     652  }
     653  FileBuffer = new ConfigFileBuffer(filename);
     654
    717655  FileBuffer->InitMapping();
    718 
    719   /* Oeffne Hauptparameterdatei */
    720   int di;
    721   double BoxLength[9];
    722   string zeile;
    723   string dummy;
     656};
     657
     658/** Loads a molecule from a ConfigFileBuffer.
     659 * \param *mol molecule to load
     660 * \param *FileBuffer ConfigFileBuffer to use
     661 * \param *periode periodentafel for finding elements
     662 * \param FastParsing whether to parse trajectories or not
     663 */
     664void LoadMolecule(molecule * const &mol, struct ConfigFileBuffer * const &FileBuffer, const periodentafel * const periode, const bool FastParsing)
     665{
     666  int MaxTypes = 0;
    724667  element *elementhash[MAX_ELEMENTS];
    725668  char name[MAX_ELEMENTS];
    726669  char keyword[MAX_ELEMENTS];
    727   int Z, No[MAX_ELEMENTS];
     670  int Z = -1;
     671  int No[MAX_ELEMENTS];
    728672  int verbose = 0;
    729673  double value[3];
    730  
    731   InitThermostats(FileBuffer);
    732  
    733   /* Namen einlesen */
    734 
    735   ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
    736   ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
    737   ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
    738   ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
    739   ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical);
    740 
    741   if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional))
    742     config::Seed = 1;
    743 
    744   if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) {
    745     config::DoOutOrbitals = 0;
    746   } else {
    747     if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0;
    748     if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1;
    749   }
    750   ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
    751   if (config::DoOutVis < 0) config::DoOutVis = 0;
    752   if (config::DoOutVis > 1) config::DoOutVis = 1;
    753   if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional))
    754     config::VectorPlane = -1;
    755   if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional))
    756     config::VectorCut = 0.;
    757   ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
    758   if (config::DoOutMes < 0) config::DoOutMes = 0;
    759   if (config::DoOutMes > 1) config::DoOutMes = 1;
    760   if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional))
    761     config::DoOutCurrent = 0;
    762   if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
    763   if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
    764   ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
    765   if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
    766   if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
    767   if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) {
    768     config::DoWannier = 0;
    769   } else {
    770     if (config::DoWannier < 0) config::DoWannier = 0;
    771     if (config::DoWannier > 1) config::DoWannier = 1;
    772   }
    773   if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) {
    774     config::CommonWannier = 0;
    775   } else {
    776     if (config::CommonWannier < 0) config::CommonWannier = 0;
    777     if (config::CommonWannier > 4) config::CommonWannier = 4;
    778   }
    779   if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) {
    780     config::SawtoothStart = 0.01;
    781   } else {
    782     if (config::SawtoothStart < 0.) config::SawtoothStart = 0.;
    783     if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
    784   }
    785  
    786   if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional))
    787     if (config::DoConstrainedMD < 0)
    788       config::DoConstrainedMD = 0;
    789   ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
    790   if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
    791     config::Deltat = 1;
    792   ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
    793   ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
    794   ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
    795   //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
    796   if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
    797     config::EpsWannier = 1e-8;
    798 
    799   // stop conditions
    800   //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
    801   ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
    802   if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
    803 
    804   ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
    805   ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
    806   ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
    807   ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical);
    808   ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical);
    809   if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
    810   if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
    811   if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
    812 
    813   ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
    814   ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
    815   ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
    816   ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
    817   ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical);
    818   if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
    819   if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
    820   if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
    821 
    822   // Unit cell and magnetic field
    823   ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
    824   mol->cell_size[0] = BoxLength[0];
    825   mol->cell_size[1] = BoxLength[3];
    826   mol->cell_size[2] = BoxLength[4];
    827   mol->cell_size[3] = BoxLength[6];
    828   mol->cell_size[4] = BoxLength[7];
    829   mol->cell_size[5] = BoxLength[8];
    830   //if (1) fprintf(stderr,"\n");
    831 
    832   ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional);
    833   ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional);
    834   if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional))
    835     config::DoFullCurrent = 0;
    836   if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
    837   if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
    838   if (config::DoOutNICS < 0) config::DoOutNICS = 0;
    839   if (config::DoOutNICS > 2) config::DoOutNICS = 2;
    840   if (config::DoPerturbation == 0) {
    841     config::DoFullCurrent = 0;
    842     config::DoOutNICS = 0;
    843   }
    844 
    845   ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
    846   ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
    847   ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
    848   if (config::Lev0Factor < 2) {
    849     config::Lev0Factor = 2;
    850   }
    851   ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
    852   if (di >= 0 && di < 2) {
    853     config::RiemannTensor = di;
    854   } else {
    855     fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
    856     exit(1);
    857   }
    858   switch (config::RiemannTensor) {
    859     case 0: //UseNoRT
    860       if (config::MaxLevel < 2) {
    861         config::MaxLevel = 2;
    862       }
    863       config::LevRFactor = 2;
    864       config::RTActualUse = 0;
    865       break;
    866     case 1: // UseRT
    867       if (config::MaxLevel < 3) {
    868         config::MaxLevel = 3;
    869       }
    870       ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
    871       if (config::RiemannLevel < 2) {
    872         config::RiemannLevel = 2;
    873       }
    874       if (config::RiemannLevel > config::MaxLevel-1) {
    875         config::RiemannLevel = config::MaxLevel-1;
    876       }
    877       ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
    878       if (config::LevRFactor < 2) {
    879         config::LevRFactor = 2;
    880       }
    881       config::Lev0Factor = 2;
    882       config::RTActualUse = 2;
    883       break;
    884   }
    885   ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
    886   if (di >= 0 && di < 2) {
    887     config::PsiType = di;
    888   } else {
    889     fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
    890     exit(1);
    891   }
    892   switch (config::PsiType) {
    893   case 0: // SpinDouble
    894     ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
    895     ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
    896     break;
    897   case 1: // SpinUpDown
    898     if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
    899     ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
    900     ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
    901     ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
    902     break;
    903   }
    904 
    905   // IonsInitRead
    906 
    907   ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
    908   ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
    909   ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical);
    910   if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional))
    911     config::RelativeCoord = 0;
    912   if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional))
    913     config::StructOpt = 0;
     674
     675  if (mol == NULL) {
     676    cerr << "Molecule is not allocated in LoadMolecule(), exit.";
     677    performCriticalExit();
     678  }
     679
     680  ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(MaxTypes), 1, critical);
    914681  if (MaxTypes == 0) {
    915682    cerr << "There are no atoms according to MaxTypes in this config file." << endl;
     
    918685    cout << Verbose(0) << "Prescanning ions per type: " << endl;
    919686    int NoAtoms = 0;
    920     for (int i=0; i < config::MaxTypes; i++) {
     687    for (int i=0; i < MaxTypes; i++) {
    921688      sprintf(name,"Ion_Type%i",i+1);
    922689      ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical);
     
    929696
    930697    // sort the lines via the LineMapping
    931     sprintf(name,"Ion_Type%i",config::MaxTypes);
     698    sprintf(name,"Ion_Type%i",MaxTypes);
    932699    if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) {
    933700      cerr << "There are no atoms in the config file!" << endl;
     
    941708    //}
    942709
    943     map<int, atom *> AtomList[config::MaxTypes];
     710    map<int, atom *> AtomList[MaxTypes];
    944711    map<int, atom *> LinearList;
    945712    atom *neues = NULL;
     
    949716      while (status) {
    950717        cout << "Currently parsing MD step " << repetition << "." << endl;
    951         for (int i=0; i < config::MaxTypes; i++) {
     718        for (int i=0; i < MaxTypes; i++) {
    952719          sprintf(name,"Ion_Type%i",i+1);
    953720          for(int j=0;j<No[i];j++) {
     
    1028795      cout << "I found " << repetition << " times the keyword Ion_Type1_1." << endl;
    1029796      // parse in molecule coordinates
    1030       for (int i=0; i < config::MaxTypes; i++) {
     797      for (int i=0; i < MaxTypes; i++) {
    1031798        sprintf(name,"Ion_Type%i",i+1);
    1032799        for(int j=0;j<No[i];j++) {
     
    1061828    }
    1062829  }
    1063   delete(FileBuffer);
    1064830};
    1065831
    1066 /** Initializes config file structure by loading elements from a give file with old pcp syntax.
    1067  * \param *file input file stream being the opened config file with old pcp syntax
     832
     833/** Initializes config file structure by loading elements from a give file.
     834 * \param *file input file stream being the opened config file
     835 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed.
    1068836 * \param *periode pointer to a periodentafel class with all elements
    1069  * \param *mol pointer to molecule containing all atoms of the molecule
    1070  */
    1071 void config::LoadOld(char *filename, periodentafel *periode, molecule *mol)
     837 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system
     838 */
     839void config::Load(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList)
    1072840{
     841  molecule *mol = new molecule(periode);
    1073842  ifstream *file = new ifstream(filename);
    1074843  if (file == NULL) {
     
    1076845    return;
    1077846  }
     847  file->close();
     848  delete(file);
     849  RetrieveConfigPathAndName(filename);
     850
     851  // ParseParameterFile
     852  struct ConfigFileBuffer *FileBuffer = NULL;
     853  PrepareFileBuffer(filename,FileBuffer);
     854
     855  /* Oeffne Hauptparameterdatei */
     856  int di = 0;
     857  double BoxLength[9];
     858  string zeile;
     859  string dummy;
     860  int verbose = 0;
     861 
     862  ParseThermostats(FileBuffer);
     863 
     864  /* Namen einlesen */
     865
     866  // 1. parse in options
     867  ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
     868  ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
     869  ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
     870  ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
     871  ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical);
     872
     873  if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional))
     874    config::Seed = 1;
     875
     876  if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) {
     877    config::DoOutOrbitals = 0;
     878  } else {
     879    if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0;
     880    if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1;
     881  }
     882  ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
     883  if (config::DoOutVis < 0) config::DoOutVis = 0;
     884  if (config::DoOutVis > 1) config::DoOutVis = 1;
     885  if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional))
     886    config::VectorPlane = -1;
     887  if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional))
     888    config::VectorCut = 0.;
     889  ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
     890  if (config::DoOutMes < 0) config::DoOutMes = 0;
     891  if (config::DoOutMes > 1) config::DoOutMes = 1;
     892  if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional))
     893    config::DoOutCurrent = 0;
     894  if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
     895  if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
     896  ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
     897  if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
     898  if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
     899  if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) {
     900    config::DoWannier = 0;
     901  } else {
     902    if (config::DoWannier < 0) config::DoWannier = 0;
     903    if (config::DoWannier > 1) config::DoWannier = 1;
     904  }
     905  if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) {
     906    config::CommonWannier = 0;
     907  } else {
     908    if (config::CommonWannier < 0) config::CommonWannier = 0;
     909    if (config::CommonWannier > 4) config::CommonWannier = 4;
     910  }
     911  if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) {
     912    config::SawtoothStart = 0.01;
     913  } else {
     914    if (config::SawtoothStart < 0.) config::SawtoothStart = 0.;
     915    if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
     916  }
     917 
     918  if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional))
     919    if (config::DoConstrainedMD < 0)
     920      config::DoConstrainedMD = 0;
     921  ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
     922  if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
     923    config::Deltat = 1;
     924  ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
     925  ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
     926  ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
     927  //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
     928  if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
     929    config::EpsWannier = 1e-8;
     930
     931  // stop conditions
     932  //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
     933  ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
     934  if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
     935
     936  ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
     937  ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
     938  ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
     939  ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical);
     940  ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical);
     941  if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
     942  if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
     943  if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
     944
     945  ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
     946  ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
     947  ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
     948  ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
     949  ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical);
     950  if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
     951  if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
     952  if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
     953
     954  // Unit cell and magnetic field
     955  ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
     956  mol->cell_size[0] = BoxLength[0];
     957  mol->cell_size[1] = BoxLength[3];
     958  mol->cell_size[2] = BoxLength[4];
     959  mol->cell_size[3] = BoxLength[6];
     960  mol->cell_size[4] = BoxLength[7];
     961  mol->cell_size[5] = BoxLength[8];
     962  //if (1) fprintf(stderr,"\n");
     963
     964  ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional);
     965  ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional);
     966  if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional))
     967    config::DoFullCurrent = 0;
     968  if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
     969  if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
     970  if (config::DoOutNICS < 0) config::DoOutNICS = 0;
     971  if (config::DoOutNICS > 2) config::DoOutNICS = 2;
     972  if (config::DoPerturbation == 0) {
     973    config::DoFullCurrent = 0;
     974    config::DoOutNICS = 0;
     975  }
     976
     977  ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
     978  ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
     979  ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
     980  if (config::Lev0Factor < 2) {
     981    config::Lev0Factor = 2;
     982  }
     983  ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
     984  if (di >= 0 && di < 2) {
     985    config::RiemannTensor = di;
     986  } else {
     987    fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
     988    exit(1);
     989  }
     990  switch (config::RiemannTensor) {
     991    case 0: //UseNoRT
     992      if (config::MaxLevel < 2) {
     993        config::MaxLevel = 2;
     994      }
     995      config::LevRFactor = 2;
     996      config::RTActualUse = 0;
     997      break;
     998    case 1: // UseRT
     999      if (config::MaxLevel < 3) {
     1000        config::MaxLevel = 3;
     1001      }
     1002      ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
     1003      if (config::RiemannLevel < 2) {
     1004        config::RiemannLevel = 2;
     1005      }
     1006      if (config::RiemannLevel > config::MaxLevel-1) {
     1007        config::RiemannLevel = config::MaxLevel-1;
     1008      }
     1009      ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
     1010      if (config::LevRFactor < 2) {
     1011        config::LevRFactor = 2;
     1012      }
     1013      config::Lev0Factor = 2;
     1014      config::RTActualUse = 2;
     1015      break;
     1016  }
     1017  ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
     1018  if (di >= 0 && di < 2) {
     1019    config::PsiType = di;
     1020  } else {
     1021    fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
     1022    exit(1);
     1023  }
     1024  switch (config::PsiType) {
     1025  case 0: // SpinDouble
     1026    ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
     1027    ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
     1028    break;
     1029  case 1: // SpinUpDown
     1030    if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
     1031    ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
     1032    ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
     1033    ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
     1034    break;
     1035  }
     1036
     1037  // IonsInitRead
     1038
     1039  ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
     1040  ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
     1041  ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(MaxTypes), 1, critical);
     1042  if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional))
     1043    config::RelativeCoord = 0;
     1044  if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional))
     1045    config::StructOpt = 0;
     1046
     1047  // 2. parse the bond graph file if given
     1048  BG = new BondGraph(IsAngstroem);
     1049  if (BG->LoadBondLengthTable((ofstream *)&cout, BondGraphFileName)) {
     1050    cout << Verbose(0) << "Bond length table loaded successfully." << endl;
     1051  } else {
     1052    cout << Verbose(0) << "Bond length table loading failed." << endl;
     1053  }
     1054
     1055  // 3. parse the molecule in
     1056  LoadMolecule(mol, FileBuffer, periode, FastParsing);
     1057
     1058  // 4. split into connected subgraphs
     1059  MolList->DissectMoleculeIntoConnectedSubgraphs((ofstream *)&cout, mol, this);
     1060
     1061  delete(mol);
     1062  delete(FileBuffer);
     1063};
     1064
     1065
     1066/** Initializes config file structure by loading elements from a give file with old pcp syntax.
     1067 * \param *file input file stream being the opened config file with old pcp syntax
     1068 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed.
     1069 * \param *periode pointer to a periodentafel class with all elements
     1070 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system
     1071 */
     1072void config::LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList)
     1073{
     1074  molecule *mol = new molecule(periode);
     1075  ifstream *file = new ifstream(filename);
     1076  if (file == NULL) {
     1077    cerr << "ERROR: config file " << filename << " missing!" << endl;
     1078    return;
     1079  }
    10781080  RetrieveConfigPathAndName(filename);
    10791081  // ParseParameters
    10801082
    10811083  /* Oeffne Hauptparameterdatei */
    1082   int l, i, di;
    1083   double a,b;
     1084  int l = 0;
     1085  int i = 0;
     1086  int di = 0;
     1087  double a = 0.;
     1088  double b = 0.;
    10841089  double BoxLength[9];
    10851090  string zeile;
    10861091  string dummy;
    10871092  element *elementhash[128];
    1088   int Z, No, AtomNo, found;
     1093  int Z = -1;
     1094  int No = -1;
     1095  int AtomNo = -1;
     1096  int found = 0;
    10891097  int verbose = 0;
    10901098
     1099  mol->ActiveFlag = true;
     1100  MolList->insert(mol);
    10911101  /* Namen einlesen */
    10921102
     
    12201230  config::StructOpt = 0;
    12211231
     1232
     1233  // 2. parse the bond graph file if given
     1234  BG = new BondGraph(IsAngstroem);
     1235  if (BG->LoadBondLengthTable((ofstream *)&cout, BondGraphFileName)) {
     1236    cout << Verbose(0) << "Bond length table loaded successfully." << endl;
     1237  } else {
     1238    cout << Verbose(0) << "Bond length table loading failed." << endl;
     1239  }
     1240
    12221241  // Routine from builder.cpp
    1223 
    12241242
    12251243  for (i=MAX_ELEMENTS;i--;)
     
    12731291 * \param *mol pointer to molecule containing all atoms of the molecule
    12741292 */
    1275 bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
     1293bool config::Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const
    12761294{
    12771295  bool result = true;
    12781296  // bring MaxTypes up to date
    12791297  mol->CountElements();
    1280   ofstream *output = NULL;
    1281   output = new ofstream(filename, ios::out);
     1298  ofstream * const output = new ofstream(filename, ios::out);
    12821299  if (output != NULL) {
    12831300    *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
     
    14031420 * \param *mol pointer to molecule containing all atoms of the molecule
    14041421 */
    1405 bool config::SaveMPQC(const char *filename, molecule *mol) const
     1422bool config::SaveMPQC(const char * const filename, const molecule * const mol) const
    14061423{
    1407   int ElementNo = 0;
    1408   int AtomNo;
    1409   atom *Walker = NULL;
    1410   element *runner = NULL;
     1424  int AtomNo = -1;
    14111425  Vector *center = NULL;
    14121426  ofstream *output = NULL;
    1413   stringstream *fname = NULL;
    14141427
    14151428  // first without hessian
    1416   fname = new stringstream;
    1417   *fname << filename << ".in";
    1418   output = new ofstream(fname->str().c_str(), ios::out);
    1419   *output << "% Created by MoleCuilder" << endl;
    1420   *output << "mpqc: (" << endl;
    1421   *output << "\tsavestate = no" << endl;
    1422   *output << "\tdo_gradient = yes" << endl;
    1423   *output << "\tmole<MBPT2>: (" << endl;
    1424   *output << "\t\tmaxiter = 200" << endl;
    1425   *output << "\t\tbasis = $:basis" << endl;
    1426   *output << "\t\tmolecule = $:molecule" << endl;
    1427   *output << "\t\treference<CLHF>: (" << endl;
    1428   *output << "\t\t\tbasis = $:basis" << endl;
    1429   *output << "\t\t\tmolecule = $:molecule" << endl;
    1430   *output << "\t\t)" << endl;
    1431   *output << "\t)" << endl;
    1432   *output << ")" << endl;
    1433   *output << "molecule<Molecule>: (" << endl;
    1434   *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1435   *output << "\t{ atoms geometry } = {" << endl;
    1436   center = mol->DetermineCenterOfAll(output);
    1437   // output of atoms
    1438   runner = mol->elemente->start;
    1439   while (runner->next != mol->elemente->end) { // go through every element
    1440     runner = runner->next;
    1441     if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
    1442       ElementNo++;
    1443       AtomNo = 0;
    1444       Walker = mol->start;
    1445       while (Walker->next != mol->end) { // go through every atom of this element
    1446         Walker = Walker->next;
    1447         if (Walker->type == runner) { // if this atom fits to element
    1448           AtomNo++;
    1449           *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
    1450         }
    1451       }
    1452     }
    1453   }
    1454   delete(center);
    1455   *output << "\t}" << endl;
    1456   *output << ")" << endl;
    1457   *output << "basis<GaussianBasisSet>: (" << endl;
    1458   *output << "\tname = \"" << basis << "\"" << endl;
    1459   *output << "\tmolecule = $:molecule" << endl;
    1460   *output << ")" << endl;
    1461   output->close();
    1462   delete(output);
    1463   delete(fname);
     1429  {
     1430    stringstream * const fname = new stringstream;;
     1431    *fname << filename << ".in";
     1432    output = new ofstream(fname->str().c_str(), ios::out);
     1433    *output << "% Created by MoleCuilder" << endl;
     1434    *output << "mpqc: (" << endl;
     1435    *output << "\tsavestate = no" << endl;
     1436    *output << "\tdo_gradient = yes" << endl;
     1437    *output << "\tmole<MBPT2>: (" << endl;
     1438    *output << "\t\tmaxiter = 200" << endl;
     1439    *output << "\t\tbasis = $:basis" << endl;
     1440    *output << "\t\tmolecule = $:molecule" << endl;
     1441    *output << "\t\treference<CLHF>: (" << endl;
     1442    *output << "\t\t\tbasis = $:basis" << endl;
     1443    *output << "\t\t\tmolecule = $:molecule" << endl;
     1444    *output << "\t\t)" << endl;
     1445    *output << "\t)" << endl;
     1446    *output << ")" << endl;
     1447    *output << "molecule<Molecule>: (" << endl;
     1448    *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
     1449    *output << "\t{ atoms geometry } = {" << endl;
     1450    center = mol->DetermineCenterOfAll(output);
     1451    // output of atoms
     1452    AtomNo = 0;
     1453    mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
     1454    delete(center);
     1455    *output << "\t}" << endl;
     1456    *output << ")" << endl;
     1457    *output << "basis<GaussianBasisSet>: (" << endl;
     1458    *output << "\tname = \"" << basis << "\"" << endl;
     1459    *output << "\tmolecule = $:molecule" << endl;
     1460    *output << ")" << endl;
     1461    output->close();
     1462    delete(output);
     1463    delete(fname);
     1464  }
    14641465
    14651466  // second with hessian
    1466   fname = new stringstream;
    1467   *fname << filename << ".hess.in";
    1468   output = new ofstream(fname->str().c_str(), ios::out);
    1469   *output << "% Created by MoleCuilder" << endl;
    1470   *output << "mpqc: (" << endl;
    1471   *output << "\tsavestate = no" << endl;
    1472   *output << "\tdo_gradient = yes" << endl;
    1473   *output << "\tmole<CLHF>: (" << endl;
    1474   *output << "\t\tmaxiter = 200" << endl;
    1475   *output << "\t\tbasis = $:basis" << endl;
    1476   *output << "\t\tmolecule = $:molecule" << endl;
    1477   *output << "\t)" << endl;
    1478   *output << "\tfreq<MolecularFrequencies>: (" << endl;
    1479   *output << "\t\tmolecule=$:molecule" << endl;
    1480   *output << "\t)" << endl;
    1481   *output << ")" << endl;
    1482   *output << "molecule<Molecule>: (" << endl;
    1483   *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1484   *output << "\t{ atoms geometry } = {" << endl;
    1485   center = mol->DetermineCenterOfAll(output);
    1486   // output of atoms
    1487   runner = mol->elemente->start;
    1488   while (runner->next != mol->elemente->end) { // go through every element
    1489     runner = runner->next;
    1490     if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
    1491       ElementNo++;
    1492       AtomNo = 0;
    1493       Walker = mol->start;
    1494       while (Walker->next != mol->end) { // go through every atom of this element
    1495         Walker = Walker->next;
    1496         if (Walker->type == runner) { // if this atom fits to element
    1497           AtomNo++;
    1498           *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
    1499         }
    1500       }
    1501     }
    1502   }
    1503   delete(center);
    1504   *output << "\t}" << endl;
    1505   *output << ")" << endl;
    1506   *output << "basis<GaussianBasisSet>: (" << endl;
    1507   *output << "\tname = \"3-21G\"" << endl;
    1508   *output << "\tmolecule = $:molecule" << endl;
    1509   *output << ")" << endl;
    1510   output->close();
    1511   delete(output);
    1512   delete(fname);
     1467  {
     1468    stringstream * const fname = new stringstream;
     1469    *fname << filename << ".hess.in";
     1470    output = new ofstream(fname->str().c_str(), ios::out);
     1471    *output << "% Created by MoleCuilder" << endl;
     1472    *output << "mpqc: (" << endl;
     1473    *output << "\tsavestate = no" << endl;
     1474    *output << "\tdo_gradient = yes" << endl;
     1475    *output << "\tmole<CLHF>: (" << endl;
     1476    *output << "\t\tmaxiter = 200" << endl;
     1477    *output << "\t\tbasis = $:basis" << endl;
     1478    *output << "\t\tmolecule = $:molecule" << endl;
     1479    *output << "\t)" << endl;
     1480    *output << "\tfreq<MolecularFrequencies>: (" << endl;
     1481    *output << "\t\tmolecule=$:molecule" << endl;
     1482    *output << "\t)" << endl;
     1483    *output << ")" << endl;
     1484    *output << "molecule<Molecule>: (" << endl;
     1485    *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
     1486    *output << "\t{ atoms geometry } = {" << endl;
     1487    center = mol->DetermineCenterOfAll(output);
     1488    // output of atoms
     1489    AtomNo = 0;
     1490    mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
     1491    delete(center);
     1492    *output << "\t}" << endl;
     1493    *output << ")" << endl;
     1494    *output << "basis<GaussianBasisSet>: (" << endl;
     1495    *output << "\tname = \"3-21G\"" << endl;
     1496    *output << "\tmolecule = $:molecule" << endl;
     1497    *output << ")" << endl;
     1498    output->close();
     1499    delete(output);
     1500    delete(fname);
     1501  }
    15131502
    15141503  return true;
     
    15361525 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
    15371526 */
    1538 int config::ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) {
    1539   int i,j;  // loop variables
    1540   int length = 0, maxlength = -1;
     1527int ParseForParameter(const int verbose, ifstream * const file, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) {
     1528  int i = 0;
     1529  int j = 0;  // loop variables
     1530  int length = 0;
     1531  int maxlength = -1;
    15411532  long file_position = file->tellg(); // mark current position
    1542   char *dummy1, *dummy, *free_dummy;    // pointers in the line that is read in per step
    1543   dummy1 = free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy");
     1533  char *dummy1 = NULL;
     1534  char *dummy = NULL;
     1535  char * const free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy");    // pointers in the line that is read in per step
     1536  dummy1 = free_dummy;
    15441537
    15451538  //fprintf(stderr,"Parsing for %s\n",name);
     
    15561549      if (file->eof()) {
    15571550        if ((critical) && (found == 0)) {
    1558           Free(&free_dummy);
     1551          Free(free_dummy);
    15591552          //Error(InitReading, name);
    15601553          fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
     
    15641557          file->clear();
    15651558          file->seekg(file_position, ios::beg);  // rewind to start position
    1566           Free(&free_dummy);
     1559          Free(free_dummy);
    15671560          return 0;
    15681561        }
     
    16161609              if (file->eof()) {
    16171610                if ((critical) && (found == 0)) {
    1618                   Free(&free_dummy);
     1611                  Free(free_dummy);
    16191612                  //Error(InitReading, name);
    16201613                  fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
     
    16241617                  file->clear();
    16251618                  file->seekg(file_position, ios::beg);  // rewind to start position
    1626                   Free(&free_dummy);
     1619                  Free(free_dummy);
    16271620                  return 0;
    16281621                }
     
    16651658                  if (critical) {
    16661659                    if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
    1667                     Free(&free_dummy);
     1660                    Free(free_dummy);
    16681661                    //return 0;
    16691662                    exit(255);
     
    16731666                    file->clear();
    16741667                    file->seekg(file_position, ios::beg);  // rewind to start position
    1675                     Free(&free_dummy);
     1668                    Free(free_dummy);
    16761669                    return 0;
    16771670                  }
     
    16861679                  file->seekg(file_position, ios::beg);  // rewind to start position
    16871680                }
    1688                 Free(&free_dummy);
     1681                Free(free_dummy);
    16891682                return 0;
    16901683              }
     
    17421735  if ((type >= row_int) && (verbose))
    17431736    fprintf(stderr,"\n");
    1744   Free(&free_dummy);
     1737  Free(free_dummy);
    17451738  if (!sequential) {
    17461739    file->clear();
     
    17741767 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
    17751768 */
    1776 int config::ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) {
    1777   int i,j;  // loop variables
    1778   int length = 0, maxlength = -1;
     1769int ParseForParameter(const int verbose, struct ConfigFileBuffer * const FileBuffer, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) {
     1770  int i = 0;
     1771  int j = 0;  // loop variables
     1772  int length = 0;
     1773  int maxlength = -1;
    17791774  int OldCurrentLine = FileBuffer->CurrentLine;
    1780   char *dummy1, *dummy;    // pointers in the line that is read in per step
     1775  char *dummy1 = NULL;
     1776  char *dummy = NULL;    // pointers in the line that is read in per step
    17811777
    17821778  //fprintf(stderr,"Parsing for %s\n",name);
  • src/config.hpp

    r06c7a3 r7326b2  
    1111using namespace std;
    1212
     13class MoleculeListClass;
     14
    1315/*********************************************** includes ***********************************/
    1416
     
    1921
    2022#include <string>
     23
     24#include "bondgraph.hpp"
    2125
    2226/****************************************** forward declarations *****************************/
     
    3539
    3640    ConfigFileBuffer();
    37     ConfigFileBuffer(char *filename);
     41    ConfigFileBuffer(const char * const filename);
    3842    ~ConfigFileBuffer();
    3943
    4044    void InitMapping();
    41     void MapIonTypesInBuffer(int NoAtoms);
     45    void MapIonTypesInBuffer(const int NoAtoms);
    4246};
    4347
     
    4751class config {
    4852  public:
     53    class BondGraph *BG;
     54
    4955    int PsiType;
    5056    int MaxPsiDouble;
     
    126132
    127133
    128   int ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
    129   int ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
    130 
    131134  public:
    132135  config();
    133136  ~config();
    134137
    135   int TestSyntax(char *filename, periodentafel *periode, molecule *mol);
    136   void Load(char *filename, periodentafel *periode, molecule *mol);
    137   void LoadOld(char *filename, periodentafel *periode, molecule *mol);
    138   void RetrieveConfigPathAndName(string filename);
    139   bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
    140   bool SaveMPQC(const char *filename, molecule *mol) const;
     138  int TestSyntax(const char * const filename, const periodentafel * const periode) const;
     139  void Load(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList);
     140  void LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList);
     141  void RetrieveConfigPathAndName(const string filename);
     142  bool Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const;
     143  bool SaveMPQC(const char * const filename, const molecule * const mol) const;
    141144  void Edit();
    142145  bool GetIsAngstroem() const;
    143146  char *GetDefaultPath() const;
    144   void SetDefaultPath(const char *path);
    145   void InitThermostats(class ConfigFileBuffer *fb);
     147  void SetDefaultPath(const char * const path);
     148  void InitThermostats();
     149  void ParseThermostats(class ConfigFileBuffer * const fb);
    146150};
    147151
     152int ParseForParameter(const int verbose, ifstream * const file, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical);
     153int ParseForParameter(const int verbose, struct ConfigFileBuffer * const FileBuffer, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical);
     154void LoadMolecule(molecule * const &mol, struct ConfigFileBuffer * const &FileBuffer, const periodentafel * const periode, const bool FastParsing);
     155void PrepareFileBuffer(const char * const filename, struct ConfigFileBuffer *&FileBuffer);
     156
    148157#endif /* CONFIG_HPP_ */
  • src/ellipsoid.cpp

    r06c7a3 r7326b2  
    234234  int index;
    235235  TesselPoint *Candidate = NULL;
    236   LinkedNodes *List = NULL;
    237236  *out << Verbose(2) << "Begin of PickRandomPointSet" << endl;
    238237
     
    249248    *out << Verbose(2) << "INFO: Center cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " ... ";
    250249    // get random cell
    251     List = LC->GetCurrentCell();
     250    const LinkedNodes *List = LC->GetCurrentCell();
    252251    if (List == NULL) {  // set index to it
    253252      continue;
     
    268267      for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    269268        for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    270           List = LC->GetCurrentCell();
     269          const LinkedNodes *List = LC->GetCurrentCell();
    271270          PointsLeft += List->size();
    272271        }
     
    293292      for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    294293        for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    295           List = LC->GetCurrentCell();
     294          const LinkedNodes *List = LC->GetCurrentCell();
    296295//          *out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
    297296          if (List != NULL) {
     
    300299//            else
    301300//              *out << Verbose(2) << "Cell is empty ... " << endl;
    302             for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     301            for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    303302              if ((current != PickedAtomNrs.end()) && (*current == index)) {
    304303                Candidate = (*Runner);
  • src/helpers.cpp

    r06c7a3 r7326b2  
    66
    77#include "helpers.hpp"
     8
     9#include "memoryusageobserver.hpp"
    810
    911/********************************************** helpful functions *********************************/
     
    4749  while (*b < lower_bound)
    4850    *b += step;
    49 };
    50 
    51 /** Flips two doubles.
    52  * \param *x pointer to first double
    53  * \param *y pointer to second double
    54  */
    55 void flip(double *x, double *y)
    56 {
    57   double tmp;
    58   tmp = *x;
    59   *x = *y;
    60   *y = tmp;
    6151};
    6252
     
    143133 * \return allocated NDIM*NDIM array with the symmetric matrix
    144134 */
    145 double * ReturnFullMatrixforSymmetric(double *symm)
     135double * ReturnFullMatrixforSymmetric(const double * const symm)
    146136{
    147137  double *matrix = Malloc<double>(NDIM * NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
     
    158148};
    159149
     150/** Calculate the inverse of a 3x3 matrix.
     151 * \param *matrix NDIM_NDIM array
     152 */
     153double * InverseMatrix( const double * const A)
     154{
     155  double *B = Malloc<double>(NDIM * NDIM, "Vector::InverseMatrix: *B");
     156  double detA = RDET3(A);
     157  double detAReci;
     158
     159  for (int i=0;i<NDIM*NDIM;++i)
     160    B[i] = 0.;
     161  // calculate the inverse B
     162  if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
     163    detAReci = 1./detA;
     164    B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);    // A_11
     165    B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);    // A_12
     166    B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);    // A_13
     167    B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);    // A_21
     168    B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);    // A_22
     169    B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);    // A_23
     170    B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);    // A_31
     171    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
     172    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
     173  }
     174  return B;
     175};
     176
     177/** hard-coded determinant of a 3x3 matrix.
     178 * \param a[9] matrix
     179 * \return \f$det(a)\f$
     180 */
     181double RDET3(const double a[NDIM*NDIM])
     182{
     183  return ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3]);
     184};
     185
     186/** hard-coded determinant of a 2x2 matrix.
     187 * \param a[4] matrix
     188 * \return \f$det(a)\f$
     189 */
     190double RDET2(const double a[4])
     191{
     192  return ((a[0])*(a[3])-(a[1])*(a[2]));
     193};
     194
     195/** hard-coded determinant of a 2x2 matrix.
     196 * \param a0 (0,0) entry of matrix
     197 * \param a1 (0,1) entry of matrix
     198 * \param a2 (1,0) entry of matrix
     199 * \param a3 (1,1) entry of matrix
     200 * \return \f$det(a)\f$
     201 */
     202double RDET2(const double a0, const double a1, const double a2, const double a3)
     203{
     204  return ((a0)*(a3)-(a1)*(a2));
     205};
     206
    160207/** Comparison function for GSL heapsort on distances in two molecules.
    161208 * \param *a
     
    202249 * Frees all memory registered by the memory observer and calls exit(225) afterwards.
    203250 */
    204 static void performCriticalExit() {
     251void performCriticalExit() {
    205252  map<void*, size_t> pointers = MemoryUsageObserver::getInstance()->getPointersToAllocatedMemory();
    206253  for (map<void*, size_t>::iterator runner = pointers.begin(); runner != pointers.end(); runner++) {
  • src/helpers.hpp

    • Property mode changed from 100755 to 100644
    r06c7a3 r7326b2  
    1818#include <fstream>
    1919
     20#include "defs.hpp"
    2021#include "memoryallocator.hpp"
     22
     23/********************************************** definitions *********************************/
     24
     25// some algebraic matrix stuff
     26double RDET3(const double a[NDIM*NDIM]);
     27double RDET2(const double a[4]);
     28double RDET2(const double a0, const double a1, const double a2, const double a3);
    2129
    2230/********************************************** helpful functions *********************************/
     
    4452bool check_bounds(double *x, double *cell_size);
    4553void bound(double *b, double lower_bound, double upper_bound);
    46 void flip(double *x, double *y);
    4754int pot(int base, int n);
    4855int CountLinesinFile(ifstream &InputFile);
     
    5057bool IsValidNumber( const char *string);
    5158int CompareDoubles (const void * a, const void * b);
    52 double * ReturnFullMatrixforSymmetric(double *cell_size);
    53 static void performCriticalExit();
     59double * ReturnFullMatrixforSymmetric(const double * const cell_size);
     60double * InverseMatrix(const double * const A);
     61void performCriticalExit();
    5462
    5563/********************************************** helpful template functions *********************************/
     64
     65/** Flips two values.
     66 * \param x first value
     67 * \param y second value
     68 */
     69template <typename T> void flip(T &x, T &y)
     70{
     71  T tmp;
     72  tmp = x;
     73  x = y;
     74  y = tmp;
     75};
    5676
    5777/** Creates a lookup table for true father's Atom::Nr -> atom ptr.
     
    6080 * \paran *end end of chain list
    6181 * \param **Lookuptable pointer to return allocated lookup table (should be NULL on start)
    62  * \param count optional predetermined count for table (otherwise we set the count to highest true father id)
     82 * \param count optional predetermined size for table (otherwise we set the count to highest true father id)
    6383 * \return true - success, false - failure
    6484 */
     
    87107  }
    88108
    89   // allocat and fill
    90   LookupTable = Malloc<T*>(count, "CreateFatherLookupTable - **LookupTable");
     109  // allocate and fill
     110  LookupTable = Calloc<T*>(count, "CreateFatherLookupTable - **LookupTable");
    91111  if (LookupTable == NULL) {
    92112    cerr << "LookupTable memory allocation failed!" << endl;
    93113    status = false;
    94114  } else {
    95     for (int i=0;i<count;i++)
    96       LookupTable[i] = NULL;
    97115    Walker = start;
    98116    while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
  • src/leastsquaremin.cpp

    r06c7a3 r7326b2  
    1616 * \return sum of square distances
    1717 */
    18 double LSQ (const gsl_vector * x, void * params)
     18double LSQ (const gsl_vector * const x, void * params)
    1919{
    2020  double sum = 0.;
    2121  struct LSQ_params *par = (struct LSQ_params *)params;
    22   Vector **vectors = par->vectors;
     22  const Vector ** vectors = par->vectors;
    2323  int num = par->num;
    2424
  • src/leastsquaremin.hpp

    r06c7a3 r7326b2  
    3131 */
    3232struct LSQ_params {
    33   Vector **vectors;
     33  const Vector **vectors;
    3434  int num;
    3535};
    3636
    37 double LSQ(const gsl_vector * x, void * params);
     37double LSQ(const gsl_vector * const x, void * params);
    3838
    3939/** Parameter structure for least square minimsation.
  • src/linkedcell.cpp

    r06c7a3 r7326b2  
    3333 * \param RADIUS edge length of cells
    3434 */
    35 LinkedCell::LinkedCell(PointCloud *set, double radius)
     35LinkedCell::LinkedCell(const PointCloud * const set, const double radius)
    3636{
    3737  TesselPoint *Walker = NULL;
     
    109109 * \param RADIUS edge length of cells
    110110 */
    111 LinkedCell::LinkedCell(LinkedNodes *set, double radius)
     111LinkedCell::LinkedCell(LinkedNodes *set, const double radius)
    112112{
    113113  class TesselPoint *Walker = NULL;
     
    192192 * \return if all in intervals - true, else -false
    193193 */
    194 bool LinkedCell::CheckBounds()
     194bool LinkedCell::CheckBounds() const
    195195{
    196196  bool status = true;
     
    202202};
    203203
     204/** Checks whether LinkedCell::n[] plus relative offset is each within [0,N[]].
     205 * Note that for this check we don't admonish if out of bounds.
     206 * \param relative[NDIM] relative offset to current cell
     207 * \return if all in intervals - true, else -false
     208 */
     209bool LinkedCell::CheckBounds(const int relative[NDIM]) const
     210{
     211  bool status = true;
     212  for(int i=0;i<NDIM;i++)
     213    status = status && ((n[i]+relative[i] >=0) && (n[i]+relative[i] < N[i]));
     214  return status;
     215};
     216
    204217
    205218/** Returns a pointer to the current cell.
    206219 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds.
    207220 */
    208 LinkedNodes* LinkedCell::GetCurrentCell()
     221const LinkedNodes* LinkedCell::GetCurrentCell() const
    209222{
    210223  if (CheckBounds()) {
     
    216229};
    217230
     231/** Returns a pointer to the current cell.
     232 * \param relative[NDIM] offset for each axis with respect to the current cell LinkedCell::n[NDIM]
     233 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[]+relative[] are out of bounds.
     234 */
     235const LinkedNodes* LinkedCell::GetRelativeToCurrentCell(const int relative[NDIM]) const
     236{
     237  if (CheckBounds(relative)) {
     238    index = (n[0]+relative[0]) * N[1] * N[2] + (n[1]+relative[1]) * N[2] + (n[2]+relative[2]);
     239    return (&(LC[index]));
     240  } else {
     241    return NULL;
     242  }
     243};
     244
    218245/** Calculates the index for a given LCNode *Walker.
    219246 * \param *Walker LCNode to set index tos
    220247 * \return if the atom is also found in this cell - true, else - false
    221248 */
    222 bool LinkedCell::SetIndexToNode(const TesselPoint *Walker)
     249bool LinkedCell::SetIndexToNode(const TesselPoint * const Walker) const
    223250{
    224251  bool status = false;
     
    241268 * \param *upper upper bounds
    242269 */
    243 void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM])
     270void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM]) const
    244271{
    245272  for (int i=0;i<NDIM;i++) {
     
    261288 * \return Vector is inside bounding box - true, else - false
    262289 */
    263 bool LinkedCell::SetIndexToVector(const Vector *x)
     290bool LinkedCell::SetIndexToVector(const Vector * const x) const
    264291{
    265292  bool status = true;
  • src/linkedcell.hpp

    r06c7a3 r7326b2  
    4646    double RADIUS;    // cell edge length
    4747    int N[NDIM];      // number of cells per axis
    48     int n[NDIM];      // temporary variable for current cell per axis
    49     int index;        // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
     48    mutable int n[NDIM];      // temporary variable for current cell per axis
     49    mutable int index;        // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
    5050
    5151    LinkedCell();
    52     LinkedCell(PointCloud *set, double RADIUS);
    53     LinkedCell(LinkedNodes *set, double radius);
     52    LinkedCell(const  PointCloud * const set, const double RADIUS);
     53    LinkedCell(LinkedNodes *set, const double radius);
    5454    ~LinkedCell();
    55     LinkedNodes* GetCurrentCell();
    56     bool SetIndexToNode(const TesselPoint *Walker);
    57     bool SetIndexToVector(const Vector *x);
    58     bool CheckBounds();
    59     void GetNeighbourBounds(int lower[NDIM], int upper[NDIM]);
     55    const LinkedNodes* GetCurrentCell()const ;
     56    const LinkedNodes* GetRelativeToCurrentCell(const int relative[NDIM])const ;
     57    bool SetIndexToNode(const TesselPoint * const Walker)const ;
     58    bool SetIndexToVector(const Vector * const x)const ;
     59    bool CheckBounds()const ;
     60    bool CheckBounds(const int relative[NDIM])const ;
     61    void GetNeighbourBounds(int lower[NDIM], int upper[NDIM])const ;
    6062
    6163    // not implemented yet
  • src/lists.hpp

    r06c7a3 r7326b2  
    3535  if (walker->previous != NULL)
    3636    walker->previous->next = walker->next;
     37  walker->next = NULL;
     38  walker->previous= NULL;
    3739};
    3840
     
    112114{
    113115  X *pointer = start->next;
    114   X *walker;
     116  X *walker = NULL;
    115117  while (pointer != end) { // go through list
    116118    walker = pointer; // mark current
    117119    pointer = pointer->next; // step onward beforehand
    118120    // remove walker
    119     unlink(walker);
    120     delete(walker);
    121     walker = NULL;
     121    removewithoutcheck(walker);
    122122  }
    123123  return true;
  • src/memoryallocator.hpp

    r06c7a3 r7326b2  
    5555template <> char* Malloc<char>(size_t size, const char* output);
    5656
    57 /** Allocates a memory range using calloc().
     57/* Allocates a memory range using calloc().
    5858 * Prints the provided error message in case of a failure.
    5959 *
     
    6161 * \param failure message which is printed if the allocation fails
    6262 * \return pointer to the allocated memory range, will be NULL if a failure occurred
    63  */
     63*/
    6464template <typename X> X* Calloc(size_t size, const char* output)
    6565{
    6666  X* buffer = NULL;
    67   buffer = (X*) calloc(sizeof(X) * size, (size_t) 0);
     67  buffer = (X*) calloc(size, sizeof(X));
    6868
    6969  if (buffer != NULL) {
     
    7676  return buffer;
    7777};
     78
    7879
    7980/** Reallocates a memory range using realloc(). If the provided pointer to the old
     
    105106};
    106107
    107 /** Frees allocated memory range using free().
     108/** Frees allocated memory range using free(), NULL'ing \a **buffer.
    108109 *
    109  * \param pointer to the allocated memory range to free; may be NULL, this function is a no-op then
     110 * \param **buffer to the allocated memory range to free; may be NULL, this function is a no-op then
    110111 * \param *msg optional error message
    111112 */
     
    120121};
    121122
     123/** Frees allocated memory range using free() for ... * const \a buffer types.
     124 *
     125 * \param *buffer to the allocated memory range to free; may be NULL, this function is a no-op then
     126 * \param *msg optional error message
     127 */
     128template <typename X> void Free(X* const buffer, const char *msg = NULL)
     129{
     130  if ((buffer == NULL))
     131    return;
     132
     133  MemoryUsageObserver::getInstance()->removeMemory(buffer, msg);
     134  free(buffer);
     135};
     136
    122137#endif /*MEMORYALLOCATOR_HPP_*/
  • src/memoryusageobserver.cpp

    r06c7a3 r7326b2  
    2323 */
    2424MemoryUsageObserver::~MemoryUsageObserver() {
    25   for (map<void*, size_t>::iterator current = memoryUsers.begin(); current != memoryUsers.end(); current++) {
     25  while (!memoryUsers.empty()) {
     26    map<void*, size_t>::iterator current = memoryUsers.begin();
     27    free(current->first);
    2628    memoryUsers.erase(current);
    2729  }
  • src/molecule.cpp

    r06c7a3 r7326b2  
    2626 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    2727 */
    28 molecule::molecule(periodentafel *teil)
     28molecule::molecule(const periodentafel * const teil) : elemente(teil), start(new atom), end(new atom),
     29  first(new bond(start, end, 1, -1)), last(new bond(start, end, 1, -1)), MDSteps(0), AtomCount(0),
     30  BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), NoCyclicBonds(0), BondDistance(0.),
     31  ActiveFlag(false), IndexNr(-1), last_atom(0), InternalPointer(start)
    2932{
    3033  // init atom chain list
    31   start = new atom;
    32   end = new atom;
    3334  start->father = NULL;
    3435  end->father = NULL;
    3536  link(start,end);
    36   InternalPointer = start;
     37
    3738  // init bond chain list
    38   first = new bond(start, end, 1, -1);
    39   last = new bond(start, end, 1, -1);
    4039  link(first,last);
     40
    4141  // other stuff
    42   MDSteps = 0;
    43   last_atom = 0;
    44   elemente = teil;
    45   AtomCount = 0;
    46   BondCount = 0;
    47   NoNonBonds = 0;
    48   NoNonHydrogen = 0;
    49   NoCyclicBonds = 0;
    50   ListOfBondsPerAtom = NULL;
    51   NumberOfBondsPerAtom = NULL;
    52   ElementCount = 0;
    5342  for(int i=MAX_ELEMENTS;i--;)
    5443    ElementsInMolecule[i] = 0;
     
    5645  cell_size[1] = cell_size[3] = cell_size[4]= 0.;
    5746  strcpy(name,"none");
    58   IndexNr  = -1;
    59   ActiveFlag = false;
    60   TesselStruct = NULL;
    6147};
    6248
     
    6652molecule::~molecule()
    6753{
    68   if (ListOfBondsPerAtom != NULL)
    69     for(int i=AtomCount;i--;)
    70       Free(&ListOfBondsPerAtom[i]);
    71   Free(&ListOfBondsPerAtom);
    72   Free(&NumberOfBondsPerAtom);
    73   if (TesselStruct != NULL)
    74     delete(TesselStruct);
    7554  CleanupMolecule();
    7655  delete(first);
     
    160139 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length
    161140 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    162  * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    163  * \param NumBond  number of bonds in \a **BondList
    164141 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    165142 * \return number of atoms added, if < bond::BondDegree then something went wrong
    166143 * \todo double and triple bonds splitting (always use the tetraeder angle!)
    167144 */
    168 bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
     145bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem)
    169146{
    170147  double bondlength;  // bond length of the bond to be replaced/cut
     
    177154  Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
    178155  Vector InBondvector;    // vector in direction of *Bond
     156  double *matrix;
    179157  bond *Binder = NULL;
    180   double *matrix;
    181158
    182159//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     
    248225    case 2:
    249226      // determine two other bonds (warning if there are more than two other) plus valence sanity check
    250       for (int i=0;i<NumBond;i++) {
    251         if (BondList[i] != TopBond) {
     227      for (BondList::const_iterator Runner = TopOrigin->ListOfBonds.begin(); Runner != TopOrigin->ListOfBonds.end(); (++Runner)) {
     228        if ((*Runner) != TopBond) {
    252229          if (FirstBond == NULL) {
    253             FirstBond = BondList[i];
    254             FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     230            FirstBond = (*Runner);
     231            FirstOtherAtom = (*Runner)->GetOtherAtom(TopOrigin);
    255232          } else if (SecondBond == NULL) {
    256             SecondBond = BondList[i];
    257             SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     233            SecondBond = (*Runner);
     234            SecondOtherAtom = (*Runner)->GetOtherAtom(TopOrigin);
    258235          } else {
    259236            *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     
    506483
    507484    // get the pendant atoms of current bond in the copy molecule
    508     copy->ActOnAllAtoms( &atom::EqualsFather, Binder->leftatom, &LeftAtom );
    509     copy->ActOnAllAtoms( &atom::EqualsFather, Binder->rightatom, &RightAtom );
     485    copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom );
     486    copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom );
    510487
    511488    NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
     
    523500  if (first->next != last) {  // if adjaceny list is present
    524501    copy->BondDistance = BondDistance;
    525     copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    526502  }
    527503
     
    536512 * @param three vectors forming the matrix that defines the shape of the parallelpiped
    537513 */
    538 molecule* molecule::CopyMoleculeFromSubRegion(Vector offset, double *parallelepiped) {
     514molecule* molecule::CopyMoleculeFromSubRegion(const Vector offset, const double *parallelepiped) const {
    539515  molecule *copy = new molecule(elemente);
    540516
     
    557533  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    558534    Binder = new bond(atom1, atom2, degree, BondCount++);
     535    atom1->RegisterBond(Binder);
     536    atom2->RegisterBond(Binder);
    559537    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    560538      NoNonBonds++;
     
    566544};
    567545
    568 /** Remove bond from bond chain list.
     546/** Remove bond from bond chain list and from the both atom::ListOfBonds.
    569547 * \todo Function not implemented yet
    570548 * \param *pointer bond pointer
     
    574552{
    575553  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     554  pointer->leftatom->RegisterBond(pointer);
     555  pointer->rightatom->RegisterBond(pointer);
    576556  removewithoutcheck(pointer);
    577557  return true;
     
    585565bool molecule::RemoveBonds(atom *BondPartner)
    586566{
    587   cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     567  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     568  BondList::const_iterator ForeRunner;
     569  while (!BondPartner->ListOfBonds.empty()) {
     570    ForeRunner = BondPartner->ListOfBonds.begin();
     571    RemoveBond(*ForeRunner);
     572  }
    588573  return false;
    589574};
     
    635620  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    636621    ElementCount--;
     622  RemoveBonds(pointer);
    637623  return remove(pointer, start, end);
    638624};
     
    661647bool molecule::CleanupMolecule()
    662648{
    663   return (cleanup(start,end) && cleanup(first,last));
     649  return (cleanup(first,last) && cleanup(start,end));
    664650};
    665651
     
    735721        ElementNo[i] = current++;
    736722    }
    737     ActOnAllAtoms( &atom::Output, out, ElementNo, AtomNo, (const char *) NULL ); // (bool (atom::*)(int *, int *, ofstream *, const char *))
     723    ActOnAllAtoms( &atom::OutputArrayIndexed, (ofstream *)out, (const int *)ElementNo, (int *)AtomNo, (const char *) NULL );
    738724    return true;
    739725  }
     
    767753          ElementNo[i] = current++;
    768754      }
    769       ActOnAllAtoms( &atom::OutputTrajectory, out, ElementNo, AtomNo, step );
     755      ActOnAllAtoms( &atom::OutputTrajectory, out, (const int *)ElementNo, AtomNo, (const int)step );
    770756    }
    771757    return true;
     
    773759};
    774760
    775 /** Outputs contents of molecule::ListOfBondsPerAtom.
     761/** Outputs contents of each atom::ListOfBonds.
    776762 * \param *out output stream
    777763 */
    778764void molecule::OutputListOfBonds(ofstream *out) const
    779765{
    780   *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    781   ActOnAllAtoms (&atom::OutputBondOfAtom, out, NumberOfBondsPerAtom, ListOfBondsPerAtom);
     766  *out << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl;
     767  ActOnAllAtoms (&atom::OutputBondOfAtom, out);
    782768  *out << endl;
    783769};
     
    902888};
    903889
    904 
    905 /** Creates an 2d array of pointer with an entry for each atom and each bond it has.
    906  * Updates molecule::ListOfBondsPerAtom, molecule::NumberOfBondsPerAtom by parsing through
    907  * bond chain list, using molecule::AtomCount and molecule::BondCount.
    908  * Allocates memory, fills the array and exits
    909  * \param *out output stream for debugging
    910  */
    911 void molecule::CreateListOfBondsPerAtom(ofstream *out)
    912 {
    913   bond *Binder = NULL;
    914   *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    915 
    916   // re-allocate memory
    917   *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    918   if (ListOfBondsPerAtom != NULL) {
    919     for(int i=AtomCount;i--;)
    920       Free(&ListOfBondsPerAtom[i]);
    921     Free(&ListOfBondsPerAtom);
    922   }
    923   if (NumberOfBondsPerAtom != NULL)
    924     Free(&NumberOfBondsPerAtom);
    925   ListOfBondsPerAtom = Malloc<bond**>(AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    926   NumberOfBondsPerAtom = Malloc<int>(AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    927 
    928   // reset bond counts per atom
    929   for(int i=AtomCount;i--;)
    930     NumberOfBondsPerAtom[i] = 0;
    931   // count bonds per atom
    932   Binder = first;
    933   while (Binder->next != last) {
    934     Binder = Binder->next;
    935     NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    936     NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    937   }
    938   for(int i=AtomCount;i--;) {
    939     // allocate list of bonds per atom
    940     ListOfBondsPerAtom[i] = Malloc<bond*>(NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    941     // clear the list again, now each NumberOfBondsPerAtom marks current free field
    942     NumberOfBondsPerAtom[i] = 0;
    943   }
    944   // fill the list
    945   Binder = first;
    946   while (Binder->next != last) {
    947     Binder = Binder->next;
    948     ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    949     ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    950   }
    951 
    952   // output list for debugging
    953   *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    954   ActOnAllAtoms( &atom::OutputBondOfAtom, out, NumberOfBondsPerAtom, ListOfBondsPerAtom );
    955 
    956   *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    957 };
    958 
    959890/** Determines whether two molecules actually contain the same atoms and coordination.
    960891 * \param *out output stream for debugging
     
    1026957  if (result) {
    1027958    *out << Verbose(5) << "Calculating distances" << endl;
    1028     Distances = Malloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    1029     OtherDistances = Malloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
    1030     SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, CenterOfGravity);
    1031     SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, CenterOfGravity);
     959    Distances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
     960    OtherDistances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     961    SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
     962    SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
    1032963
    1033964    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    1034965    *out << Verbose(5) << "Sorting distances" << endl;
    1035     PermMap = Malloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    1036     OtherPermMap = Malloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     966    PermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
     967    OtherPermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    1037968    gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    1038969    gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    1039     PermutationMap = Malloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     970    PermutationMap = Calloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    1040971    *out << Verbose(5) << "Combining Permutation Maps" << endl;
    1041972    for(int i=AtomCount;i--;)
     
    11351066  for (int step=startstep;step < endstep; step++) { // loop over all time steps
    11361067    temperature = 0.;
    1137     ActOnAllAtoms( &atom::AddKineticToTemperature, &temperature, step);
     1068    ActOnAllAtoms( &TrajectoryParticle::AddKineticToTemperature, &temperature, step);
    11381069    *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
    11391070  }
     
    11411072};
    11421073
    1143 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int TesselPoint::*index)
     1074void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const
    11441075{
    11451076  atom *Walker = start;
  • src/molecule.hpp

    r06c7a3 r7326b2  
    3535class atom;
    3636class bond;
     37class BondedParticle;
     38class BondGraph;
    3739class element;
    3840class ForceMatrix;
     
    8183  public:
    8284    double cell_size[6];//!< cell size
    83     periodentafel *elemente; //!< periodic table with each element
     85    const periodentafel * const elemente; //!< periodic table with each element
    8486    atom *start;        //!< start of atom list
    8587    atom *end;          //!< end of atom list
    8688    bond *first;        //!< start of bond list
    8789    bond *last;         //!< end of bond list
    88     bond ***ListOfBondsPerAtom; //!< pointer list for each atom and each bond it has
    8990    int MDSteps;        //!< The number of MD steps in Trajectories
    90     int *NumberOfBondsPerAtom;  //!< Number of Bonds each atom has
    9191    int AtomCount;          //!< number of atoms, brought up-to-date by CountAtoms()
    9292    int BondCount;          //!< number of atoms, brought up-to-date by CountBonds()
    9393    int ElementCount;       //!< how many unique elements are therein
    9494    int ElementsInMolecule[MAX_ELEMENTS]; //!< list whether element (sorted by atomic number) is alread present or not
    95     int NoNonHydrogen;  //!< number of non-hydrogen atoms in molecule
    96     int NoNonBonds;     //!< number of non-hydrogen bonds in molecule
    97     int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
     95    mutable int NoNonHydrogen;  //!< number of non-hydrogen atoms in molecule
     96    mutable int NoNonBonds;     //!< number of non-hydrogen bonds in molecule
     97    mutable int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    9898    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
    9999    bool ActiveFlag;    //!< in a MoleculeListClass used to discern active from inactive molecules
     
    101101    char name[MAXSTRINGSIZE];         //!< arbitrary name
    102102    int IndexNr;        //!< index of molecule in a MoleculeListClass
    103     class Tesselation *TesselStruct;
    104 
    105   molecule(periodentafel *teil);
     103
     104  molecule(const periodentafel * const teil);
    106105  virtual ~molecule();
    107106
    108107  // re-definition of virtual functions from PointCloud
    109   Vector *GetCenter(ofstream *out);
    110   TesselPoint *GetPoint();
    111   TesselPoint *GetTerminalPoint();
    112   void GoToNext();
    113   void GoToPrevious();
    114   void GoToFirst();
    115   void GoToLast();
    116   bool IsEmpty();
    117   bool IsEnd();
     108  Vector *GetCenter(ofstream *out) const ;
     109  TesselPoint *GetPoint() const ;
     110  TesselPoint *GetTerminalPoint() const ;
     111  void GoToNext() const ;
     112  void GoToPrevious() const ;
     113  void GoToFirst() const ;
     114  void GoToLast() const ;
     115  bool IsEmpty() const ;
     116  bool IsEnd() const ;
    118117
    119118  // templates for allowing global manipulation of all vectors
    120   template <typename res> void ActOnAllVectors( res (Vector::*f)() );
    121   template <typename res> void ActOnAllVectors( res (Vector::*f)() const);
    122119  template <typename res> void ActOnAllVectors( res (Vector::*f)() ) const;
    123120  template <typename res> void ActOnAllVectors( res (Vector::*f)() const) const;
    124   template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T), T t );
    125   template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T) const, T t );
    126121  template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T), T t ) const;
    127122  template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T) const, T t ) const;
    128   template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U), T t, U u );
    129   template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u );
    130123  template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const;
    131124  template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const;
    132   template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v);
    133   template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v);
    134125  template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const;
    135126  template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const;
    136127
    137128  // templates for allowing global manipulation of molecule with each atom as single argument
    138   template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) );
    139   template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) const);
    140129  template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) ) const;
    141130  template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) const) const;
    142131
    143132  // templates for allowing global copying of molecule with each atom as single argument
    144   template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy);
    145   template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const , molecule *copy);
    146133  template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const;
    147134  template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const;
    148135
    149136  // templates for allowing global manipulation of all atoms
    150   template <typename res> void ActOnAllAtoms( res (atom::*f)() );
    151   template <typename res> void ActOnAllAtoms( res (atom::*f)() const );
    152   template <typename res> void ActOnAllAtoms( res (atom::*f)() ) const;
    153   template <typename res> void ActOnAllAtoms( res (atom::*f)() const) const;
    154   template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T), T t );
    155   template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T) const, T t );
    156   template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T), T t ) const;
    157   template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T) const, T t ) const;
    158   template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U), T t, U u );
    159   template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u );
    160   template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U), T t, U u ) const;
    161   template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u ) const;
    162   template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v);
    163   template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v);
    164   template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v) const;
    165   template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v) const;
    166   template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w);
    167   template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w);
    168   template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w) const;
    169   template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w) const;
     137  template <typename res, typename typ> void ActOnAllAtoms( res (typ::*f)() ) const;
     138  template <typename res, typename typ> void ActOnAllAtoms( res (typ::*f)() const) const;
     139  template <typename res, typename typ, typename T> void ActOnAllAtoms( res (typ::*f)(T), T t ) const;
     140  template <typename res, typename typ, typename T> void ActOnAllAtoms( res (typ::*f)(T) const, T t ) const;
     141  template <typename res, typename typ, typename T, typename U> void ActOnAllAtoms( res (typ::*f)(T, U), T t, U u ) const;
     142  template <typename res, typename typ, typename T, typename U> void ActOnAllAtoms( res (typ::*f)(T, U) const, T t, U u ) const;
     143  template <typename res, typename typ, typename T, typename U, typename V> void ActOnAllAtoms( res (typ::*f)(T, U, V), T t, U u, V v) const;
     144  template <typename res, typename typ, typename T, typename U, typename V> void ActOnAllAtoms( res (typ::*f)(T, U, V) const, T t, U u, V v) const;
     145  template <typename res, typename typ, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (typ::*f)(T, U, V, W), T t, U u, V v, W w) const;
     146  template <typename res, typename typ, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (typ::*f)(T, U, V, W) const, T t, U u, V v, W w) const;
    170147
    171148  // templates for allowing conditional global copying of molecule with each atom as single argument
    172   template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () );
    173   template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t );
    174   template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u );
    175   template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v );
     149  template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ) const;
     150  template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () const ) const;
     151  template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () ) const;
     152  template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () const ) const;
     153  template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ) const;
     154  template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T) const, T t ) const;
     155  template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T), T t ) const;
     156  template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T) const, T t ) const;
     157  template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const;
     158  template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const;
     159  template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const;
     160  template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const;
     161  template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const;
     162  template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const;
     163  template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const;
     164  template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const;
    176165
    177166  // templates for allowing global manipulation of an array with one entry per atom
    178   void SetIndexedArrayForEachAtomTo ( atom **array, int TesselPoint::* index);
    179   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *));
    180   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *), T t);
    181   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *), T *t);
    182   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *));
    183   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T t);
    184   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *t);
    185   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, T (atom::*Setor)(Vector &), Vector atom::*value);
    186   template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector &vect );
     167  void SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::* index) const;
     168  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *)) const;
     169  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *), T t) const;
     170  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *), T *t) const;
     171  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *)) const;
     172  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *), T t) const;
     173  template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *), T *t) const;
     174  template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ atom::*value) const;
     175  template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ atom::*value) const;
     176  template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ &vect ) const;
     177  template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ &vect ) const;
    187178
    188179  // templates for allowing global manipulation of each atom by entries in an array
    189   template <typename T> void SetAtomValueToIndexedArray ( T *array, int TesselPoint::*index, T atom::*value );
    190   template <typename T> void SetAtomValueToIndexedArray ( T *array, int element::*index, T atom::*value );
     180  template <typename T, typename typ, typename typ2> void SetAtomValueToIndexedArray ( T *array, int typ::*index, T typ2::*value ) const;
     181  template <typename T, typename typ> void SetAtomValueToValue ( T value, T typ::*ptr ) const;
     182
     183  template <typename res, typename typ> res SumPerAtom(res (typ::*f)() ) const;
     184  template <typename res, typename typ> res SumPerAtom(res (typ::*f)() const ) const;
     185  template <typename res, typename typ, typename T> res SumPerAtom(res (typ::*f)(T) , T t ) const;
     186  template <typename res, typename typ, typename T> res SumPerAtom(res (typ::*f)(T) const, T t ) const;
    191187
    192188  /// remove atoms from molecule.
     
    199195  atom * AddCopyAtom(atom *pointer);
    200196  bool AddXYZFile(string filename);
    201   bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
     197  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem);
    202198  bond * AddBond(atom *first, atom *second, int degree = 1);
    203199  bool RemoveBond(bond *pointer);
     
    222218  void Mirror(const Vector *x);
    223219  void Align(Vector *n);
    224   void Scale(double **factor);
     220  void Scale(const double ** const factor);
    225221  void DeterminePeriodicCenter(Vector &center);
    226222  Vector * DetermineCenterOfGravity(ofstream *out);
    227   Vector * DetermineCenterOfAll(ofstream *out);
     223  Vector * DetermineCenterOfAll(ofstream *out) const;
    228224  void SetNameFromFilename(const char *filename);
    229225  void SetBoxDimension(Vector *dim);
     
    233229  void PrincipalAxisSystem(ofstream *out, bool DoRotate);
    234230  double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    235   Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);
    236 
    237231
    238232  double ConstrainedPotential(ofstream *out, struct EvaluatePotential &Params);
     
    245239
    246240  /// Initialising routines in fragmentation
    247   void CreateAdjacencyList2(ofstream *out, ifstream *output);
    248   void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    249   void CreateListOfBondsPerAtom(ofstream *out);
     241  void CreateAdjacencyListFromDbondFile(ofstream *out, ifstream *output);
     242  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem, void (BondGraph::*f)(BondedParticle * const , BondedParticle * const , double &, double &, bool), BondGraph *BG = NULL);
     243  int CorrectBondDegree(ofstream *out) const;
     244  void OutputBondsList(ofstream *out) const;
     245  void CyclicBondAnalysis() const;
     246  void OutputGraphInfoPerAtom(ofstream *out) const;
     247  void OutputGraphInfoPerBond(ofstream *out) const;
     248
    250249
    251250  // Graph analysis
    252   MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
    253   void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize);
    254   bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack);
    255   bond * FindNextUnused(atom *vertex);
    256   void SetNextComponentNumber(atom *vertex, int nr);
    257   void InitComponentNumbers();
    258   void OutputComponentNumber(ofstream *out, atom *vertex);
    259   void ResetAllBondsToUnused();
    260   void ResetAllAtomNumbers();
     251  MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) const;
     252  void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize) const;
     253  bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack) const;
     254  bond * FindNextUnused(atom *vertex) const;
     255  void SetNextComponentNumber(atom *vertex, int nr) const;
     256  void ResetAllBondsToUnused() const;
    261257  int CountCyclicBonds(ofstream *out);
    262258  bool CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment);
    263   string GetColor(enum Shading color);
     259  string GetColor(enum Shading color) const;
     260  bond * CopyBond(atom *left, atom *right, bond *CopyBond);
     261
    264262
    265263  molecule *CopyMolecule();
    266   molecule* CopyMoleculeFromSubRegion(Vector offset, double *parallelepiped);
     264  molecule* CopyMoleculeFromSubRegion(const Vector offset, const double *parallelepiped) const;
    267265
    268266  /// Fragment molecule by two different approaches:
     
    300298  private:
    301299  int last_atom;      //!< number given to last atom
    302   atom *InternalPointer;  //!< internal pointer for PointCloud
     300  mutable atom *InternalPointer;  //!< internal pointer for PointCloud
    303301};
    304302
     
    323321  void Enumerate(ofstream *out);
    324322  void Output(ofstream *out);
     323  void DissectMoleculeIntoConnectedSubgraphs(ofstream * const out, molecule * const mol, config * const configuration);
    325324
    326325  // merging of molecules
     
    352351
    353352  bool AddLeaf(molecule *ptr, MoleculeLeafClass *Previous);
    354   bool FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false);
     353  bool FillBondStructureFromReference(ofstream *out, const molecule * const reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false);
    355354  bool FillRootStackForSubgraphs(ofstream *out, KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter);
    356355  bool AssignKeySetsToFragment(ofstream *out, molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms, Graph **&FragmentList, int &FragmentCounter, bool FreeList = false);
  • src/molecule_dynamics.cpp

    r06c7a3 r7326b2  
    193193{
    194194  stringstream zeile1, zeile2;
    195   int *DoubleList = Malloc<int>(AtomCount, "PrintPermutationMap: *DoubleList");
     195  int *DoubleList = Calloc<int>(AtomCount, "PrintPermutationMap: *DoubleList");
    196196  int doubles = 0;
    197   for (int i=0;i<AtomCount;i++)
    198     DoubleList[i] = 0;
    199197  zeile1 << "PermutationMap: ";
    200198  zeile2 << "                ";
     
    243241void CreateInitialLists(ofstream *out, molecule *mol, struct EvaluatePotential &Params)
    244242{
    245   for (int i=mol->AtomCount; i--;)
    246     Params.DoubleList[i] = 0;  // stores for how many atoms in startstep this atom is a target in endstep
    247 
    248243  atom *Walker = mol->start;
    249244  while (Walker->next != mol->end) {
     
    347342  double Potential, OldPotential, OlderPotential;
    348343  struct EvaluatePotential Params;
    349   Params.PermutationMap = Malloc<atom*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**PermutationMap");
     344  Params.PermutationMap = Calloc<atom*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**PermutationMap");
    350345  Params.DistanceList = Malloc<DistanceMap*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**DistanceList");
    351346  Params.DistanceIterators = Malloc<DistanceMap::iterator>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DistanceIterators");
    352   Params.DoubleList = Malloc<int>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DoubleList");
     347  Params.DoubleList = Calloc<int>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DoubleList");
    353348  Params.StepList = Malloc<DistanceMap::iterator>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*StepList");
    354349  int round;
  • src/molecule_fragmentation.cpp

    r06c7a3 r7326b2  
    3131int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    3232{
    33   int c = 0;
     33  size_t c = 0;
    3434  int FragmentCount;
    3535  // get maximum bond degree
     
    3737  while (Walker->next != end) {
    3838    Walker = Walker->next;
    39     c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     39    c = (Walker->ListOfBonds.size() > c) ? Walker->ListOfBonds.size() : c;
    4040  }
    4141  FragmentCount = NoNonHydrogen*(1 << (c*order));
     
    123123  }
    124124
     125  Free(&filename);
    125126  return status;
    126127};
     
    565566  // ===== 1. Check whether bond structure is same as stored in files ====
    566567
    567   // fill the adjacency list
    568   CreateListOfBondsPerAtom(out);
    569 
    570568  // create lookup table for Atom::nr
    571569  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
     
    577575  // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    578576  Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    579   // fill the bond structure of the individually stored subgraphs
    580   Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     577
    581578  // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
    582579  for(int i=AtomCount;i--;)
     
    586583  while (MolecularWalker->next != NULL) {
    587584    MolecularWalker = MolecularWalker->next;
     585    // fill the bond structure of the individually stored subgraphs
     586  MolecularWalker->FillBondStructureFromReference(out, this, FragmentCounter, ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
    588587    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    589588    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     
    602601    delete(LocalBackEdgeStack);
    603602  }
     603  delete(BackEdgeStack);
    604604
    605605  // ===== 3. if structure still valid, parse key set file and others =====
     
    630630      MolecularWalker = MolecularWalker->next;
    631631      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    632       //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     632      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output atom::ListOfBonds for debugging
    633633      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    634634        // call BOSSANOVA method
     
    641641    }
    642642  }
     643  *out << Verbose(2) << "CheckOrder is " << CheckOrder << "." << endl;
    643644  delete[](RootStack);
    644645  delete[](AtomMask);
     
    666667  // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    667668  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    668     // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    669     BondFragments = new MoleculeListClass();
    670     int k=0;
    671     for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    672       KeySet test = (*runner).first;
    673       *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    674       BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
    675       k++;
    676     }
    677     *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    678 
    679     // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    680     if (BondFragments->ListOfMolecules.size() != 0) {
    681       // create the SortIndex from BFS labels to order in the config file
    682       CreateMappingLabelsToConfigSequence(out, SortIndex);
    683 
    684       *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
    685       if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    686         *out << Verbose(1) << "All configs written." << endl;
    687       else
    688         *out << Verbose(1) << "Some config writing failed." << endl;
    689 
    690       // store force index reference file
    691       BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    692 
    693       // store keysets file
    694       StoreKeySetFile(out, TotalGraph, configuration->configpath);
    695 
    696       // store Adjacency file
    697       StoreAdjacencyToFile(out, configuration->configpath);
    698 
    699       // store Hydrogen saturation correction file
    700       BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    701 
    702       // store adaptive orders into file
    703       StoreOrderAtSiteFile(out, configuration->configpath);
    704 
    705       // restore orbital and Stop values
    706       CalculateOrbitals(*configuration);
    707 
    708       // free memory for bond part
    709       *out << Verbose(1) << "Freeing bond memory" << endl;
    710       delete(FragmentList); // remove bond molecule from memory
    711       Free(&SortIndex);
    712     } else
    713       *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    714   //} else
    715   //  *out << Verbose(1) << "No fragments to store." << endl;
     669  // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     670  BondFragments = new MoleculeListClass();
     671  int k=0;
     672  for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     673    KeySet test = (*runner).first;
     674    *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     675    BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
     676    k++;
     677  }
     678  *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
     679
     680  // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     681  if (BondFragments->ListOfMolecules.size() != 0) {
     682    // create the SortIndex from BFS labels to order in the config file
     683    CreateMappingLabelsToConfigSequence(out, SortIndex);
     684
     685    *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
     686    if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     687      *out << Verbose(1) << "All configs written." << endl;
     688    else
     689      *out << Verbose(1) << "Some config writing failed." << endl;
     690
     691    // store force index reference file
     692    BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     693
     694    // store keysets file
     695    StoreKeySetFile(out, TotalGraph, configuration->configpath);
     696
     697    // store Adjacency file
     698    StoreAdjacencyToFile(out, configuration->configpath);
     699
     700    // store Hydrogen saturation correction file
     701    BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     702
     703    // store adaptive orders into file
     704    StoreOrderAtSiteFile(out, configuration->configpath);
     705
     706    // restore orbital and Stop values
     707    CalculateOrbitals(*configuration);
     708
     709    // free memory for bond part
     710    *out << Verbose(1) << "Freeing bond memory" << endl;
     711    delete(FragmentList); // remove bond molecule from memory
     712    Free(&SortIndex);
     713  } else {
     714    *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     715  }
     716  delete(BondFragments);
    716717  *out << Verbose(0) << "End of bond fragmentation." << endl;
    717718
     
    754755bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path)
    755756{
    756   unsigned char *OrderArray = Malloc<unsigned char>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    757   bool *MaxArray = Malloc<bool>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     757  unsigned char *OrderArray = Calloc<unsigned char>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     758  bool *MaxArray = Calloc<bool>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    758759  bool status;
    759760  int AtomNr, value;
     
    762763
    763764  *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
    764   for(int i=AtomCount;i--;)
    765     OrderArray[i] = 0;
    766765  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    767766  file.open(line.str().c_str());
    768767  if (file != NULL) {
    769     for (int i=AtomCount;i--;) { // initialise with 0
    770       OrderArray[i] = 0;
    771       MaxArray[i] = 0;
    772     }
    773768    while (!file.eof()) { // parse from file
    774769      AtomNr = -1;
     
    833828 * \param *Leaf fragment molecule
    834829 * \param &Leaflet pointer to KeySet structure
    835  * \param **SonList list which atom of \a *Leaf is a son of which atom in \a *mol
     830 * \param **SonList calloc'd list which atom of \a *Leaf is a son of which atom in \a *mol
    836831 * \return number of atoms in fragment
    837832 */
     
    843838  for(int i=NDIM*2;i--;)
    844839    Leaf->cell_size[i] = mol->cell_size[i];
    845 
    846   // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
    847   for(int i=mol->AtomCount;i--;)
    848     SonList[i] = NULL;
    849840
    850841  // first create the minimal set of atoms from the KeySet
     
    879870    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    880871      // create all bonds
    881       for (int i=0;i<mol->NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    882         OtherFather = mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     872      for (BondList::const_iterator BondRunner = FatherOfRunner->ListOfBonds.begin(); BondRunner != FatherOfRunner->ListOfBonds.end(); (++BondRunner)) {
     873        OtherFather = (*BondRunner)->GetOtherAtom(FatherOfRunner);
    883874//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    884875        if (SonList[OtherFather->nr] != NULL) {
     
    887878//            *out << Verbose(3) << "Adding Bond: ";
    888879//            *out <<
    889             Leaf->AddBond(Runner, SonList[OtherFather->nr], mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     880            Leaf->AddBond(Runner, SonList[OtherFather->nr], (*BondRunner)->BondDegree);
    890881//            *out << "." << endl;
    891882            //NumBonds[Runner->nr]++;
     
    898889#ifdef ADDHYDROGEN
    899890          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    900           if(!Leaf->AddHydrogenReplacementAtom(out, mol->ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, mol->ListOfBondsPerAtom[FatherOfRunner->nr],mol->NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     891          if(!Leaf->AddHydrogenReplacementAtom(out, (*BondRunner), Runner, FatherOfRunner, OtherFather, IsAngstroem))
    901892            exit(1);
    902893#endif
    903           //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     894          //NumBonds[Runner->nr] += Binder->BondDegree;
    904895        }
    905896      }
     
    927918molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem)
    928919{
    929   atom **SonList = Malloc<atom*>(AtomCount, "molecule::StoreFragmentFromStack: **SonList");
     920  atom **SonList = Calloc<atom*>(AtomCount, "molecule::StoreFragmentFromStack: **SonList");
    930921  molecule *Leaf = new molecule(elemente);
    931922
     
    936927  CreateInducedSubgraphOfFragment(out, this, Leaf, SonList, IsAngstroem);
    937928
    938   Leaf->CreateListOfBondsPerAtom(out);
    939929  //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    940930  Free(&SonList);
     
    981971    if (bit) {  // if bit is set, we add this bond partner
    982972      OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
    983       //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][CurrentCombination] << ", checking on " << *OtherWalker << "." << endl;
     973      //*out << Verbose(1+verbosity) << "Current Bond is " << BondsSet[j] << ", checking on " << *OtherWalker << "." << endl;
    984974      *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    985975      TestKeySetInsert = FragmentSet->insert(OtherWalker->nr);
     
    10891079  NumCombinations = 1 << SetDimension;
    10901080
    1091   // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    1092   // von Endstuecken (aus den Bonds) hinzugefuegt werden und fuer verbleibende ANOVAOrder
    1093   // rekursiv GraphCrawler in der naechsten Ebene aufgerufen werden
     1081  // here for all bonds of Walker all combinations of end pieces (from the bonds)
     1082  // have to be added and for the remaining ANOVA order GraphCrawler be called
     1083  // recursively for the next level
    10941084
    10951085  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     
    12581248  atom *OtherWalker = NULL;
    12591249  atom *Predecessor = NULL;
     1250  bond *CurrentEdge = NULL;
    12601251  bond *Binder = NULL;
    1261   bond *CurrentEdge = NULL;
    12621252  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    12631253  int RemainingWalkers = -1;
     
    12851275      // go through all its bonds
    12861276      *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    1287       for (int i=0;i<mol->NumberOfBondsPerAtom[AtomKeyNr];i++) {
    1288         Binder = mol->ListOfBondsPerAtom[AtomKeyNr][i];
    1289         OtherWalker = Binder->GetOtherAtom(Walker);
     1277      for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1278        OtherWalker = (*Runner)->GetOtherAtom(Walker);
    12901279        if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    12911280  #ifdef ADDHYDROGEN
     
    12931282  #endif
    12941283                                                              ) {  // skip hydrogens and restrict to fragment
    1295           *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     1284          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *(*Runner) << "." << endl;
    12961285          // set the label if not set (and push on root stack as well)
    12971286          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     
    13941383
    13951384    // prepare the subset and call the generator
    1396     BondsList = Malloc<bond*>(FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
     1385    BondsList = Calloc<bond*>(FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    13971386    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    13981387
     
    15491538  // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
    15501539  // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
    1551   NumMoleculesOfOrder = Malloc<int>(UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    1552   FragmentLowerOrdersList = Malloc<Graph**>(UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     1540  NumMoleculesOfOrder = Calloc<int>(UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     1541  FragmentLowerOrdersList = Calloc<Graph**>(UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    15531542
    15541543  // initialise the fragments structure
    1555   FragmentSearch.ShortestPathList = Malloc<int>(AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    15561544  FragmentSearch.FragmentCounter = 0;
    15571545  FragmentSearch.FragmentSet = new KeySet;
    15581546  FragmentSearch.Root = FindAtom(RootKeyNr);
     1547  FragmentSearch.ShortestPathList = Malloc<int>(AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    15591548  for (int i=AtomCount;i--;) {
    15601549    FragmentSearch.ShortestPathList[i] = -1;
     
    15921581      // allocate memory for all lower level orders in this 1D-array of ptrs
    15931582      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
    1594       FragmentLowerOrdersList[RootNr] = Malloc<Graph*>(NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    1595       for (int i=0;i<NumLevels;i++)
    1596         FragmentLowerOrdersList[RootNr][i] = NULL;
     1583      FragmentLowerOrdersList[RootNr] = Calloc<Graph*>(NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    15971584
    15981585      // create top order where nothing is reduced
     
    16701657  *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
    16711658
    1672   ColorList = Malloc<enum Shading>(AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
     1659  ColorList = Calloc<enum Shading>(AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
    16731660  while (flag) {
    16741661    // remove bonds that are beyond bonddistance
     
    17121699        ColorList[Walker->nr] = black;    // mark as explored
    17131700        Walker->x.AddVector(&Translationvector); // translate
    1714         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    1715           if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    1716             OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1701        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1702          if ((*Runner) != Binder) {
     1703            OtherWalker = (*Runner)->GetOtherAtom(Walker);
    17171704            if (ColorList[OtherWalker->nr] == white) {
    17181705              AtomStack->Push(OtherWalker); // push if yet unexplored
  • src/molecule_geometry.cpp

    r06c7a3 r7326b2  
    2424{
    2525  bool status = true;
    26   Vector x;
    2726  const Vector *Center = DetermineCenterOfAll(out);
    2827  double *M = ReturnFullMatrixforSymmetric(cell_size);
    29   double *Minv = x.InverseMatrix(M);
     28  double *Minv = InverseMatrix(M);
    3029
    3130  // go through all atoms
     
    4645{
    4746  bool status = true;
    48   Vector x;
    4947  double *M = ReturnFullMatrixforSymmetric(cell_size);
    50   double *Minv = x.InverseMatrix(M);
     48  double *Minv = InverseMatrix(M);
    5149
    5250  // go through all atoms
     
    122120 * \return pointer to center of all vector
    123121 */
    124 Vector * molecule::DetermineCenterOfAll(ofstream *out)
     122Vector * molecule::DetermineCenterOfAll(ofstream *out) const
    125123{
    126124  atom *ptr = start->next;  // start at first in list
     
    198196 * \param *factor pointer to scaling factor
    199197 */
    200 void molecule::Scale(double **factor)
     198void molecule::Scale(const double ** const factor)
    201199{
    202200  atom *ptr = start;
     
    231229void molecule::TranslatePeriodically(const Vector *trans)
    232230{
    233   Vector x;
    234231  double *M = ReturnFullMatrixforSymmetric(cell_size);
    235   double *Minv = x.InverseMatrix(M);
     232  double *Minv = InverseMatrix(M);
    236233
    237234  // go through all atoms
     
    258255{
    259256  atom *Walker = start;
    260   bond *Binder = NULL;
    261257  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    262258  double tmp;
     
    275271        Testvector.InverseMatrixMultiplication(matrix);
    276272        Translationvector.Zero();
    277         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    278           Binder = ListOfBondsPerAtom[Walker->nr][i];
    279           if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     273        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     274         if (Walker->nr < (*Runner)->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    280275            for (int j=0;j<NDIM;j++) {
    281               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     276              tmp = Walker->x.x[j] - (*Runner)->GetOtherAtom(Walker)->x.x[j];
    282277              if ((fabs(tmp)) > BondDistance) {
    283278                flag = false;
    284                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     279                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *(*Runner) << " has to be shifted due to " << tmp << "." << endl;
    285280                if (tmp > 0)
    286281                  Translationvector.x[j] -= 1.;
     
    298293#ifdef ADDHYDROGEN
    299294        // now also change all hydrogens
    300         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    301           Binder = ListOfBondsPerAtom[Walker->nr][i];
    302           if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    303             Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     295        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     296          if ((*Runner)->GetOtherAtom(Walker)->type->Z == 1) {
     297            Testvector.CopyVector(&(*Runner)->GetOtherAtom(Walker)->x);
    304298            Testvector.InverseMatrixMultiplication(matrix);
    305299            Testvector.AddVector(&Translationvector);
  • src/molecule_graph.cpp

    r06c7a3 r7326b2  
    88#include "atom.hpp"
    99#include "bond.hpp"
     10#include "bondgraph.hpp"
    1011#include "config.hpp"
    1112#include "element.hpp"
    1213#include "helpers.hpp"
     14#include "linkedcell.hpp"
    1315#include "lists.hpp"
    1416#include "memoryallocator.hpp"
    1517#include "molecule.hpp"
    1618
     19struct BFSAccounting
     20{
     21  atom **PredecessorList;
     22  int *ShortestPathList;
     23  enum Shading *ColorList;
     24  class StackClass<atom *> *BFSStack;
     25  class StackClass<atom *> *TouchedStack;
     26  int AtomCount;
     27  int BondOrder;
     28  atom *Root;
     29  bool BackStepping;
     30  int CurrentGraphNr;
     31  int ComponentNr;
     32};
     33
     34/** Accounting data for Depth First Search.
     35 */
     36struct DFSAccounting
     37{
     38  class StackClass<atom *> *AtomStack;
     39  class StackClass<bond *> *BackEdgeStack;
     40  int CurrentGraphNr;
     41  int ComponentNumber;
     42  atom *Root;
     43  bool BackStepping;
     44};
     45
    1746/************************************* Functions for class molecule *********************************/
    18 
    1947
    2048/** Creates an adjacency list of the molecule.
    2149 * We obtain an outside file with the indices of atoms which are bondmembers.
    2250 */
    23 void molecule::CreateAdjacencyList2(ofstream *out, ifstream *input)
     51void molecule::CreateAdjacencyListFromDbondFile(ofstream *out, ifstream *input)
    2452{
    2553
    2654  // 1 We will parse bonds out of the dbond file created by tremolo.
    27       int atom1, atom2, temp;
    28       atom *Walker, *OtherWalker;
    29 
    30           if (!input)
    31           {
    32             cout << Verbose(1) << "Opening silica failed \n";
    33           };
    34 
    35       *input >> ws >> atom1;
    36       *input >> ws >> atom2;
    37           cout << Verbose(1) << "Scanning file\n";
    38           while (!input->eof()) // Check whether we read everything already
    39           {
    40         *input >> ws >> atom1;
    41         *input >> ws >> atom2;
    42             if(atom2<atom1) //Sort indices of atoms in order
    43             {
    44               temp=atom1;
    45               atom1=atom2;
    46               atom2=temp;
    47             };
    48 
    49             Walker=start;
    50             while(Walker-> nr != atom1) // Find atom corresponding to first index
    51             {
    52               Walker = Walker->next;
    53             };
    54             OtherWalker = Walker->next;
    55             while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    56             {
    57               OtherWalker= OtherWalker->next;
    58             };
    59             AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    60 
    61           }
    62 
    63           CreateListOfBondsPerAtom(out);
    64 
    65 };
    66 
     55  int atom1, atom2;
     56  atom *Walker, *OtherWalker;
     57
     58  if (!input) {
     59    cout << Verbose(1) << "Opening silica failed \n";
     60  };
     61
     62  *input >> ws >> atom1;
     63  *input >> ws >> atom2;
     64  cout << Verbose(1) << "Scanning file\n";
     65  while (!input->eof()) // Check whether we read everything already
     66  {
     67    *input >> ws >> atom1;
     68    *input >> ws >> atom2;
     69
     70    if (atom2 < atom1) //Sort indices of atoms in order
     71      flip(atom1, atom2);
     72    Walker = FindAtom(atom1);
     73    OtherWalker = FindAtom(atom2);
     74    AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     75  }
     76}
     77;
    6778
    6879/** Creates an adjacency list of the molecule.
     
    7788 *  -# put each atom into its corresponding cell
    7889 *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    79  *  -# create the list of bonds via CreateListOfBondsPerAtom()
    8090 *  -# correct the bond degree iteratively (single->double->triple bond)
    8191 *  -# finally print the bond list to \a *out if desired
     
    8393 * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
    8494 * \param IsAngstroem whether coordinate system is gauged to Angstroem or Bohr radii
    85  */
    86 void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    87 {
    88 
    89   atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    90   int No, NoBonds, CandidateBondNo;
    91   int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
    92   molecule **CellList;
    93   double distance, MinDistance, MaxDistance;
    94   double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    95   Vector x;
    96   int FalseBondDegree = 0;
     95 * \param *minmaxdistance function to give upper and lower bound on whether particle is bonded to some other
     96 * \param *BG BondGraph with the member function above or NULL, if just standard covalent should be used.
     97 */
     98void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem, void (BondGraph::*minmaxdistance)(BondedParticle * const , BondedParticle * const , double &, double &, bool), BondGraph *BG)
     99{
     100  atom *Walker = NULL;
     101  atom *OtherWalker = NULL;
     102  atom **AtomMap = NULL;
     103  int n[NDIM];
     104  double MinDistance, MaxDistance;
     105  LinkedCell *LC = NULL;
     106  bool free_BG = false;
     107
     108  if (BG == NULL) {
     109    BG = new BondGraph(IsAngstroem);
     110    free_BG = true;
     111  }
    97112
    98113  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    99114  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
    100115  // remove every bond from the list
    101   if ((first->next != last) && (last->previous != first)) {  // there are bonds present
    102     cleanup(first,last);
    103   }
     116  bond *Binder = NULL;
     117  while (last->previous != first) {
     118    Binder = last->previous;
     119    Binder->leftatom->UnregisterBond(Binder);
     120    Binder->rightatom->UnregisterBond(Binder);
     121    removewithoutcheck(Binder);
     122  }
     123  BondCount = 0;
    104124
    105125  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    106126  CountAtoms(out);
    107   *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
    108 
    109   if (AtomCount != 0) {
    110     // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
    111     j=-1;
    112     for (int i=0;i<NDIM;i++) {
    113       j += i+1;
    114       divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    115       //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
    116     }
    117     // 2a. allocate memory for the cell list
    118     NumberCells = divisor[0]*divisor[1]*divisor[2];
    119     *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
    120     CellList = Malloc<molecule*>(NumberCells, "molecule::CreateAdjacencyList - ** CellList");
    121     for (int i=NumberCells;i--;)
    122       CellList[i] = NULL;
    123 
    124     // 2b. put all atoms into its corresponding list
     127  *out << Verbose(1) << "AtomCount " << AtomCount << " and bonddistance is " << bonddistance << "." << endl;
     128
     129  if ((AtomCount > 1) && (bonddistance > 1.)) {
     130    *out << Verbose(2) << "Creating Linked Cell structure ... " << endl;
     131    LC = new LinkedCell(this, bonddistance);
     132
     133    // create a list to map Tesselpoint::nr to atom *
     134    *out << Verbose(2) << "Creating TesselPoint to atom map ... " << endl;
     135    AtomMap = Calloc<atom *> (AtomCount, "molecule::CreateAdjacencyList - **AtomCount");
    125136    Walker = start;
    126     while(Walker->next != end) {
     137    while (Walker->next != end) {
    127138      Walker = Walker->next;
    128       //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
    129       //Walker->x.Output(out);
    130       //*out << "." << endl;
    131       // compute the cell by the atom's coordinates
    132       j=-1;
    133       for (int i=0;i<NDIM;i++) {
    134         j += i+1;
    135         x.CopyVector(&(Walker->x));
    136         x.KeepPeriodic(out, matrix);
    137         n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
    138       }
    139       index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    140       //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    141       // add copy atom to this cell
    142       if (CellList[index] == NULL)  // allocate molecule if not done
    143         CellList[index] = new molecule(elemente);
    144       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    145       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    146     }
    147     //for (int i=0;i<NumberCells;i++)
    148       //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    149 
     139      AtomMap[Walker->nr] = Walker;
     140    }
    150141
    151142    // 3a. go through every cell
    152     for (N[0]=divisor[0];N[0]--;)
    153       for (N[1]=divisor[1];N[1]--;)
    154         for (N[2]=divisor[2];N[2]--;) {
    155           Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
    156           if (CellList[Index] != NULL) { // if there atoms in this cell
    157             //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
    158             // 3b. for every atom therein
    159             Walker = CellList[Index]->start;
    160             while (Walker->next != CellList[Index]->end) {  // go through every atom
    161               Walker = Walker->next;
     143    *out << Verbose(2) << "Celling ... " << endl;
     144    for (LC->n[0] = 0; LC->n[0] < LC->N[0]; LC->n[0]++)
     145      for (LC->n[1] = 0; LC->n[1] < LC->N[1]; LC->n[1]++)
     146        for (LC->n[2] = 0; LC->n[2] < LC->N[2]; LC->n[2]++) {
     147          const LinkedNodes *List = LC->GetCurrentCell();
     148          //*out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
     149          if (List != NULL) {
     150            for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     151              Walker = AtomMap[(*Runner)->nr];
    162152              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    163153              // 3c. check for possible bond between each atom in this and every one in the 27 cells
    164               for (n[0]=-1;n[0]<=1;n[0]++)
    165                 for (n[1]=-1;n[1]<=1;n[1]++)
    166                   for (n[2]=-1;n[2]<=1;n[2]++) {
    167                      // compute the index of this comparison cell and make it periodic
    168                     index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2];
    169                     //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
    170                     if (CellList[index] != NULL) {  // if there are any atoms in this cell
    171                       OtherWalker = CellList[index]->start;
    172                       while(OtherWalker->next != CellList[index]->end) {  // go through every atom in this cell
    173                         OtherWalker = OtherWalker->next;
    174                         //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    175                         /// \todo periodic check is missing here!
    176                         //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    177                         MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    178                         MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    179                         MaxDistance = MinDistance + BONDTHRESHOLD;
    180                         MinDistance -= BONDTHRESHOLD;
    181                         distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
    182                         if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    183                           //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    184                           AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
    185                         } else {
    186                           //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     154              for (n[0] = -1; n[0] <= 1; n[0]++)
     155                for (n[1] = -1; n[1] <= 1; n[1]++)
     156                  for (n[2] = -1; n[2] <= 1; n[2]++) {
     157                    const LinkedNodes *OtherList = LC->GetRelativeToCurrentCell(n);
     158                    //*out << Verbose(2) << "Current relative cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
     159                    if (OtherList != NULL) {
     160                      for (LinkedNodes::const_iterator OtherRunner = OtherList->begin(); OtherRunner != OtherList->end(); OtherRunner++) {
     161                        if ((*OtherRunner)->nr > Walker->nr) {
     162                          OtherWalker = AtomMap[(*OtherRunner)->nr];
     163                          //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     164                          (BG->*minmaxdistance)(Walker, OtherWalker, MinDistance, MaxDistance, IsAngstroem);
     165                          const double distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
     166                          const bool status = (distance <= MaxDistance * MaxDistance) && (distance >= MinDistance * MinDistance);
     167                          if ((OtherWalker->father->nr > Walker->father->nr) && (status)) { // create bond if distance is smaller
     168                            //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
     169                            AddBond(Walker->father, OtherWalker->father, 1); // also increases molecule::BondCount
     170                          } else {
     171                            //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     172                          }
    187173                        }
    188174                      }
     
    192178          }
    193179        }
    194 
    195 
    196 
    197     // 4. free the cell again
    198     for (int i=NumberCells;i--;)
    199       if (CellList[i] != NULL) {
    200         delete(CellList[i]);
    201       }
    202     Free(&CellList);
    203 
    204     // create the adjacency list per atom
    205     CreateListOfBondsPerAtom(out);
    206 
    207     // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    208     // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    209     // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    210     // double bonds as was expected.
    211     if (BondCount != 0) {
    212       NoCyclicBonds = 0;
    213       *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    214       do {
    215         No = 0; // No acts as breakup flag (if 1 we still continue)
    216         Walker = start;
    217         while (Walker->next != end) { // go through every atom
    218           Walker = Walker->next;
    219           // count valence of first partner
    220           NoBonds = 0;
    221           for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
    222             NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    223           *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    224           if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    225             Candidate = NULL;
    226             CandidateBondNo = -1;
    227             for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    228               OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    229               // count valence of second partner
    230               NoBonds = 0;
    231               for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    232                 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    233               *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    234               if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    235                 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    236                   Candidate = OtherWalker;
    237                   CandidateBondNo = i;
    238                   *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    239                 }
    240               }
    241             }
    242             if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    243               ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    244               *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    245             } else
    246               *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    247               FalseBondDegree++;
    248           }
    249         }
    250       } while (No);
    251     *out << " done." << endl;
    252     } else
    253       *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    254     *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     180    Free(&AtomMap);
     181    delete (LC);
     182    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << BondDistance << "." << endl;
     183
     184    // correct bond degree by comparing valence and bond degree
     185    *out << Verbose(2) << "Correcting bond degree ... " << endl;
     186    CorrectBondDegree(out);
    255187
    256188    // output bonds for debugging (if bond chain list was correctly installed)
    257     *out << Verbose(1) << endl << "From contents of bond chain list:";
    258     bond *Binder = first;
    259     while(Binder->next != last) {
    260       Binder = Binder->next;
    261       *out << *Binder << "\t" << endl;
    262     }
    263     *out << endl;
     189    ActOnAllAtoms(&atom::OutputBondOfAtom, out);
    264190  } else
    265191    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    266192  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    267   Free(&matrix);
    268 
    269 };
     193  if (free_BG)
     194    delete(BG);
     195}
     196;
     197
     198/** Prints a list of all bonds to \a *out.
     199 * \param output stream
     200 */
     201void molecule::OutputBondsList(ofstream *out) const
     202{
     203  *out << Verbose(1) << endl << "From contents of bond chain list:";
     204  bond *Binder = first;
     205  while (Binder->next != last) {
     206    Binder = Binder->next;
     207    *out << *Binder << "\t" << endl;
     208  }
     209  *out << endl;
     210}
     211;
     212
     213/** correct bond degree by comparing valence and bond degree.
     214 * correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
     215 * iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     216 * preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
     217 * double bonds as was expected.
     218 * \param *out output stream for debugging
     219 * \return number of bonds that could not be corrected
     220 */
     221int molecule::CorrectBondDegree(ofstream *out) const
     222{
     223  int No = 0, OldNo = -1;
     224
     225  if (BondCount != 0) {
     226    *out << Verbose(1) << "Correcting Bond degree of each bond ... " << endl;
     227    do {
     228      OldNo = No;
     229      No = SumPerAtom(&atom::CorrectBondDegree, out);
     230    } while (OldNo != No);
     231    *out << " done." << endl;
     232  } else {
     233    *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
     234  }
     235  *out << No << " bonds could not be corrected." << endl;
     236
     237  return (No);
     238}
     239;
    270240
    271241/** Counts all cyclic bonds and returns their number.
     
    276246int molecule::CountCyclicBonds(ofstream *out)
    277247{
    278   int No = 0;
     248  NoCyclicBonds = 0;
    279249  int *MinimumRingSize = NULL;
    280250  MoleculeLeafClass *Subgraphs = NULL;
     
    286256    while (Subgraphs->next != NULL) {
    287257      Subgraphs = Subgraphs->next;
    288       delete(Subgraphs->previous);
    289     }
    290     delete(Subgraphs);
    291     delete[](MinimumRingSize);
    292   }
    293   while(Binder->next != last) {
     258      delete (Subgraphs->previous);
     259    }
     260    delete (Subgraphs);
     261    delete[] (MinimumRingSize);
     262  }
     263  while (Binder->next != last) {
    294264    Binder = Binder->next;
    295265    if (Binder->Cyclic)
    296       No++;
    297   }
    298   delete(BackEdgeStack);
    299   return No;
    300 };
     266      NoCyclicBonds++;
     267  }
     268  delete (BackEdgeStack);
     269  return NoCyclicBonds;
     270}
     271;
     272
    301273/** Returns Shading as a char string.
    302274 * \param color the Shading
    303275 * \return string of the flag
    304276 */
    305 string molecule::GetColor(enum Shading color)
    306 {
    307   switch(color) {
     277string molecule::GetColor(enum Shading color) const
     278{
     279  switch (color) {
    308280    case white:
    309281      return "white";
     
    322294      break;
    323295  };
    324 };
     296}
     297;
     298
     299/** Sets atom::GraphNr and atom::LowpointNr to BFSAccounting::CurrentGraphNr.
     300 * \param *out output stream for debugging
     301 * \param *Walker current node
     302 * \param &BFS structure with accounting data for BFS
     303 */
     304void DepthFirstSearchAnalysis_SetWalkersGraphNr(ofstream *out, atom *&Walker, struct DFSAccounting &DFS)
     305{
     306  if (!DFS.BackStepping) { // if we don't just return from (8)
     307    Walker->GraphNr = DFS.CurrentGraphNr;
     308    Walker->LowpointNr = DFS.CurrentGraphNr;
     309    *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
     310    DFS.AtomStack->Push(Walker);
     311    DFS.CurrentGraphNr++;
     312  }
     313}
     314;
     315
     316/** During DFS goes along unvisited bond and touches other atom.
     317 * Sets bond::type, if
     318 *  -# BackEdge: set atom::LowpointNr and push on \a BackEdgeStack
     319 *  -# TreeEgde: set atom::Ancestor and continue with Walker along this edge
     320 * Continue until molecule::FindNextUnused() finds no more unused bonds.
     321 * \param *out output stream for debugging
     322 * \param *mol molecule with atoms and finding unused bonds
     323 * \param *&Binder current edge
     324 * \param &DFS DFS accounting data
     325 */
     326void DepthFirstSearchAnalysis_ProbeAlongUnusedBond(ofstream *out, const molecule * const mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS)
     327{
     328  atom *OtherAtom = NULL;
     329
     330  do { // (3) if Walker has no unused egdes, go to (5)
     331    DFS.BackStepping = false; // reset backstepping flag for (8)
     332    if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
     333      Binder = mol->FindNextUnused(Walker);
     334    if (Binder == NULL)
     335      break;
     336    *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
     337    // (4) Mark Binder used, ...
     338    Binder->MarkUsed(black);
     339    OtherAtom = Binder->GetOtherAtom(Walker);
     340    *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
     341    if (OtherAtom->GraphNr != -1) {
     342      // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
     343      Binder->Type = BackEdge;
     344      DFS.BackEdgeStack->Push(Binder);
     345      Walker->LowpointNr = (Walker->LowpointNr < OtherAtom->GraphNr) ? Walker->LowpointNr : OtherAtom->GraphNr;
     346      *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
     347    } else {
     348      // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
     349      Binder->Type = TreeEdge;
     350      OtherAtom->Ancestor = Walker;
     351      Walker = OtherAtom;
     352      *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
     353      break;
     354    }
     355    Binder = NULL;
     356  } while (1); // (3)
     357}
     358;
     359
     360/** Checks whether we have a new component.
     361 * if atom::LowpointNr of \a *&Walker is greater than atom::GraphNr of its atom::Ancestor, we have a new component.
     362 * Meaning that if we touch upon a node who suddenly has a smaller atom::LowpointNr than its ancestor, then we
     363 * have a found a new branch in the graph tree.
     364 * \param *out output stream for debugging
     365 * \param *mol molecule with atoms and finding unused bonds
     366 * \param *&Walker current node
     367 * \param &DFS DFS accounting data
     368 */
     369void DepthFirstSearchAnalysis_CheckForaNewComponent(ofstream *out, const molecule * const mol, atom *&Walker, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker)
     370{
     371  atom *OtherAtom = NULL;
     372
     373  // (5) if Ancestor of Walker is ...
     374  *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
     375
     376  if (Walker->Ancestor->GraphNr != DFS.Root->GraphNr) {
     377    // (6)  (Ancestor of Walker is not Root)
     378    if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
     379      // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
     380      Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
     381      *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
     382    } else {
     383      // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
     384      Walker->Ancestor->SeparationVertex = true;
     385      *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
     386      mol->SetNextComponentNumber(Walker->Ancestor, DFS.ComponentNumber);
     387      *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << DFS.ComponentNumber << "." << endl;
     388      mol->SetNextComponentNumber(Walker, DFS.ComponentNumber);
     389      *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl;
     390      do {
     391        OtherAtom = DFS.AtomStack->PopLast();
     392        LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     393        mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber);
     394        *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl;
     395      } while (OtherAtom != Walker);
     396      DFS.ComponentNumber++;
     397    }
     398    // (8) Walker becomes its Ancestor, go to (3)
     399    *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
     400    Walker = Walker->Ancestor;
     401    DFS.BackStepping = true;
     402  }
     403}
     404;
     405
     406/** Cleans the root stack when we have found a component.
     407 * If we are not DFSAccounting::BackStepping, then we clear the root stack by putting everything into a
     408 * component down till we meet DFSAccounting::Root.
     409 * \param *out output stream for debugging
     410 * \param *mol molecule with atoms and finding unused bonds
     411 * \param *&Walker current node
     412 * \param *&Binder current edge
     413 * \param &DFS DFS accounting data
     414 */
     415void DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(ofstream *out, const molecule * const mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker)
     416{
     417  atom *OtherAtom = NULL;
     418
     419  if (!DFS.BackStepping) { // coming from (8) want to go to (3)
     420    // (9) remove all from stack till Walker (including), these and Root form a component
     421    //DFS.AtomStack->Output(out);
     422    mol->SetNextComponentNumber(DFS.Root, DFS.ComponentNumber);
     423    *out << Verbose(3) << "(9) Root[" << DFS.Root->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl;
     424    mol->SetNextComponentNumber(Walker, DFS.ComponentNumber);
     425    *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl;
     426    do {
     427      OtherAtom = DFS.AtomStack->PopLast();
     428      LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     429      mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber);
     430      *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl;
     431    } while (OtherAtom != Walker);
     432    DFS.ComponentNumber++;
     433
     434    // (11) Root is separation vertex,  set Walker to Root and go to (4)
     435    Walker = DFS.Root;
     436    Binder = mol->FindNextUnused(Walker);
     437    *out << Verbose(1) << "(10) Walker is Root[" << DFS.Root->Name << "], next Unused Bond is " << Binder << "." << endl;
     438    if (Binder != NULL) { // Root is separation vertex
     439      *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
     440      Walker->SeparationVertex = true;
     441    }
     442  }
     443}
     444;
     445
     446/** Initializes DFSAccounting structure.
     447 * \param *out output stream for debugging
     448 * \param &DFS accounting structure to allocate
     449 * \param *mol molecule with AtomCount, BondCount and all atoms
     450 */
     451void DepthFirstSearchAnalysis_Init(ofstream *out, struct DFSAccounting &DFS, const molecule * const mol)
     452{
     453  DFS.AtomStack = new StackClass<atom *> (mol->AtomCount);
     454  DFS.CurrentGraphNr = 0;
     455  DFS.ComponentNumber = 0;
     456  DFS.BackStepping = false;
     457  mol->ResetAllBondsToUnused();
     458  mol->SetAtomValueToValue(-1, &atom::GraphNr);
     459  mol->ActOnAllAtoms(&atom::InitComponentNr);
     460  DFS.BackEdgeStack->ClearStack();
     461}
     462;
     463
     464/** Free's DFSAccounting structure.
     465 * \param *out output stream for debugging
     466 * \param &DFS accounting structure to free
     467 */
     468void DepthFirstSearchAnalysis_Finalize(ofstream *out, struct DFSAccounting &DFS)
     469{
     470  delete (DFS.AtomStack);
     471  // delete (DFS.BackEdgeStack); // DON'T free, see DepthFirstSearchAnalysis(), is returned as allocated
     472}
     473;
    325474
    326475/** Performs a Depth-First search on this molecule.
     
    332481 * \return list of each disconnected subgraph as an individual molecule class structure
    333482 */
    334 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
    335 {
    336   class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     483MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) const
     484{
     485  struct DFSAccounting DFS;
    337486  BackEdgeStack = new StackClass<bond *> (BondCount);
     487  DFS.BackEdgeStack = BackEdgeStack;
    338488  MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    339489  MoleculeLeafClass *LeafWalker = SubGraphs;
    340   int CurrentGraphNr = 0, OldGraphNr;
    341   int ComponentNumber = 0;
    342   atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
     490  int OldGraphNr = 0;
     491  atom *Walker = NULL;
    343492  bond *Binder = NULL;
    344   bool BackStepping = false;
    345493
    346494  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    347 
    348   ResetAllBondsToUnused();
    349   ResetAllAtomNumbers();
    350   InitComponentNumbers();
    351   BackEdgeStack->ClearStack();
    352   while (Root != end) { // if there any atoms at all
    353     // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
    354     AtomStack->ClearStack();
     495  DepthFirstSearchAnalysis_Init(out, DFS, this);
     496
     497  DFS.Root = start->next;
     498  while (DFS.Root != end) { // if there any atoms at all
     499    // (1) mark all edges unused, empty stack, set atom->GraphNr = -1 for all
     500    DFS.AtomStack->ClearStack();
    355501
    356502    // put into new subgraph molecule and add this to list of subgraphs
    357503    LeafWalker = new MoleculeLeafClass(LeafWalker);
    358504    LeafWalker->Leaf = new molecule(elemente);
    359     LeafWalker->Leaf->AddCopyAtom(Root);
    360 
    361     OldGraphNr = CurrentGraphNr;
    362     Walker = Root;
     505    LeafWalker->Leaf->AddCopyAtom(DFS.Root);
     506
     507    OldGraphNr = DFS.CurrentGraphNr;
     508    Walker = DFS.Root;
    363509    do { // (10)
    364510      do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
    365         if (!BackStepping) { // if we don't just return from (8)
    366           Walker->GraphNr = CurrentGraphNr;
    367           Walker->LowpointNr = CurrentGraphNr;
    368           *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
    369           AtomStack->Push(Walker);
    370           CurrentGraphNr++;
    371         }
    372         do { // (3) if Walker has no unused egdes, go to (5)
    373           BackStepping = false; // reset backstepping flag for (8)
    374           if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
    375             Binder = FindNextUnused(Walker);
    376           if (Binder == NULL)
    377             break;
    378           *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
    379           // (4) Mark Binder used, ...
    380           Binder->MarkUsed(black);
    381           OtherAtom = Binder->GetOtherAtom(Walker);
    382           *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
    383           if (OtherAtom->GraphNr != -1) {
    384             // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
    385             Binder->Type = BackEdge;
    386             BackEdgeStack->Push(Binder);
    387             Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
    388             *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
    389           } else {
    390             // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
    391             Binder->Type = TreeEdge;
    392             OtherAtom->Ancestor = Walker;
    393             Walker = OtherAtom;
    394             *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
    395             break;
    396           }
    397           Binder = NULL;
    398         } while (1);  // (3)
     511        DepthFirstSearchAnalysis_SetWalkersGraphNr(out, Walker, DFS);
     512
     513        DepthFirstSearchAnalysis_ProbeAlongUnusedBond(out, this, Walker, Binder, DFS);
     514
    399515        if (Binder == NULL) {
    400516          *out << Verbose(2) << "No more Unused Bonds." << endl;
     
    402518        } else
    403519          Binder = NULL;
    404       } while (1);  // (2)
     520      } while (1); // (2)
    405521
    406522      // 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!
    407       if ((Walker == Root) && (Binder == NULL))
     523      if ((Walker == DFS.Root) && (Binder == NULL))
    408524        break;
    409525
    410       // (5) if Ancestor of Walker is ...
    411       *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    412       if (Walker->Ancestor->GraphNr != Root->GraphNr) {
    413         // (6)  (Ancestor of Walker is not Root)
    414         if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
    415           // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
    416           Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
    417           *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
    418         } else {
    419           // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
    420           Walker->Ancestor->SeparationVertex = true;
    421           *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
    422           SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
    423           *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
    424           SetNextComponentNumber(Walker, ComponentNumber);
    425           *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    426           do {
    427             OtherAtom = AtomStack->PopLast();
    428             LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    429             SetNextComponentNumber(OtherAtom, ComponentNumber);
    430             *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    431           } while (OtherAtom != Walker);
    432           ComponentNumber++;
    433         }
    434         // (8) Walker becomes its Ancestor, go to (3)
    435         *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
    436         Walker = Walker->Ancestor;
    437         BackStepping = true;
    438       }
    439       if (!BackStepping) {  // coming from (8) want to go to (3)
    440         // (9) remove all from stack till Walker (including), these and Root form a component
    441         AtomStack->Output(out);
    442         SetNextComponentNumber(Root, ComponentNumber);
    443         *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
    444         SetNextComponentNumber(Walker, ComponentNumber);
    445         *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
    446         do {
    447           OtherAtom = AtomStack->PopLast();
    448           LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    449           SetNextComponentNumber(OtherAtom, ComponentNumber);
    450           *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    451         } while (OtherAtom != Walker);
    452         ComponentNumber++;
    453 
    454         // (11) Root is separation vertex,  set Walker to Root and go to (4)
    455         Walker = Root;
    456         Binder = FindNextUnused(Walker);
    457         *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
    458         if (Binder != NULL) { // Root is separation vertex
    459           *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
    460           Walker->SeparationVertex = true;
    461         }
    462       }
    463     } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
     526      DepthFirstSearchAnalysis_CheckForaNewComponent(out, this, Walker, DFS, LeafWalker);
     527
     528      DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(out, this, Walker, Binder, DFS, LeafWalker);
     529
     530    } while ((DFS.BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
    464531
    465532    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    466     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     533    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << DFS.CurrentGraphNr << "." << endl;
    467534    LeafWalker->Leaf->Output(out);
    468535    *out << endl;
    469536
    470537    // step on to next root
    471     while ((Root != end) && (Root->GraphNr != -1)) {
     538    while ((DFS.Root != end) && (DFS.Root->GraphNr != -1)) {
    472539      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    473       if (Root->GraphNr != -1) // if already discovered, step on
    474         Root = Root->next;
     540      if (DFS.Root->GraphNr != -1) // if already discovered, step on
     541        DFS.Root = DFS.Root->next;
    475542    }
    476543  }
    477544  // set cyclic bond criterium on "same LP" basis
    478   Binder = first;
    479   while(Binder->next != last) {
     545  CyclicBondAnalysis();
     546
     547  OutputGraphInfoPerAtom(out);
     548
     549  OutputGraphInfoPerBond(out);
     550
     551  // free all and exit
     552  DepthFirstSearchAnalysis_Finalize(out, DFS);
     553  *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     554  return SubGraphs;
     555}
     556;
     557
     558/** Scans through all bonds and set bond::Cyclic to true where atom::LowpointNr of both ends is equal: LP criterion.
     559 */
     560void molecule::CyclicBondAnalysis() const
     561{
     562  NoCyclicBonds = 0;
     563  bond *Binder = first;
     564  while (Binder->next != last) {
    480565    Binder = Binder->next;
    481566    if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
     
    484569    }
    485570  }
    486 
    487 
     571}
     572;
     573
     574/** Output graph information per atom.
     575 * \param *out output stream
     576 */
     577void molecule::OutputGraphInfoPerAtom(ofstream *out) const
     578{
    488579  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    489   Walker = start;
    490   while (Walker->next != end) {
    491     Walker = Walker->next;
    492     *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    493     OutputComponentNumber(out, Walker);
    494     *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    495   }
    496 
     580  ActOnAllAtoms(&atom::OutputGraphInfo, out);
     581}
     582;
     583
     584/** Output graph information per bond.
     585 * \param *out output stream
     586 */
     587void molecule::OutputGraphInfoPerBond(ofstream *out) const
     588{
    497589  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    498   Binder = first;
    499   while(Binder->next != last) {
     590  bond *Binder = first;
     591  while (Binder->next != last) {
    500592    Binder = Binder->next;
    501593    *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    502594    *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    503     OutputComponentNumber(out, Binder->leftatom);
     595    Binder->leftatom->OutputComponentNumber(out);
    504596    *out << " ===  ";
    505597    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    506     OutputComponentNumber(out, Binder->rightatom);
     598    Binder->rightatom->OutputComponentNumber(out);
    507599    *out << ">." << endl;
    508600    if (Binder->Cyclic) // cyclic ??
    509601      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    510602  }
    511 
    512   // free all and exit
    513   delete(AtomStack);
    514   *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    515   return SubGraphs;
     603}
     604;
     605
     606/** Initialise each vertex as white with no predecessor, empty queue, color Root lightgray.
     607 * \param *out output stream for debugging
     608 * \param &BFS accounting structure
     609 * \param AtomCount number of entries in the array to allocate
     610 */
     611void InitializeBFSAccounting(ofstream *out, struct BFSAccounting &BFS, int AtomCount)
     612{
     613  BFS.AtomCount = AtomCount;
     614  BFS.PredecessorList = Calloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList");
     615  BFS.ShortestPathList = Malloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList");
     616  BFS.ColorList = Calloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList");
     617  BFS.BFSStack = new StackClass<atom *> (AtomCount);
     618
     619  for (int i = AtomCount; i--;)
     620    BFS.ShortestPathList[i] = -1;
    516621};
     622
     623/** Free's accounting structure.
     624 * \param *out output stream for debugging
     625 * \param &BFS accounting structure
     626 */
     627void FinalizeBFSAccounting(ofstream *out, struct BFSAccounting &BFS)
     628{
     629  Free(&BFS.PredecessorList);
     630  Free(&BFS.ShortestPathList);
     631  Free(&BFS.ColorList);
     632  delete (BFS.BFSStack);
     633  BFS.AtomCount = 0;
     634};
     635
     636/** Clean the accounting structure.
     637 * \param *out output stream for debugging
     638 * \param &BFS accounting structure
     639 */
     640void CleanBFSAccounting(ofstream *out, struct BFSAccounting &BFS)
     641{
     642  atom *Walker = NULL;
     643  while (!BFS.TouchedStack->IsEmpty()) {
     644    Walker = BFS.TouchedStack->PopFirst();
     645    BFS.PredecessorList[Walker->nr] = NULL;
     646    BFS.ShortestPathList[Walker->nr] = -1;
     647    BFS.ColorList[Walker->nr] = white;
     648  }
     649};
     650
     651/** Resets shortest path list and BFSStack.
     652 * \param *out output stream for debugging
     653 * \param *&Walker current node, pushed onto BFSAccounting::BFSStack and BFSAccounting::TouchedStack
     654 * \param &BFS accounting structure
     655 */
     656void ResetBFSAccounting(ofstream *out, atom *&Walker, struct BFSAccounting &BFS)
     657{
     658  BFS.ShortestPathList[Walker->nr] = 0;
     659  BFS.BFSStack->ClearStack(); // start with empty BFS stack
     660  BFS.BFSStack->Push(Walker);
     661  BFS.TouchedStack->Push(Walker);
     662};
     663
     664/** Performs a BFS from \a *Root, trying to find the same node and hence a cycle.
     665 * \param *out output stream for debugging
     666 * \param *&BackEdge the edge from root that we don't want to move along
     667 * \param &BFS accounting structure
     668 */
     669void CyclicStructureAnalysis_CyclicBFSFromRootToRoot(ofstream *out, bond *&BackEdge, struct BFSAccounting &BFS)
     670{
     671  atom *Walker = NULL;
     672  atom *OtherAtom = NULL;
     673  do { // look for Root
     674    Walker = BFS.BFSStack->PopFirst();
     675    *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *BFS.Root << "." << endl;
     676    for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     677      if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     678        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     679#ifdef ADDHYDROGEN
     680        if (OtherAtom->type->Z != 1) {
     681#endif
     682        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl;
     683        if (BFS.ColorList[OtherAtom->nr] == white) {
     684          BFS.TouchedStack->Push(OtherAtom);
     685          BFS.ColorList[OtherAtom->nr] = lightgray;
     686          BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor
     687          BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1;
     688          *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     689          //if (BFS.ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
     690          *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     691          BFS.BFSStack->Push(OtherAtom);
     692          //}
     693        } else {
     694          *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     695        }
     696        if (OtherAtom == BFS.Root)
     697          break;
     698#ifdef ADDHYDROGEN
     699      } else {
     700        *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     701        BFS.ColorList[OtherAtom->nr] = black;
     702      }
     703#endif
     704      } else {
     705        *out << Verbose(2) << "Bond " << *(*Runner) << " not Visiting, is the back edge." << endl;
     706      }
     707    }
     708    BFS.ColorList[Walker->nr] = black;
     709    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     710    if (OtherAtom == BFS.Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
     711      // step through predecessor list
     712      while (OtherAtom != BackEdge->rightatom) {
     713        if (!OtherAtom->GetTrueFather()->IsCyclic) // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
     714          break;
     715        else
     716          OtherAtom = BFS.PredecessorList[OtherAtom->nr];
     717      }
     718      if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
     719        *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;
     720        do {
     721          OtherAtom = BFS.TouchedStack->PopLast();
     722          if (BFS.PredecessorList[OtherAtom->nr] == Walker) {
     723            *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
     724            BFS.PredecessorList[OtherAtom->nr] = NULL;
     725            BFS.ShortestPathList[OtherAtom->nr] = -1;
     726            BFS.ColorList[OtherAtom->nr] = white;
     727            BFS.BFSStack->RemoveItem(OtherAtom);
     728          }
     729        } while ((!BFS.TouchedStack->IsEmpty()) && (BFS.PredecessorList[OtherAtom->nr] == NULL));
     730        BFS.TouchedStack->Push(OtherAtom); // last was wrongly popped
     731        OtherAtom = BackEdge->rightatom; // set to not Root
     732      } else
     733        OtherAtom = BFS.Root;
     734    }
     735  } while ((!BFS.BFSStack->IsEmpty()) && (OtherAtom != BFS.Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
     736};
     737
     738/** Climb back the BFSAccounting::PredecessorList and find cycle members.
     739 * \param *out output stream for debugging
     740 * \param *&OtherAtom
     741 * \param *&BackEdge denotes the edge we did not want to travel along when doing CyclicBFSFromRootToRoot()
     742 * \param &BFS accounting structure
     743 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom
     744 * \param &MinRingSize global minimum distance from one node without encountering oneself, set on return
     745 */
     746void CyclicStructureAnalysis_RetrieveCycleMembers(ofstream *out, atom *&OtherAtom, bond *&BackEdge, struct BFSAccounting &BFS, int *&MinimumRingSize, int &MinRingSize)
     747{
     748  atom *Walker = NULL;
     749  int NumCycles = 0;
     750  int RingSize = -1;
     751
     752  if (OtherAtom == BFS.Root) {
     753    // now climb back the predecessor list and thus find the cycle members
     754    NumCycles++;
     755    RingSize = 1;
     756    BFS.Root->GetTrueFather()->IsCyclic = true;
     757    *out << Verbose(1) << "Found ring contains: ";
     758    Walker = BFS.Root;
     759    while (Walker != BackEdge->rightatom) {
     760      *out << Walker->Name << " <-> ";
     761      Walker = BFS.PredecessorList[Walker->nr];
     762      Walker->GetTrueFather()->IsCyclic = true;
     763      RingSize++;
     764    }
     765    *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
     766    // walk through all and set MinimumRingSize
     767    Walker = BFS.Root;
     768    MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     769    while (Walker != BackEdge->rightatom) {
     770      Walker = BFS.PredecessorList[Walker->nr];
     771      if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
     772        MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     773    }
     774    if ((RingSize < MinRingSize) || (MinRingSize == -1))
     775      MinRingSize = RingSize;
     776  } else {
     777    *out << Verbose(1) << "No ring containing " << *BFS.Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
     778  }
     779};
     780
     781/** From a given node performs a BFS to touch the next cycle, for whose nodes \a *&MinimumRingSize is set and set it accordingly.
     782 * \param *out output stream for debugging
     783 * \param *&Root node to look for closest cycle from, i.e. \a *&MinimumRingSize is set for this node
     784 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom
     785 * \param AtomCount number of nodes in graph
     786 */
     787void CyclicStructureAnalysis_BFSToNextCycle(ofstream *out, atom *&Root, atom *&Walker, int *&MinimumRingSize, int AtomCount)
     788{
     789  struct BFSAccounting BFS;
     790  atom *OtherAtom = Walker;
     791
     792  InitializeBFSAccounting(out, BFS, AtomCount);
     793
     794  ResetBFSAccounting(out, Walker, BFS);
     795  while (OtherAtom != NULL) { // look for Root
     796    Walker = BFS.BFSStack->PopFirst();
     797    //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     798    for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     799      // "removed (*Runner) != BackEdge) || " from next if, is u
     800      if ((Walker->ListOfBonds.size() == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
     801        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     802        //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     803        if (BFS.ColorList[OtherAtom->nr] == white) {
     804          BFS.TouchedStack->Push(OtherAtom);
     805          BFS.ColorList[OtherAtom->nr] = lightgray;
     806          BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor
     807          BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1;
     808          //*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;
     809          if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
     810            MinimumRingSize[Root->GetTrueFather()->nr] = BFS.ShortestPathList[OtherAtom->nr] + MinimumRingSize[OtherAtom->GetTrueFather()->nr];
     811            OtherAtom = NULL; //break;
     812            break;
     813          } else
     814            BFS.BFSStack->Push(OtherAtom);
     815        } else {
     816          //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
     817        }
     818      } else {
     819        //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
     820      }
     821    }
     822    BFS.ColorList[Walker->nr] = black;
     823    //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     824  }
     825  //CleanAccountingLists(TouchedStack, PredecessorList, ShortestPathList, ColorList);
     826
     827  FinalizeBFSAccounting(out, BFS);
     828}
     829;
     830
     831/** All nodes that are not in cycles get assigned a \a *&MinimumRingSizeby BFS to next cycle.
     832 * \param *out output stream for debugging
     833 * \param *&MinimumRingSize array with minimum distance without encountering onself for each atom
     834 * \param &MinRingSize global minium distance
     835 * \param &NumCyles number of cycles in graph
     836 * \param *mol molecule with atoms
     837 */
     838void CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(ofstream *out, int *&MinimumRingSize, int &MinRingSize, int &NumCycles, const molecule * const mol)
     839{
     840  atom *Root = NULL;
     841  atom *Walker = NULL;
     842  if (MinRingSize != -1) { // if rings are present
     843    // go over all atoms
     844    Root = mol->start;
     845    while (Root->next != mol->end) {
     846      Root = Root->next;
     847
     848      if (MinimumRingSize[Root->GetTrueFather()->nr] == mol->AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
     849        Walker = Root;
     850
     851        //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     852        CyclicStructureAnalysis_BFSToNextCycle(out, Root, Walker, MinimumRingSize, mol->AtomCount);
     853
     854      }
     855      *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
     856    }
     857    *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
     858  } else
     859    *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
     860}
     861;
    517862
    518863/** Analyses the cycles found and returns minimum of all cycle lengths.
     
    526871 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
    527872 */
    528 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *  BackEdgeStack, int *&MinimumRingSize)
    529 {
    530   atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
    531   int *ShortestPathList = Malloc<int>(AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    532   enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    533   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
    534   class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    535   atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
    536   bond *Binder = NULL, *BackEdge = NULL;
    537   int RingSize, NumCycles, MinRingSize = -1;
    538 
    539   // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    540   for (int i=AtomCount;i--;) {
    541     PredecessorList[i] = NULL;
    542     ShortestPathList[i] = -1;
    543     ColorList[i] = white;
    544   }
    545 
    546   *out << Verbose(1) << "Back edge list - ";
    547   BackEdgeStack->Output(out);
     873void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> * BackEdgeStack, int *&MinimumRingSize) const
     874{
     875  struct BFSAccounting BFS;
     876  atom *Walker = NULL;
     877  atom *OtherAtom = NULL;
     878  bond *BackEdge = NULL;
     879  int NumCycles = 0;
     880  int MinRingSize = -1;
     881
     882  InitializeBFSAccounting(out, BFS, AtomCount);
     883
     884  //*out << Verbose(1) << "Back edge list - ";
     885  //BackEdgeStack->Output(out);
    548886
    549887  *out << Verbose(1) << "Analysing cycles ... " << endl;
     
    552890    BackEdge = BackEdgeStack->PopFirst();
    553891    // this is the target
    554     Root = BackEdge->leftatom;
     892    BFS.Root = BackEdge->leftatom;
    555893    // this is the source point
    556894    Walker = BackEdge->rightatom;
    557     ShortestPathList[Walker->nr] = 0;
    558     BFSStack->ClearStack();  // start with empty BFS stack
    559     BFSStack->Push(Walker);
    560     TouchedStack->Push(Walker);
     895
     896    ResetBFSAccounting(out, Walker, BFS);
     897
    561898    *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    562899    OtherAtom = NULL;
    563     do {  // look for Root
    564       Walker = BFSStack->PopFirst();
    565       *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    566       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    567         Binder = ListOfBondsPerAtom[Walker->nr][i];
    568         if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    569           OtherAtom = Binder->GetOtherAtom(Walker);
    570 #ifdef ADDHYDROGEN
    571           if (OtherAtom->type->Z != 1) {
    572 #endif
    573             *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    574             if (ColorList[OtherAtom->nr] == white) {
    575               TouchedStack->Push(OtherAtom);
    576               ColorList[OtherAtom->nr] = lightgray;
    577               PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    578               ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    579               *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;
    580               //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    581                 *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
    582                 BFSStack->Push(OtherAtom);
    583               //}
    584             } else {
    585               *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    586             }
    587             if (OtherAtom == Root)
    588               break;
    589 #ifdef ADDHYDROGEN
    590           } else {
    591             *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
    592             ColorList[OtherAtom->nr] = black;
    593           }
    594 #endif
    595         } else {
    596           *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
    597         }
    598       }
    599       ColorList[Walker->nr] = black;
    600       *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    601       if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
    602         // step through predecessor list
    603         while (OtherAtom != BackEdge->rightatom) {
    604           if (!OtherAtom->GetTrueFather()->IsCyclic)  // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
    605             break;
    606           else
    607             OtherAtom = PredecessorList[OtherAtom->nr];
    608         }
    609         if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
    610           *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
    611           do {
    612             OtherAtom = TouchedStack->PopLast();
    613             if (PredecessorList[OtherAtom->nr] == Walker) {
    614               *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
    615               PredecessorList[OtherAtom->nr] = NULL;
    616               ShortestPathList[OtherAtom->nr] = -1;
    617               ColorList[OtherAtom->nr] = white;
    618               BFSStack->RemoveItem(OtherAtom);
    619             }
    620           } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
    621           TouchedStack->Push(OtherAtom);  // last was wrongly popped
    622           OtherAtom = BackEdge->rightatom; // set to not Root
    623         } else
    624           OtherAtom = Root;
    625       }
    626     } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    627 
    628     if (OtherAtom == Root) {
    629       // now climb back the predecessor list and thus find the cycle members
    630       NumCycles++;
    631       RingSize = 1;
    632       Root->GetTrueFather()->IsCyclic = true;
    633       *out << Verbose(1) << "Found ring contains: ";
    634       Walker = Root;
    635       while (Walker != BackEdge->rightatom) {
    636         *out << Walker->Name << " <-> ";
    637         Walker = PredecessorList[Walker->nr];
    638         Walker->GetTrueFather()->IsCyclic = true;
    639         RingSize++;
    640       }
    641       *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
    642       // walk through all and set MinimumRingSize
    643       Walker = Root;
    644       MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    645       while (Walker != BackEdge->rightatom) {
    646         Walker = PredecessorList[Walker->nr];
    647         if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
    648           MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    649       }
    650       if ((RingSize < MinRingSize) || (MinRingSize == -1))
    651         MinRingSize = RingSize;
    652     } else {
    653       *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    654     }
    655 
    656     // now clean the lists
    657     while (!TouchedStack->IsEmpty()){
    658       Walker = TouchedStack->PopFirst();
    659       PredecessorList[Walker->nr] = NULL;
    660       ShortestPathList[Walker->nr] = -1;
    661       ColorList[Walker->nr] = white;
    662     }
    663   }
    664   if (MinRingSize != -1) {
    665     // go over all atoms
    666     Root = start;
    667     while(Root->next != end) {
    668       Root = Root->next;
    669 
    670       if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    671         Walker = Root;
    672         ShortestPathList[Walker->nr] = 0;
    673         BFSStack->ClearStack();  // start with empty BFS stack
    674         BFSStack->Push(Walker);
    675         TouchedStack->Push(Walker);
    676         //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    677         OtherAtom = Walker;
    678         while (OtherAtom != NULL) {  // look for Root
    679           Walker = BFSStack->PopFirst();
    680           //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    681           for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    682             Binder = ListOfBondsPerAtom[Walker->nr][i];
    683             if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
    684               OtherAtom = Binder->GetOtherAtom(Walker);
    685               //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    686               if (ColorList[OtherAtom->nr] == white) {
    687                 TouchedStack->Push(OtherAtom);
    688                 ColorList[OtherAtom->nr] = lightgray;
    689                 PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    690                 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    691                 //*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;
    692                 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
    693                   MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
    694                   OtherAtom = NULL; //break;
    695                   break;
    696                 } else
    697                   BFSStack->Push(OtherAtom);
    698               } else {
    699                 //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
    700               }
    701             } else {
    702               //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
    703             }
    704           }
    705           ColorList[Walker->nr] = black;
    706           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    707         }
    708 
    709         // now clean the lists
    710         while (!TouchedStack->IsEmpty()){
    711           Walker = TouchedStack->PopFirst();
    712           PredecessorList[Walker->nr] = NULL;
    713           ShortestPathList[Walker->nr] = -1;
    714           ColorList[Walker->nr] = white;
    715         }
    716       }
    717       *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
    718     }
    719     *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
    720   } else
    721     *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
    722 
    723   Free(&PredecessorList);
    724   Free(&ShortestPathList);
    725   Free(&ColorList);
    726   delete(BFSStack);
     900    CyclicStructureAnalysis_CyclicBFSFromRootToRoot(out, BackEdge, BFS);
     901
     902    CyclicStructureAnalysis_RetrieveCycleMembers(out, OtherAtom, BackEdge, BFS, MinimumRingSize, MinRingSize);
     903
     904    CleanBFSAccounting(out, BFS);
     905  }
     906  FinalizeBFSAccounting(out, BFS);
     907
     908  CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(out, MinimumRingSize, MinRingSize, NumCycles, this);
    727909};
    728910
     
    732914 * \param nr number to use
    733915 */
    734 void molecule::SetNextComponentNumber(atom *vertex, int nr)
    735 {
    736   int i=0;
     916void molecule::SetNextComponentNumber(atom *vertex, int nr) const
     917{
     918  size_t i = 0;
    737919  if (vertex != NULL) {
    738     for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
    739       if (vertex->ComponentNr[i] == -1) {   // check if not yet used
     920    for (; i < vertex->ListOfBonds.size(); i++) {
     921      if (vertex->ComponentNr[i] == -1) { // check if not yet used
    740922        vertex->ComponentNr[i] = nr;
    741923        break;
    742       }
    743       else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
    744         break;  // breaking here will not cause error!
    745     }
    746     if (i == NumberOfBondsPerAtom[vertex->nr])
     924      } else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
     925        break; // breaking here will not cause error!
     926    }
     927    if (i == vertex->ListOfBonds.size())
    747928      cerr << "Error: All Component entries are already occupied!" << endl;
    748929  } else
    749       cerr << "Error: Given vertex is NULL!" << endl;
    750 };
    751 
    752 /** Output a list of flags, stating whether the bond was visited or not.
    753  * \param *out output stream for debugging
    754  */
    755 void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    756 {
    757   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    758     *out << vertex->ComponentNr[i] << "  ";
    759 };
    760 
    761 /** Allocates memory for all atom::*ComponentNr in this molecule and sets each entry to -1.
    762  */
    763 void molecule::InitComponentNumbers()
    764 {
    765   atom *Walker = start;
    766   while(Walker->next != end) {
    767     Walker = Walker->next;
    768     if (Walker->ComponentNr != NULL)
    769       Free(&Walker->ComponentNr);
    770     Walker->ComponentNr = Malloc<int>(NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    771     for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
    772       Walker->ComponentNr[i] = -1;
    773   }
    774 };
     930    cerr << "Error: Given vertex is NULL!" << endl;
     931}
     932;
    775933
    776934/** Returns next unused bond for this atom \a *vertex or NULL of none exists.
     
    778936 * \return bond class or NULL
    779937 */
    780 bond * molecule::FindNextUnused(atom *vertex)
    781 {
    782   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    783     if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    784       return(ListOfBondsPerAtom[vertex->nr][i]);
     938bond * molecule::FindNextUnused(atom *vertex) const
     939{
     940  for (BondList::const_iterator Runner = vertex->ListOfBonds.begin(); Runner != vertex->ListOfBonds.end(); (++Runner))
     941    if ((*Runner)->IsUsed() == white)
     942      return ((*Runner));
    785943  return NULL;
    786 };
     944}
     945;
    787946
    788947/** Resets bond::Used flag of all bonds in this molecule.
    789948 * \return true - success, false - -failure
    790949 */
    791 void molecule::ResetAllBondsToUnused()
     950void molecule::ResetAllBondsToUnused() const
    792951{
    793952  bond *Binder = first;
     
    796955    Binder->ResetUsed();
    797956  }
    798 };
    799 
    800 /** Resets atom::nr to -1 of all atoms in this molecule.
    801  */
    802 void molecule::ResetAllAtomNumbers()
    803 {
    804   atom *Walker = start;
    805   while (Walker->next != end) {
    806     Walker = Walker->next;
    807     Walker->GraphNr  = -1;
    808   }
    809 };
     957}
     958;
    810959
    811960/** Output a list of flags, stating whether the bond was visited or not.
     
    816965{
    817966  *out << Verbose(4) << "Already Visited Bonds:\t";
    818   for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
     967  for (int i = 1; i <= list[0]; i++)
     968    *out << Verbose(0) << list[i] << "  ";
    819969  *out << endl;
    820 };
    821 
     970}
     971;
    822972
    823973/** Storing the bond structure of a molecule to file.
     
    830980{
    831981  ofstream AdjacencyFile;
    832   atom *Walker = NULL;
    833982  stringstream line;
    834983  bool status = true;
     
    838987  *out << Verbose(1) << "Saving adjacency list ... ";
    839988  if (AdjacencyFile != NULL) {
    840     Walker = start;
    841     while(Walker->next != end) {
    842       Walker = Walker->next;
    843       AdjacencyFile << Walker->nr << "\t";
    844       for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    845         AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    846       AdjacencyFile << endl;
    847     }
     989    ActOnAllAtoms(&atom::OutputAdjacency, &AdjacencyFile);
    848990    AdjacencyFile.close();
    849991    *out << Verbose(1) << "done." << endl;
     
    854996
    855997  return status;
    856 };
     998}
     999;
     1000
     1001bool CheckAdjacencyFileAgainstMolecule_Init(ofstream *out, char *path, ifstream &File, int *&CurrentBonds)
     1002{
     1003  stringstream filename;
     1004  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     1005  File.open(filename.str().c_str(), ios::out);
     1006  *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
     1007  if (File == NULL)
     1008    return false;
     1009
     1010  // allocate storage structure
     1011  CurrentBonds = Calloc<int> (8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
     1012  return true;
     1013}
     1014;
     1015
     1016void CheckAdjacencyFileAgainstMolecule_Finalize(ofstream *out, ifstream &File, int *&CurrentBonds)
     1017{
     1018  File.close();
     1019  File.clear();
     1020  Free(&CurrentBonds);
     1021}
     1022;
     1023
     1024void CheckAdjacencyFileAgainstMolecule_CompareBonds(ofstream *out, bool &status, int &NonMatchNumber, atom *&Walker, size_t &CurrentBondsOfAtom, int AtomNr, int *&CurrentBonds, atom **ListOfAtoms)
     1025{
     1026  size_t j = 0;
     1027  int id = -1;
     1028
     1029  //*out << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
     1030  if (CurrentBondsOfAtom == Walker->ListOfBonds.size()) {
     1031    for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1032      id = (*Runner)->GetOtherAtom(Walker)->nr;
     1033      j = 0;
     1034      for (; (j < CurrentBondsOfAtom) && (CurrentBonds[j++] != id);)
     1035        ; // check against all parsed bonds
     1036      if (CurrentBonds[j - 1] != id) { // no match ? Then mark in ListOfAtoms
     1037        ListOfAtoms[AtomNr] = NULL;
     1038        NonMatchNumber++;
     1039        status = false;
     1040        //*out << "[" << id << "]\t";
     1041      } else {
     1042        //*out << id << "\t";
     1043      }
     1044    }
     1045    //*out << endl;
     1046  } else {
     1047    *out << "Number of bonds for Atom " << *Walker << " does not match, parsed " << CurrentBondsOfAtom << " against " << Walker->ListOfBonds.size() << "." << endl;
     1048    status = false;
     1049  }
     1050}
     1051;
    8571052
    8581053/** Checks contents of adjacency file against bond structure in structure molecule.
     
    8651060{
    8661061  ifstream File;
    867   stringstream filename;
    8681062  bool status = true;
    869   char *buffer = Malloc<char>(MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    870 
    871   filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    872   File.open(filename.str().c_str(), ios::out);
    873   *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
    874   if (File != NULL) {
    875     // allocate storage structure
    876     int NonMatchNumber = 0;   // will number of atoms with differing bond structure
    877     int *CurrentBonds = Malloc<int>(8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    878     int CurrentBondsOfAtom;
    879 
    880     // Parse the file line by line and count the bonds
    881     while (!File.eof()) {
    882       File.getline(buffer, MAXSTRINGSIZE);
    883       stringstream line;
    884       line.str(buffer);
    885       int AtomNr = -1;
    886       line >> AtomNr;
    887       CurrentBondsOfAtom = -1; // we count one too far due to line end
    888       // parse into structure
    889       if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    890         while (!line.eof())
    891           line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    892         // compare against present bonds
    893         //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    894         if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    895           for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    896             int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    897             int j = 0;
    898             for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    899             if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
    900               ListOfAtoms[AtomNr] = NULL;
    901               NonMatchNumber++;
    902               status = false;
    903               //out << "[" << id << "]\t";
    904             } else {
    905               //out << id << "\t";
    906             }
    907           }
    908           //out << endl;
    909         } else {
    910           *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
    911           status = false;
    912         }
    913       }
    914     }
    915     File.close();
    916     File.clear();
    917     if (status) { // if equal we parse the KeySetFile
    918       *out << Verbose(1) << "done: Equal." << endl;
    919       status = true;
    920     } else
    921       *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    922     Free(&CurrentBonds);
    923   } else {
     1063  atom *Walker = NULL;
     1064  char *buffer = NULL;
     1065  int *CurrentBonds = NULL;
     1066  int NonMatchNumber = 0; // will number of atoms with differing bond structure
     1067  size_t CurrentBondsOfAtom = -1;
     1068
     1069  if (!CheckAdjacencyFileAgainstMolecule_Init(out, path, File, CurrentBonds)) {
    9241070    *out << Verbose(1) << "Adjacency file not found." << endl;
    925     status = false;
    926   }
    927   *out << endl;
     1071    return true;
     1072  }
     1073
     1074  buffer = Malloc<char> (MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     1075  // Parse the file line by line and count the bonds
     1076  while (!File.eof()) {
     1077    File.getline(buffer, MAXSTRINGSIZE);
     1078    stringstream line;
     1079    line.str(buffer);
     1080    int AtomNr = -1;
     1081    line >> AtomNr;
     1082    CurrentBondsOfAtom = -1; // we count one too far due to line end
     1083    // parse into structure
     1084    if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     1085      Walker = ListOfAtoms[AtomNr];
     1086      while (!line.eof())
     1087        line >> CurrentBonds[++CurrentBondsOfAtom];
     1088      // compare against present bonds
     1089      CheckAdjacencyFileAgainstMolecule_CompareBonds(out, status, NonMatchNumber, Walker, CurrentBondsOfAtom, AtomNr, CurrentBonds, ListOfAtoms);
     1090    }
     1091  }
    9281092  Free(&buffer);
    929 
     1093  CheckAdjacencyFileAgainstMolecule_Finalize(out, File, CurrentBonds);
     1094
     1095  if (status) { // if equal we parse the KeySetFile
     1096    *out << Verbose(1) << "done: Equal." << endl;
     1097  } else
     1098    *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    9301099  return status;
    931 };
    932 
     1100}
     1101;
    9331102
    9341103/** Picks from a global stack with all back edges the ones in the fragment.
     
    9391108 * \return true - everything ok, false - ReferenceStack was empty
    9401109 */
    941 bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
     1110bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack) const
    9421111{
    9431112  bool status = true;
     
    9471116  }
    9481117  bond *Binder = ReferenceStack->PopFirst();
    949   bond *FirstBond = Binder;   // mark the first bond, so that we don't loop through the stack indefinitely
     1118  bond *FirstBond = Binder; // mark the first bond, so that we don't loop through the stack indefinitely
    9501119  atom *Walker = NULL, *OtherAtom = NULL;
    9511120  ReferenceStack->Push(Binder);
    9521121
    953   do {  // go through all bonds and push local ones
    954     Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     1122  do { // go through all bonds and push local ones
     1123    Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule
    9551124    if (Walker != NULL) // if this Walker exists in the subgraph ...
    956       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    957         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    958         if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    959           LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    960           *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
     1125      for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1126        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     1127        if (OtherAtom == ListOfLocalAtoms[(*Runner)->rightatom->nr]) { // found the bond
     1128          LocalStack->Push((*Runner));
     1129          *out << Verbose(3) << "Found local edge " << *(*Runner) << "." << endl;
    9611130          break;
    9621131        }
    9631132      }
    964     Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     1133    Binder = ReferenceStack->PopFirst(); // loop the stack for next item
    9651134    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    9661135    ReferenceStack->Push(Binder);
     
    9681137
    9691138  return status;
    970 };
    971 
     1139}
     1140;
     1141
     1142void BreadthFirstSearchAdd_Init(struct BFSAccounting &BFS, atom *&Root, int AtomCount, int BondOrder, atom **AddedAtomList = NULL)
     1143{
     1144  BFS.AtomCount = AtomCount;
     1145  BFS.BondOrder = BondOrder;
     1146  BFS.PredecessorList = Calloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList");
     1147  BFS.ShortestPathList = Calloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList");
     1148  BFS.ColorList = Malloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList");
     1149  BFS.BFSStack = new StackClass<atom *> (AtomCount);
     1150
     1151  BFS.Root = Root;
     1152  BFS.BFSStack->ClearStack();
     1153  BFS.BFSStack->Push(Root);
     1154
     1155  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     1156  for (int i = AtomCount; i--;) {
     1157    BFS.ShortestPathList[i] = -1;
     1158    if ((AddedAtomList != NULL) && (AddedAtomList[i] != NULL)) // mark already present atoms (i.e. Root and maybe others) as visited
     1159      BFS.ColorList[i] = lightgray;
     1160    else
     1161      BFS.ColorList[i] = white;
     1162  }
     1163  //BFS.ShortestPathList[Root->nr] = 0; //is set due to Calloc()
     1164}
     1165;
     1166
     1167void BreadthFirstSearchAdd_Free(struct BFSAccounting &BFS)
     1168{
     1169  Free(&BFS.PredecessorList);
     1170  Free(&BFS.ShortestPathList);
     1171  Free(&BFS.ColorList);
     1172  delete (BFS.BFSStack);
     1173  BFS.AtomCount = 0;
     1174}
     1175;
     1176
     1177void BreadthFirstSearchAdd_UnvisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem)
     1178{
     1179  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)
     1180    BFS.ColorList[OtherAtom->nr] = lightgray;
     1181  BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor
     1182  BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1;
     1183  *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((BFS.ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     1184  if ((((BFS.ShortestPathList[OtherAtom->nr] < BFS.BondOrder) && (Binder != Bond)))) { // Check for maximum distance
     1185    *out << Verbose(3);
     1186    if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
     1187      AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
     1188      *out << "Added OtherAtom " << OtherAtom->Name;
     1189      AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder);
     1190      *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     1191    } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place)
     1192      *out << "Not adding OtherAtom " << OtherAtom->Name;
     1193      if (AddedBondList[Binder->nr] == NULL) {
     1194        AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder);
     1195        *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     1196      } else
     1197        *out << ", not added Bond ";
     1198    }
     1199    *out << ", putting OtherAtom into queue." << endl;
     1200    BFS.BFSStack->Push(OtherAtom);
     1201  } else { // out of bond order, then replace
     1202    if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     1203      BFS.ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
     1204    if (Binder == Bond)
     1205      *out << Verbose(3) << "Not Queueing, is the Root bond";
     1206    else if (BFS.ShortestPathList[OtherAtom->nr] >= BFS.BondOrder)
     1207      *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BFS.BondOrder;
     1208    if (!Binder->Cyclic)
     1209      *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
     1210    if (AddedBondList[Binder->nr] == NULL) {
     1211      if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
     1212        AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder);
     1213      } else {
     1214#ifdef ADDHYDROGEN
     1215        if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem))
     1216        exit(1);
     1217#endif
     1218      }
     1219    }
     1220  }
     1221}
     1222;
     1223
     1224void BreadthFirstSearchAdd_VisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem)
     1225{
     1226  *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     1227  // This has to be a cyclic bond, check whether it's present ...
     1228  if (AddedBondList[Binder->nr] == NULL) {
     1229    if ((Binder != Bond) && (Binder->Cyclic) && (((BFS.ShortestPathList[Walker->nr] + 1) < BFS.BondOrder))) {
     1230      AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder);
     1231    } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
     1232#ifdef ADDHYDROGEN
     1233      if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem))
     1234      exit(1);
     1235#endif
     1236    }
     1237  }
     1238}
     1239;
    9721240
    9731241/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
     
    9851253void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    9861254{
    987   atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    988   int *ShortestPathList = Malloc<int>(AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
    989   enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
    990   class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     1255  struct BFSAccounting BFS;
    9911256  atom *Walker = NULL, *OtherAtom = NULL;
    9921257  bond *Binder = NULL;
    9931258
    9941259  // add Root if not done yet
    995   AtomStack->ClearStack();
    996   if (AddedAtomList[Root->nr] == NULL)  // add Root if not yet present
     1260  if (AddedAtomList[Root->nr] == NULL) // add Root if not yet present
    9971261    AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
    998   AtomStack->Push(Root);
    999 
    1000   // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    1001   for (int i=AtomCount;i--;) {
    1002     PredecessorList[i] = NULL;
    1003     ShortestPathList[i] = -1;
    1004     if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
    1005       ColorList[i] = lightgray;
    1006     else
    1007       ColorList[i] = white;
    1008   }
    1009   ShortestPathList[Root->nr] = 0;
     1262
     1263  BreadthFirstSearchAdd_Init(BFS, Root, BondOrder, AtomCount, AddedAtomList);
    10101264
    10111265  // and go on ... Queue always contains all lightgray vertices
    1012   while (!AtomStack->IsEmpty()) {
     1266  while (!BFS.BFSStack->IsEmpty()) {
    10131267    // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
    10141268    // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again
    10151269    // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
    10161270    // followed by n+1 till top of stack.
    1017     Walker = AtomStack->PopFirst(); // pop oldest added
    1018     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    1019     for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    1020       Binder = ListOfBondsPerAtom[Walker->nr][i];
    1021       if (Binder != NULL) { // don't look at bond equal NULL
    1022         OtherAtom = Binder->GetOtherAtom(Walker);
    1023         *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    1024         if (ColorList[OtherAtom->nr] == white) {
    1025           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)
    1026             ColorList[OtherAtom->nr] = lightgray;
    1027           PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    1028           ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    1029           *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;
    1030           if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    1031             *out << Verbose(3);
    1032             if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    1033               AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    1034               *out << "Added OtherAtom " << OtherAtom->Name;
    1035               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1036               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1037               AddedBondList[Binder->nr]->Type = Binder->Type;
    1038               *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
    1039             } else {  // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place)
    1040               *out << "Not adding OtherAtom " << OtherAtom->Name;
    1041               if (AddedBondList[Binder->nr] == NULL) {
    1042                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1043                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1044                 AddedBondList[Binder->nr]->Type = Binder->Type;
    1045                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
    1046               } else
    1047                 *out << ", not added Bond ";
    1048             }
    1049             *out << ", putting OtherAtom into queue." << endl;
    1050             AtomStack->Push(OtherAtom);
    1051           } else { // out of bond order, then replace
    1052             if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
    1053               ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    1054             if (Binder == Bond)
    1055               *out << Verbose(3) << "Not Queueing, is the Root bond";
    1056             else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    1057               *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    1058             if (!Binder->Cyclic)
    1059               *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    1060             if (AddedBondList[Binder->nr] == NULL) {
    1061               if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    1062                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1063                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1064                 AddedBondList[Binder->nr]->Type = Binder->Type;
    1065               } else {
    1066 #ifdef ADDHYDROGEN
    1067                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    1068                   exit(1);
    1069 #endif
    1070               }
    1071             }
    1072           }
     1271    Walker = BFS.BFSStack->PopFirst(); // pop oldest added
     1272    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << Walker->ListOfBonds.size() << " bonds." << endl;
     1273    for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1274      if ((*Runner) != NULL) { // don't look at bond equal NULL
     1275        Binder = (*Runner);
     1276        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     1277        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl;
     1278        if (BFS.ColorList[OtherAtom->nr] == white) {
     1279          BreadthFirstSearchAdd_UnvisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem);
    10731280        } else {
    1074           *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    1075           // This has to be a cyclic bond, check whether it's present ...
    1076           if (AddedBondList[Binder->nr] == NULL) {
    1077             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    1078               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1079               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1080               AddedBondList[Binder->nr]->Type = Binder->Type;
    1081             } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    1082 #ifdef ADDHYDROGEN
    1083               if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    1084                 exit(1);
    1085 #endif
    1086             }
    1087           }
     1281          BreadthFirstSearchAdd_VisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem);
    10881282        }
    10891283      }
    10901284    }
    1091     ColorList[Walker->nr] = black;
     1285    BFS.ColorList[Walker->nr] = black;
    10921286    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    10931287  }
    1094   Free(&PredecessorList);
    1095   Free(&ShortestPathList);
    1096   Free(&ColorList);
    1097   delete(AtomStack);
    1098 };
    1099 
    1100 /** Adds bond structure to this molecule from \a Father molecule.
    1101  * This basically causes this molecule to become an induced subgraph of the \a Father, i.e. for every bond in Father
    1102  * with end points present in this molecule, bond is created in this molecule.
    1103  * Special care was taken to ensure that this is of complexity O(N), where N is the \a Father's molecule::AtomCount.
    1104  * \param *out output stream for debugging
    1105  * \param *Father father molecule
    1106  * \return true - is induced subgraph, false - there are atoms with fathers not in \a Father
    1107  * \todo not checked, not fully working probably
    1108  */
    1109 bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
    1110 {
    1111   atom *Walker = NULL, *OtherAtom = NULL;
    1112   bool status = true;
    1113   atom **ParentList = Malloc<atom*>(Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
    1114 
    1115   *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    1116 
     1288  BreadthFirstSearchAdd_Free(BFS);
     1289}
     1290;
     1291
     1292/** Adds a bond as a copy to a given one
     1293 * \param *left leftatom of new bond
     1294 * \param *right rightatom of new bond
     1295 * \param *CopyBond rest of fields in bond are copied from this
     1296 * \return pointer to new bond
     1297 */
     1298bond * molecule::CopyBond(atom *left, atom *right, bond *CopyBond)
     1299{
     1300  bond *Binder = AddBond(left, right, CopyBond->BondDegree);
     1301  Binder->Cyclic = CopyBond->Cyclic;
     1302  Binder->Type = CopyBond->Type;
     1303  return Binder;
     1304}
     1305;
     1306
     1307void BuildInducedSubgraph_Init(ofstream *out, atom **&ParentList, int AtomCount)
     1308{
    11171309  // reset parent list
     1310  ParentList = Calloc<atom*> (AtomCount, "molecule::BuildInducedSubgraph_Init: **ParentList");
    11181311  *out << Verbose(3) << "Resetting ParentList." << endl;
    1119   for (int i=Father->AtomCount;i--;)
    1120     ParentList[i] = NULL;
    1121 
     1312}
     1313;
     1314
     1315void BuildInducedSubgraph_FillParentList(ofstream *out, const molecule *mol, const molecule *Father, atom **&ParentList)
     1316{
    11221317  // fill parent list with sons
    11231318  *out << Verbose(3) << "Filling Parent List." << endl;
    1124   Walker = start;
    1125   while (Walker->next != end) {
     1319  atom *Walker = mol->start;
     1320  while (Walker->next != mol->end) {
    11261321    Walker = Walker->next;
    11271322    ParentList[Walker->father->nr] = Walker;
    11281323    // Outputting List for debugging
    1129     *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<  " is " << ParentList[Walker->father->nr] << "." << endl;
    1130   }
    1131 
     1324    *out << Verbose(4) << "Son[" << Walker->father->nr << "] of " << Walker->father << " is " << ParentList[Walker->father->nr] << "." << endl;
     1325  }
     1326
     1327}
     1328;
     1329
     1330void BuildInducedSubgraph_Finalize(ofstream *out, atom **&ParentList)
     1331{
     1332  Free(&ParentList);
     1333}
     1334;
     1335
     1336bool BuildInducedSubgraph_CreateBondsFromParent(ofstream *out, molecule *mol, const molecule *Father, atom **&ParentList)
     1337{
     1338  bool status = true;
     1339  atom *Walker = NULL;
     1340  atom *OtherAtom = NULL;
    11321341  // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
    11331342  *out << Verbose(3) << "Creating bonds." << endl;
     
    11391348        status = false;
    11401349      } else {
    1141         for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    1142           OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1350        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1351          OtherAtom = (*Runner)->GetOtherAtom(Walker);
    11431352          if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    1144             *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    1145             AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     1353            *out << Verbose(4) << "Endpoints of Bond " << (*Runner) << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     1354            mol->AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], (*Runner)->BondDegree);
    11461355          }
    11471356        }
     
    11491358    }
    11501359  }
    1151 
    1152   Free(&ParentList);
     1360  return status;
     1361}
     1362;
     1363
     1364/** Adds bond structure to this molecule from \a Father molecule.
     1365 * This basically causes this molecule to become an induced subgraph of the \a Father, i.e. for every bond in Father
     1366 * with end points present in this molecule, bond is created in this molecule.
     1367 * Special care was taken to ensure that this is of complexity O(N), where N is the \a Father's molecule::AtomCount.
     1368 * \param *out output stream for debugging
     1369 * \param *Father father molecule
     1370 * \return true - is induced subgraph, false - there are atoms with fathers not in \a Father
     1371 * \todo not checked, not fully working probably
     1372 */
     1373bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
     1374{
     1375  bool status = true;
     1376  atom **ParentList = NULL;
     1377
     1378  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
     1379  BuildInducedSubgraph_Init(out, ParentList, Father->AtomCount);
     1380  BuildInducedSubgraph_FillParentList(out, this, Father, ParentList);
     1381  status = BuildInducedSubgraph_CreateBondsFromParent(out, this, Father, ParentList);
     1382  BuildInducedSubgraph_Finalize(out, ParentList);
    11531383  *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
    11541384  return status;
    1155 };
    1156 
     1385}
     1386;
    11571387
    11581388/** For a given keyset \a *Fragment, checks whether it is connected in the current molecule.
     
    11731403  // count number of atoms in graph
    11741404  size = 0;
    1175   for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
     1405  for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
    11761406    size++;
    11771407  if (size > 1)
    1178     for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
     1408    for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
    11791409      Walker = FindAtom(*runner);
    11801410      BondStatus = false;
    1181       for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
     1411      for (KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    11821412        Walker2 = FindAtom(*runners);
    1183         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    1184           if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     1413        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1414          if ((*Runner)->GetOtherAtom(Walker) == Walker2) {
    11851415            BondStatus = true;
    11861416            break;
  • src/molecule_pointcloud.cpp

    r06c7a3 r7326b2  
    1818 * \return pointer to allocated with central coordinates
    1919 */
    20 Vector *molecule::GetCenter(ofstream *out)
     20Vector *molecule::GetCenter(ofstream *out) const
    2121{
    2222  Vector *center = DetermineCenterOfAll(out);
     
    2727 * \return pointer to atom or NULL if none present
    2828 */
    29 TesselPoint *molecule::GetPoint()
     29TesselPoint *molecule::GetPoint() const
    3030{
    3131  if ((InternalPointer != start) && (InternalPointer != end))
     
    3838 * \return pointer to end marker
    3939 */
    40 TesselPoint *molecule::GetTerminalPoint()
     40TesselPoint *molecule::GetTerminalPoint() const
    4141{
    4242  return end;
     
    4646 * Stops at last one.
    4747 */
    48 void molecule::GoToNext()
     48void molecule::GoToNext() const
    4949{
    5050  if (InternalPointer != end)
     
    5555 * Stops at first one.
    5656 */
    57 void molecule::GoToPrevious()
     57void molecule::GoToPrevious() const
    5858{
    5959  if (InternalPointer->previous != start)
     
    6363/** Goes to first atom.
    6464 */
    65 void molecule::GoToFirst()
     65void molecule::GoToFirst() const
    6666{
    6767  InternalPointer = start->next;
     
    7070/** Goes to last atom.
    7171 */
    72 void molecule::GoToLast()
     72void molecule::GoToLast() const
    7373{
    7474  InternalPointer = end->previous;
     
    7878 * \return true - no atoms, false - not empty
    7979 */
    80 bool molecule::IsEmpty()
     80bool molecule::IsEmpty() const
    8181{
    8282  return (start->next == end);
     
    8686 * \return true - current atom is last one, false - is not last one
    8787 */
    88 bool molecule::IsEnd()
     88bool molecule::IsEnd() const
    8989{
    9090  return (InternalPointer == end);
  • src/molecule_template.hpp

    r06c7a3 r7326b2  
    2121
    2222// zero arguments
    23 template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() )
    24 {
    25   atom *Walker = start;
    26   while (Walker->next != end) {
    27     Walker = Walker->next;
    28     ((Walker->node)->*f)();
    29   }
    30 };
    31 template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() const )
    32 {
    33   atom *Walker = start;
    34   while (Walker->next != end) {
    35     Walker = Walker->next;
    36     ((Walker->node)->*f)();
    37   }
    38 };
    3923template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() ) const
    4024    {
     
    5438};
    5539// one argument
    56 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t )
     40template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t ) const
    5741{
    5842  atom *Walker = start;
     
    6246  }
    6347};
    64 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t )
     48template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t ) const
    6549{
    6650  atom *Walker = start;
     
    7054  }
    7155};
    72 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t ) const
    73 {
    74   atom *Walker = start;
    75   while (Walker->next != end) {
    76     Walker = Walker->next;
    77     ((Walker->node)->*f)(t);
    78   }
    79 };
    80 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t ) const
    81 {
    82   atom *Walker = start;
    83   while (Walker->next != end) {
    84     Walker = Walker->next;
    85     ((Walker->node)->*f)(t);
    86   }
    87 };
    8856// two arguments
    89 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u )
     57template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const
    9058{
    9159  atom *Walker = start;
     
    9563  }
    9664};
    97 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u )
     65template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const
    9866{
    9967  atom *Walker = start;
     
    10371  }
    10472};
    105 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const
    106 {
    107   atom *Walker = start;
    108   while (Walker->next != end) {
    109     Walker = Walker->next;
    110     ((Walker->node)->*f)(t, u);
    111   }
    112 };
    113 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const
    114 {
    115   atom *Walker = start;
    116   while (Walker->next != end) {
    117     Walker = Walker->next;
    118     ((Walker->node)->*f)(t, u);
    119   }
    120 };
    12173// three arguments
    122 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v)
     74template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const
    12375{
    12476  atom *Walker = start;
     
    12880  }
    12981};
    130 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v)
     82template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const
    13183{
    13284  atom *Walker = start;
     
    13688  }
    13789};
    138 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const
    139 {
    140   atom *Walker = start;
    141   while (Walker->next != end) {
    142     Walker = Walker->next;
    143     ((Walker->node)->*f)(t, u, v);
    144   }
    145 };
    146 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const
    147 {
    148   atom *Walker = start;
    149   while (Walker->next != end) {
    150     Walker = Walker->next;
    151     ((Walker->node)->*f)(t, u, v);
    152   }
    153 };
     90
     91// ========================= Summing over each Atoms =================================== //
     92
     93// zero arguments
     94template <typename res, typename typ> res molecule::SumPerAtom(res (typ::*f)() ) const
     95{
     96  res result = 0;
     97  atom *Walker = start;
     98  while (Walker->next != end) {
     99    Walker = Walker->next;
     100    result += (Walker->*f)();
     101  }
     102  return result;
     103};
     104template <typename res, typename typ> res molecule::SumPerAtom(res (typ::*f)() const ) const
     105{
     106  res result = 0;
     107  atom *Walker = start;
     108  while (Walker->next != end) {
     109    Walker = Walker->next;
     110    result += (Walker->*f)();
     111  }
     112  return result;
     113};
     114// one argument
     115template <typename res, typename typ, typename T> res molecule::SumPerAtom(res (typ::*f)(T), T t ) const
     116{
     117  res result = 0;
     118  atom *Walker = start;
     119  while (Walker->next != end) {
     120    Walker = Walker->next;
     121    result += (Walker->*f)(t);
     122  }
     123  return result;
     124};
     125template <typename res, typename typ, typename T> res molecule::SumPerAtom(res (typ::*f)(T) const, T t ) const
     126{
     127  res result = 0;
     128  atom *Walker = start;
     129  while (Walker->next != end) {
     130    Walker = Walker->next;
     131    result += (Walker->*f)(t);
     132  }
     133  return result;
     134};
     135
    154136
    155137// ================== Acting with each Atoms on same molecule ========================== //
    156138
    157139// zero arguments
    158 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *))
     140template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *)) const
    159141{
    160142  atom *Walker = start;
     
    164146  }
    165147};
    166 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const)
     148template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const) const
    167149{
    168150  atom *Walker = start;
     
    172154  }
    173155};
    174 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *)) const
    175 {
    176   atom *Walker = start;
    177   while (Walker->next != end) {
    178     Walker = Walker->next;
    179     (*f)(Walker);
    180   }
    181 };
    182 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const) const
    183 {
    184   atom *Walker = start;
    185   while (Walker->next != end) {
    186     Walker = Walker->next;
    187     (*f)(Walker);
    188   }
    189 };
    190156
    191157// ================== Acting with each Atoms on copy molecule ========================== //
    192158
    193159// zero arguments
    194 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy)
     160template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const
    195161{
    196162  atom *Walker = start;
     
    200166  }
    201167};
    202 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const , molecule *copy)
     168template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const
    203169{
    204170  atom *Walker = start;
     
    208174  }
    209175};
    210 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const
    211 {
    212   atom *Walker = start;
    213   while (Walker->next != end) {
    214     Walker = Walker->next;
    215     (copy->*f)(Walker);
    216   }
    217 };
    218 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const
    219 {
    220   atom *Walker = start;
    221   while (Walker->next != end) {
    222     Walker = Walker->next;
    223     (copy->*f)(Walker);
    224   }
    225 };
    226176
    227177// ================== Acting with each Atoms on copy molecule if true ========================== //
    228178
    229179// zero arguments
    230 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () )
     180template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ) const
    231181{
    232182  atom *Walker = start;
     
    237187  }
    238188};
     189template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () const ) const
     190{
     191  atom *Walker = start;
     192  while (Walker->next != end) {
     193    Walker = Walker->next;
     194    if ((Walker->*condition)())
     195      (copy->*f)(Walker);
     196  }
     197};
     198template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () ) const
     199{
     200  atom *Walker = start;
     201  while (Walker->next != end) {
     202    Walker = Walker->next;
     203    if ((Walker->*condition)())
     204      (copy->*f)(Walker);
     205  }
     206};
     207template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) () const ) const
     208{
     209  atom *Walker = start;
     210  while (Walker->next != end) {
     211    Walker = Walker->next;
     212    if ((Walker->*condition)())
     213      (copy->*f)(Walker);
     214  }
     215};
    239216// one argument
    240 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t )
     217template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ) const
    241218{
    242219  atom *Walker = start;
     
    247224  }
    248225};
     226template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T) const, T t ) const
     227{
     228  atom *Walker = start;
     229  while (Walker->next != end) {
     230    Walker = Walker->next;
     231    if ((Walker->*condition)(t))
     232      (copy->*f)(Walker);
     233  }
     234};
     235template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T), T t ) const
     236{
     237  atom *Walker = start;
     238  while (Walker->next != end) {
     239    Walker = Walker->next;
     240    if ((Walker->*condition)(t))
     241      (copy->*f)(Walker);
     242  }
     243};
     244template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T) const, T t ) const
     245{
     246  atom *Walker = start;
     247  while (Walker->next != end) {
     248    Walker = Walker->next;
     249    if ((Walker->*condition)(t))
     250      (copy->*f)(Walker);
     251  }
     252};
    249253// two arguments
    250 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u )
     254template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const
    251255{
    252256  atom *Walker = start;
     
    257261  }
    258262};
     263template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const
     264{
     265  atom *Walker = start;
     266  while (Walker->next != end) {
     267    Walker = Walker->next;
     268    if ((Walker->*condition)(t,u))
     269      (copy->*f)(Walker);
     270  }
     271};
     272template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const
     273{
     274  atom *Walker = start;
     275  while (Walker->next != end) {
     276    Walker = Walker->next;
     277    if ((Walker->*condition)(t,u))
     278      (copy->*f)(Walker);
     279  }
     280};
     281template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const
     282{
     283  atom *Walker = start;
     284  while (Walker->next != end) {
     285    Walker = Walker->next;
     286    if ((Walker->*condition)(t,u))
     287      (copy->*f)(Walker);
     288  }
     289};
    259290// three arguments
    260 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v )
     291template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const
    261292{
    262293  atom *Walker = start;
     
    267298  }
    268299};
     300template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const
     301{
     302  atom *Walker = start;
     303  while (Walker->next != end) {
     304    Walker = Walker->next;
     305    if ((Walker->*condition)(t,u,v))
     306      (copy->*f)(Walker);
     307  }
     308};
     309template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const
     310{
     311  atom *Walker = start;
     312  while (Walker->next != end) {
     313    Walker = Walker->next;
     314    if ((Walker->*condition)(t,u,v))
     315      (copy->*f)(Walker);
     316  }
     317};
     318template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const
     319{
     320  atom *Walker = start;
     321  while (Walker->next != end) {
     322    Walker = Walker->next;
     323    if ((Walker->*condition)(t,u,v))
     324      (copy->*f)(Walker);
     325  }
     326};
    269327
    270328// ================== Acting on all Atoms ========================== //
    271329
    272330// zero arguments
    273 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)())
     331template <typename res, typename typ> void molecule::ActOnAllAtoms( res (typ::*f)()) const
    274332{
    275333  atom *Walker = start;
     
    279337  }
    280338};
    281 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)() const)
     339template <typename res, typename typ> void molecule::ActOnAllAtoms( res (typ::*f)() const) const
    282340{
    283341  atom *Walker = start;
     
    287345  }
    288346};
    289 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)()) const
    290 {
    291   atom *Walker = start;
    292   while (Walker->next != end) {
    293     Walker = Walker->next;
    294     (Walker->*f)();
    295   }
    296 };
    297 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)() const) const
    298 {
    299   atom *Walker = start;
    300   while (Walker->next != end) {
    301     Walker = Walker->next;
    302     (Walker->*f)();
    303   }
    304 };
    305347// one argument
    306 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T), T t )
     348template <typename res, typename typ, typename T> void molecule::ActOnAllAtoms( res (typ::*f)(T), T t ) const
    307349{
    308350  atom *Walker = start;
     
    312354  }
    313355};
    314 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T) const, T t )
     356template <typename res, typename typ, typename T> void molecule::ActOnAllAtoms( res (typ::*f)(T) const, T t ) const
    315357{
    316358  atom *Walker = start;
     
    320362  }
    321363};
    322 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T), T t ) const
    323 {
    324   atom *Walker = start;
    325   while (Walker->next != end) {
    326     Walker = Walker->next;
    327     (Walker->*f)(t);
    328   }
    329 };
    330 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T) const, T t ) const
    331 {
    332   atom *Walker = start;
    333   while (Walker->next != end) {
    334     Walker = Walker->next;
    335     (Walker->*f)(t);
    336   }
    337 };
    338364// two argument
    339 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U), T t, U u )
     365template <typename res, typename typ, typename T, typename U> void molecule::ActOnAllAtoms( res (typ::*f)(T, U), T t, U u ) const
    340366{
    341367  atom *Walker = start;
     
    345371  }
    346372};
    347 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u )
     373template <typename res, typename typ, typename T, typename U> void molecule::ActOnAllAtoms( res (typ::*f)(T, U) const, T t, U u ) const
    348374{
    349375  atom *Walker = start;
     
    353379  }
    354380};
    355 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U), T t, U u ) const
    356 {
    357   atom *Walker = start;
    358   while (Walker->next != end) {
    359     Walker = Walker->next;
    360     (Walker->*f)(t, u);
    361   }
    362 };
    363 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u ) const
    364 {
    365   atom *Walker = start;
    366   while (Walker->next != end) {
    367     Walker = Walker->next;
    368     (Walker->*f)(t, u);
    369   }
    370 };
    371381// three argument
    372 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v)
     382template <typename res, typename typ, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V), T t, U u, V v) const
    373383{
    374384  atom *Walker = start;
     
    378388  }
    379389};
    380 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v)
     390template <typename res, typename typ, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V) const, T t, U u, V v) const
    381391{
    382392  atom *Walker = start;
     
    386396  }
    387397};
    388 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v) const
    389 {
    390   atom *Walker = start;
    391   while (Walker->next != end) {
    392     Walker = Walker->next;
    393     (Walker->*f)(t, u, v);
    394   }
    395 };
    396 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v) const
    397 {
    398   atom *Walker = start;
    399   while (Walker->next != end) {
    400     Walker = Walker->next;
    401     (Walker->*f)(t, u, v);
    402   }
    403 };
    404398// four arguments
    405 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w)
     399template <typename res, typename typ, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V, W), T t, U u, V v, W w) const
    406400{
    407401  atom *Walker = start;
     
    411405  }
    412406};
    413 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w)
     407template <typename res, typename typ, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V, W) const, T t, U u, V v, W w) const
    414408{
    415409  atom *Walker = start;
     
    419413  }
    420414};
    421 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w) const
    422 {
    423   atom *Walker = start;
    424   while (Walker->next != end) {
    425     Walker = Walker->next;
    426     (Walker->*f)(t, u, v, w);
    427   }
    428 };
    429 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w) const
    430 {
    431   atom *Walker = start;
    432   while (Walker->next != end) {
    433     Walker = Walker->next;
    434     (Walker->*f)(t, u, v, w);
    435   }
    436 };
    437415
    438416// ===================== Accessing arrays indexed by some integer for each atom ======================
    439417
    440418// for atom ints
    441 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *) )
     419template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *) ) const
    442420{
    443421  atom *Walker = start;
     
    448426  }
    449427};
    450 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *), T value )
     428template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *), T value ) const
    451429{
    452430  atom *Walker = start;
     
    456434  }
    457435};
    458 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *), T *value )
     436template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *), T *value ) const
    459437{
    460438  atom *Walker = start;
     
    464442  }
    465443};
    466 // for element ints inside atom class
    467 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *) )
     444// for element ints
     445template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *) ) const
    468446{
    469447  atom *Walker = start;
     
    474452  }
    475453};
    476 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T value )
     454template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T value ) const
    477455{
    478456  atom *Walker = start;
     
    482460  }
    483461};
    484 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *value )
     462template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *value ) const
    485463{
    486464  atom *Walker = start;
     
    490468  }
    491469};
    492 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector atom::*value )
     470
     471template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ atom::*value ) const
    493472{
    494473  atom *Walker = start;
     
    498477  }
    499478};
    500 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector &vect )
     479template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ atom::*value ) const
     480{
     481  atom *Walker = start;
     482  while (Walker->next != end) {
     483    Walker = Walker->next;
     484    array[(Walker->*index)] = (Walker->*Setor) (Walker->*value);
     485  }
     486};
     487template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ &vect ) const
    501488{
    502489  atom *Walker = start;
     
    506493  }
    507494};
    508 
    509 template <typename T> void molecule::SetAtomValueToIndexedArray ( T *array, int TesselPoint::*index, T atom::*value )
     495template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ &vect ) const
     496{
     497  atom *Walker = start;
     498  while (Walker->next != end) {
     499    Walker = Walker->next;
     500    array[(Walker->*index)] = (Walker->*Setor) (vect);
     501  }
     502};
     503template <typename T, typename typ, typename typ2> void molecule::SetAtomValueToIndexedArray ( T *array, int typ::*index, T typ2::*value ) const
    510504{
    511505  atom *Walker = start;
     
    517511};
    518512
    519 template <typename T> void molecule::SetAtomValueToIndexedArray ( T *array, int element::*index, T atom::*value )
    520 {
    521   atom *Walker = start;
    522   while (Walker->next != end) {
    523     Walker = Walker->next;
    524     Walker->*value = array[(Walker->type->*index)];
    525     //cout << Verbose(2) << *Walker << " gets " << (Walker->*value) << endl;
    526   }
    527 };
     513template <typename T, typename typ> void molecule::SetAtomValueToValue ( T value, T typ::*ptr ) const
     514{
     515  atom *Walker = start;
     516  while (Walker->next != end) {
     517    Walker = Walker->next;
     518    Walker->*ptr = value;
     519    //cout << Verbose(2) << *Walker << " gets " << (Walker->*ptr) << endl;
     520  }
     521};
     522
    528523
    529524#endif /* MOLECULE_TEMPLATE_HPP_ */
  • src/moleculelist.cpp

    r06c7a3 r7326b2  
    1212#include "helpers.hpp"
    1313#include "linkedcell.hpp"
     14#include "lists.hpp"
    1415#include "molecule.hpp"
    1516#include "memoryallocator.hpp"
     
    306307bool MoleculeListClass::EmbedMerge(molecule *mol, molecule *srcmol)
    307308{
     309  LinkedCell *LCList = NULL;
     310  Tesselation *TesselStruct = NULL;
    308311  if ((srcmol == NULL) || (mol == NULL)) {
    309312    cout << Verbose(1) << "ERROR: Either fixed or variable molecule is given as NULL." << endl;
     
    312315
    313316  // calculate envelope for *mol
    314   LinkedCell *LCList = new LinkedCell(mol, 8.);
    315   FindNonConvexBorder((ofstream *)&cout, mol, LCList, 4., NULL);
    316   if (mol->TesselStruct == NULL) {
     317  LCList = new LinkedCell(mol, 8.);
     318  FindNonConvexBorder((ofstream *)&cout, mol, TesselStruct, (const LinkedCell *&)LCList, 4., NULL);
     319  if (TesselStruct == NULL) {
    317320    cout << Verbose(1) << "ERROR: Could not tesselate the fixed molecule." << endl;
    318321    return false;
    319322  }
    320323  delete(LCList);
    321   LCList = new LinkedCell(mol->TesselStruct, 8.);  // re-create with boundary points only!
     324  LCList = new LinkedCell(TesselStruct, 8.);  // re-create with boundary points only!
    322325
    323326  // prepare index list for bonds
     
    333336    Walker = Walker->next;
    334337    cout << Verbose(2) << "INFO: Current Walker is " << *Walker << "." << endl;
    335     if (!mol->TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) {
     338    if (!TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) {
    336339      CopyAtoms[Walker->nr] = new atom(Walker);
    337340      mol->AddAtom(CopyAtoms[Walker->nr]);
     
    376379  atom *Walker = NULL;
    377380  atom *Runner = NULL;
     381  bond *Binder = NULL;
    378382  double ***FitConstant = NULL, **correction = NULL;
    379383  int a, b;
     
    419423
    420424  // 0b. allocate memory for constants
    421   FitConstant = Malloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
     425  FitConstant = Calloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    422426  for (int k = 0; k < 3; k++) {
    423     FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
     427    FitConstant[k] = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    424428    for (int i = a; i--;) {
    425       FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
     429      FitConstant[k][i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    426430    }
    427431  }
     
    468472
    469473  // 0d. allocate final correction matrix
    470   correction = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction");
     474  correction = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction");
    471475  for (int i = a; i--;)
    472     correction[i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
     476    correction[i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
    473477
    474478  // 1a. go through every molecule in the list
     
    482486    while (Walker->next != (*ListRunner)->end) {
    483487      Walker = Walker->next;
    484       //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Walker->nr][0] << "." << endl;
     488      //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    485489      if ((Walker->type->Z == 1) && ((Walker->father == NULL)
    486490          || (Walker->father->type->Z != 1))) { // if it's a hydrogen
     
    488492        while (Runner->next != (*ListRunner)->end) {
    489493          Runner = Runner->next;
    490           //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Runner->nr][0] << "." << endl;
     494          //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    491495          // 3. take every other hydrogen that is the not the first and not bound to same bonding partner
    492           if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && ((*ListRunner)->ListOfBondsPerAtom[Runner->nr][0]->GetOtherAtom(Runner) != (*ListRunner)->ListOfBondsPerAtom[Walker->nr][0]->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
     496          Binder = *(Runner->ListOfBonds.begin());
     497          if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && (Binder->GetOtherAtom(Runner) != Binder->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
    493498            // 4. evaluate the morse potential for each matrix component and add up
    494499            distance = Runner->x.Distance(&Walker->x);
     
    544549  output.close();
    545550  // 6. free memory of parsed matrices
    546   FitConstant = Malloc<double**>(a, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    547551  for (int k = 0; k < 3; k++) {
    548     FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    549552    for (int i = a; i--;) {
    550       FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    551     }
    552   }
     553      Free(&FitConstant[k][i]);
     554    }
     555    Free(&FitConstant[k]);
     556  }
     557  Free(&FitConstant);
    553558  cout << "done." << endl;
    554559  return true;
     
    708713    //outputFragment.close();
    709714    //outputFragment.clear();
    710     delete (FragmentNumber);
    711     //Free(&FragmentNumber);
     715    Free(&FragmentNumber);
    712716  }
    713717  cout << " done." << endl;
     
    730734};
    731735
     736/** Dissects given \a *mol into connected subgraphs and inserts them as new molecules but with old atoms into \a this.
     737 * \param *out output stream for debugging
     738 * \param *mol molecule with atoms to dissect
     739 * \param *configuration config with BondGraph
     740 */
     741void MoleculeListClass::DissectMoleculeIntoConnectedSubgraphs(ofstream * const out, molecule * const mol, config * const configuration)
     742{
     743  // 1. dissect the molecule into connected subgraphs
     744  configuration ->BG->ConstructBondGraph(out, mol);
     745
     746  // 2. scan for connected subgraphs
     747  MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     748  class StackClass<bond *> *BackEdgeStack = NULL;
     749  Subgraphs = mol->DepthFirstSearchAnalysis(out, BackEdgeStack);
     750  delete(BackEdgeStack);
     751
     752  // 3. dissect (the following construct is needed to have the atoms not in the order of the DFS, but in
     753  // the original one as parsed in)
     754  // TODO: Optimize this, when molecules just contain pointer list of global atoms!
     755
     756  // 4a. create array of molecules to fill
     757  const int MolCount = Subgraphs->next->Count();
     758  molecule **molecules = Malloc<molecule *>(MolCount, "config::Load() - **molecules");
     759  for (int i=0;i<MolCount;i++) {
     760    molecules[i] = (molecule*) new molecule(mol->elemente);
     761    molecules[i]->ActiveFlag = true;
     762    insert(molecules[i]);
     763  }
     764
     765  // 4b. create and fill map of which atom is associated to which connected molecule (note, counting starts at 1)
     766  int FragmentCounter = 0;
     767  int *MolMap = Calloc<int>(mol->AtomCount, "config::Load() - *MolMap");
     768  MoleculeLeafClass *MolecularWalker = Subgraphs;
     769  atom *Walker = NULL;
     770  while (MolecularWalker->next != NULL) {
     771    MolecularWalker = MolecularWalker->next;
     772    Walker = MolecularWalker->Leaf->start;
     773    while (Walker->next != MolecularWalker->Leaf->end) {
     774      Walker = Walker->next;
     775      MolMap[Walker->GetTrueFather()->nr] = FragmentCounter+1;
     776    }
     777    FragmentCounter++;
     778  }
     779
     780  // 4c. relocate atoms to new molecules and remove from Leafs
     781  Walker = mol->start;
     782  while (mol->start->next != mol->end) {
     783    Walker = mol->start->next;
     784    if ((Walker->nr <0) || (Walker->nr >= mol->AtomCount)) {
     785      cerr << "Index of atom " << *Walker << " is invalid!" << endl;
     786      performCriticalExit();
     787    }
     788    FragmentCounter = MolMap[Walker->nr];
     789    if (FragmentCounter != 0) {
     790      cout << Verbose(3) << "Re-linking " << *Walker << "..." << endl;
     791      unlink(Walker);
     792      molecules[FragmentCounter-1]->AddAtom(Walker);    // counting starts at 1
     793    } else {
     794      cerr << "Atom " << *Walker << " not associated to molecule!" << endl;
     795      performCriticalExit();
     796    }
     797  }
     798  // 4d. we don't need to redo bonds, as they are connected subgraphs and still maintained their ListOfBonds
     799  // 4e. free Leafs
     800  MolecularWalker = Subgraphs;
     801  while (MolecularWalker->next != NULL) {
     802    MolecularWalker = MolecularWalker->next;
     803    delete(MolecularWalker->previous);
     804  }
     805  delete(MolecularWalker);
     806  Free(&MolMap);
     807  Free(&molecules);
     808  cout << Verbose(1) << "I scanned " << FragmentCounter << " molecules." << endl;
     809};
    732810
    733811/******************************************* Class MoleculeLeafClass ************************************************/
     
    810888 * \return true - success, false - faoilure
    811889 */
    812 bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList)
    813 {
    814   atom *Walker = NULL, *OtherWalker = NULL;
    815   bond *Binder = NULL;
     890bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, const molecule * const reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList)
     891{
     892  atom *Walker = NULL;
     893  atom *OtherWalker = NULL;
     894  atom *Father = NULL;
    816895  bool status = true;
    817896  int AtomNo;
     
    825904
    826905  if (status) {
    827     *out << Verbose(1) << "Creating adjacency list for subgraph " << this
    828         << "." << endl;
     906    *out << Verbose(1) << "Creating adjacency list for subgraph " << Leaf << "." << endl;
     907    // remove every bond from the list
     908    bond *Binder = NULL;
     909    while (Leaf->last->previous != Leaf->first) {
     910      Binder = Leaf->last->previous;
     911      Binder->leftatom->UnregisterBond(Binder);
     912      Binder->rightatom->UnregisterBond(Binder);
     913      removewithoutcheck(Binder);
     914    }
     915
    829916    Walker = Leaf->start;
    830917    while (Walker->next != Leaf->end) {
    831918      Walker = Walker->next;
    832       AtomNo = Walker->GetTrueFather()->nr; // global id of the current walker
    833       for (int i = 0; i < reference->NumberOfBondsPerAtom[AtomNo]; i++) { // go through father's bonds and copy them all
    834         Binder = reference->ListOfBondsPerAtom[AtomNo][i];
    835         OtherWalker = ListOfLocalAtoms[FragmentCounter][Binder->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
     919      Father = Walker->GetTrueFather();
     920      AtomNo = Father->nr; // global id of the current walker
     921      for (BondList::const_iterator Runner = Father->ListOfBonds.begin(); Runner != Father->ListOfBonds.end(); (++Runner)) {
     922        OtherWalker = ListOfLocalAtoms[FragmentCounter][(*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
    836923        if (OtherWalker != NULL) {
    837924          if (OtherWalker->nr > Walker->nr)
    838             Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);
     925            Leaf->AddBond(Walker, OtherWalker, (*Runner)->BondDegree);
    839926        } else {
    840           *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << Binder->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
     927          *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << (*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
    841928          status = false;
    842929        }
    843930      }
    844931    }
    845     Leaf->CreateListOfBondsPerAtom(out);
    846     FragmentCounter++;
    847     if (next != NULL)
    848       status = next->FillBondStructureFromReference(out, reference, FragmentCounter, ListOfLocalAtoms);
    849     FragmentCounter--;
    850932  }
    851933
     
    856938      Free(&ListOfLocalAtoms);
    857939  }
    858   FragmentCounter--;
    859940  *out << Verbose(1) << "End of FillBondStructureFromReference." << endl;
    860941  return status;
     
    903984
    904985/** Fills a lookup list of father's Atom::nr -> atom for each subgraph.
    905  * \param *out output stream fro debugging
     986 * \param *out output stream from debugging
    906987 * \param ***ListOfLocalAtoms Lookup table for each subgraph and index of each atom in global molecule, may be NULL on start, then it is filled
    907988 * \param FragmentCounter counts the fragments as we move along the list
    908989 * \param GlobalAtomCount number of atoms in the complete molecule
    909990 * \param &FreeList true - ***ListOfLocalAtoms is free'd before return, false - it is not
    910  * \return true - succes, false - failure
     991 * \return true - success, false - failure
    911992 */
    912993bool MoleculeLeafClass::FillListOfLocalAtoms(ofstream *out, atom ***&ListOfLocalAtoms, const int FragmentCounter, const int GlobalAtomCount, bool &FreeList)
     
    914995  bool status = true;
    915996
    916   int Counter = Count();
    917997  if (ListOfLocalAtoms == NULL) { // allocated initial pointer
    918998    // allocate and set each field to NULL
    919     ListOfLocalAtoms = Malloc<atom**>(Counter, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
    920     if (ListOfLocalAtoms != NULL) {
    921       for (int i = Counter; i--;)
    922         ListOfLocalAtoms[i] = NULL;
    923       FreeList = FreeList && true;
    924     } else
     999    const int Counter = Count();
     1000    ListOfLocalAtoms = Calloc<atom**>(Counter, "MoleculeLeafClass::FillListOfLocalAtoms - ***ListOfLocalAtoms");
     1001    if (ListOfLocalAtoms == NULL) {
     1002      FreeList = FreeList && false;
    9251003      status = false;
     1004    }
    9261005  }
    9271006
     
    9611040  if (FragmentList == NULL) {
    9621041    KeySetCounter = Count();
    963     FragmentList = Malloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
    964     for (int i = KeySetCounter; i--;)
    965       FragmentList[i] = NULL;
     1042    FragmentList = Calloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
    9661043    KeySetCounter = 0;
    9671044  }
  • src/periodentafel.cpp

    r06c7a3 r7326b2  
    2121 * Initialises start and end of list and resets periodentafel::checkliste to false.
    2222 */
    23 periodentafel::periodentafel()
    24 {
    25   start = new element;
    26   end = new element;
     23periodentafel::periodentafel() : start(new element), end(new element)
     24{
    2725  start->previous = NULL;
    2826  start->next = end;
     
    4543 * \return true - succeeded, false - does not occur
    4644 */
    47 bool periodentafel::AddElement(element *pointer)
     45bool periodentafel::AddElement(element * const pointer)
    4846{
    4947  pointer->sort = &pointer->Z;
     
    5755 * \return true - succeeded, false - element not found
    5856 */
    59 bool periodentafel::RemoveElement(element *pointer)
     57bool periodentafel::RemoveElement(element * const pointer)
    6058{
    6159  return remove(pointer, start, end);
     
    7169
    7270/** Finds an element by its atomic number.
    73  * If element is not yet in list, datas are asked and stored in database.
     71 * If element is not yet in list, returns NULL.
    7472 * \param Z atomic number
    75  * \return pointer to element
    76  */
    77 element * periodentafel::FindElement(int Z)
     73 * \return pointer to element or NULL if not found
     74 */
     75element * const periodentafel::FindElement(const int Z) const
    7876{
    7977  element *walker = find(&Z, start,end);
    80   if (walker == NULL) { // not found: enter and put into db
    81     cout << Verbose(0) << "Element not found in database, please enter." << endl;
    82     walker = new element;
    83     cout << Verbose(0) << "Mass: " << endl;
    84     cin >> walker->mass;
    85     walker->Z = Z;
    86     cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
    87     cout << Verbose(0) << "Name [max 64 chars]: " << endl;
    88     cin >> walker->name;
    89     cout << Verbose(0) << "Short form [max 3 chars]: " << endl;
    90     cin >> walker->symbol;
    91     periodentafel::AddElement(walker);
    92   }
    9378  return(walker);
    9479};
     
    9984 * \return pointer to element
    10085 */
    101 element * periodentafel::FindElement(const char *shorthand) const
     86element * const periodentafel::FindElement(const char * const shorthand) const
    10287{
    10388  element *walker =  periodentafel::start;
     
    11297/** Asks for element number and returns pointer to element
    11398 */
    114 element * periodentafel::AskElement()
     99element * const periodentafel::AskElement() const
    115100{
    116101  element *walker = NULL;
     
    124109};
    125110
     111/** Asks for element and if not found, presents mask to enter info.
     112 * \return pointer to either present or newly created element
     113 */
     114element * const periodentafel::EnterElement()
     115{
     116  element *walker = NULL;
     117  int Z = -1;
     118  cout << Verbose(0) << "Atomic number: " << Z << endl;
     119  cin >> Z;
     120  walker = FindElement(Z);
     121  if (walker == NULL) {
     122    cout << Verbose(0) << "Element not found in database, please enter." << endl;
     123    walker = new element;
     124    walker->Z = Z;
     125    cout << Verbose(0) << "Mass: " << endl;
     126    cin >> walker->mass;
     127    cout << Verbose(0) << "Name [max 64 chars]: " << endl;
     128    cin >> walker->name;
     129    cout << Verbose(0) << "Short form [max 3 chars]: " << endl;
     130    cin >> walker->symbol;
     131    periodentafel::AddElement(walker);
     132  }
     133  return(walker);
     134};
     135
    126136/** Prints period table to given stream.
    127137 * \param output stream
    128138 */
    129 bool periodentafel::Output(ofstream *output) const
     139bool periodentafel::Output(ofstream * const output) const
    130140{
    131141  bool result = true;
     
    145155 * \param *checkliste elements table for this molecule
    146156 */
    147 bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
     157bool periodentafel::Checkout(ofstream * const output, const int * const checkliste) const
    148158{
    149159  element *walker = start;
     
    215225        cout << "Could not parse element: ";
    216226        neues->Output((ofstream *)&cout);
     227        delete(neues);
    217228      }
    218229    }
  • src/periodentafel.hpp

    r06c7a3 r7326b2  
    3434  ~periodentafel();
    3535
    36   bool AddElement(element *pointer);
    37   bool RemoveElement(element *pointer);
     36  bool AddElement(element * const pointer);
     37  bool RemoveElement(element * const pointer);
    3838  bool CleanupPeriodtable();
    39   element * FindElement(int Z);
    40   element * FindElement(const char *shorthand) const;
    41   element * AskElement();
    42   bool Output(ofstream *output) const;
    43   bool Checkout(ofstream *output, const int *checkliste) const;
    44   bool LoadPeriodentafel(const char *path);
    45   bool StorePeriodentafel(const char *path) const;
     39  element * const FindElement(const int Z) const;
     40  element * const FindElement(const char * const shorthand) const;
     41  element * const AskElement() const;
     42  element * const EnterElement();
     43  bool Output(ofstream * const output) const;
     44  bool Checkout(ofstream * const output, const int * const checkliste) const;
     45  bool LoadPeriodentafel(const char * const path);
     46  bool StorePeriodentafel(const char * const path) const;
    4647
    4748  private:
  • src/stackclass.hpp

    r06c7a3 r7326b2  
    3333  bool RemoveItem(T ptr);
    3434  void ClearStack();
    35   bool IsEmpty();
    36   bool IsFull();
    37   int ItemCount();
    38   void Output(ofstream *out) const;
    39   void TestImplementation(ofstream *out, T test);
     35  bool IsEmpty() const;
     36  bool IsFull() const;
     37  int ItemCount() const;
     38  void Output(ofstream * const out) const;
    4039
    4140  private:
     
    4948/** Constructor of class StackClass.
    5049 */
    51 template <typename T> StackClass<T>::StackClass(int dimension)
    52 {
    53   CurrentLastEntry = 0;
    54   CurrentFirstEntry = 0;
    55   NextFreeField = 0;
    56   EntryCount = dimension;
    57   StackList = Malloc<T>(EntryCount, "StackClass::StackClass: **StackList");
     50template <typename T> StackClass<T>::StackClass(int dimension) : StackList(NULL), EntryCount(dimension), CurrentLastEntry(0), CurrentFirstEntry(0), NextFreeField(0)
     51{
     52  StackList = Calloc<T>(EntryCount, "StackClass::StackClass: **StackList");
    5853};
    5954
     
    165160};
    166161
    167 /** Test the functionality of the stack.
    168  * \param *out ofstream for debugging
    169  * \param *test one item to put on stack
    170  * \return true - all tests worked correctly
    171  */
    172 template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)
    173 {
    174   T Walker = test;
    175   *out << Verbose(1) << "Testing the snake stack..." << endl;
    176   for (int i=0;i<EntryCount;i++) {
    177     *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
    178     Push(Walker);
    179     Walker=Walker->next;
    180   }
    181   *out << endl;
    182   Output(out);
    183   if (IsFull())
    184     *out << "Stack is full as supposed to be!" << endl;
    185   else
    186     *out << "ERROR: Stack is not as full as supposed to be!" << endl;
    187   //if (StackList[(EntryCount+1)/2] != NULL) {
    188     *out << "Removing element in the middle ..." << endl;
    189     RemoveItem(StackList[(EntryCount+1)/2]);
    190     Output(out);
    191   //}
    192   //if (StackList[CurrentFirstEntry] != NULL) {
    193     *out << "Removing first element  ..." << endl;
    194     RemoveItem(StackList[CurrentFirstEntry]);
    195     Output(out);
    196   //}
    197   //if (StackList[CurrentLastEntry] != NULL) {
    198     *out << "Removing last element ..." << endl;
    199     RemoveItem(StackList[CurrentLastEntry]);
    200     Output(out);
    201   //}
    202   *out << "Clearing stack ... " << endl;
    203   ClearStack();
    204   Output(out);
    205   if (IsEmpty())
    206     *out << "Stack is empty as supposed to be!" << endl;
    207   else
    208     *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
    209   *out << "done." << endl;
    210 };
    211162
    212163/** Puts contents of stack into ofstream \a *out.
    213164 * \param *out ofstream for output
    214165 */
    215 template <typename T> void StackClass<T>::Output(ofstream *out) const
     166template <typename T> void StackClass<T>::Output(ofstream * const out) const
    216167{
    217168  *out << "Contents of Stack: ";
     
    234185 * \return true - empty, false - not
    235186 */
    236 template <typename T> bool StackClass<T>::IsEmpty()
     187template <typename T> bool StackClass<T>::IsEmpty() const
    237188{
    238189  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
     
    244195 * \return true - full, false - not
    245196 */
    246 template <typename T> bool StackClass<T>::IsFull()
     197template <typename T> bool StackClass<T>::IsFull() const
    247198{
    248199  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
     
    254205 * \warning will never return correct item count if stack is full, i.e. count would be StackClass::EntryCount.
    255206 */
    256 template <typename T> int StackClass<T>::ItemCount()
     207template <typename T> int StackClass<T>::ItemCount() const
    257208{
    258209  //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
  • src/tesselation.cpp

    r06c7a3 r7326b2  
    88#include <fstream>
    99
     10#include "helpers.hpp"
    1011#include "linkedcell.hpp"
    1112#include "tesselation.hpp"
     
    3031 * \param *Walker TesselPoint this boundary point represents
    3132 */
    32 BoundaryPointSet::BoundaryPointSet(TesselPoint *Walker)
     33BoundaryPointSet::BoundaryPointSet(TesselPoint * Walker)
    3334{
    3435  node = Walker;
     
    7273 * \param &a boundary point
    7374 */
    74 ostream & operator <<(ostream &ost, BoundaryPointSet &a)
     75ostream & operator <<(ostream &ost, const BoundaryPointSet &a)
    7576{
    7677  ost << "[" << a.Nr << "|" << a.node->Name << " at " << *a.node->node << "]";
     
    9596 * \param number number of the list
    9697 */
    97 BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number)
     98BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], const int number)
    9899{
    99100  // set number
     
    274275 * \param &a boundary line
    275276 */
    276 ostream & operator <<(ostream &ost, BoundaryLineSet &a)
     277ostream & operator <<(ostream &ost, const  BoundaryLineSet &a)
    277278{
    278279  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "]";
     
    531532 * \param &a boundary triangle
    532533 */
    533 ostream &operator <<(ostream &ost, BoundaryTriangleSet &a)
     534ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a)
    534535{
    535536  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","
     
    641642 * Uses PointsOnBoundary and STL stuff.
    642643 */   
    643 Vector * Tesselation::GetCenter(ofstream *out)
     644Vector * Tesselation::GetCenter(ofstream *out) const
    644645{
    645646  Vector *Center = new Vector(0.,0.,0.);
     
    656657 * Uses PointsOnBoundary and STL stuff.
    657658 */   
    658 TesselPoint * Tesselation::GetPoint()
     659TesselPoint * Tesselation::GetPoint() const
    659660{
    660661  return (InternalPointer->second->node);
     
    664665 * Uses PointsOnBoundary and STL stuff.
    665666 */   
    666 TesselPoint * Tesselation::GetTerminalPoint()
    667 {
    668   PointMap::iterator Runner = PointsOnBoundary.end();
     667TesselPoint * Tesselation::GetTerminalPoint() const
     668{
     669  PointMap::const_iterator Runner = PointsOnBoundary.end();
    669670  Runner--;
    670671  return (Runner->second->node);
     
    674675 * Uses PointsOnBoundary and STL stuff.
    675676 */   
    676 void Tesselation::GoToNext()
     677void Tesselation::GoToNext() const
    677678{
    678679  if (InternalPointer != PointsOnBoundary.end())
     
    683684 * Uses PointsOnBoundary and STL stuff.
    684685 */   
    685 void Tesselation::GoToPrevious()
     686void Tesselation::GoToPrevious() const
    686687{
    687688  if (InternalPointer != PointsOnBoundary.begin())
     
    692693 * Uses PointsOnBoundary and STL stuff.
    693694 */   
    694 void Tesselation::GoToFirst()
     695void Tesselation::GoToFirst() const
    695696{
    696697  InternalPointer = PointsOnBoundary.begin();
     
    699700/** PointCloud implementation of GoToLast.
    700701 * Uses PointsOnBoundary and STL stuff.
    701  */   
    702 void Tesselation::GoToLast()
     702 */
     703void Tesselation::GoToLast() const
    703704{
    704705  InternalPointer = PointsOnBoundary.end();
     
    709710 * Uses PointsOnBoundary and STL stuff.
    710711 */   
    711 bool Tesselation::IsEmpty()
     712bool Tesselation::IsEmpty() const
    712713{
    713714  return (PointsOnBoundary.empty());
     
    717718 * Uses PointsOnBoundary and STL stuff.
    718719 */   
    719 bool Tesselation::IsEnd()
     720bool Tesselation::IsEnd() const
    720721{
    721722  return (InternalPointer == PointsOnBoundary.end());
     
    898899 * \param *cloud cluster of points
    899900 */
    900 void Tesselation::TesselateOnBoundary(ofstream *out, PointCloud *cloud)
     901void Tesselation::TesselateOnBoundary(ofstream *out, const PointCloud * const cloud)
    901902{
    902903  bool flag;
     
    10961097 * \return true - all straddling points insert, false - something went wrong
    10971098 */
    1098 bool Tesselation::InsertStraddlingPoints(ofstream *out, PointCloud *cloud, LinkedCell *LC)
     1099bool Tesselation::InsertStraddlingPoints(ofstream *out, const PointCloud *cloud, const LinkedCell *LC)
    10991100{
    11001101  Vector Intersection, Normal;
     
    12061207 * \return true - new point was added, false - point already present
    12071208 */
    1208 bool
    1209 Tesselation::AddBoundaryPoint(TesselPoint *Walker, int n)
     1209bool Tesselation::AddBoundaryPoint(TesselPoint * Walker, const int n)
    12101210{
    12111211  PointTestPair InsertUnique;
     
    12281228 * @param n index for this point in Tesselation::TPS array
    12291229 */
    1230 void
    1231 Tesselation::AddTesselationPoint(TesselPoint* Candidate, int n)
     1230void Tesselation::AddTesselationPoint(TesselPoint* Candidate, const int n)
    12321231{
    12331232  PointTestPair InsertUnique;
     
    12511250 * @param n index of Tesselation::BLS giving the line with both endpoints
    12521251 */
    1253 void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) {
     1252void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) {
    12541253  bool insertNewLine = true;
    12551254
     
    12891288 * @param n index of Tesselation::BLS giving the line with both endpoints
    12901289 */
    1291 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n)
     1290void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)
    12921291{
    12931292  cout << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl;
     
    13221321 * \param nr triangle number
    13231322 */
    1324 void Tesselation::AddTesselationTriangle(int nr)
     1323void Tesselation::AddTesselationTriangle(const int nr)
    13251324{
    13261325  cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl;
     
    15531552 * \param *LC LinkedCell structure with neighbouring TesselPoint's
    15541553 */
    1555 void Tesselation::FindStartingTriangle(ofstream *out, const double RADIUS, LinkedCell *LC)
     1554void Tesselation::FindStartingTriangle(ofstream *out, const double RADIUS, const LinkedCell *LC)
    15561555{
    15571556  cout << Verbose(1) << "Begin of FindStartingTriangle\n";
    15581557  int i = 0;
    1559   LinkedNodes *List = NULL;
    15601558  TesselPoint* FirstPoint = NULL;
    15611559  TesselPoint* SecondPoint = NULL;
     
    15791577    for (LC->n[(i+1)%NDIM]=0;LC->n[(i+1)%NDIM]<LC->N[(i+1)%NDIM];LC->n[(i+1)%NDIM]++)
    15801578      for (LC->n[(i+2)%NDIM]=0;LC->n[(i+2)%NDIM]<LC->N[(i+2)%NDIM];LC->n[(i+2)%NDIM]++) {
    1581         List = LC->GetCurrentCell();
     1579        const LinkedNodes *List = LC->GetCurrentCell();
    15821580        //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
    15831581        if (List != NULL) {
    1584           for (LinkedNodes::iterator Runner = List->begin();Runner != List->end();Runner++) {
     1582          for (LinkedNodes::const_iterator Runner = List->begin();Runner != List->end();Runner++) {
    15851583            if ((*Runner)->node->x[i] > maxCoordinate[i]) {
    15861584              cout << Verbose(2) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl;
     
    16441642
    16451643    //cout << Verbose(2) << "INFO: OldSphereCenter is at " << helper << ".\n";
    1646     FindThirdPointForTesselation(
    1647       Oben, SearchDirection, helper, BLS[0], NULL, *&OptCandidates, &ShortestAngle, RADIUS, LC
    1648     );
     1644    FindThirdPointForTesselation(Oben, SearchDirection, helper, BLS[0], NULL, *&OptCandidates, &ShortestAngle, RADIUS, LC);
    16491645    cout << Verbose(1) << "List of third Points is ";
    16501646    for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) {
     
    17121708 * @param *LC LinkedCell structure with neighbouring points
    17131709 */
    1714 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC)
     1710bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC)
    17151711{
    17161712  cout << Verbose(0) << "Begin of FindNextSuitableTriangle\n";
     
    17501746
    17511747    // construct old center
    1752     GetCenterofCircumcircle(&OldSphereCenter, T.endpoints[0]->node->node, T.endpoints[1]->node->node, T.endpoints[2]->node->node);
     1748    GetCenterofCircumcircle(&OldSphereCenter, *T.endpoints[0]->node->node, *T.endpoints[1]->node->node, *T.endpoints[2]->node->node);
    17531749    helper.CopyVector(&T.NormalVector);  // normal vector ensures that this is correct center of the two possible ones
    17541750    radius = Line.endpoints[0]->node->node->DistanceSquared(&OldSphereCenter);
     
    17731769
    17741770    // add third point
    1775     FindThirdPointForTesselation(
    1776       T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, OptCandidates,
    1777       &ShortestAngle, RADIUS, LC
    1778     );
     1771    FindThirdPointForTesselation(T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, OptCandidates, &ShortestAngle, RADIUS, LC);
    17791772
    17801773  } else {
     
    18121805      AddTesselationPoint(BaseRay->endpoints[1]->node, 2);
    18131806
    1814       if (CheckLineCriteriaForDegeneratedTriangle(TPS)) {
     1807      if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) {
    18151808        AddTesselationLine(TPS[0], TPS[1], 0);
    18161809        AddTesselationLine(TPS[0], TPS[2], 1);
     
    18411834        // We demand that at most one new degenerate line is created and that this line also already exists (which has to be the case due to existentTrianglesCount == 1)
    18421835        // i.e. at least one of the three lines must be present with TriangleCount <= 1
    1843         if (CheckLineCriteriaForDegeneratedTriangle(TPS)) {
     1836        if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS)) {
    18441837          AddTesselationLine(TPS[0], TPS[1], 0);
    18451838          AddTesselationLine(TPS[0], TPS[2], 1);
     
    19481941};
    19491942
    1950 void Tesselation::PrintAllBoundaryPoints(ofstream *out)
     1943void Tesselation::PrintAllBoundaryPoints(ofstream *out) const
    19511944{
    19521945  // print all lines
    19531946  *out << Verbose(1) << "Printing all boundary points for debugging:" << endl;
    1954   for (PointMap::iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++)
     1947  for (PointMap::const_iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++)
    19551948    *out << Verbose(2) << *(PointRunner->second) << endl;
    19561949};
    19571950
    1958 void Tesselation::PrintAllBoundaryLines(ofstream *out)
     1951void Tesselation::PrintAllBoundaryLines(ofstream *out) const
    19591952{
    19601953  // print all lines
    19611954  *out << Verbose(1) << "Printing all boundary lines for debugging:" << endl;
    1962   for (LineMap::iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++)
     1955  for (LineMap::const_iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++)
    19631956    *out << Verbose(2) << *(LineRunner->second) << endl;
    19641957};
    19651958
    1966 void Tesselation::PrintAllBoundaryTriangles(ofstream *out)
     1959void Tesselation::PrintAllBoundaryTriangles(ofstream *out) const
    19671960{
    19681961  // print all triangles
    19691962  *out << Verbose(1) << "Printing all boundary triangles for debugging:" << endl;
    1970   for (TriangleMap::iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++)
     1963  for (TriangleMap::const_iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++)
    19711964    *out << Verbose(2) << *(TriangleRunner->second) << endl;
    19721965};
     
    20031996
    20041997  // calculate volume
    2005   volume = CalculateVolumeofGeneralTetraeder(Base->endpoints[1]->node->node, OtherBase->endpoints[0]->node->node, OtherBase->endpoints[1]->node->node, Base->endpoints[0]->node->node);
     1998  volume = CalculateVolumeofGeneralTetraeder(*Base->endpoints[1]->node->node, *OtherBase->endpoints[0]->node->node, *OtherBase->endpoints[1]->node->node, *Base->endpoints[0]->node->node);
    20061999
    20072000  // delete the temporary other base line and the closest points
     
    21642157 * \param *LC LinkedCell structure with neighbouring points
    21652158 */
    2166 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)
     2159void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC)
    21672160{
    21682161  cout << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl;
    21692162  Vector AngleCheck;
    21702163  class TesselPoint* Candidate = NULL;
    2171   double norm = -1., angle;
    2172   LinkedNodes *List = NULL;
    2173   int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2164  double norm = -1.;
     2165  double angle = 0.;
     2166  int N[NDIM];
     2167  int Nlower[NDIM];
     2168  int Nupper[NDIM];
    21742169
    21752170  if (LC->SetIndexToNode(a)) {  // get cell for the starting point
     
    21972192    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    21982193      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    2199         List = LC->GetCurrentCell();
     2194        const LinkedNodes *List = LC->GetCurrentCell();
    22002195        //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
    22012196        if (List != NULL) {
    2202           for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2197          for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    22032198            Candidate = (*Runner);
    22042199            // check if we only have one unique point yet ...
     
    22842279 * @param *LC LinkedCell structure with neighbouring points
    22852280 */
    2286 void Tesselation::FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint  *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, LinkedCell *LC)
     2281void Tesselation::FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint  *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, const LinkedCell *LC)
    22872282{
    22882283  Vector CircleCenter;  // center of the circle, i.e. of the band of sphere's centers
     
    22932288  Vector NewNormalVector;   // normal vector of the Candidate's triangle
    22942289  Vector helper, OptCandidateCenter, OtherOptCandidateCenter;
    2295   LinkedNodes *List = NULL;
    22962290  double CircleRadius; // radius of this circle
    22972291  double radius;
     
    23562350        for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    23572351          for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    2358             List = LC->GetCurrentCell();
     2352            const LinkedNodes *List = LC->GetCurrentCell();
    23592353            //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
    23602354            if (List != NULL) {
    2361               for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2355              for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    23622356                Candidate = (*Runner);
    23632357
     
    23672361
    23682362                  // construct both new centers
    2369                   GetCenterofCircumcircle(&NewSphereCenter, BaseLine->endpoints[0]->node->node, BaseLine->endpoints[1]->node->node, Candidate->node);
     2363                  GetCenterofCircumcircle(&NewSphereCenter, *BaseLine->endpoints[0]->node->node, *BaseLine->endpoints[1]->node->node, *Candidate->node);
    23702364                  OtherNewSphereCenter.CopyVector(&NewSphereCenter);
    23712365
     
    24702464 * \return point which is shared or NULL if none
    24712465 */
    2472 class BoundaryPointSet *Tesselation::GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
    2473 {
    2474   class BoundaryLineSet * lines[2] =
    2475     { line1, line2 };
     2466class BoundaryPointSet *Tesselation::GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const
     2467{
     2468  const BoundaryLineSet * lines[2] = { line1, line2 };
    24762469  class BoundaryPointSet *node = NULL;
    24772470  map<int, class BoundaryPointSet *> OrderMap;
     
    25012494 * \return list of BoundaryTriangleSet of nearest triangles or NULL in degenerate case.
    25022495 */
    2503 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC)
     2496list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const
    25042497{
    25052498  TesselPoint *trianglePoints[3];
     
    25112504    return NULL;
    25122505  }
    2513 
     2506  *out << Verbose(1) << "Finding closest Tesselpoint to " << *x << " ... " << endl;
    25142507  trianglePoints[0] = FindClosestPoint(x, SecondPoint, LC);
    25152508 
     
    25212514  if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) {
    25222515    *out << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl;
    2523     PointMap::iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr);
     2516    PointMap::const_iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr);
    25242517    triangles = new list<BoundaryTriangleSet*>;
    25252518    if (PointRunner != PointsOnBoundary.end()) {
     
    25452538  } else {
    25462539    list<TesselPoint*> *connectedClosestPoints = GetCircleOfConnectedPoints(out, trianglePoints[0], x);
    2547     trianglePoints[1] = connectedClosestPoints->front();
    2548     trianglePoints[2] = connectedClosestPoints->back();
    2549     for (int i=0;i<3;i++) {
    2550       if (trianglePoints[i] == NULL) {
    2551         *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl;
     2540    if (connectedClosestPoints != NULL) {
     2541      trianglePoints[1] = connectedClosestPoints->front();
     2542      trianglePoints[2] = connectedClosestPoints->back();
     2543      for (int i=0;i<3;i++) {
     2544        if (trianglePoints[i] == NULL) {
     2545          *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl;
     2546        }
     2547        //*out << Verbose(2) << "List of triangle points:" << endl;
     2548        //*out << Verbose(3) << *trianglePoints[i] << endl;
    25522549      }
    2553       //*out << Verbose(2) << "List of triangle points:" << endl;
    2554       //*out << Verbose(3) << *trianglePoints[i] << endl;
    2555     }
    2556 
    2557     triangles = FindTriangles(trianglePoints);
    2558     *out << Verbose(2) << "List of possible triangles:" << endl;
    2559     for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
    2560       *out << Verbose(3) << **Runner << endl;
    2561 
    2562     delete(connectedClosestPoints);
     2550
     2551      triangles = FindTriangles(trianglePoints);
     2552      *out << Verbose(2) << "List of possible triangles:" << endl;
     2553      for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
     2554        *out << Verbose(3) << **Runner << endl;
     2555
     2556      delete(connectedClosestPoints);
     2557    } else {
     2558      triangles = NULL;
     2559      *out << Verbose(1) << "There is no circle of connected points!" << endl;
     2560    }
    25632561  }
    25642562 
    2565   if (triangles->empty()) {
     2563  if ((triangles == NULL) || (triangles->empty())) {
    25662564    *out << Verbose(0) << "ERROR: There is no nearest triangle. Please check the tesselation structure.";
    25672565    delete(triangles);
     
    25772575 * \return list of BoundaryTriangleSet of nearest triangles or NULL.
    25782576 */
    2579 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, Vector *x, LinkedCell* LC)
     2577class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const
    25802578{
    25812579  class BoundaryTriangleSet *result = NULL;
     
    26132611 * @return true if the point is inside the tesselation structure, false otherwise
    26142612 */
    2615 bool Tesselation::IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC)
     2613bool Tesselation::IsInnerPoint(ofstream *out, const Vector &Point, const LinkedCell* const LC) const
    26162614{
    26172615  class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC);
     
    26432641 * @return true if the point is inside the tesselation structure, false otherwise
    26442642 */
    2645 bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC)
     2643bool Tesselation::IsInnerPoint(ofstream *out, const TesselPoint * const Point, const LinkedCell* const LC) const
    26462644{
    26472645  return IsInnerPoint(out, *(Point->node), LC);
     
    26542652 * @return set of the all points linked to the provided one
    26552653 */
    2656 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, TesselPoint* Point)
     2654set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, const TesselPoint* const Point) const
    26572655{
    26582656  set<TesselPoint*> *connectedPoints = new set<TesselPoint*>;
     
    26612659  bool takePoint = false;
    26622660
     2661  *out << Verbose(3) << "Begin of GetAllConnectedPoints" << endl;
     2662
    26632663  // find the respective boundary point
    2664   PointMap::iterator PointRunner = PointsOnBoundary.find(Point->nr);
     2664  PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr);
    26652665  if (PointRunner != PointsOnBoundary.end()) {
    26662666    ReferencePoint = PointRunner->second;
     
    26722672  // little trick so that we look just through lines connect to the BoundaryPoint
    26732673  // OR fall-back to look through all lines if there is no such BoundaryPoint
    2674   LineMap *Lines = &LinesOnBoundary;
     2674  const LineMap *Lines;;
    26752675  if (ReferencePoint != NULL)
    26762676    Lines = &(ReferencePoint->lines);
    2677   LineMap::iterator findLines = Lines->begin();
     2677  else
     2678    Lines = &LinesOnBoundary;
     2679  LineMap::const_iterator findLines = Lines->begin();
    26782680  while (findLines != Lines->end()) {
    26792681   takePoint = false;
     
    27002702  }
    27012703
     2704  *out << Verbose(3) << "End of GetAllConnectedPoints" << endl;
    27022705  return connectedPoints;
    27032706};
     
    27152718 * @return list of the all points linked to the provided one
    27162719 */
    2717 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference)
     2720list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, const TesselPoint* const Point, const Vector * const Reference) const
    27182721{
    27192722  map<double, TesselPoint*> anglesOfPoints;
     
    27262729  Vector helper;
    27272730
     2731  if (connectedPoints == NULL) {
     2732    *out << Verbose(2) << "Could not find any connected points!" << endl;
     2733    delete(connectedCircle);
     2734    return NULL;
     2735  }
     2736  *out << Verbose(2) << "Begin of GetCircleOfConnectedPoints" << endl;
     2737
    27282738  // calculate central point
    2729   for (set<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
     2739  for (set<TesselPoint*>::const_iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
    27302740    center.AddVector((*TesselRunner)->node);
    27312741  //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size()
     
    27412751
    27422752  // construct one orthogonal vector
    2743   if (Reference != NULL)
     2753  if (Reference != NULL) {
    27442754    AngleZero.CopyVector(Reference);
     2755    AngleZero.SubtractVector(Point->node);
     2756    AngleZero.ProjectOntoPlane(&PlaneNormal);
     2757  }
     2758  if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) {
     2759    *out << Verbose(4) << "Using alternatively " << *(*connectedPoints->begin())->node << " as angle 0 referencer." << endl;
     2760    AngleZero.CopyVector((*connectedPoints->begin())->node);
     2761    AngleZero.SubtractVector(Point->node);
     2762    AngleZero.ProjectOntoPlane(&PlaneNormal);
     2763    if (AngleZero.NormSquared() < MYEPSILON) {
     2764      cerr << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl;
     2765      performCriticalExit();
     2766    }
     2767  }
     2768  *out << Verbose(4) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl;
     2769  if (AngleZero.NormSquared() > MYEPSILON)
     2770    OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero);
    27452771  else
    2746     AngleZero.CopyVector((*connectedPoints->begin())->node);
    2747   AngleZero.SubtractVector(Point->node);
    2748   AngleZero.ProjectOntoPlane(&PlaneNormal);
    2749   *out << Verbose(4) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl;
    2750   OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero);
     2772    OrthogonalVector.MakeNormalVector(&PlaneNormal);
    27512773  *out << Verbose(4) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl;
    27522774
     
    27662788
    27672789  delete(connectedPoints);
     2790
     2791  *out << Verbose(2) << "End of GetCircleOfConnectedPoints" << endl;
     2792
    27682793  return connectedCircle;
    27692794}
     
    27752800 * @return list of the all points linked to the provided one
    27762801 */
    2777 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
     2802list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const
    27782803{
    27792804  map<double, TesselPoint*> anglesOfPoints;
     
    27922817
    27932818  // find the respective boundary point
    2794   PointMap::iterator PointRunner = PointsOnBoundary.find(Point->nr);
     2819  PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr);
    27952820  if (PointRunner != PointsOnBoundary.end()) {
    27962821    ReferencePoint = PointRunner->second;
     
    28902915 * @return list of the closed paths
    28912916 */
    2892 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
     2917list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const
    28932918{
    28942919  list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(out, Point);
     
    29512976 * \return pointer to allocated list of triangles
    29522977 */
    2953 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, class BoundaryPointSet *Point)
     2978set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, const BoundaryPointSet * const Point) const
    29542979{
    29552980  set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>;
     
    29592984  } else {
    29602985    // go through its lines and insert all triangles
    2961     for (LineMap::iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++)
     2986    for (LineMap::const_iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++)
    29622987      for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) {
    29632988      connectedTriangles->insert(TriangleRunner->second);
     
    31233148        AddTesselationTriangle();
    31243149        // calculate volume summand as a general tetraeder
    3125         volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->node, TPS[1]->node->node, TPS[2]->node->node, &OldPoint);
     3150        volume += CalculateVolumeofGeneralTetraeder(*TPS[0]->node->node, *TPS[1]->node->node, *TPS[2]->node->node, OldPoint);
    31263151        // advance number
    31273152        count++;
     
    32033228 *         will usually be one, in case of degeneration, there will be two
    32043229 */
    3205 list<BoundaryTriangleSet*> *Tesselation::FindTriangles(TesselPoint* Points[3])
     3230list<BoundaryTriangleSet*> *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const
    32063231{
    32073232  list<BoundaryTriangleSet*> *result = new list<BoundaryTriangleSet*>;
    3208   LineMap::iterator FindLine;
    3209   PointMap::iterator FindPoint;
    3210   TriangleMap::iterator FindTriangle;
     3233  LineMap::const_iterator FindLine;
     3234  TriangleMap::const_iterator FindTriangle;
    32113235  class BoundaryPointSet *TrianglePoints[3];
    32123236
    32133237  for (int i = 0; i < 3; i++) {
    3214     FindPoint = PointsOnBoundary.find(Points[i]->nr);
     3238    PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr);
    32153239    if (FindPoint != PointsOnBoundary.end()) {
    32163240      TrianglePoints[i] = FindPoint->second;
     
    32233247  for (int i = 0; i < 3; i++) {
    32243248    if (TrianglePoints[i] != NULL) {
    3225       for (int j = i; j < 3; j++) {
     3249      for (int j = i+1; j < 3; j++) {
    32263250        if (TrianglePoints[j] != NULL) {
    3227           FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr);
    3228           if (FindLine != TrianglePoints[i]->lines.end()) {
    3229             for (; FindLine->first == TrianglePoints[j]->node->nr; FindLine++) {
    3230               FindTriangle = FindLine->second->triangles.begin();
    3231               for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    3232                 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
    3233                   result->push_back(FindTriangle->second);
    3234                 }
     3251          for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap!
     3252              (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr);
     3253              FindLine++) {
     3254            for (FindTriangle = FindLine->second->triangles.begin();
     3255                FindTriangle != FindLine->second->triangles.end();
     3256                FindTriangle++) {
     3257              if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     3258                result->push_back(FindTriangle->second);
    32353259              }
    32363260            }
    3237             // Is it sufficient to consider one of the triangle lines for this.
    3238             return result;
    3239 
    32403261          }
     3262          // Is it sufficient to consider one of the triangle lines for this.
     3263          return result;
    32413264        }
    32423265      }
     
    35243547 * \param *cloud PointCloud structure with all nodes
    35253548 */
    3526 void Tesselation::Output(ofstream *out, const char *filename, PointCloud *cloud)
     3549void Tesselation::Output(ofstream *out, const char *filename, const PointCloud * const cloud)
    35273550{
    35283551  ofstream *tempstream = NULL;
  • src/tesselation.hpp

    r06c7a3 r7326b2  
    2424#include <set>
    2525
     26#include "atom_particleinfo.hpp"
     27#include "helpers.hpp"
    2628#include "vector.hpp"
    2729
     
    8183  public:
    8284    BoundaryPointSet();
    83     BoundaryPointSet(TesselPoint *Walker);
     85    BoundaryPointSet(TesselPoint * Walker);
    8486    ~BoundaryPointSet();
    8587
     
    9395};
    9496
    95 ostream & operator << (ostream &ost, BoundaryPointSet &a);
     97ostream & operator << (ostream &ost, const BoundaryPointSet &a);
    9698
    9799// ======================================================== class BoundaryLineSet ==========================================
     
    100102  public:
    101103    BoundaryLineSet();
    102     BoundaryLineSet(class BoundaryPointSet *Point[2], int number);
     104    BoundaryLineSet(class BoundaryPointSet *Point[2], const int number);
    103105    ~BoundaryLineSet();
    104106
     
    114116};
    115117
    116 ostream & operator << (ostream &ost, BoundaryLineSet &a);
     118ostream & operator << (ostream &ost, const BoundaryLineSet &a);
    117119
    118120// ======================================================== class BoundaryTriangleSet =======================================
     
    140142};
    141143
    142 ostream & operator << (ostream &ost, BoundaryTriangleSet &a);
     144ostream & operator << (ostream &ost, const BoundaryTriangleSet &a);
    143145
    144146// =========================================================== class TESSELPOINT ===========================================
     
    146148/** Is a single point of the set of Vectors, also a super-class to be inherited and and its functions to be implemented.
    147149 */
    148 class TesselPoint {
     150class TesselPoint : virtual public ParticleInfo {
    149151public:
    150152  TesselPoint();
     
    152154
    153155  Vector *node;   // pointer to position of the dot in space
    154   int nr;       // index to easierly identify
    155   char *Name;   // some name to reference to on output
    156156
    157157  virtual ostream & operator << (ostream &ost);
     
    170170  virtual ~PointCloud();
    171171
    172   virtual Vector *GetCenter(ofstream *out) { return NULL; };
    173   virtual TesselPoint *GetPoint() { return NULL; };
    174   virtual TesselPoint *GetTerminalPoint() { return NULL; };
    175   virtual void GoToNext() {};
    176   virtual void GoToPrevious() {};
    177   virtual void GoToFirst() {};
    178   virtual void GoToLast() {};
    179   virtual bool IsEmpty() { return false; };
    180   virtual bool IsEnd() { return false; };
     172  virtual Vector *GetCenter(ofstream *out) const { return NULL; };
     173  virtual TesselPoint *GetPoint() const { return NULL; };
     174  virtual TesselPoint *GetTerminalPoint() const { return NULL; };
     175  virtual void GoToNext() const {};
     176  virtual void GoToPrevious() const {};
     177  virtual void GoToFirst() const {};
     178  virtual void GoToLast() const {};
     179  virtual bool IsEmpty() const { return false; };
     180  virtual bool IsEnd() const { return false; };
    181181};
    182182
     
    204204    virtual ~Tesselation();
    205205
    206     void AddTesselationPoint(TesselPoint* Candidate, int n);
    207     void AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);
    208     void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);
     206    void AddTesselationPoint(TesselPoint* Candidate, const int n);
     207    void AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
     208    void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
    209209    void AddTesselationTriangle();
    210     void AddTesselationTriangle(int nr);
     210    void AddTesselationTriangle(const int nr);
    211211    void RemoveTesselationTriangle(class BoundaryTriangleSet *triangle);
    212212    void RemoveTesselationLine(class BoundaryLineSet *line);
    213213    void RemoveTesselationPoint(class BoundaryPointSet *point);
    214214
    215     class BoundaryPointSet *GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2);
    216215
    217216    // concave envelope
    218     void FindStartingTriangle(ofstream *out, const double RADIUS, class LinkedCell *LC);
    219     void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, class LinkedCell *LC);
    220     void FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, class LinkedCell *LC);
    221     bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC);
     217    void FindStartingTriangle(ofstream *out, const double RADIUS, const LinkedCell *LC);
     218    void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC);
     219    void FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, const LinkedCell *LC);
     220    bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC);
    222221    int CheckPresenceOfTriangle(ofstream *out, class TesselPoint *Candidates[3]);
    223222    class BoundaryTriangleSet * GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3]);
    224223
    225224    // convex envelope
    226     void TesselateOnBoundary(ofstream *out, PointCloud *cloud);
     225    void TesselateOnBoundary(ofstream *out, const PointCloud * const cloud);
    227226    void GuessStartingTriangle(ofstream *out);
    228     bool InsertStraddlingPoints(ofstream *out, PointCloud *cloud, LinkedCell *LC);
     227    bool InsertStraddlingPoints(ofstream *out, const PointCloud *cloud, const LinkedCell *LC);
    229228    double RemovePointFromTesselatedSurface(ofstream *out, class BoundaryPointSet *point);
    230229    class BoundaryLineSet * FlipBaseline(ofstream *out, class BoundaryLineSet *Base);
     
    236235    void AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC);
    237236
    238     set<TesselPoint*> * GetAllConnectedPoints(ofstream *out, TesselPoint* Point);
    239     set<BoundaryTriangleSet*> *GetAllTriangles(ofstream *out, class BoundaryPointSet *Point);
    240     list<list<TesselPoint*> *> * GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point);
    241     list<list<TesselPoint*> *> * GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point);
    242     list<TesselPoint*> * GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference = NULL);
    243     list<BoundaryTriangleSet*> *FindTriangles(TesselPoint* Points[3]);
    244     list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC);
    245     class BoundaryTriangleSet * FindClosestTriangleToPoint(ofstream *out, Vector *x, LinkedCell* LC);
    246     bool IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC);
    247     bool IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC);
    248     bool AddBoundaryPoint(TesselPoint *Walker, int n);
     237    set<TesselPoint*> * GetAllConnectedPoints(ofstream *out, const TesselPoint* const Point) const;
     238    set<BoundaryTriangleSet*> *GetAllTriangles(ofstream *out, const BoundaryPointSet * const Point) const;
     239    list<list<TesselPoint*> *> * GetPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const;
     240    list<list<TesselPoint*> *> * GetClosedPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const;
     241    list<TesselPoint*> * GetCircleOfConnectedPoints(ofstream *out, const TesselPoint* const Point, const Vector * const Reference = NULL) const;
     242    class BoundaryPointSet *GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const;
     243    list<BoundaryTriangleSet*> *FindTriangles(const TesselPoint* const Points[3]) const;
     244    list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const;
     245    class BoundaryTriangleSet * FindClosestTriangleToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const;
     246    bool IsInnerPoint(ofstream *out, const Vector &Point, const LinkedCell* const LC) const;
     247    bool IsInnerPoint(ofstream *out, const TesselPoint * const Point, const LinkedCell* const LC) const;
     248    bool AddBoundaryPoint(TesselPoint * Walker, const int n);
    249249
    250250    // print for debugging
    251     void PrintAllBoundaryPoints(ofstream *out);
    252     void PrintAllBoundaryLines(ofstream *out);
    253     void PrintAllBoundaryTriangles(ofstream *out);
     251    void PrintAllBoundaryPoints(ofstream *out) const;
     252    void PrintAllBoundaryLines(ofstream *out) const;
     253    void PrintAllBoundaryTriangles(ofstream *out) const;
    254254
    255255    // store envelope in file
    256     void Output(ofstream *out, const char *filename, PointCloud *cloud);
     256    void Output(ofstream *out, const char *filename, const PointCloud * const cloud);
    257257
    258258    PointMap PointsOnBoundary;
     
    264264
    265265    // PointCloud implementation for PointsOnBoundary
    266     virtual Vector *GetCenter(ofstream *out);
    267     virtual TesselPoint *GetPoint();
    268     virtual TesselPoint *GetTerminalPoint();
    269     virtual void GoToNext();
    270     virtual void GoToPrevious();
    271     virtual void GoToFirst();
    272     virtual void GoToLast();
    273     virtual bool IsEmpty();
    274     virtual bool IsEnd();
     266    virtual Vector *GetCenter(ofstream *out) const;
     267    virtual TesselPoint *GetPoint() const;
     268    virtual TesselPoint *GetTerminalPoint() const;
     269    virtual void GoToNext() const;
     270    virtual void GoToPrevious() const;
     271    virtual void GoToFirst() const;
     272    virtual void GoToLast() const;
     273    virtual bool IsEmpty() const;
     274    virtual bool IsEnd() const;
    275275
    276276    class BoundaryPointSet *BPS[2];
     
    283283    class BoundaryPointSet *TPS[3]; //this is a Storage for pointers to triangle points, this and BPS[2] needed due to AddLine restrictions
    284284
    285     PointMap::iterator InternalPointer;
     285    mutable PointMap::const_iterator InternalPointer;
    286286};
    287287
  • src/tesselationhelpers.cpp

    r06c7a3 r7326b2  
    1414#include "verbose.hpp"
    1515
    16 double DetGet(gsl_matrix *A, int inPlace) {
     16double DetGet(gsl_matrix * const A, const int inPlace) {
    1717  /*
    1818  inPlace = 1 => A is replaced with the LU decomposed copy.
     
    4242};
    4343
    44 void GetSphere(Vector *center, Vector &a, Vector &b, Vector &c, double RADIUS)
     44void GetSphere(Vector * const center, const Vector &a, const Vector &b, const Vector &c, const double RADIUS)
    4545{
    4646  gsl_matrix *A = gsl_matrix_calloc(3,3);
     
    9696 * @param b vector second point of triangle
    9797 * @param c vector third point of triangle
    98  * @param *Umkreismittelpunkt new cneter point of circumference
     98 * @param *Umkreismittelpunkt new center point of circumference
    9999 * @param Direction vector indicates up/down
    100  * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle
     100 * @param AlternativeDirection Vector, needed in case the triangles have 90 deg angle
    101101 * @param Halfplaneindicator double indicates whether Direction is up or down
    102  * @param AlternativeIndicator doube indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable
     102 * @param AlternativeIndicator double indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable
    103103 * @param alpha double angle at a
    104104 * @param beta double, angle at b
     
    107107 * @param Umkreisradius double radius of circumscribing circle
    108108 */
    109 void GetCenterOfSphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,
    110     double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius)
     109void GetCenterOfSphere(Vector* const & Center, const Vector &a, const Vector &b, const Vector &c, Vector * const NewUmkreismittelpunkt, const Vector* const Direction, const Vector* const AlternativeDirection,
     110    const double HalfplaneIndicator, const double AlternativeIndicator, const double alpha, const double beta, const double gamma, const double RADIUS, const double Umkreisradius)
    111111{
    112112  Vector TempNormal, helper;
     
    171171 * \param *c third point
    172172 */
    173 void GetCenterofCircumcircle(Vector *Center, Vector *a, Vector *b, Vector *c)
     173void GetCenterofCircumcircle(Vector * const Center, const Vector &a, const Vector &b, const Vector &c)
    174174{
    175175  Vector helper;
     
    177177  Vector SideA, SideB, SideC;
    178178  SideA.CopyVector(b);
    179   SideA.SubtractVector(c);
     179  SideA.SubtractVector(&c);
    180180  SideB.CopyVector(c);
    181   SideB.SubtractVector(a);
     181  SideB.SubtractVector(&a);
    182182  SideC.CopyVector(a);
    183   SideC.SubtractVector(b);
     183  SideC.SubtractVector(&b);
    184184  alpha = M_PI - SideB.Angle(&SideC);
    185185  beta = M_PI - SideC.Angle(&SideA);
     
    215215 * \return Angle between \a NewSphereCenter and \a OldSphereCenter relative to \a CircleCenter, 2.*M_PI if one test fails
    216216 */
    217 double GetPathLengthonCircumCircle(Vector &CircleCenter, Vector &CirclePlaneNormal, double CircleRadius, Vector &NewSphereCenter, Vector &OldSphereCenter, Vector &NormalVector, Vector &SearchDirection)
     217double GetPathLengthonCircumCircle(const Vector &CircleCenter, const Vector &CirclePlaneNormal, const double CircleRadius, const Vector &NewSphereCenter, const Vector &OldSphereCenter, const Vector &NormalVector, const Vector &SearchDirection)
    218218{
    219219  Vector helper;
     
    300300 * @return true if there is an intersection between the given lines, false otherwise
    301301 */
    302 bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4)
     302bool existsIntersection(const Vector &point1, const Vector &point2, const Vector &point3, const Vector &point4)
    303303{
    304304  bool result;
     
    403403 * @return angle between point and reference
    404404 */
    405 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector)
     405double GetAngle(const Vector &point, const Vector &reference, const Vector &OrthogonalVector)
    406406{
    407407  if (reference.IsZero())
     
    429429 * \return \f$ \frac{1}{6} \cdot ((a-d) \times (a-c) \cdot  (a-b)) \f$
    430430 */
    431 double CalculateVolumeofGeneralTetraeder(Vector *a, Vector *b, Vector *c, Vector *d)
     431double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d)
    432432{
    433433  Vector Point, TetraederVector[3];
     
    438438  TetraederVector[2].CopyVector(c);
    439439  for (int j=0;j<3;j++)
    440     TetraederVector[j].SubtractVector(d);
     440    TetraederVector[j].SubtractVector(&d);
    441441  Point.CopyVector(&TetraederVector[0]);
    442442  Point.VectorProduct(&TetraederVector[1]);
     
    452452 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create)
    453453 */
    454 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3])
     454bool CheckLineCriteriaForDegeneratedTriangle(const BoundaryPointSet * const nodes[3])
    455455{
    456456  bool result = false;
     
    461461    for (int j=i+1; j<3; j++) {
    462462      if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) {  // there already is a line
    463         LineMap::iterator FindLine;
    464         pair<LineMap::iterator,LineMap::iterator> FindPair;
     463        LineMap::const_iterator FindLine;
     464        pair<LineMap::const_iterator,LineMap::const_iterator> FindPair;
    465465        FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr);
    466466        for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {
     
    486486/** Sort function for the candidate list.
    487487 */
    488 bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2)
     488bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation* candidate2)
    489489{
    490490  Vector BaseLineVector, OrthogonalVector, helper;
     
    536536 * @return point which is second closest to the provided one
    537537 */
    538 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC)
    539 {
    540   LinkedNodes *List = NULL;
     538TesselPoint* FindSecondClosestPoint(const Vector* Point, const LinkedCell* const LC)
     539{
    541540  TesselPoint* closestPoint = NULL;
    542541  TesselPoint* secondClosestPoint = NULL;
     
    556555    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    557556      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    558         List = LC->GetCurrentCell();
     557        const LinkedNodes *List = LC->GetCurrentCell();
    559558        //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
    560559        if (List != NULL) {
    561           for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     560          for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    562561            helper.CopyVector(Point);
    563562            helper.SubtractVector((*Runner)->node);
     
    591590 * @return point which is closest to the provided one, NULL if none found
    592591 */
    593 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC)
    594 {
    595   LinkedNodes *List = NULL;
     592TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, const LinkedCell* const LC)
     593{
    596594  TesselPoint* closestPoint = NULL;
    597595  SecondPoint = NULL;
     
    611609    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    612610      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    613         List = LC->GetCurrentCell();
     611        const LinkedNodes *List = LC->GetCurrentCell();
    614612        //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
    615613        if (List != NULL) {
    616           for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     614          for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    617615            helper.CopyVector(Point);
    618616            helper.SubtractVector((*Runner)->node);
     
    635633        }
    636634      }
    637 
     635  // output
     636  if (closestPoint != NULL) {
     637    cout << Verbose(2) << "Closest point is " << *closestPoint;
     638    if (SecondPoint != NULL)
     639      cout << " and second closest is " << *SecondPoint;
     640    cout << "." << endl;
     641  }
    638642  return closestPoint;
    639643};
     
    645649 * \return Vector on reference line that has closest distance
    646650 */
    647 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase)
     651Vector * GetClosestPointBetweenLine(ofstream *out, const BoundaryLineSet * const Base, const BoundaryLineSet * const OtherBase)
    648652{
    649653  // construct the plane of the two baselines (i.e. take both their directional vectors)
     
    685689 * \return distance between \a *x and plane defined by \a *triangle, -1 - if something went wrong
    686690 */
    687 double DistanceToTrianglePlane(ofstream *out, Vector *x, BoundaryTriangleSet *triangle)
     691double DistanceToTrianglePlane(ofstream * const out, const Vector *x, const BoundaryTriangleSet * const triangle)
    688692{
    689693  double distance = 0.;
     
    701705 * \param *mol molecule structure with atom positions
    702706 */
    703 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud)
     707void WriteVrmlFile(ofstream * const out, ofstream * const vrmlfile, const Tesselation * const Tess, const PointCloud * const cloud)
    704708{
    705709  TesselPoint *Walker = NULL;
     
    722726
    723727    *vrmlfile << "# All tesselation triangles" << endl;
    724     for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
     728    for (TriangleMap::const_iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
    725729      *vrmlfile << "1" << endl << "  "; // 1 is triangle type
    726730      for (i=0;i<3;i++) { // print each node
     
    744748 * \param *mol molecule structure with atom positions
    745749 */
    746 void IncludeSphereinRaster3D(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)
     750void IncludeSphereinRaster3D(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud)
    747751{
    748752  Vector helper;
     
    769773 * \param *mol molecule structure with atom positions
    770774 */
    771 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)
     775void WriteRaster3dFile(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud)
    772776{
    773777  TesselPoint *Walker = NULL;
     
    791795    *rasterfile << "# All tesselation triangles" << endl;
    792796    *rasterfile << "8\n  25. -1.   1. 1. 1.   0.0    0 0 0 2\n  SOLID     1.0 0.0 0.0\n  BACKFACE  0.3 0.3 1.0   0 0\n";
    793     for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
     797    for (TriangleMap::const_iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
    794798      *rasterfile << "1" << endl << "  ";  // 1 is triangle type
    795799      for (i=0;i<3;i++) {  // print each node
     
    814818 * \param N arbitrary number to differentiate various zones in the tecplot format
    815819 */
    816 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud, int N)
     820void WriteTecplotFile(ofstream * const out, ofstream * const tecplot, const Tesselation * const TesselStruct, const PointCloud * const cloud, const int N)
    817821{
    818822  if ((tecplot != NULL) && (TesselStruct != NULL)) {
     
    834838    int Counter = 1;
    835839    TesselPoint *Walker = NULL;
    836     for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) {
     840    for (PointMap::const_iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) {
    837841      Walker = target->second->node;
    838842      LookupList[Walker->nr] = Counter++;
     
    841845    *tecplot << endl;
    842846    // print connectivity
    843     for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {
     847    for (TriangleMap::const_iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {
    844848      *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;
    845849      *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;
     
    855859 * \param *TesselStruct pointer to Tesselation structure
    856860 */
    857 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct)
     861void CalculateConcavityPerBoundaryPoint(ofstream * const out, const Tesselation * const TesselStruct)
    858862{
    859863  class BoundaryPointSet *point = NULL;
     
    862866  //*out << Verbose(2) << "Begin of CalculateConcavityPerBoundaryPoint" << endl;
    863867  // calculate remaining concavity
    864   for (PointMap::iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {
     868  for (PointMap::const_iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {
    865869    point = PointRunner->second;
    866870    *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl;
     
    882886 * \return true - all have exactly two triangles, false - some not, list is printed to screen
    883887 */
    884 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct)
    885 {
    886   LineMap::iterator testline;
     888bool CheckListOfBaselines(ofstream * const out, const Tesselation * const TesselStruct)
     889{
     890  LineMap::const_iterator testline;
    887891  bool result = false;
    888892  int counter = 0;
  • src/tesselationhelpers.hpp

    r06c7a3 r7326b2  
    4747/********************************************** declarations *******************************/
    4848
    49 double DetGet(gsl_matrix *A, int inPlace);
    50 void GetSphere(Vector *center, Vector &a, Vector &b, Vector &c, double RADIUS);
    51 void GetCenterOfSphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection, double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius);
    52 void GetCenterofCircumcircle(Vector *Center, Vector *a, Vector *b, Vector *c);
    53 double GetPathLengthonCircumCircle(Vector &CircleCenter, Vector &CirclePlaneNormal, double CircleRadius, Vector &NewSphereCenter, Vector &OldSphereCenter, Vector &NormalVector, Vector &SearchDirection);
     49double DetGet(gsl_matrix * const A, const int inPlace);
     50void GetSphere(Vector * const Center, const Vector &a, const Vector &b, const Vector &c, const double RADIUS);
     51void GetCenterOfSphere(Vector* const Center, const Vector &a, const Vector &b, const Vector &c, Vector * const NewUmkreismittelpunkt, const Vector* const Direction, const Vector* const AlternativeDirection, const double HalfplaneIndicator, const double AlternativeIndicator, const double alpha, const double beta, const double gamma, const double RADIUS, const double Umkreisradius);
     52void GetCenterofCircumcircle(Vector * const Center, const Vector &a, const Vector &b, const Vector &c);
     53double GetPathLengthonCircumCircle(const Vector &CircleCenter, const Vector &CirclePlaneNormal, const double CircleRadius, const Vector &NewSphereCenter, const Vector &OldSphereCenter, const Vector &NormalVector, const Vector &SearchDirection);
    5454double MinIntersectDistance(const gsl_vector * x, void *params);
    55 bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4);
    56 double CalculateVolumeofGeneralTetraeder(Vector *a, Vector *b, Vector *c, Vector *d);
    57 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector);
     55bool existsIntersection(const Vector &point1, const Vector &point2, const Vector &point3, const Vector &point4);
     56double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d);
     57double GetAngle(const Vector &point, const Vector &reference, const Vector &OrthogonalVector);
    5858
    59 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3]);
    60 bool SortCandidates(class CandidateForTesselation* candidate1, class CandidateForTesselation* candidate2);
    61 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC);
    62 TesselPoint* FindSecondClosestPoint(const Vector*, LinkedCell*);
    63 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase);
     59bool CheckLineCriteriaForDegeneratedTriangle(const BoundaryPointSet * const nodes[3]);
     60bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation *candidate2);
     61TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, const LinkedCell* const LC);
     62TesselPoint* FindSecondClosestPoint(const Vector*, const LinkedCell* const LC);
     63Vector * GetClosestPointBetweenLine(ofstream *out, const BoundaryLineSet * const Base, const BoundaryLineSet * const OtherBase);
    6464
    65 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud, int N);
    66 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud);
    67 void IncludeSphereinRaster3D(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud);
    68 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud);
    69 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct);
    70 double DistanceToTrianglePlane(ofstream *out, Vector *x, BoundaryTriangleSet *triangle);
     65void WriteTecplotFile(ofstream * const out, ofstream * const tecplot, const Tesselation * const TesselStruct, const PointCloud * const cloud, const int N);
     66void WriteRaster3dFile(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud);
     67void IncludeSphereinRaster3D(ofstream * const out, ofstream * const rasterfile, const Tesselation *Tess, const PointCloud *cloud);
     68void WriteVrmlFile(ofstream * const out, ofstream * const vrmlfile, const Tesselation * const Tess, const PointCloud * const cloud);
     69void CalculateConcavityPerBoundaryPoint(ofstream * const out, const Tesselation * const TesselStruct);
     70double DistanceToTrianglePlane(ofstream * const out, const Vector *x, const BoundaryTriangleSet * const triangle);
    7171
    72 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct);
     72bool CheckListOfBaselines(ofstream * const out, const Tesselation * const TesselStruct);
    7373
    7474
  • src/unittests/ActOnAllUnitTest.cpp

    r06c7a3 r7326b2  
    1212#include <cppunit/ui/text/TestRunner.h>
    1313
    14 #include "ActOnAlltest.hpp"
     14#include "../test/ActOnAlltest.hpp"
    1515#include "ActOnAllUnitTest.hpp"
    1616#include "memoryallocator.hpp"
     
    6262
    6363  // scaling by value
    64   VL.ActOnAll( (void (Vector::*)(double)) &Vector::Scale, 2. );
     64  VL.ActOnAll( (void (Vector::*)(const double)) &Vector::Scale, 2. );
    6565  CPPUNIT_ASSERT_EQUAL( VL == Ref , false );
    6666
    67   VL.ActOnAll( (void (Vector::*)(double)) &Vector::Scale, 0.5 );
     67  VL.ActOnAll( (void (Vector::*)(const double)) &Vector::Scale, 0.5 );
    6868  CPPUNIT_ASSERT_EQUAL( VL == Ref , true );
    6969
    7070  // scaling by ref
    71   VL.ActOnAll( (void (Vector::*)(double *)) &Vector::Scale, &factor );
     71  VL.ActOnAll( (void (Vector::*)(const double * const)) &Vector::Scale, (const double * const)&factor );
    7272  CPPUNIT_ASSERT_EQUAL( VL == Ref , false );
    7373
    74   VL.ActOnAll( (void (Vector::*)(double *)) &Vector::Scale, &inverse );
     74  VL.ActOnAll( (void (Vector::*)(const double * const)) &Vector::Scale, (const double * const)&inverse );
    7575  CPPUNIT_ASSERT_EQUAL( VL == Ref , true );
    7676
     
    8282    inverses[i] = 1./factors[i];
    8383  }
    84   VL.ActOnAll( (void (Vector::*)(double **)) &Vector::Scale, &factors );
     84  VL.ActOnAll( (void (Vector::*)(const double ** const)) &Vector::Scale, (const double ** const)&factors );
    8585  CPPUNIT_ASSERT_EQUAL( VL == Ref , false );
    8686
    87   VL.ActOnAll( (void (Vector::*)(double **)) &Vector::Scale, &inverses );
     87  VL.ActOnAll( (void (Vector::*)(const double ** const)) &Vector::Scale, (const double ** const)&inverses );
    8888  CPPUNIT_ASSERT_EQUAL( VL == Ref , true );
    8989};
  • src/unittests/ActOnAllUnitTest.hpp

    r06c7a3 r7326b2  
    1111#include <cppunit/extensions/HelperMacros.h>
    1212
    13 #include "ActOnAlltest.hpp"
     13#include "../test/ActOnAlltest.hpp"
    1414
    1515/********************************************** Test classes **************************************/
  • src/unittests/AnalysisCorrelationToPointUnitTest.cpp

    r06c7a3 r7326b2  
    3333
    3434  // init private all pointers to zero
     35  TestList = NULL;
    3536  TestMolecule = NULL;
    3637  hydrogen = NULL;
     
    4445  hydrogen->Z = 1;
    4546  strcpy(hydrogen->name, "hydrogen");
    46   hydrogen->symbol[0] = 'H';
     47  strcpy(hydrogen->symbol, "H");
     48
    4749
    4850  // construct periodentafel
     
    7274  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
    7375
     76  TestList = new MoleculeListClass;
     77  TestMolecule->ActiveFlag = true;
     78  TestList->insert(TestMolecule);
     79
    7480  // init point
    7581  point = new Vector(1.,1.,1.);
    7682
    7783  // init maps
    78   pointmap = CorrelationToPoint( (ofstream *)&cout, TestMolecule, hydrogen, point );
     84  pointmap = CorrelationToPoint( (ofstream *)&cout, (MoleculeListClass * const)TestList, (const element * const)hydrogen, (const Vector *)point );
    7985  binmap = NULL;
    8086
     
    9096
    9197  // remove
    92   delete(TestMolecule);
     98  delete(TestList);
    9399  // note that all the atoms are cleaned by TestMolecule
    94100  delete(point);
  • src/unittests/AnalysisCorrelationToPointUnitTest.hpp

    r06c7a3 r7326b2  
    1212
    1313class element;
     14class LinkedCell;
    1415class molecule;
    15 class LinkedCell;
     16class MoleculeListClass;
    1617class periodentafel;
    1718class Tesselation;
     
    3738private:
    3839
     40      MoleculeListClass *TestList;
    3941      molecule *TestMolecule;
    4042      element *hydrogen;
  • src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp

    r06c7a3 r7326b2  
    3333
    3434  // init private all pointers to zero
     35  TestList = NULL;
    3536  TestMolecule = NULL;
    3637  hydrogen = NULL;
     
    4142  LC = NULL;
    4243
    43 
    4444  // construct element
    4545  hydrogen = new element;
    4646  hydrogen->Z = 1;
    4747  strcpy(hydrogen->name, "hydrogen");
    48   hydrogen->symbol[0] = 'H';
     48  strcpy(hydrogen->symbol, "H");
     49  carbon = new element;
     50  carbon->Z = 6;
     51  strcpy(carbon->name, "carbon");
     52  strcpy(carbon->symbol, "C");
    4953
    5054  // construct periodentafel
    5155  tafel = new periodentafel;
    5256  tafel->AddElement(hydrogen);
    53 
    54   // construct molecule (tetraeder of hydrogens)
     57  tafel->AddElement(carbon);
     58
     59  // construct molecule (tetraeder of hydrogens) base
    5560  TestMolecule = new molecule(tafel);
    5661  Walker = new atom();
     
    7479  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
    7580
     81  TestList = new MoleculeListClass;
     82  TestMolecule->ActiveFlag = true;
     83  TestList->insert(TestMolecule);
     84
    7685  // init tesselation and linked cell
    7786  Surface = new Tesselation;
    78   TestMolecule->TesselStruct = Surface;
    79   FindNonConvexBorder((ofstream *)&cout, TestMolecule, LC, 2.5, NULL);
     87  FindNonConvexBorder((ofstream *)&cerr, TestMolecule, Surface, (const LinkedCell *&)LC, 2.5, NULL);
    8088  LC = new LinkedCell(TestMolecule, 5.);
    8189  CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->PointsOnBoundary.size() );
     
    8391  CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->TrianglesOnBoundary.size() );
    8492
     93  // add outer atoms
     94  Walker = new atom();
     95  Walker->type = carbon;
     96  Walker->node->Init(4., 0., 4. );
     97  TestMolecule->AddAtom(Walker);
     98  Walker = new atom();
     99  Walker->type = carbon;
     100  Walker->node->Init(0., 4., 4. );
     101  TestMolecule->AddAtom(Walker);
     102  Walker = new atom();
     103  Walker->type = carbon;
     104  Walker->node->Init(4., 4., 0. );
     105  TestMolecule->AddAtom(Walker);
     106  // add inner atoms
     107  Walker = new atom();
     108  Walker->type = carbon;
     109  Walker->node->Init(0.5, 0.5, 0.5 );
     110  TestMolecule->AddAtom(Walker);
     111
    85112  // init maps
    86   surfacemap = CorrelationToSurface( (ofstream *)&cout, TestMolecule, hydrogen, Surface, LC );
     113  surfacemap = NULL;
    87114  binmap = NULL;
    88115
     
    98125
    99126  // remove
    100   delete(TestMolecule);
    101   // note that Surface and all the atoms are cleaned by TestMolecule
     127  delete(TestList);
     128  delete(Surface);
     129  // note that all the atoms are cleaned by TestMolecule
    102130  delete(LC);
    103131  delete(tafel);
     
    109137{
    110138  // do the pair correlation
     139  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC );
    111140  CPPUNIT_ASSERT( surfacemap != NULL );
    112141  CPPUNIT_ASSERT_EQUAL( (size_t)4, surfacemap->size() );
    113142};
    114143
    115 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinNoRangeTest()
    116 {
    117   BinPairMap::iterator tester;
     144void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceHydrogenBinNoRangeTest()
     145{
     146  BinPairMap::iterator tester;
     147  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC );
    118148  // put pair correlation into bins and check with no range
    119149  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. );
     
    126156};
    127157
    128 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinRangeTest()
    129 {
    130   BinPairMap::iterator tester;
     158void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceHydrogenBinRangeTest()
     159{
     160  BinPairMap::iterator tester;
     161  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC );
    131162  // ... and check with [0., 2.] range
    132163  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 2. );
     
    142173};
    143174
     175void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceCarbonBinNoRangeTest()
     176{
     177  BinPairMap::iterator tester;
     178  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, carbon, Surface, LC );
     179  // put pair correlation into bins and check with no range
     180  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. );
     181  CPPUNIT_ASSERT_EQUAL( (size_t)2, binmap->size() );
     182  OutputCorrelation ( (ofstream *)&cout, binmap );
     183  // inside point is first and must have negative value
     184  tester = binmap->lower_bound(2.95); // start depends on the min value and
     185  CPPUNIT_ASSERT( tester != binmap->end() );
     186  CPPUNIT_ASSERT_EQUAL( 3, tester->second );
     187  // inner point
     188  tester = binmap->lower_bound(-0.5);
     189  CPPUNIT_ASSERT( tester != binmap->end() );
     190  CPPUNIT_ASSERT_EQUAL( 1, tester->second );
     191};
     192
     193void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceCarbonBinRangeTest()
     194{
     195  BinPairMap::iterator tester;
     196  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, carbon, Surface, LC );
     197  // ... and check with [0., 2.] range
     198  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, -2., 4. );
     199  CPPUNIT_ASSERT_EQUAL( (size_t)13, binmap->size() );
     200  OutputCorrelation ( (ofstream *)&cout, binmap );
     201  // three outside points
     202  tester = binmap->lower_bound(3.);
     203  CPPUNIT_ASSERT( tester != binmap->end() );
     204  CPPUNIT_ASSERT_EQUAL( 3, tester->second );
     205  // inner point
     206  tester = binmap->lower_bound(-0.5);
     207  CPPUNIT_ASSERT( tester != binmap->end() );
     208  CPPUNIT_ASSERT_EQUAL( 1, tester->second );
     209
     210};
     211
    144212/********************************************** Main routine **************************************/
    145213
  • src/unittests/AnalysisCorrelationToSurfaceUnitTest.hpp

    r06c7a3 r7326b2  
    1212
    1313class element;
     14class LinkedCell;
    1415class molecule;
    15 class LinkedCell;
     16class MoleculeListClass;
    1617class periodentafel;
    1718class Tesselation;
     
    2324    CPPUNIT_TEST_SUITE( AnalysisCorrelationToSurfaceUnitTest ) ;
    2425    CPPUNIT_TEST ( CorrelationToSurfaceTest );
    25     CPPUNIT_TEST ( CorrelationToSurfaceBinNoRangeTest );
    26     CPPUNIT_TEST ( CorrelationToSurfaceBinRangeTest );
     26    CPPUNIT_TEST ( CorrelationToSurfaceHydrogenBinNoRangeTest );
     27    CPPUNIT_TEST ( CorrelationToSurfaceHydrogenBinRangeTest );
     28    CPPUNIT_TEST ( CorrelationToSurfaceCarbonBinNoRangeTest );
     29    CPPUNIT_TEST ( CorrelationToSurfaceCarbonBinRangeTest );
    2730    CPPUNIT_TEST_SUITE_END();
    2831
     
    3134      void tearDown();
    3235      void CorrelationToSurfaceTest();
    33       void CorrelationToSurfaceBinNoRangeTest();
    34       void CorrelationToSurfaceBinRangeTest();
     36      void CorrelationToSurfaceHydrogenBinNoRangeTest();
     37      void CorrelationToSurfaceHydrogenBinRangeTest();
     38      void CorrelationToSurfaceCarbonBinNoRangeTest();
     39      void CorrelationToSurfaceCarbonBinRangeTest();
    3540
    3641private:
    3742
     43      MoleculeListClass *TestList;
    3844      molecule *TestMolecule;
    3945      element *hydrogen;
     46      element *carbon;
    4047      periodentafel *tafel;
    4148
  • src/unittests/AnalysisPairCorrelationUnitTest.cpp

    r06c7a3 r7326b2  
    3434
    3535  // init private all pointers to zero
     36  TestList = NULL;
    3637  TestMolecule = NULL;
    3738  hydrogen = NULL;
     
    4445  hydrogen->Z = 1;
    4546  strcpy(hydrogen->name, "hydrogen");
    46   hydrogen->symbol[0] = 'H';
     47  strcpy(hydrogen->symbol, "H");
    4748
    4849  // construct periodentafel
     
    7273  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
    7374
     75  TestList = new MoleculeListClass;
     76  TestMolecule->ActiveFlag = true;
     77  TestList->insert(TestMolecule);
     78
    7479  // init maps
    75   correlationmap = PairCorrelation( (ofstream *)&cout, TestMolecule, hydrogen, hydrogen );
     80  correlationmap = PairCorrelation( (ofstream *)&cout, TestList, hydrogen, hydrogen );
    7681  binmap = NULL;
    7782
     
    8792
    8893  // remove
    89   delete(TestMolecule);
     94  delete(TestList);
    9095  // note that all the atoms are cleaned by TestMolecule
    9196  delete(tafel);
  • src/unittests/AnalysisPairCorrelationUnitTest.hpp

    r06c7a3 r7326b2  
    1212
    1313class element;
     14class LinkedCell;
    1415class molecule;
    15 class LinkedCell;
     16class MoleculeListClass;
    1617class periodentafel;
    1718class Tesselation;
     
    3738private:
    3839
     40      MoleculeListClass *TestList;
    3941      molecule *TestMolecule;
    4042      element *hydrogen;
  • src/unittests/Makefile.am

    r06c7a3 r7326b2  
    11INCLUDES = -I$(top_srcdir)/src
    22
    3 noinst_PROGRAMS =  ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest LogUnitTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest
     3AM_LDFLAGS = $(CPPUNIT_LIBS) -ldl
     4AM_CXXFLAGS = $(CPPUNIT_CFLAGS)
    45
    5 TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest
     6TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest BondGraphUnitTest ListOfBondsUnitTest LogUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest StackClassUnitTest VectorUnitTest
    67check_PROGRAMS = $(TESTS)
     8noinst_PROGRAMS = $(TESTS)
    79
    8 ActOnAllUnitTest_SOURCES = ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp
    9 ActOnAllUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    10 ActOnAllUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    11 ActOnAllUnitTest_LDADD = ../libmolecuilder.a
     10ActOnAllUnitTest_SOURCES = ../test/ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp
    1211
    1312AnalysisCorrelationToPointUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToPointUnitTest.cpp AnalysisCorrelationToPointUnitTest.hpp
    14 AnalysisCorrelationToPointUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    15 AnalysisCorrelationToPointUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    1613AnalysisCorrelationToPointUnitTest_LDADD = ../libmolecuilder.a
    1714
    1815AnalysisCorrelationToSurfaceUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToSurfaceUnitTest.cpp AnalysisCorrelationToSurfaceUnitTest.hpp
    19 AnalysisCorrelationToSurfaceUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    20 AnalysisCorrelationToSurfaceUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    2116AnalysisCorrelationToSurfaceUnitTest_LDADD = ../libmolecuilder.a
    2217
    2318AnalysisPairCorrelationUnitTest_SOURCES = analysis_correlation.hpp AnalysisPairCorrelationUnitTest.cpp AnalysisPairCorrelationUnitTest.hpp
    24 AnalysisPairCorrelationUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    25 AnalysisPairCorrelationUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    2619AnalysisPairCorrelationUnitTest_LDADD = ../libmolecuilder.a
    2720
    28 VectorUnitTest_SOURCES = defs.hpp helpers.hpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp vectorunittest.cpp vectorunittest.hpp vector.hpp verbose.hpp
    29 VectorUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    30 VectorUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    31 VectorUnitTest_LDADD = ../libmolecuilder.a
     21BondGraphUnitTest_SOURCES = bondgraphunittest.cpp bondgraphunittest.hpp
     22BondGraphUnitTest_LDADD = ../libmolecuilder.a
    3223
    33 MemoryAllocatorUnitTest_SOURCES = defs.hpp helpers.hpp memoryallocatorunittest.cpp memoryallocatorunittest.hpp memoryallocator.hpp memoryusageobserver.hpp verbose.hpp
    34 MemoryAllocatorUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS) -I..
    35 MemoryAllocatorUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    36 MemoryAllocatorUnitTest_LDADD = ../libmolecuilder.a
     24ListOfBondsUnitTest_SOURCES = listofbondsunittest.cpp listofbondsunittest.hpp
     25ListOfBondsUnitTest_LDADD = ../libmolecuilder.a
     26
     27LogUnitTest_SOURCES = logunittest.cpp logunittest.hpp
     28LogUnitTest_LDADD = ../libmolecuilder.a
     29
     30MemoryAllocatorUnitTest_SOURCES = defs.hpp ../helpers.cpp ../helpers.hpp memoryallocatorunittest.cpp memoryallocatorunittest.hpp memoryallocator.hpp ../memoryusageobserver.cpp memoryusageobserver.hpp ../verbose.cpp verbose.hpp
    3731
    3832MemoryUsageObserverUnitTest_SOURCES = defs.hpp helpers.hpp memoryusageobserverunittest.cpp memoryusageobserverunittest.hpp memoryusageobserver.hpp verbose.hpp
    39 MemoryUsageObserverUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    40 MemoryUsageObserverUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    41 MemoryUsageObserverUnitTest_LDADD = ../libmolecuilder.a
    4233
    43 LogUnitTest_SOURCES = ../errorLogger.cpp ../errorLogger.hpp ../log.cpp ../log.hpp ../logger.cpp ../logger.hpp logunittest.cpp logunittest.hpp
    44 LogUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
    45 LogUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
    46 LogUnitTest_LDADD = ../libmolecuilder.a
     34StackClassUnitTest_SOURCES = memoryallocator.hpp stackclass.hpp stackclassunittest.cpp stackclassunittest.hpp
     35
     36VectorUnitTest_SOURCES = defs.hpp ../helpers.cpp helpers.hpp ../leastsquaremin.cpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp ../memoryusageobserver.cpp vectorunittest.cpp vectorunittest.hpp vector.hpp ../vector.cpp verbose.hpp ../verbose.cpp
     37
     38
     39#AUTOMAKE_OPTIONS = parallel-tests
     40
  • src/unittests/memoryallocatorunittest.cpp

    r06c7a3 r7326b2  
    2828void MemoryAllocatorTest::tearDown()
    2929{
     30  MemoryUsageObserver::getInstance()->purgeInstance();
    3031};
    3132
     
    4950
    5051  char** buffer4 = NULL;
    51   buffer4 = Malloc<char*>(1, "");
     52  buffer4 = Malloc<char*>(10, "");
     53  for (int i=0;i<10;i++)
     54    buffer4[i] = NULL;
    5255  Free(&buffer4);
    5356};
     
    5962{
    6063  int* buffer1 = NULL;
    61   buffer1 = Calloc<int>(1, "");
     64  buffer1 = Calloc<int>(10, "");
    6265  Free(&buffer1);
    6366
    6467  long* buffer2 = NULL;
    65   buffer2 = Calloc<long>(1, "");
     68  buffer2 = Calloc<long>(10, "");
    6669  Free(&buffer2);
    6770
    68   char* buffer3 = NULL;
    69   buffer3 = Calloc<char>(1, "");
     71  char** buffer3 = NULL;
     72  buffer3 = Calloc<char *>(10, "");
     73  for (int i=0;i<10;i++)
     74    buffer3[i] = NULL;
    7075  Free(&buffer3);
    7176};
  • src/vector.cpp

    • Property mode changed from 100755 to 100644
    r06c7a3 r7326b2  
    2121/** Constructor of class vector.
    2222 */
    23 Vector::Vector(double x1, double x2, double x3) { x[0] = x1; x[1] = x2; x[2] = x3; };
     23Vector::Vector(const double x1, const double x2, const double x3) { x[0] = x1; x[1] = x2; x[2] = x3; };
    2424
    2525/** Desctructor of class vector.
     
    3131 * \return \f$| x - y |^2\f$
    3232 */
    33 double Vector::DistanceSquared(const Vector *y) const
     33double Vector::DistanceSquared(const Vector * const y) const
    3434{
    3535  double res = 0.;
     
    4343 * \return \f$| x - y |\f$
    4444 */
    45 double Vector::Distance(const Vector *y) const
     45double Vector::Distance(const Vector * const y) const
    4646{
    4747  double res = 0.;
     
    5656 * \return \f$| x - y |\f$
    5757 */
    58 double Vector::PeriodicDistance(const Vector *y, const double *cell_size) const
     58double Vector::PeriodicDistance(const Vector * const y, const double * const cell_size) const
    5959{
    6060  double res = Distance(y), tmp, matrix[NDIM*NDIM];
     
    9494 * \return \f$| x - y |^2\f$
    9595 */
    96 double Vector::PeriodicDistanceSquared(const Vector *y, const double *cell_size) const
     96double Vector::PeriodicDistanceSquared(const Vector * const y, const double * const cell_size) const
    9797{
    9898  double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];
     
    131131 * Tries to translate a vector into each adjacent neighbouring cell.
    132132 */
    133 void Vector::KeepPeriodic(ofstream *out, double *matrix)
     133void Vector::KeepPeriodic(ofstream *out, const double * const matrix)
    134134{
    135135//  int N[NDIM];
     
    162162 * \return \f$\langle x, y \rangle\f$
    163163 */
    164 double Vector::ScalarProduct(const Vector *y) const
     164double Vector::ScalarProduct(const Vector * const y) const
    165165{
    166166  double res = 0.;
     
    177177 *  \return \f$ x \times y \f&
    178178 */
    179 void Vector::VectorProduct(const Vector *y)
     179void Vector::VectorProduct(const Vector * const y)
    180180{
    181181  Vector tmp;
     
    184184  tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
    185185  this->CopyVector(&tmp);
    186 
    187186};
    188187
     
    192191 * \return \f$\langle x, y \rangle\f$
    193192 */
    194 void Vector::ProjectOntoPlane(const Vector *y)
     193void Vector::ProjectOntoPlane(const Vector * const y)
    195194{
    196195  Vector tmp;
     
    217216 * \return true -  \a this contains intersection point on return, false - line is parallel to plane
    218217 */
    219 bool Vector::GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *Origin, Vector *LineVector)
     218bool Vector::GetIntersectionWithPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector)
    220219{
    221220  double factor;
     
    264263 * \return distance to plane
    265264 */
    266 double Vector::DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset)
     265double Vector::DistanceToPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset) const
    267266{
    268267  Vector temp;
     
    276275  temp.AddVector(this);
    277276  temp.SubtractVector(PlaneOffset);
    278 
    279   return temp.Norm();
     277  double sign = temp.ScalarProduct(PlaneNormal);
     278  if (fabs(sign) > MYEPSILON)
     279    sign /= fabs(sign);
     280  else
     281    sign = 0.;
     282
     283  return (temp.Norm()*sign);
    280284};
    281285
     
    292296 * \return true - \a this will contain the intersection on return, false - lines are parallel
    293297 */
    294 bool Vector::GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b, const Vector *PlaneNormal)
     298bool Vector::GetIntersectionOfTwoLinesOnPlane(ofstream *out, const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *PlaneNormal)
    295299{
    296300  bool result = true;
     
    375379 * \param *y array to second vector
    376380 */
    377 void Vector::ProjectIt(const Vector *y)
     381void Vector::ProjectIt(const Vector * const y)
    378382{
    379383  Vector helper(*y);
     
    386390 * \return Vector
    387391 */
    388 Vector Vector::Projection(const Vector *y) const
     392Vector Vector::Projection(const Vector * const y) const
    389393{
    390394  Vector helper(*y);
     
    435439/** Zeros all components of this vector.
    436440 */
    437 void Vector::One(double one)
     441void Vector::One(const double one)
    438442{
    439443  for (int i=NDIM;i--;)
     
    443447/** Initialises all components of this vector.
    444448 */
    445 void Vector::Init(double x1, double x2, double x3)
     449void Vector::Init(const double x1, const double x2, const double x3)
    446450{
    447451  x[0] = x1;
     
    469473 * @return true - vector is normalized, false - vector is not
    470474 */
    471 bool Vector::IsNormalTo(const Vector *normal) const
     475bool Vector::IsNormalTo(const Vector * const normal) const
    472476{
    473477  if (ScalarProduct(normal) < MYEPSILON)
     
    481485 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
    482486 */
    483 double Vector::Angle(const Vector *y) const
     487double Vector::Angle(const Vector * const y) const
    484488{
    485489  double norm1 = Norm(), norm2 = y->Norm();
     
    500504 * \param alpha rotation angle in radian
    501505 */
    502 void Vector::RotateVector(const Vector *axis, const double alpha)
     506void Vector::RotateVector(const Vector * const axis, const double alpha)
    503507{
    504508  Vector a,y;
     
    656660 * \param *factor pointer to scaling factor
    657661 */
    658 void Vector::Scale(double **factor)
     662void Vector::Scale(const double ** const factor)
    659663{
    660664  for (int i=NDIM;i--;)
     
    662666};
    663667
    664 void Vector::Scale(double *factor)
     668void Vector::Scale(const double * const factor)
    665669{
    666670  for (int i=NDIM;i--;)
     
    668672};
    669673
    670 void Vector::Scale(double factor)
     674void Vector::Scale(const double factor)
    671675{
    672676  for (int i=NDIM;i--;)
     
    677681 * \param trans[] translation vector.
    678682 */
    679 void Vector::Translate(const Vector *trans)
     683void Vector::Translate(const Vector * const trans)
    680684{
    681685  for (int i=NDIM;i--;)
     
    687691 * \param *Minv inverse matrix
    688692 */
    689 void Vector::WrapPeriodically(const double *M, const double *Minv)
     693void Vector::WrapPeriodically(const double * const M, const double * const Minv)
    690694{
    691695  MatrixMultiplication(Minv);
     
    704708 * \param *matrix NDIM_NDIM array
    705709 */
    706 void Vector::MatrixMultiplication(const double *M)
     710void Vector::MatrixMultiplication(const double * const M)
    707711{
    708712  Vector C;
     
    716720};
    717721
    718 /** Calculate the inverse of a 3x3 matrix.
     722/** Do a matrix multiplication with the \a *A' inverse.
    719723 * \param *matrix NDIM_NDIM array
    720724 */
    721 double * Vector::InverseMatrix(double *A)
    722 {
    723   double *B = Malloc<double>(NDIM * NDIM, "Vector::InverseMatrix: *B");
     725void Vector::InverseMatrixMultiplication(const double * const A)
     726{
     727  Vector C;
     728  double B[NDIM*NDIM];
    724729  double detA = RDET3(A);
    725730  double detAReci;
    726731
    727   for (int i=0;i<NDIM*NDIM;++i)
    728     B[i] = 0.;
    729732  // calculate the inverse B
    730733  if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
     
    739742    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    740743    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    741   }
    742   return B;
    743 };
    744 
    745 /** Do a matrix multiplication with the \a *A' inverse.
    746  * \param *matrix NDIM_NDIM array
    747  */
    748 void Vector::InverseMatrixMultiplication(const double *A)
    749 {
    750   Vector C;
    751   double B[NDIM*NDIM];
    752   double detA = RDET3(A);
    753   double detAReci;
    754 
    755   // calculate the inverse B
    756   if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
    757     detAReci = 1./detA;
    758     B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);    // A_11
    759     B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);    // A_12
    760     B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);    // A_13
    761     B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);    // A_21
    762     B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);    // A_22
    763     B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);    // A_23
    764     B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);    // A_31
    765     B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    766     B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    767744
    768745    // do the matrix multiplication
     
    786763 * \param *factors three-component vector with the factor for each given vector
    787764 */
    788 void Vector::LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors)
     765void Vector::LinearCombinationOfVectors(const Vector * const x1, const Vector * const x2, const Vector * const x3, const double * const factors)
    789766{
    790767  for(int i=NDIM;i--;)
     
    795772 * \param n[] normal vector of mirror plane.
    796773 */
    797 void Vector::Mirror(const Vector *n)
     774void Vector::Mirror(const Vector * const n)
    798775{
    799776  double projection;
     
    817794 * \return true - success, vectors are linear independent, false - failure due to linear dependency
    818795 */
    819 bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2, const Vector *y3)
     796bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2, const Vector * const y3)
    820797{
    821798  Vector x1, x2;
     
    853830 * \return true - success, vectors are linear independent, false - failure due to linear dependency
    854831 */
    855 bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2)
     832bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2)
    856833{
    857834  Vector x1,x2;
     
    884861 * \return true - success, false - vector is zero
    885862 */
    886 bool Vector::MakeNormalVector(const Vector *y1)
     863bool Vector::MakeNormalVector(const Vector * const y1)
    887864{
    888865  bool result = false;
     
    904881 * \return true - success, false - failure (null vector given)
    905882 */
    906 bool Vector::GetOneNormalVector(const Vector *GivenVector)
     883bool Vector::GetOneNormalVector(const Vector * const GivenVector)
    907884{
    908885  int Components[NDIM]; // contains indices of non-zero components
     
    950927 * \return scaling parameter for this vector
    951928 */
    952 double Vector::CutsPlaneAt(Vector *A, Vector *B, Vector *C)
     929double Vector::CutsPlaneAt(const Vector * const A, const Vector * const B, const Vector * const C) const
    953930{
    954931//  cout << Verbose(3) << "For comparison: ";
     
    965942 * \return true if success, false if failed due to linear dependency
    966943 */
    967 bool Vector::LSQdistance(Vector **vectors, int num)
     944bool Vector::LSQdistance(const Vector **vectors, int num)
    968945{
    969946  int j;
     
    10471024 * \param *y vector
    10481025 */
    1049 void Vector::AddVector(const Vector *y)
     1026void Vector::AddVector(const Vector * const y)
    10501027{
    10511028  for (int i=NDIM;i--;)
     
    10561033 * \param *y vector
    10571034 */
    1058 void Vector::SubtractVector(const Vector *y)
     1035void Vector::SubtractVector(const Vector * const y)
    10591036{
    10601037  for (int i=NDIM;i--;)
     
    10651042 * \param *y vector
    10661043 */
    1067 void Vector::CopyVector(const Vector *y)
     1044void Vector::CopyVector(const Vector * const y)
    10681045{
    10691046  for (int i=NDIM;i--;)
     
    10741051 * \param y vector
    10751052 */
    1076 void Vector::CopyVector(const Vector y)
     1053void Vector::CopyVector(const Vector &y)
    10771054{
    10781055  for (int i=NDIM;i--;)
     
    10851062 * \param check whether bounds shall be checked (true) or not (false)
    10861063 */
    1087 void Vector::AskPosition(double *cell_size, bool check)
     1064void Vector::AskPosition(const double * const cell_size, const bool check)
    10881065{
    10891066  char coords[3] = {'x','y','z'};
     
    11131090 * \bug this is not yet working properly
    11141091 */
    1115 bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
     1092bool Vector::SolveSystem(Vector * x1, Vector * x2, Vector * y, const double alpha, const double beta, const double c)
    11161093{
    11171094  double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C;
     
    11391116      break;
    11401117    case 2:
    1141       flip(&x1->x[0],&x1->x[1]);
    1142       flip(&x2->x[0],&x2->x[1]);
    1143       flip(&y->x[0],&y->x[1]);
    1144       //flip(&x[0],&x[1]);
    1145       flip(&x1->x[1],&x1->x[2]);
    1146       flip(&x2->x[1],&x2->x[2]);
    1147       flip(&y->x[1],&y->x[2]);
    1148       //flip(&x[1],&x[2]);
     1118      flip(x1->x[0],x1->x[1]);
     1119      flip(x2->x[0],x2->x[1]);
     1120      flip(y->x[0],y->x[1]);
     1121      //flip(x[0],x[1]);
     1122      flip(x1->x[1],x1->x[2]);
     1123      flip(x2->x[1],x2->x[2]);
     1124      flip(y->x[1],y->x[2]);
     1125      //flip(x[1],x[2]);
    11491126    case 1:
    1150       flip(&x1->x[0],&x1->x[1]);
    1151       flip(&x2->x[0],&x2->x[1]);
    1152       flip(&y->x[0],&y->x[1]);
    1153       //flip(&x[0],&x[1]);
    1154       flip(&x1->x[1],&x1->x[2]);
    1155       flip(&x2->x[1],&x2->x[2]);
    1156       flip(&y->x[1],&y->x[2]);
    1157       //flip(&x[1],&x[2]);
     1127      flip(x1->x[0],x1->x[1]);
     1128      flip(x2->x[0],x2->x[1]);
     1129      flip(y->x[0],y->x[1]);
     1130      //flip(x[0],x[1]);
     1131      flip(x1->x[1],x1->x[2]);
     1132      flip(x2->x[1],x2->x[2]);
     1133      flip(y->x[1],y->x[2]);
     1134      //flip(x[1],x[2]);
    11581135      break;
    11591136  }
     
    12241201      break;
    12251202    case 2:
    1226       flip(&x1->x[0],&x1->x[1]);
    1227       flip(&x2->x[0],&x2->x[1]);
    1228       flip(&y->x[0],&y->x[1]);
    1229       flip(&x[0],&x[1]);
    1230       flip(&x1->x[1],&x1->x[2]);
    1231       flip(&x2->x[1],&x2->x[2]);
    1232       flip(&y->x[1],&y->x[2]);
    1233       flip(&x[1],&x[2]);
     1203      flip(x1->x[0],x1->x[1]);
     1204      flip(x2->x[0],x2->x[1]);
     1205      flip(y->x[0],y->x[1]);
     1206      flip(x[0],x[1]);
     1207      flip(x1->x[1],x1->x[2]);
     1208      flip(x2->x[1],x2->x[2]);
     1209      flip(y->x[1],y->x[2]);
     1210      flip(x[1],x[2]);
    12341211    case 1:
    1235       flip(&x1->x[0],&x1->x[1]);
    1236       flip(&x2->x[0],&x2->x[1]);
    1237       flip(&y->x[0],&y->x[1]);
    1238       //flip(&x[0],&x[1]);
    1239       flip(&x1->x[1],&x1->x[2]);
    1240       flip(&x2->x[1],&x2->x[2]);
    1241       flip(&y->x[1],&y->x[2]);
    1242       flip(&x[1],&x[2]);
     1212      flip(x1->x[0],x1->x[1]);
     1213      flip(x2->x[0],x2->x[1]);
     1214      flip(y->x[0],y->x[1]);
     1215      //flip(x[0],x[1]);
     1216      flip(x1->x[1],x1->x[2]);
     1217      flip(x2->x[1],x2->x[2]);
     1218      flip(y->x[1],y->x[2]);
     1219      flip(x[1],x[2]);
    12431220      break;
    12441221  }
     
    12761253 * @param three vectors forming the matrix that defines the shape of the parallelpiped
    12771254 */
    1278 bool Vector::IsInParallelepiped(Vector offset, double *parallelepiped)
     1255bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const
    12791256{
    12801257  Vector a;
  • src/vector.hpp

    r06c7a3 r7326b2  
    1111#endif
    1212
     13#include <iostream>
    1314#include <gsl/gsl_vector.h>
    1415#include <gsl/gsl_multimin.h>
     
    2627
    2728  Vector();
    28   Vector(double x1, double x2, double x3);
     29  Vector(const double x1, const double x2, const double x3);
    2930  ~Vector();
    3031
    31   double Distance(const Vector *y) const;
    32   double DistanceSquared(const Vector *y) const;
    33   double DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset);
    34   double PeriodicDistance(const Vector *y, const double *cell_size) const;
    35   double PeriodicDistanceSquared(const Vector *y, const double *cell_size) const;
    36   double ScalarProduct(const Vector *y) const;
     32  double Distance(const Vector * const y) const;
     33  double DistanceSquared(const Vector * const y) const;
     34  double DistanceToPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset) const;
     35  double PeriodicDistance(const Vector * const y, const double * const cell_size) const;
     36  double PeriodicDistanceSquared(const Vector * const y, const double * const cell_size) const;
     37  double ScalarProduct(const Vector * const y) const;
    3738  double Norm() const;
    3839  double NormSquared() const;
    39   double Angle(const Vector *y) const;
     40  double Angle(const Vector * const y) const;
    4041  bool IsZero() const;
    4142  bool IsOne() const;
    42   bool IsNormalTo(const Vector *normal) const;
     43  bool IsNormalTo(const Vector * const normal) const;
    4344
    44   void AddVector(const Vector *y);
    45   void SubtractVector(const Vector *y);
    46   void CopyVector(const Vector *y);
    47   void CopyVector(const Vector y);
    48   void RotateVector(const Vector *y, const double alpha);
    49   void VectorProduct(const Vector *y);
    50   void ProjectOntoPlane(const Vector *y);
    51   void ProjectIt(const Vector *y);
    52   Vector Projection(const Vector *y) const;
     45  void AddVector(const Vector * const y);
     46  void SubtractVector(const Vector * const y);
     47  void CopyVector(const Vector * const y);
     48  void CopyVector(const Vector &y);
     49  void RotateVector(const Vector * const y, const double alpha);
     50  void VectorProduct(const Vector * const y);
     51  void ProjectOntoPlane(const Vector * const y);
     52  void ProjectIt(const Vector * const y);
     53  Vector Projection(const Vector * const y) const;
    5354  void Zero();
    54   void One(double one);
    55   void Init(double x1, double x2, double x3);
     55  void One(const double one);
     56  void Init(const double x1, const double x2, const double x3);
    5657  void Normalize();
    57   void Translate(const Vector *x);
    58   void Mirror(const Vector *x);
    59   void Scale(double **factor);
    60   void Scale(double *factor);
    61   void Scale(double factor);
    62   void MatrixMultiplication(const double *M);
    63   double * InverseMatrix(double *A);
    64   void InverseMatrixMultiplication(const double *M);
    65   void KeepPeriodic(ofstream *out, double *matrix);
    66   void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    67   double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    68   bool GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *Origin, Vector *LineVector);
    69   bool GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b, const Vector *Normal = NULL);
    70   bool GetOneNormalVector(const Vector *x1);
    71   bool MakeNormalVector(const Vector *y1);
    72   bool MakeNormalVector(const Vector *y1, const Vector *y2);
    73   bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3);
    74   bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c);
    75   bool LSQdistance(Vector **vectors, int dim);
    76   void AskPosition(double *cell_size, bool check);
     58  void Translate(const Vector * const x);
     59  void Mirror(const Vector * const x);
     60  void Scale(const double ** const factor);
     61  void Scale(const double * const factor);
     62  void Scale(const double factor);
     63  void MatrixMultiplication(const double * const M);
     64  void InverseMatrixMultiplication(const double * const M);
     65  void KeepPeriodic(ofstream *out, const double * const matrix);
     66  void LinearCombinationOfVectors(const Vector * const x1, const Vector * const x2, const Vector * const x3, const double * const factors);
     67  double CutsPlaneAt(const Vector * const A, const Vector * const B, const Vector * const C) const;
     68  bool GetIntersectionWithPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector);
     69  bool GetIntersectionOfTwoLinesOnPlane(ofstream *out, const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *Normal = NULL);
     70  bool GetOneNormalVector(const Vector * const x1);
     71  bool MakeNormalVector(const Vector * const y1);
     72  bool MakeNormalVector(const Vector * const y1, const Vector * const y2);
     73  bool MakeNormalVector(const Vector * const x1, const Vector * const x2, const Vector * const x3);
     74  bool SolveSystem(Vector * x1, Vector * x2, Vector * y, const double alpha, const double beta, const double c);
     75  bool LSQdistance(const Vector ** vectors, int dim);
     76  void AskPosition(const double * const cell_size, const bool check);
    7777  bool Output(ofstream *out) const;
    78   bool IsInParallelepiped(Vector offset, double *parallelepiped);
    79   void WrapPeriodically(const double *M, const double *Minv);
     78  bool IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const;
     79  void WrapPeriodically(const double * const M, const double * const Minv);
    8080};
    8181
     
    9090Vector& operator-(const Vector& a, const Vector& b);
    9191
    92 // some algebraic matrix stuff
    93 #define RDET3(a) ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3])  //!< hard-coded determinant of a 3x3 matrix
    94 #define RDET2(a0,a1,a2,a3) ((a0)*(a3)-(a1)*(a2))                      //!< hard-coded determinant of a 2x2 matrix
    95 
    96 
    9792
    9893#endif /*VECTOR_HPP_*/
Note: See TracChangeset for help on using the changeset viewer.