Changeset ce5ac3
- Timestamp:
- Jul 23, 2009, 12:32:48 PM (16 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:
- d067d45
- Parents:
- 986c80
- Location:
- src
- Files:
-
- 11 edited
-
atom.cpp (modified) (2 diffs)
-
bond.cpp (modified) (2 diffs)
-
boundary.cpp (modified) (10 diffs)
-
builder.cpp (modified) (3 diffs)
-
config.cpp (modified) (1 diff)
-
datacreator.cpp (modified) (1 diff)
-
helpers.cpp (modified) (1 diff)
-
molecules.cpp (modified) (32 diffs)
-
parser.cpp (modified) (2 diffs)
-
vector.cpp (modified) (6 diffs)
-
verbose.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/atom.cpp
r986c80 rce5ac3 13 13 atom::atom() 14 14 { 15 Name = NULL;15 Name = NULL; 16 16 previous = NULL; 17 17 next = NULL; … … 35 35 atom::~atom() 36 36 { 37 Free((void **)&Name, "atom::~atom: *Name");37 Free((void **)&Name, "atom::~atom: *Name"); 38 38 Free((void **)&ComponentNr, "atom::~atom: *ComponentNr"); 39 39 }; -
src/bond.cpp
r986c80 rce5ac3 14 14 bond::bond() 15 15 { 16 leftatom = NULL;17 rightatom = NULL;16 leftatom = NULL; 17 rightatom = NULL; 18 18 previous = NULL; 19 19 next = NULL; 20 nr = -1;21 HydrogenBond = 0;22 BondDegree = 0;20 nr = -1; 21 HydrogenBond = 0; 22 BondDegree = 0; 23 23 Used = white; 24 24 Cyclic = false; … … 34 34 bond::bond(atom *left, atom *right, int degree=1, int number=0) 35 35 { 36 leftatom = left;37 rightatom = right;36 leftatom = left; 37 rightatom = right; 38 38 previous = NULL; 39 39 next = NULL; 40 HydrogenBond = 0;40 HydrogenBond = 0; 41 41 if ((left != NULL) && (right != NULL)) { 42 if ((left->type != NULL) && (left->type->Z == 1))43 HydrogenBond++;44 if ((right->type != NULL) && (right->type->Z == 1))45 HydrogenBond++;42 if ((left->type != NULL) && (left->type->Z == 1)) 43 HydrogenBond++; 44 if ((right->type != NULL) && (right->type->Z == 1)) 45 HydrogenBond++; 46 46 } 47 47 BondDegree = degree; -
src/boundary.cpp
r986c80 rce5ac3 86 86 BoundaryLineSet::~BoundaryLineSet() 87 87 { 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 } else99 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;100 } else101 cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;102 }88 for (int i = 0; i < 2; i++) { 89 cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 90 endpoints[i]->lines.erase(Nr); 91 LineMap::iterator tester = endpoints[i]->lines.begin(); 92 tester++; 93 if (tester == endpoints[i]->lines.end()) { 94 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 95 if (endpoints[i] != NULL) { 96 delete(endpoints[i]); 97 endpoints[i] = NULL; 98 } else 99 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl; 100 } else 101 cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl; 102 } 103 103 } 104 104 ; … … 181 181 BoundaryTriangleSet::~BoundaryTriangleSet() 182 182 { 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 } else192 cerr << "ERROR: This line " << i << " has already been free'd." << endl;193 } else194 cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;195 }183 for (int i = 0; i < 3; i++) { 184 cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl; 185 lines[i]->triangles.erase(Nr); 186 if (lines[i]->triangles.empty()) { 187 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 188 if (lines[i] != NULL) { 189 delete (lines[i]); 190 lines[i] = NULL; 191 } else 192 cerr << "ERROR: This line " << i << " has already been free'd." << endl; 193 } else 194 cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl; 195 } 196 196 } 197 197 ; … … 573 573 void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol) 574 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 type587 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 colour590 }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 type596 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 colour602 }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 type607 for (i=0;i<3;i++) {// print each node608 for (int j=0;j<NDIM;j++)// and for each node all NDIM coordinates609 *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";610 *rasterfile << "\t";611 }612 *rasterfile << "1. 0. 0." << endl;// red as colour613 *rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl;// 18 is transparency type for previous object614 }615 } else {616 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;617 }618 delete(center);575 atom *Walker = mol->start; 576 bond *Binder = mol->first; 577 int i; 578 Vector *center = mol->DetermineCenterOfAll(out); 579 if (rasterfile != NULL) { 580 //cout << Verbose(1) << "Writing Raster3D file ... "; 581 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl; 582 *rasterfile << "@header.r3d" << endl; 583 *rasterfile << "# All atoms as spheres" << endl; 584 while (Walker->next != mol->end) { 585 Walker = Walker->next; 586 *rasterfile << "2" << endl << " "; // 2 is sphere type 587 for (i=0;i<NDIM;i++) 588 *rasterfile << Walker->x.x[i]+center->x[i] << " "; 589 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 590 } 591 592 *rasterfile << "# All bonds as vertices" << endl; 593 while (Binder->next != mol->last) { 594 Binder = Binder->next; 595 *rasterfile << "3" << endl << " "; // 2 is round-ended cylinder type 596 for (i=0;i<NDIM;i++) 597 *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " "; 598 *rasterfile << "\t0.03\t"; 599 for (i=0;i<NDIM;i++) 600 *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " "; 601 *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour 602 } 603 604 *rasterfile << "# All tesselation triangles" << endl; 605 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 606 *rasterfile << "1" << endl << " "; // 1 is triangle type 607 for (i=0;i<3;i++) { // print each node 608 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 609 *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " "; 610 *rasterfile << "\t"; 611 } 612 *rasterfile << "1. 0. 0." << endl; // red as colour 613 *rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 614 } 615 } else { 616 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl; 617 } 618 delete(center); 619 619 }; 620 620 … … 946 946 Tesselation::~Tesselation() 947 947 { 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 } else954 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 } else961 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 } else968 cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl;969 }948 cout << Verbose(1) << "Free'ing TesselStruct ... " << endl; 949 for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { 950 if (runner->second != NULL) { 951 delete (runner->second); 952 runner->second = NULL; 953 } else 954 cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl; 955 } 956 for (LineMap::iterator runner = LinesOnBoundary.begin(); runner != LinesOnBoundary.end(); runner++) { 957 if (runner->second != NULL) { 958 delete (runner->second); 959 runner->second = NULL; 960 } else 961 cerr << "ERROR: The line " << runner->first << " has already been free'd." << endl; 962 } 963 for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) { 964 if (runner->second != NULL) { 965 delete (runner->second); 966 runner->second = NULL; 967 } else 968 cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl; 969 } 970 970 } 971 971 ; … … 1585 1585 atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol) 1586 1586 { 1587 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1588 cout << Verbose(3) << "Candidate is "<< *Candidate << endl;1589 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;1590 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;1591 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;1592 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;1593 /* OldNormal is normal vector on the old triangle1594 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.1595 * Chord points from b to a!!!1596 */1597 Vector dif_a; //Vector from a to candidate1598 Vector dif_b; //Vector from b to candidate1599 Vector AngleCheck;1600 Vector TempNormal, Umkreismittelpunkt;1601 Vector Mittelpunkt;1602 1603 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius;1604 double BallAngle, AlternativeSign;1605 atom *Walker; // variable atom point1606 1607 Vector NewUmkreismittelpunkt;1608 1609 if (a != Candidate and b != Candidate and c != Candidate) {1610 cout << Verbose(3) << "We have a unique candidate!" << endl;1611 dif_a.CopyVector(&(a->x));1612 dif_a.SubtractVector(&(Candidate->x));1613 dif_b.CopyVector(&(b->x));1614 dif_b.SubtractVector(&(Candidate->x));1615 AngleCheck.CopyVector(&(Candidate->x));1616 AngleCheck.SubtractVector(&(a->x));1617 AngleCheck.ProjectOntoPlane(Chord);1618 1619 SideA = dif_b.Norm();1620 SideB = dif_a.Norm();1621 SideC = Chord->Norm();1622 //Chord->Scale(-1);1623 1624 alpha = Chord->Angle(&dif_a);1625 beta = M_PI - Chord->Angle(&dif_b);1626 gamma = dif_a.Angle(&dif_b);1627 1628 cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;1629 1630 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {1631 cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";1632 cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;1633 }1634 1635 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {1636 Umkreisradius = SideA / 2.0 / sin(alpha);1637 //cout << Umkreisradius << endl;1638 //cout << SideB / 2.0 / sin(beta) << endl;1639 //cout << SideC / 2.0 / sin(gamma) << endl;1640 1641 if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.1642 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;1643 cout << Verbose(2) << "Candidate is "<< *Candidate << endl;1644 sign = AngleCheck.ScalarProduct(direction1);1645 if (fabs(sign)<MYEPSILON) {1646 if (AngleCheck.ScalarProduct(OldNormal)<0) {1647 sign =0;1648 AlternativeSign=1;1649 } else {1650 sign =0;1651 AlternativeSign=-1;1652 }1653 } else {1654 sign /= fabs(sign);1655 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;1656 }1657 1658 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);1659 1660 AngleCheck.CopyVector(&ReferencePoint);1661 AngleCheck.Scale(-1);1662 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1663 AngleCheck.AddVector(&Mittelpunkt);1664 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1665 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;1666 1667 BallAngle = AngleCheck.Angle(OldNormal);1668 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;1669 1670 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;1671 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1672 1673 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;1674 1675 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);1676 1677 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {1678 if (Storage[0]< -1.5) { // first Candidate at all1679 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1680 cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";1681 Opt_Candidate = Candidate;1682 Storage[0] = sign;1683 Storage[1] = AlternativeSign;1684 Storage[2] = BallAngle;1685 cout << " angle " << Storage[2] << " and Up/Down "1686 << Storage[0] << endl;1687 } else1688 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1689 } else {1690 if ( Storage[2] > BallAngle) {1691 if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1692 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";1693 Opt_Candidate = Candidate;1694 Storage[0] = sign;1695 Storage[1] = AlternativeSign;1696 Storage[2] = BallAngle;1697 cout << " angle " << Storage[2] << " and Up/Down "1698 << Storage[0] << endl;1699 } else1700 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1701 } else {1702 if (DEBUG) {1703 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;1704 }1705 }1706 }1707 } else {1708 if (DEBUG) {1709 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;1710 }1711 }1712 } else {1713 if (DEBUG) {1714 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;1715 }1716 }1717 } else {1718 if (DEBUG) {1719 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;1720 }1721 }1722 } else {1723 if (DEBUG) {1724 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;1725 }1726 }1727 1728 if (RecursionLevel < 5) { // Seven is the recursion level threshold.1729 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond1730 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);1731 if (Walker == Parent) { // don't go back the same bond1732 continue;1733 } else {1734 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again1735 }1736 }1737 }1738 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1587 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1588 cout << Verbose(3) << "Candidate is "<< *Candidate << endl; 1589 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl; 1590 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl; 1591 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl; 1592 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl; 1593 /* OldNormal is normal vector on the old triangle 1594 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal. 1595 * Chord points from b to a!!! 1596 */ 1597 Vector dif_a; //Vector from a to candidate 1598 Vector dif_b; //Vector from b to candidate 1599 Vector AngleCheck; 1600 Vector TempNormal, Umkreismittelpunkt; 1601 Vector Mittelpunkt; 1602 1603 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius; 1604 double BallAngle, AlternativeSign; 1605 atom *Walker; // variable atom point 1606 1607 Vector NewUmkreismittelpunkt; 1608 1609 if (a != Candidate and b != Candidate and c != Candidate) { 1610 cout << Verbose(3) << "We have a unique candidate!" << endl; 1611 dif_a.CopyVector(&(a->x)); 1612 dif_a.SubtractVector(&(Candidate->x)); 1613 dif_b.CopyVector(&(b->x)); 1614 dif_b.SubtractVector(&(Candidate->x)); 1615 AngleCheck.CopyVector(&(Candidate->x)); 1616 AngleCheck.SubtractVector(&(a->x)); 1617 AngleCheck.ProjectOntoPlane(Chord); 1618 1619 SideA = dif_b.Norm(); 1620 SideB = dif_a.Norm(); 1621 SideC = Chord->Norm(); 1622 //Chord->Scale(-1); 1623 1624 alpha = Chord->Angle(&dif_a); 1625 beta = M_PI - Chord->Angle(&dif_b); 1626 gamma = dif_a.Angle(&dif_b); 1627 1628 cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 1629 1630 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) { 1631 cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 1632 cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 1633 } 1634 1635 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) { 1636 Umkreisradius = SideA / 2.0 / sin(alpha); 1637 //cout << Umkreisradius << endl; 1638 //cout << SideB / 2.0 / sin(beta) << endl; 1639 //cout << SideC / 2.0 / sin(gamma) << endl; 1640 1641 if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points. 1642 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl; 1643 cout << Verbose(2) << "Candidate is "<< *Candidate << endl; 1644 sign = AngleCheck.ScalarProduct(direction1); 1645 if (fabs(sign)<MYEPSILON) { 1646 if (AngleCheck.ScalarProduct(OldNormal)<0) { 1647 sign =0; 1648 AlternativeSign=1; 1649 } else { 1650 sign =0; 1651 AlternativeSign=-1; 1652 } 1653 } else { 1654 sign /= fabs(sign); 1655 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl; 1656 } 1657 1658 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius); 1659 1660 AngleCheck.CopyVector(&ReferencePoint); 1661 AngleCheck.Scale(-1); 1662 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1663 AngleCheck.AddVector(&Mittelpunkt); 1664 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1665 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl; 1666 1667 BallAngle = AngleCheck.Angle(OldNormal); 1668 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl; 1669 1670 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl; 1671 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1672 1673 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl; 1674 1675 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint); 1676 1677 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) { 1678 if (Storage[0]< -1.5) { // first Candidate at all 1679 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) { 1680 cout << Verbose(2) << "First good candidate is " << *Candidate << " with "; 1681 Opt_Candidate = Candidate; 1682 Storage[0] = sign; 1683 Storage[1] = AlternativeSign; 1684 Storage[2] = BallAngle; 1685 cout << " angle " << Storage[2] << " and Up/Down " 1686 << Storage[0] << endl; 1687 } else 1688 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl; 1689 } else { 1690 if ( Storage[2] > BallAngle) { 1691 if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) { 1692 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with "; 1693 Opt_Candidate = Candidate; 1694 Storage[0] = sign; 1695 Storage[1] = AlternativeSign; 1696 Storage[2] = BallAngle; 1697 cout << " angle " << Storage[2] << " and Up/Down " 1698 << Storage[0] << endl; 1699 } else 1700 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl; 1701 } else { 1702 if (DEBUG) { 1703 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl; 1704 } 1705 } 1706 } 1707 } else { 1708 if (DEBUG) { 1709 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl; 1710 } 1711 } 1712 } else { 1713 if (DEBUG) { 1714 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl; 1715 } 1716 } 1717 } else { 1718 if (DEBUG) { 1719 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl; 1720 } 1721 } 1722 } else { 1723 if (DEBUG) { 1724 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl; 1725 } 1726 } 1727 1728 if (RecursionLevel < 5) { // Seven is the recursion level threshold. 1729 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond 1730 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 1731 if (Walker == Parent) { // don't go back the same bond 1732 continue; 1733 } else { 1734 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again 1735 } 1736 } 1737 } 1738 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1739 1739 } 1740 1740 ; … … 1767 1767 atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol) 1768 1768 { 1769 /* OldNormal is normal vector on the old triangle1770 * d1 is normal on the triangle line, from which we come, as well as on OldNormal.1771 * Chord points from b to a!!!1772 */1773 Vector dif_a; //Vector from a to candidate1774 Vector dif_b; //Vector from b to candidate1775 Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;1776 Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;1777 1778 double CurrentEpsilon = 0.1;1779 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;1780 double BallAngle;1781 atom *Walker; // variable atom point1782 1783 1784 dif_a.CopyVector(&(a->x));1785 dif_a.SubtractVector(&(Candidate->x));1786 dif_b.CopyVector(&(b->x));1787 dif_b.SubtractVector(&(Candidate->x));1788 DirectionCheckPoint.CopyVector(&dif_a);1789 DirectionCheckPoint.Scale(-1);1790 DirectionCheckPoint.ProjectOntoPlane(Chord);1791 1792 SideA = dif_b.Norm();1793 SideB = dif_a.Norm();1794 SideC = Chord->Norm();1795 //Chord->Scale(-1);1796 1797 alpha = Chord->Angle(&dif_a);1798 beta = M_PI - Chord->Angle(&dif_b);1799 gamma = dif_a.Angle(&dif_b);1800 1801 1802 if (DEBUG) {1803 cout << "Atom number" << Candidate->nr << endl;1804 Candidate->x.Output((ofstream *) &cout);1805 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;1806 }1807 1808 if (a != Candidate and b != Candidate) {1809 // alpha = dif_a.Angle(&dif_b) / 2.;1810 // SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);1811 // SideB = dif_a.Norm();1812 // centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(1813 // alpha); // note this is squared of center line length1814 // centerline = (Chord->Norm()/2.) / sin(0.5*alpha);1815 // Those are remains from Freddie. Needed?1816 1817 Umkreisradius = SideA / 2.0 / sin(alpha);1818 //cout << Umkreisradius << endl;1819 //cout << SideB / 2.0 / sin(beta) << endl;1820 //cout << SideC / 2.0 / sin(gamma) << endl;1821 1822 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.1823 // intermediate calculations to aquire centre of sphere, called Mittelpunkt:1824 Umkreismittelpunkt.Zero();1825 helper.CopyVector(&a->x);1826 helper.Scale(sin(2.*alpha));1827 Umkreismittelpunkt.AddVector(&helper);1828 helper.CopyVector(&b->x);1829 helper.Scale(sin(2.*beta));1830 Umkreismittelpunkt.AddVector(&helper);1831 helper.CopyVector(&Candidate->x);1832 helper.Scale(sin(2.*gamma));1833 Umkreismittelpunkt.AddVector(&helper);1834 //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;1835 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));1836 1837 TempNormal.CopyVector(&dif_a);1838 TempNormal.VectorProduct(&dif_b);1839 if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {1840 TempNormal.Scale(-1);1841 }1842 TempNormal.Normalize();1843 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);1844 TempNormal.Scale(Restradius);1845 1846 Mittelpunkt.CopyVector(&Umkreismittelpunkt);1847 Mittelpunkt.AddVector(&TempNormal); //this is center of sphere supported by a, b and Candidate1848 1849 AngleCheck.CopyVector(Chord);1850 AngleCheck.Scale(-0.5);1851 AngleCheck.SubtractVector(&(b->x));1852 AngleCheckReference.CopyVector(&AngleCheck);1853 AngleCheckReference.AddVector(Opt_Mittelpunkt);1854 AngleCheck.AddVector(&Mittelpunkt);1855 1856 BallAngle = AngleCheck.Angle(&AngleCheckReference);1857 1858 d1->ProjectOntoPlane(&AngleCheckReference);1859 sign = AngleCheck.ScalarProduct(d1);1860 if (fabs(sign) < MYEPSILON)1861 sign = 0;1862 else1863 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...1864 1865 1866 if (Storage[0]< -1.5) { // first Candidate at all1867 cout << "Next better candidate is " << *Candidate << " with ";1868 Opt_Candidate = Candidate;1869 Storage[0] = sign;1870 Storage[1] = BallAngle;1871 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1872 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1873 } else {1874 /*1875 * removed due to change in criterium, now checking angle of ball to old normal.1876 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate1877 //within the ball.1878 1879 Distance = Opt_Candidate->x.Distance(&Mittelpunkt);1880 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;1881 1882 1883 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.1884 */1885 //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;1886 1887 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants1888 //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS)) //and those where Candidate would be within old Sphere.1889 cout << "Next better candidate is " << *Candidate << " with ";1890 Opt_Candidate = Candidate;1891 Storage[0] = sign;1892 Storage[1] = BallAngle;1893 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1894 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1895 } else {1896 if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {1897 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.1898 cout << "Next better candidate is " << *Candidate << " with ";1899 Opt_Candidate = Candidate;1900 Storage[0] = sign;1901 Storage[1] = BallAngle;1902 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1903 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1904 }1905 }1906 }1769 /* OldNormal is normal vector on the old triangle 1770 * d1 is normal on the triangle line, from which we come, as well as on OldNormal. 1771 * Chord points from b to a!!! 1772 */ 1773 Vector dif_a; //Vector from a to candidate 1774 Vector dif_b; //Vector from b to candidate 1775 Vector AngleCheck, AngleCheckReference, DirectionCheckPoint; 1776 Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper; 1777 1778 double CurrentEpsilon = 0.1; 1779 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius; 1780 double BallAngle; 1781 atom *Walker; // variable atom point 1782 1783 1784 dif_a.CopyVector(&(a->x)); 1785 dif_a.SubtractVector(&(Candidate->x)); 1786 dif_b.CopyVector(&(b->x)); 1787 dif_b.SubtractVector(&(Candidate->x)); 1788 DirectionCheckPoint.CopyVector(&dif_a); 1789 DirectionCheckPoint.Scale(-1); 1790 DirectionCheckPoint.ProjectOntoPlane(Chord); 1791 1792 SideA = dif_b.Norm(); 1793 SideB = dif_a.Norm(); 1794 SideC = Chord->Norm(); 1795 //Chord->Scale(-1); 1796 1797 alpha = Chord->Angle(&dif_a); 1798 beta = M_PI - Chord->Angle(&dif_b); 1799 gamma = dif_a.Angle(&dif_b); 1800 1801 1802 if (DEBUG) { 1803 cout << "Atom number" << Candidate->nr << endl; 1804 Candidate->x.Output((ofstream *) &cout); 1805 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl; 1806 } 1807 1808 if (a != Candidate and b != Candidate) { 1809 // alpha = dif_a.Angle(&dif_b) / 2.; 1810 // SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha); 1811 // SideB = dif_a.Norm(); 1812 // centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos( 1813 // alpha); // note this is squared of center line length 1814 // centerline = (Chord->Norm()/2.) / sin(0.5*alpha); 1815 // Those are remains from Freddie. Needed? 1816 1817 Umkreisradius = SideA / 2.0 / sin(alpha); 1818 //cout << Umkreisradius << endl; 1819 //cout << SideB / 2.0 / sin(beta) << endl; 1820 //cout << SideC / 2.0 / sin(gamma) << endl; 1821 1822 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points. 1823 // intermediate calculations to aquire centre of sphere, called Mittelpunkt: 1824 Umkreismittelpunkt.Zero(); 1825 helper.CopyVector(&a->x); 1826 helper.Scale(sin(2.*alpha)); 1827 Umkreismittelpunkt.AddVector(&helper); 1828 helper.CopyVector(&b->x); 1829 helper.Scale(sin(2.*beta)); 1830 Umkreismittelpunkt.AddVector(&helper); 1831 helper.CopyVector(&Candidate->x); 1832 helper.Scale(sin(2.*gamma)); 1833 Umkreismittelpunkt.AddVector(&helper); 1834 //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ; 1835 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 1836 1837 TempNormal.CopyVector(&dif_a); 1838 TempNormal.VectorProduct(&dif_b); 1839 if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) { 1840 TempNormal.Scale(-1); 1841 } 1842 TempNormal.Normalize(); 1843 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius); 1844 TempNormal.Scale(Restradius); 1845 1846 Mittelpunkt.CopyVector(&Umkreismittelpunkt); 1847 Mittelpunkt.AddVector(&TempNormal); //this is center of sphere supported by a, b and Candidate 1848 1849 AngleCheck.CopyVector(Chord); 1850 AngleCheck.Scale(-0.5); 1851 AngleCheck.SubtractVector(&(b->x)); 1852 AngleCheckReference.CopyVector(&AngleCheck); 1853 AngleCheckReference.AddVector(Opt_Mittelpunkt); 1854 AngleCheck.AddVector(&Mittelpunkt); 1855 1856 BallAngle = AngleCheck.Angle(&AngleCheckReference); 1857 1858 d1->ProjectOntoPlane(&AngleCheckReference); 1859 sign = AngleCheck.ScalarProduct(d1); 1860 if (fabs(sign) < MYEPSILON) 1861 sign = 0; 1862 else 1863 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction... 1864 1865 1866 if (Storage[0]< -1.5) { // first Candidate at all 1867 cout << "Next better candidate is " << *Candidate << " with "; 1868 Opt_Candidate = Candidate; 1869 Storage[0] = sign; 1870 Storage[1] = BallAngle; 1871 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1872 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1873 } else { 1874 /* 1875 * removed due to change in criterium, now checking angle of ball to old normal. 1876 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate 1877 //within the ball. 1878 1879 Distance = Opt_Candidate->x.Distance(&Mittelpunkt); 1880 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl; 1881 1882 1883 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better. 1884 */ 1885 //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl; 1886 1887 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants 1888 //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS)) //and those where Candidate would be within old Sphere. 1889 cout << "Next better candidate is " << *Candidate << " with "; 1890 Opt_Candidate = Candidate; 1891 Storage[0] = sign; 1892 Storage[1] = BallAngle; 1893 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1894 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1895 } else { 1896 if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) { 1897 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first. 1898 cout << "Next better candidate is " << *Candidate << " with "; 1899 Opt_Candidate = Candidate; 1900 Storage[0] = sign; 1901 Storage[1] = BallAngle; 1902 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1903 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1904 } 1905 } 1906 } 1907 1907 /* 1908 1908 * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle. … … 1947 1947 } 1948 1948 */ 1949 } else {1950 if (DEBUG) {1951 cout << "Doesn't satisfy requirements for circumscribing circle" << endl;1952 }1953 }1954 } else {1955 if (DEBUG) {1956 cout << "identisch mit Ursprungslinie" << endl;1957 }1958 }1959 1960 if (RecursionLevel < 9) { // Five is the recursion level threshold.1961 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond1962 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);1963 if (Walker == Parent) { // don't go back the same bond1964 continue;1965 } else {1966 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again1967 }1968 }1969 }1949 } else { 1950 if (DEBUG) { 1951 cout << "Doesn't satisfy requirements for circumscribing circle" << endl; 1952 } 1953 } 1954 } else { 1955 if (DEBUG) { 1956 cout << "identisch mit Ursprungslinie" << endl; 1957 } 1958 } 1959 1960 if (RecursionLevel < 9) { // Five is the recursion level threshold. 1961 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond 1962 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 1963 if (Walker == Parent) { // don't go back the same bond 1964 continue; 1965 } else { 1966 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again 1967 } 1968 } 1969 } 1970 1970 }; 1971 1971 … … 1984 1984 const double& RADIUS, int N, const char *tempbasename) 1985 1985 { 1986 cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";1987 Vector direction1;1988 Vector helper;1989 Vector Chord;1990 ofstream *tempstream = NULL;1991 char NumberName[255];1992 double tmp;1993 //atom* Walker;1994 atom* OldThirdPoint;1995 1996 double Storage[3];1997 Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values1998 Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive1999 Storage[2] = 9999999.;2000 atom* Opt_Candidate = NULL;2001 Vector Opt_Mittelpunkt;2002 2003 cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;2004 2005 helper.CopyVector(&(Line.endpoints[0]->node->x));2006 for (int i = 0; i < 3; i++) {2007 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {2008 OldThirdPoint = T.endpoints[i]->node;2009 helper.SubtractVector(&T.endpoints[i]->node->x);2010 break;2011 }2012 }2013 2014 direction1.CopyVector(&Line.endpoints[0]->node->x);2015 direction1.SubtractVector(&Line.endpoints[1]->node->x);2016 direction1.VectorProduct(&(T.NormalVector));2017 2018 if (direction1.ScalarProduct(&helper) < 0) {2019 direction1.Scale(-1);2020 }2021 cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";2022 2023 Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function2024 Chord.SubtractVector(&(Line.endpoints[1]->node->x));2025 cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";2026 2027 2028 Vector Umkreismittelpunkt, a, b, c;2029 double alpha, beta, gamma;2030 a.CopyVector(&(T.endpoints[0]->node->x));2031 b.CopyVector(&(T.endpoints[1]->node->x));2032 c.CopyVector(&(T.endpoints[2]->node->x));2033 a.SubtractVector(&(T.endpoints[1]->node->x));2034 b.SubtractVector(&(T.endpoints[2]->node->x));2035 c.SubtractVector(&(T.endpoints[0]->node->x));2036 2037 alpha = M_PI - a.Angle(&c);2038 beta = M_PI - b.Angle(&a);2039 gamma = M_PI - c.Angle(&b);2040 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)2041 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";2042 2043 Umkreismittelpunkt.Zero();2044 helper.CopyVector(&T.endpoints[0]->node->x);2045 helper.Scale(sin(2.*alpha));2046 Umkreismittelpunkt.AddVector(&helper);2047 helper.CopyVector(&T.endpoints[1]->node->x);2048 helper.Scale(sin(2.*beta));2049 Umkreismittelpunkt.AddVector(&helper);2050 helper.CopyVector(&T.endpoints[2]->node->x);2051 helper.Scale(sin(2.*gamma));2052 Umkreismittelpunkt.AddVector(&helper);2053 //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;2054 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;2055 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));2056 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;2057 cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;2058 cout << " Old Normal is " << (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;2059 2060 cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;2061 cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;2062 if (DEBUG)2063 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;2064 tmp = 0;2065 for (int i=0;i<NDIM;i++) {2066 helper.CopyVector(&T.endpoints[i]->node->x);2067 helper.SubtractVector(&Umkreismittelpunkt);2068 if (DEBUG)2069 cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;2070 if (tmp == 0) // set on first time for comparison against next ones2071 tmp = helper.Norm();2072 if (fabs(helper.Norm() - tmp) > MYEPSILON)2073 cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;2074 }2075 2076 cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;2077 2078 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);2079 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);2080 if (Opt_Candidate == NULL) {2081 cerr << "WARNING: Could not find a suitable candidate." << endl;2082 return false;2083 }2084 cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;2085 2086 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)2087 bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);2088 2089 if (flag) { // if so, add2090 AddTrianglePoint(Opt_Candidate, 0);2091 AddTrianglePoint(Line.endpoints[0]->node, 1);2092 AddTrianglePoint(Line.endpoints[1]->node, 2);2093 2094 AddTriangleLine(TPS[0], TPS[1], 0);2095 AddTriangleLine(TPS[0], TPS[2], 1);2096 AddTriangleLine(TPS[1], TPS[2], 2);2097 2098 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);2099 AddTriangleToLines();2100 2101 BTS->GetNormalVector(BTS->NormalVector);2102 2103 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {2104 BTS->NormalVector.Scale(-1);2105 };2106 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;2107 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;2108 } else { // else, yell and do nothing2109 cout << Verbose(1) << "This triangle consisting of ";2110 cout << *Opt_Candidate << ", ";2111 cout << *Line.endpoints[0]->node << " and ";2112 cout << *Line.endpoints[1]->node << " ";2113 cout << "is invalid!" << endl;2114 return false;2115 }2116 2117 if ((TrianglesOnBoundaryCount % 10) == 0) {2118 sprintf(NumberName, "-%d", TriangleFilesWritten);2119 if (DoTecplotOutput) {2120 string NameofTempFile(tempbasename);2121 NameofTempFile.append(NumberName);2122 NameofTempFile.append(TecplotSuffix);2123 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";2124 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);2125 write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);2126 tempstream->close();2127 tempstream->flush();2128 delete(tempstream);2129 }2130 2131 if (DoRaster3DOutput) {2132 string NameofTempFile(tempbasename);2133 NameofTempFile.append(NumberName);2134 NameofTempFile.append(Raster3DSuffix);2135 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";2136 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);2137 write_raster3d_file(out, tempstream, this, mol);2138 tempstream->close();2139 tempstream->flush();2140 delete(tempstream);2141 }2142 if (DoTecplotOutput || DoRaster3DOutput)2143 TriangleFilesWritten++;2144 }2145 2146 cout << Verbose(1) << "End of Find_next_suitable_triangle\n";2147 return true;1986 cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n"; 1987 Vector direction1; 1988 Vector helper; 1989 Vector Chord; 1990 ofstream *tempstream = NULL; 1991 char NumberName[255]; 1992 double tmp; 1993 //atom* Walker; 1994 atom* OldThirdPoint; 1995 1996 double Storage[3]; 1997 Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values 1998 Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive 1999 Storage[2] = 9999999.; 2000 atom* Opt_Candidate = NULL; 2001 Vector Opt_Mittelpunkt; 2002 2003 cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl; 2004 2005 helper.CopyVector(&(Line.endpoints[0]->node->x)); 2006 for (int i = 0; i < 3; i++) { 2007 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) { 2008 OldThirdPoint = T.endpoints[i]->node; 2009 helper.SubtractVector(&T.endpoints[i]->node->x); 2010 break; 2011 } 2012 } 2013 2014 direction1.CopyVector(&Line.endpoints[0]->node->x); 2015 direction1.SubtractVector(&Line.endpoints[1]->node->x); 2016 direction1.VectorProduct(&(T.NormalVector)); 2017 2018 if (direction1.ScalarProduct(&helper) < 0) { 2019 direction1.Scale(-1); 2020 } 2021 cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n"; 2022 2023 Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function 2024 Chord.SubtractVector(&(Line.endpoints[1]->node->x)); 2025 cout << Verbose(2) << "Baseline vector is " << Chord << ".\n"; 2026 2027 2028 Vector Umkreismittelpunkt, a, b, c; 2029 double alpha, beta, gamma; 2030 a.CopyVector(&(T.endpoints[0]->node->x)); 2031 b.CopyVector(&(T.endpoints[1]->node->x)); 2032 c.CopyVector(&(T.endpoints[2]->node->x)); 2033 a.SubtractVector(&(T.endpoints[1]->node->x)); 2034 b.SubtractVector(&(T.endpoints[2]->node->x)); 2035 c.SubtractVector(&(T.endpoints[0]->node->x)); 2036 2037 alpha = M_PI - a.Angle(&c); 2038 beta = M_PI - b.Angle(&a); 2039 gamma = M_PI - c.Angle(&b); 2040 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) 2041 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 2042 2043 Umkreismittelpunkt.Zero(); 2044 helper.CopyVector(&T.endpoints[0]->node->x); 2045 helper.Scale(sin(2.*alpha)); 2046 Umkreismittelpunkt.AddVector(&helper); 2047 helper.CopyVector(&T.endpoints[1]->node->x); 2048 helper.Scale(sin(2.*beta)); 2049 Umkreismittelpunkt.AddVector(&helper); 2050 helper.CopyVector(&T.endpoints[2]->node->x); 2051 helper.Scale(sin(2.*gamma)); 2052 Umkreismittelpunkt.AddVector(&helper); 2053 //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ; 2054 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 2055 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 2056 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 2057 cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl; 2058 cout << " Old Normal is " << (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl; 2059 2060 cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 2061 cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl; 2062 if (DEBUG) 2063 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl; 2064 tmp = 0; 2065 for (int i=0;i<NDIM;i++) { 2066 helper.CopyVector(&T.endpoints[i]->node->x); 2067 helper.SubtractVector(&Umkreismittelpunkt); 2068 if (DEBUG) 2069 cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl; 2070 if (tmp == 0) // set on first time for comparison against next ones 2071 tmp = helper.Norm(); 2072 if (fabs(helper.Norm() - tmp) > MYEPSILON) 2073 cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl; 2074 } 2075 2076 cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl; 2077 2078 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2079 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2080 if (Opt_Candidate == NULL) { 2081 cerr << "WARNING: Could not find a suitable candidate." << endl; 2082 return false; 2083 } 2084 cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl; 2085 2086 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 2087 bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node); 2088 2089 if (flag) { // if so, add 2090 AddTrianglePoint(Opt_Candidate, 0); 2091 AddTrianglePoint(Line.endpoints[0]->node, 1); 2092 AddTrianglePoint(Line.endpoints[1]->node, 2); 2093 2094 AddTriangleLine(TPS[0], TPS[1], 0); 2095 AddTriangleLine(TPS[0], TPS[2], 1); 2096 AddTriangleLine(TPS[1], TPS[2], 2); 2097 2098 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2099 AddTriangleToLines(); 2100 2101 BTS->GetNormalVector(BTS->NormalVector); 2102 2103 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) { 2104 BTS->NormalVector.Scale(-1); 2105 }; 2106 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl; 2107 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl; 2108 } else { // else, yell and do nothing 2109 cout << Verbose(1) << "This triangle consisting of "; 2110 cout << *Opt_Candidate << ", "; 2111 cout << *Line.endpoints[0]->node << " and "; 2112 cout << *Line.endpoints[1]->node << " "; 2113 cout << "is invalid!" << endl; 2114 return false; 2115 } 2116 2117 if ((TrianglesOnBoundaryCount % 10) == 0) { 2118 sprintf(NumberName, "-%d", TriangleFilesWritten); 2119 if (DoTecplotOutput) { 2120 string NameofTempFile(tempbasename); 2121 NameofTempFile.append(NumberName); 2122 NameofTempFile.append(TecplotSuffix); 2123 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 2124 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 2125 write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten); 2126 tempstream->close(); 2127 tempstream->flush(); 2128 delete(tempstream); 2129 } 2130 2131 if (DoRaster3DOutput) { 2132 string NameofTempFile(tempbasename); 2133 NameofTempFile.append(NumberName); 2134 NameofTempFile.append(Raster3DSuffix); 2135 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 2136 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 2137 write_raster3d_file(out, tempstream, this, mol); 2138 tempstream->close(); 2139 tempstream->flush(); 2140 delete(tempstream); 2141 } 2142 if (DoTecplotOutput || DoRaster3DOutput) 2143 TriangleFilesWritten++; 2144 } 2145 2146 cout << Verbose(1) << "End of Find_next_suitable_triangle\n"; 2147 return true; 2148 2148 }; 2149 2149 … … 2159 2159 */ 2160 2160 bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) { 2161 LineMap::iterator TryAndError;2162 PointTestPair InsertPoint;2163 bool Present[3];2164 2165 *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;2166 TPS[0] = new class BoundaryPointSet(a);2167 TPS[1] = new class BoundaryPointSet(b);2168 TPS[2] = new class BoundaryPointSet(c);2169 for (int i=0;i<3;i++) { // check through all endpoints2170 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));2171 Present[i] = !InsertPoint.second;2172 if (Present[i]) { // if new point was not present before, increase counter2173 delete TPS[i];2174 *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;2175 TPS[i] = (InsertPoint.first)->second;2176 }2177 }2178 2179 // check lines2180 for (int i=0;i<3;i++)2181 if (Present[i])2182 for (int j=i;j<3;j++)2183 if (Present[j]) {2184 TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);2185 if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {2186 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;2187 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;2188 return false;2189 }2190 }2191 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;2192 return true;2161 LineMap::iterator TryAndError; 2162 PointTestPair InsertPoint; 2163 bool Present[3]; 2164 2165 *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl; 2166 TPS[0] = new class BoundaryPointSet(a); 2167 TPS[1] = new class BoundaryPointSet(b); 2168 TPS[2] = new class BoundaryPointSet(c); 2169 for (int i=0;i<3;i++) { // check through all endpoints 2170 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i])); 2171 Present[i] = !InsertPoint.second; 2172 if (Present[i]) { // if new point was not present before, increase counter 2173 delete TPS[i]; 2174 *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl; 2175 TPS[i] = (InsertPoint.first)->second; 2176 } 2177 } 2178 2179 // check lines 2180 for (int i=0;i<3;i++) 2181 if (Present[i]) 2182 for (int j=i;j<3;j++) 2183 if (Present[j]) { 2184 TryAndError = TPS[i]->lines.find(TPS[j]->node->nr); 2185 if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) { 2186 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl; 2187 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 2188 return false; 2189 } 2190 } 2191 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 2192 return true; 2193 2193 }; 2194 2194 … … 2198 2198 molecule* mol, double RADIUS) 2199 2199 { 2200 cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;2201 int i;2202 Vector AngleCheck;2203 atom* Walker;2204 double norm = -1., angle;2205 2206 // check if we only have one unique point yet ...2207 if (a != Candidate) {2208 cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";2209 AngleCheck.CopyVector(&(Candidate->x));2210 AngleCheck.SubtractVector(&(a->x));2211 norm = AngleCheck.Norm();2212 // second point shall have smallest angle with respect to Oben vector2213 if (norm < RADIUS) {2214 angle = AngleCheck.Angle(&Oben);2215 if (angle < Storage[0]) {2216 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);2217 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";2218 Opt_Candidate = Candidate;2219 Storage[0] = AngleCheck.Angle(&Oben);2220 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);2221 } else {2222 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;2223 }2224 } else {2225 cout << "Refused due to Radius " << norm << endl;2226 }2227 }2228 2229 // if not recursed to deeply, look at all its bonds2230 if (RecursionLevel < 7) {2231 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {2232 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);2233 if (Walker == Parent) // don't go back along the bond we came from2234 continue;2235 else2236 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);2237 }2238 }2239 cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;2200 cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl; 2201 int i; 2202 Vector AngleCheck; 2203 atom* Walker; 2204 double norm = -1., angle; 2205 2206 // check if we only have one unique point yet ... 2207 if (a != Candidate) { 2208 cout << Verbose(3) << "Current candidate is " << *Candidate << ": "; 2209 AngleCheck.CopyVector(&(Candidate->x)); 2210 AngleCheck.SubtractVector(&(a->x)); 2211 norm = AngleCheck.Norm(); 2212 // second point shall have smallest angle with respect to Oben vector 2213 if (norm < RADIUS) { 2214 angle = AngleCheck.Angle(&Oben); 2215 if (angle < Storage[0]) { 2216 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]); 2217 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n"; 2218 Opt_Candidate = Candidate; 2219 Storage[0] = AngleCheck.Angle(&Oben); 2220 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]); 2221 } else { 2222 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl; 2223 } 2224 } else { 2225 cout << "Refused due to Radius " << norm << endl; 2226 } 2227 } 2228 2229 // if not recursed to deeply, look at all its bonds 2230 if (RecursionLevel < 7) { 2231 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { 2232 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 2233 if (Walker == Parent) // don't go back along the bond we came from 2234 continue; 2235 else 2236 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS); 2237 } 2238 } 2239 cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl; 2240 2240 }; 2241 2241 2242 2242 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS) 2243 2243 { 2244 cout << Verbose(1) << "Begin of Find_starting_triangle\n";2245 int i = 0;2246 atom* Walker;2247 atom* FirstPoint;2248 atom* SecondPoint;2249 atom* max_index[NDIM];2250 double max_coordinate[NDIM];2251 Vector Oben;2252 Vector helper;2253 Vector Chord;2254 Vector CenterOfFirstLine;2255 2256 Oben.Zero();2257 2258 for (i = 0; i < 3; i++) {2259 max_index[i] = NULL;2260 max_coordinate[i] = -1;2261 }2262 cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";2263 2264 // 1. searching topmost atom with respect to each axis2265 Walker = mol->start;2266 while (Walker->next != mol->end) {2267 Walker = Walker->next;2268 for (i = 0; i < 3; i++) {2269 if (Walker->x.x[i] > max_coordinate[i]) {2270 max_coordinate[i] = Walker->x.x[i];2271 max_index[i] = Walker;2272 }2273 }2274 }2275 2276 cout << Verbose(2) << "Found maximum coordinates: ";2277 for (int i=0;i<NDIM;i++)2278 cout << i << ": " << *max_index[i] << "\t";2279 cout << endl;2244 cout << Verbose(1) << "Begin of Find_starting_triangle\n"; 2245 int i = 0; 2246 atom* Walker; 2247 atom* FirstPoint; 2248 atom* SecondPoint; 2249 atom* max_index[NDIM]; 2250 double max_coordinate[NDIM]; 2251 Vector Oben; 2252 Vector helper; 2253 Vector Chord; 2254 Vector CenterOfFirstLine; 2255 2256 Oben.Zero(); 2257 2258 for (i = 0; i < 3; i++) { 2259 max_index[i] = NULL; 2260 max_coordinate[i] = -1; 2261 } 2262 cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n"; 2263 2264 // 1. searching topmost atom with respect to each axis 2265 Walker = mol->start; 2266 while (Walker->next != mol->end) { 2267 Walker = Walker->next; 2268 for (i = 0; i < 3; i++) { 2269 if (Walker->x.x[i] > max_coordinate[i]) { 2270 max_coordinate[i] = Walker->x.x[i]; 2271 max_index[i] = Walker; 2272 } 2273 } 2274 } 2275 2276 cout << Verbose(2) << "Found maximum coordinates: "; 2277 for (int i=0;i<NDIM;i++) 2278 cout << i << ": " << *max_index[i] << "\t"; 2279 cout << endl; 2280 2280 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0 2281 const int k = 1;2282 Oben.x[k] = 1.;2283 FirstPoint = max_index[k];2284 2285 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;2286 double Storage[3];2287 atom* Opt_Candidate = NULL;2288 Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.2289 Storage[1] = 999999.; // This will be an angle looking for the third point.2290 Storage[2] = 999999.;2291 2292 Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...2293 SecondPoint = Opt_Candidate;2294 cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";2295 2296 helper.CopyVector(&(FirstPoint->x));2297 helper.SubtractVector(&(SecondPoint->x));2298 helper.Normalize();2299 Oben.ProjectOntoPlane(&helper);2300 Oben.Normalize();2301 helper.VectorProduct(&Oben);2302 Storage[0] = -2.; // This will indicate the quadrant.2303 Storage[1] = 9999999.; // This will be an angle looking for the third point.2304 Storage[2] = 9999999.;2305 2306 Chord.CopyVector(&(FirstPoint->x)); // bring into calling function2307 Chord.SubtractVector(&(SecondPoint->x));2308 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)2309 2310 cout << Verbose(2) << "Looking for third point candidates \n";2311 // look in one direction of baseline for initial candidate2312 Opt_Candidate = NULL;2313 CenterOfFirstLine.CopyVector(&Chord);2314 CenterOfFirstLine.Scale(0.5);2315 CenterOfFirstLine.AddVector(&(SecondPoint->x));2316 2317 cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";2318 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);2319 // look in other direction of baseline for possible better candidate2320 cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";2321 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);2322 cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;2323 2324 // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate2325 2326 // Finally, we only have to add the found points2327 AddTrianglePoint(FirstPoint, 0);2328 AddTrianglePoint(SecondPoint, 1);2329 AddTrianglePoint(Opt_Candidate, 2);2330 // ... and respective lines2331 AddTriangleLine(TPS[0], TPS[1], 0);2332 AddTriangleLine(TPS[1], TPS[2], 1);2333 AddTriangleLine(TPS[0], TPS[2], 2);2334 // ... and triangles to the Maps of the Tesselation class2335 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);2336 AddTriangleToLines();2337 // ... and calculate its normal vector (with correct orientation)2338 Oben.Scale(-1.);2339 BTS->GetNormalVector(Oben);2340 cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";2341 cout << Verbose(1) << "End of Find_starting_triangle\n";2281 const int k = 1; 2282 Oben.x[k] = 1.; 2283 FirstPoint = max_index[k]; 2284 2285 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl; 2286 double Storage[3]; 2287 atom* Opt_Candidate = NULL; 2288 Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant. 2289 Storage[1] = 999999.; // This will be an angle looking for the third point. 2290 Storage[2] = 999999.; 2291 2292 Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_... 2293 SecondPoint = Opt_Candidate; 2294 cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n"; 2295 2296 helper.CopyVector(&(FirstPoint->x)); 2297 helper.SubtractVector(&(SecondPoint->x)); 2298 helper.Normalize(); 2299 Oben.ProjectOntoPlane(&helper); 2300 Oben.Normalize(); 2301 helper.VectorProduct(&Oben); 2302 Storage[0] = -2.; // This will indicate the quadrant. 2303 Storage[1] = 9999999.; // This will be an angle looking for the third point. 2304 Storage[2] = 9999999.; 2305 2306 Chord.CopyVector(&(FirstPoint->x)); // bring into calling function 2307 Chord.SubtractVector(&(SecondPoint->x)); 2308 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized) 2309 2310 cout << Verbose(2) << "Looking for third point candidates \n"; 2311 // look in one direction of baseline for initial candidate 2312 Opt_Candidate = NULL; 2313 CenterOfFirstLine.CopyVector(&Chord); 2314 CenterOfFirstLine.Scale(0.5); 2315 CenterOfFirstLine.AddVector(&(SecondPoint->x)); 2316 2317 cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n"; 2318 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2319 // look in other direction of baseline for possible better candidate 2320 cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n"; 2321 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2322 cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl; 2323 2324 // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate 2325 2326 // Finally, we only have to add the found points 2327 AddTrianglePoint(FirstPoint, 0); 2328 AddTrianglePoint(SecondPoint, 1); 2329 AddTrianglePoint(Opt_Candidate, 2); 2330 // ... and respective lines 2331 AddTriangleLine(TPS[0], TPS[1], 0); 2332 AddTriangleLine(TPS[1], TPS[2], 1); 2333 AddTriangleLine(TPS[0], TPS[2], 2); 2334 // ... and triangles to the Maps of the Tesselation class 2335 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2336 AddTriangleToLines(); 2337 // ... and calculate its normal vector (with correct orientation) 2338 Oben.Scale(-1.); 2339 BTS->GetNormalVector(Oben); 2340 cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n"; 2341 cout << Verbose(1) << "End of Find_starting_triangle\n"; 2342 2342 }; 2343 2343 2344 2344 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS) 2345 2345 { 2346 int N = 0;2347 struct Tesselation *Tess = new Tesselation;2348 cout << Verbose(1) << "Entering search for non convex hull. " << endl;2349 cout << flush;2350 LineMap::iterator baseline;2351 cout << Verbose(0) << "Begin of Find_non_convex_border\n";2352 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles2353 bool failflag = false;2354 if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))2355 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);2356 2357 Tess->Find_starting_triangle(mol, RADIUS);2358 2359 baseline = Tess->LinesOnBoundary.begin();2360 while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {2361 if (baseline->second->TrianglesCount == 1) {2362 failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.2363 flag = flag || failflag;2364 if (!failflag)2365 cerr << "WARNING: Find_next_suitable_triangle failed." << endl;2366 } else {2367 cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;2368 }2369 N++;2370 baseline++;2371 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {2372 baseline = Tess->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines2373 flag = false;2374 }2375 }2376 if (failflag) {2377 cout << Verbose(1) << "Writing final tecplot file\n";2378 if (DoTecplotOutput)2379 write_tecplot_file(out, tecplot, Tess, mol, -1);2380 if (DoRaster3DOutput)2381 write_raster3d_file(out, tecplot, Tess, mol);2382 } else {2383 cerr << "ERROR: Could definately not find all necessary triangles!" << endl;2384 }2385 2386 cout << Verbose(0) << "End of Find_non_convex_border\n";2387 delete(Tess);2346 int N = 0; 2347 struct Tesselation *Tess = new Tesselation; 2348 cout << Verbose(1) << "Entering search for non convex hull. " << endl; 2349 cout << flush; 2350 LineMap::iterator baseline; 2351 cout << Verbose(0) << "Begin of Find_non_convex_border\n"; 2352 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles 2353 bool failflag = false; 2354 if ((mol->first->next == mol->last) || (mol->last->previous == mol->first)) 2355 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true); 2356 2357 Tess->Find_starting_triangle(mol, RADIUS); 2358 2359 baseline = Tess->LinesOnBoundary.begin(); 2360 while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) { 2361 if (baseline->second->TrianglesCount == 1) { 2362 failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one. 2363 flag = flag || failflag; 2364 if (!failflag) 2365 cerr << "WARNING: Find_next_suitable_triangle failed." << endl; 2366 } else { 2367 cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl; 2368 } 2369 N++; 2370 baseline++; 2371 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) { 2372 baseline = Tess->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 2373 flag = false; 2374 } 2375 } 2376 if (failflag) { 2377 cout << Verbose(1) << "Writing final tecplot file\n"; 2378 if (DoTecplotOutput) 2379 write_tecplot_file(out, tecplot, Tess, mol, -1); 2380 if (DoRaster3DOutput) 2381 write_raster3d_file(out, tecplot, Tess, mol); 2382 } else { 2383 cerr << "ERROR: Could definately not find all necessary triangles!" << endl; 2384 } 2385 2386 cout << Verbose(0) << "End of Find_non_convex_border\n"; 2387 delete(Tess); 2388 2388 }; 2389 2389 -
src/builder.cpp
r986c80 rce5ac3 562 562 break; 563 563 case 'd': 564 cout << Verbose(0) << "Evaluating prinicipal axis." << endl;565 cout << Verbose(0) << "Shall we rotate? [0/1]: ";566 cin >> Z;567 if ((Z >=0) && (Z <=1))568 mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z);569 else570 mol->PrincipalAxisSystem((ofstream *)&cout, false);571 break;564 cout << Verbose(0) << "Evaluating prinicipal axis." << endl; 565 cout << Verbose(0) << "Shall we rotate? [0/1]: "; 566 cin >> Z; 567 if ((Z >=0) && (Z <=1)) 568 mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z); 569 else 570 mol->PrincipalAxisSystem((ofstream *)&cout, false); 571 break; 572 572 case 'e': 573 cout << Verbose(0) << "Evaluating volume of the convex envelope.";574 VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);575 break;573 cout << Verbose(0) << "Evaluating volume of the convex envelope."; 574 VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol); 575 break; 576 576 case 'f': 577 577 mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps, (ofstream *)&cout); … … 1020 1020 } 1021 1021 break; 1022 case 'A':1023 ExitFlag = 1;1024 if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {1025 ExitFlag =255;1026 cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;1027 } else {1028 cout << "Parsing bonds from " << argv[argptr] << "." << endl;1029 ifstream *input = new ifstream(argv[argptr]);1030 mol->CreateAdjacencyList2((ofstream *)&cout, input);1031 input->close();1032 }1033 break;1034 case 'N':1035 ExitFlag = 1;1036 if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){1037 ExitFlag = 255;1038 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;1039 } else {1040 cout << Verbose(0) << "Evaluating npn-convex envelope.";1041 string TempName(argv[argptr+1]);1042 TempName.append(".r3d");1043 ofstream *output = new ofstream(TempName.c_str(), ios::trunc);1044 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;1045 Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));1046 output->close();1047 delete(output);1048 argptr+=2;1049 }1050 break;1022 case 'A': 1023 ExitFlag = 1; 1024 if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) { 1025 ExitFlag =255; 1026 cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl; 1027 } else { 1028 cout << "Parsing bonds from " << argv[argptr] << "." << endl; 1029 ifstream *input = new ifstream(argv[argptr]); 1030 mol->CreateAdjacencyList2((ofstream *)&cout, input); 1031 input->close(); 1032 } 1033 break; 1034 case 'N': 1035 ExitFlag = 1; 1036 if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){ 1037 ExitFlag = 255; 1038 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl; 1039 } else { 1040 cout << Verbose(0) << "Evaluating npn-convex envelope."; 1041 string TempName(argv[argptr+1]); 1042 TempName.append(".r3d"); 1043 ofstream *output = new ofstream(TempName.c_str(), ios::trunc); 1044 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl; 1045 Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr])); 1046 output->close(); 1047 delete(output); 1048 argptr+=2; 1049 } 1050 break; 1051 1051 case 'T': 1052 1052 ExitFlag = 1; … … 1369 1369 char choice; // menu choice char 1370 1370 Vector x,y,z,n; // coordinates for absolute point in cell volume 1371 double *factor;// unit factor if desired1371 double *factor; // unit factor if desired 1372 1372 bool valid; // flag if input was valid or not 1373 1373 ifstream test; -
src/config.cpp
r986c80 rce5ac3 1082 1082 { 1083 1083 bool result = true; 1084 // bring MaxTypes up to date1085 mol->CountElements();1084 // bring MaxTypes up to date 1085 mol->CountElements(); 1086 1086 ofstream *output = NULL; 1087 1087 output = new ofstream(filename, ios::out); -
src/datacreator.cpp
r986c80 rce5ac3 335 335 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 336 336 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) { 337 tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];338 norm += tmp*tmp;337 tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l]; 338 norm += tmp*tmp; 339 339 } 340 340 } -
src/helpers.cpp
r986c80 rce5ac3 73 73 void *buffer = NULL; 74 74 if (OldPointer == NULL) 75 //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl;75 //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl; 76 76 buffer = (void *)malloc(size); // malloc 77 77 else -
src/molecules.cpp
r986c80 rce5ac3 53 53 BondCount = 0; 54 54 NoNonBonds = 0; 55 NoNonHydrogen = 0;55 NoNonHydrogen = 0; 56 56 NoCyclicBonds = 0; 57 57 ListOfBondsPerAtom = NULL; … … 117 117 { 118 118 if (pointer != NULL) { 119 atom *walker = new atom();120 walker->type = pointer->type;// copy element of atom121 walker->x.CopyVector(&pointer->x); // copy coordination119 atom *walker = new atom(); 120 walker->type = pointer->type; // copy element of atom 121 walker->x.CopyVector(&pointer->x); // copy coordination 122 122 walker->v.CopyVector(&pointer->v); // copy velocity 123 123 walker->FixedIon = pointer->FixedIon; … … 186 186 double *matrix; 187 187 188 // *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;188 // *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; 189 189 // create vector in direction of bond 190 190 InBondvector.CopyVector(&TopReplacement->x); … … 427 427 } 428 428 429 // *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;429 // *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl; 430 430 return AllWentWell; 431 431 }; … … 753 753 Vector * molecule::DetermineCenterOfGravity(ofstream *out) 754 754 { 755 atom *ptr = start->next; // start at first in list756 Vector *a = new Vector();757 Vector tmp;755 atom *ptr = start->next; // start at first in list 756 Vector *a = new Vector(); 757 Vector tmp; 758 758 double Num = 0; 759 759 760 a->Zero();760 a->Zero(); 761 761 762 762 if (ptr != end) { //list not empty? … … 909 909 void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate) 910 910 { 911 atom *ptr = start; // start at first in list912 double InertiaTensor[NDIM*NDIM];913 Vector *CenterOfGravity = DetermineCenterOfGravity(out);914 915 CenterGravity(out, CenterOfGravity);916 917 // reset inertia tensor918 for(int i=0;i<NDIM*NDIM;i++)919 InertiaTensor[i] = 0.;920 921 // sum up inertia tensor922 while (ptr->next != end) {923 ptr = ptr->next;924 Vector x;925 x.CopyVector(&ptr->x);926 //x.SubtractVector(CenterOfGravity);927 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);928 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);929 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);930 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);931 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);932 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);933 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);934 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);935 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);936 }937 // print InertiaTensor for debugging938 *out << "The inertia tensor is:" << endl;939 for(int i=0;i<NDIM;i++) {940 for(int j=0;j<NDIM;j++)941 *out << InertiaTensor[i*NDIM+j] << " ";942 *out << endl;943 }944 *out << endl;945 946 // diagonalize to determine principal axis system947 gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);948 gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);949 gsl_vector *eval = gsl_vector_alloc(NDIM);950 gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);951 gsl_eigen_symmv(&m.matrix, eval, evec, T);952 gsl_eigen_symmv_free(T);953 gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);954 955 for(int i=0;i<NDIM;i++) {956 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);957 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;958 }959 960 // check whether we rotate or not961 if (DoRotate) {962 *out << Verbose(1) << "Transforming molecule into PAS ... ";963 // the eigenvectors specify the transformation matrix964 ptr = start;965 while (ptr->next != end) {966 ptr = ptr->next;967 for (int j=0;j<MDSteps;j++)968 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);969 ptr->x.MatrixMultiplication(evec->data);970 }971 *out << "done." << endl;972 973 // summing anew for debugging (resulting matrix has to be diagonal!)974 // reset inertia tensor911 atom *ptr = start; // start at first in list 912 double InertiaTensor[NDIM*NDIM]; 913 Vector *CenterOfGravity = DetermineCenterOfGravity(out); 914 915 CenterGravity(out, CenterOfGravity); 916 917 // reset inertia tensor 918 for(int i=0;i<NDIM*NDIM;i++) 919 InertiaTensor[i] = 0.; 920 921 // sum up inertia tensor 922 while (ptr->next != end) { 923 ptr = ptr->next; 924 Vector x; 925 x.CopyVector(&ptr->x); 926 //x.SubtractVector(CenterOfGravity); 927 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]); 928 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]); 929 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]); 930 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]); 931 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]); 932 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]); 933 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]); 934 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]); 935 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]); 936 } 937 // print InertiaTensor for debugging 938 *out << "The inertia tensor is:" << endl; 939 for(int i=0;i<NDIM;i++) { 940 for(int j=0;j<NDIM;j++) 941 *out << InertiaTensor[i*NDIM+j] << " "; 942 *out << endl; 943 } 944 *out << endl; 945 946 // diagonalize to determine principal axis system 947 gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM); 948 gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM); 949 gsl_vector *eval = gsl_vector_alloc(NDIM); 950 gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM); 951 gsl_eigen_symmv(&m.matrix, eval, evec, T); 952 gsl_eigen_symmv_free(T); 953 gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); 954 955 for(int i=0;i<NDIM;i++) { 956 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i); 957 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl; 958 } 959 960 // check whether we rotate or not 961 if (DoRotate) { 962 *out << Verbose(1) << "Transforming molecule into PAS ... "; 963 // the eigenvectors specify the transformation matrix 964 ptr = start; 965 while (ptr->next != end) { 966 ptr = ptr->next; 967 for (int j=0;j<MDSteps;j++) 968 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data); 969 ptr->x.MatrixMultiplication(evec->data); 970 } 971 *out << "done." << endl; 972 973 // summing anew for debugging (resulting matrix has to be diagonal!) 974 // reset inertia tensor 975 975 for(int i=0;i<NDIM*NDIM;i++) 976 976 InertiaTensor[i] = 0.; … … 1001 1001 } 1002 1002 *out << endl; 1003 }1004 1005 // free everything1006 delete(CenterOfGravity);1007 gsl_vector_free(eval);1008 gsl_matrix_free(evec);1003 } 1004 1005 // free everything 1006 delete(CenterOfGravity); 1007 gsl_vector_free(eval); 1008 gsl_matrix_free(evec); 1009 1009 }; 1010 1010 … … 2027 2027 runner = elemente->start; 2028 2028 while (runner->next != elemente->end) { // go through every element 2029 runner = runner->next;2029 runner = runner->next; 2030 2030 if (ElementsInMolecule[runner->Z]) { // if this element got atoms 2031 2031 ElementNo++; … … 2121 2121 bool molecule::Checkout(ofstream *out) const 2122 2122 { 2123 return elemente->Checkout(out, ElementsInMolecule);2123 return elemente->Checkout(out, ElementsInMolecule); 2124 2124 }; 2125 2125 … … 2174 2174 runner = elemente->start; 2175 2175 while (runner->next != elemente->end) { // go through every element 2176 runner = runner->next;2176 runner = runner->next; 2177 2177 if (ElementsInMolecule[runner->Z]) { // if this element got atoms 2178 2178 ElementNo++; … … 2196 2196 void molecule::CountAtoms(ofstream *out) 2197 2197 { 2198 int i = 0;2199 atom *Walker = start;2198 int i = 0; 2199 atom *Walker = start; 2200 2200 while (Walker->next != end) { 2201 2201 Walker = Walker->next; … … 2204 2204 if ((AtomCount == 0) || (i != AtomCount)) { 2205 2205 *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl; 2206 AtomCount = i;2206 AtomCount = i; 2207 2207 2208 2208 // count NonHydrogen atoms and give each atom a unique name 2209 2209 if (AtomCount != 0) { 2210 i=0;2211 NoNonHydrogen = 0;2210 i=0; 2211 NoNonHydrogen = 0; 2212 2212 Walker = start; 2213 while (Walker->next != end) {2214 Walker = Walker->next;2215 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron)2216 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it2217 NoNonHydrogen++;2218 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");2219 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");2220 sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);2213 while (Walker->next != end) { 2214 Walker = Walker->next; 2215 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 2216 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it 2217 NoNonHydrogen++; 2218 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name"); 2219 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name"); 2220 sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1); 2221 2221 *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl; 2222 i++;2223 }2222 i++; 2223 } 2224 2224 } else 2225 *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;2225 *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 2226 2226 } 2227 2227 }; … … 2231 2231 void molecule::CountElements() 2232 2232 { 2233 int i = 0;2233 int i = 0; 2234 2234 for(i=MAX_ELEMENTS;i--;) 2235 ElementsInMolecule[i] = 0;2236 ElementCount = 0;2235 ElementsInMolecule[i] = 0; 2236 ElementCount = 0; 2237 2237 2238 2238 atom *walker = start; … … 2243 2243 } 2244 2244 for(i=MAX_ELEMENTS;i--;) 2245 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);2245 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0); 2246 2246 }; 2247 2247 … … 2334 2334 { 2335 2335 2336 // 1 We will parse bonds out of the dbond file created by tremolo.2337 int atom1, atom2, temp;2338 atom *Walker, *OtherWalker;2339 2340 if (!input)2341 {2342 cout << Verbose(1) << "Opening silica failed \n";2343 };2344 2345 *input >> ws >> atom1;2346 *input >> ws >> atom2;2347 cout << Verbose(1) << "Scanning file\n";2348 while (!input->eof()) // Check whether we read everything already2349 {2350 *input >> ws >> atom1;2351 *input >> ws >> atom2;2352 if(atom2<atom1) //Sort indices of atoms in order2353 {2354 temp=atom1;2355 atom1=atom2;2356 atom2=temp;2357 };2358 2359 Walker=start;2360 while(Walker-> nr != atom1) // Find atom corresponding to first index2361 {2362 Walker = Walker->next;2363 };2364 OtherWalker = Walker->next;2365 while(OtherWalker->nr != atom2) // Find atom corresponding to second index2366 {2367 OtherWalker= OtherWalker->next;2368 };2369 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.2370 2371 }2372 2373 CreateListOfBondsPerAtom(out);2336 // 1 We will parse bonds out of the dbond file created by tremolo. 2337 int atom1, atom2, temp; 2338 atom *Walker, *OtherWalker; 2339 2340 if (!input) 2341 { 2342 cout << Verbose(1) << "Opening silica failed \n"; 2343 }; 2344 2345 *input >> ws >> atom1; 2346 *input >> ws >> atom2; 2347 cout << Verbose(1) << "Scanning file\n"; 2348 while (!input->eof()) // Check whether we read everything already 2349 { 2350 *input >> ws >> atom1; 2351 *input >> ws >> atom2; 2352 if(atom2<atom1) //Sort indices of atoms in order 2353 { 2354 temp=atom1; 2355 atom1=atom2; 2356 atom2=temp; 2357 }; 2358 2359 Walker=start; 2360 while(Walker-> nr != atom1) // Find atom corresponding to first index 2361 { 2362 Walker = Walker->next; 2363 }; 2364 OtherWalker = Walker->next; 2365 while(OtherWalker->nr != atom2) // Find atom corresponding to second index 2366 { 2367 OtherWalker= OtherWalker->next; 2368 }; 2369 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices. 2370 2371 } 2372 2373 CreateListOfBondsPerAtom(out); 2374 2374 2375 2375 }; … … 2520 2520 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of 2521 2521 // double bonds as was expected. 2522 if (BondCount != 0) {2522 if (BondCount != 0) { 2523 2523 NoCyclicBonds = 0; 2524 *out << Verbose(1) << "Correcting Bond degree of each bond ... ";2525 do {2526 No = 0; // No acts as breakup flag (if 1 we still continue)2524 *out << Verbose(1) << "Correcting Bond degree of each bond ... "; 2525 do { 2526 No = 0; // No acts as breakup flag (if 1 we still continue) 2527 2527 Walker = start; 2528 2528 while (Walker->next != end) { // go through every atom … … 2538 2538 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners 2539 2539 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); 2540 // count valence of second partner2540 // count valence of second partner 2541 2541 NoBonds = 0; 2542 2542 for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++) 2543 2543 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree; 2544 2544 *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 2545 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate2546 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first2545 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate 2546 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first 2547 2547 Candidate = OtherWalker; 2548 2548 CandidateBondNo = i; 2549 *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;2550 }2551 }2552 }2549 *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl; 2550 } 2551 } 2552 } 2553 2553 if ((Candidate != NULL) && (CandidateBondNo != -1)) { 2554 2554 ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++; … … 2558 2558 FalseBondDegree++; 2559 2559 } 2560 }2561 } while (No);2562 *out << " done." << endl;2563 } else2564 *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;2565 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;2566 2567 // output bonds for debugging (if bond chain list was correctly installed)2568 *out << Verbose(1) << endl << "From contents of bond chain list:";2569 bond *Binder = first;2560 } 2561 } while (No); 2562 *out << " done." << endl; 2563 } else 2564 *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl; 2565 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl; 2566 2567 // output bonds for debugging (if bond chain list was correctly installed) 2568 *out << Verbose(1) << endl << "From contents of bond chain list:"; 2569 bond *Binder = first; 2570 2570 while(Binder->next != last) { 2571 2571 Binder = Binder->next; 2572 *out << *Binder << "\t" << endl;2572 *out << *Binder << "\t" << endl; 2573 2573 } 2574 2574 *out << endl; 2575 2575 } else 2576 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;2576 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 2577 2577 *out << Verbose(0) << "End of CreateAdjacencyList." << endl; 2578 2578 Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix"); … … 3600 3600 int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration) 3601 3601 { 3602 MoleculeListClass *BondFragments = NULL;3602 MoleculeListClass *BondFragments = NULL; 3603 3603 int *SortIndex = NULL; 3604 3604 int *MinimumRingSize = new int[AtomCount]; … … 3806 3806 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule 3807 3807 if (Walker != NULL) // if this Walker exists in the subgraph ... 3808 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through the local list of bonds3809 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);3810 if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond3811 LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);3808 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through the local list of bonds 3809 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); 3810 if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond 3811 LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]); 3812 3812 *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl; 3813 break;3814 }3815 }3813 break; 3814 } 3815 } 3816 3816 Binder = ReferenceStack->PopFirst(); // loop the stack for next item 3817 3817 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl; … … 4308 4308 for (int i=0;i<AtomCount;i++) { // reset all atom labels 4309 4309 // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons 4310 Labels[i] = -1;4310 Labels[i] = -1; 4311 4311 SonList[i] = NULL; 4312 4312 PredecessorList[i] = NULL; … … 4316 4316 for (int i=0;i<BondCount;i++) 4317 4317 ColorEdgeList[i] = white; 4318 RootStack->ClearStack();// clearstack and push first atom if exists4318 RootStack->ClearStack(); // clearstack and push first atom if exists 4319 4319 TouchedStack->ClearStack(); 4320 4320 Walker = start->next; … … 4335 4335 ///// OUTER LOOP //////////// 4336 4336 while (!RootStack->IsEmpty()) { 4337 // get new root vertex from atom stack4338 Root = RootStack->PopFirst();4337 // get new root vertex from atom stack 4338 Root = RootStack->PopFirst(); 4339 4339 ShortestPathList[Root->nr] = 0; 4340 4340 if (Labels[Root->nr] == -1) … … 4344 4344 *out << Verbose(0) << "Root for this loop is: " << Root->Name << ".\n"; 4345 4345 4346 // clear snake stack4347 SnakeStack->ClearStack();4346 // clear snake stack 4347 SnakeStack->ClearStack(); 4348 4348 //SnakeStack->TestImplementation(out, start->next); 4349 4349 … … 4352 4352 // - what about cyclic bonds? 4353 4353 Walker = Root; 4354 do {4354 do { 4355 4355 *out << Verbose(1) << "Current Walker is: " << Walker->Name; 4356 4356 // initial setting of the new Walker: label, color, shortest path and put on stacks 4357 if (Labels[Walker->nr] == -1) {// give atom a unique, monotonely increasing number4358 Labels[Walker->nr] = RunningIndex++;4357 if (Labels[Walker->nr] == -1) { // give atom a unique, monotonely increasing number 4358 Labels[Walker->nr] = RunningIndex++; 4359 4359 RootStack->Push(Walker); 4360 4360 } 4361 4361 *out << ", has label " << Labels[Walker->nr]; 4362 if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) {// color it if newly discovered and push on stacks (and if within reach!)4362 if ((ColorVertexList[Walker->nr] == white) || ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white))) { // color it if newly discovered and push on stacks (and if within reach!) 4363 4363 if ((Binder != NULL) && (ColorEdgeList[Binder->nr] == white)) { 4364 4364 // Binder ought to be set still from last neighbour search … … 4374 4374 ColorVertexList[Walker->nr] = darkgray; // mark as dark gray of on snake stack 4375 4375 } 4376 }4376 } 4377 4377 *out << ", SP of " << ShortestPathList[Walker->nr] << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl; 4378 4378 4379 4379 // then check the stack for a newly stumbled upon fragment 4380 if (SnakeStack->ItemCount() == Order) { // is stack full?4380 if (SnakeStack->ItemCount() == Order) { // is stack full? 4381 4381 // store the fragment if it is one and get a removal candidate 4382 4382 Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration); … … 4391 4391 } 4392 4392 } 4393 } else4393 } else 4394 4394 Removal = NULL; 4395 4395 … … 4398 4398 if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) { // don't look, if a new walker has been set above 4399 4399 *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl; 4400 OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour4400 OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour 4401 4401 if (ShortestPathList[Walker->nr] < Order) { 4402 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {4402 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 4403 4403 Binder = ListOfBondsPerAtom[Walker->nr][i]; 4404 4404 *out << Verbose(2) << "Current bond is " << *Binder << ": "; 4405 OtherAtom = Binder->GetOtherAtom(Walker);4405 OtherAtom = Binder->GetOtherAtom(Walker); 4406 4406 if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us 4407 4407 *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 4408 4408 //ColorVertexList[OtherAtom->nr] = lightgray; // mark as explored 4409 4409 } else { // otherwise check its colour and element 4410 if (4410 if ( 4411 4411 #ifdef ADDHYDROGEN 4412 4412 (OtherAtom->type->Z != 1) && … … 4430 4430 } 4431 4431 } 4432 }4432 } 4433 4433 } else { // means we have stepped beyond the horizon: Return! 4434 4434 Walker = PredecessorList[Walker->nr]; … … 4436 4436 *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl; 4437 4437 } 4438 if (Walker != OtherAtom) {// if no white neighbours anymore, color it black4438 if (Walker != OtherAtom) { // if no white neighbours anymore, color it black 4439 4439 *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl; 4440 ColorVertexList[Walker->nr] = black;4441 Walker = PredecessorList[Walker->nr];4442 }4443 } 4444 } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));4440 ColorVertexList[Walker->nr] = black; 4441 Walker = PredecessorList[Walker->nr]; 4442 } 4443 } 4444 } while ((Walker != Root) || (ColorVertexList[Root->nr] != black)); 4445 4445 *out << Verbose(2) << "Inner Looping is finished." << endl; 4446 4446 … … 4562 4562 bit = ((i & (1 << j)) != 0); // mask the bit for the j-th bond 4563 4563 if (bit) { // if bit is set, we add this bond partner 4564 OtherWalker = BondsSet[j]->rightatom;// rightatom is always the one more distant, i.e. the one to add4564 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add 4565 4565 //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl; 4566 4566 *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl; … … 4584 4584 if (SubOrder > 1) { // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order 4585 4585 // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion 4586 SP = RootDistance+1; // this is the next level4586 SP = RootDistance+1; // this is the next level 4587 4587 // first count the members in the subset 4588 4588 SubSetDimension = 0; 4589 Binder = FragmentSearch->BondsPerSPList[2*SP]; // start node for this level4590 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { // compare to end node of this level4589 Binder = FragmentSearch->BondsPerSPList[2*SP]; // start node for this level 4590 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { // compare to end node of this level 4591 4591 Binder = Binder->next; 4592 4592 for (int k=TouchedIndex;k--;) { -
src/parser.cpp
r986c80 rce5ac3 786 786 } 787 787 if (k != -1) { 788 //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;788 //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl; 789 789 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m]; 790 790 } … … 855 855 } 856 856 if (Order == SubOrder) { // equal order is always copy from Energies 857 //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;857 //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 858 858 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 859 859 } else { 860 //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;860 //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 861 861 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 862 862 } -
src/vector.cpp
r986c80 rce5ac3 327 327 } 328 328 ost << ")"; 329 return ost;329 return ost; 330 330 }; 331 331 … … 517 517 bool Vector::MakeNormalVector(const Vector *y1) 518 518 { 519 bool result = false;519 bool result = false; 520 520 Vector x1; 521 521 x1.CopyVector(y1); … … 523 523 SubtractVector(&x1); 524 524 for (int i=NDIM;i--;) 525 result = result || (fabs(x[i]) > MYEPSILON);525 result = result || (fabs(x[i]) > MYEPSILON); 526 526 527 527 return result; … … 597 597 bool Vector::LSQdistance(Vector **vectors, int num) 598 598 { 599 int j;600 601 for (j=0;j<num;j++) {602 cout << Verbose(1) << j << "th atom's vector: ";603 (vectors[j])->Output((ofstream *)&cout);604 cout << endl;605 }599 int j; 600 601 for (j=0;j<num;j++) { 602 cout << Verbose(1) << j << "th atom's vector: "; 603 (vectors[j])->Output((ofstream *)&cout); 604 cout << endl; 605 } 606 606 607 607 int np = 3; 608 struct LSQ_params par;608 struct LSQ_params par; 609 609 610 610 const gsl_multimin_fminimizer_type *T = … … 627 627 /* Starting point */ 628 628 par.vectors = vectors; 629 par.num = num;630 631 for (i=NDIM;i--;)632 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);629 par.num = num; 630 631 for (i=NDIM;i--;) 632 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 633 633 634 634 /* Initialize method and iterate */ … … 671 671 gsl_multimin_fminimizer_free (s); 672 672 673 return true;673 return true; 674 674 }; 675 675 -
src/verbose.cpp
r986c80 rce5ac3 22 22 ostream& operator<<(ostream& ost,const Verbose& m) 23 23 { 24 return m.print(ost);24 return m.print(ost); 25 25 }; 26 26 … … 33 33 ostream& Binary::print (ostream &ost) const 34 34 { 35 int bits = 1, counter = 1;36 while ((bits = 1 << counter) < BinaryNumber)35 int bits = 1, counter = 1; 36 while ((bits = 1 << counter) < BinaryNumber) 37 37 counter++; 38 38 for (int i=0;i<counter-1;i++) { 39 if ((BinaryNumber & (1 << i)) == 0)40 ost.put('0');41 else42 ost.put('1');39 if ((BinaryNumber & (1 << i)) == 0) 40 ost.put('0'); 41 else 42 ost.put('1'); 43 43 } 44 44 ost.put('b'); … … 56 56 ostream& operator<<(ostream& ost,const Binary& m) 57 57 { 58 return m.print(ost);58 return m.print(ost); 59 59 };
Note:
See TracChangeset
for help on using the changeset viewer.
