Changeset 946948 for src/Fragmentation
- Timestamp:
- Sep 12, 2016, 2:03:15 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:
- 8d38e6
- Parents:
- 7e81ca
- git-author:
- Frederik Heber <heber@…> (06/02/14 14:51:33)
- git-committer:
- Frederik Heber <heber@…> (09/12/16 14:03:15)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r7e81ca r946948 44 44 #include <algorithm> 45 45 #include <cmath> 46 #include <functional> 47 #include <iterator> 46 48 #include <limits> 47 49 #include <list> … … 84 86 int current; 85 87 c_unique() {current=0;} 86 int operator()() {return ++current;}88 int operator()() {return current++;} 87 89 } UniqueNumber; 88 90 … … 128 130 } 129 131 } else 130 ELOG( 2, "calculateErrorOfMatching() - Given matching is empty.");132 ELOG(3, "calculateErrorOfMatching() - Given matching's size is less than 2."); 131 133 LOG(3, "INFO: Resulting errors for matching (L1, L2): " 132 134 << errors.first << "," << errors.second << "."); … … 159 161 } 160 162 161 /** Rotates a given polygon around x, y, and z axis by the given angles.162 *163 * Essentially, we concentrate on the three returnpolygon of the polygon to rotate164 * to the correct position. First, we rotate its center via \a angles,165 * then we rotate the "triangle" around itself/\a _RotationAxis by166 * \a _RotationAngle.167 *168 * \param _polygon polygon whose returnpolygon to rotate169 * \param _angles vector with rotation angles for x,y,z axis170 * \param _RotationAxis171 * \param _RotationAngle172 */173 SphericalPointDistribution::Polygon_t rotatePolygon(174 const SphericalPointDistribution::Polygon_t &_polygon,175 const std::vector<double> &_angles,176 const Line &_RotationAxis,177 const double _RotationAngle)178 {179 SphericalPointDistribution::Polygon_t rotated_polygon = _polygon;180 RealSpaceMatrix rotation;181 ASSERT( _angles.size() == 3,182 "rotatePolygon() - not exactly "+toString(3)+" angles given.");183 rotation.setRotation(_angles[0] * M_PI/180., _angles[1] * M_PI/180., _angles[2] * M_PI/180.);184 LOG(4, "DEBUG: Rotation matrix is " << rotation);185 186 // apply rotation angles187 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_polygon.begin();188 iter != rotated_polygon.end(); ++iter) {189 *iter = rotation * (*iter);190 _RotationAxis.rotateVector(*iter, _RotationAngle);191 }192 193 return rotated_polygon;194 }195 196 163 struct MatchingControlStructure { 197 164 bool foundflag; … … 217 184 LOG(4, "DEBUG: Recursing with current matching " << _matching 218 185 << ", remaining indices " << _indices 219 << ", and sought size " << _matching size);186 << ", and sought size " << _matching.size()+_matchingsize); 220 187 //!> threshold for L1 error below which matching is immediately acceptable 221 188 const double L1THRESHOLD = 1e-2; 222 189 if (!_MCS.foundflag) { 223 LOG( 3, "INFO: Current matching has size " << _matching.size() << " of" << _matchingsize);224 if (_matching .size() < _matchingsize) {190 LOG(4, "DEBUG: Current matching has size " << _matching.size() << ", places left " << _matchingsize); 191 if (_matchingsize > 0) { 225 192 // go through all indices 226 193 for (IndexList_t::iterator iter = _indices.begin(); 227 iter != _indices.end();) {194 (iter != _indices.end()) && (!_MCS.foundflag);) { 228 195 // add index to matching 229 196 _matching.push_back(*iter); 230 LOG( 4, "DEBUG: Adding " << *iter << " to matching.");197 LOG(5, "DEBUG: Adding " << *iter << " to matching."); 231 198 // remove index but keep iterator to position (is the next to erase element) 232 199 IndexList_t::iterator backupiter = _indices.erase(iter); … … 240 207 } 241 208 // gone through all indices then exit recursion 242 _MCS.foundflag = true; 209 if (_matching.empty()) 210 _MCS.foundflag = true; 243 211 } else { 244 212 LOG(3, "INFO: Found matching " << _matching); … … 249 217 _MCS.bestmatching = _matching; 250 218 _MCS.foundflag = true; 251 } 252 if (_MCS.bestL2 > errors.second) { 219 } else if (_MCS.bestL2 > errors.second) { 253 220 _MCS.bestmatching = _matching; 254 221 _MCS.bestL2 = errors.second; … … 257 224 } 258 225 } 226 227 /** Convert cartesian to polar coordinates. 228 * 229 * \param _cartesian vector in cartesian coordinates 230 * \return vector containing \f$ (r,\theta, \varphi \f$ tuple for polar coordinates 231 */ 232 std::vector<double> getPolarCoordinates(const Vector &_cartesian) 233 { 234 std::vector<double> polar(3,0.); 235 const double xsqr = _cartesian[0] * _cartesian[0]; 236 const double ysqr = _cartesian[1] * _cartesian[1]; 237 polar[0] = sqrt(xsqr + ysqr + _cartesian[2]*_cartesian[2]); 238 if (fabs(_cartesian[2]) < std::numeric_limits<double>::epsilon()*1e4) { 239 if (fabs(xsqr + ysqr) < std::numeric_limits<double>::epsilon()*1e4) { 240 polar[1] = 0.; 241 } else { 242 // xsqr + ysqr is always non-negative 243 polar[1] = M_PI/2.; 244 } 245 } else { 246 polar[1] = atan( sqrt(xsqr + ysqr)/_cartesian[2]); 247 if (_cartesian[2] <= -std::numeric_limits<double>::epsilon()*1e4) 248 polar[1] += M_PI; 249 } 250 251 if (fabs(_cartesian[0]) < std::numeric_limits<double>::epsilon()*1e4) { 252 if (fabs(_cartesian[1]) < std::numeric_limits<double>::epsilon()*1e4) { 253 polar[2] = 0.; 254 } else if (_cartesian[1] > std::numeric_limits<double>::epsilon()*1e4) { 255 polar[2] = M_PI/2.; 256 } else { 257 polar[2] = -M_PI/2.; 258 } 259 } else { 260 polar[2] = atan ( _cartesian[1]/_cartesian[0] ); 261 if (_cartesian[0] <= -std::numeric_limits<double>::epsilon()*1e4) 262 polar[2] += M_PI; 263 } 264 return polar; 265 } 266 267 /** Calculate cartesian coordinates from given polar ones. 268 * 269 * \param _polar vector with polar coordinates 270 * \return cartesian coordinates 271 */ 272 Vector getCartesianCoordinates(const std::vector<double> &_polar) 273 { 274 Vector cartesian; 275 ASSERT( _polar.size() == 3, 276 "convertToCartesianCoordinates() - tuples has insufficient components."); 277 cartesian[0] = _polar[0] * sin(_polar[1]) * cos(_polar[2]); 278 cartesian[1] = _polar[0] * sin(_polar[1]) * sin(_polar[2]); 279 cartesian[2] = _polar[0] * cos(_polar[1]); 280 return cartesian; 281 } 282 283 /** Rotates a given polygon around x, y, and z axis by the given angles. 284 * 285 * \param _polygon polygon whose points to rotate 286 * \param _angles vector with rotation angles for x,y,z axis 287 */ 288 SphericalPointDistribution::Polygon_t rotatePolygon( 289 const SphericalPointDistribution::Polygon_t &_polygon, 290 const std::vector<double> &_angles) 291 { 292 SphericalPointDistribution::Polygon_t rotated_polygon = _polygon; 293 RealSpaceMatrix rotation; 294 ASSERT( _angles.size() == 3, 295 "rotatePolygon() - not exactly "+toString(3)+" components given."); 296 297 // apply rotation angles 298 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_polygon.begin(); 299 iter != rotated_polygon.end(); ++iter) { 300 // transform to polar 301 std::vector<double> polar = getPolarCoordinates(*iter); 302 LOG(5, "DEBUG: Converting " << *iter << " to " << polar); 303 // sum up difference 304 std::transform( 305 _angles.begin(), _angles.end(), 306 polar.begin(), 307 polar.begin(), 308 std::plus<double>()); 309 // convert back 310 *iter = getCartesianCoordinates(polar); 311 LOG(5, "DEBUG: Converting modified " << polar << " to " << *iter); 312 } 313 314 return rotated_polygon; 315 } 316 259 317 260 318 SphericalPointDistribution::Polygon_t … … 267 325 VectorArray_t remainingold(_polygon.begin(), _polygon.end()); 268 326 VectorArray_t remainingnew(_newpolygon.begin(), _newpolygon.end()); 269 LOG( 3, "INFO: Matching old polygon " << _polygon327 LOG(2, "INFO: Matching old polygon " << _polygon 270 328 << " with new polygon " << _newpolygon); 271 329 … … 290 348 recurseMatchings(MCS, matching, indices, matchingsize); 291 349 } 292 LOG( 3, "INFO: Best matching is " << MCS.bestmatching);350 LOG(2, "INFO: Best matching is " << MCS.bestmatching); 293 351 294 352 // determine rotation angles to align the two point distributions with 295 353 // respect to bestmatching 296 std::vector<double> angles( 3);354 std::vector<double> angles(NDIM); 297 355 Vector newCenter; 356 Vector oldCenter; 298 357 { 299 // calculate center of triangle/line/point consisting of first returnpolygon of matching 300 Vector oldCenter; 358 // calculate center of triangle/line/point consisting of first points of matching 301 359 IndexList_t::const_iterator iter = MCS.bestmatching.begin(); 302 360 unsigned int i = 0; … … 307 365 oldCenter *= 1./(double)i; 308 366 newCenter *= 1./(double)i; 309 LOG(3, "INFO: oldCenter is " << oldCenter << ", newCenter is " << newCenter); 310 311 Vector direction(0.,0.,0.); 312 for(size_t i=0;i<NDIM;++i) { 313 // create new rotation axis 314 direction[i] = 1.; 315 const Line axis (zeroVec, direction); 316 // calculate rotation angle for this axis 317 const double alpha = direction.Angle(oldCenter) - direction.Angle(newCenter); 318 // perform rotation 319 axis.rotateVector(newCenter, alpha); 320 // store angle 321 angles[i] = alpha; 322 // reset direction component for next iteration 323 direction[i] = 0.; 324 } 325 } 326 LOG(3, "INFO: (x,y,z) angles are" << angles); 327 const Line RotationAxis(zeroVec, newCenter); 328 const double RotationAngle = 329 newCenter.Angle(remainingold[0]) 330 - newCenter.Angle(remainingnew[*MCS.bestmatching.begin()]); 331 LOG(3, "INFO: Rotate around self is " << RotationAngle 332 << " around axis " << RotationAxis); 333 367 LOG(4, "DEBUG: oldCenter is " << oldCenter << ", newCenter is " << newCenter); 368 369 // transform to polar coordinates and note difference in angular parts 370 std::vector<double> oldpolar = getPolarCoordinates(oldCenter); 371 std::vector<double> newpolar = getPolarCoordinates(newCenter); 372 std::vector<double> differencepolar; 373 std::transform( 374 oldpolar.begin(), oldpolar.end(), 375 newpolar.begin(), 376 std::back_inserter(differencepolar), 377 std::minus<double>()); 378 LOG(3, "INFO: (r,theta,phi) angles are" << differencepolar); 379 } 334 380 // rotate _newpolygon 335 381 SphericalPointDistribution::Polygon_t rotated_newpolygon = 336 rotatePolygon(_newpolygon, angles, RotationAxis, RotationAngle); 337 LOG(3, "INFO: Rotated new polygon is " << rotated_newpolygon); 338 339 // remove all returnpolygon in matching and return remaining ones 340 return removeMatchingPoints(rotated_newpolygon, MCS.bestmatching); 382 rotatePolygon(_newpolygon, angles); 383 LOG(5, "DEBUG: Rotated new polygon is " << rotated_newpolygon); 384 385 const Line RotationAxis(zeroVec, oldCenter); 386 const double RotationAngle = 387 oldCenter.Angle(remainingold[0]) 388 - oldCenter.Angle(remainingnew[*MCS.bestmatching.begin()]); 389 LOG(5, "DEBUG: Rotate around self is " << RotationAngle 390 << " around axis " << RotationAxis); 391 392 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_newpolygon.begin(); 393 iter != rotated_newpolygon.end(); ++iter) { 394 RotationAxis.rotateVector(*iter, RotationAngle); 395 } 396 397 // remove all points in matching and return remaining ones 398 SphericalPointDistribution::Polygon_t remainingpoints = 399 removeMatchingPoints(rotated_newpolygon, MCS.bestmatching); 400 LOG(2, "INFO: Remaining points are " << remainingpoints); 401 return remainingpoints; 341 402 } else 342 403 return _newpolygon; -
src/Fragmentation/Exporters/unittests/Makefile.am
r7e81ca r946948 21 21 22 22 TESTS += $(FRAGMENTATIONEXPORTERSTESTS) 23 XFAIL_TESTS += SphericalPointDistributionUnitTest24 23 check_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS) 25 24 noinst_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS)
Note:
See TracChangeset
for help on using the changeset viewer.