- Timestamp:
- Jun 10, 2008, 11:21:32 AM (17 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, 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
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
r233e33 r49de64 1381 1381 1382 1382 // 1. calculate center of gravity 1383 *out << endl; 1383 1384 vector *CenterOfGravity = DetermineCenterOfGravity(out); 1384 1385 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 } 1385 1393 // 2. calculate distance of each atom and sort into hash table 1386 1394 // map<double, int> DistanceSet; … … 1393 1401 1394 1402 // 3. Find all points on the boundary 1403 *out << Verbose(1) << "Finding all boundary points." << endl; 1395 1404 Boundaries BoundaryPoints[NDIM]; // first is alpha, second is (r, nr) 1396 1405 BoundariesTestPair BoundaryTestPair; 1397 vector AxisVector; 1406 vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector; 1407 double radius, angle; 1398 1408 // 3a. Go through every axis 1399 1409 for (int axis=0; axis<NDIM; axis++) { 1400 1410 AxisVector.Zero(); 1411 AngleReferenceVector.Zero(); 1412 AngleReferenceNormalVector.Zero(); 1401 1413 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; 1402 1424 // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours 1403 1425 Walker = start; … … 1406 1428 vector ProjectedVector; 1407 1429 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) ) ); 1411 1448 if (BoundaryTestPair.second) { // successfully inserted 1412 } else { // same point exists, check first r, then distance of original vectors to center sof gravity1449 } else { // same point exists, check first r, then distance of original vectors to center of gravity 1413 1450 *out << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl; 1414 1451 *out << Verbose(2) << "Present vector: "; … … 1424 1461 *out << Verbose(2) << "Keeping new vector." << endl; 1425 1462 } 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 1427 1464 BoundaryTestPair.first->second.second = Walker; 1428 1465 *out << Verbose(2) << "Keeping new vector." << endl; … … 1435 1472 } 1436 1473 } 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 1438 1488 bool flag = false; 1439 1489 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; 1440 1491 flag = false; 1441 1492 Boundaries::iterator left = BoundaryPoints[axis].end(); … … 1455 1506 } 1456 1507 // 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 } 1461 1556 } 1462 1557 } … … 1472 1567 } 1473 1568 } 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 1483 1570 // 3e. Points no more in the total list, have to be thrown out of each axis lists too! 1484 1571 for (int axis=0; axis<NDIM; axis++) { 1485 1572 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; 1487 1575 BoundaryPoints[axis].erase(runner); 1576 } 1488 1577 } 1489 1578 } 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; 1490 1592 1491 1593 *out << Verbose(2) << "I found " << BoundaryPointCount << " points on the convex boundary." << endl; … … 1493 1595 1494 1596 // 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; 1513 1598 1514 1599 // then create each line 1600 *out << Verbose(1) << "Creating lines between adjacent boundary points." << endl; 1601 atom *Runner = NULL; 1515 1602 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; 1544 1652 *out << Verbose(2) << "I created " << LineCount << " edges." << endl; 1545 1653 1546 1654 // 5. Create every possible triangle from the lines (numbering of each line must be i < j < k) 1547 1655 struct triangles { 1548 atom *x1; 1549 atom *x2; 1550 atom *x3; 1656 atom *x[3]; 1551 1657 int nr; 1552 1658 } 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; 1553 1661 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 1555 1665 LinetoAtomMap LinetoAtom; 1556 1666 // 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 } 1587 1712 } 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; 1588 1719 *out << Verbose(2) << "I created " << TriangleCount << " triangles." << endl; 1589 1720 1590 1721 // 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; 1591 1723 double volume = 0.; 1592 1724 double PyramidVolume = 0.; … … 1595 1727 double a,b,c; 1596 1728 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)); 1608 1739 h = x.Norm(); // distance of CoG to triangle 1609 1740 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; 1610 1742 volume += PyramidVolume; 1611 1743 } 1612 1744 *out << Verbose(1) << "The summed volume is " << volume << " " << (IsAngstroem ? "A^3" : "a_0^3") << "." << endl; 1613 1745 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 1615 1756 delete[](AtomList); 1616 for(int i=0;i<AtomCount;i++)1617 delete[](AtomLines[i]);1618 delete[](AtomLines);1619 1757 1620 1758 return volume; -
src/molecules.hpp
r233e33 r49de64 40 40 #define KeySet set<int> 41 41 #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 > 44 44 #define KeySetTestPair pair<KeySet::iterator, bool> 45 45 #define GraphTestPair pair<Graph::iterator, bool> 46 46 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 48 51 #define Boundaries map <double, DistanceNrPair > 49 52 #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 51 59 #define LinetoAtomMap map < int, atom * > 52 60 #define LinetoAtomPair pair < int, atom * > … … 404 412 char *configpath; 405 413 char *configname; 414 bool FastParsing; 406 415 407 416 private:
Note:
See TracChangeset
for help on using the changeset viewer.