Skip to content
Snippets Groups Projects
periodic1dpq1nodalbasis.hh 6.09 KiB
Newer Older
  • Learn to ignore specific revisions
  • // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    // vi: set et ts=4 sw=2 sts=2:
    #ifndef DUNE_GFE_PERIODIC_1D_PQ1NODALBASIS_HH
    #define DUNE_GFE_PERIODIC_1D_PQ1NODALBASIS_HH
    
    #include <dune/common/exceptions.hh>
    
    #include <dune/common/math.hh>
    
    
    #include <dune/localfunctions/lagrange/pqkfactory.hh>
    
    #include <dune/functions/functionspacebases/nodes.hh>
    #include <dune/functions/functionspacebases/flatmultiindex.hh>
    
    #include <dune/functions/functionspacebases/defaultglobalbasis.hh>
    
    
    
    namespace Dune {
    namespace Functions {
    
    // *****************************************************************************
    // This is the reusable part of the basis. It contains
    //
    
    // The pre-basis allows to create the others and is the owner of possible shared
    
    // state. These three components do _not_ depend on the global basis or index
    // set and can be used without a global basis.
    // *****************************************************************************
    
    
    template<typename GV, class MI>
    class Periodic1DPQ1PreBasis
    
      //! The grid view that the FE basis is defined on
    
      //! Type used for indices and size information
      using size_type = std::size_t;
    
      using Node = Periodic1DPQ1Node<GV>;
    
      using IndexSet = Periodic1DPQ1NodeIndexSet<GV, MI>;
    
    
      /** \brief Type used for global numbering of the basis vectors */
      using MultiIndex = MI;
    
    
      //! Type used for prefixes handed to the size() method
      using SizePrefix = Dune::ReservedVector<size_type, 1>;
    
      //! Constructor for a given grid view object
      Periodic1DPQ1PreBasis(const GridView& gv) :
    
        gridView_(gv)
      {}
    
      void initializeIndices()
      {}
    
      /** \brief Obtain the grid view that the basis is defined on
       */
      const GridView& gridView() const
      {
        return gridView_;
      }
    
    
      //! Update the stored grid view, to be called if the grid has changed
      void update (const GridView& gv)
      {
        gridView_ = gv;
      }
    
      Node makeNode() const
    
      }
    
      size_type size() const
      {
        return gridView_.size(dim)-1;
      }
    
      //! Return number possible values for next position in multi index
      size_type size(const SizePrefix prefix) const
      {
        if (prefix.size() == 0)
          return size();
        if (prefix.size() == 1)
          return 0;
        DUNE_THROW(RangeError, "Method size() can only be called for prefixes of length up to one");
      }
    
    
      //! Get the total dimension of the space spanned by this basis
    
      size_type dimension() const
      {
        return size()-1;
      }
    
      size_type maxNodeSize() const
      {
    
        return Dune::power(2,GV::dimension);
    
      static const int maxSize = Dune::power(2,GV::dimension);
    
    
      using FiniteElementCache = typename Dune::PQkLocalFiniteElementCache<typename GV::ctype, double, dim, 1>;
    
    public:
    
    
      using Element = typename GV::template Codim<0>::Entity;
      using FiniteElement = typename FiniteElementCache::FiniteElementType;
    
    
        finiteElement_(nullptr),
        element_(nullptr)
      {}
    
      //! Return current element, throw if unbound
      const Element& element() const
      {
        return *element_;
      }
    
      /** \brief Return the LocalFiniteElement for the element we are bound to
       *
       * The LocalFiniteElement implements the corresponding interfaces of the dune-localfunctions module
       */
      const FiniteElement& finiteElement() const
      {
        return *finiteElement_;
      }
    
      //! Bind to element.
      void bind(const Element& e)
      {
        element_ = &e;
        finiteElement_ = &(cache_.get(element_->type()));
        this->setSize(finiteElement_->size());
      }
    
    protected:
    
      FiniteElementCache cache_;
      const FiniteElement* finiteElement_;
      const Element* element_;
    };
    
    
    
    
      constexpr static int dim = GV::dimension;
    
    
      /** \brief Type used for global numbering of the basis vectors */
      using MultiIndex = MI;
    
      using PreBasis = Periodic1DPQ1PreBasis<GV, MI>;
      using Node = Periodic1DPQ1Node<GV>;
    
      Periodic1DPQ1NodeIndexSet(const PreBasis& preBasis) :
        preBasis_(&preBasis),
        node_(nullptr)
    
      {}
    
      /** \brief Bind the view to a grid element
       *
       * Having to bind the view to an element before being able to actually access any of its data members
       * offers to centralize some expensive setup code in the 'bind' method, which can save a lot of run-time.
       */
      void bind(const Node& node)
      {
        node_ = &node;
      }
    
      /** \brief Unbind the view
       */
      void unbind()
      {
        node_ = nullptr;
      }
    
      /** \brief Size of subtree rooted in this node (element-local)
       */
      size_type size() const
      {
    
        return node_->finiteElement().size();
      }
    
      //! Maps from subtree index set [0..size-1] to a globally unique multi index in global basis
      MultiIndex index(size_type i) const
      {
        Dune::LocalKey localKey = node_->finiteElement().localCoefficients().localKey(i);
    
        const auto& gridIndexSet = preBasis_->gridView().indexSet();
    
        const auto& element = node_->element();
    
        //return {{ gridIndexSet.subIndex(element,localKey.subEntity(),dim) }};
    
        MultiIndex idx{{gridIndexSet.subIndex(element,localKey.subEntity(),dim) }};
    
        // make periodic
        if (idx == gridIndexSet.size(dim)-1)
          idx = {{0}};
    
        return idx;
      }
    
    protected:
    
    
      const Node* node_;
    };
    
    /** \brief Nodal basis of a scalar first-order Lagrangian finite element space
    
     *   on a one-dimensional domain with periodic boundary conditions
    
     *
     * \tparam GV The GridView that the space is defined on
     */
    
    template<typename GV>
    using Periodic1DPQ1NodalBasis = DefaultGlobalBasis<Periodic1DPQ1PreBasis<GV, FlatMultiIndex<std::size_t> > >;
    
    
    } // end namespace Functions
    } // end namespace Dune
    
    #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PQ1NODALBASIS_HH