Commit 7c7b7339 authored by's avatar

Merge branch 'feature/boundary-dof-power-basis' into 'master'

Boundary dofs: extent to generic dune-functions basis

See merge request !64
parents 658617b3 ffe2c269
Pipeline #27831 failed with stage
in 10 seconds
# Master (will become release 2.8)
- ...
- constructBoundaryDofs:
- Small interface change in the template parameters: drop `blocksize` and replace it by `BitSetVector`
- The method can now handle generic `dune-functions` basis types, as long as we have consistency in the data types
## Deprecations and removals
......@@ -10,59 +10,56 @@
#include <dune/fufem/boundarypatch.hh>
#include <dune/functions/backends/concepts.hh>
#include <dune/functions/backends/istlvectorbackend.hh>
#include <dune/functions/functionspacebases/subentitydofs.hh>
/** \brief For a given basis and boundary patch, determine all degrees
of freedom on the patch.
\param boundaryDofs Bit is set if corresponding dofs belongs to the boundary patch
A bit of boundaryDofs is set if corresponding dof belongs to the boundary patch.
\param boundaryDofs BitSetVector corresponding to the basis DOFs
\param sfinae Dummy parameter to instantiate this method only for dune-functions bases
template <class GridView, class Basis, int blocksize>
template <class GridView, class Basis, class BitSetVector>
void constructBoundaryDofs(const BoundaryPatch<GridView>& boundaryPatch,
const Basis& basis,
Dune::BitSetVector<blocksize>& boundaryDofs,
BitSetVector& boundaryDofs,
typename Basis::LocalView* sfinae = nullptr)
// Check consistency of the input
static_assert((std::is_same<GridView, typename Basis::GridView>::value),
"BoundaryPatch and global basis must be for the same grid view!");
// Small helper function to wrap vectors using istlVectorBackend
// if they do not already satisfy the VectorBackend interface.
auto toVectorBackend = [&](auto& v) -> decltype(auto) {
if constexpr (Dune::models<Dune::Functions::Concept::VectorBackend<Basis>, decltype(v)>()) {
return v;
} else {
return Dune::Functions::istlVectorBackend(v);
// Init output bitfield
// ensure IstlVectorBackend interface
auto boundaryDofsBackend = toVectorBackend(boundaryDofs);
auto localView = basis.localView();
auto localIndexSet = basis.localIndexSet();
boundaryDofsBackend = false;
for (auto it = boundaryPatch.begin(); it != boundaryPatch.end(); ++it)
auto localView = basis.localView();
auto seDOFs = Dune::Functions::subEntityDOFs(basis);
for(const auto& intersection : boundaryPatch)
const auto& localCoefficients = localView.tree().finiteElement().localCoefficients();
for (size_t i=0; i<localCoefficients.size(); i++)
// Test whether dof is on the boundary face
unsigned int entity = localCoefficients.localKey(i).subEntity();
unsigned int codim = localCoefficients.localKey(i).codim();
if (it.containsInsideSubentity(entity, codim))
boundaryDofs[localIndexSet.index(i)] = true;
boundaryDofs[localView.index(i)] = true;
for(auto localIndex: seDOFs.bind(localView, intersection))
boundaryDofsBackend[localView.index(localIndex)] = true;
......@@ -8,6 +8,7 @@ set(GRID_BASED_TESTS
#include <config.h>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/common/test/testsuite.hh>
#include <dune/common/bitsetvector.hh>
#include <dune/common/fvector.hh>
#include <dune/fufem/functiontools/boundarydofs.hh>
#include <dune/fufem/boundarypatch.hh>
#include <dune/fufem/test/common.hh>
#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/istl/bvector.hh>
using namespace Dune;
template<int order, class GW>
bool checkConstructBoundaryDofs(const GW& gw)
// create active vertices
const auto dim = GW::dimension;
const auto size = gw.size(dim);
BitSetVector<dim> vertices(size);
// set some values
vertices[size / 2].set();
// create BoundaryPatch
BoundaryPatch bp(gw,vertices);
// create scalar and powerBasis
using namespace Functions::BasisFactory;
auto lagrangeBasis = makeBasis(gw, lagrange<order>());
auto powerBasis = makeBasis(gw, power<3>(lagrange<order>()));
// create common bitsetvector
BitSetVector<1> lagrangeDOFs;
BitSetVector<3> powerDOFs;
// ... and functions-compatible bitVectors
Dune::BlockVector<Dune::FieldVector<char,1>> lagrangeBits;
Dune::BlockVector<Dune::FieldVector<char,3>> powerBits;
auto lagrangeBackend = Dune::Functions::istlVectorBackend(lagrangeBits);
auto powerBackend = Dune::Functions::istlVectorBackend(powerBits);
// check whether this compiles
return true;
struct Suite
template<class GridType>
bool check(const GridType& grid)
auto maxLevel = grid.maxLevel();
auto gridView = grid.levelGridView(maxLevel);
bool passed = checkConstructBoundaryDofs<0>(gridView);
passed = passed and checkConstructBoundaryDofs<1>(gridView);
passed = passed and checkConstructBoundaryDofs<2>(gridView);
return passed;
int main(int argc, char** argv)
Dune::MPIHelper::instance(argc, argv);
Suite tests;
bool passed = checkWithStructuredGrid<2>(tests, 3);
passed = passed and checkWithStructuredGrid<3>(tests, 3);
return passed ? 0 : 1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment