/* * SamplingGrid.hpp * * Created on: 25.07.2012 * Author: heber */ #ifndef SAMPLINGGRID_HPP_ #define SAMPLINGGRID_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include "boost/serialization/export.hpp" #include "boost/serialization/vector.hpp" #include "Jobs/Grid/SamplingGridProperties.hpp" class MPQCData; class SamplingGridTest; /** This class stores a sample function on a three-dimensional grid. * * \note We do not use boost::multi_array because it is not trivial to serialize. * */ class SamplingGrid : public SamplingGridProperties { //!> grant unit test access to private parts friend class SamplingGridTest; //!> grant output operator access friend std::ostream & operator<<(std::ostream &ost, const SamplingGrid& other); public: //!> typedef for sampled values typedef std::vector< double > sampledvalues_t; /** Constructor for class SamplingGrid. * * \param _begin offset for grid per axis * \param _end edge length of grid per axis * \param _level number of grid points in \f$2^{\mathrm{level}}\f$ * \param _sampled_grid sample points */ SamplingGrid(const double _begin[3], const double _end[3], const int _level, const sampledvalues_t &_sampled_grid); /** Copy constructor for class SamplingGrid. * * \param _grid grid to copy */ SamplingGrid(const SamplingGrid &_grid); /** Copy constructor for class SamplingGrid from SamplingGridProperties. * * \param _props properties to copy */ SamplingGrid(const SamplingGridProperties &_props); /** Copy constructor for class SamplingGrid from SamplingGridProperties. * * \param _props properties to copy * \param _sampled_grid sample points */ SamplingGrid( const SamplingGridProperties &_props, const sampledvalues_t &_sampled_grid); /** default cstor. */ SamplingGrid(); virtual ~SamplingGrid(); /** Assignment operator. * * \param other other instance to assign ourselves to */ SamplingGrid& operator=(const SamplingGrid& other); /** Addition operator with another SamplingGrid instance \a other. * * \param other other instance to sum onto this one. * \return ref to this instance */ SamplingGrid& operator+=(const SamplingGrid& other) { superposeOtherGrids(other, +1.); return *this; } /** Element-wise multiplication operator with another SamplingGrid instance \a other. * * \param other other instance to sum onto this one. * \return ref to this instance */ SamplingGrid& operator*=(const SamplingGrid& other); /** Subtraction operator with another SamplingGrid instance \a other. * * \param other other instance to subtract from this one. * \return ref to this instance */ SamplingGrid& operator-=(const SamplingGrid& other) { superposeOtherGrids(other, -1.); return *this; } /** Returns the numeric integral over the grid. * * @return sum of grid values times volume element */ double integral() const; /** Returns the numeric integral over the grid where the grid is element-wise multiplied with \a weight. * * @param weight grid of weights * @return sum of grid values weighted by respective element in weight times volume element */ double integral(const SamplingGrid &weight) const; /** Returns the volume of the domain for this sampled function. * * @return volume */ const double getVolume() const; /** Returns the total number of gridpoints of the discrete mesh covering the (window) volume. * * @return number of gridpoints sampled_values should have */ const size_t getWindowGridPoints() const; /** Returns the total number of gridpoints of the discrete mesh covering the volume. * * @return number of gridpoints sampled_values should have */ const size_t getTotalGridPoints() const; /** Returns the number of grid points per axis. * * @return number of grid points per unit length */ const size_t getGridPointsPerAxis() const; /** Returns the volume of the domain covered by the current window. * * @return volume of window */ const double getWindowVolume() const; private: /** Sets the size of the window. * * \note also resets the sampled points so far. * * \param _begin_window start of new window * \param _end_window end of window */ void setWindow(const double _begin_window[3], const double _end_window[3]); /** Sets the size of the domain. * * \note also resets the sampled points so far and the window. * * \param _begin start of new window * \param _end end of window */ void setDomain(const double _begin[3], const double _end[3]); /** Sets the size of the domain. * * \note this is just internally used for easing the array setting. * * \param _begin start of domain * \param _end end of domain */ void setDomainSize(const double _begin[3], const double _end[3]); /** Extends the window while keeping the values. * * \param _begin_window new start of window * \param _end_window new end of window */ void extendWindow(const double _begin_window[3], const double _end_window[3]); /** Adds another window onto the one in this instance. * * \note We assume here that the given window fits on the this one. * * \param _begin_window start of other window * \param _end_window end of other window * \param _sampled_grid other set of sampled values */ void addOntoWindow( const double _begin_window[3], const double _end_window[3], const sampledvalues_t &_sampled_grid); /** Helper function that contains all the logic of how to superpose two * grids. * * Is called by SamplingGrid::operator+=() and SamplingGrid::operator-=() * * @param other other histogram * @param prefactor +1. is then addition, -1. is subtraction. */ void superposeOtherGrids(const SamplingGrid &other, const double prefactor); /** Sets the size of the window. * * \note also resets the sampled points so far. * * \param _begin_window start of new window * \param _end_window end of window */ void setWindowSize(const double _begin_window[3], const double _end_window[3]); public: /// We do not store the whole grid if many entries are actually zero /// but only a window wherein the sampled function is non-zero. //!> sample points of the window sampledvalues_t sampled_grid; //!> start of the window relative to SamplingGridProperties::begin and SamplingGridProperties::size double begin_window[3]; //!> end of the window relative to SamplingGridProperties::begin and SamplingGridProperties::size double end_window[3]; private: friend class MPQCData; friend class boost::serialization::access; // serialization template void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_object(*this); ar & const_cast< sampledvalues_t &>(sampled_grid); for(size_t i=0;i<3;++i) { ar & begin_window[i]; ar & end_window[i]; } } //!> static typedef to use in cstor when no initial values are given static const double zeroOffset[3]; }; /** Output operator for class SamplingGrid. * * \param ost output stream to print to * \param other instance to print * \return ref to stream for concatenation */ std::ostream & operator<<(std::ostream &ost, const SamplingGrid& other); template T ZeroInstance(); template<> SamplingGrid ZeroInstance(); // we need to give this class a unique key for serialization // its is only serialized through its base class FragmentJob BOOST_CLASS_EXPORT_KEY(SamplingGrid) #endif /* SAMPLINGGRID_HPP_ */