Changeset ce5ac3
- Timestamp:
- Jul 23, 2009, 12:32:48 PM (15 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, 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
Legend:
- Unmodified
- Added
- Removed
-
src/atom.cpp
r986c80 rce5ac3 13 13 atom::atom() 14 14 { 15 15 Name = NULL; 16 16 previous = NULL; 17 17 next = NULL; … … 35 35 atom::~atom() 36 36 { 37 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 17 16 leftatom = NULL; 17 rightatom = NULL; 18 18 previous = NULL; 19 19 next = NULL; 20 21 22 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 37 36 leftatom = left; 37 rightatom = right; 38 38 previous = NULL; 39 39 next = NULL; 40 40 HydrogenBond = 0; 41 41 if ((left != NULL) && (right != NULL)) { 42 43 44 45 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 89 90 91 92 93 94 95 96 97 98 99 100 101 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 184 185 186 187 188 189 190 191 192 193 194 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 576 577 578 579 580 581 582 583 584 585 586 *rasterfile << "2" << endl << " ";// 2 is sphere type587 588 589 590 591 592 593 594 595 *rasterfile << "3" << endl << " ";// 2 is round-ended cylinder type596 597 598 599 600 601 602 603 604 605 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 610 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 616 617 618 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 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 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 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 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 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 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 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1949 } else { 1950 if (DEBUG) { 1951 cout << "Doesn't satisfy requirements for circumscribing circle" << endl; 1952 } 1953 } 1954 } else { 1955 if (DEBUG) { 1956 cout << "identisch mit Ursprungslinie" << endl; 1957 } 1958 } 1959 1960 if (RecursionLevel < 9) { // Five is the recursion level threshold. 1961 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond 1962 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 1963 if (Walker == Parent) { // don't go back the same bond 1964 continue; 1965 } else { 1966 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again 1967 } 1968 } 1969 } 1970 1970 }; 1971 1971 … … 1984 1984 const double& RADIUS, int N, const char *tempbasename) 1985 1985 { 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 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 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 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 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 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 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 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 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 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 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 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 565 566 567 568 569 570 571 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 574 575 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 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 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 1085 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 338 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 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 55 NoNonHydrogen = 0; 56 56 NoCyclicBonds = 0; 57 57 ListOfBondsPerAtom = NULL; … … 117 117 { 118 118 if (pointer != NULL) { 119 120 walker->type = pointer->type;// copy element of atom121 119 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 // 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 // 429 // *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl; 430 430 return AllWentWell; 431 431 }; … … 753 753 Vector * molecule::DetermineCenterOfGravity(ofstream *out) 754 754 { 755 756 757 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 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 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 911 atom *ptr = start; // start at first in list 912 double InertiaTensor[NDIM*NDIM]; 913 Vector *CenterOfGravity = DetermineCenterOfGravity(out); 914 915 CenterGravity(out, CenterOfGravity); 916 917 // reset inertia tensor 918 for(int i=0;i<NDIM*NDIM;i++) 919 InertiaTensor[i] = 0.; 920 921 // sum up inertia tensor 922 while (ptr->next != end) { 923 ptr = ptr->next; 924 Vector x; 925 x.CopyVector(&ptr->x); 926 //x.SubtractVector(CenterOfGravity); 927 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]); 928 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]); 929 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]); 930 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]); 931 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]); 932 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]); 933 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]); 934 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]); 935 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]); 936 } 937 // print InertiaTensor for debugging 938 *out << "The inertia tensor is:" << endl; 939 for(int i=0;i<NDIM;i++) { 940 for(int j=0;j<NDIM;j++) 941 *out << InertiaTensor[i*NDIM+j] << " "; 942 *out << endl; 943 } 944 *out << endl; 945 946 // diagonalize to determine principal axis system 947 gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM); 948 gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM); 949 gsl_vector *eval = gsl_vector_alloc(NDIM); 950 gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM); 951 gsl_eigen_symmv(&m.matrix, eval, evec, T); 952 gsl_eigen_symmv_free(T); 953 gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); 954 955 for(int i=0;i<NDIM;i++) { 956 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i); 957 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl; 958 } 959 960 // check whether we rotate or not 961 if (DoRotate) { 962 *out << Verbose(1) << "Transforming molecule into PAS ... "; 963 // the eigenvectors specify the transformation matrix 964 ptr = start; 965 while (ptr->next != end) { 966 ptr = ptr->next; 967 for (int j=0;j<MDSteps;j++) 968 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data); 969 ptr->x.MatrixMultiplication(evec->data); 970 } 971 *out << "done." << endl; 972 973 // summing anew for debugging (resulting matrix has to be diagonal!) 974 // reset inertia tensor 975 975 for(int i=0;i<NDIM*NDIM;i++) 976 976 InertiaTensor[i] = 0.; … … 1001 1001 } 1002 1002 *out << endl; 1003 1004 1005 1006 1007 1008 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 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 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 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 2199 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 2206 AtomCount = i; 2207 2207 2208 2208 // count NonHydrogen atoms and give each atom a unique name 2209 2209 if (AtomCount != 0) { 2210 2211 2210 i=0; 2211 NoNonHydrogen = 0; 2212 2212 Walker = start; 2213 2214 2215 2216 2217 2218 2219 2220 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 2223 2222 i++; 2223 } 2224 2224 } else 2225 2225 *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 2226 2226 } 2227 2227 }; … … 2231 2231 void molecule::CountElements() 2232 2232 { 2233 2233 int i = 0; 2234 2234 for(i=MAX_ELEMENTS;i--;) 2235 2236 2235 ElementsInMolecule[i] = 0; 2236 ElementCount = 0; 2237 2237 2238 2238 atom *walker = start; … … 2243 2243 } 2244 2244 for(i=MAX_ELEMENTS;i--;) 2245 2245 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0); 2246 2246 }; 2247 2247 … … 2334 2334 { 2335 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 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 2522 if (BondCount != 0) { 2523 2523 NoCyclicBonds = 0; 2524 2525 2526 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 2540 // 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 2546 2545 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate 2546 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first 2547 2547 Candidate = OtherWalker; 2548 2548 CandidateBondNo = i; 2549 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 2562 2563 2564 2565 2566 2567 2568 2569 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 2572 *out << *Binder << "\t" << endl; 2573 2573 } 2574 2574 *out << endl; 2575 2575 } else 2576 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 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 3809 3810 3811 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 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 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 4338 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 4347 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 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 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 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 4393 } 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 4400 OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour 4401 4401 if (ShortestPathList[Walker->nr] < Order) { 4402 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 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 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 4441 4442 4443 } 4444 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; 4586 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]; 4590 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { 4589 Binder = FragmentSearch->BondsPerSPList[2*SP]; // start node for this level 4590 while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) { // compare to end node of this level 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 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 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 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 329 return ost; 330 330 }; 331 331 … … 517 517 bool Vector::MakeNormalVector(const Vector *y1) 518 518 { 519 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 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 600 601 602 603 604 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 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 630 631 632 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 673 return true; 674 674 }; 675 675 -
src/verbose.cpp
r986c80 rce5ac3 22 22 ostream& operator<<(ostream& ost,const Verbose& m) 23 23 { 24 24 return m.print(ost); 25 25 }; 26 26 … … 33 33 ostream& Binary::print (ostream &ost) const 34 34 { 35 36 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 40 41 42 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 58 return m.print(ost); 59 59 };
Note:
See TracChangeset
for help on using the changeset viewer.