Changeset b3c052 for src/Fragmentation/Exporters
- Timestamp:
- Sep 12, 2016, 2:03:15 PM (9 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:
- 158ecb
- Parents:
- 8e4471
- git-author:
- Frederik Heber <heber@…> (06/05/14 17:42:39)
- git-committer:
- Frederik Heber <heber@…> (09/12/16 14:03:15)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r8e4471 rb3c052 139 139 140 140 SphericalPointDistribution::Polygon_t removeMatchingPoints( 141 const SphericalPointDistribution::Polygon_t &_returnpolygon,141 const VectorArray_t &_points, 142 142 const IndexList_t &_matchingindices 143 143 ) … … 147 147 std::sort(indices.begin(), indices.end()); 148 148 LOG(4, "DEBUG: sorted matching is " << indices); 149 IndexArray_t::const_iterator valueiter = indices.begin(); 150 SphericalPointDistribution::Polygon_t::const_iterator pointiter = 151 _returnpolygon.begin(); 152 for (unsigned int i=0; i< _returnpolygon.size(); ++i, ++pointiter) { 153 // skip all those in values 154 if (*valueiter == i) 155 ++valueiter; 156 else 157 remainingreturnpolygon.push_back(*pointiter); 149 IndexArray_t remainingindices(_points.size(), -1); 150 std::generate(remainingindices.begin(), remainingindices.end(), UniqueNumber); 151 IndexArray_t::iterator remainiter = std::set_difference( 152 remainingindices.begin(), remainingindices.end(), 153 indices.begin(), indices.end(), 154 remainingindices.begin()); 155 remainingindices.erase(remainiter, remainingindices.end()); 156 LOG(4, "DEBUG: remaining indices are " << remainingindices); 157 for (IndexArray_t::const_iterator iter = remainingindices.begin(); 158 iter != remainingindices.end(); ++iter) { 159 remainingreturnpolygon.push_back(_points[*iter]); 158 160 } 159 LOG(4, "DEBUG: remaining indices are " << remainingreturnpolygon);160 161 161 162 return remainingreturnpolygon; … … 292 293 // determine rotation angles to align the two point distributions with 293 294 // respect to bestmatching 294 SphericalPointDistribution::Polygon_t rotated_newpolygon;295 VectorArray_t rotated_newpolygon = remainingnew; 295 296 Vector oldCenter; 296 297 { … … 309 310 if ((oldCenter - newCenter).NormSquared() > std::numeric_limits<double>::epsilon()*1e4) { 310 311 // setup quaternion 311 Vector RotationAxis = newCenter; 312 RotationAxis.VectorProduct(oldCenter); 312 Vector RotationAxis = oldCenter; 313 RotationAxis.VectorProduct(newCenter); 314 Line Axis(zeroVec, RotationAxis); 313 315 RotationAxis.Normalize(); 314 const double RotationAngle = oldCenter.Angle(newCenter)/(M_PI/2.); 315 // RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter); 316 boost::math::quaternion<double> q 317 (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]); 318 LOG(5, "DEBUG: RotationAxis is " << RotationAxis 319 << ", RotationAngle is " << RotationAngle); 320 LOG(5, "DEBUG: Quaternion describing rotation is " << q); 316 const double RotationAngle = oldCenter.Angle(newCenter); // /(M_PI/2.); 317 LOG(5, "DEBUG: Rotate coordinate system by " << RotationAngle 318 << " around axis " << RotationAxis); 319 320 // apply rotation angles 321 for (VectorArray_t::iterator iter = rotated_newpolygon.begin(); 322 iter != rotated_newpolygon.end(); ++iter) { 323 Vector ¤t = *iter; 324 LOG(5, "DEBUG: Original point is " << current); 325 current = Axis.rotateVector(current, RotationAngle); 326 LOG(5, "DEBUG: Rotated point is " << current); 327 } 328 } 329 } 330 // rotate triangle/line/point around itself to match orientation 331 if (MCS.bestmatching.size() > 1) { 332 if (oldCenter.NormSquared() > std::numeric_limits<double>::epsilon()*1e4) { 333 // construct RotationAxis and two points on its plane, defining the angle 334 const Line RotationAxis(zeroVec, oldCenter); 335 Vector oldPosition(rotated_newpolygon[*MCS.bestmatching.begin()]); 336 oldPosition.ProjectOntoPlane(RotationAxis.getDirection()); 337 Vector newPosition(remainingold[*MCS.bestmatching.begin()]); 338 newPosition.ProjectOntoPlane(RotationAxis.getDirection()); 339 340 // construct reference vector to determine direction of rotation 341 Vector dreiBein(oldPosition); 342 dreiBein.VectorProduct(oldCenter); 343 dreiBein.Normalize(); 344 const double sign = 345 (dreiBein.ScalarProduct(newPosition) < 0.) ? -1. : +1.; 346 LOG(6, "DEBUG: oldCenter on plane is " << oldPosition 347 << ", newCenter in plane is " << newPosition 348 << ", and dreiBein is " << dreiBein); 349 const double RotationAngle = sign * oldPosition.Angle(newPosition); 350 LOG(5, "DEBUG: Rotating around self is " << RotationAngle 351 << " around axis " << RotationAxis); 352 321 353 #ifndef NDEBUG 354 // check: first bestmatching in rotated_newpolygon and remainingnew 355 // should now equal 322 356 { 323 // check that rotation works in DEBUG mode 324 boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]); 325 boost::math::quaternion<double> q_inverse = 326 boost::math::conj(q)/(boost::math::norm(q)); 327 p = q * p * q_inverse; 328 boost::math::quaternion<double> identity(1,0,0,0); 329 ASSERT( boost::math::norm(q*q_inverse - identity) < std::numeric_limits<double>::epsilon()*1e4, 330 "matchSphericalPointDistributions() - quaternion does not rotate newCenter " 331 +toString(q*q_inverse)+" into oldCenter "+toString(identity)+"."); 332 boost::math::quaternion<double> comparison(0., -oldCenter[0], oldCenter[1], oldCenter[2]); 333 ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4, 334 "matchSphericalPointDistributions() - quaternion does not rotate newCenter " 335 +toString(p)+" into oldCenter "+toString(comparison)+"."); 357 const IndexList_t::const_iterator iter = MCS.bestmatching.begin(); 358 Vector rotatednew = RotationAxis.rotateVector( 359 rotated_newpolygon[*iter], 360 RotationAngle); 361 LOG(4, "CHECK: rotated first new bestmatching is " << rotatednew 362 << " while old was " << remainingold[*iter]); 363 ASSERT( (rotatednew - remainingold[*iter]).Norm() 364 < std::numeric_limits<double>::epsilon()*1e4, 365 "matchSphericalPointDistributions() - orientation rotation does not work as expected."); 336 366 } 337 367 #endif 338 368 339 // rotate spherical distribution 340 rotated_newpolygon = rotatePolygon(_newpolygon, q); 341 LOG(5, "DEBUG: Rotated new polygon is " << rotated_newpolygon); 342 } else { 343 rotated_newpolygon = _newpolygon; 344 } 345 } 346 // rotate triangle/line/point around itself to match orientation 347 const Line RotationAxis(zeroVec, oldCenter); 348 const double RotationAngle = 349 oldCenter.Angle(remainingold[0]) 350 - oldCenter.Angle(remainingnew[*MCS.bestmatching.begin()]); 351 LOG(5, "DEBUG: Rotate around self is " << RotationAngle 352 << " around axis " << RotationAxis); 353 354 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_newpolygon.begin(); 355 iter != rotated_newpolygon.end(); ++iter) { 356 RotationAxis.rotateVector(*iter, RotationAngle); 369 for (VectorArray_t::iterator iter = rotated_newpolygon.begin(); 370 iter != rotated_newpolygon.end(); ++iter) { 371 Vector ¤t = *iter; 372 LOG(6, "DEBUG: Original point is " << current); 373 current = RotationAxis.rotateVector(current, RotationAngle); 374 LOG(6, "DEBUG: Rotated point is " << current); 375 } 376 } 357 377 } 358 378 -
src/Fragmentation/Exporters/unittests/Makefile.am
r8e4471 rb3c052 21 21 22 22 TESTS += $(FRAGMENTATIONEXPORTERSTESTS) 23 XFAIL_TESTS += SphericalPointDistributionUnitTest24 23 check_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS) 25 24 noinst_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS) -
src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp
r8e4471 rb3c052 82 82 } 83 83 84 void SphericalPointDistributionTest::QuaternionTest()85 {86 Vector oldCenter(0.,1.,0.);87 Vector newCenter(1.,0.,0.);88 89 {90 // setup quaternion91 Vector RotationAxis = newCenter;92 RotationAxis.VectorProduct(oldCenter);93 RotationAxis.Normalize();94 const double RotationAngle = oldCenter.Angle(newCenter)/(M_PI/2.);95 // RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter);96 boost::math::quaternion<double> q97 (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]);98 LOG(5, "DEBUG: RotationAxis is " << RotationAxis99 << ", RotationAngle is " << RotationAngle);100 LOG(5, "DEBUG: Quaternion describing rotation is " << q);101 boost::math::quaternion<double> q_inverse =102 boost::math::conj(q)/(boost::math::norm(q));103 LOG(5, "DEBUG: Quaternion inverse is " << q_inverse);104 boost::math::quaternion<double> identity(1,0,0,0);105 const boost::math::quaternion<double> unity = q*q_inverse;106 LOG(5, "DEBUG: q * q^-1 is " << unity);107 CPPUNIT_ASSERT( boost::math::norm(unity - identity) < std::numeric_limits<double>::epsilon()*1e4);108 109 // check that rotation works110 boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]);111 LOG(5, "DEBUG: Original newCenter is " << p);112 p = p * q_inverse;113 p = q * p;114 LOG(5, "DEBUG: Rotated newCenter is " << p);115 boost::math::quaternion<double> comparison(0., -oldCenter[0], oldCenter[1], oldCenter[2]);116 LOG(5, "DEBUG: Difference norm is " << boost::math::norm(p - comparison));117 CPPUNIT_ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4);118 }119 120 // rotating with angle = 0 flips the vector unwantedly121 {122 // setup quaternion123 Vector RotationAxis = newCenter;124 RotationAxis.VectorProduct(oldCenter);125 RotationAxis.Normalize();126 const double RotationAngle = 0.;127 // RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter);128 boost::math::quaternion<double> q129 (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]);130 LOG(5, "DEBUG: RotationAxis is " << RotationAxis131 << ", RotationAngle is " << RotationAngle);132 LOG(5, "DEBUG: Quaternion describing rotation is " << q);133 boost::math::quaternion<double> q_inverse =134 boost::math::conj(q)/(boost::math::norm(q));135 LOG(5, "DEBUG: Quaternion inverse is " << q_inverse);136 boost::math::quaternion<double> identity(1,0,0,0);137 const boost::math::quaternion<double> unity = q*q_inverse;138 LOG(5, "DEBUG: q * q^-1 is " << unity);139 CPPUNIT_ASSERT( boost::math::norm(unity - identity) < std::numeric_limits<double>::epsilon()*1e4);140 141 // check that rotation works142 boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]);143 boost::math::quaternion<double> comparison(0., -newCenter[0], newCenter[1], newCenter[2]);144 LOG(5, "DEBUG: Original newCenter is " << p);145 p = p * q_inverse;146 p = q * p;147 LOG(5, "DEBUG: Rotated newCenter is " << p);148 LOG(5, "DEBUG: Difference norm is " << boost::math::norm(p - comparison));149 CPPUNIT_ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4);150 }151 }152 84 153 85 /** UnitTest for matchSphericalPointDistributions() with two points -
src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.hpp
r8e4471 rb3c052 22 22 { 23 23 CPPUNIT_TEST_SUITE( SphericalPointDistributionTest) ; 24 CPPUNIT_TEST ( QuaternionTest );25 24 CPPUNIT_TEST ( matchSphericalPointDistributionsTest_2 ); 26 25 CPPUNIT_TEST ( matchSphericalPointDistributionsTest_3 ); … … 35 34 void setUp(); 36 35 void tearDown(); 37 void QuaternionTest();38 36 void matchSphericalPointDistributionsTest_2(); 39 37 void matchSphericalPointDistributionsTest_3();
Note:
See TracChangeset
for help on using the changeset viewer.