Changeset 0983e6
- Timestamp:
- Sep 12, 2016, 11:48:36 PM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, 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_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes, stable
- Children:
- 3678eb
- Parents:
- 653cea
- git-author:
- Frederik Heber <heber@…> (07/09/14 21:14:53)
- git-committer:
- Frederik Heber <heber@…> (09/12/16 23:48:36)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r653cea r0983e6 99 99 } 100 100 101 /** Calculate the center of a given set of points in \a _positions but only 102 * for those indicated by \a _indices. 103 * 104 */ 105 inline 106 Vector calculateCenter( 107 const SphericalPointDistribution::PolygonWithIndices &_polygon) 108 { 109 return calculateCenter(_polygon.polygon, _polygon.indices); 110 } 111 101 112 inline 102 113 DistanceArray_t calculatePairwiseDistances( … … 177 188 Vector &_oldCenter, 178 189 Vector &_newCenter, 179 const SphericalPointDistribution::VectorArray_t &_referencepositions, 180 const SphericalPointDistribution::VectorArray_t &_currentpositions, 181 const SphericalPointDistribution::IndexList_t &_bestmatching) 182 { 183 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 184 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 185 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 186 _oldCenter = calculateCenter(_referencepositions, continuousIds); 190 const SphericalPointDistribution::PolygonWithIndices &_referencepositions, 191 const SphericalPointDistribution::PolygonWithIndices &_currentpositions) 192 { 193 _oldCenter = calculateCenter(_referencepositions.polygon, _referencepositions.indices); 187 194 // C++11 defines a copy_n function ... 188 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 189 std::advance(enditer, NumberIds); 190 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 191 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 192 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 195 _newCenter = calculateCenter( _currentpositions.polygon, _currentpositions.indices); 193 196 } 194 197 /** Returns squared L2 error of the given \a _Matching. … … 251 254 252 255 SphericalPointDistribution::Polygon_t SphericalPointDistribution::removeMatchingPoints( 253 const VectorArray_t &_points, 254 const IndexList_t &_matchingindices 256 const PolygonWithIndices &_points 255 257 ) 256 258 { 257 SphericalPointDistribution::Polygon_t remaining returnpolygon;258 IndexArray_t indices(_ matchingindices.begin(), _matchingindices.end());259 SphericalPointDistribution::Polygon_t remainingpoints; 260 IndexArray_t indices(_points.indices.begin(), _points.indices.end()); 259 261 std::sort(indices.begin(), indices.end()); 260 262 LOG(4, "DEBUG: sorted matching is " << indices); 261 IndexArray_t remainingindices(_points. size(), -1);263 IndexArray_t remainingindices(_points.polygon.size(), -1); 262 264 std::generate(remainingindices.begin(), remainingindices.end(), UniqueNumber); 263 265 IndexArray_t::iterator remainiter = std::set_difference( … … 269 271 for (IndexArray_t::const_iterator iter = remainingindices.begin(); 270 272 iter != remainingindices.end(); ++iter) { 271 remaining returnpolygon.push_back(_points[*iter]);272 } 273 274 return remaining returnpolygon;273 remainingpoints.push_back(_points.polygon[*iter]); 274 } 275 276 return remainingpoints; 275 277 } 276 278 … … 501 503 502 504 SphericalPointDistribution::Rotation_t SphericalPointDistribution::findPlaneAligningRotation( 503 const VectorArray_t &_referencepositions, 504 const VectorArray_t &_currentpositions, 505 const IndexList_t &_bestmatching 505 const PolygonWithIndices &_referencepositions, 506 const PolygonWithIndices &_currentpositions 506 507 ) 507 508 { … … 520 521 calculateOldAndNewCenters( 521 522 oldCenter, newCenter, 522 _referencepositions, _currentpositions , _bestmatching);523 _referencepositions, _currentpositions); 523 524 524 525 if ((!oldCenter.IsZero()) && (!newCenter.IsZero())) { … … 538 539 if ((oldCenter.IsZero()) && (newCenter.IsZero())) { 539 540 // either oldCenter or newCenter (or both) is directly at origin 540 if (_ bestmatching.size() == 2) {541 if (_currentpositions.indices.size() == 2) { 541 542 // line case 542 Vector oldPosition = _currentpositions [*_bestmatching.begin()];543 Vector newPosition = _referencepositions [0];543 Vector oldPosition = _currentpositions.polygon[*_currentpositions.indices.begin()]; 544 Vector newPosition = _referencepositions.polygon[0]; 544 545 // check whether we need to rotate at all 545 546 if (!oldPosition.IsEqualTo(newPosition)) { … … 555 556 // both triangles/planes have same center, hence get axis by 556 557 // VectorProduct of Normals 557 Plane newplane(_referencepositions [0], _referencepositions[1], _referencepositions[2]);558 Plane newplane(_referencepositions.polygon[0], _referencepositions.polygon[1], _referencepositions.polygon[2]); 558 559 VectorArray_t vectors; 559 for (IndexList_t::const_iterator iter = _ bestmatching.begin();560 iter != _ bestmatching.end(); ++iter)561 vectors.push_back(_currentpositions [*iter]);560 for (IndexList_t::const_iterator iter = _currentpositions.indices.begin(); 561 iter != _currentpositions.indices.end(); ++iter) 562 vectors.push_back(_currentpositions.polygon[*iter]); 562 563 Plane oldplane(vectors[0], vectors[1], vectors[2]); 563 564 Vector oldPosition = oldplane.getNormal(); … … 607 608 608 609 SphericalPointDistribution::Rotation_t SphericalPointDistribution::findPointAligningRotation( 609 const VectorArray_t &remainingold, 610 const VectorArray_t &remainingnew, 611 const IndexList_t &_bestmatching) 610 const PolygonWithIndices &remainingold, 611 const PolygonWithIndices &remainingnew) 612 612 { 613 613 // initialize rotation to zero … … 622 622 calculateOldAndNewCenters( 623 623 oldCenter, newCenter, 624 remainingold, remainingnew, _bestmatching); 625 626 Vector oldPosition = remainingnew[*_bestmatching.begin()]; 627 Vector newPosition = remainingold[0]; 628 LOG(6, "DEBUG: oldPosition is " << oldPosition << " and newPosition is " << newPosition); 624 remainingold, remainingnew); 625 626 Vector oldPosition = remainingnew.polygon[*remainingnew.indices.begin()]; 627 Vector newPosition = remainingold.polygon[0]; 628 LOG(6, "DEBUG: oldPosition is " << oldPosition << " (length: " 629 << oldPosition.Norm() << ") and newPosition is " << newPosition << " length(: " 630 << newPosition.Norm() << ")"); 629 631 if (!oldPosition.IsEqualTo(newPosition)) { 630 632 if ((!oldCenter.IsZero()) && (!newCenter.IsZero())) { 631 oldCenter.Normalize(); // note weighted sum of normalized weight is not normalized 633 // we rotate at oldCenter and around the radial direction, which is again given 634 // by oldCenter. 632 635 Rotation.first = oldCenter; 633 LOG(6, "DEBUG: Picking normalized oldCenter as Rotation.first " << oldCenter); 634 oldPosition.ProjectOntoPlane(Rotation.first); 635 newPosition.ProjectOntoPlane(Rotation.first); 636 Rotation.first.Normalize(); // note weighted sum of normalized weight is not normalized 637 LOG(6, "DEBUG: Using oldCenter " << oldCenter << " as rotation center and " 638 << Rotation.first << " as axis."); 639 oldPosition -= oldCenter; 640 newPosition -= oldCenter; 641 oldPosition = (oldPosition - oldPosition.Projection(Rotation.first)); 642 newPosition = (newPosition - newPosition.Projection(Rotation.first)); 636 643 LOG(6, "DEBUG: Positions after projection are " << oldPosition << " and " << newPosition); 637 644 } else { 638 if ( _bestmatching.size() == 2) {645 if (remainingnew.indices.size() == 2) { 639 646 // line situation 640 647 try { … … 657 664 } else { 658 665 // triangle situation 659 Plane oldplane(remainingold [0], remainingold[1], remainingold[2]);666 Plane oldplane(remainingold.polygon[0], remainingold.polygon[1], remainingold.polygon[2]); 660 667 Rotation.first = oldplane.getNormal(); 661 668 LOG(6, "DEBUG: oldPlane is " << oldplane << " and normal is " << Rotation.first); … … 682 689 { 683 690 SphericalPointDistribution::Polygon_t remainingpoints; 684 VectorArray_t remainingold; 685 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 686 iter != _polygon.end(); ++iter) 687 remainingold.push_back(iter->first); 691 688 692 LOG(2, "INFO: Matching old polygon " << _polygon 689 693 << " with new polygon " << _newpolygon); … … 699 703 LOG(2, "INFO: Best matching is " << bestmatching); 700 704 701 // _newpolygon has changed, so now convert to array 702 VectorArray_t remainingnew(_newpolygon.begin(), _newpolygon.end()); 705 const size_t NumberIds = std::min(bestmatching.size(), (size_t)3); 706 // create old set 707 PolygonWithIndices oldSet; 708 oldSet.indices.resize(NumberIds, -1); 709 std::generate(oldSet.indices.begin(), oldSet.indices.end(), UniqueNumber); 710 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 711 iter != _polygon.end(); ++iter) 712 oldSet.polygon.push_back(iter->first); 713 714 // _newpolygon has changed, so now convert to array with matched indices 715 PolygonWithIndices newSet; 716 SphericalPointDistribution::IndexList_t::const_iterator beginiter = bestmatching.begin(); 717 SphericalPointDistribution::IndexList_t::const_iterator enditer = bestmatching.begin(); 718 std::advance(enditer, NumberIds); 719 newSet.indices.resize(NumberIds, -1); 720 std::copy(beginiter, enditer, newSet.indices.begin()); 721 std::copy(_newpolygon.begin(),_newpolygon.end(), std::back_inserter(newSet.polygon)); 703 722 704 723 // determine rotation angles to align the two point distributions with … … 706 725 // we use the center between the three first matching points 707 726 /// the first rotation brings these two centers to coincide 708 VectorArray_t rotated_newpolygon = remainingnew;727 PolygonWithIndices rotatednewSet = newSet; 709 728 { 710 Rotation_t Rotation = findPlaneAligningRotation( 711 remainingold, 712 remainingnew, 713 bestmatching); 729 Rotation_t Rotation = findPlaneAligningRotation(oldSet, newSet); 714 730 LOG(5, "DEBUG: Rotating coordinate system by " << Rotation.second 715 731 << " around axis " << Rotation.first); … … 717 733 718 734 // apply rotation angle to bring newCenter to oldCenter 719 for (VectorArray_t::iterator iter = rotated _newpolygon.begin();720 iter != rotated _newpolygon.end(); ++iter) {735 for (VectorArray_t::iterator iter = rotatednewSet.polygon.begin(); 736 iter != rotatednewSet.polygon.end(); ++iter) { 721 737 Vector ¤t = *iter; 722 738 LOG(6, "DEBUG: Original point is " << current); … … 732 748 calculateOldAndNewCenters( 733 749 oldCenter, rotatednewCenter, 734 remainingold, rotated_newpolygon, bestmatching);750 oldSet, rotatednewSet); 735 751 // NOTE: Center must not necessarily lie on the sphere with norm 1, hence, we 736 752 // have to normalize it just as before, as oldCenter and newCenter lengths may differ. … … 740 756 LOG(4, "CHECK: rotatednewCenter is " << rotatednewCenter 741 757 << ", oldCenter is " << oldCenter); 742 ASSERT( (rotatednewCenter - oldCenter).NormSquared() < std::numeric_limits<double>::epsilon()*1e4, 758 const double difference = (rotatednewCenter - oldCenter).NormSquared(); 759 ASSERT( difference < std::numeric_limits<double>::epsilon()*1e4, 743 760 "matchSphericalPointDistributions() - rotation does not work as expected by " 744 +toString( (rotatednewCenter - oldCenter).NormSquared())+".");761 +toString(difference)+"."); 745 762 } 746 763 } … … 750 767 /// points themselves coincide 751 768 if (bestmatching.size() > 1) { 752 Rotation_t Rotation = findPointAligningRotation( 753 remainingold, 754 rotated_newpolygon, 755 bestmatching); 769 Rotation_t Rotation = findPointAligningRotation(oldSet, rotatednewSet); 756 770 757 771 // construct RotationAxis and two points on its plane, defining the angle … … 767 781 { 768 782 const IndexList_t::const_iterator iter = bestmatching.begin(); 783 784 // check whether both old and newPosition are at same distance to oldCenter 785 Vector oldCenter = calculateCenter(oldSet); 786 const double distance = fabs( 787 (oldSet.polygon[0] - oldCenter).NormSquared() 788 - (rotatednewSet.polygon[*iter] - oldCenter).NormSquared() 789 ); 790 LOG(4, "CHECK: Squared distance between oldPosition and newPosition " 791 << " with respect to oldCenter " << oldCenter << " is " << distance); 792 // ASSERT( distance < warn_amplitude, 793 // "matchSphericalPointDistributions() - old and newPosition's squared distance to oldCenter differs by " 794 // +toString(distance)); 795 769 796 Vector rotatednew = RotationAxis.rotateVector( 770 rotated _newpolygon[*iter],797 rotatednewSet.polygon[*iter], 771 798 Rotation.second); 772 799 LOG(4, "CHECK: rotated first new bestmatching is " << rotatednew 773 << " while old was " << remainingold[0]); 774 ASSERT( (rotatednew - remainingold[0]).Norm() < warn_amplitude, 775 "matchSphericalPointDistributions() - orientation rotation ends up off by more than " 776 +toString(warn_amplitude)+"."); 800 << " while old was " << oldSet.polygon[0]); 801 const double difference = (rotatednew - oldSet.polygon[0]).NormSquared(); 802 ASSERT( difference < distance+1e-8, 803 "matchSphericalPointDistributions() - orientation rotation ends up off by " 804 +toString(difference)+", more than " 805 +toString(distance+1e-8)+"."); 777 806 } 778 807 #endif 779 808 780 for (VectorArray_t::iterator iter = rotated _newpolygon.begin();781 iter != rotated _newpolygon.end(); ++iter) {809 for (VectorArray_t::iterator iter = rotatednewSet.polygon.begin(); 810 iter != rotatednewSet.polygon.end(); ++iter) { 782 811 Vector ¤t = *iter; 783 812 LOG(6, "DEBUG: Original point is " << current); … … 789 818 // remove all points in matching and return remaining ones 790 819 SphericalPointDistribution::Polygon_t remainingpoints = 791 removeMatchingPoints(rotated _newpolygon, bestmatching);820 removeMatchingPoints(rotatednewSet); 792 821 LOG(2, "INFO: Remaining points are " << remainingpoints); 793 822 return remainingpoints; -
src/Fragmentation/Exporters/SphericalPointDistribution.hpp
r653cea r0983e6 105 105 static const double warn_amplitude; 106 106 107 struct PolygonWithIndices 108 { 109 //!> array with points 110 VectorArray_t polygon; 111 //!> list with indices for the above points, defining subset 112 IndexList_t indices; 113 }; 114 107 115 private: 108 116 //!> grant unit tests access to private parts … … 115 123 116 124 static Polygon_t removeMatchingPoints( 117 const VectorArray_t &_points, 118 const IndexList_t &_matchingindices 119 ); 125 const PolygonWithIndices &_points); 120 126 121 127 struct MatchingControlStructure { … … 149 155 150 156 static Rotation_t findPlaneAligningRotation( 151 const VectorArray_t &_referencepositions, 152 const VectorArray_t &_currentpositions, 153 const IndexList_t &_bestmatching 157 const PolygonWithIndices &_referencepositions, 158 const PolygonWithIndices &_currentpositions 154 159 ); 155 160 156 161 static Rotation_t findPointAligningRotation( 157 const VectorArray_t &remainingold, 158 const VectorArray_t &remainingnew, 159 const IndexList_t &_bestmatching); 162 const PolygonWithIndices &remainingold, 163 const PolygonWithIndices &remainingnew); 160 164 161 165 };
Note:
See TracChangeset
for help on using the changeset viewer.