- Timestamp:
- Dec 29, 2008, 9:46:58 PM (17 years ago)
- 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)
- Location:
- src
- Files:
-
- 2 deleted
- 32 edited
-
.#border.cpp (deleted)
-
.#molecules.hpp (deleted)
-
Hbondangle.db (modified) (1 prop)
-
Hbonddistance.db (modified) (1 prop)
-
Makefile.am (modified) (1 prop)
-
analyzer.cpp (modified) (1 prop)
-
atom.cpp (modified) (1 prop)
-
bond.cpp (modified) (1 prop)
-
boundary.cpp (modified) (12 diffs, 1 prop)
-
boundary.hpp (modified) (2 diffs, 1 prop)
-
builder.cpp (modified) (3 diffs, 1 prop)
-
config.cpp (modified) (1 prop)
-
datacreator.cpp (modified) (1 prop)
-
datacreator.hpp (modified) (1 prop)
-
defs.hpp (modified) (1 prop)
-
element.cpp (modified) (1 prop)
-
elements.db (modified) (1 prop)
-
graph.cpp (modified) (1 prop)
-
helpers.cpp (modified) (1 prop)
-
helpers.hpp (modified) (1 prop)
-
joiner.cpp (modified) (1 prop)
-
moleculelist.cpp (modified) (1 prop)
-
molecules.cpp (modified) (1 prop)
-
molecules.hpp (modified) (1 diff, 1 prop)
-
orbitals.db (modified) (1 prop)
-
parser.cpp (modified) (1 prop)
-
parser.hpp (modified) (1 prop)
-
periodentafel.cpp (modified) (19 diffs, 1 prop)
-
periodentafel.hpp (modified) (1 prop)
-
stackclass.hpp (modified) (1 prop)
-
valence.db (modified) (1 prop)
-
vector.cpp (modified) (1 prop)
-
vector.hpp (modified) (1 diff, 1 prop)
-
verbose.cpp (modified) (1 prop)
Legend:
- Unmodified
- Added
- Removed
-
src/Hbondangle.db
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/Hbonddistance.db
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/Makefile.am
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/analyzer.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/atom.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/bond.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/boundary.cpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 3 3 4 4 #define DEBUG 1 5 #define DoTecplotOutput 0 6 #define DoRaster3DOutput 1 7 #define TecplotSuffix ".dat" 8 #define Raster3DSuffix ".r3d" 5 9 6 10 // ======================================== Points on Boundary ================================= … … 25 29 cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl; 26 30 node = NULL; 31 lines.clear(); 27 32 } 28 33 ; … … 81 86 BoundaryLineSet::~BoundaryLineSet() 82 87 { 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 } 100 103 } 101 104 ; … … 178 181 BoundaryTriangleSet::~BoundaryTriangleSet() 179 182 { 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 } 196 196 } 197 197 ; … … 565 565 ; 566 566 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 */ 573 void 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. 569 622 * \param *out output stream for debugging 570 623 * \param *tecplot output stream for tecplot data … … 893 946 Tesselation::~Tesselation() 894 947 { 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 } 901 970 } 902 971 ; … … 1439 1508 double Restradius; 1440 1509 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) ; 1442 1521 Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma))); 1443 1522 NewUmkreismittelpunkt->CopyVector(Center); … … 1503 1582 */ 1504 1583 1505 void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,1584 void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent, 1506 1585 int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, 1507 1586 atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol) 1508 1587 { 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"; 1685 1741 } 1686 1742 ; … … 1709 1765 * @param mol molecule structure with atoms and bonds 1710 1766 */ 1711 1712 1767 void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, atom* Parent, 1713 1768 int RecursionLevel, Vector *Chord, Vector *d1, Vector *OldNormal, 1714 1769 atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol) 1715 1770 { 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 /* 1874 1910 * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle. 1875 1911 * … … 1913 1949 } 1914 1950 */ 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 }; 1953 1973 1954 1974 /** This function finds a triangle to a line, adjacent to an existing one. … … 1960 1980 * @param RADIUS radius of the rolling ball 1961 1981 * @param N number of found triangles 1982 * @param *filename filename base for intermediate envelopes 1962 1983 */ 1963 voidTesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,1984 bool Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot, 1964 1985 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 */ 2162 bool 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 2134 2197 2135 2198 void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent, … … 2137 2200 molecule* mol, double RADIUS) 2138 2201 { 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 }; 2197 2243 2198 2244 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS) 2199 2245 { 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; 2241 2282 //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 2346 void 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 -
Property mode
changed from
-
src/boundary.hpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 86 86 void AddTriangleToLines(); 87 87 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); 89 91 90 92 PointMap PointsOnBoundary; … … 110 112 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem); 111 113 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity); 114 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS); 112 115 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule *mol, bool problem); 113 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol);114 116 115 117 -
Property mode
changed from
-
src/builder.cpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 259 259 static void CenterAtoms(molecule *mol) 260 260 { 261 Vector x, y ;261 Vector x, y, helper; 262 262 char choice; // menu choice char 263 263 … … 292 292 mol->CenterEdge((ofstream *)&cout, &x); // make every coordinate positive 293 293 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 295 298 break; 296 299 case 'd': … … 1004 1007 } 1005 1008 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; 1035 1038 case 'T': 1036 1039 ExitFlag = 1; -
Property mode
changed from
-
src/config.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/datacreator.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/datacreator.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/defs.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/element.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/elements.db
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/graph.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/helpers.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/helpers.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/joiner.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/moleculelist.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/molecules.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/molecules.hpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 60 60 #define LineMap map < int, class BoundaryLineSet * > 61 61 #define LinePair pair < int, class BoundaryLineSet * > 62 #define LineTestPair pair < Line Pair::iterator, bool >62 #define LineTestPair pair < LineMap::iterator, bool > 63 63 64 64 #define TriangleMap map < int, class BoundaryTriangleSet * > -
Property mode
changed from
-
src/orbitals.db
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/parser.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/parser.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/periodentafel.cpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 1 1 /** \file periodentafel.cpp 2 * 2 * 3 3 * Function implementations for the class periodentafel. 4 * 4 * 5 5 */ 6 6 … … 14 14 * Initialises start and end of list and resets periodentafel::checkliste to false. 15 15 */ 16 periodentafel::periodentafel() 17 { 18 start = new element; 19 end = new element; 20 start->previous = NULL; 21 start->next = end; 22 end->previous = start; 16 periodentafel::periodentafel() 17 { 18 start = new element; 19 end = new element; 20 start->previous = NULL; 21 start->next = end; 22 end->previous = start; 23 23 end->next = NULL; 24 24 }; … … 27 27 * Removes every element and afterwards deletes start and end of list. 28 28 */ 29 periodentafel::~periodentafel() 30 { 31 CleanupPeriodtable(); 32 delete(end); 33 delete(start); 34 }; 29 periodentafel::~periodentafel() 30 { 31 CleanupPeriodtable(); 32 delete(end); 33 delete(start); 34 }; 35 35 36 36 /** Adds element to period table list … … 38 38 * \return true - succeeded, false - does not occur 39 39 */ 40 bool periodentafel::AddElement(element *pointer) 41 { 40 bool periodentafel::AddElement(element *pointer) 41 { 42 42 pointer->sort = &pointer->Z; 43 43 if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS) 44 44 cout << Verbose(0) << "Invalid Z number!\n"; 45 return add(pointer, end); 45 return add(pointer, end); 46 46 }; 47 47 … … 50 50 * \return true - succeeded, false - element not found 51 51 */ 52 bool periodentafel::RemoveElement(element *pointer) 53 { 54 return remove(pointer, start, end); 52 bool periodentafel::RemoveElement(element *pointer) 53 { 54 return remove(pointer, start, end); 55 55 }; 56 56 … … 58 58 * \return true - succeeded, false - does not occur 59 59 */ 60 bool periodentafel::CleanupPeriodtable() 61 { 62 return cleanup(start,end); 60 bool periodentafel::CleanupPeriodtable() 61 { 62 return cleanup(start,end); 63 63 }; 64 64 … … 76 76 cout << Verbose(0) << "Mass: " << endl; 77 77 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; 80 80 cout << Verbose(0) << "Name [max 64 chars]: " << endl; 81 81 cin >> walker->name; … … 105 105 /** Asks for element number and returns pointer to element 106 106 */ 107 element * periodentafel::AskElement() 107 element * periodentafel::AskElement() 108 108 { 109 109 element *walker = NULL; … … 117 117 }; 118 118 119 120 119 /** Prints period table to given stream. 121 120 * \param output stream 122 */ 121 */ 123 122 bool periodentafel::Output(ofstream *output) const 124 123 { … … 131 130 } 132 131 return result; 133 } else 132 } else 134 133 return false; 135 134 }; … … 138 137 * \param *output output stream 139 138 * \param *checkliste elements table for this molecule 140 */ 139 */ 141 140 bool periodentafel::Checkout(ofstream *output, const int *checkliste) const 142 141 { … … 152 151 if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) { 153 152 walker->No = No; 154 result = result && walker->Checkout(output, No++, checkliste[walker->Z]); 153 result = result && walker->Checkout(output, No++, checkliste[walker->Z]); 155 154 } 156 155 } 157 156 return result; 158 } else 157 } else 159 158 return false; 160 159 }; 161 162 160 163 161 /** Loads element list from file. … … 171 169 bool status = true; 172 170 bool otherstatus = true; 173 char *filename = new char[MAXSTRINGSIZE];174 171 char filename[255]; 172 175 173 // fill elements DB 176 174 strncpy(filename, path, MAXSTRINGSIZE); … … 225 223 if (infile != NULL) { 226 224 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; 232 230 } 233 231 infile.close(); … … 253 251 } else 254 252 otherstatus = false; 255 253 256 254 // fill H-BondDistance DB per element 257 255 strncpy(filename, path, MAXSTRINGSIZE); … … 261 259 if (infile != NULL) { 262 260 while (!infile.eof()) { 263 infile >> tmp;261 infile >> tmp; 264 262 ptr = FindElement((int)tmp); 265 infile >> ws;263 infile >> ws; 266 264 infile >> ptr->HBondDistance[0]; 267 265 infile >> ptr->HBondDistance[1]; 268 266 infile >> ptr->HBondDistance[2]; 269 infile >> ws;267 infile >> ws; 270 268 //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl; 271 269 } … … 274 272 } else 275 273 otherstatus = false; 276 274 277 275 // fill H-BondAngle DB per element 278 276 strncpy(filename, path, MAXSTRINGSIZE); … … 294 292 } else 295 293 otherstatus = false; 296 294 297 295 if (!otherstatus) 298 296 cerr << "WARNING: Something went wrong while parsing the other databases!" << endl; 299 297 300 298 return status; 301 299 }; … … 308 306 ofstream f; 309 307 char filename[MAXSTRINGSIZE]; 310 308 311 309 strncpy(filename, path, MAXSTRINGSIZE); 312 310 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename)); -
Property mode
changed from
-
src/periodentafel.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/stackclass.hpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/valence.db
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/vector.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
-
src/vector.hpp
-
Property mode
changed from
100644to100755
r02bfde rcc2ee5 56 56 57 57 ostream & 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); 62 62 63 63 #endif /*VECTOR_HPP_*/ -
Property mode
changed from
-
src/verbose.cpp
-
Property mode
changed from
100644to100755
-
Property mode
changed from
Note:
See TracChangeset
for help on using the changeset viewer.
