Loading...
Searching...
No Matches
brezzidouglasmarinibasis.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
#include <array>
#include <dune/common/exceptions.hh>
#include <dune/geometry/referenceelements.hh>
#include <dune/localfunctions/common/virtualinterface.hh>
#include <dune/localfunctions/common/virtualwrappers.hh>
#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube2d.hh>
#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube3d.hh>
#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1simplex2d.hh>
#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2cube2d.hh>
#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2simplex2d.hh>
#include <dune/functions/functionspacebases/globalvaluedlocalfiniteelement.hh>
#include <dune/functions/functionspacebases/nodes.hh>
#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
#include <dune/functions/functionspacebases/leafprebasismappermixin.hh>
namespace Dune {
namespace Functions {
namespace Impl {
template<int dim, typename D, typename R, std::size_t k>
struct BDMSimplexLocalInfo
{
static_assert((AlwaysFalse<D>::value),"The requested type of BDM element is not implemented, sorry!");
};
template<typename D, typename R>
struct BDMSimplexLocalInfo<2,D,R,1>
{
using FiniteElement = BDM1Simplex2DLocalFiniteElement<D,R>;
static const std::size_t Variants = 8;
};
template<typename D, typename R>
struct BDMSimplexLocalInfo<2,D,R,2>
{
using FiniteElement = BDM2Simplex2DLocalFiniteElement<D,R>;
static const std::size_t Variants = 8;
};
template<int dim, typename D, typename R, std::size_t k>
struct BDMCubeLocalInfo
{
static_assert((AlwaysFalse<D>::value),"The requested type of BDM element is not implemented, sorry!");
};
template<typename D, typename R>
struct BDMCubeLocalInfo<2,D,R,1>
{
using FiniteElement = BDM1Cube2DLocalFiniteElement<D,R>;
static const std::size_t Variants = 16;
};
template<typename D, typename R>
struct BDMCubeLocalInfo<2,D,R,2>
{
using FiniteElement = BDM2Cube2DLocalFiniteElement<D,R>;
static const std::size_t Variants = 16;
};
template<typename D, typename R>
struct BDMCubeLocalInfo<3,D,R,1>
{
using FiniteElement = BDM1Cube3DLocalFiniteElement<D,R>;
static const std::size_t Variants = 64;
};
template<typename GV, typename R, std::size_t k>
class BDMLocalFiniteElementMap
{
using D = typename GV::ctype;
constexpr static auto dim = GV::dimension;
using CubeFiniteElement = typename BDMCubeLocalInfo<dim, D, R, k>::FiniteElement;
using SimplexFiniteElement = typename BDMSimplexLocalInfo<dim, D, R, k>::FiniteElement;
public:
using T = LocalBasisTraits<D, dim, FieldVector<D,dim>, R, dim, FieldVector<R,dim>, FieldMatrix<D,dim,dim> >;
using FiniteElement = LocalFiniteElementVirtualInterface<T>;
BDMLocalFiniteElementMap(const GV& gv)
: is_(&(gv.indexSet())), orient_(gv.size(0))
{
update(gv);
}
void update(const GV& gv)
{
is_ = &(gv.indexSet());
orient_.resize(gv.size(0));
cubeVariant_.resize(BDMCubeLocalInfo<dim, D, R, k>::Variants);
simplexVariant_.resize(BDMSimplexLocalInfo<dim, D, R, k>::Variants);
// create all variants
for (size_t i = 0; i < cubeVariant_.size(); i++)
cubeVariant_[i] = std::make_shared<LocalFiniteElementVirtualImp<CubeFiniteElement> >(CubeFiniteElement(i));
for (size_t i = 0; i < simplexVariant_.size(); i++)
simplexVariant_[i] = std::make_shared<LocalFiniteElementVirtualImp<SimplexFiniteElement> >(SimplexFiniteElement(i));
// compute orientation for all elements
// loop once over the grid
for(const auto& cell : elements(gv))
{
unsigned int myId = is_->index(cell);
orient_[myId] = 0;
for (const auto& intersection : intersections(gv,cell))
{
if (intersection.neighbor() && (is_->index(intersection.outside()) > myId))
orient_[myId] |= (1 << intersection.indexInInside());
}
}
}
template<class EntityType>
const FiniteElement& find(const EntityType& e) const
{
if (e.type().isCube())
return *cubeVariant_[orient_[is_->index(e)]];
else
return *simplexVariant_[orient_[is_->index(e)]];
}
private:
std::vector<std::shared_ptr<LocalFiniteElementVirtualImp<CubeFiniteElement> > > cubeVariant_;
std::vector<std::shared_ptr<LocalFiniteElementVirtualImp<SimplexFiniteElement> > > simplexVariant_;
const typename GV::IndexSet* is_;
std::vector<unsigned char> orient_;
};
} // namespace Impl
// *****************************************************************************
// This is the reusable part of the basis. It contains
//
// BrezziDouglasMariniPreBasis
// BrezziDouglasMariniNode
//
// The pre-basis allows to create the others and is the owner of possible shared
// state. These components do _not_ depend on the global basis and local view
// and can be used without a global basis.
// *****************************************************************************
template<typename GV, int k>
class BrezziDouglasMariniNode;
template<typename GV, int k>
class BrezziDouglasMariniPreBasis :
public LeafPreBasisMapperMixin<GV>
{
using Base = LeafPreBasisMapperMixin<GV>;
static const int dim = GV::dimension;
// Degrees of freedom per subentity
static MCMGLayout dofLayout()
{
return [](GeometryType gt, size_t gridDim) -> size_t {
if (gt.dim() == gridDim)
return dim*(k-1)*3;
if (gt.dim() == gridDim-1)
return dim+(k-1);
return 0;
};
}
using FiniteElementMap = typename Impl::BDMLocalFiniteElementMap<GV, double, k>;
public:
using GridView = GV;
using size_type = std::size_t;
using Node = BrezziDouglasMariniNode<GV, k>;
BrezziDouglasMariniPreBasis(const GridView& gv) :
Base(gv, dofLayout()),
finiteElementMap_(gv)
{
// There is no inherent reason why the basis shouldn't work for grids with more than one
// element types. Somebody simply has to sit down and implement the missing bits.
if (gv.indexSet().types(0).size() > 1)
DUNE_THROW(Dune::NotImplemented, "Brezzi-Douglas-Marini basis is only implemented for grids with a single element type");
}
/* \brief Update the stored grid view, to be called if the grid has changed */
void update (const GridView& gv)
{
Base::update(gv);
finiteElementMap_.update(gv);
}
Node makeNode() const
{
return Node{&finiteElementMap_};
}
protected:
FiniteElementMap finiteElementMap_;
};
template<typename GV, int k>
class BrezziDouglasMariniNode :
public LeafBasisNode
{
public:
using size_type = std::size_t;
using Element = typename GV::template Codim<0>::Entity;
using FiniteElementMap = typename Impl::BDMLocalFiniteElementMap<GV, double, k>;
using FiniteElement = Impl::GlobalValuedLocalFiniteElement<Impl::ContravariantPiolaTransformator,
typename FiniteElementMap::FiniteElement,
Element>;
BrezziDouglasMariniNode(const FiniteElementMap* finiteElementMap) :
element_(nullptr),
finiteElementMap_(finiteElementMap)
{}
const Element& element() const
{
return *element_;
}
const FiniteElement& finiteElement() const
{
return finiteElement_;
}
void bind(const Element& e)
{
element_ = &e;
finiteElement_.bind((finiteElementMap_->find(*element_)), e);
this->setSize(finiteElement_.size());
}
protected:
FiniteElement finiteElement_;
const Element* element_;
const FiniteElementMap* finiteElementMap_;
};
namespace BasisFactory {
template<std::size_t k>
auto brezziDouglasMarini()
{
return [](const auto& gridView) {
return BrezziDouglasMariniPreBasis<std::decay_t<decltype(gridView)>, k>(gridView);
};
}
} // end namespace BasisFactory
// *****************************************************************************
// This is the actual global basis implementation based on the reusable parts.
// *****************************************************************************
template<typename GV, int k>
using BrezziDouglasMariniBasis = DefaultGlobalBasis<BrezziDouglasMariniPreBasis<GV, k> >;
} // end namespace Functions
} // end namespace Dune
#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
nodes.hh
globalvaluedlocalfiniteelement.hh
leafprebasismappermixin.hh
defaultglobalbasis.hh
Dune::Functions::BasisFactory::brezziDouglasMarini
auto brezziDouglasMarini()
Create a pre-basis factory that can create a Brezzi-Douglas-Marini pre-basis.
Definition brezzidouglasmarinibasis.hh:285
Dune::Functions::Experimental::elements
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView)
ADL findable access to element range for a SubDomainGridView.
Definition subdomain.hh:487
Dune::Functions::Experimental::intersections
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition subdomain.hh:510
Dune
Definition monomialset.hh:19
Dune::Functions
Definition monomialset.hh:19
Dune::Functions::BrezziDouglasMariniBasis
DefaultGlobalBasis< BrezziDouglasMariniPreBasis< GV, k > > BrezziDouglasMariniBasis
Basis of a scalar k-th-order BDM finite element space on simplex and cube grids.
Definition brezzidouglasmarinibasis.hh:308
Dune::Functions::BasisFactory
Definition argyrisbasis.hh:926
Dune::Functions::BrezziDouglasMariniNode
Definition brezzidouglasmarinibasis.hh:228
Dune::Functions::BrezziDouglasMariniNode::finiteElement
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition brezzidouglasmarinibasis.hh:253
Dune::Functions::BrezziDouglasMariniNode::FiniteElementMap
typename Impl::BDMLocalFiniteElementMap< GV, double, k > FiniteElementMap
Definition brezzidouglasmarinibasis.hh:233
Dune::Functions::BrezziDouglasMariniNode::Element
typename GV::template Codim< 0 >::Entity Element
Definition brezzidouglasmarinibasis.hh:232
Dune::Functions::BrezziDouglasMariniNode::FiniteElement
Impl::GlobalValuedLocalFiniteElement< Impl::ContravariantPiolaTransformator, typename FiniteElementMap::FiniteElement, Element > FiniteElement
Definition brezzidouglasmarinibasis.hh:234
Dune::Functions::BrezziDouglasMariniNode::finiteElementMap_
const FiniteElementMap * finiteElementMap_
Definition brezzidouglasmarinibasis.hh:270
Dune::Functions::BrezziDouglasMariniNode::size_type
std::size_t size_type
Definition brezzidouglasmarinibasis.hh:231
Dune::Functions::BrezziDouglasMariniNode::finiteElement_
FiniteElement finiteElement_
Definition brezzidouglasmarinibasis.hh:268
Dune::Functions::BrezziDouglasMariniNode::element_
const Element * element_
Definition brezzidouglasmarinibasis.hh:269
Dune::Functions::BrezziDouglasMariniNode::bind
void bind(const Element &e)
Bind to element.
Definition brezzidouglasmarinibasis.hh:259
Dune::Functions::BrezziDouglasMariniNode::BrezziDouglasMariniNode
BrezziDouglasMariniNode(const FiniteElementMap *finiteElementMap)
Definition brezzidouglasmarinibasis.hh:238
Dune::Functions::BrezziDouglasMariniNode::element
const Element & element() const
Return current element, throw if unbound.
Definition brezzidouglasmarinibasis.hh:244
Dune::Functions::BrezziDouglasMariniPreBasis
Definition brezzidouglasmarinibasis.hh:167
Dune::Functions::BrezziDouglasMariniPreBasis::size_type
std::size_t size_type
Definition brezzidouglasmarinibasis.hh:189
Dune::Functions::BrezziDouglasMariniPreBasis::Node
BrezziDouglasMariniNode< GV, k > Node
Definition brezzidouglasmarinibasis.hh:191
Dune::Functions::BrezziDouglasMariniPreBasis::makeNode
Node makeNode() const
Create tree node.
Definition brezzidouglasmarinibasis.hh:214
Dune::Functions::BrezziDouglasMariniPreBasis::GridView
GV GridView
The grid view that the FE space is defined on.
Definition brezzidouglasmarinibasis.hh:188
Dune::Functions::BrezziDouglasMariniPreBasis::BrezziDouglasMariniPreBasis
BrezziDouglasMariniPreBasis(const GridView &gv)
Constructor for a given grid view object.
Definition brezzidouglasmarinibasis.hh:194
Dune::Functions::BrezziDouglasMariniPreBasis::finiteElementMap_
FiniteElementMap finiteElementMap_
Definition brezzidouglasmarinibasis.hh:220
Dune::Functions::BrezziDouglasMariniPreBasis::update
void update(const GridView &gv)
Definition brezzidouglasmarinibasis.hh:205
Dune::Functions::DefaultGlobalBasis
Global basis for given pre-basis.
Definition defaultglobalbasis.hh:53
Dune::Functions::LeafPreBasisMapperMixin::update
void update(const GridView &gv)
Update the stored GridView.
Definition leafprebasismappermixin.hh:101
Dune::Functions::LeafPreBasisMapperMixin::LeafPreBasisMapperMixin
LeafPreBasisMapperMixin(const GridView &gv, Dune::MCMGLayout layout)
Construct from GridView and local DOF layout.
Definition leafprebasismappermixin.hh:74
Dune::Functions::BasisNodeMixin::setSize
void setSize(const size_type size)
Definition nodes.hh:197
Dune::Functions::LeafBasisNode
Definition nodes.hh:218