13#ifndef FUNCTIONAL_AUX_HH
14#define FUNCTIONAL_AUX_HH
18#include <dune/common/fvector.hh>
19#include <dune/common/fmatrix.hh>
61 template <ProblemType Type>
102 template <
int row,
int col>
151 template <
int row,
int col>
165 template <
class Cell>
168 return 2*shapeFunctionOrder;
181 template <
class Face>
196 template <
int ,
int >
199 return -10*std::numeric_limits<double>::epsilon();
211 template <
class TestVars,
int row>
223 template <
class TestVars,
int row,
class AnsatzVars,
int col>
230 namespace Functional_Aux_Detail
232 template <
class Functional,
int n>
235 static constexpr bool ok = (!Functional::template D2<n,n>::present)
236 || Functional::template D2<n,n>::symmetric;
241 template <
class Functional>
244 static constexpr bool pass =
true;
248 template <
class Functional,
int n>
256 namespace Functional_Aux_Detail
258 template <
int a,
int b>
261 static constexpr bool value = a<b;
264 template <
int a,
int b>
267 static constexpr bool value = a==b;
279 template <
class AnsatzVars,
class TestVars>
283 using Scalar =
typename AnsatzVars::Scalar;
285 template <
class Entity>
288 template <
class Position,
class Evaluators>
296 template <
int row,
int dim>
302 template <
int row,
int col,
int dim>
326 template <
class Functional,
class Cache,
class ScalarT =
typename Functional::Scalar>
337 template <
int row>
using TestComponents = std::integral_constant<int,TestVars::template Components<row>::m>;
338 template <
int row>
using AnsatzComponents = std::integral_constant<int,AnsatzVars::template Components<row>::m>;
342 template <
int row,
int dimw>
345 return static_cast<Cache const*
>(
this)->
template d1_impl<row>(arg);
348 template <
int row,
int dimw>
355 template <int row, int dimw, class enable = typename std::enable_if_t<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>>
361 for(
int i=0; i<TestComponents<row>::value; ++i)
366 result[i] = d1_local<row>(arg);
373 template <
int row,
int col,
int dim>
376 return static_cast<Cache const*
>(
this)->
template d2_impl<row,col>(arg1,arg2);
379 template <
int row,
int col,
int dim,
380 class enable1 =
typename std::enable_if_t<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>,
381 class enable2 =
typename std::enable_if_t<Functional_Aux_Detail::LessThan<1,AnsatzComponents<row>::value>::value>
385 return d2_local<row,col>(arg1,arg2);
389 template <
int row,
int col,
int dim,
int m2,
390 class enable1 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>::type,
391 class enable2 =
typename std::enable_if<Functional_Aux_Detail::Equals<m2,AnsatzComponents<col>::value>::value>::type,
392 class enable3 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,AnsatzComponents<col>::value>::value>::type
398 for(
int i=0; i<AnsatzComponents<row>::value; ++i)
403 result[i] = d2_local<row,col>(arg1,arg2);
410 template <
int row,
int col,
int dim,
int m1,
411 class enable1 =
typename std::enable_if<Functional_Aux_Detail::Equals<m1,TestComponents<row>::value>::value>::type,
412 class enable2 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>::type,
413 class enable3 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,AnsatzComponents<col>::value>::value>::type
419 for(
int i=0; i<AnsatzComponents<row>::value; ++i)
424 result[i] = d2_local<row,col>(arg1,arg2);
431 template <
int row,
int col,
int dim>
437 for(
int i=0; i<TestComponents<row>::value; ++i)
441 for(
int j=0; j<AnsatzComponents<col>::value; ++j)
446 result[i][j] = d2_local<row,col>(arg1,arg2);
455 template <
int row,
int col,
int dim>
458 return static_cast<Cache const*
>(
this)->
template b2_impl<row,col>(arg1,arg2);
461 template <
int row,
int col,
int dim,
462 class enable1 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>::type,
463 class enable2 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,AnsatzComponents<row>::value>::value>::type
467 return b2_local<row,col>(arg1,arg2);
471 template <
int row,
int col,
int dim,
int m2,
472 class enable1 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>::type,
473 class enable2 =
typename std::enable_if<Functional_Aux_Detail::Equals<m2,AnsatzComponents<col>::value>::value>::type,
474 class enable3 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,AnsatzComponents<col>::value>::value>::type
480 for(
int i=0; i<AnsatzComponents<row>::value; ++i)
485 result[i] = b2_local<row,col>(arg1,arg2);
492 template <
int row,
int col,
int dim,
int m1,
493 class enable1 =
typename std::enable_if<Functional_Aux_Detail::Equals<m1,TestComponents<row>::value>::value>::type,
494 class enable2 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,TestComponents<row>::value>::value>::type,
495 class enable3 =
typename std::enable_if<Functional_Aux_Detail::LessThan<1,AnsatzComponents<col>::value>::value>::type
501 for(
int i=0; i<AnsatzComponents<row>::value; ++i)
506 result[i] = b2_local<row,col>(arg1,arg2);
513 template <
int row,
int col,
int dim>
519 for(
int i=0; i<TestComponents<row>::value; ++i)
523 for(
int j=0; j<AnsatzComponents<col>::value; ++j)
528 result[i][j] = b2_local<row,col>(arg1,arg2);
539 namespace Functional_Aux_Detail
544 template <
class Functional>
545 constexpr std::true_type hasInnerBoundaryCacheImpl(
typename Functional::InnerBoundaryCache*);
548 template <
class Functional>
549 constexpr std::false_type hasInnerBoundaryCacheImpl(...);
557 template <
class Functional>
559 decltype(Functional_Aux_Detail::hasInnerBoundaryCacheImpl<Functional>(
nullptr))::value;
566 namespace Functional_Aux_Detail
568 template <
class Functional,
class Linearization,
bool hasInnerBoundaryCache>
569 struct InnerBoundaryPolicyImpl
573 template <
class Functional,
class Linearization>
574 struct InnerBoundaryPolicyImpl<Functional,Linearization,true>
576 using InnerBoundaryCache =
typename Functional::InnerBoundaryCache;
579 InnerBoundaryCache createInnerBoundaryCache(
int flags)
const
581 return InnerBoundaryCache(
static_cast<Linearization const*
>(
this)->
getFunctional(),
582 static_cast<Linearization const*
>(
this)->getOrigin(),flags);
585 template <
class Face>
588 return static_cast<Linearization const*
>(
this)->
getFunctional().considerFace(face);
592 template <
class Functional,
class Linearization>
593 using InnerBoundaryPolicy = InnerBoundaryPolicyImpl<Functional,Linearization,hasInnerBoundaryCache<Functional>>;
613 template<
class Functional_>
614 class LinearizationAt :
public Functional_Aux_Detail::InnerBoundaryPolicy<Functional_,LinearizationAt<Functional_>>
620 typedef typename Functional::Scalar
Scalar;
669 struct D1:
public Functional::template
D1<row> {};
672 template <
int row,
int col>
673 struct D2:
public Functional::template
D2<row,col> {};
676 template <
class Cell>
679 return f.integrationOrder(cell,shapeFunctionOrder,boundary);
682 template <
int row,
int col>
685 return f.template makePositiveThreshold<row,col>();
705 return f.derivatives();
720 template<
class Functional>
747 template<
class Functional_>
748 class LinearizationDifferenceAt :
public Functional_Aux_Detail::InnerBoundaryPolicy<Functional_,LinearizationDifferenceAt<Functional_> >
754 typedef typename Functional::Scalar
Scalar;
776 :
f(f_),
u1(u1_),
u2(u2_) {};
782 : dc1(
f,
u1,flags), dc2(
f,
u2,flags) {}
784 template <
class Cell>
785 void moveTo(
Cell const& entity) { dc1.moveTo(entity); dc2.moveTo(entity); }
787 template <
class Position,
class Evaluators>
788 void evaluateAt(Position
const& x,
Evaluators const& evaluators) { dc1.evaluateAt(x,evaluators); dc2.evaluateAt(x,evaluators); }
792 template<
int row,
int dim>
796 return dc1.template d1<row>(arg)-dc2.template d1<row>(arg);
799 template<
int row,
int col,
int dim>
803 return dc1.template d2<row,col>(arg1,arg2)-dc2.template d2<row,col>(arg1,arg2);
808 typename Functional::DomainCache dc1, dc2;
815 : bc1(
f,
u1,flags), bc2(
f,
u2,flags) {}
817 template <
class FaceIterator>
818 void moveTo(FaceIterator
const& entity) { bc1.moveTo(entity); bc2.moveTo(entity); }
820 template <
class Position,
class Evaluators>
821 void evaluateAt(Position
const& x,
Evaluators const& evaluators) { bc1.evaluateAt(x,evaluators); bc2.evaluateAt(x,evaluators); }
825 template<
int row,
int dim>
829 return bc1.template d1<row>(arg)-bc2.template d1<row>(arg);
832 template<
int row,
int col,
int dim>
836 return bc1.template d2<row,col>(arg1,arg2)-bc2.template d2<row,col>(arg1,arg2);
840 typename Functional::BoundaryCache bc1, bc2;
859 struct D1:
public Functional::template
D1<row> {};
862 template <
int row,
int col>
863 struct D2:
public Functional::template
D2<row,col> {};
866 template <
class Cell>
869 return f.template integrationOrder<Cell>(cell, shapeFunctionOrder, boundary);
884 template<
class Functional>
886 typename Functional::OriginVars::VariableSet
const & u1,
887 typename Functional::OriginVars::VariableSet
const & u2)
905 template <
class Functional>
917 typename Functional::AnsatzVars::VariableSet
const& u_,
918 typename Functional::AnsatzVars::VariableSet
const& uJ_,
919 typename Functional::AnsatzVars::VariableSet
const& du_):
924 return typename Functional::DomainCache(this->
f,this->
u,uJ,du,flags);
929 return typename Functional::BoundaryCache(this->
f,this->
u,uJ,du,flags);
933 typename Functional::AnsatzVars::VariableSet
const& uJ;
934 typename Functional::AnsatzVars::VariableSet
const& du;
937 template <
class Functional>
949 typename Functional::AnsatzVars::VariableSet
const& u_,
950 typename Functional::AnsatzVars::VariableSet
const& uJ_,
951 typename Functional::AnsatzVars::VariableSet
const& du_):
956 return typename Functional::DomainCache(this->
f,this->
u,uJ,du,flags);
961 return typename Functional::BoundaryCache(this->
f,this->
u,uJ,du,flags);
966 return typename Functional::InnerBoundaryCache(this->
f,this->
u,uJ,du,flags);
970 typename Functional::AnsatzVars::VariableSet
const& uJ;
971 typename Functional::AnsatzVars::VariableSet
const& du;
978 template<
class Functional>
980 typename Functional::AnsatzVars::VariableSet
const& u,
981 typename Functional::AnsatzVars::VariableSet
const& uJ,
982 typename Functional::AnsatzVars::VariableSet
const& du)
Provides implementations of d1 and d2 for (possibly mixed) use of scalar and power spaces.
Matrix< row, col > d2(VariationalArg< Scalar, dim > const &scalarArg1, VariationalArg< Scalar, dim > const &scalarArg2) const
scalar argument for multi-component variables
Scalar b2_local(VariationalArg< Scalar, dim, TestComponents< row >::value > const &arg1, VariationalArg< Scalar, dim, AnsatzComponents< col >::value > const &arg2) const
forward to implementation via CRTP
Scalar d2_local(VariationalArg< Scalar, dim, TestComponents< row >::value > const &arg1, VariationalArg< Scalar, dim, AnsatzComponents< col >::value > const &arg2) const
forward to implementation via CRTP
Matrix< row, col > b2(VariationalArg< Scalar, dim > const &scalarArg1, VariationalArg< Scalar, dim > const &scalarArg2) const
scalar argument for multi-component variables
Scalar d1_local(VariationalArg< Scalar, dimw, TestComponents< row >::value > const &arg) const
forward to implementation via CRTP
Vector< row > d1(VariationalArg< Scalar, dimw > const &scalarArg) const
scalar argument for multi-component variables
typename Functional::AnsatzVars AnsatzVars
Vector< row > b2(VariationalArg< Scalar, dim > const &scalarArg, VariationalArg< Scalar, dim, m2 > const &arg2) const
scalar argument for multi-component variables
typename Functional::TestVars TestVars
Dune::FieldVector< Scalar, 1 > d1(VariationalArg< Scalar, dimw, TestComponents< row >::value > const &arg) const
Dune::FieldMatrix< Scalar, 1, 1 > d2(VariationalArg< Scalar, dim, TestComponents< row >::value > const &arg1, VariationalArg< Scalar, dim, AnsatzComponents< col >::value > const &arg2) const
Vector< row > b2(VariationalArg< Scalar, dim, m1 > const &arg1, VariationalArg< Scalar, dim > const &scalarArg) const
scalar argument for multi-component variables
Vector< row > d2(VariationalArg< Scalar, dim, m1 > const &arg1, VariationalArg< Scalar, dim > const &scalarArg) const
scalar argument for multi-component variables
Vector< row > d2(VariationalArg< Scalar, dim > const &scalarArg, VariationalArg< Scalar, dim, m2 > const &arg2) const
scalar argument for multi-component variables
Dune::FieldMatrix< Scalar, 1, 1 > b2(VariationalArg< Scalar, dim, TestComponents< row >::value > const &arg1, VariationalArg< Scalar, dim, AnsatzComponents< col >::value > const &arg2) const
Convenience base class for the easy definition of variational functionals and weak formulations.
bool considerFace(Face const &) const
Default implementation for which faces are to be considered for assembly in case an InnerBoundaryCach...
bool inDomain(T const &) const
int integrationOrder(Cell const &, int shapeFunctionOrder, bool) const
Default implementation specifying the integration order.
static constexpr ProblemType type
double makePositiveThreshold() const
Defines the eigenvalue threshold when enforcing positivity of local stiffness matrices.
Proxy class for the linearization of a nonlinear functional.
Functional::DomainCache DomainCache
DomainCache createDomainCache(int flags) const
create a domain cache
PointOfLinearization const & getOrigin() const
Get point of linearization.
Functional::Scalar Scalar
Functional::OriginVars OriginVars
Functional::AnsatzVars AnsatzVars
int derivatives() const
Gives the highest derivative that arises in the weak formulation.
PointOfLinearization const & u
Functional::BoundaryCache BoundaryCache
LinearizationAt(Functional const &f_, PointOfLinearization const &u_)
Construct a linearization from a given functional.
static ProblemType const type
Functional const & getFunctional() const
Get functional.
Functional::TestVars TestVars
Functional::OriginVars::VariableSet PointOfLinearization
Type of variables around which the functional will be linearized.
auto makePositiveThreshold() const
int integrationOrder(Cell const &cell, int shapeFunctionOrder, bool boundary) const
integration order
BoundaryCache createBoundaryCache(int flags) const
create a boundary cache
void evaluateAt(Position const &x, Evaluators const &evaluators)
BoundaryCache(Functional const &f, PointOfLinearization const &u1, PointOfLinearization const &u2, int flags)
void moveTo(FaceIterator const &entity)
Dune::FieldVector< Scalar, TestVars::template Components< row >::m > d1(VariationalArg< Scalar, dim > const &arg) const
Dune::FieldMatrix< Scalar, TestVars::template Components< row >::m, AnsatzVars::template Components< col >::m > d2(VariationalArg< Scalar, dim > const &arg1, VariationalArg< Scalar, dim > const &arg2) const
DomainCache(Functional const &f, PointOfLinearization const &u1, PointOfLinearization const &u2, int flags)
void moveTo(Cell const &entity)
Dune::FieldVector< Scalar, TestVars::template Components< row >::m > d1(VariationalArg< Scalar, dim > const &arg) const
void evaluateAt(Position const &x, Evaluators const &evaluators)
Dune::FieldMatrix< Scalar, TestVars::template Components< row >::m, AnsatzVars::template Components< col >::m > d2(VariationalArg< Scalar, dim > const &arg1, VariationalArg< Scalar, dim > const &arg2) const
Proxy class for evaluating differences of linearizations of a nonlinear functional.
PointOfLinearization const & u1
PointOfLinearization const & u2
Functional::OriginVars::VariableSet PointOfLinearization
Type of variables around which the functional will be linearized.
Functional const & getFunctional() const
Get functional.
Functional::Scalar Scalar
int integrationOrder(Cell const &cell, int shapeFunctionOrder, bool boundary) const
integration order
LinearizationDifferenceAt(Functional const &f_, PointOfLinearization const &u1_, PointOfLinearization const &u2_)
Construct a difference of linearizations from a given functional.
Functional::OriginVars OriginVars
BoundaryCache createBoundaryCache(int flags) const
create a boundary cache
DomainCache createDomainCache(int flags) const
create a domain cache
static ProblemType const type
Functional::AnsatzVars AnsatzVars
Functional::TestVars TestVars
Proxy class for the linearization of semi-linear time stepping schemes.
SemiLinearizationAt(Functional const &f_, typename Functional::AnsatzVars::VariableSet const &u_, typename Functional::AnsatzVars::VariableSet const &uJ_, typename Functional::AnsatzVars::VariableSet const &du_)
Constructor.
Functional::BoundaryCache createBoundaryCache(int flags) const
Functional::DomainCache createDomainCache(int flags) const
SemiLinearizationAt< Functional > semiLinearization(Functional const &f, typename Functional::AnsatzVars::VariableSet const &u, typename Functional::AnsatzVars::VariableSet const &uJ, typename Functional::AnsatzVars::VariableSet const &du)
Convenience routine for constructing semi-linearizations.
SemiLinearizationAtInner(Functional const &f_, typename Functional::AnsatzVars::VariableSet const &u_, typename Functional::AnsatzVars::VariableSet const &uJ_, typename Functional::AnsatzVars::VariableSet const &du_)
Constructor.
Functional::InnerBoundaryCache createInnerBoundaryCache(int flags) const
Functional::BoundaryCache createBoundaryCache(int flags) const
Functional::DomainCache createDomainCache(int flags) const
Base class simplifying the definition of domain and boundary caches.
Dune::FieldVector< Scalar, TestVars::template components< row > > d1(VariationalArg< Scalar, dim > const &arg) const
void evaluateAt(Position const &, Evaluators const &)
typename AnsatzVars::Scalar Scalar
Dune::FieldMatrix< Scalar, TestVars::template components< row >, AnsatzVars::template components< row > > d2(VariationalArg< Scalar, dim > const &, VariationalArg< Scalar, dim > const &) const
void moveTo(Entity const &)
Documentation of the concept of a quadratic variational functionalThe variational functional concept ...
FEFunctionSpace and FunctionSpaceElement and the like.
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
ProblemType
A type for describing the nature of a PDE problem.
constexpr bool hasInnerBoundaryCache
Checks whether InnerBoundaryCache is declared in Functional.
LinearizationAt< Functional > linearization(Functional const &f, typename Functional::OriginVars::VariableSet const &u)
Convenience routine: construct linearization without having to know the type of the functional.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
typename GridView::Intersection Face
The type of faces in the grid view.
std::unique_ptr< AbstractFunctional > getFunctional(std::unique_ptr< Functional > &&F)
bool considerFace(Face const &face, std::vector< int > const &boundaryIds, std::vector< int > const &usedIds)
LinearizationDifferenceAt< Functional > linearizationDifference(Functional const &f, typename Functional::OriginVars::VariableSet const &u1, typename Functional::OriginVars::VariableSet const &u2)
Convenience routine: construct linearization without having to know the type of the functional.
constexpr bool symmetryCheck
Helper class for specifying the number of components of a variable.
static constexpr bool pass
static bool const symmetric
static bool const present
static bool const constant
Static a priori default information about the right hand side blocks.
static constexpr bool present
Whether the block is to be assembled at all.
static constexpr int derivatives
The maximum ansatz and test function derivative occuring in this block.
Static a priori default information about the matrix blocks.
static constexpr bool constant
static constexpr bool makePositive
If this flag is true (and symmetric==true), the assembler will enforce positive semidefiniteness of a...
static constexpr int derivatives
The maximum ansatz and test function derivative occuring in this block.
static constexpr bool lumped
If this flag is true, only the diagonal of this block will be assembled and stored....
static constexpr bool symmetric
Whether the block is structurally symmetric (or hermitian). The default is true for diagonal blocks o...
static constexpr bool present
Whether the block is to be assembled and stored or not. The default value is the conservative one (bu...
A class that stores values, gradients, and Hessians of evaluated shape functions.
Dune::FieldMatrix< Scalar, components, dim > derivative
The shape function's spatial derivative, a components x dim matrix.
ValueType value
The shape function's value, a vector of dimension components