45#include <dune/fem/operator/common/differentiableoperator.hh>
46#include <dune/fem/operator/common/operator.hh>
47#include <dune/fem/operator/common/stencil.hh>
48#include <dune/fem/quadrature/cachingquadrature.hh>
49#include <dune/fem/operator/common/temporarylocalmatrix.hh>
51#include <dune/fem/schemes/elliptic.hh>
56template <
class DFSpace>
59 DefaultPenalty(
const DFSpace &space,
double penalty)
63 template <
class Intersection>
64 double operator()(
const Intersection &intersection,
65 double intersectionArea,
double area,
double nbArea)
const
67 const double hInv = intersectionArea / std::min( area, nbArea );
68 return penalty_ * hInv;
70 const double &factor()
const {
return penalty_; }
72 const DFSpace &space_;
76template<
class DiscreteFunction,
class Model,
77 class Penalty = DefaultPenalty<typename DiscreteFunction::DiscreteFunctionSpaceType > >
78struct DGEllipticOperator
82 typedef Model ModelType;
84 typedef DiscreteFunction DomainDiscreteFunctionType;
85 typedef DiscreteFunction RangeDiscreteFunctionType;
93 typedef typename IteratorType::Entity EntityType;
96 typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
98 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
100 typedef typename IntersectionIteratorType::Intersection IntersectionType;
101 typedef typename IntersectionType::Geometry IntersectionGeometryType;
103 typedef Dune::Fem::ElementQuadrature< GridPartType, 1 > FaceQuadratureType;
111 DGEllipticOperator (
const DiscreteFunctionSpaceType &space,
112 const ModelType &model,
113 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
115 penalty_( space, parameter.getValue< double >(
"penalty", 40 ) ),
121 DGEllipticOperator (
const DiscreteFunctionSpaceType &dSpace,
122 const DiscreteFunctionSpaceType &rSpace,
123 const ModelType &model,
124 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
126 penalty_( dSpace, parameter.getValue< double >(
"penalty", 40 ) ),
133 virtual void operator() (
const DomainDiscreteFunctionType &u, RangeDiscreteFunctionType &w )
const
136 void apply(
const GF &u, RangeDiscreteFunctionType &w )
const;
138 size_t gridSizeInterior()
const {
return grdSzeInt_; }
141 const ModelType &model ()
const {
return model_; }
142 Penalty penalty()
const {
return penalty_; }
145 const ModelType &model_;
147 mutable size_t grdSzeInt_;
153template<
class JacobianOperator,
class Model,
154 class Penalty = DefaultPenalty<typename JacobianOperator::DomainFunctionType::DiscreteFunctionSpaceType > >
155struct DifferentiableDGEllipticOperator
156:
public DGEllipticOperator< typename JacobianOperator::DomainFunctionType, Model, Penalty >,
159 typedef DGEllipticOperator< typename JacobianOperator::DomainFunctionType, Model, Penalty > BaseType;
164 typedef typename BaseType::ModelType ModelType;
165 typedef typename BaseType::DomainDiscreteFunctionType DomainDiscreteFunctionType;
166 typedef typename BaseType::RangeDiscreteFunctionType RangeDiscreteFunctionType;
169 typedef typename DomainDiscreteFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
170 typedef typename DomainDiscreteFunctionType::LocalFunctionType DomainLocalFunctionType;
171 typedef typename DomainLocalFunctionType::RangeType DomainRangeType;
172 typedef typename DomainLocalFunctionType::JacobianRangeType DomainJacobianRangeType;
173 typedef typename RangeDiscreteFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
174 typedef typename RangeDiscreteFunctionType::LocalFunctionType RangeLocalFunctionType;
175 typedef typename RangeLocalFunctionType::RangeType RangeRangeType;
176 typedef typename RangeLocalFunctionType::JacobianRangeType RangeJacobianRangeType;
185 typedef typename IteratorType::Entity EntityType;
188 typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
190 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
192 typedef typename IntersectionIteratorType::Intersection IntersectionType;
193 typedef typename IntersectionType::Geometry IntersectionGeometryType;
195 typedef Dune::Fem::ElementQuadrature< GridPartType, 1 > FaceQuadratureType;
203 DifferentiableDGEllipticOperator (
const DiscreteFunctionSpaceType &space,
204 const ModelType &model,
205 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
206 : BaseType( space, model, parameter )
208 DifferentiableDGEllipticOperator (
const DiscreteFunctionSpaceType &dSpace,
209 const DiscreteFunctionSpaceType &rSpace,
210 const ModelType &model,
211 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
212 : BaseType( dSpace, rSpace, model, parameter )
216 void jacobian (
const DomainDiscreteFunctionType &u, JacobianOperatorType &jOp )
const
218 template <
class Gr
idFunctionType>
219 void apply (
const GridFunctionType &u, JacobianOperatorType &jOp )
const;
220 using BaseType::apply;
223 using BaseType::model;
224 using BaseType::penalty;
225 using BaseType::grdSzeInt_;
231template<
class RangeDiscreteFunction,
class Model,
class Penalty >
233void DGEllipticOperator< RangeDiscreteFunction, Model, Penalty >
234 ::apply(
const GF &u, RangeDiscreteFunctionType &w )
const
240 const DiscreteFunctionSpaceType &dfSpace = w.space();
241 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
242 Dune::Fem::ConstLocalFunction< GF > uOutLocal( u );
243 Dune::Fem::AddLocalContribution< RangeDiscreteFunctionType > wLocal( w );
248 const IteratorType end = dfSpace.end();
249 for( IteratorType it = dfSpace.begin(); it != end; ++it )
252 const EntityType &entity = *it;
257 bool needsCalculation = model().init( entity );
258 if (! needsCalculation )
265 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
266 auto wGuard = Dune::Fem::bindGuard( wLocal, entity );
269 const int quadOrder = uLocal.order() + wLocal.order();
272 QuadratureType quadrature( entity, quadOrder );
273 const size_t numQuadraturePoints = quadrature.nop();
274 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
276 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
277 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
280 uLocal.evaluate( quadrature[ pt ], vu );
281 JacobianRangeType du;
282 uLocal.jacobian( quadrature[ pt ], du );
286 model().source( quadrature[ pt ], vu, du, avu );
290 JacobianRangeType adu( 0 );
292 model().flux( quadrature[ pt ], vu, du, adu );
296 wLocal.axpy( quadrature[ pt ], avu, adu );
299 if ( ! dfSpace.continuous() )
301 const double area = entity.geometry().volume();
302 const IntersectionIteratorType iitend = dfSpace.gridPart().iend( entity );
303 for( IntersectionIteratorType iit = dfSpace.gridPart().ibegin( entity ); iit != iitend; ++iit )
306 const IntersectionType &intersection = *iit;
307 if ( intersection.neighbor() )
309 const EntityType outside = intersection.outside() ;
311 typedef typename IntersectionType::Geometry IntersectionGeometryType;
312 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
315 const double intersectionArea = intersectionGeometry.volume();
316 const double beta = penalty()(intersection,intersectionArea,area,outside.geometry().volume());
318 auto uOutGuard = Dune::Fem::bindGuard( uOutLocal, outside );
320 FaceQuadratureType quadInside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
321 FaceQuadratureType quadOutside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::OUTSIDE );
322 const size_t numQuadraturePoints = quadInside.nop();
325 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
329 const typename FaceQuadratureType::LocalCoordinateType &x = quadInside.localPoint( pt );
330 DomainType normal = intersection.integrationOuterNormal( x );
331 double faceVol = normal.two_norm();
333 const double weight = quadInside.weight( pt ) * faceVol;
335 RangeType vuIn,vuOut;
336 JacobianRangeType duIn, duOut;
337 uLocal.evaluate( quadInside[ pt ], vuIn );
338 uLocal.jacobian( quadInside[ pt ], duIn );
339 uOutLocal.evaluate( quadOutside[ pt ], vuOut );
340 uOutLocal.jacobian( quadOutside[ pt ], duOut );
341 RangeType jump = vuIn - vuOut;
343 JacobianRangeType dvalue;
344 for (
int r=0;r<dimRange;++r)
345 for (
int d=0;d<dimDomain;++d)
346 dvalue[r][d] = -0.5 * normal[d] * jump[r];
347 JacobianRangeType aduIn,aduOut;
348 model().init( outside );
349 model().flux( quadOutside[ pt ], vuOut, duOut, aduOut );
350 auto pFactor = model().penalty( quadOutside[ pt ], vuOut );
351 model().init( entity );
352 model().flux( quadInside[ pt ], vuIn, duIn, aduIn );
353 JacobianRangeType affine;
354 model().flux( quadInside[ pt ], RangeType(0), JacobianRangeType(0), affine);
355 pFactor += model().penalty( quadInside[ pt ], vuIn );
360 JacobianRangeType advalue;
363 for (
unsigned int r=0;r<dimRange;++r)
364 value[r] *= beta * pFactor[r]/2.;
368 aduIn.umv(normal,value);
372 model().flux( quadInside[ pt ], vuIn, dvalue, advalue );
377 wLocal.axpy( quadInside[ pt ], value, advalue );
381 else if( intersection.boundary() )
383 std::array<int,dimRange> components;
385 model().isDirichletIntersection( intersection, components);
387 typedef typename IntersectionType::Geometry IntersectionGeometryType;
388 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
391 const double intersectionArea = intersectionGeometry.volume();
392 const double beta = penalty()(intersection,intersectionArea,area,area);
394 FaceQuadratureType quadInside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
395 const size_t numQuadraturePoints = quadInside.nop();
397 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
399 const typename FaceQuadratureType::LocalCoordinateType &x = quadInside.localPoint( pt );
400 const DomainType normal = intersection.integrationOuterNormal( x );
401 const double weight = quadInside.weight( pt );
404 model().dirichlet(1, quadInside[pt], bndValue);
407 JacobianRangeType dvalue,advalue;
410 JacobianRangeType duIn, aduIn;
411 uLocal.evaluate( quadInside[ pt ], vuIn );
412 uLocal.jacobian( quadInside[ pt ], duIn );
417 auto pFactor = model().penalty( quadInside[ pt ], vuIn );
419 for (
unsigned int r=0;r<dimRange;++r)
420 value[r] *= beta * pFactor[r] * intersectionGeometry.integrationElement( x );
424 for (
int r=0;r<dimRange;++r)
425 for (
int d=0;d<dimDomain;++d)
426 dvalue[r][d] = -0.5 * normal[d] * jump[r];
428 model().flux( quadInside[ pt ], jump, dvalue, advalue );
432 model().flux( quadInside[ pt ], vuIn, duIn, aduIn );
433 aduIn.mmv(normal,value);
435 for (
int r=0;r<dimRange;++r)
444 wLocal.axpy( quadInside[ pt ], value, advalue );
458template<
class JacobianOperator,
class Model,
class Penalty >
460void DifferentiableDGEllipticOperator< JacobianOperator, Model, Penalty >
461 ::apply (
const GF &u, JacobianOperator &jOp )
const
465 typedef typename DiscreteFunctionSpaceType::BasisFunctionSetType BasisFunctionSetType;
468 const DomainDiscreteFunctionSpaceType &domainSpace = jOp.
domainSpace();
469 const RangeDiscreteFunctionSpaceType &rangeSpace = jOp.rangeSpace();
472 jOp.reserve(stencil);
475 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
476 TmpLocalMatrixType jLocal( domainSpace, rangeSpace );
477 TmpLocalMatrixType localOpNb( domainSpace, rangeSpace );
479 const GridPartType& gridPart = rangeSpace.gridPart();
481 const unsigned int numDofs = rangeSpace.blockMapper().maxNumDofs() *
482 DiscreteFunctionSpaceType :: localBlockSize ;
484 std::vector< RangeType > phi( numDofs );
485 std::vector< JacobianRangeType > dphi( numDofs );
487 std::vector< RangeType > phiNb( numDofs );
488 std::vector< JacobianRangeType > dphiNb( numDofs );
493 const IteratorType end = rangeSpace.end();
494 for( IteratorType it = rangeSpace.begin(); it != end; ++it )
496 const EntityType &entity = *it;
501 bool needsCalculation = model().init( entity );
502 if (! needsCalculation )
507 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
509 jLocal.bind( entity, entity );
512 const BasisFunctionSetType &baseSet = jLocal.domainBasisFunctionSet();
513 const unsigned int numBaseFunctions = baseSet.size();
515 QuadratureType quadrature( entity, 2*rangeSpace.order() );
516 const size_t numQuadraturePoints = quadrature.nop();
517 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
519 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
520 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
523 baseSet.evaluateAll( quadrature[ pt ], phi );
526 baseSet.jacobianAll( quadrature[ pt ], dphi );
530 JacobianRangeType jacU0;
531 uLocal.evaluate( quadrature[ pt ], u0 );
532 uLocal.jacobian( quadrature[ pt ], jacU0 );
535 JacobianRangeType adphi( 0 );
536 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
539 model().linSource( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[ localCol ], aphi );
542 model().linFlux( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[ localCol ], adphi );
545 jLocal.column( localCol ).axpy( phi, dphi, aphi, adphi, weight );
548 if ( rangeSpace.continuous() )
550 jOp.addLocalMatrix( entity, entity, jLocal );
555 double area = geometry.volume();
556 const IntersectionIteratorType endiit = gridPart.iend( entity );
557 for ( IntersectionIteratorType iit = gridPart.ibegin( entity );
558 iit != endiit ; ++ iit )
560 const IntersectionType& intersection = *iit ;
562 if( intersection.neighbor() )
564 const EntityType neighbor = intersection.outside() ;
566 typedef typename IntersectionType::Geometry IntersectionGeometryType;
567 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
571 localOpNb.bind( neighbor, entity );
575 const BasisFunctionSetType &baseSetNb = localOpNb.domainBasisFunctionSet();
579 const double intersectionArea = intersectionGeometry.volume();
580 const double beta = penalty()(intersection,intersectionArea,area,neighbor.geometry().volume());
583 FaceQuadratureType faceQuadInside(gridPart, intersection, 2*rangeSpace.order() + 1,
584 FaceQuadratureType::INSIDE);
585 FaceQuadratureType faceQuadOutside(gridPart, intersection, 2*rangeSpace.order() + 1,
586 FaceQuadratureType::OUTSIDE);
588 const size_t numFaceQuadPoints = faceQuadInside.nop();
589 for(
size_t pt = 0; pt < numFaceQuadPoints; ++pt )
591 const typename FaceQuadratureType::LocalCoordinateType &x = faceQuadInside.localPoint( pt );
592 DomainType normal = intersection.integrationOuterNormal( x );
593 double faceVol = normal.two_norm();
596 const double quadWeight = faceQuadInside.weight( pt );
597 const double weight = quadWeight * faceVol;
601 JacobianRangeType u0EnJac;
602 uLocal.evaluate( faceQuadInside[ pt ], u0En );
603 uLocal.jacobian( faceQuadInside[ pt ], u0EnJac );
610 baseSet.evaluateAll( faceQuadInside[ pt ], phi );
613 baseSet.jacobianAll( faceQuadInside[ pt ], dphi );
620 baseSetNb.evaluateAll( faceQuadOutside[ pt ], phiNb );
623 baseSetNb.jacobianAll( faceQuadOutside[ pt ], dphiNb );
625 model().init( entity );
626 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
628 JacobianRangeType adphiEn = dphi[ i ];
629 model().linFlux( u0En, u0EnJac, faceQuadInside[ pt ], phi[i], adphiEn, dphi[ i ] );
631 auto pFactor = model().penalty( faceQuadInside[ pt ], u0En );
632 model().init( neighbor );
633 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
635 JacobianRangeType adphiNb = dphiNb[ i ];
636 model().linFlux( u0En, u0EnJac, faceQuadOutside[ pt ], phiNb[i], adphiNb, dphiNb[ i ] );
638 pFactor += model().penalty( faceQuadOutside[ pt ], u0En );
639 model().init( entity );
643 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
645 RangeType valueEn(0), valueNb(0);
646 JacobianRangeType dvalueEn(0), dvalueNb(0);
649 dphi[localCol].usmv( -0.5, normal, valueEn );
652 dphiNb[localCol].usmv( -0.5, normal, valueNb );
655 for (
unsigned int r=0;r<dimRange;++r)
657 valueEn[r] += beta*pFactor[r]/2.*phi[localCol][r];
658 valueNb[r] -= beta*pFactor[r]/2.*phiNb[localCol][r];
661 for (
int r=0; r< dimRange; ++r )
662 for (
int d=0; d< dimDomain; ++d )
665 dvalueEn[r][d] = - 0.5 * normal[d] * phi[localCol][r];
668 dvalueNb[r][d] = 0.5 * normal[d] * phiNb[localCol][r];
671 jLocal.column( localCol ).axpy( phi, dphi, valueEn, dvalueEn, weight );
672 localOpNb.column( localCol ).axpy( phi, dphi, valueNb, dvalueNb, weight );
675 jOp.addLocalMatrix( neighbor, entity, localOpNb );
678 else if( intersection.boundary() )
680 std::array<int,dimRange> components;
682 model().isDirichletIntersection( intersection, components);
684 typedef typename IntersectionType::Geometry IntersectionGeometryType;
685 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
688 const double intersectionArea = intersectionGeometry.volume();
689 const double beta = penalty()(intersection,intersectionArea,area,area);
692 FaceQuadratureType faceQuadInside(gridPart, intersection, 2*rangeSpace.order() + 1,
693 FaceQuadratureType::INSIDE);
695 const size_t numFaceQuadPoints = faceQuadInside.nop();
696 for(
size_t pt = 0; pt < numFaceQuadPoints; ++pt )
698 const typename FaceQuadratureType::LocalCoordinateType &x = faceQuadInside.localPoint( pt );
699 DomainType normal = intersection.integrationOuterNormal( x );
700 double faceVol = normal.two_norm();
703 const double quadWeight = faceQuadInside.weight( pt );
704 const double weight = quadWeight * faceVol;
707 JacobianRangeType u0EnJac;
708 uLocal.evaluate( faceQuadInside[ pt ], u0En );
709 uLocal.jacobian( faceQuadInside[ pt ], u0EnJac );
716 baseSet.evaluateAll( faceQuadInside[ pt ], phi );
719 baseSet.jacobianAll( faceQuadInside[ pt ], dphi );
721 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
723 JacobianRangeType adphiEn = dphi[ i ];
724 model().linFlux( u0En, u0EnJac, faceQuadInside[ pt ], phi[i], adphiEn, dphi[ i ] );
727 auto pFactor = model().penalty( faceQuadInside[ pt ], u0En );
729 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
731 RangeType valueEn(0);
732 JacobianRangeType dvalueEn(0);
735 dphi[localCol].usmv( -1.0, normal, valueEn );
738 for (
unsigned int r=0;r<dimRange;++r)
739 valueEn[r] += beta*pFactor[r]*phi[ localCol ][r];
742 for (
int r=0; r< dimRange; ++r )
743 for (
int d=0; d< dimDomain; ++d )
746 dvalueEn[r][d] = - 0.5 * normal[d] * phi[localCol][r];
749 for (
int r=0;r<dimRange;++r)
756 jLocal.column( localCol ).axpy( phi, dphi, valueEn, dvalueEn, weight );
761 jOp.addLocalMatrix( entity, entity, jLocal );
Traits::IntersectionIteratorType IntersectionIteratorType
type of intersection iterator
Definition: adaptiveleafgridpart.hh:92
quadrature class supporting base function caching
Definition: cachingquadrature.hh:106
abstract differentiable operator
Definition: differentiableoperator.hh:29
JacobianOperator JacobianOperatorType
type of linear operator modelling the operator's Jacobian
Definition: differentiableoperator.hh:35
virtual void jacobian(const DomainFunctionType &u, JacobianOperatorType &jOp) const =0
obtain linearization
RangeFunctionType::RangeFieldType RangeFieldType
field type of the operator's range
Definition: differentiableoperator.hh:45
GridPartType::template Codim< Traits::codimension >::IteratorType IteratorType
type of iterator for grid traversal
Definition: discretefunctionspace.hh:222
static const int dimDomain
dimension of the domain
Definition: localfunction.hh:120
FunctionSpaceType::RangeType RangeType
type of range vectors, i.e., type of function values
Definition: localfunction.hh:110
FunctionSpaceType::JacobianRangeType JacobianRangeType
type of the Jacobian, i.e., type of evaluated Jacobian matrix
Definition: localfunction.hh:112
static const int dimRange
dimension of the range
Definition: localfunction.hh:122
FunctionSpaceType::RangeFieldType RangeFieldType
field type of the range
Definition: localfunction.hh:106
const DomainSpaceType & domainSpace() const
access to the domain space
Definition: localmatrix.hh:382
A local matrix with a small array as storage.
Definition: temporarylocalmatrix.hh:100
forward declaration
Definition: discretefunction.hh:51
TupleDiscreteFunctionSpace< typename DiscreteFunctions::DiscreteFunctionSpaceType ... > DiscreteFunctionSpaceType
type for the discrete function space this function lives in
Definition: discretefunction.hh:69
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Stencil contaning the entries (en,en) and (en,nb) for all entities en in the space and neighbors nb o...
Definition: stencil.hh:387
abstract operator
Definition: operator.hh:34
virtual void operator()(const DomainFunctionType &u, RangeFunctionType &w) const =0
application operator