Index: src/Jobs/Grid/SamplingGrid.cpp
===================================================================
--- src/Jobs/Grid/SamplingGrid.cpp	(revision fb3485c1da8740bf16cf170a4d8a9bbbac971be7)
+++ src/Jobs/Grid/SamplingGrid.cpp	(revision 313f836ec20460ebbd14dc92299a0031bcfe28d3)
@@ -135,12 +135,48 @@
 }
 
+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 (isCongruent(other)) {
-    sampledvalues_t::iterator iter = sampled_grid.begin();
-    sampledvalues_t::const_iterator otheriter = other.sampled_grid.begin();
-    for(; iter != sampled_grid.end(); ++iter, ++otheriter )
-      *iter *= (*otheriter);
+  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.");
@@ -334,4 +370,42 @@
 }
 
+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,
@@ -356,23 +430,40 @@
       _sampled_grid,
       boost::bind(addElements, _1, _2, boost::cref(prefactor)),
-      thiswindow);
+      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 wbegin[3],
-    const double wend[3],
-    const double other_wbegin[3],
-    const double other_wend[3],
-    sampledvalues_t &sampled_grid,
-    const sampledvalues_t &other_sampled_grid,
+    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 LargerWindow choice)
+    enum eLargerWindow larger_window)
 {
 #ifndef NDEBUG
   for(size_t index=0;index<3;++index) {
-    ASSERT( other_wbegin[index] >= wbegin[index],
+    ASSERT( smaller_wbegin[index] >= larger_wbegin[index],
         "SamplingGrid::addWindowOntoWindow() - given smaller window starts earlier than larger window in component "
         +toString(index)+".");
-    ASSERT( other_wend[index] <= wend[index],
+    ASSERT( smaller_wend[index] <= larger_wend[index],
         "SamplingGrid::addWindowOntoWindow() - given smaller window ends later than larger window in component "
         +toString(index)+".");
@@ -394,8 +485,8 @@
     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*(other_wbegin[index] - wbegin[index])+round_offset;
-    length[index] = delta*(other_wend[index] - other_wbegin[index])+round_offset;
-    post_offset[index] = delta*(wend[index] - other_wend[index])+round_offset;
-    total[index] = delta*(wend[index] - wbegin[index])+round_offset;
+    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],
@@ -406,63 +497,78 @@
 #ifndef NDEBUG
   const size_t calculated_size = length[0]*length[1]*length[2];
-  ASSERT( calculated_size == other_sampled_grid.size(),
-      "SamplingGrid::addWindowOntoWindow() - not enough sampled values given: "
-      +toString(calculated_size)+" != "+toString(other_sampled_grid.size())+".");
-  ASSERT( calculated_size <=  sampled_grid.size(),
-      "SamplingGrid::addWindowOntoWindow() - not enough sampled values available: "
-      +toString(calculated_size)+" <= "+toString(sampled_grid.size())+".");
+  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];
-  ASSERT( total_size == sampled_grid.size(),
-      "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present points: "
-      +toString(total_size)+" != "+toString(sampled_grid.size())+".");
+  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 griditer = sampled_grid.begin();
-  sampledvalues_t::const_iterator copyiter = other_sampled_grid.begin();
-  if (choice == thiswindow)
-    std::advance(griditer, pre_offset[0]*total[1]*total[2]);
+  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(copyiter, pre_offset[0]*total[1]*total[2]);
+    std::advance(sourceiter, pre_offset[0]*total[1]*total[2]);
   for(N[0]=0; N[0] < length[0]; ++N[0]) {
-    if (choice == thiswindow)
-      std::advance(griditer, pre_offset[1]*total[2]);
+    if (larger_window == destwindow)
+      std::advance(destiter, pre_offset[1]*total[2]);
     else
-      std::advance(copyiter, pre_offset[1]*total[2]);
+      std::advance(sourceiter, pre_offset[1]*total[2]);
     for(N[1]=0; N[1] < length[1]; ++N[1]) {
-      if (choice == thiswindow)
-        std::advance(griditer, pre_offset[2]);
+      if (larger_window == destwindow)
+        std::advance(destiter, pre_offset[2]);
       else
-        std::advance(copyiter, pre_offset[2]);
+        std::advance(sourceiter, pre_offset[2]);
       for(N[2]=0; N[2] < length[2]; ++N[2]) {
-        ASSERT( griditer != sampled_grid.end(),
-            "SamplingGrid::addWindowOntoWindow() - griditer is already at end of window.");
-        ASSERT( copyiter != other_sampled_grid.end(),
-            "SamplingGrid::addWindowOntoWindow() - griditer is already at end of window.");
-        op(*griditer, *copyiter);
-        ++griditer;
-        ++copyiter;
+        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 (choice == thiswindow)
-        std::advance(griditer, post_offset[2]);
+      if (larger_window == destwindow)
+        std::advance(destiter, post_offset[2]);
       else
-        std::advance(copyiter, post_offset[2]);
+        std::advance(sourceiter, post_offset[2]);
     }
-    if (choice == thiswindow)
-      std::advance(griditer, post_offset[1]*total[2]);
+    if (larger_window == destwindow)
+      std::advance(destiter, post_offset[1]*total[2]);
     else
-      std::advance(copyiter, post_offset[1]*total[2]);
+      std::advance(sourceiter, post_offset[1]*total[2]);
   }
 #ifndef NDEBUG
-  if (choice == thiswindow)
-    std::advance(griditer, post_offset[0]*total[1]*total[2]);
+  if (larger_window == destwindow)
+    std::advance(destiter, post_offset[0]*total[1]*total[2]);
   else
-    std::advance(copyiter, post_offset[0]*total[1]*total[2]);
-  ASSERT( griditer == sampled_grid.end(),
-      "SamplingGrid::addWindowOntoWindow() - griditer is not at end of window.");
-  ASSERT( copyiter == other_sampled_grid.end(),
-      "SamplingGrid::addWindowOntoWindow() - copyiter is not at end of window.");
+    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 " << sampled_grid << ".");
+  LOG(2, "DEBUG: Grid after adding other is " << dest_sampled_grid << ".");
 }
 
