diff --git a/Core/Aggregate/FormFactorCoherentPart.cpp b/Core/Aggregate/FormFactorCoherentPart.cpp
index 7394159ee604207cd5405ee9f03f149260836790..b2e1550b49268b8feeea8924828e95eaf492f345 100644
--- a/Core/Aggregate/FormFactorCoherentPart.cpp
+++ b/Core/Aggregate/FormFactorCoherentPart.cpp
@@ -14,22 +14,23 @@
 // ************************************************************************** //
 
 #include "FormFactorCoherentPart.h"
+#include "IFresnelMap.h"
 #include "IFormFactor.h"
 #include "SimulationElement.h"
 #include "WavevectorInfo.h"
-#include "ILayerSpecularInfo.h"
 #include "ILayerRTCoefficients.h"
 
 
 FormFactorCoherentPart::FormFactorCoherentPart(IFormFactor* p_ff)
-: mP_ff(p_ff)
+    : mP_ff(p_ff)
 {
 }
 
 FormFactorCoherentPart::FormFactorCoherentPart(const FormFactorCoherentPart& other)
-: mP_ff(other.mP_ff->clone())
+    : mP_ff(other.mP_ff->clone())
+    , mp_fresnel_map(other.mp_fresnel_map)
+    , m_layer_index(other.m_layer_index)
 {
-    setSpecularInfo(*other.mP_specular_info);
 }
 
 FormFactorCoherentPart::~FormFactorCoherentPart() {}
@@ -40,9 +41,9 @@ complex_t FormFactorCoherentPart::evaluate(const SimulationElement& sim_element)
                                sim_element.getWavelength());
 
     const std::unique_ptr<const ILayerRTCoefficients> P_in_coeffs(
-        mP_specular_info->getInCoefficients(sim_element));
+        mp_fresnel_map->getInCoefficients(sim_element, m_layer_index));
     const std::unique_ptr<const ILayerRTCoefficients> P_out_coeffs(
-        mP_specular_info->getOutCoefficients(sim_element));
+        mp_fresnel_map->getOutCoefficients(sim_element, m_layer_index));
     mP_ff->setSpecularInfo(P_in_coeffs.get(), P_out_coeffs.get());
     return mP_ff->evaluate(wavevectors);
 }
@@ -53,16 +54,17 @@ Eigen::Matrix2cd FormFactorCoherentPart::evaluatePol(const SimulationElement& si
                                sim_element.getWavelength());
 
     const std::unique_ptr<const ILayerRTCoefficients> P_in_coeffs(
-        mP_specular_info->getInCoefficients(sim_element));
+        mp_fresnel_map->getInCoefficients(sim_element, m_layer_index));
     const std::unique_ptr<const ILayerRTCoefficients> P_out_coeffs(
-        mP_specular_info->getOutCoefficients(sim_element));
+        mp_fresnel_map->getOutCoefficients(sim_element, m_layer_index));
     mP_ff->setSpecularInfo(P_in_coeffs.get(), P_out_coeffs.get());
     return mP_ff->evaluatePol(wavevectors);
 }
 
-void FormFactorCoherentPart::setSpecularInfo(const ILayerSpecularInfo& specular_info)
+void FormFactorCoherentPart::setSpecularInfo(const IFresnelMap* p_fresnel_map, size_t layer_index)
 {
-    mP_specular_info.reset(specular_info.clone());
+    mp_fresnel_map = p_fresnel_map;
+    m_layer_index = layer_index;
 }
 
 double FormFactorCoherentPart::radialExtension() const
diff --git a/Core/Aggregate/FormFactorCoherentPart.h b/Core/Aggregate/FormFactorCoherentPart.h
index 45a1f2b44329934192568e974140b14b72a7c4b6..bfff22b6fa2c397510842cfd5f975167052e4b2e 100644
--- a/Core/Aggregate/FormFactorCoherentPart.h
+++ b/Core/Aggregate/FormFactorCoherentPart.h
@@ -21,9 +21,9 @@
 #include "WinDllMacros.h"
 #include <memory>
 
+class IFresnelMap;
 class IFormFactor;
 class SimulationElement;
-class ILayerSpecularInfo;
 
 //! Information about single particle form factor and specular info of the embedding layer.
 //! @ingroup formfactors_internal
@@ -40,11 +40,12 @@ public:
     Eigen::Matrix2cd evaluatePol(const SimulationElement& sim_element) const;
 #endif
 
-    void setSpecularInfo(const ILayerSpecularInfo& specular_info);
+    void setSpecularInfo(const IFresnelMap* p_fresnel_map, size_t layer_index);
     double radialExtension() const;
 private:
     std::unique_ptr<IFormFactor> mP_ff;
-    std::unique_ptr<ILayerSpecularInfo> mP_specular_info; //!< R and T coefficients for DWBA
+    const IFresnelMap* mp_fresnel_map;
+    size_t m_layer_index;
 };
 
 #endif // FORMFACTORCOHERENTPART_H
diff --git a/Core/Aggregate/FormFactorCoherentSum.cpp b/Core/Aggregate/FormFactorCoherentSum.cpp
index 24648d869404bb869be670cd03fc8ec962d26e33..d7da22ee4feee4a38a860a792a0befe6d75367e5 100644
--- a/Core/Aggregate/FormFactorCoherentSum.cpp
+++ b/Core/Aggregate/FormFactorCoherentSum.cpp
@@ -17,7 +17,7 @@
 #include "IFormFactor.h"
 #include "SimulationElement.h"
 #include "WavevectorInfo.h"
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 #include "ILayerRTCoefficients.h"
 #include "Exceptions.h"
 
@@ -52,9 +52,9 @@ Eigen::Matrix2cd FormFactorCoherentSum::evaluatePol(const SimulationElement& sim
     return result;
 }
 
-void FormFactorCoherentSum::setSpecularInfo(const ILayerSpecularInfo& specular_info)
+void FormFactorCoherentSum::setSpecularInfo(const IFresnelMap* p_fresnel_map, size_t layer_index)
 {
-    m_parts[0].setSpecularInfo(specular_info);
+    m_parts[0].setSpecularInfo(p_fresnel_map, layer_index);
 }
 
 void FormFactorCoherentSum::scaleRelativeAbundance(double total_abundance)
diff --git a/Core/Aggregate/FormFactorCoherentSum.h b/Core/Aggregate/FormFactorCoherentSum.h
index 441d25e45f454140ef15243c7221769730de7e72..d34e44e315a8661d64bba58aaac4e8b8dc5bf45a 100644
--- a/Core/Aggregate/FormFactorCoherentSum.h
+++ b/Core/Aggregate/FormFactorCoherentSum.h
@@ -22,9 +22,9 @@
 #include "FormFactorCoherentPart.h"
 #include <vector>
 
+class IFresnelMap;
 class IFormFactor;
 class SimulationElement;
-class ILayerSpecularInfo;
 
 //! Information about particle form factor and abundance.
 //! @ingroup formfactors_internal
@@ -41,7 +41,8 @@ public:
     Eigen::Matrix2cd evaluatePol(const SimulationElement& sim_element) const;
 #endif
 
-    void setSpecularInfo(const ILayerSpecularInfo& specular_info);
+    void setSpecularInfo(const IFresnelMap* p_fresnel_map, size_t layer_index);
+
     double relativeAbundance() const { return m_abundance; }
     void scaleRelativeAbundance(double total_abundance);
     double radialExtension() const;
diff --git a/Core/Computation/IComputationTerm.cpp b/Core/Computation/IComputationTerm.cpp
index bd0388e2bdcb43140e332765b4bc89ce623db347..079de3deb676c68c72a023adfa0f0fc4c66d6e3b 100644
--- a/Core/Computation/IComputationTerm.cpp
+++ b/Core/Computation/IComputationTerm.cpp
@@ -16,21 +16,11 @@
 #include "IComputationTerm.h"
 
 
-IComputationTerm::IComputationTerm(const MultiLayer* p_multilayer)
+IComputationTerm::IComputationTerm(const MultiLayer* p_multilayer,
+                                   const IFresnelMap* p_fresnel_map)
     : mp_multilayer(p_multilayer)
-    , mp_full_fresnel_map(nullptr)
+    , mp_fresnel_map(p_fresnel_map)
 {}
 
 IComputationTerm::~IComputationTerm()
 {}
-
-void IComputationTerm::setSpecularInfo(
-        const FullFresnelMap* p_full_map)
-{
-    mp_full_fresnel_map = p_full_map;
-}
-
-const ILayerSpecularInfo* IComputationTerm::layerFresnelMap(size_t index) const
-{
-    return mp_full_fresnel_map->layerFresnelMap(index);
-}
diff --git a/Core/Computation/IComputationTerm.h b/Core/Computation/IComputationTerm.h
index 61587abe5159d77c55a805b774066810d1534df5..c44e79ebe874c9aa90a472113833fe64be20eadd 100644
--- a/Core/Computation/IComputationTerm.h
+++ b/Core/Computation/IComputationTerm.h
@@ -16,11 +16,9 @@
 #ifndef ICOMPUTATIONTERM_H
 #define ICOMPUTATIONTERM_H
 
-#include "FullFresnelMap.h"
 #include <vector>
 
-
-class ILayerSpecularInfo;
+class IFresnelMap;
 class MultiLayer;
 class ProgressHandler;
 class SimulationElement;
@@ -34,24 +32,20 @@ class SimulationOptions;
 class IComputationTerm
 {
 public:
-    IComputationTerm(const MultiLayer* p_multilayer);
+    IComputationTerm(const MultiLayer* p_multilayer, const IFresnelMap* p_fresnel_map);
     virtual ~IComputationTerm();
 
-    //! Sets magnetic reflection/transmission info for all layers
-    void setSpecularInfo(const FullFresnelMap* p_full_map);
-
     //! Calculate scattering intensity for each SimulationElement
     //! returns false if nothing needed to be calculated
-    virtual bool eval(const SimulationOptions& options,
+    virtual void eval(const SimulationOptions& options,
               ProgressHandler* progress,
               bool polarized,
               const std::vector<SimulationElement>::iterator& begin_it,
               const std::vector<SimulationElement>::iterator& end_it) const =0;
 
 protected:
-    const ILayerSpecularInfo* layerFresnelMap(size_t index) const;
     const MultiLayer* mp_multilayer;
-    const FullFresnelMap* mp_full_fresnel_map;
+    const IFresnelMap* mp_fresnel_map;
 };
 
 #endif // ICOMPUTATIONTERM_H
diff --git a/Core/Computation/MainComputation.cpp b/Core/Computation/MainComputation.cpp
index 39bf86b0bfe4b8ded8728867efd27affeed5a85e..d657a339f96d990627a08f9b2237b494301591dc 100644
--- a/Core/Computation/MainComputation.cpp
+++ b/Core/Computation/MainComputation.cpp
@@ -16,16 +16,14 @@
 #include "MainComputation.h"
 #include "ParticleLayoutComputation.h"
 #include "Layer.h"
-#include "ILayerSpecularInfo.h"
-#include "MatrixSpecularInfoMap.h"
+#include "IFresnelMap.h"
+#include "MatrixFresnelMap.h"
 #include "MultiLayer.h"
 #include "RoughMultiLayerComputation.h"
 #include "SpecularComputation.h"
-#include "ScalarSpecularInfoMap.h"
+#include "ScalarFresnelMap.h"
 #include "ProgressHandler.h"
 #include "SimulationElement.h"
-#include "SpecularMagnetic.h"
-#include "SpecularMatrix.h"
 #include <iterator> // needed for back_inserter
 
 MainComputation::MainComputation(
@@ -35,25 +33,28 @@ MainComputation::MainComputation(
     const std::vector<SimulationElement>::iterator& begin_it,
     const std::vector<SimulationElement>::iterator& end_it)
     : mP_multi_layer(multi_layer.clone())
-    , mP_inverted_multilayer(nullptr)
+    , mP_inverted_multilayer(multi_layer.cloneInvertB())
     , m_sim_options(options)
     , m_progress(&progress)
     , m_begin_it(begin_it)
     , m_end_it(end_it)
+    , mP_fresnel_map(createFresnelMap(mP_multi_layer.get(), mP_inverted_multilayer.get()))
 {
     size_t nLayers = mP_multi_layer->getNumberOfLayers();
     for (size_t i=0; i<nLayers; ++i) {
         const Layer* layer = mP_multi_layer->getLayer(i);
         for (size_t j=0; j<layer->getNumberOfLayouts(); ++j)
             m_computation_terms.push_back(
-                        new ParticleLayoutComputation(mP_multi_layer.get(),
+                        new ParticleLayoutComputation(mP_multi_layer.get(), mP_fresnel_map.get(),
                                                       layer->getLayout(j), i));
     }
     // scattering from rough surfaces in DWBA
     if (mP_multi_layer->hasRoughness())
-        m_computation_terms.push_back(new RoughMultiLayerComputation(mP_multi_layer.get()));
+        m_computation_terms.push_back(new RoughMultiLayerComputation(mP_multi_layer.get(),
+                                                                     mP_fresnel_map.get()));
     if (m_sim_options.includeSpecular())
-        m_computation_terms.push_back(new SpecularComputation(mP_multi_layer.get()));
+        m_computation_terms.push_back(new SpecularComputation(mP_multi_layer.get(),
+                                                              mP_fresnel_map.get()));
 }
 
 MainComputation::~MainComputation()
@@ -81,51 +82,20 @@ void MainComputation::run()
 // This allows them to be added and normalized together to the beam afterwards
 void MainComputation::runProtected()
 {
-    if (mP_multi_layer->requiresMatrixRTCoefficients())
-        collectFresnelMatrix();
-    else
-        collectFresnelScalar();
-
-    std::vector<SimulationElement> layer_elements;
-    std::copy(m_begin_it, m_end_it, std::back_inserter(layer_elements));
     bool polarized = mP_multi_layer->containsMagneticMaterial();
     // add all IComputationTerms:
     for (const IComputationTerm* comp: m_computation_terms) {
         if (!m_progress->alive())
             return;
-        if (comp->eval(m_sim_options, m_progress, polarized,
-                       layer_elements.begin(), layer_elements.end()) )
-            addElementsWithWeight(layer_elements.begin(), layer_elements.end(), m_begin_it, 1.0);
-    }
-}
-
-void MainComputation::collectFresnelScalar()
-{
-    if (m_full_fresnel_map.size()!=0) return;
-
-    // run through layers and construct T,R maps
-    for(size_t i=0; i<mP_multi_layer->getNumberOfLayers(); ++i) {
-        m_full_fresnel_map.push_back(new ScalarSpecularInfoMap(mP_multi_layer.get(), i));
+        comp->eval(m_sim_options, m_progress, polarized, m_begin_it, m_end_it );
     }
-    passFresnelInfo();
 }
 
-void MainComputation::collectFresnelMatrix()
+IFresnelMap* MainComputation::createFresnelMap(const MultiLayer* p_multilayer,
+                                               const MultiLayer* p_inverted_multilayer)
 {
-    if (m_full_fresnel_map.size()!=0) return;
-    mP_inverted_multilayer.reset(mP_multi_layer->cloneInvertB());
-
-    // run through layers and construct T,R maps
-    for(size_t i=0; i<mP_multi_layer->getNumberOfLayers(); ++i) {
-        m_full_fresnel_map.push_back(new MatrixSpecularInfoMap(mP_multi_layer.get(),
-                                                           mP_inverted_multilayer.get(), i));
-    }
-    passFresnelInfo();
-}
-
-void MainComputation::passFresnelInfo()
-{
-    for (IComputationTerm* comp: m_computation_terms) {
-        comp->setSpecularInfo(&m_full_fresnel_map);
-    }
+        if (!p_multilayer->requiresMatrixRTCoefficients())
+            return new ScalarFresnelMap(p_multilayer);
+        else
+            return new MatrixFresnelMap(p_multilayer, p_inverted_multilayer);
 }
diff --git a/Core/Computation/MainComputation.h b/Core/Computation/MainComputation.h
index fd9d74dc868c3a6b4f0e007e249ed52fa02b65fa..1b60f5843872b2f8efd624b48fe9940532a55707 100644
--- a/Core/Computation/MainComputation.h
+++ b/Core/Computation/MainComputation.h
@@ -19,12 +19,11 @@
 #include "ComputationStatus.h"
 #include "Complex.h"
 #include "INoncopyable.h"
-#include "FullFresnelMap.h"
 #include "SimulationOptions.h"
 #include <memory>
 #include <vector>
 
-class ILayerSpecularInfo;
+class IFresnelMap;
 class MultiLayer;
 class IComputationTerm;
 class ProgressHandler;
@@ -55,9 +54,8 @@ public:
 
 private:
     void runProtected();
-    void collectFresnelScalar();
-    void collectFresnelMatrix();
-    void passFresnelInfo();
+    static IFresnelMap* createFresnelMap(const MultiLayer* p_multilayer,
+                                         const MultiLayer* p_inverted_multilayer);
 
     std::unique_ptr<MultiLayer> mP_multi_layer;
     std::unique_ptr<MultiLayer> mP_inverted_multilayer;
@@ -66,11 +64,10 @@ private:
     //! these iterators define the span of detector bins this simulation will work on
     std::vector<SimulationElement>::iterator m_begin_it, m_end_it;
 
-    std::vector<IComputationTerm*> m_computation_terms;
-
     //! contains the information, necessary to calculate the Fresnel coefficients
-    FullFresnelMap m_full_fresnel_map;
+    std::unique_ptr<IFresnelMap> mP_fresnel_map;
 
+    std::vector<IComputationTerm*> m_computation_terms;
     ComputationStatus m_status;
 };
 
diff --git a/Core/Computation/ParticleLayoutComputation.cpp b/Core/Computation/ParticleLayoutComputation.cpp
index bd34a975a5a1f35a7350667cd72f461c2d8b214c..9b1489338915c423dadbcdffc1682f8f626bca29 100644
--- a/Core/Computation/ParticleLayoutComputation.cpp
+++ b/Core/Computation/ParticleLayoutComputation.cpp
@@ -17,7 +17,7 @@
 #include "DelayedProgressCounter.h"
 #include "Exceptions.h"
 #include "IInterferenceFunctionStrategy.h"
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 #include "ILayout.h"
 #include "LayerStrategyBuilder.h"
 #include "MultiLayer.h"
@@ -25,14 +25,15 @@
 #include "SimulationElement.h"
 
 ParticleLayoutComputation::ParticleLayoutComputation(const MultiLayer* p_multilayer,
+                                                     const IFresnelMap* p_fresnel_map,
                                                      const ILayout* p_layout, size_t layer_index)
-    : IComputationTerm(p_multilayer)
+    : IComputationTerm(p_multilayer, p_fresnel_map)
     , mp_layout(p_layout)
     , m_layer_index(layer_index)
 {}
 
 //! Computes scattering intensity for given range of simulation elements.
-bool ParticleLayoutComputation::eval(
+void ParticleLayoutComputation::eval(
     const SimulationOptions& options,
     ProgressHandler* progress,
     bool polarized,
@@ -40,22 +41,21 @@ bool ParticleLayoutComputation::eval(
     const std::vector<SimulationElement>::iterator& end_it) const
 {
     const std::unique_ptr<const IInterferenceFunctionStrategy> p_strategy {
-        LayerStrategyBuilder(mp_multilayer, mp_layout, mp_full_fresnel_map,
+        LayerStrategyBuilder(mp_multilayer, mp_layout, mp_fresnel_map,
                              polarized, options, m_layer_index).createStrategy() };
     double total_surface_density = mp_layout->getTotalParticleSurfaceDensity();
 
     DelayedProgressCounter counter(100);
     for (std::vector<SimulationElement>::iterator it = begin_it; it != end_it; ++it) {
         if (!progress->alive())
-            return false;
+            return;
         double alpha_f = it->getAlphaMean();
         size_t n_layers = mp_multilayer->getNumberOfLayers();
         if (n_layers > 1 && alpha_f < 0) {
-            it->setIntensity(0.0); // zero for transmission with multilayers (n>1)
+            continue; // zero for transmission with multilayers (n>1)
         } else {
-            it->setIntensity(p_strategy->evaluate(*it) * total_surface_density);
+            it->addIntensity(p_strategy->evaluate(*it) * total_surface_density);
         }
         counter.stepProgress(progress);
     }
-    return true;
 }
diff --git a/Core/Computation/ParticleLayoutComputation.h b/Core/Computation/ParticleLayoutComputation.h
index 715f6c1d25995f84ae3ebf83c2a5bd37b2354e61..76e378b2cbfa348bb1bfbf8f44e315dd09911b02 100644
--- a/Core/Computation/ParticleLayoutComputation.h
+++ b/Core/Computation/ParticleLayoutComputation.h
@@ -29,10 +29,11 @@ class ILayout;
 class ParticleLayoutComputation final : public IComputationTerm
 {
 public:
-    ParticleLayoutComputation(const MultiLayer* p_multilayer, const ILayout* p_layout,
-                              size_t layer_index);
+    ParticleLayoutComputation(
+        const MultiLayer* p_multilayer, const IFresnelMap* p_fresnel_map,
+        const ILayout* p_layout, size_t layer_index);
 
-    bool eval(const SimulationOptions& options,
+    void eval(const SimulationOptions& options,
               ProgressHandler* progress,
               bool polarized,
               const std::vector<SimulationElement>::iterator& begin_it,
diff --git a/Core/Computation/RoughMultiLayerComputation.cpp b/Core/Computation/RoughMultiLayerComputation.cpp
index 21b4111e7a57e70b5cfdcccd2d62d40467c10bb9..ce7e5fd501753fb7113e1bd11b68127aa9ec6853 100644
--- a/Core/Computation/RoughMultiLayerComputation.cpp
+++ b/Core/Computation/RoughMultiLayerComputation.cpp
@@ -16,11 +16,11 @@
 #include "RoughMultiLayerComputation.h"
 #include "DelayedProgressCounter.h"
 #include "ILayerRTCoefficients.h"
+#include "IFresnelMap.h"
 #include "Faddeeva.hh"
 #include "Layer.h"
 #include "LayerInterface.h"
 #include "LayerRoughness.h"
-#include "ILayerSpecularInfo.h"
 #include "MultiLayer.h"
 #include "MathConstants.h"
 #include "ProgressHandler.h"
@@ -40,31 +40,29 @@ namespace {
     }
 }
 
-RoughMultiLayerComputation::RoughMultiLayerComputation(const MultiLayer *p_multi_layer)
-    : IComputationTerm(p_multi_layer)
-{
-}
+RoughMultiLayerComputation::RoughMultiLayerComputation(const MultiLayer *p_multi_layer,
+                                                       const IFresnelMap* p_fresnel_map)
+    : IComputationTerm(p_multi_layer, p_fresnel_map)
+{}
 
 RoughMultiLayerComputation::~RoughMultiLayerComputation()
-{
-}
+{}
 
-bool RoughMultiLayerComputation::eval(
+void RoughMultiLayerComputation::eval(
     const SimulationOptions&, ProgressHandler* progress, bool,
     const std::vector<SimulationElement>::iterator& begin_it,
     const std::vector<SimulationElement>::iterator& end_it) const
 {
     if (mp_multilayer->requiresMatrixRTCoefficients()) {
-        return false;
+        return;
     }
     DelayedProgressCounter counter(100);
     for (std::vector<SimulationElement>::iterator it = begin_it; it != end_it; ++it) {
         if (!progress->alive())
-            return false;
-        it->setIntensity(evaluate(*it));
+            return;
+        it->addIntensity(evaluate(*it));
         counter.stepProgress(progress);
     }
-    return true;
 }
 
 double RoughMultiLayerComputation::evaluate(const SimulationElement& sim_element) const
@@ -117,14 +115,14 @@ complex_t RoughMultiLayerComputation::get_sum8terms(
     size_t ilayer, const SimulationElement& sim_element) const
 {
     const std::unique_ptr<const ILayerRTCoefficients> P_in_plus(
-        layerFresnelMap(ilayer)->getInCoefficients(sim_element));
+                mp_fresnel_map->getInCoefficients(sim_element, ilayer));
     const std::unique_ptr<const ILayerRTCoefficients> P_out_plus(
-        layerFresnelMap(ilayer)->getOutCoefficients(sim_element));
+                mp_fresnel_map->getOutCoefficients(sim_element, ilayer));
 
     const std::unique_ptr<const ILayerRTCoefficients> P_in_minus(
-        layerFresnelMap(ilayer+1)->getInCoefficients(sim_element));
+                mp_fresnel_map->getInCoefficients(sim_element, ilayer+1));
     const std::unique_ptr<const ILayerRTCoefficients> P_out_minus(
-        layerFresnelMap(ilayer+1)->getOutCoefficients(sim_element));
+                mp_fresnel_map->getOutCoefficients(sim_element, ilayer+1));
 
     complex_t kiz_plus = P_in_plus->getScalarKz();
     complex_t kfz_plus = P_out_plus->getScalarKz();
diff --git a/Core/Computation/RoughMultiLayerComputation.h b/Core/Computation/RoughMultiLayerComputation.h
index c54d014cbf454b93516ed3cea1c1b491bca63926..74fda308731249996780f20bfb21d02083a59af8 100644
--- a/Core/Computation/RoughMultiLayerComputation.h
+++ b/Core/Computation/RoughMultiLayerComputation.h
@@ -30,10 +30,11 @@ class SimulationElement;
 class RoughMultiLayerComputation final : public IComputationTerm
 {
 public:
-    RoughMultiLayerComputation(const MultiLayer* p_multi_layer);
+    RoughMultiLayerComputation(const MultiLayer* p_multi_layer,
+                               const IFresnelMap* p_fresnel_map);
     ~RoughMultiLayerComputation();
 
-    bool eval(const SimulationOptions& options,
+    void eval(const SimulationOptions& options,
               ProgressHandler* progress,
               bool polarized,
               const std::vector<SimulationElement>::iterator& begin_it,
diff --git a/Core/Computation/SpecularComputation.cpp b/Core/Computation/SpecularComputation.cpp
index 55e0c795ffaf1b7b7ccf64d9487a67052eb71f7a..10927382b01ffcd3a5cc32d11968782d93fe4ca0 100644
--- a/Core/Computation/SpecularComputation.cpp
+++ b/Core/Computation/SpecularComputation.cpp
@@ -15,25 +15,26 @@
 
 #include "SpecularComputation.h"
 #include "SimulationElement.h"
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 #include "ILayerRTCoefficients.h"
 #include "MultiLayer.h"
 
-SpecularComputation::SpecularComputation(const MultiLayer* p_multi_layer)
-    : IComputationTerm(p_multi_layer)
+SpecularComputation::SpecularComputation(const MultiLayer* p_multi_layer,
+                                         const IFresnelMap* p_fresnel_map)
+    : IComputationTerm(p_multi_layer, p_fresnel_map)
 {}
 
-bool SpecularComputation::eval(
+void SpecularComputation::eval(
     const SimulationOptions&, ProgressHandler*, bool,
     const std::vector<SimulationElement>::iterator& begin_it,
     const std::vector<SimulationElement>::iterator& end_it) const
 {
     if (mp_multilayer->requiresMatrixRTCoefficients())
-        return false;
+        return;
 
     for (auto it = begin_it; it != end_it; ++it) {
         if (it->containsSpecularWavevector()) {
-            complex_t R = layerFresnelMap(0)->getInCoefficients(*it)->getScalarR();
+            complex_t R = mp_fresnel_map->getInCoefficients(*it, 0)->getScalarR();
             double sin_alpha_i = std::abs(std::sin(it->getAlphaI()));
             if (sin_alpha_i==0.0)
                 sin_alpha_i = 1.0;
@@ -42,9 +43,6 @@ bool SpecularComputation::eval(
                 continue;
             double intensity = std::norm(R)*sin_alpha_i/solid_angle;
             it->setIntensity(intensity);
-        } else {
-            it->setIntensity(0.0);
         }
     }
-    return true;
 }
diff --git a/Core/Computation/SpecularComputation.h b/Core/Computation/SpecularComputation.h
index 688f14b730bc816cdf8bd59b879e5f7a740f3ed4..f86107b456e852004cd0857c21f5b2a35af00cdf 100644
--- a/Core/Computation/SpecularComputation.h
+++ b/Core/Computation/SpecularComputation.h
@@ -25,9 +25,9 @@
 class SpecularComputation final : public IComputationTerm
 {
 public:
-    SpecularComputation(const MultiLayer* p_multi_layer);
+    SpecularComputation(const MultiLayer* p_multi_layer, const IFresnelMap* p_fresnel_map);
 
-    bool eval(const SimulationOptions& options,
+    void eval(const SimulationOptions& options,
               ProgressHandler* progress,
               bool polarized,
               const std::vector<SimulationElement>::iterator& begin_it,
diff --git a/Core/Multilayer/DWBADiffuseReflection.h b/Core/Multilayer/DWBADiffuseReflection.h
index 5b3e872449ed4966cd597a6e29f98a4dc732c33c..e4ca5180cf41a16082d92929c5a2dd98c9bb63a6 100644
--- a/Core/Multilayer/DWBADiffuseReflection.h
+++ b/Core/Multilayer/DWBADiffuseReflection.h
@@ -49,8 +49,8 @@ private:
     complex_t get_sum4terms(size_t ilayer);
 
     const MultiLayer* m_sample;
-    SpecularMatrix::MultiLayerCoeff_t m_fcoeff_i;
-    SpecularMatrix::MultiLayerCoeff_t m_fcoeff_f;
+    std::vector<ScalarRTCoefficients> m_fcoeff_i;
+    std::vector<ScalarRTCoefficients> m_fcoeff_f;
     double m_diffuse_autocorr;
     double m_diffuse_crosscorr;
 
diff --git a/Core/Computation/FullFresnelMap.cpp b/Core/Multilayer/Hash2Doubles.cpp
similarity index 51%
rename from Core/Computation/FullFresnelMap.cpp
rename to Core/Multilayer/Hash2Doubles.cpp
index 69642908712fd4cc11bf7832fcc9cf7221cb94f4..68a5eff31a26ceb79d109bb1314b157332506cfb 100644
--- a/Core/Computation/FullFresnelMap.cpp
+++ b/Core/Multilayer/Hash2Doubles.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Computation/FullFresnelMap.cpp
-//! @brief     Implements class FullFresnelMap.
+//! @file      Core/Computation/Hash2Doubles.cpp
+//! @brief     Implements class Hash2Doubles.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,26 +13,10 @@
 //
 // ************************************************************************** //
 
-#include "FullFresnelMap.h"
-#include "ILayerSpecularInfo.h"
+#include "Hash2Doubles.h"
 
-FullFresnelMap::FullFresnelMap()
-{}
-
-FullFresnelMap::~FullFresnelMap()
-{}
-
-void FullFresnelMap::push_back(ILayerSpecularInfo* p_layer_map)
-{
-    m_full_map.push_back(p_layer_map);
-}
-
-size_t FullFresnelMap::size() const
-{
-    return m_full_map.size();
-}
-
-const ILayerSpecularInfo* FullFresnelMap::layerFresnelMap(size_t index) const
+// Simple exclusive or of the std::hash<double> of its parts
+size_t Hash2Doubles::operator()(std::pair<double, double> doubles) const noexcept
 {
-    return m_full_map[index];
+    return m_double_hash(doubles.first) ^ m_double_hash(doubles.second);
 }
diff --git a/Core/Multilayer/Hash2Doubles.h b/Core/Multilayer/Hash2Doubles.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8417f02f5a1304e2803ff80f65a5ba94518f82f
--- /dev/null
+++ b/Core/Multilayer/Hash2Doubles.h
@@ -0,0 +1,32 @@
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Computation/Hash2Doubles.h
+//! @brief     Defines class Hash2Doubles.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2017
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   J. Burle, J. M. Fisher, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef HASH2DOUBLES_H
+#define HASH2DOUBLES_H
+
+#include <functional>
+#include <utility>
+
+class Hash2Doubles
+{
+public:
+    Hash2Doubles() {}
+    ~Hash2Doubles() {}
+
+    size_t operator()(std::pair<double, double> doubles) const noexcept;
+private:
+    std::hash<double> m_double_hash;
+};
+
+#endif // HASH2DOUBLES_H
diff --git a/Core/Multilayer/HashKVector.cpp b/Core/Multilayer/HashKVector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..706690ba9cb55914c7301c785925c6de46ffeaa2
--- /dev/null
+++ b/Core/Multilayer/HashKVector.cpp
@@ -0,0 +1,22 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Computation/HashKVector.cpp
+//! @brief     Implements class HashKVector.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2017
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   J. Burle, J. M. Fisher, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "HashKVector.h"
+
+// Simple exclusive or of the std::hash<double> of its components
+size_t HashKVector::operator()(kvector_t kvec) const noexcept
+{
+    return m_double_hash(kvec.x()) ^ m_double_hash(kvec.y()) ^ m_double_hash(kvec.z());
+}
diff --git a/Core/Computation/FullFresnelMap.h b/Core/Multilayer/HashKVector.h
similarity index 53%
rename from Core/Computation/FullFresnelMap.h
rename to Core/Multilayer/HashKVector.h
index 2e1092d09a6ae0bde6dec0fbed661fb39a4c6752..2adae33b1a5cfe8a59c85217b0165c9c6fe704b6 100644
--- a/Core/Computation/FullFresnelMap.h
+++ b/Core/Multilayer/HashKVector.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Computation/FullFresnelMap.h
-//! @brief     Defines class FullFresnelMap.
+//! @file      Core/Computation/HashKVector.h
+//! @brief     Defines class HashKVector.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,26 +13,22 @@
 //
 // ************************************************************************** //
 
-#ifndef FULLFRESNELMAP_H
-#define FULLFRESNELMAP_H
+#ifndef HASHKVECTOR_H
+#define HASHKVECTOR_H
 
-#include "SafePointerVector.h"
+#include "Vectors3D.h"
+#include <functional>
+#include <utility>
 
-class ILayerSpecularInfo;
-
-class FullFresnelMap
+class HashKVector
 {
 public:
-    FullFresnelMap();
-    ~FullFresnelMap();
-
-    void push_back(ILayerSpecularInfo* layer_map);
-
-    size_t size() const;
+    HashKVector() {}
+    ~HashKVector() {}
 
-    const ILayerSpecularInfo* layerFresnelMap(size_t index) const;
+    size_t operator()(kvector_t kvec) const noexcept;
 private:
-    SafePointerVector<ILayerSpecularInfo> m_full_map;
+    std::hash<double> m_double_hash;
 };
 
-#endif // FULLFRESNELMAP_H
+#endif // HASHKVECTOR_H
diff --git a/Core/Multilayer/ILayerSpecularInfo.cpp b/Core/Multilayer/IFresnelMap.cpp
similarity index 70%
rename from Core/Multilayer/ILayerSpecularInfo.cpp
rename to Core/Multilayer/IFresnelMap.cpp
index 0befcdb582ec5044fb9f7d01bbce42eb2aad4c2d..8d38597ccab47671ac8278f6ee23161296cf0210 100644
--- a/Core/Multilayer/ILayerSpecularInfo.cpp
+++ b/Core/Multilayer/IFresnelMap.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Multilayer/ILayerSpecularInfo.cpp
-//! @brief     Implements class ILayerSpecularInfo.
+//! @file      Core/Multilayer/IFresnelMap.cpp
+//! @brief     Implements class IFresnelMap.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,7 +13,7 @@
 //
 // ************************************************************************** //
 
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 
-ILayerSpecularInfo::ILayerSpecularInfo() {}
-ILayerSpecularInfo::~ILayerSpecularInfo() {}
+IFresnelMap::IFresnelMap() {}
+IFresnelMap::~IFresnelMap() {}
diff --git a/Core/Multilayer/ILayerSpecularInfo.h b/Core/Multilayer/IFresnelMap.h
similarity index 68%
rename from Core/Multilayer/ILayerSpecularInfo.h
rename to Core/Multilayer/IFresnelMap.h
index b640cff8b92c3349c9c53feeefdc210e6c929027..6717196999677b3e95189ecbb682e9e60077b06e 100644
--- a/Core/Multilayer/ILayerSpecularInfo.h
+++ b/Core/Multilayer/IFresnelMap.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Multilayer/ILayerSpecularInfo.h
-//! @brief     Defines class ILayerSpecularInfo.
+//! @file      Core/Multilayer/IFresnelMap.h
+//! @brief     Defines class IFresnelMap.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,34 +13,33 @@
 //
 // ************************************************************************** //
 
-#ifndef ILAYERSPECULARINFO_H
-#define ILAYERSPECULARINFO_H
+#ifndef IFRESNELMAP_H
+#define IFRESNELMAP_H
 
-#include "ICloneable.h"
+#include "INoncopyable.h"
+#include <cstddef>
 
 class ILayerRTCoefficients;
 class SimulationElement;
 
-//! Holds the necessary information to calculate the radiation wavefunction in a specific layer
+//! Holds the necessary information to calculate the radiation wavefunction in every layer
 //! for different incoming (outgoing) angles of the beam in the top layer
 //! (these amplitudes correspond to the specular part of the wavefunction).
 //! @ingroup algorithms_internal
 
-class BA_CORE_API_ ILayerSpecularInfo : public ICloneable
+class BA_CORE_API_ IFresnelMap : public INoncopyable
 {
 public:
-    ILayerSpecularInfo();
-    ~ILayerSpecularInfo();
-
-    ILayerSpecularInfo* clone() const =0;
+    IFresnelMap();
+    ~IFresnelMap();
 
     //! Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector.
     virtual const ILayerRTCoefficients* getOutCoefficients(
-            const SimulationElement& sim_element) const =0;
+            const SimulationElement& sim_element, size_t layer_index) const =0;
 
     //! Retrieves the amplitude coefficients for an incoming wavevector.
     virtual const ILayerRTCoefficients* getInCoefficients(
-            const SimulationElement& sim_element) const =0;
+            const SimulationElement& sim_element, size_t layer_index) const =0;
 };
 
-#endif // ILAYERSPECULARINFO_H
+#endif // IFRESNELMAP_H
diff --git a/Core/Multilayer/IInterferenceFunctionStrategy.cpp b/Core/Multilayer/IInterferenceFunctionStrategy.cpp
index 62365c21754804e29ffa8d9bd9321893c0936b91..f814e588a3648f0f7f37c61be44cd6ac1d72ed65 100644
--- a/Core/Multilayer/IInterferenceFunctionStrategy.cpp
+++ b/Core/Multilayer/IInterferenceFunctionStrategy.cpp
@@ -20,7 +20,7 @@
 #include "IFormFactor.h"
 #include "IInterferenceFunction.h"
 #include "IntegratorMCMiser.h"
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 #include "MathConstants.h"
 #include "RealParameter.h"
 #include "ScalarRTCoefficients.h"
diff --git a/Core/Multilayer/IInterferenceFunctionStrategy.h b/Core/Multilayer/IInterferenceFunctionStrategy.h
index 02990ebd862e1c6abe13bf6c19460ea6e269b71e..3ee1c7a8ee6bf314a7de12d1ca9573ea4b9e4ae1 100644
--- a/Core/Multilayer/IInterferenceFunctionStrategy.h
+++ b/Core/Multilayer/IInterferenceFunctionStrategy.h
@@ -29,7 +29,7 @@ template <class T> class IntegratorMCMiser;
 class Bin1DCVector;
 class FormFactorCoherentSum;
 class IInterferenceFunction;
-class ILayerSpecularInfo;
+class IFresnelMap;
 class SimulationElement;
 
 //! Pure virtual base class of all interference function strategy classes.
diff --git a/Core/Multilayer/LayerStrategyBuilder.cpp b/Core/Multilayer/LayerStrategyBuilder.cpp
index ff51341756310304c1088631671cf0b067f45afa..5065115fde2ccc64a9fd55d9408f33ae32778526 100644
--- a/Core/Multilayer/LayerStrategyBuilder.cpp
+++ b/Core/Multilayer/LayerStrategyBuilder.cpp
@@ -23,17 +23,17 @@
 #include "InterferenceFunctionNone.h"
 #include "MultiLayer.h"
 #include "Layer.h"
-#include "ILayerSpecularInfo.h"
+#include "IFresnelMap.h"
 #include "DecouplingApproximationStrategy.h"
 #include "SSCApproximationStrategy.h"
 
 LayerStrategyBuilder::LayerStrategyBuilder(
     const MultiLayer* p_multilayer, const ILayout* p_layout,
-    const FullFresnelMap* p_full_map, bool polarized,
+    const IFresnelMap* p_fresnel_map, bool polarized,
     const SimulationOptions& sim_params, size_t layer_index)
     : mp_multilayer(p_multilayer)
     , mp_layout(p_layout)
-    , mp_full_fresnel_map(p_full_map)
+    , mp_fresnel_map(p_fresnel_map)
     , m_polarized {polarized}
     , m_sim_params (sim_params)
     , m_layer_index(layer_index)
@@ -88,7 +88,7 @@ SafePointerVector<class FormFactorCoherentSum> LayerStrategyBuilder::collectForm
         FormFactorCoherentSum* p_ff_coh;
         p_ff_coh = createFormFactorCoherentSum(particle, p_layer_material);
         p_ff_coh->scaleRelativeAbundance(layout_abundance);
-        p_ff_coh->setSpecularInfo(*mp_full_fresnel_map->layerFresnelMap(m_layer_index));
+        p_ff_coh->setSpecularInfo(mp_fresnel_map, m_layer_index);
         result.push_back(p_ff_coh);
     }
     return result;
diff --git a/Core/Multilayer/LayerStrategyBuilder.h b/Core/Multilayer/LayerStrategyBuilder.h
index ab428f35fc8348958c3239ca64ed2d51c83b368f..24f67278ee6e686b479fe5f13663114cffb2c3db 100644
--- a/Core/Multilayer/LayerStrategyBuilder.h
+++ b/Core/Multilayer/LayerStrategyBuilder.h
@@ -16,7 +16,6 @@
 #ifndef LAYERSTRATEGYBUILDER_H
 #define LAYERSTRATEGYBUILDER_H
 
-#include "FullFresnelMap.h"
 #include "SafePointerVector.h"
 #include "SimulationOptions.h"
 #include <memory>
@@ -26,7 +25,7 @@ class IInterferenceFunctionStrategy;
 class ILayout;
 class IMaterial;
 class IParticle;
-class ILayerSpecularInfo;
+class IFresnelMap;
 class MultiLayer;
 
 //! Methods to generate a simulation strategy for a ParticleLayoutComputation.
@@ -37,7 +36,7 @@ class BA_CORE_API_ LayerStrategyBuilder
 public:
     LayerStrategyBuilder(
         const MultiLayer* p_multilayer, const ILayout* p_layout,
-        const FullFresnelMap* p_full_map, bool polarized,
+        const IFresnelMap* p_fresnel_map, bool polarized,
         const SimulationOptions& sim_params, size_t layer_index);
 
     ~LayerStrategyBuilder();
@@ -52,7 +51,7 @@ private:
     const MultiLayer* mp_multilayer;
     const ILayout* mp_layout;
     //! R and T coefficients for DWBA
-    const FullFresnelMap* mp_full_fresnel_map;
+    const IFresnelMap* mp_fresnel_map;
     bool m_polarized;  //!< polarized computation required?
     SimulationOptions m_sim_params;
     size_t m_layer_index;
diff --git a/Core/Multilayer/MatrixFresnelMap.cpp b/Core/Multilayer/MatrixFresnelMap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..76f8e12b1727299976a40650a8435a458c7f3961
--- /dev/null
+++ b/Core/Multilayer/MatrixFresnelMap.cpp
@@ -0,0 +1,64 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Multilayer/MatrixFresnelMap.cpp
+//! @brief     Implements class MatrixFresnelMap.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "MatrixFresnelMap.h"
+#include "ILayerRTCoefficients.h"
+#include "MatrixRTCoefficients.h"
+#include "MultiLayer.h"
+#include "SimulationElement.h"
+#include "SpecularMagnetic.h"
+
+MatrixFresnelMap::MatrixFresnelMap(const MultiLayer* p_multilayer,
+                                   const MultiLayer* p_inverted_multilayer)
+    : mp_multilayer(p_multilayer)
+    , mp_inverted_multilayer(p_inverted_multilayer)
+{}
+
+MatrixFresnelMap::~MatrixFresnelMap()
+{}
+
+const ILayerRTCoefficients* MatrixFresnelMap::getOutCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const
+{
+    MatrixRTCoefficients* result;
+    kvector_t kvec = -sim_element.getMeanKf();
+    auto it = m_hash_table_out.find(kvec);
+    if (it != m_hash_table_out.end())
+        result = new MatrixRTCoefficients(it->second[layer_index]);
+    else {
+        std::vector<MatrixRTCoefficients> coeffs;
+        SpecularMagnetic::execute(*mp_inverted_multilayer, kvec, coeffs);
+        result = new MatrixRTCoefficients(coeffs[layer_index]);
+        m_hash_table_out[kvec] = std::move(coeffs);
+    }
+    return result;
+}
+
+const ILayerRTCoefficients* MatrixFresnelMap::getInCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const
+{
+    MatrixRTCoefficients* result;
+    kvector_t kvec = sim_element.getKi();
+    auto it = m_hash_table_in.find(kvec);
+    if (it != m_hash_table_in.end())
+        result = new MatrixRTCoefficients(it->second[layer_index]);
+    else {
+        std::vector<MatrixRTCoefficients> coeffs;
+        SpecularMagnetic::execute(*mp_multilayer, kvec, coeffs);
+        result = new MatrixRTCoefficients(coeffs[layer_index]);
+        m_hash_table_in[kvec] = std::move(coeffs);
+    }
+    return result;
+}
diff --git a/Core/Multilayer/MatrixFresnelMap.h b/Core/Multilayer/MatrixFresnelMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..dada248147b26e4143a9dbb12c9022f5fbbb4b44
--- /dev/null
+++ b/Core/Multilayer/MatrixFresnelMap.h
@@ -0,0 +1,55 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Multilayer/MatrixFresnelMap.h
+//! @brief     Defines class MatrixFresnelMap.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef MATRIXFRESNELMAP_H
+#define MATRIXFRESNELMAP_H
+
+#include "HashKVector.h"
+#include "IFresnelMap.h"
+#include <unordered_map>
+#include <vector>
+
+class ILayerRTCoefficients;
+class MatrixRTCoefficients;
+class MultiLayer;
+class SimulationElement;
+
+//! Implementation of IFresnelMap for matrix valued reflection/transmission coefficients.
+//! @ingroup algorithms_internal
+
+class BA_CORE_API_ MatrixFresnelMap : public IFresnelMap
+{
+public:
+    MatrixFresnelMap(const MultiLayer* p_multilayer, const MultiLayer* p_inverted_multilayer);
+    ~MatrixFresnelMap() final;
+
+    //! Retrieves the amplitude coefficients for the given angles
+    const ILayerRTCoefficients* getOutCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const final override;
+
+    //! Retrieves the amplitude coefficients for the given angles
+    const ILayerRTCoefficients* getInCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const final override;
+
+private:
+    const MultiLayer* mp_multilayer;
+    const MultiLayer* mp_inverted_multilayer;
+    mutable std::unordered_map<kvector_t, std::vector<MatrixRTCoefficients>,
+                               HashKVector> m_hash_table_out;
+    mutable std::unordered_map<kvector_t, std::vector<MatrixRTCoefficients>,
+                               HashKVector> m_hash_table_in;
+};
+
+#endif // MATRIXFRESNELMAP_H
diff --git a/Core/Multilayer/MatrixSpecularInfoMap.cpp b/Core/Multilayer/MatrixSpecularInfoMap.cpp
deleted file mode 100644
index 728600aeb629153ba3a08d1f5dc58ecf39fb431d..0000000000000000000000000000000000000000
--- a/Core/Multilayer/MatrixSpecularInfoMap.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Multilayer/MatrixSpecularInfoMap.cpp
-//! @brief     Implements class ScalarSpecularInfoMap.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "MatrixSpecularInfoMap.h"
-#include "ILayerRTCoefficients.h"
-#include "MatrixRTCoefficients.h"
-#include "MultiLayer.h"
-#include "SimulationElement.h"
-#include "SpecularMagnetic.h"
-
-MatrixSpecularInfoMap::MatrixSpecularInfoMap(
-        const MultiLayer* p_multilayer, const MultiLayer* p_inverted_multilayer,
-        size_t layer_index)
-    : mp_multilayer(p_multilayer)
-    , mp_inverted_multilayer(p_inverted_multilayer)
-    , m_layer_index(layer_index)
-{}
-
-MatrixSpecularInfoMap* MatrixSpecularInfoMap::clone() const
-{
-    return new MatrixSpecularInfoMap(mp_multilayer, mp_inverted_multilayer, m_layer_index);
-}
-
-const ILayerRTCoefficients* MatrixSpecularInfoMap::getOutCoefficients(
-        const SimulationElement& sim_element) const
-{
-    SpecularMagnetic::MultiLayerCoeff_t coeffs;
-    SpecularMagnetic::execute(*mp_inverted_multilayer, -sim_element.getMeanKf(), coeffs);
-    return new MatrixRTCoefficients(coeffs[m_layer_index]);
-}
-
-const ILayerRTCoefficients* MatrixSpecularInfoMap::getInCoefficients(
-        const SimulationElement& sim_element) const
-{
-    SpecularMagnetic::MultiLayerCoeff_t coeffs;
-    SpecularMagnetic::execute(*mp_multilayer, sim_element.getKi(), coeffs);
-    return new MatrixRTCoefficients(coeffs[m_layer_index]);
-}
diff --git a/Core/Multilayer/MatrixSpecularInfoMap.h b/Core/Multilayer/MatrixSpecularInfoMap.h
deleted file mode 100644
index 578984089e030a2fa3d51377c1425a73bac23dc7..0000000000000000000000000000000000000000
--- a/Core/Multilayer/MatrixSpecularInfoMap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Multilayer/MatrixSpecularInfoMap.h
-//! @brief     Defines class MatrixSpecularInfoMap.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef MATRIXSPECULARINFOMAP_H
-#define MATRIXSPECULARINFOMAP_H
-
-#include "ILayerSpecularInfo.h"
-#include <cstddef>
-
-class ILayerRTCoefficients;
-class MultiLayer;
-class SimulationElement;
-
-//! Implementation of ISpecularInfoMap for matrix valued reflection/transmission coefficients.
-//! @ingroup algorithms_internal
-
-class BA_CORE_API_ MatrixSpecularInfoMap : public ILayerSpecularInfo
-{
-public:
-    MatrixSpecularInfoMap(const MultiLayer* p_multilayer, const MultiLayer* p_inverted_multilayer,
-                          size_t layer_index);
-    ~MatrixSpecularInfoMap() final {}
-
-    MatrixSpecularInfoMap* clone() const final override;
-
-    //! Retrieves the amplitude coefficients for the given angles
-    const ILayerRTCoefficients* getOutCoefficients(
-        const SimulationElement& sim_element) const final override;
-
-    //! Retrieves the amplitude coefficients for the given angles
-    const ILayerRTCoefficients* getInCoefficients(
-        const SimulationElement& sim_element) const final override;
-
-private:
-    const MultiLayer* mp_multilayer;
-    const MultiLayer* mp_inverted_multilayer;
-    const size_t m_layer_index;
-};
-
-#endif // MATRIXSPECULARINFOMAP_H
diff --git a/Core/Multilayer/ScalarFresnelMap.cpp b/Core/Multilayer/ScalarFresnelMap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55839fbcf7a60c64771b34873d17863953962c4c
--- /dev/null
+++ b/Core/Multilayer/ScalarFresnelMap.cpp
@@ -0,0 +1,56 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Multilayer/ScalarFresnelMap.cpp
+//! @brief     Implements class ScalarFresnelMap.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ScalarFresnelMap.h"
+#include "MultiLayer.h"
+#include "ScalarRTCoefficients.h"
+#include "SimulationElement.h"
+#include "SpecularMatrix.h"
+
+ScalarFresnelMap::ScalarFresnelMap(const MultiLayer* multilayer)
+    : mp_multilayer(multilayer)
+{}
+
+ScalarFresnelMap::~ScalarFresnelMap()
+{}
+
+const ILayerRTCoefficients* ScalarFresnelMap::getOutCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const
+{
+    return getCoefficients(-sim_element.getMeanKf(), layer_index);
+}
+
+const ILayerRTCoefficients* ScalarFresnelMap::getInCoefficients(
+        const SimulationElement& sim_element, size_t layer_index) const
+{
+    return getCoefficients(sim_element.getKi(), layer_index);
+}
+
+const ScalarRTCoefficients* ScalarFresnelMap::getCoefficients(
+        kvector_t kvec, size_t layer_index) const
+{
+    ScalarRTCoefficients* result;
+    std::pair<double, double> k2_theta(kvec.mag2(), kvec.theta());
+    auto it = m_hash_table.find(k2_theta);
+    if (it != m_hash_table.end())
+        result = new ScalarRTCoefficients(it->second[layer_index]);
+    else {
+        std::vector<ScalarRTCoefficients> coeffs;
+        SpecularMatrix::execute(*mp_multilayer, kvec, coeffs);
+        result = new ScalarRTCoefficients(coeffs[layer_index]);
+        m_hash_table[k2_theta] = std::move(coeffs);
+    }
+    return result;
+}
diff --git a/Core/Multilayer/ScalarSpecularInfoMap.h b/Core/Multilayer/ScalarFresnelMap.h
similarity index 51%
rename from Core/Multilayer/ScalarSpecularInfoMap.h
rename to Core/Multilayer/ScalarFresnelMap.h
index d387716ca7973e494cd505c5ba47e6e67eba8017..007d20ad9eb32c90337f5544ca3d87d9466d890a 100644
--- a/Core/Multilayer/ScalarSpecularInfoMap.h
+++ b/Core/Multilayer/ScalarFresnelMap.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Multilayer/ScalarSpecularInfoMap.h
-//! @brief     Defines class ScalarSpecularInfoMap.
+//! @file      Core/Multilayer/ScalarFresnelMap.h
+//! @brief     Defines class ScalarFresnelMap.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,41 +13,43 @@
 //
 // ************************************************************************** //
 
-#ifndef SCALARSPECULARINFOMAP_H
-#define SCALARSPECULARINFOMAP_H
+#ifndef SCALARFRESNELMAP_H
+#define SCALARFRESNELMAP_H
 
-#include "ILayerSpecularInfo.h"
+#include "Hash2Doubles.h"
+#include "IFresnelMap.h"
 #include "Vectors3D.h"
+#include <unordered_map>
+#include <utility>
+#include <vector>
 
-class MultiLayer;
 class ILayerRTCoefficients;
+class MultiLayer;
 class ScalarRTCoefficients;
 class SimulationElement;
 
-//! Implementation of ISpecularInfoMap for scalar valued reflection/transmission coefficients.
+//! Implementation of IFresnelMap for scalar valued reflection/transmission coefficients.
 //! @ingroup algorithms_internal
 
-class BA_CORE_API_ ScalarSpecularInfoMap : public ILayerSpecularInfo
+class BA_CORE_API_ ScalarFresnelMap : public IFresnelMap
 {
 public:
-    ScalarSpecularInfoMap(const MultiLayer* multilayer, size_t layer_index);
-    ~ScalarSpecularInfoMap() final {}
-
-    ScalarSpecularInfoMap* clone() const final override {
-        return new ScalarSpecularInfoMap(mp_multilayer, m_layer_index); }
+    ScalarFresnelMap(const MultiLayer* multilayer);
+    ~ScalarFresnelMap() final;
 
     //! Retrieves the amplitude coefficients for the given angles
     const ILayerRTCoefficients* getOutCoefficients (
-        const SimulationElement& sim_element) const final override;
+        const SimulationElement& sim_element, size_t layer_index) const final override;
 
     //! Retrieves the amplitude coefficients for the given angles
     const ILayerRTCoefficients* getInCoefficients(
-        const SimulationElement& sim_element) const final override;
+        const SimulationElement& sim_element, size_t layer_index) const final override;
 
 private:
     const MultiLayer* mp_multilayer;
-    const size_t m_layer_index;
-    const ScalarRTCoefficients* getCoefficients(kvector_t kvec) const;
+    const ScalarRTCoefficients* getCoefficients(kvector_t kvec, size_t layer_index) const;
+    mutable std::unordered_map<std::pair<double, double>, std::vector<ScalarRTCoefficients>,
+                               Hash2Doubles> m_hash_table;
 };
 
-#endif // SCALARSPECULARINFOMAP_H
+#endif // SCALARFRESNELMAP_H
diff --git a/Core/Multilayer/ScalarSpecularInfoMap.cpp b/Core/Multilayer/ScalarSpecularInfoMap.cpp
deleted file mode 100644
index 4247200315f5f99fe82804f843f2a63bfdecbe7e..0000000000000000000000000000000000000000
--- a/Core/Multilayer/ScalarSpecularInfoMap.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Multilayer/ScalarSpecularInfoMap.cpp
-//! @brief     Implements class ScalarSpecularInfoMap.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "ScalarSpecularInfoMap.h"
-#include "MultiLayer.h"
-#include "ScalarRTCoefficients.h"
-#include "SimulationElement.h"
-#include "SpecularMatrix.h"
-
-ScalarSpecularInfoMap::ScalarSpecularInfoMap(const MultiLayer* multilayer, size_t layer_index)
-    : mp_multilayer(multilayer)
-    , m_layer_index(layer_index)
-{}
-
-const ILayerRTCoefficients* ScalarSpecularInfoMap::getOutCoefficients(
-        const SimulationElement& sim_element) const
-{
-    return getCoefficients(-sim_element.getMeanKf());
-}
-
-const ILayerRTCoefficients* ScalarSpecularInfoMap::getInCoefficients(
-        const SimulationElement& sim_element) const
-{
-    return getCoefficients(sim_element.getKi());
-}
-
-const ScalarRTCoefficients* ScalarSpecularInfoMap::getCoefficients(kvector_t kvec) const
-{
-    SpecularMatrix::MultiLayerCoeff_t coeffs;
-    SpecularMatrix::execute(*mp_multilayer, kvec, coeffs);
-    return new ScalarRTCoefficients(coeffs[m_layer_index]);
-}
diff --git a/Core/Multilayer/SpecularMagnetic.cpp b/Core/Multilayer/SpecularMagnetic.cpp
index 362f09a9fd56176a2c39f6b1e71ed69899cdee8f..e22a527af425748f5be84897259527b30b116b8d 100644
--- a/Core/Multilayer/SpecularMagnetic.cpp
+++ b/Core/Multilayer/SpecularMagnetic.cpp
@@ -26,7 +26,7 @@ namespace {
 }
 
 void SpecularMagnetic::execute(
-    const MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff)
+    const MultiLayer& sample, const kvector_t k, std::vector<MatrixRTCoefficients>& coeff)
 {
     coeff.clear();
     coeff.resize(sample.getNumberOfLayers());
@@ -37,7 +37,7 @@ void SpecularMagnetic::execute(
 }
 
 void SpecularMagnetic::calculateEigenvalues(
-    const MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff)
+    const MultiLayer& sample, const kvector_t k, std::vector<MatrixRTCoefficients>& coeff)
 {
     double mag_k = k.mag();
     double sign_kz = k.z() > 0.0 ? -1.0 : 1.0;
@@ -64,7 +64,7 @@ void SpecularMagnetic::calculateEigenvalues(
 
 // todo: avoid overflows (see SpecularMatrix.cpp)
 void SpecularMagnetic::calculateTransferAndBoundary(
-    const MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff)
+    const MultiLayer& sample, const kvector_t k, std::vector<MatrixRTCoefficients>& coeff)
 {
     (void)k;
     size_t N = coeff.size();
@@ -127,7 +127,7 @@ void SpecularMagnetic::calculateTransferAndBoundary(
     }
 }
 
-void SpecularMagnetic::setForNoTransmission(MultiLayerCoeff_t& coeff)
+void SpecularMagnetic::setForNoTransmission(std::vector<MatrixRTCoefficients>& coeff)
 {
     size_t N = coeff.size();
     for (size_t i=0; i<N; ++i) {
diff --git a/Core/Multilayer/SpecularMagnetic.h b/Core/Multilayer/SpecularMagnetic.h
index 87bea205fc4cbf9c65f1d6a956d3e5544b37cd61..84986df1a4cb30e794ddbfe5e2e7ace2e0a5f530 100644
--- a/Core/Multilayer/SpecularMagnetic.h
+++ b/Core/Multilayer/SpecularMagnetic.h
@@ -27,20 +27,17 @@
 class BA_CORE_API_ SpecularMagnetic
 {
 public:
-    //! Layer coefficients describing refraction and reflection/transmission.
-    typedef std::vector<MatrixRTCoefficients> MultiLayerCoeff_t;
-
     //! Computes refraction angle reflection/transmission coefficients
     //! for given multilayer and wavevector k
-    static void execute(
-        const class MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff);
+    static void execute(const class MultiLayer& sample, const kvector_t k,
+                        std::vector<MatrixRTCoefficients>& coeff);
 
 private:
-    static void calculateEigenvalues(
-        const class MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff);
-    static void calculateTransferAndBoundary(
-        const MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff);
-    static void setForNoTransmission(MultiLayerCoeff_t& coeff);
+    static void calculateEigenvalues(const class MultiLayer& sample, const kvector_t k,
+                                     std::vector<MatrixRTCoefficients>& coeff);
+    static void calculateTransferAndBoundary(const MultiLayer& sample, const kvector_t k,
+                                             std::vector<MatrixRTCoefficients>& coeff);
+    static void setForNoTransmission(std::vector<MatrixRTCoefficients>& coeff);
     static complex_t getImExponential(complex_t exponent);
 };
 
diff --git a/Core/Multilayer/SpecularMatrix.cpp b/Core/Multilayer/SpecularMatrix.cpp
index fcc33dfc212522dafe36011042c5c5f486949186..9a0aa43bf7ee6ebe59b1cf9116f63dcaeaaafd7f 100644
--- a/Core/Multilayer/SpecularMatrix.cpp
+++ b/Core/Multilayer/SpecularMatrix.cpp
@@ -27,12 +27,12 @@ namespace {
     const complex_t imag_unit = complex_t(0.0, 1.0);
 }
 
-void setZeroBelow(SpecularMatrix::MultiLayerCoeff_t& coeff, size_t current_layer);
+void setZeroBelow(std::vector<ScalarRTCoefficients>& coeff, size_t current_layer);
 bool calculateUpFromLayer(
-    SpecularMatrix::MultiLayerCoeff_t& coeff, const MultiLayer& sample,
+    std::vector<ScalarRTCoefficients>& coeff, const MultiLayer& sample,
     const double kmag, size_t layer_index);
 size_t bisectRTcomputation(
-    SpecularMatrix::MultiLayerCoeff_t& coeff, const MultiLayer& sample,
+    std::vector<ScalarRTCoefficients>& coeff, const MultiLayer& sample,
     const double kmag, const size_t lgood, const size_t lbad, const size_t l);
 
 //! Computes refraction angles and transmission/reflection coefficients
@@ -40,7 +40,8 @@ size_t bisectRTcomputation(
 //! Roughness is modelled by tanh profile [see e.g. Phys. Rev. B, vol. 47 (8), p. 4385 (1993)].
 //! k : length: wavenumber in vacuum, direction: defined in layer 0.
 
-void SpecularMatrix::execute(const MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff)
+void SpecularMatrix::execute(const MultiLayer& sample, const kvector_t k,
+                             std::vector<ScalarRTCoefficients>& coeff)
 {
     size_t N = sample.getNumberOfLayers();
     assert(N>0);
@@ -102,7 +103,7 @@ void SpecularMatrix::execute(const MultiLayer& sample, const kvector_t k, MultiL
 
 //! Sets coeff to zero for all layers below current_layer.
 
-void setZeroBelow(SpecularMatrix::MultiLayerCoeff_t& coeff, size_t current_layer)
+void setZeroBelow(std::vector<ScalarRTCoefficients>& coeff, size_t current_layer)
 {
     size_t N = coeff.size();
     for (size_t i=current_layer+1; i<N; ++i) {
@@ -113,7 +114,7 @@ void setZeroBelow(SpecularMatrix::MultiLayerCoeff_t& coeff, size_t current_layer
 //! Computes RT coefficients coeff, starting from layer number layer_index.
 //! Returns true if no overflow happens.
 
-bool calculateUpFromLayer(SpecularMatrix::MultiLayerCoeff_t& coeff, const MultiLayer& sample,
+bool calculateUpFromLayer(std::vector<ScalarRTCoefficients>& coeff, const MultiLayer& sample,
                           const double kmag, size_t layer_index)
 {
     coeff[layer_index+1].t_r(0) = 1.0;
@@ -154,7 +155,7 @@ bool calculateUpFromLayer(SpecularMatrix::MultiLayerCoeff_t& coeff, const MultiL
 //! Computes coeff, and returns largest possible start layer index.
 
 size_t bisectRTcomputation(
-    SpecularMatrix::MultiLayerCoeff_t& coeff, const MultiLayer& sample,
+    std::vector<ScalarRTCoefficients>& coeff, const MultiLayer& sample,
     const double kmag, const size_t lgood, const size_t lbad, const size_t l)
 {
     if (calculateUpFromLayer(coeff, sample, kmag, l)) {
diff --git a/Core/Multilayer/SpecularMatrix.h b/Core/Multilayer/SpecularMatrix.h
index 75ae0ade4b05b386e912fc0ccf6b5474b31c5818..edb4a3dab71142d3a1fde9f3f1f7e62f793e391c 100644
--- a/Core/Multilayer/SpecularMatrix.h
+++ b/Core/Multilayer/SpecularMatrix.h
@@ -27,13 +27,10 @@
 class BA_CORE_API_ SpecularMatrix
 {
 public:
-    //! Layer coefficients describing refraction and transmission/reflection.
-    typedef std::vector<ScalarRTCoefficients> MultiLayerCoeff_t;
-
     //! Computes refraction angles and transmission/reflection coefficients
     //! for given coherent wave propagation in a multilayer.
-    static void execute(
-        const class MultiLayer& sample, const kvector_t k, MultiLayerCoeff_t& coeff);
+    static void execute(const class MultiLayer& sample, const kvector_t k,
+                        std::vector<ScalarRTCoefficients>& coeff);
 };
 
 #endif // SPECULARMATRIX_H
diff --git a/Core/Simulation/GISASSimulation.cpp b/Core/Simulation/GISASSimulation.cpp
index 174a04704bed364e22fb092c8a5cf89cb37706b0..251500c2ca6ba9feaf6de4c1bc4bacd975c36550 100644
--- a/Core/Simulation/GISASSimulation.cpp
+++ b/Core/Simulation/GISASSimulation.cpp
@@ -52,7 +52,7 @@ void GISASSimulation::prepareSimulation()
     Simulation::prepareSimulation();
 }
 
-int GISASSimulation::numberOfSimulationElements() const
+size_t GISASSimulation::numberOfSimulationElements() const
 {
     return getInstrument().getDetector()->numberOfSimulationElements();
 }
diff --git a/Core/Simulation/GISASSimulation.h b/Core/Simulation/GISASSimulation.h
index ca51cde535d0b0ea6dad22a58f9bc331aece0f74..d42ba234737a893e9af4a06366213ecda75e8297 100644
--- a/Core/Simulation/GISASSimulation.h
+++ b/Core/Simulation/GISASSimulation.h
@@ -43,7 +43,7 @@ public:
     void prepareSimulation() final;
 
     //! Gets the number of elements this simulation needs to calculate
-    int numberOfSimulationElements() const final;
+    size_t numberOfSimulationElements() const final;
 
     //! Returns clone of the detector intensity map with detector resolution applied
     OutputData<double>* getDetectorIntensity(
diff --git a/Core/Simulation/OffSpecSimulation.cpp b/Core/Simulation/OffSpecSimulation.cpp
index 282b5bcc5334400aa7e194e9881b7e1b44d000a6..832bf39edc1b53e5b6df17be0a1c7407fe6b3bee 100644
--- a/Core/Simulation/OffSpecSimulation.cpp
+++ b/Core/Simulation/OffSpecSimulation.cpp
@@ -55,7 +55,7 @@ void OffSpecSimulation::prepareSimulation()
     Simulation::prepareSimulation();
 }
 
-int OffSpecSimulation::numberOfSimulationElements() const
+size_t OffSpecSimulation::numberOfSimulationElements() const
 {
     checkInitialization();
     return getInstrument().getDetector()->numberOfSimulationElements()*mp_alpha_i_axis->size();
diff --git a/Core/Simulation/OffSpecSimulation.h b/Core/Simulation/OffSpecSimulation.h
index cf63576ca79ba86a9b54ca378645cdeff38504b7..8db60398d630d0fcd7e21a893974c6e3d8012fc6 100644
--- a/Core/Simulation/OffSpecSimulation.h
+++ b/Core/Simulation/OffSpecSimulation.h
@@ -39,7 +39,7 @@ public:
     void prepareSimulation() final;
 
     //! Gets the number of elements this simulation needs to calculate
-    int numberOfSimulationElements() const final;
+    size_t numberOfSimulationElements() const final;
 
     //! Returns clone of the detector intensity map
     OutputData<double>* getDetectorIntensity(
diff --git a/Core/Simulation/Simulation.cpp b/Core/Simulation/Simulation.cpp
index 63a8143d1599fecc4b77dd68c85d6279a5e312bb..b2664bfe5965635a2871162157812a9a903dd62b 100644
--- a/Core/Simulation/Simulation.cpp
+++ b/Core/Simulation/Simulation.cpp
@@ -125,9 +125,9 @@ void Simulation::runSimulation()
     size_t param_combinations = m_distribution_handler.getTotalNumberOfSamples();
 
     m_progress.reset();
-    int prefac = ( mP_sample->totalNofLayouts()>0 ? 1 : 0 )
+    size_t prefactor = ( mP_sample->totalNofLayouts()>0 ? 1 : 0 )
         + ( mP_sample->hasRoughness() ? 1 : 0 );
-    m_progress.setExpectedNTicks(prefac*param_combinations*numberOfSimulationElements());
+    m_progress.setExpectedNTicks(prefactor*param_combinations*numberOfSimulationElements());
 
     // no averaging needed:
     if (param_combinations == 1) {
diff --git a/Core/Simulation/Simulation.h b/Core/Simulation/Simulation.h
index 9ff1746457375a5534622527752a25848fccafca..73b7ecaa6c6c3bdefb2027c73c78e1ecf7597de2 100644
--- a/Core/Simulation/Simulation.h
+++ b/Core/Simulation/Simulation.h
@@ -69,7 +69,7 @@ public:
     void setSampleBuilder(const std::shared_ptr<IMultiLayerBuilder> sample_builder);
     std::shared_ptr<IMultiLayerBuilder> getSampleBuilder() const { return mP_sample_builder; }
 
-    virtual int numberOfSimulationElements() const=0;
+    virtual size_t numberOfSimulationElements() const=0;
 
     //! Clone simulated intensity map
     virtual OutputData<double>* getDetectorIntensity(
diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp
index a9312fd3e97201f203463dbe64c9c16f3fa7e742..5d1d43e4f5a8330c4b5b3d44d427969d61af8be1 100644
--- a/Core/Simulation/SpecularSimulation.cpp
+++ b/Core/Simulation/SpecularSimulation.cpp
@@ -213,7 +213,7 @@ void SpecularSimulation::collectRTCoefficientsScalar(const MultiLayer *multilaye
         double alpha_i = m_data.getAxisValue(it.getIndex(), 0);
         kvector_t kvec = vecOfLambdaAlphaPhi(m_lambda, -alpha_i, 0.0);
 
-        SpecularMatrix::MultiLayerCoeff_t coeffs;
+        std::vector<ScalarRTCoefficients> coeffs;
         SpecularMatrix::execute(*multilayer, kvec, coeffs);
 
         MultiLayerRTCoefficients_t ml_coeffs;
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h
index 7063a99d5932bf2635996130d6e9ed4c9c7cfa1c..ea10dfa222c65892966e0c8008bbdc192bef5290 100644
--- a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h
+++ b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h
@@ -16,7 +16,7 @@ TEST_F(SpecularMagneticTest, initial)
 {
     MultiLayer mLayer;
     kvector_t v;
-    SpecularMagnetic::MultiLayerCoeff_t coeff;
+    std::vector<MatrixRTCoefficients> coeff;
 
     // @Error: Throws exception (Layer index is out of bounds)
     //matrix.execute(mLayer, v, coeff);
@@ -45,14 +45,14 @@ TEST_F(SpecularMagneticTest, zerofield)
     Layer substr_layer_scalar(substr_material_scalar);
     multi_layer_scalar.addLayer(air_layer);
     multi_layer_scalar.addLayer(substr_layer_scalar);
-    SpecularMatrix::MultiLayerCoeff_t coeffs_scalar;
+    std::vector<ScalarRTCoefficients> coeffs_scalar;
 
     MultiLayer multi_layer_zerofield;
     HomogeneousMagneticMaterial substr_material_zerofield("Substrate", 7e-6, 2e-8, substr_field);
     Layer substr_layer_zerofield(substr_material_zerofield);
     multi_layer_zerofield.addLayer(air_layer);
     multi_layer_zerofield.addLayer(substr_layer_zerofield);
-    SpecularMagnetic::MultiLayerCoeff_t coeffs_zerofield;
+    std::vector<MatrixRTCoefficients> coeffs_zerofield;
 
     // k1
     SpecularMatrix::execute(multi_layer_scalar, k1, coeffs_scalar);
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h b/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h
index b5ea32dfafda657317b19e682562dd083bb28e8a..c382c1fc3bd61562566adc34f6c7e1ad551d4f9e 100644
--- a/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h
+++ b/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h
@@ -14,7 +14,7 @@ TEST_F(SpecularMatrixTest, initial)
 {
     MultiLayer mLayer;
     kvector_t v;
-    SpecularMatrix::MultiLayerCoeff_t coeff;
+    std::vector<ScalarRTCoefficients> coeff;
 
     // @Error: Throws exception (Layer index is out of bounds)
     //matrix.execute(mLayer, v, coeff);
diff --git a/auto/Wrap/doxygen_core.i b/auto/Wrap/doxygen_core.i
index e82701a68679e453e2f305ee3f5cb75b1bdddeab..09b9cbda7cdebbaa2d78b1c611b6f10d261ad059 100644
--- a/auto/Wrap/doxygen_core.i
+++ b/auto/Wrap/doxygen_core.i
@@ -1134,6 +1134,11 @@ generate list of sample values
 Returns true if the distribution is in the limit case of a Dirac delta distribution. 
 ";
 
+%feature("docstring")  DistributionCosine::accept "void DistributionCosine::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 
 // File: classDistributionGate.xml
 %feature("docstring") DistributionGate "
@@ -1181,6 +1186,11 @@ Returns list of sample values.
 Returns true if the distribution is in the limit case of a Dirac delta distribution. 
 ";
 
+%feature("docstring")  DistributionGate::accept "void DistributionGate::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 
 // File: classDistributionGaussian.xml
 %feature("docstring") DistributionGaussian "
@@ -1225,6 +1235,11 @@ generate list of sample values
 Returns true if the distribution is in the limit case of a Dirac delta distribution. 
 ";
 
+%feature("docstring")  DistributionGaussian::accept "void DistributionGaussian::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 
 // File: classDistributionHandler.xml
 %feature("docstring") DistributionHandler "
@@ -1308,6 +1323,11 @@ generate list of sample values
 Returns true if the distribution is in the limit case of a Dirac delta distribution. 
 ";
 
+%feature("docstring")  DistributionLogNormal::accept "void DistributionLogNormal::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 
 // File: classDistributionLorentz.xml
 %feature("docstring") DistributionLorentz "
@@ -1352,6 +1372,11 @@ generate list of sample values
 Returns true if the distribution is in the limit case of a Dirac delta distribution. 
 ";
 
+%feature("docstring")  DistributionLorentz::accept "void DistributionLorentz::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 
 // File: classExceptions_1_1DivisionByZeroException.xml
 %feature("docstring") Exceptions::DivisionByZeroException "";
@@ -2590,7 +2615,7 @@ C++ includes: FormFactorCoherentPart.h
 %feature("docstring")  FormFactorCoherentPart::evaluatePol "Eigen::Matrix2cd FormFactorCoherentPart::evaluatePol(const SimulationElement &sim_element) const 
 ";
 
-%feature("docstring")  FormFactorCoherentPart::setSpecularInfo "void FormFactorCoherentPart::setSpecularInfo(const ILayerSpecularInfo &specular_info)
+%feature("docstring")  FormFactorCoherentPart::setSpecularInfo "void FormFactorCoherentPart::setSpecularInfo(const IFresnelMap *p_fresnel_map, size_t layer_index)
 ";
 
 %feature("docstring")  FormFactorCoherentPart::radialExtension "double FormFactorCoherentPart::radialExtension() const 
@@ -2620,7 +2645,7 @@ C++ includes: FormFactorCoherentSum.h
 %feature("docstring")  FormFactorCoherentSum::evaluatePol "Eigen::Matrix2cd FormFactorCoherentSum::evaluatePol(const SimulationElement &sim_element) const 
 ";
 
-%feature("docstring")  FormFactorCoherentSum::setSpecularInfo "void FormFactorCoherentSum::setSpecularInfo(const ILayerSpecularInfo &specular_info)
+%feature("docstring")  FormFactorCoherentSum::setSpecularInfo "void FormFactorCoherentSum::setSpecularInfo(const IFresnelMap *p_fresnel_map, size_t layer_index)
 ";
 
 %feature("docstring")  FormFactorCoherentSum::relativeAbundance "double FormFactorCoherentSum::relativeAbundance() const 
@@ -4663,6 +4688,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DCauchy::clone "FTDistribution1DCauchy* FTDistribution1DCauchy::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DCauchy::accept "void FTDistribution1DCauchy::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DCauchy::evaluate "double FTDistribution1DCauchy::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4683,6 +4713,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DCosine::clone "FTDistribution1DCosine* FTDistribution1DCosine::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DCosine::accept "void FTDistribution1DCosine::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DCosine::evaluate "double FTDistribution1DCosine::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4703,6 +4738,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DGate::clone "FTDistribution1DGate* FTDistribution1DGate::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DGate::accept "void FTDistribution1DGate::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DGate::evaluate "double FTDistribution1DGate::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4723,6 +4763,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DGauss::clone "FTDistribution1DGauss* FTDistribution1DGauss::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DGauss::accept "void FTDistribution1DGauss::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DGauss::evaluate "double FTDistribution1DGauss::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4746,6 +4791,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DTriangle::clone "FTDistribution1DTriangle* FTDistribution1DTriangle::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DTriangle::accept "void FTDistribution1DTriangle::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DTriangle::evaluate "double FTDistribution1DTriangle::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4766,6 +4816,11 @@ C++ includes: FTDistributions1D.h
 %feature("docstring")  FTDistribution1DVoigt::clone "FTDistribution1DVoigt* FTDistribution1DVoigt::clone() const final
 ";
 
+%feature("docstring")  FTDistribution1DVoigt::accept "void FTDistribution1DVoigt::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
 %feature("docstring")  FTDistribution1DVoigt::evaluate "double FTDistribution1DVoigt::evaluate(double q) const final
 
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
@@ -4903,25 +4958,6 @@ evaluate Fourier transformed distribution for q in X,Y coordinates the original
 ";
 
 
-// File: classFullFresnelMap.xml
-%feature("docstring") FullFresnelMap "";
-
-%feature("docstring")  FullFresnelMap::FullFresnelMap "FullFresnelMap::FullFresnelMap()
-";
-
-%feature("docstring")  FullFresnelMap::~FullFresnelMap "FullFresnelMap::~FullFresnelMap()
-";
-
-%feature("docstring")  FullFresnelMap::push_back "void FullFresnelMap::push_back(ILayerSpecularInfo *layer_map)
-";
-
-%feature("docstring")  FullFresnelMap::size "size_t FullFresnelMap::size() const 
-";
-
-%feature("docstring")  FullFresnelMap::layerFresnelMap "const ILayerSpecularInfo * FullFresnelMap::layerFresnelMap(size_t index) const 
-";
-
-
 // File: classGISASSimulation.xml
 %feature("docstring") GISASSimulation "
 
@@ -4955,7 +4991,7 @@ Calls the  INodeVisitor's visit method.
 Put into a clean state for running a simulation. 
 ";
 
-%feature("docstring")  GISASSimulation::numberOfSimulationElements "int GISASSimulation::numberOfSimulationElements() const final
+%feature("docstring")  GISASSimulation::numberOfSimulationElements "size_t GISASSimulation::numberOfSimulationElements() const final
 
 Gets the number of elements this simulation needs to calculate. 
 ";
@@ -5041,6 +5077,16 @@ Resets region of interest making whole detector plane available for the simulati
 ";
 
 
+// File: classHashKVector.xml
+%feature("docstring") HashKVector "";
+
+%feature("docstring")  HashKVector::HashKVector "HashKVector::HashKVector()
+";
+
+%feature("docstring")  HashKVector::~HashKVector "HashKVector::~HashKVector()
+";
+
+
 // File: classHexagonalLattice.xml
 %feature("docstring") HexagonalLattice "";
 
@@ -5723,18 +5769,13 @@ Computes an independent term of the scattering intensity. Controlled by  MainCom
 C++ includes: IComputationTerm.h
 ";
 
-%feature("docstring")  IComputationTerm::IComputationTerm "IComputationTerm::IComputationTerm(const MultiLayer *p_multilayer)
+%feature("docstring")  IComputationTerm::IComputationTerm "IComputationTerm::IComputationTerm(const MultiLayer *p_multilayer, const IFresnelMap *p_fresnel_map)
 ";
 
 %feature("docstring")  IComputationTerm::~IComputationTerm "IComputationTerm::~IComputationTerm()
 ";
 
-%feature("docstring")  IComputationTerm::setSpecularInfo "void IComputationTerm::setSpecularInfo(const FullFresnelMap *p_full_map)
-
-Sets magnetic reflection/transmission info for all layers. 
-";
-
-%feature("docstring")  IComputationTerm::eval "virtual bool IComputationTerm::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const =0
+%feature("docstring")  IComputationTerm::eval "virtual void IComputationTerm::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const =0
 
 Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
 ";
@@ -6230,6 +6271,31 @@ Returns the (approximate in some cases) radial size of the particle of this form
 ";
 
 
+// File: classIFresnelMap.xml
+%feature("docstring") IFresnelMap "
+
+Holds the necessary information to calculate the radiation wavefunction in every layer for different incoming (outgoing) angles of the beam in the top layer (these amplitudes correspond to the specular part of the wavefunction).
+
+C++ includes: IFresnelMap.h
+";
+
+%feature("docstring")  IFresnelMap::IFresnelMap "IFresnelMap::IFresnelMap()
+";
+
+%feature("docstring")  IFresnelMap::~IFresnelMap "IFresnelMap::~IFresnelMap()
+";
+
+%feature("docstring")  IFresnelMap::getOutCoefficients "virtual const ILayerRTCoefficients* IFresnelMap::getOutCoefficients(const SimulationElement &sim_element, size_t layer_index) const =0
+
+Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector. 
+";
+
+%feature("docstring")  IFresnelMap::getInCoefficients "virtual const ILayerRTCoefficients* IFresnelMap::getInCoefficients(const SimulationElement &sim_element, size_t layer_index) const =0
+
+Retrieves the amplitude coefficients for an incoming wavevector. 
+";
+
+
 // File: classIFTDecayFunction1D.xml
 %feature("docstring") IFTDecayFunction1D "
 
@@ -6836,34 +6902,6 @@ Scalar value getters; these throw errors by default as they should only be used
 ";
 
 
-// File: classILayerSpecularInfo.xml
-%feature("docstring") ILayerSpecularInfo "
-
-Holds the necessary information to calculate the radiation wavefunction in a specific layer for different incoming (outgoing) angles of the beam in the top layer (these amplitudes correspond to the specular part of the wavefunction).
-
-C++ includes: ILayerSpecularInfo.h
-";
-
-%feature("docstring")  ILayerSpecularInfo::ILayerSpecularInfo "ILayerSpecularInfo::ILayerSpecularInfo()
-";
-
-%feature("docstring")  ILayerSpecularInfo::~ILayerSpecularInfo "ILayerSpecularInfo::~ILayerSpecularInfo()
-";
-
-%feature("docstring")  ILayerSpecularInfo::clone "ILayerSpecularInfo* ILayerSpecularInfo::clone() const =0
-";
-
-%feature("docstring")  ILayerSpecularInfo::getOutCoefficients "virtual const ILayerRTCoefficients* ILayerSpecularInfo::getOutCoefficients(const SimulationElement &sim_element) const =0
-
-Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector. 
-";
-
-%feature("docstring")  ILayerSpecularInfo::getInCoefficients "virtual const ILayerRTCoefficients* ILayerSpecularInfo::getInCoefficients(const SimulationElement &sim_element) const =0
-
-Retrieves the amplitude coefficients for an incoming wavevector. 
-";
-
-
 // File: classILayout.xml
 %feature("docstring") ILayout "
 
@@ -7450,6 +7488,39 @@ C++ includes: INodeVisitor.h
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const HexagonalLattice *)
 ";
 
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DCauchy *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DGauss *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DGate *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DTriangle *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DCosine *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FTDistribution1DVoigt *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionGate *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionLorentz *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionGaussian *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionLogNormal *)
+";
+
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionCosine *)
+";
+
 %feature("docstring")  INodeVisitor::depth "int INodeVisitor::depth() const
 
 Returns depth of the visitor in the composite hierarchy. 
@@ -7845,6 +7916,11 @@ Calls the  INodeVisitor's visit method.
 Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 ";
 
+%feature("docstring")  InterferenceFunction1DLattice::getChildren "std::vector< const INode * > InterferenceFunction1DLattice::getChildren() const override
+
+Returns a vector of children (const). 
+";
+
 
 // File: classInterferenceFunction2DLattice.xml
 %feature("docstring") InterferenceFunction2DLattice "
@@ -8110,6 +8186,11 @@ Evaluates the interference function for a given wavevector transfer (only the re
 %feature("docstring")  InterferenceFunctionRadialParaCrystal::getDampingLength "double InterferenceFunctionRadialParaCrystal::getDampingLength() const 
 ";
 
+%feature("docstring")  InterferenceFunctionRadialParaCrystal::getChildren "std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override
+
+Returns a vector of children (const). 
+";
+
 
 // File: classIObservable.xml
 %feature("docstring") IObservable "
@@ -8265,6 +8346,9 @@ Returns parameter with given 'name'.
 Action to be taken in inherited class when a parameter has changed. 
 ";
 
+%feature("docstring")  IParameterized::removeParameter "void IParameterized::removeParameter(const std::string &name)
+";
+
 
 // File: classIParticle.xml
 %feature("docstring") IParticle "
@@ -8342,6 +8426,14 @@ Applies extra translation by adding it to the current one.
 Returns a vector of children (const). 
 ";
 
+%feature("docstring")  IParticle::registerAbundance "void IParticle::registerAbundance(bool make_registered=true)
+";
+
+%feature("docstring")  IParticle::registerPosition "void IParticle::registerPosition(bool make_registered=true)
+
+Registers the three components of its position. 
+";
+
 
 // File: classIPixel.xml
 %feature("docstring") IPixel "
@@ -8840,7 +8932,7 @@ length:
  Lattice constant.
 
 xi: 
-TODO: seems unused; explain or remove 
+ Lattice rotation angle. 
 ";
 
 
@@ -8871,6 +8963,9 @@ TODO: seems unused; explain or remove
 %feature("docstring")  Lattice2D::reciprocalBases "Lattice2D::ReciprocalBases Lattice2D::reciprocalBases() const 
 ";
 
+%feature("docstring")  Lattice2D::setRotationEnabled "void Lattice2D::setRotationEnabled(bool enabled)
+";
+
 
 // File: classLayer.xml
 %feature("docstring") Layer "
@@ -8946,6 +9041,9 @@ Returns true if decoration is present.
 Returns a vector of children (const). 
 ";
 
+%feature("docstring")  Layer::registerThickness "void Layer::registerThickness(bool make_registered=true)
+";
+
 
 // File: classLayerInterface.xml
 %feature("docstring") LayerInterface "
@@ -9069,7 +9167,7 @@ Methods to generate a simulation strategy for a  ParticleLayoutComputation.
 C++ includes: LayerStrategyBuilder.h
 ";
 
-%feature("docstring")  LayerStrategyBuilder::LayerStrategyBuilder "LayerStrategyBuilder::LayerStrategyBuilder(const MultiLayer *p_multilayer, const ILayout *p_layout, const FullFresnelMap *p_full_map, bool polarized, const SimulationOptions &sim_params, size_t layer_index)
+%feature("docstring")  LayerStrategyBuilder::LayerStrategyBuilder "LayerStrategyBuilder::LayerStrategyBuilder(const MultiLayer *p_multilayer, const ILayout *p_layout, const IFresnelMap *p_fresnel_map, bool polarized, const SimulationOptions &sim_params, size_t layer_index)
 ";
 
 %feature("docstring")  LayerStrategyBuilder::~LayerStrategyBuilder "LayerStrategyBuilder::~LayerStrategyBuilder()
@@ -9247,6 +9345,31 @@ C++ includes: MainComputation.h
 ";
 
 
+// File: classMatrixFresnelMap.xml
+%feature("docstring") MatrixFresnelMap "
+
+Implementation of  IFresnelMap for matrix valued reflection/transmission coefficients.
+
+C++ includes: MatrixFresnelMap.h
+";
+
+%feature("docstring")  MatrixFresnelMap::MatrixFresnelMap "MatrixFresnelMap::MatrixFresnelMap(const MultiLayer *p_multilayer, const MultiLayer *p_inverted_multilayer)
+";
+
+%feature("docstring")  MatrixFresnelMap::~MatrixFresnelMap "MatrixFresnelMap::~MatrixFresnelMap() final
+";
+
+%feature("docstring")  MatrixFresnelMap::getOutCoefficients "const ILayerRTCoefficients * MatrixFresnelMap::getOutCoefficients(const SimulationElement &sim_element, size_t layer_index) const finaloverride
+
+Retrieves the amplitude coefficients for the given angles. 
+";
+
+%feature("docstring")  MatrixFresnelMap::getInCoefficients "const ILayerRTCoefficients * MatrixFresnelMap::getInCoefficients(const SimulationElement &sim_element, size_t layer_index) const finaloverride
+
+Retrieves the amplitude coefficients for the given angles. 
+";
+
+
 // File: classMatrixRTCoefficients.xml
 %feature("docstring") MatrixRTCoefficients "
 
@@ -9296,34 +9419,6 @@ Returns z-part of the two wavevector eigenmodes.
 ";
 
 
-// File: classMatrixSpecularInfoMap.xml
-%feature("docstring") MatrixSpecularInfoMap "
-
-Implementation of ISpecularInfoMap for matrix valued reflection/transmission coefficients.
-
-C++ includes: MatrixSpecularInfoMap.h
-";
-
-%feature("docstring")  MatrixSpecularInfoMap::MatrixSpecularInfoMap "MatrixSpecularInfoMap::MatrixSpecularInfoMap(const MultiLayer *p_multilayer, const MultiLayer *p_inverted_multilayer, size_t layer_index)
-";
-
-%feature("docstring")  MatrixSpecularInfoMap::~MatrixSpecularInfoMap "MatrixSpecularInfoMap::~MatrixSpecularInfoMap() final
-";
-
-%feature("docstring")  MatrixSpecularInfoMap::clone "MatrixSpecularInfoMap * MatrixSpecularInfoMap::clone() const finaloverride
-";
-
-%feature("docstring")  MatrixSpecularInfoMap::getOutCoefficients "const ILayerRTCoefficients * MatrixSpecularInfoMap::getOutCoefficients(const SimulationElement &sim_element) const finaloverride
-
-Retrieves the amplitude coefficients for the given angles. 
-";
-
-%feature("docstring")  MatrixSpecularInfoMap::getInCoefficients "const ILayerRTCoefficients * MatrixSpecularInfoMap::getInCoefficients(const SimulationElement &sim_element) const finaloverride
-
-Retrieves the amplitude coefficients for the given angles. 
-";
-
-
 // File: classMesoCrystal.xml
 %feature("docstring") MesoCrystal "
 
@@ -9627,7 +9722,7 @@ Calls the  INodeVisitor's visit method.
 Put into a clean state for running a simulation. 
 ";
 
-%feature("docstring")  OffSpecSimulation::numberOfSimulationElements "int OffSpecSimulation::numberOfSimulationElements() const final
+%feature("docstring")  OffSpecSimulation::numberOfSimulationElements "size_t OffSpecSimulation::numberOfSimulationElements() const final
 
 Gets the number of elements this simulation needs to calculate. 
 ";
@@ -10158,6 +10253,9 @@ get the sigma factor
 %feature("docstring")  ParameterDistribution::getDistribution "const IDistribution1D * ParameterDistribution::getDistribution() const 
 ";
 
+%feature("docstring")  ParameterDistribution::getDistribution "IDistribution1D * ParameterDistribution::getDistribution()
+";
+
 %feature("docstring")  ParameterDistribution::generateSamples "std::vector< ParameterSample > ParameterDistribution::generateSamples() const
 
 generate list of sampled values with their weight 
@@ -10288,6 +10386,11 @@ Sets value of the one parameter that matches  pattern ('*' allowed), or throws.
 %feature("docstring")  ParameterPool::parameterNames "std::vector< std::string > ParameterPool::parameterNames() const 
 ";
 
+%feature("docstring")  ParameterPool::removeParameter "void ParameterPool::removeParameter(const std::string &name)
+
+Removes parameter with given name from the pool. 
+";
+
 
 // File: classParameterSample.xml
 %feature("docstring") ParameterSample "
@@ -10748,10 +10851,10 @@ Computes the scattering contribution from one particle layout. Controlled by  Ma
 C++ includes: ParticleLayoutComputation.h
 ";
 
-%feature("docstring")  ParticleLayoutComputation::ParticleLayoutComputation "ParticleLayoutComputation::ParticleLayoutComputation(const MultiLayer *p_multilayer, const ILayout *p_layout, size_t layer_index)
+%feature("docstring")  ParticleLayoutComputation::ParticleLayoutComputation "ParticleLayoutComputation::ParticleLayoutComputation(const MultiLayer *p_multilayer, const IFresnelMap *p_fresnel_map, const ILayout *p_layout, size_t layer_index)
 ";
 
-%feature("docstring")  ParticleLayoutComputation::eval "bool ParticleLayoutComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
+%feature("docstring")  ParticleLayoutComputation::eval "void ParticleLayoutComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
 
 Computes scattering intensity for given range of simulation elements. 
 ";
@@ -11488,13 +11591,13 @@ Computes the diffuse reflection from the rough interfaces of a multilayer. Contr
 C++ includes: RoughMultiLayerComputation.h
 ";
 
-%feature("docstring")  RoughMultiLayerComputation::RoughMultiLayerComputation "RoughMultiLayerComputation::RoughMultiLayerComputation(const MultiLayer *p_multi_layer)
+%feature("docstring")  RoughMultiLayerComputation::RoughMultiLayerComputation "RoughMultiLayerComputation::RoughMultiLayerComputation(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
 ";
 
 %feature("docstring")  RoughMultiLayerComputation::~RoughMultiLayerComputation "RoughMultiLayerComputation::~RoughMultiLayerComputation()
 ";
 
-%feature("docstring")  RoughMultiLayerComputation::eval "bool RoughMultiLayerComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
+%feature("docstring")  RoughMultiLayerComputation::eval "void RoughMultiLayerComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
 
 Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
 ";
@@ -11773,6 +11876,31 @@ C++ includes: SampleTreeIterator.h
 ";
 
 
+// File: classScalarFresnelMap.xml
+%feature("docstring") ScalarFresnelMap "
+
+Implementation of  IFresnelMap for scalar valued reflection/transmission coefficients.
+
+C++ includes: ScalarFresnelMap.h
+";
+
+%feature("docstring")  ScalarFresnelMap::ScalarFresnelMap "ScalarFresnelMap::ScalarFresnelMap(const MultiLayer *multilayer)
+";
+
+%feature("docstring")  ScalarFresnelMap::~ScalarFresnelMap "ScalarFresnelMap::~ScalarFresnelMap() final
+";
+
+%feature("docstring")  ScalarFresnelMap::getOutCoefficients "const ILayerRTCoefficients * ScalarFresnelMap::getOutCoefficients(const SimulationElement &sim_element, size_t layer_index) const finaloverride
+
+Retrieves the amplitude coefficients for the given angles. 
+";
+
+%feature("docstring")  ScalarFresnelMap::getInCoefficients "const ILayerRTCoefficients * ScalarFresnelMap::getInCoefficients(const SimulationElement &sim_element, size_t layer_index) const finaloverride
+
+Retrieves the amplitude coefficients for the given angles. 
+";
+
+
 // File: classScalarRTCoefficients.xml
 %feature("docstring") ScalarRTCoefficients "
 
@@ -11833,34 +11961,6 @@ Scalar value getters; these throw errors by default as they should only be used
 ";
 
 
-// File: classScalarSpecularInfoMap.xml
-%feature("docstring") ScalarSpecularInfoMap "
-
-Implementation of ISpecularInfoMap for scalar valued reflection/transmission coefficients.
-
-C++ includes: ScalarSpecularInfoMap.h
-";
-
-%feature("docstring")  ScalarSpecularInfoMap::ScalarSpecularInfoMap "ScalarSpecularInfoMap::ScalarSpecularInfoMap(const MultiLayer *multilayer, size_t layer_index)
-";
-
-%feature("docstring")  ScalarSpecularInfoMap::~ScalarSpecularInfoMap "ScalarSpecularInfoMap::~ScalarSpecularInfoMap() final
-";
-
-%feature("docstring")  ScalarSpecularInfoMap::clone "ScalarSpecularInfoMap* ScalarSpecularInfoMap::clone() const finaloverride
-";
-
-%feature("docstring")  ScalarSpecularInfoMap::getOutCoefficients "const ILayerRTCoefficients * ScalarSpecularInfoMap::getOutCoefficients(const SimulationElement &sim_element) const finaloverride
-
-Retrieves the amplitude coefficients for the given angles. 
-";
-
-%feature("docstring")  ScalarSpecularInfoMap::getInCoefficients "const ILayerRTCoefficients * ScalarSpecularInfoMap::getInCoefficients(const SimulationElement &sim_element) const finaloverride
-
-Retrieves the amplitude coefficients for the given angles. 
-";
-
-
 // File: classExceptions_1_1SelfReferenceException.xml
 %feature("docstring") Exceptions::SelfReferenceException "";
 
@@ -11969,7 +12069,7 @@ The  MultiLayer object will not be owned by the  Simulation object.
 %feature("docstring")  Simulation::getSampleBuilder "std::shared_ptr<IMultiLayerBuilder> Simulation::getSampleBuilder() const 
 ";
 
-%feature("docstring")  Simulation::numberOfSimulationElements "virtual int Simulation::numberOfSimulationElements() const =0
+%feature("docstring")  Simulation::numberOfSimulationElements "virtual size_t Simulation::numberOfSimulationElements() const =0
 ";
 
 %feature("docstring")  Simulation::getDetectorIntensity "virtual OutputData<double>* Simulation::getDetectorIntensity(IDetector2D::EAxesUnits units_type=IDetector2D::DEFAULT) const =0
@@ -12342,10 +12442,10 @@ Computes the specular scattering. Controlled by  MainComputation.
 C++ includes: SpecularComputation.h
 ";
 
-%feature("docstring")  SpecularComputation::SpecularComputation "SpecularComputation::SpecularComputation(const MultiLayer *p_multi_layer)
+%feature("docstring")  SpecularComputation::SpecularComputation "SpecularComputation::SpecularComputation(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
 ";
 
-%feature("docstring")  SpecularComputation::eval "bool SpecularComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
+%feature("docstring")  SpecularComputation::eval "void SpecularComputation::eval(const SimulationOptions &options, ProgressHandler *progress, bool polarized, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
 
 Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
 ";
@@ -13074,16 +13174,19 @@ C++ includes: WavevectorInfo.h
 // File: classConvolve_1_1Workspace.xml
 
 
-// File: namespace_0D147.xml
+// File: namespace_0D145.xml
 
 
-// File: namespace_0D190.xml
+// File: namespace_0D188.xml
 
 
-// File: namespace_0D270.xml
+// File: namespace_0D22.xml
 
 
-// File: namespace_0D282.xml
+// File: namespace_0D268.xml
+
+
+// File: namespace_0D280.xml
 
 
 // File: namespace_0D308.xml
@@ -13098,10 +13201,10 @@ C++ includes: WavevectorInfo.h
 // File: namespace_0D436.xml
 
 
-// File: namespace_0D62.xml
+// File: namespace_0D60.xml
 
 
-// File: namespace_0D77.xml
+// File: namespace_0D75.xml
 
 
 // File: namespaceArrayUtils.xml
@@ -13813,12 +13916,6 @@ Add element vector to element vector with weight.
 // File: DelayedProgressCounter_8h.xml
 
 
-// File: FullFresnelMap_8cpp.xml
-
-
-// File: FullFresnelMap_8h.xml
-
-
 // File: IComputationTerm_8cpp.xml
 
 
@@ -14515,19 +14612,25 @@ make Swappable
 // File: FormFactorDWBAPol_8h.xml
 
 
-// File: IInterferenceFunctionStrategy_8cpp.xml
+// File: HashKVector_8cpp.xml
 
 
-// File: IInterferenceFunctionStrategy_8h.xml
+// File: HashKVector_8h.xml
 
 
-// File: ILayerRTCoefficients_8h.xml
+// File: IFresnelMap_8cpp.xml
+
+
+// File: IFresnelMap_8h.xml
 
 
-// File: ILayerSpecularInfo_8cpp.xml
+// File: IInterferenceFunctionStrategy_8cpp.xml
+
 
+// File: IInterferenceFunctionStrategy_8h.xml
 
-// File: ILayerSpecularInfo_8h.xml
+
+// File: ILayerRTCoefficients_8h.xml
 
 
 // File: IMultiLayerBuilder_8cpp.xml
@@ -14560,16 +14663,16 @@ make Swappable
 // File: LayerStrategyBuilder_8h.xml
 
 
-// File: MatrixRTCoefficients_8cpp.xml
+// File: MatrixFresnelMap_8cpp.xml
 
 
-// File: MatrixRTCoefficients_8h.xml
+// File: MatrixFresnelMap_8h.xml
 
 
-// File: MatrixSpecularInfoMap_8cpp.xml
+// File: MatrixRTCoefficients_8cpp.xml
 
 
-// File: MatrixSpecularInfoMap_8h.xml
+// File: MatrixRTCoefficients_8h.xml
 
 
 // File: MultiLayer_8cpp.xml
@@ -14578,13 +14681,13 @@ make Swappable
 // File: MultiLayer_8h.xml
 
 
-// File: ScalarRTCoefficients_8h.xml
+// File: ScalarFresnelMap_8cpp.xml
 
 
-// File: ScalarSpecularInfoMap_8cpp.xml
+// File: ScalarFresnelMap_8h.xml
 
 
-// File: ScalarSpecularInfoMap_8h.xml
+// File: ScalarRTCoefficients_8h.xml
 
 
 // File: SpecularMagnetic_8cpp.xml
@@ -14594,17 +14697,17 @@ make Swappable
 
 
 // File: SpecularMatrix_8cpp.xml
-%feature("docstring")  setZeroBelow "void setZeroBelow(SpecularMatrix::MultiLayerCoeff_t &coeff, size_t current_layer)
+%feature("docstring")  setZeroBelow "void setZeroBelow(std::vector< ScalarRTCoefficients > &coeff, size_t current_layer)
 
 Sets coeff to zero for all layers below current_layer. 
 ";
 
-%feature("docstring")  calculateUpFromLayer "bool calculateUpFromLayer(SpecularMatrix::MultiLayerCoeff_t &coeff, const MultiLayer &sample, const double kmag, size_t layer_index)
+%feature("docstring")  calculateUpFromLayer "bool calculateUpFromLayer(std::vector< ScalarRTCoefficients > &coeff, const MultiLayer &sample, const double kmag, size_t layer_index)
 
 Computes RT coefficients coeff, starting from layer number layer_index. Returns true if no overflow happens. 
 ";
 
-%feature("docstring")  bisectRTcomputation "size_t bisectRTcomputation(SpecularMatrix::MultiLayerCoeff_t &coeff, const MultiLayer &sample, const double kmag, const size_t lgood, const size_t lbad, const size_t l)
+%feature("docstring")  bisectRTcomputation "size_t bisectRTcomputation(std::vector< ScalarRTCoefficients > &coeff, const MultiLayer &sample, const double kmag, const size_t lgood, const size_t lbad, const size_t l)
 
 Recursive bisection to determine the number of the deepest layer where RT computation can be started without running into overflow. Computes coeff, and returns largest possible start layer index. 
 ";
diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py
index 85b9003291ed2d1761ace9638d759dc937f0f2cb..435ef244d408336f77af063daf1188335ad8df27 100644
--- a/auto/Wrap/libBornAgainCore.py
+++ b/auto/Wrap/libBornAgainCore.py
@@ -1987,7 +1987,12 @@ class IParameterized(INamed):
 
 
     def removeParameter(self, name):
-        """removeParameter(IParameterized self, std::string const & name)"""
+        """
+        removeParameter(IParameterized self, std::string const & name)
+
+        void IParameterized::removeParameter(const std::string &name)
+
+        """
         return _libBornAgainCore.IParameterized_removeParameter(self, name)
 
     def __disown__(self):
@@ -7506,7 +7511,7 @@ class INodeVisitor(_object):
         visit(INodeVisitor self, DistributionLogNormal arg2)
         visit(INodeVisitor self, DistributionCosine arg2)
 
-        virtual void INodeVisitor::visit(const HexagonalLattice *)
+        virtual void INodeVisitor::visit(const DistributionCosine *)
 
         """
         return _libBornAgainCore.INodeVisitor_visit(self, *args)
@@ -8035,7 +8040,7 @@ class DistributionGate(IDistribution1D):
         """
         accept(DistributionGate self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void DistributionGate::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -8154,7 +8159,7 @@ class DistributionLorentz(IDistribution1D):
         """
         accept(DistributionLorentz self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void DistributionLorentz::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -8273,7 +8278,7 @@ class DistributionGaussian(IDistribution1D):
         """
         accept(DistributionGaussian self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void DistributionGaussian::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -8402,7 +8407,7 @@ class DistributionLogNormal(IDistribution1D):
         """
         accept(DistributionLogNormal self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void DistributionLogNormal::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -8521,7 +8526,7 @@ class DistributionCosine(IDistribution1D):
         """
         accept(DistributionCosine self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void DistributionCosine::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9629,7 +9634,7 @@ class FTDistribution1DCauchy(IFTDistribution1D):
         """
         accept(FTDistribution1DCauchy self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DCauchy::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9700,7 +9705,7 @@ class FTDistribution1DGauss(IFTDistribution1D):
         """
         accept(FTDistribution1DGauss self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DGauss::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9771,7 +9776,7 @@ class FTDistribution1DGate(IFTDistribution1D):
         """
         accept(FTDistribution1DGate self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DGate::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9844,7 +9849,7 @@ class FTDistribution1DTriangle(IFTDistribution1D):
         """
         accept(FTDistribution1DTriangle self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DTriangle::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9913,7 +9918,7 @@ class FTDistribution1DCosine(IFTDistribution1D):
         """
         accept(FTDistribution1DCosine self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DCosine::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -9984,7 +9989,7 @@ class FTDistribution1DVoigt(IFTDistribution1D):
         """
         accept(FTDistribution1DVoigt self, INodeVisitor visitor)
 
-        virtual void INode::accept(INodeVisitor *visitor) const =0
+        void FTDistribution1DVoigt::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
@@ -15784,9 +15789,9 @@ class Simulation(ICloneable, INode):
 
     def numberOfSimulationElements(self):
         """
-        numberOfSimulationElements(Simulation self) -> int
+        numberOfSimulationElements(Simulation self) -> size_t
 
-        virtual int Simulation::numberOfSimulationElements() const =0
+        virtual size_t Simulation::numberOfSimulationElements() const =0
 
         """
         return _libBornAgainCore.Simulation_numberOfSimulationElements(self)
@@ -16137,9 +16142,9 @@ class GISASSimulation(Simulation):
 
     def numberOfSimulationElements(self):
         """
-        numberOfSimulationElements(GISASSimulation self) -> int
+        numberOfSimulationElements(GISASSimulation self) -> size_t
 
-        int GISASSimulation::numberOfSimulationElements() const final
+        size_t GISASSimulation::numberOfSimulationElements() const final
 
         Gets the number of elements this simulation needs to calculate. 
 
@@ -18614,6 +18619,9 @@ class IParticle(IAbstractParticle):
         """
         registerAbundance(IParticle self, bool make_registered=True)
         registerAbundance(IParticle self)
+
+        void IParticle::registerAbundance(bool make_registered=true)
+
         """
         return _libBornAgainCore.IParticle_registerAbundance(self, make_registered)
 
@@ -18622,6 +18630,11 @@ class IParticle(IAbstractParticle):
         """
         registerPosition(IParticle self, bool make_registered=True)
         registerPosition(IParticle self)
+
+        void IParticle::registerPosition(bool make_registered=true)
+
+        Registers the three components of its position. 
+
         """
         return _libBornAgainCore.IParticle_registerPosition(self, make_registered)
 
@@ -19832,7 +19845,7 @@ class InterferenceFunction1DLattice(IInterferenceFunction):
         """
         getChildren(InterferenceFunction1DLattice self) -> swig_dummy_type_const_inode_vector
 
-        std::vector< const INode * > INode::getChildren() const
+        std::vector< const INode * > InterferenceFunction1DLattice::getChildren() const override
 
         Returns a vector of children (const). 
 
@@ -20008,7 +20021,7 @@ class InterferenceFunctionRadialParaCrystal(IInterferenceFunction):
         """
         getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector
 
-        std::vector< const INode * > INode::getChildren() const
+        std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override
 
         Returns a vector of children (const). 
 
@@ -21081,7 +21094,7 @@ class Lattice1DParameters(_object):
          Lattice constant.
 
         xi: 
-        TODO: seems unused; explain or remove 
+         Lattice rotation angle. 
 
         """
         this = _libBornAgainCore.new_Lattice1DParameters(*args)
@@ -21189,7 +21202,12 @@ class Lattice2D(ICloneable, INode):
 
 
     def setRotationEnabled(self, enabled):
-        """setRotationEnabled(Lattice2D self, bool enabled)"""
+        """
+        setRotationEnabled(Lattice2D self, bool enabled)
+
+        void Lattice2D::setRotationEnabled(bool enabled)
+
+        """
         return _libBornAgainCore.Lattice2D_setRotationEnabled(self, enabled)
 
     __swig_destroy__ = _libBornAgainCore.delete_Lattice2D
@@ -21574,6 +21592,9 @@ class Layer(ISample):
         """
         registerThickness(Layer self, bool make_registered=True)
         registerThickness(Layer self)
+
+        void Layer::registerThickness(bool make_registered=true)
+
         """
         return _libBornAgainCore.Layer_registerThickness(self, make_registered)
 
@@ -22533,9 +22554,9 @@ class OffSpecSimulation(Simulation):
 
     def numberOfSimulationElements(self):
         """
-        numberOfSimulationElements(OffSpecSimulation self) -> int
+        numberOfSimulationElements(OffSpecSimulation self) -> size_t
 
-        int OffSpecSimulation::numberOfSimulationElements() const final
+        size_t OffSpecSimulation::numberOfSimulationElements() const final
 
         Gets the number of elements this simulation needs to calculate. 
 
@@ -23159,7 +23180,7 @@ class ParameterDistribution(IParameterized):
         getDistribution(ParameterDistribution self) -> IDistribution1D
         getDistribution(ParameterDistribution self) -> IDistribution1D
 
-        const IDistribution1D * ParameterDistribution::getDistribution() const 
+        IDistribution1D * ParameterDistribution::getDistribution()
 
         """
         return _libBornAgainCore.ParameterDistribution_getDistribution(self, *args)
@@ -23416,7 +23437,14 @@ class ParameterPool(ICloneable):
 
 
     def removeParameter(self, name):
-        """removeParameter(ParameterPool self, std::string const & name)"""
+        """
+        removeParameter(ParameterPool self, std::string const & name)
+
+        void ParameterPool::removeParameter(const std::string &name)
+
+        Removes parameter with given name from the pool. 
+
+        """
         return _libBornAgainCore.ParameterPool_removeParameter(self, name)
 
 ParameterPool_swigregister = _libBornAgainCore.ParameterPool_swigregister
diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp
index 25ff2e44b31f18ff73dd6c868e7e4f7bc166fcc5..9ff9998abcae9dc7c91e7b12028daed36ec66f7c 100644
--- a/auto/Wrap/libBornAgainCore_wrap.cpp
+++ b/auto/Wrap/libBornAgainCore_wrap.cpp
@@ -5983,7 +5983,7 @@ SWIG_AsVal_std_complex_Sl_double_Sg_  (PyObject *o, std::complex<double>* val)
 
 
 SWIGINTERNINLINE PyObject*
-SWIG_From_std_complex_Sl_double_Sg_  (/*@SWIG:/home/pospelov/software/local/share/swig/3.0.8/typemaps/swigmacros.swg,104,%ifcplusplus@*/
+SWIG_From_std_complex_Sl_double_Sg_  (/*@SWIG:/usr/share/swig3.0/typemaps/swigmacros.swg,104,%ifcplusplus@*/
 
 const std::complex<double>&
 
@@ -73691,7 +73691,7 @@ SWIGINTERN PyObject *_wrap_Simulation_numberOfSimulationElements(PyObject *SWIGU
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  size_t result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Simulation_numberOfSimulationElements",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Simulation, 0 |  0 );
@@ -73699,8 +73699,8 @@ SWIGINTERN PyObject *_wrap_Simulation_numberOfSimulationElements(PyObject *SWIGU
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Simulation_numberOfSimulationElements" "', argument " "1"" of type '" "Simulation const *""'"); 
   }
   arg1 = reinterpret_cast< Simulation * >(argp1);
-  result = (int)((Simulation const *)arg1)->numberOfSimulationElements();
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = ((Simulation const *)arg1)->numberOfSimulationElements();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
@@ -75074,7 +75074,7 @@ SWIGINTERN PyObject *_wrap_GISASSimulation_numberOfSimulationElements(PyObject *
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  size_t result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:GISASSimulation_numberOfSimulationElements",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GISASSimulation, 0 |  0 );
@@ -75082,8 +75082,8 @@ SWIGINTERN PyObject *_wrap_GISASSimulation_numberOfSimulationElements(PyObject *
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GISASSimulation_numberOfSimulationElements" "', argument " "1"" of type '" "GISASSimulation const *""'"); 
   }
   arg1 = reinterpret_cast< GISASSimulation * >(argp1);
-  result = (int)((GISASSimulation const *)arg1)->numberOfSimulationElements();
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = ((GISASSimulation const *)arg1)->numberOfSimulationElements();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
@@ -94975,7 +94975,7 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_numberOfSimulationElements(PyObject
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  size_t result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:OffSpecSimulation_numberOfSimulationElements",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
@@ -94983,8 +94983,8 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_numberOfSimulationElements(PyObject
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_numberOfSimulationElements" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
   }
   arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
-  result = (int)((OffSpecSimulation const *)arg1)->numberOfSimulationElements();
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = ((OffSpecSimulation const *)arg1)->numberOfSimulationElements();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
@@ -108842,7 +108842,12 @@ static PyMethodDef SwigMethods[] = {
 		"Action to be taken in inherited class when a parameter has changed. \n"
 		"\n"
 		""},
-	 { (char *)"IParameterized_removeParameter", _wrap_IParameterized_removeParameter, METH_VARARGS, (char *)"IParameterized_removeParameter(IParameterized self, std::string const & name)"},
+	 { (char *)"IParameterized_removeParameter", _wrap_IParameterized_removeParameter, METH_VARARGS, (char *)"\n"
+		"IParameterized_removeParameter(IParameterized self, std::string const & name)\n"
+		"\n"
+		"void IParameterized::removeParameter(const std::string &name)\n"
+		"\n"
+		""},
 	 { (char *)"disown_IParameterized", _wrap_disown_IParameterized, METH_VARARGS, NULL},
 	 { (char *)"IParameterized_swigregister", IParameterized_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_INode", _wrap_new_INode, METH_VARARGS, (char *)"\n"
@@ -111704,7 +111709,7 @@ static PyMethodDef SwigMethods[] = {
 		"visit(DistributionLogNormal arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, DistributionCosine arg3)\n"
 		"\n"
-		"virtual void INodeVisitor::visit(const HexagonalLattice *)\n"
+		"virtual void INodeVisitor::visit(const DistributionCosine *)\n"
 		"\n"
 		""},
 	 { (char *)"INodeVisitor_depth", _wrap_INodeVisitor_depth, METH_VARARGS, (char *)"\n"
@@ -112002,7 +112007,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DistributionGate_accept", _wrap_DistributionGate_accept, METH_VARARGS, (char *)"\n"
 		"DistributionGate_accept(DistributionGate self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void DistributionGate::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112069,7 +112074,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DistributionLorentz_accept", _wrap_DistributionLorentz_accept, METH_VARARGS, (char *)"\n"
 		"DistributionLorentz_accept(DistributionLorentz self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void DistributionLorentz::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112136,7 +112141,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DistributionGaussian_accept", _wrap_DistributionGaussian_accept, METH_VARARGS, (char *)"\n"
 		"DistributionGaussian_accept(DistributionGaussian self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void DistributionGaussian::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112209,7 +112214,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DistributionLogNormal_accept", _wrap_DistributionLogNormal_accept, METH_VARARGS, (char *)"\n"
 		"DistributionLogNormal_accept(DistributionLogNormal self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void DistributionLogNormal::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112276,7 +112281,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DistributionCosine_accept", _wrap_DistributionCosine_accept, METH_VARARGS, (char *)"\n"
 		"DistributionCosine_accept(DistributionCosine self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void DistributionCosine::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112792,7 +112797,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DCauchy_accept", _wrap_FTDistribution1DCauchy_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DCauchy_accept(FTDistribution1DCauchy self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DCauchy::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112822,7 +112827,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DGauss_accept", _wrap_FTDistribution1DGauss_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DGauss_accept(FTDistribution1DGauss self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DGauss::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112852,7 +112857,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DGate_accept", _wrap_FTDistribution1DGate_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DGate_accept(FTDistribution1DGate self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DGate::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112888,7 +112893,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DTriangle_accept", _wrap_FTDistribution1DTriangle_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DTriangle_accept(FTDistribution1DTriangle self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DTriangle::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112917,7 +112922,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DCosine_accept", _wrap_FTDistribution1DCosine_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DCosine_accept(FTDistribution1DCosine self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DCosine::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -112947,7 +112952,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FTDistribution1DVoigt_accept", _wrap_FTDistribution1DVoigt_accept, METH_VARARGS, (char *)"\n"
 		"FTDistribution1DVoigt_accept(FTDistribution1DVoigt self, INodeVisitor visitor)\n"
 		"\n"
-		"virtual void INode::accept(INodeVisitor *visitor) const =0\n"
+		"void FTDistribution1DVoigt::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
@@ -115897,9 +115902,9 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"Simulation_numberOfSimulationElements", _wrap_Simulation_numberOfSimulationElements, METH_VARARGS, (char *)"\n"
-		"Simulation_numberOfSimulationElements(Simulation self) -> int\n"
+		"Simulation_numberOfSimulationElements(Simulation self) -> size_t\n"
 		"\n"
-		"virtual int Simulation::numberOfSimulationElements() const =0\n"
+		"virtual size_t Simulation::numberOfSimulationElements() const =0\n"
 		"\n"
 		""},
 	 { (char *)"Simulation_getDetectorIntensity", _wrap_Simulation_getDetectorIntensity, METH_VARARGS, (char *)"\n"
@@ -116098,9 +116103,9 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"GISASSimulation_numberOfSimulationElements", _wrap_GISASSimulation_numberOfSimulationElements, METH_VARARGS, (char *)"\n"
-		"GISASSimulation_numberOfSimulationElements(GISASSimulation self) -> int\n"
+		"GISASSimulation_numberOfSimulationElements(GISASSimulation self) -> size_t\n"
 		"\n"
-		"int GISASSimulation::numberOfSimulationElements() const final\n"
+		"size_t GISASSimulation::numberOfSimulationElements() const final\n"
 		"\n"
 		"Gets the number of elements this simulation needs to calculate. \n"
 		"\n"
@@ -117566,10 +117571,18 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"IParticle_registerAbundance", _wrap_IParticle_registerAbundance, METH_VARARGS, (char *)"\n"
 		"registerAbundance(bool make_registered=True)\n"
 		"IParticle_registerAbundance(IParticle self)\n"
+		"\n"
+		"void IParticle::registerAbundance(bool make_registered=true)\n"
+		"\n"
 		""},
 	 { (char *)"IParticle_registerPosition", _wrap_IParticle_registerPosition, METH_VARARGS, (char *)"\n"
 		"registerPosition(bool make_registered=True)\n"
 		"IParticle_registerPosition(IParticle self)\n"
+		"\n"
+		"void IParticle::registerPosition(bool make_registered=true)\n"
+		"\n"
+		"Registers the three components of its position. \n"
+		"\n"
 		""},
 	 { (char *)"IParticle_swigregister", IParticle_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_IResolutionFunction2D", _wrap_delete_IResolutionFunction2D, METH_VARARGS, (char *)"\n"
@@ -118211,7 +118224,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"InterferenceFunction1DLattice_getChildren", _wrap_InterferenceFunction1DLattice_getChildren, METH_VARARGS, (char *)"\n"
 		"InterferenceFunction1DLattice_getChildren(InterferenceFunction1DLattice self) -> swig_dummy_type_const_inode_vector\n"
 		"\n"
-		"std::vector< const INode * > INode::getChildren() const\n"
+		"std::vector< const INode * > InterferenceFunction1DLattice::getChildren() const override\n"
 		"\n"
 		"Returns a vector of children (const). \n"
 		"\n"
@@ -118307,7 +118320,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"InterferenceFunctionRadialParaCrystal_getChildren", _wrap_InterferenceFunctionRadialParaCrystal_getChildren, METH_VARARGS, (char *)"\n"
 		"InterferenceFunctionRadialParaCrystal_getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector\n"
 		"\n"
-		"std::vector< const INode * > INode::getChildren() const\n"
+		"std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override\n"
 		"\n"
 		"Returns a vector of children (const). \n"
 		"\n"
@@ -118881,7 +118894,7 @@ static PyMethodDef SwigMethods[] = {
 		" Lattice constant.\n"
 		"\n"
 		"xi: \n"
-		"TODO: seems unused; explain or remove \n"
+		" Lattice rotation angle. \n"
 		"\n"
 		""},
 	 { (char *)"Lattice1DParameters_m_length_set", _wrap_Lattice1DParameters_m_length_set, METH_VARARGS, (char *)"Lattice1DParameters_m_length_set(Lattice1DParameters self, double m_length)"},
@@ -118932,7 +118945,12 @@ static PyMethodDef SwigMethods[] = {
 		"Lattice2D::ReciprocalBases Lattice2D::reciprocalBases() const \n"
 		"\n"
 		""},
-	 { (char *)"Lattice2D_setRotationEnabled", _wrap_Lattice2D_setRotationEnabled, METH_VARARGS, (char *)"Lattice2D_setRotationEnabled(Lattice2D self, bool enabled)"},
+	 { (char *)"Lattice2D_setRotationEnabled", _wrap_Lattice2D_setRotationEnabled, METH_VARARGS, (char *)"\n"
+		"Lattice2D_setRotationEnabled(Lattice2D self, bool enabled)\n"
+		"\n"
+		"void Lattice2D::setRotationEnabled(bool enabled)\n"
+		"\n"
+		""},
 	 { (char *)"delete_Lattice2D", _wrap_delete_Lattice2D, METH_VARARGS, (char *)"delete_Lattice2D(Lattice2D self)"},
 	 { (char *)"Lattice2D_swigregister", Lattice2D_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_BasicLattice", _wrap_new_BasicLattice, METH_VARARGS, (char *)"\n"
@@ -119134,6 +119152,9 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"Layer_registerThickness", _wrap_Layer_registerThickness, METH_VARARGS, (char *)"\n"
 		"registerThickness(bool make_registered=True)\n"
 		"Layer_registerThickness(Layer self)\n"
+		"\n"
+		"void Layer::registerThickness(bool make_registered=true)\n"
+		"\n"
 		""},
 	 { (char *)"Layer_swigregister", Layer_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_LayerRoughness", _wrap_new_LayerRoughness, METH_VARARGS, (char *)"\n"
@@ -119669,9 +119690,9 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"OffSpecSimulation_numberOfSimulationElements", _wrap_OffSpecSimulation_numberOfSimulationElements, METH_VARARGS, (char *)"\n"
-		"OffSpecSimulation_numberOfSimulationElements(OffSpecSimulation self) -> int\n"
+		"OffSpecSimulation_numberOfSimulationElements(OffSpecSimulation self) -> size_t\n"
 		"\n"
-		"int OffSpecSimulation::numberOfSimulationElements() const final\n"
+		"size_t OffSpecSimulation::numberOfSimulationElements() const final\n"
 		"\n"
 		"Gets the number of elements this simulation needs to calculate. \n"
 		"\n"
@@ -120078,7 +120099,7 @@ static PyMethodDef SwigMethods[] = {
 		"getDistribution() -> IDistribution1D\n"
 		"ParameterDistribution_getDistribution(ParameterDistribution self) -> IDistribution1D\n"
 		"\n"
-		"const IDistribution1D * ParameterDistribution::getDistribution() const \n"
+		"IDistribution1D * ParameterDistribution::getDistribution()\n"
 		"\n"
 		""},
 	 { (char *)"ParameterDistribution_generateSamples", _wrap_ParameterDistribution_generateSamples, METH_VARARGS, (char *)"\n"
@@ -120235,7 +120256,14 @@ static PyMethodDef SwigMethods[] = {
 		"std::vector< std::string > ParameterPool::parameterNames() const \n"
 		"\n"
 		""},
-	 { (char *)"ParameterPool_removeParameter", _wrap_ParameterPool_removeParameter, METH_VARARGS, (char *)"ParameterPool_removeParameter(ParameterPool self, std::string const & name)"},
+	 { (char *)"ParameterPool_removeParameter", _wrap_ParameterPool_removeParameter, METH_VARARGS, (char *)"\n"
+		"ParameterPool_removeParameter(ParameterPool self, std::string const & name)\n"
+		"\n"
+		"void ParameterPool::removeParameter(const std::string &name)\n"
+		"\n"
+		"Removes parameter with given name from the pool. \n"
+		"\n"
+		""},
 	 { (char *)"ParameterPool_swigregister", ParameterPool_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_ParameterSample", _wrap_new_ParameterSample, METH_VARARGS, (char *)"\n"
 		"ParameterSample(double _value=0., double _weight=1.)\n"
diff --git a/auto/Wrap/libBornAgainFit_wrap.cpp b/auto/Wrap/libBornAgainFit_wrap.cpp
index a8a3c751a8094442c52e1b7abbe78704cd1f1807..46739cef97b8b1ac2c23eb7707d001c93fef1fb8 100644
--- a/auto/Wrap/libBornAgainFit_wrap.cpp
+++ b/auto/Wrap/libBornAgainFit_wrap.cpp
@@ -5626,7 +5626,7 @@ SWIG_AsVal_std_complex_Sl_double_Sg_  (PyObject *o, std::complex<double>* val)
 
 
 SWIGINTERNINLINE PyObject*
-SWIG_From_std_complex_Sl_double_Sg_  (/*@SWIG:/home/pospelov/software/local/share/swig/3.0.8/typemaps/swigmacros.swg,104,%ifcplusplus@*/
+SWIG_From_std_complex_Sl_double_Sg_  (/*@SWIG:/usr/share/swig3.0/typemaps/swigmacros.swg,104,%ifcplusplus@*/
 
 const std::complex<double>&
 
diff --git a/unused/MatrixSpecularInfoMapTest.h b/unused/MatrixSpecularInfoMapTest.h
index 6353f79822953b0a0308e45a52f4d6891df59257..61fb53e3f867bc8cc980fd6992ac2bff7fe36429 100644
--- a/unused/MatrixSpecularInfoMapTest.h
+++ b/unused/MatrixSpecularInfoMapTest.h
@@ -4,7 +4,7 @@
 #include "HomogeneousMaterial.h"
 #include "Layer.h"
 #include "MatrixRTCoefficients.h"
-#include "MatrixSpecularInfoMap.h"
+#include "MatrixFresnelMap.h"
 #include "MultiLayer.h"
 #include "MathConstants.h"
 #include "SimulationElement.h"