Changeset 62d092 for src/Jobs


Ignore:
Timestamp:
Oct 13, 2015, 8:14:33 PM (9 years ago)
Author:
Frederik Heber <heber@…>
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:
3690e4
Parents:
17e4fd
git-author:
Frederik Heber <heber@…> (09/08/15 22:12:20)
git-committer:
Frederik Heber <heber@…> (10/13/15 20:14:33)
Message:

Rewrote ChargeSmearer to use visitor pattern.

  • this is used for going over the bspline domain.
  • we need it when the support does not fit onto grid and when we need to recalculate the normalization.
Location:
src/Jobs
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Jobs/ChargeSmearer.cpp

    r17e4fd r62d092  
    3737#include "ChargeSmearer.hpp"
    3838
     39#include "CodePatterns/Log.hpp"
    3940#include "CodePatterns/Singleton_impl.hpp"
    4041
     
    6869  // reallocate memory for spline values
    6970  delete[] vals;
    70   double *vals = new double[VMG::Helper::intpow(2*nfc+1,3)];
     71  vals = new double[VMG::Helper::intpow(2*nfc+1,3)];
    7172
    7273  // recalculate spline values
    7374  unsigned int c=0;
    7475  int_val = 0.;
    75   for (double dir_x=-1*nfc*meshwidth; dir_x<=nfc*meshwidth; dir_x+=meshwidth) {
    76     for (double dir_y=-1*nfc*meshwidth; dir_y<=nfc*meshwidth; dir_y+=meshwidth) {
    77       for (double dir_z=-1*nfc*meshwidth; dir_z<=nfc*meshwidth; dir_z+=meshwidth) {
    78 
     76  std::pair<int, int> bounds[3];
     77  for (int dim=0;dim<3;++dim) {
     78    bounds[dim].first = -1*nfc;
     79    bounds[dim].second = nfc;
     80  }
     81  for (int i=bounds[0].first; i<=bounds[0].second; ++i)
     82    for (int j=bounds[1].first; j<=bounds[1].second; ++j)
     83      for (int k=bounds[2].first; k<=bounds[2].second; ++k) {
     84        const double dir_x = (double)i*meshwidth;
     85        const double dir_y = (double)j*meshwidth;
     86        const double dir_z = (double)k*meshwidth;
    7987        // Compute distance from grid point to particle
    8088        const double distance = std::sqrt(dir_x*dir_x+dir_y*dir_y+dir_z*dir_z);
     
    8290        vals[c++] = temp_val;
    8391        int_val += temp_val;
     92        LOG(4, "DEBUG: Spline evaluated at " << distance << " is " << temp_val);
    8493      }
    85     }
    86   }
    8794
    8895  /// then integrate
    89   int_val = 1.0 / (int_val * meshwidth * meshwidth * meshwidth);
     96  int_val = 1.0 / int_val;
     97
     98  LOG(3, "DEBUG: Spline for smearing electronic charge distribution has norm factor of " << int_val);
     99}
     100
     101void ChargeSmearer::visitBSplineDomain(
     102    const VMG::GridIterator &_iter,
     103    const visitor_t &_visitor
     104    ) const
     105{
     106  unsigned int c = 0;
     107  VMG::Index index;
     108  const VMG::Index end = _iter.GetIndex() + (int)nfc;
     109  for (index[0] = _iter.GetIndex()[0] - (int)nfc; index[0]<=end[0]; ++index[0])
     110    for (index[1] = _iter.GetIndex()[1] - (int)nfc; index[1]<=end[1]; ++index[1])
     111      for (index[2] = _iter.GetIndex()[2] - (int)nfc; index[2]<=end[2]; ++index[2]) {
     112        if (index.IsInBounds(_iter.GetBegin(), _iter.GetEnd()))
     113          _visitor(index, vals[c++]);
     114        else
     115          ++c;
     116      }
     117  assert( c == (unsigned int)VMG::Helper::intpow(2*nfc+1,3) );
     118}
     119
     120static void DomainIntegrator(
     121    const VMG::Index & _index,
     122    const double _val,
     123    double &_int_val)
     124{
     125  _int_val += _val;
     126}
     127
     128static void SplineSetter(
     129    const VMG::Index & _index,
     130    const double _val,
     131    const double _factor,
     132    VMG::Grid& _grid)
     133{
     134  _grid(_index) += _val * _factor;
    90135}
    91136
     
    95140    const double _charge) const
    96141{
    97   /// prepare bounds
    98   std::pair<int, int> bounds[3];
     142  // check whether we go over whole bspline support
     143  bool renormalize = false;
    99144  for (int dim=0;dim<3;++dim) {
    100     bounds[dim].first = std::max(_iter.GetBegin()[dim], _iter.GetIndex()[dim] - (int)nfc);
    101     bounds[dim].second = std::min(_iter.GetEnd()[dim], _iter.GetIndex()[dim] + (int)nfc);
     145    renormalize |= (_iter.GetBegin()[dim] > _iter.GetIndex()[dim] - (int)nfc);
     146    renormalize |= (_iter.GetEnd()[dim] < _iter.GetIndex()[dim] + (int)nfc);
     147  }
     148
     149  /// renormalize bspline if necessary (bounds don't fit in window)
     150  double temp_int_val = 0.;
     151  if (renormalize) {
     152    const visitor_t integrator = boost::bind(DomainIntegrator, _1, _2, boost::ref(temp_int_val));
     153    visitBSplineDomain(_iter, integrator);
     154    temp_int_val = 1.0 / temp_int_val;
     155  } else {
     156    temp_int_val = int_val;
    102157  }
    103158
    104159  /// then transfer to grid in bounded window
    105   unsigned int c = 0;
    106   for (int i=bounds[0].first; i<=bounds[0].second; ++i)
    107     for (int j=bounds[1].first; j<=bounds[1].second; ++j)
    108       for (int k=bounds[2].first; k<=bounds[2].second; ++k)
    109         _grid(i,j,k) += vals[c++] * int_val * _charge;
    110   assert( c == (unsigned int)VMG::Helper::intpow(2*nfc+1,3) );
     160  {
     161    const visitor_t setter = boost::bind(SplineSetter, _1, _2, temp_int_val * _charge, boost::ref(_grid));
     162    visitBSplineDomain(_iter, setter);
     163  }
    111164}
    112165
  • src/Jobs/ChargeSmearer.hpp

    r17e4fd r62d092  
    1919  class Grid;
    2020  class GridIterator;
     21  class Index;
    2122
    2223  namespace Particle {
     
    109110
    110111private:
     112  //!> typedef for the visitor functor
     113  typedef boost::function<void (const VMG::Index &, const double)> visitor_t;
     114
     115  /** Visitor pattern for going over bspline support and executing the given
     116   * functor at each valid node.
     117   *
     118   * \param _iter iterator giving central node for support on grid
     119   * \param _visitor visitor functor to execute at each node (that's still inside grid)
     120   */
     121  void visitBSplineDomain(
     122      const VMG::GridIterator &_iter,
     123      const visitor_t &_visitor
     124      ) const;
     125
     126private:
    111127  //!> near field radius for bspline
    112128  unsigned int nfc;
Note: See TracChangeset for help on using the changeset viewer.