diff --git a/src/common/field.hh b/src/common/field.hh
index 3aaa29f..1643470 100644
--- a/src/common/field.hh
+++ b/src/common/field.hh
@@ -1,971 +1,1028 @@
 /**
  * @file   field.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  *
  * @date   07 Sep 2017
  *
  * @brief  header-only implementation of a field for field collections
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 
 #ifndef FIELD_H
 #define FIELD_H
 
 #include "common/T4_map_proxy.hh"
 
 #include <Eigen/Dense>
 
 #include <string>
 #include <sstream>
 #include <utility>
 #include <typeinfo>
 #include <vector>
 #include <algorithm>
 #include <cmath>
 #include <memory>
 #include <type_traits>
 
 namespace muSpectre {
 
   /* ---------------------------------------------------------------------- */
   /**
    * base class for field collection-related exceptions
    */
   class FieldCollectionError: public std::runtime_error {
   public:
     //! constructor
     explicit FieldCollectionError(const std::string& what)
       :std::runtime_error(what){}
     //! constructor
     explicit FieldCollectionError(const char * what)
       :std::runtime_error(what){}
   };
 
   /// base class for field-related exceptions
   class FieldError: public FieldCollectionError {
     using Parent = FieldCollectionError;
   public:
     //! constructor
     explicit FieldError(const std::string& what)
       :Parent(what){}
     //! constructor
     explicit FieldError(const char * what)
       :Parent(what){}
   };
 
   /**
    * Thrown when a associating a field map to and incompatible field
    * is attempted
    */
   class FieldInterpretationError: public FieldError
   {
   public:
     //! constructor
     explicit FieldInterpretationError(const std::string & what)
       :FieldError(what){}
     //! constructor
     explicit FieldInterpretationError(const char * what)
       :FieldError(what){}
   };
 
 
   namespace internal {
 
     /* ---------------------------------------------------------------------- */
     /**
-     * Virtual base class for all fields. A field represents the per-voxel
-     * storage for a scalar, vector or tensor quantity. It is used for type and
-     * size checking at runtime and for storage of polymorphic pointers to
-     * fully typed and sized fields. FieldBase (and its children) are
-     * templated with a specific FieldCollection. A FieldCollection stores
-     * multiple fields that all apply to the same set of voxels. Allocating
-     * and managing the data for all voxels is handled by the FieldCollection.
-     * Note that FieldBase does not know anything about the data type of the
-     * field.
+     * Virtual base class for all fields. A field represents meta-information
+     * for the per-pixel storage for a scalar, vector or tensor quantity and
+     * is therefore the abstract class defining the field. It is used for type
+     * and size checking at runtime and for storage of polymorphic pointers to
+     * fully typed and sized fields. `FieldBase` (and its children) are
+     * templated with a specific `FieldCollection`. A `FieldCollection` stores
+     * multiple fields that all apply to the same set of pixels. Allocating
+     * and managing the data for all pixels is handled by the `FieldCollection`.
+     * Note that `FieldBase` does not know anything about about mathematical
+     * operations on the data or how to iterate over all pixels. Mapping the
+     * raw data onto Eigen classes and iterating over those is handled by
+     * the `FieldMap`.
+     * `FieldBase` has the specialisation `TypedFieldBase`.
      */
     template <class FieldCollection>
     class FieldBase
     {
 
     protected:
       //! constructor
       //! unique name (whithin Collection)
       //! number of components
       //! collection to which this field belongs (eg, material, system)
       FieldBase(std::string unique_name,
                 size_t nb_components,
                 FieldCollection & collection);
 
     public:
       using collection_t = FieldCollection; //!< for type checks
 
       //! Copy constructor
       FieldBase(const FieldBase &other) = delete;
 
       //! Move constructor
       FieldBase(FieldBase &&other) = delete;
 
       //! Destructor
       virtual ~FieldBase() = default;
 
       //! Copy assignment operator
       FieldBase& operator=(const FieldBase &other) = delete;
 
       //! Move assignment operator
       FieldBase& operator=(FieldBase &&other) = delete;
 
       /* ---------------------------------------------------------------------- */
       //!Identifying accessors
       //! return field name
       inline const std::string & get_name() const;
       //! return field type
       //inline const Field_t & get_type() const;
       //! return my collection (for iterating)
       inline const FieldCollection & get_collection() const;
       //! return my collection (for iterating)
       inline const size_t & get_nb_components() const;
       //! return type_id of stored type
       virtual const std::type_info & get_stored_typeid() const = 0;
 
       //! number of pixels in the field
       virtual size_t size() const = 0;
 
       //! initialise field to zero (do more complicated initialisations through
       //! fully typed maps)
       virtual void set_zero() = 0;
 
       //! give access to collections
       friend FieldCollection;
       //! give access to collection's base class
       friend typename FieldCollection::Parent;
 
     protected:
       /* ---------------------------------------------------------------------- */
       //! allocate memory etc
       virtual void resize(size_t size) = 0;
       const std::string name; //!< the field's unique name
       const size_t nb_components; //!< number of components per entry
       //! reference to the collection this field belongs to
       const FieldCollection & collection;
     private:
     };
 
 
     /**
      * Dummy intermediate class to provide a run-time polymorphic
-     * typed field. Mainly for binding python. TypedFieldBase specifies methods
+     * typed field. Mainly for binding Python. TypedFieldBase specifies methods
      * that return typed Eigen maps and vectors in addition to pointers to the
      * raw data.
+     * `TypedFieldBase` has the specialisation `TypedSizedFieldBase`.
      */
     template <class FieldCollection, typename T>
     class TypedFieldBase: public FieldBase<FieldCollection>
     {
     public:
       using Parent = FieldBase<FieldCollection>; //!< base class
       //! for type checks when mapping this field
       using collection_t = typename Parent::collection_t;
       using Scalar = T; //!< for type checks
       using Base = Parent; //!< for uniformity of interface
       //! Plain Eigen type to map
       using EigenRep = Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic>;
       //! map returned when iterating over field
       using EigenMap = Eigen::Map<EigenRep>;
       //! Plain eigen vector to map
       using EigenVec = Eigen::Map<Eigen::VectorXd>;
       //! vector map returned when iterating over field
       using EigenVecConst = Eigen::Map<const Eigen::VectorXd>;
       //! Default constructor
       TypedFieldBase() = delete;
 
       //! constructor
       TypedFieldBase(std::string unique_name,
                      size_t nb_components,
                      FieldCollection& collection);
 
       //! Copy constructor
       TypedFieldBase(const TypedFieldBase &other) = delete;
 
       //! Move constructor
       TypedFieldBase(TypedFieldBase &&other) = delete;
 
       //! Destructor
       virtual ~TypedFieldBase() = default;
 
       //! Copy assignment operator
       TypedFieldBase& operator=(const TypedFieldBase &other) = delete;
 
       //! Move assignment operator
       TypedFieldBase& operator=(TypedFieldBase &&other) = delete;
 
       //! return type_id of stored type
       virtual const std::type_info & get_stored_typeid() const override final;
 
       virtual size_t size() const override = 0;
 
       //! initialise field to zero (do more complicated initialisations through
       //! fully typed maps)
       virtual void set_zero() override = 0;
 
       //! raw pointer to content (e.g., for Eigen maps)
       virtual T* data() = 0;
       //! raw pointer to content (e.g., for Eigen maps)
       virtual const T* data() const = 0;
 
       //! return a map representing the entire field as a single `Eigen::Array`
       EigenMap eigen();
       //! return a map representing the entire field as a single Eigen vector
       EigenVec eigenvec();
       //! return a map representing the entire field as a single Eigen vector
       EigenVecConst eigenvec() const;
 
     protected:
     private:
     };
 
     /* ---------------------------------------------------------------------- */
     //! declaraton for friending
     template <class FieldCollection, typename T, Dim_t NbComponents, bool isConst>
     class FieldMap;
 
     /* ---------------------------------------------------------------------- */
     /**
-     * implements Fields that contain a statically known number of
-     * scalars of a statically known type per pixel in a
-     * `muSpectre::FieldCollection`
+     * A `TypedSizeFieldBase` is the base class for fields that contain
+     * statically known number of scalars of a statically known type per pixel
+     * in a `muSpectre::FieldCollection`. The actual data for all pixels is
+     * stored in `TypedSizeFieldBase::values`.
+     * `TypedSizedFieldBase` has the specialisations `MatrixField` and
+     * `TensorField`.
      */
     template <class FieldCollection, typename T, Dim_t NbComponents,
               bool ArrayStore=false>
     class TypedSizedFieldBase: public TypedFieldBase<FieldCollection, T>
     {
       friend class FieldMap<FieldCollection, T, NbComponents, true>;
       friend class FieldMap<FieldCollection, T, NbComponents, false>;
     public:
       //! for compatibility checks
       constexpr static auto nb_components{NbComponents};
       using Parent = TypedFieldBase<FieldCollection, T>; //!< base class
       using Scalar = T; //!< for type checking
       using Base = typename Parent::Base; //!< root base class
 
       //! type stored if ArrayStore is true
       using StoredType = Eigen::Array<T, NbComponents, 1>;
       //! storage container
       using StorageType = std::conditional_t
         <ArrayStore,
          std::vector<StoredType,
                      Eigen::aligned_allocator<StoredType>>,
          std::vector<T,Eigen::aligned_allocator<T>>>;
 
       //! Plain type that is being mapped (Eigen lingo)
       using EigenRep = Eigen::Array<T, NbComponents, Eigen::Dynamic>;
       //! maps returned when iterating over field
       using EigenMap = std::conditional_t<
         ArrayStore,
         Eigen::Map<EigenRep, Eigen::Aligned,
                    Eigen::OuterStride<sizeof(StoredType)/sizeof(T)>>,
         Eigen::Map<EigenRep>>;
 
       //! maps returned when iterating over field
       using ConstEigenMap = std::conditional_t<
         ArrayStore,
         Eigen::Map<const EigenRep, Eigen::Aligned,
                    Eigen::OuterStride<sizeof(StoredType)/sizeof(T)>>,
         Eigen::Map<const EigenRep>>;
 
       //! constructor
       TypedSizedFieldBase(std::string unique_name,
                      FieldCollection& collection);
       virtual ~TypedSizedFieldBase() = default;
 
       //! initialise field to zero (do more complicated initialisations through
       //! fully typed maps)
       inline void set_zero() override final;
 
       //! add a new value at the end of the field
       template <bool isArrayStore = ArrayStore>
       inline void push_back(const
                             std::enable_if_t<isArrayStore, StoredType> &
                             value);
 
       //! add a new value at the end of the field
       template <bool componentStore = !ArrayStore>
       inline std::enable_if_t<componentStore> push_back(const StoredType & value);
 
       //! Number of stored arrays (i.e. total number of stored
       //! scalars/NbComponents)
       size_t size() const override final;
 
       /**
        * returns an upcasted reference to a field, or throws an
        * exception if the field is incompatible
        */
       static TypedSizedFieldBase & check_ref(Base & other);
       /**
        * returns an upcasted reference to a field, or throws an
        * exception if the field is incompatible
        */
       static const TypedSizedFieldBase & check_ref(const Base & other);
 
       //! return raw pointer to stored data (necessary for Eigen maps)
       inline T* data() override final {return this->get_ptr_to_entry(0);}
       //! return raw pointer to stored data (necessary for Eigen maps)
       inline const T* data() const override final {return this->get_ptr_to_entry(0);}
 
       //! return a map representing the entire field as a single `Eigen::Array`
       inline EigenMap eigen();
       //! return a map representing the entire field as a single `Eigen::Array`
       inline ConstEigenMap eigen() const;
       /**
        * return a map representing the entire field as a single
        * dynamically sized `Eigen::Array` (for python bindings)
        */
       inline typename Parent::EigenMap dyn_eigen() {return Parent::eigen();}
 
       //! inner product between compatible fields
       template<typename otherT>
       inline Real inner_product(const TypedSizedFieldBase<FieldCollection, otherT, NbComponents,
                                 ArrayStore> & other) const;
     protected:
 
       //! returns a raw pointer to the entry, for `Eigen::Map`
       template <bool isArray=ArrayStore>
       inline std::enable_if_t<isArray, T*> get_ptr_to_entry(const size_t&& index);
 
       //! returns a raw pointer to the entry, for `Eigen::Map`
       template <bool isArray=ArrayStore>
       inline std::enable_if_t<isArray, const T*>
       get_ptr_to_entry(const size_t&& index) const;
 
       //! returns a raw pointer to the entry, for `Eigen::Map`
       template <bool noArray = !ArrayStore>
       inline T* get_ptr_to_entry(std::enable_if_t<noArray, const size_t&&> index);
 
       //! returns a raw pointer to the entry, for `Eigen::Map`
       template <bool noArray = !ArrayStore>
       inline const T*
       get_ptr_to_entry(std::enable_if_t<noArray, const size_t&&> index) const;
 
       //! set the storage size of this field
       inline virtual void resize(size_t size) override final;
 
       //! The actual storage container
       StorageType values{};
     };
 
   }  // internal
 
 
   /* ---------------------------------------------------------------------- */
   /**
-   * subclass of `muSpectre::internal::TypedSizedFieldBase` to
-   * represent tensorial fields defined by a stored scalar type,
-   * spatial dimension, and tensorial order
+   * The `TensorField` is a subclass of `muSpectre::internal::TypedSizedFieldBase`
+   * that represents tensorial fields, i.e. arbitrary-dimensional arrays with
+   * identical number of rows/columns (that typically correspond to the spatial
+   * cartesian dimensions). It is defined by the stored scalar type @a T, the
+   * tensorial order @a order (often also called degree or rank) and the
+   * number of spatial dimensions @a dim.
    */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   class TensorField: public internal::TypedSizedFieldBase<FieldCollection,
                                                      T,
                                                      ipow(dim,order)>
   {
   public:
     //! base class
     using Parent = internal::TypedSizedFieldBase<FieldCollection,
                                             T,
                                             ipow(dim,order)>;
     using Base = typename Parent::Base; //!< root base class
     //! polymorphic base class
     using Field_p = typename FieldCollection::Field_p;
     using Scalar = typename Parent::Scalar; //!< for type checking
     //! Copy constructor
     TensorField(const TensorField &other) = delete;
 
     //! Move constructor
     TensorField(TensorField &&other) = delete;
 
     //! Destructor
     virtual ~TensorField() = default;
 
     //! Copy assignment operator
     TensorField& operator=(const TensorField &other) = delete;
 
     //! Move assignment operator
     TensorField& operator=(TensorField &&other) = delete;
 
     //! return the order of the stored tensor
     inline Dim_t get_order() const;
     //! return the dimension of the stored tensor
     inline Dim_t get_dim() const;
 
 
     //! factory function
     template<class FieldType, class CollectionType, typename... Args>
     friend FieldType& make_field(std::string unique_name,
                                  CollectionType & collection,
                                  Args&&... args);
 
     //! return a reference or throw an exception if `other` is incompatible
     static TensorField & check_ref(Base & other) {
       return static_cast<TensorField &>(Parent::check_ref(other));}
     //! return a reference or throw an exception if `other` is incompatible
     static const TensorField & check_ref(const Base & other) {
       return static_cast<const TensorField &>(Parent::check_ref(other));}
 
     /**
-     * Pure convenience functions to get a MatrixFieldMap of
-     * appropriate dimensions mapped to this field. You can also
-     * create other types of maps, as long as they have the right
-     * fundamental type (T) and the correct size (nbComponents).
+     * Convenience functions to return a map onto this field. A map allows
+     * iteration over all pixels. The map's iterator returns an object that
+     * represents the underlying mathematical structure of the field and
+     * implements common linear algebra operations on it.
+     * Specifically, this function returns
+     * - A `MatrixFieldMap` with @a dim rows and one column if the tensorial
+     * order @a order is unity.
+     * - A `MatrixFieldMap` with @a dim rows and @a dim columns if the tensorial
+     * order @a order is 2.
+     * - A `T4MatrixFieldMap` if the tensorial order is 4.
      */
     decltype(auto) get_map();
     /**
-     * Pure convenience functions to get a MatrixFieldMap of
-     * appropriate dimensions mapped to this field. You can also
-     * create other types of maps, as long as they have the right
-     * fundamental type (T) and the correct size (nbComponents).
+     * Convenience functions to return a map onto this field. A map allows
+     * iteration over all pixels. The map's iterator returns an object that
+     * represents the underlying mathematical structure of the field and
+     * implements common linear algebra operations on it.
+     * Specifically, this function returns
+     * - A `MatrixFieldMap` with @a dim rows and one column if the tensorial
+     * order @a order is unity.
+     * - A `MatrixFieldMap` with @a dim rows and @a dim columns if the tensorial
+     * order @a order is 2.
+     * - A `T4MatrixFieldMap` if the tensorial order is 4.
      */
     decltype(auto) get_const_map();
     /**
-     * Pure convenience functions to get a MatrixFieldMap of
-     * appropriate dimensions mapped to this field. You can also
-     * create other types of maps, as long as they have the right
-     * fundamental type (T) and the correct size (nbComponents).
+     * Convenience functions to return a map onto this field. A map allows
+     * iteration over all pixels. The map's iterator returns an object that
+     * represents the underlying mathematical structure of the field and
+     * implements common linear algebra operations on it.
+     * Specifically, this function returns
+     * - A `MatrixFieldMap` with @a dim rows and one column if the tensorial
+     * order @a order is unity.
+     * - A `MatrixFieldMap` with @a dim rows and @a dim columns if the tensorial
+     * order @a order is 2.
+     * - A `T4MatrixFieldMap` if the tensorial order is 4.
      */
     decltype(auto) get_map() const;
 
   protected:
     //! constructor protected!
     TensorField(std::string unique_name, FieldCollection & collection);
 
   private:
   };
 
   /* ---------------------------------------------------------------------- */
   /**
-   * subclass of `muSpectre::internal::TypedSizedFieldBase` to
-   * represent matrix fields defined by a stored scalar type and the
-   * number of rows and columns of the field
+   * The `MatrixField` is subclass of `muSpectre::internal::TypedSizedFieldBase`
+   * that represents matrix fields, i.e. a two dimensional arrays, defined by
+   * the stored scalar type @a T and the number of rows @a NbRow and columns
+   * @a NbCol of the matrix.
    */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol=NbRow>
   class MatrixField: public internal::TypedSizedFieldBase<FieldCollection,
                                                      T,
                                                      NbRow*NbCol>
   {
   public:
     //! base class
     using Parent = internal::TypedSizedFieldBase<FieldCollection,
                                             T,
                                             NbRow*NbCol>;
     using Base = typename Parent::Base; //!< root base class
     //! polymorphic base field ptr to store
     using Field_p = std::unique_ptr<internal::FieldBase<FieldCollection>>;
     //! Copy constructor
     MatrixField(const MatrixField &other) = delete;
 
     //! Move constructor
     MatrixField(MatrixField &&other) = delete;
 
     //! Destructor
     virtual ~MatrixField() = default;
 
     //! Copy assignment operator
     MatrixField& operator=(const MatrixField &other) = delete;
 
     //! Move assignment operator
     MatrixField& operator=(MatrixField &&other) = delete;
 
     //! returns the number of rows
     inline Dim_t get_nb_row() const;
     //! returns the number of columns
     inline Dim_t get_nb_col() const;
 
 
     //! factory function
     template<class FieldType, class CollectionType, typename... Args>
     friend FieldType&  make_field(std::string unique_name,
                                   CollectionType & collection,
                                   Args&&... args);
 
     //! returns a `MatrixField` reference if `other` is a compatible field
     static MatrixField & check_ref(Base & other) {
       return static_cast<MatrixField &>(Parent::check_ref(other));}
     //! returns a `MatrixField` reference if `other` is a compatible field
     static const MatrixField & check_ref(const Base & other) {
       return static_cast<const MatrixField &>(Parent::check_ref(other));}
 
-    //! returns the default map type
+    /**
+      * Convenience functions to return a map onto this field. A map allows
+      * iteration over all pixels. The map's iterator returns an object that
+      * represents the underlying mathematical structure of the field and
+      * implements common linear algebra operations on it.
+      * Specifically, this function returns
+      * - A `ScalarFieldMap` if @a NbRows and @a NbCols are unity.
+      * - A `MatrixFieldMap` with @a NbRows rows and @a NbCols columns
+      * otherwise.
+      */
     decltype(auto) get_map();
-    //! returns the default map type
+    /**
+     * Convenience functions to return a map onto this field. A map allows
+     * iteration over all pixels. The map's iterator returns an object that
+     * represents the underlying mathematical structure of the field and
+     * implements common linear algebra operations on it.
+     * Specifically, this function returns
+     * - A `ScalarFieldMap` if @a NbRows and @a NbCols are unity.
+     * - A `MatrixFieldMap` with @a NbRows rows and @a NbCols columns
+     * otherwise.
+     */
     decltype(auto) get_const_map();
-    //! returns the default map type
+    /**
+     * Convenience functions to return a map onto this field. A map allows
+     * iteration over all pixels. The map's iterator returns an object that
+     * represents the underlying mathematical structure of the field and
+     * implements common linear algebra operations on it.
+     * Specifically, this function returns
+     * - A `ScalarFieldMap` if @a NbRows and @a NbCols are unity.
+     * - A `MatrixFieldMap` with @a NbRows rows and @a NbCols columns
+     * otherwise.
+     */
     decltype(auto) get_map() const;
 
 
 protected:
     //! constructor protected!
     MatrixField(std::string unique_name, FieldCollection & collection);
 
   private:
   };
 
   /* ---------------------------------------------------------------------- */
   //! convenience alias (
   template <class FieldCollection, typename T>
   using ScalarField = MatrixField<FieldCollection, T, 1, 1>;
   /* ---------------------------------------------------------------------- */
   // Implementations
   namespace internal {
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection>
     FieldBase<FieldCollection>::FieldBase(std::string unique_name,
                                           size_t nb_components_,
                                           FieldCollection & collection_)
       :name(unique_name), nb_components(nb_components_),
        collection(collection_) {}
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection>
     inline const std::string & FieldBase<FieldCollection>::get_name() const {
       return this->name;
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection>
     inline const FieldCollection & FieldBase<FieldCollection>::
     get_collection() const {
       return this->collection;
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection>
     inline const size_t & FieldBase<FieldCollection>::
     get_nb_components() const {
       return this->nb_components;
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T>
     TypedFieldBase<FieldCollection, T>::
     TypedFieldBase(std::string unique_name, size_t nb_components,
                    FieldCollection & collection)
       :Parent(unique_name, nb_components, collection)
     {}
 
     /* ---------------------------------------------------------------------- */
     //! return type_id of stored type
     template <class FieldCollection, typename T>
     const std::type_info & TypedFieldBase<FieldCollection, T>::
     get_stored_typeid() const {
       return typeid(T);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T>
     typename TypedFieldBase<FieldCollection, T>::EigenMap
     TypedFieldBase<FieldCollection, T>::
     eigen() {
       return EigenMap(this->data(), this->get_nb_components(), this->size());
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T>
     typename TypedFieldBase<FieldCollection, T>::EigenVec
     TypedFieldBase<FieldCollection, T>::
     eigenvec() {
       return EigenVec(this->data(), this->get_nb_components() * this->size());
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T>
     typename TypedFieldBase<FieldCollection, T>::EigenVecConst
     TypedFieldBase<FieldCollection, T>::
     eigenvec() const{
       return EigenVecConst(this->data(), this->get_nb_components() * this->size());
     }
 
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     TypedSizedFieldBase(std::string unique_name, FieldCollection & collection)
       :Parent(unique_name, NbComponents, collection){
       static_assert
         ((std::is_arithmetic<T>::value ||
           std::is_same<T, Complex>::value),
          "Use TypedSizedFieldBase for integer, real or complex scalars for T");
       static_assert(NbComponents > 0,
                     "Only fields with more than 0 components");
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     void
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     set_zero() {
       std::fill(this->values.begin(), this->values.end(), T{});
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     size_t TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     size() const {
       if (ArrayStore) {
         return this->values.size();
       } else  {
         return this->values.size()/NbComponents;
       }
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore> &
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     check_ref(Base & other) {
       if (typeid(T).hash_code() != other.get_stored_typeid().hash_code()) {
         std::string err ="Cannot create a Reference of requested type " +(
            "for field '" + other.get_name() + "' of type '" +
            other.get_stored_typeid().name() + "'");
         throw std::runtime_error
           (err);
       }
       //check size compatibility
       if (NbComponents != other.get_nb_components()) {
         throw std::runtime_error
           ("Cannot create a Reference to a field with " +
            std::to_string(NbComponents) + " components " +
            "for field '" + other.get_name() + "' with " +
            std::to_string(other.get_nb_components()) + " components");
       }
       return static_cast<TypedSizedFieldBase&>(other);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents,
               bool ArrayStore>
     const TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore> &
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     check_ref(const Base & other) {
       if (typeid(T).hash_code() != other.get_stored_typeid().hash_code()) {
         std::stringstream err_str{};
         err_str << "Cannot create a Reference of requested type "
                 << "for field '"  << other.get_name() << "' of type '"
                 << other.get_stored_typeid().name() << "'";
         throw std::runtime_error
           (err_str.str());
       }
       //check size compatibility
       if (NbComponents != other.get_nb_components()) {
         throw std::runtime_error
           ("Cannot create a Reference to a field with " +
            std::to_string(NbComponents) + " components " +
            "for field '" + other.get_name() + "' with " +
            std::to_string(other.get_nb_components()) + " components");
       }
       return static_cast<const TypedSizedFieldBase&>(other);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents,
               bool ArrayStore>
     typename TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::EigenMap
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     eigen() {
       return EigenMap(this->data(), NbComponents, this->size());
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents,
               bool ArrayStore>
     typename TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::ConstEigenMap
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     eigen() const {
       return ConstEigenMap(this->data(), NbComponents, this->size());
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents,
               bool ArrayStore>
     template<typename otherT>
     Real
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     inner_product(const TypedSizedFieldBase<FieldCollection, otherT, NbComponents,
                   ArrayStore> & other) const {
       return (this->eigen() * other.eigen()).sum();
     }
 
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool isArray>
     std::enable_if_t<isArray, T*>
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     get_ptr_to_entry(const size_t&& index) {
       static_assert (isArray == ArrayStore, "SFINAE");
       return &this->values[std::move(index)](0, 0);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool noArray>
     T* TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     get_ptr_to_entry(std::enable_if_t<noArray, const size_t&&> index) {
       static_assert (noArray != ArrayStore, "SFINAE");
       return &this->values[NbComponents*std::move(index)];
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool isArray>
     std::enable_if_t<isArray, const T*>
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     get_ptr_to_entry(const size_t&& index) const {
       static_assert (isArray == ArrayStore, "SFINAE");
       return &this->values[std::move(index)](0, 0);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool noArray>
     const T* TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     get_ptr_to_entry(std::enable_if_t<noArray, const size_t&&> index) const {
       static_assert (noArray != ArrayStore, "SFINAE");
       return &this->values[NbComponents*std::move(index)];
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     void TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     resize(size_t size) {
       if (ArrayStore) {
         this->values.resize(size);
       } else {
         this->values.resize(size*NbComponents);
       }
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool isArrayStore>
     void
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     push_back(const std::enable_if_t<isArrayStore,StoredType> & value) {
       static_assert(isArrayStore == ArrayStore, "SFINAE");
       this->values.push_back(value);
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ArrayStore>
     template <bool componentStore>
     std::enable_if_t<componentStore>
     TypedSizedFieldBase<FieldCollection, T, NbComponents, ArrayStore>::
     push_back(const StoredType & value) {
       static_assert(componentStore != ArrayStore, "SFINAE");
       for (Dim_t i = 0; i < NbComponents; ++i) {
         this->values.push_back(value(i));
       }
     }
 
   }  // internal
 
   /* ---------------------------------------------------------------------- */
   //! Factory function, guarantees that only fields get created that are
   //! properly registered and linked to a collection.
   template<class FieldType, class FieldCollection, typename... Args>
   FieldType &
   make_field(std::string unique_name,
              FieldCollection & collection,
              Args&&... args) {
     auto ptr = std::unique_ptr<FieldType>{
       new FieldType(unique_name, collection, args...)};
     auto& retref = *ptr;
     collection.register_field(std::move(ptr));
     return retref;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   TensorField<FieldCollection, T, order, dim>::
   TensorField(std::string unique_name, FieldCollection & collection)
     :Parent(unique_name, collection) {}
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   Dim_t TensorField<FieldCollection, T, order, dim>::
   get_order() const {
     return order;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   Dim_t TensorField<FieldCollection, T, order, dim>::
   get_dim() const {
     return dim;
   }
 
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   MatrixField<FieldCollection, T, NbRow, NbCol>::
   MatrixField(std::string unique_name, FieldCollection & collection)
     :Parent(unique_name, collection) {}
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   Dim_t MatrixField<FieldCollection, T, NbRow, NbCol>::
   get_nb_col() const {
     return NbCol;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   Dim_t MatrixField<FieldCollection, T, NbRow, NbCol>::
   get_nb_row() const {
     return NbRow;
   }
 
 }  // muSpectre
 
 #include "common/field_map.hh"
 
 namespace muSpectre {
 
   namespace internal {
 
     /* ---------------------------------------------------------------------- */
     /**
      * defines the default mapped type obtained when calling
      * `muSpectre::TensorField::get_map()`
      */
     template <class FieldCollection, typename T, size_t order, Dim_t dim,
               bool ConstMap>
     struct tensor_map_type {
     };
 
     /// specialisation for vectors
     template <class FieldCollection, typename T, Dim_t dim, bool ConstMap>
     struct tensor_map_type<FieldCollection, T, firstOrder, dim, ConstMap> {
       //! use this type
       using type = MatrixFieldMap<FieldCollection, T, dim, 1, ConstMap>;
     };
 
     /// specialisation to second-order tensors (matrices)
     template <class FieldCollection, typename T, Dim_t dim, bool ConstMap>
     struct tensor_map_type<FieldCollection, T, secondOrder, dim, ConstMap> {
       //! use this type
       using type = MatrixFieldMap<FieldCollection, T, dim, dim, ConstMap>;
     };
 
     /// specialisation to fourth-order tensors
     template <class FieldCollection, typename T, Dim_t dim, bool ConstMap>
     struct tensor_map_type<FieldCollection, T, fourthOrder, dim, ConstMap> {
       //! use this type
       using type = T4MatrixFieldMap<FieldCollection, T, dim, ConstMap>;
     };
 
     /* ---------------------------------------------------------------------- */
     /**
      * defines the default mapped type obtained when calling
      * `muSpectre::MatrixField::get_map()`
      */
     template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol,
               bool ConstMap>
     struct matrix_map_type {
       //! mapping type
       using type =
         MatrixFieldMap<FieldCollection, T, NbRow, NbCol, ConstMap>;
     };
 
-    //! spectialisation to scalar fields
+    //! specialisation to scalar fields
     template <class FieldCollection, typename T, bool ConstMap>
     struct matrix_map_type<FieldCollection, T, oneD, oneD, ConstMap> {
       //! mapping type
       using type = ScalarFieldMap<FieldCollection, T, ConstMap>;
     };
 
   }  // internal
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   decltype(auto) TensorField<FieldCollection, T, order, dim>::
   get_map() {
     constexpr bool map_constness{false};
     using RawMap_t =
       typename internal::tensor_map_type<FieldCollection, T, order, dim,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   decltype(auto) TensorField<FieldCollection, T, order, dim>::
   get_const_map() {
     constexpr bool map_constness{true};
     using RawMap_t =
       typename internal::tensor_map_type<FieldCollection, T, order, dim,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim>
   decltype(auto) TensorField<FieldCollection, T, order, dim>::
   get_map() const {
     constexpr bool map_constness{true};
     using RawMap_t =
       typename internal::tensor_map_type<FieldCollection, T, order, dim,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   decltype(auto) MatrixField<FieldCollection, T, NbRow, NbCol>::
   get_map() {
     constexpr bool map_constness{false};
     using RawMap_t =
       typename internal::matrix_map_type<FieldCollection, T, NbRow, NbCol,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   decltype(auto) MatrixField<FieldCollection, T, NbRow, NbCol>::
   get_const_map() {
     constexpr bool map_constness{true};
     using RawMap_t =
       typename internal::matrix_map_type<FieldCollection, T, NbRow, NbCol,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t NbRow, Dim_t NbCol>
   decltype(auto) MatrixField<FieldCollection, T, NbRow, NbCol>::
   get_map() const {
     constexpr bool map_constness{true};
     using RawMap_t =
       typename internal::matrix_map_type<FieldCollection, T, NbRow, NbCol,
                                          map_constness>::type;
     return RawMap_t(*this);
   }
 
 
 }  // muSpectre
 
 #endif /* FIELD_H */
diff --git a/src/common/field_collection_base.hh b/src/common/field_collection_base.hh
index 7c59c61..d7d13c1 100644
--- a/src/common/field_collection_base.hh
+++ b/src/common/field_collection_base.hh
@@ -1,173 +1,184 @@
 /**
  * @file   field_collection_base.hh
  *
  * @author Till Junge <till.junge@altermail.ch>
  *
  * @date   05 Nov 2017
  *
  * @brief  Base class for field collections
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef FIELD_COLLECTION_BASE_H
 #define FIELD_COLLECTION_BASE_H
 
 #include "common/common.hh"
 #include "common/field.hh"
 
 #include <map>
 #include <vector>
 
 namespace muSpectre {
   /* ---------------------------------------------------------------------- */
-  //! DimS spatial dimension (dimension of problem)
-  //! DimM material_dimension (dimension of constitutive law)
+  /** `FieldCollectionBase` is the base class for collections of fields. All
+    * fields in a field collection have the same number of pixels. The field
+    * collection is templated with @a DimS is the spatial dimension (i.e.
+    * whether the simulation domain is one, two or three-dimensional) and
+    * @a DimM is the material dimension (i.e., the dimension of constitutive
+    * law; even for e.g. two-dimensional problems the constitutive law could
+    * live in three-dimensional space for e.g. plane strain or stress problems).
+    * All fields within a field collection have a unique string identifier.
+    * A `FieldCollectionBase` is therefore comparable to a dictionary of fields
+    * that live on the same grid.
+    * `FieldCollectionBase` has the specialisations `GlobalFieldCollection` and
+    * `LocalFieldCollection`.
+    */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   class FieldCollectionBase
   {
   public:
     //! polymorphic base type to store
     using Field = internal::FieldBase<FieldCollectionDerived>;
     using Field_p = std::unique_ptr<Field>; //!< stored type
     using Ccoord = Ccoord_t<DimS>; //!< cell coordinates type
 
     //! Default constructor
     FieldCollectionBase();
 
     //! Copy constructor
     FieldCollectionBase(const FieldCollectionBase &other) = delete;
 
     //! Move constructor
     FieldCollectionBase(FieldCollectionBase &&other) = delete;
 
     //! Destructor
     virtual ~FieldCollectionBase() = default;
 
     //! Copy assignment operator
     FieldCollectionBase& operator=(const FieldCollectionBase &other) = delete;
 
     //! Move assignment operator
     FieldCollectionBase& operator=(FieldCollectionBase &&other) = delete;
 
     //! Register a new field (fields need to be in heap, so I want to keep them
     //! as shared pointers
     void register_field(Field_p&& field);
 
     //! for return values of iterators
     constexpr inline static Dim_t spatial_dim();
 
     //! for return values of iterators
     inline Dim_t get_spatial_dim() const;
 
     //! retrieve field by unique_name
     inline Field& operator[](std::string unique_name);
 
     //! retrieve field by unique_name with bounds checking
     inline Field& at(std::string unique_name);
 
     //! returns size of collection, this refers to the number of pixels handled
     //! by the collection, not the number of fields
     inline size_t size() const {return this->size_;}
 
     //! check whether a field is present
     bool check_field_exists(std::string unique_name);
 
 
   protected:
     std::map<const std::string, Field_p> fields{}; //!< contains the field ptrs
     bool is_initialised{false}; //!< to handle double initialisation correctly
     const Uint id; //!< unique identifier
     static Uint counter; //!< used to assign unique identifiers
     size_t size_{0}; //!< holds the number of pixels after initialisation
   private:
   };
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   Uint FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::counter{0};
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::FieldCollectionBase()
     :id(counter++){}
 
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   void FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::register_field(Field_p &&field) {
     auto&& search_it = this->fields.find(field->get_name());
     auto&& does_exist = search_it != this->fields.end();
     if (does_exist) {
       std::stringstream err_str;
       err_str << "a field named " << field->get_name()
               << "is already registered in this field collection. "
               << "Currently registered fields: ";
       for (const auto& name_field_pair: this->fields) {
         err_str << ", " << name_field_pair.first;
       }
       throw FieldCollectionError(err_str.str());
     }
     if (this->is_initialised) {
       field->resize(this->size());
     }
     this->fields[field->get_name()] = std::move(field);
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   constexpr Dim_t FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::
   spatial_dim() {
     return DimS;
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   Dim_t FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::
   get_spatial_dim() const {
     return DimS;
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   typename FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::Field&
   FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::
   operator[](std::string unique_name) {
     return *(this->fields[unique_name]);
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   typename FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::Field&
   FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::
   at(std::string unique_name) {
     return *(this->fields.at(unique_name));
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM, class FieldCollectionDerived>
   bool
   FieldCollectionBase<DimS, DimM, FieldCollectionDerived>::
   check_field_exists(std::string unique_name) {
     return this->fields.find(unique_name) != this->fields.end();
   }
 
 
 }  // muSpectre
 
 #endif /* FIELD_COLLECTION_BASE_H */
diff --git a/src/common/field_collection_global.hh b/src/common/field_collection_global.hh
index 2af5958..98eb516 100644
--- a/src/common/field_collection_global.hh
+++ b/src/common/field_collection_global.hh
@@ -1,191 +1,193 @@
 /**
  * @file   field_collection_global.hh
  *
  * @author Till Junge <till.junge@altermail.ch>
  *
  * @date   05 Nov 2017
  *
  * @brief  FieldCollection base-class for global fields
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 
 #ifndef FIELD_COLLECTION_GLOBAL_H
 #define FIELD_COLLECTION_GLOBAL_H
 
 #include "common/field_collection_base.hh"
 #include "common/ccoord_operations.hh"
 
 
 namespace muSpectre {
 
   /* ---------------------------------------------------------------------- */
-  //! DimS spatial dimension (dimension of problem)
-  //! DimM material_dimension (dimension of constitutive law)
+  /** `GlobalFieldCollection` derives from `FieldCollectionBase` and stores
+    * global fields that live throughout the whole computational domain, i.e.
+    * are defined for each pixel.
+    */
   template<Dim_t DimS, Dim_t DimM>
   class GlobalFieldCollection:
     public FieldCollectionBase<DimS, DimM, GlobalFieldCollection<DimS, DimM>>
   {
   public:
     using Parent = FieldCollectionBase
       <DimS, DimM, GlobalFieldCollection<DimS, DimM>>; //!< base class
     using Ccoord = typename Parent::Ccoord; //!< cell coordinates type
     using Field_p = typename Parent::Field_p; //!< spatial coordinates type
     //! iterator over all pixels contained it the collection
     using iterator = typename CcoordOps::Pixels<DimS>::iterator;
     //! Default constructor
     GlobalFieldCollection();
 
     //! Copy constructor
     GlobalFieldCollection(const GlobalFieldCollection &other) = delete;
 
     //! Move constructor
     GlobalFieldCollection
       (GlobalFieldCollection &&other) = default;
 
     //! Destructor
     virtual ~GlobalFieldCollection()  = default;
 
     //! Copy assignment operator
     GlobalFieldCollection&
     operator=(const GlobalFieldCollection &other) = delete;
 
     //! Move assignment operator
     GlobalFieldCollection&
     operator=(GlobalFieldCollection &&other) = default;
 
     /** allocate memory, etc. At this point, the collection is
         informed aboud the size and shape of the domain (through the
         sizes parameter). The job of initialise is to make sure that
         all fields are either of size 0, in which case they need to be
         allocated, or are of the same size as the product of 'sizes'
         (if standard strides apply) any field of a different size is
         wrong.
 
         TODO: check whether it makes sense to put a runtime check here
      **/
     inline void initialise(Ccoord sizes);
 
     //! return the pixel sizes
     inline const Ccoord & get_sizes() const;
 
     //! returns the linear index corresponding to cell coordinates
     template <class CcoordRef>
     inline size_t get_index(CcoordRef && ccoord) const;
     //! returns the cell coordinates corresponding to a linear index
     inline Ccoord get_ccoord(size_t index) const;
 
     inline iterator begin(); //!< returns iterator to first pixel
     inline iterator end(); //!< returns iterator past the last pixel
 
     //! return spatial dimension (template parameter)
     static constexpr inline Dim_t spatial_dim() {return DimS;}
     //! return material dimension (template parameter)
     static constexpr inline Dim_t material_dim() {return DimM;}
   protected:
     //! number of discretisation cells in each of the DimS spatial directions
     Ccoord sizes{};
     CcoordOps::Pixels<DimS> pixels{}; //!< helper to iterate over the grid
   private:
   };
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   GlobalFieldCollection<DimS, DimM>::GlobalFieldCollection()
     :Parent()
   {}
 
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   void GlobalFieldCollection<DimS, DimM>::
   initialise(Ccoord sizes) {
     if (this->is_initialised) {
       throw std::runtime_error("double initialisation");
     }
     this->pixels = CcoordOps::Pixels<DimS>(sizes);
     this->size_ = CcoordOps::get_size(sizes);
     this->sizes = sizes;
 
     std::for_each(std::begin(this->fields), std::end(this->fields),
                   [this](auto && item) {
                     auto && field = *item.second;
                     const auto field_size = field.size();
                     if (field_size == 0) {
                       field.resize(this->size());
                     } else if (field_size != this->size()) {
                       std::stringstream err_stream;
                       err_stream << "Field '" << field.get_name()
                                  << "' contains " << field_size
                                  << " entries, but the field collection "
                                  << "has " << this->size() << " pixels";
                       throw FieldCollectionError(err_stream.str());
                     }
                   });
     this->is_initialised = true;
   }
 
   //----------------------------------------------------------------------------//
   //! return the pixel sizes
   template <Dim_t DimS, Dim_t DimM>
   const typename GlobalFieldCollection<DimS, DimM>::Ccoord &
   GlobalFieldCollection<DimS, DimM>::get_sizes() const {
     return this->sizes;
   }
 
   //----------------------------------------------------------------------------//
   //! returns the cell coordinates corresponding to a linear index
   template <Dim_t DimS, Dim_t DimM>
   typename GlobalFieldCollection<DimS, DimM>::Ccoord
   GlobalFieldCollection<DimS, DimM>::get_ccoord(size_t index) const {
     return CcoordOps::get_ccoord(this->get_sizes(), std::move(index));
   }
 
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   typename GlobalFieldCollection<DimS, DimM>::iterator
   GlobalFieldCollection<DimS, DimM>::begin() {
     return this->pixels.begin();
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   typename GlobalFieldCollection<DimS, DimM>::iterator
   GlobalFieldCollection<DimS, DimM>::end() {
     return this->pixels.end();
   }
   //----------------------------------------------------------------------------//
   //! returns the linear index corresponding to cell coordinates
   template <Dim_t DimS, Dim_t DimM>
   template <class CcoordRef>
   size_t
   GlobalFieldCollection<DimS, DimM>::get_index(CcoordRef && ccoord) const {
     static_assert(std::is_same<
                     Ccoord,
                     std::remove_const_t<
                       std::remove_reference_t<CcoordRef>>>::value,
                   "can only be called with values or references of Ccoord");
     return CcoordOps::get_index(this->get_sizes(),
                                 std::forward<CcoordRef>(ccoord));
   }
 
 }  // muSpectre
 
 #endif /* FIELD_COLLECTION_GLOBAL_H */
diff --git a/src/common/field_collection_local.hh b/src/common/field_collection_local.hh
index 3eff772..2de7864 100644
--- a/src/common/field_collection_local.hh
+++ b/src/common/field_collection_local.hh
@@ -1,176 +1,181 @@
 /**
  * @file   field_collection_local.hh
  *
  * @author Till Junge <till.junge@altermail.ch>
  *
  * @date   05 Nov 2017
  *
  * @brief  FieldCollection base-class for local fields
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef FIELD_COLLECTION_LOCAL_H
 #define FIELD_COLLECTION_LOCAL_H
 
 #include "common/field_collection_base.hh"
 
 namespace muSpectre {
 
   /* ---------------------------------------------------------------------- */
-  //! DimS spatial dimension (dimension of problem)
-  //! DimM material_dimension (dimension of constitutive law)
+  /** `LocalFieldCollection` derives from `FieldCollectionBase` and stores
+    * local fields, i.e. fields that are only defined for a subset of all pixels
+    * in the computational domain. The coordinates of these active pixels are
+    * explicitly stored by this field collection.
+    * `LocalFieldCollection::add_pixel` allows to add individual pixels to the
+    * field collection.
+    */
   template<Dim_t DimS, Dim_t DimM>
   class LocalFieldCollection:
     public FieldCollectionBase<DimS, DimM, LocalFieldCollection<DimS, DimM>>
   {
   public:
     //! base class
     using Parent = FieldCollectionBase<DimS, DimM,
                                        LocalFieldCollection<DimS, DimM>>;
     using Ccoord = typename Parent::Ccoord; //!< cell coordinates type
     using Field_p = typename Parent::Field_p; //!< field pointer
     using ccoords_container = std::vector<Ccoord>; //!< list of pixels
     //! iterator over managed pixels
     using iterator = typename ccoords_container::iterator;
 
     //! Default constructor
     LocalFieldCollection();
 
     //! Copy constructor
     LocalFieldCollection(const LocalFieldCollection &other) = delete;
 
     //! Move constructor
     LocalFieldCollection(LocalFieldCollection &&other) = delete;
 
     //! Destructor
     virtual ~LocalFieldCollection()  = default;
 
     //! Copy assignment operator
     LocalFieldCollection& operator=(const LocalFieldCollection &other) = delete;
 
     //! Move assignment operator
     LocalFieldCollection& operator=(LocalFieldCollection &&other) = delete;
 
     //! add a pixel/voxel to the field collection
     inline void add_pixel(const Ccoord & local_ccoord);
 
     /** allocate memory, etc. at this point, the field collection
         knows how many entries it should have from the size of the
         coords containes (which grows by one every time add_pixel is
         called. The job of initialise is to make sure that all fields
         are either of size 0, in which case they need to be allocated,
         or are of the same size as the product of 'sizes' any field of
         a different size is wrong TODO: check whether it makes sense
         to put a runtime check here
      **/
     inline void initialise();
 
 
     //! returns the linear index corresponding to cell coordinates
     template <class CcoordRef>
     inline size_t get_index(CcoordRef && ccoord) const;
     //! returns the cell coordinates corresponding to a linear index
     inline Ccoord get_ccoord(size_t index) const;
 
     //! iterator to first pixel
     inline iterator begin() {return this->ccoords.begin();}
     //! iterator past last pixel
     inline iterator end() {return this->ccoords.end();}
 
   protected:
     //! container of pixel coords for non-global collections
     ccoords_container ccoords{};
     //! container of indices for non-global collections (slow!)
     std::map<Ccoord, size_t> indices{};
   private:
   };
 
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   LocalFieldCollection<DimS, DimM>::LocalFieldCollection()
     :Parent(){}
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   void LocalFieldCollection<DimS, DimM>::
   add_pixel(const Ccoord & local_ccoord) {
     if (this->is_initialised) {
       throw FieldCollectionError
         ("once a field collection has been initialised, you can't add new "
          "pixels.");
     }
     this->indices[local_ccoord] = this->ccoords.size();
     this->ccoords.push_back(local_ccoord);
     this->size_++;
   }
 
   /* ---------------------------------------------------------------------- */
   template <Dim_t DimS, Dim_t DimM>
   void LocalFieldCollection<DimS, DimM>::
   initialise() {
     if (this->is_initialised) {
       throw std::runtime_error("double initialisation");
     }
     std::for_each(std::begin(this->fields), std::end(this->fields),
                   [this](auto && item) {
                     auto && field = *item.second;
                     const auto field_size = field.size();
                     if (field_size == 0) {
                       field.resize(this->size());
                     } else if (field_size != this->size()) {
                       std::stringstream err_stream;
                       err_stream << "Field '" << field.get_name()
                                  << "' contains " << field_size
                                  << " entries, but the field collection "
                                  << "has " << this->size() << " pixels";
                       throw FieldCollectionError(err_stream.str());
                     }
                   });
     this->is_initialised = true;
   }
 
 
   //----------------------------------------------------------------------------//
   //! returns the linear index corresponding to cell coordinates
   template <Dim_t DimS, Dim_t DimM>
   template <class CcoordRef>
   size_t
   LocalFieldCollection<DimS, DimM>::get_index(CcoordRef && ccoord) const {
     static_assert(std::is_same<
                     Ccoord,
                     std::remove_const_t<
                       std::remove_reference_t<CcoordRef>>>::value,
                   "can only be called with values or references of Ccoord");
     return this->indices.at(std::forward<CcoordRef>(ccoord));
   }
 
 
   //----------------------------------------------------------------------------//
   //! returns the cell coordinates corresponding to a linear index
   template <Dim_t DimS, Dim_t DimM>
   typename LocalFieldCollection<DimS, DimM>::Ccoord
   LocalFieldCollection<DimS, DimM>::get_ccoord(size_t index) const {
     return this->ccoords[std::move(index)];
   }
 
 
 }  // muSpectre
 
 #endif /* FIELD_COLLECTION_LOCAL_H */
diff --git a/src/common/field_map_base.hh b/src/common/field_map_base.hh
index 891fbfb..827c11c 100644
--- a/src/common/field_map_base.hh
+++ b/src/common/field_map_base.hh
@@ -1,644 +1,654 @@
 /**
  * @file   field_map.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  *
  * @date   12 Sep 2017
  *
  * @brief  Defined a strongly defines proxy that iterates efficiently over a field
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 
 #ifndef FIELD_MAP_H
 #define FIELD_MAP_H
 
 #include "common/field.hh"
 #include "field_collection_base.hh"
 #include "common/common.hh"
 
 #include <unsupported/Eigen/CXX11/Tensor>
 
 #include <array>
 #include <string>
 #include <memory>
 #include <type_traits>
 
 namespace muSpectre {
 
   namespace internal {
     //----------------------------------------------------------------------------//
     //! little helper to automate creation of const maps without duplication
     template<class T, bool isConst>
     struct const_corrector {
       //! non-const type
       using type = typename T::reference;
     };
 
     //! specialisation for constant case
     template<class T>
     struct const_corrector<T, true> {
       //! const type
       using type = typename T::const_reference;
     };
 
     //! convenience alias
     template<class T, bool isConst>
     using const_corrector_t = typename const_corrector<T, isConst>::type;
 
     //----------------------------------------------------------------------------//
+    /**
+     * `FieldMap` provides two central mechanisms:
+     * - Map a field (that knows only about the size of the underlying object,
+     * onto the mathematical object (reprensented by the respective Eigen class)
+     * that provides linear algebra functionality.
+     * - Provide an iterator that allows to iterate over all pixels.
+     * A field is represented by `FieldBase` or a derived class.
+     * `FieldMap` has the specialisations `MatrixLikeFieldMap`,
+     * `ScalarFieldMap` and `TensorFieldMap`.
+     */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     class FieldMap
     {
     public:
       //! number of scalars per entry
       constexpr static auto nb_components{NbComponents};
       using TypedField_nc = TypedSizedFieldBase
         <FieldCollection, T, NbComponents>; //!< non-constant version of field
       //! field type as seen from iterator
       using TypedField = std::conditional_t<ConstField,
                                             const TypedField_nc,
                                             TypedField_nc>;
       using Field = typename TypedField::Base; //!< iterated field type
       using size_type = std::size_t;  //!< stl conformance
       using pointer = std::conditional_t<ConstField,
                                          const T*,
                                          T*>; //!< stl conformance
       //! Default constructor
       FieldMap() = delete;
 
       //! constructor
       template <bool isntConst=!ConstField>
       FieldMap(std::enable_if_t<isntConst, Field &> field);
       //! constructor
       template <bool isConst=ConstField>
       FieldMap(std::enable_if_t<isConst, const Field &> field);
 
       //! constructor with run-time cost (for python and debugging)
       template<class FC, typename T2, Dim_t NbC>
       FieldMap(TypedSizedFieldBase<FC, T2, NbC> & field);
 
       //! Copy constructor
       FieldMap(const FieldMap &other) = default;
 
       //! Move constructor
       FieldMap(FieldMap &&other) = default;
 
       //! Destructor
       virtual ~FieldMap() = default;
 
       //! Copy assignment operator
       FieldMap& operator=(const FieldMap &other) = delete;
 
       //! Move assignment operator
       FieldMap& operator=(FieldMap &&other) = delete;
 
       //! give human-readable field map type
       virtual std::string info_string() const = 0;
 
       //! return field name
       inline const std::string & get_name() const;
 
       //! return my collection (for iterating)
       inline const FieldCollection & get_collection() const;
 
       //! member access needs to be implemented by inheriting classes
       //inline value_type operator[](size_t index);
       //inline value_type operator[](Ccoord ccord);
 
       //! check compatibility (must be called by all inheriting classes at the
       //! end of their constructors
       inline void check_compatibility();
 
       //! convenience call to collection's size method
       inline size_t size() const;
 
       //! compile-time compatibility check
       template<class TypedField>
       struct is_compatible;
 
       /**
        * iterates over all pixels in the `muSpectre::FieldCollection`
        * and dereferences to an Eigen map to the currently used field.
        */
       template <class FullyTypedFieldMap, bool ConstIter=false>
       class iterator
       {
         static_assert(!((ConstIter==false) && (ConstField==true)),
                       "You can't have a non-const iterator over a const "
                       "field");
       public:
         //! stl conformance
         using value_type =
           const_corrector_t<FullyTypedFieldMap, ConstIter>;
         //! stl conformance
         using const_value_type =
           const_corrector_t<FullyTypedFieldMap, true>;
         //! stl conformance
         using pointer = typename FullyTypedFieldMap::pointer;
         //! stl conformance
         using difference_type = std::ptrdiff_t;
         //! stl conformance
         using iterator_category = std::random_access_iterator_tag;
         //! cell coordinates type
         using Ccoord = typename FieldCollection::Ccoord;
         //! stl conformance
         using reference = typename FullyTypedFieldMap::reference;
         //! fully typed reference as seen by the iterator
         using TypedRef = std::conditional_t<ConstIter,
                                             const FullyTypedFieldMap &,
                                             FullyTypedFieldMap>;
 
         //! Default constructor
         iterator() = delete;
 
         //! constructor
         inline iterator(TypedRef fieldmap, bool begin=true);
 
         //! constructor for random access
         inline iterator(TypedRef fieldmap, size_t index);
 
         //! Copy constructor
         iterator(const iterator &other)= default;
 
         //! Move constructor
         iterator(iterator &&other) = default;
 
         //! Destructor
         virtual ~iterator() = default;
 
         //! Copy assignment operator
         iterator& operator=(const iterator &other) = default;
 
         //! Move assignment operator
         iterator& operator=(iterator &&other) = default;
 
         //! pre-increment
         inline iterator & operator++();
         //! post-increment
         inline iterator operator++(int);
         //! dereference
         inline value_type operator*();
         //! dereference
         inline const_value_type operator*() const;
         //! member of pointer
         inline pointer operator->();
         //! pre-decrement
         inline iterator & operator--();
         //! post-decrement
         inline iterator operator--(int);
         //! access subscripting
         inline value_type operator[](difference_type diff);
         //! access subscripting
         inline const_value_type operator[](const difference_type diff) const;
         //! equality
         inline bool operator==(const iterator & other) const;
         //! inequality
         inline bool operator!=(const iterator & other) const;
         //! div. comparisons
         inline bool operator<(const iterator & other) const;
         //! div. comparisons
         inline bool operator<=(const iterator & other) const;
         //! div. comparisons
         inline bool operator>(const iterator & other) const;
         //! div. comparisons
         inline bool operator>=(const iterator & other) const;
         //! additions, subtractions and corresponding assignments
         inline iterator operator+(difference_type diff) const;
         //! additions, subtractions and corresponding assignments
         inline iterator operator-(difference_type diff) const;
         //! additions, subtractions and corresponding assignments
         inline iterator& operator+=(difference_type diff);
         //! additions, subtractions and corresponding assignments
         inline iterator& operator-=(difference_type diff);
 
         //! get pixel coordinates
         inline Ccoord get_ccoord() const;
 
         //! ostream operator (mainly for debug
         friend std::ostream & operator<<(std::ostream & os,
                                          const iterator& it) {
           if (ConstIter) {
             os << "const ";
           }
           os << "iterator on field '"
              << it.fieldmap.get_name()
              << "', entry " << it.index;
           return os;
         }
 
       protected:
         const FieldCollection & collection; //!< collection of the field
         TypedRef fieldmap; //!< ref to the field itself
         size_t index; //!< index of currently pointed-to pixel
       private:
       };
 
 
     protected:
       //! raw pointer to entry (for Eigen Map)
       inline pointer get_ptr_to_entry(size_t index);
       //! raw pointer to entry (for Eigen Map)
       inline const T* get_ptr_to_entry(size_t index) const;
       const FieldCollection & collection; //!< collection holding Field
       TypedField  & field;  //!< mapped Field
     private:
     };
   }  // internal
 
 
   namespace internal {
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template <bool isntConst>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     FieldMap(std::enable_if_t<isntConst, Field &> field)
       :collection(field.get_collection()), field(static_cast<TypedField&>(field)) {
       static_assert(NbComponents>0,
                     "Only fields with more than 0 components allowed");
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template <bool isConst>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     FieldMap(std::enable_if_t<isConst, const Field &> field)
       :collection(field.get_collection()), field(static_cast<const TypedField&>(field)) {
       static_assert(NbComponents>0,
                     "Only fields with more than 0 components allowed");
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template <class FC, typename T2, Dim_t NbC>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     FieldMap(TypedSizedFieldBase<FC, T2, NbC> & field)
       :collection(field.get_collection()), field(static_cast<TypedField&>(field)) {
       static_assert(std::is_same<FC, FieldCollection>::value,
                     "The field does not have the expected FieldCollection type");
       static_assert(std::is_same<T2, T>::value,
                     "The field does not have the expected Scalar type");
       static_assert((NbC == NbComponents),
                     "The field does not have the expected number of components");
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     void
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     check_compatibility() {
      if (typeid(T).hash_code() !=
           this->field.get_stored_typeid().hash_code()) {
        std::string err{"Cannot create a Map of type '" +
            this->info_string() +
            "' for field '" + this->field.get_name() + "' of type '" +
            this->field.get_stored_typeid().name() + "'"};
         throw FieldInterpretationError
           (err);
       }
       //check size compatibility
       if (NbComponents != this->field.get_nb_components()) {
         throw FieldInterpretationError
           ("Cannot create a Map of type '" +
            this->info_string() +
            "' for field '" + this->field.get_name() + "' with " +
            std::to_string(this->field.get_nb_components()) + " components");
       }
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     size_t
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     size() const {
       return this->collection.size();
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template <class myField>
     struct FieldMap<FieldCollection, T, NbComponents, ConstField>::is_compatible {
       //! creates a more readable compile error
       constexpr static bool explain() {
         static_assert
           (std::is_same<typename myField::collection_t, FieldCollection>::value,
            "The field does not have the expected FieldCollection type");
         static_assert
           (std::is_same<typename myField::Scalar, T>::value,
            "The // field does not have the expected Scalar type");
         static_assert((TypedField::nb_components == NbComponents),
                       "The field does not have the expected number of components");
         //The static asserts wouldn't pass in the incompatible case, so this is it
         return true;
       }
       //! evaluated compatibility
       constexpr static bool value{std::is_base_of<TypedField, myField>::value};
     };
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     const std::string &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     get_name() const {
       return this->field.get_name();
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     const FieldCollection &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     get_collection() const {
       return this->collection;
     }
 
     /* ---------------------------------------------------------------------- */
     /* ---------------------------------------------------------------------- */
     // Iterator implementations
     //! constructor
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::iterator
     <FullyTypedFieldMap, ConstIter>::
     iterator(TypedRef fieldmap, bool begin)
       :collection(fieldmap.get_collection()), fieldmap(fieldmap),
        index(begin ? 0 : fieldmap.field.size()) {}
 
     /* ---------------------------------------------------------------------- */
     //! constructor for random access
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::iterator<FullyTypedFieldMap, ConstIter>::
     iterator(TypedRef fieldmap, size_t index)
       :collection(fieldmap.collection), fieldmap(fieldmap),
        index(index) {}
 
     /* ---------------------------------------------------------------------- */
     //! pre-increment
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter> &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::iterator<FullyTypedFieldMap, ConstIter>::
     operator++() {
       this->index++;
       return *this;
     }
 
     /* ---------------------------------------------------------------------- */
     //! post-increment
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::iterator<FullyTypedFieldMap, ConstIter>::
     operator++(int) {
       iterator current = *this;
       this->index++;
       return current;
     }
 
     /* ---------------------------------------------------------------------- */
     //! dereference
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::
     template iterator<FullyTypedFieldMap, ConstIter>::value_type
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator*() {
       return this->fieldmap.operator[](this->index);
     }
 
     /* ---------------------------------------------------------------------- */
     //! dereference
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::
     template iterator<FullyTypedFieldMap, ConstIter>::const_value_type
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator*() const {
       return this->fieldmap.operator[](this->index);
     }
 
     /* ---------------------------------------------------------------------- */
     //! member of pointer
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FullyTypedFieldMap::pointer
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator->() {
       return this->fieldmap.ptr_to_val_t(this->index);
     }
 
     /* ---------------------------------------------------------------------- */
     //! pre-decrement
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter> &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator--() {
       this->index--;
       return *this;
     }
 
     /* ---------------------------------------------------------------------- */
     //! post-decrement
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator--(int) {
       iterator current = *this;
       this->index--;
       return current;
     }
 
     /* ---------------------------------------------------------------------- */
     //! Access subscripting
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::
     template iterator<FullyTypedFieldMap, ConstIter>::value_type
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator[](difference_type diff) {
       return this->fieldmap[this->index+diff];
     }
 
     /* ---------------------------------------------------------------------- */
     //! Access subscripting
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template iterator<FullyTypedFieldMap, ConstIter>::const_value_type
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator[](const difference_type diff) const {
       return this->fieldmap[this->index+diff];
     }
 
     /* ---------------------------------------------------------------------- */
     //! equality
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator==(const iterator & other) const {
       return (this->index == other.index);
     }
 
     /* ---------------------------------------------------------------------- */
     //! inquality
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator!=(const iterator & other) const {
       return !(*this == other);
     }
 
     /* ---------------------------------------------------------------------- */
     //! div. comparisons
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator<(const iterator & other) const {
       return (this->index < other.index);
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator<=(const iterator & other) const {
       return (this->index <= other.index);
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator>(const iterator & other) const {
       return (this->index > other.index);
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     bool
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator>=(const iterator & other) const {
       return (this->index >= other.index);
     }
 
     /* ---------------------------------------------------------------------- */
     //! additions, subtractions and corresponding assignments
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator+(difference_type diff) const {
       return iterator(this->fieldmap, this->index + diff);
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter>
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator-(difference_type diff) const {
       return iterator(this->fieldmap, this->index - diff);
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter> &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator+=(difference_type diff) {
       this->index += diff;
       return *this;
     }
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::template
     iterator<FullyTypedFieldMap, ConstIter> &
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     operator-=(difference_type diff) {
       this->index -= diff;
       return *this;
     }
 
     /* ---------------------------------------------------------------------- */
     //! get pixel coordinates
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     template<class FullyTypedFieldMap, bool ConstIter>
     typename FieldCollection::Ccoord
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     iterator<FullyTypedFieldMap, ConstIter>::
     get_ccoord() const {
       return this->collection.get_ccoord(this->index);
     }
 
 ////----------------------------------------------------------------------------//
 //template<class FieldCollection, typename T, Dim_t NbComponents, class FullyTypedFieldMap>
 //std::ostream & operator <<
 //(std::ostream &os,
 // const typename FieldMap<FieldCollection, T, NbComponents, ConstField>::
 // template iterator<FullyTypedFieldMap, ConstIter> & it) {
 //  os << "iterator on field '"
 //     << it.field.get_name()
 //     << "', entry " << it.index;
 //  return os;
 //}
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     typename FieldMap<FieldCollection, T, NbComponents, ConstField>::pointer
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     get_ptr_to_entry(size_t index) {
       return this->field.get_ptr_to_entry(std::move(index));
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, typename T, Dim_t NbComponents, bool ConstField>
     const T*
     FieldMap<FieldCollection, T, NbComponents, ConstField>::
     get_ptr_to_entry(size_t index) const {
       return this->field.get_ptr_to_entry(std::move(index));
     }
 
   }  // internal
 
 
 }  // muSpectre
 
 #endif /* FIELD_MAP_H */
diff --git a/src/common/field_map_matrixlike.hh b/src/common/field_map_matrixlike.hh
index 332bc3f..ac4f67e 100644
--- a/src/common/field_map_matrixlike.hh
+++ b/src/common/field_map_matrixlike.hh
@@ -1,402 +1,404 @@
 /**
  * @file   field_map_matrixlike.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  *
  * @date   26 Sep 2017
  *
  * @brief  Eigen-Matrix and -Array maps over strongly typed fields
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef FIELD_MAP_MATRIXLIKE_H
 #define FIELD_MAP_MATRIXLIKE_H
 
 #include "common/field_map_base.hh"
 #include "common/T4_map_proxy.hh"
 
 #include <Eigen/Dense>
 
 #include <memory>
 
 namespace muSpectre {
 
   namespace internal {
 
     /* ---------------------------------------------------------------------- */
     /**
      * lists all matrix-like types consideres by
      * `muSpectre::internal::MatrixLikeFieldMap`
      */
     enum class Map_t{
       Matrix,  //!< for wrapping `Eigen::Matrix`
       Array,   //!< for wrapping `Eigen::Array`
       T4Matrix //!< for wrapping `Eigen::T4Matrix`
     };
 
     /**
      * traits structure to define the name shown when a
      * `muSpectre::MatrixLikeFieldMap` output into an ostream
      */
     template<Map_t map_type>
     struct NameWrapper {
     };
 
     /// specialisation for `muSpectre::ArrayFieldMap`
     template<>
     struct NameWrapper<Map_t::Array> {
       //! string to use for printing
       static std::string field_info_root() {return "Array";}
     };
 
     /// specialisation for `muSpectre::MatrixFieldMap`
     template<>
     struct NameWrapper<Map_t::Matrix> {
       //! string to use for printing
       static std::string field_info_root() {return "Matrix";}
     };
 
     /// specialisation for `muSpectre::T4MatrixFieldMap`
     template<>
     struct NameWrapper<Map_t::T4Matrix> {
       //! string to use for printing
       static std::string field_info_root() {return "T4Matrix";}
     };
 
     /* ---------------------------------------------------------------------- */
     /*!
-     * base class for maps of matrices, arrays and fourth-order
-     * tensors mapped onty matrices
+     * A `MatrixLikeFieldMap` is the base class for maps of matrices, arrays and
+     * fourth-order tensors mapped onto matrices.
      *
      * It should never be necessary to call directly any of the
-     * constructors if this class, but rather use the template aliases
-     * `muSpectre::ArrayFieldMap`, `muSpectre::MatrixFieldMap`, and
-     * `muSpectre::T4MatrixFieldMap`
+     * constructors if this class, but rather use the template aliases:
+     * - `ArrayFieldMap`: iterate in the form of `Eigen::Array<...>`.
+     * - `MatrixFieldMap`: iterate in the form of
+     * `Eigen::Matrix<...>`.
+     * - `T4MatrixFieldMap`: iterate in the form of `T4MatMap`.
      */
     template <class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type, bool ConstField>
     class MatrixLikeFieldMap: public FieldMap<FieldCollection,
                                               typename EigenArray::Scalar,
                                               EigenArray::SizeAtCompileTime,
                                               ConstField>
     {
     public:
       //! base class
       using Parent = FieldMap<FieldCollection,
                               typename EigenArray::Scalar,
                               EigenArray::SizeAtCompileTime, ConstField>;
       using T_t = EigenPlain; //!< plain Eigen type to map
       //! cell coordinates type
       using Ccoord = Ccoord_t<FieldCollection::spatial_dim()>;
       using value_type = EigenArray; //!< stl conformance
       using const_reference = EigenConstArray; //!< stl conformance
       //! stl conformance
       using reference = std::conditional_t<ConstField,
                                            const_reference,
                                            value_type>; // since it's a resource handle
       using size_type = typename Parent::size_type; //!< stl conformance
       using pointer = std::unique_ptr<EigenArray>; //!< stl conformance
       using TypedField = typename Parent::TypedField; //!< stl conformance
       using Field = typename TypedField::Base; //!< stl conformance
       //! stl conformance
       using const_iterator= typename Parent::template iterator<MatrixLikeFieldMap, true>;
       //! stl conformance
       using iterator = std::conditional_t<
         ConstField,
         const_iterator,
         typename Parent::template iterator<MatrixLikeFieldMap>>;
       using reverse_iterator = std::reverse_iterator<iterator>; //!< stl conformance
        //! stl conformance
       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
       //! stl conformance
       friend iterator;
 
       //! Default constructor
       MatrixLikeFieldMap() = delete;
 
       /**
        * Constructor using a (non-typed) field. Compatibility is enforced at
        * runtime.  This should not be a performance concern, as this constructor
        * will not be called in anny inner loops (if used as intended).
        */
       template <bool isntConst=!ConstField>
       MatrixLikeFieldMap(std::enable_if_t<isntConst, Field &> field);
       /**
        * Constructor using a (non-typed) field. Compatibility is enforced at
        * runtime.  This should not be a performance concern, as this constructor
        * will not be called in anny inner loops (if used as intended).
        */
       template <bool isConst=ConstField>
       MatrixLikeFieldMap(std::enable_if_t<isConst, const Field &> field);
 
       /**
        * Constructor using a typed field. Compatibility is enforced
        * statically. It is not always possible to call this constructor, as the
        * type of the field might not be known at compile time.
        */
       template<class FC, typename T2, Dim_t NbC>
       MatrixLikeFieldMap(TypedSizedFieldBase<FC, T2, NbC> & field);
 
       //! Copy constructor
       MatrixLikeFieldMap(const MatrixLikeFieldMap &other) = default;
 
       //! Move constructor
       MatrixLikeFieldMap(MatrixLikeFieldMap &&other) = default;
 
       //! Destructor
       virtual ~MatrixLikeFieldMap()  = default;
 
       //! Copy assignment operator
       MatrixLikeFieldMap& operator=(const MatrixLikeFieldMap &other) = delete;
 
       //! Move assignment operator
       MatrixLikeFieldMap& operator=(MatrixLikeFieldMap &&other) = delete;
 
       //! Assign a matrixlike value to every entry
       template <class Derived>
       inline MatrixLikeFieldMap & operator=(const Eigen::EigenBase<Derived> & val);
 
       //! give human-readable field map type
       inline std::string info_string() const override final;
 
       //! member access
       inline reference operator[](size_type index);
       //! member access
       inline reference operator[](const Ccoord& ccoord);
 
       //! member access
       inline const_reference operator[](size_type index) const;
       //! member access
       inline const_reference operator[](const Ccoord& ccoord) const;
 
       //! return an iterator to head of field for ranges
       inline iterator begin(){return iterator(*this);}
       //! return an iterator to head of field for ranges
       inline const_iterator cbegin() const {return const_iterator(*this);}
       //! return an iterator to head of field for ranges
       inline const_iterator begin() const {return this->cbegin();}
       //! return an iterator to tail of field for ranges
       inline iterator end(){return iterator(*this, false);};
       //! return an iterator to tail of field for ranges
       inline const_iterator cend() const {return const_iterator(*this, false);}
       //! return an iterator to tail of field for ranges
       inline const_iterator end() const {return this->cend();}
 
       //! evaluate the average of the field
       inline T_t mean() const;
 
     protected:
       //! for sad, legacy iterator use
       inline pointer ptr_to_val_t(size_type index);
       const static std::string field_info_root; //!< for printing and debug
     private:
     };
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     const std::string MatrixLikeFieldMap<FieldCollection, EigenArray,
                                          EigenConstArray, EigenPlain, map_type,
                                          ConstField>::
     field_info_root{NameWrapper<map_type>::field_info_root()};
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, class EigenArray, class EigenConstArray,
              class EigenPlain, Map_t map_type,  bool ConstField>
     template <bool isntConst>
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     MatrixLikeFieldMap(std::enable_if_t<isntConst, Field &> field)
       :Parent(field) {
       static_assert((isntConst != ConstField),
                     "let the compiler deduce isntConst, this is a SFINAE "
                     "parameter");
       this->check_compatibility();
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     template <bool isConst>
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     MatrixLikeFieldMap(std::enable_if_t<isConst, const Field &> field)
       :Parent(field) {
       static_assert((isConst == ConstField),
                     "let the compiler deduce isntConst, this is a SFINAE "
                     "parameter");
       this->check_compatibility();
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     template<class FC, typename T2, Dim_t NbC>
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField>::
     MatrixLikeFieldMap(TypedSizedFieldBase<FC, T2, NbC> & field)
       :Parent(field) {
     }
 
     /* ---------------------------------------------------------------------- */
     //! human-readable field map type
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     std::string
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField>::
     info_string() const {
       std::stringstream info;
       info << field_info_root << "("
            << typeid(typename EigenArray::value_type).name() << ", "
            << EigenArray::RowsAtCompileTime << "x"
            << EigenArray::ColsAtCompileTime << ")";
       return info.str();
     }
 
     /* ---------------------------------------------------------------------- */
     //! member access
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::reference
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField>::
     operator[](size_type index) {
       return reference(this->get_ptr_to_entry(index));
     }
 
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::reference
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     operator[](const Ccoord & ccoord) {
       size_t index{};
       index = this->collection.get_index(ccoord);
       return reference(this->get_ptr_to_entry(std::move(index)));
     }
 
     /* ---------------------------------------------------------------------- */
     //! member access
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::const_reference
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     operator[](size_type index) const {
       return const_reference(this->get_ptr_to_entry(index));
     }
 
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::const_reference
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     operator[](const Ccoord & ccoord) const{
       size_t index{};
       index = this->collection.get_index(ccoord);
       return const_reference(this->get_ptr_to_entry(std::move(index)));
     }
 
     //----------------------------------------------------------------------------//
     template <class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     template <class Derived>
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField> &
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField>::
     operator=(const Eigen::EigenBase<Derived> & val) {
       for (auto && entry: *this) {
         entry = val;
       }
       return *this;
     }
 
     /* ---------------------------------------------------------------------- */
     template <class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type, bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::T_t
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                        EigenPlain, map_type, ConstField>::
     mean() const {
       T_t mean{T_t::Zero()};
       for (auto && val: *this) {
         mean += val;
       }
       mean *= 1./Real(this->size());
       return mean;
     }
 
     /* ---------------------------------------------------------------------- */
     template<class FieldCollection, class EigenArray, class EigenConstArray,
               class EigenPlain, Map_t map_type,  bool ConstField>
     typename MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray,
                                 EigenPlain, map_type, ConstField>::pointer
     MatrixLikeFieldMap<FieldCollection, EigenArray, EigenConstArray, EigenPlain,
                        map_type, ConstField>::
     ptr_to_val_t(size_type index) {
       return std::make_unique<value_type>
         (this->get_ptr_to_entry(std::move(index)));
     }
 
   }  // internal
 
   /* ---------------------------------------------------------------------- */
   //! short-hand for an Eigen matrix map as iterate
   template <class FieldCollection, typename T, Dim_t NbRows, Dim_t NbCols,
             bool ConstField=false>
   using MatrixFieldMap = internal::MatrixLikeFieldMap
     <FieldCollection,
      Eigen::Map<Eigen::Matrix<T, NbRows, NbCols>>,
      Eigen::Map<const Eigen::Matrix<T, NbRows, NbCols>>,
      Eigen::Matrix<T, NbRows, NbCols>,
      internal::Map_t::Matrix, ConstField>;
 
   /* ---------------------------------------------------------------------- */
   //! short-hand for an Eigen matrix map as iterate
   template <class FieldCollection, typename T, Dim_t Dim,
             bool MapConst=false>
   using T4MatrixFieldMap = internal::MatrixLikeFieldMap
     <FieldCollection,
      T4MatMap<T, Dim, false>,
      T4MatMap<T, Dim, true>,
      T4Mat<T, Dim>,
      internal::Map_t::T4Matrix, MapConst>;
 
   /* ---------------------------------------------------------------------- */
   //! short-hand for an Eigen array map as iterate
   template <class FieldCollection, typename T, Dim_t NbRows, Dim_t NbCols,
             bool ConstField=false>
   using ArrayFieldMap = internal::MatrixLikeFieldMap
     <FieldCollection,
      Eigen::Map<Eigen::Array<T, NbRows, NbCols>>,
      Eigen::Map<const Eigen::Array<T, NbRows, NbCols>>,
      Eigen::Array<T, NbRows, NbCols>,
      internal::Map_t::Array, ConstField>;
 
 
 }  // muSpectre
 
 #endif /* FIELD_MAP_MATRIXLIKE_H */
diff --git a/src/common/field_map_scalar.hh b/src/common/field_map_scalar.hh
index 70e2eaf..3982a39 100644
--- a/src/common/field_map_scalar.hh
+++ b/src/common/field_map_scalar.hh
@@ -1,233 +1,234 @@
 /**
  * @file   field_map_scalar.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  *
  * @date   26 Sep 2017
  *
  * @brief  maps over scalar fields
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef FIELD_MAP_SCALAR_H
 #define FIELD_MAP_SCALAR_H
 
 #include "common/field_map_base.hh"
 
 namespace muSpectre {
   /**
-   * implements maps on scalar fields (i.e. material properties,
-   * temperatures, etc)
+   * Implements maps on scalar fields (i.e. material properties,
+   * temperatures, etc). Maps onto a `muSpectre::internal::TypedSizedFieldBase`
+   * and lets you iterate over it in the form of the bare type of the field.
    */
   template <class FieldCollection, typename T, bool ConstField=false>
   class ScalarFieldMap
     : public internal::FieldMap<FieldCollection, T, 1, ConstField>
     {
     public:
       //! base class
       using parent = internal::FieldMap<FieldCollection, T, 1, ConstField>;
       //! cell coordinates type
       using Ccoord = Ccoord_t<FieldCollection::spatial_dim()>;
       using value_type = T; //!< stl conformance
       using const_reference = const value_type &; //!< stl conformance
       //! stl conformance
       using reference = std::conditional_t<ConstField,
                                            const_reference,
                                            value_type &>;
       using size_type = typename parent::size_type; //!< stl conformance
       using pointer = T*; //!< stl conformance
       using Field = typename parent::Field; //!< stl conformance
       //! stl conformance
       using const_iterator= typename parent::template iterator<ScalarFieldMap, true>;
       //! iterator over a scalar field
       using iterator = std::conditional_t
         <ConstField,
          const_iterator,
          typename parent::template iterator<ScalarFieldMap>>;
       using reverse_iterator = std::reverse_iterator<iterator>; //!< stl conformance
       //! stl conformance
       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
       //! give access to the protected fields
       friend iterator;
 
       //! Default constructor
       ScalarFieldMap() = delete;
 
       //! constructor
       template <bool isntConst=!ConstField>
       ScalarFieldMap(std::enable_if_t<isntConst, Field &> field);
       //! constructor
       template <bool isConst=ConstField>
       ScalarFieldMap(std::enable_if_t<isConst, const Field &> field);
 
       //! Copy constructor
       ScalarFieldMap(const ScalarFieldMap &other) = default;
 
       //! Move constructor
       ScalarFieldMap(ScalarFieldMap &&other) = default;
 
       //! Destructor
       virtual ~ScalarFieldMap() = default;
 
       //! Copy assignment operator
       ScalarFieldMap& operator=(const ScalarFieldMap &other) = delete;
 
       //! Move assignment operator
       ScalarFieldMap& operator=(ScalarFieldMap &&other) = delete;
 
       //! Assign a value to every entry
       ScalarFieldMap& operator=(T val);
 
       //! give human-readable field map type
       inline std::string info_string() const override final;
 
       //! member access
       inline reference operator[](size_type index);
       inline reference operator[](const Ccoord&  ccoord);
 
       inline const_reference operator[] (size_type index) const;
       inline const_reference operator[] (const Ccoord&  ccoord) const;
 
       //! return an iterator to the first pixel of the field
       inline iterator begin(){return iterator(*this);}
       //! return an iterator to the first pixel of the field
       inline const_iterator cbegin() const {return const_iterator(*this);}
       //! return an iterator to the first pixel of the field
       inline const_iterator begin() const {return this->cbegin();}
       //! return an iterator to tail of field for ranges
       inline iterator end(){return iterator(*this, false);}
       //! return an iterator to tail of field for ranges
       inline const_iterator cend() const {return const_iterator(*this, false);}
       //! return an iterator to tail of field for ranges
       inline const_iterator end() const {return this->cend();}
 
       //! evaluate the average of the field
       inline T mean() const;
 
     protected:
       //! for sad, legacy iterator use
       inline pointer ptr_to_val_t(size_type index);
 
       //! type identifier for printing and debugging
       const static std::string field_info_root;
     private:
   };
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, bool ConstField>
   template <bool isntConst>
   ScalarFieldMap<FieldCollection, T, ConstField>::
   ScalarFieldMap(std::enable_if_t<isntConst, Field &> field)
     :parent(field) {
     static_assert((isntConst != ConstField),
                   "let the compiler deduce isntConst, this is a SFINAE "
                   "parameter");
     this->check_compatibility();
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, bool ConstField>
   template <bool isConst>
   ScalarFieldMap<FieldCollection, T, ConstField>::
   ScalarFieldMap(std::enable_if_t<isConst, const Field &> field)
     :parent(field) {
     static_assert((isConst == ConstField),
                   "let the compiler deduce isntConst, this is a SFINAE "
                   "parameter");
     this->check_compatibility();
   }
 
   /* ---------------------------------------------------------------------- */
   //! human-readable field map type
   template<class FieldCollection, typename T, bool ConstField>
   std::string
   ScalarFieldMap<FieldCollection, T, ConstField>::info_string() const {
     std::stringstream info;
     info << "Scalar(" << typeid(T).name() << ")";
     return info.str();
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, bool ConstField>
   const std::string ScalarFieldMap<FieldCollection, T, ConstField>::field_info_root{
     "Scalar"};
 
   /* ---------------------------------------------------------------------- */
   //! member access
   template <class FieldCollection, typename T, bool ConstField>
   typename ScalarFieldMap<FieldCollection, T, ConstField>::reference
   ScalarFieldMap<FieldCollection, T, ConstField>::operator[](size_type index) {
     return this->get_ptr_to_entry(std::move(index))[0];
   }
 
   /* ---------------------------------------------------------------------- */
   //! member access
   template <class FieldCollection, typename T, bool ConstField>
   typename ScalarFieldMap<FieldCollection, T, ConstField>::reference
   ScalarFieldMap<FieldCollection, T, ConstField>::operator[](const Ccoord& ccoord) {
     auto && index = this->collection.get_index(std::move(ccoord));
     return this->get_ptr_to_entry(std::move(index))[0];
   }
 
   /* ---------------------------------------------------------------------- */
   //! member access
   template <class FieldCollection, typename T, bool ConstField>
   typename ScalarFieldMap<FieldCollection, T, ConstField>::const_reference
   ScalarFieldMap<FieldCollection, T, ConstField>::
   operator[](size_type index) const {
     return this->get_ptr_to_entry(std::move(index))[0];
   }
 
   /* ---------------------------------------------------------------------- */
   //! member access
   template <class FieldCollection, typename T, bool ConstField>
   typename ScalarFieldMap<FieldCollection, T, ConstField>::const_reference
   ScalarFieldMap<FieldCollection, T, ConstField>::
   operator[](const Ccoord& ccoord) const {
     auto && index = this->collection.get_index(std::move(ccoord));
     return this->get_ptr_to_entry(std::move(index))[0];
   }
 
   /* ---------------------------------------------------------------------- */
   //! Assign a value to every entry
   template <class FieldCollection, typename T, bool ConstField>
   ScalarFieldMap<FieldCollection, T, ConstField> &
   ScalarFieldMap<FieldCollection, T, ConstField>::operator=(T val) {
     for (auto & scalar:*this) {
       scalar = val;
     }
     return *this;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, bool ConstField>
   T
   ScalarFieldMap<FieldCollection, T, ConstField>::
   mean() const {
     T mean{0};
     for (auto && val: *this) {
       mean += val;
     }
     mean /= Real(this->size());
     return mean;
   }
 
 }  // muSpectre
 
 #endif /* FIELD_MAP_SCALAR_H */
diff --git a/src/common/field_map_tensor.hh b/src/common/field_map_tensor.hh
index cab4d16..e112ef7 100644
--- a/src/common/field_map_tensor.hh
+++ b/src/common/field_map_tensor.hh
@@ -1,287 +1,286 @@
 /**
  * @file   field_map_tensor.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  *
  * @date   26 Sep 2017
  *
  * @brief  Defines an Eigen-Tensor map over strongly typed fields
  *
  * Copyright © 2017 Till Junge
  *
  * µSpectre is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, either version 3, or (at
  * your option) any later version.
  *
  * µSpectre is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with GNU Emacs; see the file COPYING. If not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef FIELD_MAP_TENSOR_H
 #define FIELD_MAP_TENSOR_H
 
 #include "common/eigen_tools.hh"
 #include "common/field_map_base.hh"
 
 #include <sstream>
 #include <memory>
 
 namespace muSpectre {
 
 
   /* ---------------------------------------------------------------------- */
   /**
-   * maps onto a `muSpectre::internal::TypedSizedFieldBase` and lets
-   * you iterate over it in the form ot
-   * `Eigen::TensorMap<TensorFixedSize<...>>`
+   * Maps onto a `muSpectre::internal::TypedSizedFieldBase` and lets
+   * you iterate over it in the form of `Eigen::TensorMap<TensorFixedSize<...>>`
    */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim,
             bool ConstField=false>
   class TensorFieldMap: public
     internal::FieldMap<FieldCollection,
                        T,
                        SizesByOrder<order, dim>::Sizes::total_size,
                        ConstField>
   {
   public:
     //! base class
     using Parent = internal::FieldMap<FieldCollection, T,
                                       TensorFieldMap::nb_components, ConstField>;
     //! cell coordinates type
     using Ccoord = Ccoord_t<FieldCollection::spatial_dim()>;
     //! static tensor size
     using Sizes = typename SizesByOrder<order, dim>::Sizes;
     //! plain Eigen type
     using T_t = Eigen::TensorFixedSize<T, Sizes>;
     using value_type = Eigen::TensorMap<T_t>; //!< stl conformance
     using const_reference = Eigen::TensorMap<const T_t>; //!< stl conformance
     //! stl conformance
     using reference = std::conditional_t<ConstField,
                                          const_reference,
                                          value_type>; // since it's a resource handle
     using size_type = typename Parent::size_type; //!< stl conformance
     using pointer = std::unique_ptr<value_type>; //!< stl conformance
     using TypedField = typename Parent::TypedField; //!< field to map
     //! polymorphic base field type (for debug and python)
     using Field = typename TypedField::Base;
     //! stl conformance
     using const_iterator = typename Parent::template iterator<TensorFieldMap, true>;
     //! stl conformance
     using iterator = std::conditional_t<
       ConstField,
       const_iterator,
       typename Parent::template iterator<TensorFieldMap>>;
     //! stl conformance
     using reverse_iterator = std::reverse_iterator<iterator>;
     //! stl conformance
     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
     //! stl conformance
     friend iterator;
 
     //! Default constructor
     TensorFieldMap() = delete;
 
     //! constructor
     template <bool isntConst=!ConstField>
     TensorFieldMap(std::enable_if_t<isntConst, Field &> field);
     //! constructor
     template <bool isConst=ConstField>
     TensorFieldMap(std::enable_if_t<isConst, const Field &> field);
 
     //! Copy constructor
     TensorFieldMap(const TensorFieldMap &other) = default;
 
     //! Move constructor
     TensorFieldMap(TensorFieldMap &&other) = default;
 
     //! Destructor
     virtual ~TensorFieldMap() = default;
 
     //! Copy assignment operator
     TensorFieldMap& operator=(const TensorFieldMap &other) = delete;
 
     //! Assign a matrixlike value to every entry
     inline TensorFieldMap & operator=(const T_t & val);
 
     //! Move assignment operator
     TensorFieldMap& operator=(TensorFieldMap &&other) = delete;
 
     //! give human-readable field map type
     inline std::string info_string() const override final;
 
     //! member access
     inline reference operator[](size_type index);
     //! member access
     inline reference operator[](const Ccoord & ccoord);
 
     //! member access
     inline const_reference operator[](size_type index) const;
     //! member access
     inline const_reference operator[](const Ccoord& ccoord) const;
 
     //! return an iterator to first entry of field
     inline iterator begin(){return iterator(*this);}
     //! return an iterator to first entry of field
     inline const_iterator cbegin() const {return const_iterator(*this);}
     //! return an iterator to first entry of field
     inline const_iterator begin() const {return this->cbegin();}
     //! return an iterator past the last entry of field
     inline iterator end(){return iterator(*this, false);}
     //! return an iterator past the last entry of field
     inline const_iterator cend() const {return const_iterator(*this, false);}
     //! return an iterator past the last entry of field
     inline const_iterator end() const {return this->cend();}
 
     //! evaluate the average of the field
     inline T_t mean() const;
   protected:
     //! for sad, legacy iterator use
     inline pointer ptr_to_val_t(size_type index);
   private:
   };
 
   /* ---------------------------------------------------------------------- */
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   template <bool isntConst>
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   TensorFieldMap(std::enable_if_t<isntConst, Field &> field)
     :Parent(field) {
     static_assert((isntConst != ConstField),
                   "let the compiler deduce isntConst, this is a SFINAE "
                   "parameter");
     this->check_compatibility();
   }
 
   /* ---------------------------------------------------------------------- */
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   template <bool isConst>
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   TensorFieldMap(std::enable_if_t<isConst, const Field &> field)
     :Parent(field) {
     static_assert((isConst == ConstField),
                   "let the compiler deduce isntConst, this is a SFINAE "
                   "parameter");
     this->check_compatibility();
   }
 
   /* ---------------------------------------------------------------------- */
   //! human-readable field map type
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim, bool ConstField>
   std::string
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::info_string() const {
     std::stringstream info;
     info << "Tensor(" << typeid(T).name() << ", " << order
          << "_o, " << dim << "_d)";
     return info.str();
   }
 
   /* ---------------------------------------------------------------------- */
   //! member access
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim,
             bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::reference
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   operator[](size_type index) {
     auto && lambda = [this, &index](auto&&...tens_sizes) {
       return reference(this->get_ptr_to_entry(index), tens_sizes...);
     };
     return call_sizes<order, dim>(lambda);
   }
 
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::reference
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   operator[](const Ccoord & ccoord) {
     auto && index = this->collection.get_index(ccoord);
     auto && lambda = [this, &index](auto&&...sizes) {
       return reference(this->get_ptr_to_entry(index), sizes...);
     };
     return call_sizes<order, dim>(lambda);
   }
 
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim,
             bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   const_reference
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   operator[](size_type index) const {
     // Warning: due to a inconsistency in Eigen's API, tensor maps
     // cannot be constructed from a const ptr, hence this nasty const
     // cast :(
     auto && lambda = [this, &index](auto&&...tens_sizes) {
       return const_reference(const_cast<T*>(this->get_ptr_to_entry(index)),
                    tens_sizes...);
     };
     return call_sizes<order, dim>(lambda);
   }
 
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   const_reference
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   operator[](const Ccoord & ccoord) const {
     auto && index = this->collection.get_index(ccoord);
     auto && lambda = [this, &index](auto&&...sizes) {
       return const_reference(const_cast<T*>(this->get_ptr_to_entry(index)),
                              sizes...);
     };
     return call_sizes<order, dim>(lambda);
   }
 
   /* ---------------------------------------------------------------------- */
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   TensorFieldMap<FieldCollection, T, order, dim, ConstField> &
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   operator=(const T_t & val) {
     for (auto && tens: *this) {
       tens = val;
     }
     return *this;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class FieldCollection, typename T, Dim_t order, Dim_t dim,
             bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::T_t
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   mean() const {
     T_t mean{T_t::Zero()};
     for (auto && val: *this) {
       mean += val;
     }
     mean *= 1./Real(this->size());
     return mean;
   }
 
   /* ---------------------------------------------------------------------- */
   //! for sad, legacy iterator use. Don't use unless you have to.
   template<class FieldCollection, typename T, Dim_t order, Dim_t dim,
            bool ConstField>
   typename TensorFieldMap<FieldCollection, T, order, dim, ConstField>::pointer
   TensorFieldMap<FieldCollection, T, order, dim, ConstField>::
   ptr_to_val_t(size_type index) {
     auto && lambda = [this, &index](auto&&... tens_sizes) {
       return std::make_unique<value_type>(this->get_ptr_to_entry(index),
                                        tens_sizes...);
     };
     return call_sizes<order, dim>(lambda);
   }
 
 
 }  // muSpectre
 
 
 #endif /* FIELD_MAP_TENSOR_H */