Changeset ce5ac3


Ignore:
Timestamp:
Jul 23, 2009, 12:32:48 PM (15 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:
d067d45
Parents:
986c80
Message:

Fix indentation from tabs to two spaces to prepare merging with MultipleMolecules

Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/atom.cpp

    r986c80 rce5ac3  
    1313atom::atom()
    1414{
    15         Name = NULL;
     15  Name = NULL;
    1616  previous = NULL;
    1717  next = NULL;
     
    3535atom::~atom()
    3636{
    37         Free((void **)&Name, "atom::~atom: *Name");
     37  Free((void **)&Name, "atom::~atom: *Name");
    3838  Free((void **)&ComponentNr, "atom::~atom: *ComponentNr");
    3939};
  • src/bond.cpp

    r986c80 rce5ac3  
    1414bond::bond()
    1515{
    16         leftatom = NULL;
    17         rightatom = NULL;
     16  leftatom = NULL;
     17  rightatom = NULL;
    1818  previous = NULL;
    1919  next = NULL;
    20         nr = -1;
    21         HydrogenBond = 0;
    22         BondDegree = 0;
     20  nr = -1;
     21  HydrogenBond = 0;
     22  BondDegree = 0;
    2323  Used = white;
    2424  Cyclic = false;
     
    3434bond::bond(atom *left, atom *right, int degree=1, int number=0)
    3535{
    36         leftatom = left;
    37         rightatom = right;
     36  leftatom = left;
     37  rightatom = right;
    3838  previous = NULL;
    3939  next = NULL;
    40         HydrogenBond = 0;
     40  HydrogenBond = 0;
    4141  if ((left != NULL) && (right != NULL)) {
    42         if ((left->type != NULL) && (left->type->Z == 1))
    43                 HydrogenBond++;
    44         if ((right->type != NULL) && (right->type->Z == 1))
    45                 HydrogenBond++;
     42    if ((left->type != NULL) && (left->type->Z == 1))
     43      HydrogenBond++;
     44    if ((right->type != NULL) && (right->type->Z == 1))
     45      HydrogenBond++;
    4646  }
    4747  BondDegree = degree;
  • src/boundary.cpp

    r986c80 rce5ac3  
    8686BoundaryLineSet::~BoundaryLineSet()
    8787{
    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         }
     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  }
    103103}
    104104;
     
    181181BoundaryTriangleSet::~BoundaryTriangleSet()
    182182{
    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         }
     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  }
    196196}
    197197;
     
    573573void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol)
    574574{
    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);
     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);
    619619};
    620620
     
    946946Tesselation::~Tesselation()
    947947{
    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         }
     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  }
    970970}
    971971;
     
    15851585    atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol)
    15861586{
    1587         cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    1588         cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
    1589         cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
    1590         cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
    1591         cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
    1592         cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
    1593         /* OldNormal is normal vector on the old triangle
    1594         * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1595         * Chord points from b to a!!!
    1596         */
    1597         Vector dif_a; //Vector from a to candidate
    1598         Vector dif_b; //Vector from b to candidate
    1599         Vector AngleCheck;
    1600         Vector TempNormal, Umkreismittelpunkt;
    1601         Vector Mittelpunkt;
    1602 
    1603         double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius;
    1604         double BallAngle, AlternativeSign;
    1605         atom *Walker; // variable atom point
    1606 
    1607         Vector NewUmkreismittelpunkt;
    1608 
    1609         if (a != Candidate and b != Candidate and c != Candidate) {
    1610                 cout << Verbose(3) << "We have a unique candidate!" << endl;
    1611                 dif_a.CopyVector(&(a->x));
    1612                 dif_a.SubtractVector(&(Candidate->x));
    1613                 dif_b.CopyVector(&(b->x));
    1614                 dif_b.SubtractVector(&(Candidate->x));
    1615                 AngleCheck.CopyVector(&(Candidate->x));
    1616                 AngleCheck.SubtractVector(&(a->x));
    1617                 AngleCheck.ProjectOntoPlane(Chord);
    1618 
    1619                 SideA = dif_b.Norm();
    1620                 SideB = dif_a.Norm();
    1621                 SideC = Chord->Norm();
    1622                 //Chord->Scale(-1);
    1623 
    1624                 alpha = Chord->Angle(&dif_a);
    1625                 beta = M_PI - Chord->Angle(&dif_b);
    1626                 gamma = dif_a.Angle(&dif_b);
    1627 
    1628                 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;
    1629 
    1630                 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {
    1631                         cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    1632                         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;
    1633                 }
    1634 
    1635                 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
    1636                         Umkreisradius = SideA / 2.0 / sin(alpha);
    1637                         //cout << Umkreisradius << endl;
    1638                         //cout << SideB / 2.0 / sin(beta) << endl;
    1639                         //cout << SideC / 2.0 / sin(gamma) << endl;
    1640 
    1641                         if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.
    1642                                 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
    1643                                 cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
    1644                                 sign = AngleCheck.ScalarProduct(direction1);
    1645                                 if (fabs(sign)<MYEPSILON) {
    1646                                         if (AngleCheck.ScalarProduct(OldNormal)<0) {
    1647                                                 sign =0;
    1648                                                 AlternativeSign=1;
    1649                                         } else {
    1650                                                 sign =0;
    1651                                                 AlternativeSign=-1;
    1652                                         }
    1653                                 } else {
    1654                                         sign /= fabs(sign);
    1655                                         cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
    1656                                 }
    1657 
    1658                                 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
    1659 
    1660                                 AngleCheck.CopyVector(&ReferencePoint);
    1661                                 AngleCheck.Scale(-1);
    1662                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1663                                 AngleCheck.AddVector(&Mittelpunkt);
    1664                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1665                                 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
    1666 
    1667                                 BallAngle = AngleCheck.Angle(OldNormal);
    1668                                 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
    1669 
    1670                                 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
    1671                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1672 
    1673                                 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
    1674 
    1675                                 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
    1676 
    1677                                 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
    1678                                         if (Storage[0]< -1.5) { // first Candidate at all
    1679                                                 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1680                                                         cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
    1681                                                         Opt_Candidate = Candidate;
    1682                                                         Storage[0] = sign;
    1683                                                         Storage[1] = AlternativeSign;
    1684                                                         Storage[2] = BallAngle;
    1685                                                         cout << " angle " << Storage[2] << " and Up/Down "
    1686                                                         << Storage[0] << endl;
    1687                                                 } else
    1688                                                         cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    1689                                         } else {
    1690                                                 if ( Storage[2] > BallAngle) {
    1691                                                         if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1692                                                                 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
    1693                                                                 Opt_Candidate = Candidate;
    1694                                                                 Storage[0] = sign;
    1695                                                                 Storage[1] = AlternativeSign;
    1696                                                                 Storage[2] = BallAngle;
    1697                                                                 cout << " angle " << Storage[2] << " and Up/Down "
    1698                                                                 << Storage[0] << endl;
    1699                                                         } else
    1700                                                                 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    1701                                                 } else {
    1702                                                         if (DEBUG) {
    1703                                                                 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
    1704                                                         }
    1705                                                 }
    1706                                         }
    1707                                 } else {
    1708                                         if (DEBUG) {
    1709                                                 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
    1710                                         }
    1711                                 }
    1712                         } else {
    1713                                 if (DEBUG) {
    1714                                         cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
    1715                                 }
    1716                         }
    1717                 } else {
    1718                         if (DEBUG) {
    1719                                 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;
    1720                         }
    1721                 }
    1722         } else {
    1723                 if (DEBUG) {
    1724                         cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
    1725                 }
    1726         }
    1727 
    1728         if (RecursionLevel < 5) { // Seven is the recursion level threshold.
    1729                 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
    1730                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    1731                         if (Walker == Parent) { // don't go back the same bond
    1732                                 continue;
    1733                         } else {
    1734                                 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
    1735                         }
    1736                 }
    1737         }
    1738         cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1587  cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1588  cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
     1589  cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
     1590  cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
     1591  cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
     1592  cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
     1593  /* OldNormal is normal vector on the old triangle
     1594  * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1595  * Chord points from b to a!!!
     1596  */
     1597  Vector dif_a; //Vector from a to candidate
     1598  Vector dif_b; //Vector from b to candidate
     1599  Vector AngleCheck;
     1600  Vector TempNormal, Umkreismittelpunkt;
     1601  Vector Mittelpunkt;
     1602
     1603  double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius;
     1604  double BallAngle, AlternativeSign;
     1605  atom *Walker; // variable atom point
     1606
     1607  Vector NewUmkreismittelpunkt;
     1608
     1609  if (a != Candidate and b != Candidate and c != Candidate) {
     1610    cout << Verbose(3) << "We have a unique candidate!" << endl;
     1611    dif_a.CopyVector(&(a->x));
     1612    dif_a.SubtractVector(&(Candidate->x));
     1613    dif_b.CopyVector(&(b->x));
     1614    dif_b.SubtractVector(&(Candidate->x));
     1615    AngleCheck.CopyVector(&(Candidate->x));
     1616    AngleCheck.SubtractVector(&(a->x));
     1617    AngleCheck.ProjectOntoPlane(Chord);
     1618
     1619    SideA = dif_b.Norm();
     1620    SideB = dif_a.Norm();
     1621    SideC = Chord->Norm();
     1622    //Chord->Scale(-1);
     1623
     1624    alpha = Chord->Angle(&dif_a);
     1625    beta = M_PI - Chord->Angle(&dif_b);
     1626    gamma = dif_a.Angle(&dif_b);
     1627
     1628    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;
     1629
     1630    if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {
     1631      cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     1632      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;
     1633    }
     1634
     1635    if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
     1636      Umkreisradius = SideA / 2.0 / sin(alpha);
     1637      //cout << Umkreisradius << endl;
     1638      //cout << SideB / 2.0 / sin(beta) << endl;
     1639      //cout << SideC / 2.0 / sin(gamma) << endl;
     1640
     1641      if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.
     1642        cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
     1643        cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
     1644        sign = AngleCheck.ScalarProduct(direction1);
     1645        if (fabs(sign)<MYEPSILON) {
     1646          if (AngleCheck.ScalarProduct(OldNormal)<0) {
     1647            sign =0;
     1648            AlternativeSign=1;
     1649          } else {
     1650            sign =0;
     1651            AlternativeSign=-1;
     1652          }
     1653        } else {
     1654          sign /= fabs(sign);
     1655          cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
     1656        }
     1657
     1658        Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
     1659
     1660        AngleCheck.CopyVector(&ReferencePoint);
     1661        AngleCheck.Scale(-1);
     1662        //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1663        AngleCheck.AddVector(&Mittelpunkt);
     1664        //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1665        cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
     1666
     1667        BallAngle = AngleCheck.Angle(OldNormal);
     1668        cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
     1669
     1670        //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
     1671        //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1672
     1673        cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
     1674
     1675        NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
     1676
     1677        if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
     1678          if (Storage[0]< -1.5) { // first Candidate at all
     1679            if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1680              cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
     1681              Opt_Candidate = Candidate;
     1682              Storage[0] = sign;
     1683              Storage[1] = AlternativeSign;
     1684              Storage[2] = BallAngle;
     1685              cout << " angle " << Storage[2] << " and Up/Down "
     1686              << Storage[0] << endl;
     1687            } else
     1688              cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1689          } else {
     1690            if ( Storage[2] > BallAngle) {
     1691              if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1692                cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
     1693                Opt_Candidate = Candidate;
     1694                Storage[0] = sign;
     1695                Storage[1] = AlternativeSign;
     1696                Storage[2] = BallAngle;
     1697                cout << " angle " << Storage[2] << " and Up/Down "
     1698                << Storage[0] << endl;
     1699              } else
     1700                cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1701            } else {
     1702              if (DEBUG) {
     1703                cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
     1704              }
     1705            }
     1706          }
     1707        } else {
     1708          if (DEBUG) {
     1709            cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
     1710          }
     1711        }
     1712      } else {
     1713        if (DEBUG) {
     1714          cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
     1715        }
     1716      }
     1717    } else {
     1718      if (DEBUG) {
     1719        cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;
     1720      }
     1721    }
     1722  } else {
     1723    if (DEBUG) {
     1724      cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
     1725    }
     1726  }
     1727
     1728  if (RecursionLevel < 5) { // Seven is the recursion level threshold.
     1729    for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1730      Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1731      if (Walker == Parent) { // don't go back the same bond
     1732        continue;
     1733      } else {
     1734        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
     1735      }
     1736    }
     1737  }
     1738  cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    17391739}
    17401740;
     
    17671767    atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol)
    17681768{
    1769         /* OldNormal is normal vector on the old triangle
    1770         * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1771         * Chord points from b to a!!!
    1772         */
    1773         Vector dif_a; //Vector from a to candidate
    1774         Vector dif_b; //Vector from b to candidate
    1775         Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
    1776         Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
    1777 
    1778         double CurrentEpsilon = 0.1;
    1779         double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;
    1780         double BallAngle;
    1781         atom *Walker; // variable atom point
    1782 
    1783 
    1784         dif_a.CopyVector(&(a->x));
    1785         dif_a.SubtractVector(&(Candidate->x));
    1786         dif_b.CopyVector(&(b->x));
    1787         dif_b.SubtractVector(&(Candidate->x));
    1788         DirectionCheckPoint.CopyVector(&dif_a);
    1789         DirectionCheckPoint.Scale(-1);
    1790         DirectionCheckPoint.ProjectOntoPlane(Chord);
    1791 
    1792         SideA = dif_b.Norm();
    1793         SideB = dif_a.Norm();
    1794         SideC = Chord->Norm();
    1795         //Chord->Scale(-1);
    1796 
    1797         alpha = Chord->Angle(&dif_a);
    1798         beta = M_PI - Chord->Angle(&dif_b);
    1799         gamma = dif_a.Angle(&dif_b);
    1800 
    1801 
    1802         if (DEBUG) {
    1803                 cout << "Atom number" << Candidate->nr << endl;
    1804                 Candidate->x.Output((ofstream *) &cout);
    1805                 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
    1806         }
    1807 
    1808         if (a != Candidate and b != Candidate) {
    1809                 //      alpha = dif_a.Angle(&dif_b) / 2.;
    1810                 //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
    1811                 //      SideB = dif_a.Norm();
    1812                 //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
    1813                 //          alpha); // note this is squared of center line length
    1814                 //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
    1815                 // Those are remains from Freddie. Needed?
    1816 
    1817                 Umkreisradius = SideA / 2.0 / sin(alpha);
    1818                 //cout << Umkreisradius << endl;
    1819                 //cout << SideB / 2.0 / sin(beta) << endl;
    1820                 //cout << SideC / 2.0 / sin(gamma) << endl;
    1821 
    1822                 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
    1823                         // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
    1824                         Umkreismittelpunkt.Zero();
    1825                         helper.CopyVector(&a->x);
    1826                         helper.Scale(sin(2.*alpha));
    1827                         Umkreismittelpunkt.AddVector(&helper);
    1828                         helper.CopyVector(&b->x);
    1829                         helper.Scale(sin(2.*beta));
    1830                         Umkreismittelpunkt.AddVector(&helper);
    1831                         helper.CopyVector(&Candidate->x);
    1832                         helper.Scale(sin(2.*gamma));
    1833                         Umkreismittelpunkt.AddVector(&helper);
    1834                         //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
    1835                         Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    1836 
    1837                         TempNormal.CopyVector(&dif_a);
    1838                         TempNormal.VectorProduct(&dif_b);
    1839                         if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
    1840                                 TempNormal.Scale(-1);
    1841                         }
    1842                         TempNormal.Normalize();
    1843                         Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1844                         TempNormal.Scale(Restradius);
    1845 
    1846                         Mittelpunkt.CopyVector(&Umkreismittelpunkt);
    1847                         Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
    1848 
    1849                         AngleCheck.CopyVector(Chord);
    1850                         AngleCheck.Scale(-0.5);
    1851                         AngleCheck.SubtractVector(&(b->x));
    1852                         AngleCheckReference.CopyVector(&AngleCheck);
    1853                         AngleCheckReference.AddVector(Opt_Mittelpunkt);
    1854                         AngleCheck.AddVector(&Mittelpunkt);
    1855 
    1856                         BallAngle = AngleCheck.Angle(&AngleCheckReference);
    1857 
    1858                         d1->ProjectOntoPlane(&AngleCheckReference);
    1859                         sign = AngleCheck.ScalarProduct(d1);
    1860                         if (fabs(sign) < MYEPSILON)
    1861                                 sign = 0;
    1862                         else
    1863                                 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
    1864 
    1865 
    1866                         if (Storage[0]< -1.5) { // first Candidate at all
    1867                                 cout << "Next better candidate is " << *Candidate << " with ";
    1868                                 Opt_Candidate = Candidate;
    1869                                 Storage[0] = sign;
    1870                                 Storage[1] = BallAngle;
    1871                                 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1872                                 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1873                         } else {
    1874                                 /*
    1875                                 * removed due to change in criterium, now checking angle of ball to old normal.
    1876                                 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
    1877                                 //within the ball.
    1878 
    1879                                 Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
    1880                                 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
    1881 
    1882 
    1883                                 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
    1884                                 */
    1885                                         //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
    1886 
    1887                                 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
    1888                                         //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
    1889                                         cout << "Next better candidate is " << *Candidate << " with ";
    1890                                         Opt_Candidate = Candidate;
    1891                                         Storage[0] = sign;
    1892                                         Storage[1] = BallAngle;
    1893                                         Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1894                                         cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1895                                 } else {
    1896                                         if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
    1897                                                 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
    1898                                                 cout << "Next better candidate is " << *Candidate << " with ";
    1899                                                 Opt_Candidate = Candidate;
    1900                                                 Storage[0] = sign;
    1901                                                 Storage[1] = BallAngle;
    1902                                                 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1903                                                 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1904                                         }
    1905                                 }
    1906                         }
     1769  /* OldNormal is normal vector on the old triangle
     1770  * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1771  * Chord points from b to a!!!
     1772  */
     1773  Vector dif_a; //Vector from a to candidate
     1774  Vector dif_b; //Vector from b to candidate
     1775  Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
     1776  Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
     1777
     1778  double CurrentEpsilon = 0.1;
     1779  double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;
     1780  double BallAngle;
     1781  atom *Walker; // variable atom point
     1782
     1783
     1784  dif_a.CopyVector(&(a->x));
     1785  dif_a.SubtractVector(&(Candidate->x));
     1786  dif_b.CopyVector(&(b->x));
     1787  dif_b.SubtractVector(&(Candidate->x));
     1788  DirectionCheckPoint.CopyVector(&dif_a);
     1789  DirectionCheckPoint.Scale(-1);
     1790  DirectionCheckPoint.ProjectOntoPlane(Chord);
     1791
     1792  SideA = dif_b.Norm();
     1793  SideB = dif_a.Norm();
     1794  SideC = Chord->Norm();
     1795  //Chord->Scale(-1);
     1796
     1797  alpha = Chord->Angle(&dif_a);
     1798  beta = M_PI - Chord->Angle(&dif_b);
     1799  gamma = dif_a.Angle(&dif_b);
     1800
     1801
     1802  if (DEBUG) {
     1803    cout << "Atom number" << Candidate->nr << endl;
     1804    Candidate->x.Output((ofstream *) &cout);
     1805    cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
     1806  }
     1807
     1808  if (a != Candidate and b != Candidate) {
     1809    //      alpha = dif_a.Angle(&dif_b) / 2.;
     1810    //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
     1811    //      SideB = dif_a.Norm();
     1812    //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
     1813    //          alpha); // note this is squared of center line length
     1814    //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
     1815    // Those are remains from Freddie. Needed?
     1816
     1817    Umkreisradius = SideA / 2.0 / sin(alpha);
     1818    //cout << Umkreisradius << endl;
     1819    //cout << SideB / 2.0 / sin(beta) << endl;
     1820    //cout << SideC / 2.0 / sin(gamma) << endl;
     1821
     1822    if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
     1823      // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
     1824      Umkreismittelpunkt.Zero();
     1825      helper.CopyVector(&a->x);
     1826      helper.Scale(sin(2.*alpha));
     1827      Umkreismittelpunkt.AddVector(&helper);
     1828      helper.CopyVector(&b->x);
     1829      helper.Scale(sin(2.*beta));
     1830      Umkreismittelpunkt.AddVector(&helper);
     1831      helper.CopyVector(&Candidate->x);
     1832      helper.Scale(sin(2.*gamma));
     1833      Umkreismittelpunkt.AddVector(&helper);
     1834      //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
     1835      Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     1836
     1837      TempNormal.CopyVector(&dif_a);
     1838      TempNormal.VectorProduct(&dif_b);
     1839      if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
     1840        TempNormal.Scale(-1);
     1841      }
     1842      TempNormal.Normalize();
     1843      Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
     1844      TempNormal.Scale(Restradius);
     1845
     1846      Mittelpunkt.CopyVector(&Umkreismittelpunkt);
     1847      Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
     1848
     1849      AngleCheck.CopyVector(Chord);
     1850      AngleCheck.Scale(-0.5);
     1851      AngleCheck.SubtractVector(&(b->x));
     1852      AngleCheckReference.CopyVector(&AngleCheck);
     1853      AngleCheckReference.AddVector(Opt_Mittelpunkt);
     1854      AngleCheck.AddVector(&Mittelpunkt);
     1855
     1856      BallAngle = AngleCheck.Angle(&AngleCheckReference);
     1857
     1858      d1->ProjectOntoPlane(&AngleCheckReference);
     1859      sign = AngleCheck.ScalarProduct(d1);
     1860      if (fabs(sign) < MYEPSILON)
     1861        sign = 0;
     1862      else
     1863        sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
     1864
     1865
     1866      if (Storage[0]< -1.5) { // first Candidate at all
     1867        cout << "Next better candidate is " << *Candidate << " with ";
     1868        Opt_Candidate = Candidate;
     1869        Storage[0] = sign;
     1870        Storage[1] = BallAngle;
     1871        Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1872        cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1873      } else {
     1874        /*
     1875        * removed due to change in criterium, now checking angle of ball to old normal.
     1876        //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
     1877        //within the ball.
     1878
     1879        Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
     1880        //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
     1881
     1882
     1883        if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
     1884        */
     1885          //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
     1886
     1887        if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
     1888          //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
     1889          cout << "Next better candidate is " << *Candidate << " with ";
     1890          Opt_Candidate = Candidate;
     1891          Storage[0] = sign;
     1892          Storage[1] = BallAngle;
     1893          Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1894          cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1895        } else {
     1896          if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
     1897            //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
     1898            cout << "Next better candidate is " << *Candidate << " with ";
     1899            Opt_Candidate = Candidate;
     1900            Storage[0] = sign;
     1901            Storage[1] = BallAngle;
     1902            Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1903            cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1904          }
     1905        }
     1906      }
    19071907/*
    19081908               * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle.
     
    19471947                }
    19481948                */
    1949                 } else {
    1950                         if (DEBUG) {
    1951                                 cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
    1952                         }
    1953                 }
    1954         } else {
    1955                 if (DEBUG) {
    1956                         cout << "identisch mit Ursprungslinie" << endl;
    1957                 }
    1958         }
    1959 
    1960         if (RecursionLevel < 9) { // Five is the recursion level threshold.
    1961                 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
    1962                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    1963                         if (Walker == Parent) { // don't go back the same bond
    1964                                 continue;
    1965                         } else {
    1966                                 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
    1967                         }
    1968                 }
    1969         }
     1949    } else {
     1950      if (DEBUG) {
     1951        cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
     1952      }
     1953    }
     1954  } else {
     1955    if (DEBUG) {
     1956      cout << "identisch mit Ursprungslinie" << endl;
     1957    }
     1958  }
     1959
     1960  if (RecursionLevel < 9) { // Five is the recursion level threshold.
     1961    for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1962      Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1963      if (Walker == Parent) { // don't go back the same bond
     1964        continue;
     1965      } else {
     1966        Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
     1967      }
     1968    }
     1969  }
    19701970};
    19711971
     
    19841984    const double& RADIUS, int N, const char *tempbasename)
    19851985{
    1986         cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
    1987         Vector direction1;
    1988         Vector helper;
    1989         Vector Chord;
    1990         ofstream *tempstream = NULL;
    1991         char NumberName[255];
    1992         double tmp;
    1993         //atom* Walker;
    1994         atom* OldThirdPoint;
    1995 
    1996         double Storage[3];
    1997         Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
    1998         Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
    1999         Storage[2] = 9999999.;
    2000         atom* Opt_Candidate = NULL;
    2001         Vector Opt_Mittelpunkt;
    2002 
    2003         cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
    2004 
    2005         helper.CopyVector(&(Line.endpoints[0]->node->x));
    2006         for (int i = 0; i < 3; i++) {
    2007                 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
    2008                         OldThirdPoint = T.endpoints[i]->node;
    2009                         helper.SubtractVector(&T.endpoints[i]->node->x);
    2010                         break;
    2011                 }
    2012         }
    2013 
    2014         direction1.CopyVector(&Line.endpoints[0]->node->x);
    2015         direction1.SubtractVector(&Line.endpoints[1]->node->x);
    2016         direction1.VectorProduct(&(T.NormalVector));
    2017 
    2018         if (direction1.ScalarProduct(&helper) < 0) {
    2019                 direction1.Scale(-1);
    2020         }
    2021         cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
    2022 
    2023         Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
    2024         Chord.SubtractVector(&(Line.endpoints[1]->node->x));
    2025         cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
    2026 
    2027 
    2028         Vector Umkreismittelpunkt, a, b, c;
    2029         double alpha, beta, gamma;
    2030         a.CopyVector(&(T.endpoints[0]->node->x));
    2031         b.CopyVector(&(T.endpoints[1]->node->x));
    2032         c.CopyVector(&(T.endpoints[2]->node->x));
    2033         a.SubtractVector(&(T.endpoints[1]->node->x));
    2034         b.SubtractVector(&(T.endpoints[2]->node->x));
    2035         c.SubtractVector(&(T.endpoints[0]->node->x));
    2036 
    2037         alpha = M_PI - a.Angle(&c);
    2038         beta = M_PI - b.Angle(&a);
    2039         gamma = M_PI - c.Angle(&b);
    2040         if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
    2041                 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    2042 
    2043         Umkreismittelpunkt.Zero();
    2044         helper.CopyVector(&T.endpoints[0]->node->x);
    2045         helper.Scale(sin(2.*alpha));
    2046         Umkreismittelpunkt.AddVector(&helper);
    2047         helper.CopyVector(&T.endpoints[1]->node->x);
    2048         helper.Scale(sin(2.*beta));
    2049         Umkreismittelpunkt.AddVector(&helper);
    2050         helper.CopyVector(&T.endpoints[2]->node->x);
    2051         helper.Scale(sin(2.*gamma));
    2052         Umkreismittelpunkt.AddVector(&helper);
    2053         //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;
    2054         //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2055         Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    2056         //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2057         cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
    2058         cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
    2059 
    2060         cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
    2061         cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
    2062         if (DEBUG)
    2063                 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
    2064         tmp = 0;
    2065         for (int i=0;i<NDIM;i++) {
    2066                 helper.CopyVector(&T.endpoints[i]->node->x);
    2067                 helper.SubtractVector(&Umkreismittelpunkt);
    2068                 if (DEBUG)
    2069                         cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
    2070                 if (tmp == 0) // set on first time for comparison against next ones
    2071                         tmp = helper.Norm();
    2072                 if (fabs(helper.Norm() - tmp) > MYEPSILON)
    2073                         cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
    2074         }
    2075 
    2076         cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
    2077 
    2078         Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2079         Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2080         if (Opt_Candidate == NULL) {
    2081                 cerr << "WARNING: Could not find a suitable candidate." << endl;
    2082                 return false;
    2083         }
    2084         cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
    2085 
    2086         // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
    2087         bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
    2088 
    2089         if (flag) { // if so, add
    2090                 AddTrianglePoint(Opt_Candidate, 0);
    2091                 AddTrianglePoint(Line.endpoints[0]->node, 1);
    2092                 AddTrianglePoint(Line.endpoints[1]->node, 2);
    2093 
    2094                 AddTriangleLine(TPS[0], TPS[1], 0);
    2095                 AddTriangleLine(TPS[0], TPS[2], 1);
    2096                 AddTriangleLine(TPS[1], TPS[2], 2);
    2097 
    2098                 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2099                 AddTriangleToLines();
    2100 
    2101                 BTS->GetNormalVector(BTS->NormalVector);
    2102 
    2103                 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {
    2104                         BTS->NormalVector.Scale(-1);
    2105                 };
    2106                 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
    2107                 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
    2108         } else { // else, yell and do nothing
    2109                 cout << Verbose(1) << "This triangle consisting of ";
    2110                 cout << *Opt_Candidate << ", ";
    2111                 cout << *Line.endpoints[0]->node << " and ";
    2112                 cout << *Line.endpoints[1]->node << " ";
    2113                 cout << "is invalid!" << endl;
    2114                 return false;
    2115         }
    2116 
    2117         if ((TrianglesOnBoundaryCount % 10) == 0) {
    2118                 sprintf(NumberName, "-%d", TriangleFilesWritten);
    2119                 if (DoTecplotOutput) {
    2120                         string NameofTempFile(tempbasename);
    2121                         NameofTempFile.append(NumberName);
    2122                         NameofTempFile.append(TecplotSuffix);
    2123                         cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2124                         tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2125                         write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
    2126                         tempstream->close();
    2127                         tempstream->flush();
    2128                         delete(tempstream);
    2129                 }
    2130 
    2131                 if (DoRaster3DOutput) {
    2132                         string NameofTempFile(tempbasename);
    2133                         NameofTempFile.append(NumberName);
    2134                         NameofTempFile.append(Raster3DSuffix);
    2135                         cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2136                         tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2137                         write_raster3d_file(out, tempstream, this, mol);
    2138                         tempstream->close();
    2139                         tempstream->flush();
    2140                         delete(tempstream);
    2141                 }
    2142                 if (DoTecplotOutput || DoRaster3DOutput)
    2143                         TriangleFilesWritten++;
    2144         }
    2145 
    2146         cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
    2147         return true;
     1986  cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
     1987  Vector direction1;
     1988  Vector helper;
     1989  Vector Chord;
     1990  ofstream *tempstream = NULL;
     1991  char NumberName[255];
     1992  double tmp;
     1993  //atom* Walker;
     1994  atom* OldThirdPoint;
     1995
     1996  double Storage[3];
     1997  Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
     1998  Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
     1999  Storage[2] = 9999999.;
     2000  atom* Opt_Candidate = NULL;
     2001  Vector Opt_Mittelpunkt;
     2002
     2003  cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
     2004
     2005  helper.CopyVector(&(Line.endpoints[0]->node->x));
     2006  for (int i = 0; i < 3; i++) {
     2007    if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
     2008      OldThirdPoint = T.endpoints[i]->node;
     2009      helper.SubtractVector(&T.endpoints[i]->node->x);
     2010      break;
     2011    }
     2012  }
     2013
     2014  direction1.CopyVector(&Line.endpoints[0]->node->x);
     2015  direction1.SubtractVector(&Line.endpoints[1]->node->x);
     2016  direction1.VectorProduct(&(T.NormalVector));
     2017
     2018  if (direction1.ScalarProduct(&helper) < 0) {
     2019    direction1.Scale(-1);
     2020  }
     2021  cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
     2022
     2023  Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
     2024  Chord.SubtractVector(&(Line.endpoints[1]->node->x));
     2025  cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
     2026
     2027
     2028  Vector Umkreismittelpunkt, a, b, c;
     2029  double alpha, beta, gamma;
     2030  a.CopyVector(&(T.endpoints[0]->node->x));
     2031  b.CopyVector(&(T.endpoints[1]->node->x));
     2032  c.CopyVector(&(T.endpoints[2]->node->x));
     2033  a.SubtractVector(&(T.endpoints[1]->node->x));
     2034  b.SubtractVector(&(T.endpoints[2]->node->x));
     2035  c.SubtractVector(&(T.endpoints[0]->node->x));
     2036
     2037  alpha = M_PI - a.Angle(&c);
     2038  beta = M_PI - b.Angle(&a);
     2039  gamma = M_PI - c.Angle(&b);
     2040  if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
     2041    cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     2042
     2043  Umkreismittelpunkt.Zero();
     2044  helper.CopyVector(&T.endpoints[0]->node->x);
     2045  helper.Scale(sin(2.*alpha));
     2046  Umkreismittelpunkt.AddVector(&helper);
     2047  helper.CopyVector(&T.endpoints[1]->node->x);
     2048  helper.Scale(sin(2.*beta));
     2049  Umkreismittelpunkt.AddVector(&helper);
     2050  helper.CopyVector(&T.endpoints[2]->node->x);
     2051  helper.Scale(sin(2.*gamma));
     2052  Umkreismittelpunkt.AddVector(&helper);
     2053  //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;
     2054  //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2055  Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     2056  //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2057  cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
     2058  cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
     2059
     2060  cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     2061  cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
     2062  if (DEBUG)
     2063    cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
     2064  tmp = 0;
     2065  for (int i=0;i<NDIM;i++) {
     2066    helper.CopyVector(&T.endpoints[i]->node->x);
     2067    helper.SubtractVector(&Umkreismittelpunkt);
     2068    if (DEBUG)
     2069      cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
     2070    if (tmp == 0) // set on first time for comparison against next ones
     2071      tmp = helper.Norm();
     2072    if (fabs(helper.Norm() - tmp) > MYEPSILON)
     2073      cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
     2074  }
     2075
     2076  cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
     2077
     2078  Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
     2079  Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
     2080  if (Opt_Candidate == NULL) {
     2081    cerr << "WARNING: Could not find a suitable candidate." << endl;
     2082    return false;
     2083  }
     2084  cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
     2085
     2086  // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
     2087  bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
     2088
     2089  if (flag) { // if so, add
     2090    AddTrianglePoint(Opt_Candidate, 0);
     2091    AddTrianglePoint(Line.endpoints[0]->node, 1);
     2092    AddTrianglePoint(Line.endpoints[1]->node, 2);
     2093
     2094    AddTriangleLine(TPS[0], TPS[1], 0);
     2095    AddTriangleLine(TPS[0], TPS[2], 1);
     2096    AddTriangleLine(TPS[1], TPS[2], 2);
     2097
     2098    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2099    AddTriangleToLines();
     2100
     2101    BTS->GetNormalVector(BTS->NormalVector);
     2102
     2103    if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {
     2104      BTS->NormalVector.Scale(-1);
     2105    };
     2106    cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
     2107    cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
     2108  } else { // else, yell and do nothing
     2109    cout << Verbose(1) << "This triangle consisting of ";
     2110    cout << *Opt_Candidate << ", ";
     2111    cout << *Line.endpoints[0]->node << " and ";
     2112    cout << *Line.endpoints[1]->node << " ";
     2113    cout << "is invalid!" << endl;
     2114    return false;
     2115  }
     2116
     2117  if ((TrianglesOnBoundaryCount % 10) == 0) {
     2118    sprintf(NumberName, "-%d", TriangleFilesWritten);
     2119    if (DoTecplotOutput) {
     2120      string NameofTempFile(tempbasename);
     2121      NameofTempFile.append(NumberName);
     2122      NameofTempFile.append(TecplotSuffix);
     2123      cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2124      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2125      write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
     2126      tempstream->close();
     2127      tempstream->flush();
     2128      delete(tempstream);
     2129    }
     2130
     2131    if (DoRaster3DOutput) {
     2132      string NameofTempFile(tempbasename);
     2133      NameofTempFile.append(NumberName);
     2134      NameofTempFile.append(Raster3DSuffix);
     2135      cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2136      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2137      write_raster3d_file(out, tempstream, this, mol);
     2138      tempstream->close();
     2139      tempstream->flush();
     2140      delete(tempstream);
     2141    }
     2142    if (DoTecplotOutput || DoRaster3DOutput)
     2143      TriangleFilesWritten++;
     2144  }
     2145
     2146  cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
     2147  return true;
    21482148};
    21492149
     
    21592159 */
    21602160bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) {
    2161         LineMap::iterator TryAndError;
    2162         PointTestPair InsertPoint;
    2163         bool Present[3];
    2164 
    2165         *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;
    2166         TPS[0] = new class BoundaryPointSet(a);
    2167         TPS[1] = new class BoundaryPointSet(b);
    2168         TPS[2] = new class BoundaryPointSet(c);
    2169         for (int i=0;i<3;i++) { // check through all endpoints
    2170                 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));
    2171                 Present[i] = !InsertPoint.second;
    2172                 if (Present[i]) { // if new point was not present before, increase counter
    2173                         delete TPS[i];
    2174                         *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;
    2175                         TPS[i] = (InsertPoint.first)->second;
    2176                 }
    2177         }
    2178 
    2179         // check lines
    2180         for (int i=0;i<3;i++)
    2181                 if (Present[i])
    2182                         for (int j=i;j<3;j++)
    2183                                 if (Present[j]) {
    2184                                         TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);
    2185                                         if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {
    2186                                                 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;
    2187                                                 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    2188                                                 return false;
    2189                                         }
    2190                                 }
    2191         *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    2192         return true;
     2161  LineMap::iterator TryAndError;
     2162  PointTestPair InsertPoint;
     2163  bool Present[3];
     2164
     2165  *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;
     2166  TPS[0] = new class BoundaryPointSet(a);
     2167  TPS[1] = new class BoundaryPointSet(b);
     2168  TPS[2] = new class BoundaryPointSet(c);
     2169  for (int i=0;i<3;i++) { // check through all endpoints
     2170    InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));
     2171    Present[i] = !InsertPoint.second;
     2172    if (Present[i]) { // if new point was not present before, increase counter
     2173      delete TPS[i];
     2174      *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;
     2175      TPS[i] = (InsertPoint.first)->second;
     2176    }
     2177  }
     2178
     2179  // check lines
     2180  for (int i=0;i<3;i++)
     2181    if (Present[i])
     2182      for (int j=i;j<3;j++)
     2183        if (Present[j]) {
     2184          TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);
     2185          if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {
     2186            *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;
     2187            *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2188            return false;
     2189          }
     2190        }
     2191  *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2192  return true;
    21932193};
    21942194
     
    21982198    molecule* mol, double RADIUS)
    21992199{
    2200         cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
    2201         int i;
    2202         Vector AngleCheck;
    2203         atom* Walker;
    2204         double norm = -1., angle;
    2205 
    2206         // check if we only have one unique point yet ...
    2207         if (a != Candidate) {
    2208                 cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
    2209                 AngleCheck.CopyVector(&(Candidate->x));
    2210                 AngleCheck.SubtractVector(&(a->x));
    2211                 norm = AngleCheck.Norm();
    2212                 // second point shall have smallest angle with respect to Oben vector
    2213                 if (norm < RADIUS) {
    2214                         angle = AngleCheck.Angle(&Oben);
    2215                         if (angle < Storage[0]) {
    2216                                 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
    2217                                 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
    2218                                 Opt_Candidate = Candidate;
    2219                                 Storage[0] = AngleCheck.Angle(&Oben);
    2220                                 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
    2221                         } else {
    2222                                 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
    2223                         }
    2224                 } else {
    2225                         cout << "Refused due to Radius " << norm << endl;
    2226                 }
    2227         }
    2228 
    2229         // if not recursed to deeply, look at all its bonds
    2230         if (RecursionLevel < 7) {
    2231                 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
    2232                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    2233                         if (Walker == Parent) // don't go back along the bond we came from
    2234                                 continue;
    2235                         else
    2236                                 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
    2237                 }
    2238         }
    2239         cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2200  cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2201  int i;
     2202  Vector AngleCheck;
     2203  atom* Walker;
     2204  double norm = -1., angle;
     2205
     2206  // check if we only have one unique point yet ...
     2207  if (a != Candidate) {
     2208    cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
     2209    AngleCheck.CopyVector(&(Candidate->x));
     2210    AngleCheck.SubtractVector(&(a->x));
     2211    norm = AngleCheck.Norm();
     2212    // second point shall have smallest angle with respect to Oben vector
     2213    if (norm < RADIUS) {
     2214      angle = AngleCheck.Angle(&Oben);
     2215      if (angle < Storage[0]) {
     2216        //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
     2217        cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
     2218        Opt_Candidate = Candidate;
     2219        Storage[0] = AngleCheck.Angle(&Oben);
     2220        //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
     2221      } else {
     2222        cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
     2223      }
     2224    } else {
     2225      cout << "Refused due to Radius " << norm << endl;
     2226    }
     2227  }
     2228
     2229  // if not recursed to deeply, look at all its bonds
     2230  if (RecursionLevel < 7) {
     2231    for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
     2232      Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     2233      if (Walker == Parent) // don't go back along the bond we came from
     2234        continue;
     2235      else
     2236        Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
     2237    }
     2238  }
     2239  cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
    22402240};
    22412241
    22422242void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
    22432243{
    2244         cout << Verbose(1) << "Begin of Find_starting_triangle\n";
    2245         int i = 0;
    2246         atom* Walker;
    2247         atom* FirstPoint;
    2248         atom* SecondPoint;
    2249         atom* max_index[NDIM];
    2250         double max_coordinate[NDIM];
    2251         Vector Oben;
    2252         Vector helper;
    2253         Vector Chord;
    2254         Vector CenterOfFirstLine;
    2255 
    2256         Oben.Zero();
    2257 
    2258         for (i = 0; i < 3; i++) {
    2259                 max_index[i] = NULL;
    2260                 max_coordinate[i] = -1;
    2261         }
    2262         cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
    2263 
    2264         // 1. searching topmost atom with respect to each axis
    2265         Walker = mol->start;
    2266         while (Walker->next != mol->end) {
    2267                 Walker = Walker->next;
    2268                 for (i = 0; i < 3; i++) {
    2269                         if (Walker->x.x[i] > max_coordinate[i]) {
    2270                                 max_coordinate[i] = Walker->x.x[i];
    2271                                 max_index[i] = Walker;
    2272                         }
    2273                 }
    2274         }
    2275 
    2276         cout << Verbose(2) << "Found maximum coordinates: ";
    2277         for (int i=0;i<NDIM;i++)
    2278                 cout << i << ": " << *max_index[i] << "\t";
    2279         cout << endl;
     2244  cout << Verbose(1) << "Begin of Find_starting_triangle\n";
     2245  int i = 0;
     2246  atom* Walker;
     2247  atom* FirstPoint;
     2248  atom* SecondPoint;
     2249  atom* max_index[NDIM];
     2250  double max_coordinate[NDIM];
     2251  Vector Oben;
     2252  Vector helper;
     2253  Vector Chord;
     2254  Vector CenterOfFirstLine;
     2255
     2256  Oben.Zero();
     2257
     2258  for (i = 0; i < 3; i++) {
     2259    max_index[i] = NULL;
     2260    max_coordinate[i] = -1;
     2261  }
     2262  cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
     2263
     2264  // 1. searching topmost atom with respect to each axis
     2265  Walker = mol->start;
     2266  while (Walker->next != mol->end) {
     2267    Walker = Walker->next;
     2268    for (i = 0; i < 3; i++) {
     2269      if (Walker->x.x[i] > max_coordinate[i]) {
     2270        max_coordinate[i] = Walker->x.x[i];
     2271        max_index[i] = Walker;
     2272      }
     2273    }
     2274  }
     2275
     2276  cout << Verbose(2) << "Found maximum coordinates: ";
     2277  for (int i=0;i<NDIM;i++)
     2278    cout << i << ": " << *max_index[i] << "\t";
     2279  cout << endl;
    22802280  //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
    2281         const int k = 1;
    2282         Oben.x[k] = 1.;
    2283         FirstPoint = max_index[k];
    2284 
    2285         cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
    2286         double Storage[3];
    2287         atom* Opt_Candidate = NULL;
    2288         Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
    2289         Storage[1] = 999999.; // This will be an angle looking for the third point.
    2290         Storage[2] = 999999.;
    2291 
    2292         Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
    2293         SecondPoint = Opt_Candidate;
    2294         cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
    2295 
    2296         helper.CopyVector(&(FirstPoint->x));
    2297         helper.SubtractVector(&(SecondPoint->x));
    2298         helper.Normalize();
    2299         Oben.ProjectOntoPlane(&helper);
    2300         Oben.Normalize();
    2301         helper.VectorProduct(&Oben);
    2302         Storage[0] = -2.; // This will indicate the quadrant.
    2303         Storage[1] = 9999999.; // This will be an angle looking for the third point.
    2304         Storage[2] = 9999999.;
    2305 
    2306         Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
    2307         Chord.SubtractVector(&(SecondPoint->x));
    2308         // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
    2309 
    2310         cout << Verbose(2) << "Looking for third point candidates \n";
    2311         // look in one direction of baseline for initial candidate
    2312         Opt_Candidate = NULL;
    2313         CenterOfFirstLine.CopyVector(&Chord);
    2314         CenterOfFirstLine.Scale(0.5);
    2315         CenterOfFirstLine.AddVector(&(SecondPoint->x));
    2316 
    2317         cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
    2318         Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
    2319         // look in other direction of baseline for possible better candidate
    2320         cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
    2321         Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
    2322         cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
    2323 
    2324         // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
    2325 
    2326         // Finally, we only have to add the found points
    2327         AddTrianglePoint(FirstPoint, 0);
    2328         AddTrianglePoint(SecondPoint, 1);
    2329         AddTrianglePoint(Opt_Candidate, 2);
    2330         // ... and respective lines
    2331         AddTriangleLine(TPS[0], TPS[1], 0);
    2332         AddTriangleLine(TPS[1], TPS[2], 1);
    2333         AddTriangleLine(TPS[0], TPS[2], 2);
    2334         // ... and triangles to the Maps of the Tesselation class
    2335         BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2336         AddTriangleToLines();
    2337         // ... and calculate its normal vector (with correct orientation)
    2338         Oben.Scale(-1.);
    2339         BTS->GetNormalVector(Oben);
    2340         cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
    2341         cout << Verbose(1) << "End of Find_starting_triangle\n";
     2281  const int k = 1;
     2282  Oben.x[k] = 1.;
     2283  FirstPoint = max_index[k];
     2284
     2285  cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
     2286  double Storage[3];
     2287  atom* Opt_Candidate = NULL;
     2288  Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
     2289  Storage[1] = 999999.; // This will be an angle looking for the third point.
     2290  Storage[2] = 999999.;
     2291
     2292  Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
     2293  SecondPoint = Opt_Candidate;
     2294  cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
     2295
     2296  helper.CopyVector(&(FirstPoint->x));
     2297  helper.SubtractVector(&(SecondPoint->x));
     2298  helper.Normalize();
     2299  Oben.ProjectOntoPlane(&helper);
     2300  Oben.Normalize();
     2301  helper.VectorProduct(&Oben);
     2302  Storage[0] = -2.; // This will indicate the quadrant.
     2303  Storage[1] = 9999999.; // This will be an angle looking for the third point.
     2304  Storage[2] = 9999999.;
     2305
     2306  Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
     2307  Chord.SubtractVector(&(SecondPoint->x));
     2308  // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
     2309
     2310  cout << Verbose(2) << "Looking for third point candidates \n";
     2311  // look in one direction of baseline for initial candidate
     2312  Opt_Candidate = NULL;
     2313  CenterOfFirstLine.CopyVector(&Chord);
     2314  CenterOfFirstLine.Scale(0.5);
     2315  CenterOfFirstLine.AddVector(&(SecondPoint->x));
     2316
     2317  cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
     2318  Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
     2319  // look in other direction of baseline for possible better candidate
     2320  cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
     2321  Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
     2322  cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
     2323
     2324  // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
     2325
     2326  // Finally, we only have to add the found points
     2327  AddTrianglePoint(FirstPoint, 0);
     2328  AddTrianglePoint(SecondPoint, 1);
     2329  AddTrianglePoint(Opt_Candidate, 2);
     2330  // ... and respective lines
     2331  AddTriangleLine(TPS[0], TPS[1], 0);
     2332  AddTriangleLine(TPS[1], TPS[2], 1);
     2333  AddTriangleLine(TPS[0], TPS[2], 2);
     2334  // ... and triangles to the Maps of the Tesselation class
     2335  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2336  AddTriangleToLines();
     2337  // ... and calculate its normal vector (with correct orientation)
     2338  Oben.Scale(-1.);
     2339  BTS->GetNormalVector(Oben);
     2340  cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
     2341  cout << Verbose(1) << "End of Find_starting_triangle\n";
    23422342};
    23432343
    23442344void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS)
    23452345{
    2346         int N = 0;
    2347         struct Tesselation *Tess = new Tesselation;
    2348         cout << Verbose(1) << "Entering search for non convex hull. " << endl;
    2349         cout << flush;
    2350         LineMap::iterator baseline;
    2351         cout << Verbose(0) << "Begin of Find_non_convex_border\n";
    2352         bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
    2353         bool failflag = false;
    2354         if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
    2355                 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
    2356 
    2357         Tess->Find_starting_triangle(mol, RADIUS);
    2358 
    2359         baseline = Tess->LinesOnBoundary.begin();
    2360         while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
    2361                 if (baseline->second->TrianglesCount == 1) {
    2362                         failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.
    2363                         flag = flag || failflag;
    2364                         if (!failflag)
    2365                                 cerr << "WARNING: Find_next_suitable_triangle failed." << endl;
    2366                 } else {
    2367                         cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;
    2368                 }
    2369                 N++;
    2370                 baseline++;
    2371                 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
    2372                         baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
    2373                         flag = false;
    2374                 }
    2375         }
    2376         if (failflag) {
    2377                 cout << Verbose(1) << "Writing final tecplot file\n";
    2378                 if (DoTecplotOutput)
    2379                         write_tecplot_file(out, tecplot, Tess, mol, -1);
    2380                 if (DoRaster3DOutput)
    2381                         write_raster3d_file(out, tecplot, Tess, mol);
    2382         } else {
    2383                 cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
    2384         }
    2385 
    2386         cout << Verbose(0) << "End of Find_non_convex_border\n";
    2387         delete(Tess);
     2346  int N = 0;
     2347  struct Tesselation *Tess = new Tesselation;
     2348  cout << Verbose(1) << "Entering search for non convex hull. " << endl;
     2349  cout << flush;
     2350  LineMap::iterator baseline;
     2351  cout << Verbose(0) << "Begin of Find_non_convex_border\n";
     2352  bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
     2353  bool failflag = false;
     2354  if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
     2355    mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
     2356
     2357  Tess->Find_starting_triangle(mol, RADIUS);
     2358
     2359  baseline = Tess->LinesOnBoundary.begin();
     2360  while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
     2361    if (baseline->second->TrianglesCount == 1) {
     2362      failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.
     2363      flag = flag || failflag;
     2364      if (!failflag)
     2365        cerr << "WARNING: Find_next_suitable_triangle failed." << endl;
     2366    } else {
     2367      cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;
     2368    }
     2369    N++;
     2370    baseline++;
     2371    if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
     2372      baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
     2373      flag = false;
     2374    }
     2375  }
     2376  if (failflag) {
     2377    cout << Verbose(1) << "Writing final tecplot file\n";
     2378    if (DoTecplotOutput)
     2379      write_tecplot_file(out, tecplot, Tess, mol, -1);
     2380    if (DoRaster3DOutput)
     2381      write_raster3d_file(out, tecplot, Tess, mol);
     2382  } else {
     2383    cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
     2384  }
     2385
     2386  cout << Verbose(0) << "End of Find_non_convex_border\n";
     2387  delete(Tess);
    23882388};
    23892389
  • src/builder.cpp

    r986c80 rce5ac3  
    562562      break;
    563563    case 'd':
    564         cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
    565         cout << Verbose(0) << "Shall we rotate? [0/1]: ";
    566         cin >> Z;
    567         if ((Z >=0) && (Z <=1))
    568           mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z);
    569         else
    570           mol->PrincipalAxisSystem((ofstream *)&cout, false);
    571         break;
     564      cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
     565      cout << Verbose(0) << "Shall we rotate? [0/1]: ";
     566      cin >> Z;
     567      if ((Z >=0) && (Z <=1))
     568        mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z);
     569      else
     570        mol->PrincipalAxisSystem((ofstream *)&cout, false);
     571      break;
    572572    case 'e':
    573         cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    574         VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
    575         break;
     573      cout << Verbose(0) << "Evaluating volume of the convex envelope.";
     574      VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
     575      break;
    576576    case 'f':
    577577      mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps, (ofstream *)&cout);
     
    10201020              }
    10211021              break;
    1022                                                 case 'A':
    1023                                                         ExitFlag = 1;
    1024                                                         if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
    1025                                                                 ExitFlag =255;
    1026                                                                 cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
    1027                                                         } else {
    1028                                                                 cout << "Parsing bonds from " << argv[argptr] << "." << endl;
    1029                                                                 ifstream *input = new ifstream(argv[argptr]);
    1030                                                                 mol->CreateAdjacencyList2((ofstream *)&cout, input);
    1031                                                                 input->close();
    1032                                                         }
    1033                                                         break;
    1034                                                 case 'N':
    1035                                                         ExitFlag = 1;
    1036                                                         if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
    1037                                                                 ExitFlag = 255;
    1038                                                                 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
    1039                                                         } else {
    1040                                                                 cout << Verbose(0) << "Evaluating npn-convex envelope.";
    1041                                                                 string TempName(argv[argptr+1]);
    1042                                                                 TempName.append(".r3d");
    1043                                                                 ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
    1044                                                                 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
    1045                                                                 Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
    1046                                                                 output->close();
    1047                                                                 delete(output);
    1048                                                                 argptr+=2;
    1049                                                         }
    1050                                                         break;
     1022            case 'A':
     1023              ExitFlag = 1;
     1024              if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
     1025                ExitFlag =255;
     1026                cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
     1027              } else {
     1028                cout << "Parsing bonds from " << argv[argptr] << "." << endl;
     1029                ifstream *input = new ifstream(argv[argptr]);
     1030                mol->CreateAdjacencyList2((ofstream *)&cout, input);
     1031                input->close();
     1032              }
     1033              break;
     1034            case 'N':
     1035              ExitFlag = 1;
     1036              if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
     1037                ExitFlag = 255;
     1038                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
     1039              } else {
     1040                cout << Verbose(0) << "Evaluating npn-convex envelope.";
     1041                string TempName(argv[argptr+1]);
     1042                TempName.append(".r3d");
     1043                ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
     1044                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
     1045                Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
     1046                output->close();
     1047                delete(output);
     1048                argptr+=2;
     1049              }
     1050              break;
    10511051            case 'T':
    10521052              ExitFlag = 1;
     
    13691369  char choice;  // menu choice char
    13701370  Vector x,y,z,n;  // coordinates for absolute point in cell volume
    1371         double *factor; // unit factor if desired
     1371  double *factor;  // unit factor if desired
    13721372  bool valid; // flag if input was valid or not
    13731373  ifstream test;
  • src/config.cpp

    r986c80 rce5ac3  
    10821082{
    10831083  bool result = true;
    1084         // bring MaxTypes up to date
    1085         mol->CountElements();
     1084  // bring MaxTypes up to date
     1085  mol->CountElements();
    10861086  ofstream *output = NULL;
    10871087  output = new ofstream(filename, ios::out);
  • src/datacreator.cpp

    r986c80 rce5ac3  
    335335    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    336336      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
    337         tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];
    338         norm += tmp*tmp;
     337        tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];
     338        norm += tmp*tmp;
    339339      }
    340340    }
  • src/helpers.cpp

    r986c80 rce5ac3  
    7373  void *buffer = NULL;
    7474  if (OldPointer == NULL)
    75         //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl;
     75    //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl;
    7676    buffer = (void *)malloc(size); // malloc
    7777  else
  • src/molecules.cpp

    r986c80 rce5ac3  
    5353  BondCount = 0;
    5454  NoNonBonds = 0;
    55         NoNonHydrogen = 0;
     55  NoNonHydrogen = 0;
    5656  NoCyclicBonds = 0;
    5757  ListOfBondsPerAtom = NULL;
     
    117117{
    118118  if (pointer != NULL) {
    119         atom *walker = new atom();
    120         walker->type = pointer->type;   // copy element of atom
    121         walker->x.CopyVector(&pointer->x); // copy coordination
     119    atom *walker = new atom();
     120    walker->type = pointer->type;  // copy element of atom
     121    walker->x.CopyVector(&pointer->x); // copy coordination
    122122    walker->v.CopyVector(&pointer->v); // copy velocity
    123123    walker->FixedIon = pointer->FixedIon;
     
    186186  double *matrix;
    187187
    188 //      *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     188//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
    189189  // create vector in direction of bond
    190190  InBondvector.CopyVector(&TopReplacement->x);
     
    427427  }
    428428
    429 //      *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
     429//  *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
    430430  return AllWentWell;
    431431};
     
    753753Vector * molecule::DetermineCenterOfGravity(ofstream *out)
    754754{
    755         atom *ptr = start->next;  // start at first in list
    756         Vector *a = new Vector();
    757         Vector tmp;
     755  atom *ptr = start->next;  // start at first in list
     756  Vector *a = new Vector();
     757  Vector tmp;
    758758  double Num = 0;
    759759
    760         a->Zero();
     760  a->Zero();
    761761
    762762  if (ptr != end) {   //list not empty?
     
    909909void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate)
    910910{
    911         atom *ptr = start;  // start at first in list
    912         double InertiaTensor[NDIM*NDIM];
    913         Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    914 
    915         CenterGravity(out, CenterOfGravity);
    916 
    917         // reset inertia tensor
    918         for(int i=0;i<NDIM*NDIM;i++)
    919                 InertiaTensor[i] = 0.;
    920 
    921         // sum up inertia tensor
    922         while (ptr->next != end) {
    923                 ptr = ptr->next;
    924                 Vector x;
    925                 x.CopyVector(&ptr->x);
    926                 //x.SubtractVector(CenterOfGravity);
    927                 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    928                 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    929                 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    930                 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    931                 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    932                 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    933                 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    934                 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    935                 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    936         }
    937         // print InertiaTensor for debugging
    938         *out << "The inertia tensor is:" << endl;
    939         for(int i=0;i<NDIM;i++) {
    940           for(int j=0;j<NDIM;j++)
    941             *out << InertiaTensor[i*NDIM+j] << " ";
    942           *out << endl;
    943         }
    944         *out << endl;
    945 
    946         // diagonalize to determine principal axis system
    947         gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
    948         gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
    949         gsl_vector *eval = gsl_vector_alloc(NDIM);
    950         gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
    951         gsl_eigen_symmv(&m.matrix, eval, evec, T);
    952         gsl_eigen_symmv_free(T);
    953         gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    954 
    955         for(int i=0;i<NDIM;i++) {
    956                 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    957                 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    958         }
    959 
    960         // check whether we rotate or not
    961         if (DoRotate) {
    962           *out << Verbose(1) << "Transforming molecule into PAS ... ";
    963           // the eigenvectors specify the transformation matrix
    964           ptr = start;
    965           while (ptr->next != end) {
    966             ptr = ptr->next;
    967             for (int j=0;j<MDSteps;j++)
    968               Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
    969             ptr->x.MatrixMultiplication(evec->data);
    970           }
    971           *out << "done." << endl;
    972 
    973           // summing anew for debugging (resulting matrix has to be diagonal!)
    974           // reset inertia tensor
     911  atom *ptr = start;  // start at first in list
     912  double InertiaTensor[NDIM*NDIM];
     913  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
     914
     915  CenterGravity(out, CenterOfGravity);
     916
     917  // reset inertia tensor
     918  for(int i=0;i<NDIM*NDIM;i++)
     919    InertiaTensor[i] = 0.;
     920
     921  // sum up inertia tensor
     922  while (ptr->next != end) {
     923    ptr = ptr->next;
     924    Vector x;
     925    x.CopyVector(&ptr->x);
     926    //x.SubtractVector(CenterOfGravity);
     927    InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     928    InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     929    InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     930    InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     931    InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     932    InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     933    InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     934    InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     935    InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     936  }
     937  // print InertiaTensor for debugging
     938  *out << "The inertia tensor is:" << endl;
     939  for(int i=0;i<NDIM;i++) {
     940    for(int j=0;j<NDIM;j++)
     941      *out << InertiaTensor[i*NDIM+j] << " ";
     942    *out << endl;
     943  }
     944  *out << endl;
     945
     946  // diagonalize to determine principal axis system
     947  gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     948  gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
     949  gsl_vector *eval = gsl_vector_alloc(NDIM);
     950  gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
     951  gsl_eigen_symmv(&m.matrix, eval, evec, T);
     952  gsl_eigen_symmv_free(T);
     953  gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
     954
     955  for(int i=0;i<NDIM;i++) {
     956    *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
     957    *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
     958  }
     959
     960  // check whether we rotate or not
     961  if (DoRotate) {
     962    *out << Verbose(1) << "Transforming molecule into PAS ... ";
     963    // the eigenvectors specify the transformation matrix
     964    ptr = start;
     965    while (ptr->next != end) {
     966      ptr = ptr->next;
     967      for (int j=0;j<MDSteps;j++)
     968        Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
     969      ptr->x.MatrixMultiplication(evec->data);
     970    }
     971    *out << "done." << endl;
     972
     973    // summing anew for debugging (resulting matrix has to be diagonal!)
     974    // reset inertia tensor
    975975    for(int i=0;i<NDIM*NDIM;i++)
    976976      InertiaTensor[i] = 0.;
     
    10011001    }
    10021002    *out << endl;
    1003         }
    1004 
    1005         // free everything
    1006         delete(CenterOfGravity);
    1007         gsl_vector_free(eval);
    1008         gsl_matrix_free(evec);
     1003  }
     1004
     1005  // free everything
     1006  delete(CenterOfGravity);
     1007  gsl_vector_free(eval);
     1008  gsl_matrix_free(evec);
    10091009};
    10101010
     
    20272027    runner = elemente->start;
    20282028    while (runner->next != elemente->end) { // go through every element
    2029                 runner = runner->next;
     2029      runner = runner->next;
    20302030      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    20312031        ElementNo++;
     
    21212121bool molecule::Checkout(ofstream *out)  const
    21222122{
    2123         return elemente->Checkout(out, ElementsInMolecule);
     2123  return elemente->Checkout(out, ElementsInMolecule);
    21242124};
    21252125
     
    21742174    runner = elemente->start;
    21752175    while (runner->next != elemente->end) { // go through every element
    2176                 runner = runner->next;
     2176      runner = runner->next;
    21772177      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    21782178        ElementNo++;
     
    21962196void molecule::CountAtoms(ofstream *out)
    21972197{
    2198         int i = 0;
    2199         atom *Walker = start;
     2198  int i = 0;
     2199  atom *Walker = start;
    22002200  while (Walker->next != end) {
    22012201    Walker = Walker->next;
     
    22042204  if ((AtomCount == 0) || (i != AtomCount)) {
    22052205    *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
    2206         AtomCount = i;
     2206    AtomCount = i;
    22072207
    22082208    // count NonHydrogen atoms and give each atom a unique name
    22092209    if (AtomCount != 0) {
    2210             i=0;
    2211             NoNonHydrogen = 0;
     2210      i=0;
     2211      NoNonHydrogen = 0;
    22122212      Walker = start;
    2213             while (Walker->next != end) {
    2214               Walker = Walker->next;
    2215               Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    2216               if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    2217                 NoNonHydrogen++;
    2218               Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    2219               Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
    2220               sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
     2213      while (Walker->next != end) {
     2214        Walker = Walker->next;
     2215        Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
     2216        if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
     2217          NoNonHydrogen++;
     2218        Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
     2219        Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     2220        sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
    22212221        *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
    2222               i++;
    2223             }
     2222        i++;
     2223      }
    22242224    } else
    2225         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     2225      *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    22262226  }
    22272227};
     
    22312231void molecule::CountElements()
    22322232{
    2233         int i = 0;
     2233  int i = 0;
    22342234  for(i=MAX_ELEMENTS;i--;)
    2235         ElementsInMolecule[i] = 0;
    2236         ElementCount = 0;
     2235    ElementsInMolecule[i] = 0;
     2236  ElementCount = 0;
    22372237
    22382238  atom *walker = start;
     
    22432243  }
    22442244  for(i=MAX_ELEMENTS;i--;)
    2245         ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
     2245    ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
    22462246};
    22472247
     
    23342334{
    23352335
    2336         // 1 We will parse bonds out of the dbond file created by tremolo.
    2337                         int atom1, atom2, temp;
    2338                         atom *Walker, *OtherWalker;
    2339 
    2340                 if (!input)
    2341                 {
    2342                         cout << Verbose(1) << "Opening silica failed \n";
    2343                 };
    2344 
    2345                         *input >> ws >> atom1;
    2346                         *input >> ws >> atom2;
    2347                 cout << Verbose(1) << "Scanning file\n";
    2348                 while (!input->eof()) // Check whether we read everything already
    2349                 {
    2350                                 *input >> ws >> atom1;
    2351                                 *input >> ws >> atom2;
    2352                         if(atom2<atom1) //Sort indices of atoms in order
    2353                         {
    2354                                 temp=atom1;
    2355                                 atom1=atom2;
    2356                                 atom2=temp;
    2357                         };
    2358 
    2359                         Walker=start;
    2360                         while(Walker-> nr != atom1) // Find atom corresponding to first index
    2361                         {
    2362                                 Walker = Walker->next;
    2363                         };
    2364                         OtherWalker = Walker->next;
    2365                         while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    2366                         {
    2367                                 OtherWalker= OtherWalker->next;
    2368                         };
    2369                         AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    2370                        
    2371                 }
    2372 
    2373                 CreateListOfBondsPerAtom(out);
     2336  // 1 We will parse bonds out of the dbond file created by tremolo.
     2337      int atom1, atom2, temp;
     2338      atom *Walker, *OtherWalker;
     2339
     2340          if (!input)
     2341          {
     2342            cout << Verbose(1) << "Opening silica failed \n";
     2343          };
     2344
     2345      *input >> ws >> atom1;
     2346      *input >> ws >> atom2;
     2347          cout << Verbose(1) << "Scanning file\n";
     2348          while (!input->eof()) // Check whether we read everything already
     2349          {
     2350        *input >> ws >> atom1;
     2351        *input >> ws >> atom2;
     2352            if(atom2<atom1) //Sort indices of atoms in order
     2353            {
     2354              temp=atom1;
     2355              atom1=atom2;
     2356              atom2=temp;
     2357            };
     2358
     2359            Walker=start;
     2360            while(Walker-> nr != atom1) // Find atom corresponding to first index
     2361            {
     2362              Walker = Walker->next;
     2363            };
     2364            OtherWalker = Walker->next;
     2365            while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     2366            {
     2367              OtherWalker= OtherWalker->next;
     2368            };
     2369            AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     2370           
     2371          }
     2372
     2373          CreateListOfBondsPerAtom(out);
    23742374
    23752375};
     
    25202520    // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    25212521    // double bonds as was expected.
    2522                 if (BondCount != 0) {
     2522    if (BondCount != 0) {
    25232523      NoCyclicBonds = 0;
    2524                   *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    2525                   do {
    2526                     No = 0; // No acts as breakup flag (if 1 we still continue)
     2524      *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     2525      do {
     2526        No = 0; // No acts as breakup flag (if 1 we still continue)
    25272527        Walker = start;
    25282528        while (Walker->next != end) { // go through every atom
     
    25382538            for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    25392539              OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    2540                     // count valence of second partner
     2540              // count valence of second partner
    25412541              NoBonds = 0;
    25422542              for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    25432543                NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    25442544              *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    2545                     if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    2546                       if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
     2545              if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     2546                if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    25472547                  Candidate = OtherWalker;
    25482548                  CandidateBondNo = i;
    2549                         *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    2550                       }
    2551                     }
    2552                   }
     2549                  *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
     2550                }
     2551              }
     2552            }
    25532553            if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    25542554              ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
     
    25582558              FalseBondDegree++;
    25592559          }
    2560                     }
    2561                   } while (No);
    2562                 *out << " done." << endl;
    2563                 } else
    2564                         *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    2565           *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    2566                
    2567           // output bonds for debugging (if bond chain list was correctly installed)
    2568           *out << Verbose(1) << endl << "From contents of bond chain list:";
    2569           bond *Binder = first;
     2560        }
     2561      } while (No);
     2562    *out << " done." << endl;
     2563    } else
     2564      *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
     2565    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     2566   
     2567    // output bonds for debugging (if bond chain list was correctly installed)
     2568    *out << Verbose(1) << endl << "From contents of bond chain list:";
     2569    bond *Binder = first;
    25702570    while(Binder->next != last) {
    25712571      Binder = Binder->next;
    2572                         *out << *Binder << "\t" << endl;
     2572      *out << *Binder << "\t" << endl;
    25732573    }
    25742574    *out << endl;
    25752575  } else
    2576         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     2576    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    25772577  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    25782578  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
     
    36003600int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
    36013601{
    3602         MoleculeListClass *BondFragments = NULL;
     3602  MoleculeListClass *BondFragments = NULL;
    36033603  int *SortIndex = NULL;
    36043604  int *MinimumRingSize = new int[AtomCount];
     
    38063806    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    38073807    if (Walker != NULL) // if this Walker exists in the subgraph ...
    3808         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3809         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3810               if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3811                 LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3808      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3809        OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3810        if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3811            LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    38123812                *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3813                 break;
    3814             }
    3815         }
     3813          break;
     3814        }
     3815      }
    38163816    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
    38173817    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
     
    43084308  for (int i=0;i<AtomCount;i++) { // reset all atom labels
    43094309    // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons
    4310                 Labels[i] = -1;
     4310    Labels[i] = -1;
    43114311    SonList[i] = NULL;
    43124312    PredecessorList[i] = NULL;
     
    43164316  for (int i=0;i<BondCount;i++)
    43174317    ColorEdgeList[i] = white;
    4318         RootStack->ClearStack();        // clearstack and push first atom if exists
     4318  RootStack->ClearStack();  // clearstack and push first atom if exists
    43194319  TouchedStack->ClearStack();
    43204320  Walker = start->next;
     
    43354335  ///// OUTER LOOP ////////////
    43364336  while (!RootStack->IsEmpty()) {
    4337         // get new root vertex from atom stack
    4338         Root = RootStack->PopFirst();
     4337    // get new root vertex from atom stack
     4338    Root = RootStack->PopFirst();
    43394339    ShortestPathList[Root->nr] = 0;
    43404340    if (Labels[Root->nr] == -1)
     
    43444344    *out << Verbose(0) << "Root for this loop is: " << Root->Name << ".\n";
    43454345
    4346                 // clear snake stack
    4347           SnakeStack->ClearStack();
     4346    // clear snake stack
     4347    SnakeStack->ClearStack();
    43484348    //SnakeStack->TestImplementation(out, start->next);
    43494349
     
    43524352    // - what about cyclic bonds?
    43534353    Walker = Root;
    4354         do {
     4354    do {
    43554355      *out << Verbose(1) << "Current Walker is: " << Walker->Name;
    43564356      // initial setting of the new Walker: label, color, shortest path and put on stacks
    4357                 if (Labels[Walker->nr] == -1)   {       // give atom a unique, monotonely increasing number
    4358                         Labels[Walker->nr] = RunningIndex++;
     4357      if (Labels[Walker->nr] == -1)  {  // give atom a unique, monotonely increasing number
     4358        Labels[Walker->nr] = RunningIndex++;
    43594359        RootStack->Push(Walker);
    43604360      }
    43614361      *out << ", has label " << Labels[Walker->nr];
    4362                 if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) {     // color it if newly discovered and push on stacks (and if within reach!)
     4362      if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) {  // color it if newly discovered and push on stacks (and if within reach!)
    43634363        if ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white)) {
    43644364          // Binder ought to be set still from last neighbour search
     
    43744374          ColorVertexList[Walker->nr] = darkgray; // mark as dark gray of on snake stack
    43754375        }
    4376                 }
     4376      }
    43774377      *out << ", SP of " << ShortestPathList[Walker->nr]  << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl;
    43784378
    43794379      // then check the stack for a newly stumbled upon fragment
    4380                 if (SnakeStack->ItemCount() == Order) { // is stack full?
     4380      if (SnakeStack->ItemCount() == Order) { // is stack full?
    43814381        // store the fragment if it is one and get a removal candidate
    43824382        Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration);
     
    43914391          }
    43924392        }
    4393                 } else
     4393      } else
    43944394        Removal = NULL;
    43954395
     
    43984398      if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) {  // don't look, if a new walker has been set above
    43994399        *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl;
    4400                         OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour
     4400        OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour
    44014401        if (ShortestPathList[Walker->nr] < Order) {
    4402                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     4402          for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    44034403            Binder = ListOfBondsPerAtom[Walker->nr][i];
    44044404            *out << Verbose(2) << "Current bond is " << *Binder << ": ";
    4405                                 OtherAtom = Binder->GetOtherAtom(Walker);
     4405            OtherAtom = Binder->GetOtherAtom(Walker);
    44064406            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    44074407              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    44084408              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    44094409            } else { // otherwise check its colour and element
    4410                                 if (
     4410              if (
    44114411#ifdef ADDHYDROGEN
    44124412              (OtherAtom->type->Z != 1) &&
     
    44304430              }
    44314431            }
    4432                         }
     4432          }
    44334433        } else {  // means we have stepped beyond the horizon: Return!
    44344434          Walker = PredecessorList[Walker->nr];
     
    44364436          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    44374437        }
    4438                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
     4438        if (Walker != OtherAtom) {  // if no white neighbours anymore, color it black
    44394439          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    4440                                 ColorVertexList[Walker->nr] = black;
    4441                                 Walker = PredecessorList[Walker->nr];
    4442                         }
    4443       }
    4444         } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
     4440          ColorVertexList[Walker->nr] = black;
     4441          Walker = PredecessorList[Walker->nr];
     4442        }
     4443      }
     4444    } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    44454445    *out << Verbose(2) << "Inner Looping is finished." << endl;
    44464446
     
    45624562        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    45634563        if (bit) {  // if bit is set, we add this bond partner
    4564                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
     4564          OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
    45654565          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    45664566          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
     
    45844584        if (SubOrder > 1) {    // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
    45854585          // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
    4586           SP = RootDistance+1;  // this is the next level
     4586          SP = RootDistance+1;  // this is the next level
    45874587          // first count the members in the subset
    45884588          SubSetDimension = 0;
    4589           Binder = FragmentSearch->BondsPerSPList[2*SP];                // start node for this level
    4590           while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {              // compare to end node of this level
     4589          Binder = FragmentSearch->BondsPerSPList[2*SP];    // start node for this level
     4590          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {    // compare to end node of this level
    45914591            Binder = Binder->next;
    45924592            for (int k=TouchedIndex;k--;) {
  • src/parser.cpp

    r986c80 rce5ac3  
    786786          }
    787787          if (k != -1) {
    788                 //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
     788            //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
    789789            Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
    790790          }
     
    855855                  }
    856856                  if (Order == SubOrder) { // equal order is always copy from Energies
    857                         //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
     857                    //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
    858858                    Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    859859                  } else {
    860                         //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
     860                    //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
    861861                    Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    862862                  }
  • src/vector.cpp

    r986c80 rce5ac3  
    327327  }
    328328  ost << ")";
    329         return ost;
     329  return ost;
    330330};
    331331
     
    517517bool Vector::MakeNormalVector(const Vector *y1)
    518518{
    519         bool result = false;
     519  bool result = false;
    520520  Vector x1;
    521521  x1.CopyVector(y1);
     
    523523  SubtractVector(&x1);
    524524  for (int i=NDIM;i--;)
    525           result = result || (fabs(x[i]) > MYEPSILON);
     525    result = result || (fabs(x[i]) > MYEPSILON);
    526526
    527527  return result;
     
    597597bool Vector::LSQdistance(Vector **vectors, int num)
    598598{
    599         int j;
    600 
    601         for (j=0;j<num;j++) {
    602                 cout << Verbose(1) << j << "th atom's vector: ";
    603                 (vectors[j])->Output((ofstream *)&cout);
    604                 cout << endl;
    605         }
     599  int j;
     600
     601  for (j=0;j<num;j++) {
     602    cout << Verbose(1) << j << "th atom's vector: ";
     603    (vectors[j])->Output((ofstream *)&cout);
     604    cout << endl;
     605  }
    606606
    607607  int np = 3;
    608         struct LSQ_params par;
     608  struct LSQ_params par;
    609609
    610610   const gsl_multimin_fminimizer_type *T =
     
    627627   /* Starting point */
    628628   par.vectors = vectors;
    629         par.num = num;
    630 
    631         for (i=NDIM;i--;)
    632                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     629  par.num = num;
     630
     631  for (i=NDIM;i--;)
     632    gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
    633633
    634634   /* Initialize method and iterate */
     
    671671   gsl_multimin_fminimizer_free (s);
    672672
    673         return true;
     673  return true;
    674674};
    675675
  • src/verbose.cpp

    r986c80 rce5ac3  
    2222ostream& operator<<(ostream& ost,const Verbose& m)
    2323{
    24         return m.print(ost);
     24  return m.print(ost);
    2525};
    2626
     
    3333ostream& Binary::print (ostream &ost) const
    3434{
    35         int bits = 1, counter = 1;
    36         while ((bits = 1 << counter) < BinaryNumber)
     35  int bits = 1, counter = 1;
     36  while ((bits = 1 << counter) < BinaryNumber)
    3737    counter++;
    3838  for (int i=0;i<counter-1;i++) {
    39         if ((BinaryNumber & (1 << i)) == 0)
    40                 ost.put('0');
    41                 else
    42                 ost.put('1');
     39    if ((BinaryNumber & (1 << i)) == 0)
     40      ost.put('0');
     41     else
     42      ost.put('1');
    4343  }
    4444  ost.put('b');
     
    5656ostream& operator<<(ostream& ost,const Binary& m)
    5757{
    58         return m.print(ost);
     58  return m.print(ost);
    5959};
Note: See TracChangeset for help on using the changeset viewer.