/* * ChargeSmearer.hpp * * Created on: Sep 2, 2015 * Author: heber */ #ifndef CHARGESMEARER_HPP_ #define CHARGESMEARER_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/Singleton.hpp" namespace VMG { class Grid; class GridIterator; class Index; namespace Particle { class BSpline; } } /** This class smears out a given (peak-like) charge value by using a radial * b-spline of compile-defined degree and runtime-defined width ("near field * cells"). * * This is used to smear out the electronic charge distribution in the same * way as is done with the (point-like) nuclei charge distribution to increase * accuracy for the long-range calculations. * * The trick relies on two distant and non-overlapping charge distributions * behave actually as two point charges and vice versa. Core electron charge * distributions are strongly peaked and hence almost appear like the point-like * nuclei charge distributions. Hence, we perform the same trick as is done * with the nuclei. The charges are smeared out to such a degree that charge * distributions do not overlap except within a single fragment. Within * fragments the short-range Coulomb energy and forces is calculated accurately. * In between fragments the long-range calculations via vmg is used and hence * charges there may not overlap. The maximum distance allowed and hence the * maximum near field cells can be obtained from the Interfragmenter class. * * This class is a singleton as we only need to precalculate the spline values * for a given nfc once and then may use of all FragmentJobs. * * The code here is taken from vmg's units/particles/bspline.cpp::SetSpline(). */ class ChargeSmearer : public Singleton { friend class Singleton; private: /** Private cstor for ChargeSmearer. * * Must be private as is singleton. * */ ChargeSmearer(); /** Dstor for ChargeSmearer. * */ ~ChargeSmearer(); public: /** Setter for the values defining the grid and the spline extent. * * This function recalculates the spline values but only if the * values have changed with respect to the old ones. * * \param _spl spline to evaluate * \param _nfc near field cells * \param _meshwdith mesh spacing */ void initializeSplineArray( const VMG::Particle::BSpline &_spl, const unsigned int _nfc, const double _meshwidth); /** Getter for the width of the smearing area, i.e. number of near field * cells. * * \return number of near field cells, i.e. 2nfc+1 equals width of array */ unsigned int getNearFielCells() const { return nfc; } /** Getter for the meshwidth. * * \return meshwidth */ unsigned int getMeshwidth() const { return meshwidth; } /** Smears out the given charge \a _value with the current \a nfc and bspline * on the \a _grid. * * \param _grid grid to smear out charge on * \param _iter central node on grid where to add smearing * \param _charge charge to smear out */ void operator()( VMG::Grid& _grid, const VMG::GridIterator &_iter, const double _charge) const; private: //!> typedef for the visitor functor typedef boost::function visitor_t; /** Visitor pattern for going over bspline support and executing the given * functor at each valid node. * * \param _iter iterator giving central node for support on grid * \param _visitor visitor functor to execute at each node (that's still inside grid) */ void visitBSplineDomain( const VMG::GridIterator &_iter, const visitor_t &_visitor ) const; private: //!> near field radius for bspline unsigned int nfc; //!> mesh width of the grid double meshwidth; //!> contains the array of pre-compiled spline values double *vals; //!> integrated value of spline array for normalization double int_val; }; #endif /* CHARGESMEARER_HPP_ */