Changes in / [ce5ac3:d067d45]


Ignore:
Location:
src
Files:
4 added
3 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.am

    rce5ac3 rd067d45  
    1 SOURCE = atom.cpp bond.cpp boundary.cpp builder.cpp config.cpp element.cpp helpers.cpp molecules.cpp moleculelist.cpp parser.cpp periodentafel.cpp vector.cpp verbose.cpp
    2 HEADER = boundary.hpp defs.hpp helpers.hpp molecules.hpp parser.hpp periodentafel.hpp stackclass.hpp vector.hpp
     1SOURCE = atom.cpp bond.cpp boundary.cpp builder.cpp config.cpp element.cpp ellipsoid.cpp helpers.cpp molecules.cpp linkedcell.cpp moleculelist.cpp parser.cpp periodentafel.cpp vector.cpp verbose.cpp
     2HEADER = boundary.hpp defs.hpp ellipsoid.hpp helpers.hpp linkedcell.hpp molecules.hpp parser.hpp periodentafel.hpp stackclass.hpp vector.hpp
    33
    44bin_PROGRAMS = molecuilder joiner analyzer
    55molecuilderdir = ${bindir}
    6 molecuilder_DATA = elements.db valence.db       orbitals.db Hbonddistance.db Hbondangle.db
     6molecuilder_DATA = elements.db valence.db orbitals.db Hbonddistance.db Hbondangle.db
    77molecuilder_SOURCES =  ${SOURCE} ${HEADER}
    88joiner_SOURCES = joiner.cpp datacreator.cpp element.cpp helpers.cpp periodentafel.cpp parser.cpp verbose.cpp datacreator.hpp helpers.hpp parser.hpp periodentafel.hpp
  • src/analyzer.cpp

    rce5ac3 rd067d45  
    33 * Takes evaluated fragments (energy and forces) and does evaluation of how sensible the BOSSANOVA
    44 * approach was, e.g. in the decay of the many-body-contributions.
    5  *   
     5 *
    66 */
    77
     
    99
    1010#include "datacreator.hpp"
    11 #include "helpers.hpp" 
     11#include "helpers.hpp"
    1212#include "parser.hpp"
    13 #include "periodentafel.hpp" 
     13#include "periodentafel.hpp"
    1414
    1515// include config.h
     
    5555  stringstream yrange;
    5656  char *dir = NULL;
    57   bool NoHCorrection = false;
    5857  bool NoHessian = false;
    5958  bool NoTime = false;
     59  bool NoHCorrection = true;
    6060  int counter;
    61  
     61
    6262  cout << "ANOVA Analyzer" << endl;
    6363  cout << "==============" << endl;
    64  
     64
    6565  // Get the command line options
    6666  if (argc < 4) {
     
    7676    strcat(dir, argv[2]);
    7777  }
    78  
     78
    7979  if (argc > 4) {
    8080    cout << "Loading periodentafel." << endl;
     
    8282    periode->LoadPeriodentafel(argv[4]);
    8383  }
    84  
     84
    8585  // Test the given directory
    8686  if (!TestParams(argc, argv))
     
    8888
    8989  // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
    90  
     90
    9191  // ------------- Parse through all Fragment subdirs --------
    9292  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
     
    113113
    114114  // ---------- Parse the TE Factors into an array -----------------
    115   if (!Energy.InitialiseIndices()) return 1;
    116   if (!NoHCorrection)
    117     Hcorrection.InitialiseIndices();
    118  
     115  if (!Energy.ParseIndices()) return 1;
     116  if (!NoHCorrection) Hcorrection.ParseIndices();
     117
    119118  // ---------- Parse the Force indices into an array ---------------
    120119  if (!Force.ParseIndices(argv[1])) return 1;
     
    148147  if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
    149148  if (!KeySet.ParseManyBodyTerms()) return 1;
    150  
     149
    151150  // ---------- Parse fragment files created by 'joiner' into an array -------------
    152151  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
     
    164163
    165164  // +++++++++++++++ TESTING ++++++++++++++++++++++++++++++
    166  
     165
    167166  // print energy and forces to file
    168167  filename.str("");
     
    245244
    246245  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
    247  
     246
    248247  cout << "Analyzing ..." << endl;
    249248
     
    330329  }
    331330
    332  
     331
    333332  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    334333  if (!CreateDataDeltaEnergyOrder(Energy, EnergyFragments, KeySet, argv[3], "DeltaEnergies-Order", "Plot of error between approximated and full energies energies versus the Bond Order", datum)) return 1;
    335  
     334
    336335  // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
    337336  if (!CreateDataEnergyOrder(EnergyFragments, KeySet, argv[3], "Energies-Order", "Plot of approximated energies versus the Bond Order", datum)) return 1;
    338  
     337
    339338  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
    340339  if (!CreateDataDeltaForcesOrderPerAtom(Force, ForceFragments, KeySet, argv[3], "DeltaForces-Order", "Plot of error between approximated forces and full forces versus the Bond Order", datum)) return 1;
     
    399398
    400399  // ======================================= Creating the plot files ==============================================================
    401  
     400
    402401  Orderxrange << "[1:" << KeySet.Order << "]";
    403402  Fragmentxrange << "[0:" << KeySet.FragmentCounter+1 << "]";
     
    411410  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    412411  if (!CreatePlotOrder(Energy, KeySet, argv[3], "DeltaEnergies-Order", 1, "outside", "y", "",  1, 1, "bond order k", "absolute error in energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
    413  
     412
    414413  // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
    415414  if (!CreatePlotOrder(Energy, KeySet, argv[3], "Energies-Order", 1, "outside", "", "",  1, 1, "bond order k", "approximate energy [Ht]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
     
    429428  if(!OpenOutputFile(output, argv[3], "DeltaMinMeanMaxTotalForce-Order.pyx")) return 1;
    430429  CreatePlotHeader(output, "DeltaMinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL,  1, 1, "bond order k", "absolute error in total forces [Ht/a.u.]");
    431   output << "plot " << Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl; 
     430  output << "plot " << Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
    432431  output << "'DeltaMinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
    433432  output << "'DeltaMeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
    434433  output << "'DeltaMaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
    435   output.close(); 
     434  output.close();
    436435
    437436  // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
     
    448447  if(!OpenOutputFile(output, argv[3],"MinMeanMaxTotalForce-Order.pyx")) return 1;
    449448  CreatePlotHeader(output, "MinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL, 1, 1, "bond order k", "absolute total force [Ht/a.u.]");
    450   output << "plot "<< Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl; 
     449  output << "plot "<< Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
    451450  output << "'MinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
    452451  output << "'MeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
    453452  output << "'MaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
    454   output.close(); 
     453  output.close();
    455454
    456455  // ++++++++++++++++++++++++++++++++++++++Plotting vector sum vs. Order
     
    471470  // min
    472471  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "minimum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    473    
     472
    474473  // mean
    475474  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "mean of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
    476    
     475
    477476  // max
    478477  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "maximum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
     
    481480  // min
    482481  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "minimum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    483    
     482
    484483  // mean
    485484  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "mean of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
    486    
     485
    487486  // max
    488487  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "maximum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    489  
     488
    490489  // +++++++++++++++++++++++++++++++=Ploting approximated and true shielding for each atom
    491490  if (periode != NULL) { // also look for PAS values
     
    553552  output << "\trm -rf $(EPS)" << endl;
    554553  output.close();
    555  
     554
    556555  // ++++++++++++++++ exit ++++++++++++++++++++++++++++++++++
    557556  delete(periode);
  • src/atom.cpp

    rce5ac3 rd067d45  
    11/** \file atom.cpp
    2  * 
     2 *
    33 * Function implementations for the class atom.
    4  * 
     4 *
    55 */
    66
    77#include "molecules.hpp"
    8  
     8
    99/************************************* Functions for class atom *************************************/
    1010
    1111/** Constructor of class atom.
    1212 */
    13 atom::atom() 
     13atom::atom()
    1414{
    1515  Name = NULL;
     
    3333/** Destructor of class atom.
    3434 */
    35 atom::~atom() 
     35atom::~atom()
    3636{
    3737  Free((void **)&Name, "atom::~atom: *Name");
     
    5858 * \param AtomNo cardinal number among these atoms of the same element
    5959 * \param *out stream to output to
     60 * \param *comment commentary after '#' sign
    6061 */
    61 bool atom::Output(int ElementNo, int AtomNo, ofstream *out) const
     62bool atom::Output(int ElementNo, int AtomNo, ofstream *out, const char *comment) const
    6263{
    6364  if (out != NULL) {
     
    6768    if (v.Norm() > MYEPSILON)
    6869      *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
    69     *out << " # Number in molecule " << nr << endl;
     70    if (comment != NULL)
     71      *out << " # " << comment << endl;
     72    else
     73      *out << " # molecule nr " << nr << endl;
    7074    return true;
    7175  } else
     
    9498 * \param ptr atom to compare index against
    9599 * \return true - this one's is smaller, false - not
    96  */ 
     100 */
    97101bool atom::Compare(atom &ptr)
    98102{
     
    103107};
    104108
    105 bool operator < (atom &a, atom &b) 
     109bool operator < (atom &a, atom &b)
    106110{
    107111  return a.Compare(b);
  • src/boundary.cpp

    rce5ac3 rd067d45  
    1 #include "molecules.hpp"
    21#include "boundary.hpp"
    32
    43#define DEBUG 1
    5 #define DoTecplotOutput 0
     4#define DoSingleStepOutput 0
     5#define DoTecplotOutput 1
    66#define DoRaster3DOutput 1
     7#define DoVRMLOutput 1
    78#define TecplotSuffix ".dat"
    89#define Raster3DSuffix ".r3d"
     10#define VRMLSUffix ".wrl"
     11#define HULLEPSILON MYEPSILON
    912
    1013// ======================================== Points on Boundary =================================
     
    2831{
    2932  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
     33  if (!lines.empty())
     34    cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some lines." << endl;
    3035  node = NULL;
    3136  lines.clear();
     
    3338;
    3439
    35 void
    36 BoundaryPointSet::AddLine(class BoundaryLineSet *line)
     40void BoundaryPointSet::AddLine(class BoundaryLineSet *line)
    3741{
    3842  cout << Verbose(6) << "Adding " << *this << " to line " << *line << "."
     
    101105      cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;
    102106  }
     107  if (!triangles.empty())
     108    cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some triangles." << endl;
    103109}
    104110;
     
    109115  cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "."
    110116      << endl;
    111   triangles.insert(TrianglePair(TrianglesCount, triangle));
     117  triangles.insert(TrianglePair(triangle->Nr, triangle));
    112118  TrianglesCount++;
    113119}
     
    205211
    206212  // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
    207   if (endpoints[0]->node->x.Projection(&OtherVector) > 0)
     213  if (NormalVector.Projection(&OtherVector) > 0)
    208214    NormalVector.Scale(-1.);
    209215}
     
    565571;
    566572
    567 /** Creates the objects in a raster3d file (renderable with a header.r3d)
     573/** Creates the objects in a VRML file.
    568574 * \param *out output stream for debugging
    569  * \param *tecplot output stream for tecplot data
     575 * \param *vrmlfile output stream for tecplot data
     576 * \param *Tess Tesselation structure with constructed triangles
     577 * \param *mol molecule structure with atom positions
     578 */
     579void write_vrml_file(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, class molecule *mol)
     580{
     581  atom *Walker = mol->start;
     582  bond *Binder = mol->first;
     583  int i;
     584  Vector *center = mol->DetermineCenterOfAll(out);
     585  if (vrmlfile != NULL) {
     586    //cout << Verbose(1) << "Writing Raster3D file ... ";
     587    *vrmlfile << "#VRML V2.0 utf8" << endl;
     588    *vrmlfile << "#Created by molecuilder" << endl;
     589    *vrmlfile << "#All atoms as spheres" << endl;
     590    while (Walker->next != mol->end) {
     591      Walker = Walker->next;
     592      *vrmlfile << "Sphere {" << endl << "  "; // 2 is sphere type
     593      for (i=0;i<NDIM;i++)
     594        *vrmlfile << Walker->x.x[i]+center->x[i] << " ";
     595      *vrmlfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour
     596    }
     597
     598    *vrmlfile << "# All bonds as vertices" << endl;
     599    while (Binder->next != mol->last) {
     600      Binder = Binder->next;
     601      *vrmlfile << "3" << endl << "  "; // 2 is round-ended cylinder type
     602      for (i=0;i<NDIM;i++)
     603        *vrmlfile << Binder->leftatom->x.x[i]+center->x[i] << " ";
     604      *vrmlfile << "\t0.03\t";
     605      for (i=0;i<NDIM;i++)
     606        *vrmlfile << Binder->rightatom->x.x[i]+center->x[i] << " ";
     607      *vrmlfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour
     608    }
     609
     610    *vrmlfile << "# All tesselation triangles" << endl;
     611    for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
     612      *vrmlfile << "1" << endl << "  "; // 1 is triangle type
     613      for (i=0;i<3;i++) { // print each node
     614        for (int j=0;j<NDIM;j++)  // and for each node all NDIM coordinates
     615          *vrmlfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";
     616        *vrmlfile << "\t";
     617      }
     618      *vrmlfile << "1. 0. 0." << endl;  // red as colour
     619      *vrmlfile << "18" << endl << "  0.5 0.5 0.5" << endl; // 18 is transparency type for previous object
     620    }
     621  } else {
     622    cerr << "ERROR: Given vrmlfile is " << vrmlfile << "." << endl;
     623  }
     624  delete(center);
     625};
     626
     627/** Creates the objects in a raster3d file (renderable with a header.r3d).
     628 * \param *out output stream for debugging
     629 * \param *rasterfile output stream for tecplot data
    570630 * \param *Tess Tesselation structure with constructed triangles
    571631 * \param *mol molecule structure with atom positions
     
    603663
    604664    *rasterfile << "# All tesselation triangles" << endl;
     665    *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";
    605666    for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
    606667      *rasterfile << "1" << endl << "  ";  // 1 is triangle type
     
    613674      *rasterfile << "18" << endl << "  0.5 0.5 0.5" << endl;  // 18 is transparency type for previous object
    614675    }
     676    *rasterfile << "9\n  terminating special property\n";
    615677  } else {
    616678    cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;
     
    673735 * Determines first the convex envelope, then tesselates it and calculates its volume.
    674736 * \param *out output stream for debugging
    675  * \param *tecplot output stream for tecplot data
     737 * \param *filename filename prefix for output of vertex data
    676738 * \param *configuration needed for path to store convex envelope file
    677739 * \param *BoundaryPoints NDIM set of boundary points on the projected plane per axis, on return if desired
     
    680742 */
    681743double
    682 VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration,
     744VolumeOfConvexEnvelope(ofstream *out, const char *filename, config *configuration,
    683745    Boundaries *BoundaryPtr, molecule *mol)
    684746{
     
    761823      y.CopyVector(&runner->second->endpoints[0]->node->x);
    762824      y.SubtractVector(&runner->second->endpoints[2]->node->x);
    763       a = sqrt(runner->second->endpoints[0]->node->x.Distance(
     825      a = sqrt(runner->second->endpoints[0]->node->x.DistanceSquared(
    764826          &runner->second->endpoints[1]->node->x));
    765       b = sqrt(runner->second->endpoints[0]->node->x.Distance(
     827      b = sqrt(runner->second->endpoints[0]->node->x.DistanceSquared(
    766828          &runner->second->endpoints[2]->node->x));
    767       c = sqrt(runner->second->endpoints[2]->node->x.Distance(
     829      c = sqrt(runner->second->endpoints[2]->node->x.DistanceSquared(
    768830          &runner->second->endpoints[1]->node->x));
    769       G = sqrt(((a * a + b * b + c * c) * (a * a + b * b + c * c) - 2 * (a * a
    770           * a * a + b * b * b * b + c * c * c * c)) / 16.); // area of tesselated triangle
     831      G = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle
    771832      x.MakeNormalVector(&runner->second->endpoints[0]->node->x,
    772833          &runner->second->endpoints[1]->node->x,
     
    797858
    798859  // 8. Store triangles in tecplot file
     860  string OutputName(filename);
     861  OutputName.append(TecplotSuffix);
     862  ofstream *tecplot = new ofstream(OutputName.c_str());
    799863  write_tecplot_file(out, tecplot, TesselStruct, mol, 0);
     864  tecplot->close();
     865  delete(tecplot);
    800866
    801867  // free reference lists
     
    9981064          for (; C != PointsOnBoundary.end(); C++)
    9991065            {
    1000               tmp = A->second->node->x.Distance(&B->second->node->x);
     1066              tmp = A->second->node->x.DistanceSquared(&B->second->node->x);
    10011067              distance = tmp * tmp;
    1002               tmp = A->second->node->x.Distance(&C->second->node->x);
     1068              tmp = A->second->node->x.DistanceSquared(&C->second->node->x);
    10031069              distance += tmp * tmp;
    1004               tmp = B->second->node->x.Distance(&C->second->node->x);
     1070              tmp = B->second->node->x.DistanceSquared(&C->second->node->x);
    10051071              distance += tmp * tmp;
    10061072              DistanceMMap.insert(DistanceMultiMapPair(distance, pair<
     
    10701136            }
    10711137          // 4d. Check whether the point is inside the triangle (check distance to each node
    1072           tmp = checker->second->node->x.Distance(&A->second->node->x);
     1138          tmp = checker->second->node->x.DistanceSquared(&A->second->node->x);
    10731139          int innerpoint = 0;
    1074           if ((tmp < A->second->node->x.Distance(
     1140          if ((tmp < A->second->node->x.DistanceSquared(
    10751141              &baseline->second.first->second->node->x)) && (tmp
    1076               < A->second->node->x.Distance(
     1142              < A->second->node->x.DistanceSquared(
    10771143                  &baseline->second.second->second->node->x)))
    10781144            innerpoint++;
    1079           tmp = checker->second->node->x.Distance(
     1145          tmp = checker->second->node->x.DistanceSquared(
    10801146              &baseline->second.first->second->node->x);
    1081           if ((tmp < baseline->second.first->second->node->x.Distance(
     1147          if ((tmp < baseline->second.first->second->node->x.DistanceSquared(
    10821148              &A->second->node->x)) && (tmp
    1083               < baseline->second.first->second->node->x.Distance(
     1149              < baseline->second.first->second->node->x.DistanceSquared(
    10841150                  &baseline->second.second->second->node->x)))
    10851151            innerpoint++;
    1086           tmp = checker->second->node->x.Distance(
     1152          tmp = checker->second->node->x.DistanceSquared(
    10871153              &baseline->second.second->second->node->x);
    1088           if ((tmp < baseline->second.second->second->node->x.Distance(
     1154          if ((tmp < baseline->second.second->second->node->x.DistanceSquared(
    10891155              &baseline->second.first->second->node->x)) && (tmp
    1090               < baseline->second.second->second->node->x.Distance(
     1156              < baseline->second.second->second->node->x.DistanceSquared(
    10911157                  &A->second->node->x)))
    10921158            innerpoint++;
     
    14831549;
    14841550
     1551
     1552double det_get(gsl_matrix *A, int inPlace) {
     1553  /*
     1554  inPlace = 1 => A is replaced with the LU decomposed copy.
     1555  inPlace = 0 => A is retained, and a copy is used for LU.
     1556  */
     1557
     1558  double det;
     1559  int signum;
     1560  gsl_permutation *p = gsl_permutation_alloc(A->size1);
     1561  gsl_matrix *tmpA;
     1562
     1563  if (inPlace)
     1564  tmpA = A;
     1565  else {
     1566  gsl_matrix *tmpA = gsl_matrix_alloc(A->size1, A->size2);
     1567  gsl_matrix_memcpy(tmpA , A);
     1568  }
     1569
     1570
     1571  gsl_linalg_LU_decomp(tmpA , p , &signum);
     1572  det = gsl_linalg_LU_det(tmpA , signum);
     1573  gsl_permutation_free(p);
     1574  if (! inPlace)
     1575  gsl_matrix_free(tmpA);
     1576
     1577  return det;
     1578};
     1579
     1580void get_sphere(Vector *center, Vector &a, Vector &b, Vector &c, double RADIUS)
     1581{
     1582  gsl_matrix *A = gsl_matrix_calloc(3,3);
     1583  double m11, m12, m13, m14;
     1584
     1585  for(int i=0;i<3;i++) {
     1586    gsl_matrix_set(A, i, 0, a.x[i]);
     1587    gsl_matrix_set(A, i, 1, b.x[i]);
     1588    gsl_matrix_set(A, i, 2, c.x[i]);
     1589  }
     1590  m11 = det_get(A, 1);
     1591
     1592  for(int i=0;i<3;i++) {
     1593    gsl_matrix_set(A, i, 0, a.x[i]*a.x[i] + b.x[i]*b.x[i] + c.x[i]*c.x[i]);
     1594    gsl_matrix_set(A, i, 1, b.x[i]);
     1595    gsl_matrix_set(A, i, 2, c.x[i]);
     1596  }
     1597  m12 = det_get(A, 1);
     1598
     1599  for(int i=0;i<3;i++) {
     1600    gsl_matrix_set(A, i, 0, a.x[i]*a.x[i] + b.x[i]*b.x[i] + c.x[i]*c.x[i]);
     1601    gsl_matrix_set(A, i, 1, a.x[i]);
     1602    gsl_matrix_set(A, i, 2, c.x[i]);
     1603  }
     1604  m13 = det_get(A, 1);
     1605
     1606  for(int i=0;i<3;i++) {
     1607    gsl_matrix_set(A, i, 0, a.x[i]*a.x[i] + b.x[i]*b.x[i] + c.x[i]*c.x[i]);
     1608    gsl_matrix_set(A, i, 1, a.x[i]);
     1609    gsl_matrix_set(A, i, 2, b.x[i]);
     1610  }
     1611  m14 = det_get(A, 1);
     1612
     1613  if (fabs(m11) < MYEPSILON)
     1614    cerr << "ERROR: three points are colinear." << endl;
     1615
     1616  center->x[0] =  0.5 * m12/ m11;
     1617  center->x[1] = -0.5 * m13/ m11;
     1618  center->x[2] =  0.5 * m14/ m11;
     1619
     1620  if (fabs(a.Distance(center) - RADIUS) > MYEPSILON)
     1621    cerr << "ERROR: The given center is further way by " << fabs(a.Distance(center) - RADIUS) << " from a than RADIUS." << endl;
     1622
     1623  gsl_matrix_free(A);
     1624};
     1625
     1626
     1627
    14851628/**
    14861629 * Function returns center of sphere with RADIUS, which rests on points a, b, c
     
    14891632 * @param b vector second point of triangle
    14901633 * @param c vector third point of triangle
    1491  * @param *Umkreismittelpunkt new cneter point of circumference
    14921634 * @param Direction vector indicates up/down
    14931635 * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle
     
    15001642 * @param Umkreisradius double radius of circumscribing circle
    15011643 */
    1502 
    1503   void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,
    1504       double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius)
    1505   {
    1506     Vector TempNormal, helper;
    1507     double Restradius;
    1508     cout << Verbose(3) << "Begin of Get_center_of_sphere.\n";
    1509     Center->Zero();
    1510     helper.CopyVector(&a);
    1511     helper.Scale(sin(2.*alpha));
    1512     Center->AddVector(&helper);
    1513     helper.CopyVector(&b);
    1514     helper.Scale(sin(2.*beta));
    1515     Center->AddVector(&helper);
    1516     helper.CopyVector(&c);
    1517     helper.Scale(sin(2.*gamma));
    1518     Center->AddVector(&helper);
    1519     //*Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
    1520     Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
    1521     NewUmkreismittelpunkt->CopyVector(Center);
    1522     cout << Verbose(4) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n";
    1523     // Here we calculated center of circumscribing circle, using barycentric coordinates
    1524     cout << Verbose(4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n";
    1525 
    1526     TempNormal.CopyVector(&a);
    1527     TempNormal.SubtractVector(&b);
    1528     helper.CopyVector(&a);
    1529     helper.SubtractVector(&c);
    1530     TempNormal.VectorProduct(&helper);
    1531     if (fabs(HalfplaneIndicator) < MYEPSILON)
    1532       {
    1533         if ((TempNormal.ScalarProduct(AlternativeDirection) <0 and AlternativeIndicator >0) or (TempNormal.ScalarProduct(AlternativeDirection) >0 and AlternativeIndicator <0))
    1534           {
    1535             TempNormal.Scale(-1);
    1536           }
    1537       }
    1538     else
    1539       {
    1540         if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0)
    1541           {
    1542             TempNormal.Scale(-1);
    1543           }
    1544       }
    1545 
    1546     TempNormal.Normalize();
    1547     Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1548     cout << Verbose(4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n";
    1549     TempNormal.Scale(Restradius);
    1550     cout << Verbose(4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n";
    1551 
    1552     Center->AddVector(&TempNormal);
    1553     cout << Verbose(4) << "Center of sphere of circumference is " << *Center << ".\n";
    1554     cout << Verbose(3) << "End of Get_center_of_sphere.\n";
    1555   }
    1556   ;
    1557 
     1644void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,
     1645    double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius)
     1646{
     1647  Vector TempNormal, helper;
     1648  double Restradius;
     1649  Vector OtherCenter;
     1650  cout << Verbose(3) << "Begin of Get_center_of_sphere.\n";
     1651  Center->Zero();
     1652  helper.CopyVector(&a);
     1653  helper.Scale(sin(2.*alpha));
     1654  Center->AddVector(&helper);
     1655  helper.CopyVector(&b);
     1656  helper.Scale(sin(2.*beta));
     1657  Center->AddVector(&helper);
     1658  helper.CopyVector(&c);
     1659  helper.Scale(sin(2.*gamma));
     1660  Center->AddVector(&helper);
     1661  //*Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
     1662  Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
     1663  NewUmkreismittelpunkt->CopyVector(Center);
     1664  cout << Verbose(4) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n";
     1665  // Here we calculated center of circumscribing circle, using barycentric coordinates
     1666  cout << Verbose(4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n";
     1667
     1668  TempNormal.CopyVector(&a);
     1669  TempNormal.SubtractVector(&b);
     1670  helper.CopyVector(&a);
     1671  helper.SubtractVector(&c);
     1672  TempNormal.VectorProduct(&helper);
     1673  if (fabs(HalfplaneIndicator) < MYEPSILON)
     1674    {
     1675      if ((TempNormal.ScalarProduct(AlternativeDirection) <0 and AlternativeIndicator >0) or (TempNormal.ScalarProduct(AlternativeDirection) >0 and AlternativeIndicator <0))
     1676        {
     1677          TempNormal.Scale(-1);
     1678        }
     1679    }
     1680  else
     1681    {
     1682      if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0)
     1683        {
     1684          TempNormal.Scale(-1);
     1685        }
     1686    }
     1687  TempNormal.Normalize();
     1688  Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
     1689  cout << Verbose(4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n";
     1690  TempNormal.Scale(Restradius);
     1691  cout << Verbose(4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n";
     1692
     1693  Center->AddVector(&TempNormal);
     1694  cout << Verbose(0) << "Center of sphere of circumference is " << *Center << ".\n";
     1695  get_sphere(&OtherCenter, a, b, c, RADIUS);
     1696  cout << Verbose(0) << "OtherCenter of sphere of circumference is " << OtherCenter << ".\n";
     1697  cout << Verbose(3) << "End of Get_center_of_sphere.\n";
     1698};
    15581699
    15591700/** This recursive function finds a third point, to form a triangle with two given ones.
     
    15801721 * @param mol molecule structure with atoms and bonds
    15811722 */
    1582 
    15831723void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,
    15841724    int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint,
     
    16331773    }
    16341774
    1635     if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
     1775    if ((M_PI*179./180. > alpha) && (M_PI*179./180. > beta) && (M_PI*179./180. > gamma)) {
    16361776      Umkreisradius = SideA / 2.0 / sin(alpha);
    16371777      //cout << Umkreisradius << endl;
     
    16551795          cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
    16561796        }
    1657 
    1658         Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
    1659 
    1660         AngleCheck.CopyVector(&ReferencePoint);
    1661         AngleCheck.Scale(-1);
    1662         //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1663         AngleCheck.AddVector(&Mittelpunkt);
    1664         //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1665         cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
    1666 
    1667         BallAngle = AngleCheck.Angle(OldNormal);
    1668         cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
    1669 
    1670         //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
    1671         //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1797        if (sign >= 0) {
     1798          cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
     1799          Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
     1800          Mittelpunkt.SubtractVector(&ReferencePoint);
     1801          cout << Verbose(3) << "Reference vector to sphere's center is " << Mittelpunkt << "." << endl;
     1802          BallAngle = Mittelpunkt.Angle(OldNormal);
     1803          cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
     1804
    16721805
    16731806        cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
    16741807
    1675         NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
    1676 
    1677         if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
    1678           if (Storage[0]< -1.5) { // first Candidate at all
    1679             if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1680               cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
    1681               Opt_Candidate = Candidate;
    1682               Storage[0] = sign;
    1683               Storage[1] = AlternativeSign;
    1684               Storage[2] = BallAngle;
    1685               cout << " angle " << Storage[2] << " and Up/Down "
    1686               << Storage[0] << endl;
    1687             } else
    1688               cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    1689           } else {
    1690             if ( Storage[2] > BallAngle) {
    1691               if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1692                 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
     1808          if ((Mittelpunkt.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
     1809            if (Storage[0]< -1.5) { // first Candidate at all
     1810              if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1811                cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
    16931812                Opt_Candidate = Candidate;
    16941813                Storage[0] = sign;
    16951814                Storage[1] = AlternativeSign;
    16961815                Storage[2] = BallAngle;
    1697                 cout << " angle " << Storage[2] << " and Up/Down "
    1698                 << Storage[0] << endl;
     1816                cout << " angle " << Storage[2] << " and Up/Down " << Storage[0] << endl;
    16991817              } else
    17001818                cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    17011819            } else {
    1702               if (DEBUG) {
    1703                 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
     1820              if ( Storage[2] > BallAngle) {
     1821                if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1822                  cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
     1823                  Opt_Candidate = Candidate;
     1824                  Storage[0] = sign;
     1825                  Storage[1] = AlternativeSign;
     1826                  Storage[2] = BallAngle;
     1827                  cout << " angle " << Storage[2] << " and Up/Down " << Storage[0] << endl;
     1828                } else
     1829                  cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1830              } else {
     1831                if (DEBUG) {
     1832                  cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
     1833                }
    17041834              }
     1835            }
     1836          } else {
     1837            if (DEBUG) {
     1838              cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
    17051839            }
    17061840          }
    17071841        } else {
    17081842          if (DEBUG) {
    1709             cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
     1843            cout << Verbose(3) << *Candidate << " is not in search direction." << endl;
    17101844          }
    17111845        }
     
    17411875
    17421876
    1743   /** This recursive function finds a third point, to form a triangle with two given ones.
    1744    * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
    1745    *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
    1746    *  upon which we operate.
    1747    *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \
    1748    *  direction and angle into Storage.
    1749    *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
    1750    *  with all neighbours of the candidate.
    1751    * @param a first point
    1752    * @param b second point
    1753    * @param Candidate base point along whose bonds to start looking from
    1754    * @param Parent point to avoid during search as its wrong direction
    1755    * @param RecursionLevel contains current recursion depth
    1756    * @param Chord baseline vector of first and second point
    1757    * @param d1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to
    1758    * @param OldNormal normal of the triangle which the baseline belongs to
    1759    * @param Opt_Candidate candidate reference to return
    1760    * @param Opt_Mittelpunkt Centerpoint of ball, when resting on Opt_Candidate
    1761    * @param Storage array containing two angles of current Opt_Candidate
    1762    * @param RADIUS radius of ball
    1763    * @param mol molecule structure with atoms and bonds
    1764    */
    1765 void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, atom* Parent,
    1766     int RecursionLevel, Vector *Chord, Vector *d1, Vector *OldNormal,
    1767     atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol)
    1768 {
    1769   /* OldNormal is normal vector on the old triangle
    1770    * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1771    * Chord points from b to a!!!
    1772    */
    1773   Vector dif_a; //Vector from a to candidate
    1774   Vector dif_b; //Vector from b to candidate
    1775   Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
    1776   Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
    1777 
    1778   double CurrentEpsilon = 0.1;
    1779   double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;
    1780   double BallAngle;
    1781   atom *Walker; // variable atom point
    1782 
    1783 
    1784   dif_a.CopyVector(&(a->x));
    1785   dif_a.SubtractVector(&(Candidate->x));
    1786   dif_b.CopyVector(&(b->x));
    1787   dif_b.SubtractVector(&(Candidate->x));
    1788   DirectionCheckPoint.CopyVector(&dif_a);
    1789   DirectionCheckPoint.Scale(-1);
    1790   DirectionCheckPoint.ProjectOntoPlane(Chord);
    1791 
    1792   SideA = dif_b.Norm();
    1793   SideB = dif_a.Norm();
    1794   SideC = Chord->Norm();
    1795   //Chord->Scale(-1);
    1796 
    1797   alpha = Chord->Angle(&dif_a);
    1798   beta = M_PI - Chord->Angle(&dif_b);
    1799   gamma = dif_a.Angle(&dif_b);
    1800 
    1801 
    1802   if (DEBUG) {
    1803     cout << "Atom number" << Candidate->nr << endl;
    1804     Candidate->x.Output((ofstream *) &cout);
    1805     cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
    1806   }
    1807 
    1808   if (a != Candidate and b != Candidate) {
    1809     //      alpha = dif_a.Angle(&dif_b) / 2.;
    1810     //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
    1811     //      SideB = dif_a.Norm();
    1812     //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
    1813     //          alpha); // note this is squared of center line length
    1814     //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
    1815     // Those are remains from Freddie. Needed?
    1816 
    1817     Umkreisradius = SideA / 2.0 / sin(alpha);
    1818     //cout << Umkreisradius << endl;
    1819     //cout << SideB / 2.0 / sin(beta) << endl;
    1820     //cout << SideC / 2.0 / sin(gamma) << endl;
    1821 
    1822     if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
    1823       // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
    1824       Umkreismittelpunkt.Zero();
    1825       helper.CopyVector(&a->x);
    1826       helper.Scale(sin(2.*alpha));
    1827       Umkreismittelpunkt.AddVector(&helper);
    1828       helper.CopyVector(&b->x);
    1829       helper.Scale(sin(2.*beta));
    1830       Umkreismittelpunkt.AddVector(&helper);
    1831       helper.CopyVector(&Candidate->x);
    1832       helper.Scale(sin(2.*gamma));
    1833       Umkreismittelpunkt.AddVector(&helper);
    1834       //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
    1835       Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    1836 
    1837       TempNormal.CopyVector(&dif_a);
    1838       TempNormal.VectorProduct(&dif_b);
    1839       if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
    1840         TempNormal.Scale(-1);
     1877/** Constructs the center of the circumcircle defined by three points \a *a, \a *b and \a *c.
     1878 * \param *Center new center on return
     1879 * \param *a first point
     1880 * \param *b second point
     1881 * \param *c third point
     1882 */
     1883void GetCenterofCircumcircle(Vector *Center, Vector *a, Vector *b, Vector *c)
     1884{
     1885  Vector helper;
     1886  double alpha, beta, gamma;
     1887  Vector SideA, SideB, SideC;
     1888  SideA.CopyVector(b);
     1889  SideA.SubtractVector(c);
     1890  SideB.CopyVector(c);
     1891  SideB.SubtractVector(a);
     1892  SideC.CopyVector(a);
     1893  SideC.SubtractVector(b);
     1894  alpha = M_PI - SideB.Angle(&SideC);
     1895  beta = M_PI - SideC.Angle(&SideA);
     1896  gamma = M_PI - SideA.Angle(&SideB);
     1897  cout << Verbose(3) << "INFO: alpha = " << alpha/M_PI*180. << ", beta = " << beta/M_PI*180. << ", gamma = " << gamma/M_PI*180. << "." << endl;
     1898  if (fabs(M_PI - alpha - beta - gamma) > HULLEPSILON)
     1899    cerr << "Sum of angles " << (alpha+beta+gamma)/M_PI*180. << " > 180 degrees by " << fabs(M_PI - alpha - beta - gamma)/M_PI*180. << "!" << endl;
     1900
     1901  Center->Zero();
     1902  helper.CopyVector(a);
     1903  helper.Scale(sin(2.*alpha));
     1904  Center->AddVector(&helper);
     1905  helper.CopyVector(b);
     1906  helper.Scale(sin(2.*beta));
     1907  Center->AddVector(&helper);
     1908  helper.CopyVector(c);
     1909  helper.Scale(sin(2.*gamma));
     1910  Center->AddVector(&helper);
     1911  Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
     1912};
     1913
     1914/** Returns the parameter "path length" for a given \a NewSphereCenter relative to \a OldSphereCenter on a circle on the plane \a CirclePlaneNormal with center \a CircleCenter and radius \a CircleRadius.
     1915 * Test whether the \a NewSphereCenter is really on the given plane and in distance \a CircleRadius from \a CircleCenter.
     1916 * It calculates the angle, making it unique on [0,2.*M_PI) by comparing to SearchDirection.
     1917 * Also the new center is invalid if it the same as the old one and does not lie right above (\a NormalVector) the base line (\a CircleCenter).
     1918 * \param CircleCenter Center of the parameter circle
     1919 * \param CirclePlaneNormal normal vector to plane of the parameter circle
     1920 * \param CircleRadius radius of the parameter circle
     1921 * \param NewSphereCenter new center of a circumcircle
     1922 * \param OldSphereCenter old center of a circumcircle, defining the zero "path length" on the parameter circle
     1923 * \param NormalVector normal vector
     1924 * \param SearchDirection search direction to make angle unique on return.
     1925 * \return Angle between \a NewSphereCenter and \a OldSphereCenter relative to \a CircleCenter, 2.*M_PI if one test fails
     1926 */
     1927double GetPathLengthonCircumCircle(Vector &CircleCenter, Vector &CirclePlaneNormal, double CircleRadius, Vector &NewSphereCenter, Vector &OldSphereCenter, Vector &NormalVector, Vector &SearchDirection)
     1928{
     1929  Vector helper;
     1930  double radius, alpha;
     1931
     1932  helper.CopyVector(&NewSphereCenter);
     1933  // test whether new center is on the parameter circle's plane
     1934  if (fabs(helper.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {
     1935    cerr << "ERROR: Something's very wrong here: NewSphereCenter is not on the band's plane as desired by " <<fabs(helper.ScalarProduct(&CirclePlaneNormal))  << "!" << endl;
     1936    helper.ProjectOntoPlane(&CirclePlaneNormal);
     1937  }
     1938  radius = helper.ScalarProduct(&helper);
     1939  // test whether the new center vector has length of CircleRadius
     1940  if (fabs(radius - CircleRadius) > HULLEPSILON)
     1941    cerr << Verbose(1) << "ERROR: The projected center of the new sphere has radius " << radius << " instead of " << CircleRadius << "." << endl;
     1942  alpha = helper.Angle(&OldSphereCenter);
     1943  // make the angle unique by checking the halfplanes/search direction
     1944  if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)  // acos is not unique on [0, 2.*M_PI), hence extra check to decide between two half intervals
     1945    alpha = 2.*M_PI - alpha;
     1946  cout << Verbose(2) << "INFO: RelativeNewSphereCenter is " << helper << ", RelativeOldSphereCenter is " << OldSphereCenter << " and resulting angle is " << alpha << "." << endl;
     1947  radius = helper.Distance(&OldSphereCenter);
     1948  helper.ProjectOntoPlane(&NormalVector);
     1949  // check whether new center is somewhat away or at least right over the current baseline to prevent intersecting triangles
     1950  if ((radius > HULLEPSILON) || (helper.Norm() < HULLEPSILON)) {
     1951    cout << Verbose(2) << "INFO: Distance between old and new center is " << radius << " and between new center and baseline center is " << helper.Norm() << "." << endl;
     1952    return alpha;
     1953  } else {
     1954    cout << Verbose(1) << "ERROR: NewSphereCenter " << helper << " is too close to OldSphereCenter" << OldSphereCenter << "." << endl;
     1955    return 2.*M_PI;
     1956  }
     1957};
     1958
     1959
     1960/** This recursive function finds a third point, to form a triangle with two given ones.
     1961 * The idea is as follows: A sphere with fixed radius is (almost) uniquely defined in space by three points
     1962 * that sit on its boundary. Hence, when two points are given and we look for the (next) third point, then
     1963 * the center of the sphere is still fixed up to a single parameter. The band of possible values
     1964 * describes a circle in 3D-space. The old center of the sphere for the current base triangle gives
     1965 * us the "null" on this circle, the new center of the candidate point will be some way along this
     1966 * circle. The shorter the way the better is the candidate. Note that the direction is clearly given
     1967 * by the normal vector of the base triangle that always points outwards by construction.
     1968 * Hence, we construct a Center of this circle which sits right in the middle of the current base line.
     1969 * We construct the normal vector that defines the plane this circle lies in, it is just in the
     1970 * direction of the baseline. And finally, we need the radius of the circle, which is given by the rest
     1971 * with respect to the length of the baseline and the sphere's fixed \a RADIUS.
     1972 * Note that there is one difficulty: The circumcircle is uniquely defined, but for the circumsphere's center
     1973 * there are two possibilities which becomes clear from the construction as seen below. Hence, we must check
     1974 * both.
     1975 * Note also that the acos() function is not unique on [0, 2.*M_PI). Hence, we need an additional check
     1976 * to decide for one of the two possible angles. Therefore we need a SearchDirection and to make this check
     1977 * sensible we need OldSphereCenter to be orthogonal to it. Either we construct SearchDirection orthogonal
     1978 * right away, or -- what we do here -- we rotate the relative sphere centers such that this orthogonality
     1979 * holds. Then, the normalized projection onto the SearchDirection is either +1 or -1 and thus states whether
     1980 * the angle is uniquely in either (0,M_PI] or [M_PI, 2.*M_PI).
     1981 * @param BaseTriangle BoundaryTriangleSet of the current base triangle with all three points
     1982 * @param BaseLine BoundaryLineSet of BaseTriangle with the current base line
     1983 * @param OptCandidate candidate reference on return
     1984 * @param OptCandidateCenter candidate's sphere center on return
     1985 * @param ShortestAngle the current path length on this circle band for the current Opt_Candidate
     1986 * @param RADIUS radius of sphere
     1987 * @param *LC LinkedCell structure with neighbouring atoms
     1988 */
     1989// void Find_next_suitable_point(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC)
     1990// {
     1991//   atom *Walker = NULL;
     1992//   Vector CircleCenter;  // center of the circle, i.e. of the band of sphere's centers
     1993//   Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in
     1994//   Vector OldSphereCenter;   // center of the sphere defined by the three points of BaseTriangle
     1995//   Vector NewSphereCenter;   // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility
     1996//   Vector OtherNewSphereCenter;   // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility
     1997//   Vector NewNormalVector;   // normal vector of the Candidate's triangle
     1998//   Vector SearchDirection;   // vector that points out of BaseTriangle and is orthonormal to its NormalVector (i.e. the desired direction for the best Candidate)
     1999//   Vector helper;
     2000//   LinkedAtoms *List = NULL;
     2001//   double CircleRadius; // radius of this circle
     2002//   double radius;
     2003//   double alpha, Otheralpha; // angles (i.e. parameter for the circle).
     2004//   double Nullalpha; // angle between OldSphereCenter and NormalVector of base triangle
     2005//   int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2006//   atom *Candidate = NULL;
     2007//
     2008//   cout << Verbose(1) << "Begin of Find_next_suitable_point" << endl;
     2009//
     2010//   cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << BaseTriangle->NormalVector << "." << endl;
     2011//
     2012//   // construct center of circle
     2013//   CircleCenter.CopyVector(&(BaseLine->endpoints[0]->node->x));
     2014//   CircleCenter.AddVector(&BaseLine->endpoints[1]->node->x);
     2015//   CircleCenter.Scale(0.5);
     2016//
     2017//   // construct normal vector of circle
     2018//   CirclePlaneNormal.CopyVector(&BaseLine->endpoints[0]->node->x);
     2019//   CirclePlaneNormal.SubtractVector(&BaseLine->endpoints[1]->node->x);
     2020//
     2021//   // calculate squared radius of circle
     2022//   radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal);
     2023//   if (radius/4. < RADIUS*RADIUS) {
     2024//     CircleRadius = RADIUS*RADIUS - radius/4.;
     2025//     CirclePlaneNormal.Normalize();
     2026//     cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
     2027//
     2028//     // construct old center
     2029//     GetCenterofCircumcircle(&OldSphereCenter, &(BaseTriangle->endpoints[0]->node->x), &(BaseTriangle->endpoints[1]->node->x), &(BaseTriangle->endpoints[2]->node->x));
     2030//     helper.CopyVector(&BaseTriangle->NormalVector);  // normal vector ensures that this is correct center of the two possible ones
     2031//     radius = BaseLine->endpoints[0]->node->x.DistanceSquared(&OldSphereCenter);
     2032//     helper.Scale(sqrt(RADIUS*RADIUS - radius));
     2033//     OldSphereCenter.AddVector(&helper);
     2034//     OldSphereCenter.SubtractVector(&CircleCenter);
     2035//     cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl;
     2036//
     2037//     // test whether old center is on the band's plane
     2038//     if (fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {
     2039//       cerr << "ERROR: Something's very wrong here: OldSphereCenter is not on the band's plane as desired by " << fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;
     2040//       OldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal);
     2041//     }
     2042//     radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);
     2043//     if (fabs(radius - CircleRadius) < HULLEPSILON) {
     2044//
     2045//       // construct SearchDirection
     2046//       SearchDirection.MakeNormalVector(&BaseTriangle->NormalVector, &CirclePlaneNormal);
     2047//       helper.CopyVector(&BaseLine->endpoints[0]->node->x);
     2048//       for(int i=0;i<3;i++)  // just take next different endpoint
     2049//         if ((BaseTriangle->endpoints[i]->node != BaseLine->endpoints[0]->node) && (BaseTriangle->endpoints[i]->node != BaseLine->endpoints[1]->node)) {
     2050//           helper.SubtractVector(&BaseTriangle->endpoints[i]->node->x);
     2051//         }
     2052//       if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)  // ohoh, SearchDirection points inwards!
     2053//         SearchDirection.Scale(-1.);
     2054//       SearchDirection.ProjectOntoPlane(&OldSphereCenter);
     2055//       SearchDirection.Normalize();
     2056//       cout << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl;
     2057//       if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) {  // rotated the wrong way!
     2058//         cerr << "ERROR: SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl;
     2059//       }
     2060//
     2061//       if (LC->SetIndexToVector(&CircleCenter)) {  // get cell for the starting atom
     2062//         for(int i=0;i<NDIM;i++) // store indices of this cell
     2063//           N[i] = LC->n[i];
     2064//         cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
     2065//       } else {
     2066//         cerr << "ERROR: Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl;
     2067//         return;
     2068//       }
     2069//       // then go through the current and all neighbouring cells and check the contained atoms for possible candidates
     2070//       cout << Verbose(2) << "LC Intervals:";
     2071//       for (int i=0;i<NDIM;i++) {
     2072//         Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0;
     2073//         Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1;
     2074//         cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
     2075//       }
     2076//       cout << endl;
     2077//       for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2078//         for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2079//           for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2080//             List = LC->GetCurrentCell();
     2081//             cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
     2082//             if (List != NULL) {
     2083//               for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2084//                 Candidate = (*Runner);
     2085//
     2086//                 // check for three unique points
     2087//                 if ((Candidate != BaseTriangle->endpoints[0]->node) && (Candidate != BaseTriangle->endpoints[1]->node) && (Candidate != BaseTriangle->endpoints[2]->node)) {
     2088//                   cout << Verbose(1) << "INFO: Current Candidate is " << *Candidate << " at " << Candidate->x << "." << endl;
     2089//
     2090//                   // construct both new centers
     2091//                   GetCenterofCircumcircle(&NewSphereCenter, &(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x));
     2092//                   OtherNewSphereCenter.CopyVector(&NewSphereCenter);
     2093//
     2094//                   if ((NewNormalVector.MakeNormalVector(&(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x))) && (fabs(NewNormalVector.ScalarProduct(&NewNormalVector)) > HULLEPSILON)) {
     2095//                     helper.CopyVector(&NewNormalVector);
     2096//                     cout << Verbose(2) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl;
     2097//                     radius = BaseLine->endpoints[0]->node->x.DistanceSquared(&NewSphereCenter);
     2098//                     if (radius < RADIUS*RADIUS) {
     2099//                       helper.Scale(sqrt(RADIUS*RADIUS - radius));
     2100//                       cout << Verbose(3) << "INFO: Distance of NewCircleCenter to NewSphereCenter is " << helper.Norm() << "." << endl;
     2101//                       NewSphereCenter.AddVector(&helper);
     2102//                       NewSphereCenter.SubtractVector(&CircleCenter);
     2103//                       cout << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl;
     2104//
     2105//                       helper.Scale(-1.); // OtherNewSphereCenter is created by the same vector just in the other direction
     2106//                       OtherNewSphereCenter.AddVector(&helper);
     2107//                       OtherNewSphereCenter.SubtractVector(&CircleCenter);
     2108//                       cout << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl;
     2109//
     2110//                       // check both possible centers
     2111//                       alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, BaseTriangle->NormalVector, SearchDirection);
     2112//                       Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, BaseTriangle->NormalVector, SearchDirection);
     2113//                       alpha = min(alpha, Otheralpha);
     2114//                       if (*ShortestAngle > alpha) {
     2115//                           OptCandidate = Candidate;
     2116//                           *ShortestAngle = alpha;
     2117//                           if (alpha != Otheralpha)
     2118//                             OptCandidateCenter->CopyVector(&NewSphereCenter);
     2119//                           else
     2120//                             OptCandidateCenter->CopyVector(&OtherNewSphereCenter);
     2121//                           cout << Verbose(1) << "We have found a better candidate: " << *OptCandidate << " with " << alpha << " and circumsphere's center at " << *OptCandidateCenter << "." << endl;
     2122//                       } else {
     2123//                         if (OptCandidate != NULL)
     2124//                           cout << Verbose(1) << "REJECT: Old candidate: " << *OptCandidate << " is better than " << alpha << " with " << *ShortestAngle << "." << endl;
     2125//                         else
     2126//                           cout << Verbose(2) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl;
     2127//                       }
     2128//
     2129//                     } else {
     2130//                       cout << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " is too far away: " << radius << "." << endl;
     2131//                     }
     2132//                   } else {
     2133//                     cout << Verbose(1) << "REJECT: Three points from " << *BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl;
     2134//                   }
     2135//                 } else {
     2136//                   cout << Verbose(1) << "REJECT: Base triangle " << *BaseTriangle << " contains Candidate " << *Candidate << "." << endl;
     2137//                 }
     2138//               }
     2139//             }
     2140//           }
     2141//     } else {
     2142//       cerr << Verbose(1) << "ERROR: The projected center of the old sphere has radius " << radius << " instead of " << CircleRadius << "." << endl;
     2143//     }
     2144//   } else {
     2145//     cout << Verbose(1) << "Circumcircle for base line " << *BaseLine << " and base triangle " << *BaseTriangle << " is too big!" << endl;
     2146//   }
     2147//
     2148//   cout << Verbose(1) << "End of Find_next_suitable_point" << endl;
     2149// };
     2150
     2151
     2152/** This recursive function finds a third point, to form a triangle with two given ones.
     2153 * Note that this function is for the starting triangle.
     2154 * The idea is as follows: A sphere with fixed radius is (almost) uniquely defined in space by three points
     2155 * that sit on its boundary. Hence, when two points are given and we look for the (next) third point, then
     2156 * the center of the sphere is still fixed up to a single parameter. The band of possible values
     2157 * describes a circle in 3D-space. The old center of the sphere for the current base triangle gives
     2158 * us the "null" on this circle, the new center of the candidate point will be some way along this
     2159 * circle. The shorter the way the better is the candidate. Note that the direction is clearly given
     2160 * by the normal vector of the base triangle that always points outwards by construction.
     2161 * Hence, we construct a Center of this circle which sits right in the middle of the current base line.
     2162 * We construct the normal vector that defines the plane this circle lies in, it is just in the
     2163 * direction of the baseline. And finally, we need the radius of the circle, which is given by the rest
     2164 * with respect to the length of the baseline and the sphere's fixed \a RADIUS.
     2165 * Note that there is one difficulty: The circumcircle is uniquely defined, but for the circumsphere's center
     2166 * there are two possibilities which becomes clear from the construction as seen below. Hence, we must check
     2167 * both.
     2168 * Note also that the acos() function is not unique on [0, 2.*M_PI). Hence, we need an additional check
     2169 * to decide for one of the two possible angles. Therefore we need a SearchDirection and to make this check
     2170 * sensible we need OldSphereCenter to be orthogonal to it. Either we construct SearchDirection orthogonal
     2171 * right away, or -- what we do here -- we rotate the relative sphere centers such that this orthogonality
     2172 * holds. Then, the normalized projection onto the SearchDirection is either +1 or -1 and thus states whether
     2173 * the angle is uniquely in either (0,M_PI] or [M_PI, 2.*M_PI).
     2174 * @param NormalVector normal direction of the base triangle (here the unit axis vector, \sa Find_starting_triangle())
     2175 * @param SearchDirection general direction where to search for the next point, relative to center of BaseLine
     2176 * @param OldSphereCenter center of sphere for base triangle, relative to center of BaseLine, giving null angle for the parameter circle
     2177 * @param BaseLine BoundaryLineSet with the current base line
     2178 * @param ThirdNode third atom to avoid in search
     2179 * @param OptCandidate candidate reference on return
     2180 * @param OptCandidateCenter candidate's sphere center on return
     2181 * @param ShortestAngle the current path length on this circle band for the current Opt_Candidate
     2182 * @param RADIUS radius of sphere
     2183 * @param *LC LinkedCell structure with neighbouring atoms
     2184 */
     2185void Find_third_point_for_Tesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, atom *ThirdNode, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC)
     2186{
     2187  Vector CircleCenter;  // center of the circle, i.e. of the band of sphere's centers
     2188  Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in
     2189  Vector NewSphereCenter;   // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility
     2190  Vector OtherNewSphereCenter;   // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility
     2191  Vector NewNormalVector;   // normal vector of the Candidate's triangle
     2192  Vector helper;
     2193  LinkedAtoms *List = NULL;
     2194  double CircleRadius; // radius of this circle
     2195  double radius;
     2196  double alpha, Otheralpha; // angles (i.e. parameter for the circle).
     2197  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2198  atom *Candidate = NULL;
     2199
     2200  cout << Verbose(1) << "Begin of Find_third_point_for_Tesselation" << endl;
     2201
     2202  cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;
     2203
     2204  // construct center of circle
     2205  CircleCenter.CopyVector(&(BaseLine->endpoints[0]->node->x));
     2206  CircleCenter.AddVector(&BaseLine->endpoints[1]->node->x);
     2207  CircleCenter.Scale(0.5);
     2208
     2209  // construct normal vector of circle
     2210  CirclePlaneNormal.CopyVector(&BaseLine->endpoints[0]->node->x);
     2211  CirclePlaneNormal.SubtractVector(&BaseLine->endpoints[1]->node->x);
     2212
     2213  // calculate squared radius of circle
     2214  radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal);
     2215  if (radius/4. < RADIUS*RADIUS) {
     2216    CircleRadius = RADIUS*RADIUS - radius/4.;
     2217    CirclePlaneNormal.Normalize();
     2218    cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
     2219
     2220    // test whether old center is on the band's plane
     2221    if (fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {
     2222      cerr << "ERROR: Something's very wrong here: OldSphereCenter is not on the band's plane as desired by " << fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;
     2223      OldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal);
     2224    }
     2225    radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);
     2226    if (fabs(radius - CircleRadius) < HULLEPSILON) {
     2227
     2228      // check SearchDirection
     2229      cout << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl;
     2230      if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) {  // rotated the wrong way!
     2231        cerr << "ERROR: SearchDirection and RelativeOldSphereCenter are not orthogonal!" << endl;
    18412232      }
    1842       TempNormal.Normalize();
    1843       Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1844       TempNormal.Scale(Restradius);
    1845 
    1846       Mittelpunkt.CopyVector(&Umkreismittelpunkt);
    1847       Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
    1848 
    1849       AngleCheck.CopyVector(Chord);
    1850       AngleCheck.Scale(-0.5);
    1851       AngleCheck.SubtractVector(&(b->x));
    1852       AngleCheckReference.CopyVector(&AngleCheck);
    1853       AngleCheckReference.AddVector(Opt_Mittelpunkt);
    1854       AngleCheck.AddVector(&Mittelpunkt);
    1855 
    1856       BallAngle = AngleCheck.Angle(&AngleCheckReference);
    1857 
    1858       d1->ProjectOntoPlane(&AngleCheckReference);
    1859       sign = AngleCheck.ScalarProduct(d1);
    1860       if (fabs(sign) < MYEPSILON)
    1861         sign = 0;
    1862       else
    1863         sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
    1864 
    1865 
    1866       if (Storage[0]< -1.5) { // first Candidate at all
    1867         cout << "Next better candidate is " << *Candidate << " with ";
    1868         Opt_Candidate = Candidate;
    1869         Storage[0] = sign;
    1870         Storage[1] = BallAngle;
    1871         Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1872         cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     2233      // get cell for the starting atom
     2234      if (LC->SetIndexToVector(&CircleCenter)) {
     2235          for(int i=0;i<NDIM;i++) // store indices of this cell
     2236          N[i] = LC->n[i];
     2237        cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
    18732238      } else {
    1874         /*
    1875          * removed due to change in criterium, now checking angle of ball to old normal.
    1876         //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
    1877         //within the ball.
    1878 
    1879         Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
    1880         //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
    1881 
    1882 
    1883         if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
    1884          */
    1885           //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
    1886 
    1887         if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
    1888           //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
    1889           cout << "Next better candidate is " << *Candidate << " with ";
    1890           Opt_Candidate = Candidate;
    1891           Storage[0] = sign;
    1892           Storage[1] = BallAngle;
    1893           Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1894           cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1895         } else {
    1896           if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
    1897             //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
    1898             cout << "Next better candidate is " << *Candidate << " with ";
    1899             Opt_Candidate = Candidate;
    1900             Storage[0] = sign;
    1901             Storage[1] = BallAngle;
    1902             Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1903             cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     2239        cerr << "ERROR: Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl;
     2240        return;
     2241      }
     2242      // then go through the current and all neighbouring cells and check the contained atoms for possible candidates
     2243      cout << Verbose(2) << "LC Intervals:";
     2244      for (int i=0;i<NDIM;i++) {
     2245        Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0;
     2246        Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1;
     2247        cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
     2248      }
     2249      cout << endl;
     2250      for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2251        for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2252          for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2253            List = LC->GetCurrentCell();
     2254            //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
     2255            if (List != NULL) {
     2256              for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2257                Candidate = (*Runner);
     2258
     2259                // check for three unique points
     2260                if ((Candidate != BaseLine->endpoints[0]->node) && (Candidate != BaseLine->endpoints[1]->node) && (Candidate != ThirdNode)) {
     2261                  cout << Verbose(1) << "INFO: Current Candidate is " << *Candidate << " at " << Candidate->x << "." << endl;
     2262
     2263                  // construct both new centers
     2264                  GetCenterofCircumcircle(&NewSphereCenter, &(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x));
     2265                  OtherNewSphereCenter.CopyVector(&NewSphereCenter);
     2266
     2267                  if ((NewNormalVector.MakeNormalVector(&(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x))) && (fabs(NewNormalVector.ScalarProduct(&NewNormalVector)) > HULLEPSILON)) {
     2268                    helper.CopyVector(&NewNormalVector);
     2269                    cout << Verbose(2) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl;
     2270                    radius = BaseLine->endpoints[0]->node->x.DistanceSquared(&NewSphereCenter);
     2271                    if (radius < RADIUS*RADIUS) {
     2272                      helper.Scale(sqrt(RADIUS*RADIUS - radius));
     2273                      cout << Verbose(3) << "INFO: Distance of NewCircleCenter to NewSphereCenter is " << helper.Norm() << "." << endl;
     2274                      NewSphereCenter.AddVector(&helper);
     2275                      NewSphereCenter.SubtractVector(&CircleCenter);
     2276                      cout << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl;
     2277
     2278                      helper.Scale(-1.); // OtherNewSphereCenter is created by the same vector just in the other direction
     2279                      OtherNewSphereCenter.AddVector(&helper);
     2280                      OtherNewSphereCenter.SubtractVector(&CircleCenter);
     2281                      cout << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl;
     2282
     2283                      // check both possible centers
     2284                      alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection);
     2285                      Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection);
     2286                      alpha = min(alpha, Otheralpha);
     2287                      if (*ShortestAngle > alpha) {
     2288                          OptCandidate = Candidate;
     2289                          *ShortestAngle = alpha;
     2290                          if (alpha != Otheralpha)
     2291                            OptCandidateCenter->CopyVector(&NewSphereCenter);
     2292                          else
     2293                            OptCandidateCenter->CopyVector(&OtherNewSphereCenter);
     2294                          cout << Verbose(1) << "ACCEPT: We have found a better candidate: " << *OptCandidate << " with " << alpha << " and circumsphere's center at " << *OptCandidateCenter << "." << endl;
     2295                      } else {
     2296                        if (OptCandidate != NULL)
     2297                          cout << Verbose(1) << "REJECT: Old candidate: " << *OptCandidate << " is better than " << alpha << " with " << *ShortestAngle << "." << endl;
     2298                        else
     2299                          cout << Verbose(2) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl;
     2300                      }
     2301
     2302                    } else {
     2303                      cout << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " is too far away: " << radius << "." << endl;
     2304                    }
     2305                  } else {
     2306                    cout << Verbose(1) << "REJECT: Three points from " << *BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl;
     2307                  }
     2308                } else {
     2309                  if (ThirdNode != NULL)
     2310                    cout << Verbose(1) << "REJECT: Base triangle " << *BaseLine << " and " << *ThirdNode << " contains Candidate " << *Candidate << "." << endl;
     2311                  else
     2312                    cout << Verbose(1) << "REJECT: Base triangle " << *BaseLine << " contains Candidate " << *Candidate << "." << endl;
     2313                }
     2314              }
     2315            }
    19042316          }
    1905         }
    1906       }
    1907 /*
    1908                * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle.
    1909                *
    1910                 else
    1911                 {
    1912                   if (sign>0 && BallAngle>0 && Storage[0]<0)
    1913                     {
    1914                       cout << "Next better candidate is " << *Candidate << " with ";
    1915                       Opt_Candidate = Candidate;
    1916                       Storage[0] = sign;
    1917                       Storage[1] = BallAngle;
    1918                       Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1919                       cout << "Angle is " << Storage[1] << ", Halbraum ist "
    1920                       << Storage[0] << endl;
    1921 
    1922 //Debugging purposes only
    1923                       cout << "Umkreismittelpunkt has coordinates" << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] <<" "<<Umkreismittelpunkt.x[2] << endl;
    1924                       cout << "Candidate has coordinates" << Candidate->x.x[0]<< " " << Candidate->x.x[1] << " " << Candidate->x.x[2] << endl;
    1925                       cout << "a has coordinates" << a->x.x[0]<< " " << a->x.x[1] << " " << a->x.x[2] << endl;
    1926                       cout << "b has coordinates" << b->x.x[0]<< " " << b->x.x[1] << " " << b->x.x[2] << endl;
    1927                       cout << "Mittelpunkt has coordinates" << Mittelpunkt.x[0] << " " << Mittelpunkt.x[1]<< " "  <<Mittelpunkt.x[2] << endl;
    1928                       cout << "Umkreisradius ist " << Umkreisradius << endl;
    1929                       cout << "Restradius ist " << Restradius << endl;
    1930                       cout << "TempNormal has coordinates " << TempNormal.x[0] << " " << TempNormal.x[1] << " " << TempNormal.x[2] << " " << endl;
    1931                       cout << "OldNormal has coordinates " << OldNormal->x[0] << " " << OldNormal->x[1] << " " << OldNormal->x[2] << " " << endl;
    1932                       cout << "Dist a to UmkreisMittelpunkt " << a->x.Distance(&Umkreismittelpunkt) << endl;
    1933                       cout << "Dist b to UmkreisMittelpunkt " << b->x.Distance(&Umkreismittelpunkt) << endl;
    1934                       cout << "Dist Candidate to UmkreisMittelpunkt " << Candidate->x.Distance(&Umkreismittelpunkt) << endl;
    1935                       cout << "Dist a to Mittelpunkt " << a->x.Distance(&Mittelpunkt) << endl;
    1936                       cout << "Dist b to Mittelpunkt " << b->x.Distance(&Mittelpunkt) << endl;
    1937                       cout << "Dist Candidate to Mittelpunkt " << Candidate->x.Distance(&Mittelpunkt) << endl;
    1938 
    1939 
    1940 
    1941                     }
    1942                   else
    1943                     {
    1944                       if (DEBUG)
    1945                         cout << "Looses to better candidate" << endl;
    1946                     }
    1947                 }
    1948                 */
    19492317    } else {
    1950       if (DEBUG) {
    1951         cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
    1952       }
     2318      cerr << Verbose(1) << "ERROR: The projected center of the old sphere has radius " << radius << " instead of " << CircleRadius << "." << endl;
    19532319    }
    19542320  } else {
    1955     if (DEBUG) {
    1956       cout << "identisch mit Ursprungslinie" << endl;
    1957     }
    1958   }
    1959 
    1960   if (RecursionLevel < 9) { // Five is the recursion level threshold.
    1961     for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
    1962       Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    1963       if (Walker == Parent) { // don't go back the same bond
    1964         continue;
    1965       } else {
    1966         Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
    1967       }
    1968     }
    1969   }
    1970 };
    1971 
    1972 /** This function finds a triangle to a line, adjacent to an existing one.
    1973  * @param out   output stream for debugging
    1974  * @param tecplot output stream for writing found triangles in TecPlot format
    1975  * @param mol molecule structure with all atoms and bonds
    1976  * @param Line current baseline to search from
    1977  * @param T current triangle which \a Line is edge of
    1978  * @param RADIUS radius of the rolling ball
    1979  * @param N number of found triangles
    1980  * @param *filename filename base for intermediate envelopes
    1981  */
    1982 bool Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,
    1983     molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T,
    1984     const double& RADIUS, int N, const char *tempbasename)
    1985 {
    1986   cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
    1987   Vector direction1;
    1988   Vector helper;
    1989   Vector Chord;
    1990   ofstream *tempstream = NULL;
    1991   char NumberName[255];
    1992   double tmp;
    1993   //atom* Walker;
    1994   atom* OldThirdPoint;
    1995 
    1996   double Storage[3];
    1997   Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
    1998   Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
    1999   Storage[2] = 9999999.;
    2000   atom* Opt_Candidate = NULL;
    2001   Vector Opt_Mittelpunkt;
    2002 
    2003   cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
    2004 
    2005   helper.CopyVector(&(Line.endpoints[0]->node->x));
    2006   for (int i = 0; i < 3; i++) {
    2007     if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
    2008       OldThirdPoint = T.endpoints[i]->node;
    2009       helper.SubtractVector(&T.endpoints[i]->node->x);
    2010       break;
    2011     }
    2012   }
    2013 
    2014   direction1.CopyVector(&Line.endpoints[0]->node->x);
    2015   direction1.SubtractVector(&Line.endpoints[1]->node->x);
    2016   direction1.VectorProduct(&(T.NormalVector));
    2017 
    2018   if (direction1.ScalarProduct(&helper) < 0) {
    2019     direction1.Scale(-1);
    2020   }
    2021   cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
    2022 
    2023   Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
    2024   Chord.SubtractVector(&(Line.endpoints[1]->node->x));
    2025   cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
    2026 
    2027 
    2028   Vector Umkreismittelpunkt, a, b, c;
    2029   double alpha, beta, gamma;
    2030   a.CopyVector(&(T.endpoints[0]->node->x));
    2031   b.CopyVector(&(T.endpoints[1]->node->x));
    2032   c.CopyVector(&(T.endpoints[2]->node->x));
    2033   a.SubtractVector(&(T.endpoints[1]->node->x));
    2034   b.SubtractVector(&(T.endpoints[2]->node->x));
    2035   c.SubtractVector(&(T.endpoints[0]->node->x));
    2036 
    2037   alpha = M_PI - a.Angle(&c);
    2038   beta = M_PI - b.Angle(&a);
    2039   gamma = M_PI - c.Angle(&b);
    2040   if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
    2041     cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    2042 
    2043   Umkreismittelpunkt.Zero();
    2044   helper.CopyVector(&T.endpoints[0]->node->x);
    2045   helper.Scale(sin(2.*alpha));
    2046   Umkreismittelpunkt.AddVector(&helper);
    2047   helper.CopyVector(&T.endpoints[1]->node->x);
    2048   helper.Scale(sin(2.*beta));
    2049   Umkreismittelpunkt.AddVector(&helper);
    2050   helper.CopyVector(&T.endpoints[2]->node->x);
    2051   helper.Scale(sin(2.*gamma));
    2052   Umkreismittelpunkt.AddVector(&helper);
    2053   //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;
    2054   //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2055   Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    2056   //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2057   cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
    2058   cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
    2059 
    2060   cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
    2061   cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
    2062   if (DEBUG)
    2063     cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
    2064   tmp = 0;
    2065   for (int i=0;i<NDIM;i++) {
    2066     helper.CopyVector(&T.endpoints[i]->node->x);
    2067     helper.SubtractVector(&Umkreismittelpunkt);
    2068     if (DEBUG)
    2069       cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
    2070     if (tmp == 0) // set on first time for comparison against next ones
    2071       tmp = helper.Norm();
    2072     if (fabs(helper.Norm() - tmp) > MYEPSILON)
    2073       cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
    2074   }
    2075 
    2076   cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
    2077 
    2078   Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2079   Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2080   if (Opt_Candidate == NULL) {
    2081     cerr << "WARNING: Could not find a suitable candidate." << endl;
    2082     return false;
    2083   }
    2084   cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
    2085 
    2086   // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
    2087   bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
    2088 
    2089   if (flag) { // if so, add
    2090     AddTrianglePoint(Opt_Candidate, 0);
    2091     AddTrianglePoint(Line.endpoints[0]->node, 1);
    2092     AddTrianglePoint(Line.endpoints[1]->node, 2);
    2093 
    2094     AddTriangleLine(TPS[0], TPS[1], 0);
    2095     AddTriangleLine(TPS[0], TPS[2], 1);
    2096     AddTriangleLine(TPS[1], TPS[2], 2);
    2097 
    2098     BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2099     AddTriangleToLines();
    2100 
    2101     BTS->GetNormalVector(BTS->NormalVector);
    2102 
    2103     if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {
    2104       BTS->NormalVector.Scale(-1);
    2105     };
    2106     cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
    2107     cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
    2108   } else { // else, yell and do nothing
    2109     cout << Verbose(1) << "This triangle consisting of ";
    2110     cout << *Opt_Candidate << ", ";
    2111     cout << *Line.endpoints[0]->node << " and ";
    2112     cout << *Line.endpoints[1]->node << " ";
    2113     cout << "is invalid!" << endl;
    2114     return false;
    2115   }
    2116 
    2117   if ((TrianglesOnBoundaryCount % 10) == 0) {
    2118     sprintf(NumberName, "-%d", TriangleFilesWritten);
    2119     if (DoTecplotOutput) {
    2120       string NameofTempFile(tempbasename);
    2121       NameofTempFile.append(NumberName);
    2122       NameofTempFile.append(TecplotSuffix);
    2123       cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2124       tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2125       write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
    2126       tempstream->close();
    2127       tempstream->flush();
    2128       delete(tempstream);
    2129     }
    2130 
    2131     if (DoRaster3DOutput) {
    2132       string NameofTempFile(tempbasename);
    2133       NameofTempFile.append(NumberName);
    2134       NameofTempFile.append(Raster3DSuffix);
    2135       cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2136       tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2137       write_raster3d_file(out, tempstream, this, mol);
    2138       tempstream->close();
    2139       tempstream->flush();
    2140       delete(tempstream);
    2141     }
    2142     if (DoTecplotOutput || DoRaster3DOutput)
    2143       TriangleFilesWritten++;
    2144   }
    2145 
    2146   cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
    2147   return true;
     2321    if (ThirdNode != NULL)
     2322      cout << Verbose(1) << "Circumcircle for base line " << *BaseLine << " and third node " << *ThirdNode << " is too big!" << endl;
     2323    else
     2324      cout << Verbose(1) << "Circumcircle for base line " << *BaseLine << " is too big!" << endl;
     2325  }
     2326
     2327
     2328  cout << Verbose(1) << "End of Find_third_point_for_Tesselation" << endl;
    21482329};
    21492330
     
    21942375
    21952376
    2196 void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent,
    2197     int RecursionLevel, Vector Oben, atom*& Opt_Candidate, double Storage[3],
    2198     molecule* mol, double RADIUS)
    2199 {
    2200   cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
    2201   int i;
     2377/** Finds the second point of starting triangle.
     2378 * \param *a first atom
     2379 * \param *Candidate pointer to candidate atom on return
     2380 * \param Oben vector indicating the outside
     2381 * \param Opt_Candidate reference to recommended candidate on return
     2382 * \param Storage[3] array storing angles and other candidate information
     2383 * \param RADIUS radius of virtual sphere
     2384 * \param *LC LinkedCell structure with neighbouring atoms
     2385 */
     2386void Find_second_point_for_Tesselation(atom* a, atom* Candidate, Vector Oben, atom*& Opt_Candidate, double Storage[3], double RADIUS, LinkedCell *LC)
     2387{
     2388  cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation" << endl;
    22022389  Vector AngleCheck;
    2203   atom* Walker;
    22042390  double norm = -1., angle;
    2205 
    2206   // check if we only have one unique point yet ...
    2207   if (a != Candidate) {
    2208     cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
    2209     AngleCheck.CopyVector(&(Candidate->x));
    2210     AngleCheck.SubtractVector(&(a->x));
    2211     norm = AngleCheck.Norm();
    2212     // second point shall have smallest angle with respect to Oben vector
    2213     if (norm < RADIUS) {
    2214       angle = AngleCheck.Angle(&Oben);
    2215       if (angle < Storage[0]) {
    2216         //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
    2217         cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
    2218         Opt_Candidate = Candidate;
    2219         Storage[0] = AngleCheck.Angle(&Oben);
    2220         //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
    2221       } else {
    2222         cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
     2391  LinkedAtoms *List = NULL;
     2392  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2393
     2394  if (LC->SetIndexToAtom(a)) {  // get cell for the starting atom
     2395    for(int i=0;i<NDIM;i++) // store indices of this cell
     2396      N[i] = LC->n[i];
     2397  } else {
     2398    cerr << "ERROR: Atom " << *a << " is not found in cell " << LC->index << "." << endl;
     2399    return;
     2400  }
     2401  // then go through the current and all neighbouring cells and check the contained atoms for possible candidates
     2402  cout << Verbose(2) << "LC Intervals:";
     2403  for (int i=0;i<NDIM;i++) {
     2404    Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0;
     2405    Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1;
     2406    cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
     2407  }
     2408  cout << endl;
     2409  for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2410    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2411      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2412        List = LC->GetCurrentCell();
     2413        //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
     2414        if (List != NULL) {
     2415          for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2416            Candidate = (*Runner);
     2417                // check if we only have one unique point yet ...
     2418                if (a != Candidate) {
     2419      cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
     2420      AngleCheck.CopyVector(&(Candidate->x));
     2421      AngleCheck.SubtractVector(&(a->x));
     2422      norm = AngleCheck.Norm();
     2423              // second point shall have smallest angle with respect to Oben vector
     2424              if (norm < RADIUS) {
     2425                angle = AngleCheck.Angle(&Oben);
     2426                if (angle < Storage[0]) {
     2427                  //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
     2428                  cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
     2429                  Opt_Candidate = Candidate;
     2430                  Storage[0] = AngleCheck.Angle(&Oben);
     2431                  //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
     2432                } else {
     2433                  cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
     2434                }
     2435              } else {
     2436                cout << "Refused due to Radius " << norm << endl;
     2437              }
     2438            }
     2439          }
     2440        }
    22232441      }
    2224     } else {
    2225       cout << "Refused due to Radius " << norm << endl;
    2226     }
    2227   }
    2228 
    2229   // if not recursed to deeply, look at all its bonds
    2230   if (RecursionLevel < 7) {
    2231     for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
    2232       Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    2233       if (Walker == Parent) // don't go back along the bond we came from
    2234         continue;
    2235       else
    2236         Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
    2237     }
    2238   }
    2239   cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2442  cout << Verbose(2) << "End of Find_second_point_for_Tesselation" << endl;
    22402443};
    22412444
    2242 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
     2445/** Finds the starting triangle for find_non_convex_border().
     2446 * Looks at the outermost atom per axis, then Find_second_point_for_Tesselation()
     2447 * for the second and Find_next_suitable_point_via_Angle_of_Sphere() for the third
     2448 * point are called.
     2449 * \param RADIUS radius of virtual rolling sphere
     2450 * \param *LC LinkedCell structure with neighbouring atoms
     2451 */
     2452void Tesselation::Find_starting_triangle(ofstream *out, molecule *mol, const double RADIUS, LinkedCell *LC)
    22432453{
    22442454  cout << Verbose(1) << "Begin of Find_starting_triangle\n";
    22452455  int i = 0;
    2246   atom* Walker;
     2456  LinkedAtoms *List = NULL;
    22472457  atom* FirstPoint;
    22482458  atom* SecondPoint;
    2249   atom* max_index[NDIM];
     2459  atom* MaxAtom[NDIM];
    22502460  double max_coordinate[NDIM];
    22512461  Vector Oben;
    22522462  Vector helper;
    22532463  Vector Chord;
    2254   Vector CenterOfFirstLine;
     2464  Vector SearchDirection;
     2465  Vector OptCandidateCenter;
    22552466
    22562467  Oben.Zero();
    22572468
    22582469  for (i = 0; i < 3; i++) {
    2259     max_index[i] = NULL;
     2470    MaxAtom[i] = NULL;
    22602471    max_coordinate[i] = -1;
    22612472  }
    2262   cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
    22632473
    22642474  // 1. searching topmost atom with respect to each axis
    2265   Walker = mol->start;
    2266   while (Walker->next != mol->end) {
    2267     Walker = Walker->next;
    2268     for (i = 0; i < 3; i++) {
    2269       if (Walker->x.x[i] > max_coordinate[i]) {
    2270         max_coordinate[i] = Walker->x.x[i];
    2271         max_index[i] = Walker;
     2475  for (int i=0;i<NDIM;i++) { // each axis
     2476    LC->n[i] = LC->N[i]-1; // current axis is topmost cell
     2477    for (LC->n[(i+1)%NDIM]=0;LC->n[(i+1)%NDIM]<LC->N[(i+1)%NDIM];LC->n[(i+1)%NDIM]++)
     2478      for (LC->n[(i+2)%NDIM]=0;LC->n[(i+2)%NDIM]<LC->N[(i+2)%NDIM];LC->n[(i+2)%NDIM]++) {
     2479        List = LC->GetCurrentCell();
     2480        //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
     2481        if (List != NULL) {
     2482          for (LinkedAtoms::iterator Runner = List->begin();Runner != List->end();Runner++) {
     2483            cout << Verbose(2) << "Current atom is " << *(*Runner) << "." << endl;
     2484            if ((*Runner)->x.x[i] > max_coordinate[i]) {
     2485              max_coordinate[i] = (*Runner)->x.x[i];
     2486              MaxAtom[i] = (*Runner);
     2487            }
     2488          }
     2489        } else {
     2490          cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl;
     2491        }
    22722492      }
    2273     }
    22742493  }
    22752494
    22762495  cout << Verbose(2) << "Found maximum coordinates: ";
    22772496  for (int i=0;i<NDIM;i++)
    2278     cout << i << ": " << *max_index[i] << "\t";
     2497    cout << i << ": " << *MaxAtom[i] << "\t";
    22792498  cout << endl;
    2280   //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
    2281   const int k = 1;
     2499  const int k = 1;    // arbitrary choice
    22822500  Oben.x[k] = 1.;
    2283   FirstPoint = max_index[k];
    2284 
    2285   cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
    2286   double Storage[3];
     2501  FirstPoint = MaxAtom[k];
     2502  cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << "." << endl;
     2503
     2504  // add first point
     2505  AddTrianglePoint(FirstPoint, 0);
     2506
     2507  double ShortestAngle;
    22872508  atom* Opt_Candidate = NULL;
    2288   Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
    2289   Storage[1] = 999999.; // This will be an angle looking for the third point.
    2290   Storage[2] = 999999.;
    2291 
    2292   Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
     2509  ShortestAngle = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
     2510
     2511  Find_second_point_for_Tesselation(FirstPoint, NULL, Oben, Opt_Candidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
    22932512  SecondPoint = Opt_Candidate;
    22942513  cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
     2514
     2515  // add second point and first baseline
     2516  AddTrianglePoint(SecondPoint, 1);
     2517  AddTriangleLine(TPS[0], TPS[1], 0);
    22952518
    22962519  helper.CopyVector(&(FirstPoint->x));
     
    23002523  Oben.Normalize();
    23012524  helper.VectorProduct(&Oben);
    2302   Storage[0] = -2.; // This will indicate the quadrant.
    2303   Storage[1] = 9999999.; // This will be an angle looking for the third point.
    2304   Storage[2] = 9999999.;
     2525  ShortestAngle = 2.*M_PI; // This will indicate the quadrant.
    23052526
    23062527  Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
    23072528  Chord.SubtractVector(&(SecondPoint->x));
     2529  double radius = Chord.ScalarProduct(&Chord);
     2530  double CircleRadius = sqrt(RADIUS*RADIUS - radius/4.);
     2531  helper.CopyVector(&Oben);
     2532  helper.Scale(CircleRadius);
    23082533  // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
    23092534
     
    23112536  // look in one direction of baseline for initial candidate
    23122537  Opt_Candidate = NULL;
    2313   CenterOfFirstLine.CopyVector(&Chord);
    2314   CenterOfFirstLine.Scale(0.5);
    2315   CenterOfFirstLine.AddVector(&(SecondPoint->x));
    2316 
    2317   cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
    2318   Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
    2319   // look in other direction of baseline for possible better candidate
    2320   cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
    2321   Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
     2538  SearchDirection.MakeNormalVector(&Chord, &Oben);  // whether we look "left" first or "right" first is not important ...
     2539
     2540  cout << Verbose(1) << "Looking for third point candidates ...\n";
     2541  Find_third_point_for_Tesselation(Oben, SearchDirection, helper, BLS[0], NULL, Opt_Candidate, &OptCandidateCenter, &ShortestAngle, RADIUS, LC);
    23222542  cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
    23232543
     2544  // add third point
     2545  AddTrianglePoint(Opt_Candidate, 2);
     2546
    23242547  // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
    23252548
    2326   // Finally, we only have to add the found points
    2327   AddTrianglePoint(FirstPoint, 0);
    2328   AddTrianglePoint(SecondPoint, 1);
    2329   AddTrianglePoint(Opt_Candidate, 2);
    2330   // ... and respective lines
    2331   AddTriangleLine(TPS[0], TPS[1], 0);
     2549  // Finally, we only have to add the found further lines
    23322550  AddTriangleLine(TPS[1], TPS[2], 1);
    23332551  AddTriangleLine(TPS[0], TPS[2], 2);
     
    23362554  AddTriangleToLines();
    23372555  // ... and calculate its normal vector (with correct orientation)
    2338   Oben.Scale(-1.);
    2339   BTS->GetNormalVector(Oben);
     2556  OptCandidateCenter.Scale(-1.);
     2557  cout << Verbose(2) << "Oben is currently " << OptCandidateCenter << "." << endl;
     2558  BTS->GetNormalVector(OptCandidateCenter);
    23402559  cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
     2560  cout << Verbose(2) << "Projection is " << BTS->NormalVector.Projection(&Oben) << "." << endl;
    23412561  cout << Verbose(1) << "End of Find_starting_triangle\n";
    23422562};
    23432563
    2344 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS)
     2564/** This function finds a triangle to a line, adjacent to an existing one.
     2565 * @param out output stream for debugging
     2566 * @param *mol molecule with Atom's and Bond's
     2567 * @param Line current baseline to search from
     2568 * @param T current triangle which \a Line is edge of
     2569 * @param RADIUS radius of the rolling ball
     2570 * @param N number of found triangles
     2571 * @param *filename filename base for intermediate envelopes
     2572 * @param *LC LinkedCell structure with neighbouring atoms
     2573 */
     2574bool Tesselation::Find_next_suitable_triangle(ofstream *out,
     2575    molecule *mol, BoundaryLineSet &Line, BoundaryTriangleSet &T,
     2576    const double& RADIUS, int N, const char *tempbasename, LinkedCell *LC)
     2577{
     2578  cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
     2579  ofstream *tempstream = NULL;
     2580  char NumberName[255];
     2581
     2582  atom* Opt_Candidate = NULL;
     2583  Vector OptCandidateCenter;
     2584
     2585  Vector CircleCenter;
     2586  Vector CirclePlaneNormal;
     2587  Vector OldSphereCenter;
     2588  Vector SearchDirection;
     2589  Vector helper;
     2590  atom *ThirdNode = NULL;
     2591  double ShortestAngle = 2.*M_PI; // This will indicate the quadrant.
     2592  double radius, CircleRadius;
     2593
     2594  cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
     2595  for (int i=0;i<3;i++)
     2596    if ((T.endpoints[i]->node != Line.endpoints[0]->node) && (T.endpoints[i]->node != Line.endpoints[1]->node))
     2597      ThirdNode = T.endpoints[i]->node;
     2598
     2599  // construct center of circle
     2600  CircleCenter.CopyVector(&Line.endpoints[0]->node->x);
     2601  CircleCenter.AddVector(&Line.endpoints[1]->node->x);
     2602  CircleCenter.Scale(0.5);
     2603
     2604  // construct normal vector of circle
     2605  CirclePlaneNormal.CopyVector(&Line.endpoints[0]->node->x);
     2606  CirclePlaneNormal.SubtractVector(&Line.endpoints[1]->node->x);
     2607
     2608  // calculate squared radius of circle
     2609  radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal);
     2610  if (radius/4. < RADIUS*RADIUS) {
     2611    CircleRadius = RADIUS*RADIUS - radius/4.;
     2612    CirclePlaneNormal.Normalize();
     2613    cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
     2614
     2615    // construct old center
     2616    GetCenterofCircumcircle(&OldSphereCenter, &(T.endpoints[0]->node->x), &(T.endpoints[1]->node->x), &(T.endpoints[2]->node->x));
     2617    helper.CopyVector(&T.NormalVector);  // normal vector ensures that this is correct center of the two possible ones
     2618    radius = Line.endpoints[0]->node->x.DistanceSquared(&OldSphereCenter);
     2619    helper.Scale(sqrt(RADIUS*RADIUS - radius));
     2620    OldSphereCenter.AddVector(&helper);
     2621    OldSphereCenter.SubtractVector(&CircleCenter);
     2622    cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl;
     2623
     2624    // construct SearchDirection
     2625    SearchDirection.MakeNormalVector(&T.NormalVector, &CirclePlaneNormal);
     2626    helper.CopyVector(&Line.endpoints[0]->node->x);
     2627    helper.SubtractVector(&ThirdNode->x);
     2628    if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)  // ohoh, SearchDirection points inwards!
     2629      SearchDirection.Scale(-1.);
     2630    SearchDirection.ProjectOntoPlane(&OldSphereCenter);
     2631    SearchDirection.Normalize();
     2632    cout << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl;
     2633    if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) {  // rotated the wrong way!
     2634      cerr << "ERROR: SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl;
     2635    }
     2636
     2637    // add third point
     2638    cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
     2639    Find_third_point_for_Tesselation(T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, Opt_Candidate, &OptCandidateCenter, &ShortestAngle, RADIUS, LC);
     2640
     2641  } else {
     2642    cout << Verbose(1) << "Circumcircle for base line " << Line << " and base triangle " << T << " is too big!" << endl;
     2643  }
     2644
     2645  if (Opt_Candidate == NULL) {
     2646    cerr << "WARNING: Could not find a suitable candidate." << endl;
     2647    return false;
     2648  }
     2649  cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << " with circumsphere's center at " << OptCandidateCenter << "." << endl;
     2650
     2651  // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
     2652  bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
     2653
     2654  if (flag) { // if so, add
     2655    AddTrianglePoint(Opt_Candidate, 0);
     2656    AddTrianglePoint(Line.endpoints[0]->node, 1);
     2657    AddTrianglePoint(Line.endpoints[1]->node, 2);
     2658
     2659    AddTriangleLine(TPS[0], TPS[1], 0);
     2660    AddTriangleLine(TPS[0], TPS[2], 1);
     2661    AddTriangleLine(TPS[1], TPS[2], 2);
     2662
     2663    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2664    AddTriangleToLines();
     2665
     2666    OptCandidateCenter.Scale(-1.);
     2667    BTS->GetNormalVector(OptCandidateCenter);
     2668    OptCandidateCenter.Scale(-1.);
     2669
     2670    cout << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
     2671    cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
     2672  } else { // else, yell and do nothing
     2673    cout << Verbose(1) << "This triangle consisting of ";
     2674    cout << *Opt_Candidate << ", ";
     2675    cout << *Line.endpoints[0]->node << " and ";
     2676    cout << *Line.endpoints[1]->node << " ";
     2677    cout << "is invalid!" << endl;
     2678    return false;
     2679  }
     2680
     2681  if (flag && (DoSingleStepOutput && (TrianglesOnBoundaryCount % 10 == 0))) { // if we have a new triangle and want to output each new triangle configuration
     2682    sprintf(NumberName, "-%04d-%s_%s_%s", TriangleFilesWritten, BTS->endpoints[0]->node->Name, BTS->endpoints[1]->node->Name, BTS->endpoints[2]->node->Name);
     2683    if (DoTecplotOutput) {
     2684      string NameofTempFile(tempbasename);
     2685      NameofTempFile.append(NumberName);
     2686      for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
     2687        NameofTempFile.erase(npos, 1);
     2688      NameofTempFile.append(TecplotSuffix);
     2689      cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2690      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2691      write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
     2692      tempstream->close();
     2693      tempstream->flush();
     2694      delete(tempstream);
     2695    }
     2696
     2697    if (DoRaster3DOutput) {
     2698      string NameofTempFile(tempbasename);
     2699      NameofTempFile.append(NumberName);
     2700      for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
     2701        NameofTempFile.erase(npos, 1);
     2702      NameofTempFile.append(Raster3DSuffix);
     2703      cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2704      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2705      write_raster3d_file(out, tempstream, this, mol);
     2706      // include the current position of the virtual sphere in the temporary raster3d file
     2707      // make the circumsphere's center absolute again
     2708      helper.CopyVector(&Line.endpoints[0]->node->x);
     2709      helper.AddVector(&Line.endpoints[1]->node->x);
     2710      helper.Scale(0.5);
     2711      OptCandidateCenter.AddVector(&helper);
     2712      Vector *center = mol->DetermineCenterOfAll(out);
     2713      OptCandidateCenter.AddVector(center);
     2714      delete(center);
     2715      // and add to file plus translucency object
     2716      *tempstream << "# current virtual sphere\n";
     2717      *tempstream << "8\n  25.0    0.6     -1.0 -1.0 -1.0     0.2        0 0 0 0\n";
     2718      *tempstream << "2\n  " << OptCandidateCenter.x[0] << " " << OptCandidateCenter.x[1] << " " << OptCandidateCenter.x[2] << "\t" << RADIUS << "\t1 0 0\n";
     2719      *tempstream << "9\n  terminating special property\n";
     2720      tempstream->close();
     2721      tempstream->flush();
     2722      delete(tempstream);
     2723    }
     2724    if (DoTecplotOutput || DoRaster3DOutput)
     2725      TriangleFilesWritten++;
     2726  }
     2727
     2728  cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
     2729  return true;
     2730};
     2731
     2732/** Tesselates the non convex boundary by rolling a virtual sphere along the surface of the molecule.
     2733 * \param *out output stream for debugging
     2734 * \param *mol molecule structure with Atom's and Bond's
     2735 * \param *Tess Tesselation filled with points, lines and triangles on boundary on return
     2736 * \param *LCList linked cell list of all atoms
     2737 * \param *filename filename prefix for output of vertex data
     2738 * \para RADIUS radius of the virtual sphere
     2739 */
     2740void Find_non_convex_border(ofstream *out, molecule* mol, class Tesselation *Tess, class LinkedCell *LCList, const char *filename, const double RADIUS)
    23452741{
    23462742  int N = 0;
    2347   struct Tesselation *Tess = new Tesselation;
    2348   cout << Verbose(1) << "Entering search for non convex hull. " << endl;
    2349   cout << flush;
     2743  bool freeTess = false;
     2744  *out << Verbose(1) << "Entering search for non convex hull. " << endl;
     2745  if (Tess == NULL) {
     2746    *out << Verbose(1) << "Allocating Tesselation struct ..." << endl;
     2747    Tess = new Tesselation;
     2748    freeTess = true;
     2749  }
     2750  bool freeLC = false;
    23502751  LineMap::iterator baseline;
    2351   cout << Verbose(0) << "Begin of Find_non_convex_border\n";
     2752  *out << Verbose(0) << "Begin of Find_non_convex_border\n";
    23522753  bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
    23532754  bool failflag = false;
    2354   if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
    2355     mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
    2356 
    2357   Tess->Find_starting_triangle(mol, RADIUS);
     2755
     2756  if (LCList == NULL) {
     2757    LCList = new LinkedCell(mol, 2.*RADIUS);
     2758    freeLC = true;
     2759  }
     2760
     2761  Tess->Find_starting_triangle(out, mol, RADIUS, LCList);
    23582762
    23592763  baseline = Tess->LinesOnBoundary.begin();
    23602764  while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
    23612765    if (baseline->second->TrianglesCount == 1) {
    2362       failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.
     2766      failflag = Tess->Find_next_suitable_triangle(out, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename, LCList); //the line is there, so there is a triangle, but only one.
    23632767      flag = flag || failflag;
    23642768      if (!failflag)
     
    23742778    }
    23752779  }
    2376   if (failflag) {
    2377     cout << Verbose(1) << "Writing final tecplot file\n";
    2378     if (DoTecplotOutput)
     2780  if (1) { //failflag) {
     2781    *out << Verbose(1) << "Writing final tecplot file\n";
     2782    if (DoTecplotOutput) {
     2783      string OutputName(filename);
     2784      OutputName.append(TecplotSuffix);
     2785      ofstream *tecplot = new ofstream(OutputName.c_str());
    23792786      write_tecplot_file(out, tecplot, Tess, mol, -1);
    2380     if (DoRaster3DOutput)
    2381       write_raster3d_file(out, tecplot, Tess, mol);
     2787      tecplot->close();
     2788      delete(tecplot);
     2789    }
     2790    if (DoRaster3DOutput) {
     2791      string OutputName(filename);
     2792      OutputName.append(Raster3DSuffix);
     2793      ofstream *raster = new ofstream(OutputName.c_str());
     2794      write_raster3d_file(out, raster, Tess, mol);
     2795      raster->close();
     2796      delete(raster);
     2797    }
    23822798  } else {
    23832799    cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
    23842800  }
    2385 
    2386   cout << Verbose(0) << "End of Find_non_convex_border\n";
    2387   delete(Tess);
     2801  if (freeTess)
     2802    delete(Tess);
     2803  if (freeLC)
     2804    delete(LCList);
     2805  *out << Verbose(0) << "End of Find_non_convex_border\n";
    23882806};
    23892807
     2808/** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it.
     2809 * \param *out output stream for debugging
     2810 * \param *srcmol molecule to embed into
     2811 * \return *Vector new center of \a *srcmol for embedding relative to \a this
     2812 */
     2813Vector* molecule::FindEmbeddingHole(ofstream *out, molecule *srcmol)
     2814{
     2815  Vector *Center = new Vector;
     2816  Center->Zero();
     2817  // calculate volume/shape of \a *srcmol
     2818
     2819  // find embedding holes
     2820
     2821  // if more than one, let user choose
     2822
     2823  // return embedding center
     2824  return Center;
     2825};
     2826
  • src/boundary.hpp

    rce5ac3 rd067d45  
    1717
    1818#include <gsl/gsl_poly.h>
     19#include <gsl/gsl_matrix.h>
     20#include <gsl/gsl_linalg.h>
     21#include <gsl/gsl_multimin.h>
     22#include <gsl/gsl_permutation.h>
    1923
     24#include "linkedcell.hpp"
    2025#include "molecules.hpp"
    2126
     
    8590    void AddTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);
    8691    void AddTriangleToLines();
    87     void Find_starting_triangle(molecule* mol, const double RADIUS);
    88     bool Find_next_suitable_triangle(ofstream *out, ofstream *tecplot, molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, const char *filename);
     92    void Find_starting_triangle(ofstream *out, molecule* mol, const double RADIUS, LinkedCell *LC);
     93    bool Find_next_suitable_triangle(ofstream *out, molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, const char *filename, LinkedCell *LC);
    8994    bool CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c);
    9095    void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent, int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol);
     
    109114
    110115
    111 double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
     116double VolumeOfConvexEnvelope(ofstream *out, const char *filename, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
    112117double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    113118void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
    114 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS);
    115 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule *mol, bool problem);
    116 
     119void Find_non_convex_border(ofstream *out, molecule* mol, class Tesselation *T, class LinkedCell *LCList, const char *tempbasename, const double RADIUS);
     120void Find_next_suitable_point(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC);
    117121
    118122#endif /*BOUNDARY_HPP_*/
  • src/builder.cpp

    rce5ac3 rd067d45  
    5050using namespace std;
    5151
     52#include "boundary.hpp"
     53#include "ellipsoid.hpp"
    5254#include "helpers.hpp"
    5355#include "molecules.hpp"
    54 #include "boundary.hpp"
    55 
    56 /********************************************** Submenu routine **************************************/
     56
     57/********************************************* Subsubmenu routine ************************************/
    5758
    5859/** Submenu for adding atoms to the molecule.
    5960 * \param *periode periodentafel
    60  * \param *mol the molecule to add to
     61 * \param *molecule molecules with atoms
    6162 */
    6263static void AddAtoms(periodentafel *periode, molecule *mol)
     
    8283
    8384  switch (choice) {
     85    default:
     86      cout << Verbose(0) << "Not a valid choice." << endl;
     87      break;
    8488      case 'a': // absolute coordinates of atom
    8589        cout << Verbose(0) << "Enter absolute coordinates." << endl;
     
    122126        break;
    123127
    124       case 'd': // two atoms, two angles and a distance
     128    case 'd': // two atoms, two angles and a distance
    125129        first = new atom;
    126130        valid = true;
     
    255259
    256260/** Submenu for centering the atoms in the molecule.
    257  * \param *mol the molecule with all the atoms
     261 * \param *mol molecule with all the atoms
    258262 */
    259263static void CenterAtoms(molecule *mol)
     
    278282    case 'a':
    279283      cout << Verbose(0) << "Centering atoms in config file on origin." << endl;
    280       mol->CenterOrigin((ofstream *)&cout, &x);
     284      mol->CenterOrigin((ofstream *)&cout);
    281285      break;
    282286    case 'b':
    283287      cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl;
    284       mol->CenterGravity((ofstream *)&cout, &x);
     288      mol->CenterPeriodic((ofstream *)&cout);
    285289      break;
    286290    case 'c':
     
    291295      }
    292296      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
    293       mol->Translate(&y); // translate by boundary
     297      mol->Center.AddVector(&y); // translate by boundary
    294298      helper.CopyVector(&y);
    295299      helper.Scale(2.);
     
    313317/** Submenu for aligning the atoms in the molecule.
    314318 * \param *periode periodentafel
    315  * \param *mol the molecule with all the atoms
     319 * \param *mol molecule with all the atoms
    316320 */
    317321static void AlignAtoms(periodentafel *periode, molecule *mol)
     
    381385
    382386/** Submenu for mirroring the atoms in the molecule.
    383  * \param *mol the molecule with all the atoms
     387 * \param *mol molecule with all the atoms
    384388 */
    385389static void MirrorAtoms(molecule *mol)
     
    428432
    429433/** Submenu for removing the atoms from the molecule.
    430  * \param *mol the molecule with all the atoms
     434 * \param *mol molecule with all the atoms
    431435 */
    432436static void RemoveAtoms(molecule *mol)
     
    461465      while(first->next != mol->end) {
    462466        first = first->next;
    463         if (first->x.Distance((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ...
     467        if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ...
    464468          mol->RemoveAtom(first);
    465469      }
     
    486490/** Submenu for measuring out the atoms in the molecule.
    487491 * \param *periode periodentafel
    488  * \param *mol the molecule with all the atoms
     492 * \param *mol molecule with all the atoms
    489493 */
    490494static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration)
     
    596600
    597601/** Submenu for measuring out the atoms in the molecule.
    598  * \param *mol the molecule with all the atoms
     602 * \param *mol molecule with all the atoms
    599603 * \param *configuration configuration structure for the to be written config files of all fragments
    600604 */
     
    616620};
    617621
     622/********************************************** Submenu routine **************************************/
     623
     624/** Submenu for manipulating atoms.
     625 * \param *periode periodentafel
     626 * \param *molecules list of molecules whose atoms are to be manipulated
     627 */
     628static void ManipulateAtoms(periodentafel *periode, MoleculeListClass *molecules, config *configuration)
     629{
     630  atom *first, *second;
     631  molecule *mol = NULL;
     632  Vector x,y,z,n; // coordinates for absolute point in cell volume
     633  double *factor; // unit factor if desired
     634  double bond, min_bond;
     635  char choice;  // menu choice char
     636  bool valid;
     637
     638  cout << Verbose(0) << "=========MANIPULATE ATOMS======================" << endl;
     639  cout << Verbose(0) << "a - add an atom" << endl;
     640  cout << Verbose(0) << "r - remove an atom" << endl;
     641  cout << Verbose(0) << "b - scale a bond between atoms" << endl;
     642  cout << Verbose(0) << "u - change an atoms element" << endl;
     643  cout << Verbose(0) << "l - measure lengths, angles, ... for an atom" << endl;
     644  cout << Verbose(0) << "all else - go back" << endl;
     645  cout << Verbose(0) << "===============================================" << endl;
     646  if (molecules->NumberOfActiveMolecules() > 1)
     647    cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl;
     648  cout << Verbose(0) << "INPUT: ";
     649  cin >> choice;
     650
     651  switch (choice) {
     652    default:
     653      cout << Verbose(0) << "Not a valid choice." << endl;
     654      break;
     655
     656    case 'a': // add atom
     657      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     658        if ((*ListRunner)->ActiveFlag) {
     659        mol = *ListRunner;
     660        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     661        AddAtoms(periode, mol);
     662      }
     663      break;
     664
     665    case 'b': // scale a bond
     666      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     667        if ((*ListRunner)->ActiveFlag) {
     668        mol = *ListRunner;
     669        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     670        cout << Verbose(0) << "Scaling bond length between two atoms." << endl;
     671        first = mol->AskAtom("Enter first (fixed) atom: ");
     672        second = mol->AskAtom("Enter second (shifting) atom: ");
     673        min_bond = 0.;
     674        for (int i=NDIM;i--;)
     675          min_bond += (first->x.x[i]-second->x.x[i])*(first->x.x[i] - second->x.x[i]);
     676        min_bond = sqrt(min_bond);
     677        cout << Verbose(0) << "Current Bond length between " << first->type->name << " Atom " << first->nr << " and " << second->type->name << " Atom " << second->nr << ": " << min_bond << " a.u." << endl;
     678        cout << Verbose(0) << "Enter new bond length [a.u.]: ";
     679        cin >> bond;
     680        for (int i=NDIM;i--;) {
     681          second->x.x[i] -= (second->x.x[i]-first->x.x[i])/min_bond*(min_bond-bond);
     682        }
     683        //cout << Verbose(0) << "New coordinates of Atom " << second->nr << " are: ";
     684        //second->Output(second->type->No, 1, (ofstream *)&cout);
     685      }
     686      break;
     687
     688    case 'c': // unit scaling of the metric
     689      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     690        if ((*ListRunner)->ActiveFlag) {
     691        mol = *ListRunner;
     692        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     693       cout << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl;
     694       cout << Verbose(0) << "Enter three factors: ";
     695       factor = new double[NDIM];
     696       cin >> factor[0];
     697       cin >> factor[1];
     698       cin >> factor[2];
     699       valid = true;
     700       mol->Scale(&factor);
     701       delete[](factor);
     702      }
     703     break;
     704
     705    case 'l': // measure distances or angles
     706      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     707        if ((*ListRunner)->ActiveFlag) {
     708        mol = *ListRunner;
     709        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     710        MeasureAtoms(periode, mol, configuration);
     711      }
     712      break;
     713
     714    case 'r': // remove atom
     715      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     716        if ((*ListRunner)->ActiveFlag) {
     717        mol = *ListRunner;
     718        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     719        RemoveAtoms(mol);
     720      }
     721      break;
     722
     723    case 'u': // change an atom's element
     724      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     725        if ((*ListRunner)->ActiveFlag) {
     726        int Z;
     727        mol = *ListRunner;
     728        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     729        first = NULL;
     730        do {
     731          cout << Verbose(0) << "Change the element of which atom: ";
     732          cin >> Z;
     733        } while ((first = mol->FindAtom(Z)) == NULL);
     734        cout << Verbose(0) << "New element by atomic number Z: ";
     735        cin >> Z;
     736        first->type = periode->FindElement(Z);
     737        cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;
     738      }
     739      break;
     740  }
     741};
     742
     743/** Submenu for manipulating molecules.
     744 * \param *periode periodentafel
     745 * \param *molecules list of molecule to manipulate
     746 */
     747static void ManipulateMolecules(periodentafel *periode, MoleculeListClass *molecules, config *configuration)
     748{
     749  atom *first;
     750  Vector x,y,z,n; // coordinates for absolute point in cell volume
     751  int j, axis, count, faktor;
     752  char choice;  // menu choice char
     753  molecule *mol = NULL;
     754  element **Elements;
     755  Vector **vectors;
     756  MoleculeLeafClass *Subgraphs = NULL;
     757
     758  cout << Verbose(0) << "=========MANIPULATE GLOBALLY===================" << endl;
     759  cout << Verbose(0) << "c - scale by unit transformation" << endl;
     760  cout << Verbose(0) << "d - duplicate molecule/periodic cell" << endl;
     761  cout << Verbose(0) << "f - fragment molecule many-body bond order style" << endl;
     762  cout << Verbose(0) << "g - center atoms in box" << endl;
     763  cout << Verbose(0) << "i - realign molecule" << endl;
     764  cout << Verbose(0) << "m - mirror all molecules" << endl;
     765  cout << Verbose(0) << "o - create connection matrix" << endl;
     766  cout << Verbose(0) << "t - translate molecule by vector" << endl;
     767  cout << Verbose(0) << "all else - go back" << endl;
     768  cout << Verbose(0) << "===============================================" << endl;
     769  if (molecules->NumberOfActiveMolecules() > 1)
     770    cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl;
     771  cout << Verbose(0) << "INPUT: ";
     772  cin >> choice;
     773
     774  switch (choice) {
     775    default:
     776      cout << Verbose(0) << "Not a valid choice." << endl;
     777      break;
     778
     779    case 'd': // duplicate the periodic cell along a given axis, given times
     780      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     781        if ((*ListRunner)->ActiveFlag) {
     782        mol = *ListRunner;
     783        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     784        cout << Verbose(0) << "State the axis [(+-)123]: ";
     785        cin >> axis;
     786        cout << Verbose(0) << "State the factor: ";
     787        cin >> faktor;
     788
     789        mol->CountAtoms((ofstream *)&cout); // recount atoms
     790        if (mol->AtomCount != 0) {  // if there is more than none
     791          count = mol->AtomCount;  // is changed becausing of adding, thus has to be stored away beforehand
     792          Elements = new element *[count];
     793          vectors = new Vector *[count];
     794          j = 0;
     795          first = mol->start;
     796          while (first->next != mol->end) { // make a list of all atoms with coordinates and element
     797            first = first->next;
     798            Elements[j] = first->type;
     799            vectors[j] = &first->x;
     800            j++;
     801          }
     802          if (count != j)
     803            cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
     804          x.Zero();
     805          y.Zero();
     806          y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude
     807          for (int i=1;i<faktor;i++) {  // then add this list with respective translation factor times
     808            x.AddVector(&y); // per factor one cell width further
     809            for (int k=count;k--;) { // go through every atom of the original cell
     810              first = new atom(); // create a new body
     811              first->x.CopyVector(vectors[k]);  // use coordinate of original atom
     812              first->x.AddVector(&x);     // translate the coordinates
     813              first->type = Elements[k];  // insert original element
     814              mol->AddAtom(first);        // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
     815            }
     816          }
     817          if (mol->first->next != mol->last) // if connect matrix is present already, redo it
     818            mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration->GetIsAngstroem());
     819          // free memory
     820          delete[](Elements);
     821          delete[](vectors);
     822          // correct cell size
     823          if (axis < 0) { // if sign was negative, we have to translate everything
     824            x.Zero();
     825            x.AddVector(&y);
     826            x.Scale(-(faktor-1));
     827            mol->Translate(&x);
     828          }
     829          mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
     830        }
     831      }
     832      break;
     833
     834    case 'f':
     835      FragmentAtoms(mol, configuration);
     836      break;
     837
     838    case 'g': // center the atoms
     839      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     840        if ((*ListRunner)->ActiveFlag) {
     841        mol = *ListRunner;
     842        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     843        CenterAtoms(mol);
     844      }
     845      break;
     846
     847    case 'i': // align all atoms
     848      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     849        if ((*ListRunner)->ActiveFlag) {
     850        mol = *ListRunner;
     851        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     852        AlignAtoms(periode, mol);
     853      }
     854      break;
     855
     856    case 'm': // mirror atoms along a given axis
     857      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     858        if ((*ListRunner)->ActiveFlag) {
     859        mol = *ListRunner;
     860        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     861        MirrorAtoms(mol);
     862      }
     863      break;
     864
     865    case 'o': // create the connection matrix
     866      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     867        if ((*ListRunner)->ActiveFlag) {
     868        double bonddistance;
     869        clock_t start,end;
     870        cout << Verbose(0) << "What's the maximum bond distance: ";
     871        cin >> bonddistance;
     872        start = clock();
     873        mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem());
     874        mol->CreateListOfBondsPerAtom((ofstream *)&cout);
     875        end = clock();
     876        cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     877      }
     878      break;
     879
     880    case 't': // translate all atoms
     881      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     882        if ((*ListRunner)->ActiveFlag) {
     883        mol = *ListRunner;
     884        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     885        cout << Verbose(0) << "Enter translation vector." << endl;
     886        x.AskPosition(mol->cell_size,0);
     887        mol->Center.AddVector((const Vector *)&x);
     888     }
     889     break;
     890  }
     891  // Free all
     892  if (Subgraphs != NULL) {  // free disconnected subgraph list of DFS analysis was performed
     893    while (Subgraphs->next != NULL) {
     894      Subgraphs = Subgraphs->next;
     895      delete(Subgraphs->previous);
     896    }
     897    delete(Subgraphs);
     898  }
     899};
     900
     901
     902/** Submenu for creating new molecules.
     903 * \param *periode periodentafel
     904 * \param *molecules list of molecules to add to
     905 */
     906static void EditMolecules(periodentafel *periode, MoleculeListClass *molecules)
     907{
     908  char choice;  // menu choice char
     909  Vector center;
     910  int nr, count;
     911  molecule *mol = NULL;
     912
     913  cout << Verbose(0) << "==========EDIT MOLECULES=====================" << endl;
     914  cout << Verbose(0) << "c - create new molecule" << endl;
     915  cout << Verbose(0) << "l - load molecule from xyz file" << endl;
     916  cout << Verbose(0) << "n - change molecule's name" << endl;
     917  cout << Verbose(0) << "N - give molecules filename" << endl;
     918  cout << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl;
     919  cout << Verbose(0) << "r - remove a molecule" << endl;
     920  cout << Verbose(0) << "all else - go back" << endl;
     921  cout << Verbose(0) << "===============================================" << endl;
     922  cout << Verbose(0) << "INPUT: ";
     923  cin >> choice;
     924
     925  switch (choice) {
     926    default:
     927      cout << Verbose(0) << "Not a valid choice." << endl;
     928      break;
     929    case 'c':
     930      mol = new molecule(periode);
     931      molecules->insert(mol);
     932      break;
     933
     934    case 'l': // load from XYZ file
     935      {
     936        char filename[MAXSTRINGSIZE];
     937        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     938        mol = new molecule(periode);
     939        do {
     940          cout << Verbose(0) << "Enter file name: ";
     941          cin >> filename;
     942        } while (!mol->AddXYZFile(filename));
     943        mol->SetNameFromFilename(filename);
     944        // center at set box dimensions
     945        mol->CenterEdge((ofstream *)&cout, &center);
     946        mol->cell_size[0] = center.x[0];
     947        mol->cell_size[1] = 0;
     948        mol->cell_size[2] = center.x[1];
     949        mol->cell_size[3] = 0;
     950        mol->cell_size[4] = 0;
     951        mol->cell_size[5] = center.x[2];
     952        molecules->insert(mol);
     953      }
     954      break;
     955
     956    case 'n':
     957      {
     958        char filename[MAXSTRINGSIZE];
     959        do {
     960          cout << Verbose(0) << "Enter index of molecule: ";
     961          cin >> nr;
     962          mol = molecules->ReturnIndex(nr);
     963        } while (mol == NULL);
     964        cout << Verbose(0) << "Enter name: ";
     965        cin >> filename;
     966        strcpy(mol->name, filename);
     967      }
     968      break;
     969
     970    case 'N':
     971      {
     972        char filename[MAXSTRINGSIZE];
     973        do {
     974          cout << Verbose(0) << "Enter index of molecule: ";
     975          cin >> nr;
     976          mol = molecules->ReturnIndex(nr);
     977        } while (mol == NULL);
     978        cout << Verbose(0) << "Enter name: ";
     979        cin >> filename;
     980        mol->SetNameFromFilename(filename);
     981      }
     982      break;
     983
     984    case 'p': // parse XYZ file
     985      {
     986        char filename[MAXSTRINGSIZE];
     987        mol = NULL;
     988        do {
     989          cout << Verbose(0) << "Enter index of molecule: ";
     990          cin >> nr;
     991          mol = molecules->ReturnIndex(nr);
     992        } while (mol == NULL);
     993        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     994        do {
     995          cout << Verbose(0) << "Enter file name: ";
     996          cin >> filename;
     997        } while (!mol->AddXYZFile(filename));
     998        mol->SetNameFromFilename(filename);
     999      }
     1000      break;
     1001
     1002    case 'r':
     1003      cout << Verbose(0) << "Enter index of molecule: ";
     1004      cin >> nr;
     1005      count = 1;
     1006      for( MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1007        if (nr == (*ListRunner)->IndexNr) {
     1008          mol = *ListRunner;
     1009          molecules->ListOfMolecules.erase(ListRunner);
     1010          delete(mol);
     1011        }
     1012      break;
     1013  }
     1014};
     1015
     1016
     1017/** Submenu for merging molecules.
     1018 * \param *periode periodentafel
     1019 * \param *molecules list of molecules to add to
     1020 */
     1021static void MergeMolecules(periodentafel *periode, MoleculeListClass *molecules)
     1022{
     1023  char choice;  // menu choice char
     1024
     1025  cout << Verbose(0) << "===========MERGE MOLECULES=====================" << endl;
     1026  cout << Verbose(0) << "a - simple add of one molecule to another" << endl;
     1027  cout << Verbose(0) << "e - embedding merge of two molecules" << endl;
     1028  cout << Verbose(0) << "m - multi-merge of all molecules" << endl;
     1029  cout << Verbose(0) << "s - scatter merge of two molecules" << endl;
     1030  cout << Verbose(0) << "t - simple merge of two molecules" << endl;
     1031  cout << Verbose(0) << "all else - go back" << endl;
     1032  cout << Verbose(0) << "===============================================" << endl;
     1033  cout << Verbose(0) << "INPUT: ";
     1034  cin >> choice;
     1035
     1036  switch (choice) {
     1037    default:
     1038      cout << Verbose(0) << "Not a valid choice." << endl;
     1039      break;
     1040
     1041    case 'a':
     1042      {
     1043        int src, dest;
     1044        molecule *srcmol = NULL, *destmol = NULL;
     1045        {
     1046          do {
     1047            cout << Verbose(0) << "Enter index of destination molecule: ";
     1048            cin >> dest;
     1049            destmol = molecules->ReturnIndex(dest);
     1050          } while ((destmol == NULL) && (dest != -1));
     1051          do {
     1052            cout << Verbose(0) << "Enter index of source molecule to add from: ";
     1053            cin >> src;
     1054            srcmol = molecules->ReturnIndex(src);
     1055          } while ((srcmol == NULL) && (src != -1));
     1056          if ((src != -1) && (dest != -1))
     1057            molecules->SimpleAdd(srcmol, destmol);
     1058        }
     1059      }
     1060      break;
     1061
     1062    case 'e':
     1063      cout << Verbose(0) << "Not implemented yet." << endl;
     1064      break;
     1065
     1066    case 'm':
     1067      {
     1068        int nr;
     1069        molecule *mol = NULL;
     1070        do {
     1071          cout << Verbose(0) << "Enter index of molecule to merge into: ";
     1072          cin >> nr;
     1073          mol = molecules->ReturnIndex(nr);
     1074        } while ((mol == NULL) && (nr != -1));
     1075        if (nr != -1) {
     1076          int N = molecules->ListOfMolecules.size()-1;
     1077          int *src = new int(N);
     1078          for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1079            if ((*ListRunner)->IndexNr != nr)
     1080              src[N++] = (*ListRunner)->IndexNr;       
     1081          molecules->SimpleMultiMerge(mol, src, N);
     1082          delete[](src);
     1083        }
     1084      }
     1085      break;
     1086
     1087    case 's':
     1088      cout << Verbose(0) << "Not implemented yet." << endl;
     1089      break;
     1090
     1091    case 't':
     1092      {
     1093        int src, dest;
     1094        molecule *srcmol = NULL, *destmol = NULL;
     1095        {
     1096          do {
     1097            cout << Verbose(0) << "Enter index of destination molecule: ";
     1098            cin >> dest;
     1099            destmol = molecules->ReturnIndex(dest);
     1100          } while ((destmol == NULL) && (dest != -1));
     1101          do {
     1102            cout << Verbose(0) << "Enter index of source molecule to merge into: ";
     1103            cin >> src;
     1104            srcmol = molecules->ReturnIndex(src);
     1105          } while ((srcmol == NULL) && (src != -1));
     1106          if ((src != -1) && (dest != -1))
     1107            molecules->SimpleMerge(srcmol, destmol);
     1108        }
     1109      }
     1110      break;
     1111  }
     1112};
     1113
     1114
    6181115/********************************************** Test routine **************************************/
    6191116
    6201117/** Is called always as option 'T' in the menu.
     1118 * \param *molecules list of molecules
    6211119 */
    622 static void testroutine(molecule *mol)
     1120static void testroutine(MoleculeListClass *molecules)
    6231121{
    6241122  // the current test routine checks the functionality of the KeySet&Graph concept:
    6251123  // We want to have a multiindex (the KeySet) describing a unique subgraph
     1124  int i, comp, counter=0;
     1125
     1126  // create a clone
     1127  molecule *mol = NULL;
     1128  if (molecules->ListOfMolecules.size() != 0) // clone
     1129    mol = (molecules->ListOfMolecules.front())->CopyMolecule();
     1130  else {
     1131    cerr << "I don't have anything to test on ... ";
     1132    return;
     1133  }
    6261134  atom *Walker = mol->start;
    627   int i, comp, counter=0;
    6281135
    6291136  // generate some KeySets
     
    6851192    A++;
    6861193  }
     1194  delete(mol);
    6871195};
    6881196
     
    6911199 * \param *configuration pointer to configuration structure with all the values
    6921200 * \param *periode pointer to periodentafel structure with all the elements
    693  * \param *mol pointer to molecule structure with all the atoms and coordinates
     1201 * \param *molecules list of molecules structure with all the atoms and coordinates
    6941202 */
    695 static void SaveConfig(char *ConfigFileName, config *configuration, periodentafel *periode, molecule *mol)
     1203static void SaveConfig(char *ConfigFileName, config *configuration, periodentafel *periode, MoleculeListClass *molecules)
    6961204{
    6971205  char filename[MAXSTRINGSIZE];
    6981206  ofstream output;
    699   string basis("3-21G");
     1207  molecule *mol = new molecule(periode);
     1208
     1209  // translate each to its center and merge all molecules in MoleculeListClass into this molecule
     1210  int N = molecules->ListOfMolecules.size();
     1211  int *src = new int(N);
     1212  N=0;
     1213  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     1214    src[N++] = (*ListRunner)->IndexNr;
     1215    (*ListRunner)->Translate(&(*ListRunner)->Center);
     1216  }
     1217  molecules->SimpleMultiAdd(mol, src, N);
     1218  delete[](src);
     1219  // ... and translate back
     1220  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     1221    (*ListRunner)->Center.Scale(-1.);
     1222    (*ListRunner)->Translate(&(*ListRunner)->Center);
     1223    (*ListRunner)->Center.Scale(-1.);
     1224  }
    7001225
    7011226  cout << Verbose(0) << "Storing configuration ... " << endl;
     
    7031228  mol->CalculateOrbitals(*configuration);
    7041229  configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
    705   strcpy(filename, ConfigFileName);
    7061230  if (ConfigFileName != NULL) { // test the file name
    707     output.open(ConfigFileName, ios::trunc);
     1231    strcpy(filename, ConfigFileName);
     1232    output.open(filename, ios::trunc);
    7081233  } else if (strlen(configuration->configname) != 0) {
    7091234    strcpy(filename, configuration->configname);
     
    7611286    cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
    7621287  }
     1288  delete(mol);
    7631289};
    7641290
     
    7661292 * \param argc argument count
    7671293 * \param **argv arguments array
    768  * \param *mol molecule structure
     1294 * \param *molecules list of molecules structure
    7691295 * \param *periode elements structure
    7701296 * \param configuration config file structure
     
    7731299 * \return exit code (0 - successful, all else - something's wrong)
    7741300 */
    775 static int ParseCommandLineOptions(int argc, char **argv, molecule *&mol, periodentafel *&periode, config& configuration, char *&ConfigFileName, char *&PathToDatabases)
     1301static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode, config& configuration, char *ConfigFileName, char *&PathToDatabases)
    7761302{
    7771303  Vector x,y,z,n;  // coordinates for absolute point in cell volume
     
    7891315  int argptr;
    7901316  PathToDatabases = LocalPath;
     1317
     1318  // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
     1319  molecule *mol = new molecule(periode);
     1320  mol->ActiveFlag = true;
     1321  molecules->insert(mol);
    7911322
    7921323  if (argc > 1) { // config file specified as option
     
    8071338            cout << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
    8081339            cout << "\t-b x1 x2 x3\tCenter atoms in domain with given edge lengths of (x1,x2,x3)." << endl;
    809             cout << "\t-B <basis>\tgive gaussian basis for MPQC output." << endl;
     1340            cout << "\t-B <basis>\tSetting basis to store to MPQC config files." << endl;
    8101341            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
    8111342            cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
     
    8711402      return 1;
    8721403    }
    873 
    8741404    // 3. Find config file name and parse if possible
    8751405    if (argv[1][0] != '-') {
     
    8841414        } else {
    8851415          cout << "Empty configuration file." << endl;
    886           ConfigFileName = argv[1];
     1416          strcpy(ConfigFileName, argv[1]);
    8871417          config_present = empty;
    8881418          output.close();
     
    8901420      } else {
    8911421        test.close();
    892         ConfigFileName = argv[1];
     1422        strcpy(ConfigFileName, argv[1]);
    8931423        cout << Verbose(1) << "Specified config file found, parsing ... ";
    8941424        switch (configuration.TestSyntax(ConfigFileName, periode, mol)) {
     
    9101440    } else
    9111441      config_present = absent;
    912 
    9131442    // 4. parse again through options, now for those depending on elements db and config presence
    9141443    argptr = 1;
     
    9651494          switch(argv[argptr-1][1]) {
    9661495            case 'B':
    967               if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
     1496              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    9681497                ExitFlag = 255;
    969                 cerr << "Not enough or invalid arguments given for giving gaussian basis: -B <basis>" << endl;
     1498                cerr << "Not enough or invalid arguments given for setting MPQC basis: -B <basis name>" << endl;
    9701499              } else {
    971                 cout << Verbose(1) << "Setting gaussian basis to " << argv[argptr] << "." << endl;
    972                 configuration.basis.copy(argv[argptr],strlen(argv[argptr]));
     1500                configuration.basis = argv[argptr];
     1501                cout << Verbose(1) << "Setting MPQC basis to " << configuration.basis << "." << endl;
    9731502                argptr+=1;
    9741503              }
     
    10221551            case 'A':
    10231552              ExitFlag = 1;
    1024               if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
     1553              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    10251554                ExitFlag =255;
    10261555                cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
     
    10301559                mol->CreateAdjacencyList2((ofstream *)&cout, input);
    10311560                input->close();
     1561                argptr+=1;
    10321562              }
    10331563              break;
     
    10381568                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
    10391569              } else {
    1040                 cout << Verbose(0) << "Evaluating npn-convex envelope.";
    1041                 string TempName(argv[argptr+1]);
    1042                 TempName.append(".r3d");
    1043                 ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
     1570                class Tesselation T;
     1571                int N = 15;
     1572                int number = 100;
     1573                string filename(argv[argptr+1]);
     1574                filename.append(".csv");
     1575                cout << Verbose(0) << "Evaluating non-convex envelope.";
    10441576                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
    1045                 Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
    1046                 output->close();
    1047                 delete(output);
     1577                LinkedCell LCList(mol, atof(argv[argptr]));    // \NOTE not twice the radius??
     1578                Find_non_convex_border((ofstream *)&cout, mol, &T, &LCList, argv[argptr+1], atof(argv[argptr]));
     1579                FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str());
    10481580                argptr+=2;
    10491581              }
     
    11801712              ExitFlag = 1;
    11811713              SaveFlag = true;
    1182               cout << Verbose(1) << "Centering atoms in origin." << endl;
    1183               mol->CenterOrigin((ofstream *)&cout, &x);
     1714              cout << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl;
     1715              mol->CenterEdge((ofstream *)&cout, &x);
    11841716              mol->SetBoxDimension(&x);
    11851717              break;
     
    12301762              } else {
    12311763                cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    1232                 ofstream *output = new ofstream(argv[argptr], ios::trunc);
    1233                 //$$$
    12341764                cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
    1235                 VolumeOfConvexEnvelope((ofstream *)&cout, output, &configuration, NULL, mol);
    1236                 output->close();
    1237                 delete(output);
     1765                VolumeOfConvexEnvelope((ofstream *)&cout, argv[argptr], &configuration, NULL, mol);
    12381766                argptr+=1;
    12391767              }
     
    13411869    } while (argptr < argc);
    13421870    if (SaveFlag)
    1343       SaveConfig(ConfigFileName, &configuration, periode, mol);
     1871      SaveConfig(ConfigFileName, &configuration, periode, molecules);
    13441872    if ((ExitFlag >= 1)) {
    13451873      delete(mol);
     
    13621890{
    13631891  periodentafel *periode = new periodentafel; // and a period table of all elements
    1364   molecule *mol = new molecule(periode);    // first we need an empty molecule
     1892  MoleculeListClass *molecules = new MoleculeListClass;  // list of all molecules
     1893  molecule *mol = NULL;
    13651894  config configuration;
    1366   double tmp1;
    1367   double bond, min_bond;
    1368   atom *first, *second;
    13691895  char choice;  // menu choice char
    13701896  Vector x,y,z,n;  // coordinates for absolute point in cell volume
    1371   double *factor;  // unit factor if desired
    1372   bool valid; // flag if input was valid or not
    13731897  ifstream test;
    13741898  ofstream output;
    13751899  string line;
    1376   char filename[MAXSTRINGSIZE];
    1377   char *ConfigFileName = NULL;
     1900  char ConfigFileName[MAXSTRINGSIZE];
    13781901  char *ElementsFileName = NULL;
    1379   int Z;
    1380   int j, axis, count, faktor;
    1381   clock_t start,end;
    1382 //  int *MinimumRingSize = NULL;
    1383   MoleculeLeafClass *Subgraphs = NULL;
    1384 //  class StackClass<bond *> *BackEdgeStack = NULL;
    1385   element **Elements;
    1386   Vector **vectors;
     1902  int j;
    13871903
    13881904  // =========================== PARSE COMMAND LINE OPTIONS ====================================
    1389   j = ParseCommandLineOptions(argc, argv, mol, periode, configuration, ConfigFileName, ElementsFileName);
     1905  ConfigFileName[0] = '\0';
     1906  j = ParseCommandLineOptions(argc, argv, molecules, periode, configuration, ConfigFileName, ElementsFileName);
    13901907  if (j == 1) return 0; // just for -v and -h options
    13911908  if (j) return j;  // something went wrong
    13921909
    13931910  // General stuff
    1394   if (mol->cell_size[0] == 0.) {
    1395     cout << Verbose(0) << "enter lower triadiagonal form of basis matrix" << endl << endl;
    1396     for (int i=0;i<6;i++) {
    1397       cout << Verbose(1) << "Cell size" << i << ": ";
    1398       cin >> mol->cell_size[i];
     1911  if (molecules->ListOfMolecules.size() == 0) {
     1912    mol = new molecule(periode);
     1913    if (mol->cell_size[0] == 0.) {
     1914      cout << Verbose(0) << "enter lower tridiagonal form of basis matrix" << endl << endl;
     1915      for (int i=0;i<6;i++) {
     1916        cout << Verbose(1) << "Cell size" << i << ": ";
     1917        cin >> mol->cell_size[i];
     1918      }
    13991919    }
     1920    molecules->insert(mol);
    14001921  }
     1922  if (strlen(ConfigFileName) == 0)
     1923    strcpy(ConfigFileName, DEFAULTCONFIG);
     1924   
    14011925
    14021926  // =========================== START INTERACTIVE SESSION ====================================
     
    14061930  do {
    14071931    cout << Verbose(0) << endl << endl;
    1408     cout << Verbose(0) << "============Element list=======================" << endl;
    1409     mol->Checkout((ofstream *)&cout);
    1410     cout << Verbose(0) << "============Atom list==========================" << endl;
    1411     mol->Output((ofstream *)&cout);
     1932    cout << Verbose(0) << "============Molecule list=======================" << endl;
     1933    molecules->Enumerate((ofstream *)&cout);
    14121934    cout << Verbose(0) << "============Menu===============================" << endl;
    1413     cout << Verbose(0) << "a - add an atom" << endl;
    1414     cout << Verbose(0) << "r - remove an atom" << endl;
    1415     cout << Verbose(0) << "b - scale a bond between atoms" << endl;
    1416     cout << Verbose(0) << "u - change an atoms element" << endl;
    1417     cout << Verbose(0) << "l - measure lengths, angles, ... for an atom" << endl;
     1935    cout << Verbose(0) << "a - set molecule (in)active" << endl;
     1936    cout << Verbose(0) << "e - edit molecules (load, parse, save)" << endl;
     1937    cout << Verbose(0) << "g - globally manipulate atoms in molecule" << endl;
     1938    cout << Verbose(0) << "M - Merge molecules" << endl;
     1939    cout << Verbose(0) << "m - manipulate atoms" << endl;
    14181940    cout << Verbose(0) << "-----------------------------------------------" << endl;
    1419     cout << Verbose(0) << "p - Parse xyz file" << endl;
    1420     cout << Verbose(0) << "e - edit the current configuration" << endl;
    1421     cout << Verbose(0) << "o - create connection matrix" << endl;
    1422     cout << Verbose(0) << "f - fragment molecule many-body bond order style" << endl;
    1423     cout << Verbose(0) << "-----------------------------------------------" << endl;
    1424     cout << Verbose(0) << "d - duplicate molecule/periodic cell" << endl;
    1425     cout << Verbose(0) << "i - realign molecule" << endl;
    1426     cout << Verbose(0) << "m - mirror all molecules" << endl;
    1427     cout << Verbose(0) << "t - translate molecule by vector" << endl;
    1428     cout << Verbose(0) << "c - scale by unit transformation" << endl;
    1429     cout << Verbose(0) << "g - center atoms in box" << endl;
     1941    cout << Verbose(0) << "c - edit the current configuration" << endl;
    14301942    cout << Verbose(0) << "-----------------------------------------------" << endl;
    14311943    cout << Verbose(0) << "s - save current setup to config file" << endl;
     
    14371949
    14381950    switch (choice) {
    1439       default:
    1440       case 'a': // add atom
    1441         AddAtoms(periode, mol);
    1442         choice = 'a';
    1443         break;
    1444 
    1445       case 'b': // scale a bond
    1446         cout << Verbose(0) << "Scaling bond length between two atoms." << endl;
    1447         first = mol->AskAtom("Enter first (fixed) atom: ");
    1448         second = mol->AskAtom("Enter second (shifting) atom: ");
    1449         min_bond = 0.;
    1450         for (int i=NDIM;i--;)
    1451           min_bond += (first->x.x[i]-second->x.x[i])*(first->x.x[i] - second->x.x[i]);
    1452         min_bond = sqrt(min_bond);
    1453         cout << Verbose(0) << "Current Bond length between " << first->type->name << " Atom " << first->nr << " and " << second->type->name << " Atom " << second->nr << ": " << min_bond << " a.u." << endl;
    1454         cout << Verbose(0) << "Enter new bond length [a.u.]: ";
    1455         cin >> bond;
    1456         for (int i=NDIM;i--;) {
    1457           second->x.x[i] -= (second->x.x[i]-first->x.x[i])/min_bond*(min_bond-bond);
    1458         }
    1459         //cout << Verbose(0) << "New coordinates of Atom " << second->nr << " are: ";
    1460         //second->Output(second->type->No, 1, (ofstream *)&cout);
    1461         break;
    1462 
    1463       case 'c': // unit scaling of the metric
    1464        cout << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl;
    1465        cout << Verbose(0) << "Enter three factors: ";
    1466        factor = new double[NDIM];
    1467        cin >> factor[0];
    1468        cin >> factor[1];
    1469        cin >> factor[2];
    1470        valid = true;
    1471        mol->Scale(&factor);
    1472        delete[](factor);
    1473        break;
    1474 
    1475       case 'd': // duplicate the periodic cell along a given axis, given times
    1476         cout << Verbose(0) << "State the axis [(+-)123]: ";
    1477         cin >> axis;
    1478         cout << Verbose(0) << "State the factor: ";
    1479         cin >> faktor;
    1480 
    1481         mol->CountAtoms((ofstream *)&cout);  // recount atoms
    1482         if (mol->AtomCount != 0) {  // if there is more than none
    1483           count = mol->AtomCount;   // is changed becausing of adding, thus has to be stored away beforehand
    1484           Elements = new element *[count];
    1485           vectors = new Vector *[count];
    1486           j = 0;
    1487           first = mol->start;
    1488           while (first->next != mol->end) {  // make a list of all atoms with coordinates and element
    1489             first = first->next;
    1490             Elements[j] = first->type;
    1491             vectors[j] = &first->x;
    1492             j++;
    1493           }
    1494           if (count != j)
    1495             cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
    1496           x.Zero();
    1497           y.Zero();
    1498           y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude
    1499           for (int i=1;i<faktor;i++) {  // then add this list with respective translation factor times
    1500             x.AddVector(&y); // per factor one cell width further
    1501             for (int k=count;k--;) { // go through every atom of the original cell
    1502               first = new atom(); // create a new body
    1503               first->x.CopyVector(vectors[k]);  // use coordinate of original atom
    1504               first->x.AddVector(&x);      // translate the coordinates
    1505               first->type = Elements[k];  // insert original element
    1506               mol->AddAtom(first);        // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
    1507             }
    1508           }
    1509           if (mol->first->next != mol->last) // if connect matrix is present already, redo it
    1510             mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration.GetIsAngstroem());
    1511           // free memory
    1512           delete[](Elements);
    1513           delete[](vectors);
    1514           // correct cell size
    1515           if (axis < 0) { // if sign was negative, we have to translate everything
    1516             x.Zero();
    1517             x.AddVector(&y);
    1518             x.Scale(-(faktor-1));
    1519             mol->Translate(&x);
    1520           }
    1521           mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
     1951      case 'a':  // (in)activate molecule
     1952        {
     1953          cout << "Enter index of molecule: ";
     1954          cin >> j;
     1955          for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1956            if ((*ListRunner)->IndexNr == j)
     1957              (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag;
    15221958        }
    15231959        break;
    15241960
    1525       case 'e': // edit each field of the configuration
    1526        configuration.Edit(mol);
     1961      case 'c': // edit each field of the configuration
     1962       configuration.Edit();
    15271963       break;
    15281964
    1529       case 'f':
    1530         FragmentAtoms(mol, &configuration);
     1965      case 'e': // create molecule
     1966        EditMolecules(periode, molecules);
    15311967        break;
    15321968
    1533       case 'g': // center the atoms
    1534         CenterAtoms(mol);
     1969      case 'g': // manipulate molecules
     1970        ManipulateMolecules(periode, molecules, &configuration);
    15351971        break;
    15361972
    1537       case 'i': // align all atoms
    1538         AlignAtoms(periode, mol);
     1973      case 'M':  // merge molecules
     1974        MergeMolecules(periode, molecules);
    15391975        break;
    15401976
    1541       case 'l': // measure distances or angles
    1542         MeasureAtoms(periode, mol, &configuration);
    1543         break;
    1544 
    1545       case 'm': // mirror atoms along a given axis
    1546         MirrorAtoms(mol);
    1547         break;
    1548 
    1549       case 'o': // create the connection matrix
    1550         {
    1551           cout << Verbose(0) << "What's the maximum bond distance: ";
    1552           cin >> tmp1;
    1553           start = clock();
    1554           mol->CreateAdjacencyList((ofstream *)&cout, tmp1, configuration.GetIsAngstroem());
    1555           mol->CreateListOfBondsPerAtom((ofstream *)&cout);
    1556 //          Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
    1557 //          while (Subgraphs->next != NULL) {
    1558 //            Subgraphs = Subgraphs->next;
    1559 //            Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, BackEdgeStack, MinimumRingSize);
    1560 //            delete(Subgraphs->previous);
    1561 //          }
    1562 //          delete(Subgraphs);    // we don't need the list here, so free everything
    1563 //          delete[](MinimumRingSize);
    1564 //          Subgraphs = NULL;
    1565           end = clock();
    1566           cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    1567         }
    1568         break;
    1569 
    1570       case 'p': // parse and XYZ file
    1571         cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
    1572         do {
    1573           cout << Verbose(0) << "Enter file name: ";
    1574           cin >> filename;
    1575         } while (!mol->AddXYZFile(filename));
     1977      case 'm': // manipulate atoms
     1978        ManipulateAtoms(periode, molecules, &configuration);
    15761979        break;
    15771980
     
    15791982        break;
    15801983
    1581       case 'r': // remove atom
    1582         RemoveAtoms(mol);
     1984      case 's': // save to config file
     1985        SaveConfig(ConfigFileName, &configuration, periode, molecules);
    15831986        break;
    15841987
    1585       case 's': // save to config file
    1586         SaveConfig(ConfigFileName, &configuration, periode, mol);
     1988      case 'T':
     1989        testroutine(molecules);
    15871990        break;
    15881991
    1589       case 't': // translate all atoms
    1590        cout << Verbose(0) << "Enter translation vector." << endl;
    1591        x.AskPosition(mol->cell_size,0);
    1592        mol->Translate((const Vector *)&x);
    1593        break;
    1594 
    1595       case 'T':
    1596         testroutine(mol);
    1597         break;
    1598 
    1599       case 'u': // change an atom's element
    1600         first = NULL;
    1601         do {
    1602           cout << Verbose(0) << "Change the element of which atom: ";
    1603           cin >> Z;
    1604         } while ((first = mol->FindAtom(Z)) == NULL);
    1605         cout << Verbose(0) << "New element by atomic number Z: ";
    1606         cin >> Z;
    1607         first->type = periode->FindElement(Z);
    1608         cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;
     1992      default:
    16091993        break;
    16101994    };
     
    16172001    cout << Verbose(0) << "Saving of elements.db failed." << endl;
    16182002
    1619   // Free all
    1620   if (Subgraphs != NULL) {  // free disconnected subgraph list of DFS analysis was performed
    1621     while (Subgraphs->next != NULL) {
    1622       Subgraphs = Subgraphs->next;
    1623       delete(Subgraphs->previous);
    1624     }
    1625     delete(Subgraphs);
    1626   }
    1627   delete(mol);
     2003  delete(molecules);
    16282004  delete(periode);
    16292005  return (0);
  • src/config.cpp

    rce5ac3 rd067d45  
    11/** \file config.cpp
    2  * 
     2 *
    33 * Function implementations for the class config.
    4  * 
     4 *
    55 */
    66
     
    6565  UseAddGramSch=1;
    6666  Seed=1;
     67
    6768  MaxOuterStep=0;
    6869  Deltat=0.01;
     
    7374  MaxPsiStep=0;
    7475  EpsWannier=1e-7;
    75  
     76
    7677  MaxMinStep=100;
    7778  RelEpsTotalEnergy=1e-7;
     
    8485  InitMaxMinStopStep=1;
    8586  InitMaxMinGapStopStep=0;
    86  
     87
    8788  //BoxLength[NDIM*NDIM];
    88  
     89
    8990  ECut=128.;
    9091  MaxLevel=5;
     
    99100  PsiMaxNoDown=0;
    100101  AddPsis=0;
    101  
     102
    102103  RCut=20.;
    103104  StructOpt=0;
     
    199200 * for each entry of the config file structure.
    200201 */
    201 void config::Edit(molecule *mol)
     202void config::Edit()
    202203{
    203204  char choice;
    204  
     205
    205206  do {
    206207    cout << Verbose(0) << "===========EDIT CONFIGURATION============================" << endl;
     
    235236    cout << Verbose(0) << " g - Relative change in kinetic energy to stop min. iteration during initial level" << endl;
    236237    cout << Verbose(0) << " h - Check stop conditions every ..th step during min. iteration during initial level" << endl;
    237     cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl;
     238//    cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl;
    238239    cout << Verbose(0) << " k - Energy cutoff of plane wave basis in Hartree" << endl;
    239240    cout << Verbose(0) << " l - Maximum number of levels in multi-level-ansatz" << endl;
     
    255256    cout << Verbose(0) << "INPUT: ";
    256257    cin >> choice;
    257    
     258
    258259    switch (choice) {
    259260        case 'A': // mainname
     
    380381          cin >> config::InitMaxMinStopStep;
    381382          break;
    382        
    383         case 'j': // BoxLength
    384           cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl;
    385           for (int i=0;i<6;i++) {
    386             cout << Verbose(0) << "Cell size" << i << ": ";
    387             cin >> mol->cell_size[i];
    388           }
    389           break;
    390        
     383
     384//        case 'j': // BoxLength
     385//          cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl;
     386//          for (int i=0;i<6;i++) {
     387//            cout << Verbose(0) << "Cell size" << i << ": ";
     388//            cin >> mol->cell_size[i];
     389//          }
     390//          break;
     391
    391392        case 'k': // ECut
    392393          cout << Verbose(0) << "Old: " << config::ECut << "\t new: ";
     
    462463 * \param *periode pointer to a periodentafel class with all elements
    463464 * \param *mol pointer to molecule containing all atoms of the molecule
    464  * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax 
     465 * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax
    465466 */
    466467int config::TestSyntax(char *filename, periodentafel *periode, molecule *mol)
     
    468469  int test;
    469470  ifstream file(filename);
    470  
     471
    471472  // search file for keyword: ProcPEGamma (new syntax)
    472473  if (ParseForParameter(1,&file,"ProcPEGamma", 0, 1, 1, int_type, &test, 1, optional)) {
     
    539540 * \param *file input file stream being the opened config file
    540541 * \param *periode pointer to a periodentafel class with all elements
    541  * \param *mol pointer to molecule containing all atoms of the molecule 
     542 * \param *mol pointer to molecule containing all atoms of the molecule
    542543 */
    543544void config::Load(char *filename, periodentafel *periode, molecule *mol)
     
    550551  RetrieveConfigPathAndName(filename);
    551552  // ParseParameters
    552  
     553
    553554  /* Oeffne Hauptparameterdatei */
    554555  int di;
     
    595596    config::DoOutCurrent = 0;
    596597  if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
    597   if (config::DoOutCurrent > 1) config::DoOutCurrent = 1; 
     598  if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
    598599  ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
    599600  if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
     
    630631  if (!ParseForParameter(verbose,file,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
    631632    config::EpsWannier = 1e-8;
    632  
     633
    633634  // stop conditions
    634635  //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
    635636  ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
    636637  if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
    637  
     638
    638639  ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
    639640  ParseForParameter(verbose,file,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
     
    644645  if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
    645646  if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
    646  
     647
    647648  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
    648649  ParseForParameter(verbose,file,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
     
    653654  if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
    654655  if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
    655  
     656
    656657  // Unit cell and magnetic field
    657658  ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
     
    669670    config::DoFullCurrent = 0;
    670671  if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
    671   if (config::DoFullCurrent > 2) config::DoFullCurrent = 2; 
     672  if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
    672673  if (config::DoOutNICS < 0) config::DoOutNICS = 0;
    673   if (config::DoOutNICS > 2) config::DoOutNICS = 2; 
     674  if (config::DoOutNICS > 2) config::DoOutNICS = 2;
    674675  if (config::DoPerturbation == 0) {
    675676    config::DoFullCurrent = 0;
     
    688689  } else {
    689690    fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
    690     exit(1); 
     691    exit(1);
    691692  }
    692693  switch (config::RiemannTensor) {
     
    705706      if (config::RiemannLevel < 2) {
    706707        config::RiemannLevel = 2;
    707       } 
     708      }
    708709      if (config::RiemannLevel > config::MaxLevel-1) {
    709710        config::RiemannLevel = config::MaxLevel-1;
     
    712713      if (config::LevRFactor < 2) {
    713714        config::LevRFactor = 2;
    714       } 
     715      }
    715716      config::Lev0Factor = 2;
    716717      config::RTActualUse = 2;
     
    722723  } else {
    723724    fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
    724     exit(1); 
     725    exit(1);
    725726  }
    726727  switch (config::PsiType) {
     
    736737    break;
    737738  }
    738  
     739
    739740  // IonsInitRead
    740  
     741
    741742  ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
    742743  ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
     
    756757      ParseForParameter(verbose,file, name, 0, 2, 1, int_type, &Z, 1, critical);
    757758      elementhash[i] = periode->FindElement(Z);
    758       cout << Verbose(1) << i << ". Z = " << elementhash[i]->Z << " with " << No[i] << " ions." << endl; 
     759      cout << Verbose(1) << i << ". Z = " << elementhash[i]->Z << " with " << No[i] << " ions." << endl;
    759760    }
    760761    int repetition = 0; // which repeated keyword shall be read
    761  
     762
    762763    map<int, atom *> AtomList[config::MaxTypes];
    763764    if (!FastParsing) {
     
    778779            } else
    779780              neues = AtomList[i][j];
    780             status = (status && 
     781            status = (status &&
    781782                    ParseForParameter(verbose,file, keyword, 0, 1, 1, double_type, &neues->x.x[0], 1, (repetition == 0) ? critical : optional) &&
    782783                    ParseForParameter(verbose,file, keyword, 0, 2, 1, double_type, &neues->x.x[1], 1, (repetition == 0) ? critical : optional) &&
     
    784785                    ParseForParameter(verbose,file, keyword, 0, 4, 1, int_type, &neues->FixedIon, 1, (repetition == 0) ? critical : optional));
    785786            if (!status) break;
    786    
     787
    787788            // check size of vectors
    788789            if (mol->Trajectories[neues].R.size() <= (unsigned int)(repetition)) {
     
    792793              mol->Trajectories[neues].F.resize(repetition+10);
    793794            }
    794          
     795
    795796            // put into trajectories list
    796797            for (int d=0;d<NDIM;d++)
    797798              mol->Trajectories[neues].R.at(repetition).x[d] = neues->x.x[d];
    798            
     799
    799800            // parse velocities if present
    800801            if(!ParseForParameter(verbose,file, keyword, 0, 5, 1, double_type, &neues->v.x[0], 1,optional))
     
    806807            for (int d=0;d<NDIM;d++)
    807808              mol->Trajectories[neues].U.at(repetition).x[d] = neues->v.x[d];
    808      
     809
    809810            // parse forces if present
    810811            if(!ParseForParameter(verbose,file, keyword, 0, 8, 1, double_type, &value[0], 1,optional))
     
    816817            for (int d=0;d<NDIM;d++)
    817818              mol->Trajectories[neues].F.at(repetition).x[d] = value[d];
    818  
    819   //            cout << "Parsed position of step " << (repetition) << ": ("; 
     819
     820  //            cout << "Parsed position of step " << (repetition) << ": (";
    820821  //            for (int d=0;d<NDIM;d++)
    821822  //              cout << mol->Trajectories[neues].R.at(repetition).x[d] << " ";          // next step
     
    873874 * \param *file input file stream being the opened config file with old pcp syntax
    874875 * \param *periode pointer to a periodentafel class with all elements
    875  * \param *mol pointer to molecule containing all atoms of the molecule 
     876 * \param *mol pointer to molecule containing all atoms of the molecule
    876877 */
    877878void config::LoadOld(char *filename, periodentafel *periode, molecule *mol)
     
    884885  RetrieveConfigPathAndName(filename);
    885886  // ParseParameters
    886  
     887
    887888  /* Oeffne Hauptparameterdatei */
    888889  int l, i, di;
     
    894895  int Z, No, AtomNo, found;
    895896  int verbose = 0;
    896  
     897
    897898  /* Namen einlesen */
    898899
     
    926927  ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
    927928  config::EpsWannier = 1e-8;
    928  
     929
    929930  // stop conditions
    930931  //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
    931932  ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
    932933  if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
    933  
     934
    934935  ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
    935936  ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
     
    939940  if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
    940941  config::MaxMinGapStopStep = 1;
    941  
     942
    942943  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
    943944  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
     
    970971  } else {
    971972    fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
    972     exit(1); 
     973    exit(1);
    973974  }
    974975  switch (config::RiemannTensor) {
     
    987988      if (config::RiemannLevel < 2) {
    988989        config::RiemannLevel = 2;
    989       } 
     990      }
    990991      if (config::RiemannLevel > config::MaxLevel-1) {
    991992        config::RiemannLevel = config::MaxLevel-1;
     
    994995      if (config::LevRFactor < 2) {
    995996        config::LevRFactor = 2;
    996       } 
     997      }
    997998      config::Lev0Factor = 2;
    998999      config::RTActualUse = 2;
     
    10041005  } else {
    10051006    fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
    1006     exit(1); 
     1007    exit(1);
    10071008  }
    10081009  switch (config::PsiType) {
     
    10181019    break;
    10191020  }
    1020  
     1021
    10211022  // IonsInitRead
    1022  
     1023
    10231024  ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
    10241025  ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
     
    10271028
    10281029  // Routine from builder.cpp
    1029  
    1030  
    1031   for (i=MAX_ELEMENTS;i--;) 
     1030
     1031
     1032  for (i=MAX_ELEMENTS;i--;)
    10321033    elementhash[i] = NULL;
    10331034  cout << Verbose(0) << "Parsing Ions ..." << endl;
     
    10401041    }
    10411042    if (found > 0) {
    1042       if (zeile.find("Ions_Data") == 0) 
     1043      if (zeile.find("Ions_Data") == 0)
    10431044        getline(*file,zeile,'\n'); // read next line and parse this one
    10441045      istringstream input(zeile);
     
    10691070      No++;
    10701071    }
    1071   }   
     1072  }
    10721073  file->close();
    10731074  delete(file);
     
    10771078 * \param *filename name of file
    10781079 * \param *periode pointer to a periodentafel class with all elements
    1079  * \param *mol pointer to molecule containing all atoms of the molecule 
     1080 * \param *mol pointer to molecule containing all atoms of the molecule
    10801081 */
    10811082bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
     
    12071208 * Note that this format cannot be parsed again.
    12081209 * \param *filename name of file (without ".in" suffix!)
    1209  * \param *mol pointer to molecule containing all atoms of the molecule 
     1210 * \param *mol pointer to molecule containing all atoms of the molecule
    12101211 */
    12111212bool config::SaveMPQC(const char *filename, molecule *mol) const
     
    12181219  ofstream *output = NULL;
    12191220  stringstream *fname = NULL;
    1220  
     1221
    12211222  // first without hessian
    12221223  fname = new stringstream;
     
    12271228  *output << "\tsavestate = no" << endl;
    12281229  *output << "\tdo_gradient = yes" << endl;
    1229   *output << "\tmole<CLHF>: (" << endl;
     1230  *output << "\tmole<MBPT2>: (" << endl;
    12301231  *output << "\t\tmaxiter = 200" << endl;
    12311232  *output << "\t\tbasis = $:basis" << endl;
    12321233  *output << "\t\tmolecule = $:molecule" << endl;
     1234  *output << "\t\treference<CLHF>: (" << endl;
     1235  *output << "\t\t\tbasis = $:basis" << endl;
     1236  *output << "\t\t\tmolecule = $:molecule" << endl;
     1237  *output << "\t\t)" << endl;
    12331238  *output << "\t)" << endl;
    12341239  *output << ")" << endl;
     
    13131318  delete(output);
    13141319  delete(fname);
    1315  
     1320
    13161321  return true;
    13171322};
     
    13251330 * \param file file to be parsed
    13261331 * \param name Name of value in file (at least 3 chars!)
    1327  * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning 
     1332 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
    13281333 *        (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
    13291334 *         best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
     
    13451350  dummy1 = free_dummy = (char *) Malloc(256 * sizeof(char), "config::ParseForParameter: *free_dummy");
    13461351
    1347   //fprintf(stderr,"Parsing for %s\n",name); 
     1352  //fprintf(stderr,"Parsing for %s\n",name);
    13481353  if (repetition == 0)
    13491354    //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
     
    13661371          file->clear();
    13671372          file->seekg(file_position, ios::beg);  // rewind to start position
    1368           Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");         
     1373          Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    13691374          return 0;
    13701375        }
     
    13721377      line++;
    13731378    } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
    1374    
     1379
    13751380    // C++ getline removes newline at end, thus re-add
    13761381    if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
     
    13981403        //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
    13991404        //Free((void **)&free_dummy);
    1400         //Error(FileOpenParams, NULL);     
     1405        //Error(FileOpenParams, NULL);
    14011406      } else {
    14021407        //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
     
    14071412    if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
    14081413      found++; // found the parameter!
    1409       //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);   
    1410      
     1414      //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
     1415
    14111416      if (found == repetition) {
    14121417        for (i=0;i<xth;i++) { // i = rows
     
    14471452            dummy1[j+1] = '\0';
    14481453          }
    1449  
     1454
    14501455          int start = (type >= grid) ? 0 : yth-1 ;
    14511456          for (j=start;j<yth;j++) { // j = columns
     
    14701475                    //return 0;
    14711476                    exit(255);
    1472                     //Error(FileOpenParams, NULL);     
     1477                    //Error(FileOpenParams, NULL);
    14731478                  } else {
    14741479                    //if (!sequential)
     
    14851490                // found comment, skipping rest of line
    14861491                //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
    1487                 if (!sequential) { // here we need it! 
     1492                if (!sequential) { // here we need it!
    14881493                  file->seekg(file_position, ios::beg);  // rewind to start position
    14891494                }
     
    15001505                    //value += sizeof(int);
    15011506                  break;
    1502                 case(row_double): 
     1507                case(row_double):
    15031508                case(grid):
    15041509                case(lower_trigrid):
     
    15411546      }
    15421547    }
    1543   } 
     1548  }
    15441549  if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
    15451550  Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     
    15491554  }
    15501555  //fprintf(stderr, "End of Parsing\n\n");
    1551  
     1556
    15521557  return (found); // true if found, false if not
    15531558}
  • src/datacreator.cpp

    rce5ac3 rd067d45  
    11/** \file datacreator.cpp
    22 *
    3  * Declarations of assisting functions in creating data and plot files. 
    4  *   
     3 * Declarations of assisting functions in creating data and plot files.
     4 *
    55 */
    66
     
    2727  }
    2828  return true;
    29 }; 
     29};
    3030
    3131/** Opens a file for appending with \a *filename in \a *dir.
     
    4545  }
    4646  return true;
    47 }; 
     47};
    4848
    4949/** Plots an energy vs. order.
     
    5454 * \return true if file was written successfully
    5555 */
    56 bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum) 
    57 {
    58   stringstream filename;
    59   ofstream output;
    60 
    61   filename << prefix << ".dat";
    62   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     56bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
     57{
     58  stringstream filename;
     59  ofstream output;
     60
     61  filename << prefix << ".dat";
     62  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    6363  cout << msg << endl;
    6464  output << "# " << msg << ", created on " << datum;
     
    8787 * \return true if file was written successfully
    8888 */
    89 bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum) 
    90 {
    91   stringstream filename;
    92   ofstream output;
    93 
    94   filename << prefix << ".dat";
    95   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     89bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
     90{
     91  stringstream filename;
     92  ofstream output;
     93
     94  filename << prefix << ".dat";
     95  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    9696  cout << msg << endl;
    9797  output << "# " << msg << ", created on " << datum;
     
    130130
    131131  filename << prefix << ".dat";
    132   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     132  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    133133  cout << msg << endl;
    134134  output << "# " << msg << ", created on " << datum;
     
    162162
    163163  filename << prefix << ".dat";
    164   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     164  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    165165  cout << msg << endl;
    166166  output << "# " << msg << ", created on " << datum;
     
    188188 * \return true if file was written successfully
    189189 */
    190 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum) 
     190bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
    191191{
    192192  stringstream filename;
     
    195195
    196196  filename << prefix << ".dat";
    197   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     197  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    198198  cout << msg << endl;
    199199  output << "# " << msg << ", created on " << datum;
     
    205205    // errors per atom
    206206    output << endl << "#Order\t" << BondOrder+1 << endl;
    207     for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 
     207    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    208208      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    209209      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
     
    213213            norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m];
    214214          norm = sqrt(norm);
    215         }                                                                                                           
     215        }                                                                                                   
    216216//        if (norm < MYEPSILON)
    217217          output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     
    235235 * \return true if file was written successfully
    236236 */
    237 bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum) 
    238 {
    239   stringstream filename;
    240   ofstream output;
    241 
    242   filename << prefix << ".dat";
    243   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     237bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
     238{
     239  stringstream filename;
     240  ofstream output;
     241
     242  filename << prefix << ".dat";
     243  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    244244  cout << msg << endl;
    245245  output << "# " << msg << ", created on " << datum;
     
    250250    // errors per atom
    251251    output << endl << "#Order\t" << BondOrder+1 << endl;
    252     for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 
     252    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    253253      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    254254      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
     
    390390
    391391  filename << prefix << ".dat";
    392   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     392  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    393393  cout << msg << endl;
    394394  output << "# " << msg << ", created on " << datum << endl;
     
    411411 * \param &KeySet KeySetsContainer with associations of each fragment to a bond order
    412412 * \param BondOrder current bond order
    413  */ 
     413 */
    414414void CreateMaxFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet, int BondOrder)
    415415{
     
    420420          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    421421      }
    422     }     
     422    }
    423423  }
    424424};
     
    428428 * \param &KeySet KeySetsContainer with associations of each fragment to a bond order
    429429 * \param BondOrder current bond order
    430  */ 
     430 */
    431431void CreateMinFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet, int BondOrder)
    432432{
     
    443443          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    444444      }
    445     }     
     445    }
    446446  }
    447447};
     
    455455
    456456  filename << prefix << ".dat";
    457   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     457  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    458458  cout << msg << endl;
    459459  output << "# " << msg << ", created on " << datum;
     
    496496    do {
    497497      for (int m=NDIM;m--;) {
    498         stored += Force.Matrix[MatrixNumber][ k ][l+m] 
     498        stored += Force.Matrix[MatrixNumber][ k ][l+m]
    499499              * Force.Matrix[MatrixNumber][ k ][l+m];
    500         Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m]; 
     500        Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
    501501      }
    502502      k++;
     
    505505      double tmp = 0;
    506506      for (int m=NDIM;m--;)
    507         tmp += Force.Matrix[MatrixNumber][ k ][l+m] 
     507        tmp += Force.Matrix[MatrixNumber][ k ][l+m]
    508508              * Force.Matrix[MatrixNumber][ k ][l+m];
    509509      if ((fabs(tmp) > MYEPSILON) && (tmp < stored)) {  // current force is greater than stored
    510510        for (int m=NDIM;m--;)
    511           Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m]; 
     511          Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
    512512        stored = tmp;
    513513      }
     
    531531      double norm = 0.;
    532532      for (int m=NDIM;m--;)
    533         norm += Force.Matrix[MatrixNumber][ k ][l+m] 
     533        norm += Force.Matrix[MatrixNumber][ k ][l+m]
    534534              * Force.Matrix[MatrixNumber][ k ][l+m];
    535535      tmp += sqrt(norm);
     
    553553      double tmp = 0;
    554554      for (int m=NDIM;m--;)
    555         tmp += Force.Matrix[MatrixNumber][ k ][l+m] 
     555        tmp += Force.Matrix[MatrixNumber][ k ][l+m]
    556556              * Force.Matrix[MatrixNumber][ k ][l+m];
    557557      if (tmp > stored) {  // current force is greater than stored
    558558        for (int m=NDIM;m--;)
    559           Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m]; 
     559          Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
    560560        stored = tmp;
    561561      }
     
    592592 * \param *key position of key
    593593 * \param *logscale axis for logscale
    594  * \param *extraline extra set lines if desired 
     594 * \param *extraline extra set lines if desired
    595595 * \param mxtics small tics at ...
    596596 * \param xtics large tics at ...
    597  * \param *xlabel label for x axis 
     597 * \param *xlabel label for x axis
    598598 * \param *ylabel label for y axis
    599  */ 
     599 */
    600600void CreatePlotHeader(ofstream &output, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel)
    601601{
     
    626626 * \param mxtics small tics at ...
    627627 * \param xtics large tics at ...
    628  * \param xlabel label for x axis 
     628 * \param xlabel label for x axis
    629629 * \param xlabel label for x axis
    630630 * \param *xrange xrange
     
    634634 * \param (*CreatePlotLines) function reference that writes a single plot line
    635635 * \return true if file was written successfully
    636  */   
     636 */
    637637bool CreatePlotOrder(class MatrixContainer &Matrix, const class KeySetsContainer &KeySet, const char *dir, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel, const char *xrange, const char *yrange, const char *xargument, const char *uses, void (*CreatePlotLines)(ofstream &, class MatrixContainer &, const char *, const char *, const char *))
    638638{
     
    641641
    642642  filename << prefix << ".pyx";
    643   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 
     643  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    644644  CreatePlotHeader(output, prefix, keycolumns, key, logscale, extraline, mxtics, xtics, xlabel, ylabel);
    645645  output << "plot " << xrange << " " << yrange << " \\" << endl;
    646646  CreatePlotLines(output, Matrix, prefix, xargument, uses);
    647   output.close(); 
     647  output.close();
    648648  return true;
    649649};
  • src/datacreator.hpp

    rce5ac3 rd067d45  
    11/** \file datacreator.cpp
    22 *
    3  * Definitions of assisting functions in creating data and plot files. 
    4  *   
     3 * Definitions of assisting functions in creating data and plot files.
     4 *
    55 */
    66
     
    1212//============================ INCLUDES ===========================
    1313
    14 #include "helpers.hpp" 
     14#include "helpers.hpp"
    1515#include "parser.hpp"
    1616
     
    2020bool AppendOutputFile(ofstream &output, const char *dir, const char *filename);
    2121
    22 bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum); 
    23 bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum); 
     22bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     23bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    2424bool CreateDataForcesOrder(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateForce)(class MatrixContainer &, int));
    2525bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
  • src/element.cpp

    rce5ac3 rd067d45  
    1212 */
    1313element::element() {
    14   Z = -1;
    15   No = -1;
    16   previous = NULL;
    17   next = NULL;
    18   sort = NULL;
     14        Z = -1;
     15        No = -1;
     16        previous = NULL;
     17        next = NULL;
     18        sort = NULL;
    1919};
    2020
     
    2828bool element::Output(ofstream *out) const
    2929{
    30   if (out != NULL) {
    31     *out << name << "\t" << symbol << "\t" << period << "\t" << group << "\t" << block << "\t" << Z << "\t" << mass << "\t" << CovalentRadius << "\t" << VanDerWaalsRadius << endl;
    32     //*out << Z << "\t"  << fixed << setprecision(11) << showpoint << mass << "g/mol\t" << name << "\t" << symbol << "\t" << endl;
    33     return true;
    34   } else
    35     return false;
     30        if (out != NULL) {
     31                *out << name << "\t" << symbol << "\t" << period << "\t" << group << "\t" << block << "\t" << Z << "\t" << mass << "\t" << CovalentRadius << "\t" << VanDerWaalsRadius << endl;
     32                //*out << Z << "\t"     << fixed << setprecision(11) << showpoint << mass << "g/mol\t" << name << "\t" << symbol << "\t" << endl;
     33                return true;
     34        } else
     35                return false;
    3636};
    3737
    3838/** Prints element data to \a *out.
    3939 * \param *out outstream
    40  * \param No  cardinal number of element
     40 * \param No    cardinal number of element
    4141 * \param NoOfAtoms total number of atom of this element type
    4242 */
    4343bool element::Checkout(ofstream *out, const int Number, const int NoOfAtoms) const
    4444{
    45   if (out != NULL) {
    46     *out << "Ion_Type" << Number << "\t" << NoOfAtoms << "\t" << Z << "\t1.0\t3\t3\t" << fixed << setprecision(11) << showpoint << mass << "\t" << name << "\t" << symbol <<endl;
    47     return true;
    48   } else
    49     return false;
     45        if (out != NULL) {
     46                *out << "Ion_Type" << Number << "\t" << NoOfAtoms << "\t" << Z << "\t1.0\t3\t3\t" << fixed << setprecision(11) << showpoint << mass << "\t" << name << "\t" << symbol <<endl;
     47                return true;
     48        } else
     49                return false;
    5050};
  • src/graph.cpp

    rce5ac3 rd067d45  
    11/** \file graph.cpp
    2  * 
     2 *
    33 * Function implementations for the class graph.
    4  * 
     4 *
    55 */
    66
  • src/helpers.cpp

    rce5ac3 rd067d45  
    11/** \file helpers.cpp
    22 *
    3  * Implementation of some auxiliary functions for memory dis-/allocation and so on 
     3 * Implementation of some auxiliary functions for memory dis-/allocation and so on
    44 */
    55
     
    1515double ask_value(const char *text)
    1616{
    17   double test = 0.1439851348959832147598734598273456723948652983045928346598365;
    18   do {
    19     cout << Verbose(0) << text;
    20     cin >> test;
    21   } while (test == 0.1439851348959832147598734598273456723948652983045928346598365);
    22   return test;   
     17        double test = 0.1439851348959832147598734598273456723948652983045928346598365;
     18        do {
     19                cout << Verbose(0) << text;
     20                cin >> test;
     21        } while (test == 0.1439851348959832147598734598273456723948652983045928346598365);
     22        return test;
    2323};
    2424
     
    2929#ifdef HAVE_DEBUG
    3030void debug_in(const char *output, const char *file, const int line) {
    31   if (output) fprintf(stderr,"DEBUG: in %s at line %i: %s\n", file, line, output);
     31        if (output) fprintf(stderr,"DEBUG: in %s at line %i: %s\n", file, line, output);
    3232}
    3333#else
    34 void debug_in(const char *output, const char *file, const int line) {}  // print nothing
     34void debug_in(const char *output, const char *file, const int line) {}  // print nothing
    3535#endif
    3636
     
    4040 * \return pointer to memory range
    4141 */
    42 void * Malloc(size_t size, const char* output) 
     42void * Malloc(size_t size, const char* output)
    4343{
    44   void *buffer = NULL;
    45   buffer = (void *)malloc(size); // alloc
    46   if (buffer == NULL)
    47     cout << Verbose(0) << "Malloc failed - pointer is NULL: " << output << endl;
    48   return(buffer);
     44        void *buffer = NULL;
     45        buffer = (void *)malloc(size); // alloc
     46        if (buffer == NULL)
     47                cout << Verbose(0) << "Malloc failed - pointer is NULL: " << output << endl;
     48        return(buffer);
    4949};
    5050
     
    5454 * \return pointer to memory range
    5555 */
    56 void * Calloc(size_t size, const char* output) 
     56void * Calloc(size_t size, const char* output)
    5757{
    58   void *buffer = NULL;
    59   buffer = (void *)calloc(size, (size_t)0); // alloc
    60   if (buffer == NULL)
    61     cout << Verbose(0) << "Calloc failed - pointer is NULL: " << output << endl;
    62   return(buffer);
     58        void *buffer = NULL;
     59        buffer = (void *)calloc(size, (size_t)0); // alloc
     60        if (buffer == NULL)
     61                cout << Verbose(0) << "Calloc failed - pointer is NULL: " << output << endl;
     62        return(buffer);
    6363};
    6464
     
    6969 * \return pointer to memory range
    7070 */
    71 void * ReAlloc(void * OldPointer, size_t size, const char* output) 
     71void * ReAlloc(void * OldPointer, size_t size, const char* output)
    7272{
    7373  void *buffer = NULL;
     
    8686 * \param *output message if free fails
    8787 */
    88 void Free(void ** buffer, const char* output) 
     88void Free(void ** buffer, const char* output)
    8989{
    90   if (*buffer == NULL) {
    91     //cout << Verbose(5) << "Free not necesary: " << output << endl;
    92   } else {
    93     free(*buffer);
    94     *buffer = NULL;
    95   }
     90        if (*buffer == NULL) {
     91                //cout << Verbose(5) << "Free not necesary: " << output << endl;
     92        } else {
     93                free(*buffer);
     94                *buffer = NULL;
     95        }
    9696};
    9797
     
    101101 * \return pointer to string array
    102102 */
    103 char* MallocString(size_t size, const char* output) 
     103char* MallocString(size_t size, const char* output)
    104104{
    105   size_t i;
    106   char *buffer;
    107   buffer = (char *)malloc(sizeof(char) * (size+1)); // alloc
    108   if (buffer == NULL)
    109     cout << Verbose(0) << output << endl;
    110   for (i=size;i--;)  // reset
    111     buffer[i] = i % 2 == 0 ? 'p': 'c';
    112   buffer[size] = '\0'; // and set length marker on its end
    113   return(buffer);
     105        size_t i;
     106        char *buffer;
     107        buffer = (char *)malloc(sizeof(char) * (size+1)); // alloc
     108        if (buffer == NULL)
     109                cout << Verbose(0) << output << endl;
     110        for (i=size;i--;)       // reset
     111                buffer[i] = i % 2 == 0 ? 'p': 'c';
     112        buffer[size] = '\0'; // and set length marker on its end
     113        return(buffer);
    114114}
    115115
     
    121121void bound(double *b, double lower_bound, double upper_bound)
    122122{
    123   double step = (upper_bound - lower_bound);
    124   while (*b >= upper_bound)
    125     *b -= step;   
    126   while (*b < lower_bound)
    127     *b += step;   
    128 }; 
     123        double step = (upper_bound - lower_bound);
     124        while (*b >= upper_bound)
     125                *b -= step;
     126        while (*b < lower_bound)
     127                *b += step;
     128};
    129129
    130130/** Flips two doubles.
     
    134134void flip(double *x, double *y)
    135135{
    136   double tmp;
    137   tmp = *x;
    138   *x = *y;
    139   *y = tmp;
     136        double tmp;
     137        tmp = *x;
     138        *x = *y;
     139        *y = tmp;
    140140};
    141141
     
    147147int pot(int base, int n)
    148148{
    149   int res = 1;
    150   int j;
    151   for (j=n;j--;)
    152     res *= base;
    153   return res;
     149        int res = 1;
     150        int j;
     151        for (j=n;j--;)
     152                res *= base;
     153        return res;
    154154};
    155155
     
    161161char *FixedDigitNumber(const int FragmentNumber, const int digits)
    162162{
    163   char *returnstring;
    164   int number = FragmentNumber;
    165   int order = 0;
    166   while (number != 0) { // determine number of digits needed
    167     number = (int)floor(((double)number / 10.));
    168     order++;
    169     //cout << "Number is " << number << ", order is " << order << "." << endl;
    170   }
    171   // allocate string
    172   returnstring = (char *) Malloc(sizeof(char)*(order+2), "MoleculeListClass::CreateFragmentNumberForOutput: *returnstring");
    173   // terminate  and fill string array from end backward
    174   returnstring[order] = '\0';
    175   number = digits;
    176   for (int i=order;i--;) {
    177     returnstring[i] = '0' + (char)(number % 10);
    178     number = (int)floor(((double)number / 10.));
    179   }
    180   //cout << returnstring << endl;
    181   return returnstring;
     163        char *returnstring;
     164        int number = FragmentNumber;
     165        int order = 0;
     166        while (number != 0) { // determine number of digits needed
     167                number = (int)floor(((double)number / 10.));
     168                order++;
     169                //cout << "Number is " << number << ", order is " << order << "." << endl;
     170        }
     171        // allocate string
     172        returnstring = (char *) Malloc(sizeof(char)*(order+2), "FixedDigitNumber: *returnstring");
     173        // terminate    and fill string array from end backward
     174        returnstring[order] = '\0';
     175        number = digits;
     176        for (int i=order;i--;) {
     177                returnstring[i] = '0' + (char)(number % 10);
     178                number = (int)floor(((double)number / 10.));
     179        }
     180        //cout << returnstring << endl;
     181        return returnstring;
    182182};
    183183
     
    186186 * \return true - is a number, false - is not a valid number
    187187 */
    188 bool IsValidNumber( const char *string) 
     188bool IsValidNumber( const char *string)
    189189{
    190   int ptr = 0;
    191   if ((string[ptr] == '.') || (string[ptr] == '-')) // number may be negative or start with dot
    192     ptr++;
    193   if ((string[ptr] >= '0') && (string[ptr] <= '9'))
    194     return true;
    195   return false;
     190        int ptr = 0;
     191        if ((string[ptr] == '.') || (string[ptr] == '-')) // number may be negative or start with dot
     192                ptr++;
     193        if ((string[ptr] >= '0') && (string[ptr] <= '9'))
     194                return true;
     195        return false;
    196196};
    197197
  • src/helpers.hpp

    rce5ac3 rd067d45  
    11/** \file helpers.hpp
    22 *
    3  * Declaration of some auxiliary functions for memory dis-/allocation and so on 
     3 * Declaration of some auxiliary functions for memory dis-/allocation and so on
    44 */
    55
     
    3838
    3939/* Behandelt aufgetretene Fehler. error ist der Fehlertyp(enum Errors)
    40   void *SpecialData ist ein untypisierter Zeiger auf Spezielle Daten zur Fehlerbehandlung.
    41   Man koennte auch noch einen Zeiger auf eine Funktion uebergeben */
     40        void *SpecialData ist ein untypisierter Zeiger auf Spezielle Daten zur Fehlerbehandlung.
     41        Man koennte auch noch einen Zeiger auf eine Funktion uebergeben */
    4242extern void /*@exits@*/ debug(const char *output);
    43   //__attribute__ ((__return__));
     43        //__attribute__ ((__return__));
    4444#define debug(data) debug_in((data), __FILE__, __LINE__)
    4545
    4646extern void /*@exits@*/ debug_in(const char *output,
    47     const char *file, const int line);
    48   //__attribute__ ((__return__));
     47                const char *file, const int line);
     48        //__attribute__ ((__return__));
    4949
    5050double ask_value(const char *text);
     
    7373template <typename T> bool CreateFatherLookupTable(ofstream *out, T *start, T *end, T **&LookupTable, int count = 0)
    7474{
    75   bool status = true;
    76   T *Walker = NULL;
    77   int AtomNo;
    78  
    79   if (LookupTable != NULL) {
    80     *out << "Pointer for Lookup table is not NULL! Aborting ..." <<endl;
    81     return false;
    82   }
    83  
    84   // count them
    85   if (count == 0) {
    86     Walker = start;
    87     while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
    88       Walker = Walker->next;
    89       count = (count < Walker->GetTrueFather()->nr) ? Walker->GetTrueFather()->nr : count;
    90     }
    91   }
    92   if (count <= 0) {
    93     *out << "Count of lookup list is 0 or less." << endl;
    94     return false;
    95   }
    96 
    97   // allocat and fill
    98   LookupTable = (T **) Malloc(sizeof(T *)*count, "CreateFatherLookupTable - **LookupTable");
    99   if (LookupTable == NULL) {
    100     cerr << "LookupTable memory allocation failed!" << endl;
    101     status = false;
    102   } else {
    103     for (int i=0;i<count;i++)
    104       LookupTable[i] = NULL;
    105     Walker = start;
    106     while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
    107       Walker = Walker->next;
    108       AtomNo = Walker->GetTrueFather()->nr;
    109       if ((AtomNo >= 0) && (AtomNo < count)) {
    110         //*out << "Setting LookupTable[" << AtomNo << "] to " << *Walker << endl;
    111         LookupTable[AtomNo] = Walker;
    112       } else {
    113         *out << "Walker " << *Walker << " exceeded range of nuclear ids [0, " << count << ")." << endl;
    114         status = false;
    115         break;
    116       }
    117     }
    118   }
    119  
    120   return status;
     75        bool status = true;
     76        T *Walker = NULL;
     77        int AtomNo;
     78
     79        if (LookupTable != NULL) {
     80                *out << "Pointer for Lookup table is not NULL! Aborting ..." <<endl;
     81                return false;
     82        }
     83
     84        // count them
     85        if (count == 0) {
     86                Walker = start;
     87                while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
     88                        Walker = Walker->next;
     89                        count = (count < Walker->GetTrueFather()->nr) ? Walker->GetTrueFather()->nr : count;
     90                }
     91        }
     92        if (count <= 0) {
     93                *out << "Count of lookup list is 0 or less." << endl;
     94                return false;
     95        }
     96
     97        // allocat and fill
     98        LookupTable = (T **) Malloc(sizeof(T *)*count, "CreateFatherLookupTable - **LookupTable");
     99        if (LookupTable == NULL) {
     100                cerr << "LookupTable memory allocation failed!" << endl;
     101                status = false;
     102        } else {
     103                for (int i=0;i<count;i++)
     104                        LookupTable[i] = NULL;
     105                Walker = start;
     106                while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
     107                        Walker = Walker->next;
     108                        AtomNo = Walker->GetTrueFather()->nr;
     109                        if ((AtomNo >= 0) && (AtomNo < count)) {
     110                                //*out << "Setting LookupTable[" << AtomNo << "] to " << *Walker << endl;
     111                                LookupTable[AtomNo] = Walker;
     112                        } else {
     113                                *out << "Walker " << *Walker << " exceeded range of nuclear ids [0, " << count << ")." << endl;
     114                                status = false;
     115                                break;
     116                        }
     117                }
     118        }
     119
     120        return status;
    121121};
    122122
     
    129129template <typename X> void link(X *walker, X *end)
    130130{
    131   X *vorher = end->previous;
    132   if (vorher != NULL)
    133     vorher->next = walker;
    134   end->previous = walker;
    135   walker->previous = vorher;
    136   walker->next = end;
     131        X *vorher = end->previous;
     132        if (vorher != NULL)
     133                vorher->next = walker;
     134        end->previous = walker;
     135        walker->previous = vorher;
     136        walker->next = end;
    137137};
    138138
     
    143143template <typename X> void unlink(X *walker)
    144144{
    145   if (walker->next != NULL)
    146     walker->next->previous = walker->previous;
    147   if (walker->previous != NULL)
    148     walker->previous->next = walker->next;
     145        if (walker->next != NULL)
     146                walker->next->previous = walker->previous;
     147        if (walker->previous != NULL)
     148                walker->previous->next = walker->next;
    149149};
    150150
    151151/** Adds new item before an item \a *end in a list.
    152  * \param *pointer  item to be added
    153  * \param *end  end of list
     152 * \param *pointer      item to be added
     153 * \param *end  end of list
    154154 * \return true - addition succeeded, false - unable to add item to list
    155155 */
    156 template <typename X>  bool add(X *pointer, X *end)
    157 {
    158   if (end != NULL) {
    159     link(pointer, end);
    160   } else {
    161     pointer->previous = NULL;
    162     pointer->next = NULL;
    163   }
    164   return true;
     156template <typename X>   bool add(X *pointer, X *end)
     157{
     158        if (end != NULL) {
     159                link(pointer, end);
     160        } else {
     161                pointer->previous = NULL;
     162                pointer->next = NULL;
     163        }
     164        return true;
    165165};
    166166
    167167/** Finds item in list
    168  * \param *suche  search criteria
    169  * \param *start  begin of list
    170  * \param *end  end of list
     168 * \param *suche        search criteria
     169 * \param *start        begin of list
     170 * \param *end  end of list
    171171 * \return X - if found, NULL - if not found
    172172 */
    173173template <typename X, typename Y> X * find(Y *suche, X *start, X *end)
    174174{
    175   X *walker = start;
    176   while (walker->next != end) { // go through list
    177     walker = walker->next; // step onward beforehand
    178     if (*walker->sort == *suche) return (walker);
    179   }
    180   return NULL;
     175        X *walker = start;
     176        while (walker->next != end) { // go through list
     177                walker = walker->next; // step onward beforehand
     178                if (*walker->sort == *suche) return (walker);
     179        }
     180        return NULL;
    181181};
    182182
     
    187187template <typename X> void removewithoutcheck(X *walker)
    188188{
    189   if (walker != NULL) {
    190     unlink(walker);
    191     delete(walker);
    192     walker = NULL;
    193   }
     189        if (walker != NULL) {
     190                unlink(walker);
     191                delete(walker);
     192                walker = NULL;
     193        }
    194194};
    195195
    196196/** Removes an item from the list, checks if exists.
    197197 * Checks beforehand if atom is really within molecule list.
    198  * \param *pointer  item to be removed
    199  * \param *start  begin of list
    200  * \param *end  end of list
     198 * \param *pointer      item to be removed
     199 * \param *start        begin of list
     200 * \param *end  end of list
    201201 * \return true - removing succeeded, false - given item not found in list
    202202 */
    203203template <typename X> bool remove(X *pointer, X *start, X *end)
    204204{
    205   X *walker = find (pointer->sort, start, end);
    206 /*  while (walker->next != pointer) { // search through list
    207     walker = walker->next;
    208     if (walker == end) return false;  // item not found in list
    209   }*/
    210   // atom found, now unlink
    211   if (walker != NULL)
    212     removewithoutcheck(walker);
    213   else
    214     return false;
    215   return true;
     205        X *walker = find (pointer->sort, start, end);
     206/*      while (walker->next != pointer) { // search through list
     207                walker = walker->next;
     208                if (walker == end) return false;        // item not found in list
     209        }*/
     210        // atom found, now unlink
     211        if (walker != NULL)
     212                removewithoutcheck(walker);
     213        else
     214                return false;
     215        return true;
    216216};
    217217
     
    223223template <typename X> bool cleanup(X *start, X *end)
    224224{
    225   X *pointer = start->next;
    226   X *walker;
    227   while (pointer != end) { // go through list
    228     walker = pointer; // mark current
    229     pointer = pointer->next; // step onward beforehand
    230     // remove walker
    231     unlink(walker);
    232     delete(walker);
    233     walker = NULL;
    234   }
    235   return true;
     225        X *pointer = start->next;
     226        X *walker;
     227        while (pointer != end) { // go through list
     228                walker = pointer; // mark current
     229                pointer = pointer->next; // step onward beforehand
     230                // remove walker
     231                unlink(walker);
     232                delete(walker);
     233                walker = NULL;
     234        }
     235        return true;
    236236};
    237237
     
    242242template <typename X> X *GetFirst(X *me)
    243243{
    244   X *Binder = me;
    245   while(Binder->previous != NULL)
    246     Binder = Binder->previous;
    247   return Binder;
    248 }; 
     244        X *Binder = me;
     245        while(Binder->previous != NULL)
     246                Binder = Binder->previous;
     247        return Binder;
     248};
    249249
    250250/** Returns the last marker in a chain list.
     
    254254template <typename X> X *GetLast(X *me)
    255255{
    256   X *Binder = me;
    257   while(Binder->next != NULL)
    258     Binder = Binder->next;
    259   return Binder;
    260 }; 
     256        X *Binder = me;
     257        while(Binder->next != NULL)
     258                Binder = Binder->next;
     259        return Binder;
     260};
    261261
    262262/** Frees a two-dimensional array.
     
    266266template <typename X> void Free2DArray(X **ptr, int dim)
    267267{
    268   int i;
    269   if (ptr != NULL) {
    270     for(i=dim;i--;)
    271       if (ptr[i] != NULL)
    272         free(ptr[i]);
    273     free(ptr);
    274   }
     268        int i;
     269        if (ptr != NULL) {
     270                for(i=dim;i--;)
     271                        if (ptr[i] != NULL)
     272                                free(ptr[i]);
     273                free(ptr);
     274        }
    275275};
    276276
     
    281281class Verbose
    282282{
    283   public:
    284     Verbose(int value) : Verbosity(value) { }
    285 
    286     ostream& print (ostream &ost) const;
    287   private:
    288     int Verbosity;
     283        public:
     284                Verbose(int value) : Verbosity(value) { }
     285
     286                ostream& print (ostream &ost) const;
     287        private:
     288                int Verbosity;
    289289};
    290290
     
    295295class Binary
    296296{
    297   public:
    298     Binary(int value) : BinaryNumber(value) { }
    299 
    300     ostream& print (ostream &ost) const;
    301   private:
    302     int BinaryNumber;
     297        public:
     298                Binary(int value) : BinaryNumber(value) { }
     299
     300                ostream& print (ostream &ost) const;
     301        private:
     302                int BinaryNumber;
    303303};
    304304
  • src/joiner.cpp

    rce5ac3 rd067d45  
    22 *
    33 * Takes evaluated fragments (energy and forces) and by reading the factors files determines total energy
    4  * and each force for the whole molecule. 
    5  *   
     4 * and each force for the whole molecule.
     5 *
    66 */
    77
    88//============================ INCLUDES ===========================
    99
    10 #include "datacreator.hpp" 
    11 #include "helpers.hpp" 
    12 #include "parser.hpp" 
    13 #include "periodentafel.hpp" 
     10#include "datacreator.hpp"
     11#include "helpers.hpp"
     12#include "parser.hpp"
     13#include "periodentafel.hpp"
    1414
    1515//============================== MAIN =============================
     
    4646  cout << "Joiner" << endl;
    4747  cout << "======" << endl;
    48  
     48
    4949  // Get the command line options
    5050  if (argc < 3) {
     
    6363    periode->LoadPeriodentafel(argv[3]);
    6464  }
    65  
     65
    6666  // Test the given directory
    6767  if (!TestParams(argc, argv))
    6868    return 1;
    69  
     69
    7070  // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
    71  
     71
    7272  // ------------- Parse through all Fragment subdirs --------
    7373  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
     
    124124    if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
    125125  }
    126  
     126
    127127  // ----------- Resetting last matrices (where full QM values are stored right now)
    128128  if(!Energy.SetLastMatrix(0., 0)) return 1;
     
    237237  }
    238238
    239   // exit 
     239  // exit
    240240  delete(periode);
    241241  Free((void **)&dir, "main: *dir");
  • src/moleculelist.cpp

    rce5ac3 rd067d45  
    11/** \file MoleculeListClass.cpp
    2  * 
     2 *
    33 * Function implementations for the class MoleculeListClass.
    4  * 
     4 *
    55 */
    66
     
    1313MoleculeListClass::MoleculeListClass()
    1414{
    15 };
    16 
    17 /** constructor for MoleculeListClass.
    18  * \param NumMolecules number of molecules to allocate for
    19  * \param NumAtoms number of atoms to allocate for
    20  */
    21 MoleculeListClass::MoleculeListClass(int NumMolecules, int NumAtoms)
    22 {
    23   ListOfMolecules = (molecule **) Malloc(sizeof(molecule *)*NumMolecules, "MoleculeListClass:MoleculeListClass: **ListOfMolecules");
    24   for (int i=NumMolecules;i--;)
    25     ListOfMolecules[i] = NULL;
    26   NumberOfMolecules = NumMolecules;
    27   NumberOfTopAtoms = NumAtoms;
    28 };
    29 
     15  // empty lists
     16  ListOfMolecules.clear();
     17  MaxIndex = 1;
     18};
    3019
    3120/** Destructor for MoleculeListClass.
     
    3423{
    3524  cout << Verbose(3) << this << ": Freeing ListOfMolcules." << endl;
    36   for (int i=NumberOfMolecules;i--;) {
    37     if (ListOfMolecules[i] != NULL) { // if NULL don't free
    38       cout << Verbose(4) << "ListOfMolecules: Freeing " << ListOfMolecules[i] << "." << endl;
    39       delete(ListOfMolecules[i]);
    40       ListOfMolecules[i] = NULL;
    41     }
     25  for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
     26    cout << Verbose(4) << "ListOfMolecules: Freeing " << *ListRunner << "." << endl;
     27    delete (*ListRunner);
    4228  }
    4329  cout << Verbose(4) << "Freeing ListOfMolecules." << endl;
    44   Free((void **)&ListOfMolecules, "MoleculeListClass:MoleculeListClass: **ListOfMolecules");
     30  ListOfMolecules.clear(); // empty list
     31};
     32
     33/** Insert a new molecule into the list and set its number.
     34 * \param *mol molecule to add to list.
     35 * \return true - add successful
     36 */
     37void MoleculeListClass::insert(molecule *mol)
     38{
     39  mol->IndexNr = MaxIndex++;
     40  ListOfMolecules.push_back(mol);
    4541};
    4642
     
    5753  atom *aWalker = NULL;
    5854  atom *bWalker = NULL;
    59  
     55
    6056  // sort each atom list and put the numbers into a list, then go through
    6157  //cout << "Comparing fragment no. " << *(molecule **)a << " to " << *(molecule **)b << "." << endl;
    62   if ( (**(molecule **)a).AtomCount < (**(molecule **)b).AtomCount ) {
     58  if ((**(molecule **) a).AtomCount < (**(molecule **) b).AtomCount) {
    6359    return -1;
    64   } else { if ((**(molecule **)a).AtomCount > (**(molecule **)b).AtomCount)
    65     return +1;
     60  } else {
     61    if ((**(molecule **) a).AtomCount > (**(molecule **) b).AtomCount)
     62      return +1;
    6663    else {
    67       Count = (**(molecule **)a).AtomCount;
     64      Count = (**(molecule **) a).AtomCount;
    6865      aList = new int[Count];
    6966      bList = new int[Count];
    70  
     67
    7168      // fill the lists
    72       aWalker = (**(molecule **)a).start;
    73       bWalker = (**(molecule **)b).start;
     69      aWalker = (**(molecule **) a).start;
     70      bWalker = (**(molecule **) b).start;
    7471      Counter = 0;
    7572      aCounter = 0;
    7673      bCounter = 0;
    77       while ((aWalker->next != (**(molecule **)a).end) && (bWalker->next != (**(molecule **)b).end)) {
     74      while ((aWalker->next != (**(molecule **) a).end) && (bWalker->next != (**(molecule **) b).end)) {
    7875        aWalker = aWalker->next;
    7976        bWalker = bWalker->next;
     
    9087      // check if AtomCount was for real
    9188      flag = 0;
    92       if ((aWalker->next == (**(molecule **)a).end) && (bWalker->next != (**(molecule **)b).end)) {
     89      if ((aWalker->next == (**(molecule **) a).end) && (bWalker->next != (**(molecule **) b).end)) {
    9390        flag = -1;
    9491      } else {
    95         if ((aWalker->next != (**(molecule **)a).end) && (bWalker->next == (**(molecule **)b).end))
     92        if ((aWalker->next != (**(molecule **) a).end) && (bWalker->next == (**(molecule **) b).end))
    9693          flag = 1;
    9794      }
    9895      if (flag == 0) {
    9996        // sort the lists
    100         gsl_heapsort(aList,Count, sizeof(int), CompareDoubles);
    101         gsl_heapsort(bList,Count, sizeof(int), CompareDoubles);
    102         // compare the lists 
    103        
     97        gsl_heapsort(aList, Count, sizeof(int), CompareDoubles);
     98        gsl_heapsort(bList, Count, sizeof(int), CompareDoubles);
     99        // compare the lists
     100
    104101        flag = 0;
    105         for(int i=0;i<Count;i++) {
     102        for (int i = 0; i < Count; i++) {
    106103          if (aList[i] < bList[i]) {
    107104            flag = -1;
     
    114111        }
    115112      }
    116       delete[](aList);
    117       delete[](bList);
     113      delete[] (aList);
     114      delete[] (bList);
    118115      return flag;
    119116    }
    120117  }
    121   return  -1;
     118  return -1;
     119};
     120
     121/** Output of a list of all molecules.
     122 * \param *out output stream
     123 */
     124void MoleculeListClass::Enumerate(ofstream *out)
     125{
     126  element* Elemental = NULL;
     127  atom *Walker = NULL;
     128  int Counts[MAX_ELEMENTS];
     129  double size=0;
     130  Vector Origin;
     131
     132  // header
     133  *out << "Index\tName\t\tAtoms\tFormula\tCenter\tSize" << endl;
     134  cout << Verbose(0) << "-----------------------------------------------" << endl;
     135  if (ListOfMolecules.size() == 0)
     136    *out << "\tNone" << endl;
     137  else {
     138    Origin.Zero();
     139    for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
     140      // reset element counts
     141      for (int j = 0; j<MAX_ELEMENTS;j++)
     142        Counts[j] = 0;
     143      // count atoms per element and determine size of bounding sphere
     144      size=0.;
     145      Walker = (*ListRunner)->start;
     146      while (Walker->next != (*ListRunner)->end) {
     147        Walker = Walker->next;
     148        Counts[Walker->type->Z]++;
     149        if (Walker->x.DistanceSquared(&Origin) > size)
     150          size = Walker->x.DistanceSquared(&Origin);
     151      }
     152      // output Index, Name, number of atoms, chemical formula
     153      *out << ((*ListRunner)->ActiveFlag ? "*" : " ") << (*ListRunner)->IndexNr << "\t" << (*ListRunner)->name << "\t\t" << (*ListRunner)->AtomCount << "\t";
     154      Elemental = (*ListRunner)->elemente->end;
     155      while(Elemental->previous != (*ListRunner)->elemente->start) {
     156        Elemental = Elemental->previous;
     157        if (Counts[Elemental->Z] != 0)
     158          *out << Elemental->symbol << Counts[Elemental->Z];
     159      }
     160      // Center and size
     161      *out << "\t" << (*ListRunner)->Center << "\t" << sqrt(size) << endl;
     162    }
     163  }
     164};
     165
     166/** Returns the molecule with the given index \a index.
     167 * \param index index of the desired molecule
     168 * \return pointer to molecule structure, NULL if not found
     169 */
     170molecule * MoleculeListClass::ReturnIndex(int index)
     171{
     172  for(MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
     173    if ((*ListRunner)->IndexNr == index)
     174      return (*ListRunner);
     175  return NULL;
     176};
     177
     178/** Simple merge of two molecules into one.
     179 * \param *mol destination molecule
     180 * \param *srcmol source molecule
     181 * \return true - merge successful, false - merge failed (probably due to non-existant indices
     182 */
     183bool MoleculeListClass::SimpleMerge(molecule *mol, molecule *srcmol)
     184{
     185  if (srcmol == NULL)
     186    return false;
     187
     188  // put all molecules of src into mol
     189  atom *Walker = srcmol->start;
     190  atom *NextAtom = Walker->next;
     191  while (NextAtom != srcmol->end) {
     192    Walker = NextAtom;
     193    NextAtom = Walker->next;
     194    srcmol->UnlinkAtom(Walker);
     195    mol->AddAtom(Walker);
     196  }
     197
     198  // remove src
     199  ListOfMolecules.remove(srcmol);
     200  delete(srcmol);
     201  return true;
     202};
     203
     204/** Simple add of one molecules into another.
     205 * \param *mol destination molecule
     206 * \param *srcmol source molecule
     207 * \return true - merge successful, false - merge failed (probably due to non-existant indices
     208 */
     209bool MoleculeListClass::SimpleAdd(molecule *mol, molecule *srcmol)
     210{
     211  if (srcmol == NULL)
     212    return false;
     213
     214  // put all molecules of src into mol
     215  atom *Walker = srcmol->start;
     216  atom *NextAtom = Walker->next;
     217  while (NextAtom != srcmol->end) {
     218    Walker = NextAtom;
     219    NextAtom = Walker->next;
     220    Walker = mol->AddCopyAtom(Walker);
     221    Walker->father = Walker;
     222  }
     223
     224  return true;
     225};
     226
     227/** Simple merge of a given set of molecules into one.
     228 * \param *mol destination molecule
     229 * \param *src index of set of source molecule
     230 * \param N number of source molecules
     231 * \return true - merge successful, false - some merges failed (probably due to non-existant indices)
     232 */
     233bool MoleculeListClass::SimpleMultiMerge(molecule *mol, int *src, int N)
     234{
     235  bool status = true;
     236  // check presence of all source molecules
     237  for (int i=0;i<N;i++) {
     238    molecule *srcmol = ReturnIndex(src[i]);
     239    status = status && SimpleMerge(mol, srcmol);
     240  }
     241  return status;
     242};
     243
     244/** Simple add of a given set of molecules into one.
     245 * \param *mol destination molecule
     246 * \param *src index of set of source molecule
     247 * \param N number of source molecules
     248 * \return true - merge successful, false - some merges failed (probably due to non-existant indices)
     249 */
     250bool MoleculeListClass::SimpleMultiAdd(molecule *mol, int *src, int N)
     251{
     252  bool status = true;
     253  // check presence of all source molecules
     254  for (int i=0;i<N;i++) {
     255    molecule *srcmol = ReturnIndex(src[i]);
     256    status = status && SimpleAdd(mol, srcmol);
     257  }
     258  return status;
     259};
     260
     261/** Scatter merge of a given set of molecules into one.
     262 * Scatter merge distributes the molecules in such a manner that they don't overlap.
     263 * \param *mol destination molecule
     264 * \param *src index of set of source molecule
     265 * \param N number of source molecules
     266 * \return true - merge successful, false - merge failed (probably due to non-existant indices
     267 * \TODO find scatter center for each src molecule
     268 */
     269bool MoleculeListClass::ScatterMerge(molecule *mol, int *src, int N)
     270{
     271  // check presence of all source molecules
     272  for (int i=0;i<N;i++) {
     273    // get pointer to src molecule
     274    molecule *srcmol = ReturnIndex(src[i]);
     275    if (srcmol == NULL)
     276      return false;
     277  }
     278  // adapt each Center
     279  for (int i=0;i<N;i++) {
     280    // get pointer to src molecule
     281    molecule *srcmol = ReturnIndex(src[i]);
     282    //srcmol->Center.Zero();
     283    srcmol->Translate(&srcmol->Center);
     284  }
     285  // perform a simple multi merge
     286  SimpleMultiMerge(mol, src, N);
     287  return true;
     288};
     289
     290/** Embedding merge of a given set of molecules into one.
     291 * Embedding merge inserts one molecule into the other.
     292 * \param *mol destination molecule
     293 * \param *srcmol source molecule
     294 * \return true - merge successful, false - merge failed (probably due to non-existant indices
     295 * \TODO find embedding center
     296 */
     297bool MoleculeListClass::EmbedMerge(molecule *mol, molecule *srcmol)
     298{
     299  if (srcmol == NULL)
     300    return false;
     301
     302  // calculate center for merge
     303  srcmol->Center.CopyVector(mol->FindEmbeddingHole((ofstream *)&cout, srcmol));
     304  srcmol->Center.Zero();
     305
     306  // perform simple merge
     307  SimpleMerge(mol, srcmol);
     308  return true;
    122309};
    123310
     
    127314void MoleculeListClass::Output(ofstream *out)
    128315{
    129   *out<< Verbose(1) << "MoleculeList: ";
    130   for (int i=0;i<NumberOfMolecules;i++)
    131     *out << ListOfMolecules[i] << "\t";
     316  *out << Verbose(1) << "MoleculeList: ";
     317  for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
     318    *out << *ListRunner << "\t";
    132319  *out << endl;
    133320};
     
    145332  atom *Runner = NULL;
    146333  double ***FitConstant = NULL, **correction = NULL;
    147   int a,b;
     334  int a, b;
    148335  ofstream output;
    149336  ifstream input;
     
    165352  input.open(line.c_str());
    166353  if (input == NULL) {
    167     cerr << endl << "Unable to open " << line << ", is the directory correct?" << endl;
     354    cerr << endl << "Unable to open " << line << ", is the directory correct?"
     355        << endl;
    168356    return false;
    169357  }
    170   a=0;
    171   b=-1; // we overcount by one
     358  a = 0;
     359  b = -1; // we overcount by one
    172360  while (!input.eof()) {
    173361    input.getline(ParsedLine, 1023);
    174362    zeile.str(ParsedLine);
    175     int i=0;
     363    int i = 0;
    176364    while (!zeile.eof()) {
    177365      zeile >> distance;
    178366      i++;
    179367    }
    180     if (i > a) 
    181       a = i; 
     368    if (i > a)
     369      a = i;
    182370    b++;
    183371  }
    184372  cout << "I recognized " << a << " columns and " << b << " rows, ";
    185373  input.close();
    186  
     374
    187375  // 0b. allocate memory for constants
    188   FitConstant = (double ***) Malloc(sizeof(double **)*3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    189   for (int k=0;k<3;k++) {
    190     FitConstant[k] = (double **) Malloc(sizeof(double *)*a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    191     for (int i=a;i--;) {
    192       FitConstant[k][i] = (double *) Malloc(sizeof(double)*b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
     376  FitConstant = (double ***) Malloc(sizeof(double **) * 3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
     377  for (int k = 0; k < 3; k++) {
     378    FitConstant[k] = (double **) Malloc(sizeof(double *) * a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
     379    for (int i = a; i--;) {
     380      FitConstant[k][i] = (double *) Malloc(sizeof(double) * b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    193381    }
    194382  }
    195383  // 0c. parse in constants
    196   for (int i=0;i<3;i++) {
     384  for (int i = 0; i < 3; i++) {
    197385    line = path;
    198386    line.append("/");
    199387    line += FRAGMENTPREFIX;
    200     sprintf(ParsedLine, "%d", i+1);
     388    sprintf(ParsedLine, "%d", i + 1);
    201389    line += ParsedLine;
    202390    line += FITCONSTANTSUFFIX;
     
    206394      return false;
    207395    }
    208     int k = 0,l;
     396    int k = 0, l;
    209397    while ((!input.eof()) && (k < b)) {
    210398      input.getline(ParsedLine, 1023);
     
    223411    input.close();
    224412  }
    225   for(int k=0;k<3;k++) {
     413  for (int k = 0; k < 3; k++) {
    226414    cout << "Constants " << k << ":" << endl;
    227     for (int j=0;j<b;j++) {
    228       for (int i=0;i<a;i++) {
     415    for (int j = 0; j < b; j++) {
     416      for (int i = 0; i < a; i++) {
    229417        cout << FitConstant[k][i][j] << "\t";
    230418      }
     
    233421    cout << endl;
    234422  }
    235  
     423
    236424  // 0d. allocate final correction matrix
    237   correction = (double **) Malloc(sizeof(double *)*a, "MoleculeListClass::AddHydrogenCorrection: **correction");
    238   for (int i=a;i--;)
    239     correction[i] = (double *) Malloc(sizeof(double)*b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
    240        
     425  correction = (double **) Malloc(sizeof(double *) * a, "MoleculeListClass::AddHydrogenCorrection: **correction");
     426  for (int i = a; i--;)
     427    correction[i] = (double *) Malloc(sizeof(double) * b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
     428
    241429  // 1a. go through every molecule in the list
    242   for(int i=NumberOfMolecules;i--;) {
     430  for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
    243431    // 1b. zero final correction matrix
    244     for (int k=a;k--;)
    245       for (int j=b;j--;)
     432    for (int k = a; k--;)
     433      for (int j = b; j--;)
    246434        correction[k][j] = 0.;
    247435    // 2. take every hydrogen that is a saturated one
    248     Walker = ListOfMolecules[i]->start;
    249     while (Walker->next != ListOfMolecules[i]->end) {
     436    Walker = (*ListRunner)->start;
     437    while (Walker->next != (*ListRunner)->end) {
    250438      Walker = Walker->next;
    251       //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *ListOfMolecules[i]->ListOfBondsPerAtom[Walker->nr][0] << "." << endl;
    252       if ((Walker->type->Z == 1) && ((Walker->father == NULL) || (Walker->father->type->Z != 1))) { // if it's a hydrogen
    253         Runner = ListOfMolecules[i]->start;
    254         while (Runner->next != ListOfMolecules[i]->end) {
     439      //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Walker->nr][0] << "." << endl;
     440      if ((Walker->type->Z == 1) && ((Walker->father == NULL)
     441          || (Walker->father->type->Z != 1))) { // if it's a hydrogen
     442        Runner = (*ListRunner)->start;
     443        while (Runner->next != (*ListRunner)->end) {
    255444          Runner = Runner->next;
    256           //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *ListOfMolecules[i]->ListOfBondsPerAtom[Runner->nr][0] << "." << endl;
     445          //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Runner->nr][0] << "." << endl;
    257446          // 3. take every other hydrogen that is the not the first and not bound to same bonding partner
    258           if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && (ListOfMolecules[i]->ListOfBondsPerAtom[Runner->nr][0]->GetOtherAtom(Runner) != ListOfMolecules[i]->ListOfBondsPerAtom[Walker->nr][0]->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
     447          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!)
    259448            // 4. evaluate the morse potential for each matrix component and add up
    260             distance = sqrt(Runner->x.Distance(&Walker->x));
    261             //cout << "Fragment " << i << ": " << *Runner << "<= " << distance << "=>" << *Walker << ":" << endl;
    262             for(int k=0;k<a;k++) {
    263               for (int j=0;j<b;j++) {
    264                 switch(k) {
    265                 case 1:
    266                 case 7:
    267                 case 11:
    268                   tmp = pow(FitConstant[0][k][j] * ( 1. - exp(-FitConstant[1][k][j] * (distance - FitConstant[2][k][j]) ) ),2);
    269                   break;
    270                 default:
    271                   tmp = FitConstant[0][k][j] * pow( distance, FitConstant[1][k][j]) + FitConstant[2][k][j];
     449            distance = Runner->x.Distance(&Walker->x);
     450            //cout << "Fragment " << (*ListRunner)->name << ": " << *Runner << "<= " << distance << "=>" << *Walker << ":" << endl;
     451            for (int k = 0; k < a; k++) {
     452              for (int j = 0; j < b; j++) {
     453                switch (k) {
     454                  case 1:
     455                  case 7:
     456                  case 11:
     457                    tmp = pow(FitConstant[0][k][j] * (1. - exp(-FitConstant[1][k][j] * (distance - FitConstant[2][k][j]))), 2);
     458                    break;
     459                  default:
     460                    tmp = FitConstant[0][k][j] * pow(distance, FitConstant[1][k][j]) + FitConstant[2][k][j];
    272461                };
    273                 correction[k][j] -= tmp;    // ground state is actually lower (disturbed by additional interaction)
     462                correction[k][j] -= tmp; // ground state is actually lower (disturbed by additional interaction)
    274463                //cout << tmp << "\t";
    275464              }
     
    285474    line.append("/");
    286475    line += FRAGMENTPREFIX;
    287     FragmentNumber = FixedDigitNumber(NumberOfMolecules, i);
     476    FragmentNumber = FixedDigitNumber(ListOfMolecules.size(), (*ListRunner)->IndexNr);
    288477    line += FragmentNumber;
    289     delete(FragmentNumber);
     478    delete (FragmentNumber);
    290479    line += HCORRECTIONSUFFIX;
    291480    output.open(line.c_str());
    292481    output << "Time\t\tTotal\t\tKinetic\t\tNonLocal\tCorrelation\tExchange\tPseudo\t\tHartree\t\t-Gauss\t\tEwald\t\tIonKin\t\tETotal" << endl;
    293     for (int j=0;j<b;j++) {
    294       for(int i=0;i<a;i++)
     482    for (int j = 0; j < b; j++) {
     483      for (int i = 0; i < a; i++)
    295484        output << correction[i][j] << "\t";
    296485      output << endl;
     
    303492  output.open(line.c_str());
    304493  output << "Time\t\tTotal\t\tKinetic\t\tNonLocal\tCorrelation\tExchange\tPseudo\t\tHartree\t\t-Gauss\t\tEwald\t\tIonKin\t\tETotal" << endl;
    305   for (int j=0;j<b;j++) {
    306     for(int i=0;i<a;i++)
     494  for (int j = 0; j < b; j++) {
     495    for (int i = 0; i < a; i++)
    307496      output << 0 << "\t";
    308497    output << endl;
     
    310499  output.close();
    311500  // 6. free memory of parsed matrices
    312   FitConstant = (double ***) Malloc(sizeof(double **)*a, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    313   for (int k=0;k<3;k++) {
    314     FitConstant[k] = (double **) Malloc(sizeof(double *)*a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    315     for (int i=a;i--;) {
    316       FitConstant[k][i] = (double *) Malloc(sizeof(double)*b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
     501  FitConstant = (double ***) Malloc(sizeof(double **) * a, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
     502  for (int k = 0; k < 3; k++) {
     503    FitConstant[k] = (double **) Malloc(sizeof(double *) * a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
     504    for (int i = a; i--;) {
     505      FitConstant[k][i] = (double *) Malloc(sizeof(double) * b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    317506    }
    318507  }
     
    327516 * \return true - file written successfully, false - writing failed
    328517 */
    329 bool MoleculeListClass::StoreForcesFile(ofstream *out, char *path, int *SortIndex)
     518bool MoleculeListClass::StoreForcesFile(ofstream *out, char *path,
     519    int *SortIndex)
    330520{
    331521  bool status = true;
     
    342532    //cout << Verbose(1) << "Final AtomicForcesList: ";
    343533    //output << prefix << "Forces" << endl;
    344     for(int j=0;j<NumberOfMolecules;j++) {
    345       //if (TEList[j] != 0) {
    346       runner = ListOfMolecules[j]->elemente->start;
    347       while (runner->next != ListOfMolecules[j]->elemente->end) { // go through every element
     534    for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
     535      runner = (*ListRunner)->elemente->start;
     536      while (runner->next != (*ListRunner)->elemente->end) { // go through every element
    348537        runner = runner->next;
    349         if (ListOfMolecules[j]->ElementsInMolecule[runner->Z]) { // if this element got atoms
    350           Walker = ListOfMolecules[j]->start;
    351           while (Walker->next != ListOfMolecules[j]->end) { // go through every atom of this element
     538        if ((*ListRunner)->ElementsInMolecule[runner->Z]) { // if this element got atoms
     539          Walker = (*ListRunner)->start;
     540          while (Walker->next != (*ListRunner)->end) { // go through every atom of this element
    352541            Walker = Walker->next;
    353542            if (Walker->type->Z == runner->Z) {
    354543              if ((Walker->GetTrueFather() != NULL) && (Walker->GetTrueFather() != Walker)) {// if there is a rea
    355544                //cout << "Walker is " << *Walker << " with true father " << *( Walker->GetTrueFather()) << ", it
    356                 ForcesFile <<  SortIndex[Walker->GetTrueFather()->nr] << "\t";
    357                 } else  // otherwise a -1 to indicate an added saturation hydrogen
    358                   ForcesFile << "-1\t";
    359               }
     545                ForcesFile << SortIndex[Walker->GetTrueFather()->nr] << "\t";
     546              } else
     547                // otherwise a -1 to indicate an added saturation hydrogen
     548                ForcesFile << "-1\t";
    360549            }
    361550          }
     551        }
    362552      }
    363553      ForcesFile << endl;
     
    370560  }
    371561  ForcesFile.close();
    372  
     562
    373563  return status;
    374564};
     
    382572 * \return true - success (each file was written), false - something went wrong.
    383573 */
    384 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering)
     574bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex)
    385575{
    386576  ofstream outputFragment;
     
    395585  int FragmentCounter = 0;
    396586  ofstream output;
    397   string basis("3-21G");
    398  
     587
    399588  // store the fragments as config and as xyz
    400   for(int i=0;i<NumberOfMolecules;i++) {
     589  for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
    401590    // save default path as it is changed for each fragment
    402591    path = configuration->GetDefaultPath();
     
    407596
    408597    // correct periodic
    409     if (DoPeriodic)
    410       ListOfMolecules[i]->ScanForPeriodicCorrection(out);
     598    (*ListRunner)->ScanForPeriodicCorrection(out);
    411599
    412600    // output xyz file
    413     FragmentNumber = FixedDigitNumber(NumberOfMolecules, FragmentCounter++);
    414     sprintf(FragmentName, "%s/%s%s.conf.xyz", configuration->configpath, fragmentprefix, FragmentNumber);
     601    FragmentNumber = FixedDigitNumber(ListOfMolecules.size(), FragmentCounter++);
     602    sprintf(FragmentName, "%s/%s%s.conf.xyz", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);
    415603    outputFragment.open(FragmentName, ios::out);
    416     *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as XYZ ...";
    417     if ((intermediateResult = ListOfMolecules[i]->OutputXYZ(&outputFragment)))
     604    *out << Verbose(2) << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as XYZ ...";
     605    if ((intermediateResult = (*ListRunner)->OutputXYZ(&outputFragment)))
    418606      *out << " done." << endl;
    419607    else
     
    425613    // list atoms in fragment for debugging
    426614    *out << Verbose(2) << "Contained atoms: ";
    427     Walker = ListOfMolecules[i]->start;
    428     while (Walker->next != ListOfMolecules[i]->end) {
     615    Walker = (*ListRunner)->start;
     616    while (Walker->next != (*ListRunner)->end) {
    429617      Walker = Walker->next;
    430618      *out << Walker->Name << " ";
    431619    }
    432620    *out << endl;
    433    
     621
    434622    // center on edge
    435     if (DoCentering) {
    436       ListOfMolecules[i]->CenterEdge(out, &BoxDimension);
    437       ListOfMolecules[i]->SetBoxDimension(&BoxDimension);  // update Box of atoms by boundary
    438       int j = -1;
    439       for (int k=0;k<NDIM;k++) {
    440         j += k+1;
    441         BoxDimension.x[k] = 2.5* (configuration->GetIsAngstroem() ? 1. : 1./AtomicLengthToAngstroem);
    442         ListOfMolecules[i]->cell_size[j] += BoxDimension.x[k]*2.;
    443       }
    444       ListOfMolecules[i]->Translate(&BoxDimension);
    445     }
     623    (*ListRunner)->CenterEdge(out, &BoxDimension);
     624    (*ListRunner)->SetBoxDimension(&BoxDimension); // update Box of atoms by boundary
     625    int j = -1;
     626    for (int k = 0; k < NDIM; k++) {
     627      j += k + 1;
     628      BoxDimension.x[k] = 2.5 * (configuration->GetIsAngstroem() ? 1. : 1. / AtomicLengthToAngstroem);
     629      (*ListRunner)->cell_size[j] += BoxDimension.x[k] * 2.;
     630    }
     631    (*ListRunner)->Translate(&BoxDimension);
    446632
    447633    // also calculate necessary orbitals
    448     ListOfMolecules[i]->CountElements();  // this is a bugfix, atoms should should actually be added correctly to this fragment
    449     ListOfMolecules[i]->CalculateOrbitals(*configuration);
    450    
     634    (*ListRunner)->CountElements(); // this is a bugfix, atoms should shoulds actually be added correctly to this fragment
     635    (*ListRunner)->CalculateOrbitals(*configuration);
     636
    451637    // change path in config
    452638    //strcpy(PathBackup, configuration->configpath);
    453     sprintf(FragmentName, "%s/%s%s/", PathBackup, fragmentprefix, FragmentNumber);
     639    sprintf(FragmentName, "%s/%s%s/", PathBackup, FRAGMENTPREFIX, FragmentNumber);
    454640    configuration->SetDefaultPath(FragmentName);
    455    
     641
    456642    // and save as config
    457     sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, fragmentprefix, FragmentNumber);
    458     *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as config ...";
    459     if ((intermediateResult = configuration->Save(FragmentName, ListOfMolecules[i]->elemente, ListOfMolecules[i])))
     643    sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);
     644    *out << Verbose(2) << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as config ...";
     645    if ((intermediateResult = configuration->Save(FragmentName, (*ListRunner)->elemente, (*ListRunner))))
    460646      *out << " done." << endl;
    461647    else
     
    466652    configuration->SetDefaultPath(PathBackup);
    467653
    468 
    469654    // and save as mpqc input file
    470     sprintf(FragmentName, "%s/%s%s.in", configuration->configpath, fragmentprefix, FragmentNumber);
    471     *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as mpqc input ...";
    472     if ((intermediateResult = configuration->SaveMPQC(FragmentName, ListOfMolecules[i])))
     655    sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);
     656    *out << Verbose(2) << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as mpqc input ...";
     657    if ((intermediateResult = configuration->SaveMPQC(FragmentName, (*ListRunner))))
    473658      *out << " done." << endl;
    474659    else
    475660      *out << " failed." << endl;
    476        
     661
    477662    result = result && intermediateResult;
    478663    //outputFragment.close();
    479664    //outputFragment.clear();
    480     delete(FragmentNumber);
     665    delete (FragmentNumber);
    481666    //Free((void **)&FragmentNumber, "MoleculeListClass::OutputConfigForListOfFragments: *FragmentNumber");
    482667  }
    483668  cout << " done." << endl;
    484  
     669
    485670  // printing final number
    486671  *out << "Final number of fragments: " << FragmentCounter << "." << endl;
    487      
     672
    488673  return result;
    489674};
     675
     676/** Counts the number of molecules with the molecule::ActiveFlag set.
     677 * \return number of molecules with ActiveFlag set to true.
     678 */
     679int MoleculeListClass::NumberOfActiveMolecules()
     680{
     681  int count = 0;
     682  for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
     683    count += ((*ListRunner)->ActiveFlag ? 1 : 0);
     684  return count;
     685};
     686
    490687
    491688/******************************************* Class MoleculeLeafClass ************************************************/
     
    498695MoleculeLeafClass::MoleculeLeafClass(MoleculeLeafClass *PreviousLeaf = NULL)
    499696{
    500 //  if (Up != NULL)
    501 //    if (Up->DownLeaf == NULL) // are we the first down leaf for the upper leaf?
    502 //      Up->DownLeaf = this;
    503 //  UpLeaf = Up;
    504 //  DownLeaf = NULL;
     697  //  if (Up != NULL)
     698  //    if (Up->DownLeaf == NULL) // are we the first down leaf for the upper leaf?
     699  //      Up->DownLeaf = this;
     700  //  UpLeaf = Up;
     701  //  DownLeaf = NULL;
    505702  Leaf = NULL;
    506703  previous = PreviousLeaf;
     
    518715MoleculeLeafClass::~MoleculeLeafClass()
    519716{
    520 //  if (DownLeaf != NULL) {// drop leaves further down
    521 //    MoleculeLeafClass *Walker = DownLeaf;
    522 //    MoleculeLeafClass *Next;
    523 //    do {
    524 //      Next = Walker->NextLeaf;
    525 //      delete(Walker);
    526 //      Walker = Next;
    527 //    } while (Walker != NULL);
    528 //    // Last Walker sets DownLeaf automatically to NULL
    529 //  }
     717  //  if (DownLeaf != NULL) {// drop leaves further down
     718  //    MoleculeLeafClass *Walker = DownLeaf;
     719  //    MoleculeLeafClass *Next;
     720  //    do {
     721  //      Next = Walker->NextLeaf;
     722  //      delete(Walker);
     723  //      Walker = Next;
     724  //    } while (Walker != NULL);
     725  //    // Last Walker sets DownLeaf automatically to NULL
     726  //  }
    530727  // remove the leaf itself
    531728  if (Leaf != NULL) {
    532     delete(Leaf);
     729    delete (Leaf);
    533730    Leaf = NULL;
    534731  }
    535732  // remove this Leaf from level list
    536   if (previous != NULL)   
     733  if (previous != NULL)
    537734    previous->next = next;
    538 //  } else { // we are first in list (connects to UpLeaf->DownLeaf)
    539 //    if ((NextLeaf != NULL) && (NextLeaf->UpLeaf == NULL))
    540 //      NextLeaf->UpLeaf = UpLeaf;  // either null as we are top level or the upleaf of the first node
    541 //    if (UpLeaf != NULL)
    542 //      UpLeaf->DownLeaf = NextLeaf;  // either null as we are only leaf or NextLeaf if we are just the first
    543 //  }
    544 //  UpLeaf = NULL;
     735  //  } else { // we are first in list (connects to UpLeaf->DownLeaf)
     736  //    if ((NextLeaf != NULL) && (NextLeaf->UpLeaf == NULL))
     737  //      NextLeaf->UpLeaf = UpLeaf;  // either null as we are top level or the upleaf of the first node
     738  //    if (UpLeaf != NULL)
     739  //      UpLeaf->DownLeaf = NextLeaf;  // either null as we are only leaf or NextLeaf if we are just the first
     740  //  }
     741  //  UpLeaf = NULL;
    545742  if (next != NULL) // are we last in list
    546743    next->previous = previous;
     
    581778    return false;
    582779  }
    583  
     780
    584781  if (status) {
    585     *out << Verbose(1) << "Creating adjacency list for subgraph " << this << "." << endl;
     782    *out << Verbose(1) << "Creating adjacency list for subgraph " << this
     783        << "." << endl;
    586784    Walker = Leaf->start;
    587785    while (Walker->next != Leaf->end) {
    588786      Walker = Walker->next;
    589       AtomNo = Walker->GetTrueFather()->nr;  // global id of the current walker
    590       for(int i=0;i<reference->NumberOfBondsPerAtom[AtomNo];i++) { // go through father's bonds and copy them all
     787      AtomNo = Walker->GetTrueFather()->nr; // global id of the current walker
     788      for (int i = 0; i < reference->NumberOfBondsPerAtom[AtomNo]; i++) { // go through father's bonds and copy them all
    591789        Binder = reference->ListOfBondsPerAtom[AtomNo][i];
    592         OtherWalker = ListOfLocalAtoms[FragmentCounter][Binder->GetOtherAtom(Walker->GetTrueFather())->nr];    // local copy of current bond partner of walker
     790        OtherWalker = ListOfLocalAtoms[FragmentCounter][Binder->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
    593791        if (OtherWalker != NULL) {
    594792          if (OtherWalker->nr > Walker->nr)
    595           Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);
     793            Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);
    596794        } else {
    597795          *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << Binder->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
     
    606804    FragmentCounter--;
    607805  }
    608  
     806
    609807  if ((FreeList) && (ListOfLocalAtoms != NULL)) {
    610808    // free the index lookup list
    611     Free((void **)&ListOfLocalAtoms[FragmentCounter], "MoleculeLeafClass::FillBondStructureFromReference - **ListOfLocalAtoms[]");
     809    Free((void **) &ListOfLocalAtoms[FragmentCounter], "MoleculeLeafClass::FillBondStructureFromReference - **ListOfLocalAtoms[]");
    612810    if (FragmentCounter == 0) // first fragments frees the initial pointer to list
    613       Free((void **)&ListOfLocalAtoms, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
     811      Free((void **) &ListOfLocalAtoms, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
    614812  }
    615813  FragmentCounter--;
     
    626824 * \return true - stack is non-empty, fragmentation necessary, false - stack is empty, no more sites to update
    627825 */
    628 bool MoleculeLeafClass::FillRootStackForSubgraphs(ofstream *out, KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter)
     826bool MoleculeLeafClass::FillRootStackForSubgraphs(ofstream *out,
     827    KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter)
    629828{
    630829  atom *Walker = NULL, *Father = NULL;
    631830
    632831  if (RootStack != NULL) {
    633     // find first root candidates 
     832    // find first root candidates
    634833    if (&(RootStack[FragmentCounter]) != NULL) {
    635       RootStack[FragmentCounter].clear(); 
     834      RootStack[FragmentCounter].clear();
    636835      Walker = Leaf->start;
    637836      while (Walker->next != Leaf->end) { // go through all (non-hydrogen) atoms
     
    639838        Father = Walker->GetTrueFather();
    640839        if (AtomMask[Father->nr]) // apply mask
    641     #ifdef ADDHYDROGEN
     840#ifdef ADDHYDROGEN
    642841          if (Walker->type->Z != 1) // skip hydrogen
    643     #endif
    644             RootStack[FragmentCounter].push_front(Walker->nr);
     842#endif
     843          RootStack[FragmentCounter].push_front(Walker->nr);
    645844      }
    646845      if (next != NULL)
    647846        next->FillRootStackForSubgraphs(out, RootStack, AtomMask, ++FragmentCounter);
    648     }  else {
    649       *out << Verbose(1) << "Rootstack[" << FragmentCounter  << "] is NULL." << endl;
     847    } else {
     848      *out << Verbose(1) << "Rootstack[" << FragmentCounter << "] is NULL." << endl;
    650849      return false;
    651850    }
     
    669868{
    670869  bool status = true;
    671  
     870
    672871  int Counter = Count();
    673872  if (ListOfLocalAtoms == NULL) { // allocated initial pointer
    674873    // allocate and set each field to NULL
    675     ListOfLocalAtoms = (atom ***) Malloc(sizeof(atom **)*Counter, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
     874    ListOfLocalAtoms = (atom ***) Malloc(sizeof(atom **) * Counter, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
    676875    if (ListOfLocalAtoms != NULL) {
    677       for (int i=Counter;i--;)
     876      for (int i = Counter; i--;)
    678877        ListOfLocalAtoms[i] = NULL;
    679878      FreeList = FreeList && true;
     
    681880      status = false;
    682881  }
    683  
     882
    684883  if ((ListOfLocalAtoms != NULL) && (ListOfLocalAtoms[FragmentCounter] == NULL)) { // allocate and fill list of this fragment/subgraph
    685884    status = status && CreateFatherLookupTable(out, Leaf->start, Leaf->end, ListOfLocalAtoms[FragmentCounter], GlobalAtomCount);
    686885    FreeList = FreeList && true;
    687886  }
    688  
     887
    689888  return status;
    690889};
     
    700899 * \retuen true - success, false - failure
    701900 */
    702 bool MoleculeLeafClass::AssignKeySetsToFragment(ofstream *out, molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms, Graph **&FragmentList, int &FragmentCounter, bool FreeList)
     901bool MoleculeLeafClass::AssignKeySetsToFragment(ofstream *out,
     902    molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms,
     903    Graph **&FragmentList, int &FragmentCounter, bool FreeList)
    703904{
    704905  bool status = true;
    705906  int KeySetCounter = 0;
    706  
     907
    707908  *out << Verbose(1) << "Begin of AssignKeySetsToFragment." << endl;
    708909  // fill ListOfLocalAtoms if NULL was given
     
    715916  if (FragmentList == NULL) {
    716917    KeySetCounter = Count();
    717     FragmentList = (Graph **) Malloc(sizeof(Graph *)*KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
    718     for(int i=KeySetCounter;i--;)
     918    FragmentList = (Graph **) Malloc(sizeof(Graph *) * KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
     919    for (int i = KeySetCounter; i--;)
    719920      FragmentList[i] = NULL;
    720921    KeySetCounter = 0;
    721922  }
    722  
     923
    723924  if ((KeySetList != NULL) && (KeySetList->size() != 0)) { // if there are some scanned keysets at all
    724925    // assign scanned keysets
     
    726927      FragmentList[FragmentCounter] = new Graph;
    727928    KeySet *TempSet = new KeySet;
    728     for(Graph::iterator runner = KeySetList->begin();runner != KeySetList->end(); runner++) { // key sets contain global numbers!
    729       if ( ListOfLocalAtoms[FragmentCounter][reference->FindAtom(*((*runner).first.begin()))->nr] != NULL) {// as we may assume that that bond structure is unchanged, we only test the first key in each set
     929    for (Graph::iterator runner = KeySetList->begin(); runner != KeySetList->end(); runner++) { // key sets contain global numbers!
     930      if (ListOfLocalAtoms[FragmentCounter][reference->FindAtom(*((*runner).first.begin()))->nr] != NULL) {// as we may assume that that bond structure is unchanged, we only test the first key in each set
    730931        // translate keyset to local numbers
    731         for(KeySet::iterator sprinter = (*runner).first.begin(); sprinter != (*runner).first.end(); sprinter++)
     932        for (KeySet::iterator sprinter = (*runner).first.begin(); sprinter != (*runner).first.end(); sprinter++)
    732933          TempSet->insert(ListOfLocalAtoms[FragmentCounter][reference->FindAtom(*sprinter)->nr]->nr);
    733934        // insert into FragmentList
    734         FragmentList[FragmentCounter]->insert(GraphPair (*TempSet, pair<int,double>(KeySetCounter++, (*runner).second.second)));
     935        FragmentList[FragmentCounter]->insert(GraphPair(*TempSet, pair<int, double> (KeySetCounter++, (*runner).second.second)));
    735936      }
    736937      TempSet->clear();
    737938    }
    738     delete(TempSet);
     939    delete (TempSet);
    739940    if (KeySetCounter == 0) {// if there are no keysets, delete the list
    740941      *out << Verbose(1) << "KeySetCounter is zero, deleting FragmentList." << endl;
    741       delete(FragmentList[FragmentCounter]);
     942      delete (FragmentList[FragmentCounter]);
    742943    } else
    743944      *out << Verbose(1) << KeySetCounter << " keysets were assigned to subgraph " << FragmentCounter << "." << endl;
     
    748949  } else
    749950    *out << Verbose(1) << "KeySetList is NULL or empty." << endl;
    750  
     951
    751952  if ((FreeList) && (ListOfLocalAtoms != NULL)) {
    752953    // free the index lookup list
    753     Free((void **)&ListOfLocalAtoms[FragmentCounter], "MoleculeLeafClass::AssignKeySetsToFragment - **ListOfLocalAtoms[]");
     954    Free((void **) &ListOfLocalAtoms[FragmentCounter], "MoleculeLeafClass::AssignKeySetsToFragment - **ListOfLocalAtoms[]");
    754955    if (FragmentCounter == 0) // first fragments frees the initial pointer to list
    755       Free((void **)&ListOfLocalAtoms, "MoleculeLeafClass::AssignKeySetsToFragment - ***ListOfLocalAtoms");
     956      Free((void **) &ListOfLocalAtoms, "MoleculeLeafClass::AssignKeySetsToFragment - ***ListOfLocalAtoms");
    756957  }
    757958  *out << Verbose(1) << "End of AssignKeySetsToFragment." << endl;
     
    765966 * \param &TotalNumberOfKeySets global key set counter
    766967 * \param &TotalGraph Graph to be filled with global numbers
    767  */
    768 void MoleculeLeafClass::TranslateIndicesToGlobalIDs(ofstream *out, Graph **FragmentList, int &FragmentCounter, int &TotalNumberOfKeySets, Graph &TotalGraph)
     968 */
     969void MoleculeLeafClass::TranslateIndicesToGlobalIDs(ofstream *out,
     970    Graph **FragmentList, int &FragmentCounter, int &TotalNumberOfKeySets,
     971    Graph &TotalGraph)
    769972{
    770973  *out << Verbose(1) << "Begin of TranslateIndicesToGlobalIDs." << endl;
    771974  KeySet *TempSet = new KeySet;
    772975  if (FragmentList[FragmentCounter] != NULL) {
    773     for(Graph::iterator runner = FragmentList[FragmentCounter]->begin(); runner != FragmentList[FragmentCounter]->end(); runner++) {
    774       for(KeySet::iterator sprinter = (*runner).first.begin(); sprinter != (*runner).first.end(); sprinter++)
     976    for (Graph::iterator runner = FragmentList[FragmentCounter]->begin(); runner != FragmentList[FragmentCounter]->end(); runner++) {
     977      for (KeySet::iterator sprinter = (*runner).first.begin(); sprinter != (*runner).first.end(); sprinter++)
    775978        TempSet->insert((Leaf->FindAtom(*sprinter))->GetTrueFather()->nr);
    776       TotalGraph.insert(GraphPair(*TempSet, pair<int,double>(TotalNumberOfKeySets++, (*runner).second.second)));
     979      TotalGraph.insert(GraphPair(*TempSet, pair<int, double> (TotalNumberOfKeySets++, (*runner).second.second)));
    777980      TempSet->clear();
    778981    }
    779     delete(TempSet);
     982    delete (TempSet);
    780983  } else {
    781984    *out << Verbose(1) << "FragmentList is NULL." << endl;
     
    793996{
    794997  if (next != NULL)
    795     return next->Count()+1;
     998    return next->Count() + 1;
    796999  else
    797     return 1;
    798 };
     1000    return 1;
     1001};
     1002
  • src/molecules.cpp

    rce5ac3 rd067d45  
    6262  cell_size[0] = cell_size[2] = cell_size[5]= 20.;
    6363  cell_size[1] = cell_size[3] = cell_size[4]= 0.;
     64  strcpy(name,"none");
     65  IndexNr  = -1;
     66  ActiveFlag = false;
    6467};
    6568
     
    598601};
    599602
     603/** Set molecule::name from the basename without suffix in the given \a *filename.
     604 * \param *filename filename
     605 */
     606void molecule::SetNameFromFilename(const char *filename)
     607{
     608  int length = 0;
     609  char *molname = strrchr(filename, '/')+sizeof(char);  // search for filename without dirs
     610  char *endname = strchr(molname, '.');
     611  if ((endname == NULL) || (endname < molname))
     612    length = strlen(molname);
     613  else
     614    length = strlen(molname) - strlen(endname);
     615  strncpy(name, molname, length);
     616  name[length]='\0';
     617};
     618
    600619/** Sets the molecule::cell_size to the components of \a *dim (rectangular box)
    601620 * \param *dim vector class
     
    652671    max->Scale(0.5);
    653672    Translate(max);
     673    Center.Zero();
    654674  }
    655675
     
    691711    max->AddVector(min);
    692712    Translate(min);
     713    Center.Zero();
    693714  }
    694715  delete(min);
     
    700721 * \param *center return vector for translation vector
    701722 */
    702 void molecule::CenterOrigin(ofstream *out, Vector *center)
     723void molecule::CenterOrigin(ofstream *out)
    703724{
    704725  int Num = 0;
    705726  atom *ptr = start->next;  // start at first in list
    706727
    707   for(int i=NDIM;i--;) // zero center vector
    708     center->x[i] = 0.;
     728  Center.Zero();
    709729
    710730  if (ptr != end) {   //list not empty?
     
    712732      ptr = ptr->next;
    713733      Num++;
    714       center->AddVector(&ptr->x);
    715     }
    716     center->Scale(-1./Num); // divide through total number (and sign for direction)
    717     Translate(center);
     734      Center.AddVector(&ptr->x);
     735    }
     736    Center.Scale(-1./Num); // divide through total number (and sign for direction)
     737    Translate(&Center);
     738    Center.Zero();
    718739  }
    719740};
     
    780801 * \param *center return vector for translation vector
    781802 */
    782 void molecule::CenterGravity(ofstream *out, Vector *center)
    783 {
    784   if (center == NULL) {
    785     DetermineCenter(*center);
    786     Translate(center);
    787     delete(center);
    788   } else {
    789     Translate(center);
    790   }
     803void molecule::CenterPeriodic(ofstream *out)
     804{
     805  DeterminePeriodicCenter(Center);
     806};
     807
     808/** Centers the center of gravity of the atoms at (0,0,0).
     809 * \param *out output stream for debugging
     810 * \param *center return vector for translation vector
     811 */
     812void molecule::CenterAtVector(ofstream *out, Vector *newcenter)
     813{
     814  Center.CopyVector(newcenter);
    791815};
    792816
     
    837861
    838862/** Determines center of molecule (yet not considering atom masses).
    839  * \param Center reference to return vector
    840  */
    841 void molecule::DetermineCenter(Vector &Center)
     863 * \param center reference to return vector
     864 */
     865void molecule::DeterminePeriodicCenter(Vector &center)
    842866{
    843867  atom *Walker = start;
     
    849873
    850874  do {
    851     Center.Zero();
     875    center.Zero();
    852876    flag = true;
    853877    while (Walker->next != end) {
     
    876900        Testvector.AddVector(&Translationvector);
    877901        Testvector.MatrixMultiplication(matrix);
    878         Center.AddVector(&Testvector);
     902        center.AddVector(&Testvector);
    879903        cout << Verbose(1) << "vector is: ";
    880904        Testvector.Output((ofstream *)&cout);
     
    889913            Testvector.AddVector(&Translationvector);
    890914            Testvector.MatrixMultiplication(matrix);
    891             Center.AddVector(&Testvector);
     915            center.AddVector(&Testvector);
    892916            cout << Verbose(1) << "Hydrogen vector is: ";
    893917            Testvector.Output((ofstream *)&cout);
     
    900924  } while (!flag);
    901925  Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
    902   Center.Scale(1./(double)AtomCount);
     926  center.Scale(1./(double)AtomCount);
    903927};
    904928
     
    913937  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    914938
    915   CenterGravity(out, CenterOfGravity);
     939  CenterAtVector(out, CenterOfGravity);
    916940
    917941  // reset inertia tensor
     
    14091433bool molecule::LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration)
    14101434{
     1435  molecule *mol = NULL;
    14111436  bool status = true;
    14121437  int MaxSteps = configuration.MaxOuterStep;
    1413   MoleculeListClass *MoleculePerStep = new MoleculeListClass(MaxSteps+1, AtomCount);
     1438  MoleculeListClass *MoleculePerStep = new MoleculeListClass();
    14141439  // Get the Permutation Map by MinimiseConstrainedPotential
    14151440  atom **PermutationMap = NULL;
     
    14431468  *out << Verbose(1) << "Filling intermediate " << MaxSteps << " steps with MDSteps of " << MDSteps << "." << endl;
    14441469  for (int step = 0; step <= MaxSteps; step++) {
    1445     MoleculePerStep->ListOfMolecules[step] = new molecule(elemente);
     1470    mol = new molecule(elemente);
     1471    MoleculePerStep->insert(mol);
    14461472    Walker = start;
    14471473    while (Walker->next != end) {
    14481474      Walker = Walker->next;
    14491475      // add to molecule list
    1450       Sprinter = MoleculePerStep->ListOfMolecules[step]->AddCopyAtom(Walker);
     1476      Sprinter = mol->AddCopyAtom(Walker);
    14511477      for (int n=NDIM;n--;) {
    14521478        Sprinter->x.x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps);
     
    14671493  for (int i=AtomCount; i--; )
    14681494    SortIndex[i] = i;
    1469   status = MoleculePerStep->OutputConfigForListOfFragments(out, "ConstrainedStep", &configuration, SortIndex, false, false);
     1495  status = MoleculePerStep->OutputConfigForListOfFragments(out, &configuration, SortIndex);
    14701496 
    14711497  // free and return
     
    18281854};
    18291855
    1830 /** Removes atom from molecule list.
     1856/** Removes atom from molecule list and deletes it.
    18311857 * \param *pointer atom to be removed
    18321858 * \return true - succeeded, false - atom not found in list
     
    18421868  Trajectories.erase(pointer);
    18431869  return remove(pointer, start, end);
     1870};
     1871
     1872/** Removes atom from molecule list, but does not delete it.
     1873 * \param *pointer atom to be removed
     1874 * \return true - succeeded, false - atom not found in list
     1875 */
     1876bool molecule::UnlinkAtom(atom *pointer)
     1877{
     1878  if (pointer == NULL)
     1879    return false;
     1880  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1881    ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element
     1882  else
     1883    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1884  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     1885    ElementCount--;
     1886  Trajectories.erase(pointer);
     1887  unlink(pointer);
     1888  return true;
    18441889};
    18451890
     
    23682413            };
    23692414            AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    2370            
     2415
    23712416          }
    23722417
     
    24842529                        //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    24852530                        /// \todo periodic check is missing here!
    2486                         //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistance(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     2531                        //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    24872532                        MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    24882533                        MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    24892534                        MaxDistance = MinDistance + BONDTHRESHOLD;
    24902535                        MinDistance -= BONDTHRESHOLD;
    2491                         distance =   OtherWalker->x.PeriodicDistance(&(Walker->x), cell_size);
     2536                        distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
    24922537                        if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    2493                           //*out << Verbose(0) << "Adding Bond between " << *Walker << " and " << *OtherWalker << "." << endl;
     2538                          //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    24942539                          AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
    2495                           BondCount++;
    24962540                        } else {
    24972541                          //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     
    25642608      *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    25652609    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    2566    
     2610
    25672611    // output bonds for debugging (if bond chain list was correctly installed)
    25682612    *out << Verbose(1) << endl << "From contents of bond chain list:";
     
    31713215          cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    31723216        }
    3173         //FragmentList->ListOfMolecules[NumberOfFragments++] = StoreFragmentFromKeySet(out, CurrentSet, IsAngstroem);
    31743217      }
    31753218    }
     
    37313774  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    37323775    // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3733     BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
     3776    BondFragments = new MoleculeListClass();
    37343777    int k=0;
    37353778    for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    37363779      KeySet test = (*runner).first;
    37373780      *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    3738       BondFragments->ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);
     3781      BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
    37393782      k++;
    37403783    }
    3741     *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
     3784    *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    37423785
    37433786    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3744     if (BondFragments->NumberOfMolecules != 0) {
     3787    if (BondFragments->ListOfMolecules.size() != 0) {
    37453788      // create the SortIndex from BFS labels to order in the config file
    37463789      CreateMappingLabelsToConfigSequence(out, SortIndex);
    37473790
    3748       *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    3749       if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true))
     3791      *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
     3792      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    37503793        *out << Verbose(1) << "All configs written." << endl;
    37513794      else
     
    53185361  if (result) {
    53195362    *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    5320     DetermineCenter(CenterOfGravity);
    5321     OtherMolecule->DetermineCenter(OtherCenterOfGravity);
     5363    DeterminePeriodicCenter(CenterOfGravity);
     5364    OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);
    53225365    *out << Verbose(5) << "Center of Gravity: ";
    53235366    CenterOfGravity.Output(out);
     
    53255368    OtherCenterOfGravity.Output(out);
    53265369    *out << endl;
    5327     if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
     5370    if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
    53285371      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    53295372      result = false;
     
    53395382    while (Walker->next != end) {
    53405383      Walker = Walker->next;
    5341       Distances[Walker->nr] = CenterOfGravity.Distance(&Walker->x);
     5384      Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
    53425385    }
    53435386    Walker = OtherMolecule->start;
    53445387    while (Walker->next != OtherMolecule->end) {
    53455388      Walker = Walker->next;
    5346       OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
     5389      OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
    53475390    }
    53485391
     
    53625405    flag = 0;
    53635406    for (int i=0;i<AtomCount;i++) {
    5364       *out << Verbose(5) << "Distances: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
    5365       if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold)
     5407      *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
     5408      if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
    53665409        flag = 1;
    53675410    }
  • src/molecules.hpp

    rce5ac3 rd067d45  
    7171#define DistanceMultiMapPair pair <double, pair < PointMap::iterator, PointMap::iterator> >
    7272
     73#define MoleculeList list <molecule *>
     74#define MoleculeListTest pair <MoleculeList::iterator, bool>
     75
    7376/******************************** Some small functions and/or structures **********************************/
    7477
     
    116119  element *type;
    117120};
    118 
    119 
    120121
    121122/** Single atom.
     
    131132    atom *father;   //!< In many-body bond order fragmentations points to originating atom
    132133    atom *Ancestor; //!< "Father" in Depth-First-Search
    133     char *Name;                 //!< unique name used during many-body bond-order fragmentation
     134    char *Name;      //!< unique name used during many-body bond-order fragmentation
    134135    int FixedIon;   //!< config variable that states whether forces act on the ion or not
    135136    int *sort;      //!< sort criteria
     
    146147  ~atom();
    147148
    148   bool Output(int ElementNo, int AtomNo, ofstream *out) const;
     149  bool Output(int ElementNo, int AtomNo, ofstream *out, const char *comment = NULL) const;
    149150  bool OutputXYZLine(ofstream *out) const;
    150151  atom *GetTrueFather();
     
    163164class bond {
    164165  public:
    165         atom *leftatom;         //!< first bond partner
    166         atom *rightatom;        //!< second bond partner
     166    atom *leftatom;    //!< first bond partner
     167    atom *rightatom;  //!< second bond partner
    167168    bond *previous; //!< previous atom in molecule list
    168169    bond *next;     //!< next atom in molecule list
    169         int HydrogenBond;       //!< Number of hydrogen atoms in the bond
    170         int BondDegree;         //!< single, double, triple, ... bond
     170    int HydrogenBond;  //!< Number of hydrogen atoms in the bond
     171    int BondDegree;    //!< single, double, triple, ... bond
    171172    int nr;           //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
    172173    bool Cyclic;      //!< flag whether bond is part of a cycle or not, given in DepthFirstSearchAnalysis()
     
    218219    int MDSteps;        //!< The number of MD steps in Trajectories
    219220    int *NumberOfBondsPerAtom;  //!< Number of Bonds each atom has
    220     int AtomCount;                                      //!< number of atoms, brought up-to-date by CountAtoms()
    221     int BondCount;                                      //!< number of atoms, brought up-to-date by CountBonds()
     221    int AtomCount;          //!< number of atoms, brought up-to-date by CountAtoms()
     222    int BondCount;          //!< number of atoms, brought up-to-date by CountBonds()
    222223    int ElementCount;       //!< how many unique elements are therein
    223224    int ElementsInMolecule[MAX_ELEMENTS]; //!< list whether element (sorted by atomic number) is alread present or not
    224     int NoNonHydrogen;  //!< number of non-hydrogen atoms in molecule
     225    int NoNonHydrogen;  //!< number of non-hydrogen atoms in molecule
    225226    int NoNonBonds;     //!< number of non-hydrogen bonds in molecule
    226227    int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    227228    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
     229    bool ActiveFlag;    //!< in a MoleculeListClass used to discern active from inactive molecules
     230    Vector Center;      //!< Center of molecule in a global box
     231    char name[MAXSTRINGSIZE];         //!< arbitrary name
     232    int IndexNr;        //!< index of molecule in a MoleculeListClass
    228233
    229234  molecule(periodentafel *teil);
     
    233238  bool AddAtom(atom *pointer);
    234239  bool RemoveAtom(atom *pointer);
     240  bool UnlinkAtom(atom *pointer);
    235241  bool CleanupMolecule();
    236242
     
    253259  bool CenterInBox(ofstream *out, Vector *BoxLengths);
    254260  void CenterEdge(ofstream *out, Vector *max);
    255   void CenterOrigin(ofstream *out, Vector *max);
    256   void CenterGravity(ofstream *out, Vector *max);
     261  void CenterOrigin(ofstream *out);
     262  void CenterPeriodic(ofstream *out);
     263  void CenterAtVector(ofstream *out, Vector *newcenter);
    257264  void Translate(const Vector *x);
    258265  void Mirror(const Vector *x);
    259266  void Align(Vector *n);
    260267  void Scale(double **factor);
    261   void DetermineCenter(Vector &center);
     268  void DeterminePeriodicCenter(Vector &center);
    262269  Vector * DetermineCenterOfGravity(ofstream *out);
    263270  Vector * DetermineCenterOfAll(ofstream *out);
     271  void SetNameFromFilename(const char *filename);
    264272  void SetBoxDimension(Vector *dim);
    265273  double * ReturnFullMatrixforSymmetric(double *cell_size);
    266274  void ScanForPeriodicCorrection(ofstream *out);
    267         void PrincipalAxisSystem(ofstream *out, bool DoRotate);
    268         double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    269        
    270275  bool VerletForceIntegration(ofstream *out, char *file, config &configuration);
    271276  void Thermostats(config &configuration, double ActualTemp, int Thermostat);
     277  void PrincipalAxisSystem(ofstream *out, bool DoRotate);
     278  double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
     279  Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);
     280
    272281
    273282  double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem);
     
    315324  /// -# BOSSANOVA
    316325  void FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize);
    317         int PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet);
     326  int PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet);
    318327  bool BuildInducedSubgraph(ofstream *out, const molecule *Father);
    319328  molecule * StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem);
     
    343352class MoleculeListClass {
    344353  public:
    345     molecule **ListOfMolecules;   //!< pointer list of fragment molecules to check for equality
    346     int NumberOfMolecules;        //!< Number of entries in \a **FragmentList and of to be returned one.
    347     int NumberOfTopAtoms;         //!< Number of atoms in the molecule from which all fragments originate
     354    MoleculeList ListOfMolecules; //!< List of the contained molecules
     355    int MaxIndex;
    348356
    349357  MoleculeListClass();
    350   MoleculeListClass(int Num, int NumAtoms);
    351358  ~MoleculeListClass();
    352359
    353   /// Output configs.
    354360  bool AddHydrogenCorrection(ofstream *out, char *path);
    355361  bool StoreForcesFile(ofstream *out, char *path, int *SortIndex);
    356   bool OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering);
     362  void insert(molecule *mol);
     363  molecule * ReturnIndex(int index);
     364  bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex);
     365  int NumberOfActiveMolecules();
     366  void Enumerate(ofstream *out);
    357367  void Output(ofstream *out);
     368
     369  // merging of molecules
     370  bool SimpleMerge(molecule *mol, molecule *srcmol);
     371  bool SimpleAdd(molecule *mol, molecule *srcmol);
     372  bool SimpleMultiMerge(molecule *mol, int *src, int N);
     373  bool SimpleMultiAdd(molecule *mol, int *src, int N);
     374  bool ScatterMerge(molecule *mol, int *src, int N);
     375  bool EmbedMerge(molecule *mol, molecule *srcmol);
    358376
    359377  private:
     
    479497  bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
    480498  bool SaveMPQC(const char *filename, molecule *mol) const;
    481   void Edit(molecule *mol);
     499  void Edit();
    482500  bool GetIsAngstroem() const;
    483501  char *GetDefaultPath() const;
  • src/parser.cpp

    rce5ac3 rd067d45  
    22 *
    33 * Declarations of various class functions for the parsing of value files.
    4  *   
     4 *
    55 */
    66
    77// ======================================= INCLUDES ==========================================
    88
    9 #include "helpers.hpp" 
     9#include "helpers.hpp"
    1010#include "parser.hpp"
    1111
     
    2525{
    2626  ifstream input;
    27  
     27
    2828  input.open(filename, ios::in);
    2929  if (input == NULL) {
     
    145145 * \param skiplines number of inital columns to skip
    146146 * \param MatrixNr index number in Matrix array to parse into
    147  * \return parsing successful 
     147 * \return parsing successful
    148148 */
    149149bool MatrixContainer::ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr)
     
    183183  // scan rest for number of rows/lines
    184184  RowCounter[MatrixNr]=-1;    // counts one line too much
    185   while (!input.eof()) { 
     185  while (!input.eof()) {
    186186    input.getline(filename, 1023);
    187187    //cout << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
     
    194194  if (RowCounter[MatrixNr] == 0)
    195195    cerr << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl;
    196  
     196
    197197  // allocate matrix if it's not zero dimension in one direction
    198198  if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
     
    233233/** Parsing a number of matrices.
    234234 * -# First, count the number of matrices by counting lines in KEYSETFILE
    235  * -# Then, 
     235 * -# Then,
    236236 *    -# construct the fragment number
    237237 *    -# open the matrix file
     
    241241 *    -# allocate matrix
    242242 *    -# loop over found column and row counts and parse in each entry
    243  * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values 
     243 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
    244244 * \param *name directory with files
    245245 * \param *prefix prefix of each matrix file
     
    247247 * \param skiplines number of inital lines to skip
    248248 * \param skiplines number of inital columns to skip
    249  * \return parsing successful 
     249 * \return parsing successful
    250250 */
    251251bool MatrixContainer::ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns)
     
    256256  stringstream file;
    257257  string token;
    258  
     258
    259259  // count the number of matrices
    260260  MatrixCounter = -1; // we count one too much
     
    270270    MatrixCounter++;
    271271  }
    272   input.close(); 
     272  input.close();
    273273  cout << "Determined " << MatrixCounter << " fragments." << endl;
    274  
     274
    275275  cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
    276276  Header = (char **) ReAlloc(Header, sizeof(char *)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: **Header"); // one more each for the total molecule
     
    421421                if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
    422422                  m = l;
    423                   break; 
     423                  break;
    424424                }
    425425              }
     
    447447   //cout << "Final Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl;
    448448  }
    449  
     449
    450450  return true;
    451451};
     
    512512
    513513// ======================================= CLASS EnergyMatrix =============================
     514
     515/** Create a trivial energy index mapping.
     516 * This just maps 1 to 1, 2 to 2 and so on for all fragments.
     517 * \return creation sucessful
     518 */
     519bool EnergyMatrix::ParseIndices()
     520{
     521  cout << "Parsing energy indices." << endl;
     522  Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "EnergyMatrix::ParseIndices: **Indices");
     523  for(int i=MatrixCounter+1;i--;) {
     524    Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "EnergyMatrix::ParseIndices: *Indices[]");
     525    for(int j=RowCounter[i];j--;)
     526      Indices[i][j] = j;
     527  }
     528  return true;
     529};
    514530
    515531/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
     
    545561 * \param skiplines number of inital columns to skip
    546562 * \return parsing successful
    547  */ 
     563 */
    548564bool EnergyMatrix::ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns)
    549565{
     
    580596/** Parsing force Indices of each fragment
    581597 * \param *name directory with \a ForcesFile
    582  * \return parsing successful 
    583  */
    584 bool ForceMatrix::ParseIndices(char *name) 
     598 * \return parsing successful
     599 */
     600bool ForceMatrix::ParseIndices(char *name)
    585601{
    586602  ifstream input;
     
    588604  char filename[1023];
    589605  stringstream line;
    590  
     606
    591607  cout << "Parsing force indices for " << MatrixCounter << " matrices." << endl;
    592608  Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "ForceMatrix::ParseIndices: **Indices");
     
    659675 * \param skiplines number of inital columns to skip
    660676 * \return parsing successful
    661  */ 
     677 */
    662678bool ForceMatrix::ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns)
    663679{
     
    932948    ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
    933949  }
    934  
     950
    935951
    936952  return status;
     
    974990  stringstream file;
    975991  char filename[1023];
    976  
     992
    977993  FragmentCounter = FCounter;
    978994  cout << "Parsing key sets." << endl;
     
    9861002    return false;
    9871003  }
    988  
     1004
    9891005  AtomCounter = (int *) Malloc(sizeof(int)*FragmentCounter, "KeySetsContainer::ParseKeySets: *RowCounter");
    9901006  for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
     
    10161032{
    10171033  int Counter;
    1018  
     1034
    10191035  cout << "Creating Fragment terms." << endl;
    10201036  // scan through all to determine maximum order
     
    10291045  }
    10301046  cout << "Found Order is " << Order << "." << endl;
    1031  
     1047
    10321048  // scan through all to determine fragments per order
    10331049  FragmentsPerOrder = (int *) Malloc(sizeof(int)*Order, "KeySetsContainer::ParseManyBodyTerms: *FragmentsPerOrder");
     
    10431059  for(int i=0;i<Order;i++)
    10441060    cout << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl;
    1045    
     1061
    10461062  // scan through all to gather indices to each order set
    10471063  OrderSet = (int **) Malloc(sizeof(int *)*Order, "KeySetsContainer::ParseManyBodyTerms: **OrderSet");
     
    10661082  }
    10671083  cout << endl;
    1068  
    1069    
     1084
     1085
    10701086  return true;
    10711087};
  • src/parser.hpp

    rce5ac3 rd067d45  
    22 *
    33 * Definitions of various class functions for the parsing of value files.
    4  *   
     4 *
    55 */
    66
     
    7171  bool WriteTotalFragments(const char *name, const char *prefix);
    7272  bool WriteLastMatrix(const char *name, const char *prefix, const char *suffix);
    73 }; 
     73};
    7474
    7575// ======================================= CLASS EnergyMatrix =============================
     
    7777class EnergyMatrix : public MatrixContainer {
    7878  public:
     79    bool ParseIndices();
    7980    bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign);
    8081    bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
     
    8485
    8586class ForceMatrix : public MatrixContainer {
    86   public: 
     87  public:
    8788    bool ParseIndices(char *name);
    8889    bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
     
    114115    int *FragmentsPerOrder;
    115116    int **OrderSet;
    116  
     117
    117118  KeySetsContainer();
    118119  ~KeySetsContainer();
    119    
     120
    120121  bool ParseKeySets(const char *name, const int *ACounter, const int FCounter);
    121122  bool ParseManyBodyTerms();
  • src/periodentafel.hpp

    rce5ac3 rd067d45  
    2121 */
    2222class element {
    23   public:
    24     double mass;    //!< mass in g/mol
    25     double CovalentRadius;  //!< covalent radius
    26     double VanDerWaalsRadius;  //!< can-der-Waals radius
    27     int Z;          //!< atomic number
    28     char name[64];  //!< atom name, i.e. "Hydrogren"
    29     char symbol[3]; //!< short form of the atom, i.e. "H"
    30     char period[8];    //!< period: n quantum number
    31     char group[8];    //!< group: l quantum number
    32     char block[8];    //!< block: l quantum number
    33     element *previous;  //!< previous item in list
    34     element *next;  //!< next element in list
    35     int *sort;      //!< sorc criteria
    36     int No;        //!< number of element set on periodentafel::Output()
    37     double Valence;  //!< number of valence electrons for this element
    38     int NoValenceOrbitals;  //!< number of valence orbitals, used for determining bond degree in molecule::CreateConnectmatrix()
    39     double HBondDistance[NDIM]; //!< distance in Angstrom of this element to hydrogen  (for single, double and triple bonds)
    40     double HBondAngle[NDIM];    //!< typical angle for one, two, three bonded hydrogen (in degrees)
     23        public:
     24                double mass;            //!< mass in g/mol
     25                double CovalentRadius;  //!< covalent radius
     26                double VanDerWaalsRadius;       //!< can-der-Waals radius
     27                int Z;                                  //!< atomic number
     28                char name[64];  //!< atom name, i.e. "Hydrogren"
     29                char symbol[3]; //!< short form of the atom, i.e. "H"
     30                char period[8];         //!< period: n quantum number
     31                char group[8];          //!< group: l quantum number
     32                char block[8];          //!< block: l quantum number
     33                element *previous;      //!< previous item in list
     34                element *next;  //!< next element in list
     35                int *sort;                      //!< sorc criteria
     36                int No;                          //!< number of element set on periodentafel::Output()
     37                double Valence; //!< number of valence electrons for this element
     38                int NoValenceOrbitals;  //!< number of valence orbitals, used for determining bond degree in molecule::CreateConnectmatrix()
     39                double HBondDistance[NDIM]; //!< distance in Angstrom of this element to hydrogen       (for single, double and triple bonds)
     40                double HBondAngle[NDIM];                //!< typical angle for one, two, three bonded hydrogen (in degrees)
    4141
    42   element();
    43   ~element();
     42        element();
     43        ~element();
    4444
    45   //> print element entries to screen
    46   bool Output(ofstream *out) const;
    47   bool Checkout(ofstream *out, const int No, const int NoOfAtoms) const;
    48  
    49   private:
     45        //> print element entries to screen
     46        bool Output(ofstream *out) const;
     47        bool Checkout(ofstream *out, const int No, const int NoOfAtoms) const;
     48
     49        private:
    5050};
    5151
     
    5353 */
    5454class periodentafel {
    55   public:
    56     element *start; //!< start of element list
    57     element *end;  //!< end of element list
    58     char header1[MAXSTRINGSIZE]; //!< store first header line
    59     char header2[MAXSTRINGSIZE]; //!< store second header line
    60  
    61   periodentafel();
    62   ~periodentafel();
    63  
    64   bool AddElement(element *pointer);
    65   bool RemoveElement(element *pointer);
    66   bool CleanupPeriodtable();
    67   element * FindElement(int Z);
    68   element * FindElement(char *shorthand) const;
    69   element * AskElement();
    70   bool Output(ofstream *output) const;
    71   bool Checkout(ofstream *output, const int *checkliste) const;
    72   bool LoadPeriodentafel(char *path = NULL);
    73   bool StorePeriodentafel(char *path = NULL) const;
    74  
    75   private:
     55        public:
     56                element *start; //!< start of element list
     57                element *end;    //!< end of element list
     58                char header1[MAXSTRINGSIZE]; //!< store first header line
     59                char header2[MAXSTRINGSIZE]; //!< store second header line
     60
     61        periodentafel();
     62        ~periodentafel();
     63
     64        bool AddElement(element *pointer);
     65        bool RemoveElement(element *pointer);
     66        bool CleanupPeriodtable();
     67        element * FindElement(int Z);
     68        element * FindElement(char *shorthand) const;
     69        element * AskElement();
     70        bool Output(ofstream *output) const;
     71        bool Checkout(ofstream *output, const int *checkliste) const;
     72        bool LoadPeriodentafel(char *path = NULL);
     73        bool StorePeriodentafel(char *path = NULL) const;
     74
     75        private:
    7676};
    7777
  • src/stackclass.hpp

    rce5ac3 rd067d45  
    1010 */
    1111template <typename T> class StackClass {
    12   public:
    13   StackClass<T>(int dimension);
    14   ~StackClass<T>();
    15  
    16   bool Push(T object);
    17   T PopFirst();
    18   T PopLast();
    19   bool RemoveItem(T ptr);
    20   void ClearStack();
    21   bool IsEmpty();
    22   bool IsFull();
    23   int ItemCount();
    24   void Output(ofstream *out) const;
    25   void TestImplementation(ofstream *out, T test);
    26  
    27   private:
    28     T *StackList;  //!< the list containing the atom pointers
    29     int EntryCount;    //!< number of entries in the stack
    30     int CurrentLastEntry;  //!< Current last entry (newest item on stack)
    31     int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
    32     int NextFreeField;      //!< Current index of next free field
     12        public:
     13        StackClass<T>(int dimension);
     14        ~StackClass<T>();
     15
     16        bool Push(T object);
     17        T PopFirst();
     18        T PopLast();
     19        bool RemoveItem(T ptr);
     20        void ClearStack();
     21        bool IsEmpty();
     22        bool IsFull();
     23        int ItemCount();
     24        void Output(ofstream *out) const;
     25        void TestImplementation(ofstream *out, T test);
     26
     27        private:
     28                T *StackList;    //!< the list containing the atom pointers
     29                int EntryCount;          //!< number of entries in the stack
     30                int CurrentLastEntry;    //!< Current last entry (newest item on stack)
     31                int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
     32                int NextFreeField;                      //!< Current index of next free field
    3333};
    3434
     
    3737template <typename T> StackClass<T>::StackClass(int dimension)
    3838{
    39   CurrentLastEntry = 0;
    40   CurrentFirstEntry = 0;
    41   NextFreeField = 0;
    42   EntryCount = dimension;
    43   StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
     39        CurrentLastEntry = 0;
     40        CurrentFirstEntry = 0;
     41        NextFreeField = 0;
     42        EntryCount = dimension;
     43        StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
    4444};
    4545
     
    4848template <typename T> StackClass<T>::~StackClass()
    4949{
    50   Free((void **)&StackList, "StackClass::StackClass: **StackList");
     50        Free((void **)&StackList, "StackClass::StackClass: **StackList");
    5151};
    5252
     
    5757template <typename T> bool StackClass<T>::Push(T object)
    5858{
    59   if (!IsFull()) {    // check whether free field is really not occupied
    60     StackList[NextFreeField] = object;
    61     CurrentLastEntry = NextFreeField;
    62     NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
    63     return true;
    64   } else {
    65     cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
    66     return false;
    67   }
     59        if (!IsFull()) {                // check whether free field is really not occupied
     60                StackList[NextFreeField] = object;
     61                CurrentLastEntry = NextFreeField;
     62                NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
     63                return true;
     64        } else {
     65                cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
     66                return false;
     67        }
    6868};
    6969
     
    7474template <typename T> T StackClass<T>::PopFirst()
    7575{
    76   T Walker = NULL;
    77   if (!IsEmpty()) {
    78     Walker = StackList[CurrentFirstEntry];
    79     if (Walker == NULL)
    80       cerr << "ERROR: Stack's field is empty!" << endl;
    81     StackList[CurrentFirstEntry] = NULL;
    82     if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
    83       CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    84     } else {
    85       CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    86       CurrentLastEntry = CurrentFirstEntry;
    87     }
    88   } else
    89     cerr << "ERROR: Stack is empty!" << endl;
    90   return Walker;
     76        T Walker = NULL;
     77        if (!IsEmpty()) {
     78                Walker = StackList[CurrentFirstEntry];
     79                if (Walker == NULL)
     80                        cerr << "ERROR: Stack's field is empty!" << endl;
     81                StackList[CurrentFirstEntry] = NULL;
     82                if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
     83                        CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     84                } else {
     85                        CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     86                        CurrentLastEntry = CurrentFirstEntry;
     87                }
     88        } else
     89                cerr << "ERROR: Stack is empty!" << endl;
     90        return Walker;
    9191};
    9292
     
    9797template <typename T> T StackClass<T>::PopLast()
    9898{
    99   T Walker = NULL;
    100   if (!IsEmpty()) {
    101     Walker = StackList[CurrentLastEntry];
    102     StackList[CurrentLastEntry] = NULL;
    103     if (Walker == NULL)
    104       cerr << "ERROR: Stack's field is empty!" << endl;
    105     NextFreeField = CurrentLastEntry;
    106     if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
    107       CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
    108   } else {
    109     cerr << "ERROR: Stack is empty!" << endl;
    110   }
    111   return Walker;
     99        T Walker = NULL;
     100        if (!IsEmpty()) {
     101                Walker = StackList[CurrentLastEntry];
     102                StackList[CurrentLastEntry] = NULL;
     103                if (Walker == NULL)
     104                        cerr << "ERROR: Stack's field is empty!" << endl;
     105                NextFreeField = CurrentLastEntry;
     106                if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
     107                        CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
     108        } else {
     109                cerr << "ERROR: Stack is empty!" << endl;
     110        }
     111        return Walker;
    112112};
    113113
     
    120120template <typename T> bool StackClass<T>::RemoveItem(T ptr)
    121121{
    122   bool found = false;
    123   cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
    124   int i=CurrentFirstEntry;
    125   if (!IsEmpty())
    126     do {
    127       if (StackList[i] == ptr) {  // if item found, remove
    128         cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
    129         found = true;
    130         StackList[i] = NULL;
    131       }
    132       if ((found) && (StackList[i] != NULL)) {  // means we have to shift (and not the removed item)
    133         if (i == 0) { // we are down to first item in stack, have to put onto last item
    134           cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
    135           StackList[EntryCount-1] = StackList[0];
    136         } else {
    137           cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
    138           StackList[i-1] = StackList[i];
    139         }
    140       }
    141       i=((i + 1) % EntryCount); // step on
    142     } while (i!=NextFreeField);
    143   else
    144     cerr << "ERROR: Stack is already empty!" << endl;
    145   if (found) {
    146     NextFreeField = CurrentLastEntry;
    147     if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
    148       CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
    149   }
    150   return found;
     122        bool found = false;
     123        cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
     124        int i=CurrentFirstEntry;
     125        if (!IsEmpty())
     126                do {
     127                        if (StackList[i] == ptr) {      // if item found, remove
     128                                cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
     129                                found = true;
     130                                StackList[i] = NULL;
     131                        }
     132                        if ((found) && (StackList[i] != NULL)) {        // means we have to shift (and not the removed item)
     133                                if (i == 0) { // we are down to first item in stack, have to put onto last item
     134                                        cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
     135                                        StackList[EntryCount-1] = StackList[0];
     136                                } else {
     137                                        cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
     138                                        StackList[i-1] = StackList[i];
     139                                }
     140                        }
     141                        i=((i + 1) % EntryCount); // step on
     142                } while (i!=NextFreeField);
     143        else
     144                cerr << "ERROR: Stack is already empty!" << endl;
     145        if (found) {
     146                NextFreeField = CurrentLastEntry;
     147                if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
     148                        CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
     149        }
     150        return found;
    151151};
    152152
    153153/** Test the functionality of the stack.
    154154 * \param *out ofstream for debugging
    155  * \param *test one item to put on stack 
     155 * \param *test one item to put on stack
    156156 * \return true - all tests worked correctly
    157157 */
    158158template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)
    159159{
    160   T Walker = test;
    161   *out << Verbose(1) << "Testing the snake stack..." << endl;
    162   for (int i=0;i<EntryCount;i++) {
    163     *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
    164     Push(Walker);
    165     Walker=Walker->next;
    166   }
    167   *out << endl;
    168   Output(out);
    169   if (IsFull())
    170     *out << "Stack is full as supposed to be!" << endl;
    171   else
    172     *out << "ERROR: Stack is not as full as supposed to be!" << endl;
    173   //if (StackList[(EntryCount+1)/2] != NULL) {
    174     *out << "Removing element in the middle ..." << endl;
    175     RemoveItem(StackList[(EntryCount+1)/2]);
    176     Output(out);
    177   //}
    178   //if (StackList[CurrentFirstEntry] != NULL) {
    179     *out << "Removing first element  ..." << endl;
    180     RemoveItem(StackList[CurrentFirstEntry]);
    181     Output(out);
    182   //}
    183   //if (StackList[CurrentLastEntry] != NULL) {
    184     *out << "Removing last element ..." << endl;
    185     RemoveItem(StackList[CurrentLastEntry]);
    186     Output(out);
    187   //}
    188   *out << "Clearing stack ... " << endl; 
    189   ClearStack();
    190   Output(out);
    191   if (IsEmpty())
    192     *out << "Stack is empty as supposed to be!" << endl;
    193   else
    194     *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
    195   *out << "done." << endl;
     160        T Walker = test;
     161        *out << Verbose(1) << "Testing the snake stack..." << endl;
     162        for (int i=0;i<EntryCount;i++) {
     163                *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
     164                Push(Walker);
     165                Walker=Walker->next;
     166        }
     167        *out << endl;
     168        Output(out);
     169        if (IsFull())
     170                *out << "Stack is full as supposed to be!" << endl;
     171        else
     172                *out << "ERROR: Stack is not as full as supposed to be!" << endl;
     173        //if (StackList[(EntryCount+1)/2] != NULL) {
     174                *out << "Removing element in the middle ..." << endl;
     175                RemoveItem(StackList[(EntryCount+1)/2]);
     176                Output(out);
     177        //}
     178        //if (StackList[CurrentFirstEntry] != NULL) {
     179                *out << "Removing first element ..." << endl;
     180                RemoveItem(StackList[CurrentFirstEntry]);
     181                Output(out);
     182        //}
     183        //if (StackList[CurrentLastEntry] != NULL) {
     184                *out << "Removing last element ..." << endl;
     185                RemoveItem(StackList[CurrentLastEntry]);
     186                Output(out);
     187        //}
     188        *out << "Clearing stack ... " << endl;
     189        ClearStack();
     190        Output(out);
     191        if (IsEmpty())
     192                *out << "Stack is empty as supposed to be!" << endl;
     193        else
     194                *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
     195        *out << "done." << endl;
    196196};
    197197
     
    201201template <typename T> void StackClass<T>::Output(ofstream *out) const
    202202{
    203   *out << "Contents of Stack: ";
    204   for(int i=0;i<EntryCount;i++) {
    205     *out << "\t";
    206     if (i == CurrentFirstEntry)
    207       *out << " 1";
    208     if  (i == CurrentLastEntry)
    209       *out << " "<< EntryCount;
    210     if (i ==  NextFreeField)
    211       *out << " F";
    212     *out << ": " << StackList[i];
    213   }
    214   *out << endl;
     203        *out << "Contents of Stack: ";
     204        for(int i=0;i<EntryCount;i++) {
     205                *out << "\t";
     206                if (i == CurrentFirstEntry)
     207                        *out << " 1";
     208                if      (i == CurrentLastEntry)
     209                        *out << " "<< EntryCount;
     210                if (i ==        NextFreeField)
     211                        *out << " F";
     212                *out << ": " << StackList[i];
     213        }
     214        *out << endl;
    215215};
    216216
     
    222222template <typename T> bool StackClass<T>::IsEmpty()
    223223{
    224   return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
     224        return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
    225225};
    226226
     
    232232template <typename T> bool StackClass<T>::IsFull()
    233233{
    234   return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
     234        return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
    235235};
    236236
     
    242242template <typename T> int StackClass<T>::ItemCount()
    243243{
    244   //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
    245   return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
     244        //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
     245        return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
    246246};
    247247
     
    251251template <typename T> void StackClass<T>::ClearStack()
    252252{
    253   for(int i=EntryCount; i--;)
    254     StackList[i] = NULL;
    255   CurrentFirstEntry = 0;
    256   CurrentLastEntry = 0;
    257   NextFreeField = 0;
     253        for(int i=EntryCount; i--;)
     254                StackList[i] = NULL;
     255        CurrentFirstEntry = 0;
     256        CurrentLastEntry = 0;
     257        NextFreeField = 0;
    258258};
    259259
  • src/vector.cpp

    rce5ac3 rd067d45  
    2828double Vector::DistanceSquared(const Vector *y) const
    2929{
    30   double res = 0.;
    31   for (int i=NDIM;i--;)
    32     res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33   return (res);
     30        double res = 0.;
     31        for (int i=NDIM;i--;)
     32                res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     33        return (res);
    3434};
    3535
     
    4040double Vector::Distance(const Vector *y) const
    4141{
    42   double res = 0.;
    43   for (int i=NDIM;i--;)
    44     res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    45   return (sqrt(res));
     42        double res = 0.;
     43        for (int i=NDIM;i--;)
     44                res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     45        return (sqrt(res));
     46};
     47
     48/** Calculates distance between this and another vector in a periodic cell.
     49 * \param *y array to second vector
     50 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell
     51 * \return \f$| x - y |\f$
     52 */
     53double Vector::PeriodicDistance(const Vector *y, const double *cell_size) const
     54{
     55        double res = Distance(y), tmp, matrix[NDIM*NDIM];
     56        Vector Shiftedy, TranslationVector;
     57        int N[NDIM];
     58        matrix[0] = cell_size[0];
     59        matrix[1] = cell_size[1];
     60        matrix[2] = cell_size[3];
     61        matrix[3] = cell_size[1];
     62        matrix[4] = cell_size[2];
     63        matrix[5] = cell_size[4];
     64        matrix[6] = cell_size[3];
     65        matrix[7] = cell_size[4];
     66        matrix[8] = cell_size[5];
     67        // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     68        for (N[0]=-1;N[0]<=1;N[0]++)
     69                for (N[1]=-1;N[1]<=1;N[1]++)
     70                        for (N[2]=-1;N[2]<=1;N[2]++) {
     71                                // create the translation vector
     72                                TranslationVector.Zero();
     73                                for (int i=NDIM;i--;)
     74                                        TranslationVector.x[i] = (double)N[i];
     75                                TranslationVector.MatrixMultiplication(matrix);
     76                                // add onto the original vector to compare with
     77                                Shiftedy.CopyVector(y);
     78                                Shiftedy.AddVector(&TranslationVector);
     79                                // get distance and compare with minimum so far
     80                                tmp = Distance(&Shiftedy);
     81                                if (tmp < res) res = tmp;
     82                        }
     83        return (res);
    4684};
    4785
     
    5189 * \return \f$| x - y |^2\f$
    5290 */
    53 double Vector::PeriodicDistance(const Vector *y, const double *cell_size) const
    54 {
    55   double res = Distance(y), tmp, matrix[NDIM*NDIM];
    56   Vector Shiftedy, TranslationVector;
    57   int N[NDIM];
    58   matrix[0] = cell_size[0];
    59   matrix[1] = cell_size[1];
    60   matrix[2] = cell_size[3];
    61   matrix[3] = cell_size[1];
    62   matrix[4] = cell_size[2];
    63   matrix[5] = cell_size[4];
    64   matrix[6] = cell_size[3];
    65   matrix[7] = cell_size[4];
    66   matrix[8] = cell_size[5];
    67   // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
    68   for (N[0]=-1;N[0]<=1;N[0]++)
    69     for (N[1]=-1;N[1]<=1;N[1]++)
    70       for (N[2]=-1;N[2]<=1;N[2]++) {
    71         // create the translation vector
    72         TranslationVector.Zero();
    73         for (int i=NDIM;i--;)
    74           TranslationVector.x[i] = (double)N[i];
    75         TranslationVector.MatrixMultiplication(matrix);
    76         // add onto the original vector to compare with
    77         Shiftedy.CopyVector(y);
    78         Shiftedy.AddVector(&TranslationVector);
    79         // get distance and compare with minimum so far
    80         tmp = Distance(&Shiftedy);
    81         if (tmp < res) res = tmp;
    82       }
    83   return (res);
     91double Vector::PeriodicDistanceSquared(const Vector *y, const double *cell_size) const
     92{
     93        double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];
     94        Vector Shiftedy, TranslationVector;
     95        int N[NDIM];
     96        matrix[0] = cell_size[0];
     97        matrix[1] = cell_size[1];
     98        matrix[2] = cell_size[3];
     99        matrix[3] = cell_size[1];
     100        matrix[4] = cell_size[2];
     101        matrix[5] = cell_size[4];
     102        matrix[6] = cell_size[3];
     103        matrix[7] = cell_size[4];
     104        matrix[8] = cell_size[5];
     105        // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     106        for (N[0]=-1;N[0]<=1;N[0]++)
     107                for (N[1]=-1;N[1]<=1;N[1]++)
     108                        for (N[2]=-1;N[2]<=1;N[2]++) {
     109                                // create the translation vector
     110                                TranslationVector.Zero();
     111                                for (int i=NDIM;i--;)
     112                                        TranslationVector.x[i] = (double)N[i];
     113                                TranslationVector.MatrixMultiplication(matrix);
     114                                // add onto the original vector to compare with
     115                                Shiftedy.CopyVector(y);
     116                                Shiftedy.AddVector(&TranslationVector);
     117                                // get distance and compare with minimum so far
     118                                tmp = DistanceSquared(&Shiftedy);
     119                                if (tmp < res) res = tmp;
     120                        }
     121        return (res);
    84122};
    85123
     
    90128void Vector::KeepPeriodic(ofstream *out, double *matrix)
    91129{
    92 //  int N[NDIM];
    93 //  bool flag = false;
    94   //vector Shifted, TranslationVector;
    95   Vector TestVector;
    96 //  *out << Verbose(1) << "Begin of KeepPeriodic." << endl;
    97 //  *out << Verbose(2) << "Vector is: ";
    98 //  Output(out);
    99 //  *out << endl;
    100   TestVector.CopyVector(this);
    101   TestVector.InverseMatrixMultiplication(matrix);
    102   for(int i=NDIM;i--;) { // correct periodically
    103     if (TestVector.x[i] < 0) {  // get every coefficient into the interval [0,1)
    104       TestVector.x[i] += ceil(TestVector.x[i]);
    105     } else {
    106       TestVector.x[i] -= floor(TestVector.x[i]);
    107     }
    108   }
    109   TestVector.MatrixMultiplication(matrix);
    110   CopyVector(&TestVector);
    111 //  *out << Verbose(2) << "New corrected vector is: ";
    112 //  Output(out);
    113 //  *out << endl;
    114 //  *out << Verbose(1) << "End of KeepPeriodic." << endl;
     130//      int N[NDIM];
     131//      bool flag = false;
     132        //vector Shifted, TranslationVector;
     133        Vector TestVector;
     134//      *out << Verbose(1) << "Begin of KeepPeriodic." << endl;
     135//      *out << Verbose(2) << "Vector is: ";
     136//      Output(out);
     137//      *out << endl;
     138        TestVector.CopyVector(this);
     139        TestVector.InverseMatrixMultiplication(matrix);
     140        for(int i=NDIM;i--;) { // correct periodically
     141                if (TestVector.x[i] < 0) {      // get every coefficient into the interval [0,1)
     142                        TestVector.x[i] += ceil(TestVector.x[i]);
     143                } else {
     144                        TestVector.x[i] -= floor(TestVector.x[i]);
     145                }
     146        }
     147        TestVector.MatrixMultiplication(matrix);
     148        CopyVector(&TestVector);
     149//      *out << Verbose(2) << "New corrected vector is: ";
     150//      Output(out);
     151//      *out << endl;
     152//      *out << Verbose(1) << "End of KeepPeriodic." << endl;
    115153};
    116154
     
    121159double Vector::ScalarProduct(const Vector *y) const
    122160{
    123   double res = 0.;
    124   for (int i=NDIM;i--;)
    125     res += x[i]*y->x[i];
    126   return (res);
     161        double res = 0.;
     162        for (int i=NDIM;i--;)
     163                res += x[i]*y->x[i];
     164        return (res);
    127165};
    128166
    129167
    130168/** Calculates VectorProduct between this and another vector.
    131  *  -# returns the Product in place of vector from which it was initiated
    132  *  -# ATTENTION: Only three dim.
    133  *  \param *y array to vector with which to calculate crossproduct
    134  *  \return \f$ x \times y \f&
     169 *      -# returns the Product in place of vector from which it was initiated
     170 *      -# ATTENTION: Only three dim.
     171 *      \param *y array to vector with which to calculate crossproduct
     172 *      \return \f$ x \times y \f&
    135173 */
    136174void Vector::VectorProduct(const Vector *y)
    137175{
    138   Vector tmp;
    139   tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
    140   tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
    141   tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
    142   this->CopyVector(&tmp);
     176        Vector tmp;
     177        tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
     178        tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
     179        tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
     180        this->CopyVector(&tmp);
    143181
    144182};
     
    151189void Vector::ProjectOntoPlane(const Vector *y)
    152190{
    153   Vector tmp;
    154   tmp.CopyVector(y);
    155   tmp.Normalize();
    156   tmp.Scale(ScalarProduct(&tmp));
    157   this->SubtractVector(&tmp);
     191        Vector tmp;
     192        tmp.CopyVector(y);
     193        tmp.Normalize();
     194        tmp.Scale(ScalarProduct(&tmp));
     195        this->SubtractVector(&tmp);
    158196};
    159197
     
    164202double Vector::Projection(const Vector *y) const
    165203{
    166   return (ScalarProduct(y));
     204        return (ScalarProduct(y));
    167205};
    168206
     
    172210double Vector::Norm() const
    173211{
    174   double res = 0.;
    175   for (int i=NDIM;i--;)
    176     res += this->x[i]*this->x[i];
    177   return (sqrt(res));
     212        double res = 0.;
     213        for (int i=NDIM;i--;)
     214                res += this->x[i]*this->x[i];
     215        return (sqrt(res));
    178216};
    179217
     
    182220void Vector::Normalize()
    183221{
    184   double res = 0.;
    185   for (int i=NDIM;i--;)
    186     res += this->x[i]*this->x[i];
    187   if (fabs(res) > MYEPSILON)
    188     res = 1./sqrt(res);
    189   Scale(&res);
     222        double res = 0.;
     223        for (int i=NDIM;i--;)
     224                res += this->x[i]*this->x[i];
     225        if (fabs(res) > MYEPSILON)
     226                res = 1./sqrt(res);
     227        Scale(&res);
    190228};
    191229
     
    194232void Vector::Zero()
    195233{
    196   for (int i=NDIM;i--;)
    197     this->x[i] = 0.;
     234        for (int i=NDIM;i--;)
     235                this->x[i] = 0.;
    198236};
    199237
     
    202240void Vector::One(double one)
    203241{
    204   for (int i=NDIM;i--;)
    205     this->x[i] = one;
     242        for (int i=NDIM;i--;)
     243                this->x[i] = one;
    206244};
    207245
     
    210248void Vector::Init(double x1, double x2, double x3)
    211249{
    212   x[0] = x1;
    213   x[1] = x2;
    214   x[2] = x3;
     250        x[0] = x1;
     251        x[1] = x2;
     252        x[2] = x3;
    215253};
    216254
     
    221259double Vector::Angle(const Vector *y) const
    222260{
    223   return acos(this->ScalarProduct(y)/Norm()/y->Norm());
     261        return acos(this->ScalarProduct(y)/Norm()/y->Norm());
    224262};
    225263
     
    230268void Vector::RotateVector(const Vector *axis, const double alpha)
    231269{
    232   Vector a,y;
    233   // normalise this vector with respect to axis
    234   a.CopyVector(this);
    235   a.Scale(Projection(axis));
    236   SubtractVector(&a);
    237   // construct normal vector
    238   y.MakeNormalVector(axis,this);
    239   y.Scale(Norm());
    240   // scale normal vector by sine and this vector by cosine
    241   y.Scale(sin(alpha));
    242   Scale(cos(alpha));
    243   // add scaled normal vector onto this vector
    244   AddVector(&y);
    245   // add part in axis direction
    246   AddVector(&a);
     270        Vector a,y;
     271        // normalise this vector with respect to axis
     272        a.CopyVector(this);
     273        a.Scale(Projection(axis));
     274        SubtractVector(&a);
     275        // construct normal vector
     276        y.MakeNormalVector(axis,this);
     277        y.Scale(Norm());
     278        // scale normal vector by sine and this vector by cosine
     279        y.Scale(sin(alpha));
     280        Scale(cos(alpha));
     281        // add scaled normal vector onto this vector
     282        AddVector(&y);
     283        // add part in axis direction
     284        AddVector(&a);
    247285};
    248286
     
    254292Vector& operator+=(Vector& a, const Vector& b)
    255293{
    256   a.AddVector(&b);
    257   return a;
     294        a.AddVector(&b);
     295        return a;
    258296};
    259297/** factor each component of \a a times a double \a m.
     
    264302Vector& operator*=(Vector& a, const double m)
    265303{
    266   a.Scale(m);
    267   return a;
    268 };
    269 
    270 /** Sums two vectors \a  and \b component-wise.
     304        a.Scale(m);
     305        return a;
     306};
     307
     308/** Sums two vectors \a and \b component-wise.
    271309 * \param a first vector
    272310 * \param b second vector
     
    275313Vector& operator+(const Vector& a, const Vector& b)
    276314{
    277   Vector *x = new Vector;
    278   x->CopyVector(&a);
    279   x->AddVector(&b);
    280   return *x;
     315        Vector *x = new Vector;
     316        x->CopyVector(&a);
     317        x->AddVector(&b);
     318        return *x;
    281319};
    282320
     
    288326Vector& operator*(const Vector& a, const double m)
    289327{
    290   Vector *x = new Vector;
    291   x->CopyVector(&a);
    292   x->Scale(m);
    293   return *x;
     328        Vector *x = new Vector;
     329        x->CopyVector(&a);
     330        x->Scale(m);
     331        return *x;
    294332};
    295333
     
    300338bool Vector::Output(ofstream *out) const
    301339{
    302   if (out != NULL) {
    303     *out << "(";
    304     for (int i=0;i<NDIM;i++) {
    305       *out << x[i];
    306       if (i != 2)
    307         *out << ",";
    308     }
    309     *out << ")";
    310     return true;
    311   } else
    312     return false;
    313 };
    314 
    315 /** Prints a 3dim vector to a stream.
    316  * \param ost output stream
    317  * \param v Vector to be printed
    318  * \return output stream
    319  */
     340        if (out != NULL) {
     341                *out << "(";
     342                for (int i=0;i<NDIM;i++) {
     343                        *out << x[i];
     344                        if (i != 2)
     345                                *out << ",";
     346                }
     347                *out << ")";
     348                return true;
     349        } else
     350                return false;
     351};
     352
    320353ostream& operator<<(ostream& ost,Vector& m)
    321354{
    322   ost << "(";
    323   for (int i=0;i<NDIM;i++) {
    324     ost << m.x[i];
    325     if (i != 2)
    326       ost << ",";
    327   }
    328   ost << ")";
    329   return ost;
     355        ost << "(";
     356        for (int i=0;i<NDIM;i++) {
     357                ost << m.x[i];
     358                if (i != 2)
     359                        ost << ",";
     360        }
     361        ost << ")";
     362        return ost;
    330363};
    331364
     
    335368void Vector::Scale(double **factor)
    336369{
    337   for (int i=NDIM;i--;)
    338     x[i] *= (*factor)[i];
     370        for (int i=NDIM;i--;)
     371                x[i] *= (*factor)[i];
    339372};
    340373
    341374void Vector::Scale(double *factor)
    342375{
    343   for (int i=NDIM;i--;)
    344     x[i] *= *factor;
     376        for (int i=NDIM;i--;)
     377                x[i] *= *factor;
    345378};
    346379
    347380void Vector::Scale(double factor)
    348381{
    349   for (int i=NDIM;i--;)
    350     x[i] *= factor;
     382        for (int i=NDIM;i--;)
     383                x[i] *= factor;
    351384};
    352385
     
    356389void Vector::Translate(const Vector *trans)
    357390{
    358   for (int i=NDIM;i--;)
    359     x[i] += trans->x[i];
     391        for (int i=NDIM;i--;)
     392                x[i] += trans->x[i];
    360393};
    361394
     
    365398void Vector::MatrixMultiplication(double *M)
    366399{
    367   Vector C;
    368   // do the matrix multiplication
    369   C.x[0] = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];
    370   C.x[1] = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];
    371   C.x[2] = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];
    372   // transfer the result into this
    373   for (int i=NDIM;i--;)
    374     x[i] = C.x[i];
     400        Vector C;
     401        // do the matrix multiplication
     402        C.x[0] = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];
     403        C.x[1] = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];
     404        C.x[2] = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];
     405        // transfer the result into this
     406        for (int i=NDIM;i--;)
     407                x[i] = C.x[i];
    375408};
    376409
     
    380413void Vector::InverseMatrixMultiplication(double *A)
    381414{
    382   Vector C;
    383   double B[NDIM*NDIM];
    384   double detA = RDET3(A);
    385   double detAReci;
    386 
    387   // calculate the inverse B
    388   if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
    389     detAReci = 1./detA;
    390     B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);    // A_11
    391     B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);    // A_12
    392     B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);    // A_13
    393     B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);    // A_21
    394     B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);    // A_22
    395     B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);    // A_23
    396     B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);    // A_31
    397     B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    398     B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    399 
    400     // do the matrix multiplication
    401     C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
    402     C.x[1] = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];
    403     C.x[2] = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];
    404     // transfer the result into this
    405     for (int i=NDIM;i--;)
    406       x[i] = C.x[i];
    407   } else {
    408     cerr << "ERROR: inverse of matrix does not exists!" << endl;
    409   }
     415        Vector C;
     416        double B[NDIM*NDIM];
     417        double detA = RDET3(A);
     418        double detAReci;
     419
     420        // calculate the inverse B
     421        if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
     422                detAReci = 1./detA;
     423                B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);            // A_11
     424                B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);            // A_12
     425                B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);            // A_13
     426                B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);            // A_21
     427                B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);            // A_22
     428                B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);            // A_23
     429                B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);            // A_31
     430                B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);            // A_32
     431                B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);            // A_33
     432
     433                // do the matrix multiplication
     434                C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     435                C.x[1] = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];
     436                C.x[2] = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];
     437                // transfer the result into this
     438                for (int i=NDIM;i--;)
     439                        x[i] = C.x[i];
     440        } else {
     441                cerr << "ERROR: inverse of matrix does not exists!" << endl;
     442        }
    410443};
    411444
     
    420453void Vector::LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors)
    421454{
    422   for(int i=NDIM;i--;)
    423     x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
     455        for(int i=NDIM;i--;)
     456                x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
    424457};
    425458
     
    429462void Vector::Mirror(const Vector *n)
    430463{
    431   double projection;
    432   projection = ScalarProduct(n)/n->ScalarProduct(n);    // remove constancy from n (keep as logical one)
    433   // withdraw projected vector twice from original one
    434   cout << Verbose(1) << "Vector: ";
    435   Output((ofstream *)&cout);
    436   cout << "\t";
    437   for (int i=NDIM;i--;)
    438     x[i] -= 2.*projection*n->x[i];
    439   cout << "Projected vector: ";
    440   Output((ofstream *)&cout);
    441   cout << endl;
     464        double projection;
     465        projection = ScalarProduct(n)/n->ScalarProduct(n);              // remove constancy from n (keep as logical one)
     466        // withdraw projected vector twice from original one
     467        cout << Verbose(1) << "Vector: ";
     468        Output((ofstream *)&cout);
     469        cout << "\t";
     470        for (int i=NDIM;i--;)
     471                x[i] -= 2.*projection*n->x[i];
     472        cout << "Projected vector: ";
     473        Output((ofstream *)&cout);
     474        cout << endl;
    442475};
    443476
     
    451484bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2, const Vector *y3)
    452485{
    453   Vector x1, x2;
    454 
    455   x1.CopyVector(y1);
    456   x1.SubtractVector(y2);
    457   x2.CopyVector(y3);
    458   x2.SubtractVector(y2);
    459   if ((x1.Norm()==0) || (x2.Norm()==0)) {
    460     cout << Verbose(4) << "Given vectors are linear dependent." << endl;
    461     return false;
    462   }
    463 //  cout << Verbose(4) << "relative, first plane coordinates:";
    464 //  x1.Output((ofstream *)&cout);
    465 //  cout << endl;
    466 //  cout << Verbose(4) << "second plane coordinates:";
    467 //  x2.Output((ofstream *)&cout);
    468 //  cout << endl;
    469 
    470   this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
    471   this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
    472   this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    473   Normalize();
    474 
    475   return true;
     486        Vector x1, x2;
     487
     488        x1.CopyVector(y1);
     489        x1.SubtractVector(y2);
     490        x2.CopyVector(y3);
     491        x2.SubtractVector(y2);
     492        if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
     493                cout << Verbose(4) << "Given vectors are linear dependent." << endl;
     494                return false;
     495        }
     496//      cout << Verbose(4) << "relative, first plane coordinates:";
     497//      x1.Output((ofstream *)&cout);
     498//      cout << endl;
     499//      cout << Verbose(4) << "second plane coordinates:";
     500//      x2.Output((ofstream *)&cout);
     501//      cout << endl;
     502
     503        this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
     504        this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
     505        this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
     506        Normalize();
     507
     508        return true;
    476509};
    477510
     
    487520bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2)
    488521{
    489   Vector x1,x2;
    490   x1.CopyVector(y1);
    491   x2.CopyVector(y2);
    492   Zero();
    493   if ((x1.Norm()==0) || (x2.Norm()==0)) {
    494     cout << Verbose(4) << "Given vectors are linear dependent." << endl;
    495     return false;
    496   }
    497 //  cout << Verbose(4) << "relative, first plane coordinates:";
    498 //  x1.Output((ofstream *)&cout);
    499 //  cout << endl;
    500 //  cout << Verbose(4) << "second plane coordinates:";
    501 //  x2.Output((ofstream *)&cout);
    502 //  cout << endl;
    503 
    504   this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
    505   this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
    506   this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    507   Normalize();
    508 
    509   return true;
     522        Vector x1,x2;
     523        x1.CopyVector(y1);
     524        x2.CopyVector(y2);
     525        Zero();
     526        if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
     527                cout << Verbose(4) << "Given vectors are linear dependent." << endl;
     528                return false;
     529        }
     530//      cout << Verbose(4) << "relative, first plane coordinates:";
     531//      x1.Output((ofstream *)&cout);
     532//      cout << endl;
     533//      cout << Verbose(4) << "second plane coordinates:";
     534//      x2.Output((ofstream *)&cout);
     535//      cout << endl;
     536
     537        this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
     538        this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
     539        this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
     540        Normalize();
     541
     542        return true;
    510543};
    511544
     
    517550bool Vector::MakeNormalVector(const Vector *y1)
    518551{
    519   bool result = false;
    520   Vector x1;
    521   x1.CopyVector(y1);
    522   x1.Scale(x1.Projection(this));
    523   SubtractVector(&x1);
    524   for (int i=NDIM;i--;)
    525     result = result || (fabs(x[i]) > MYEPSILON);
    526 
    527   return result;
     552        bool result = false;
     553        Vector x1;
     554        x1.CopyVector(y1);
     555        x1.Scale(x1.Projection(this));
     556        SubtractVector(&x1);
     557        for (int i=NDIM;i--;)
     558                result = result || (fabs(x[i]) > MYEPSILON);
     559
     560        return result;
    528561};
    529562
     
    536569bool Vector::GetOneNormalVector(const Vector *GivenVector)
    537570{
    538   int Components[NDIM]; // contains indices of non-zero components
    539   int Last = 0;  // count the number of non-zero entries in vector
    540   int j;  // loop variables
    541   double norm;
    542 
    543   cout << Verbose(4);
    544   GivenVector->Output((ofstream *)&cout);
    545   cout << endl;
    546   for (j=NDIM;j--;)
    547     Components[j] = -1;
    548   // find two components != 0
    549   for (j=0;j<NDIM;j++)
    550     if (fabs(GivenVector->x[j]) > MYEPSILON)
    551       Components[Last++] = j;
    552   cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    553 
    554   switch(Last) {
    555     case 3:  // threecomponent system
    556     case 2:  // two component system
    557       norm = sqrt(1./(GivenVector->x[Components[1]]*GivenVector->x[Components[1]]) + 1./(GivenVector->x[Components[0]]*GivenVector->x[Components[0]]));
    558       x[Components[2]] = 0.;
    559       // in skp both remaining parts shall become zero but with opposite sign and third is zero
    560       x[Components[1]] = -1./GivenVector->x[Components[1]] / norm;
    561       x[Components[0]] = 1./GivenVector->x[Components[0]] / norm;
    562       return true;
    563       break;
    564     case 1: // one component system
    565       // set sole non-zero component to 0, and one of the other zero component pendants to 1
    566       x[(Components[0]+2)%NDIM] = 0.;
    567       x[(Components[0]+1)%NDIM] = 1.;
    568       x[Components[0]] = 0.;
    569       return true;
    570       break;
    571     default:
    572       return false;
    573   }
     571        int Components[NDIM]; // contains indices of non-zero components
     572        int Last = 0;    // count the number of non-zero entries in vector
     573        int j;  // loop variables
     574        double norm;
     575
     576        cout << Verbose(4);
     577        GivenVector->Output((ofstream *)&cout);
     578        cout << endl;
     579        for (j=NDIM;j--;)
     580                Components[j] = -1;
     581        // find two components != 0
     582        for (j=0;j<NDIM;j++)
     583                if (fabs(GivenVector->x[j]) > MYEPSILON)
     584                        Components[Last++] = j;
     585        cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
     586
     587        switch(Last) {
     588                case 3: // threecomponent system
     589                case 2: // two component system
     590                        norm = sqrt(1./(GivenVector->x[Components[1]]*GivenVector->x[Components[1]]) + 1./(GivenVector->x[Components[0]]*GivenVector->x[Components[0]]));
     591                        x[Components[2]] = 0.;
     592                        // in skp both remaining parts shall become zero but with opposite sign and third is zero
     593                        x[Components[1]] = -1./GivenVector->x[Components[1]] / norm;
     594                        x[Components[0]] = 1./GivenVector->x[Components[0]] / norm;
     595                        return true;
     596                        break;
     597                case 1: // one component system
     598                        // set sole non-zero component to 0, and one of the other zero component pendants to 1
     599                        x[(Components[0]+2)%NDIM] = 0.;
     600                        x[(Components[0]+1)%NDIM] = 1.;
     601                        x[Components[0]] = 0.;
     602                        return true;
     603                        break;
     604                default:
     605                        return false;
     606        }
    574607};
    575608
     
    582615double Vector::CutsPlaneAt(Vector *A, Vector *B, Vector *C)
    583616{
    584 //  cout << Verbose(3) << "For comparison: ";
    585 //  cout << "A " << A->Projection(this) << "\t";
    586 //  cout << "B " << B->Projection(this) << "\t";
    587 //  cout << "C " << C->Projection(this) << "\t";
    588 //  cout << endl;
    589   return A->Projection(this);
     617//      cout << Verbose(3) << "For comparison: ";
     618//      cout << "A " << A->Projection(this) << "\t";
     619//      cout << "B " << B->Projection(this) << "\t";
     620//      cout << "C " << C->Projection(this) << "\t";
     621//      cout << endl;
     622        return A->Projection(this);
    590623};
    591624
     
    597630bool Vector::LSQdistance(Vector **vectors, int num)
    598631{
    599   int j;
    600 
    601   for (j=0;j<num;j++) {
    602     cout << Verbose(1) << j << "th atom's vector: ";
    603     (vectors[j])->Output((ofstream *)&cout);
    604     cout << endl;
    605   }
    606 
    607   int np = 3;
    608   struct LSQ_params par;
    609 
    610   const gsl_multimin_fminimizer_type *T =
    611     gsl_multimin_fminimizer_nmsimplex;
    612   gsl_multimin_fminimizer *s = NULL;
    613   gsl_vector *ss, *y;
    614   gsl_multimin_function minex_func;
    615 
    616   size_t iter = 0, i;
    617   int status;
    618   double size;
    619 
    620   /* Initial vertex size vector */
    621   ss = gsl_vector_alloc (np);
    622   y = gsl_vector_alloc (np);
    623 
    624   /* Set all step sizes to 1 */
    625   gsl_vector_set_all (ss, 1.0);
    626 
    627   /* Starting point */
    628   par.vectors = vectors;
    629   par.num = num;
    630 
    631   for (i=NDIM;i--;)
    632     gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
    633 
    634   /* Initialize method and iterate */
    635   minex_func.f = &LSQ;
    636   minex_func.n = np;
    637   minex_func.params = (void *)&par;
    638 
    639   s = gsl_multimin_fminimizer_alloc (T, np);
    640   gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    641 
    642   do
    643     {
    644       iter++;
    645       status = gsl_multimin_fminimizer_iterate(s);
    646 
    647       if (status)
    648         break;
    649 
    650       size = gsl_multimin_fminimizer_size (s);
    651       status = gsl_multimin_test_size (size, 1e-2);
    652 
    653       if (status == GSL_SUCCESS)
    654         {
    655           printf ("converged to minimum at\n");
    656         }
    657 
    658       printf ("%5d ", (int)iter);
    659       for (i = 0; i < (size_t)np; i++)
    660         {
    661           printf ("%10.3e ", gsl_vector_get (s->x, i));
    662         }
    663       printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    664     }
    665   while (status == GSL_CONTINUE && iter < 100);
    666 
    667   for (i=(size_t)np;i--;)
    668     this->x[i] = gsl_vector_get(s->x, i);
    669   gsl_vector_free(y);
    670   gsl_vector_free(ss);
    671   gsl_multimin_fminimizer_free (s);
    672 
    673   return true;
     632        int j;
     633
     634        for (j=0;j<num;j++) {
     635                cout << Verbose(1) << j << "th atom's vector: ";
     636                (vectors[j])->Output((ofstream *)&cout);
     637                cout << endl;
     638        }
     639
     640        int np = 3;
     641        struct LSQ_params par;
     642
     643        const gsl_multimin_fminimizer_type *T =
     644                gsl_multimin_fminimizer_nmsimplex;
     645        gsl_multimin_fminimizer *s = NULL;
     646        gsl_vector *ss, *y;
     647        gsl_multimin_function minex_func;
     648
     649        size_t iter = 0, i;
     650        int status;
     651        double size;
     652
     653        /* Initial vertex size vector */
     654        ss = gsl_vector_alloc (np);
     655        y = gsl_vector_alloc (np);
     656
     657        /* Set all step sizes to 1 */
     658        gsl_vector_set_all (ss, 1.0);
     659
     660        /* Starting point */
     661        par.vectors = vectors;
     662        par.num = num;
     663
     664        for (i=NDIM;i--;)
     665                gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     666
     667        /* Initialize method and iterate */
     668        minex_func.f = &LSQ;
     669        minex_func.n = np;
     670        minex_func.params = (void *)&par;
     671
     672        s = gsl_multimin_fminimizer_alloc (T, np);
     673        gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
     674
     675        do
     676                {
     677                        iter++;
     678                        status = gsl_multimin_fminimizer_iterate(s);
     679
     680                        if (status)
     681                                break;
     682
     683                        size = gsl_multimin_fminimizer_size (s);
     684                        status = gsl_multimin_test_size (size, 1e-2);
     685
     686                        if (status == GSL_SUCCESS)
     687                                {
     688                                        printf ("converged to minimum at\n");
     689                                }
     690
     691                        printf ("%5d ", (int)iter);
     692                        for (i = 0; i < (size_t)np; i++)
     693                                {
     694                                        printf ("%10.3e ", gsl_vector_get (s->x, i));
     695                                }
     696                        printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     697                }
     698        while (status == GSL_CONTINUE && iter < 100);
     699
     700        for (i=(size_t)np;i--;)
     701                this->x[i] = gsl_vector_get(s->x, i);
     702        gsl_vector_free(y);
     703        gsl_vector_free(ss);
     704        gsl_multimin_fminimizer_free (s);
     705
     706        return true;
    674707};
    675708
     
    679712void Vector::AddVector(const Vector *y)
    680713{
    681   for (int i=NDIM;i--;)
    682     this->x[i] += y->x[i];
     714        for (int i=NDIM;i--;)
     715                this->x[i] += y->x[i];
    683716}
    684717
     
    688721void Vector::SubtractVector(const Vector *y)
    689722{
    690   for (int i=NDIM;i--;)
    691     this->x[i] -= y->x[i];
     723        for (int i=NDIM;i--;)
     724                this->x[i] -= y->x[i];
    692725}
    693726
     
    697730void Vector::CopyVector(const Vector *y)
    698731{
    699   for (int i=NDIM;i--;)
    700     this->x[i] = y->x[i];
     732        for (int i=NDIM;i--;)
     733                this->x[i] = y->x[i];
    701734}
    702735
     
    708741void Vector::AskPosition(double *cell_size, bool check)
    709742{
    710   char coords[3] = {'x','y','z'};
    711   int j = -1;
    712   for (int i=0;i<3;i++) {
    713     j += i+1;
    714     do {
    715       cout << Verbose(0) << coords[i] << "[0.." << cell_size[j] << "]: ";
    716       cin >> x[i];
    717     } while (((x[i] < 0) || (x[i] >= cell_size[j])) && (check));
    718   }
     743        char coords[3] = {'x','y','z'};
     744        int j = -1;
     745        for (int i=0;i<3;i++) {
     746                j += i+1;
     747                do {
     748                        cout << Verbose(0) << coords[i] << "[0.." << cell_size[j] << "]: ";
     749                        cin >> x[i];
     750                } while (((x[i] < 0) || (x[i] >= cell_size[j])) && (check));
     751        }
    719752};
    720753
     
    736769bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
    737770{
    738   double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C;
    739   double ang; // angle on testing
    740   double sign[3];
    741   int i,j,k;
    742   A = cos(alpha) * x1->Norm() * c;
    743   B1 = cos(beta + M_PI/2.) * y->Norm() * c;
    744   B2 = cos(beta) * x2->Norm() * c;
    745   C = c * c;
    746   cout << Verbose(2) << "A " << A << "\tB " << B1 << "\tC " << C << endl;
    747   int flag = 0;
    748   if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    749     if (fabs(x1->x[1]) > MYEPSILON) {
    750       flag = 1;
    751     } else if (fabs(x1->x[2]) > MYEPSILON) {
    752       flag = 2;
    753     } else {
    754       return false;
    755     }
    756   }
    757   switch (flag) {
    758     default:
    759     case 0:
    760       break;
    761     case 2:
    762       flip(&x1->x[0],&x1->x[1]);
    763       flip(&x2->x[0],&x2->x[1]);
    764       flip(&y->x[0],&y->x[1]);
    765       //flip(&x[0],&x[1]);
    766       flip(&x1->x[1],&x1->x[2]);
    767       flip(&x2->x[1],&x2->x[2]);
    768       flip(&y->x[1],&y->x[2]);
    769       //flip(&x[1],&x[2]);
    770     case 1:
    771       flip(&x1->x[0],&x1->x[1]);
    772       flip(&x2->x[0],&x2->x[1]);
    773       flip(&y->x[0],&y->x[1]);
    774       //flip(&x[0],&x[1]);
    775       flip(&x1->x[1],&x1->x[2]);
    776       flip(&x2->x[1],&x2->x[2]);
    777       flip(&y->x[1],&y->x[2]);
    778       //flip(&x[1],&x[2]);
    779       break;
    780   }
    781   // now comes the case system
    782   D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    783   D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
    784   D3 = y->x[0]/x1->x[0]*A-B1;
    785   cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    786   if (fabs(D1) < MYEPSILON) {
    787     cout << Verbose(2) << "D1 == 0!\n";
    788     if (fabs(D2) > MYEPSILON) {
    789       cout << Verbose(3) << "D2 != 0!\n";
    790       x[2] = -D3/D2;
    791       E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
    792       E2 = -x1->x[1]/x1->x[0];
    793       cout << Verbose(3) << "E1 " << E1 << "\tE2 " << E2 << "\n";
    794       F1 = E1*E1 + 1.;
    795       F2 = -E1*E2;
    796       F3 = E1*E1 + D3*D3/(D2*D2) - C;
    797       cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    798       if (fabs(F1) < MYEPSILON) {
    799         cout << Verbose(4) << "F1 == 0!\n";
    800         cout << Verbose(4) << "Gleichungssystem linear\n";
    801         x[1] = F3/(2.*F2);
    802       } else {
    803         p = F2/F1;
    804         q = p*p - F3/F1;
    805         cout << Verbose(4) << "p " << p << "\tq " << q << endl;
    806         if (q < 0) {
    807           cout << Verbose(4) << "q < 0" << endl;
    808           return false;
    809         }
    810         x[1] = p + sqrt(q);
    811       }
    812       x[0] =  A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
    813     } else {
    814       cout << Verbose(2) << "Gleichungssystem unterbestimmt\n";
    815       return false;
    816     }
    817   } else {
    818     E1 = A/x1->x[0]+x1->x[1]/x1->x[0]*D3/D1;
    819     E2 = x1->x[1]/x1->x[0]*D2/D1 - x1->x[2];
    820     cout << Verbose(2) << "E1 " << E1 << "\tE2 " << E2 << "\n";
    821     F1 = E2*E2 + D2*D2/(D1*D1) + 1.;
    822     F2 = -(E1*E2 + D2*D3/(D1*D1));
    823     F3 = E1*E1 + D3*D3/(D1*D1) - C;
    824     cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    825     if (fabs(F1) < MYEPSILON) {
    826       cout << Verbose(3) << "F1 == 0!\n";
    827       cout << Verbose(3) << "Gleichungssystem linear\n";
    828       x[2] = F3/(2.*F2);
    829     } else {
    830       p = F2/F1;
    831       q = p*p - F3/F1;
    832       cout << Verbose(3) << "p " << p << "\tq " << q << endl;
    833       if (q < 0) {
    834         cout << Verbose(3) << "q < 0" << endl;
    835         return false;
    836       }
    837       x[2] = p + sqrt(q);
    838     }
    839     x[1] = (-D2 * x[2] - D3)/D1;
    840     x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
    841   }
    842   switch (flag) { // back-flipping
    843     default:
    844     case 0:
    845       break;
    846     case 2:
    847       flip(&x1->x[0],&x1->x[1]);
    848       flip(&x2->x[0],&x2->x[1]);
    849       flip(&y->x[0],&y->x[1]);
    850       flip(&x[0],&x[1]);
    851       flip(&x1->x[1],&x1->x[2]);
    852       flip(&x2->x[1],&x2->x[2]);
    853       flip(&y->x[1],&y->x[2]);
    854       flip(&x[1],&x[2]);
    855     case 1:
    856       flip(&x1->x[0],&x1->x[1]);
    857       flip(&x2->x[0],&x2->x[1]);
    858       flip(&y->x[0],&y->x[1]);
    859       //flip(&x[0],&x[1]);
    860       flip(&x1->x[1],&x1->x[2]);
    861       flip(&x2->x[1],&x2->x[2]);
    862       flip(&y->x[1],&y->x[2]);
    863       flip(&x[1],&x[2]);
    864       break;
    865   }
    866   // one z component is only determined by its radius (without sign)
    867   // thus check eight possible sign flips and determine by checking angle with second vector
    868   for (i=0;i<8;i++) {
    869     // set sign vector accordingly
    870     for (j=2;j>=0;j--) {
    871       k = (i & pot(2,j)) << j;
    872       cout << Verbose(2) << "k " << k << "\tpot(2,j) " << pot(2,j) << endl;
    873       sign[j] = (k == 0) ? 1. : -1.;
    874     }
    875     cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    876     // apply sign matrix
    877     for (j=NDIM;j--;)
    878       x[j] *= sign[j];
    879     // calculate angle and check
    880     ang = x2->Angle (this);
    881     cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    882     if (fabs(ang - cos(beta)) < MYEPSILON) {
    883       break;
    884     }
    885     // unapply sign matrix (is its own inverse)
    886     for (j=NDIM;j--;)
    887       x[j] *= sign[j];
    888   }
    889   return true;
    890 };
     771        double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C;
     772        double ang; // angle on testing
     773        double sign[3];
     774        int i,j,k;
     775        A = cos(alpha) * x1->Norm() * c;
     776        B1 = cos(beta + M_PI/2.) * y->Norm() * c;
     777        B2 = cos(beta) * x2->Norm() * c;
     778        C = c * c;
     779        cout << Verbose(2) << "A " << A << "\tB " << B1 << "\tC " << C << endl;
     780        int flag = 0;
     781        if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
     782                if (fabs(x1->x[1]) > MYEPSILON) {
     783                        flag = 1;
     784                } else if (fabs(x1->x[2]) > MYEPSILON) {
     785                        flag = 2;
     786                } else {
     787                        return false;
     788                }
     789        }
     790        switch (flag) {
     791                default:
     792                case 0:
     793                        break;
     794                case 2:
     795                        flip(&x1->x[0],&x1->x[1]);
     796                        flip(&x2->x[0],&x2->x[1]);
     797                        flip(&y->x[0],&y->x[1]);
     798                        //flip(&x[0],&x[1]);
     799                        flip(&x1->x[1],&x1->x[2]);
     800                        flip(&x2->x[1],&x2->x[2]);
     801                        flip(&y->x[1],&y->x[2]);
     802                        //flip(&x[1],&x[2]);
     803                case 1:
     804                        flip(&x1->x[0],&x1->x[1]);
     805                        flip(&x2->x[0],&x2->x[1]);
     806                        flip(&y->x[0],&y->x[1]);
     807                        //flip(&x[0],&x[1]);
     808                        flip(&x1->x[1],&x1->x[2]);
     809                        flip(&x2->x[1],&x2->x[2]);
     810                        flip(&y->x[1],&y->x[2]);
     811                        //flip(&x[1],&x[2]);
     812                        break;
     813        }
     814        // now comes the case system
     815        D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
     816        D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
     817        D3 = y->x[0]/x1->x[0]*A-B1;
     818        cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
     819        if (fabs(D1) < MYEPSILON) {
     820                cout << Verbose(2) << "D1 == 0!\n";
     821                if (fabs(D2) > MYEPSILON) {
     822                        cout << Verbose(3) << "D2 != 0!\n";
     823                        x[2] = -D3/D2;
     824                        E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     825                        E2 = -x1->x[1]/x1->x[0];
     826                        cout << Verbose(3) << "E1 " << E1 << "\tE2 " << E2 << "\n";
     827                        F1 = E1*E1 + 1.;
     828                        F2 = -E1*E2;
     829                        F3 = E1*E1 + D3*D3/(D2*D2) - C;
     830                        cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
     831                        if (fabs(F1) < MYEPSILON) {
     832                                cout << Verbose(4) << "F1 == 0!\n";
     833                                cout << Verbose(4) << "Gleichungssystem linear\n";
     834                                x[1] = F3/(2.*F2);
     835                        } else {
     836                                p = F2/F1;
     837                                q = p*p - F3/F1;
     838                                cout << Verbose(4) << "p " << p << "\tq " << q << endl;
     839                                if (q < 0) {
     840                                        cout << Verbose(4) << "q < 0" << endl;
     841                                        return false;
     842                                }
     843                                x[1] = p + sqrt(q);
     844                        }
     845                        x[0] =  A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
     846                } else {
     847                        cout << Verbose(2) << "Gleichungssystem unterbestimmt\n";
     848                        return false;
     849                }
     850        } else {
     851                E1 = A/x1->x[0]+x1->x[1]/x1->x[0]*D3/D1;
     852                E2 = x1->x[1]/x1->x[0]*D2/D1 - x1->x[2];
     853                cout << Verbose(2) << "E1 " << E1 << "\tE2 " << E2 << "\n";
     854                F1 = E2*E2 + D2*D2/(D1*D1) + 1.;
     855                F2 = -(E1*E2 + D2*D3/(D1*D1));
     856                F3 = E1*E1 + D3*D3/(D1*D1) - C;
     857                cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
     858                if (fabs(F1) < MYEPSILON) {
     859                        cout << Verbose(3) << "F1 == 0!\n";
     860                        cout << Verbose(3) << "Gleichungssystem linear\n";
     861                        x[2] = F3/(2.*F2);
     862                } else {
     863                        p = F2/F1;
     864                        q = p*p - F3/F1;
     865                        cout << Verbose(3) << "p " << p << "\tq " << q << endl;
     866                        if (q < 0) {
     867                                cout << Verbose(3) << "q < 0" << endl;
     868                                return false;
     869                        }
     870                        x[2] = p + sqrt(q);
     871                }
     872                x[1] = (-D2 * x[2] - D3)/D1;
     873                x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
     874        }
     875        switch (flag) { // back-flipping
     876                default:
     877                case 0:
     878                        break;
     879                case 2:
     880                        flip(&x1->x[0],&x1->x[1]);
     881                        flip(&x2->x[0],&x2->x[1]);
     882                        flip(&y->x[0],&y->x[1]);
     883                        flip(&x[0],&x[1]);
     884                        flip(&x1->x[1],&x1->x[2]);
     885                        flip(&x2->x[1],&x2->x[2]);
     886                        flip(&y->x[1],&y->x[2]);
     887                        flip(&x[1],&x[2]);
     888                case 1:
     889                        flip(&x1->x[0],&x1->x[1]);
     890                        flip(&x2->x[0],&x2->x[1]);
     891                        flip(&y->x[0],&y->x[1]);
     892                        //flip(&x[0],&x[1]);
     893                        flip(&x1->x[1],&x1->x[2]);
     894                        flip(&x2->x[1],&x2->x[2]);
     895                        flip(&y->x[1],&y->x[2]);
     896                        flip(&x[1],&x[2]);
     897                        break;
     898        }
     899        // one z component is only determined by its radius (without sign)
     900        // thus check eight possible sign flips and determine by checking angle with second vector
     901        for (i=0;i<8;i++) {
     902                // set sign vector accordingly
     903                for (j=2;j>=0;j--) {
     904                        k = (i & pot(2,j)) << j;
     905                        cout << Verbose(2) << "k " << k << "\tpot(2,j) " << pot(2,j) << endl;
     906                        sign[j] = (k == 0) ? 1. : -1.;
     907                }
     908                cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
     909                // apply sign matrix
     910                for (j=NDIM;j--;)
     911                        x[j] *= sign[j];
     912                // calculate angle and check
     913                ang = x2->Angle (this);
     914                cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
     915                if (fabs(ang - cos(beta)) < MYEPSILON) {
     916                        break;
     917                }
     918                // unapply sign matrix (is its own inverse)
     919                for (j=NDIM;j--;)
     920                        x[j] *= sign[j];
     921        }
     922        return true;
     923};
  • src/vector.hpp

    rce5ac3 rd067d45  
    88 */
    99class Vector {
    10   public:
    11     double x[NDIM];
     10        public:
     11                double x[NDIM];
    1212
    13   Vector();
    14   Vector(double x1, double x2, double x3);
    15   ~Vector();
     13        Vector();
     14        Vector(double x1, double x2, double x3);
     15        ~Vector();
    1616
    17   double Distance(const Vector *y) const;
    18   double DistanceSquared(const Vector *y) const;
    19   double PeriodicDistance(const Vector *y, const double *cell_size) const;
    20   double ScalarProduct(const Vector *y) const;
    21   double Projection(const Vector *y) const;
    22   double Norm() const ;
    23   double Angle(const Vector *y) const;
     17        double Distance(const Vector *y) const;
     18        double DistanceSquared(const Vector *y) const;
     19        double PeriodicDistance(const Vector *y, const double *cell_size) const;
     20        double PeriodicDistanceSquared(const Vector *y, const double *cell_size) const;
     21        double ScalarProduct(const Vector *y) const;
     22        double Projection(const Vector *y) const;
     23        double Norm() const ;
     24        double Angle(const Vector *y) const;
    2425
    25   void AddVector(const Vector *y);
    26   void SubtractVector(const Vector *y);
    27   void CopyVector(const Vector *y);
    28   void RotateVector(const Vector *y, const double alpha);
    29   void VectorProduct(const Vector *y);
    30   void ProjectOntoPlane(const Vector *y);
    31   void Zero();
    32   void One(double one);
    33   void Init(double x1, double x2, double x3);
    34   void Normalize();
    35   void Translate(const Vector *x);
    36   void Mirror(const Vector *x);
    37   void Scale(double **factor);
    38   void Scale(double *factor);
    39   void Scale(double factor);
    40   void MatrixMultiplication(double *M);
    41   void InverseMatrixMultiplication(double *M);
    42   void KeepPeriodic(ofstream *out, double *matrix);
    43   void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    44 
    45   double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    46   bool GetOneNormalVector(const Vector *x1);
    47   bool MakeNormalVector(const Vector *y1);
    48   bool MakeNormalVector(const Vector *y1, const Vector *y2);
    49   bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3);
    50   bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c);
    51   bool LSQdistance(Vector **vectors, int dim);
    52 
    53   void AskPosition(double *cell_size, bool check);
    54   bool Output(ofstream *out) const;
     26        void AddVector(const Vector *y);
     27        void SubtractVector(const Vector *y);
     28        void CopyVector(const Vector *y);
     29        void RotateVector(const Vector *y, const double alpha);
     30        void VectorProduct(const Vector *y);
     31        void ProjectOntoPlane(const Vector *y);
     32        void Zero();
     33        void One(double one);
     34        void Init(double x1, double x2, double x3);
     35        void Normalize();
     36        void Translate(const Vector *x);
     37        void Mirror(const Vector *x);
     38        void Scale(double **factor);
     39        void Scale(double *factor);
     40        void Scale(double factor);
     41        void MatrixMultiplication(double *M);
     42        void InverseMatrixMultiplication(double *M);
     43        void KeepPeriodic(ofstream *out, double *matrix);
     44        void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
     45        double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
     46        bool GetOneNormalVector(const Vector *x1);
     47        bool MakeNormalVector(const Vector *y1);
     48        bool MakeNormalVector(const Vector *y1, const Vector *y2);
     49        bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3);
     50        bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c);
     51        bool LSQdistance(Vector **vectors, int dim);
     52        void AskPosition(double *cell_size, bool check);
     53        bool Output(ofstream *out) const;
    5554};
    5655
  • src/verbose.cpp

    rce5ac3 rd067d45  
    77ostream& Verbose::print (ostream &ost) const
    88{
    9   for (int i=Verbosity;i--;)
    10     ost.put('\t');
    11   //cout << "Verbose(.) called." << endl;
    12   return ost;
     9        for (int i=Verbosity;i--;)
     10                ost.put('\t');
     11        //cout << "Verbose(.) called." << endl;
     12        return ost;
    1313};
    1414
Note: See TracChangeset for help on using the changeset viewer.