Changeset 49de64 for src


Ignore:
Timestamp:
Jun 10, 2008, 11:21:32 AM (17 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, 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:
cdee6b
Parents:
233e33
Message:

VolumeOfConvexEnvelope() finished and tested with SiOH4, 1_2_dimethoxyethane and CSHCluster (Ratio1-1)

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/molecules.cpp

    r233e33 r49de64  
    13811381       
    13821382        // 1. calculate center of gravity
     1383        *out << endl;
    13831384        vector *CenterOfGravity = DetermineCenterOfGravity(out);
    13841385       
     1386        // 2. translate all points into CoG
     1387        *out << Verbose(1) << "Translating system to Center of Gravity." << endl;
     1388        Walker=start;
     1389        while (Walker->next != end) {
     1390          Walker = Walker->next;
     1391          Walker->x.Translate(CenterOfGravity);
     1392        }
    13851393        // 2. calculate distance of each atom and sort into hash table
    13861394//      map<double, int> DistanceSet;
     
    13931401       
    13941402        // 3. Find all points on the boundary
     1403  *out << Verbose(1) << "Finding all boundary points." << endl;
    13951404        Boundaries BoundaryPoints[NDIM];        // first is alpha, second is (r, nr)
    13961405        BoundariesTestPair BoundaryTestPair;
    1397         vector AxisVector;
     1406        vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;
     1407        double radius, angle;
    13981408        // 3a. Go through every axis
    13991409        for (int axis=0; axis<NDIM; axis++)  {
    14001410                AxisVector.Zero();
     1411    AngleReferenceVector.Zero();
     1412    AngleReferenceNormalVector.Zero();
    14011413                AxisVector.x[axis] = 1.;
     1414                AngleReferenceVector.x[(axis+1)%NDIM] = 1.;
     1415                AngleReferenceNormalVector.x[(axis+2)%NDIM] = 1.;
     1416//              *out << Verbose(1) << "Axisvector is ";
     1417//              AxisVector.Output(out);
     1418//              *out << " and AngleReferenceVector is ";
     1419//              AngleReferenceVector.Output(out);
     1420//              *out << "." << endl;
     1421//    *out << " and AngleReferenceNormalVector is ";
     1422//    AngleReferenceNormalVector.Output(out);
     1423//    *out << "." << endl;
    14021424                // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours
    14031425                Walker = start;
     
    14061428                        vector ProjectedVector;
    14071429                        ProjectedVector.CopyVector(&Walker->x);
    1408                         ProjectedVector.Scale(-1.*Walker->x.Projection(&AxisVector));
    1409                         ProjectedVector.AddVector(&Walker->x);  // subtract projection from vector
    1410                         BoundaryTestPair = BoundaryPoints[axis].insert( BoundariesPair (ProjectedVector.Angle(&AxisVector), DistanceNrPair (ProjectedVector.Norm(), Walker) ) );
     1430                        ProjectedVector.ProjectOntoPlane(&AxisVector);
     1431                  // correct for negative side
     1432                  //if (Projection(y) < 0)
     1433                    //angle = 2.*M_PI - angle;
     1434                        radius = ProjectedVector.Norm();
     1435                        if (fabs(radius) > MYEPSILON)
     1436                          angle = ProjectedVector.Angle(&AngleReferenceVector);
     1437                        else
     1438                          angle = 0.;  // otherwise it's a vector in Axis Direction and unimportant for boundary issues
     1439                         
     1440                        //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
     1441                        if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0) {
     1442                          angle = 2.*M_PI - angle;
     1443                        }
     1444                        *out << Verbose(2) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): ";
     1445                        ProjectedVector.Output(out);
     1446                        *out << endl;
     1447                        BoundaryTestPair = BoundaryPoints[axis].insert( BoundariesPair (angle, DistanceNrPair (radius, Walker) ) );
    14111448                        if (BoundaryTestPair.second) { // successfully inserted
    1412                         } else { // same point exists, check first r, then distance of original vectors to centers of gravity
     1449                        } else { // same point exists, check first r, then distance of original vectors to center of gravity
    14131450                                *out << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl;
    14141451                                *out << Verbose(2) << "Present vector: ";
     
    14241461                                        *out << Verbose(2) << "Keeping new vector." << endl;
    14251462                                } else if (tmp == BoundaryTestPair.first->second.first) {
    1426                                         if (BoundaryTestPair.first->second.second->x.Distance(CenterOfGravity) < Walker->x.Distance(CenterOfGravity)) {
     1463                                        if (BoundaryTestPair.first->second.second->x.ScalarProduct(&BoundaryTestPair.first->second.second->x) < Walker->x.ScalarProduct(&Walker->x)) { // Norm() does a sqrt, which makes it a lot slower
    14271464                                                BoundaryTestPair.first->second.second = Walker;
    14281465                                                *out << Verbose(2) << "Keeping new vector." << endl;
     
    14351472                        }
    14361473                }
    1437                 // 3c. throw out points whose distance is less than the mean of left and right neighbours
     1474                // printing all inserted for debugging
     1475                {
     1476      *out << Verbose(2) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl;
     1477      int i=0;
     1478      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     1479        if (runner != BoundaryPoints[axis].begin())
     1480          *out << ", " << i << ": " << *runner->second.second;
     1481        else
     1482          *out << i << ": " << *runner->second.second;
     1483        i++;
     1484      }
     1485      *out << endl;
     1486                }
     1487    // 3c. throw out points whose distance is less than the mean of left and right neighbours
    14381488                bool flag = false;
    14391489                do { // do as long as we still throw one out per round
     1490                  *out << Verbose(1) << "Looking for candidates to kick out by convex condition ... " << endl;
    14401491                        flag = false;
    14411492                        Boundaries::iterator left = BoundaryPoints[axis].end();
     
    14551506                                }
    14561507                                // check distance
    1457                                 if (runner->second.first < (left->second.first + right->second.first)/2. ) {
    1458                                         // throw out point
    1459                                         BoundaryPoints[axis].erase(runner);
    1460                                         flag = true;
     1508                               
     1509                                // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
     1510                                {
     1511          vector SideA, SideB, SideC, SideH;
     1512          SideA.CopyVector(&left->second.second->x);
     1513          SideA.ProjectOntoPlane(&AxisVector);
     1514//          *out << "SideA: ";
     1515//          SideA.Output(out);
     1516//          *out << endl;
     1517         
     1518          SideB.CopyVector(&right->second.second->x);
     1519          SideB.ProjectOntoPlane(&AxisVector);
     1520//          *out << "SideB: ";
     1521//          SideB.Output(out);
     1522//          *out << endl;
     1523         
     1524          SideC.CopyVector(&left->second.second->x);
     1525          SideC.SubtractVector(&right->second.second->x);
     1526          SideC.ProjectOntoPlane(&AxisVector);
     1527//          *out << "SideC: ";
     1528//          SideC.Output(out);
     1529//          *out << endl;
     1530
     1531          SideH.CopyVector(&runner->second.second->x);
     1532          SideH.ProjectOntoPlane(&AxisVector);
     1533//          *out << "SideH: ";
     1534//          SideH.Output(out);
     1535//          *out << endl;
     1536         
     1537          // calculate each length
     1538          double a = SideA.Norm();
     1539          //double b = SideB.Norm();
     1540          //double c = SideC.Norm();
     1541          double h = SideH.Norm();
     1542          // calculate the angles
     1543          double alpha = SideA.Angle(&SideH);
     1544                                double beta = SideA.Angle(&SideC);
     1545                                double gamma = SideB.Angle(&SideH);
     1546                                double delta = SideC.Angle(&SideH);
     1547                                double MinDistance = a * sin(beta)/(sin(delta)) * (((alpha < M_PI/2.) || (gamma < M_PI/2.)) ? 1. : -1.);
     1548//                              *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
     1549                                *out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
     1550                                if ((fabs(h/fabs(h) - MinDistance/fabs(MinDistance)) < MYEPSILON) && (h <  MinDistance)) {
     1551                                        // throw out point
     1552                                  *out << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl;
     1553                                        BoundaryPoints[axis].erase(runner);
     1554                                        flag = true;
     1555                                }
    14611556                                }
    14621557                        }
     
    14721567                }
    14731568        }
    1474         int BoundaryPointCount = 0;
    1475         Walker = start;
    1476         while (Walker->next != end) {
    1477                 Walker = Walker->next;
    1478                 if (AtomList[Walker->nr] < NDIM) {      // enter all neighbouring points
    1479                         BoundaryPointCount++;
    1480                 }
    1481         }
    1482        
     1569
    14831570        // 3e. Points no more in the total list, have to be thrown out of each axis lists too!
    14841571        for (int axis=0; axis<NDIM; axis++)  {
    14851572                for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    1486                         if (AtomList[runner->second.second->nr] < NDIM)
     1573                        if (AtomList[runner->second.second->nr] < 1) {
     1574                          *out << Verbose(1) << "Throwing out " << *runner->second.second << " in axial projection of axis " << axis << "." << endl;
    14871575                                BoundaryPoints[axis].erase(runner);
     1576                        }
    14881577                }
    14891578        }
     1579       
     1580        // listing boundary points
     1581        *out << Verbose(1) << "The following atoms are on the boundary:";
     1582  int BoundaryPointCount = 0;
     1583  Walker = start;
     1584  while (Walker->next != end) {
     1585    Walker = Walker->next;
     1586    if (AtomList[Walker->nr] > 0) {
     1587      BoundaryPointCount ++;
     1588      *out << " " << Walker->Name;
     1589    }
     1590  }
     1591  *out << endl;
    14901592
    14911593        *out << Verbose(2) << "I found " << BoundaryPointCount << " points on the convex boundary." << endl;
     
    14931595       
    14941596        // 4. Create each possible line, number them and put them into a list (3 * AtomCount possible)
    1495         struct lines {
    1496                 atom *x[2];
    1497                 int nr;
    1498         } LinesList[3 * AtomCount];
    1499        
    1500         // initialise reference storage (needed lateron)
    1501         int **AtomLines = new int *[AtomCount];
    1502         Walker = start;
    1503         while (Walker->next != end) {   // go through all points
    1504                 Walker = Walker->next;
    1505                 if (AtomList[Walker->nr] == NDIM) {     // if this is a boundary point
    1506                         AtomLines[Walker->nr] = new int[NDIM];
    1507                         for(int axis=0;axis<NDIM;axis++) {
    1508                                 AtomLines[Walker->nr][2*axis+0] = -1;
    1509                                 AtomLines[Walker->nr][2*axis+1] = -1;
    1510                         }
    1511                 }
    1512         }
     1597        LinesMap AllTriangleLines;
    15131598       
    15141599        // then create each line
     1600  *out << Verbose(1) << "Creating lines between adjacent boundary points." << endl;
     1601  atom *Runner = NULL;
    15151602  int LineCount = 0;
    1516         for(int axis=0;axis<NDIM;axis++) {      // go through every axis
    1517           for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    1518             // get left and right neighbours
    1519             Boundaries::iterator NN[2] = runner;
    1520             if (NN[0] == BoundaryPoints[axis].begin())
    1521               NN[0] = BoundaryPoints[axis].end();
    1522             NN[0]--;
    1523             NN[1] = runner;
    1524       NN[1]++;
    1525       if (NN[1] == BoundaryPoints[axis].end())
    1526         NN[1] = BoundaryPoints[axis].begin();
    1527       // check those neighbours for their atomic index
    1528       for (int k=0;k<2;k++) {
    1529                         if (runner->second.second->nr > NN[k]->second.second->nr) { // check left neighbour on this projected axis
    1530                                 LinesList[LineCount].x[0] = runner->second.second;
    1531                                 LinesList[LineCount].x[1] = NN[k]->second.second;
    1532                                 if (AtomLines[LinesList[LineCount].x[0]->nr][axis] == -1) {
    1533                                         AtomLines[LinesList[LineCount].x[0]->nr][axis] = LineCount;
    1534                                 } else if (AtomLines[LinesList[LineCount].x[1]->nr][axis] == -1) {
    1535                                         AtomLines[LinesList[LineCount].x[1]->nr][axis] = LineCount;
    1536                                 } else {
    1537                                         *out << Verbose(2) << "Could not store line number " << LineCount << "." << endl;
    1538                                 }
    1539                                 LineCount++;
    1540                         }
    1541       }
    1542                 }
    1543         }
     1603  Walker = start;
     1604  while (Walker->next != end) {
     1605    Walker = Walker->next;
     1606    if (AtomList[Walker->nr] > 0) { // boundary point!
     1607      *out << Verbose(1) << "Current Walker is " << *Walker << "." << endl;
     1608      // make a list of all neighbours
     1609      DistanceMap Distances;
     1610      double distance = 0;
     1611      Runner = start;
     1612      while (Runner->next != end) {
     1613        Runner = Runner->next;
     1614        if ((AtomList[Runner->nr] > 0) && (Runner != Walker)) { // don't mess with ourselves!
     1615          distance = Walker->x.Distance(&Runner->x);    // note this is squared distance
     1616          Distances.insert ( DistanceNrPair( distance, Runner) );
     1617          *out << Verbose(2) << "Inserted distance " << distance << " to " << *Runner << " successfully." << endl;
     1618        }
     1619      } // end of distance filling while loop
     1620      // take 3NNs to draw a line in between
     1621      int Counter = 0;  // counts up to three inserted lines
     1622      LinesTestPair LinesTest;
     1623      for (DistanceMap::iterator spanner = Distances.begin(); spanner != Distances.end(); spanner++) {
     1624        *out << Verbose(1) << "Current distance to insert is " << spanner->first << " to " << spanner->second+1 << "." << endl;
     1625        LinesTest = AllTriangleLines.insert ( LinesPair( (Walker->nr*AtomCount)+spanner->second->nr, LineCount) );
     1626        if (!LinesTest.second) {
     1627          *out << Verbose(2) << "Insertion of line between " << Walker->nr+1 << " and " << spanner->second->nr+1 << " failed, already present line nr. " << LinesTest.first->second << "." << endl;
     1628        } else {
     1629          LineCount++;
     1630          Counter++;
     1631          *out << Verbose(2) << "Insertion of line between " << (LinesTest.first->first/AtomCount)+1 << " and " << (LinesTest.first->first%AtomCount)+1 << " successful, inserting mirrored line and increased counter to " << Counter << "." << endl;
     1632          LinesTest = AllTriangleLines.insert ( LinesPair( Walker->nr+(spanner->second->nr*AtomCount), LineCount) );
     1633          if (!LinesTest.second) {
     1634            *out << Verbose(2) << "Insertion of mirror line between " << Walker->nr << " and " << spanner->second->nr << " failed, already present line nr. " << LinesTest.first->second << "." << endl;
     1635            *out << Verbose(0) << "SERIOUS ERROR!!!" << endl;
     1636          }
     1637        }
     1638        if (Counter >= 3) { // stop after three lines (if not run out of possible NNs already)
     1639          *out << Verbose(2) << "Ok, three lines inserted from current walker " << *Walker << ", stopping." << endl;
     1640          break;
     1641        }
     1642      }
     1643    } // end of if boundary pointy
     1644  } // end of loop through all atoms
     1645
     1646        // listing created lines
     1647        *out << Verbose(2) << "The following lines were created:";
     1648        for (LinesMap::iterator liner = AllTriangleLines.begin(); liner != AllTriangleLines.end(); liner++)
     1649          if ((liner->first/AtomCount) < (liner->first%AtomCount))
     1650            *out << " " << (liner->first/AtomCount)+1 << "<->" << (liner->first%AtomCount)+1;
     1651        *out << endl;
    15441652        *out << Verbose(2) << "I created " << LineCount << " edges." << endl;
    15451653       
    15461654        // 5. Create every possible triangle from the lines (numbering of each line must be i < j < k)
    15471655        struct triangles {
    1548                 atom *x1;
    1549                 atom *x2;
    1550                 atom *x3;
     1656                atom *x[3];
    15511657                int nr;
    15521658        } TriangleList[2 * 3 * AtomCount];      // each line can be part in at most 2 triangles
     1659
     1660  *out << Verbose(1) << "Creating triangles out of these lines." << endl;
    15531661        int TriangleCount = 0;
    1554         for (int i=0; i<LineCount; i++) {       // go through every line
     1662  LinetoAtomPair InsertionPair = LinetoAtomPair(-1, NULL);
     1663  int endpoints[3];
     1664  for (LinesMap::iterator liner = AllTriangleLines.begin(); liner != AllTriangleLines.end(); liner++) { // go through every line
    15551665                LinetoAtomMap LinetoAtom;
    15561666                // we have two points, check the lines at either end, whether they share a common endpoint
    1557                 for (int endpoint=0;endpoint<2;endpoint++) {
    1558                         Walker = LinesList[LineCount].x[endpoint];             
    1559                         for (int axis=0;axis<NDIM;axis++) {
    1560                                 LinetoAtomTestPair LinetoAtomTest;
    1561                                 LinetoAtomPair InsertionPair = LinetoAtomPair(-1, NULL);
    1562                                 struct lines *TempLine = &LinesList[ AtomLines[Walker->nr][axis] ];
    1563                                 if (AtomLines[Walker->nr][axis] != LineCount) {
    1564                                         if (TempLine->x[0] != Walker) {
    1565                                                 InsertionPair = LinetoAtomPair(TempLine->x[0]->nr, TempLine->x[0]);
    1566                                         } else if (TempLine->x[1] != Walker) {
    1567                                                 InsertionPair = LinetoAtomPair(TempLine->x[1]->nr, TempLine->x[0]);
    1568                                         } else {
    1569                                                 *out << Verbose(2) << "Atom " << *Walker << "is both the end of line " << AtomLines[Walker->nr][axis] << "." << endl;
    1570                                         }
    1571                                         if (InsertionPair.first != -1)          // insert if present
    1572                                                 LinetoAtomTest = LinetoAtom.insert( InsertionPair );
    1573                                         if (!LinetoAtomTest.second) {
    1574                                                 // atom is already present in list, hence we have found a possible triangle
    1575                                                 if ((Walker->nr < LinetoAtomTest.first->first) && (LinetoAtomTest.first->first < InsertionPair.first)) {        // check if numbering is in correct order for uniqueness, if so add
    1576                                                         TriangleList[TriangleCount].x1 = Walker;
    1577                                                         TriangleList[TriangleCount].x2 = LinetoAtomTest.first->second;
    1578                                                         TriangleList[TriangleCount].x3 = InsertionPair.second;
    1579                                                         TriangleCount++;
    1580                                                 }
    1581                                         }       //else {   // check if insertion was successful
    1582           // successfully inserted, hence nothing found yet
    1583         //}
    1584                                 }
    1585                         }
    1586                 }
     1667    *out << Verbose(1) << "Examining line between " << (liner->first/AtomCount)+1 << " and " << (liner->first%AtomCount)+1 << "." << endl;
     1668    int enden[3][2];
     1669    enden[0][0] = (liner->first/AtomCount);
     1670    enden[0][1] = (liner->first%AtomCount);
     1671    if (enden[0][0] < enden[0][1]) {
     1672                for (int endpoint=0;endpoint<2;endpoint++) {
     1673                        endpoints[0] = enden[0][endpoint];
     1674                        *out << Verbose(2) << "Current first endpoint is " << endpoints[0]+1 << "." << endl;
     1675                       
     1676                        LinesMap::iterator LineRangeStart = AllTriangleLines.lower_bound(endpoints[0]*AtomCount);
     1677                        for (LinesMap::iterator coach = LineRangeStart; (coach->first/AtomCount) == endpoints[0]; coach++) { // look at all line's other endpoint
     1678                    enden[1][0] = (coach->first/AtomCount);
     1679                    enden[1][1] = (coach->first%AtomCount);
     1680          //*out << Verbose(3) << "Line is " << coach->first << " with nr. " << coach->second << ": " << enden[1][0+1] << "<->" << enden[1][1]+1 << "." << endl;
     1681                          endpoints[1] = (enden[1][0] != endpoints[0] ) ? enden[1][0] : enden[1][1];
     1682                          if ((endpoints[1] > endpoints[0]) && (endpoints[1] != enden[0][(endpoint+1)%2])) {  // don't go back the very same line!
     1683                          *out << Verbose(3) << "Current second endpoint is " << endpoints[1]+1 << "." << endl; 
     1684                         
     1685              LinesMap::iterator LineRangeStart2 = AllTriangleLines.lower_bound(endpoints[1]*AtomCount);
     1686              for (LinesMap::iterator coacher = LineRangeStart2; (coacher->first/AtomCount) == endpoints[1]; coacher++) { // look at all line's other endpoint
     1687                enden[2][0] = (coacher->first/AtomCount);
     1688                enden[2][1] = (coacher->first%AtomCount);
     1689              //*out << Verbose(3) << "Line is " << coacher->first << " with nr. " << coacher->second << ": " << enden[2][0]+1 << "<->" << enden[2][1]+1 << "." << endl;
     1690                endpoints[2] = (enden[2][0] != endpoints[1]) ? enden[2][0] : enden[2][1];
     1691                if ((endpoints[2] > endpoints[1]) && (endpoints[2] != endpoints[0])) {  // don't go back the very same line!
     1692                *out << Verbose(4) << "Current third endpoint is " << endpoints[2]+1 << "." << endl;
     1693               
     1694                if (endpoints[2] == enden[0][(endpoint+1)%2]) { // jo, closing triangle
     1695                  *out << Verbose(3) << "MATCH: Triangle is ";
     1696                  for (int k=0;k<3;k++) {
     1697                    *out << endpoints[k]+1 << "\t";
     1698                    TriangleList[TriangleCount].x[k] = FindAtom(endpoints[k]);
     1699                  }
     1700                  *out << endl;
     1701                  TriangleList[TriangleCount].nr = TriangleCount;
     1702                  TriangleCount++;
     1703                } else {
     1704                  *out << Verbose(3) << "No match!" << endl;
     1705                }
     1706              }
     1707              }
     1708                        }
     1709                        }
     1710                }
     1711    }
    15871712        }
     1713  // listing created lines
     1714  *out << Verbose(2) << "The following triangles were created:";
     1715  for (int i=0;i<TriangleCount;i++) {
     1716    *out << " " << TriangleList[i].x[0]->Name << "<->" << TriangleList[i].x[1]->Name << "<->" << TriangleList[i].x[2]->Name;
     1717  }
     1718  *out << endl;
    15881719        *out << Verbose(2) << "I created " << TriangleCount << " triangles." << endl;
    15891720
    15901721        // 6. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
     1722  *out << Verbose(1) << "Calculating the volume of the pyramids formed out of triangles and center of gravity." << endl;
    15911723        double volume = 0.;
    15921724        double PyramidVolume = 0.;
     
    15951727        double a,b,c;
    15961728        for (int i=0; i<TriangleCount; i++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
    1597                 x.CopyVector(&TriangleList[TriangleCount].x1->x);
    1598                 x.SubtractVector(&TriangleList[TriangleCount].x2->x);
    1599                 y.CopyVector(&TriangleList[TriangleCount].x1->x);
    1600                 y.SubtractVector(&TriangleList[TriangleCount].x3->x);
    1601                 a = sqrt(TriangleList[TriangleCount].x1->x.Distance(&TriangleList[TriangleCount].x2->x));
    1602                 b = sqrt(TriangleList[TriangleCount].x1->x.Distance(&TriangleList[TriangleCount].x3->x));
    1603                 c = sqrt(TriangleList[TriangleCount].x3->x.Distance(&TriangleList[TriangleCount].x2->x));
    1604                 G =  c * (sin(x.Angle(&y))*a); // area of tesselated triangle
    1605                 x.MakeNormalVector(&TriangleList[TriangleCount].x1->x, &TriangleList[TriangleCount].x2->x, &TriangleList[TriangleCount].x3->x);
    1606                 y.CopyVector(&x);
    1607                 x.Scale(CenterOfGravity->Projection(&x));
     1729                x.CopyVector(&TriangleList[i].x[0]->x);
     1730                x.SubtractVector(&TriangleList[i].x[1]->x);
     1731                y.CopyVector(&TriangleList[i].x[0]->x);
     1732                y.SubtractVector(&TriangleList[i].x[2]->x);
     1733                a = sqrt(TriangleList[i].x[0]->x.Distance(&TriangleList[i].x[1]->x));
     1734                b = sqrt(TriangleList[i].x[0]->x.Distance(&TriangleList[i].x[2]->x));
     1735                c = sqrt(TriangleList[i].x[2]->x.Distance(&TriangleList[i].x[1]->x));
     1736                G =  sqrt( ( (a*a+b*b+c*c)*(a*a+b*b+c*c) - 2*(a*a*a*a + b*b*b*b + c*c*c*c) )/16.); // area of tesselated triangle
     1737                x.MakeNormalVector(&TriangleList[i].x[0]->x, &TriangleList[i].x[1]->x, &TriangleList[i].x[2]->x);
     1738                x.Scale(TriangleList[i].x[1]->x.Projection(&x));
    16081739                h = x.Norm(); // distance of CoG to triangle
    16091740                PyramidVolume = (1./3.) * G * h;                // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
     1741                *out << Verbose(2) << "Area of triangle is " << G << "A^2, height is " << h << " and the volume is " << PyramidVolume << "." << endl;
    16101742                volume += PyramidVolume;
    16111743        }
    16121744        *out << Verbose(1) << "The summed volume is " << volume << " " << (IsAngstroem ? "A^3" : "a_0^3") << "." << endl;
    16131745
    1614         // free reference lists
     1746  // 7. translate all points back from CoG
     1747  *out << Verbose(1) << "Translating system back from Center of Gravity." << endl;
     1748        CenterOfGravity->Scale(-1);
     1749  Walker=start;
     1750  while (Walker->next != end) {
     1751    Walker = Walker->next;
     1752    Walker->x.Translate(CenterOfGravity);
     1753  }
     1754
     1755  // free reference lists
    16151756        delete[](AtomList);
    1616   for(int i=0;i<AtomCount;i++)
    1617     delete[](AtomLines[i]);
    1618   delete[](AtomLines);
    16191757
    16201758        return volume;
  • src/molecules.hpp

    r233e33 r49de64  
    4040#define KeySet set<int>
    4141#define NumberValuePair pair<int, double>
    42 #define Graph map<KeySet, NumberValuePair, KeyCompare >
    43 #define GraphPair pair<KeySet, NumberValuePair >
     42#define Graph map <KeySet, NumberValuePair, KeyCompare >
     43#define GraphPair pair <KeySet, NumberValuePair >
    4444#define KeySetTestPair pair<KeySet::iterator, bool>
    4545#define GraphTestPair pair<Graph::iterator, bool>
    4646
    47 #define DistanceNrPair pair< double, atom* >
     47#define DistanceNrPair pair < double, atom* >
     48#define DistanceMap multimap < double, atom* >
     49#define DistanceTestPair pair < DistanceMap::iterator, bool>
     50
    4851#define Boundaries map <double, DistanceNrPair >
    4952#define BoundariesPair pair<double, DistanceNrPair >
    50 #define BoundariesTestPair pair<Boundaries::iterator, bool>
     53#define BoundariesTestPair pair< Boundaries::iterator, bool>
     54
     55#define LinesMap map <int, int>
     56#define LinesPair pair <int, int>
     57#define LinesTestPair pair < LinesMap::iterator, bool>
     58
    5159#define LinetoAtomMap map < int, atom * >
    5260#define LinetoAtomPair pair < int, atom * >
     
    404412    char *configpath;
    405413    char *configname;
     414    bool FastParsing;
    406415   
    407416    private:
Note: See TracChangeset for help on using the changeset viewer.