Changeset a98603 for src


Ignore:
Timestamp:
Feb 9, 2009, 2:18:13 PM (16 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
5bc4d0
Parents:
674220 (diff), cc2ee5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge ../espack3

Location:
src
Files:
5 added
32 edited

Legend:

Unmodified
Added
Removed
  • src/Hbondangle.db

    • Property mode changed from 100644 to 100755
  • src/Hbonddistance.db

    • Property mode changed from 100644 to 100755
  • src/Makefile.am

    • Property mode changed from 100644 to 100755
  • src/analyzer.cpp

    • Property mode changed from 100644 to 100755
  • src/atom.cpp

    • Property mode changed from 100644 to 100755
  • src/bond.cpp

    • Property mode changed from 100644 to 100755
  • TabularUnified src/boundary.cpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    22#include "boundary.hpp"
    33
     4#define DEBUG 1
     5#define DoTecplotOutput 0
     6#define DoRaster3DOutput 1
     7#define TecplotSuffix ".dat"
     8#define Raster3DSuffix ".r3d"
     9
    410// ======================================== Points on Boundary =================================
    511
     
    814  LinesCount = 0;
    915  Nr = -1;
    10 };
     16}
     17;
    1118
    1219BoundaryPointSet::BoundaryPointSet(atom *Walker)
     
    1522  LinesCount = 0;
    1623  Nr = Walker->nr;
    17 };
     24}
     25;
    1826
    1927BoundaryPointSet::~BoundaryPointSet()
     
    2129  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    2230  node = NULL;
    23 };
    24 
    25 void BoundaryPointSet::AddLine(class BoundaryLineSet *line)
    26 {
    27   cout << Verbose(6) << "Adding line " << *line << " to " << *this << "." << endl;
    28   if (line->endpoints[0] == this) {
    29     lines.insert ( LinePair( line->endpoints[1]->Nr, line) );
    30   } else {
    31     lines.insert ( LinePair( line->endpoints[0]->Nr, line) );
    32   }
     31  lines.clear();
     32}
     33;
     34
     35void
     36BoundaryPointSet::AddLine(class BoundaryLineSet *line)
     37{
     38  cout << Verbose(6) << "Adding " << *this << " to line " << *line << "."
     39      << endl;
     40  if (line->endpoints[0] == this)
     41    {
     42      lines.insert(LinePair(line->endpoints[1]->Nr, line));
     43    }
     44  else
     45    {
     46      lines.insert(LinePair(line->endpoints[0]->Nr, line));
     47    }
    3348  LinesCount++;
    34 };
    35 
    36 ostream & operator << (ostream &ost, BoundaryPointSet &a)
     49}
     50;
     51
     52ostream &
     53operator <<(ostream &ost, BoundaryPointSet &a)
    3754{
    3855  ost << "[" << a.Nr << "|" << a.node->Name << "]";
    3956  return ost;
    40 };
     57}
     58;
    4159
    4260// ======================================== Lines on Boundary =================================
     
    4462BoundaryLineSet::BoundaryLineSet()
    4563{
    46   for (int i=0;i<2;i++)
     64  for (int i = 0; i < 2; i++)
    4765    endpoints[i] = NULL;
    4866  TrianglesCount = 0;
    4967  Nr = -1;
    50 };
     68}
     69;
    5170
    5271BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number)
     
    5776  SetEndpointsOrdered(endpoints, Point[0], Point[1]);
    5877  // add this line to the hash maps of both endpoints
    59   Point[0]->AddLine(this);
    60   Point[1]->AddLine(this);
     78  Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding.
     79  Point[1]->AddLine(this); //
    6180  // clear triangles list
    6281  TrianglesCount = 0;
    6382  cout << Verbose(5) << "New Line with endpoints " << *this << "." << endl;
    64 };
     83}
     84;
    6585
    6686BoundaryLineSet::~BoundaryLineSet()
    6787{
    68   for (int i=0;i<2;i++) {
    69     cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    70     endpoints[i]->lines.erase(Nr);
    71     LineMap::iterator tester = endpoints[i]->lines.begin();
    72     tester++;
    73     if (tester == endpoints[i]->lines.end()) {
    74       cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    75       delete(endpoints[i]);
    76     } else
    77       cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;
    78   }
    79 };
    80 
    81 void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
    82 {
    83   cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." << endl;
    84   triangles.insert ( TrianglePair( TrianglesCount, triangle) );
     88        for (int i = 0; i < 2; i++) {
     89                cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     90                endpoints[i]->lines.erase(Nr);
     91                LineMap::iterator tester = endpoints[i]->lines.begin();
     92                tester++;
     93                if (tester == endpoints[i]->lines.end()) {
     94                        cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
     95                        if (endpoints[i] != NULL) {
     96                                delete(endpoints[i]);
     97                                endpoints[i] = NULL;
     98                        } else
     99                                cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;
     100                } else
     101                        cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;
     102        }
     103}
     104;
     105
     106void
     107BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
     108{
     109  cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "."
     110      << endl;
     111  triangles.insert(TrianglePair(TrianglesCount, triangle));
    85112  TrianglesCount++;
    86 };
    87 
    88 ostream & operator << (ostream &ost, BoundaryLineSet &a)
    89 {
    90   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
     113}
     114;
     115
     116ostream &
     117operator <<(ostream &ost, BoundaryLineSet &a)
     118{
     119  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
     120      << a.endpoints[1]->node->Name << "]";
    91121  return ost;
    92 };
     122}
     123;
    93124
    94125// ======================================== Triangles on Boundary =================================
     
    97128BoundaryTriangleSet::BoundaryTriangleSet()
    98129{
    99   for (int i=0;i<3;i++) {
    100     endpoints[i] = NULL;
    101     lines[i] = NULL;
    102   }
     130  for (int i = 0; i < 3; i++)
     131    {
     132      endpoints[i] = NULL;
     133      lines[i] = NULL;
     134    }
    103135  Nr = -1;
    104 };
    105 
    106 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3], int number)
     136}
     137;
     138
     139BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3],
     140    int number)
    107141{
    108142  // set number
     
    110144  // set lines
    111145  cout << Verbose(5) << "New triangle " << Nr << ":" << endl;
    112   for (int i=0;i<3;i++) {
    113     lines[i] = line[i];
    114     lines[i]->AddTriangle(this);
    115   }
     146  for (int i = 0; i < 3; i++)
     147    {
     148      lines[i] = line[i];
     149      lines[i]->AddTriangle(this);
     150    }
    116151  // get ascending order of endpoints
    117   map <int, class BoundaryPointSet * > OrderMap;
    118   for(int i=0;i<3;i++)  // for all three lines
    119     for (int j=0;j<2;j++) { // for both endpoints
    120       OrderMap.insert ( pair <int, class BoundaryPointSet * >( line[i]->endpoints[j]->Nr, line[i]->endpoints[j]) );
    121       // and we don't care whether insertion fails
    122     }
     152  map<int, class BoundaryPointSet *> OrderMap;
     153  for (int i = 0; i < 3; i++)
     154    // for all three lines
     155    for (int j = 0; j < 2; j++)
     156      { // for both endpoints
     157        OrderMap.insert(pair<int, class BoundaryPointSet *> (
     158            line[i]->endpoints[j]->Nr, line[i]->endpoints[j]));
     159        // and we don't care whether insertion fails
     160      }
    123161  // set endpoints
    124162  int Counter = 0;
    125163  cout << Verbose(6) << " with end points ";
    126   for (map <int, class BoundaryPointSet * >::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) {
    127     endpoints[Counter] = runner->second;
    128     cout << " " << *endpoints[Counter];
    129     Counter++;
    130   }
    131   if (Counter < 3) {
    132     cerr << "ERROR! We have a triangle with only two distinct endpoints!" << endl;
    133     //exit(1);
    134   }
     164  for (map<int, class BoundaryPointSet *>::iterator runner = OrderMap.begin(); runner
     165      != OrderMap.end(); runner++)
     166    {
     167      endpoints[Counter] = runner->second;
     168      cout << " " << *endpoints[Counter];
     169      Counter++;
     170    }
     171  if (Counter < 3)
     172    {
     173      cerr << "ERROR! We have a triangle with only two distinct endpoints!"
     174          << endl;
     175      //exit(1);
     176    }
    135177  cout << "." << endl;
    136 };
     178}
     179;
    137180
    138181BoundaryTriangleSet::~BoundaryTriangleSet()
    139182{
    140   for (int i=0;i<3;i++) {
    141     cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;
    142     lines[i]->triangles.erase(Nr);
    143     TriangleMap::iterator tester = lines[i]->triangles.begin();
    144     tester++;
    145     if (tester == lines[i]->triangles.end()) {
    146       cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
    147       delete(lines[i]);
    148     } else
    149       cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;
    150   }
    151 };
    152 
    153 void BoundaryTriangleSet::GetNormalVector(Vector &NormalVector)
     183        for (int i = 0; i < 3; i++) {
     184                cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;
     185                lines[i]->triangles.erase(Nr);
     186                if (lines[i]->triangles.empty()) {
     187                        cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
     188                        if (lines[i] != NULL) {
     189                                delete (lines[i]);
     190                                lines[i] = NULL;
     191                        } else
     192                                cerr << "ERROR: This line " << i << " has already been free'd." << endl;
     193                } else
     194                        cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;
     195        }
     196}
     197;
     198
     199void
     200BoundaryTriangleSet::GetNormalVector(Vector &OtherVector)
    154201{
    155202  // get normal vector
    156   NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x, &endpoints[2]->node->x);
    157  
     203  NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x,
     204      &endpoints[2]->node->x);
     205
    158206  // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
    159   if (endpoints[0]->node->x.Projection(&NormalVector) > 0)
     207  if (endpoints[0]->node->x.Projection(&OtherVector) > 0)
    160208    NormalVector.Scale(-1.);
    161 };
    162 
    163 ostream & operator << (ostream &ost, BoundaryTriangleSet &a)
    164 {
    165   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
     209}
     210;
     211
     212ostream &
     213operator <<(ostream &ost, BoundaryTriangleSet &a)
     214{
     215  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
     216      << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
    166217  return ost;
    167 };
     218}
     219;
    168220
    169221// ========================================== F U N C T I O N S =================================
     
    174226 * \return point which is shared or NULL if none
    175227 */
    176 class BoundaryPointSet * GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
    177 {
    178   class BoundaryLineSet * lines[2] = {line1, line2};
     228class BoundaryPointSet *
     229GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
     230{
     231  class BoundaryLineSet * lines[2] =
     232    { line1, line2 };
    179233  class BoundaryPointSet *node = NULL;
    180   map <int, class BoundaryPointSet * > OrderMap;
    181   pair < map <int, class BoundaryPointSet * >::iterator, bool > OrderTest;
    182   for(int i=0;i<2;i++)  // for both lines
    183     for (int j=0;j<2;j++) { // for both endpoints
    184       OrderTest = OrderMap.insert ( pair <int, class BoundaryPointSet * >( lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]) );
    185       if (!OrderTest.second) { // if insertion fails, we have common endpoint
    186         node = OrderTest.first->second;
    187         cout << Verbose(5) << "Common endpoint of lines " << *line1 << " and " << *line2 << " is: " << *node << "." << endl;
    188         j=2;
    189         i=2;
    190         break;
     234  map<int, class BoundaryPointSet *> OrderMap;
     235  pair<map<int, class BoundaryPointSet *>::iterator, bool> OrderTest;
     236  for (int i = 0; i < 2; i++)
     237    // for both lines
     238    for (int j = 0; j < 2; j++)
     239      { // for both endpoints
     240        OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> (
     241            lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
     242        if (!OrderTest.second)
     243          { // if insertion fails, we have common endpoint
     244            node = OrderTest.first->second;
     245            cout << Verbose(5) << "Common endpoint of lines " << *line1
     246                << " and " << *line2 << " is: " << *node << "." << endl;
     247            j = 2;
     248            i = 2;
     249            break;
     250          }
    191251      }
    192     }
    193252  return node;
    194 };
     253}
     254;
    195255
    196256/** Determines the boundary points of a cluster.
     
    201261 * \param *mol molecule structure representing the cluster
    202262 */
    203 Boundaries * GetBoundaryPoints(ofstream *out, molecule *mol)
     263Boundaries *
     264GetBoundaryPoints(ofstream *out, molecule *mol)
    204265{
    205266  atom *Walker = NULL;
     
    207268  LineMap LinesOnBoundary;
    208269  TriangleMap TrianglesOnBoundary;
    209  
     270
    210271  *out << Verbose(1) << "Finding all boundary points." << endl;
    211   Boundaries *BoundaryPoints = new Boundaries [NDIM]; // first is alpha, second is (r, nr)
     272  Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)
    212273  BoundariesTestPair BoundaryTestPair;
    213274  Vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;
    214275  double radius, angle;
    215276  // 3a. Go through every axis
    216   for (int axis=0; axis<NDIM; axis++)  {
    217     AxisVector.Zero();
    218     AngleReferenceVector.Zero();
    219     AngleReferenceNormalVector.Zero();
    220     AxisVector.x[axis] = 1.;
    221     AngleReferenceVector.x[(axis+1)%NDIM] = 1.;
    222     AngleReferenceNormalVector.x[(axis+2)%NDIM] = 1.;
    223   //    *out << Verbose(1) << "Axisvector is ";
    224   //    AxisVector.Output(out);
    225   //    *out << " and AngleReferenceVector is ";
    226   //    AngleReferenceVector.Output(out);
    227   //    *out << "." << endl;
    228   //    *out << " and AngleReferenceNormalVector is ";
    229   //    AngleReferenceNormalVector.Output(out);
    230   //    *out << "." << endl;
    231     // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours
    232     Walker = mol->start;
    233     while (Walker->next != mol->end) {
    234       Walker = Walker->next;
    235       Vector ProjectedVector;
    236       ProjectedVector.CopyVector(&Walker->x);
    237       ProjectedVector.ProjectOntoPlane(&AxisVector);
    238       // correct for negative side
    239       //if (Projection(y) < 0)
    240         //angle = 2.*M_PI - angle;
    241       radius = ProjectedVector.Norm();
    242       if (fabs(radius) > MYEPSILON)
    243         angle = ProjectedVector.Angle(&AngleReferenceVector);
    244       else
    245         angle = 0.;  // otherwise it's a vector in Axis Direction and unimportant for boundary issues
    246        
    247       //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
    248       if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0) {
    249         angle = 2.*M_PI - angle;
    250       }
    251       //*out << Verbose(2) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): ";
    252       //ProjectedVector.Output(out);
    253       //*out << endl;
    254       BoundaryTestPair = BoundaryPoints[axis].insert( BoundariesPair (angle, DistancePair (radius, Walker) ) );
    255       if (BoundaryTestPair.second) { // successfully inserted
    256       } else { // same point exists, check first r, then distance of original vectors to center of gravity
    257         *out << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl;
    258         *out << Verbose(2) << "Present vector: ";
    259         BoundaryTestPair.first->second.second->x.Output(out);
    260         *out << endl;
    261         *out << Verbose(2) << "New vector: ";
    262         Walker->x.Output(out);
    263         *out << endl;
    264         double tmp = ProjectedVector.Norm();
    265         if (tmp > BoundaryTestPair.first->second.first) {
    266           BoundaryTestPair.first->second.first = tmp;
    267           BoundaryTestPair.first->second.second = Walker;
    268           *out << Verbose(2) << "Keeping new vector." << endl;
    269         } else if (tmp == BoundaryTestPair.first->second.first) {
    270           if (BoundaryTestPair.first->second.second->x.ScalarProduct(&BoundaryTestPair.first->second.second->x) < Walker->x.ScalarProduct(&Walker->x)) { // Norm() does a sqrt, which makes it a lot slower
    271             BoundaryTestPair.first->second.second = Walker;
    272             *out << Verbose(2) << "Keeping new vector." << endl;
    273           } else {
    274             *out << Verbose(2) << "Keeping present vector." << endl;
    275           }
    276         } else {
    277             *out << Verbose(2) << "Keeping present vector." << endl;
     277  for (int axis = 0; axis < NDIM; axis++)
     278    {
     279      AxisVector.Zero();
     280      AngleReferenceVector.Zero();
     281      AngleReferenceNormalVector.Zero();
     282      AxisVector.x[axis] = 1.;
     283      AngleReferenceVector.x[(axis + 1) % NDIM] = 1.;
     284      AngleReferenceNormalVector.x[(axis + 2) % NDIM] = 1.;
     285      //    *out << Verbose(1) << "Axisvector is ";
     286      //    AxisVector.Output(out);
     287      //    *out << " and AngleReferenceVector is ";
     288      //    AngleReferenceVector.Output(out);
     289      //    *out << "." << endl;
     290      //    *out << " and AngleReferenceNormalVector is ";
     291      //    AngleReferenceNormalVector.Output(out);
     292      //    *out << "." << endl;
     293      // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours
     294      Walker = mol->start;
     295      while (Walker->next != mol->end)
     296        {
     297          Walker = Walker->next;
     298          Vector ProjectedVector;
     299          ProjectedVector.CopyVector(&Walker->x);
     300          ProjectedVector.ProjectOntoPlane(&AxisVector);
     301          // correct for negative side
     302          //if (Projection(y) < 0)
     303          //angle = 2.*M_PI - angle;
     304          radius = ProjectedVector.Norm();
     305          if (fabs(radius) > MYEPSILON)
     306            angle = ProjectedVector.Angle(&AngleReferenceVector);
     307          else
     308            angle = 0.; // otherwise it's a vector in Axis Direction and unimportant for boundary issues
     309
     310          //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
     311          if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0)
     312            {
     313              angle = 2. * M_PI - angle;
     314            }
     315          //*out << Verbose(2) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): ";
     316          //ProjectedVector.Output(out);
     317          //*out << endl;
     318          BoundaryTestPair = BoundaryPoints[axis].insert(BoundariesPair(angle,
     319              DistancePair (radius, Walker)));
     320          if (BoundaryTestPair.second)
     321            { // successfully inserted
     322            }
     323          else
     324            { // same point exists, check first r, then distance of original vectors to center of gravity
     325              *out << Verbose(2)
     326                  << "Encountered two vectors whose projection onto axis "
     327                  << axis << " is equal: " << endl;
     328              *out << Verbose(2) << "Present vector: ";
     329              BoundaryTestPair.first->second.second->x.Output(out);
     330              *out << endl;
     331              *out << Verbose(2) << "New vector: ";
     332              Walker->x.Output(out);
     333              *out << endl;
     334              double tmp = ProjectedVector.Norm();
     335              if (tmp > BoundaryTestPair.first->second.first)
     336                {
     337                  BoundaryTestPair.first->second.first = tmp;
     338                  BoundaryTestPair.first->second.second = Walker;
     339                  *out << Verbose(2) << "Keeping new vector." << endl;
     340                }
     341              else if (tmp == BoundaryTestPair.first->second.first)
     342                {
     343                  if (BoundaryTestPair.first->second.second->x.ScalarProduct(
     344                      &BoundaryTestPair.first->second.second->x)
     345                      < Walker->x.ScalarProduct(&Walker->x))
     346                    { // Norm() does a sqrt, which makes it a lot slower
     347                      BoundaryTestPair.first->second.second = Walker;
     348                      *out << Verbose(2) << "Keeping new vector." << endl;
     349                    }
     350                  else
     351                    {
     352                      *out << Verbose(2) << "Keeping present vector." << endl;
     353                    }
     354                }
     355              else
     356                {
     357                  *out << Verbose(2) << "Keeping present vector." << endl;
     358                }
     359            }
    278360        }
    279       }
    280     }
    281     // printing all inserted for debugging
    282   //    {
    283   //      *out << Verbose(2) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl;
    284   //      int i=0;
    285   //      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    286   //        if (runner != BoundaryPoints[axis].begin())
    287   //          *out << ", " << i << ": " << *runner->second.second;
    288   //        else
    289   //          *out << i << ": " << *runner->second.second;
    290   //        i++;
    291   //      }
    292   //      *out << endl;
    293   //    }
    294     // 3c. throw out points whose distance is less than the mean of left and right neighbours
    295     bool flag = false;
    296     do { // do as long as we still throw one out per round
    297       *out << Verbose(1) << "Looking for candidates to kick out by convex condition ... " << endl;
    298       flag = false;
    299       Boundaries::iterator left = BoundaryPoints[axis].end();
    300       Boundaries::iterator right = BoundaryPoints[axis].end();
    301       for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    302         // set neighbours correctly
    303         if (runner == BoundaryPoints[axis].begin()) {
    304           left = BoundaryPoints[axis].end();
    305         } else {
    306           left = runner;
     361      // printing all inserted for debugging
     362      //    {
     363      //      *out << Verbose(2) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl;
     364      //      int i=0;
     365      //      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     366      //        if (runner != BoundaryPoints[axis].begin())
     367      //          *out << ", " << i << ": " << *runner->second.second;
     368      //        else
     369      //          *out << i << ": " << *runner->second.second;
     370      //        i++;
     371      //      }
     372      //      *out << endl;
     373      //    }
     374      // 3c. throw out points whose distance is less than the mean of left and right neighbours
     375      bool flag = false;
     376      do
     377        { // do as long as we still throw one out per round
     378          *out << Verbose(1)
     379              << "Looking for candidates to kick out by convex condition ... "
     380              << endl;
     381          flag = false;
     382          Boundaries::iterator left = BoundaryPoints[axis].end();
     383          Boundaries::iterator right = BoundaryPoints[axis].end();
     384          for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
     385              != BoundaryPoints[axis].end(); runner++)
     386            {
     387              // set neighbours correctly
     388              if (runner == BoundaryPoints[axis].begin())
     389                {
     390                  left = BoundaryPoints[axis].end();
     391                }
     392              else
     393                {
     394                  left = runner;
     395                }
     396              left--;
     397              right = runner;
     398              right++;
     399              if (right == BoundaryPoints[axis].end())
     400                {
     401                  right = BoundaryPoints[axis].begin();
     402                }
     403              // check distance
     404
     405              // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
     406                {
     407                  Vector SideA, SideB, SideC, SideH;
     408                  SideA.CopyVector(&left->second.second->x);
     409                  SideA.ProjectOntoPlane(&AxisVector);
     410                  //          *out << "SideA: ";
     411                  //          SideA.Output(out);
     412                  //          *out << endl;
     413
     414                  SideB.CopyVector(&right->second.second->x);
     415                  SideB.ProjectOntoPlane(&AxisVector);
     416                  //          *out << "SideB: ";
     417                  //          SideB.Output(out);
     418                  //          *out << endl;
     419
     420                  SideC.CopyVector(&left->second.second->x);
     421                  SideC.SubtractVector(&right->second.second->x);
     422                  SideC.ProjectOntoPlane(&AxisVector);
     423                  //          *out << "SideC: ";
     424                  //          SideC.Output(out);
     425                  //          *out << endl;
     426
     427                  SideH.CopyVector(&runner->second.second->x);
     428                  SideH.ProjectOntoPlane(&AxisVector);
     429                  //          *out << "SideH: ";
     430                  //          SideH.Output(out);
     431                  //          *out << endl;
     432
     433                  // calculate each length
     434                  double a = SideA.Norm();
     435                  //double b = SideB.Norm();
     436                  //double c = SideC.Norm();
     437                  double h = SideH.Norm();
     438                  // calculate the angles
     439                  double alpha = SideA.Angle(&SideH);
     440                  double beta = SideA.Angle(&SideC);
     441                  double gamma = SideB.Angle(&SideH);
     442                  double delta = SideC.Angle(&SideH);
     443                  double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha
     444                      < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.);
     445                  //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
     446                  //*out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
     447                  if ((fabs(h / fabs(h) - MinDistance / fabs(MinDistance))
     448                      < MYEPSILON) && (h < MinDistance))
     449                    {
     450                      // throw out point
     451                      //*out << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl;
     452                      BoundaryPoints[axis].erase(runner);
     453                      flag = true;
     454                    }
     455                }
     456            }
    307457        }
    308         left--;
    309         right = runner;
    310         right++;
    311         if (right == BoundaryPoints[axis].end()) {
    312           right = BoundaryPoints[axis].begin();
    313         }
    314         // check distance
    315        
    316         // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
    317         {
    318           Vector SideA, SideB, SideC, SideH;
    319           SideA.CopyVector(&left->second.second->x);
    320           SideA.ProjectOntoPlane(&AxisVector);
    321   //          *out << "SideA: ";
    322   //          SideA.Output(out);
    323   //          *out << endl;
    324          
    325           SideB.CopyVector(&right->second.second->x);
    326           SideB.ProjectOntoPlane(&AxisVector);
    327   //          *out << "SideB: ";
    328   //          SideB.Output(out);
    329   //          *out << endl;
    330          
    331           SideC.CopyVector(&left->second.second->x);
    332           SideC.SubtractVector(&right->second.second->x);
    333           SideC.ProjectOntoPlane(&AxisVector);
    334   //          *out << "SideC: ";
    335   //          SideC.Output(out);
    336   //          *out << endl;
    337  
    338           SideH.CopyVector(&runner->second.second->x);
    339           SideH.ProjectOntoPlane(&AxisVector);
    340   //          *out << "SideH: ";
    341   //          SideH.Output(out);
    342   //          *out << endl;
    343          
    344           // calculate each length
    345           double a = SideA.Norm();
    346           //double b = SideB.Norm();
    347           //double c = SideC.Norm();
    348           double h = SideH.Norm();
    349           // calculate the angles
    350           double alpha = SideA.Angle(&SideH);
    351           double beta = SideA.Angle(&SideC);
    352           double gamma = SideB.Angle(&SideH);
    353           double delta = SideC.Angle(&SideH);
    354           double MinDistance = a * sin(beta)/(sin(delta)) * (((alpha < M_PI/2.) || (gamma < M_PI/2.)) ? 1. : -1.);
    355   //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
    356           //*out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
    357           if ((fabs(h/fabs(h) - MinDistance/fabs(MinDistance)) < MYEPSILON) && (h <  MinDistance)) {
    358             // throw out point
    359             //*out << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl;
    360             BoundaryPoints[axis].erase(runner);
    361             flag = true;
    362           }
    363         }
    364       }
    365     } while (flag);
    366   }
     458      while (flag);
     459    }
    367460  return BoundaryPoints;
    368 };
     461}
     462;
    369463
    370464/** Determines greatest diameters of a cluster defined by its convex envelope.
     
    375469 * \param IsAngstroem whether we have angstroem or atomic units
    376470 * \return NDIM array of the diameters
    377  */
    378 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
     471 */
     472double *
     473GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,
     474    bool IsAngstroem)
    379475{
    380476  // get points on boundary of NULL was given as parameter
    381477  bool BoundaryFreeFlag = false;
    382478  Boundaries *BoundaryPoints = BoundaryPtr;
    383   if (BoundaryPoints == NULL) {
    384     BoundaryFreeFlag = true;
    385     BoundaryPoints = GetBoundaryPoints(out, mol);
    386   } else {
    387     *out << Verbose(1) << "Using given boundary points set." << endl;
    388   }
    389  
     479  if (BoundaryPoints == NULL)
     480    {
     481      BoundaryFreeFlag = true;
     482      BoundaryPoints = GetBoundaryPoints(out, mol);
     483    }
     484  else
     485    {
     486      *out << Verbose(1) << "Using given boundary points set." << endl;
     487    }
    390488  // determine biggest "diameter" of cluster for each axis
    391489  Boundaries::iterator Neighbour, OtherNeighbour;
    392490  double *GreatestDiameter = new double[NDIM];
    393   for(int i=0;i<NDIM;i++)
     491  for (int i = 0; i < NDIM; i++)
    394492    GreatestDiameter[i] = 0.;
    395493  double OldComponent, tmp, w1, w2;
    396494  Vector DistanceVector, OtherVector;
    397495  int component, Othercomponent;
    398   for(int axis=0;axis<NDIM;axis++) { // regard each projected plane
    399     //*out << Verbose(1) << "Current axis is " << axis << "." << endl;
    400     for (int j=0;j<2;j++) { // and for both axis on the current plane
    401       component = (axis+j+1)%NDIM;
    402       Othercomponent = (axis+1+((j+1) & 1))%NDIM;
    403       //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl;
    404       for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    405         //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl;
    406         // seek for the neighbours pair where the Othercomponent sign flips
    407         Neighbour = runner;
    408         Neighbour++;
    409         if (Neighbour == BoundaryPoints[axis].end())  // make it wrap around
    410           Neighbour = BoundaryPoints[axis].begin();
    411         DistanceVector.CopyVector(&runner->second.second->x);
    412         DistanceVector.SubtractVector(&Neighbour->second.second->x);
    413         do {  // seek for neighbour pair where it flips
    414           OldComponent = DistanceVector.x[Othercomponent];
    415           Neighbour++;
    416           if (Neighbour == BoundaryPoints[axis].end())  // make it wrap around
    417             Neighbour = BoundaryPoints[axis].begin();
    418           DistanceVector.CopyVector(&runner->second.second->x);
    419           DistanceVector.SubtractVector(&Neighbour->second.second->x);
    420           //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl;
    421         } while ((runner != Neighbour) && ( fabs( OldComponent/fabs(OldComponent) - DistanceVector.x[Othercomponent]/fabs(DistanceVector.x[Othercomponent]) ) < MYEPSILON)); // as long as sign does not flip
    422         if (runner != Neighbour) {
    423           OtherNeighbour = Neighbour;
    424           if (OtherNeighbour == BoundaryPoints[axis].begin())  // make it wrap around
    425             OtherNeighbour = BoundaryPoints[axis].end();
    426           OtherNeighbour--;
    427           //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl;
    428           // now we have found the pair: Neighbour and OtherNeighbour
    429           OtherVector.CopyVector(&runner->second.second->x);
    430           OtherVector.SubtractVector(&OtherNeighbour->second.second->x);
    431           //*out << Verbose(2) << "Distances to Neighbour and OtherNeighbour are " << DistanceVector.x[component] << " and " << OtherVector.x[component] << "." << endl;
    432           //*out << Verbose(2) << "OtherComponents to Neighbour and OtherNeighbour are " << DistanceVector.x[Othercomponent] << " and " << OtherVector.x[Othercomponent] << "." << endl;
    433           // do linear interpolation between points (is exact) to extract exact intersection between Neighbour and OtherNeighbour
    434           w1 = fabs(OtherVector.x[Othercomponent]);
    435           w2 = fabs(DistanceVector.x[Othercomponent]);
    436           tmp = fabs((w1*DistanceVector.x[component] + w2*OtherVector.x[component])/(w1+w2));
    437           // mark if it has greater diameter
    438           //*out << Verbose(2) << "Comparing current greatest " << GreatestDiameter[component] << " to new " << tmp << "." << endl;
    439           GreatestDiameter[component] = (GreatestDiameter[component] > tmp) ? GreatestDiameter[component] : tmp;
    440         } //else
    441           //*out << Verbose(2) << "Saw no sign flip, probably top or bottom node." << endl;
    442       }
    443     }
    444   }
    445   *out << Verbose(0) << "RESULT: The biggest diameters are " << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and " << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "." << endl;
     496  for (int axis = 0; axis < NDIM; axis++)
     497    { // regard each projected plane
     498      //*out << Verbose(1) << "Current axis is " << axis << "." << endl;
     499      for (int j = 0; j < 2; j++)
     500        { // and for both axis on the current plane
     501          component = (axis + j + 1) % NDIM;
     502          Othercomponent = (axis + 1 + ((j + 1) & 1)) % NDIM;
     503          //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl;
     504          for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
     505              != BoundaryPoints[axis].end(); runner++)
     506            {
     507              //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl;
     508              // seek for the neighbours pair where the Othercomponent sign flips
     509              Neighbour = runner;
     510              Neighbour++;
     511              if (Neighbour == BoundaryPoints[axis].end()) // make it wrap around
     512                Neighbour = BoundaryPoints[axis].begin();
     513              DistanceVector.CopyVector(&runner->second.second->x);
     514              DistanceVector.SubtractVector(&Neighbour->second.second->x);
     515              do
     516                { // seek for neighbour pair where it flips
     517                  OldComponent = DistanceVector.x[Othercomponent];
     518                  Neighbour++;
     519                  if (Neighbour == BoundaryPoints[axis].end()) // make it wrap around
     520                    Neighbour = BoundaryPoints[axis].begin();
     521                  DistanceVector.CopyVector(&runner->second.second->x);
     522                  DistanceVector.SubtractVector(&Neighbour->second.second->x);
     523                  //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl;
     524                }
     525              while ((runner != Neighbour) && (fabs(OldComponent / fabs(
     526                  OldComponent) - DistanceVector.x[Othercomponent] / fabs(
     527                  DistanceVector.x[Othercomponent])) < MYEPSILON)); // as long as sign does not flip
     528              if (runner != Neighbour)
     529                {
     530                  OtherNeighbour = Neighbour;
     531                  if (OtherNeighbour == BoundaryPoints[axis].begin()) // make it wrap around
     532                    OtherNeighbour = BoundaryPoints[axis].end();
     533                  OtherNeighbour--;
     534                  //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl;
     535                  // now we have found the pair: Neighbour and OtherNeighbour
     536                  OtherVector.CopyVector(&runner->second.second->x);
     537                  OtherVector.SubtractVector(&OtherNeighbour->second.second->x);
     538                  //*out << Verbose(2) << "Distances to Neighbour and OtherNeighbour are " << DistanceVector.x[component] << " and " << OtherVector.x[component] << "." << endl;
     539                  //*out << Verbose(2) << "OtherComponents to Neighbour and OtherNeighbour are " << DistanceVector.x[Othercomponent] << " and " << OtherVector.x[Othercomponent] << "." << endl;
     540                  // do linear interpolation between points (is exact) to extract exact intersection between Neighbour and OtherNeighbour
     541                  w1 = fabs(OtherVector.x[Othercomponent]);
     542                  w2 = fabs(DistanceVector.x[Othercomponent]);
     543                  tmp = fabs((w1 * DistanceVector.x[component] + w2
     544                      * OtherVector.x[component]) / (w1 + w2));
     545                  // mark if it has greater diameter
     546                  //*out << Verbose(2) << "Comparing current greatest " << GreatestDiameter[component] << " to new " << tmp << "." << endl;
     547                  GreatestDiameter[component] = (GreatestDiameter[component]
     548                      > tmp) ? GreatestDiameter[component] : tmp;
     549                } //else
     550              //*out << Verbose(2) << "Saw no sign flip, probably top or bottom node." << endl;
     551            }
     552        }
     553    }
     554  *out << Verbose(0) << "RESULT: The biggest diameters are "
     555      << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and "
     556      << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom"
     557      : "atomiclength") << "." << endl;
    446558
    447559  // free reference lists
    448560  if (BoundaryFreeFlag)
    449     delete[](BoundaryPoints);
     561    delete[] (BoundaryPoints);
    450562
    451563  return GreatestDiameter;
     564}
     565;
     566
     567/** Creates the objects in a raster3d file (renderable with a header.r3d)
     568 * \param *out output stream for debugging
     569 * \param *tecplot output stream for tecplot data
     570 * \param *Tess Tesselation structure with constructed triangles
     571 * \param *mol molecule structure with atom positions
     572 */
     573void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol)
     574{
     575        atom *Walker = mol->start;
     576        bond *Binder = mol->first;
     577        int i;
     578        Vector *center = mol->DetermineCenterOfAll(out);
     579        if (rasterfile != NULL) {
     580                //cout << Verbose(1) << "Writing Raster3D file ... ";
     581                *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;
     582                *rasterfile << "@header.r3d" << endl;
     583                *rasterfile << "# All atoms as spheres" << endl;
     584                while (Walker->next != mol->end) {
     585                        Walker = Walker->next;
     586                        *rasterfile << "2" << endl << "  ";     // 2 is sphere type
     587                        for (i=0;i<NDIM;i++)
     588                                *rasterfile << Walker->x.x[i]+center->x[i] << " ";
     589                        *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour
     590                }
     591
     592                *rasterfile << "# All bonds as vertices" << endl;
     593                while (Binder->next != mol->last) {
     594                        Binder = Binder->next;
     595                        *rasterfile << "3" << endl << "  ";     // 2 is round-ended cylinder type
     596                        for (i=0;i<NDIM;i++)
     597                                *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " ";
     598                        *rasterfile << "\t0.03\t";
     599                        for (i=0;i<NDIM;i++)
     600                                *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " ";
     601                        *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour
     602                }
     603
     604                *rasterfile << "# All tesselation triangles" << endl;
     605                for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
     606                        *rasterfile << "1" << endl << "  ";     // 1 is triangle type
     607                        for (i=0;i<3;i++) {     // print each node
     608                                for (int j=0;j<NDIM;j++)        // and for each node all NDIM coordinates
     609                                        *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";
     610                                *rasterfile << "\t";
     611                        }
     612                        *rasterfile << "1. 0. 0." << endl;      // red as colour
     613                        *rasterfile << "18" << endl << "  0.5 0.5 0.5" << endl; // 18 is transparency type for previous object
     614                }
     615        } else {
     616                cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;
     617        }
     618        delete(center);
    452619};
    453620
     621/** This function creates the tecplot file, displaying the tesselation of the hull.
     622 * \param *out output stream for debugging
     623 * \param *tecplot output stream for tecplot data
     624 * \param N arbitrary number to differentiate various zones in the tecplot format
     625 */
     626void
     627write_tecplot_file(ofstream *out, ofstream *tecplot,
     628    class Tesselation *TesselStruct, class molecule *mol, int N)
     629{
     630  if (tecplot != NULL)
     631    {
     632      *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl;
     633      *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\"" << endl;
     634      *tecplot << "ZONE T=\"TRIANGLES" << N << "\", N="
     635          << TesselStruct->PointsOnBoundaryCount << ", E="
     636          << TesselStruct->TrianglesOnBoundaryCount
     637          << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;
     638      int *LookupList = new int[mol->AtomCount];
     639      for (int i = 0; i < mol->AtomCount; i++)
     640        LookupList[i] = -1;
     641
     642      // print atom coordinates
     643      *out << Verbose(2) << "The following triangles were created:";
     644      int Counter = 1;
     645      atom *Walker = NULL;
     646      for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target
     647          != TesselStruct->PointsOnBoundary.end(); target++)
     648        {
     649          Walker = target->second->node;
     650          LookupList[Walker->nr] = Counter++;
     651          *tecplot << Walker->x.x[0] << " " << Walker->x.x[1] << " "
     652              << Walker->x.x[2] << " " << endl;
     653        }
     654      *tecplot << endl;
     655      // print connectivity
     656      for (TriangleMap::iterator runner =
     657          TesselStruct->TrianglesOnBoundary.begin(); runner
     658          != TesselStruct->TrianglesOnBoundary.end(); runner++)
     659        {
     660          *out << " " << runner->second->endpoints[0]->node->Name << "<->"
     661              << runner->second->endpoints[1]->node->Name << "<->"
     662              << runner->second->endpoints[2]->node->Name;
     663          *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " "
     664              << LookupList[runner->second->endpoints[1]->node->nr] << " "
     665              << LookupList[runner->second->endpoints[2]->node->nr] << endl;
     666        }
     667      delete[] (LookupList);
     668      *out << endl;
     669    }
     670}
    454671
    455672/** Determines the volume of a cluster.
     
    460677 * \param *BoundaryPoints NDIM set of boundary points on the projected plane per axis, on return if desired
    461678 * \param *mol molecule structure representing the cluster
    462  * \return determined volume of the cluster in cubed config:GetIsAngstroem() 
     679 * \return determined volume of the cluster in cubed config:GetIsAngstroem()
    463680 */
    464 double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPtr, molecule *mol)
     681double
     682VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration,
     683    Boundaries *BoundaryPtr, molecule *mol)
    465684{
    466685  bool IsAngstroem = configuration->GetIsAngstroem();
     
    471690  double volume = 0.;
    472691  double PyramidVolume = 0.;
    473   double G,h;
    474   Vector x,y;
    475   double a,b,c;
     692  double G, h;
     693  Vector x, y;
     694  double a, b, c;
     695
     696  //Find_non_convex_border(out, tecplot, *TesselStruct, mol); // Is now called from command line.
    476697
    477698  // 1. calculate center of gravity
    478699  *out << endl;
    479700  Vector *CenterOfGravity = mol->DetermineCenterOfGravity(out);
    480  
     701
    481702  // 2. translate all points into CoG
    482703  *out << Verbose(1) << "Translating system to Center of Gravity." << endl;
    483704  Walker = mol->start;
    484   while (Walker->next != mol->end) {
    485     Walker = Walker->next;
    486     Walker->x.Translate(CenterOfGravity);
    487   }
    488  
     705  while (Walker->next != mol->end)
     706    {
     707      Walker = Walker->next;
     708      Walker->x.Translate(CenterOfGravity);
     709    }
     710
    489711  // 3. Find all points on the boundary
    490   if (BoundaryPoints == NULL) {
    491     BoundaryFreeFlag = true;
    492     BoundaryPoints = GetBoundaryPoints(out, mol);
    493   } else {
    494     *out << Verbose(1) << "Using given boundary points set." << endl;
    495   }
    496  
     712  if (BoundaryPoints == NULL)
     713    {
     714      BoundaryFreeFlag = true;
     715      BoundaryPoints = GetBoundaryPoints(out, mol);
     716    }
     717  else
     718    {
     719      *out << Verbose(1) << "Using given boundary points set." << endl;
     720    }
     721
    497722  // 4. fill the boundary point list
    498   for (int axis=0;axis<NDIM;axis++)
    499     for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    500       TesselStruct->AddPoint(runner->second.second);
    501     }
    502 
    503   *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;
     723  for (int axis = 0; axis < NDIM; axis++)
     724    for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
     725        != BoundaryPoints[axis].end(); runner++)
     726      {
     727        TesselStruct->AddPoint(runner->second.second);
     728      }
     729
     730  *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount
     731      << " points on the convex boundary." << endl;
    504732  // now we have the whole set of edge points in the BoundaryList
    505733
    506734  // listing for debugging
    507 //  *out << Verbose(1) << "Listing PointsOnBoundary:";
    508 //  for(PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
    509 //    *out << " " << *runner->second;
    510 //  }
    511 //  *out << endl;
    512  
     735  //  *out << Verbose(1) << "Listing PointsOnBoundary:";
     736  //  for(PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
     737  //    *out << " " << *runner->second;
     738  //  }
     739  //  *out << endl;
     740
    513741  // 5a. guess starting triangle
    514742  TesselStruct->GuessStartingTriangle(out);
    515  
     743
    516744  // 5b. go through all lines, that are not yet part of two triangles (only of one so far)
    517745  TesselStruct->TesselateOnBoundary(out, configuration, mol);
    518746
    519   *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl;
     747  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount
     748      << " triangles with " << TesselStruct->LinesOnBoundaryCount
     749      << " lines and " << TesselStruct->PointsOnBoundaryCount << " points."
     750      << endl;
    520751
    521752  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    522   *out << Verbose(1) << "Calculating the volume of the pyramids formed out of triangles and center of gravity." << endl;
    523   for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
    524     x.CopyVector(&runner->second->endpoints[0]->node->x);
    525     x.SubtractVector(&runner->second->endpoints[1]->node->x);
    526     y.CopyVector(&runner->second->endpoints[0]->node->x);
    527     y.SubtractVector(&runner->second->endpoints[2]->node->x);
    528     a = sqrt(runner->second->endpoints[0]->node->x.Distance(&runner->second->endpoints[1]->node->x));
    529     b = sqrt(runner->second->endpoints[0]->node->x.Distance(&runner->second->endpoints[2]->node->x));
    530     c = sqrt(runner->second->endpoints[2]->node->x.Distance(&runner->second->endpoints[1]->node->x));
    531     G =  sqrt( ( (a*a+b*b+c*c)*(a*a+b*b+c*c) - 2*(a*a*a*a + b*b*b*b + c*c*c*c) )/16.); // area of tesselated triangle
    532     x.MakeNormalVector(&runner->second->endpoints[0]->node->x, &runner->second->endpoints[1]->node->x, &runner->second->endpoints[2]->node->x);
    533     x.Scale(runner->second->endpoints[1]->node->x.Projection(&x));
    534     h = x.Norm(); // distance of CoG to triangle
    535     PyramidVolume = (1./3.) * G * h;    // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    536     *out << Verbose(2) << "Area of triangle is " << G << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is " << h << " and the volume is " << PyramidVolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    537     volume += PyramidVolume;
    538   }
    539   *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10) << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    540 
     753  *out << Verbose(1)
     754      << "Calculating the volume of the pyramids formed out of triangles and center of gravity."
     755      << endl;
     756  for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner
     757      != TesselStruct->TrianglesOnBoundary.end(); runner++)
     758    { // go through every triangle, calculate volume of its pyramid with CoG as peak
     759      x.CopyVector(&runner->second->endpoints[0]->node->x);
     760      x.SubtractVector(&runner->second->endpoints[1]->node->x);
     761      y.CopyVector(&runner->second->endpoints[0]->node->x);
     762      y.SubtractVector(&runner->second->endpoints[2]->node->x);
     763      a = sqrt(runner->second->endpoints[0]->node->x.Distance(
     764          &runner->second->endpoints[1]->node->x));
     765      b = sqrt(runner->second->endpoints[0]->node->x.Distance(
     766          &runner->second->endpoints[2]->node->x));
     767      c = sqrt(runner->second->endpoints[2]->node->x.Distance(
     768          &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
     771      x.MakeNormalVector(&runner->second->endpoints[0]->node->x,
     772          &runner->second->endpoints[1]->node->x,
     773          &runner->second->endpoints[2]->node->x);
     774      x.Scale(runner->second->endpoints[1]->node->x.Projection(&x));
     775      h = x.Norm(); // distance of CoG to triangle
     776      PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
     777      *out << Verbose(2) << "Area of triangle is " << G << " "
     778          << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is "
     779          << h << " and the volume is " << PyramidVolume << " "
     780          << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     781      volume += PyramidVolume;
     782    }
     783  *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10)
     784      << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3."
     785      << endl;
    541786
    542787  // 7. translate all points back from CoG
    543   *out << Verbose(1) << "Translating system back from Center of Gravity." << endl;
     788  *out << Verbose(1) << "Translating system back from Center of Gravity."
     789      << endl;
    544790  CenterOfGravity->Scale(-1);
    545791  Walker = mol->start;
    546   while (Walker->next != mol->end) {
    547     Walker = Walker->next;
    548     Walker->x.Translate(CenterOfGravity);
    549   }
    550  
     792  while (Walker->next != mol->end)
     793    {
     794      Walker = Walker->next;
     795      Walker->x.Translate(CenterOfGravity);
     796    }
     797
    551798  // 8. Store triangles in tecplot file
    552   if (tecplot != NULL) {
    553     *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl;
    554     *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\"" << endl;
    555     *tecplot << "ZONE T=\"TRIANGLES\", N=" <<  TesselStruct->PointsOnBoundaryCount << ", E=" <<  TesselStruct->TrianglesOnBoundaryCount << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;
    556     int *LookupList = new int[mol->AtomCount];
    557     for (int i=0;i<mol->AtomCount;i++)
    558       LookupList[i] = -1;
    559    
    560     // print atom coordinates
    561     *out << Verbose(2) << "The following triangles were created:";
    562     int Counter = 1;
    563     atom *Walker = NULL;
    564     for (PointMap::iterator target =  TesselStruct->PointsOnBoundary.begin(); target !=  TesselStruct->PointsOnBoundary.end(); target++) {
    565       Walker = target->second->node;
    566       LookupList[Walker->nr] = Counter++;
    567       *tecplot << Walker->x.x[0] << " " << Walker->x.x[1] << " " << Walker->x.x[2] << " " << endl;
    568     }
    569     *tecplot << endl;
    570       // print connectivity
    571     for (TriangleMap::iterator runner =  TesselStruct->TrianglesOnBoundary.begin(); runner !=  TesselStruct->TrianglesOnBoundary.end(); runner++) {
    572       *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;
    573       *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;
    574     }
    575     delete[](LookupList);
    576     *out << endl;
    577   }
     799  write_tecplot_file(out, tecplot, TesselStruct, mol, 0);
    578800
    579801  // free reference lists
    580802  if (BoundaryFreeFlag)
    581     delete[](BoundaryPoints);
    582  
     803    delete[] (BoundaryPoints);
     804
    583805  return volume;
    584 };
    585 
     806}
     807;
    586808
    587809/** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density.
     
    593815 * \param celldensity desired average density in final cell
    594816 */
    595 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity)
     817void
     818PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol,
     819    double ClusterVolume, double celldensity)
    596820{
    597821  // transform to PAS
    598822  mol->PrincipalAxisSystem(out, true);
    599  
     823
    600824  // some preparations beforehand
    601825  bool IsAngstroem = configuration->GetIsAngstroem();
     
    603827  double clustervolume;
    604828  if (ClusterVolume == 0)
    605     clustervolume = VolumeOfConvexEnvelope(out, NULL, configuration, BoundaryPoints, mol);
    606   else
     829    clustervolume = VolumeOfConvexEnvelope(out, NULL, configuration,
     830        BoundaryPoints, mol);
     831  else
    607832    clustervolume = ClusterVolume;
    608   double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem);
     833  double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol,
     834      IsAngstroem);
    609835  Vector BoxLengths;
    610   int repetition[NDIM] = {1, 1, 1};
     836  int repetition[NDIM] =
     837    { 1, 1, 1 };
    611838  int TotalNoClusters = 1;
    612   for (int i=0;i<NDIM;i++)
     839  for (int i = 0; i < NDIM; i++)
    613840    TotalNoClusters *= repetition[i];
    614841
     
    616843  double totalmass = 0.;
    617844  atom *Walker = mol->start;
    618   while (Walker->next != mol->end) {
    619     Walker = Walker->next;
    620     totalmass += Walker->type->mass;
    621   }
    622   *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl;
    623  
    624   *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass/clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    625  
     845  while (Walker->next != mol->end)
     846    {
     847      Walker = Walker->next;
     848      totalmass += Walker->type->mass;
     849    }
     850  *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10)
     851      << totalmass << " atomicmassunit." << endl;
     852
     853  *out << Verbose(0) << "RESULT: The average density is " << setprecision(10)
     854      << totalmass / clustervolume << " atomicmassunit/"
     855      << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     856
    626857  // solve cubic polynomial
    627   *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl;
     858  *out << Verbose(1) << "Solving equidistant suspension in water problem ..."
     859      << endl;
    628860  double cellvolume;
    629861  if (IsAngstroem)
    630     cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_A - (totalmass/clustervolume))/(celldensity-1);
     862    cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass
     863        / clustervolume)) / (celldensity - 1);
    631864  else
    632     cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_a0 - (totalmass/clustervolume))/(celldensity-1);
    633   *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    634  
    635   double minimumvolume = TotalNoClusters*(GreatestDiameter[0]*GreatestDiameter[1]*GreatestDiameter[2]);
    636   *out << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    637   if (minimumvolume > cellvolume) {
    638     cerr << Verbose(0) << "ERROR: the containing box already has a greater volume than the envisaged cell volume!" << endl;
    639     cout << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl;
    640     for(int i=0;i<NDIM;i++)
    641       BoxLengths.x[i] = GreatestDiameter[i];
    642     mol->CenterEdge(out, &BoxLengths);
    643   } else {
    644     BoxLengths.x[0] = (repetition[0]*GreatestDiameter[0] + repetition[1]*GreatestDiameter[1] + repetition[2]*GreatestDiameter[2]);
    645     BoxLengths.x[1] = (repetition[0]*repetition[1]*GreatestDiameter[0]*GreatestDiameter[1]
    646               + repetition[0]*repetition[2]*GreatestDiameter[0]*GreatestDiameter[2]
    647               + repetition[1]*repetition[2]*GreatestDiameter[1]*GreatestDiameter[2]);
    648     BoxLengths.x[2] = minimumvolume - cellvolume;
    649     double x0 = 0.,x1 = 0.,x2 = 0.;
    650     if (gsl_poly_solve_cubic(BoxLengths.x[0],BoxLengths.x[1],BoxLengths.x[2],&x0,&x1,&x2) == 1) // either 1 or 3 on return
    651       *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl;
    652     else {
    653       *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl;
    654       x0 = x2;  // sorted in ascending order
    655     }
    656  
    657     cellvolume = 1;
    658     for(int i=0;i<NDIM;i++) {
    659       BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
    660       cellvolume *= BoxLengths.x[i];
    661     }
    662  
    663     // set new box dimensions
    664     *out << Verbose(0) << "Translating to box with these boundaries." << endl;
    665     mol->CenterInBox((ofstream *)&cout, &BoxLengths);
    666   }
     865    cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass
     866        / clustervolume)) / (celldensity - 1);
     867  *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity
     868      << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom"
     869      : "atomiclength") << "^3." << endl;
     870
     871  double minimumvolume = TotalNoClusters * (GreatestDiameter[0]
     872      * GreatestDiameter[1] * GreatestDiameter[2]);
     873  *out << Verbose(1)
     874      << "Minimum volume of the convex envelope contained in a rectangular box is "
     875      << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom"
     876      : "atomiclength") << "^3." << endl;
     877  if (minimumvolume > cellvolume)
     878    {
     879      cerr << Verbose(0)
     880          << "ERROR: the containing box already has a greater volume than the envisaged cell volume!"
     881          << endl;
     882      cout << Verbose(0)
     883          << "Setting Box dimensions to minimum possible, the greatest diameters."
     884          << endl;
     885      for (int i = 0; i < NDIM; i++)
     886        BoxLengths.x[i] = GreatestDiameter[i];
     887      mol->CenterEdge(out, &BoxLengths);
     888    }
     889  else
     890    {
     891      BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1]
     892          * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]);
     893      BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0]
     894          * GreatestDiameter[1] + repetition[0] * repetition[2]
     895          * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1]
     896          * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]);
     897      BoxLengths.x[2] = minimumvolume - cellvolume;
     898      double x0 = 0., x1 = 0., x2 = 0.;
     899      if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1],
     900          BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return
     901        *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0
     902            << " ." << endl;
     903      else
     904        {
     905          *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0
     906              << " and " << x1 << " and " << x2 << " ." << endl;
     907          x0 = x2; // sorted in ascending order
     908        }
     909
     910      cellvolume = 1;
     911      for (int i = 0; i < NDIM; i++)
     912        {
     913          BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
     914          cellvolume *= BoxLengths.x[i];
     915        }
     916
     917      // set new box dimensions
     918      *out << Verbose(0) << "Translating to box with these boundaries." << endl;
     919      mol->CenterInBox((ofstream *) &cout, &BoxLengths);
     920    }
    667921  // update Box of atoms by boundary
    668922  mol->SetBoxDimension(&BoxLengths);
    669   *out << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    670 };
    671 
     923  *out << Verbose(0) << "RESULT: The resulting cell dimensions are: "
     924      << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and "
     925      << BoxLengths.x[2] << " with total volume of " << cellvolume << " "
     926      << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     927}
     928;
    672929
    673930// =========================================================== class TESSELATION ===========================================
     
    677934Tesselation::Tesselation()
    678935{
    679   PointsOnBoundaryCount = 0; 
    680   LinesOnBoundaryCount = 0; 
     936  PointsOnBoundaryCount = 0;
     937  LinesOnBoundaryCount = 0;
    681938  TrianglesOnBoundaryCount = 0;
    682 };
     939  TriangleFilesWritten = 0;
     940}
     941;
    683942
    684943/** Constructor of class Tesselation.
     
    687946Tesselation::~Tesselation()
    688947{
    689   for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
    690     delete(runner->second);
    691   }
    692 };
     948        cout << Verbose(1) << "Free'ing TesselStruct ... " << endl;
     949        for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
     950                if (runner->second != NULL) {
     951                        delete (runner->second);
     952                        runner->second = NULL;
     953                } else
     954                        cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl;
     955        }
     956        for (LineMap::iterator runner = LinesOnBoundary.begin(); runner != LinesOnBoundary.end(); runner++) {
     957                if (runner->second != NULL) {
     958                        delete (runner->second);
     959                        runner->second = NULL;
     960                } else
     961                        cerr << "ERROR: The line " << runner->first << " has already been free'd." << endl;
     962        }
     963        for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
     964                if (runner->second != NULL) {
     965                        delete (runner->second);
     966                        runner->second = NULL;
     967                } else
     968                        cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl;
     969        }
     970}
     971;
    693972
    694973/** Gueses first starting triangle of the convex envelope.
     
    696975 * \param *out output stream for debugging
    697976 * \param PointsOnBoundary set of boundary points defining the convex envelope of the cluster
    698  */
    699 void Tesselation::GuessStartingTriangle(ofstream *out)
     977 */
     978void
     979Tesselation::GuessStartingTriangle(ofstream *out)
    700980{
    701981  // 4b. create a starting triangle
     
    707987  A = PointsOnBoundary.begin(); // the first may be chosen arbitrarily
    708988
    709   // with A chosen, take each pair B,C and sort
    710   if (A != PointsOnBoundary.end()) {
    711     B = A;
    712     B++;
    713     for (; B != PointsOnBoundary.end(); B++) {
    714       C = B;
    715       C++;
    716       for (; C != PointsOnBoundary.end(); C++) {
    717         tmp = A->second->node->x.Distance(&B->second->node->x);
    718         distance = tmp*tmp;
    719         tmp = A->second->node->x.Distance(&C->second->node->x);
    720         distance += tmp*tmp;
    721         tmp = B->second->node->x.Distance(&C->second->node->x);
    722         distance += tmp*tmp;
    723         DistanceMMap.insert( DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(B,C) ) );
    724       }
    725     }
    726   }
    727 //    // listing distances
    728 //    *out << Verbose(1) << "Listing DistanceMMap:";
    729 //    for(DistanceMultiMap::iterator runner = DistanceMMap.begin(); runner != DistanceMMap.end(); runner++) {
    730 //      *out << " " << runner->first << "(" << *runner->second.first->second << ", " << *runner->second.second->second << ")";
    731 //    }
    732 //    *out << endl;
    733  
     989  // with A chosen, take each pair B,C and sort
     990  if (A != PointsOnBoundary.end())
     991    {
     992      B = A;
     993      B++;
     994      for (; B != PointsOnBoundary.end(); B++)
     995        {
     996          C = B;
     997          C++;
     998          for (; C != PointsOnBoundary.end(); C++)
     999            {
     1000              tmp = A->second->node->x.Distance(&B->second->node->x);
     1001              distance = tmp * tmp;
     1002              tmp = A->second->node->x.Distance(&C->second->node->x);
     1003              distance += tmp * tmp;
     1004              tmp = B->second->node->x.Distance(&C->second->node->x);
     1005              distance += tmp * tmp;
     1006              DistanceMMap.insert(DistanceMultiMapPair(distance, pair<
     1007                  PointMap::iterator, PointMap::iterator> (B, C)));
     1008            }
     1009        }
     1010    }
     1011  //    // listing distances
     1012  //    *out << Verbose(1) << "Listing DistanceMMap:";
     1013  //    for(DistanceMultiMap::iterator runner = DistanceMMap.begin(); runner != DistanceMMap.end(); runner++) {
     1014  //      *out << " " << runner->first << "(" << *runner->second.first->second << ", " << *runner->second.second->second << ")";
     1015  //    }
     1016  //    *out << endl;
    7341017  // 4b2. pick three baselines forming a triangle
    7351018  // 1. we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
    7361019  DistanceMultiMap::iterator baseline = DistanceMMap.begin();
    737   for (; baseline != DistanceMMap.end(); baseline++) {
    738     // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
    739     // 2. next, we have to check whether all points reside on only one side of the triangle
    740     // 3. construct plane vector
    741     PlaneVector.MakeNormalVector(&A->second->node->x, &baseline->second.first->second->node->x, &baseline->second.second->second->node->x);
    742     *out << Verbose(2) << "Plane vector of candidate triangle is ";
    743     PlaneVector.Output(out);
    744     *out << endl;
    745     // 4. loop over all points
    746     double sign = 0.;
    747     PointMap::iterator checker = PointsOnBoundary.begin();
    748     for (; checker != PointsOnBoundary.end(); checker++) {
    749       // (neglecting A,B,C)
    750       if ((checker == A) || (checker == baseline->second.first) || (checker == baseline->second.second))
    751         continue;
    752       // 4a. project onto plane vector
    753       TrialVector.CopyVector(&checker->second->node->x);
    754       TrialVector.SubtractVector(&A->second->node->x);
    755       distance = TrialVector.Projection(&PlaneVector);
    756       if (fabs(distance) < 1e-4)  // we need to have a small epsilon around 0 which is still ok
    757         continue;
    758       *out << Verbose(3) << "Projection of " << checker->second->node->Name << " yields distance of " << distance << "." << endl;
    759       tmp = distance/fabs(distance);
    760       // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle)
    761       if ((sign != 0) && (tmp != sign)) {
    762         // 4c. If so, break 4. loop and continue with next candidate in 1. loop
    763         *out << Verbose(2) << "Current candidates: " << A->second->node->Name << "," << baseline->second.first->second->node->Name  << "," << baseline->second.second->second->node->Name << " leave " << checker->second->node->Name << " outside the convex hull." << endl;
    764         break;
    765       } else { // note the sign for later
    766         *out << Verbose(2) << "Current candidates: " << A->second->node->Name << "," << baseline->second.first->second->node->Name  << "," << baseline->second.second->second->node->Name << " leave " << checker->second->node->Name << " inside the convex hull." << endl;
    767         sign = tmp;
    768       }
    769       // 4d. Check whether the point is inside the triangle (check distance to each node
    770       tmp = checker->second->node->x.Distance(&A->second->node->x);
    771       int innerpoint = 0;
    772       if ((tmp < A->second->node->x.Distance(&baseline->second.first->second->node->x))
    773           && (tmp < A->second->node->x.Distance(&baseline->second.second->second->node->x)))
    774         innerpoint++;
    775       tmp = checker->second->node->x.Distance(&baseline->second.first->second->node->x);
    776       if ((tmp < baseline->second.first->second->node->x.Distance(&A->second->node->x))
    777           && (tmp < baseline->second.first->second->node->x.Distance(&baseline->second.second->second->node->x)))
    778         innerpoint++;
    779       tmp = checker->second->node->x.Distance(&baseline->second.second->second->node->x);
    780       if ((tmp < baseline->second.second->second->node->x.Distance(&baseline->second.first->second->node->x))
    781           && (tmp < baseline->second.second->second->node->x.Distance(&A->second->node->x)))
    782         innerpoint++;
    783       // 4e. If so, break 4. loop and continue with next candidate in 1. loop
    784       if (innerpoint == 3)
    785         break;
    786     }
    787     // 5. come this far, all on same side? Then break 1. loop and construct triangle
    788     if (checker == PointsOnBoundary.end()) {
    789       *out << "Looks like we have a candidate!" << endl;
    790       break;
    791     }
    792   }
    793   if (baseline != DistanceMMap.end()) {
    794     BPS[0] = baseline->second.first->second;
    795     BPS[1] = baseline->second.second->second;
    796     BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    797     BPS[0] = A->second;
    798     BPS[1] = baseline->second.second->second;
    799     BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    800     BPS[0] = baseline->second.first->second;
    801     BPS[1] = A->second;
    802     BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 
    803    
    804     // 4b3. insert created triangle
    805     BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    806     TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
    807     TrianglesOnBoundaryCount++;
    808     for(int i=0;i<NDIM;i++) {
    809       LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
    810       LinesOnBoundaryCount++;
    811     }
    812  
    813     *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
    814   } else {
    815     *out << Verbose(1) << "No starting triangle found." << endl;
    816     exit(255);
    817   }
    818 };
    819 
     1020  for (; baseline != DistanceMMap.end(); baseline++)
     1021    {
     1022      // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
     1023      // 2. next, we have to check whether all points reside on only one side of the triangle
     1024      // 3. construct plane vector
     1025      PlaneVector.MakeNormalVector(&A->second->node->x,
     1026          &baseline->second.first->second->node->x,
     1027          &baseline->second.second->second->node->x);
     1028      *out << Verbose(2) << "Plane vector of candidate triangle is ";
     1029      PlaneVector.Output(out);
     1030      *out << endl;
     1031      // 4. loop over all points
     1032      double sign = 0.;
     1033      PointMap::iterator checker = PointsOnBoundary.begin();
     1034      for (; checker != PointsOnBoundary.end(); checker++)
     1035        {
     1036          // (neglecting A,B,C)
     1037          if ((checker == A) || (checker == baseline->second.first) || (checker
     1038              == baseline->second.second))
     1039            continue;
     1040          // 4a. project onto plane vector
     1041          TrialVector.CopyVector(&checker->second->node->x);
     1042          TrialVector.SubtractVector(&A->second->node->x);
     1043          distance = TrialVector.Projection(&PlaneVector);
     1044          if (fabs(distance) < 1e-4) // we need to have a small epsilon around 0 which is still ok
     1045            continue;
     1046          *out << Verbose(3) << "Projection of " << checker->second->node->Name
     1047              << " yields distance of " << distance << "." << endl;
     1048          tmp = distance / fabs(distance);
     1049          // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle)
     1050          if ((sign != 0) && (tmp != sign))
     1051            {
     1052              // 4c. If so, break 4. loop and continue with next candidate in 1. loop
     1053              *out << Verbose(2) << "Current candidates: "
     1054                  << A->second->node->Name << ","
     1055                  << baseline->second.first->second->node->Name << ","
     1056                  << baseline->second.second->second->node->Name << " leave "
     1057                  << checker->second->node->Name << " outside the convex hull."
     1058                  << endl;
     1059              break;
     1060            }
     1061          else
     1062            { // note the sign for later
     1063              *out << Verbose(2) << "Current candidates: "
     1064                  << A->second->node->Name << ","
     1065                  << baseline->second.first->second->node->Name << ","
     1066                  << baseline->second.second->second->node->Name << " leave "
     1067                  << checker->second->node->Name << " inside the convex hull."
     1068                  << endl;
     1069              sign = tmp;
     1070            }
     1071          // 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);
     1073          int innerpoint = 0;
     1074          if ((tmp < A->second->node->x.Distance(
     1075              &baseline->second.first->second->node->x)) && (tmp
     1076              < A->second->node->x.Distance(
     1077                  &baseline->second.second->second->node->x)))
     1078            innerpoint++;
     1079          tmp = checker->second->node->x.Distance(
     1080              &baseline->second.first->second->node->x);
     1081          if ((tmp < baseline->second.first->second->node->x.Distance(
     1082              &A->second->node->x)) && (tmp
     1083              < baseline->second.first->second->node->x.Distance(
     1084                  &baseline->second.second->second->node->x)))
     1085            innerpoint++;
     1086          tmp = checker->second->node->x.Distance(
     1087              &baseline->second.second->second->node->x);
     1088          if ((tmp < baseline->second.second->second->node->x.Distance(
     1089              &baseline->second.first->second->node->x)) && (tmp
     1090              < baseline->second.second->second->node->x.Distance(
     1091                  &A->second->node->x)))
     1092            innerpoint++;
     1093          // 4e. If so, break 4. loop and continue with next candidate in 1. loop
     1094          if (innerpoint == 3)
     1095            break;
     1096        }
     1097      // 5. come this far, all on same side? Then break 1. loop and construct triangle
     1098      if (checker == PointsOnBoundary.end())
     1099        {
     1100          *out << "Looks like we have a candidate!" << endl;
     1101          break;
     1102        }
     1103    }
     1104  if (baseline != DistanceMMap.end())
     1105    {
     1106      BPS[0] = baseline->second.first->second;
     1107      BPS[1] = baseline->second.second->second;
     1108      BLS[0] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     1109      BPS[0] = A->second;
     1110      BPS[1] = baseline->second.second->second;
     1111      BLS[1] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     1112      BPS[0] = baseline->second.first->second;
     1113      BPS[1] = A->second;
     1114      BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     1115
     1116      // 4b3. insert created triangle
     1117      BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     1118      TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
     1119      TrianglesOnBoundaryCount++;
     1120      for (int i = 0; i < NDIM; i++)
     1121        {
     1122          LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BTS->lines[i]));
     1123          LinesOnBoundaryCount++;
     1124        }
     1125
     1126      *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
     1127    }
     1128  else
     1129    {
     1130      *out << Verbose(1) << "No starting triangle found." << endl;
     1131      exit(255);
     1132    }
     1133}
     1134;
    8201135
    8211136/** Tesselates the convex envelope of a cluster from a single starting triangle.
     
    8321147 * \param *mol the cluster as a molecule structure
    8331148 */
    834 void Tesselation::TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol)
     1149void
     1150Tesselation::TesselateOnBoundary(ofstream *out, config *configuration,
     1151    molecule *mol)
    8351152{
    8361153  bool flag;
     
    8381155  class BoundaryPointSet *peak = NULL;
    8391156  double SmallestAngle, TempAngle;
    840   Vector NormalVector, VirtualNormalVector, CenterVector, TempVector, PropagationVector;
     1157  Vector NormalVector, VirtualNormalVector, CenterVector, TempVector,
     1158      PropagationVector;
    8411159  LineMap::iterator LineChecker[2];
    842   do {
    843     flag = false;
    844     for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++)
    845       if (baseline->second->TrianglesCount == 1) {
    846         *out << Verbose(2) << "Current baseline is between " << *(baseline->second) << "." << endl;
    847         // 5a. go through each boundary point if not _both_ edges between either endpoint of the current line and this point exist (and belong to 2 triangles)
    848         SmallestAngle = M_PI;
    849         BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far
    850         // get peak point with respect to this base line's only triangle
    851         for(int i=0;i<3;i++)
    852           if ((BTS->endpoints[i] != baseline->second->endpoints[0]) && (BTS->endpoints[i] != baseline->second->endpoints[1]))
    853             peak = BTS->endpoints[i];
    854         *out << Verbose(3) << " and has peak " << *peak << "." << endl;
    855         // normal vector of triangle
    856         BTS->GetNormalVector(NormalVector);
    857         *out << Verbose(4) << "NormalVector of base triangle is ";
    858         NormalVector.Output(out);
    859         *out << endl;
    860         // offset to center of triangle
    861         CenterVector.Zero();
    862         for(int i=0;i<3;i++)
    863           CenterVector.AddVector(&BTS->endpoints[i]->node->x);
    864         CenterVector.Scale(1./3.);
    865         *out << Verbose(4) << "CenterVector of base triangle is ";
    866         CenterVector.Output(out);
    867         *out << endl;
    868         // vector in propagation direction (out of triangle)
    869         // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
    870         TempVector.CopyVector(&baseline->second->endpoints[0]->node->x);
    871         TempVector.SubtractVector(&baseline->second->endpoints[1]->node->x);
    872         PropagationVector.MakeNormalVector(&TempVector, &NormalVector);
    873         TempVector.CopyVector(&CenterVector);
    874         TempVector.SubtractVector(&baseline->second->endpoints[0]->node->x);  // TempVector is vector on triangle plane pointing from one baseline egde towards center!
    875         //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;
    876         if (PropagationVector.Projection(&TempVector) > 0)  // make sure normal propagation vector points outward from baseline
    877           PropagationVector.Scale(-1.);
    878         *out << Verbose(4) << "PropagationVector of base triangle is ";
    879         PropagationVector.Output(out);
    880         *out << endl;
    881         winner = PointsOnBoundary.end();
    882         for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++)
    883           if ((target->second != baseline->second->endpoints[0]) && (target->second != baseline->second->endpoints[1])) { // don't take the same endpoints
    884             *out << Verbose(3) << "Target point is " << *(target->second) << ":";
    885             bool continueflag = true;
    886            
    887             VirtualNormalVector.CopyVector(&baseline->second->endpoints[0]->node->x);
    888             VirtualNormalVector.AddVector(&baseline->second->endpoints[0]->node->x);
    889             VirtualNormalVector.Scale(-1./2.);   // points now to center of base line
    890             VirtualNormalVector.AddVector(&target->second->node->x); // points from center of base line to target
    891             TempAngle = VirtualNormalVector.Angle(&PropagationVector);
    892             continueflag = continueflag && (TempAngle < (M_PI/2.)); // no bends bigger than Pi/2 (90 degrees)
    893             if (!continueflag) {
    894               *out << Verbose(4) << "Angle between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl;
    895               continue;
    896             } else
    897               *out << Verbose(4) << "Angle between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl;
    898             LineChecker[0] = baseline->second->endpoints[0]->lines.find(target->first);
    899             LineChecker[1] = baseline->second->endpoints[1]->lines.find(target->first);
    900   //            if (LineChecker[0] != baseline->second->endpoints[0]->lines.end())
    901   //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
    902   //            else
    903   //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has no line to " << *(target->second) << " as endpoint." << endl;
    904   //            if (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
    905   //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
    906   //            else
    907   //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has no line to " << *(target->second) << " as endpoint." << endl;
    908             // check first endpoint (if any connecting line goes to target or at least not more than 1)
    909             continueflag = continueflag && (( (LineChecker[0] == baseline->second->endpoints[0]->lines.end()) || (LineChecker[0]->second->TrianglesCount == 1)));
    910             if (!continueflag) {
    911               *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
    912               continue;
    913             }
    914             // check second endpoint (if any connecting line goes to target or at least not more than 1)
    915             continueflag = continueflag && (( (LineChecker[1] == baseline->second->endpoints[1]->lines.end()) || (LineChecker[1]->second->TrianglesCount == 1)));
    916             if (!continueflag) {
    917               *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
    918               continue;
    919             }
    920             // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint)
    921             continueflag = continueflag && (!(
    922                 ((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
    923                 && (GetCommonEndpoint(LineChecker[0]->second, LineChecker[1]->second) == peak))
    924                ));
    925             if (!continueflag) {
    926               *out << Verbose(4) << "Current target is peak!" << endl;
    927               continue;
    928             }
    929             // in case NOT both were found
    930             if (continueflag) {  // create virtually this triangle, get its normal vector, calculate angle
    931               flag = true;
    932               VirtualNormalVector.MakeNormalVector(&baseline->second->endpoints[0]->node->x, &baseline->second->endpoints[1]->node->x, &target->second->node->x);
    933               // make it always point inward
    934               if (baseline->second->endpoints[0]->node->x.Projection(&VirtualNormalVector) > 0)
    935                 VirtualNormalVector.Scale(-1.);
    936               // calculate angle
    937               TempAngle = NormalVector.Angle(&VirtualNormalVector);
    938               *out << Verbose(4) << "NormalVector is ";
    939               VirtualNormalVector.Output(out);
    940               *out << " and the angle is " << TempAngle << "." << endl;
    941               if (SmallestAngle > TempAngle) {  // set to new possible winner
    942                 SmallestAngle = TempAngle;
    943                 winner = target;
     1160  do
     1161    {
     1162      flag = false;
     1163      for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline
     1164          != LinesOnBoundary.end(); baseline++)
     1165        if (baseline->second->TrianglesCount == 1)
     1166          {
     1167            *out << Verbose(2) << "Current baseline is between "
     1168                << *(baseline->second) << "." << endl;
     1169            // 5a. go through each boundary point if not _both_ edges between either endpoint of the current line and this point exist (and belong to 2 triangles)
     1170            SmallestAngle = M_PI;
     1171            BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far
     1172            // get peak point with respect to this base line's only triangle
     1173            for (int i = 0; i < 3; i++)
     1174              if ((BTS->endpoints[i] != baseline->second->endpoints[0])
     1175                  && (BTS->endpoints[i] != baseline->second->endpoints[1]))
     1176                peak = BTS->endpoints[i];
     1177            *out << Verbose(3) << " and has peak " << *peak << "." << endl;
     1178            // normal vector of triangle
     1179            BTS->GetNormalVector(NormalVector);
     1180            *out << Verbose(4) << "NormalVector of base triangle is ";
     1181            NormalVector.Output(out);
     1182            *out << endl;
     1183            // offset to center of triangle
     1184            CenterVector.Zero();
     1185            for (int i = 0; i < 3; i++)
     1186              CenterVector.AddVector(&BTS->endpoints[i]->node->x);
     1187            CenterVector.Scale(1. / 3.);
     1188            *out << Verbose(4) << "CenterVector of base triangle is ";
     1189            CenterVector.Output(out);
     1190            *out << endl;
     1191            // vector in propagation direction (out of triangle)
     1192            // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
     1193            TempVector.CopyVector(&baseline->second->endpoints[0]->node->x);
     1194            TempVector.SubtractVector(&baseline->second->endpoints[1]->node->x);
     1195            PropagationVector.MakeNormalVector(&TempVector, &NormalVector);
     1196            TempVector.CopyVector(&CenterVector);
     1197            TempVector.SubtractVector(&baseline->second->endpoints[0]->node->x); // TempVector is vector on triangle plane pointing from one baseline egde towards center!
     1198            //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;
     1199            if (PropagationVector.Projection(&TempVector) > 0) // make sure normal propagation vector points outward from baseline
     1200              PropagationVector.Scale(-1.);
     1201            *out << Verbose(4) << "PropagationVector of base triangle is ";
     1202            PropagationVector.Output(out);
     1203            *out << endl;
     1204            winner = PointsOnBoundary.end();
     1205            for (PointMap::iterator target = PointsOnBoundary.begin(); target
     1206                != PointsOnBoundary.end(); target++)
     1207              if ((target->second != baseline->second->endpoints[0])
     1208                  && (target->second != baseline->second->endpoints[1]))
     1209                { // don't take the same endpoints
     1210                  *out << Verbose(3) << "Target point is " << *(target->second)
     1211                      << ":";
     1212                  bool continueflag = true;
     1213
     1214                  VirtualNormalVector.CopyVector(
     1215                      &baseline->second->endpoints[0]->node->x);
     1216                  VirtualNormalVector.AddVector(
     1217                      &baseline->second->endpoints[0]->node->x);
     1218                  VirtualNormalVector.Scale(-1. / 2.); // points now to center of base line
     1219                  VirtualNormalVector.AddVector(&target->second->node->x); // points from center of base line to target
     1220                  TempAngle = VirtualNormalVector.Angle(&PropagationVector);
     1221                  continueflag = continueflag && (TempAngle < (M_PI/2.)); // no bends bigger than Pi/2 (90 degrees)
     1222                  if (!continueflag)
     1223                    {
     1224                      *out << Verbose(4)
     1225                          << "Angle between propagation direction and base line to "
     1226                          << *(target->second) << " is " << TempAngle
     1227                          << ", bad direction!" << endl;
     1228                      continue;
     1229                    }
     1230                  else
     1231                    *out << Verbose(4)
     1232                        << "Angle between propagation direction and base line to "
     1233                        << *(target->second) << " is " << TempAngle
     1234                        << ", good direction!" << endl;
     1235                  LineChecker[0] = baseline->second->endpoints[0]->lines.find(
     1236                      target->first);
     1237                  LineChecker[1] = baseline->second->endpoints[1]->lines.find(
     1238                      target->first);
     1239                  //            if (LineChecker[0] != baseline->second->endpoints[0]->lines.end())
     1240                  //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
     1241                  //            else
     1242                  //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has no line to " << *(target->second) << " as endpoint." << endl;
     1243                  //            if (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
     1244                  //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
     1245                  //            else
     1246                  //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has no line to " << *(target->second) << " as endpoint." << endl;
     1247                  // check first endpoint (if any connecting line goes to target or at least not more than 1)
     1248                  continueflag = continueflag && (((LineChecker[0]
     1249                      == baseline->second->endpoints[0]->lines.end())
     1250                      || (LineChecker[0]->second->TrianglesCount == 1)));
     1251                  if (!continueflag)
     1252                    {
     1253                      *out << Verbose(4) << *(baseline->second->endpoints[0])
     1254                          << " has line " << *(LineChecker[0]->second)
     1255                          << " to " << *(target->second)
     1256                          << " as endpoint with "
     1257                          << LineChecker[0]->second->TrianglesCount
     1258                          << " triangles." << endl;
     1259                      continue;
     1260                    }
     1261                  // check second endpoint (if any connecting line goes to target or at least not more than 1)
     1262                  continueflag = continueflag && (((LineChecker[1]
     1263                      == baseline->second->endpoints[1]->lines.end())
     1264                      || (LineChecker[1]->second->TrianglesCount == 1)));
     1265                  if (!continueflag)
     1266                    {
     1267                      *out << Verbose(4) << *(baseline->second->endpoints[1])
     1268                          << " has line " << *(LineChecker[1]->second)
     1269                          << " to " << *(target->second)
     1270                          << " as endpoint with "
     1271                          << LineChecker[1]->second->TrianglesCount
     1272                          << " triangles." << endl;
     1273                      continue;
     1274                    }
     1275                  // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint)
     1276                  continueflag = continueflag && (!(((LineChecker[0]
     1277                      != baseline->second->endpoints[0]->lines.end())
     1278                      && (LineChecker[1]
     1279                          != baseline->second->endpoints[1]->lines.end())
     1280                      && (GetCommonEndpoint(LineChecker[0]->second,
     1281                          LineChecker[1]->second) == peak))));
     1282                  if (!continueflag)
     1283                    {
     1284                      *out << Verbose(4) << "Current target is peak!" << endl;
     1285                      continue;
     1286                    }
     1287                  // in case NOT both were found
     1288                  if (continueflag)
     1289                    { // create virtually this triangle, get its normal vector, calculate angle
     1290                      flag = true;
     1291                      VirtualNormalVector.MakeNormalVector(
     1292                          &baseline->second->endpoints[0]->node->x,
     1293                          &baseline->second->endpoints[1]->node->x,
     1294                          &target->second->node->x);
     1295                      // make it always point inward
     1296                      if (baseline->second->endpoints[0]->node->x.Projection(
     1297                          &VirtualNormalVector) > 0)
     1298                        VirtualNormalVector.Scale(-1.);
     1299                      // calculate angle
     1300                      TempAngle = NormalVector.Angle(&VirtualNormalVector);
     1301                      *out << Verbose(4) << "NormalVector is ";
     1302                      VirtualNormalVector.Output(out);
     1303                      *out << " and the angle is " << TempAngle << "." << endl;
     1304                      if (SmallestAngle > TempAngle)
     1305                        { // set to new possible winner
     1306                          SmallestAngle = TempAngle;
     1307                          winner = target;
     1308                        }
     1309                    }
     1310                }
     1311            // 5b. The point of the above whose triangle has the greatest angle with the triangle the current line belongs to (it only belongs to one, remember!): New triangle
     1312            if (winner != PointsOnBoundary.end())
     1313              {
     1314                *out << Verbose(2) << "Winning target point is "
     1315                    << *(winner->second) << " with angle " << SmallestAngle
     1316                    << "." << endl;
     1317                // create the lins of not yet present
     1318                BLS[0] = baseline->second;
     1319                // 5c. add lines to the line set if those were new (not yet part of a triangle), delete lines that belong to two triangles)
     1320                LineChecker[0] = baseline->second->endpoints[0]->lines.find(
     1321                    winner->first);
     1322                LineChecker[1] = baseline->second->endpoints[1]->lines.find(
     1323                    winner->first);
     1324                if (LineChecker[0]
     1325                    == baseline->second->endpoints[0]->lines.end())
     1326                  { // create
     1327                    BPS[0] = baseline->second->endpoints[0];
     1328                    BPS[1] = winner->second;
     1329                    BLS[1] = new class BoundaryLineSet(BPS,
     1330                        LinesOnBoundaryCount);
     1331                    LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount,
     1332                        BLS[1]));
     1333                    LinesOnBoundaryCount++;
     1334                  }
     1335                else
     1336                  BLS[1] = LineChecker[0]->second;
     1337                if (LineChecker[1]
     1338                    == baseline->second->endpoints[1]->lines.end())
     1339                  { // create
     1340                    BPS[0] = baseline->second->endpoints[1];
     1341                    BPS[1] = winner->second;
     1342                    BLS[2] = new class BoundaryLineSet(BPS,
     1343                        LinesOnBoundaryCount);
     1344                    LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount,
     1345                        BLS[2]));
     1346                    LinesOnBoundaryCount++;
     1347                  }
     1348                else
     1349                  BLS[2] = LineChecker[1]->second;
     1350                BTS = new class BoundaryTriangleSet(BLS,
     1351                    TrianglesOnBoundaryCount);
     1352                TrianglesOnBoundary.insert(TrianglePair(
     1353                    TrianglesOnBoundaryCount, BTS));
     1354                TrianglesOnBoundaryCount++;
    9441355              }
    945             }
     1356            else
     1357              {
     1358                *out << Verbose(1)
     1359                    << "I could not determine a winner for this baseline "
     1360                    << *(baseline->second) << "." << endl;
     1361              }
     1362
     1363            // 5d. If the set of lines is not yet empty, go to 5. and continue
    9461364          }
    947         // 5b. The point of the above whose triangle has the greatest angle with the triangle the current line belongs to (it only belongs to one, remember!): New triangle
    948         if (winner != PointsOnBoundary.end()) {
    949           *out << Verbose(2) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl;
    950           // create the lins of not yet present
    951           BLS[0] = baseline->second;
    952           // 5c. add lines to the line set if those were new (not yet part of a triangle), delete lines that belong to two triangles)
    953           LineChecker[0] = baseline->second->endpoints[0]->lines.find(winner->first);
    954           LineChecker[1] = baseline->second->endpoints[1]->lines.find(winner->first);
    955           if (LineChecker[0] == baseline->second->endpoints[0]->lines.end()) { // create
    956             BPS[0] = baseline->second->endpoints[0];
    957             BPS[1] = winner->second;
    958             BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    959             LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BLS[1]) );
    960             LinesOnBoundaryCount++;
    961           } else
    962             BLS[1] = LineChecker[0]->second;
    963           if (LineChecker[1] == baseline->second->endpoints[1]->lines.end()) { // create
    964             BPS[0] = baseline->second->endpoints[1];
    965             BPS[1] = winner->second;
    966             BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    967             LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BLS[2]) );
    968             LinesOnBoundaryCount++;
    969           } else
    970             BLS[2] = LineChecker[1]->second;
    971           BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    972           TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
    973           TrianglesOnBoundaryCount++;
    974         } else {
    975           *out << Verbose(1) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl;
    976         }
    977  
    978         // 5d. If the set of lines is not yet empty, go to 5. and continue
    979       } else
    980         *out << Verbose(2) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->TrianglesCount << "." << endl;
    981   } while (flag);
    982  
    983 };
     1365        else
     1366          *out << Verbose(2) << "Baseline candidate " << *(baseline->second)
     1367              << " has a triangle count of "
     1368              << baseline->second->TrianglesCount << "." << endl;
     1369    }
     1370  while (flag);
     1371
     1372}
     1373;
    9841374
    9851375/** Adds an atom to the tesselation::PointsOnBoundary list.
    9861376 * \param *Walker atom to add
    9871377 */
    988 void Tesselation::AddPoint(atom *Walker)
     1378void
     1379Tesselation::AddPoint(atom *Walker)
    9891380{
    9901381  PointTestPair InsertUnique;
    9911382  BPS[0] = new class BoundaryPointSet(Walker);
    992   InsertUnique = PointsOnBoundary.insert( PointPair(Walker->nr, BPS[0]) );
    993   if (InsertUnique.second)  // if new point was not present before, increase counter
     1383  InsertUnique = PointsOnBoundary.insert(PointPair(Walker->nr, BPS[0]));
     1384  if (InsertUnique.second) // if new point was not present before, increase counter
    9941385    PointsOnBoundaryCount++;
     1386}
     1387;
     1388
     1389/** Adds point to Tesselation::PointsOnBoundary if not yet present.
     1390 * Tesselation::TPS is set to either this new BoundaryPointSet or to the existing one of not unique.
     1391 * @param Candidate point to add
     1392 * @param n index for this point in Tesselation::TPS array
     1393 */
     1394void
     1395Tesselation::AddTrianglePoint(atom* Candidate, int n)
     1396{
     1397  PointTestPair InsertUnique;
     1398  TPS[n] = new class BoundaryPointSet(Candidate);
     1399  InsertUnique = PointsOnBoundary.insert(PointPair(Candidate->nr, TPS[n]));
     1400  if (InsertUnique.second) // if new point was not present before, increase counter
     1401    {
     1402      PointsOnBoundaryCount++;
     1403    }
     1404  else
     1405    {
     1406      delete TPS[n];
     1407      cout << Verbose(2) << "Atom " << *((InsertUnique.first)->second->node)
     1408          << " gibt's schon in der PointMap." << endl;
     1409      TPS[n] = (InsertUnique.first)->second;
     1410    }
     1411}
     1412;
     1413
     1414/** Function tries to add line from current Points in BPS to BoundaryLineSet.
     1415 * If succesful it raises the line count and inserts the new line into the BLS,
     1416 * if unsuccesful, it writes the line which had been present into the BLS, deleting the new constructed one.
     1417 * @param *a first endpoint
     1418 * @param *b second endpoint
     1419 * @param n index of Tesselation::BLS giving the line with both endpoints
     1420 */
     1421void
     1422Tesselation::AddTriangleLine(class BoundaryPointSet *a,
     1423    class BoundaryPointSet *b, int n)
     1424{
     1425  LineMap::iterator LineWalker;
     1426  //cout << "Manually checking endpoints for line." << endl;
     1427  if ((a->lines.find(b->node->nr)) != a->lines.end()) // ->first == b->node->nr)
     1428  //If a line is there, how do I recognize that beyond a shadow of a doubt?
     1429    {
     1430      //cout << Verbose(2) << "Line exists already, retrieving it from LinesOnBoundarySet" << endl;
     1431
     1432      LineWalker = LinesOnBoundary.end();
     1433      LineWalker--;
     1434
     1435      while (LineWalker->second->endpoints[0]->node->nr != min(a->node->nr,
     1436          b->node->nr) or LineWalker->second->endpoints[1]->node->nr != max(
     1437          a->node->nr, b->node->nr))
     1438        {
     1439          //cout << Verbose(1) << "Looking for line which already exists"<< endl;
     1440          LineWalker--;
     1441        }
     1442      BPS[0] = LineWalker->second->endpoints[0];
     1443      BPS[1] = LineWalker->second->endpoints[1];
     1444      BLS[n] = LineWalker->second;
     1445
     1446    }
     1447  else
     1448    {
     1449      cout << Verbose(2)
     1450          << "Adding line which has not been used before between "
     1451          << *(a->node) << " and " << *(b->node) << "." << endl;
     1452      BPS[0] = a;
     1453      BPS[1] = b;
     1454      BLS[n] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     1455
     1456      LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BLS[n]));
     1457      LinesOnBoundaryCount++;
     1458
     1459    }
     1460}
     1461;
     1462
     1463/** Function tries to add Triangle just created to Triangle and remarks if already existent (Failure of algorithm).
     1464 * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later.
     1465 */
     1466void
     1467Tesselation::AddTriangleToLines()
     1468{
     1469
     1470  cout << Verbose(1) << "Adding triangle to its lines" << endl;
     1471  int i = 0;
     1472  TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
     1473  TrianglesOnBoundaryCount++;
     1474
     1475  /*
     1476   * this is apparently done when constructing triangle
     1477
     1478   for (i=0; i<3; i++)
     1479   {
     1480   BLS[i]->AddTriangle(BTS);
     1481   }
     1482   */
     1483}
     1484;
     1485
     1486/**
     1487 * Function returns center of sphere with RADIUS, which rests on points a, b, c
     1488 * @param Center this vector will be used for return
     1489 * @param a vector first point of triangle
     1490 * @param b vector second point of triangle
     1491 * @param c vector third point of triangle
     1492 * @param *Umkreismittelpunkt new cneter point of circumference
     1493 * @param Direction vector indicates up/down
     1494 * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle
     1495 * @param Halfplaneindicator double indicates whether Direction is up or down
     1496 * @param AlternativeIndicator doube indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable
     1497 * @param alpha double angle at a
     1498 * @param beta double, angle at b
     1499 * @param gamma, double, angle at c
     1500 * @param Radius, double
     1501 * @param Umkreisradius double radius of circumscribing circle
     1502 */
     1503
     1504  void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,
     1505      double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius)
     1506  {
     1507    Vector TempNormal, helper;
     1508    double Restradius;
     1509    cout << Verbose(3) << "Begin of Get_center_of_sphere.\n";
     1510    Center->Zero();
     1511    helper.CopyVector(&a);
     1512    helper.Scale(sin(2.*alpha));
     1513    Center->AddVector(&helper);
     1514    helper.CopyVector(&b);
     1515    helper.Scale(sin(2.*beta));
     1516    Center->AddVector(&helper);
     1517    helper.CopyVector(&c);
     1518    helper.Scale(sin(2.*gamma));
     1519    Center->AddVector(&helper);
     1520    //*Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
     1521    Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
     1522    NewUmkreismittelpunkt->CopyVector(Center);
     1523    cout << Verbose(4) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n";
     1524    // Here we calculated center of circumscribing circle, using barycentric coordinates
     1525    cout << Verbose(4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n";
     1526
     1527    TempNormal.CopyVector(&a);
     1528    TempNormal.SubtractVector(&b);
     1529    helper.CopyVector(&a);
     1530    helper.SubtractVector(&c);
     1531    TempNormal.VectorProduct(&helper);
     1532    if (fabs(HalfplaneIndicator) < MYEPSILON)
     1533      {
     1534        if ((TempNormal.ScalarProduct(AlternativeDirection) <0 and AlternativeIndicator >0) or (TempNormal.ScalarProduct(AlternativeDirection) >0 and AlternativeIndicator <0))
     1535          {
     1536            TempNormal.Scale(-1);
     1537          }
     1538      }
     1539    else
     1540      {
     1541        if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0)
     1542          {
     1543            TempNormal.Scale(-1);
     1544          }
     1545      }
     1546
     1547    TempNormal.Normalize();
     1548    Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
     1549    cout << Verbose(4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n";
     1550    TempNormal.Scale(Restradius);
     1551    cout << Verbose(4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n";
     1552
     1553    Center->AddVector(&TempNormal);
     1554    cout << Verbose(4) << "Center of sphere of circumference is " << *Center << ".\n";
     1555    cout << Verbose(3) << "End of Get_center_of_sphere.\n";
     1556  }
     1557  ;
     1558
     1559
     1560/** This recursive function finds a third point, to form a triangle with two given ones.
     1561 * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
     1562 *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
     1563 *  upon which we operate.
     1564 *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \
     1565 *  direction and angle into Storage.
     1566 *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
     1567 *  with all neighbours of the candidate.
     1568 * @param a first point
     1569 * @param b second point
     1570 * *param c atom old third point of old triangle
     1571 * @param Candidate base point along whose bonds to start looking from
     1572 * @param Parent point to avoid during search as its wrong direction
     1573 * @param RecursionLevel contains current recursion depth
     1574 * @param Chord baseline vector of first and second point
     1575 * @param direction1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to
     1576 * @param OldNormal normal of the triangle which the baseline belongs to
     1577 * @param ReferencePoint Vector of center of circumscribing circle from which we look towards center of sphere
     1578 * @param Opt_Candidate candidate reference to return
     1579 * @param Storage array containing two angles of current Opt_Candidate
     1580 * @param RADIUS radius of ball
     1581 * @param mol molecule structure with atoms and bonds
     1582 */
     1583
     1584void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,
     1585    int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint,
     1586    atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol)
     1587{
     1588        cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1589        cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
     1590        cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
     1591        cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
     1592        cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
     1593        cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
     1594        /* OldNormal is normal vector on the old triangle
     1595         * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1596         * Chord points from b to a!!!
     1597         */
     1598        Vector dif_a; //Vector from a to candidate
     1599        Vector dif_b; //Vector from b to candidate
     1600        Vector AngleCheck;
     1601        Vector TempNormal, Umkreismittelpunkt;
     1602        Vector Mittelpunkt;
     1603
     1604        double CurrentEpsilon = 0.1;
     1605        double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
     1606        double BallAngle, AlternativeSign;
     1607        atom *Walker; // variable atom point
     1608
     1609        Vector NewUmkreismittelpunkt;
     1610
     1611        if (a != Candidate and b != Candidate and c != Candidate) {
     1612                cout << Verbose(3) << "We have a unique candidate!" << endl;
     1613                dif_a.CopyVector(&(a->x));
     1614                dif_a.SubtractVector(&(Candidate->x));
     1615                dif_b.CopyVector(&(b->x));
     1616                dif_b.SubtractVector(&(Candidate->x));
     1617                AngleCheck.CopyVector(&(Candidate->x));
     1618                AngleCheck.SubtractVector(&(a->x));
     1619                AngleCheck.ProjectOntoPlane(Chord);
     1620
     1621                SideA = dif_b.Norm();
     1622                SideB = dif_a.Norm();
     1623                SideC = Chord->Norm();
     1624                //Chord->Scale(-1);
     1625
     1626                alpha = Chord->Angle(&dif_a);
     1627                beta = M_PI - Chord->Angle(&dif_b);
     1628                gamma = dif_a.Angle(&dif_b);
     1629
     1630                cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     1631
     1632                if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {
     1633                        cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     1634                        cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     1635                }
     1636
     1637                if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
     1638                        Umkreisradius = SideA / 2.0 / sin(alpha);
     1639                        //cout << Umkreisradius << endl;
     1640                        //cout << SideB / 2.0 / sin(beta) << endl;
     1641                        //cout << SideC / 2.0 / sin(gamma) << endl;
     1642
     1643                        if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.
     1644                                cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
     1645                                cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
     1646                                sign = AngleCheck.ScalarProduct(direction1);
     1647                                if (fabs(sign)<MYEPSILON) {
     1648                                        if (AngleCheck.ScalarProduct(OldNormal)<0) {
     1649                                                sign =0;
     1650                                                AlternativeSign=1;
     1651                                        } else {
     1652                                                sign =0;
     1653                                                AlternativeSign=-1;
     1654                                        }
     1655                                } else {
     1656                                        sign /= fabs(sign);
     1657                                        cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
     1658                                }
     1659
     1660                                Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
     1661
     1662                                AngleCheck.CopyVector(&ReferencePoint);
     1663                                AngleCheck.Scale(-1);
     1664                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1665                                AngleCheck.AddVector(&Mittelpunkt);
     1666                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1667                                cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
     1668
     1669                                BallAngle = AngleCheck.Angle(OldNormal);
     1670                                cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
     1671
     1672                                //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
     1673                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1674
     1675                                cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
     1676
     1677                                NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
     1678
     1679                                if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
     1680                                        if (Storage[0]< -1.5) { // first Candidate at all
     1681                                                if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1682                                                        cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
     1683                                                        Opt_Candidate = Candidate;
     1684                                                        Storage[0] = sign;
     1685                                                        Storage[1] = AlternativeSign;
     1686                                                        Storage[2] = BallAngle;
     1687                                                        cout << " angle " << Storage[2] << " and Up/Down "
     1688                                                        << Storage[0] << endl;
     1689                                                } else
     1690                                                        cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1691                                        } else {
     1692                                                if ( Storage[2] > BallAngle) {
     1693                                                        if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1694                                                                cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
     1695                                                                Opt_Candidate = Candidate;
     1696                                                                Storage[0] = sign;
     1697                                                                Storage[1] = AlternativeSign;
     1698                                                                Storage[2] = BallAngle;
     1699                                                                cout << " angle " << Storage[2] << " and Up/Down "
     1700                                                                << Storage[0] << endl;
     1701                                                        } else
     1702                                                                cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1703                                                } else {
     1704                                                        if (DEBUG) {
     1705                                                                cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
     1706                                                        }
     1707                                                }
     1708                                        }
     1709                                } else {
     1710                                        if (DEBUG) {
     1711                                                cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
     1712                                        }
     1713                                }
     1714                        } else {
     1715                                if (DEBUG) {
     1716                                        cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
     1717                                }
     1718                        }
     1719                } else {
     1720                        if (DEBUG) {
     1721                                cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;
     1722                        }
     1723                }
     1724        } else {
     1725                if (DEBUG) {
     1726                        cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
     1727                }
     1728        }
     1729
     1730        if (RecursionLevel < 5) { // Seven is the recursion level threshold.
     1731                for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1732                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1733                        if (Walker == Parent) { // don't go back the same bond
     1734                                continue;
     1735                        } else {
     1736                                Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again
     1737                        }
     1738                }
     1739        }
     1740        cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1741}
     1742;
     1743
     1744
     1745  /** This recursive function finds a third point, to form a triangle with two given ones.
     1746   * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
     1747   *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
     1748   *  upon which we operate.
     1749   *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \
     1750   *  direction and angle into Storage.
     1751   *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
     1752   *  with all neighbours of the candidate.
     1753   * @param a first point
     1754   * @param b second point
     1755   * @param Candidate base point along whose bonds to start looking from
     1756   * @param Parent point to avoid during search as its wrong direction
     1757   * @param RecursionLevel contains current recursion depth
     1758   * @param Chord baseline vector of first and second point
     1759   * @param d1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to
     1760   * @param OldNormal normal of the triangle which the baseline belongs to
     1761   * @param Opt_Candidate candidate reference to return
     1762   * @param Opt_Mittelpunkt Centerpoint of ball, when resting on Opt_Candidate
     1763   * @param Storage array containing two angles of current Opt_Candidate
     1764   * @param RADIUS radius of ball
     1765   * @param mol molecule structure with atoms and bonds
     1766   */
     1767void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, atom* Parent,
     1768    int RecursionLevel, Vector *Chord, Vector *d1, Vector *OldNormal,
     1769    atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol)
     1770{
     1771        /* OldNormal is normal vector on the old triangle
     1772         * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1773         * Chord points from b to a!!!
     1774         */
     1775        Vector dif_a; //Vector from a to candidate
     1776        Vector dif_b; //Vector from b to candidate
     1777        Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
     1778        Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
     1779
     1780        double CurrentEpsilon = 0.1;
     1781        double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
     1782        double BallAngle;
     1783        atom *Walker; // variable atom point
     1784
     1785
     1786        dif_a.CopyVector(&(a->x));
     1787        dif_a.SubtractVector(&(Candidate->x));
     1788        dif_b.CopyVector(&(b->x));
     1789        dif_b.SubtractVector(&(Candidate->x));
     1790        DirectionCheckPoint.CopyVector(&dif_a);
     1791        DirectionCheckPoint.Scale(-1);
     1792        DirectionCheckPoint.ProjectOntoPlane(Chord);
     1793
     1794        SideA = dif_b.Norm();
     1795        SideB = dif_a.Norm();
     1796        SideC = Chord->Norm();
     1797        //Chord->Scale(-1);
     1798
     1799        alpha = Chord->Angle(&dif_a);
     1800        beta = M_PI - Chord->Angle(&dif_b);
     1801        gamma = dif_a.Angle(&dif_b);
     1802
     1803
     1804        if (DEBUG) {
     1805                cout << "Atom number" << Candidate->nr << endl;
     1806                Candidate->x.Output((ofstream *) &cout);
     1807                cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
     1808        }
     1809
     1810        if (a != Candidate and b != Candidate) {
     1811                //      alpha = dif_a.Angle(&dif_b) / 2.;
     1812                //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
     1813                //      SideB = dif_a.Norm();
     1814                //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
     1815                //          alpha); // note this is squared of center line length
     1816                //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
     1817                // Those are remains from Freddie. Needed?
     1818
     1819                Umkreisradius = SideA / 2.0 / sin(alpha);
     1820                //cout << Umkreisradius << endl;
     1821                //cout << SideB / 2.0 / sin(beta) << endl;
     1822                //cout << SideC / 2.0 / sin(gamma) << endl;
     1823
     1824                if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
     1825                        // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
     1826                        Umkreismittelpunkt.Zero();
     1827                        helper.CopyVector(&a->x);
     1828                        helper.Scale(sin(2.*alpha));
     1829                        Umkreismittelpunkt.AddVector(&helper);
     1830                        helper.CopyVector(&b->x);
     1831                        helper.Scale(sin(2.*beta));
     1832                        Umkreismittelpunkt.AddVector(&helper);
     1833                        helper.CopyVector(&Candidate->x);
     1834                        helper.Scale(sin(2.*gamma));
     1835                        Umkreismittelpunkt.AddVector(&helper);
     1836                        //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
     1837                        Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     1838
     1839                        TempNormal.CopyVector(&dif_a);
     1840                        TempNormal.VectorProduct(&dif_b);
     1841                        if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
     1842                                TempNormal.Scale(-1);
     1843                        }
     1844                        TempNormal.Normalize();
     1845                        Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
     1846                        TempNormal.Scale(Restradius);
     1847
     1848                        Mittelpunkt.CopyVector(&Umkreismittelpunkt);
     1849                        Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
     1850
     1851                        AngleCheck.CopyVector(Chord);
     1852                        AngleCheck.Scale(-0.5);
     1853                        AngleCheck.SubtractVector(&(b->x));
     1854                        AngleCheckReference.CopyVector(&AngleCheck);
     1855                        AngleCheckReference.AddVector(Opt_Mittelpunkt);
     1856                        AngleCheck.AddVector(&Mittelpunkt);
     1857
     1858                        BallAngle = AngleCheck.Angle(&AngleCheckReference);
     1859
     1860                        d1->ProjectOntoPlane(&AngleCheckReference);
     1861                        sign = AngleCheck.ScalarProduct(d1);
     1862                        if (fabs(sign) < MYEPSILON)
     1863                                sign = 0;
     1864                        else
     1865                                sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
     1866
     1867
     1868                        if (Storage[0]< -1.5) { // first Candidate at all
     1869                                cout << "Next better candidate is " << *Candidate << " with ";
     1870                                Opt_Candidate = Candidate;
     1871                                Storage[0] = sign;
     1872                                Storage[1] = BallAngle;
     1873                                Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1874                                cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1875                        } else {
     1876                                /*
     1877                                 * removed due to change in criterium, now checking angle of ball to old normal.
     1878                                //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
     1879                                //within the ball.
     1880
     1881                                Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
     1882                                //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
     1883
     1884
     1885                                if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
     1886                                 */
     1887                                        //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
     1888
     1889                                if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
     1890                                        //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
     1891                                        cout << "Next better candidate is " << *Candidate << " with ";
     1892                                        Opt_Candidate = Candidate;
     1893                                        Storage[0] = sign;
     1894                                        Storage[1] = BallAngle;
     1895                                        Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1896                                        cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1897                                } else {
     1898                                        if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
     1899                                                //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
     1900                                                cout << "Next better candidate is " << *Candidate << " with ";
     1901                                                Opt_Candidate = Candidate;
     1902                                                Storage[0] = sign;
     1903                                                Storage[1] = BallAngle;
     1904                                                Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1905                                                cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1906                                        }
     1907                                }
     1908                        }
     1909/*
     1910               * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle.
     1911               *
     1912                else
     1913                {
     1914                  if (sign>0 && BallAngle>0 && Storage[0]<0)
     1915                    {
     1916                      cout << "Next better candidate is " << *Candidate << " with ";
     1917                      Opt_Candidate = Candidate;
     1918                      Storage[0] = sign;
     1919                      Storage[1] = BallAngle;
     1920                      Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1921                      cout << "Angle is " << Storage[1] << ", Halbraum ist "
     1922                      << Storage[0] << endl;
     1923
     1924//Debugging purposes only
     1925                      cout << "Umkreismittelpunkt has coordinates" << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] <<" "<<Umkreismittelpunkt.x[2] << endl;
     1926                      cout << "Candidate has coordinates" << Candidate->x.x[0]<< " " << Candidate->x.x[1] << " " << Candidate->x.x[2] << endl;
     1927                      cout << "a has coordinates" << a->x.x[0]<< " " << a->x.x[1] << " " << a->x.x[2] << endl;
     1928                      cout << "b has coordinates" << b->x.x[0]<< " " << b->x.x[1] << " " << b->x.x[2] << endl;
     1929                      cout << "Mittelpunkt has coordinates" << Mittelpunkt.x[0] << " " << Mittelpunkt.x[1]<< " "  <<Mittelpunkt.x[2] << endl;
     1930                      cout << "Umkreisradius ist " << Umkreisradius << endl;
     1931                      cout << "Restradius ist " << Restradius << endl;
     1932                      cout << "TempNormal has coordinates " << TempNormal.x[0] << " " << TempNormal.x[1] << " " << TempNormal.x[2] << " " << endl;
     1933                      cout << "OldNormal has coordinates " << OldNormal->x[0] << " " << OldNormal->x[1] << " " << OldNormal->x[2] << " " << endl;
     1934                      cout << "Dist a to UmkreisMittelpunkt " << a->x.Distance(&Umkreismittelpunkt) << endl;
     1935                      cout << "Dist b to UmkreisMittelpunkt " << b->x.Distance(&Umkreismittelpunkt) << endl;
     1936                      cout << "Dist Candidate to UmkreisMittelpunkt " << Candidate->x.Distance(&Umkreismittelpunkt) << endl;
     1937                      cout << "Dist a to Mittelpunkt " << a->x.Distance(&Mittelpunkt) << endl;
     1938                      cout << "Dist b to Mittelpunkt " << b->x.Distance(&Mittelpunkt) << endl;
     1939                      cout << "Dist Candidate to Mittelpunkt " << Candidate->x.Distance(&Mittelpunkt) << endl;
     1940
     1941
     1942
     1943                    }
     1944                  else
     1945                    {
     1946                      if (DEBUG)
     1947                        cout << "Looses to better candidate" << endl;
     1948                    }
     1949                }
     1950                */
     1951                } else {
     1952                        if (DEBUG) {
     1953                                cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
     1954                        }
     1955                }
     1956        } else {
     1957                if (DEBUG) {
     1958                        cout << "identisch mit Ursprungslinie" << endl;
     1959                }
     1960        }
     1961
     1962        if (RecursionLevel < 9) { // Five is the recursion level threshold.
     1963                for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1964                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1965                        if (Walker == Parent) { // don't go back the same bond
     1966                                continue;
     1967                        } else {
     1968                                Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
     1969                        }
     1970                }
     1971        }
    9951972};
     1973
     1974/** This function finds a triangle to a line, adjacent to an existing one.
     1975 * @param out   output stream for debugging
     1976 * @param tecplot output stream for writing found triangles in TecPlot format
     1977 * @param mol molecule structure with all atoms and bonds
     1978 * @param Line current baseline to search from
     1979 * @param T current triangle which \a Line is edge of
     1980 * @param RADIUS radius of the rolling ball
     1981 * @param N number of found triangles
     1982 * @param *filename filename base for intermediate envelopes
     1983 */
     1984bool Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,
     1985    molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T,
     1986    const double& RADIUS, int N, const char *tempbasename)
     1987{
     1988        cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
     1989        Vector direction1;
     1990        Vector helper;
     1991        Vector Chord;
     1992        ofstream *tempstream = NULL;
     1993        char NumberName[255];
     1994        double tmp;
     1995        //atom* Walker;
     1996        atom* OldThirdPoint;
     1997
     1998        double Storage[3];
     1999        Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
     2000        Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
     2001        Storage[2] = 9999999.;
     2002        atom* Opt_Candidate = NULL;
     2003        Vector Opt_Mittelpunkt;
     2004
     2005        cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
     2006
     2007        helper.CopyVector(&(Line.endpoints[0]->node->x));
     2008        for (int i = 0; i < 3; i++) {
     2009                if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
     2010                        OldThirdPoint = T.endpoints[i]->node;
     2011                        helper.SubtractVector(&T.endpoints[i]->node->x);
     2012                        break;
     2013                }
     2014        }
     2015
     2016        direction1.CopyVector(&Line.endpoints[0]->node->x);
     2017        direction1.SubtractVector(&Line.endpoints[1]->node->x);
     2018        direction1.VectorProduct(&(T.NormalVector));
     2019
     2020        if (direction1.ScalarProduct(&helper) < 0) {
     2021                direction1.Scale(-1);
     2022        }
     2023        cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
     2024
     2025        Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
     2026        Chord.SubtractVector(&(Line.endpoints[1]->node->x));
     2027        cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
     2028
     2029
     2030        Vector Umkreismittelpunkt, a, b, c;
     2031        double alpha, beta, gamma;
     2032        a.CopyVector(&(T.endpoints[0]->node->x));
     2033        b.CopyVector(&(T.endpoints[1]->node->x));
     2034        c.CopyVector(&(T.endpoints[2]->node->x));
     2035        a.SubtractVector(&(T.endpoints[1]->node->x));
     2036        b.SubtractVector(&(T.endpoints[2]->node->x));
     2037        c.SubtractVector(&(T.endpoints[0]->node->x));
     2038
     2039        alpha = M_PI - a.Angle(&c);
     2040        beta = M_PI - b.Angle(&a);
     2041        gamma = M_PI - c.Angle(&b);
     2042        if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
     2043                cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     2044
     2045        Umkreismittelpunkt.Zero();
     2046        helper.CopyVector(&T.endpoints[0]->node->x);
     2047        helper.Scale(sin(2.*alpha));
     2048        Umkreismittelpunkt.AddVector(&helper);
     2049        helper.CopyVector(&T.endpoints[1]->node->x);
     2050        helper.Scale(sin(2.*beta));
     2051        Umkreismittelpunkt.AddVector(&helper);
     2052        helper.CopyVector(&T.endpoints[2]->node->x);
     2053        helper.Scale(sin(2.*gamma));
     2054        Umkreismittelpunkt.AddVector(&helper);
     2055        //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) ;
     2056        //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2057        Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     2058        //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2059        cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
     2060        cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
     2061
     2062        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;
     2063        cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
     2064        if (DEBUG)
     2065                cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
     2066        tmp = 0;
     2067        for (int i=0;i<NDIM;i++) {
     2068                helper.CopyVector(&T.endpoints[i]->node->x);
     2069                helper.SubtractVector(&Umkreismittelpunkt);
     2070                if (DEBUG)
     2071                        cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
     2072                if (tmp == 0) // set on first time for comparison against next ones
     2073                        tmp = helper.Norm();
     2074                if (fabs(helper.Norm() - tmp) > MYEPSILON)
     2075                        cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
     2076        }
     2077
     2078        cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
     2079
     2080        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);
     2081        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);
     2082        if (Opt_Candidate == NULL) {
     2083                cerr << "WARNING: Could not find a suitable candidate." << endl;
     2084                return false;
     2085        }
     2086        cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
     2087
     2088        // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
     2089        bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
     2090
     2091        if (flag) { // if so, add
     2092                AddTrianglePoint(Opt_Candidate, 0);
     2093                AddTrianglePoint(Line.endpoints[0]->node, 1);
     2094                AddTrianglePoint(Line.endpoints[1]->node, 2);
     2095
     2096                AddTriangleLine(TPS[0], TPS[1], 0);
     2097                AddTriangleLine(TPS[0], TPS[2], 1);
     2098                AddTriangleLine(TPS[1], TPS[2], 2);
     2099
     2100                BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2101                AddTriangleToLines();
     2102
     2103                BTS->GetNormalVector(BTS->NormalVector);
     2104
     2105                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) ) {
     2106                        BTS->NormalVector.Scale(-1);
     2107                };
     2108                cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
     2109                cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
     2110        } else { // else, yell and do nothing
     2111                cout << Verbose(1) << "This triangle consisting of ";
     2112                cout << *Opt_Candidate << ", ";
     2113                cout << *Line.endpoints[0]->node << " and ";
     2114                cout << *Line.endpoints[1]->node << " ";
     2115                cout << "is invalid!" << endl;
     2116                return false;
     2117        }
     2118
     2119        if ((TrianglesOnBoundaryCount % 10) == 0) {
     2120                sprintf(NumberName, "-%d", TriangleFilesWritten);
     2121                if (DoTecplotOutput) {
     2122                        string NameofTempFile(tempbasename);
     2123                        NameofTempFile.append(NumberName);
     2124                        NameofTempFile.append(TecplotSuffix);
     2125                        cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2126                        tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2127                        write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
     2128                        tempstream->close();
     2129                        tempstream->flush();
     2130                        delete(tempstream);
     2131                }
     2132
     2133                if (DoRaster3DOutput) {
     2134                        string NameofTempFile(tempbasename);
     2135                        NameofTempFile.append(NumberName);
     2136                        NameofTempFile.append(Raster3DSuffix);
     2137                        cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2138                        tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2139                        write_raster3d_file(out, tempstream, this, mol);
     2140                        tempstream->close();
     2141                        tempstream->flush();
     2142                        delete(tempstream);
     2143                }
     2144                if (DoTecplotOutput || DoRaster3DOutput)
     2145                        TriangleFilesWritten++;
     2146        }
     2147
     2148        cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
     2149        return true;
     2150};
     2151
     2152/** Checks whether the triangle consisting of the three atoms is already present.
     2153 * Searches for the points in Tesselation::PointsOnBoundary and checks their
     2154 * lines. If any of the three edges already has two triangles attached, false is
     2155 * returned.
     2156 * \param *out output stream for debugging
     2157 * \param *a first endpoint
     2158 * \param *b second endpoint
     2159 * \param *c third endpoint
     2160 * \return false - triangle invalid due to edge criteria, true - triangle may be added.
     2161 */
     2162bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) {
     2163        LineMap::iterator TryAndError;
     2164        PointTestPair InsertPoint;
     2165        bool Present[3];
     2166
     2167        *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;
     2168        TPS[0] = new class BoundaryPointSet(a);
     2169        TPS[1] = new class BoundaryPointSet(b);
     2170        TPS[2] = new class BoundaryPointSet(c);
     2171        for (int i=0;i<3;i++) { // check through all endpoints
     2172                InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));
     2173                Present[i] = !InsertPoint.second;
     2174                if (Present[i]) { // if new point was not present before, increase counter
     2175                        delete TPS[i];
     2176                        *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;
     2177                        TPS[i] = (InsertPoint.first)->second;
     2178                }
     2179        }
     2180
     2181        // check lines
     2182        for (int i=0;i<3;i++)
     2183                if (Present[i])
     2184                        for (int j=i;j<3;j++)
     2185                                if (Present[j]) {
     2186                                        TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);
     2187                                        if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {
     2188                                                *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;
     2189                                                *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2190                                                return false;
     2191                                        }
     2192                                }
     2193        *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2194        return true;
     2195};
     2196
     2197
     2198void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent,
     2199    int RecursionLevel, Vector Oben, atom*& Opt_Candidate, double Storage[3],
     2200    molecule* mol, double RADIUS)
     2201{
     2202        cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2203        int i;
     2204        Vector AngleCheck;
     2205        atom* Walker;
     2206        double norm = -1., angle;
     2207
     2208        // check if we only have one unique point yet ...
     2209        if (a != Candidate) {
     2210                cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
     2211                AngleCheck.CopyVector(&(Candidate->x));
     2212                AngleCheck.SubtractVector(&(a->x));
     2213                norm = AngleCheck.Norm();
     2214                // second point shall have smallest angle with respect to Oben vector
     2215                if (norm < RADIUS) {
     2216                        angle = AngleCheck.Angle(&Oben);
     2217                        if (angle < Storage[0]) {
     2218                                //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
     2219                                cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
     2220                                Opt_Candidate = Candidate;
     2221                                Storage[0] = AngleCheck.Angle(&Oben);
     2222                                //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
     2223                        } else {
     2224                                cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
     2225                        }
     2226                } else {
     2227                        cout << "Refused due to Radius " << norm << endl;
     2228                }
     2229        }
     2230
     2231        // if not recursed to deeply, look at all its bonds
     2232        if (RecursionLevel < 7) {
     2233                for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
     2234                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     2235                        if (Walker == Parent) // don't go back along the bond we came from
     2236                                continue;
     2237                        else
     2238                                Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
     2239                }
     2240        }
     2241        cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2242};
     2243
     2244void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
     2245{
     2246        cout << Verbose(1) << "Begin of Find_starting_triangle\n";
     2247        int i = 0;
     2248        atom* Walker;
     2249        atom* FirstPoint;
     2250        atom* SecondPoint;
     2251        atom* max_index[NDIM];
     2252        double max_coordinate[NDIM];
     2253        Vector Oben;
     2254        Vector helper;
     2255        Vector Chord;
     2256        Vector CenterOfFirstLine;
     2257
     2258        Oben.Zero();
     2259
     2260        for (i = 0; i < 3; i++) {
     2261                max_index[i] = NULL;
     2262                max_coordinate[i] = -1;
     2263        }
     2264        cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
     2265
     2266        // 1. searching topmost atom with respect to each axis
     2267        Walker = mol->start;
     2268        while (Walker->next != mol->end) {
     2269                Walker = Walker->next;
     2270                for (i = 0; i < 3; i++) {
     2271                        if (Walker->x.x[i] > max_coordinate[i]) {
     2272                                max_coordinate[i] = Walker->x.x[i];
     2273                                max_index[i] = Walker;
     2274                        }
     2275                }
     2276        }
     2277
     2278        cout << Verbose(2) << "Found maximum coordinates: ";
     2279        for (int i=0;i<NDIM;i++)
     2280                cout << i << ": " << *max_index[i] << "\t";
     2281        cout << endl;
     2282  //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
     2283        const int k = 1;
     2284        Oben.x[k] = 1.;
     2285        FirstPoint = max_index[k];
     2286
     2287        cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
     2288        double Storage[3];
     2289        atom* Opt_Candidate = NULL;
     2290        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.
     2291        Storage[1] = 999999.; // This will be an angle looking for the third point.
     2292        Storage[2] = 999999.;
     2293
     2294        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_...
     2295        SecondPoint = Opt_Candidate;
     2296        cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
     2297
     2298        helper.CopyVector(&(FirstPoint->x));
     2299        helper.SubtractVector(&(SecondPoint->x));
     2300        helper.Normalize();
     2301        Oben.ProjectOntoPlane(&helper);
     2302        Oben.Normalize();
     2303        helper.VectorProduct(&Oben);
     2304        Storage[0] = -2.; // This will indicate the quadrant.
     2305        Storage[1] = 9999999.; // This will be an angle looking for the third point.
     2306        Storage[2] = 9999999.;
     2307
     2308        Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
     2309        Chord.SubtractVector(&(SecondPoint->x));
     2310        // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
     2311
     2312        cout << Verbose(2) << "Looking for third point candidates \n";
     2313        // look in one direction of baseline for initial candidate
     2314        Opt_Candidate = NULL;
     2315        CenterOfFirstLine.CopyVector(&Chord);
     2316        CenterOfFirstLine.Scale(0.5);
     2317        CenterOfFirstLine.AddVector(&(SecondPoint->x));
     2318
     2319        cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
     2320        Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
     2321        // look in other direction of baseline for possible better candidate
     2322        cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
     2323        Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
     2324        cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
     2325
     2326        // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
     2327
     2328        // Finally, we only have to add the found points
     2329        AddTrianglePoint(FirstPoint, 0);
     2330        AddTrianglePoint(SecondPoint, 1);
     2331        AddTrianglePoint(Opt_Candidate, 2);
     2332        // ... and respective lines
     2333        AddTriangleLine(TPS[0], TPS[1], 0);
     2334        AddTriangleLine(TPS[1], TPS[2], 1);
     2335        AddTriangleLine(TPS[0], TPS[2], 2);
     2336        // ... and triangles to the Maps of the Tesselation class
     2337        BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2338        AddTriangleToLines();
     2339        // ... and calculate its normal vector (with correct orientation)
     2340        Oben.Scale(-1.);
     2341        BTS->GetNormalVector(Oben);
     2342        cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
     2343        cout << Verbose(1) << "End of Find_starting_triangle\n";
     2344};
     2345
     2346void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS)
     2347{
     2348        int N = 0;
     2349        struct Tesselation *Tess = new Tesselation;
     2350        cout << Verbose(1) << "Entering search for non convex hull. " << endl;
     2351        cout << flush;
     2352        LineMap::iterator baseline;
     2353        cout << Verbose(0) << "Begin of Find_non_convex_border\n";
     2354        bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
     2355        bool failflag = false;
     2356        if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
     2357                mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
     2358
     2359        Tess->Find_starting_triangle(mol, RADIUS);
     2360
     2361        baseline = Tess->LinesOnBoundary.begin();
     2362        while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
     2363                if (baseline->second->TrianglesCount == 1) {
     2364                        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.
     2365                        flag = flag || failflag;
     2366                        if (!failflag)
     2367                                cerr << "WARNING: Find_next_suitable_triangle failed." << endl;
     2368                } else {
     2369                        cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;
     2370                }
     2371                N++;
     2372                baseline++;
     2373                if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
     2374                        baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
     2375                        flag = false;
     2376                }
     2377        }
     2378        if (failflag) {
     2379                cout << Verbose(1) << "Writing final tecplot file\n";
     2380                if (DoTecplotOutput)
     2381                        write_tecplot_file(out, tecplot, Tess, mol, -1);
     2382                if (DoRaster3DOutput)
     2383                        write_raster3d_file(out, tecplot, Tess, mol);
     2384        } else {
     2385                cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
     2386        }
     2387
     2388        cout << Verbose(0) << "End of Find_non_convex_border\n";
     2389        delete(Tess);
     2390};
     2391
  • TabularUnified src/boundary.hpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    3636    BoundaryPointSet(atom *Walker);
    3737    ~BoundaryPointSet();
    38    
     38
    3939    void AddLine(class BoundaryLineSet *line);
    40    
     40
    4141    LineMap lines;
    4242    int LinesCount;
     
    6464    BoundaryTriangleSet(class BoundaryLineSet *line[3], int number);
    6565    ~BoundaryTriangleSet();
    66    
     66
    6767    void GetNormalVector(Vector &NormalVector);
    68    
     68
    6969    class BoundaryPointSet *endpoints[3];
    7070    class BoundaryLineSet *lines[3];
     71    Vector NormalVector;
    7172    int Nr;
    7273};
     
    7475class Tesselation {
    7576  public:
    76    
     77
    7778    Tesselation();
    7879    ~Tesselation();
    79    
     80
    8081    void TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol);
    8182    void GuessStartingTriangle(ofstream *out);
    8283    void AddPoint(atom * Walker);
    83    
     84    void AddTrianglePoint(atom* Candidate, int n);
     85    void AddTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);
     86    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);
     89    bool CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c);
     90    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);
     91
    8492    PointMap PointsOnBoundary;
    8593    LineMap LinesOnBoundary;
    8694    TriangleMap TrianglesOnBoundary;
     95    class BoundaryPointSet *TPS[3]; //this is a Storage for pointers to triangle points, this and BPS[2] needed due to AddLine restrictions
    8796    class BoundaryPointSet *BPS[2];
    8897    class BoundaryLineSet *BLS[3];
     
    91100    int LinesOnBoundaryCount;
    92101    int TrianglesOnBoundaryCount;
     102    int TriangleFilesWritten;
    93103};
    94104
     
    102112double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    103113void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
     114void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS);
     115void 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);
    104116
    105117
  • TabularUnified src/builder.cpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    11/** \file builder.cpp
    2  * 
     2 *
    33 * By stating absolute positions or binding angles and distances atomic positions of a molecule can be constructed.
    44 * The output is the complete configuration file for PCP for direct use.
     
    66 * -# Atomic data is retrieved from a file, if not found requested and stored there for later re-use
    77 * -# step-by-step construction of the molecule beginning either at a centre of with a certain atom
    8  *   
     8 *
    99 */
    1010
    1111/*! \mainpage Molecuilder - a molecular set builder
    12  * 
     12 *
    1313 * This introductory shall briefly make aquainted with the program, helping in installing and a first run.
    14  * 
     14 *
    1515 * \section about About the Program
    16  * 
     16 *
    1717 *  Molecuilder is a short program, written in C++, that enables the construction of a coordinate set for the
    1818 *  atoms making up an molecule by the successive statement of binding angles and distances and referencing to
    1919 *  already constructed atoms.
    20  * 
     20 *
    2121 *  A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
    2222 *  molecular dynamics implementation.
    23  * 
     23 *
    2424 * \section install Installation
    25  * 
     25 *
    2626 *  Installation should without problems succeed as follows:
    2727 *  -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run)
    2828 *  -# make
    2929 *  -# make install
    30  * 
     30 *
    3131 *  Further useful commands are
    3232 *  -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n
    33  *  -# make doxygen-doc: Creates these html pages out of the documented source 
    34  * 
     33 *  -# make doxygen-doc: Creates these html pages out of the documented source
     34 *
    3535 * \section run Running
    36  * 
     36 *
    3737 *  The program can be executed by running: ./molecuilder
    38  * 
     38 *
    3939 *  Note, that it uses a database, called "elements.db", in the executable's directory. If the file is not found,
    4040 *  it is created and any given data on elements of the periodic table will be stored therein and re-used on
    41  *  later re-execution. 
    42  * 
     41 *  later re-execution.
     42 *
    4343 * \section ref References
    44  * 
     44 *
    4545 *  For the special configuration file format, see the documentation of pcp.
    46  * 
     46 *
    4747 */
    4848
     
    8080  cout << Verbose(0) << "INPUT: ";
    8181  cin >> choice;
    82  
     82
    8383  switch (choice) {
    8484      case 'a': // absolute coordinates of atom
     
    8989        mol->AddAtom(first);  // add to molecule
    9090        break;
    91        
     91
    9292      case 'b': // relative coordinates of atom wrt to reference point
    9393        first = new atom;
     
    105105        mol->AddAtom(first);  // add to molecule
    106106        break;
    107        
     107
    108108      case 'c': // relative coordinates of atom wrt to already placed atom
    109109        first = new atom;
     
    111111        do {
    112112          if (!valid) cout << Verbose(0) << "Resulting position out of cell." << endl;
    113           second = mol->AskAtom("Enter atom number: ");               
     113          second = mol->AskAtom("Enter atom number: ");
    114114          cout << Verbose(0) << "Enter relative coordinates." << endl;
    115115          first->x.AskPosition(mol->cell_size, false);
     
    121121        mol->AddAtom(first);  // add to molecule
    122122        break;
    123      
     123
    124124      case 'd': // two atoms, two angles and a distance
    125125        first = new atom;
     
    152152          x.Copyvector(&fourth->x);
    153153          x.SubtractVector(&third->x);
    154          
     154
    155155          if (!z.SolveSystem(&x,&y,&n, b, c, a)) {
    156156            cout << Verbose(0) << "Failure solving self-dependent linear system!" << endl;
     
    167167          cout << "x: ",
    168168          x.Output((ofstream *)&cout);
    169           cout << endl;         
     169          cout << endl;
    170170          z.MakeNormalVector(&second->x,&third->x,&fourth->x);
    171171          cout << "z: ",
    172172          z.Output((ofstream *)&cout);
    173           cout << endl;         
     173          cout << endl;
    174174          y.MakeNormalVector(&x,&z);
    175175          cout << "y: ",
    176176          y.Output((ofstream *)&cout);
    177           cout << endl;         
    178          
     177          cout << endl;
     178
    179179          // rotate vector around first angle
    180180          first->x.CopyVector(&x);
     
    182182          cout << "Rotated vector: ",
    183183          first->x.Output((ofstream *)&cout);
    184           cout << endl;         
     184          cout << endl;
    185185          // remove the projection onto the rotation plane of the second angle
    186186          n.CopyVector(&y);
     
    188188          cout << "N1: ",
    189189          n.Output((ofstream *)&cout);
    190           cout << endl;         
     190          cout << endl;
    191191          first->x.SubtractVector(&n);
    192192          cout << "Subtracted vector: ",
    193193          first->x.Output((ofstream *)&cout);
    194           cout << endl;         
     194          cout << endl;
    195195          n.CopyVector(&z);
    196196          n.Scale(first->x.Projection(&z));
    197197          cout << "N2: ",
    198198          n.Output((ofstream *)&cout);
    199           cout << endl;         
     199          cout << endl;
    200200          first->x.SubtractVector(&n);
    201201          cout << "2nd subtracted vector: ",
    202202          first->x.Output((ofstream *)&cout);
    203           cout << endl;         
    204          
     203          cout << endl;
     204
    205205          // rotate another vector around second angle
    206206          n.CopyVector(&y);
     
    208208          cout << "2nd Rotated vector: ",
    209209          n.Output((ofstream *)&cout);
    210           cout << endl;         
    211          
     210          cout << endl;
     211
    212212          // add the two linear independent vectors
    213213          first->x.AddVector(&n);
    214           first->x.Normalize();         
     214          first->x.Normalize();
    215215          first->x.Scale(a);
    216216          first->x.AddVector(&second->x);
    217          
     217
    218218          cout << Verbose(0) << "resulting coordinates: ";
    219219          first->x.Output((ofstream *)&cout);
     
    241241        } while ((j != -1) && (i<128));
    242242        if (i >= 2) {
    243           first->x.LSQdistance(atoms, i);             
     243          first->x.LSQdistance(atoms, i);
    244244
    245245          first->x.Output((ofstream *)&cout);
     
    259259static void CenterAtoms(molecule *mol)
    260260{
    261   Vector x, y;
     261  Vector x, y, helper;
    262262  char choice;  // menu choice char
    263  
     263
    264264  cout << Verbose(0) << "===========CENTER ATOMS=========================" << endl;
    265265  cout << Verbose(0) << " a - on origin" << endl;
     
    271271  cout << Verbose(0) << "INPUT: ";
    272272  cin >> choice;
    273  
     273
    274274  switch (choice) {
    275275    default:
     
    292292      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
    293293      mol->Translate(&y); // translate by boundary
    294       mol->SetBoxDimension(&(x+y*2));  // update Box of atoms by boundary
     294      helper.CopyVector(&y);
     295      helper.Scale(2.);
     296      helper.AddVector(&x);
     297      mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
    295298      break;
    296299    case 'd':
     
    327330  cout << Verbose(0) << "INPUT: ";
    328331  cin >> choice;
    329  
     332
    330333  switch (choice) {
    331334    default:
     
    346349      second = mol->AskAtom("Enter second atom: ");
    347350
    348       n.CopyVector((const Vector *)&first->x); 
    349       n.SubtractVector((const Vector *)&second->x); 
     351      n.CopyVector((const Vector *)&first->x);
     352      n.SubtractVector((const Vector *)&second->x);
    350353      n.Normalize();
    351       break;       
     354      break;
    352355    case 'd':
    353356      char shorthand[4];
     
    363366        x.x[i] = gsl_vector_get(param.x,i);
    364367        n.x[i] = gsl_vector_get(param.x,i+NDIM);
    365       } 
     368      }
    366369      gsl_vector_free(param.x);
    367370      cout << Verbose(0) << "Offset vector: ";
     
    369372      cout << Verbose(0) << endl;
    370373      n.Normalize();
    371       break;       
     374      break;
    372375  };
    373376  cout << Verbose(0) << "Alignment vector: ";
     
    385388  Vector n;
    386389  char choice;  // menu choice char
    387  
     390
    388391  cout << Verbose(0) << "===========MIRROR ATOMS=========================" << endl;
    389392  cout << Verbose(0) << " a - state three atoms defining mirror plane" << endl;
     
    394397  cout << Verbose(0) << "INPUT: ";
    395398  cin >> choice;
    396  
     399
    397400  switch (choice) {
    398401    default:
     
    413416      second = mol->AskAtom("Enter second atom: ");
    414417
    415       n.CopyVector((const Vector *)&first->x); 
    416       n.SubtractVector((const Vector *)&second->x); 
     418      n.CopyVector((const Vector *)&first->x);
     419      n.SubtractVector((const Vector *)&second->x);
    417420      n.Normalize();
    418       break;         
     421      break;
    419422  };
    420423  cout << Verbose(0) << "Normal vector: ";
     
    433436  double tmp1, tmp2;
    434437  char choice;  // menu choice char
    435  
     438
    436439  cout << Verbose(0) << "===========REMOVE ATOMS=========================" << endl;
    437440  cout << Verbose(0) << " a - state atom for removal by number" << endl;
     
    442445  cout << Verbose(0) << "INPUT: ";
    443446  cin >> choice;
    444  
     447
    445448  switch (choice) {
    446449    default:
     
    475478          mol->RemoveAtom(first);
    476479      }
    477       break;         
     480      break;
    478481  };
    479482  //mol->Output((ofstream *)&cout);
     
    492495  int Z;
    493496  char choice;  // menu choice char
    494  
     497
    495498  cout << Verbose(0) << "===========MEASURE ATOMS=========================" << endl;
    496499  cout << Verbose(0) << " a - calculate bond length between one atom and all others" << endl;
     
    514517      for (int i=MAX_ELEMENTS;i--;)
    515518        min[i] = 0.;
    516        
    517       second = mol->start;   
     519
     520      second = mol->start;
    518521      while ((second->next != mol->end)) {
    519522        second = second->next; // advance
     
    526529        }
    527530        if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1;
    528         //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;         
     531        //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;
    529532      }
    530533      for (int i=MAX_ELEMENTS;i--;)
    531534        if (min[i] != 0.) cout << Verbose(0) << "Minimum Bond length between " << first->type->name << " Atom " << first->nr << " and next Ion of type " << (periode->FindElement(i))->name << ": " << min[i] << " a.u." << endl;
    532535      break;
    533      
     536
    534537    case 'b':
    535538      first = mol->AskAtom("Enter first atom: ");
     
    556559      y.SubtractVector((const Vector *)&second->x);
    557560      cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": ";
    558       cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;         
     561      cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;
    559562      break;
    560563    case 'd':
     
    600603  int Order1;
    601604  clock_t start, end;
    602  
     605
    603606  cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    604607  cout << Verbose(0) << "What's the desired bond order: ";
     
    609612    end = clock();
    610613    cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    611   } else 
     614  } else
    612615    cout << Verbose(0) << "Connection matrix has not yet been generated!" << endl;
    613616};
     
    623626  atom *Walker = mol->start;
    624627  int i, comp, counter=0;
    625  
     628
    626629  // generate some KeySets
    627630  cout << "Generating KeySets." << endl;
     
    637640  cout << "Testing insertion of already present item in KeySets." << endl;
    638641  KeySetTestPair test;
    639   test = TestSets[mol->AtomCount-1].insert(Walker->nr); 
     642  test = TestSets[mol->AtomCount-1].insert(Walker->nr);
    640643  if (test.second) {
    641644    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    646649  TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr);
    647650
    648   // constructing Graph structure 
     651  // constructing Graph structure
    649652  cout << "Generating Subgraph class." << endl;
    650653  Graph Subgraphs;
     
    657660  cout << "Testing insertion of already present item in Subgraph." << endl;
    658661  GraphTestPair test2;
    659   test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.))); 
     662  test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.)));
    660663  if (test2.second) {
    661664    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    663666    cout << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl;
    664667  }
    665  
     668
    666669  // show graphs
    667670  cout << "Showing Subgraph's contents, checking that it's sorted." << endl;
     
    674677      if ((*key) > comp)
    675678        cout << (*key) << " ";
    676       else 
     679      else
    677680        cout << (*key) << "! ";
    678681      comp = (*key);
     
    716719  else
    717720    cout << "failed." << endl;
    718  
     721
    719722  // and save to xyz file
    720723  if (ConfigFileName != NULL) {
     
    727730    strcat(filename, ".xyz");
    728731    output.open(filename, ios::trunc);
    729   } 
     732  }
    730733  cout << Verbose(0) << "Saving of XYZ file ";
    731734  if (mol->MDSteps <= 1) {
     
    742745  output.close();
    743746  output.clear();
    744  
     747
    745748  // and save as MPQC configuration
    746749  if (ConfigFileName != NULL)
     
    753756  else
    754757    cout << "failed." << endl;
    755  
     758
    756759  if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) {
    757760    cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
     
    785788  int argptr;
    786789  PathToDatabases = LocalPath;
    787  
     790
    788791  if (argc > 1) { // config file specified as option
    789792    // 1. : Parse options that just set variables or print help
     
    798801          case '?':
    799802            cout << "MoleCuilder suite" << endl << "==================" << endl << endl;
    800             cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl; 
     803            cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
    801804            cout << "or simply " << argv[0] << " without arguments for interactive session." << endl;
    802805            cout << "\t-a Z x1 x2 x3\tAdd new atom of element Z at coordinates (x1,x2,x3)." << endl;
     806            cout << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
    803807            cout << "\t-b x1 x2 x3\tCenter atoms in domain with given edge lengths of (x1,x2,x3)." << endl;
    804808            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
     
    812816            cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
    813817            cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
    814             cout << "\t-o\tGet volume of the convex envelope (and store to tecplot file)." << endl;
     818            cout << "\t-N\tGet non-convex-envelope." << endl;
     819            cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
    815820            cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
    816821            cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
    817822            cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
    818823            cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
    819             cout << "\t-T <file> Store temperatures from the config file in <file>." << endl; 
     824            cout << "\t-T <file> Store temperatures from the config file in <file>." << endl;
    820825            cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
    821             cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl; 
     826            cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
    822827            cout << "\t-v/-V\t\tGives version information." << endl;
    823828            cout << "Note: config files must not begin with '-' !" << endl;
     
    854859        argptr++;
    855860    } while (argptr < argc);
    856    
     861
    857862    // 2. Parse the element database
    858863    if (periode->LoadPeriodentafel(PathToDatabases)) {
     
    863868      return 1;
    864869    }
    865    
     870
    866871    // 3. Find config file name and parse if possible
    867872    if (argv[1][0] != '-') {
     
    902907    } else
    903908      config_present = absent;
    904    
     909
    905910    // 4. parse again through options, now for those depending on elements db and config presence
    906911    argptr = 1;
     
    946951                    config_present = present;
    947952                } else
    948                   cerr << Verbose(1) << "Could not find the specified element." << endl; 
     953                  cerr << Verbose(1) << "Could not find the specified element." << endl;
    949954                argptr+=4;
    950955              }
     
    956961        if (config_present == present) {
    957962          switch(argv[argptr-1][1]) {
    958             case 'D': 
     963            case 'D':
    959964              ExitFlag = 1;
    960965              {
     
    10021007              }
    10031008              break;
     1009                                                case 'A':
     1010                                                        ExitFlag = 1;
     1011                                                        if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
     1012                                                                ExitFlag =255;
     1013                                                                cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
     1014                                                        } else {
     1015                                                                cout << "Parsing bonds from " << argv[argptr] << "." << endl;
     1016                                                                ifstream *input = new ifstream(argv[argptr]);
     1017                                                                mol->CreateAdjacencyList2((ofstream *)&cout, input);
     1018                                                                input->close();
     1019                                                        }
     1020                                                        break;
     1021                                                case 'N':
     1022                                                        ExitFlag = 1;
     1023                                                        if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
     1024                                                                ExitFlag = 255;
     1025                                                                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
     1026                                                        } else {
     1027                                                                cout << Verbose(0) << "Evaluating npn-convex envelope.";
     1028                                                                string TempName(argv[argptr+1]);
     1029                                                                TempName.append(".r3d");
     1030                                                                ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
     1031                                                                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
     1032                                                                Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
     1033                                                                output->close();
     1034                                                                delete(output);
     1035                                                                argptr+=2;
     1036                                                        }
     1037                                                        break;
    10041038            case 'T':
    10051039              ExitFlag = 1;
     
    11681202            case 'o':
    11691203              ExitFlag = 1;
    1170               if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1204              if ((argptr >= argc) || (argv[argptr][0] == '-')){
    11711205                ExitFlag = 255;
    11721206                cerr << "Not enough or invalid arguments given for convex envelope: -o <tecplot output file>" << endl;
    11731207              } else {
    11741208                cout << Verbose(0) << "Evaluating volume of the convex envelope.";
     1209                ofstream *output = new ofstream(argv[argptr], ios::trunc);
     1210                //$$$
    11751211                cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
    1176                 ofstream *output = new ofstream(argv[argptr], ios::trunc);
    11771212                VolumeOfConvexEnvelope((ofstream *)&cout, output, &configuration, NULL, mol);
    11781213                output->close();
     
    12691304                      mol->Translate(&x);
    12701305                    }
    1271                     mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 
     1306                    mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    12721307                  }
    12731308                }
     
    13321367  if (j == 1) return 0; // just for -v and -h options
    13331368  if (j) return j;  // something went wrong
    1334  
     1369
    13351370  // General stuff
    13361371  if (mol->cell_size[0] == 0.) {
     
    13461381  // now the main construction loop
    13471382  cout << Verbose(0) << endl << "Now comes the real construction..." << endl;
    1348   do {   
     1383  do {
    13491384    cout << Verbose(0) << endl << endl;
    13501385    cout << Verbose(0) << "============Element list=======================" << endl;
     
    13651400    cout << Verbose(0) << "-----------------------------------------------" << endl;
    13661401    cout << Verbose(0) << "d - duplicate molecule/periodic cell" << endl;
    1367     cout << Verbose(0) << "i - realign molecule" << endl; 
    1368     cout << Verbose(0) << "m - mirror all molecules" << endl; 
     1402    cout << Verbose(0) << "i - realign molecule" << endl;
     1403    cout << Verbose(0) << "m - mirror all molecules" << endl;
    13691404    cout << Verbose(0) << "t - translate molecule by vector" << endl;
    13701405    cout << Verbose(0) << "c - scale by unit transformation" << endl;
     
    13771412    cout << Verbose(0) << "Input: ";
    13781413    cin >> choice;
    1379    
     1414
    13801415    switch (choice) {
    13811416      default:
    13821417      case 'a': // add atom
    13831418        AddAtoms(periode, mol);
    1384         choice = 'a'; 
    1385         break;
    1386      
     1419        choice = 'a';
     1420        break;
     1421
    13871422      case 'b': // scale a bond
    13881423        cout << Verbose(0) << "Scaling bond length between two atoms." << endl;
     
    14001435        }
    14011436        //cout << Verbose(0) << "New coordinates of Atom " << second->nr << " are: ";
    1402         //second->Output(second->type->No, 1, (ofstream *)&cout);       
    1403         break;
    1404 
    1405       case 'c': // unit scaling of the metric 
     1437        //second->Output(second->type->No, 1, (ofstream *)&cout);
     1438        break;
     1439
     1440      case 'c': // unit scaling of the metric
    14061441       cout << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl;
    14071442       cout << Verbose(0) << "Enter three factors: ";
     
    14141449       delete[](factor);
    14151450       break;
    1416        
     1451
    14171452      case 'd': // duplicate the periodic cell along a given axis, given times
    14181453        cout << Verbose(0) << "State the axis [(+-)123]: ";
     
    14201455        cout << Verbose(0) << "State the factor: ";
    14211456        cin >> faktor;
    1422        
     1457
    14231458        mol->CountAtoms((ofstream *)&cout);  // recount atoms
    14241459        if (mol->AtomCount != 0) {  // if there is more than none
     
    14611496            mol->Translate(&x);
    14621497          }
    1463           mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 
     1498          mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    14641499        }
    14651500        break;
    1466      
     1501
    14671502      case 'e': // edit each field of the configuration
    14681503       configuration.Edit(mol);
    14691504       break;
    1470  
     1505
    14711506      case 'f':
    14721507        FragmentAtoms(mol, &configuration);
    14731508        break;
    1474        
     1509
    14751510      case 'g': // center the atoms
    14761511        CenterAtoms(mol);
    14771512        break;
    1478        
    1479       case 'i': // align all atoms 
     1513
     1514      case 'i': // align all atoms
    14801515        AlignAtoms(periode, mol);
    14811516        break;
     
    14881523        MirrorAtoms(mol);
    14891524        break;
    1490        
     1525
    14911526      case 'o': // create the connection matrix
    14921527        {
     
    15091544        }
    15101545        break;
    1511        
     1546
    15121547      case 'p': // parse and XYZ file
    15131548        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     
    15181553        break;
    15191554
    1520       case 'q': // quit 
    1521         break;
    1522        
     1555      case 'q': // quit
     1556        break;
     1557
    15231558      case 'r': // remove atom
    1524         RemoveAtoms(mol);       
    1525         break;
    1526        
     1559        RemoveAtoms(mol);
     1560        break;
     1561
    15271562      case 's': // save to config file
    15281563        SaveConfig(ConfigFileName, &configuration, periode, mol);
     
    15301565
    15311566      case 't': // translate all atoms
    1532        cout << Verbose(0) << "Enter translation vector." << endl;       
     1567       cout << Verbose(0) << "Enter translation vector." << endl;
    15331568       x.AskPosition(mol->cell_size,0);
    15341569       mol->Translate((const Vector *)&x);
    15351570       break;
    1536  
     1571
    15371572      case 'T':
    15381573        testroutine(mol);
    15391574        break;
    1540      
     1575
    15411576      case 'u': // change an atom's element
    15421577        first = NULL;
     
    15451580          cin >> Z;
    15461581        } while ((first = mol->FindAtom(Z)) == NULL);
    1547         cout << Verbose(0) << "New element by atomic number Z: ";       
     1582        cout << Verbose(0) << "New element by atomic number Z: ";
    15481583        cin >> Z;
    15491584        first->type = periode->FindElement(Z);
    1550         cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;   
     1585        cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;
    15511586        break;
    15521587    };
    15531588  } while (choice != 'q');
    1554  
     1589
    15551590  // save element data base
    15561591  if (periode->StorePeriodentafel(ElementsFileName)) //ElementsFileName
  • src/config.cpp

    • Property mode changed from 100644 to 100755
  • src/datacreator.cpp

    • Property mode changed from 100644 to 100755
  • src/datacreator.hpp

    • Property mode changed from 100644 to 100755
  • src/defs.hpp

    • Property mode changed from 100644 to 100755
  • src/element.cpp

    • Property mode changed from 100644 to 100755
  • src/elements.db

    • Property mode changed from 100644 to 100755
  • src/graph.cpp

    • Property mode changed from 100644 to 100755
  • src/helpers.cpp

    • Property mode changed from 100644 to 100755
  • src/helpers.hpp

    • Property mode changed from 100644 to 100755
  • src/joiner.cpp

    • Property mode changed from 100644 to 100755
  • src/moleculelist.cpp

    • Property mode changed from 100644 to 100755
  • TabularUnified src/molecules.cpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    11/** \file molecules.cpp
    2  * 
     2 *
    33 * Functions for the class molecule.
    4  * 
     4 *
    55 */
    66
     
    2525      sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
    2626  }
    27  
     27
    2828  return sum;
    2929};
     
    3434 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    3535 */
    36 molecule::molecule(periodentafel *teil) 
    37 { 
     36molecule::molecule(periodentafel *teil)
     37{
    3838  // init atom chain list
    39   start = new atom; 
     39  start = new atom;
    4040  end = new atom;
    41   start->father = NULL; 
     41  start->father = NULL;
    4242  end->father = NULL;
    4343  link(start,end);
     
    4646  last = new bond(start, end, 1, -1);
    4747  link(first,last);
    48   // other stuff 
     48  // other stuff
    4949  MDSteps = 0;
    50   last_atom = 0; 
     50  last_atom = 0;
    5151  elemente = teil;
    5252  AtomCount = 0;
     
    6767 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    6868 */
    69 molecule::~molecule() 
     69molecule::~molecule()
    7070{
    7171  if (ListOfBondsPerAtom != NULL)
     
    7878  delete(last);
    7979  delete(end);
    80   delete(start); 
     80  delete(start);
    8181};
    8282
    8383/** Adds given atom \a *pointer from molecule list.
    84  * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount 
     84 * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount
    8585 * \param *pointer allocated and set atom
    8686 * \return true - succeeded, false - atom not found in list
    8787 */
    8888bool molecule::AddAtom(atom *pointer)
    89 { 
     89{
    9090  if (pointer != NULL) {
    91     pointer->sort = &pointer->nr; 
     91    pointer->sort = &pointer->nr;
    9292    pointer->nr = last_atom++;  // increase number within molecule
    9393    AtomCount++;
     
    106106    return add(pointer, end);
    107107  } else
    108     return false; 
     108    return false;
    109109};
    110110
     
    115115 */
    116116atom * molecule::AddCopyAtom(atom *pointer)
    117 { 
     117{
    118118  if (pointer != NULL) {
    119119        atom *walker = new atom();
     
    122122    walker->v.CopyVector(&pointer->v); // copy velocity
    123123    walker->FixedIon = pointer->FixedIon;
    124     walker->sort = &walker->nr; 
     124    walker->sort = &walker->nr;
    125125    walker->nr = last_atom++;  // increase number within molecule
    126126    walker->father = pointer; //->GetTrueFather();
     
    133133    return walker;
    134134  } else
    135     return NULL; 
     135    return NULL;
    136136};
    137137
     
    156156 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    157157 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    158  *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2} 
     158 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
    159159 *    \f]
    160  *    as the coordination of all three atoms in the coordinate system of these three vectors: 
     160 *    as the coordination of all three atoms in the coordinate system of these three vectors:
    161161 *    \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$.
    162  * 
     162 *
    163163 * \param *out output stream for debugging
    164  * \param *Bond pointer to bond between \a *origin and \a *replacement 
    165  * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin) 
     164 * \param *Bond pointer to bond between \a *origin and \a *replacement
     165 * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin)
    166166 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length
    167167 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
     
    191191  InBondvector.SubtractVector(&TopOrigin->x);
    192192  bondlength = InBondvector.Norm();
    193    
     193
    194194   // is greater than typical bond distance? Then we have to correct periodically
    195195   // the problem is not the H being out of the box, but InBondvector have the wrong direction
    196    // due to TopReplacement or Origin being on the wrong side! 
    197   if (bondlength > BondDistance) { 
     196   // due to TopReplacement or Origin being on the wrong side!
     197  if (bondlength > BondDistance) {
    198198//    *out << Verbose(4) << "InBondvector is: ";
    199199//    InBondvector.Output(out);
     
    215215//    *out << endl;
    216216  } // periodic correction finished
    217  
     217
    218218  InBondvector.Normalize();
    219219  // get typical bond length and store as scale factor for later
     
    222222    cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223223    return false;
    224     BondRescale = bondlength; 
     224    BondRescale = bondlength;
    225225  } else {
    226226    if (!IsAngstroem)
     
    273273      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    274274//        *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
    275        
     275
    276276        // determine the plane of these two with the *origin
    277277        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     
    286286      Orthovector1.Normalize();
    287287      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    288      
     288
    289289      // create the two Hydrogens ...
    290290      FirstOtherAtom = new atom();
     
    318318        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    319319      }
    320       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance 
     320      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    321321      SecondOtherAtom->x.Scale(&BondRescale);
    322322      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    323323      for(int i=NDIM;i--;) { // and make relative to origin atom
    324         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 
     324        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    325325        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326326      }
     
    365365//      *out << endl;
    366366      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    367 //      *out << Verbose(3) << "Orthovector2: "; 
     367//      *out << Verbose(3) << "Orthovector2: ";
    368368//      Orthovector2.Output(out);
    369369//      *out << endl;
    370      
     370
    371371      // create correct coordination for the three atoms
    372372      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     
    380380      factors[0] = d;
    381381      factors[1] = f;
    382       factors[2] = 0.; 
     382      factors[2] = 0.;
    383383      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    384384      factors[1] = -0.5*f;
    385       factors[2] = g; 
     385      factors[2] = g;
    386386      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387       factors[2] = -g; 
     387      factors[2] = -g;
    388388      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    389389
     
    437437 */
    438438bool molecule::AddXYZFile(string filename)
    439 { 
     439{
    440440  istringstream *input = NULL;
    441441  int NumberOfAtoms = 0; // atom number in xyz read
     
    446446  string line;    // currently parsed line
    447447  double x[3];    // atom coordinates
    448  
     448
    449449  xyzfile.open(filename.c_str());
    450450  if (!xyzfile)
     
    454454  input = new istringstream(line);
    455455  *input >> NumberOfAtoms;
    456   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 
     456  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    457457  getline(xyzfile,line,'\n'); // Read comment
    458458  cout << Verbose(1) << "Comment: " << line << endl;
    459  
     459
    460460  if (MDSteps == 0) // no atoms yet present
    461461    MDSteps++;
     
    491491  xyzfile.close();
    492492  delete(input);
    493   return true; 
     493  return true;
    494494};
    495495
     
    503503  atom *LeftAtom = NULL, *RightAtom = NULL;
    504504  atom *Walker = NULL;
    505  
     505
    506506  // copy all atoms
    507507  Walker = start;
     
    510510    CurrentAtom = copy->AddCopyAtom(Walker);
    511511  }
    512  
     512
    513513  // copy all bonds
    514514  bond *Binder = first;
     
    534534      copy->NoCyclicBonds++;
    535535    NewBond->Type = Binder->Type;
    536   } 
     536  }
    537537  // correct fathers
    538538  Walker = copy->start;
     
    551551    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    552552  }
    553  
     553
    554554  return copy;
    555555};
     
    576576
    577577/** Remove bond from bond chain list.
    578  * \todo Function not implemented yet 
     578 * \todo Function not implemented yet
    579579 * \param *pointer bond pointer
    580580 * \return true - bound found and removed, false - bond not found/removed
     
    588588
    589589/** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of.
    590  * \todo Function not implemented yet 
     590 * \todo Function not implemented yet
    591591 * \param *BondPartner atom to be removed
    592592 * \return true - bounds found and removed, false - bonds not found/removed
     
    621621  Vector *min = new Vector;
    622622  Vector *max = new Vector;
    623  
     623
    624624  // gather min and max for each axis
    625625  ptr = start->next;  // start at first in list
     
    667667{
    668668  Vector *min = new Vector;
    669  
     669
    670670//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    671671  atom *ptr = start->next;  // start at first in list
     
    683683      }
    684684    }
    685 //    *out << Verbose(4) << "Maximum is "; 
     685//    *out << Verbose(4) << "Maximum is ";
    686686//    max->Output(out);
    687687//    *out << ", Minimum is ";
     
    691691    max->AddVector(min);
    692692    Translate(min);
    693   } 
     693  }
    694694  delete(min);
    695695//  *out << Verbose(3) << "End of CenterEdge." << endl;
    696 }; 
     696};
    697697
    698698/** Centers the center of the atoms at (0,0,0).
     
    704704  int Num = 0;
    705705  atom *ptr = start->next;  // start at first in list
    706  
     706
    707707  for(int i=NDIM;i--;) // zero center vector
    708708    center->x[i] = 0.;
    709    
     709
    710710  if (ptr != end) {   //list not empty?
    711711    while (ptr->next != end) {  // continue with second if present
    712712      ptr = ptr->next;
    713713      Num++;
    714       center->AddVector(&ptr->x);       
     714      center->AddVector(&ptr->x);
    715715    }
    716716    center->Scale(-1./Num); // divide through total number (and sign for direction)
    717717    Translate(center);
    718718  }
    719 }; 
     719};
    720720
    721721/** Returns vector pointing to center of gravity.
     
    729729  Vector tmp;
    730730  double Num = 0;
    731  
     731
    732732  a->Zero();
    733733
     
    737737      Num += 1.;
    738738      tmp.CopyVector(&ptr->x);
    739       a->AddVector(&tmp);       
     739      a->AddVector(&tmp);
    740740    }
    741741    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    757757        Vector tmp;
    758758  double Num = 0;
    759        
     759
    760760        a->Zero();
    761761
     
    766766      tmp.CopyVector(&ptr->x);
    767767      tmp.Scale(ptr->type->mass);  // scale by mass
    768       a->AddVector(&tmp);       
     768      a->AddVector(&tmp);
    769769    }
    770770    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    789789    Translate(center);
    790790  }
    791 }; 
     791};
    792792
    793793/** Scales all atoms by \a *factor.
     
    803803      Trajectories[ptr].R.at(j).Scale(factor);
    804804    ptr->x.Scale(factor);
    805   }     
    806 };
    807 
    808 /** Translate all atoms by given vector. 
     805  }
     806};
     807
     808/** Translate all atoms by given vector.
    809809 * \param trans[] translation vector.
    810810 */
     
    818818      Trajectories[ptr].R.at(j).Translate(trans);
    819819    ptr->x.Translate(trans);
    820   }     
    821 };
    822 
    823 /** Mirrors all atoms against a given plane. 
     820  }
     821};
     822
     823/** Mirrors all atoms against a given plane.
    824824 * \param n[] normal vector of mirror plane.
    825825 */
     
    833833      Trajectories[ptr].R.at(j).Mirror(n);
    834834    ptr->x.Mirror(n);
    835   }     
     835  }
    836836};
    837837
     
    847847  bool flag;
    848848  Vector Testvector, Translationvector;
    849  
     849
    850850  do {
    851851    Center.Zero();
     
    863863          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    864864            for (int j=0;j<NDIM;j++) {
    865               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 
     865              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    866866              if ((fabs(tmp)) > BondDistance) {
    867867                flag = false;
     
    879879        cout << Verbose(1) << "vector is: ";
    880880        Testvector.Output((ofstream *)&cout);
    881         cout << endl;     
     881        cout << endl;
    882882#ifdef ADDHYDROGEN
    883883        // now also change all hydrogens
     
    892892            cout << Verbose(1) << "Hydrogen vector is: ";
    893893            Testvector.Output((ofstream *)&cout);
    894             cout << endl;     
     894            cout << endl;
    895895          }
    896896        }
     
    914914
    915915        CenterGravity(out, CenterOfGravity);
    916        
    917         // reset inertia tensor 
     916
     917        // reset inertia tensor
    918918        for(int i=0;i<NDIM*NDIM;i++)
    919919                InertiaTensor[i] = 0.;
    920        
     920
    921921        // sum up inertia tensor
    922922        while (ptr->next != end) {
     
    943943        }
    944944        *out << endl;
    945        
     945
    946946        // diagonalize to determine principal axis system
    947947        gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     
    952952        gsl_eigen_symmv_free(T);
    953953        gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    954        
     954
    955955        for(int i=0;i<NDIM;i++) {
    956956                *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    957957                *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    958958        }
    959        
     959
    960960        // check whether we rotate or not
    961961        if (DoRotate) {
    962           *out << Verbose(1) << "Transforming molecule into PAS ... "; 
     962          *out << Verbose(1) << "Transforming molecule into PAS ... ";
    963963          // the eigenvectors specify the transformation matrix
    964964          ptr = start;
     
    972972
    973973          // summing anew for debugging (resulting matrix has to be diagonal!)
    974           // reset inertia tensor 
     974          // reset inertia tensor
    975975    for(int i=0;i<NDIM*NDIM;i++)
    976976      InertiaTensor[i] = 0.;
    977    
     977
    978978    // sum up inertia tensor
    979979    ptr = start;
     
    10021002    *out << endl;
    10031003        }
    1004        
     1004
    10051005        // free everything
    10061006        delete(CenterOfGravity);
     
    10311031
    10321032  CountElements();  // make sure ElementsInMolecule is up to date
    1033  
     1033
    10341034  // check file
    10351035  if (input == NULL) {
     
    10871087              Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
    10881088            }
    1089 //            cout << "Integrated position&velocity of step " << (MDSteps) << ": ("; 
     1089//            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
    10901090//            for (int d=0;d<NDIM;d++)
    10911091//              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     
    11211121  MDSteps++;
    11221122
    1123  
     1123
    11241124  // exit
    11251125  return true;
    11261126};
    11271127
    1128 /** Align all atoms in such a manner that given vector \a *n is along z axis. 
     1128/** Align all atoms in such a manner that given vector \a *n is along z axis.
    11291129 * \param n[] alignment vector.
    11301130 */
     
    11451145    ptr = ptr->next;
    11461146    tmp = ptr->x.x[0];
    1147     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1147    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    11481148    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    11491149    for (int j=0;j<MDSteps;j++) {
    11501150      tmp = Trajectories[ptr].R.at(j).x[0];
    1151       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1151      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    11521152      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    11531153    }
    1154   }     
     1154  }
    11551155  // rotate n vector
    11561156  tmp = n->x[0];
     
    11601160  n->Output((ofstream *)&cout);
    11611161  cout << endl;
    1162  
     1162
    11631163  // rotate on z-y plane
    11641164  ptr = start;
     
    11681168    ptr = ptr->next;
    11691169    tmp = ptr->x.x[1];
    1170     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1170    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    11711171    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    11721172    for (int j=0;j<MDSteps;j++) {
    11731173      tmp = Trajectories[ptr].R.at(j).x[1];
    1174       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1174      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    11751175      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    11761176    }
    1177   }     
     1177  }
    11781178  // rotate n vector (for consistency check)
    11791179  tmp = n->x[1];
    11801180  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    11811181  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1182  
     1182
    11831183  cout << Verbose(1) << "alignment vector after second rotation: ";
    11841184  n->Output((ofstream *)&cout);
     
    11911191 * \return true - succeeded, false - atom not found in list
    11921192 */
    1193 bool molecule::RemoveAtom(atom *pointer) 
    1194 { 
     1193bool molecule::RemoveAtom(atom *pointer)
     1194{
    11951195  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    11961196    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    11971197  else
    1198     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 
     1198    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    11991199  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    12001200    ElementCount--;
     
    12061206 * \return true - succeeded, false - atom not found in list
    12071207 */
    1208 bool molecule::CleanupMolecule() 
    1209 { 
    1210   return (cleanup(start,end) && cleanup(first,last)); 
     1208bool molecule::CleanupMolecule()
     1209{
     1210  return (cleanup(start,end) && cleanup(first,last));
    12111211};
    12121212
     
    12221222  } else {
    12231223    cout << Verbose(0) << "Atom not found in list." << endl;
    1224     return NULL; 
     1224    return NULL;
    12251225  }
    12261226};
     
    12711271  struct lsq_params *par = (struct lsq_params *)params;
    12721272  atom *ptr = par->mol->start;
    1273  
     1273
    12741274  // initialize vectors
    12751275  a.x[0] = gsl_vector_get(x,0);
     
    13011301{
    13021302    int np = 6;
    1303    
     1303
    13041304   const gsl_multimin_fminimizer_type *T =
    13051305     gsl_multimin_fminimizer_nmsimplex;
     
    13071307   gsl_vector *ss;
    13081308   gsl_multimin_function minex_func;
    1309  
     1309
    13101310   size_t iter = 0, i;
    13111311   int status;
    13121312   double size;
    1313  
     1313
    13141314   /* Initial vertex size vector */
    13151315   ss = gsl_vector_alloc (np);
    1316  
     1316
    13171317   /* Set all step sizes to 1 */
    13181318   gsl_vector_set_all (ss, 1.0);
    1319  
     1319
    13201320   /* Starting point */
    13211321   par->x = gsl_vector_alloc (np);
    13221322   par->mol = this;
    1323  
     1323
    13241324   gsl_vector_set (par->x, 0, 0.0);  // offset
    13251325   gsl_vector_set (par->x, 1, 0.0);
     
    13281328   gsl_vector_set (par->x, 4, 0.0);
    13291329   gsl_vector_set (par->x, 5, 1.0);
    1330  
     1330
    13311331   /* Initialize method and iterate */
    13321332   minex_func.f = &LeastSquareDistance;
    13331333   minex_func.n = np;
    13341334   minex_func.params = (void *)par;
    1335  
     1335
    13361336   s = gsl_multimin_fminimizer_alloc (T, np);
    13371337   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1338  
     1338
    13391339   do
    13401340     {
    13411341       iter++;
    13421342       status = gsl_multimin_fminimizer_iterate(s);
    1343  
     1343
    13441344       if (status)
    13451345         break;
    1346  
     1346
    13471347       size = gsl_multimin_fminimizer_size (s);
    13481348       status = gsl_multimin_test_size (size, 1e-2);
    1349  
     1349
    13501350       if (status == GSL_SUCCESS)
    13511351         {
    13521352           printf ("converged to minimum at\n");
    13531353         }
    1354  
     1354
    13551355       printf ("%5d ", (int)iter);
    13561356       for (i = 0; i < (size_t)np; i++)
     
    13611361     }
    13621362   while (status == GSL_CONTINUE && iter < 100);
    1363  
     1363
    13641364  for (i=0;i<(size_t)np;i++)
    13651365    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     
    13781378  int ElementNo, AtomNo;
    13791379  CountElements();
    1380  
     1380
    13811381  if (out == NULL) {
    13821382    return false;
     
    14131413  int ElementNo, AtomNo;
    14141414  CountElements();
    1415  
     1415
    14161416  if (out == NULL) {
    14171417    return false;
     
    14601460  atom *Walker = start;
    14611461  while (Walker->next != end) {
    1462     Walker = Walker->next; 
     1462    Walker = Walker->next;
    14631463#ifdef ADDHYDROGEN
    14641464    if (Walker->type->Z != 1) {   // regard only non-hydrogen
     
    14911491  int No = 0;
    14921492  time_t now;
    1493  
     1493
    14941494  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    14951495  walker = start;
     
    15181518{
    15191519  atom *walker = NULL;
    1520   int No = 0;
     1520  int AtomNo = 0, ElementNo;
    15211521  time_t now;
    1522  
     1522  element *runner = NULL;
     1523
    15231524  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    15241525  walker = start;
    15251526  while (walker->next != end) { // go through every atom and count
    15261527    walker = walker->next;
    1527     No++;
     1528    AtomNo++;
    15281529  }
    15291530  if (out != NULL) {
    1530     *out << No << "\n\tCreated by molecuilder on " << ctime(&now);
    1531     walker = start;
    1532     while (walker->next != end) { // go through every atom of this element
    1533       walker = walker->next;
    1534       walker->OutputXYZLine(out);
     1531    *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
     1532    ElementNo = 0;
     1533    runner = elemente->start;
     1534    while (runner->next != elemente->end) { // go through every element
     1535                runner = runner->next;
     1536      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1537        ElementNo++;
     1538        walker = start;
     1539        while (walker->next != end) { // go through every atom of this element
     1540          walker = walker->next;
     1541          if (walker->type == runner) { // if this atom fits to element
     1542            walker->OutputXYZLine(out);
     1543          }
     1544        }
     1545      }
    15351546    }
    15361547    return true;
     
    15631574              Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    15641575              if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1565                 NoNonHydrogen++; 
     1576                NoNonHydrogen++;
    15661577              Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    15671578              Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     
    15711582            }
    15721583    } else
    1573         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 
     1584        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    15741585  }
    15751586};
     
    15831594        ElementsInMolecule[i] = 0;
    15841595        ElementCount = 0;
    1585        
     1596
    15861597  atom *walker = start;
    15871598  while (walker->next != end) {
     
    16191630    Binder = Binder->next;
    16201631    if (Binder->Cyclic)
    1621       No++;   
     1632      No++;
    16221633  }
    16231634  delete(BackEdgeStack);
     
    16771688
    16781689/** Creates an adjacency list of the molecule.
     1690 * We obtain an outside file with the indices of atoms which are bondmembers.
     1691 */
     1692void molecule::CreateAdjacencyList2(ofstream *out, ifstream *input)
     1693{
     1694
     1695        // 1 We will parse bonds out of the dbond file created by tremolo.
     1696                        int atom1, atom2, temp;
     1697                        atom *Walker, *OtherWalker;
     1698
     1699                if (!input)
     1700                {
     1701                        cout << Verbose(1) << "Opening silica failed \n";
     1702                };
     1703
     1704                        *input >> ws >> atom1;
     1705                        *input >> ws >> atom2;
     1706                cout << Verbose(1) << "Scanning file\n";
     1707                while (!input->eof()) // Check whether we read everything already
     1708                {
     1709                                *input >> ws >> atom1;
     1710                                *input >> ws >> atom2;
     1711                        if(atom2<atom1) //Sort indices of atoms in order
     1712                        {
     1713                                temp=atom1;
     1714                                atom1=atom2;
     1715                                atom2=temp;
     1716                        };
     1717
     1718                        Walker=start;
     1719                        while(Walker-> nr != atom1) // Find atom corresponding to first index
     1720                        {
     1721                                Walker = Walker->next;
     1722                        };
     1723                        OtherWalker = Walker->next;
     1724                        while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     1725                        {
     1726                                OtherWalker= OtherWalker->next;
     1727                        };
     1728                        AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     1729                       
     1730                }
     1731
     1732                CreateListOfBondsPerAtom(out);
     1733
     1734};
     1735
     1736
     1737/** Creates an adjacency list of the molecule.
    16791738 * Generally, we use the CSD approach to bond recognition, that is the the distance
    16801739 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    1681  * a threshold t = 0.4 Angstroem. 
     1740 * a threshold t = 0.4 Angstroem.
    16821741 * To make it O(N log N) the function uses the linked-cell technique as follows:
    16831742 * The procedure is step-wise:
     
    16961755void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    16971756{
     1757
    16981758  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    16991759  int No, NoBonds, CandidateBondNo;
     
    17041764  Vector x;
    17051765  int FalseBondDegree = 0;
    1706  
     1766
    17071767  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    17081768  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     
    17111771    cleanup(first,last);
    17121772  }
    1713        
     1773
    17141774  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    17151775  CountAtoms(out);
     
    17301790    for (int i=NumberCells;i--;)
    17311791      CellList[i] = NULL;
    1732  
     1792
    17331793    // 2b. put all atoms into its corresponding list
    17341794    Walker = start;
     
    17511811      if (CellList[index] == NULL)  // allocate molecule if not done
    17521812        CellList[index] = new molecule(elemente);
    1753       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 
    1754       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 
     1813      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
     1814      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    17551815    }
    17561816    //for (int i=0;i<NumberCells;i++)
    17571817      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1758      
     1818
     1819
    17591820    // 3a. go through every cell
    17601821    for (N[0]=divisor[0];N[0]--;)
     
    17691830              Walker = Walker->next;
    17701831              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1771               // 3c. check for possible bond between each atom in this and every one in the 27 cells 
     1832              // 3c. check for possible bond between each atom in this and every one in the 27 cells
    17721833              for (n[0]=-1;n[0]<=1;n[0]++)
    17731834                for (n[1]=-1;n[1]<=1;n[1]++)
     
    18011862          }
    18021863        }
     1864
     1865
     1866
    18031867    // 4. free the cell again
    18041868    for (int i=NumberCells;i--;)
     
    18071871      }
    18081872    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1809    
     1873
    18101874    // create the adjacency list per atom
    18111875    CreateListOfBondsPerAtom(out);
    1812                
     1876
    18131877    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    18141878    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     
    18591923                        *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    18601924          *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    1861                
     1925
    18621926          // output bonds for debugging (if bond chain list was correctly installed)
    18631927          *out << Verbose(1) << endl << "From contents of bond chain list:";
     
    18691933    *out << endl;
    18701934  } else
    1871         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 
     1935        *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    18721936  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    18731937  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    1874 };
     1938
     1939};
     1940
     1941
    18751942
    18761943/** Performs a Depth-First search on this molecule.
     
    18931960  bond *Binder = NULL;
    18941961  bool BackStepping = false;
    1895  
     1962
    18961963  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    1897  
     1964
    18981965  ResetAllBondsToUnused();
    18991966  ResetAllAtomNumbers();
     
    19081975    LeafWalker->Leaf = new molecule(elemente);
    19091976    LeafWalker->Leaf->AddCopyAtom(Root);
    1910    
     1977
    19111978    OldGraphNr = CurrentGraphNr;
    19121979    Walker = Root;
     
    19191986          AtomStack->Push(Walker);
    19201987          CurrentGraphNr++;
    1921         }     
     1988        }
    19221989        do { // (3) if Walker has no unused egdes, go to (5)
    19231990          BackStepping = false; // reset backstepping flag for (8)
     
    19532020          Binder = NULL;
    19542021      } while (1);  // (2)
    1955      
     2022
    19562023      // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished!
    19572024      if ((Walker == Root) && (Binder == NULL))
    19582025        break;
    1959        
    1960       // (5) if Ancestor of Walker is ... 
     2026
     2027      // (5) if Ancestor of Walker is ...
    19612028      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    19622029      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     
    20012068        } while (OtherAtom != Walker);
    20022069        ComponentNumber++;
    2003    
     2070
    20042071        // (11) Root is separation vertex,  set Walker to Root and go to (4)
    20052072        Walker = Root;
     
    20142081
    20152082    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2016     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;   
     2083    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    20172084    LeafWalker->Leaf->Output(out);
    20182085    *out << endl;
     
    20222089      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    20232090      if (Root->GraphNr != -1) // if already discovered, step on
    2024         Root = Root->next; 
     2091        Root = Root->next;
    20252092    }
    20262093  }
     
    20442111    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    20452112  }
    2046  
     2113
    20472114  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    20482115  Binder = first;
     
    20552122    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    20562123    OutputComponentNumber(out, Binder->rightatom);
    2057     *out << ">." << endl; 
     2124    *out << ">." << endl;
    20582125    if (Binder->Cyclic) // cyclic ??
    20592126      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     
    20702137 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as
    20712138 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds
    2072  * as cyclic and print out the cycles. 
     2139 * as cyclic and print out the cycles.
    20732140 * \param *out output stream for debugging
    20742141 * \param *BackEdgeStack stack with all back edges found during DFS scan. Beware: This stack contains the bonds from the total molecule, not from the subgraph!
     
    20812148  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    20822149  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2083   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring 
     2150  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
    20842151  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    20852152  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     
    20932160    ColorList[i] = white;
    20942161  }
    2095  
     2162
    20962163  *out << Verbose(1) << "Back edge list - ";
    20972164  BackEdgeStack->Output(out);
    2098  
     2165
    20992166  *out << Verbose(1) << "Analysing cycles ... " << endl;
    21002167  NumCycles = 0;
     
    21022169    BackEdge = BackEdgeStack->PopFirst();
    21032170    // this is the target
    2104     Root = BackEdge->leftatom; 
     2171    Root = BackEdge->leftatom;
    21052172    // this is the source point
    2106     Walker = BackEdge->rightatom; 
     2173    Walker = BackEdge->rightatom;
    21072174    ShortestPathList[Walker->nr] = 0;
    21082175    BFSStack->ClearStack();  // start with empty BFS stack
     
    21182185        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    21192186          OtherAtom = Binder->GetOtherAtom(Walker);
    2120 #ifdef ADDHYDROGEN         
     2187#ifdef ADDHYDROGEN
    21212188          if (OtherAtom->type->Z != 1) {
    21222189#endif
     
    21272194              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    21282195              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2129               *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 
     2196              *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    21302197              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    21312198                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     
    21372204            if (OtherAtom == Root)
    21382205              break;
    2139 #ifdef ADDHYDROGEN         
     2206#ifdef ADDHYDROGEN
    21402207          } else {
    21412208            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     
    21752242      }
    21762243    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2177    
     2244
    21782245    if (OtherAtom == Root) {
    21792246      // now climb back the predecessor list and thus find the cycle members
     
    22032270      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    22042271    }
    2205    
     2272
    22062273    // now clean the lists
    22072274    while (!TouchedStack->IsEmpty()){
     
    22132280  }
    22142281  if (MinRingSize != -1) {
    2215     // go over all atoms 
     2282    // go over all atoms
    22162283    Root = start;
    22172284    while(Root->next != end) {
    22182285      Root = Root->next;
    2219      
     2286
    22202287      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    22212288        Walker = Root;
     
    22542321          }
    22552322          ColorList[Walker->nr] = black;
    2256           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     2323          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    22572324        }
    2258    
     2325
    22592326        // now clean the lists
    22602327        while (!TouchedStack->IsEmpty()){
     
    23052372void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    23062373{
    2307   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 
     2374  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    23082375    *out << vertex->ComponentNr[i] << "  ";
    23092376};
     
    23832450{
    23842451  int c = 0;
    2385   int FragmentCount; 
     2452  int FragmentCount;
    23862453  // get maximum bond degree
    23872454  atom *Walker = start;
     
    23932460  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    23942461  return FragmentCount;
    2395 }; 
     2462};
    23962463
    23972464/** Scans a single line for number and puts them into \a KeySet.
    23982465 * \param *out output stream for debugging
    23992466 * \param *buffer buffer to scan
    2400  * \param &CurrentSet filled KeySet on return 
     2467 * \param &CurrentSet filled KeySet on return
    24012468 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
    24022469 */
     
    24062473  int AtomNr;
    24072474  int status = 0;
    2408  
     2475
    24092476  line.str(buffer);
    24102477  while (!line.eof()) {
     
    24422509  double TEFactor;
    24432510  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2444  
     2511
    24452512  if (FragmentList == NULL) { // check list pointer
    24462513    FragmentList = new Graph;
    24472514  }
    2448  
     2515
    24492516  // 1st pass: open file and read
    24502517  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     
    24752542    status = false;
    24762543  }
    2477  
     2544
    24782545  // 2nd pass: open TEFactors file and read
    24792546  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     
    24872554        InputFile >> TEFactor;
    24882555        (*runner).second.second = TEFactor;
    2489         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 
     2556        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    24902557      } else {
    24912558        status = false;
     
    25282595  if(output != NULL) {
    25292596    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2530       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 
     2597      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    25312598        if (sprinter != (*runner).first.begin())
    25322599          output << "\t";
     
    25942661    status = false;
    25952662  }
    2596  
     2663
    25972664  return status;
    25982665};
     
    26032670 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom
    26042671 * \return true - structure is equal, false - not equivalence
    2605  */ 
     2672 */
    26062673bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    26072674{
     
    26102677  bool status = true;
    26112678  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2612  
     2679
    26132680  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    26142681  File.open(filename.str().c_str(), ios::out);
     
    26692736  *out << endl;
    26702737  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2671  
     2738
    26722739  return status;
    26732740};
     
    26912758  for(int i=AtomCount;i--;)
    26922759    AtomMask[i] = false;
    2693  
     2760
    26942761  if (Order < 0) { // adaptive increase of BondOrder per site
    26952762    if (AtomMask[AtomCount] == true)  // break after one step
     
    27312798          line >> ws >> Value; // skip time entry
    27322799          line >> ws >> Value;
    2733           No -= 1;  // indices start at 1 in file, not 0 
     2800          No -= 1;  // indices start at 1 in file, not 0
    27342801          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    27352802
     
    27402807            // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
    27412808            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2742             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 
     2809            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    27432810            if (!InsertedElement.second) { // this root is already present
    2744               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term 
    2745                 //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase) 
     2811              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
     2812                //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
    27462813                {  // if value is smaller, update value and order
    27472814                (*PresentItem).second.first = fabs(Value);
     
    27812848        Walker = FindAtom(No);
    27822849        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2783           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 
     2850          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    27842851          AtomMask[No] = true;
    27852852          status = true;
    27862853        //} else
    2787           //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl; 
     2854          //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl;
    27882855      }
    27892856      // close and done
     
    28192886    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    28202887      status = true;
    2821      
     2888
    28222889    if (!status) {
    28232890      if (Order == 0)
     
    28272894    }
    28282895  }
    2829  
     2896
    28302897  // print atom mask for debugging
    28312898  *out << "              ";
     
    28362903    *out << (AtomMask[i] ? "t" : "f");
    28372904  *out << endl;
    2838  
     2905
    28392906  return status;
    28402907};
     
    28502917  int AtomNo = 0;
    28512918  atom *Walker = NULL;
    2852  
     2919
    28532920  if (SortIndex != NULL) {
    28542921    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     
    29082975  atom **ListOfAtoms = NULL;
    29092976  atom ***ListOfLocalAtoms = NULL;
    2910   bool *AtomMask = NULL; 
    2911  
     2977  bool *AtomMask = NULL;
     2978
    29122979  *out << endl;
    29132980#ifdef ADDHYDROGEN
     
    29182985
    29192986  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    2920  
     2987
    29212988  // ===== 1. Check whether bond structure is same as stored in files ====
    2922  
     2989
    29232990  // fill the adjacency list
    29242991  CreateListOfBondsPerAtom(out);
     
    29262993  // create lookup table for Atom::nr
    29272994  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    2928  
     2995
    29292996  // === compare it with adjacency file ===
    2930   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 
     2997  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    29312998  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    29322999
     
    29573024    delete(LocalBackEdgeStack);
    29583025  }
    2959  
     3026
    29603027  // ===== 3. if structure still valid, parse key set file and others =====
    29613028  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     
    29633030  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    29643031  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    2965  
    2966   // =================================== Begin of FRAGMENTATION =============================== 
    2967   // ===== 6a. assign each keyset to its respective subgraph ===== 
     3032
     3033  // =================================== Begin of FRAGMENTATION ===============================
     3034  // ===== 6a. assign each keyset to its respective subgraph =====
    29683035  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    29693036
     
    29763043    FragmentationToDo = FragmentationToDo || CheckOrder;
    29773044    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    2978     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 
     3045    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    29793046    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    29803047
     
    30003067  delete(ParsedFragmentList);
    30013068  delete[](MinimumRingSize);
    3002  
     3069
    30033070
    30043071  // ==================================== End of FRAGMENTATION ============================================
     
    30063073  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    30073074  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3008  
     3075
    30093076  // free subgraph memory again
    30103077  FragmentCounter = 0;
     
    30313098    }
    30323099    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3033    
     3100
    30343101    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    30353102    if (BondFragments->NumberOfMolecules != 0) {
    30363103      // create the SortIndex from BFS labels to order in the config file
    30373104      CreateMappingLabelsToConfigSequence(out, SortIndex);
    3038      
     3105
    30393106      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    30403107      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     
    30423109      else
    30433110        *out << Verbose(1) << "Some config writing failed." << endl;
    3044  
     3111
    30453112      // store force index reference file
    30463113      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3047      
    3048       // store keysets file 
     3114
     3115      // store keysets file
    30493116      StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3050  
    3051       // store Adjacency file 
     3117
     3118      // store Adjacency file
    30523119      StoreAdjacencyToFile(out, configuration->configpath);
    3053  
     3120
    30543121      // store Hydrogen saturation correction file
    30553122      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3056      
     3123
    30573124      // store adaptive orders into file
    30583125      StoreOrderAtSiteFile(out, configuration->configpath);
    3059      
     3126
    30603127      // restore orbital and Stop values
    30613128      CalculateOrbitals(*configuration);
    3062      
     3129
    30633130      // free memory for bond part
    30643131      *out << Verbose(1) << "Freeing bond memory" << endl;
    30653132      delete(FragmentList); // remove bond molecule from memory
    3066       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 
     3133      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    30673134    } else
    30683135      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3069   //} else 
     3136  //} else
    30703137  //  *out << Verbose(1) << "No fragments to store." << endl;
    30713138  *out << Verbose(0) << "End of bond fragmentation." << endl;
     
    30933160  atom *Walker = NULL, *OtherAtom = NULL;
    30943161  ReferenceStack->Push(Binder);
    3095  
     3162
    30963163  do {  // go through all bonds and push local ones
    30973164    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3098     if (Walker != NULL) // if this Walker exists in the subgraph ... 
     3165    if (Walker != NULL) // if this Walker exists in the subgraph ...
    30993166        for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    31003167        OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     
    31093176    ReferenceStack->Push(Binder);
    31103177  } while (FirstBond != Binder);
    3111  
     3178
    31123179  return status;
    31133180};
     
    31853252      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    31863253      Walker->MaxOrder = MaxArray[Walker->nr];
    3187       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 
     3254      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    31883255    }
    31893256    file.close();
     
    31963263  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    31973264  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3198  
     3265
    31993266  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    32003267  return status;
     
    32543321  Walker = start;
    32553322  while (Walker->next != end) {
    3256     Walker = Walker->next; 
     3323    Walker = Walker->next;
    32573324    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    32583325    TotalDegree = 0;
     
    32623329    }
    32633330    *out << " -- TotalDegree: " << TotalDegree << endl;
    3264   }     
     3331  }
    32653332  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    32663333};
     
    32683335/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
    32693336 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was
    3270  * white and putting into queue. 
     3337 * white and putting into queue.
    32713338 * \param *out output stream for debugging
    32723339 * \param *Mol Molecule class to add atoms to
     
    32773344 * \param BondOrder maximum distance for vertices to add
    32783345 * \param IsAngstroem lengths are in angstroem or bohrradii
    3279  */ 
     3346 */
    32803347void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    32813348{
     
    33033370  }
    33043371  ShortestPathList[Root->nr] = 0;
    3305  
     3372
    33063373  // and go on ... Queue always contains all lightgray vertices
    33073374  while (!AtomStack->IsEmpty()) {
     
    33113378    // followed by n+1 till top of stack.
    33123379    Walker = AtomStack->PopFirst(); // pop oldest added
    3313     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 
     3380    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    33143381    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    33153382      Binder = ListOfBondsPerAtom[Walker->nr][i];
     
    33183385        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    33193386        if (ColorList[OtherAtom->nr] == white) {
    3320           if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 
     3387          if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem)
    33213388            ColorList[OtherAtom->nr] = lightgray;
    33223389          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    33233390          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3324           *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 
     3391          *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    33253392          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    33263393            *out << Verbose(3);
     
    33703437          // This has to be a cyclic bond, check whether it's present ...
    33713438          if (AddedBondList[Binder->nr] == NULL) {
    3372             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 
     3439            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    33733440              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    33743441              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     
    33853452    }
    33863453    ColorList[Walker->nr] = black;
    3387     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     3454    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    33883455  }
    33893456  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     
    34093476
    34103477  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3411  
     3478
    34123479  // reset parent list
    34133480  *out << Verbose(3) << "Resetting ParentList." << endl;
    34143481  for (int i=Father->AtomCount;i--;)
    34153482    ParentList[i] = NULL;
    3416  
     3483
    34173484  // fill parent list with sons
    34183485  *out << Verbose(3) << "Filling Parent List." << endl;
     
    34553522 * \param *&Leaf KeySet to look through
    34563523 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end
    3457  * \param index of the atom suggested for removal 
     3524 * \param index of the atom suggested for removal
    34583525 */
    34593526int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
     
    34613528  atom *Runner = NULL;
    34623529  int SP, Removal;
    3463  
     3530
    34643531  *out << Verbose(2) << "Looking for removal candidate." << endl;
    34653532  SP = -1; //0;  // not -1, so that Root is never removed
     
    34793546/** Stores a fragment from \a KeySet into \a molecule.
    34803547 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
    3481  * molecule and adds missing hydrogen where bonds were cut. 
     3548 * molecule and adds missing hydrogen where bonds were cut.
    34823549 * \param *out output stream for debugging messages
    3483  * \param &Leaflet pointer to KeySet structure 
     3550 * \param &Leaflet pointer to KeySet structure
    34843551 * \param IsAngstroem whether we have Ansgtroem or bohrradius
    34853552 * \return pointer to constructed molecule
     
    34923559  bool LonelyFlag = false;
    34933560  int size;
    3494  
     3561
    34953562//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3496  
     3563
    34973564  Leaf->BondDistance = BondDistance;
    34983565  for(int i=NDIM*2;i--;)
    3499     Leaf->cell_size[i] = cell_size[i]; 
     3566    Leaf->cell_size[i] = cell_size[i];
    35003567
    35013568  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     
    35103577    size++;
    35113578  }
    3512  
     3579
    35133580  // create the bonds between all: Make it an induced subgraph and add hydrogen
    35143581//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     
    35203587    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    35213588      // create all bonds
    3522       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 
     3589      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    35233590        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    35243591//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    35253592        if (SonList[OtherFather->nr] != NULL) {
    3526 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 
     3593//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    35273594          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    35283595//            *out << Verbose(3) << "Adding Bond: ";
    3529 //            *out << 
     3596//            *out <<
    35303597            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    35313598//            *out << "." << endl;
    35323599            //NumBonds[Runner->nr]++;
    3533           } else { 
     3600          } else {
    35343601//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    35353602          }
    35363603          LonelyFlag = false;
    35373604        } else {
    3538 //          *out << ", who has no son in this fragment molecule." << endl; 
     3605//          *out << ", who has no son in this fragment molecule." << endl;
    35393606#ifdef ADDHYDROGEN
    35403607          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
     
    35543621    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    35553622      Runner = Runner->next;
    3556 #endif       
     3623#endif
    35573624  }
    35583625  Leaf->CreateListOfBondsPerAtom(out);
     
    35873654  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    35883655  StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack!
    3589   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 
     3656  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
    35903657  MoleculeListClass *FragmentList = NULL;
    35913658  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     
    36373704                // clear snake stack
    36383705          SnakeStack->ClearStack();
    3639     //SnakeStack->TestImplementation(out, start->next);   
     3706    //SnakeStack->TestImplementation(out, start->next);
    36403707
    36413708    ///// INNER LOOP ////////////
     
    36583725        }
    36593726        if (ShortestPathList[Walker->nr] == -1) {
    3660           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 
     3727          ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
    36613728          TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    36623729        }
     
    36963763                                OtherAtom = Binder->GetOtherAtom(Walker);
    36973764            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    3698               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 
     3765              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    36993766              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    37003767            } else { // otherwise check its colour and element
    37013768                                if (
    37023769#ifdef ADDHYDROGEN
    3703               (OtherAtom->type->Z != 1) && 
     3770              (OtherAtom->type->Z != 1) &&
    37043771#endif
    37053772                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     
    37113778                //} else {
    37123779                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    3713                 //} 
     3780                //}
    37143781                Walker = OtherAtom;
    37153782                break;
    37163783              } else {
    3717                 if (OtherAtom->type->Z == 1) 
     3784                if (OtherAtom->type->Z == 1)
    37183785                  *out << "Links to a hydrogen atom." << endl;
    3719                 else                 
     3786                else
    37203787                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    37213788              }
     
    37273794          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    37283795        }
    3729                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black 
     3796                        if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
    37303797          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    37313798                                ColorVertexList[Walker->nr] = black;
     
    37343801      }
    37353802        } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    3736     *out << Verbose(2) << "Inner Looping is finished." << endl;   
     3803    *out << Verbose(2) << "Inner Looping is finished." << endl;
    37373804
    37383805    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     
    37503817    }
    37513818  }
    3752   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 
     3819  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
    37533820
    37543821  // copy together
    3755   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 
     3822  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
    37563823  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    37573824  RunningIndex = 0;
     
    38243891
    38253892  NumCombinations = 1 << SetDimension;
    3826  
     3893
    38273894  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    38283895  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    38293896  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3830  
     3897
    38313898  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    38323899  *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " <<  NumCombinations-1 << " combination(s)." << endl;
    38333900
    3834   // initialised touched list (stores added atoms on this level) 
     3901  // initialised touched list (stores added atoms on this level)
    38353902  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    38363903  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    38373904    TouchedList[TouchedIndex] = -1;
    38383905  TouchedIndex = 0;
    3839  
     3906
    38403907  // create every possible combination of the endpieces
    38413908  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     
    38453912    for (int j=SetDimension;j--;)
    38463913      bits += (i & (1 << j)) >> j;
    3847      
     3914
    38483915    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    38493916    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     
    38533920        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    38543921        if (bit) {  // if bit is set, we add this bond partner
    3855                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add 
     3922                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    38563923          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    38573924          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3858           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 
     3925          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    38593926          if (TestKeySetInsert.second) {
    38603927            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     
    38693936        }
    38703937      }
    3871      
    3872       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 
     3938
     3939      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    38733940      if (SpaceLeft > 0) {
    38743941        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     
    38983965          }
    38993966          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3900           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 
     3967          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    39013968          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    39023969        }
     
    39073974        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    39083975        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3909           *out << (*runner) << " "; 
     3976          *out << (*runner) << " ";
    39103977        *out << endl;
    39113978        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     
    39153982        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    39163983      }
    3917      
     3984
    39183985      // --3-- remove all added items in this level from snake stack
    39193986      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     
    39263993      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    39273994      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3928         *out << (*runner) << " "; 
     3995        *out << (*runner) << " ";
    39293996      *out << endl;
    39303997      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     
    39334000    }
    39344001  }
    3935   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 
     4002  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    39364003  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    39374004};
     
    39424009 * \return true - connected, false - disconnected
    39434010 * \note this is O(n^2) for it's just a bug checker not meant for permanent use!
    3944  */ 
     4011 */
    39454012bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    39464013{
     
    39484015  bool BondStatus = false;
    39494016  int size;
    3950  
     4017
    39514018  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    39524019  *out << Verbose(2) << "Disconnected atom: ";
    3953  
     4020
    39544021  // count number of atoms in graph
    39554022  size = 0;
     
    39974064 * \param *out output stream for debugging
    39984065 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation
    3999  * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 
     4066 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on
    40004067 * \param RestrictedKeySet Restricted vertex set to use in context of molecule
    40014068 * \return number of inserted fragments
    40024069 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore
    40034070 */
    4004 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 
     4071int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    40054072{
    40064073  int SP, AtomKeyNr;
     
    40234090    FragmentSearch.BondsPerSPCount[i] = 0;
    40244091  FragmentSearch.BondsPerSPCount[0] = 1;
    4025   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 
     4092  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    40264093  add(Binder, FragmentSearch.BondsPerSPList[1]);
    4027  
     4094
    40284095  // do a BFS search to fill the SP lists and label the found vertices
    40294096  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    40304097  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    40314098  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4032   // (EdgeinSPLevel) of this tree ... 
     4099  // (EdgeinSPLevel) of this tree ...
    40334100  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    40344101  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     
    40834150    }
    40844151  }
    4085  
     4152
    40864153  // outputting all list for debugging
    40874154  *out << Verbose(0) << "Printing all found lists." << endl;
     
    40924159      Binder = Binder->next;
    40934160      *out << Verbose(2) << *Binder << endl;
    4094     } 
    4095   }
    4096  
     4161    }
     4162  }
     4163
    40974164  // creating fragments with the found edge sets  (may be done in reverse order, faster)
    40984165  SP = -1;  // the Root <-> Root edge must be subtracted!
     
    41014168    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    41024169      Binder = Binder->next;
    4103       SP ++; 
     4170      SP ++;
    41044171    }
    41054172  }
     
    41084175    // start with root (push on fragment stack)
    41094176    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4110     FragmentSearch.FragmentSet->clear(); 
     4177    FragmentSearch.FragmentSet->clear();
    41114178    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    41124179    // prepare the subset and call the generator
    41134180    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    41144181    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4115    
     4182
    41164183    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4117    
     4184
    41184185    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    41194186  } else {
     
    41244191  // remove root from stack
    41254192  *out << Verbose(0) << "Removing root again from stack." << endl;
    4126   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);   
     4193  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    41274194
    41284195  // free'ing the bonds lists
     
    41434210  }
    41444211
    4145   // return list 
     4212  // return list
    41464213  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    41474214  return (FragmentSearch.FragmentCounter - Counter);
     
    41744241    // remove bonds that are beyond bonddistance
    41754242    for(int i=NDIM;i--;)
    4176       Translationvector.x[i] = 0.; 
     4243      Translationvector.x[i] = 0.;
    41774244    // scan all bonds
    41784245    Binder = first;
     
    42214288        }
    42224289      }
    4223       // re-add bond   
     4290      // re-add bond
    42244291      link(Binder, OtherBinder);
    42254292    } else {
     
    42754342        IteratorB++;
    42764343      } // end of while loop
    4277     }// end of check in case of equal sizes 
     4344    }// end of check in case of equal sizes
    42784345  }
    42794346  return false; // if we reach this point, they are equal
     
    43194386 * \param graph1 first (dest) graph
    43204387 * \param graph2 second (source) graph
    4321  * \param *counter keyset counter that gets increased 
     4388 * \param *counter keyset counter that gets increased
    43224389 */
    43234390inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
     
    43644431  int RootKeyNr, RootNr;
    43654432  struct UniqueFragments FragmentSearch;
    4366  
     4433
    43674434  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    43684435
     
    43874454    Walker = Walker->next;
    43884455    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4389   } 
     4456  }
    43904457
    43914458  // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as
     
    44014468    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    44024469    //  *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl;
    4403     //} else 
     4470    //} else
    44044471    {
    44054472      // increase adaptive order by one
    44064473      Walker->GetTrueFather()->AdaptiveOrder++;
    44074474      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4408  
     4475
    44094476      // initialise Order-dependent entries of UniqueFragments structure
    44104477      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     
    44134480        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    44144481        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    4415         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two 
     4482        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two
    44164483        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    44174484        FragmentSearch.BondsPerSPCount[i] = 0;
    4418       } 
    4419  
     4485      }
     4486
    44204487      // allocate memory for all lower level orders in this 1D-array of ptrs
    44214488      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     
    44234490      for (int i=0;i<NumLevels;i++)
    44244491        FragmentLowerOrdersList[RootNr][i] = NULL;
    4425      
     4492
    44264493      // create top order where nothing is reduced
    44274494      *out << Verbose(0) << "==============================================================================================================" << endl;
    44284495      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4429  
     4496
    44304497      // Create list of Graphs of current Bond Order (i.e. F_{ij})
    44314498      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     
    44404507        // we don't have to dive into suborders! These keysets are all already created on lower orders!
    44414508        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4442        
     4509
    44434510//        if ((NumLevels >> 1) > 0) {
    44444511//          // create lower order fragments
     
    44474514//          for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again)
    44484515//            // step down to next order at (virtual) boundary of powers of 2 in array
    4449 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
     4516//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    44504517//              Order--;
    44514518//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     
    44544521//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    44554522//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    4456 //       
     4523//
    44574524//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    44584525//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     
    44854552      RootStack.push_back(RootKeyNr); // put back on stack
    44864553      RootNr++;
    4487  
     4554
    44884555      // free Order-dependent entries of UniqueFragments structure for next loop cycle
    44894556      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     
    44914558        delete(FragmentSearch.BondsPerSPList[2*i]);
    44924559        delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4493       } 
     4560      }
    44944561      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    44954562    }
     
    45024569  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    45034570  delete(FragmentSearch.FragmentSet);
    4504  
    4505   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 
     4571
     4572  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    45064573  // 5433222211111111
    45074574  // 43221111
     
    45234590    RootKeyNr = RootStack.front();
    45244591    RootStack.pop_front();
    4525     Walker = FindAtom(RootKeyNr); 
     4592    Walker = FindAtom(RootKeyNr);
    45264593    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    45274594    for(int i=0;i<NumLevels;i++) {
     
    45364603  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    45374604  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4538  
     4605
    45394606  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    45404607};
     
    45704637  atom *Walker = NULL;
    45714638  bool result = true; // status of comparison
    4572  
    4573   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 
     4639
     4640  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    45744641  /// first count both their atoms and elements and update lists thereby ...
    45754642  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     
    46184685    if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    46194686      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4620       result = false; 
    4621     }
    4622   }
    4623  
     4687      result = false;
     4688    }
     4689  }
     4690
    46244691  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    46254692  if (result) {
     
    46374704      OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    46384705    }
    4639  
     4706
    46404707    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    46414708    *out << Verbose(5) << "Sorting distances" << endl;
     
    46484715    for(int i=AtomCount;i--;)
    46494716      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4650    
     4717
    46514718    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    46524719    *out << Verbose(4) << "Comparing distances" << endl;
     
    46594726    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    46604727    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4661      
     4728
    46624729    /// free memory
    46634730    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     
    46674734      result = false;
    46684735    }
    4669   } 
     4736  }
    46704737  /// return pointer to map if all distances were below \a threshold
    46714738  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     
    46764743    *out << Verbose(3) << "Result: Not equal." << endl;
    46774744    return NULL;
    4678   } 
     4745  }
    46794746};
    46804747
     
    47314798 * \param *output output stream of temperature file
    47324799 * \return file written (true), failure on writing file (false)
    4733  */ 
     4800 */
    47344801bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    47354802{
     
    47394806  if (output == NULL)
    47404807    return false;
    4741   else 
     4808  else
    47424809    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    47434810  for (int step=startstep;step < endstep; step++) { // loop over all time steps
  • TabularUnified src/molecules.hpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    11/** \file molecules.hpp
    22 *
    3  * Class definitions of atom and molecule, element and periodentafel 
     3 * Class definitions of atom and molecule, element and periodentafel
    44 */
    55
     
    5454#define BoundariesTestPair pair< Boundaries::iterator, bool>
    5555
    56 #define PointMap map < int, class BoundaryPointSet * > 
    57 #define PointPair pair < int, class BoundaryPointSet * > 
    58 #define PointTestPair pair < PointMap::iterator, bool > 
    59 
    60 #define LineMap map < int, class BoundaryLineSet * > 
    61 #define LinePair pair < int, class BoundaryLineSet * > 
    62 #define LineTestPair pair < LinePair::iterator, bool >
    63 
    64 #define TriangleMap map < int, class BoundaryTriangleSet * > 
    65 #define TrianglePair pair < int, class BoundaryTriangleSet * > 
    66 #define TriangleTestPair pair < TrianglePair::iterator, bool > 
     56#define PointMap map < int, class BoundaryPointSet * >
     57#define PointPair pair < int, class BoundaryPointSet * >
     58#define PointTestPair pair < PointMap::iterator, bool >
     59
     60#define LineMap map < int, class BoundaryLineSet * >
     61#define LinePair pair < int, class BoundaryLineSet * >
     62#define LineTestPair pair < LineMap::iterator, bool >
     63
     64#define TriangleMap map < int, class BoundaryTriangleSet * >
     65#define TrianglePair pair < int, class BoundaryTriangleSet * >
     66#define TriangleTestPair pair < TrianglePair::iterator, bool >
    6767
    6868#define DistanceMultiMap multimap <double, pair < PointMap::iterator, PointMap::iterator> >
     
    8686//bool operator < (KeySet SubgraphA, KeySet SubgraphB);   //note: this declaration is important, otherwise normal < is used (producing wrong order)
    8787inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment); // Insert a KeySet into a Graph
    88 inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph 
     88inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph
    8989int CompareDoubles (const void * a, const void * b);
    9090
     
    140140    unsigned char AdaptiveOrder;  //!< current present bond order at site (0 means "not set")
    141141    bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
    142  
     142
    143143  atom();
    144144  ~atom();
    145  
     145
    146146  bool Output(int ElementNo, int AtomNo, ofstream *out) const;
    147147  bool OutputXYZLine(ofstream *out) const;
    148148  atom *GetTrueFather();
    149149  bool Compare(atom &ptr);
    150  
     150
    151151  private:
    152152};
     
    169169    int nr;           //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
    170170    bool Cyclic;      //!< flag whether bond is part of a cycle or not, given in DepthFirstSearchAnalysis()
    171     enum EdgeType Type;//!< whether this is a tree or back edge 
    172        
     171    enum EdgeType Type;//!< whether this is a tree or back edge
     172
    173173  atom * GetOtherAtom(atom *Atom) const;
    174174  bond * GetFirstBond();
    175175  bond * GetLastBond();
    176  
     176
    177177  bool MarkUsed(enum Shading color);
    178178  enum Shading IsUsed();
     
    180180  bool Contains(const atom *ptr);
    181181  bool Contains(const int nr);
    182  
     182
    183183  bond();
    184184  bond(atom *left, atom *right);
     
    186186  bond(atom *left, atom *right, int degree, int number);
    187187  ~bond();
    188    
    189   private: 
     188
     189  private:
    190190    enum Shading Used;        //!< marker in depth-first search, DepthFirstSearchAnalysis()
    191191};
     
    218218    int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    219219    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
    220  
     220
    221221  molecule(periodentafel *teil);
    222222  ~molecule();
    223  
     223
    224224  /// remove atoms from molecule.
    225225  bool AddAtom(atom *pointer);
     
    230230  atom * AddCopyAtom(atom *pointer);
    231231  bool AddXYZFile(string filename);
    232   bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem); 
     232  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
    233233  bond * AddBond(atom *first, atom *second, int degree);
    234234  bool RemoveBond(bond *pointer);
    235235  bool RemoveBonds(atom *BondPartner);
    236    
     236
    237237  /// Find atoms.
    238   atom * FindAtom(int Nr) const; 
     238  atom * FindAtom(int Nr) const;
    239239  atom * AskAtom(string text);
    240240
     
    244244  void CalculateOrbitals(class config &configuration);
    245245  bool CenterInBox(ofstream *out, Vector *BoxLengths);
    246   void CenterEdge(ofstream *out, Vector *max); 
    247   void CenterOrigin(ofstream *out, Vector *max); 
     246  void CenterEdge(ofstream *out, Vector *max);
     247  void CenterOrigin(ofstream *out, Vector *max);
    248248  void CenterGravity(ofstream *out, Vector *max);
    249249  void Translate(const Vector *x);
     
    260260        double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    261261        bool VerletForceIntegration(char *file, double delta_t, bool IsAngstroem);
    262        
     262
    263263  bool CheckBounds(const Vector *x) const;
    264264  void GetAlignvector(struct lsq_params * par) const;
    265265
    266   /// Initialising routines in fragmentation 
     266  /// Initialising routines in fragmentation
     267  void CreateAdjacencyList2(ofstream *out, ifstream *output);
    267268  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    268269  void CreateListOfBondsPerAtom(ofstream *out);
    269  
     270
    270271  // Graph analysis
    271272  MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
     
    283284
    284285  molecule *CopyMolecule();
    285  
     286
    286287  /// Fragment molecule by two different approaches:
    287288  int FragmentMolecule(ofstream *out, int Order, config *configuration);
     
    305306  int LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList);
    306307  int GuesstimateFragmentCount(ofstream *out, int order);
    307          
    308   // Recognize doubly appearing molecules in a list of them   
     308
     309  // Recognize doubly appearing molecules in a list of them
    309310  int * IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold);
    310311  int * GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule);
    311        
     312
    312313  // Output routines.
    313314  bool Output(ofstream *out);
     
    330331    int NumberOfMolecules;        //!< Number of entries in \a **FragmentList and of to be returned one.
    331332    int NumberOfTopAtoms;         //!< Number of atoms in the molecule from which all fragments originate
    332    
     333
    333334  MoleculeListClass();
    334335  MoleculeListClass(int Num, int NumAtoms);
     
    340341  bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex);
    341342  void Output(ofstream *out);
    342  
     343
    343344  private:
    344345};
     
    350351class MoleculeLeafClass {
    351352  public:
    352     molecule *Leaf;                   //!< molecule of this leaf 
     353    molecule *Leaf;                   //!< molecule of this leaf
    353354    //MoleculeLeafClass *UpLeaf;        //!< Leaf one level up
    354355    //MoleculeLeafClass *DownLeaf;      //!< First leaf one level down
     
    386387    bool FastParsing;
    387388    double Deltat;
    388    
     389
    389390    private:
    390391    char *mainname;
    391392    char *defaultpath;
    392393    char *pseudopotpath;
    393    
     394
    394395    int DoOutVis;
    395396    int DoOutMes;
     
    406407    int UseAddGramSch;
    407408    int Seed;
    408    
     409
    409410    int MaxOuterStep;
    410411    int OutVisStep;
     
    414415    int MaxPsiStep;
    415416    double EpsWannier;
    416    
     417
    417418    int MaxMinStep;
    418419    double RelEpsTotalEnergy;
     
    423424    double InitRelEpsKineticEnergy;
    424425    int InitMaxMinGapStopStep;
    425    
     426
    426427    //double BoxLength[NDIM*NDIM];
    427    
     428
    428429    double ECut;
    429430    int MaxLevel;
     
    434435    int RTActualUse;
    435436    int AddPsis;
    436    
     437
    437438    double RCut;
    438439    int StructOpt;
     
    441442    int MaxTypes;
    442443
    443  
     444
    444445  int ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
    445  
     446
    446447  public:
    447448  config();
  • src/orbitals.db

    • Property mode changed from 100644 to 100755
  • src/parser.cpp

    • Property mode changed from 100644 to 100755
  • src/parser.hpp

    • Property mode changed from 100644 to 100755
  • TabularUnified src/periodentafel.cpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    11/** \file periodentafel.cpp
    2  * 
     2 *
    33 * Function implementations for the class periodentafel.
    4  * 
     4 *
    55 */
    66
     
    1414 * Initialises start and end of list and resets periodentafel::checkliste to false.
    1515 */
    16 periodentafel::periodentafel() 
    17 { 
    18   start = new element; 
    19   end = new element; 
    20   start->previous = NULL; 
    21   start->next = end; 
    22   end->previous = start; 
     16periodentafel::periodentafel()
     17{
     18  start = new element;
     19  end = new element;
     20  start->previous = NULL;
     21  start->next = end;
     22  end->previous = start;
    2323  end->next = NULL;
    2424};
     
    2727 * Removes every element and afterwards deletes start and end of list.
    2828 */
    29 periodentafel::~periodentafel() 
    30 { 
    31   CleanupPeriodtable(); 
    32   delete(end); 
    33   delete(start); 
    34 }; 
     29periodentafel::~periodentafel()
     30{
     31  CleanupPeriodtable();
     32  delete(end);
     33  delete(start);
     34};
    3535
    3636/** Adds element to period table list
     
    3838 * \return true - succeeded, false - does not occur
    3939 */
    40 bool periodentafel::AddElement(element *pointer) 
    41 { 
     40bool periodentafel::AddElement(element *pointer)
     41{
    4242  pointer->sort = &pointer->Z;
    4343  if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
    4444    cout << Verbose(0) << "Invalid Z number!\n";
    45   return add(pointer, end); 
     45  return add(pointer, end);
    4646};
    4747
     
    5050 * \return true - succeeded, false - element not found
    5151 */
    52 bool periodentafel::RemoveElement(element *pointer) 
    53 { 
    54   return remove(pointer, start, end); 
     52bool periodentafel::RemoveElement(element *pointer)
     53{
     54  return remove(pointer, start, end);
    5555};
    5656
     
    5858 * \return true - succeeded, false - does not occur
    5959 */
    60 bool periodentafel::CleanupPeriodtable() 
    61 { 
    62   return cleanup(start,end); 
     60bool periodentafel::CleanupPeriodtable()
     61{
     62  return cleanup(start,end);
    6363};
    6464
     
    7676    cout << Verbose(0) << "Mass: " << endl;
    7777    cin >> walker->mass;
    78     walker->Z = Z; 
    79     cout << Verbose(0) << "Atomic number: " << walker->Z << endl; 
     78    walker->Z = Z;
     79    cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
    8080    cout << Verbose(0) << "Name [max 64 chars]: " << endl;
    8181    cin >> walker->name;
     
    105105/** Asks for element number and returns pointer to element
    106106 */
    107 element * periodentafel::AskElement() 
     107element * periodentafel::AskElement()
    108108{
    109109  element *walker = NULL;
     
    117117};
    118118
    119 
    120119/** Prints period table to given stream.
    121120 * \param output stream
    122  */ 
     121 */
    123122bool periodentafel::Output(ofstream *output) const
    124123{
     
    131130    }
    132131    return result;
    133   } else 
     132  } else
    134133    return false;
    135134};
     
    138137 * \param *output output stream
    139138 * \param *checkliste elements table for this molecule
    140  */ 
     139 */
    141140bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
    142141{
     
    152151      if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    153152        walker->No = No;
    154         result = result && walker->Checkout(output, No++, checkliste[walker->Z]);     
     153        result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
    155154      }
    156155    }
    157156    return result;
    158   } else 
     157  } else
    159158    return false;
    160159};
    161 
    162160
    163161/** Loads element list from file.
     
    171169  bool status = true;
    172170  bool otherstatus = true;
    173   char *filename = new char[MAXSTRINGSIZE];
    174  
     171  char filename[255];
     172
    175173  // fill elements DB
    176174  strncpy(filename, path, MAXSTRINGSIZE);
     
    225223  if (infile != NULL) {
    226224    while (!infile.eof()) {
    227         infile >> tmp;
    228         infile >> ws;
    229         infile >> FindElement((int)tmp)->Valence;
    230         infile >> ws;
    231         //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
     225      infile >> tmp;
     226      infile >> ws;
     227      infile >> FindElement((int)tmp)->Valence;
     228      infile >> ws;
     229      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
    232230    }
    233231    infile.close();
     
    253251  } else
    254252    otherstatus = false;
    255  
     253
    256254  // fill H-BondDistance DB per element
    257255  strncpy(filename, path, MAXSTRINGSIZE);
     
    261259  if (infile != NULL) {
    262260    while (!infile.eof()) {
    263         infile >> tmp;
     261      infile >> tmp;
    264262      ptr = FindElement((int)tmp);
    265         infile >> ws;
     263      infile >> ws;
    266264      infile >> ptr->HBondDistance[0];
    267265      infile >> ptr->HBondDistance[1];
    268266      infile >> ptr->HBondDistance[2];
    269         infile >> ws;
     267      infile >> ws;
    270268      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    271269    }
     
    274272  } else
    275273    otherstatus = false;
    276  
     274
    277275  // fill H-BondAngle DB per element
    278276  strncpy(filename, path, MAXSTRINGSIZE);
     
    294292  } else
    295293    otherstatus = false;
    296  
     294
    297295  if (!otherstatus)
    298296    cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
    299  
     297
    300298  return status;
    301299};
     
    308306  ofstream f;
    309307  char filename[MAXSTRINGSIZE];
    310  
     308
    311309  strncpy(filename, path, MAXSTRINGSIZE);
    312310  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
  • src/periodentafel.hpp

    • Property mode changed from 100644 to 100755
  • src/stackclass.hpp

    • Property mode changed from 100644 to 100755
  • src/valence.db

    • Property mode changed from 100644 to 100755
  • TabularUnified src/vector.cpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    11/** \file vector.cpp
    2  * 
     2 *
    33 * Function implementations for the class vector.
    4  * 
    5  */
    6  
     4 *
     5 */
     6
    77#include "molecules.hpp"
    8  
     8
    99
    1010/************************************ Functions for class vector ************************************/
     
    2121 */
    2222Vector::~Vector() {};
     23
     24/** Calculates square of distance between this and another vector.
     25 * \param *y array to second vector
     26 * \return \f$| x - y |^2\f$
     27 */
     28double Vector::DistanceSquared(const Vector *y) const
     29{
     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);
     34};
    2335
    2436/** Calculates distance between this and another vector.
    2537 * \param *y array to second vector
    26  * \return \f$| x - y |^2\f$
     38 * \return \f$| x - y |\f$
    2739 */
    2840double Vector::Distance(const Vector *y) const
     
    3143  for (int i=NDIM;i--;)
    3244    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33   return (res); 
     45  return (sqrt(res));
    3446};
    3547
     
    6981        if (tmp < res) res = tmp;
    7082      }
    71   return (res); 
     83  return (res);
    7284};
    7385
     
    112124  for (int i=NDIM;i--;)
    113125    res += x[i]*y->x[i];
    114   return (res); 
    115 };
     126  return (res);
     127};
     128
     129
     130/** 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&
     135 */
     136void Vector::VectorProduct(const Vector *y)
     137{
     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);
     143
     144};
     145
    116146
    117147/** projects this vector onto plane defined by \a *y.
    118  * \param *y array to normal vector of plane
     148 * \param *y normal vector of plane
    119149 * \return \f$\langle x, y \rangle\f$
    120150 */
     
    123153  Vector tmp;
    124154  tmp.CopyVector(y);
    125   tmp.Scale(Projection(y));
     155  tmp.Normalize();
     156  tmp.Scale(ScalarProduct(&tmp));
    126157  this->SubtractVector(&tmp);
    127158};
     
    144175  for (int i=NDIM;i--;)
    145176    res += this->x[i]*this->x[i];
    146   return (sqrt(res)); 
     177  return (sqrt(res));
    147178};
    148179
     
    178209 */
    179210void Vector::Init(double x1, double x2, double x3)
    180 { 
     211{
    181212  x[0] = x1;
    182213  x[1] = x2;
     
    188219 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
    189220 */
    190 double Vector::Angle(Vector *y) const
    191 {
    192   return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 
     221double Vector::Angle(const Vector *y) const
     222{
     223  return acos(this->ScalarProduct(y)/Norm()/y->Norm());
    193224};
    194225
     
    238269
    239270/** Sums two vectors \a  and \b component-wise.
    240  * \param a first vector 
     271 * \param a first vector
    241272 * \param b second vector
    242273 * \return a + b
     
    251282
    252283/** Factors given vector \a a times \a m.
    253  * \param a vector 
     284 * \param a vector
    254285 * \param m factor
    255286 * \return a + b
     
    282313};
    283314
    284 ofstream& operator<<(ofstream& ost,Vector& m)
    285 {
    286         m.Output(&ost);
     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 */
     320ostream& operator<<(ostream& ost,Vector& m)
     321{
     322  ost << "(";
     323  for (int i=0;i<NDIM;i++) {
     324    ost << m.x[i];
     325    if (i != 2)
     326      ost << ",";
     327  }
     328  ost << ")";
    287329        return ost;
    288330};
     
    309351};
    310352
    311 /** Translate atom by given vector. 
     353/** Translate atom by given vector.
    312354 * \param trans[] translation vector.
    313355 */
     
    316358  for (int i=NDIM;i--;)
    317359    x[i] += trans->x[i];
    318 }; 
     360};
    319361
    320362/** Do a matrix multiplication.
     
    355397    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    356398    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    357  
     399
    358400    // do the matrix multiplication
    359401    C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     
    379421{
    380422  for(int i=NDIM;i--;)
    381     x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 
    382 };
    383 
    384 /** Mirrors atom against a given plane. 
     423    x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
     424};
     425
     426/** Mirrors atom against a given plane.
    385427 * \param n[] normal vector of mirror plane.
    386428 */
     
    398440  Output((ofstream *)&cout);
    399441  cout << endl;
    400 }; 
     442};
    401443
    402444/** Calculates normal vector for three given vectors (being three points in space).
     
    430472  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    431473  Normalize();
    432  
     474
    433475  return true;
    434476};
     
    488530/** Creates this vector as one of the possible orthonormal ones to the given one.
    489531 * Just scan how many components of given *vector are unequal to zero and
    490  * try to get the skp of both to be zero accordingly. 
     532 * try to get the skp of both to be zero accordingly.
    491533 * \param *vector given vector
    492534 * \return true - success, false - failure (null vector given)
     
    509551      Components[Last++] = j;
    510552  cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    511        
     553
    512554  switch(Last) {
    513555    case 3:  // threecomponent system
     
    522564    case 1: // one component system
    523565      // set sole non-zero component to 0, and one of the other zero component pendants to 1
    524       x[(Components[0]+2)%NDIM] = 0.;   
    525       x[(Components[0]+1)%NDIM] = 1.;   
    526       x[Components[0]] = 0.;   
     566      x[(Components[0]+2)%NDIM] = 0.;
     567      x[(Components[0]+1)%NDIM] = 1.;
     568      x[Components[0]] = 0.;
    527569      return true;
    528570      break;
     
    541583{
    542584//  cout << Verbose(3) << "For comparison: ";
    543 //  cout << "A " << A->Projection(this) << "\t"; 
    544 //  cout << "B " << B->Projection(this) << "\t"; 
    545 //  cout << "C " << C->Projection(this) << "\t"; 
     585//  cout << "A " << A->Projection(this) << "\t";
     586//  cout << "B " << B->Projection(this) << "\t";
     587//  cout << "C " << C->Projection(this) << "\t";
    546588//  cout << endl;
    547589  return A->Projection(this);
     
    553595 * \return true if success, false if failed due to linear dependency
    554596 */
    555 bool Vector::LSQdistance(Vector **vectors, int num) 
     597bool Vector::LSQdistance(Vector **vectors, int num)
    556598{
    557599        int j;
    558                                
     600
    559601        for (j=0;j<num;j++) {
    560602                cout << Verbose(1) << j << "th atom's vector: ";
     
    565607  int np = 3;
    566608        struct LSQ_params par;
    567    
     609
    568610   const gsl_multimin_fminimizer_type *T =
    569611     gsl_multimin_fminimizer_nmsimplex;
     
    571613   gsl_vector *ss, *y;
    572614   gsl_multimin_function minex_func;
    573  
     615
    574616   size_t iter = 0, i;
    575617   int status;
    576618   double size;
    577  
     619
    578620   /* Initial vertex size vector */
    579621   ss = gsl_vector_alloc (np);
    580622   y = gsl_vector_alloc (np);
    581  
     623
    582624   /* Set all step sizes to 1 */
    583625   gsl_vector_set_all (ss, 1.0);
    584  
     626
    585627   /* Starting point */
    586628   par.vectors = vectors;
    587629         par.num = num;
    588        
     630
    589631         for (i=NDIM;i--;)
    590                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 
    591          
     632                gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     633
    592634   /* Initialize method and iterate */
    593635   minex_func.f = &LSQ;
    594636   minex_func.n = np;
    595637   minex_func.params = (void *)&par;
    596  
     638
    597639   s = gsl_multimin_fminimizer_alloc (T, np);
    598640   gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    599  
     641
    600642   do
    601643     {
    602644       iter++;
    603645       status = gsl_multimin_fminimizer_iterate(s);
    604  
     646
    605647       if (status)
    606648         break;
    607  
     649
    608650       size = gsl_multimin_fminimizer_size (s);
    609651       status = gsl_multimin_test_size (size, 1e-2);
    610  
     652
    611653       if (status == GSL_SUCCESS)
    612654         {
    613655           printf ("converged to minimum at\n");
    614656         }
    615  
     657
    616658       printf ("%5d ", (int)iter);
    617659       for (i = 0; i < (size_t)np; i++)
     
    622664     }
    623665   while (status == GSL_CONTINUE && iter < 100);
    624  
     666
    625667  for (i=(size_t)np;i--;)
    626668    this->x[i] = gsl_vector_get(s->x, i);
     
    688730 * \param alpha first angle
    689731 * \param beta second angle
    690  * \param c norm of final vector 
     732 * \param c norm of final vector
    691733 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c.
    692  * \bug this is not yet working properly 
     734 * \bug this is not yet working properly
    693735 */
    694736bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
     
    706748  if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    707749    if (fabs(x1->x[1]) > MYEPSILON) {
    708       flag = 1;   
     750      flag = 1;
    709751    } else if (fabs(x1->x[2]) > MYEPSILON) {
    710752       flag = 2;
     
    739781  // now comes the case system
    740782  D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    741   D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 
     783  D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
    742784  D3 = y->x[0]/x1->x[0]*A-B1;
    743785  cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    744786  if (fabs(D1) < MYEPSILON) {
    745     cout << Verbose(2) << "D1 == 0!\n"; 
     787    cout << Verbose(2) << "D1 == 0!\n";
    746788    if (fabs(D2) > MYEPSILON) {
    747       cout << Verbose(3) << "D2 != 0!\n"; 
     789      cout << Verbose(3) << "D2 != 0!\n";
    748790      x[2] = -D3/D2;
    749791      E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     
    755797      cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    756798      if (fabs(F1) < MYEPSILON) {
    757         cout << Verbose(4) << "F1 == 0!\n"; 
     799        cout << Verbose(4) << "F1 == 0!\n";
    758800        cout << Verbose(4) << "Gleichungssystem linear\n";
    759         x[1] = F3/(2.*F2); 
     801        x[1] = F3/(2.*F2);
    760802      } else {
    761803        p = F2/F1;
    762804        q = p*p - F3/F1;
    763         cout << Verbose(4) << "p " << p << "\tq " << q << endl; 
     805        cout << Verbose(4) << "p " << p << "\tq " << q << endl;
    764806        if (q < 0) {
    765807          cout << Verbose(4) << "q < 0" << endl;
     
    782824    cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    783825    if (fabs(F1) < MYEPSILON) {
    784       cout << Verbose(3) << "F1 == 0!\n"; 
     826      cout << Verbose(3) << "F1 == 0!\n";
    785827      cout << Verbose(3) << "Gleichungssystem linear\n";
    786       x[2] = F3/(2.*F2);     
     828      x[2] = F3/(2.*F2);
    787829    } else {
    788830      p = F2/F1;
    789831      q = p*p - F3/F1;
    790       cout << Verbose(3) << "p " << p << "\tq " << q << endl; 
     832      cout << Verbose(3) << "p " << p << "\tq " << q << endl;
    791833      if (q < 0) {
    792834        cout << Verbose(3) << "q < 0" << endl;
     
    832874    }
    833875    cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    834     // apply sign matrix 
     876    // apply sign matrix
    835877    for (j=NDIM;j--;)
    836878      x[j] *= sign[j];
     
    838880    ang = x2->Angle (this);
    839881    cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    840     if (fabs(ang - cos(beta)) < MYEPSILON) { 
     882    if (fabs(ang - cos(beta)) < MYEPSILON) {
    841883      break;
    842884    }
  • TabularUnified src/vector.hpp

    • Property mode changed from 100644 to 100755
    r674220 ra98603  
    77 * basically, just a x[3] but with helpful functions
    88 */
    9 class Vector {   
     9class Vector {
    1010  public:
    1111    double x[NDIM];
     
    1616
    1717  double Distance(const Vector *y) const;
     18  double DistanceSquared(const Vector *y) const;
    1819  double PeriodicDistance(const Vector *y, const double *cell_size) const;
    1920  double ScalarProduct(const Vector *y) const;
    2021  double Projection(const Vector *y) const;
    2122  double Norm() const ;
    22   double Angle(Vector *y) const;
     23  double Angle(const Vector *y) const;
    2324
    2425  void AddVector(const Vector *y);
     
    2627  void CopyVector(const Vector *y);
    2728  void RotateVector(const Vector *y, const double alpha);
     29  void VectorProduct(const Vector *y);
    2830  void ProjectOntoPlane(const Vector *y);
    29   void Zero(); 
     31  void Zero();
    3032  void One(double one);
    3133  void Init(double x1, double x2, double x3);
     
    4042  void KeepPeriodic(ofstream *out, double *matrix);
    4143  void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    42  
     44
    4345  double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    4446  bool GetOneNormalVector(const Vector *x1);
     
    5355};
    5456
    55 ofstream& operator<<(ofstream& ost, Vector& m);
    56 Vector& operator+=(Vector& a, const Vector& b);
    57 Vector& operator*=(Vector& a, const double m);
    58 Vector& operator*(const Vector& a, const double m);
    59 Vector& operator+(const Vector& a, const Vector& b);
     57ostream & operator << (ostream& ost, Vector &m);
     58//Vector& operator+=(Vector& a, const Vector& b);
     59//Vector& operator*=(Vector& a, const double m);
     60//Vector& operator*(const Vector& a, const double m);
     61//Vector& operator+(const Vector& a, const Vector& b);
    6062
    6163#endif /*VECTOR_HPP_*/
  • src/verbose.cpp

    • Property mode changed from 100644 to 100755
Note: See TracChangeset for help on using the changeset viewer.