Index: src/Fragmentation/SetValues/Makefile.am
===================================================================
--- src/Fragmentation/SetValues/Makefile.am	(revision 4a77be7c74807798597478c1e2a88d09178390fe)
+++ src/Fragmentation/SetValues/Makefile.am	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -5,13 +5,17 @@
 	Fragmentation/SetValues/Fragment.cpp \
 	Fragmentation/SetValues/Histogram.cpp \
-	Fragmentation/SetValues/IndexedVectors.cpp
+	Fragmentation/SetValues/IndexedVectors.cpp \
+	Fragmentation/SetValues/SamplingGrid.cpp \
+	Fragmentation/SetValues/SamplingGridProperties.cpp
 
 FRAGMENTATIONSETVALUESHEADER = \
 	Fragmentation/SetValues/Fragment.hpp \
 	Fragmentation/SetValues/Histogram.hpp \
-	Fragmentation/SetValues/IndexedVectors.hpp
+	Fragmentation/SetValues/IndexedVectors.hpp \
+	Fragmentation/SetValues/SamplingGrid.hpp \
+	Fragmentation/SetValues/SamplingGrid_inline.hpp \
+	Fragmentation/SetValues/SamplingGridProperties.hpp
 
-
-noinst_LTLIBRARIES += libMolecuilderFragmentationSetValues.la
+lib_LTLIBRARIES += libMolecuilderFragmentationSetValues.la
 libMolecuilderFragmentationSetValues_la_includedir = $(includedir)/MoleCuilder/Fragmentation/SetValues/
 libMolecuilderFragmentationSetValues_la_CPPFLAGS = ${BOOST_CPPFLAGS} ${CodePatterns_CFLAGS}
@@ -36,5 +40,5 @@
 ## library file (.so).  The library ABI version is defined in configure.ac, so
 ## that all version information is kept in one place.
-#libMolecuilderFragmentationSetValues_la_LDFLAGS = -version-info $(MOLECUILDER_SO_VERSION)
+libMolecuilderFragmentationSetValues_la_LDFLAGS += -version-info $(MOLECUILDER_SO_VERSION)
 
 ## The generated configuration header is installed in its own subdirectory of
@@ -49,6 +53,6 @@
 ## configuration header file is generated at configure time and should not be
 ## shipped with the source tarball.
-#libMolecuilderFragmentationSetValues_libincludedir = $(libdir)/MoleCuilder/include
-#nodist_libMolecuilderFragmentationSetValues_libinclude_HEADERS = $(top_builddir)/libmolecuilder_config.h
+libMolecuilderFragmentationSetValues_libincludedir = $(libdir)/MoleCuilder/include
+nodist_libMolecuilderFragmentationSetValues_libinclude_HEADERS = $(top_builddir)/libmolecuilder_config.h
 
 ## Install the generated pkg-config file (.pc) into the expected location for
Index: src/Fragmentation/SetValues/SamplingGrid.cpp
===================================================================
--- src/Fragmentation/SetValues/SamplingGrid.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/SamplingGrid.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,599 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SamplingGrid.cpp
+ *
+ *  Created on: 25.07.2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include headers that implement a archive in simple text format
+// otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Fragmentation/SetValues/SamplingGrid.hpp"
+
+#include <boost/bind.hpp>
+#include <limits>
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+// static instances
+const double SamplingGrid::zeroOffset[3] = { 0., 0., 0. };
+
+SamplingGrid::SamplingGrid() :
+    SamplingGridProperties()
+{
+  setWindowSize(zeroOffset, zeroOffset);
+  ASSERT( getWindowGridPoints() == (size_t)0,
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::SamplingGrid(const double _begin[3],
+    const double _end[3],
+    const int _level) :
+  SamplingGridProperties(_begin, _end, _level)
+{
+  setWindowSize(zeroOffset, zeroOffset);
+  ASSERT( getWindowGridPoints() == (size_t)0,
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::SamplingGrid(const double _begin[3],
+    const double _end[3],
+    const int _level,
+    const sampledvalues_t &_sampled_grid) :
+  SamplingGridProperties(_begin, _end, _level),
+  sampled_grid(_sampled_grid)
+{
+  setWindowSize(_begin, _end);
+  ASSERT( getWindowGridPoints() == (size_t)_sampled_grid.size(),
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::SamplingGrid(const SamplingGrid &_grid) :
+  SamplingGridProperties(_grid),
+  sampled_grid(_grid.sampled_grid)
+{
+  setWindowSize(_grid.begin_window, _grid.end_window);
+  ASSERT( getWindowGridPoints() == _grid.getWindowGridPoints(),
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::SamplingGrid(const SamplingGridProperties &_props) :
+  SamplingGridProperties(_props)
+{
+  setWindowSize(zeroOffset, zeroOffset);
+  ASSERT( getWindowGridPoints() == (size_t)0,
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::SamplingGrid(
+    const SamplingGridProperties &_props,
+    const sampledvalues_t &_sampled_grid) :
+  SamplingGridProperties(_props),
+  sampled_grid(_sampled_grid)
+{
+  setWindowSize(_props.begin, _props.end);
+  ASSERT( getWindowGridPoints() == (size_t)_sampled_grid.size(),
+      "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
+}
+
+SamplingGrid::~SamplingGrid()
+{}
+
+bool SamplingGrid::isCongruent(const SamplingGrid &_props) const
+{
+  bool status = true;
+  status &= (static_cast<const SamplingGridProperties &>(*this) ==
+      static_cast<const SamplingGridProperties &>(_props));
+  for(size_t i = 0; i<3; ++i) {
+    status &= begin_window[i] == _props.begin_window[i];
+    status &= end_window[i] == _props.end_window[i];
+  }
+  return status;
+}
+
+SamplingGrid& SamplingGrid::operator=(const SamplingGrid& other)
+{
+  // check for self-assignment
+  if (this != &other) {
+    static_cast<SamplingGridProperties &>(*this) = other;
+    setWindowSize(other.begin_window, other.end_window);
+    sampled_grid = other.sampled_grid;
+  }
+  return *this;
+}
+
+static void multiplyElements(
+    double &dest,
+    const double &source,
+    const double prefactor)
+{
+  dest *= prefactor*(source);
+}
+
+
+SamplingGrid& SamplingGrid::operator*=(const SamplingGrid& other)
+{
+  // check that grids are compatible
+  if (isCompatible(other)) {
+    /// get minimum of window
+    double min_begin_window[3];
+    double min_end_window[3];
+    bool doShrink = false;
+    for (size_t index=0; index<3;++index) {
+      if (begin_window[index] <= other.begin_window[index]) {
+        min_begin_window[index] = other.begin_window[index];
+        doShrink = true;
+      } else {
+        min_begin_window[index] = begin_window[index];
+      }
+      if (end_window[index] <= other.end_window[index]) {
+        min_end_window[index] = end_window[index];
+      } else {
+        min_end_window[index] = other.end_window[index];
+        doShrink = true;
+      }
+    }
+    LOG(2, "DEBUG: min begin is " << min_begin_window[0] << "," << min_begin_window[1] << "," << min_begin_window[2] << ".");
+    LOG(2, "DEBUG: min end is " << min_end_window[0] << "," << min_end_window[1] << "," << min_end_window[2] << ".");
+    if (doShrink)
+      shrinkWindow(min_begin_window, min_end_window);
+    addWindowOntoWindow(
+        other.begin_window,
+        other.end_window,
+        begin_window,
+        end_window,
+        sampled_grid,
+        other.sampled_grid,
+        boost::bind(multiplyElements, _1, _2, 1.),
+        sourcewindow);
+  } else {
+    ASSERT(0, "SamplingGrid::operator*=() - multiplying incongruent grids is so far not in the cards.");
+  }
+  return *this;
+}
+
+void SamplingGrid::superposeOtherGrids(const SamplingGrid &other, const double prefactor)
+{
+  /// check that grids are compatible
+  if (isCompatible(other)) {
+    /// get maximum of window
+    double max_begin_window[3];
+    double max_end_window[3];
+    bool doExtend = false;
+    for (size_t index=0; index<3;++index) {
+      if (begin_window[index] >= other.begin_window[index]) {
+        max_begin_window[index] = other.begin_window[index];
+        doExtend = true;
+      } else {
+        max_begin_window[index] = begin_window[index];
+      }
+      if (end_window[index] >= other.end_window[index]) {
+        max_end_window[index] = end_window[index];
+      } else {
+        max_end_window[index] = other.end_window[index];
+        doExtend = true;
+      }
+    }
+    LOG(2, "DEBUG: max begin is " << max_begin_window[0] << "," << max_begin_window[1] << "," << max_begin_window[2] << ".");
+    LOG(2, "DEBUG: max end is " << max_end_window[0] << "," << max_end_window[1] << "," << max_end_window[2] << ".");
+    if (doExtend)
+      extendWindow(max_begin_window, max_end_window);
+    /// and copy other into larger window, too
+    addOntoWindow(other.begin_window, other.end_window, other.sampled_grid, prefactor);
+  } else {
+    ASSERT(0, "SamplingGrid::superposeOtherGrids() - superposing incompatible grids is so far not in the cards.");
+  }
+}
+
+const size_t SamplingGrid::getWindowGridPointsPerAxis(const size_t axis) const
+{
+  static const double round_offset(
+      (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
+          0.5 : 0.); // need offset to get to round_toward_nearest behavior
+//  const double total = getTotalLengthPerAxis(axis);
+  const double delta = getDeltaPerAxis(axis);
+  if (delta == 0)
+    return 0;
+  const double length = getWindowLengthPerAxis(axis);
+  if (length == 0)
+    return 0;
+  return (size_t)(length/delta+round_offset);
+}
+
+double SamplingGrid::integral() const
+{
+  const double volume_element = getVolume()/(double)getTotalGridPoints();
+  double int_value = 0.;
+  for (sampledvalues_t::const_iterator iter = sampled_grid.begin();
+      iter != sampled_grid.end();
+      ++iter)
+    int_value += *iter;
+  int_value *= volume_element;
+  LOG(2, "DEBUG: SamplingGrid::integral() is " << scientific << setprecision(13) << int_value << ".");
+  return int_value;
+}
+
+double SamplingGrid::integral(const SamplingGrid &weight) const
+{
+  if (isCompatible(weight)) {
+    const double volume_element = getVolume()/(double)getTotalGridPoints();
+    double int_value = 0.;
+    sampledvalues_t::const_iterator iter = sampled_grid.begin();
+    sampledvalues_t::const_iterator weightiter = weight.sampled_grid.begin();
+    for (;iter != sampled_grid.end();++iter,++weightiter)
+      int_value += (*weightiter) * (*iter);
+    int_value *= volume_element;
+    //LOG(2, "DEBUG: SamplingGrid::integral() is " << scientific << setprecision(13) << int_value << ".");
+    return int_value;
+  } else
+    return 0.;
+}
+
+double SamplingGrid::getNearestLowerGridPoint(
+    const double value, const size_t axis) const
+{
+  const double length = end[axis] - begin[axis];
+  if ((fabs(length) < std::numeric_limits<double>::epsilon()) || (getGridPointsPerAxis() == 0))
+    return begin[axis];
+  if (value > end[axis])
+    return end[axis];
+  const double offset = value - begin[axis];
+  if (offset < 0)
+    return begin[axis];
+  // modify value a little if value actually has been on a grid point but
+  // perturbed by numerical rounding: here up, as we always go lower
+  const double factor =
+      floor((double)getGridPointsPerAxis()*(offset/length)
+          +std::numeric_limits<double>::epsilon()*1.e4);
+  return factor*(length/(double)getGridPointsPerAxis());
+}
+
+double SamplingGrid::getNearestHigherGridPoint(
+    const double value, const size_t axis) const
+{
+  const double length = end[axis] - begin[axis];
+  if ((fabs(length) < std::numeric_limits<double>::epsilon()) || (getGridPointsPerAxis() == 0))
+    return end[axis];
+  if (value > end[axis])
+    return end[axis];
+  const double offset = value - begin[axis];
+  if (offset < 0)
+    return begin[axis];
+  // modify value a little if value actually has been on a grid point but
+  // perturbed by numerical rounding: here down, as we always go higher
+  const double factor =
+      ceil((double)getGridPointsPerAxis()*(offset/length)
+          -std::numeric_limits<double>::epsilon()*1.e4);
+  return factor*(length/(double)getGridPointsPerAxis());
+}
+
+void SamplingGrid::setWindowSize(
+    const double _begin_window[3],
+    const double _end_window[3])
+{
+  for (size_t index=0;index<3;++index) {
+    begin_window[index] = getNearestLowerGridPoint(_begin_window[index], index);
+    ASSERT( begin_window[index] >= begin[index],
+        "SamplingGrid::setWindowSize() - window starts earlier than domain on "
+        +toString(index)+"th component.");
+    end_window[index] = getNearestHigherGridPoint(_end_window[index], index);
+    ASSERT( end_window[index] <= end[index],
+        "SamplingGrid::setWindowSize() - window ends later than domain on "
+        +toString(index)+"th component.");
+  }
+}
+
+void SamplingGrid::setWindow(
+    const double _begin_window[3],
+    const double _end_window[3])
+{
+  setWindowSize(_begin_window, _end_window);
+  const size_t gridpoints_window = getWindowGridPoints();
+  sampled_grid.clear();
+  sampled_grid.resize(gridpoints_window, 0.);
+}
+
+void SamplingGrid::setDomain(
+    const double _begin[3],
+    const double _end[3])
+{
+  setDomainSize(_begin, _end);
+  setWindowSize(_begin, _end);
+  const size_t gridpoints = getTotalGridPoints();
+  sampled_grid.resize(gridpoints, 0.);
+}
+
+void SamplingGrid::extendWindow(
+    const double _begin_window[3],
+    const double _end_window[3])
+{
+#ifndef NDEBUG
+  for(size_t index=0;index < 3; ++index) {
+    // check that we truly have to extend the window
+    ASSERT ( begin_window[index] >= _begin_window[index],
+        "SamplingGrid::extendWindow() - component "+toString(index)+
+        " of window start is greater than old value.");
+    ASSERT ( end_window[index] <= _end_window[index],
+        "SamplingGrid::extendWindow() - component "+toString(index)+
+        " of window end is less than old value.");
+
+    // check that we are still less than domain
+    ASSERT ( _begin_window[index] >= begin[index],
+        "SamplingGrid::extendWindow() - component "+toString(index)+
+        " of window start is less than domain start.");
+    ASSERT ( _end_window[index] <= end[index],
+        "SamplingGrid::extendWindow() - component "+toString(index)+
+        " of window end is greater than domain end.");
+  }
+#endif
+  // copy old window size and values
+  double old_begin_window[3];
+  double old_end_window[3];
+  for(size_t index=0;index<3;++index) {
+    old_begin_window[index] = begin_window[index];
+    old_end_window[index] = end_window[index];
+  }
+  sampledvalues_t old_values(sampled_grid);
+  // set new window
+  setWindow(_begin_window,_end_window);
+  // now extend it ...
+  addOntoWindow(old_begin_window, old_end_window, old_values, +1.);
+  LOG(2, "DEBUG: Grid after extension is " << sampled_grid << ".");
+}
+
+void SamplingGrid::shrinkWindow(
+    const double _begin_window[3],
+    const double _end_window[3])
+{
+#ifndef NDEBUG
+  for(size_t index=0;index < 3; ++index) {
+    // check that we truly have to shrink the window
+    ASSERT ( begin_window[index] <= _begin_window[index],
+        "SamplingGrid::shrinkWindow() - component "+toString(index)+
+        " of window start is less than old value.");
+    ASSERT ( end_window[index] >= _end_window[index],
+        "SamplingGrid::shrinkWindow() - component "+toString(index)+
+        " of window end is greater than old value.");
+
+    // check that we are still less than domain
+    ASSERT ( _begin_window[index] >= begin[index],
+        "SamplingGrid::shrinkWindow() - component "+toString(index)+
+        " of window start is less than domain start.");
+    ASSERT ( _end_window[index] <= end[index],
+        "SamplingGrid::shrinkWindow() - component "+toString(index)+
+        " of window end is greater than domain end.");
+  }
+#endif
+  // copy old window size and values
+  double old_begin_window[3];
+  double old_end_window[3];
+  for(size_t index=0;index<3;++index) {
+    old_begin_window[index] = begin_window[index];
+    old_end_window[index] = end_window[index];
+  }
+  sampledvalues_t old_values(sampled_grid);
+  // set new window
+  setWindow(_begin_window,_end_window);
+  // now extend it ...
+  addIntoWindow(old_begin_window, old_end_window, old_values, +1.);
+  LOG(2, "DEBUG: Grid after extension is " << sampled_grid << ".");
+}
+
+static void addElements(
+    double &dest,
+    const double &source,
+    const double prefactor)
+{
+  dest += prefactor*(source);
+}
+
+void SamplingGrid::addOntoWindow(
+    const double _begin_window[3],
+    const double _end_window[3],
+    const sampledvalues_t &_sampled_grid,
+    const double prefactor)
+{
+  addWindowOntoWindow(
+      begin_window,
+      end_window,
+      _begin_window,
+      _end_window,
+      sampled_grid,
+      _sampled_grid,
+      boost::bind(addElements, _1, _2, boost::cref(prefactor)),
+      destwindow);
+}
+
+void SamplingGrid::addIntoWindow(
+    const double _begin_window[3],
+    const double _end_window[3],
+    const sampledvalues_t &_sampled_grid,
+    const double prefactor)
+{
+  addWindowOntoWindow(
+      _begin_window,
+      _end_window,
+      begin_window,
+      end_window,
+      sampled_grid,
+      _sampled_grid,
+      boost::bind(addElements, _1, _2, boost::cref(prefactor)),
+      sourcewindow);
+}
+
+void SamplingGrid::addWindowOntoWindow(
+    const double larger_wbegin[3],
+    const double larger_wend[3],
+    const double smaller_wbegin[3],
+    const double smaller_wend[3],
+    sampledvalues_t &dest_sampled_grid,
+    const sampledvalues_t &source_sampled_grid,
+    boost::function<void (double &, const double &)> op,
+    enum eLargerWindow larger_window)
+{
+#ifndef NDEBUG
+  for(size_t index=0;index<3;++index) {
+    ASSERT( smaller_wbegin[index] >= larger_wbegin[index],
+        "SamplingGrid::addWindowOntoWindow() - given smaller window starts earlier than larger window in component "
+        +toString(index)+".");
+    ASSERT( smaller_wend[index] <= larger_wend[index],
+        "SamplingGrid::addWindowOntoWindow() - given smaller window ends later than larger window in component "
+        +toString(index)+".");
+  }
+#endif
+  // the only issue are indices
+  const size_t gridpoints_axis = getGridPointsPerAxis();
+  size_t pre_offset[3];
+  size_t post_offset[3];
+  size_t length[3];
+  size_t total[3];
+  const double round_offset =
+      (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
+          0.5 : 0.; // need offset to get to round_toward_nearest behavior
+  for(size_t index=0;index<3;++index) {
+    // we refrain from using floor/ceil as the window's starts and ends,
+    // the grids have to be compatible (equal level), should always be on
+    // discrete grid point locations.
+    const double delta = (double)gridpoints_axis/(end[index] - begin[index]);
+    // delta is conversion factor from box length to discrete length, i.e. number of points
+    pre_offset[index] = delta*(smaller_wbegin[index] - larger_wbegin[index])+round_offset;
+    length[index] = delta*(smaller_wend[index] - smaller_wbegin[index])+round_offset;
+    post_offset[index] = delta*(larger_wend[index] - smaller_wend[index])+round_offset;
+    total[index] = delta*(larger_wend[index] - larger_wbegin[index])+round_offset;
+    // total is used as safe-guard against loss due to discrete conversion
+    ASSERT( pre_offset[index]+post_offset[index]+length[index] == total[index],
+        "SamplingGrid::addWindowOntoWindow() - pre, post, and length don't sum up to total for "
+        +toString(index)+"th component.");
+  }
+  // assert that calculated lengths match with given vector sizes
+#ifndef NDEBUG
+  const size_t calculated_size = length[0]*length[1]*length[2];
+  if (larger_window == destwindow) {
+    ASSERT( calculated_size == source_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - not enough source sampled values given: "
+        +toString(calculated_size)+" != "+toString(source_sampled_grid.size())+".");
+    ASSERT( calculated_size <= dest_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - not enough sampled values available: "
+        +toString(calculated_size)+" <= "+toString(dest_sampled_grid.size())+".");
+  } else {
+    ASSERT( calculated_size == dest_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - not enough dest sampled values given: "
+        +toString(calculated_size)+" != "+toString(dest_sampled_grid.size())+".");
+    ASSERT( calculated_size <= source_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - not enough source sampled values available: "
+        +toString(calculated_size)+" <= "+toString(source_sampled_grid.size())+".");
+  }
+  const size_t total_size = total[0]*total[1]*total[2];
+  if (larger_window == destwindow) {
+    ASSERT( total_size == dest_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present dest points: "
+        +toString(total_size)+" != "+toString(dest_sampled_grid.size())+".");
+  } else {
+    ASSERT( total_size == source_sampled_grid.size(),
+        "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present source points: "
+        +toString(total_size)+" != "+toString(source_sampled_grid.size())+".");
+  }
+#endif
+  size_t N[3];
+//  size_t counter = 0;
+  sampledvalues_t::iterator destiter = dest_sampled_grid.begin();
+  sampledvalues_t::const_iterator sourceiter = source_sampled_grid.begin();
+  if (larger_window == destwindow)
+    std::advance(destiter, pre_offset[0]*total[1]*total[2]);
+  else
+    std::advance(sourceiter, pre_offset[0]*total[1]*total[2]);
+  for(N[0]=0; N[0] < length[0]; ++N[0]) {
+    if (larger_window == destwindow)
+      std::advance(destiter, pre_offset[1]*total[2]);
+    else
+      std::advance(sourceiter, pre_offset[1]*total[2]);
+    for(N[1]=0; N[1] < length[1]; ++N[1]) {
+      if (larger_window == destwindow)
+        std::advance(destiter, pre_offset[2]);
+      else
+        std::advance(sourceiter, pre_offset[2]);
+      for(N[2]=0; N[2] < length[2]; ++N[2]) {
+        ASSERT( destiter != dest_sampled_grid.end(),
+            "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
+        ASSERT( sourceiter != source_sampled_grid.end(),
+            "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
+        op(*destiter, *sourceiter);
+        ++destiter;
+        ++sourceiter;
+      }
+      if (larger_window == destwindow)
+        std::advance(destiter, post_offset[2]);
+      else
+        std::advance(sourceiter, post_offset[2]);
+    }
+    if (larger_window == destwindow)
+      std::advance(destiter, post_offset[1]*total[2]);
+    else
+      std::advance(sourceiter, post_offset[1]*total[2]);
+  }
+#ifndef NDEBUG
+  if (larger_window == destwindow)
+    std::advance(destiter, post_offset[0]*total[1]*total[2]);
+  else
+    std::advance(sourceiter, post_offset[0]*total[1]*total[2]);
+  ASSERT( destiter == dest_sampled_grid.end(),
+      "SamplingGrid::addWindowOntoWindow() - destiter is not at end of window.");
+  ASSERT( sourceiter == source_sampled_grid.end(),
+      "SamplingGrid::addWindowOntoWindow() - sourceiter is not at end of window.");
+#endif
+  LOG(2, "DEBUG: Grid after adding other is " << dest_sampled_grid << ".");
+}
+
+std::ostream & operator<<(std::ostream &ost, const SamplingGrid& other)
+{
+  ost << "SamplingGrid";
+  ost << " starting at " << other.begin[0] << "," << other.begin[1] << "," << other.begin[2];
+  ost << " ending at " << other.end[0] << "," << other.end[1] << "," << other.end[2];
+  ost << ", window starting at " << other.begin_window[0] << "," << other.begin_window[1] << "," << other.begin_window[2];
+  ost << ", window ending at " << other.end_window[0] << "," << other.end_window[1] << "," << other.end_window[2];
+  ost << ", level of " << other.level;
+  ost << " and integrated value of " << other.integral();
+  return ost;
+}
+
+template<> SamplingGrid ZeroInstance<SamplingGrid>()
+{
+  SamplingGrid returnvalue;
+  return returnvalue;
+}
+
+// we need to explicitly instantiate the serialization functions as
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_IMPLEMENT(SamplingGrid)
Index: src/Fragmentation/SetValues/SamplingGrid.hpp
===================================================================
--- src/Fragmentation/SetValues/SamplingGrid.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/SamplingGrid.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,416 @@
+/*
+ * SamplingGrid.hpp
+ *
+ *  Created on: 25.07.2012
+ *      Author: heber
+ */
+
+#ifndef SAMPLINGGRID_HPP_
+#define SAMPLINGGRID_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/function.hpp>
+#include <iosfwd>
+#include <vector>
+
+#include "boost/serialization/export.hpp"
+#include "boost/serialization/vector.hpp"
+
+#include "Fragmentation/SetValues/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 for full window.
+   *
+   * Here, the window of sampled values spans the given domain.
+   *
+   * \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);
+
+  /** Constructor for class SamplingGrid for empty window.
+   *
+   * Here, the window is initially of size zero.
+   *
+   * \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$
+   */
+  SamplingGrid(const double _begin[3],
+      const double _end[3],
+      const int _level);
+
+  /** Copy constructor for class SamplingGrid with full window from SamplingGridProperties.
+   *
+   * Here, the window is initially empty.
+   *
+   * \param _props properties to copy
+   */
+  SamplingGrid(const SamplingGridProperties &_props);
+
+  /** Copy constructor for class SamplingGrid with empty window from SamplingGridProperties.
+   *
+   * Here, the window must span the whole domain
+   *
+   * \param _props properties to copy
+   * \param _sampled_grid sample points
+   */
+  SamplingGrid(
+      const SamplingGridProperties &_props,
+      const sampledvalues_t &_sampled_grid);
+
+  /** Copy constructor for class SamplingGrid.
+   *
+   * The window of sampled values corresponds to the one on \a _grid.
+   *
+   * \param _grid grid to copy
+   */
+  SamplingGrid(const SamplingGrid &_grid);
+
+  /** default cstor.
+   */
+  SamplingGrid();
+
+  virtual ~SamplingGrid();
+
+  /** Checks whether another instance is consistent with this one.
+   *
+   *  \note Conistency is stronger as grids must have the same window.
+   *
+   * \param _props other properties to check against
+   * \return true - are consistent, false - else
+   */
+  bool isCongruent(const SamplingGrid &_props) const;
+
+  /** 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.
+   *
+   * With non-zero windows we have to pay some more attention here.
+   * Now, the windows may not be congruent but we have to find the intersection
+   * of the two windows and then construct the new window only of this size and
+   * multiply. The trick then is not to copy&change the other grid but to
+   * access it properly.
+   *
+   * \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 number of gridpoints of the discrete mesh for the current
+   * window size for given axis \axis.
+   *
+   * \param axis axis to calculate number of gridpoints for
+   * \return number of gridpoints along this axis
+   */
+  const size_t getWindowGridPointsPerAxis(const size_t axis) 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 length of the domain for the given \a axis.
+   *
+   * \param axis axis for which to get step length
+   * \return domain length for the given axis, i.e. end - begin
+   */
+  const double getTotalLengthPerAxis(const size_t axis) const;
+
+  /** Returns the length of the window for the given \a axis.
+   *
+   * \param axis axis for which to get step length
+   * \return window length for the given axis, i.e. end - begin
+   */
+  const double getWindowLengthPerAxis(const size_t axis) const;
+
+  /** Returns the real step length from one discrete grid point to the next.
+   *
+   * \param axis axis for which to get step length
+   * \return step length for the given axis, as domain length over getGridPointsPerAxis()
+   */
+  const double getDeltaPerAxis(const size_t axis) const;
+
+  /** Returns the volume of the domain covered by the current window.
+   *
+   * @return volume of window
+   */
+  const double getWindowVolume() const;
+
+  /** 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]);
+
+private:
+  /** 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]);
+
+  /** Shrinks the window while keeping the values.
+   *
+   * \param _begin_window new start of window
+   * \param _end_window new end of window
+   */
+  void shrinkWindow(const double _begin_window[3], const double _end_window[3]);
+
+  /** Adds another (smaller) 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
+   * @param prefactor +1. is then addition, -1. is subtraction.
+   */
+  void addOntoWindow(
+      const double _begin_window[3],
+      const double _end_window[3],
+      const sampledvalues_t &_sampled_grid,
+      const double prefactor);
+
+  /** Adds another (larger) window into the one in this instance.
+   *
+   * \note We assume here that the given window is larger than this one.
+   *
+   * \param _begin_window start of other window
+   * \param _end_window end of other window
+   * \param _sampled_grid other set of sampled values
+   * @param prefactor +1. is then addition, -1. is subtraction.
+   */
+  void addIntoWindow(
+      const double _begin_window[3],
+      const double _end_window[3],
+      const sampledvalues_t &_sampled_grid,
+      const double prefactor);
+
+  /** Enum to help in addWindowOntoWindow() decide which iterator needs to be
+   * advanced.
+   */
+  enum eLargerWindow {
+    destwindow,
+    sourcewindow
+  };
+
+  /** Helper function to copy one (larger) window into a (smaller) window.
+   *
+   * \note Why do we need the extra \a choice? We need to know which window
+   * tuples is associated with which sampled values that are constrained by
+   * one of them being constant, hence the source values
+   *
+   * \param larger_wbegin start of larger window
+   * \param larger_wend end of larger window
+   * \param smaller_wbegin start of smaller window
+   * \param smaller_wend end of smaller window
+   * \param dest_sampled_grid larger set of sampled values
+   * \param source_sampled_grid smaller set of sampled values
+   * \param op operation to perform with the two elements
+   * \param larger_window indicates which is the larger window
+   */
+  void addWindowOntoWindow(
+      const double larger_wbegin[3],
+      const double larger_wend[3],
+      const double smaller_wbegin[3],
+      const double smaller_wend[3],
+      sampledvalues_t &dest_sampled_grid,
+      const sampledvalues_t &source_sampled_grid,
+      boost::function<void (double &, const double &)> op,
+      enum eLargerWindow larger_window);
+
+  /** 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]);
+
+  /** Helper function to get point at grid point for given \a axis and less than value.
+   *
+   * @param value value to find nearest grid point to
+   * @param axis axis of the value
+   * @return nearest lower grid point
+   */
+  double getNearestLowerGridPoint(
+      const double value, const size_t axis) const;
+
+  /** Helper function to get point at grid point for given \a axis and greater than value.
+   *
+   * @param value value to find nearest grid point to
+   * @param axis axis of the value
+   * @return nearest lower grid point
+   */
+  double getNearestHigherGridPoint(
+      const double value, const size_t axis) const;
+
+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 <typename Archive>
+  void serialize(Archive& ar, const unsigned int version)
+  {
+    ar & boost::serialization::base_object<SamplingGridProperties>(*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<typename T> T ZeroInstance();
+template<> SamplingGrid ZeroInstance<SamplingGrid>();
+
+// 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)
+
+// define inline functions
+#include "SamplingGrid_inline.hpp"
+
+#endif /* SAMPLINGGRID_HPP_ */
Index: src/Fragmentation/SetValues/SamplingGridProperties.cpp
===================================================================
--- src/Fragmentation/SetValues/SamplingGridProperties.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/SamplingGridProperties.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,103 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SamplingGrid.cpp
+ *
+ *  Created on: 25.07.2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include headers that implement a archive in simple text format
+// otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Fragmentation/SetValues/SamplingGridProperties.hpp"
+
+SamplingGridProperties::SamplingGridProperties(
+    const double _begin[3],
+    const double _end[3],
+    const int _level) :
+  level(_level)
+{
+  for(size_t i=0; i<3; ++i) {
+    begin[i] = _begin[i];
+    end[i] = _end[i];
+  }
+}
+
+SamplingGridProperties::SamplingGridProperties(const SamplingGridProperties &_props) :
+  level(_props.level)
+{
+  for(size_t i=0; i<3; ++i) {
+    begin[i] = _props.begin[i];
+    end[i] = _props.end[i];
+  }
+}
+
+SamplingGridProperties::SamplingGridProperties() :
+  level(0)
+{
+  for(size_t i=0; i<3; ++i) {
+    begin[i] = 0.;
+    end[i] = 0.;
+  }
+}
+
+SamplingGridProperties::~SamplingGridProperties()
+{}
+
+SamplingGridProperties& SamplingGridProperties::operator=(const SamplingGridProperties& other)
+{
+  // check for self-assignment
+  if (this != &other) {
+    for(size_t index=0; index<3; ++index) {
+      begin[index] = other.begin[index];
+      end[index] = other.end[index];
+    }
+    level = other.level;
+  }
+  return *this;
+}
+
+bool SamplingGridProperties::operator==(const SamplingGridProperties &_props) const
+{
+  bool status = true;
+  for (size_t i=0; i<3; ++i) {
+    status &= begin[i] == _props.begin[i];
+    status &= end[i] == _props.end[i];
+  }
+  status &= level == _props.level;
+  return status;
+}
+
+// we need to explicitly instantiate the serialization functions as
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_IMPLEMENT(SamplingGridProperties)
Index: src/Fragmentation/SetValues/SamplingGridProperties.hpp
===================================================================
--- src/Fragmentation/SetValues/SamplingGridProperties.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/SamplingGridProperties.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,109 @@
+/*
+ * SamplingGridProperties.hpp
+ *
+ *  Created on: 25.07.2012
+ *      Author: heber
+ */
+
+#ifndef SAMPLINGGRIDPROPERTIES_HPP_
+#define SAMPLINGGRIDPROPERTIES_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "boost/serialization/export.hpp"
+#include "boost/serialization/array.hpp"
+
+/** This class stores a sample function on a three-dimensional grid.
+ *
+ */
+class SamplingGridProperties {
+public:
+  /** Constructor for class SamplingGridProperties.
+   *
+   * \param _begin offset of grid
+   * \param _end edge length per axis
+   * \param _level number of gridpoints as \f$2^{\mathrm{level}}\f$ per unit(!) length
+   */
+  SamplingGridProperties(
+      const double _begin[3],
+      const double _end[3],
+      const int _level);
+
+  /** Copy constructor for class SamplingGridProperties.
+   *
+   * \param _props instance to copy from
+   */
+  SamplingGridProperties(const SamplingGridProperties &_props);
+
+  /** Default constructor.
+   */
+  SamplingGridProperties();
+
+  virtual ~SamplingGridProperties();
+
+  /** Checks whether another instance is compatible with this one.
+   *
+   *  \note Compatibility implies only that both grids have same grid spacing.
+   *
+   * \param _props other properties to check against
+   * \return true - are compatible, false - else
+   */
+  bool isCompatible(const SamplingGridProperties &_props) const
+  {
+    return level == _props.level;
+  }
+
+  /** Assignment operator.
+   *
+   * \param other other instance to assign ourselves to
+   */
+  SamplingGridProperties& operator=(const SamplingGridProperties& other);
+
+  /** Equality operator for class SamplingGridProperties.
+   *
+   * \param _props other object to compare to
+   */
+  bool operator==(const SamplingGridProperties &_props) const;
+
+  /** Inequality operator for class SamplingGridProperties.
+   *
+   * \param _props other object to compare to
+   */
+  bool operator!=(const SamplingGridProperties &_props) const
+  {
+    return (!(*this == _props));
+  }
+
+public:
+  //!> offset of grid
+  double begin[3];
+  //!> size of grid, i.e. edge length per axis of domain
+  double end[3];
+  //!> level, i.e. \f$2^{\mathrm{level}}\f$ grid points per axis per unit(!) length
+  int level;
+
+private:
+
+  friend class boost::serialization::access;
+  // serialization
+  template <typename Archive>
+  void serialize(Archive& ar, const unsigned int version)
+  {
+    int i;
+    for (i=0; i<3; ++i)
+      ar & begin[i];
+    for (i=0; i<3; ++i)
+      ar & end[i];
+    ar & level;
+  }
+
+};
+
+// we need to give this class a unique key for serialization
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_KEY(SamplingGridProperties)
+
+#endif /* SAMPLINGGRIDPROPERTIES_HPP_ */
Index: src/Fragmentation/SetValues/SamplingGrid_inline.hpp
===================================================================
--- src/Fragmentation/SetValues/SamplingGrid_inline.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/SamplingGrid_inline.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,106 @@
+/*
+ * SamplingGrid_inline.hpp
+ *
+ *  Created on: Jan 27, 2013
+ *      Author: heber
+ */
+
+#ifndef SAMPLINGGRID_INLINE_HPP_
+#define SAMPLINGGRID_INLINE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SamplingGrid.hpp"
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const double SamplingGrid::getVolume() const
+{
+  double volume = 1.;
+  for (size_t i=0;i<3;++i)
+    volume *= end[i]-begin[i];
+  return volume;
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const double SamplingGrid::getWindowVolume() const
+{
+  double volume = 1.;
+  for (size_t i=0;i<3;++i)
+    volume *= end_window[i]-begin_window[i];
+  return volume;
+}
+
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const size_t SamplingGrid::getTotalGridPoints() const
+{
+  return pow(getGridPointsPerAxis(),3);
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const size_t SamplingGrid::getGridPointsPerAxis() const
+{
+  return pow(2, level);
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const double SamplingGrid::getDeltaPerAxis(const size_t axis) const
+{
+  return getTotalLengthPerAxis(axis)/(double)getGridPointsPerAxis();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const double SamplingGrid::getTotalLengthPerAxis(const size_t axis) const
+{
+  return (end[axis] - begin[axis]);
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const double SamplingGrid::getWindowLengthPerAxis(const size_t axis) const
+{
+  return (end_window[axis] - begin_window[axis]);
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+const size_t SamplingGrid::getWindowGridPoints() const
+{
+  return getWindowGridPointsPerAxis(0)
+      *getWindowGridPointsPerAxis(1)
+      *getWindowGridPointsPerAxis(2);
+}
+
+
+#ifdef HAVE_INLINE
+inline
+#endif
+void SamplingGrid::setDomainSize(
+    const double _begin[3],
+    const double _end[3])
+{
+  for (size_t index=0;index<3;++index) {
+    begin[index] = _begin[index];
+    end[index] = _end[index];
+  }
+}
+
+
+#endif /* SAMPLINGGRID_INLINE_HPP_ */
Index: src/Fragmentation/SetValues/unittests/Makefile.am
===================================================================
--- src/Fragmentation/SetValues/unittests/Makefile.am	(revision 4a77be7c74807798597478c1e2a88d09178390fe)
+++ src/Fragmentation/SetValues/unittests/Makefile.am	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -5,15 +5,21 @@
 	../Fragmentation/SetValues/unittests/FragmentUnitTest.cpp \
 	../Fragmentation/SetValues/unittests/HistogramUnitTest.cpp \
-	../Fragmentation/SetValues/unittests/IndexedVectorsUnitTest.cpp
+	../Fragmentation/SetValues/unittests/IndexedVectorsUnitTest.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridUnitTest.cpp
 
 FRAGMENTATIONSETVALUESTESTSHEADERS = \
 	../Fragmentation/SetValues/unittests/FragmentUnitTest.hpp \
 	../Fragmentation/SetValues/unittests/HistogramUnitTest.hpp \
-	../Fragmentation/SetValues/unittests/IndexedVectorsUnitTest.hpp
+	../Fragmentation/SetValues/unittests/IndexedVectorsUnitTest.hpp \
+	../Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.hpp \
+	../Fragmentation/SetValues/unittests/SamplingGridUnitTest.hpp
 
 FRAGMENTATIONSETVALUESTESTS = \
 	FragmentUnitTest \
-  HistogramUnitTest \
-  IndexedVectorsUnitTest
+	HistogramUnitTest \
+	IndexedVectorsUnitTest \
+	SamplingGridPropertiesUnitTest \
+	SamplingGridUnitTest
 
 TESTS += $(FRAGMENTATIONSETVALUESTESTS)
@@ -32,5 +38,4 @@
 	${FRAGMENTATIONSETVALUESLIBS} \
 	$(BOOST_SERIALIZATION_LDFLAGS) $(BOOST_SERIALIZATION_LIBS)
-	
 
 HistogramUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
@@ -44,3 +49,13 @@
 IndexedVectorsUnitTest_LDADD = ${FRAGMENTATIONSETVALUESLIBS}
 
+SamplingGridPropertiesUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.hpp
+SamplingGridPropertiesUnitTest_LDADD = ${FRAGMENTATIONSETVALUESLIBS}
+
+SamplingGridUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridUnitTest.cpp \
+	../Fragmentation/SetValues/unittests/SamplingGridUnitTest.hpp
+SamplingGridUnitTest_LDADD = ${FRAGMENTATIONSETVALUESLIBS}
+
 #AUTOMAKE_OPTIONS = parallel-tests
Index: src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.cpp
===================================================================
--- src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,125 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SamplingGridPropertiesUnitTest.cpp
+ *
+ *  Created on: Jul 29, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace std;
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "SamplingGridPropertiesUnitTest.hpp"
+
+#include "CodePatterns/Assert.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( SamplingGridPropertiesTest );
+
+
+void SamplingGridPropertiesTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // create the grid
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 1., 1., 1. };
+  props = new SamplingGridProperties(begin, end, 2);
+}
+
+
+void SamplingGridPropertiesTest::tearDown()
+{
+  delete props;
+}
+
+/** UnitTest for isCompatible()
+ */
+void SamplingGridPropertiesTest::isCompatible_Test()
+{
+  const double begin[3] = { 0., 0., 0. };
+  const double otherbegin[3] = { 1., 0.1, -0.5 };
+  const double end[3] = { 1., 1., 1. };
+  const double otherend[3] = { 2., 2., 2. };
+
+  // create other props
+  SamplingGridProperties sameprops(begin, end, 2);
+  SamplingGridProperties otherprops(otherbegin, end, 2);
+  SamplingGridProperties anotherprops(begin, otherend, 2);
+  SamplingGridProperties moreotherprops(begin, end, 4);
+
+  // only checks for same level
+  CPPUNIT_ASSERT( props->isCompatible(*props) );
+  CPPUNIT_ASSERT( props->isCompatible(sameprops) );
+  CPPUNIT_ASSERT( sameprops.isCompatible(*props) );
+  CPPUNIT_ASSERT( props->isCompatible(otherprops) );
+  CPPUNIT_ASSERT( otherprops.isCompatible(*props) );
+  CPPUNIT_ASSERT( props->isCompatible(anotherprops) );
+  CPPUNIT_ASSERT( anotherprops.isCompatible(*props) );
+  CPPUNIT_ASSERT( !props->isCompatible(moreotherprops) );
+  CPPUNIT_ASSERT( !moreotherprops.isCompatible(*props) );
+}
+
+/** UnitTest for operator==()
+ */
+void SamplingGridPropertiesTest::equality_Test()
+{
+  const double begin[3] = { 0., 0., 0. };
+  const double otherbegin[3] = { 1., 0.1, -0.5 };
+  const double end[3] = { 1., 1., 1. };
+  const double otherend[3] = { 2., 2., 2. };
+
+  // create other props
+  SamplingGridProperties sameprops(begin, end, 2);
+  SamplingGridProperties otherprops(otherbegin, end, 2);
+  SamplingGridProperties anotherprops(begin, otherend, 2);
+  SamplingGridProperties moreotherprops(begin, end, 4);
+
+  // check for same level, begin, and end
+  CPPUNIT_ASSERT( *props == *props );
+  CPPUNIT_ASSERT( *props == sameprops );
+  CPPUNIT_ASSERT( sameprops == *props);
+  CPPUNIT_ASSERT( *props != otherprops);
+  CPPUNIT_ASSERT( otherprops != *props);
+  CPPUNIT_ASSERT( *props != anotherprops );
+  CPPUNIT_ASSERT( anotherprops != *props );
+  CPPUNIT_ASSERT( *props != moreotherprops );
+  CPPUNIT_ASSERT( moreotherprops != *props );
+}
+
Index: src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.hpp
===================================================================
--- src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/unittests/SamplingGridPropertiesUnitTest.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,41 @@
+/*
+ * SamplingGridPropertiesUnitTest.hpp
+ *
+ *  Created on: Jul 29, 2012
+ *      Author: heber
+ */
+
+#ifndef SAMPLINGGRIDPROPERTIESUNITTEST_HPP_
+#define SAMPLINGGRIDPROPERTIESUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "Fragmentation/SetValues/SamplingGridProperties.hpp"
+
+/********************************************** Test classes **************************************/
+
+class SamplingGridPropertiesTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( SamplingGridPropertiesTest) ;
+    CPPUNIT_TEST ( isCompatible_Test );
+    CPPUNIT_TEST ( equality_Test );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void isCompatible_Test();
+      void equality_Test();
+
+private:
+      SamplingGridProperties *props;
+
+};
+
+#endif /* SAMPLINGGRIDPROPERTIESUNITTEST_HPP_ */
Index: src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.cpp
===================================================================
--- src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.cpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,422 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SamplingGridUnitTest.cpp
+ *
+ *  Created on: Jul 29, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace std;
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "SamplingGridUnitTest.hpp"
+
+#include "CodePatterns/Assert.hpp"
+
+#include <boost/assign.hpp>
+#include <cmath>
+#include <numeric>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+using namespace boost::assign;
+
+/********************************************** Test classes **************************************/
+
+const double grid_value=1.;
+
+#define NUMBEROFSAMPLES(n) (size_t)(pow(pow(2,n),3))
+#define DOMAINVOLUME(l) (size_t)pow(l,3)
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( SamplingGridTest );
+
+
+void SamplingGridTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // create the grid
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 1., 1., 1. };
+  for (size_t i=0; i< DOMAINVOLUME(1)*NUMBEROFSAMPLES(2); ++i)
+    values += grid_value;
+  grid = new SamplingGrid(begin, end, 2, values);
+  CPPUNIT_ASSERT_EQUAL( grid_value, *(grid->sampled_grid.begin()) );
+}
+
+
+void SamplingGridTest::tearDown()
+{
+  delete grid;
+}
+
+/** UnitTest on compatible combination of props and values
+ */
+void SamplingGridTest::compatibleGrids_Test()
+{
+  // check illegal grid
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 2., 2., 2. };
+  SamplingGridProperties illegal_props(begin, end, 5);
+  SamplingGridProperties legal_props(begin, end, 2);
+  CPPUNIT_ASSERT( !grid->isCompatible(illegal_props) );
+  CPPUNIT_ASSERT( grid->isCompatible(legal_props) );
+  SamplingGrid::sampledvalues_t illegal_values;
+  for (size_t i=0; i< NUMBEROFSAMPLES(1); ++i)
+    illegal_values += 1.5;
+  SamplingGrid::sampledvalues_t legal_values;
+  for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
+    legal_values += 1.5;
+#ifndef NDEBUG
+  // throws because props and size of illegal_values don't match
+  std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, illegal_values), Assert::AssertionFailure );
+  std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(legal_props, illegal_values), Assert::AssertionFailure );
+  std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, legal_values), Assert::AssertionFailure );
+#endif
+  // check that grid is still the same
+  for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
+      iter != grid->sampled_grid.end(); ++iter)
+    CPPUNIT_ASSERT_EQUAL( grid_value, *iter );
+}
+
+/** UnitTest for isCongruent()
+ */
+void SamplingGridTest::isCongruent_Test()
+{
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 2., 2., 2. };
+  const double otherbegin[3] = { 0.1, 0.1, 0.1 };
+  const double otherend[3] = { 1., 1., 1. };
+  SamplingGridProperties illegal_begin_props(otherbegin, end, 5);
+  SamplingGridProperties illegal_end_props(begin, otherend, 5);
+  SamplingGridProperties illegal_level_props(begin, end, 5);
+  SamplingGridProperties legal_props(begin, end, 2);
+
+  // differing windows
+  const double begin_window[3] = { 0.5, 0.5, 0.5 };
+  const double end_window[3] = { 1., 1., 1. };
+  const double otherbegin_window[3] = { 0.45, 0.45, 0.45 };
+  const double otherend_window[3] = { 1.05, 1.05, 1.05 };
+
+  // check that incompatible grid are also incongruent
+  SamplingGrid default_grid(legal_props);
+  // note that we always construct a temporary SamplingGrid from given props
+  CPPUNIT_ASSERT( default_grid.isCompatible(illegal_begin_props) == default_grid.isCongruent(illegal_begin_props));
+  CPPUNIT_ASSERT( default_grid.isCompatible(illegal_end_props) == default_grid.isCongruent(illegal_end_props));
+  CPPUNIT_ASSERT( default_grid.isCompatible(illegal_level_props) == default_grid.isCongruent(illegal_level_props));
+  CPPUNIT_ASSERT( default_grid.isCompatible(legal_props) == default_grid.isCongruent(legal_props) );
+
+  default_grid.setWindowSize(begin, end);
+  // same window
+  {
+    SamplingGrid illegal_begin_grid(illegal_begin_props);
+    SamplingGrid illegal_end_grid(illegal_end_props);
+    SamplingGrid illegal_level_grid(illegal_level_props);
+    SamplingGrid legal_grid(legal_props);
+    illegal_begin_grid.setWindowSize(begin, end);
+    illegal_end_grid.setWindowSize(begin, end);
+    illegal_level_grid.setWindowSize(begin, end);
+    legal_grid.setWindowSize(begin, end);
+    CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(default_grid) );
+    CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(default_grid) );
+    CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(default_grid) );
+    CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
+  }
+
+  // different begin
+  {
+    SamplingGrid illegal_begin_grid(illegal_begin_props);
+    SamplingGrid illegal_end_grid(illegal_end_props);
+    SamplingGrid illegal_level_grid(illegal_level_props);
+    SamplingGrid legal_grid(legal_props);
+    illegal_begin_grid.setWindowSize(otherbegin_window, end);
+    illegal_end_grid.setWindowSize(otherbegin_window, end);
+    illegal_level_grid.setWindowSize(otherbegin_window, end);
+    legal_grid.setWindowSize(begin, end);
+    CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
+  }
+
+  // different end
+  {
+    SamplingGrid illegal_begin_grid(illegal_begin_props);
+    SamplingGrid illegal_end_grid(illegal_end_props);
+    SamplingGrid illegal_level_grid(illegal_level_props);
+    SamplingGrid legal_grid(legal_props);
+    illegal_begin_grid.setWindowSize(begin, otherend_window);
+    illegal_end_grid.setWindowSize(begin, otherend_window);
+    illegal_level_grid.setWindowSize(begin, otherend_window);
+    legal_grid.setWindowSize(begin, end);
+    CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
+  }
+
+  // different begin and end
+  {
+    SamplingGrid illegal_begin_grid(illegal_begin_props);
+    SamplingGrid illegal_end_grid(illegal_end_props);
+    SamplingGrid illegal_level_grid(illegal_level_props);
+    SamplingGrid legal_grid(legal_props);
+    illegal_begin_grid.setWindowSize(otherbegin_window, otherend_window);
+    illegal_end_grid.setWindowSize(otherbegin_window, otherend_window);
+    illegal_level_grid.setWindowSize(otherbegin_window, otherend_window);
+    legal_grid.setWindowSize(begin, end);
+    CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
+    CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
+  }
+}
+
+/** UnitTest for integral()
+ */
+void SamplingGridTest::integral_Test()
+{
+  double sum = 0.;
+  sum = std::accumulate( grid->sampled_grid.begin(), grid->sampled_grid.end(), sum );
+  CPPUNIT_ASSERT_EQUAL( sum*grid->getVolume()/grid->getWindowGridPoints(), grid->integral() );
+}
+
+/** UnitTest for getVolume()
+ */
+void SamplingGridTest::getVolume_Test()
+{
+  CPPUNIT_ASSERT_EQUAL( 1., grid->getVolume() );
+}
+
+/** UnitTest for getWindowSize()
+ */
+void SamplingGridTest::getWindowSize_Test()
+{
+  // check size of default grid
+  CPPUNIT_ASSERT_EQUAL( (size_t)(NUMBEROFSAMPLES(grid->level)), grid->getWindowGridPoints() );
+
+  // create another one and check its size, too
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 1., 1., 1. };
+  for (size_t level = 3; level<=6; ++level) {
+    values.clear();
+    for (size_t i=0; i< NUMBEROFSAMPLES(level); ++i)
+      values += grid_value;
+    delete grid;
+    // use other pointer in case something fails
+    SamplingGrid *tmpgrid = new SamplingGrid(begin, end, level, values);
+    grid = tmpgrid;
+    CPPUNIT_ASSERT_EQUAL( (size_t)NUMBEROFSAMPLES(level), grid->getWindowGridPoints() );
+  }
+}
+
+/** UnitTest for extendWindow()
+ */
+void SamplingGridTest::extendWindow_Test()
+{
+  // we have a grid with size of one, extend to twice the size and check
+  const double begin[3] = { 0., 0., 0. };
+  const double size = 2.;
+  const double end[3] = { size, size, size };
+  double offset[3];
+  for (offset[0] = 0.; offset[0] <= 1.; offset[0] += .5)
+    for (offset[1] = 0.; offset[1] <= 1.; offset[1] += .5)
+      for (offset[2] = 0.; offset[2] <= 1.; offset[2] += .5) {
+        const double window_begin[3] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
+        const double window_end[3] = { 1.+offset[0], 1.+offset[1], 1.+offset[2]};
+        SamplingGrid newgrid(begin, end, 2);
+        newgrid.setWindowSize(window_begin, window_end);
+        // resize values by hand to new window size. Otherwise they get zero'd.
+        newgrid.sampled_grid = values;
+        newgrid.sampled_grid.resize(NUMBEROFSAMPLES(1));
+        newgrid.extendWindow(begin, end);
+
+        // check integral
+        CPPUNIT_ASSERT_EQUAL(
+            grid_value/(NUMBEROFSAMPLES(grid->level)/NUMBEROFSAMPLES(grid->level)),
+            grid->integral()
+            );
+
+        // check number of points
+        CPPUNIT_ASSERT_EQUAL(
+            (size_t)NUMBEROFSAMPLES(grid->level),
+            grid->getWindowGridPoints()
+            );
+      }
+}
+
+/** UnitTest for extendWindow() with asymmetric values
+ */
+void SamplingGridTest::extendWindow_asymmetric_Test()
+{
+  std::cout << "SamplingGridTest::extendWindow_asymmetric_Test()" << std::endl;
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 2., 2., 2. };
+  double offset[3];
+  for (offset[0] = 0.; offset[0] <= 1.; offset[0] += .5)
+    for (offset[1] = 0.; offset[1] <= 1.; offset[1] += .5)
+      for (offset[2] = 0.; offset[2] <= 1.; offset[2] += .5) {
+        const double window_begin[3] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
+        const double window_end[3] = { 1.+offset[0], 1.+offset[1], 1.+offset[2]};
+        SamplingGrid newgrid(begin, end, 2);
+        CPPUNIT_ASSERT_EQUAL( (size_t)0, newgrid.getWindowGridPoints() );
+        newgrid.setWindowSize(window_begin, window_end);
+        // window size is only half of domain size
+        const size_t max_samples = NUMBEROFSAMPLES(newgrid.level)*pow(0.5,3);
+        for (size_t i=0; i< max_samples; ++i)
+          newgrid.sampled_grid += grid_value*i;
+        const size_t sum_weight = (max_samples)*(max_samples-1)/2;
+        const double integral = newgrid.integral();
+        newgrid.extendWindow(begin, end);
+
+        // check that integral has remained the same
+        CPPUNIT_ASSERT_EQUAL( integral, newgrid.integral() );
+        CPPUNIT_ASSERT_EQUAL( grid_value*sum_weight/DOMAINVOLUME(2), newgrid.integral() );
+      }
+}
+
+/** UnitTest for addOntoWindow()
+ */
+void SamplingGridTest::addOntoWindow_Test()
+{
+  // first window is from (0,0,0) to (1,1,1)
+  CPPUNIT_ASSERT_EQUAL( 1.*grid_value, grid->integral() );
+
+  // create values for half-sized window
+  values.clear();
+  for (size_t i=0; i< (size_t)pow(.5*pow(2,2),3); ++i)
+    values += grid_value;
+
+  // check that too large a window throws
+#ifndef NDEBUG
+  const double begin[3] = { .5, .5, .5 };
+  const double wrongend[3] = { 1.5, 1.5, 1.5 };
+  std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( grid->addOntoWindow(begin, wrongend, values, +1.), Assert::AssertionFailure );
+#endif
+
+  // create another window from (.5,.5,.5) to (1., 1., 1.)
+  double offset[3];
+  for (offset[0] = 0.; offset[0] <= .5; offset[0] += .5)
+    for (offset[1] = 0.; offset[1] <= .5; offset[1] += .5)
+      for (offset[2] = 0.; offset[2] <= .5; offset[2] += .5) {
+        const double window_begin[3] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
+        const double window_end[3] = { .5+offset[0], .5+offset[1], .5+offset[2]};
+
+        SamplingGrid newgrid(*grid);
+        // now perform working operation
+        newgrid.addOntoWindow(window_begin, window_end, values, +1.);
+
+        // check integral to be one and one eighth times the old value
+        CPPUNIT_ASSERT_EQUAL( (1.+pow(.5,3))*grid_value, newgrid.integral() );
+      }
+}
+
+/** UnitTest for addOntoWindow() with asymmetric values
+ */
+void SamplingGridTest::addOntoWindow_asymmetric_Test()
+{
+  const size_t size = grid->end[0]-grid->begin[0];
+  // check with asymmetric values
+  grid->sampled_grid.clear();
+  grid->sampled_grid.resize(DOMAINVOLUME(size)*NUMBEROFSAMPLES(grid->level), 0.);
+
+  for (size_t i=0;i<grid->level*(grid->end[0]-grid->begin[0]);++i)
+    grid->sampled_grid[(i*2+0)*2+0] += .5*grid_value;
+  for (size_t i=0;i<grid->level*(grid->end[1]-grid->begin[1]);++i)
+    grid->sampled_grid[(0*2+i)*2+0] += 1.*grid_value;
+  for (size_t i=0;i<grid->level*(grid->end[2]-grid->begin[2]);++i)
+    grid->sampled_grid[(0*2+0)*2+i] += 1.5*grid_value;
+
+  const double integral = grid->integral();
+
+  // now perform working operation
+  grid->addOntoWindow(grid->begin, grid->end, values, +1.);
+  // values is equal to integral of 1.
+  CPPUNIT_ASSERT_EQUAL( 1.+integral, grid->integral() );
+}
+
+/** UnitTest for operator+=()
+ */
+void SamplingGridTest::operatorPlusEqual_Test()
+{
+  // create other grid
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 1., 1., 1. };
+  SamplingGrid::sampledvalues_t othervalues;
+  const double othergrid_value = 1.5;
+  for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
+    othervalues += othergrid_value;
+  SamplingGrid othergrid(begin, end, 2, othervalues);
+  CPPUNIT_ASSERT_EQUAL( othergrid_value, *(othergrid.sampled_grid.begin()) );
+
+  // perform operation
+  CPPUNIT_ASSERT_NO_THROW( *grid += othergrid );
+
+  // check the contents of the grid
+  const double sum = grid_value+othergrid_value;
+  for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
+      iter != grid->sampled_grid.end(); ++iter)
+    CPPUNIT_ASSERT_EQUAL( sum, *iter );
+}
+
+/** UnitTest for operator-=()
+ */
+void SamplingGridTest::operatorMinusEqual_Test()
+{
+  // create other grid
+  const double begin[3] = { 0., 0., 0. };
+  const double end[3] = { 1., 1., 1. };
+  SamplingGrid::sampledvalues_t othervalues;
+  const double othergrid_value = 1.5;
+  for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
+    othervalues += othergrid_value;
+  SamplingGrid othergrid(begin, end, 2, othervalues);
+  CPPUNIT_ASSERT_EQUAL( othergrid_value, *(othergrid.sampled_grid.begin()) );
+
+  // perform operation
+  CPPUNIT_ASSERT_NO_THROW( *grid -= othergrid );
+
+  // check the contents of the grid
+  const double difference = grid_value-othergrid_value;
+  for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
+      iter != grid->sampled_grid.end(); ++iter)
+    CPPUNIT_ASSERT_EQUAL( difference, *iter );
+}
+
Index: src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.hpp
===================================================================
--- src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
+++ src/Fragmentation/SetValues/unittests/SamplingGridUnitTest.hpp	(revision 41040547d7cca2be6d6456c7796d5460aa47b92e)
@@ -0,0 +1,59 @@
+/*
+ * SamplingGridUnitTest.hpp
+ *
+ *  Created on: Jul 29, 2012
+ *      Author: heber
+ */
+
+#ifndef SAMPLINGGRIDUNITTEST_HPP_
+#define SAMPLINGGRIDUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "Fragmentation/SetValues/SamplingGrid.hpp"
+
+/********************************************** Test classes **************************************/
+
+class SamplingGridTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( SamplingGridTest) ;
+    CPPUNIT_TEST ( compatibleGrids_Test );
+    CPPUNIT_TEST ( operatorPlusEqual_Test );
+    CPPUNIT_TEST ( operatorMinusEqual_Test );
+    CPPUNIT_TEST ( isCongruent_Test );
+    CPPUNIT_TEST ( integral_Test );
+    CPPUNIT_TEST ( getVolume_Test );
+    CPPUNIT_TEST ( getWindowSize_Test );
+    CPPUNIT_TEST ( extendWindow_Test );
+    CPPUNIT_TEST ( extendWindow_asymmetric_Test );
+    CPPUNIT_TEST ( addOntoWindow_Test );
+    CPPUNIT_TEST ( addOntoWindow_asymmetric_Test );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void compatibleGrids_Test();
+      void isCongruent_Test();
+      void integral_Test();
+      void getVolume_Test();
+      void getWindowSize_Test();
+      void extendWindow_Test();
+      void extendWindow_asymmetric_Test();
+      void addOntoWindow_Test();
+      void addOntoWindow_asymmetric_Test();
+      void operatorPlusEqual_Test();
+      void operatorMinusEqual_Test();
+
+private:
+      SamplingGrid *grid;
+      SamplingGrid::sampledvalues_t values;
+};
+
+#endif /* SAMPLINGGRIDUNITTEST_HPP_ */
