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

Steffen Müthing steffen.muething at iwr.uni-heidelberg.de
Sun Aug 18 22:34:50 CEST 2013


Sorry, it's late, I of course meant all *PDELab* users…

Steffen


Am 18.08.2013 um 22:33 schrieb Steffen Müthing:

> Hi Christian (and all DUNE users, this could be important for everyone),
> 
> Am 18.08.2013 um 21:37 schrieb Christian Engwer:
> 
>> 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?
> 
> yes, I'm afraid it really is rather invasive, but it shouldn't be very noticeable for most users
> because PDELab makes sure to correctly initialize any GridFunctionSpace it can get a hold
> of. The following actions correctly initialize a GFS (there may be more, but I don't know from the
> top of my head):
> 
> - instantiating a vector for it
> - calculating constraints for it
> - Creating a GridOperator with it
> 
> After one of those operations has happened at least once, everything should work as before. If
> you call one of the following methods *before* doing any of the things listed above, you have to
> make sure the Ordering inside the GFS gets initialized by calling either gfs.ordering() or gfs.update():
> 
> size() - Returns the number of DOFs in the space
> blockCount() - Returns the number of blocks a vector for this space would have
> globalSize() - Returns the number of DOFs in the root space (this method didn't work at all previously)
> maxLocalSize() - Returns the maximum size of a LocalFunctionSpace for the complete tree
> containsPartition() - Returns whether the space spans the given Grid partition (important for parallel case)
> 
> If you forget to set up the GFS, you get a runtime exception.
> 
> The methods ordering() and update() may *only* be called on the root space (they create an ordering object,
> and that should only exist for the root space). If you call the methods on a space in the middle of a hierarchy,
> you again get an exception at runtime, so that's another thing to look out for in existing code. On the other
> hand, the old code had some weird corner cases if you did that, but it didn't warn you about those issues at all…
> 
> The other major upside of the patch is that you can now call all the query methods listed above on all spaces in
> the tree and get the correct information without triggering a recalculation at each queried level (which might even
> have require a grid traversal each with the old code).
> 
> I hope this clarifies the impact of the change a little.
> 
> Steffen
> 
>> 
>> 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
>> 
>> _______________________________________________
>> dune-pdelab mailing list
>> dune-pdelab at dune-project.org
>> http://lists.dune-project.org/mailman/listinfo/dune-pdelab
> 
> _______________________________________________
> dune-pdelab mailing list
> dune-pdelab at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-pdelab

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.dune-project.org/pipermail/dune-pdelab/attachments/20130818/6193bd9e/attachment.sig>


More information about the dune-pdelab mailing list