Skip to content
Snippets Groups Projects
Commit 151195f0 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Add some utilitilies for unified treatment of grid functions

All utilities in this header are for transitional purposes to
migrate dune-fufem from the `Dune::VirtualFunction`-based to a
`std::function`-based interface, while keeping some compatibility.

Unfortunately the dune-functions utilities (e.g. `makeGridViewFunction()`)
cannot directly be used, because the old dune-fufem assemblers do not
know a `GridView`, but only a `Grid`, while the dune-functions grid-function
concept always required an `EntitySet` that typically represents a `GridView`.
The work-around provided by this header works as follows:

* Provide a utility `Dune::Fufem::Impl::localFunctionForGrid<Grid>(f)`
  that creates a local function suitable for a given `Grid` type - either by
  forwarding to `localFunction(f)` or by providing a wrapper.
* To avoid implementing the wrapper again, `Dune::Functions::AnalyticGridViewFunction`
  is reused with a dummy `Dune::Fufem::Impl::AllEntityGridView` that contains all
  entities (but does not allow iteration or to obtain an index set).
* Since the `GridView` type may differ, depending on which code path
  is used to create the grid function, we cannot directly store the
  global grid function in a `Dune::Functions::GridFunction` type-erasure
  wrapper. Instead we have to store the local function in a
  `Dune::Functions::LocalFunction` that only depends on the entity type.
  Since creating precise type of the latter from the `Grid` and `Range`
  is a little cumbersome, this is simplified by the alias
  `Dune::Fufem::Impl::LocalFunctionInterfaceForGrid<Grid,Range>`.
parent 3299eead
No related branches found
No related tags found
1 merge request!146Stop using Dune::VirtualFunction interface
......@@ -5,6 +5,7 @@ install(FILES
cachedcomponentwrapper.hh
coarsegridfunctionwrapper.hh
deformationfunction.hh
gridfunctionhelper.hh
localbasisderivativefunction.hh
localbasisjacobianfunction.hh
portablegreymap.hh
......
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set ts=8 sw=2 et sts=2:
#ifndef DUNE_FUFEM_FUNCTIONS_GRIDFUNCTIONHELPER_HH
#define DUNE_FUFEM_FUNCTIONS_GRIDFUNCTIONHELPER_HH
#include <cstddef>
#include <utility>
#include <type_traits>
#include <functional>
#include <dune/common/concept.hh>
#include <dune/functions/common/localfunction.hh>
#include <dune/functions/gridfunctions/analyticgridviewfunction.hh>
#include <dune/functions/gridfunctions/localderivativetraits.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
// All utilities are for transitional purposes to migrate dune-fufem
// from the Dune::VirtualFunction-based to a std::function-based
// interface, while keeping some compatibility.
//
// The dune-functions utilities cannot directly be used, because the
// old dune-fufem assemblers do not know a GridView, but only a Grid,
// while the dune-functions grid-function concept always required
// an EntitySet that typically represents a GridView. (*)
namespace Dune::Fufem::Impl {
// A dummy GridView that contains all entities but does not provide an iterator.
// This is helpful to implement a grid function that is defined on any element
// without knowing the actual GridView type (cf (*)).
template<class Grid>
struct AllEntityGridView
{
template<int codim>
struct Codim : public Grid::template Codim<codim> {
using Iterator = int;
};
template<int codim>
bool contains(const typename Codim<codim>::Entity&) const {
return true;
}
template<int codim>
int begin() const {
return 0;
}
template<int codim>
int end() const {
return 0;
}
std::size_t size(int codim) const {
return 0;
}
};
// Concept for a function that can be localized on Grid elements.
// We cannot use the GridFunction concept because of (*).
template<class Grid>
struct HasLocalFunctionConcept
{
using Element = typename Grid::template Codim<0>::Entity;
template<class F>
auto require(F&& f) -> decltype(
localFunction(f).bind(std::declval<const Element&>()),
localFunction(f)(std::declval<typename Element::Geometry::LocalCoordinate>())
);
};
// Obtain local function from localizable function.
// We cannot use Dune::Functions::makeGridViewFunction() because of (*)
template<class Grid, class Range, class F, std::enable_if_t<Dune::models<HasLocalFunctionConcept<Grid>, F>(), int> = 0>
auto localFunctionForGrid(const F& f)
{
return localFunction(f);
}
// Obtain local function from non-localizable function by wrapping it into
// an AnalyticGridViewFunction first. Since the corresponding LocalFunction type
// is an implementation detail, we should not create it directly.
//
// We need to pass the Range type explicitly, to handle the case where
// the functions return type is only convertible to Range. We must be
// careful here, because even for to compatible/convertible Range types
// the associated DerivativeRange and thus LocalFunction types may be
// incompatible.
//
// Notice that the return value stores a reference to the passed global function
// whose life time has to be guaranteed externally.
//
// We cannot use Dune::Functions::makeGridViewFunction() because of (*)
template<class Grid, class Range, class F, std::enable_if_t<not Dune::models<HasLocalFunctionConcept<Grid>, F>(), int> = 0>
auto localFunctionForGrid(const F& f)
{
using GlobalDomain = typename Grid::template Codim<0>::Entity::Geometry::GlobalCoordinate;
using LocalDomain = typename Grid::template Codim<0>::Entity::Geometry::LocalCoordinate;
using GridView = AllEntityGridView<Grid>;
using FR = std::reference_wrapper<const F>;
using GF = Dune::Functions::AnalyticGridViewFunction<Range(GlobalDomain), GridView, FR>;
return localFunction(GF(std::cref(f), AllEntityGridView<Grid>()));
}
// Alias for the type erasure wrapper to store local functions
// for the given Grid and Range type.
template<class Grid, class Range>
using LocalFunctionInterfaceForGrid = Dune::Functions::LocalFunction<
Range(typename Grid::template Codim<0>::Entity::Geometry::LocalCoordinate),
typename Grid::template Codim<0>::Entity,
Dune::Functions::LocalDerivativeTraits<Dune::Functions::GridViewEntitySet<AllEntityGridView<Grid>,0>>::template Traits>;
} // namespace Dune::Fufem::Impl
#endif // DUNE_FUFEM_FUNCTIONS_GRIDFUNCTIONHELPER_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment