Changeset cc2ee5 for src


Ignore:
Timestamp:
Dec 29, 2008, 9:46:58 PM (17 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, Candidate_v1.7.0, 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:
a98603
Parents:
02bfde
git-author:
Frederik Heber <heber@…> (12/29/08 21:26:43)
git-committer:
Frederik Heber <heber@…> (12/29/08 21:46:58)
Message:

Just a temporary commit

Location:
src
Files:
2 deleted
32 edited

Legend:

Unmodified
Added
Removed
  • src/Hbondangle.db

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

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

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

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

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

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

    • Property mode changed from 100644 to 100755
    r02bfde rcc2ee5  
    33
    44#define DEBUG 1
     5#define DoTecplotOutput 0
     6#define DoRaster3DOutput 1
     7#define TecplotSuffix ".dat"
     8#define Raster3DSuffix ".r3d"
    59
    610// ======================================== Points on Boundary =================================
     
    2529  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    2630  node = NULL;
     31  lines.clear();
    2732}
    2833;
     
    8186BoundaryLineSet::~BoundaryLineSet()
    8287{
    83   for (int i = 0; i < 2; i++)
    84     {
    85       cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point "
    86           << *endpoints[i] << "." << endl;
    87       endpoints[i]->lines.erase(Nr);
    88       LineMap::iterator tester = endpoints[i]->lines.begin();
    89       tester++;
    90       if (tester == endpoints[i]->lines.end())
    91         {
    92           cout << Verbose(5) << *endpoints[i]
    93               << " has no more lines it's attached to, erasing." << endl;
    94           //delete(endpoints[i]);
    95         }
    96       else
    97         cout << Verbose(5) << *endpoints[i]
    98             << " has still lines it's attached to." << endl;
    99     }
     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        }
    100103}
    101104;
     
    178181BoundaryTriangleSet::~BoundaryTriangleSet()
    179182{
    180   for (int i = 0; i < 3; i++)
    181     {
    182       cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;
    183       lines[i]->triangles.erase(Nr);
    184       TriangleMap::iterator tester = lines[i]->triangles.begin();
    185       tester++;
    186       if (tester == lines[i]->triangles.end())
    187         {
    188           cout << Verbose(5) << *lines[i]
    189               << " is no more attached to any triangle, erasing." << endl;
    190           delete (lines[i]);
    191         }
    192       else
    193         cout << Verbose(5) << *lines[i] << " is still attached to a triangle."
    194             << 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;
     
    565565;
    566566
    567 /*
    568  * This function creates the tecplot file, displaying the tesselation of the hull.
     567/** Creates the objects in a raster3d file (renderable with a header.r3d)
     568 * \param *out output stream for debugging
     569 * \param *tecplot output stream for tecplot data
     570 * \param *Tess Tesselation structure with constructed triangles
     571 * \param *mol molecule structure with atom positions
     572 */
     573void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol)
     574{
     575        atom *Walker = mol->start;
     576        bond *Binder = mol->first;
     577        int i;
     578        Vector *center = mol->DetermineCenterOfAll(out);
     579        if (rasterfile != NULL) {
     580                //cout << Verbose(1) << "Writing Raster3D file ... ";
     581                *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;
     582                *rasterfile << "@header.r3d" << endl;
     583                *rasterfile << "# All atoms as spheres" << endl;
     584                while (Walker->next != mol->end) {
     585                        Walker = Walker->next;
     586                        *rasterfile << "2" << endl << "  ";     // 2 is sphere type
     587                        for (i=0;i<NDIM;i++)
     588                                *rasterfile << Walker->x.x[i]+center->x[i] << " ";
     589                        *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour
     590                }
     591
     592                *rasterfile << "# All bonds as vertices" << endl;
     593                while (Binder->next != mol->last) {
     594                        Binder = Binder->next;
     595                        *rasterfile << "3" << endl << "  ";     // 2 is round-ended cylinder type
     596                        for (i=0;i<NDIM;i++)
     597                                *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " ";
     598                        *rasterfile << "\t0.03\t";
     599                        for (i=0;i<NDIM;i++)
     600                                *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " ";
     601                        *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour
     602                }
     603
     604                *rasterfile << "# All tesselation triangles" << endl;
     605                for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
     606                        *rasterfile << "1" << endl << "  ";     // 1 is triangle type
     607                        for (i=0;i<3;i++) {     // print each node
     608                                for (int j=0;j<NDIM;j++)        // and for each node all NDIM coordinates
     609                                        *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";
     610                                *rasterfile << "\t";
     611                        }
     612                        *rasterfile << "1. 0. 0." << endl;      // red as colour
     613                        *rasterfile << "18" << endl << "  0.5 0.5 0.5" << endl; // 18 is transparency type for previous object
     614                }
     615        } else {
     616                cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;
     617        }
     618        delete(center);
     619};
     620
     621/** This function creates the tecplot file, displaying the tesselation of the hull.
    569622 * \param *out output stream for debugging
    570623 * \param *tecplot output stream for tecplot data
     
    893946Tesselation::~Tesselation()
    894947{
    895   cout << Verbose(1) << "Free'ing TesselStruct ... " << endl;
    896   for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner
    897       != TrianglesOnBoundary.end(); runner++)
    898     {
    899       delete (runner->second);
    900     }
     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        }
    901970}
    902971;
     
    14391508    double Restradius;
    14401509    cout << Verbose(3) << "Begin of Get_center_of_sphere.\n";
    1441     *Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
     1510    Center->Zero();
     1511    helper.CopyVector(&a);
     1512    helper.Scale(sin(2.*alpha));
     1513    Center->AddVector(&helper);
     1514    helper.CopyVector(&b);
     1515    helper.Scale(sin(2.*beta));
     1516    Center->AddVector(&helper);
     1517    helper.CopyVector(&c);
     1518    helper.Scale(sin(2.*gamma));
     1519    Center->AddVector(&helper);
     1520    //*Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
    14421521    Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
    14431522    NewUmkreismittelpunkt->CopyVector(Center);
     
    15031582 */
    15041583
    1505 void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,
     1584void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,
    15061585    int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint,
    15071586    atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol)
    15081587{
    1509   cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    1510   cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
    1511   cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
    1512   cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
    1513   cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
    1514   cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
    1515   /* OldNormal is normal vector on the old triangle
    1516    * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1517    * Chord points from b to a!!!
    1518    */
    1519   Vector dif_a; //Vector from a to candidate
    1520   Vector dif_b; //Vector from b to candidate
    1521   Vector AngleCheck;
    1522   Vector TempNormal, Umkreismittelpunkt;
    1523   Vector Mittelpunkt;
    1524 
    1525   double CurrentEpsilon = 0.1;
    1526   double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
    1527   double BallAngle, AlternativeSign;
    1528   atom *Walker; // variable atom point
    1529 
    1530   Vector NewUmkreismittelpunkt;
    1531 
    1532 
    1533   if (a != Candidate and b != Candidate and c != Candidate)
    1534     {
    1535       cout << Verbose(3) << "We have a unique candidate!" << endl;
    1536       dif_a.CopyVector(&(a->x));
    1537       dif_a.SubtractVector(&(Candidate->x));
    1538       dif_b.CopyVector(&(b->x));
    1539       dif_b.SubtractVector(&(Candidate->x));
    1540       AngleCheck.CopyVector(&(Candidate->x));
    1541       AngleCheck.SubtractVector(&(a->x));
    1542       AngleCheck.ProjectOntoPlane(Chord);
    1543 
    1544       SideA = dif_b.Norm();
    1545       SideB = dif_a.Norm();
    1546       SideC = Chord->Norm();
    1547       //Chord->Scale(-1);
    1548 
    1549       alpha = Chord->Angle(&dif_a);
    1550       beta = M_PI - Chord->Angle(&dif_b);
    1551       gamma = dif_a.Angle(&dif_b);
    1552 
    1553       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;
    1554 
    1555       if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
    1556         cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    1557 
    1558       Umkreisradius = SideA / 2.0 / sin(alpha);
    1559       //cout << Umkreisradius << endl;
    1560       //cout << SideB / 2.0 / sin(beta) << endl;
    1561       //cout << SideC / 2.0 / sin(gamma) << endl;
    1562 
    1563       if (Umkreisradius < RADIUS) //Checking whether ball will at least rest on points.
    1564         {
    1565           cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
    1566           cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
    1567           sign = AngleCheck.ScalarProduct(direction1);
    1568           if (fabs(sign)<MYEPSILON)
    1569             {
    1570               if (AngleCheck.ScalarProduct(OldNormal)<0)
    1571                 {
    1572                   sign =0;
    1573                   AlternativeSign=1;
    1574                 }
    1575               else
    1576                 {
    1577                   sign =0;
    1578                   AlternativeSign=-1;
    1579                 }
    1580             }
    1581           else
    1582             {
    1583               sign /= fabs(sign);
    1584               cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
    1585             }
    1586 
    1587           Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
    1588 
    1589           AngleCheck.CopyVector(&ReferencePoint);
    1590           AngleCheck.Scale(-1);
    1591           //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1592           AngleCheck.AddVector(&Mittelpunkt);
    1593           //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1594           cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
    1595 
    1596           BallAngle = AngleCheck.Angle(OldNormal);
    1597           cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
    1598 
    1599           //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
    1600           //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1601 
    1602           cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
    1603 
    1604           NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
    1605 
    1606           if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON))
    1607             {
    1608               if (Storage[0]< -1.5) // first Candidate at all
    1609                 {
    1610 
    1611                   cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
    1612                   Opt_Candidate = Candidate;
    1613                   Storage[0] = sign;
    1614                   Storage[1] = AlternativeSign;
    1615                   Storage[2] = BallAngle;
    1616                   cout << " angle " << Storage[2] << " and Up/Down "
    1617                     << Storage[0] << endl;
    1618                 }
    1619               else
    1620                 {
    1621                   if ( Storage[2] > BallAngle)
    1622                     {
    1623                       cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
    1624                       Opt_Candidate = Candidate;
    1625                       Storage[0] = sign;
    1626                       Storage[1] = AlternativeSign;
    1627                       Storage[2] = BallAngle;
    1628                       cout << " angle " << Storage[2] << " and Up/Down "
    1629                         << Storage[0] << endl;
    1630                     }
    1631                   else
    1632                     {
    1633                       if (DEBUG)
    1634                         {
    1635                           cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
    1636                         }
    1637                     }
    1638                 }
    1639               }
    1640             else
    1641               {
    1642               if (DEBUG)
    1643                 {
    1644                   cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
    1645                 }
    1646               }
    1647           }
    1648         else
    1649           {
    1650             if (DEBUG)
    1651               {
    1652                 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
    1653               }
    1654           }
    1655       }
    1656     else
    1657       {
    1658         if (DEBUG)
    1659           {
    1660             cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
    1661           }
    1662       }
    1663 
    1664 
    1665 
    1666   if (RecursionLevel < 9) // Seven is the recursion level threshold.
    1667     {
    1668       for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) // go through all bond
    1669         {
    1670           Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(
    1671               Candidate);
    1672           if (Walker == Parent)
    1673             { // don't go back the same bond
    1674               continue;
    1675             }
    1676           else
    1677             {
    1678               Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel
    1679                   + 1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS,
    1680                   mol); //call function again
    1681             }
    1682         }
    1683     }
    1684   cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1588        cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
     1589        cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
     1590        cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
     1591        cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
     1592        cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
     1593        cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
     1594        /* OldNormal is normal vector on the old triangle
     1595         * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1596         * Chord points from b to a!!!
     1597         */
     1598        Vector dif_a; //Vector from a to candidate
     1599        Vector dif_b; //Vector from b to candidate
     1600        Vector AngleCheck;
     1601        Vector TempNormal, Umkreismittelpunkt;
     1602        Vector Mittelpunkt;
     1603
     1604        double CurrentEpsilon = 0.1;
     1605        double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
     1606        double BallAngle, AlternativeSign;
     1607        atom *Walker; // variable atom point
     1608
     1609        Vector NewUmkreismittelpunkt;
     1610
     1611        if (a != Candidate and b != Candidate and c != Candidate) {
     1612                cout << Verbose(3) << "We have a unique candidate!" << endl;
     1613                dif_a.CopyVector(&(a->x));
     1614                dif_a.SubtractVector(&(Candidate->x));
     1615                dif_b.CopyVector(&(b->x));
     1616                dif_b.SubtractVector(&(Candidate->x));
     1617                AngleCheck.CopyVector(&(Candidate->x));
     1618                AngleCheck.SubtractVector(&(a->x));
     1619                AngleCheck.ProjectOntoPlane(Chord);
     1620
     1621                SideA = dif_b.Norm();
     1622                SideB = dif_a.Norm();
     1623                SideC = Chord->Norm();
     1624                //Chord->Scale(-1);
     1625
     1626                alpha = Chord->Angle(&dif_a);
     1627                beta = M_PI - Chord->Angle(&dif_b);
     1628                gamma = dif_a.Angle(&dif_b);
     1629
     1630                cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     1631
     1632                if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {
     1633                        cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     1634                        cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     1635                }
     1636
     1637                if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
     1638                        Umkreisradius = SideA / 2.0 / sin(alpha);
     1639                        //cout << Umkreisradius << endl;
     1640                        //cout << SideB / 2.0 / sin(beta) << endl;
     1641                        //cout << SideC / 2.0 / sin(gamma) << endl;
     1642
     1643                        if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.
     1644                                cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
     1645                                cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
     1646                                sign = AngleCheck.ScalarProduct(direction1);
     1647                                if (fabs(sign)<MYEPSILON) {
     1648                                        if (AngleCheck.ScalarProduct(OldNormal)<0) {
     1649                                                sign =0;
     1650                                                AlternativeSign=1;
     1651                                        } else {
     1652                                                sign =0;
     1653                                                AlternativeSign=-1;
     1654                                        }
     1655                                } else {
     1656                                        sign /= fabs(sign);
     1657                                        cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
     1658                                }
     1659
     1660                                Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
     1661
     1662                                AngleCheck.CopyVector(&ReferencePoint);
     1663                                AngleCheck.Scale(-1);
     1664                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1665                                AngleCheck.AddVector(&Mittelpunkt);
     1666                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1667                                cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
     1668
     1669                                BallAngle = AngleCheck.Angle(OldNormal);
     1670                                cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
     1671
     1672                                //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
     1673                                //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
     1674
     1675                                cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
     1676
     1677                                NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
     1678
     1679                                if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
     1680                                        if (Storage[0]< -1.5) { // first Candidate at all
     1681                                                if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1682                                                        cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
     1683                                                        Opt_Candidate = Candidate;
     1684                                                        Storage[0] = sign;
     1685                                                        Storage[1] = AlternativeSign;
     1686                                                        Storage[2] = BallAngle;
     1687                                                        cout << " angle " << Storage[2] << " and Up/Down "
     1688                                                        << Storage[0] << endl;
     1689                                                } else
     1690                                                        cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1691                                        } else {
     1692                                                if ( Storage[2] > BallAngle) {
     1693                                                        if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
     1694                                                                cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
     1695                                                                Opt_Candidate = Candidate;
     1696                                                                Storage[0] = sign;
     1697                                                                Storage[1] = AlternativeSign;
     1698                                                                Storage[2] = BallAngle;
     1699                                                                cout << " angle " << Storage[2] << " and Up/Down "
     1700                                                                << Storage[0] << endl;
     1701                                                        } else
     1702                                                                cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
     1703                                                } else {
     1704                                                        if (DEBUG) {
     1705                                                                cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
     1706                                                        }
     1707                                                }
     1708                                        }
     1709                                } else {
     1710                                        if (DEBUG) {
     1711                                                cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
     1712                                        }
     1713                                }
     1714                        } else {
     1715                                if (DEBUG) {
     1716                                        cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
     1717                                }
     1718                        }
     1719                } else {
     1720                        if (DEBUG) {
     1721                                cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;
     1722                        }
     1723                }
     1724        } else {
     1725                if (DEBUG) {
     1726                        cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
     1727                }
     1728        }
     1729
     1730        if (RecursionLevel < 5) { // Seven is the recursion level threshold.
     1731                for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1732                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1733                        if (Walker == Parent) { // don't go back the same bond
     1734                                continue;
     1735                        } else {
     1736                                Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again
     1737                        }
     1738                }
     1739        }
     1740        cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    16851741}
    16861742;
     
    17091765   * @param mol molecule structure with atoms and bonds
    17101766   */
    1711 
    17121767void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, atom* Parent,
    17131768    int RecursionLevel, Vector *Chord, Vector *d1, Vector *OldNormal,
    17141769    atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol)
    17151770{
    1716   /* OldNormal is normal vector on the old triangle
    1717    * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1718    * Chord points from b to a!!!
    1719    */
    1720   Vector dif_a; //Vector from a to candidate
    1721   Vector dif_b; //Vector from b to candidate
    1722   Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
    1723   Vector TempNormal, Umkreismittelpunkt, Mittelpunkt;
    1724 
    1725   double CurrentEpsilon = 0.1;
    1726   double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
    1727   double BallAngle;
    1728   atom *Walker; // variable atom point
    1729 
    1730 
    1731   dif_a.CopyVector(&(a->x));
    1732   dif_a.SubtractVector(&(Candidate->x));
    1733   dif_b.CopyVector(&(b->x));
    1734   dif_b.SubtractVector(&(Candidate->x));
    1735   DirectionCheckPoint.CopyVector(&dif_a);
    1736   DirectionCheckPoint.Scale(-1);
    1737   DirectionCheckPoint.ProjectOntoPlane(Chord);
    1738 
    1739   SideA = dif_b.Norm();
    1740   SideB = dif_a.Norm();
    1741   SideC = Chord->Norm();
    1742   //Chord->Scale(-1);
    1743 
    1744   alpha = Chord->Angle(&dif_a);
    1745   beta = M_PI - Chord->Angle(&dif_b);
    1746   gamma = dif_a.Angle(&dif_b);
    1747 
    1748 
    1749   if (DEBUG)
    1750     {
    1751       cout << "Atom number" << Candidate->nr << endl;
    1752       Candidate->x.Output((ofstream *) &cout);
    1753       cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr]
    1754           << endl;
    1755     }
    1756 
    1757   if (a != Candidate and b != Candidate)
    1758     {
    1759       //      alpha = dif_a.Angle(&dif_b) / 2.;
    1760       //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
    1761       //      SideB = dif_a.Norm();
    1762       //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
    1763       //          alpha); // note this is squared of center line length
    1764       //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
    1765       // Those are remains from Freddie. Needed?
    1766 
    1767 
    1768 
    1769       Umkreisradius = SideA / 2.0 / sin(alpha);
    1770       //cout << Umkreisradius << endl;
    1771       //cout << SideB / 2.0 / sin(beta) << endl;
    1772       //cout << SideC / 2.0 / sin(gamma) << endl;
    1773 
    1774       if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) //Checking whether ball will at least rest o points.
    1775         {
    1776 
    1777           // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
    1778 
    1779           Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
    1780           Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    1781 
    1782           TempNormal.CopyVector(&dif_a);
    1783           TempNormal.VectorProduct(&dif_b);
    1784           if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0)
    1785             {
    1786               TempNormal.Scale(-1);
    1787             }
    1788           TempNormal.Normalize();
    1789           Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1790           TempNormal.Scale(Restradius);
    1791 
    1792           Mittelpunkt.CopyVector(&Umkreismittelpunkt);
    1793           Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
    1794 
    1795           AngleCheck.CopyVector(Chord);
    1796           AngleCheck.Scale(-0.5);
    1797           AngleCheck.SubtractVector(&(b->x));
    1798           AngleCheckReference.CopyVector(&AngleCheck);
    1799           AngleCheckReference.AddVector(Opt_Mittelpunkt);
    1800           AngleCheck.AddVector(&Mittelpunkt);
    1801 
    1802           BallAngle = AngleCheck.Angle(&AngleCheckReference);
    1803 
    1804           d1->ProjectOntoPlane(&AngleCheckReference);
    1805           sign = AngleCheck.ScalarProduct(d1);
    1806           if (fabs(sign) < MYEPSILON)
    1807             sign = 0;
    1808           else
    1809             sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
    1810 
    1811 
    1812           if (Storage[0]< -1.5) // first Candidate at all
    1813             {
    1814 
    1815               cout << "Next better candidate is " << *Candidate << " with ";
    1816               Opt_Candidate = Candidate;
    1817               Storage[0] = sign;
    1818               Storage[1] = BallAngle;
    1819               Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1820               cout << "Angle is " << Storage[1] << ", Halbraum ist "
    1821                   << Storage[0] << endl;
    1822 
    1823 
    1824             }
    1825           else
    1826             {
    1827               /*
    1828                * removed due to change in criterium, now checking angle of ball to old normal.
    1829               //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
    1830               //within the ball.
    1831 
    1832               Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
    1833               //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
    1834 
    1835 
    1836               if (Distance >RADIUS) // We have no interference and may now check whether the new point is better.
    1837                 */
    1838                 {
    1839                   //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
    1840 
    1841                   if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon)))  //This will give absolute preference to those in "right-hand" quadrants
    1842                       //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
    1843                     {
    1844                       cout << "Next better candidate is " << *Candidate << " with ";
    1845                       Opt_Candidate = Candidate;
    1846                       Storage[0] = sign;
    1847                       Storage[1] = BallAngle;
    1848                       Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1849                       cout << "Angle is " << Storage[1] << ", Halbraum ist "
    1850                           << Storage[0] << endl;
    1851 
    1852 
    1853                     }
    1854                   else
    1855                     {
    1856                       if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0
    1857                           && Storage[1] > BallAngle) ||
    1858                           (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0
    1859                           && Storage[1] < BallAngle))
    1860                       //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
    1861                         {
    1862                           cout << "Next better candidate is " << *Candidate << " with ";
    1863                           Opt_Candidate = Candidate;
    1864                           Storage[0] = sign;
    1865                           Storage[1] = BallAngle;
    1866                           Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1867                           cout << "Angle is " << Storage[1] << ", Halbraum ist "
    1868                               << Storage[0] << endl;
    1869                         }
    1870 
    1871                     }
    1872                 }
    1873               /*
     1771        /* OldNormal is normal vector on the old triangle
     1772         * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
     1773         * Chord points from b to a!!!
     1774         */
     1775        Vector dif_a; //Vector from a to candidate
     1776        Vector dif_b; //Vector from b to candidate
     1777        Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
     1778        Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
     1779
     1780        double CurrentEpsilon = 0.1;
     1781        double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;
     1782        double BallAngle;
     1783        atom *Walker; // variable atom point
     1784
     1785
     1786        dif_a.CopyVector(&(a->x));
     1787        dif_a.SubtractVector(&(Candidate->x));
     1788        dif_b.CopyVector(&(b->x));
     1789        dif_b.SubtractVector(&(Candidate->x));
     1790        DirectionCheckPoint.CopyVector(&dif_a);
     1791        DirectionCheckPoint.Scale(-1);
     1792        DirectionCheckPoint.ProjectOntoPlane(Chord);
     1793
     1794        SideA = dif_b.Norm();
     1795        SideB = dif_a.Norm();
     1796        SideC = Chord->Norm();
     1797        //Chord->Scale(-1);
     1798
     1799        alpha = Chord->Angle(&dif_a);
     1800        beta = M_PI - Chord->Angle(&dif_b);
     1801        gamma = dif_a.Angle(&dif_b);
     1802
     1803
     1804        if (DEBUG) {
     1805                cout << "Atom number" << Candidate->nr << endl;
     1806                Candidate->x.Output((ofstream *) &cout);
     1807                cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
     1808        }
     1809
     1810        if (a != Candidate and b != Candidate) {
     1811                //      alpha = dif_a.Angle(&dif_b) / 2.;
     1812                //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
     1813                //      SideB = dif_a.Norm();
     1814                //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
     1815                //          alpha); // note this is squared of center line length
     1816                //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
     1817                // Those are remains from Freddie. Needed?
     1818
     1819                Umkreisradius = SideA / 2.0 / sin(alpha);
     1820                //cout << Umkreisradius << endl;
     1821                //cout << SideB / 2.0 / sin(beta) << endl;
     1822                //cout << SideC / 2.0 / sin(gamma) << endl;
     1823
     1824                if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
     1825                        // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
     1826                        Umkreismittelpunkt.Zero();
     1827                        helper.CopyVector(&a->x);
     1828                        helper.Scale(sin(2.*alpha));
     1829                        Umkreismittelpunkt.AddVector(&helper);
     1830                        helper.CopyVector(&b->x);
     1831                        helper.Scale(sin(2.*beta));
     1832                        Umkreismittelpunkt.AddVector(&helper);
     1833                        helper.CopyVector(&Candidate->x);
     1834                        helper.Scale(sin(2.*gamma));
     1835                        Umkreismittelpunkt.AddVector(&helper);
     1836                        //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
     1837                        Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     1838
     1839                        TempNormal.CopyVector(&dif_a);
     1840                        TempNormal.VectorProduct(&dif_b);
     1841                        if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
     1842                                TempNormal.Scale(-1);
     1843                        }
     1844                        TempNormal.Normalize();
     1845                        Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
     1846                        TempNormal.Scale(Restradius);
     1847
     1848                        Mittelpunkt.CopyVector(&Umkreismittelpunkt);
     1849                        Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
     1850
     1851                        AngleCheck.CopyVector(Chord);
     1852                        AngleCheck.Scale(-0.5);
     1853                        AngleCheck.SubtractVector(&(b->x));
     1854                        AngleCheckReference.CopyVector(&AngleCheck);
     1855                        AngleCheckReference.AddVector(Opt_Mittelpunkt);
     1856                        AngleCheck.AddVector(&Mittelpunkt);
     1857
     1858                        BallAngle = AngleCheck.Angle(&AngleCheckReference);
     1859
     1860                        d1->ProjectOntoPlane(&AngleCheckReference);
     1861                        sign = AngleCheck.ScalarProduct(d1);
     1862                        if (fabs(sign) < MYEPSILON)
     1863                                sign = 0;
     1864                        else
     1865                                sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
     1866
     1867
     1868                        if (Storage[0]< -1.5) { // first Candidate at all
     1869                                cout << "Next better candidate is " << *Candidate << " with ";
     1870                                Opt_Candidate = Candidate;
     1871                                Storage[0] = sign;
     1872                                Storage[1] = BallAngle;
     1873                                Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1874                                cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1875                        } else {
     1876                                /*
     1877                                 * removed due to change in criterium, now checking angle of ball to old normal.
     1878                                //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
     1879                                //within the ball.
     1880
     1881                                Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
     1882                                //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
     1883
     1884
     1885                                if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
     1886                                 */
     1887                                        //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
     1888
     1889                                if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
     1890                                        //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
     1891                                        cout << "Next better candidate is " << *Candidate << " with ";
     1892                                        Opt_Candidate = Candidate;
     1893                                        Storage[0] = sign;
     1894                                        Storage[1] = BallAngle;
     1895                                        Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1896                                        cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1897                                } else {
     1898                                        if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
     1899                                                //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
     1900                                                cout << "Next better candidate is " << *Candidate << " with ";
     1901                                                Opt_Candidate = Candidate;
     1902                                                Storage[0] = sign;
     1903                                                Storage[1] = BallAngle;
     1904                                                Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
     1905                                                cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
     1906                                        }
     1907                                }
     1908                        }
     1909/*
    18741910               * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle.
    18751911               *
     
    19131949                }
    19141950                */
    1915             }
    1916         }
    1917       else
    1918         {
    1919           if (DEBUG)
    1920             {
    1921               cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
    1922             }
    1923         }
    1924     }
    1925 
    1926   else
    1927     {
    1928       if (DEBUG)
    1929         cout << "identisch mit Ursprungslinie" << endl;
    1930     }
    1931 
    1932   if (RecursionLevel < 9) // Five is the recursion level threshold.
    1933     {
    1934       for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) // go through all bond
    1935         {
    1936           Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(
    1937               Candidate);
    1938           if (Walker == Parent)
    1939             { // don't go back the same bond
    1940               continue;
    1941             }
    1942           else
    1943             {
    1944               Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel
    1945                   + 1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS,
    1946                   mol); //call function again
    1947 
    1948             }
    1949         }
    1950     }
    1951 }
    1952 ;
     1951                } else {
     1952                        if (DEBUG) {
     1953                                cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
     1954                        }
     1955                }
     1956        } else {
     1957                if (DEBUG) {
     1958                        cout << "identisch mit Ursprungslinie" << endl;
     1959                }
     1960        }
     1961
     1962        if (RecursionLevel < 9) { // Five is the recursion level threshold.
     1963                for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
     1964                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     1965                        if (Walker == Parent) { // don't go back the same bond
     1966                                continue;
     1967                        } else {
     1968                                Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
     1969                        }
     1970                }
     1971        }
     1972};
    19531973
    19541974/** This function finds a triangle to a line, adjacent to an existing one.
     
    19601980 * @param RADIUS radius of the rolling ball
    19611981 * @param N number of found triangles
     1982 * @param *filename filename base for intermediate envelopes
    19621983 */
    1963 void Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,
     1984bool Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,
    19641985    molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T,
    1965     const double& RADIUS, int N)
    1966 {
    1967   cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
    1968   Vector direction1;
    1969   Vector helper;
    1970   Vector Chord;
    1971   ofstream *tempstream = NULL;
    1972   char filename[255];
    1973   double tmp;
    1974   //atom* Walker;
    1975   atom* OldThirdPoint;
    1976 
    1977   double Storage[3];
    1978   Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
    1979   Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
    1980   Storage[2] = 9999999.;
    1981   atom* Opt_Candidate = NULL;
    1982   Vector Opt_Mittelpunkt;
    1983 
    1984   cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
    1985 
    1986   helper.CopyVector(&(Line.endpoints[0]->node->x));
    1987   for (int i = 0; i < 3; i++)
    1988     {
    1989       if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr
    1990           && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr)
    1991         {
    1992           OldThirdPoint = T.endpoints[i]->node;
    1993           helper.SubtractVector(&T.endpoints[i]->node->x);
    1994           break;
    1995         }
    1996     }
    1997 
    1998   direction1.CopyVector(&Line.endpoints[0]->node->x);
    1999   direction1.SubtractVector(&Line.endpoints[1]->node->x);
    2000   direction1.VectorProduct(&(T.NormalVector));
    2001 
    2002   if (direction1.ScalarProduct(&helper) < 0)
    2003     {
    2004       direction1.Scale(-1);
    2005     }
    2006   cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
    2007 
    2008   Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
    2009   Chord.SubtractVector(&(Line.endpoints[1]->node->x));
    2010   cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
    2011 
    2012 
    2013   Vector Umkreismittelpunkt, a, b, c;
    2014   double alpha, beta, gamma;
    2015   a.CopyVector(&(T.endpoints[0]->node->x));
    2016   b.CopyVector(&(T.endpoints[1]->node->x));
    2017   c.CopyVector(&(T.endpoints[2]->node->x));
    2018   a.SubtractVector(&(T.endpoints[1]->node->x));
    2019   b.SubtractVector(&(T.endpoints[2]->node->x));
    2020   c.SubtractVector(&(T.endpoints[0]->node->x));
    2021 
    2022 //  alpha = a.Angle(&c) - M_PI/2.;
    2023 //  beta = b.Angle(&a);
    2024 //  gamma = c.Angle(&b) - M_PI/2.;
    2025     alpha = M_PI - a.Angle(&c);
    2026     beta = M_PI - b.Angle(&a);
    2027     gamma = M_PI - c.Angle(&b);
    2028     if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
    2029       cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    2030 
    2031     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) ;
    2032     //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2033     Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    2034     cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2035     cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
    2036     cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
    2037 
    2038   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;
    2039   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) ;
    2040   Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    2041   cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
    2042   if (DEBUG)
    2043     cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
    2044   tmp = 0;
    2045   for (int i=0;i<NDIM;i++) {
    2046     helper.CopyVector(&T.endpoints[i]->node->x);
    2047     helper.SubtractVector(&Umkreismittelpunkt);
    2048     if (DEBUG)
    2049       cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
    2050     if (tmp == 0) // set on first time for comparison against next ones
    2051       tmp = helper.Norm();
    2052     if (fabs(helper.Norm() - tmp) > MYEPSILON)
    2053       cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
    2054   }
    2055 
    2056   cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
    2057 
    2058   Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint,
    2059       Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1,
    2060       &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2061   Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint,
    2062       Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1,
    2063       &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2064 
    2065 
    2066       cout << "Letzter Winkel bei " << TrianglesOnBoundaryCount << " Winkel ist " << Storage[2] << endl;
    2067 
    2068 
    2069   if ((TrianglesOnBoundaryCount % 1) == 0)
    2070     {
    2071     cout << Verbose(1) << "Writing temporary non convex hull to file testEnvelope-" << TriangleFilesWritten << "d.dat.\n";
    2072     sprintf(filename, "testEnvelope-%d.dat", TriangleFilesWritten);
    2073     tempstream = new ofstream(filename, ios::trunc);
    2074     write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten++);
    2075     tempstream->close();
    2076     tempstream->flush();
    2077     delete(tempstream);
    2078   }
    2079 
    2080   if (TrianglesOnBoundaryCount >189 and TrianglesOnBoundaryCount < 200 )
    2081     {
    2082       cerr << Verbose(0)
    2083           << "WARNING: Already more than " << TrianglesOnBoundaryCount-1 << "triangles, construction probably has crashed." << endl;
    2084       write_tecplot_file(out, tecplot, this, mol, TriangleFilesWritten);
    2085       cout << Verbose(2) << "This is currently added candidate" << Opt_Candidate << endl;
    2086     }
    2087   // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke
    2088 
    2089   cout << Verbose(2) << " Optimal candidate is " << *Opt_Candidate << endl;
    2090 
    2091   // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
    2092 
    2093   AddTrianglePoint(Opt_Candidate, 0);
    2094   LineMap::iterator TryAndError;
    2095   TryAndError = TPS[0]->lines.find(Line.endpoints[0]->node->nr);
    2096   bool flag = true;
    2097   if ((TryAndError != TPS[0]->lines.end()) && (TryAndError->second->TrianglesCount > 1))
    2098     flag = false;
    2099   TryAndError = TPS[0]->lines.find(Line.endpoints[1]->node->nr);
    2100   if ((TryAndError !=  TPS[0]->lines.end()) && (TryAndError->second->TrianglesCount > 1))
    2101     flag = false;
    2102 
    2103   if (flag) { // if so, add
    2104     AddTrianglePoint(Line.endpoints[0]->node, 1);
    2105     AddTrianglePoint(Line.endpoints[1]->node, 2);
    2106 
    2107     AddTriangleLine(TPS[0], TPS[1], 0);
    2108     AddTriangleLine(TPS[0], TPS[2], 1);
    2109     AddTriangleLine(TPS[1], TPS[2], 2);
    2110 
    2111     BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2112     AddTriangleToLines();
    2113 
    2114     BTS->GetNormalVector(BTS->NormalVector);
    2115 
    2116     if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  ||
    2117         (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) ||
    2118         (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) )
    2119 
    2120       {
    2121         BTS->NormalVector.Scale(-1);
    2122       };
    2123     cout << Verbose(2) << "New triangle with " << *BTS << "and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
    2124     cout << Verbose(2) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
    2125   } else { // else, yell and do nothing
    2126     cout << Verbose(2) << "This triangle consisting of ";
    2127     for (int i=0;i<NDIM;i++)
    2128       cout << BLS[i] << "(" << BLS[i]->TrianglesCount << "), ";
    2129     cout << " is invalid!" << endl;
    2130   }
    2131   cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
    2132 }
    2133 ;
     1986    const double& RADIUS, int N, const char *tempbasename)
     1987{
     1988        cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
     1989        Vector direction1;
     1990        Vector helper;
     1991        Vector Chord;
     1992        ofstream *tempstream = NULL;
     1993        char NumberName[255];
     1994        double tmp;
     1995        //atom* Walker;
     1996        atom* OldThirdPoint;
     1997
     1998        double Storage[3];
     1999        Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
     2000        Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
     2001        Storage[2] = 9999999.;
     2002        atom* Opt_Candidate = NULL;
     2003        Vector Opt_Mittelpunkt;
     2004
     2005        cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
     2006
     2007        helper.CopyVector(&(Line.endpoints[0]->node->x));
     2008        for (int i = 0; i < 3; i++) {
     2009                if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
     2010                        OldThirdPoint = T.endpoints[i]->node;
     2011                        helper.SubtractVector(&T.endpoints[i]->node->x);
     2012                        break;
     2013                }
     2014        }
     2015
     2016        direction1.CopyVector(&Line.endpoints[0]->node->x);
     2017        direction1.SubtractVector(&Line.endpoints[1]->node->x);
     2018        direction1.VectorProduct(&(T.NormalVector));
     2019
     2020        if (direction1.ScalarProduct(&helper) < 0) {
     2021                direction1.Scale(-1);
     2022        }
     2023        cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
     2024
     2025        Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
     2026        Chord.SubtractVector(&(Line.endpoints[1]->node->x));
     2027        cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
     2028
     2029
     2030        Vector Umkreismittelpunkt, a, b, c;
     2031        double alpha, beta, gamma;
     2032        a.CopyVector(&(T.endpoints[0]->node->x));
     2033        b.CopyVector(&(T.endpoints[1]->node->x));
     2034        c.CopyVector(&(T.endpoints[2]->node->x));
     2035        a.SubtractVector(&(T.endpoints[1]->node->x));
     2036        b.SubtractVector(&(T.endpoints[2]->node->x));
     2037        c.SubtractVector(&(T.endpoints[0]->node->x));
     2038
     2039        alpha = M_PI - a.Angle(&c);
     2040        beta = M_PI - b.Angle(&a);
     2041        gamma = M_PI - c.Angle(&b);
     2042        if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
     2043                cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
     2044
     2045        Umkreismittelpunkt.Zero();
     2046        helper.CopyVector(&T.endpoints[0]->node->x);
     2047        helper.Scale(sin(2.*alpha));
     2048        Umkreismittelpunkt.AddVector(&helper);
     2049        helper.CopyVector(&T.endpoints[1]->node->x);
     2050        helper.Scale(sin(2.*beta));
     2051        Umkreismittelpunkt.AddVector(&helper);
     2052        helper.CopyVector(&T.endpoints[2]->node->x);
     2053        helper.Scale(sin(2.*gamma));
     2054        Umkreismittelpunkt.AddVector(&helper);
     2055        //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;
     2056        //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2057        Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
     2058        //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
     2059        cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
     2060        cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
     2061
     2062        cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
     2063        cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
     2064        if (DEBUG)
     2065                cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
     2066        tmp = 0;
     2067        for (int i=0;i<NDIM;i++) {
     2068                helper.CopyVector(&T.endpoints[i]->node->x);
     2069                helper.SubtractVector(&Umkreismittelpunkt);
     2070                if (DEBUG)
     2071                        cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
     2072                if (tmp == 0) // set on first time for comparison against next ones
     2073                        tmp = helper.Norm();
     2074                if (fabs(helper.Norm() - tmp) > MYEPSILON)
     2075                        cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
     2076        }
     2077
     2078        cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
     2079
     2080        Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
     2081        Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
     2082        if (Opt_Candidate == NULL) {
     2083                cerr << "WARNING: Could not find a suitable candidate." << endl;
     2084                return false;
     2085        }
     2086        cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
     2087
     2088        // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
     2089        bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
     2090
     2091        if (flag) { // if so, add
     2092                AddTrianglePoint(Opt_Candidate, 0);
     2093                AddTrianglePoint(Line.endpoints[0]->node, 1);
     2094                AddTrianglePoint(Line.endpoints[1]->node, 2);
     2095
     2096                AddTriangleLine(TPS[0], TPS[1], 0);
     2097                AddTriangleLine(TPS[0], TPS[2], 1);
     2098                AddTriangleLine(TPS[1], TPS[2], 2);
     2099
     2100                BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2101                AddTriangleToLines();
     2102
     2103                BTS->GetNormalVector(BTS->NormalVector);
     2104
     2105                if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {
     2106                        BTS->NormalVector.Scale(-1);
     2107                };
     2108                cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
     2109                cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
     2110        } else { // else, yell and do nothing
     2111                cout << Verbose(1) << "This triangle consisting of ";
     2112                cout << *Opt_Candidate << ", ";
     2113                cout << *Line.endpoints[0]->node << " and ";
     2114                cout << *Line.endpoints[1]->node << " ";
     2115                cout << "is invalid!" << endl;
     2116                return false;
     2117        }
     2118
     2119        if ((TrianglesOnBoundaryCount % 10) == 0) {
     2120                sprintf(NumberName, "-%d", TriangleFilesWritten);
     2121                if (DoTecplotOutput) {
     2122                        string NameofTempFile(tempbasename);
     2123                        NameofTempFile.append(NumberName);
     2124                        NameofTempFile.append(TecplotSuffix);
     2125                        cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2126                        tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2127                        write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
     2128                        tempstream->close();
     2129                        tempstream->flush();
     2130                        delete(tempstream);
     2131                }
     2132
     2133                if (DoRaster3DOutput) {
     2134                        string NameofTempFile(tempbasename);
     2135                        NameofTempFile.append(NumberName);
     2136                        NameofTempFile.append(Raster3DSuffix);
     2137                        cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     2138                        tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     2139                        write_raster3d_file(out, tempstream, this, mol);
     2140                        tempstream->close();
     2141                        tempstream->flush();
     2142                        delete(tempstream);
     2143                }
     2144                if (DoTecplotOutput || DoRaster3DOutput)
     2145                        TriangleFilesWritten++;
     2146        }
     2147
     2148        cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
     2149        return true;
     2150};
     2151
     2152/** Checks whether the triangle consisting of the three atoms is already present.
     2153 * Searches for the points in Tesselation::PointsOnBoundary and checks their
     2154 * lines. If any of the three edges already has two triangles attached, false is
     2155 * returned.
     2156 * \param *out output stream for debugging
     2157 * \param *a first endpoint
     2158 * \param *b second endpoint
     2159 * \param *c third endpoint
     2160 * \return false - triangle invalid due to edge criteria, true - triangle may be added.
     2161 */
     2162bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) {
     2163        LineMap::iterator TryAndError;
     2164        PointTestPair InsertPoint;
     2165        bool Present[3];
     2166
     2167        *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;
     2168        TPS[0] = new class BoundaryPointSet(a);
     2169        TPS[1] = new class BoundaryPointSet(b);
     2170        TPS[2] = new class BoundaryPointSet(c);
     2171        for (int i=0;i<3;i++) { // check through all endpoints
     2172                InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));
     2173                Present[i] = !InsertPoint.second;
     2174                if (Present[i]) { // if new point was not present before, increase counter
     2175                        delete TPS[i];
     2176                        *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;
     2177                        TPS[i] = (InsertPoint.first)->second;
     2178                }
     2179        }
     2180
     2181        // check lines
     2182        for (int i=0;i<3;i++)
     2183                if (Present[i])
     2184                        for (int j=i;j<3;j++)
     2185                                if (Present[j]) {
     2186                                        TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);
     2187                                        if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {
     2188                                                *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;
     2189                                                *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2190                                                return false;
     2191                                        }
     2192                                }
     2193        *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
     2194        return true;
     2195};
     2196
    21342197
    21352198void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent,
     
    21372200    molecule* mol, double RADIUS)
    21382201{
    2139   cout << Verbose(2)
    2140       << "Begin of Find_second_point_for_Tesselation, recursive level "
    2141       << RecursionLevel << endl;
    2142   int i;
    2143   Vector AngleCheck;
    2144   atom* Walker;
    2145   double norm = -1., angle;
    2146 
    2147   // check if we only have one unique point yet ...
    2148   if (a != Candidate)
    2149     {
    2150     cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
    2151       AngleCheck.CopyVector(&(Candidate->x));
    2152       AngleCheck.SubtractVector(&(a->x));
    2153       norm = AngleCheck.Norm();
    2154       // second point shall have smallest angle with respect to Oben vector
    2155       if (norm < RADIUS)
    2156         {
    2157         angle = AngleCheck.Angle(&Oben);
    2158           if (angle < Storage[0])
    2159             {
    2160               //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
    2161               cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
    2162               Opt_Candidate = Candidate;
    2163               Storage[0] = AngleCheck.Angle(&Oben);
    2164               //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
    2165             }
    2166           else
    2167             {
    2168               cout << "Looses with angle " << angle << " to a better candidate "
    2169                   << *Opt_Candidate << endl;
    2170             }
    2171         }
    2172       else
    2173         {
    2174           cout << "Refused due to Radius " << norm
    2175               << endl;
    2176         }
    2177     }
    2178 
    2179   // if not recursed to deeply, look at all its bonds
    2180   if (RecursionLevel < 7)
    2181     {
    2182       for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++)
    2183         {
    2184           Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(
    2185               Candidate);
    2186           if (Walker == Parent) // don't go back along the bond we came from
    2187             continue;
    2188           else
    2189             Find_second_point_for_Tesselation(a, Walker, Candidate,
    2190                 RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
    2191         };
    2192     };
    2193   cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level "
    2194       << RecursionLevel << endl;
    2195 }
    2196 ;
     2202        cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2203        int i;
     2204        Vector AngleCheck;
     2205        atom* Walker;
     2206        double norm = -1., angle;
     2207
     2208        // check if we only have one unique point yet ...
     2209        if (a != Candidate) {
     2210                cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
     2211                AngleCheck.CopyVector(&(Candidate->x));
     2212                AngleCheck.SubtractVector(&(a->x));
     2213                norm = AngleCheck.Norm();
     2214                // second point shall have smallest angle with respect to Oben vector
     2215                if (norm < RADIUS) {
     2216                        angle = AngleCheck.Angle(&Oben);
     2217                        if (angle < Storage[0]) {
     2218                                //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
     2219                                cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
     2220                                Opt_Candidate = Candidate;
     2221                                Storage[0] = AngleCheck.Angle(&Oben);
     2222                                //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
     2223                        } else {
     2224                                cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
     2225                        }
     2226                } else {
     2227                        cout << "Refused due to Radius " << norm << endl;
     2228                }
     2229        }
     2230
     2231        // if not recursed to deeply, look at all its bonds
     2232        if (RecursionLevel < 7) {
     2233                for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
     2234                        Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
     2235                        if (Walker == Parent) // don't go back along the bond we came from
     2236                                continue;
     2237                        else
     2238                                Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
     2239                }
     2240        }
     2241        cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
     2242};
    21972243
    21982244void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
    21992245{
    2200   cout << Verbose(1) << "Begin of Find_starting_triangle\n";
    2201   int i = 0;
    2202   atom* Walker;
    2203   atom* FirstPoint;
    2204   atom* SecondPoint;
    2205   atom* max_index[NDIM];
    2206   double max_coordinate[NDIM];
    2207   Vector Oben;
    2208   Vector helper;
    2209   Vector Chord;
    2210   Vector CenterOfFirstLine;
    2211 
    2212   Oben.Zero();
    2213 
    2214   for (i = 0; i < 3; i++)
    2215     {
    2216       max_index[i] = NULL;
    2217       max_coordinate[i] = -1;
    2218     }
    2219   cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount
    2220       << " Atoms \n";
    2221 
    2222   // 1. searching topmost atom with respect to each axis
    2223   Walker = mol->start;
    2224   while (Walker->next != mol->end)
    2225     {
    2226       Walker = Walker->next;
    2227       for (i = 0; i < 3; i++)
    2228         {
    2229           if (Walker->x.x[i] > max_coordinate[i])
    2230             {
    2231               max_coordinate[i] = Walker->x.x[i];
    2232               max_index[i] = Walker;
    2233             }
    2234         }
    2235     }
    2236 
    2237   cout << Verbose(2) << "Found maximum coordinates: ";
    2238   for (int i=0;i<NDIM;i++)
    2239     cout << i << ": " << *max_index[i] << "\t";
    2240   cout << endl;
     2246        cout << Verbose(1) << "Begin of Find_starting_triangle\n";
     2247        int i = 0;
     2248        atom* Walker;
     2249        atom* FirstPoint;
     2250        atom* SecondPoint;
     2251        atom* max_index[NDIM];
     2252        double max_coordinate[NDIM];
     2253        Vector Oben;
     2254        Vector helper;
     2255        Vector Chord;
     2256        Vector CenterOfFirstLine;
     2257
     2258        Oben.Zero();
     2259
     2260        for (i = 0; i < 3; i++) {
     2261                max_index[i] = NULL;
     2262                max_coordinate[i] = -1;
     2263        }
     2264        cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
     2265
     2266        // 1. searching topmost atom with respect to each axis
     2267        Walker = mol->start;
     2268        while (Walker->next != mol->end) {
     2269                Walker = Walker->next;
     2270                for (i = 0; i < 3; i++) {
     2271                        if (Walker->x.x[i] > max_coordinate[i]) {
     2272                                max_coordinate[i] = Walker->x.x[i];
     2273                                max_index[i] = Walker;
     2274                        }
     2275                }
     2276        }
     2277
     2278        cout << Verbose(2) << "Found maximum coordinates: ";
     2279        for (int i=0;i<NDIM;i++)
     2280                cout << i << ": " << *max_index[i] << "\t";
     2281        cout << endl;
    22412282  //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
    2242   const int k = 1;
    2243   Oben.x[k] = 1.;
    2244   FirstPoint = max_index[k];
    2245 
    2246   cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
    2247   double Storage[3];
    2248   atom* Opt_Candidate = NULL;
    2249   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.
    2250   Storage[1] = 999999.; // This will be an angle looking for the third point.
    2251   Storage[2] = 999999.;
    2252 
    2253   Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0,
    2254       Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
    2255   SecondPoint = Opt_Candidate;
    2256   cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
    2257 
    2258   helper.CopyVector(&(FirstPoint->x));
    2259   helper.SubtractVector(&(SecondPoint->x));
    2260   helper.Normalize();
    2261   Oben.ProjectOntoPlane(&helper);
    2262   Oben.Normalize();
    2263   helper.VectorProduct(&Oben);
    2264   Storage[0] = -2.; // This will indicate the quadrant.
    2265   Storage[1] = 9999999.; // This will be an angle looking for the third point.
    2266   Storage[2] = 9999999.;
    2267 
    2268   Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
    2269   Chord.SubtractVector(&(SecondPoint->x));
    2270   // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
    2271 
    2272   cout << Verbose(2) << "Looking for third point candidates \n";
    2273   // look in one direction of baseline for initial candidate
    2274   Opt_Candidate = NULL;
    2275   CenterOfFirstLine.CopyVector(&Chord);
    2276   CenterOfFirstLine.Scale(0.5);
    2277   CenterOfFirstLine.AddVector(&(SecondPoint->x));
    2278 
    2279   cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
    2280   Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0,
    2281       &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
    2282   // look in other direction of baseline for possible better candidate
    2283   cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
    2284   Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0,
    2285       &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
    2286   cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
    2287 
    2288   // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
    2289 
    2290   // Finally, we only have to add the found points
    2291   AddTrianglePoint(FirstPoint, 0);
    2292   AddTrianglePoint(SecondPoint, 1);
    2293   AddTrianglePoint(Opt_Candidate, 2);
    2294   // ... and respective lines
    2295   AddTriangleLine(TPS[0], TPS[1], 0);
    2296   AddTriangleLine(TPS[1], TPS[2], 1);
    2297   AddTriangleLine(TPS[0], TPS[2], 2);
    2298   // ... and triangles to the Maps of the Tesselation class
    2299   BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2300   AddTriangleToLines();
    2301   // ... and calculate its normal vector (with correct orientation)
    2302   Oben.Scale(-1.);
    2303   BTS->GetNormalVector(Oben);
    2304   cout << Verbose(0) << "==> The found starting triangle consists of "
    2305       << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate
    2306       << " with normal vector " << BTS->NormalVector << ".\n";
    2307   cout << Verbose(1) << "End of Find_starting_triangle\n";
    2308 }
    2309 ;
    2310 
    2311 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol)
    2312 {
    2313   int N = 0;
    2314   struct Tesselation *Tess = new Tesselation;
    2315   cout << Verbose(1) << "Entering search for non convex hull. " << endl;
    2316   cout << flush;
    2317   const double RADIUS = 6.;
    2318   LineMap::iterator baseline;
    2319   cout << Verbose(0) << "Begin of Find_non_convex_border\n";
    2320   bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
    2321 
    2322   Tess->Find_starting_triangle(mol, RADIUS);
    2323 
    2324   baseline = Tess->LinesOnBoundary.begin();
    2325   while ((baseline != Tess->LinesOnBoundary.end()) || (flag))
    2326     {
    2327       if (baseline->second->TrianglesCount == 1)
    2328         {
    2329           Tess->Find_next_suitable_triangle(out, tecplot, mol,
    2330               *(baseline->second),
    2331               *(((baseline->second->triangles.begin()))->second), RADIUS, N); //the line is there, so there is a triangle, but only one.
    2332           flag = true;
    2333         }
    2334       else
    2335         {
    2336           cout << Verbose(1) << "Line " << baseline->second << " has "
    2337               << baseline->second->TrianglesCount << " triangles adjacent"
    2338               << endl;
    2339         }
    2340       N++;
    2341       baseline++;
    2342       if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
    2343         baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
    2344         flag = false;
    2345       }
    2346     }
    2347   cout << Verbose(1) << "Writing final tecplot file\n";
    2348   write_tecplot_file(out, tecplot, Tess, mol, -1);
    2349 
    2350   cout << Verbose(0) << "End of Find_non_convex_border\n";
    2351 }
    2352 ;
    2353 
     2283        const int k = 1;
     2284        Oben.x[k] = 1.;
     2285        FirstPoint = max_index[k];
     2286
     2287        cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
     2288        double Storage[3];
     2289        atom* Opt_Candidate = NULL;
     2290        Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
     2291        Storage[1] = 999999.; // This will be an angle looking for the third point.
     2292        Storage[2] = 999999.;
     2293
     2294        Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
     2295        SecondPoint = Opt_Candidate;
     2296        cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
     2297
     2298        helper.CopyVector(&(FirstPoint->x));
     2299        helper.SubtractVector(&(SecondPoint->x));
     2300        helper.Normalize();
     2301        Oben.ProjectOntoPlane(&helper);
     2302        Oben.Normalize();
     2303        helper.VectorProduct(&Oben);
     2304        Storage[0] = -2.; // This will indicate the quadrant.
     2305        Storage[1] = 9999999.; // This will be an angle looking for the third point.
     2306        Storage[2] = 9999999.;
     2307
     2308        Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
     2309        Chord.SubtractVector(&(SecondPoint->x));
     2310        // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
     2311
     2312        cout << Verbose(2) << "Looking for third point candidates \n";
     2313        // look in one direction of baseline for initial candidate
     2314        Opt_Candidate = NULL;
     2315        CenterOfFirstLine.CopyVector(&Chord);
     2316        CenterOfFirstLine.Scale(0.5);
     2317        CenterOfFirstLine.AddVector(&(SecondPoint->x));
     2318
     2319        cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
     2320        Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
     2321        // look in other direction of baseline for possible better candidate
     2322        cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
     2323        Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
     2324        cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
     2325
     2326        // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
     2327
     2328        // Finally, we only have to add the found points
     2329        AddTrianglePoint(FirstPoint, 0);
     2330        AddTrianglePoint(SecondPoint, 1);
     2331        AddTrianglePoint(Opt_Candidate, 2);
     2332        // ... and respective lines
     2333        AddTriangleLine(TPS[0], TPS[1], 0);
     2334        AddTriangleLine(TPS[1], TPS[2], 1);
     2335        AddTriangleLine(TPS[0], TPS[2], 2);
     2336        // ... and triangles to the Maps of the Tesselation class
     2337        BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2338        AddTriangleToLines();
     2339        // ... and calculate its normal vector (with correct orientation)
     2340        Oben.Scale(-1.);
     2341        BTS->GetNormalVector(Oben);
     2342        cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
     2343        cout << Verbose(1) << "End of Find_starting_triangle\n";
     2344};
     2345
     2346void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS)
     2347{
     2348        int N = 0;
     2349        struct Tesselation *Tess = new Tesselation;
     2350        cout << Verbose(1) << "Entering search for non convex hull. " << endl;
     2351        cout << flush;
     2352        LineMap::iterator baseline;
     2353        cout << Verbose(0) << "Begin of Find_non_convex_border\n";
     2354        bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
     2355        bool failflag = false;
     2356        if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
     2357                mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
     2358
     2359        Tess->Find_starting_triangle(mol, RADIUS);
     2360
     2361        baseline = Tess->LinesOnBoundary.begin();
     2362        while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
     2363                if (baseline->second->TrianglesCount == 1) {
     2364                        failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.
     2365                        flag = flag || failflag;
     2366                        if (!failflag)
     2367                                cerr << "WARNING: Find_next_suitable_triangle failed." << endl;
     2368                } else {
     2369                        cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;
     2370                }
     2371                N++;
     2372                baseline++;
     2373                if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
     2374                        baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
     2375                        flag = false;
     2376                }
     2377        }
     2378        if (failflag) {
     2379                cout << Verbose(1) << "Writing final tecplot file\n";
     2380                if (DoTecplotOutput)
     2381                        write_tecplot_file(out, tecplot, Tess, mol, -1);
     2382                if (DoRaster3DOutput)
     2383                        write_raster3d_file(out, tecplot, Tess, mol);
     2384        } else {
     2385                cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
     2386        }
     2387
     2388        cout << Verbose(0) << "End of Find_non_convex_border\n";
     2389        delete(Tess);
     2390};
     2391
  • src/boundary.hpp

    • Property mode changed from 100644 to 100755
    r02bfde rcc2ee5  
    8686    void AddTriangleToLines();
    8787    void Find_starting_triangle(molecule* mol, const double RADIUS);
    88     void Find_next_suitable_triangle(ofstream *out, ofstream *tecplot, molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N);
     88    bool Find_next_suitable_triangle(ofstream *out, ofstream *tecplot, molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, const char *filename);
     89    bool CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c);
     90    void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent, int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol);
    8991
    9092    PointMap PointsOnBoundary;
     
    110112double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    111113void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
     114void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS);
    112115void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule *mol, bool problem);
    113 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol);
    114116
    115117
  • src/builder.cpp

    • Property mode changed from 100644 to 100755
    r02bfde rcc2ee5  
    259259static void CenterAtoms(molecule *mol)
    260260{
    261   Vector x, y;
     261  Vector x, y, helper;
    262262  char choice;  // menu choice char
    263263
     
    292292      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
    293293      mol->Translate(&y); // translate by boundary
    294       mol->SetBoxDimension(&(x+y*2));  // update Box of atoms by boundary
     294      helper.CopyVector(&y);
     295      helper.Scale(2.);
     296      helper.AddVector(&x);
     297      mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
    295298      break;
    296299    case 'd':
     
    10041007              }
    10051008              break;
    1006             case 'A':
    1007                 ExitFlag = 1;
    1008                 if ((argptr >= argc) || (argv[argptr][0] == '-')){
    1009                         ExitFlag =255;
    1010                         cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
    1011                 }
    1012                 else{
    1013                         cout << "Parsing bonds from " << argv[argptr] << "." << endl;
    1014                     ifstream *input = new ifstream(argv[argptr]);
    1015                         mol->CreateAdjacencyList2((ofstream *)&cout, input);
    1016                         input->close();
    1017                 }
    1018                 break;
    1019             case 'N':
    1020                 ExitFlag = 1;
    1021                 if ((argptr >= argc) || (argv[argptr][0] == '-')){
    1022                         ExitFlag = 255;
    1023                         cerr << "Not enough or invalid arguments given for non-convex envelope: -o <tecplot output file>" << endl;
    1024                         }
    1025                 else {
    1026                         cout << Verbose(0) << "Evaluating npn-convex envelope.";
    1027                         ofstream *output = new ofstream(argv[argptr], ios::trunc);
    1028                         cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
    1029                         Find_non_convex_border((ofstream *)&cout, output, mol);
    1030                         output->close();
    1031                         delete(output);
    1032                         argptr+=1;
    1033                         }
    1034                 break;
     1009                                                case 'A':
     1010                                                        ExitFlag = 1;
     1011                                                        if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
     1012                                                                ExitFlag =255;
     1013                                                                cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
     1014                                                        } else {
     1015                                                                cout << "Parsing bonds from " << argv[argptr] << "." << endl;
     1016                                                                ifstream *input = new ifstream(argv[argptr]);
     1017                                                                mol->CreateAdjacencyList2((ofstream *)&cout, input);
     1018                                                                input->close();
     1019                                                        }
     1020                                                        break;
     1021                                                case 'N':
     1022                                                        ExitFlag = 1;
     1023                                                        if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
     1024                                                                ExitFlag = 255;
     1025                                                                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
     1026                                                        } else {
     1027                                                                cout << Verbose(0) << "Evaluating npn-convex envelope.";
     1028                                                                string TempName(argv[argptr+1]);
     1029                                                                TempName.append(".r3d");
     1030                                                                ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
     1031                                                                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
     1032                                                                Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
     1033                                                                output->close();
     1034                                                                delete(output);
     1035                                                                argptr+=2;
     1036                                                        }
     1037                                                        break;
    10351038            case 'T':
    10361039              ExitFlag = 1;
  • src/config.cpp

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

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

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

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

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

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

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

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

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

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

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

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

    • Property mode changed from 100644 to 100755
    r02bfde rcc2ee5  
    6060#define LineMap map < int, class BoundaryLineSet * >
    6161#define LinePair pair < int, class BoundaryLineSet * >
    62 #define LineTestPair pair < LinePair::iterator, bool >
     62#define LineTestPair pair < LineMap::iterator, bool >
    6363
    6464#define TriangleMap map < int, class BoundaryTriangleSet * >
  • src/orbitals.db

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

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

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

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

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

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

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

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

    • Property mode changed from 100644 to 100755
    r02bfde rcc2ee5  
    5656
    5757ostream & operator << (ostream& ost, Vector &m);
    58 Vector& operator+=(Vector& a, const Vector& b);
    59 Vector& operator*=(Vector& a, const double m);
    60 Vector& operator*(const Vector& a, const double m);
    61 Vector& operator+(const Vector& a, const Vector& b);
     58//Vector& operator+=(Vector& a, const Vector& b);
     59//Vector& operator*=(Vector& a, const double m);
     60//Vector& operator*(const Vector& a, const double m);
     61//Vector& operator+(const Vector& a, const Vector& b);
    6262
    6363#endif /*VECTOR_HPP_*/
  • src/verbose.cpp

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