[dune-pdelab] [dune-pdelab-commit] [Commit] dune-pdelab - 17c90dd: [GridFunctionSpace/Ordering] Feed size information from Orderings to GridFunctionSpaces and introduce GFS base class

Christian Engwer christian.engwer at uni-muenster.de
Sun Aug 18 21:37:54 CEST 2013


Hi Steffen,

this patch seems pretty invasive, could you comment on what needs to
be done in the user code? Or is this usually hidden in the guts of
pdelab?

Christian

On Sun, Aug 18, 2013 at 09:05:05PM +0200, Steffen Müthing wrote:
> New commit, appeared at Sun Aug 18 21:05:05 2013 +0200
> as part of the following ref changes:
> 
>     branch refs/heads/master    updated from f2e9974 -> f9d1e4c
> 
> Browsable version: http://cgit.dune-project.org/repositories/dune-pdelab/commit/?id=17c90dd4b31ebba8db645a5fbc2a0390443dd6f1
> 
> ======================================================================
> 
> commit 17c90dd4b31ebba8db645a5fbc2a0390443dd6f1
> Author: Steffen Müthing <muething at dune-project.org>
> Date:   Mon Jul 8 18:27:00 2013 +0200
> 
>     [GridFunctionSpace/Ordering] Feed size information from Orderings to GridFunctionSpaces and introduce GFS base class
>     
>     Disclaimer: This patch has gotten a little big, but it touches too many intertwined
>     pieces to separate any further...
>     
>     One important feature of the way the Orderings are created from the GridFunctionSpaces
>     now is the fact that there should only be a single Ordering tree created from the
>     root of the GFS tree, reducing the number of template instantiations and thus reducing
>     compile times. Additionally, this scheme also reduces the number of grid traversals during
>     function space setup for composite spaces. Unfortunately, these advantage are lost as
>     soon as the size() method is called on one of the child spaces - that creates a separate
>     Ordering tree for that child space and immediately traverses the grid to calculate the
>     size information. The main problem here is the lack of feedback from the Ordering tree
>     to the GFS tree.
>     
>     In order to resolve this issue, this patch introduces a very simple, commen base class
>     for all GridFunctionSpaces that holds size information like the size of the space, the
>     block count, the global size etc. This information is then updated from the Ordering
>     tree whenever the Orderings are updated through the GridFunctionSpace interface.
>     
>     As this change required touching all the relevant methods on the GridFunctionSpaces, I
>     also went ahead and consolidated as many methods as possible into a new class called
>     GridFunctionSpaceBase, eliminating quite a bit of duplicate code in the process.
>     
>     WARNING: This patch is not backwards-compatible in all cases! It is not possible anymore
>     to call size() or similar global methods directly after constructing a space - doing so
>     will raise an exception! To avoid the problem call ordering() or update() before size()
>     et. al.
>     
>     Some smaller gems in this patch:
>     
>     - GridFunctionSpace lost a bunch of old variables still left from ancient times
>       (before there were Orderings).
>     
>     - GridFunctionSpaces now track whether they are at the root of the tree.
> 
>  dune/pdelab/common/exceptions.hh                   |  16 ++
>  dune/pdelab/gridfunctionspace/CMakeLists.txt       |   1 +
>  dune/pdelab/gridfunctionspace/Makefile.am          |   1 +
>  .../compositegridfunctionspace.hh                  |  20 +-
>  dune/pdelab/gridfunctionspace/gridfunctionspace.hh | 145 +++-------
>  .../gridfunctionspace/gridfunctionspacebase.hh     | 316 +++++++++++++++++++++
>  .../powercompositegridfunctionspacebase.hh         |  81 +-----
>  .../gridfunctionspace/powergridfunctionspace.hh    |  50 ++--
>  .../gridfunctionspace/vectorgridfunctionspace.hh   |  19 +-
>  dune/pdelab/ordering/directleaflocalordering.hh    |  23 ++
>  dune/pdelab/ordering/entityblockedlocalordering.hh |  12 +-
>  dune/pdelab/ordering/gridviewordering.hh           |   4 +-
>  dune/pdelab/ordering/interleavedordering.hh        |  22 +-
>  dune/pdelab/ordering/leafgridviewordering.hh       |   8 +-
>  dune/pdelab/ordering/leaflocalordering.hh          |   8 +-
>  dune/pdelab/ordering/lexicographicordering.hh      |  22 +-
>  dune/pdelab/ordering/localorderingbase.hh          |  23 +-
>  dune/pdelab/ordering/orderingbase.hh               |  24 ++
>  18 files changed, 554 insertions(+), 241 deletions(-)
>  create mode 100644 dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh
> 
> 
> 
> diff --git a/dune/pdelab/common/exceptions.hh b/dune/pdelab/common/exceptions.hh
> index 0497649..0817a20 100644
> --- a/dune/pdelab/common/exceptions.hh
> +++ b/dune/pdelab/common/exceptions.hh
> @@ -19,6 +19,22 @@ namespace Dune {
>      {};
>  
>  
> +    //! GridFunctionSpace-related error.
> +    class GridFunctionSpaceError
> +      : public Exception
> +    {};
> +
> +    //! Called a GridFunctionSpace method that requires initialization of the space.
> +    class UninitializedGridFunctionSpaceError
> +      : public GridFunctionSpaceError
> +    {};
> +
> +    //! Called a method on a GridFunctionSpace that is not valid
> +    //! at its current place in the function space tree.
> +    class GridFunctionSpaceHierarchyError
> +      : public GridFunctionSpaceError
> +    {};
> +
>      //! Ordering-related error.
>      class OrderingError
>        : public Exception
> diff --git a/dune/pdelab/gridfunctionspace/CMakeLists.txt b/dune/pdelab/gridfunctionspace/CMakeLists.txt
> index bb1ec42..6980b9b 100644
> --- a/dune/pdelab/gridfunctionspace/CMakeLists.txt
> +++ b/dune/pdelab/gridfunctionspace/CMakeLists.txt
> @@ -7,6 +7,7 @@ set(gridfunctionspace_HEADERS
>    dofinfo.hh
>    genericdatahandle.hh
>    gridfunctionspace.hh
> +  gridfunctionspacebase.hh
>    gridfunctionspaceutilities.hh
>    interpolate.hh
>    intersectionindexset.hh
> diff --git a/dune/pdelab/gridfunctionspace/Makefile.am b/dune/pdelab/gridfunctionspace/Makefile.am
> index 797f6e8..d174483 100644
> --- a/dune/pdelab/gridfunctionspace/Makefile.am
> +++ b/dune/pdelab/gridfunctionspace/Makefile.am
> @@ -6,6 +6,7 @@ gridfunctionspace_HEADERS =			\
>  	dofinfo.hh				\
>  	genericdatahandle.hh			\
>  	gridfunctionspace.hh			\
> +	gridfunctionspacebase.hh		\
>  	gridfunctionspaceutilities.hh		\
>  	interpolate.hh				\
>  	intersectionindexset.hh			\
> diff --git a/dune/pdelab/gridfunctionspace/compositegridfunctionspace.hh b/dune/pdelab/gridfunctionspace/compositegridfunctionspace.hh
> index c719f23..16678d2 100644
> --- a/dune/pdelab/gridfunctionspace/compositegridfunctionspace.hh
> +++ b/dune/pdelab/gridfunctionspace/compositegridfunctionspace.hh
> @@ -71,6 +71,9 @@ namespace Dune {
>                                        gfs_to_ordering<CompositeGridFunctionSpace>
>                                        > ordering_transformation;
>  
> +      template<typename,typename>
> +      friend class GridFunctionSpaceBase;
> +
>      public:
>        typedef CompositeGridFunctionSpaceTag ImplementationTag;
>  
> @@ -115,8 +118,8 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
> @@ -126,13 +129,22 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
>  
> +
>      private:
> +
> +      // This method here is to avoid a double update of the Ordering when the user calls
> +      // GFS::update() before GFS::ordering().
> +      void create_ordering() const
> +      {
> +        _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> +      }
> +
>        mutable shared_ptr<Ordering> _ordering;
>  
>      };
> diff --git a/dune/pdelab/gridfunctionspace/gridfunctionspace.hh b/dune/pdelab/gridfunctionspace/gridfunctionspace.hh
> index 50ce013..a26e055 100644
> --- a/dune/pdelab/gridfunctionspace/gridfunctionspace.hh
> +++ b/dune/pdelab/gridfunctionspace/gridfunctionspace.hh
> @@ -30,6 +30,7 @@
>  #include <dune/pdelab/gridfunctionspace/utility.hh>
>  #include <dune/pdelab/ordering/gridviewordering.hh>
>  #include <dune/pdelab/ordering/lexicographicordering.hh>
> +#include <dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh>
>  #include <dune/pdelab/gridfunctionspace/localfunctionspace.hh>
>  #include <dune/pdelab/gridfunctionspace/datahandleprovider.hh>
>  #include <dune/pdelab/gridfunctionspace/powergridfunctionspace.hh>
> @@ -110,15 +111,29 @@ namespace Dune {
>               typename B=ISTLVectorBackend<>, typename P=DefaultLeafOrderingTag>
>      class GridFunctionSpace
>        : public TypeTree::LeafNode
> +      , public GridFunctionSpaceBase<
> +                 GridFunctionSpace<GV,FEM,CE,B,P>,
> +                 GridFunctionSpaceTraits<GV,FEM,CE,B,P>
> +                 >
>        , public GridFunctionOutputParameters
>        , public DataHandleProvider<GridFunctionSpace<GV,FEM,CE,B,P> >
>      {
>  
>        typedef TypeTree::TransformTree<GridFunctionSpace,gfs_to_ordering<GridFunctionSpace> > ordering_transformation;
>  
> +      template<typename,typename>
> +      friend class GridFunctionSpaceBase;
> +
>      public:
>        //! export Traits class
>        typedef GridFunctionSpaceTraits<GV,FEM,CE,B,P> Traits;
> +
> +    private:
> +
> +      typedef GridFunctionSpaceBase<GridFunctionSpace,Traits> BaseT;
> +
> +    public:
> +
>        typedef typename GV::Traits::template Codim<0>::Entity Element;
>        typedef typename GV::Traits::template Codim<0>::Iterator ElementIterator;
>  
> @@ -151,43 +166,38 @@ namespace Dune {
>  
>        //! constructor
>        GridFunctionSpace (const GV& gridview, const FEM& fem, const CE& ce_, const B& backend = B(), const OrderingTag& ordering_tag = OrderingTag())
> -        : defaultce(ce_)
> +        : BaseT(backend,ordering_tag)
> +        , defaultce(ce_)
>          , gv(gridview)
>          , pfem(stackobject_to_shared_ptr(fem))
>          , ce(ce_)
> -        , _backend(backend)
> -        , _ordering_tag(ordering_tag)
>        {
>        }
>  
>        //! constructor
>        GridFunctionSpace (const GV& gridview, const shared_ptr<const FEM>& fem, const CE& ce_, const B& backend = B(), const OrderingTag& ordering_tag = OrderingTag())
> -        : defaultce(ce_)
> +        : BaseT(backend,ordering_tag)
> +        , defaultce(ce_)
>          , gv(gridview)
>          , pfem(fem)
>          , ce(ce_)
> -        , _backend(backend)
> -        , _ordering_tag(ordering_tag)
> -      {
> -      }
> +      {}
>  
>        //! constructor
>        GridFunctionSpace (const GV& gridview, const FEM& fem, const B& backend = B(), const OrderingTag& ordering_tag = OrderingTag())
> -        : gv(gridview)
> +        : BaseT(backend,ordering_tag)
> +        , gv(gridview)
>          , pfem(stackobject_to_shared_ptr(fem))
>          , ce(defaultce)
> -        , _backend(backend)
> -        , _ordering_tag(ordering_tag)
> -      {
> -      }
> +      {}
>  
>        //! constructor
>        GridFunctionSpace (const GV& gridview, const shared_ptr<const FEM>& fem, const B& backend = B(), const OrderingTag& ordering_tag = OrderingTag())
> -        : gv(gridview)
> +        : BaseT(backend,ordering_tag)
> +        , gv(gridview)
>          , pfem(fem)
>          , ce(defaultce)
> -        , _backend(backend)
> -        , _ordering_tag(ordering_tag)
> +      {}
>        {
>        }
>  
> @@ -221,6 +231,14 @@ namespace Dune {
>          return *pfem;
>        }
>  
> +      // return constraints engine
> +      const typename Traits::ConstraintsType& constraints () const
> +      {
> +        return ce;
> +      }
> +
> +      //------------------------------
> +
>        //! Direct access to the DOF ordering.
>        const Ordering &ordering() const
>        {
> @@ -238,8 +256,8 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
> @@ -249,102 +267,25 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
>  
> -      //! get dimension of root finite element space
> -      typename Traits::SizeType globalSize () const
> -      {
> -        return ordering().size();
> -      }
> -
> -      //! get dimension of this finite element space
> -      typename Traits::SizeType size () const
> -      {
> -        return ordering().size();
> -      }
> -
> -      //! get max dimension of shape function space
> -      //! \todo What are the exact semantics of maxLocalSize?
> -      typename Traits::SizeType maxLocalSize () const
> -      {
> -        return ordering().maxLocalSize();
> -      }
> -
> -      //! Returns whether this GridFunctionSpace contains entities with PartitionType partition.
> -      bool containsPartition(PartitionType partition) const
> -      {
> -        return ordering().containsPartition(partition);
> -      }
> -
> -      //! map index from our index set [0,size()-1] to root index set
> -      typename Traits::SizeType upMap (typename Traits::SizeType i) const
> -      {
> -        return i;
> -      }
> -
> -      // return constraints engine
> -      const typename Traits::ConstraintsType& constraints () const
> -      {
> -        return ce;
> -      }
> -
> -      //------------------------------
> -
> -      B& backend()
> -      {
> -        return _backend;
> -      }
> -
> -      const B& backend() const
> -      {
> -        return _backend;
> -      }
> -
> -      OrderingTag& orderingTag()
> -      {
> -        return _ordering_tag;
> -      }
> -
> -      const OrderingTag& orderingTag() const
> -      {
> -        return _ordering_tag;
> -      }
> -
> -      const std::string& name() const
> -      {
> -        return _name;
> -      }
> -
> -      void name(const std::string& name)
> -      {
> -        _name = name;
> -      }
> +    private:
>  
> -      void update()
> +      // This method here is to avoid a double update of the Ordering when the user calls
> +      // GFS::update() before GFS::ordering().
> +      void create_ordering() const
>        {
> -        ordering().update();
> +        _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
>        }
>  
> -    private:
>        CE defaultce;
>        const GV gv;
>        shared_ptr<FEM const> pfem;
> -      typename Traits::SizeType nlocal;
> -      typename Traits::SizeType nglobal;
>        const CE& ce;
> -      B _backend;
> -      OrderingTag _ordering_tag;
> -      bool fixed_size;
> -      std::string _name;
> -
> -      typedef std::map<Dune::GeometryType,typename Traits::SizeType> GTOffsetMap;
> -      GTOffsetMap gtoffset; // offset in vector for given geometry type
> -      std::vector<typename Traits::SizeType> offset; // offset into big vector for each entity;
> -      std::set<unsigned int> codimUsed;
>  
>        mutable shared_ptr<Ordering> _ordering;
>      };
> diff --git a/dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh b/dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh
> new file mode 100644
> index 0000000..0a7852c
> --- /dev/null
> +++ b/dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh
> @@ -0,0 +1,316 @@
> +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
> +// vi: set et ts=4 sw=2 sts=2:
> +#ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
> +#define DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
> +
> +#include <dune/pdelab/common/exceptions.hh>
> +#include <dune/pdelab/common/partitioninfoprovider.hh>
> +#include <dune/pdelab/common/typetree/visitor.hh>
> +#include <dune/pdelab/common/typetree/traversal.hh>
> +
> +namespace Dune {
> +  namespace PDELab {
> +
> +    //! \addtogroup GridFunctionSpace grid function space
> +    //! \ingroup PDELab
> +    //! \{
> +
> +#ifndef DOXYGEN
> +
> +    // forward declaration for friend declaration
> +    template<typename GFS, typename GFSTraits>
> +    class GridFunctionSpaceBase;
> +
> +    namespace impl {
> +
> +      struct reset_root_space_flag
> +        : public TypeTree::DirectChildrenVisitor
> +        , public TypeTree::DynamicTraversal
> +      {
> +
> +        template<typename GFS, typename Child, typename TreePath, typename ChildIndex>
> +        void afterChild(const GFS& gfs, Child& child, TreePath, ChildIndex) const
> +        {
> +          if (child._initialized && child._is_root_space)
> +            {
> +              DUNE_THROW(GridFunctionSpaceHierarchyError,"initialized space cannot become part of larger GridFunctionSpace tree");
> +            }
> +          child._is_root_space = false;
> +        }
> +
> +      };
> +
> +      template<typename size_type>
> +      struct update_ordering_data;
> +
> +      // helper class with minimal dependencies. Orderings keep a pointer to this structure and populate it
> +      // during their update procedure.
> +
> +      template<typename size_type>
> +      class GridFunctionSpaceOrderingData
> +        : public PartitionInfoProvider
> +      {
> +
> +        template<typename,typename>
> +        friend class ::Dune::PDELab::GridFunctionSpaceBase;
> +
> +        template<typename>
> +        friend struct update_ordering_data;
> +
> +        GridFunctionSpaceOrderingData()
> +          : _size(0)
> +          , _block_count(0)
> +          , _global_size(0)
> +          , _max_local_size(0)
> +          , _is_root_space(true)
> +          , _initialized(false)
> +          , _size_available(true)
> +        {}
> +
> +        size_type _size;
> +        size_type _block_count;
> +        size_type _global_size;
> +        size_type _max_local_size;
> +        bool _is_root_space;
> +        bool _initialized;
> +        bool _size_available;
> +
> +      };
> +
> +      template<typename size_type>
> +      struct update_ordering_data
> +        : public TypeTree::TreeVisitor
> +        , public TypeTree::DynamicTraversal
> +      {
> +
> +        typedef GridFunctionSpaceOrderingData<size_type> Data;
> +
> +        template<typename Ordering>
> +        void update(const Ordering& ordering, bool is_root)
> +        {
> +          if (ordering._gfs_data)
> +            {
> +              Data& data = *ordering._gfs_data;
> +              // if (data._initialized && data._is_root_space && !is_root)
> +              //   {
> +              //     DUNE_THROW(GridFunctionSpaceHierarchyError,"former root space is now part of a larger tree");
> +              //   }
> +              data._initialized = true;
> +              data._global_size = _global_size;
> +              data._max_local_size = _max_local_size;
> +              data._size_available = ordering.update_gfs_data_size(data._size,data._block_count);
> +            }
> +        }
> +
> +        template<typename Ordering, typename TreePath>
> +        void leaf(const Ordering& ordering, TreePath tp)
> +        {
> +          update(ordering,tp.size() == 0);
> +        }
> +
> +        template<typename Ordering, typename TreePath>
> +        void post(const Ordering& ordering, TreePath tp)
> +        {
> +          update(ordering,tp.size() == 0);
> +        }
> +
> +        template<typename Ordering>
> +        explicit update_ordering_data(const Ordering& ordering)
> +          : _global_size(ordering.size())
> +          , _max_local_size(ordering.maxLocalSize())
> +        {}
> +
> +        const size_type _global_size;
> +        const size_type _max_local_size;
> +
> +      };
> +
> +
> +    } // namespace impl
> +
> +#endif // DOXYGEN
> +
> +
> +    template<typename GFS, typename GFSTraits>
> +    class GridFunctionSpaceBase
> +      : public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
> +    {
> +
> +      friend struct impl::reset_root_space_flag;
> +
> +    public:
> +
> +      typedef GFSTraits Traits;
> +
> +#if HAVE_RVALUE_REFERENCES
> +
> +      template<typename Backend_, typename OrderingTag_>
> +      GridFunctionSpaceBase(Backend_&& backend, OrderingTag_&& ordering_tag)
> +        : _backend(std::forward<Backend_>(backend))
> +        , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
> +      {
> +        TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
> +      }
> +
> +#else
> +
> +      GridFunctionSpaceBase(const B& backend, const OrderingTag& ordering_tag)
> +        : _backend(backend)
> +        , _ordering_tag(ordering_tag)
> +        , _size(0)
> +        , _global_size(0)
> +        , _is_root_space(true)
> +        , _initialized(false)
> +      {
> +        TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
> +      }
> +
> +#endif
> +
> +      typename Traits::SizeType size() const
> +      {
> +        if (!_initialized)
> +          {
> +            DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
> +          }
> +        if (!_size_available)
> +          {
> +            DUNE_THROW(GridFunctionSpaceHierarchyError,
> +                       "Size cannot be calculated at this point in the GFS tree.");
> +          }
> +        return _size;
> +      }
> +
> +      typename Traits::SizeType blockCount() const
> +      {
> +        if (!_initialized)
> +          {
> +            DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
> +          }
> +        if (!_size_available)
> +          {
> +            DUNE_THROW(GridFunctionSpaceHierarchyError,
> +                       "Block count cannot be calculated at this point in the GFS tree.");
> +          }
> +        return _block_count;
> +      }
> +
> +      typename Traits::SizeType globalSize() const
> +      {
> +        if (!_initialized)
> +          {
> +            DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
> +          }
> +        return _global_size;
> +      }
> +
> +      //! get max dimension of shape function space
> +      typename Traits::SizeType maxLocalSize () const
> +      {
> +        if (!_initialized)
> +          {
> +            DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
> +          }
> +        return _max_local_size;
> +      }
> +
> +      //! Returns whether this GridFunctionSpace contains entities with PartitionType partition.
> +      bool containsPartition(PartitionType partition) const
> +      {
> +        if (!_initialized)
> +          {
> +            DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
> +          }
> +        return PartitionInfoProvider::containsPartition(partition);
> +      }
> +
> +      void update()
> +      {
> +        // We bypass the normal access using ordering() here to avoid a double
> +        // update if the Ordering has not been created yet.
> +        if (!gfs()._ordering)
> +          gfs().create_ordering();
> +        update(*gfs()._ordering);
> +      }
> +
> +      const std::string& name() const
> +      {
> +        return _name;
> +      }
> +
> +      void name(const std::string& name)
> +      {
> +        _name = name;
> +      }
> +
> +      typename Traits::Backend& backend()
> +      {
> +        return _backend;
> +      }
> +
> +      const typename Traits::Backend& backend() const
> +      {
> +        return _backend;
> +      }
> +
> +      typename Traits::OrderingTag& orderingTag()
> +      {
> +        return _ordering_tag;
> +      }
> +
> +      const typename Traits::OrderingTag& orderingTag() const
> +      {
> +        return _ordering_tag;
> +      }
> +
> +      bool isRootSpace() const
> +      {
> +        return _is_root_space;
> +      }
> +
> +    protected:
> +
> +      template<typename Ordering>
> +      void update(Ordering& ordering) const
> +      {
> +        if (!_is_root_space)
> +          {
> +            DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
> +          }
> +        ordering.update();
> +        TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
> +      }
> +
> +    private:
> +
> +      typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
> +
> +      GFS& gfs()
> +      {
> +        return static_cast<GFS&>(*this);
> +      }
> +
> +      const GFS& gfs() const
> +      {
> +        return static_cast<const GFS&>(*this);
> +      }
> +
> +      std::string _name;
> +      typename Traits::Backend _backend;
> +      typename Traits::OrderingTag _ordering_tag;
> +
> +      using BaseT::_size;
> +      using BaseT::_block_count;
> +      using BaseT::_global_size;
> +      using BaseT::_max_local_size;
> +      using BaseT::_is_root_space;
> +      using BaseT::_initialized;
> +      using BaseT::_size_available;
> +
> +    };
> +
> +
> +  } // namespace PDELab
> +} // namespace Dune
> +
> +#endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
> diff --git a/dune/pdelab/gridfunctionspace/powercompositegridfunctionspacebase.hh b/dune/pdelab/gridfunctionspace/powercompositegridfunctionspacebase.hh
> index 1a9db3b..d39c64e 100644
> --- a/dune/pdelab/gridfunctionspace/powercompositegridfunctionspacebase.hh
> +++ b/dune/pdelab/gridfunctionspace/powercompositegridfunctionspacebase.hh
> @@ -16,6 +16,7 @@
>  #include <dune/pdelab/constraints/constraintstransformation.hh>
>  
>  #include <dune/pdelab/gridfunctionspace/tags.hh>
> +#include <dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh>
>  #include <dune/pdelab/gridfunctionspace/utility.hh>
>  #include <dune/pdelab/ordering/lexicographicordering.hh>
>  #include <dune/pdelab/ordering/entityblockedlocalordering.hh>
> @@ -62,6 +63,10 @@ namespace Dune {
>      //! Mixin class providing common functionality of PowerGridFunctionSpace and CompositeGridFunctionSpace
>      template<typename GridFunctionSpace, typename GV, typename B, typename O, std::size_t k>
>      class PowerCompositeGridFunctionSpaceBase
> +      : public GridFunctionSpaceBase<
> +                 GridFunctionSpace,
> +                 PowerCompositeGridFunctionSpaceTraits<GV,B,O,k>
> +                 >
>      {
>  
>  #ifndef DOXYGEN
> @@ -83,6 +88,12 @@ namespace Dune {
>        //! export traits class
>        typedef PowerCompositeGridFunctionSpaceTraits<GV,B,O,k> Traits;
>  
> +    private:
> +
> +      typedef GridFunctionSpaceBase<GridFunctionSpace,Traits> BaseT;
> +
> +    public:
> +
>        typedef O OrderingTag;
>  
>        // TODO: Do not just use constraints from child 0!
> @@ -104,37 +115,6 @@ namespace Dune {
>            >::Type Type;
>        };
>  
> -      //! recalculate sizes
> -      void update ()
> -      {
> -        gfs().ordering().update();
> -      }
> -
> -      //! get dimension of root finite element space
> -      typename Traits::SizeType globalSize () const
> -      {
> -        return gfs().ordering().size();
> -      }
> -
> -      //! get dimension of this finite element space
> -      typename Traits::SizeType size () const
> -      {
> -        return gfs().ordering().size();
> -      }
> -
> -      //! get max dimension of shape function space
> -      typename Traits::SizeType maxLocalSize () const
> -      {
> -        // this is bullshit !
> -        return gfs().ordering().maxLocalSize();
> -      }
> -
> -      //! Returns whether this GridFunctionSpace contains entities with PartitionType partition.
> -      bool containsPartition(PartitionType partition) const
> -      {
> -        return gfs().ordering().containsPartition(partition);
> -      }
> -
>        //! get grid view
>        const typename Traits::GridViewType& gridview () const DUNE_DEPRECATED_MSG("Use gridView() instead of gridview()")
>        {
> @@ -147,47 +127,10 @@ namespace Dune {
>          return gfs().template child<0>().gridView();
>        }
>  
> -      B& backend()
> -      {
> -        return _backend;
> -      }
> -
> -      const B& backend() const
> -      {
> -        return _backend;
> -      }
> -
> -      OrderingTag& orderingTag()
> -      {
> -        return _ordering_tag;
> -      }
> -
> -      const OrderingTag& orderingTag() const
> -      {
> -        return _ordering_tag;
> -      }
> -
>        PowerCompositeGridFunctionSpaceBase(const B& backend, const OrderingTag& ordering_tag)
> -        : _backend(backend)
> -        , _ordering_tag(ordering_tag)
> +        : BaseT(backend,ordering_tag)
>        {}
>  
> -      const std::string& name() const
> -      {
> -        return _name;
> -      }
> -
> -      void name(const std::string& name)
> -      {
> -        _name = name;
> -      }
> -
> -    private:
> -
> -      B _backend;
> -      OrderingTag _ordering_tag;
> -      std::string _name;
> -
>      };
>  
>    }
> diff --git a/dune/pdelab/gridfunctionspace/powergridfunctionspace.hh b/dune/pdelab/gridfunctionspace/powergridfunctionspace.hh
> index d410bca..284a2ad 100644
> --- a/dune/pdelab/gridfunctionspace/powergridfunctionspace.hh
> +++ b/dune/pdelab/gridfunctionspace/powergridfunctionspace.hh
> @@ -54,6 +54,8 @@ namespace Dune {
>  
>        typedef TypeTree::PowerNode<T,k> BaseT;
>  
> +    private:
> +
>        typedef PowerCompositeGridFunctionSpaceBase<
>          PowerGridFunctionSpace,
>          typename T::Traits::GridViewType,
> @@ -69,6 +71,9 @@ namespace Dune {
>          OrderingTag,
>          k>;
>  
> +      template<typename,typename>
> +      friend class GridFunctionSpaceBase;
> +
>        typedef TypeTree::TransformTree<PowerGridFunctionSpace,
>                                        gfs_to_ordering<PowerGridFunctionSpace>
>                                        > ordering_transformation;
> @@ -80,11 +85,11 @@ namespace Dune {
>        //! export traits class
>        typedef typename ImplementationBase::Traits Traits;
>  
> +
>        PowerGridFunctionSpace(T& c, const Backend& backend = Backend(), const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -92,8 +97,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -102,8 +106,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -113,8 +116,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -125,8 +127,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -138,8 +139,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4,c5)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -152,8 +152,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4,c5,c6)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -167,8 +166,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4,c5,c6,c7)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -183,8 +181,7 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4,c5,c6,c7,c8)
>          , ImplementationBase(backend,ordering_tag)
> -      {
> -      }
> +      {}
>  
>        PowerGridFunctionSpace (T& c0,
>                                T& c1,
> @@ -200,6 +197,8 @@ namespace Dune {
>                                const OrderingTag ordering_tag = OrderingTag())
>          : BaseT(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9)
>          , ImplementationBase(backend,ordering_tag)
> +      {}
> +
>        {
>        }
>  
> @@ -220,8 +219,8 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
> @@ -231,14 +230,21 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> -            _ordering->update();
> +            create_ordering();
> +            this->update(*_ordering);
>            }
>          return _ordering;
>        }
>  
>      private:
>  
> +      // This method here is to avoid a double update of the Ordering when the user calls
> +      // GFS::update() before GFS::ordering().
> +      void create_ordering() const
> +      {
> +        _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> +      }
> +
>        mutable shared_ptr<Ordering> _ordering;
>  
>      };
> diff --git a/dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh b/dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh
> index f51ba95..2c11523 100644
> --- a/dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh
> +++ b/dune/pdelab/gridfunctionspace/vectorgridfunctionspace.hh
> @@ -77,6 +77,9 @@ namespace Dune {
>          LeafOrderingTag
>          > LeafGFS;
>  
> +      template<typename,typename>
> +      friend class GridFunctionSpaceBase;
> +
>      public:
>  
>        typedef VectorGridFunctionSpaceTag ImplementationTag;
> @@ -129,11 +132,6 @@ namespace Dune {
>            }
>        }
>  
> -      std::string name() const
> -      {
> -        return ImplementationBase::name();
> -      }
> -
>        //! Direct access to the DOF ordering.
>        const Ordering &ordering() const
>        {
> @@ -151,7 +149,7 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> +            create_ordering();
>              _ordering->update();
>            }
>          return _ordering;
> @@ -162,7 +160,7 @@ namespace Dune {
>        {
>          if (!_ordering)
>            {
> -            _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> +            create_ordering();
>              _ordering->update();
>            }
>          return _ordering;
> @@ -170,6 +168,13 @@ namespace Dune {
>  
>      private:
>  
> +      // This method here is to avoid a double update of the Ordering when the user calls
> +      // GFS::update() before GFS::ordering().
> +      void create_ordering() const
> +      {
> +        _ordering = make_shared<Ordering>(ordering_transformation::transform(*this));
> +      }
> +
>        mutable shared_ptr<Ordering> _ordering;
>  
>      };
> diff --git a/dune/pdelab/ordering/directleaflocalordering.hh b/dune/pdelab/ordering/directleaflocalordering.hh
> 
>    .... 529 lines (22.2 KiB) of output suppressed ....
> 
> _______________________________________________
> dune-pdelab-commit mailing list
> dune-pdelab-commit at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-pdelab-commit

-- 
Prof. Dr. Christian Engwer 
Institut für Numerische und Angewandte Mathematik
Fachbereich Mathematik und Informatik der Universität Münster
Einsteinstrasse 62
48149 Münster

E-Mail	christian.engwer at uni-muenster.de
Telefon	+49 251 83-35067
FAX		+49 251 83-32729




More information about the dune-pdelab mailing list