Changeset 0983e6


Ignore:
Timestamp:
Sep 12, 2016, 11:48:36 PM (8 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

Refactoring SphericalPointDistribution to combine point list and subset of indices.

Location:
src/Fragmentation/Exporters
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Exporters/SphericalPointDistribution.cpp

    r653cea r0983e6  
    9999}
    100100
     101/** Calculate the center of a given set of points in \a _positions but only
     102 * for those indicated by \a _indices.
     103 *
     104 */
     105inline
     106Vector calculateCenter(
     107    const SphericalPointDistribution::PolygonWithIndices &_polygon)
     108{
     109  return calculateCenter(_polygon.polygon, _polygon.indices);
     110}
     111
    101112inline
    102113DistanceArray_t calculatePairwiseDistances(
     
    177188    Vector &_oldCenter,
    178189    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);
    187194  // 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);
    193196}
    194197/** Returns squared L2 error of the given \a _Matching.
     
    251254
    252255SphericalPointDistribution::Polygon_t SphericalPointDistribution::removeMatchingPoints(
    253     const VectorArray_t &_points,
    254     const IndexList_t &_matchingindices
     256    const PolygonWithIndices &_points
    255257    )
    256258{
    257   SphericalPointDistribution::Polygon_t remainingreturnpolygon;
    258   IndexArray_t indices(_matchingindices.begin(), _matchingindices.end());
     259  SphericalPointDistribution::Polygon_t remainingpoints;
     260  IndexArray_t indices(_points.indices.begin(), _points.indices.end());
    259261  std::sort(indices.begin(), indices.end());
    260262  LOG(4, "DEBUG: sorted matching is " << indices);
    261   IndexArray_t remainingindices(_points.size(), -1);
     263  IndexArray_t remainingindices(_points.polygon.size(), -1);
    262264  std::generate(remainingindices.begin(), remainingindices.end(), UniqueNumber);
    263265  IndexArray_t::iterator remainiter = std::set_difference(
     
    269271  for (IndexArray_t::const_iterator iter = remainingindices.begin();
    270272      iter != remainingindices.end(); ++iter) {
    271     remainingreturnpolygon.push_back(_points[*iter]);
    272   }
    273 
    274   return remainingreturnpolygon;
     273    remainingpoints.push_back(_points.polygon[*iter]);
     274  }
     275
     276  return remainingpoints;
    275277}
    276278
     
    501503
    502504SphericalPointDistribution::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
    506507    )
    507508{
     
    520521  calculateOldAndNewCenters(
    521522      oldCenter, newCenter,
    522       _referencepositions, _currentpositions, _bestmatching);
     523      _referencepositions, _currentpositions);
    523524
    524525  if ((!oldCenter.IsZero()) && (!newCenter.IsZero())) {
     
    538539    if ((oldCenter.IsZero()) && (newCenter.IsZero())) {
    539540      // either oldCenter or newCenter (or both) is directly at origin
    540       if (_bestmatching.size() == 2) {
     541      if (_currentpositions.indices.size() == 2) {
    541542        // 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];
    544545        // check whether we need to rotate at all
    545546        if (!oldPosition.IsEqualTo(newPosition)) {
     
    555556        // both triangles/planes have same center, hence get axis by
    556557        // VectorProduct of Normals
    557         Plane newplane(_referencepositions[0], _referencepositions[1], _referencepositions[2]);
     558        Plane newplane(_referencepositions.polygon[0], _referencepositions.polygon[1], _referencepositions.polygon[2]);
    558559        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]);
    562563        Plane oldplane(vectors[0], vectors[1], vectors[2]);
    563564        Vector oldPosition = oldplane.getNormal();
     
    607608
    608609SphericalPointDistribution::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)
    612612{
    613613  // initialize rotation to zero
     
    622622  calculateOldAndNewCenters(
    623623      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() << ")");
    629631  if (!oldPosition.IsEqualTo(newPosition)) {
    630632    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.
    632635      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));
    636643      LOG(6, "DEBUG: Positions after projection are " << oldPosition << " and " << newPosition);
    637644    } else {
    638       if (_bestmatching.size() == 2) {
     645      if (remainingnew.indices.size() == 2) {
    639646        // line situation
    640647        try {
     
    657664      } else {
    658665        // triangle situation
    659         Plane oldplane(remainingold[0], remainingold[1], remainingold[2]);
     666        Plane oldplane(remainingold.polygon[0], remainingold.polygon[1], remainingold.polygon[2]);
    660667        Rotation.first = oldplane.getNormal();
    661668        LOG(6, "DEBUG: oldPlane is " << oldplane << " and normal is " << Rotation.first);
     
    682689{
    683690  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
    688692  LOG(2, "INFO: Matching old polygon " << _polygon
    689693      << " with new polygon " << _newpolygon);
     
    699703    LOG(2, "INFO: Best matching is " << bestmatching);
    700704
    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));
    703722
    704723    // determine rotation angles to align the two point distributions with
     
    706725    // we use the center between the three first matching points
    707726    /// the first rotation brings these two centers to coincide
    708     VectorArray_t rotated_newpolygon = remainingnew;
     727    PolygonWithIndices rotatednewSet = newSet;
    709728    {
    710       Rotation_t Rotation = findPlaneAligningRotation(
    711           remainingold,
    712           remainingnew,
    713           bestmatching);
     729      Rotation_t Rotation = findPlaneAligningRotation(oldSet, newSet);
    714730      LOG(5, "DEBUG: Rotating coordinate system by " << Rotation.second
    715731          << " around axis " << Rotation.first);
     
    717733
    718734      // 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) {
    721737        Vector &current = *iter;
    722738        LOG(6, "DEBUG: Original point is " << current);
     
    732748        calculateOldAndNewCenters(
    733749            oldCenter, rotatednewCenter,
    734             remainingold, rotated_newpolygon, bestmatching);
     750            oldSet, rotatednewSet);
    735751        // NOTE: Center must not necessarily lie on the sphere with norm 1, hence, we
    736752        // have to normalize it just as before, as oldCenter and newCenter lengths may differ.
     
    740756          LOG(4, "CHECK: rotatednewCenter is " << rotatednewCenter
    741757              << ", 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,
    743760              "matchSphericalPointDistributions() - rotation does not work as expected by "
    744               +toString((rotatednewCenter - oldCenter).NormSquared())+".");
     761              +toString(difference)+".");
    745762        }
    746763      }
     
    750767    /// points themselves coincide
    751768    if (bestmatching.size() > 1) {
    752       Rotation_t Rotation = findPointAligningRotation(
    753           remainingold,
    754           rotated_newpolygon,
    755           bestmatching);
     769      Rotation_t Rotation = findPointAligningRotation(oldSet, rotatednewSet);
    756770
    757771      // construct RotationAxis and two points on its plane, defining the angle
     
    767781      {
    768782        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
    769796        Vector rotatednew = RotationAxis.rotateVector(
    770             rotated_newpolygon[*iter],
     797            rotatednewSet.polygon[*iter],
    771798            Rotation.second);
    772799        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)+".");
    777806      }
    778807#endif
    779808
    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) {
    782811        Vector &current = *iter;
    783812        LOG(6, "DEBUG: Original point is " << current);
     
    789818    // remove all points in matching and return remaining ones
    790819    SphericalPointDistribution::Polygon_t remainingpoints =
    791         removeMatchingPoints(rotated_newpolygon, bestmatching);
     820        removeMatchingPoints(rotatednewSet);
    792821    LOG(2, "INFO: Remaining points are " << remainingpoints);
    793822    return remainingpoints;
  • src/Fragmentation/Exporters/SphericalPointDistribution.hpp

    r653cea r0983e6  
    105105  static const double warn_amplitude;
    106106
     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
    107115private:
    108116  //!> grant unit tests access to private parts
     
    115123
    116124  static Polygon_t removeMatchingPoints(
    117       const VectorArray_t &_points,
    118       const IndexList_t &_matchingindices
    119       );
     125      const PolygonWithIndices &_points);
    120126
    121127  struct MatchingControlStructure {
     
    149155
    150156  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
    154159      );
    155160
    156161  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);
    160164
    161165};
Note: See TracChangeset for help on using the changeset viewer.