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 ) )
120 DGEllipticOperator (
const DiscreteFunctionSpaceType &dSpace,
121 const DiscreteFunctionSpaceType &rSpace,
122 const ModelType &model,
123 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
125 penalty_( dSpace, parameter.getValue< double >(
"penalty", 40 ) )
131 virtual void operator() (
const DomainDiscreteFunctionType &u, RangeDiscreteFunctionType &w )
const
134 void apply(
const GF &u, RangeDiscreteFunctionType &w )
const;
137 const ModelType &model ()
const {
return model_; }
138 Penalty penalty()
const {
return penalty_; }
141 const ModelType &model_;
148template<
class JacobianOperator,
class Model,
149 class Penalty = DefaultPenalty<typename JacobianOperator::DomainFunctionType::DiscreteFunctionSpaceType > >
150struct DifferentiableDGEllipticOperator
151:
public DGEllipticOperator< typename JacobianOperator::DomainFunctionType, Model, Penalty >,
154 typedef DGEllipticOperator< typename JacobianOperator::DomainFunctionType, Model, Penalty > BaseType;
159 typedef typename BaseType::ModelType ModelType;
160 typedef typename BaseType::DomainDiscreteFunctionType DomainDiscreteFunctionType;
161 typedef typename BaseType::RangeDiscreteFunctionType RangeDiscreteFunctionType;
164 typedef typename DomainDiscreteFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
165 typedef typename DomainDiscreteFunctionType::LocalFunctionType DomainLocalFunctionType;
166 typedef typename DomainLocalFunctionType::RangeType DomainRangeType;
167 typedef typename DomainLocalFunctionType::JacobianRangeType DomainJacobianRangeType;
168 typedef typename RangeDiscreteFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
169 typedef typename RangeDiscreteFunctionType::LocalFunctionType RangeLocalFunctionType;
170 typedef typename RangeLocalFunctionType::RangeType RangeRangeType;
171 typedef typename RangeLocalFunctionType::JacobianRangeType RangeJacobianRangeType;
180 typedef typename IteratorType::Entity EntityType;
183 typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
185 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
187 typedef typename IntersectionIteratorType::Intersection IntersectionType;
188 typedef typename IntersectionType::Geometry IntersectionGeometryType;
190 typedef Dune::Fem::ElementQuadrature< GridPartType, 1 > FaceQuadratureType;
198 DifferentiableDGEllipticOperator (
const DiscreteFunctionSpaceType &space,
199 const ModelType &model,
200 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
201 : BaseType( space, model, parameter )
203 DifferentiableDGEllipticOperator (
const DiscreteFunctionSpaceType &dSpace,
204 const DiscreteFunctionSpaceType &rSpace,
205 const ModelType &model,
206 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
207 : BaseType( dSpace, rSpace, model, parameter )
211 void jacobian (
const DomainDiscreteFunctionType &u, JacobianOperatorType &jOp )
const
213 template <
class Gr
idFunctionType>
214 void apply (
const GridFunctionType &u, JacobianOperatorType &jOp )
const;
215 using BaseType::apply;
218 using BaseType::model;
219 using BaseType::penalty;
225template<
class RangeDiscreteFunction,
class Model,
class Penalty >
227void DGEllipticOperator< RangeDiscreteFunction, Model, Penalty >
228 ::apply(
const GF &u, RangeDiscreteFunctionType &w )
const
234 const DiscreteFunctionSpaceType &dfSpace = w.space();
235 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
236 Dune::Fem::ConstLocalFunction< GF > uOutLocal( u );
237 Dune::Fem::AddLocalContribution< RangeDiscreteFunctionType > wLocal( w );
240 const IteratorType end = dfSpace.end();
241 for( IteratorType it = dfSpace.begin(); it != end; ++it )
244 const EntityType &entity = *it;
246 bool needsCalculation = model().init( entity );
247 if (! needsCalculation )
254 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
255 auto wGuard = Dune::Fem::bindGuard( wLocal, entity );
258 const int quadOrder = uLocal.order() + wLocal.order();
261 QuadratureType quadrature( entity, quadOrder );
262 const size_t numQuadraturePoints = quadrature.nop();
263 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
265 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
266 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
269 uLocal.evaluate( quadrature[ pt ], vu );
270 JacobianRangeType du;
271 uLocal.jacobian( quadrature[ pt ], du );
275 model().source( quadrature[ pt ], vu, du, avu );
279 JacobianRangeType adu( 0 );
281 model().flux( quadrature[ pt ], vu, du, adu );
285 wLocal.axpy( quadrature[ pt ], avu, adu );
288 if ( ! dfSpace.continuous() )
290 const double area = entity.geometry().volume();
291 const IntersectionIteratorType iitend = dfSpace.gridPart().iend( entity );
292 for( IntersectionIteratorType iit = dfSpace.gridPart().ibegin( entity ); iit != iitend; ++iit )
295 const IntersectionType &intersection = *iit;
296 if ( intersection.neighbor() )
298 const EntityType outside = intersection.outside() ;
300 typedef typename IntersectionType::Geometry IntersectionGeometryType;
301 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
304 const double intersectionArea = intersectionGeometry.volume();
305 const double beta = penalty()(intersection,intersectionArea,area,outside.geometry().volume());
307 auto uOutGuard = Dune::Fem::bindGuard( uOutLocal, outside );
309 FaceQuadratureType quadInside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
310 FaceQuadratureType quadOutside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::OUTSIDE );
311 const size_t numQuadraturePoints = quadInside.nop();
314 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
318 const typename FaceQuadratureType::LocalCoordinateType &x = quadInside.localPoint( pt );
319 DomainType normal = intersection.integrationOuterNormal( x );
320 double faceVol = normal.two_norm();
322 const double weight = quadInside.weight( pt ) * faceVol;
324 RangeType vuIn,vuOut;
325 JacobianRangeType duIn, duOut;
326 uLocal.evaluate( quadInside[ pt ], vuIn );
327 uLocal.jacobian( quadInside[ pt ], duIn );
328 uOutLocal.evaluate( quadOutside[ pt ], vuOut );
329 uOutLocal.jacobian( quadOutside[ pt ], duOut );
330 RangeType jump = vuIn - vuOut;
332 JacobianRangeType dvalue;
333 for (
int r=0;r<dimRange;++r)
334 for (
int d=0;d<dimDomain;++d)
335 dvalue[r][d] = -0.5 * normal[d] * jump[r];
336 JacobianRangeType aduIn,aduOut;
337 model().init( outside );
338 model().flux( quadOutside[ pt ], vuOut, duOut, aduOut );
339 auto pFactor = model().penalty( quadOutside[ pt ], vuOut );
340 model().init( entity );
341 model().flux( quadInside[ pt ], vuIn, duIn, aduIn );
342 JacobianRangeType affine;
343 model().flux( quadInside[ pt ], RangeType(0), JacobianRangeType(0), affine);
344 pFactor += model().penalty( quadInside[ pt ], vuIn );
349 JacobianRangeType advalue;
352 for (
unsigned int r=0;r<dimRange;++r)
353 value[r] *= beta * pFactor[r]/2.;
357 aduIn.umv(normal,value);
361 model().flux( quadInside[ pt ], vuIn, dvalue, advalue );
366 wLocal.axpy( quadInside[ pt ], value, advalue );
370 else if( intersection.boundary() )
372 std::array<int,dimRange> components;
374 model().isDirichletIntersection( intersection, components);
376 typedef typename IntersectionType::Geometry IntersectionGeometryType;
377 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
380 const double intersectionArea = intersectionGeometry.volume();
381 const double beta = penalty()(intersection,intersectionArea,area,area);
383 FaceQuadratureType quadInside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
384 const size_t numQuadraturePoints = quadInside.nop();
386 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
388 const typename FaceQuadratureType::LocalCoordinateType &x = quadInside.localPoint( pt );
389 const DomainType normal = intersection.integrationOuterNormal( x );
390 const double weight = quadInside.weight( pt );
393 model().dirichlet(1, quadInside[pt], bndValue);
396 JacobianRangeType dvalue,advalue;
399 JacobianRangeType duIn, aduIn;
400 uLocal.evaluate( quadInside[ pt ], vuIn );
401 uLocal.jacobian( quadInside[ pt ], duIn );
406 auto pFactor = model().penalty( quadInside[ pt ], vuIn );
408 for (
unsigned int r=0;r<dimRange;++r)
409 value[r] *= beta * pFactor[r] * intersectionGeometry.integrationElement( x );
413 for (
int r=0;r<dimRange;++r)
414 for (
int d=0;d<dimDomain;++d)
415 dvalue[r][d] = -0.5 * normal[d] * jump[r];
417 model().flux( quadInside[ pt ], jump, dvalue, advalue );
421 model().flux( quadInside[ pt ], vuIn, duIn, aduIn );
422 aduIn.mmv(normal,value);
424 for (
int r=0;r<dimRange;++r)
433 wLocal.axpy( quadInside[ pt ], value, advalue );
447template<
class JacobianOperator,
class Model,
class Penalty >
449void DifferentiableDGEllipticOperator< JacobianOperator, Model, Penalty >
450 ::apply (
const GF &u, JacobianOperator &jOp )
const
454 typedef typename DiscreteFunctionSpaceType::BasisFunctionSetType BasisFunctionSetType;
457 const DomainDiscreteFunctionSpaceType &domainSpace = jOp.
domainSpace();
458 const RangeDiscreteFunctionSpaceType &rangeSpace = jOp.rangeSpace();
461 jOp.reserve(stencil);
464 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
465 TmpLocalMatrixType jLocal( domainSpace, rangeSpace );
466 TmpLocalMatrixType localOpNb( domainSpace, rangeSpace );
468 const GridPartType& gridPart = rangeSpace.gridPart();
470 const unsigned int numDofs = rangeSpace.blockMapper().maxNumDofs() *
471 DiscreteFunctionSpaceType :: localBlockSize ;
473 std::vector< RangeType > phi( numDofs );
474 std::vector< JacobianRangeType > dphi( numDofs );
476 std::vector< RangeType > phiNb( numDofs );
477 std::vector< JacobianRangeType > dphiNb( numDofs );
480 const IteratorType end = rangeSpace.end();
481 for( IteratorType it = rangeSpace.begin(); it != end; ++it )
483 const EntityType &entity = *it;
485 bool needsCalculation = model().init( entity );
486 if (! needsCalculation )
491 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
493 jLocal.bind( entity, entity );
496 const BasisFunctionSetType &baseSet = jLocal.domainBasisFunctionSet();
497 const unsigned int numBaseFunctions = baseSet.size();
499 QuadratureType quadrature( entity, 2*rangeSpace.order() );
500 const size_t numQuadraturePoints = quadrature.nop();
501 for(
size_t pt = 0; pt < numQuadraturePoints; ++pt )
503 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
504 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
507 baseSet.evaluateAll( quadrature[ pt ], phi );
510 baseSet.jacobianAll( quadrature[ pt ], dphi );
514 JacobianRangeType jacU0;
515 uLocal.evaluate( quadrature[ pt ], u0 );
516 uLocal.jacobian( quadrature[ pt ], jacU0 );
519 JacobianRangeType adphi( 0 );
520 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
523 model().linSource( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[ localCol ], aphi );
526 model().linFlux( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[ localCol ], adphi );
529 jLocal.column( localCol ).axpy( phi, dphi, aphi, adphi, weight );
532 if ( rangeSpace.continuous() )
534 jOp.addLocalMatrix( entity, entity, jLocal );
539 double area = geometry.volume();
540 const IntersectionIteratorType endiit = gridPart.iend( entity );
541 for ( IntersectionIteratorType iit = gridPart.ibegin( entity );
542 iit != endiit ; ++ iit )
544 const IntersectionType& intersection = *iit ;
546 if( intersection.neighbor() )
548 const EntityType neighbor = intersection.outside() ;
550 typedef typename IntersectionType::Geometry IntersectionGeometryType;
551 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
555 localOpNb.bind( neighbor, entity );
559 const BasisFunctionSetType &baseSetNb = localOpNb.domainBasisFunctionSet();
563 const double intersectionArea = intersectionGeometry.volume();
564 const double beta = penalty()(intersection,intersectionArea,area,neighbor.geometry().volume());
567 FaceQuadratureType faceQuadInside(gridPart, intersection, 2*rangeSpace.order() + 1,
568 FaceQuadratureType::INSIDE);
569 FaceQuadratureType faceQuadOutside(gridPart, intersection, 2*rangeSpace.order() + 1,
570 FaceQuadratureType::OUTSIDE);
572 const size_t numFaceQuadPoints = faceQuadInside.nop();
573 for(
size_t pt = 0; pt < numFaceQuadPoints; ++pt )
575 const typename FaceQuadratureType::LocalCoordinateType &x = faceQuadInside.localPoint( pt );
576 DomainType normal = intersection.integrationOuterNormal( x );
577 double faceVol = normal.two_norm();
580 const double quadWeight = faceQuadInside.weight( pt );
581 const double weight = quadWeight * faceVol;
585 JacobianRangeType u0EnJac;
586 uLocal.evaluate( faceQuadInside[ pt ], u0En );
587 uLocal.jacobian( faceQuadInside[ pt ], u0EnJac );
594 baseSet.evaluateAll( faceQuadInside[ pt ], phi );
597 baseSet.jacobianAll( faceQuadInside[ pt ], dphi );
604 baseSetNb.evaluateAll( faceQuadOutside[ pt ], phiNb );
607 baseSetNb.jacobianAll( faceQuadOutside[ pt ], dphiNb );
609 model().init( entity );
610 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
612 JacobianRangeType adphiEn = dphi[ i ];
613 model().linFlux( u0En, u0EnJac, faceQuadInside[ pt ], phi[i], adphiEn, dphi[ i ] );
615 auto pFactor = model().penalty( faceQuadInside[ pt ], u0En );
616 model().init( neighbor );
617 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
619 JacobianRangeType adphiNb = dphiNb[ i ];
620 model().linFlux( u0En, u0EnJac, faceQuadOutside[ pt ], phiNb[i], adphiNb, dphiNb[ i ] );
622 pFactor += model().penalty( faceQuadOutside[ pt ], u0En );
623 model().init( entity );
627 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
629 RangeType valueEn(0), valueNb(0);
630 JacobianRangeType dvalueEn(0), dvalueNb(0);
633 dphi[localCol].usmv( -0.5, normal, valueEn );
636 dphiNb[localCol].usmv( -0.5, normal, valueNb );
639 for (
unsigned int r=0;r<dimRange;++r)
641 valueEn[r] += beta*pFactor[r]/2.*phi[localCol][r];
642 valueNb[r] -= beta*pFactor[r]/2.*phiNb[localCol][r];
645 for (
int r=0; r< dimRange; ++r )
646 for (
int d=0; d< dimDomain; ++d )
649 dvalueEn[r][d] = - 0.5 * normal[d] * phi[localCol][r];
652 dvalueNb[r][d] = 0.5 * normal[d] * phiNb[localCol][r];
655 jLocal.column( localCol ).axpy( phi, dphi, valueEn, dvalueEn, weight );
656 localOpNb.column( localCol ).axpy( phi, dphi, valueNb, dvalueNb, weight );
659 jOp.addLocalMatrix( neighbor, entity, localOpNb );
662 else if( intersection.boundary() )
664 std::array<int,dimRange> components;
666 model().isDirichletIntersection( intersection, components);
668 typedef typename IntersectionType::Geometry IntersectionGeometryType;
669 const IntersectionGeometryType &intersectionGeometry = intersection.geometry();
672 const double intersectionArea = intersectionGeometry.volume();
673 const double beta = penalty()(intersection,intersectionArea,area,area);
676 FaceQuadratureType faceQuadInside(gridPart, intersection, 2*rangeSpace.order() + 1,
677 FaceQuadratureType::INSIDE);
679 const size_t numFaceQuadPoints = faceQuadInside.nop();
680 for(
size_t pt = 0; pt < numFaceQuadPoints; ++pt )
682 const typename FaceQuadratureType::LocalCoordinateType &x = faceQuadInside.localPoint( pt );
683 DomainType normal = intersection.integrationOuterNormal( x );
684 double faceVol = normal.two_norm();
687 const double quadWeight = faceQuadInside.weight( pt );
688 const double weight = quadWeight * faceVol;
691 JacobianRangeType u0EnJac;
692 uLocal.evaluate( faceQuadInside[ pt ], u0En );
693 uLocal.jacobian( faceQuadInside[ pt ], u0EnJac );
700 baseSet.evaluateAll( faceQuadInside[ pt ], phi );
703 baseSet.jacobianAll( faceQuadInside[ pt ], dphi );
705 for(
unsigned int i = 0; i < numBaseFunctions; ++i )
707 JacobianRangeType adphiEn = dphi[ i ];
708 model().linFlux( u0En, u0EnJac, faceQuadInside[ pt ], phi[i], adphiEn, dphi[ i ] );
711 auto pFactor = model().penalty( faceQuadInside[ pt ], u0En );
713 for(
unsigned int localCol = 0; localCol < numBaseFunctions; ++localCol )
715 RangeType valueEn(0);
716 JacobianRangeType dvalueEn(0);
719 dphi[localCol].usmv( -1.0, normal, valueEn );
722 for (
unsigned int r=0;r<dimRange;++r)
723 valueEn[r] += beta*pFactor[r]*phi[ localCol ][r];
726 for (
int r=0; r< dimRange; ++r )
727 for (
int d=0; d< dimDomain; ++d )
730 dvalueEn[r][d] = - 0.5 * normal[d] * phi[localCol][r];
733 for (
int r=0;r<dimRange;++r)
740 jLocal.column( localCol ).axpy( phi, dphi, valueEn, dvalueEn, weight );
745 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:101
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