1#ifndef DUNE_FEM_SCHEMES_MOLGALERKIN_HH
2#define DUNE_FEM_SCHEMES_MOLGALERKIN_HH
5#include <dune/fem/schemes/galerkin.hh>
6#include <dune/fem/function/localfunction/temporary.hh>
7#include <dune/fem/common/bindguard.hh>
17 template <
typename DomainFunction,
typename RangeFunction >
18 class PetscLinearOperator ;
24 template<
class Integrands,
class DomainFunction,
class RangeFunction = DomainFunction >
25 struct MOLGalerkinOperator
26 :
public virtual Operator< DomainFunction, RangeFunction >
28 typedef DomainFunction DomainFunctionType;
29 typedef RangeFunction RangeFunctionType;
32 static_assert( std::is_same< typename DomainFunctionType::GridPartType, typename RangeFunctionType::GridPartType >::value,
"DomainFunction and RangeFunction must be defined on the same grid part." );
34 typedef typename RangeFunctionType::GridPartType GridPartType;
37 typedef Impl::GalerkinOperator< GridPartType > GalerkinOperatorImplType;
38 typedef Impl::LocalGalerkinOperator< Integrands > LocalGalerkinOperatorImplType;
40 typedef typename RangeFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
42 typedef typename LocalGalerkinOperatorImplType::template QuadratureSelector<
43 DiscreteFunctionSpaceType > :: InteriorQuadratureType InteriorQuadratureType;
45 typedef LocalMassMatrix< DiscreteFunctionSpaceType, InteriorQuadratureType > LocalMassMatrixType ;
47 template<
class... Args >
48 explicit MOLGalerkinOperator (
const GridPartType &gridPart, Args &&... args )
49 : iterators_( gridPart ),
51 localOp_( gridPart,
std::forward< Args >( args )... ),
52 gridSizeInterior_( 0 ),
57 void setCommunicate(
const bool communicate )
59 communicate_ = communicate;
62 std::cout <<
"MOLGalerkinOperator::setCommunicate: communicate was disabled!" << std::endl;
66 void setQuadratureOrders(
unsigned int interior,
unsigned int surface)
68 size_t size = localOp_.size();
69 for(
size_t i=0; i<
size; ++i )
70 localOp_[ i ].setQuadratureOrders(interior,surface);
73 virtual void operator() (
const DomainFunctionType &u, RangeFunctionType &w )
const final override
78 template<
class Gr
idFunction >
79 void operator() (
const GridFunction &u, RangeFunctionType &w )
const
84 const GridPartType &gridPart ()
const {
return op().gridPart(); }
86 typedef Integrands ModelType;
87 typedef Integrands DirichletModelType;
88 ModelType &model()
const {
return localOperator().model(); }
90 [[deprecated(
"Use localOperator instead!")]]
91 const GalerkinOperatorImplType& impl()
const {
return localOperator(); }
93 const LocalGalerkinOperatorImplType& localOperator()
const {
return (*localOp_); }
95 std::size_t gridSizeInterior ()
const {
return gridSizeInterior_; }
98 const GalerkinOperatorImplType& op()
const {
return (*opImpl_); }
100 template <
class Iterators>
101 void applyInverseMass(
const Iterators& iterators, RangeFunctionType& w )
const
104 typedef TemporaryLocalFunction< typename RangeFunctionType::DiscreteFunctionSpaceType > TemporaryLocalFunctionType;
105 TemporaryLocalFunctionType wLocal( w.space() );
106 LocalMassMatrixType localMassMatrix( w.space(), localOperator().interiorQuadratureOrder( w.space().order() ) );
110 for(
const auto& entity : iterators )
113 auto guard = bindGuard( wLocal, entity );
115 w.getLocalDofs( entity, wLocal.localDofVector() );
119 localMassMatrix.applyInverse( entity, wLocal );
122 w.setLocalDofs( entity, wLocal.localDofVector() );
126 template<
class Gr
idFunction >
127 void evaluate(
const GridFunction &u, RangeFunctionType &w )
const
132 std::shared_mutex mutex;
134 auto doEval = [
this, &u, &w, &mutex] ()
137 std::tuple< const LocalGalerkinOperatorImplType& > integrands( localOperator() );
138 this->op().evaluate( u, w, this->iterators_, integrands, mutex );
147 bool singleThreadModeError = false ;
151 MPIManager :: run ( doEval );
154 gridSizeInterior_ = Impl::accumulateGridSize( opImpl_ );
156 catch (
const SingleThreadModeError& e )
158 singleThreadModeError =
true;
162 auto doInvMass = [
this, &w] ()
164 this->applyInverseMass( this->iterators_, w );
167 if( ! singleThreadModeError )
171 MPIManager :: run ( doInvMass );
173 catch (
const SingleThreadModeError& e )
175 singleThreadModeError =
true;
180 if( singleThreadModeError )
185 std::tuple< const LocalGalerkinOperatorImplType& > integrands( localOperator() );
186 op().evaluate( u, w, iterators_, integrands );
189 gridSizeInterior_ = Impl::accumulateGridSize( opImpl_ );
191 applyInverseMass( iterators_, w );
200 mutable ThreadIteratorType iterators_;
204 mutable std::size_t gridSizeInterior_;
213 template<
class Integrands,
class JacobianOperator >
214 class MOLDifferentiableGalerkinOperator
215 :
public MOLGalerkinOperator< Integrands, typename JacobianOperator::DomainFunctionType, typename JacobianOperator::RangeFunctionType >,
216 public DifferentiableOperator< JacobianOperator >
218 typedef MOLGalerkinOperator< Integrands, typename JacobianOperator::DomainFunctionType, typename JacobianOperator::RangeFunctionType > BaseType;
221 typedef JacobianOperator JacobianOperatorType;
223 typedef typename BaseType::DomainFunctionType DomainFunctionType;
224 typedef typename BaseType::RangeFunctionType RangeFunctionType;
225 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
226 typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
228 typedef typename BaseType::LocalGalerkinOperatorImplType LocalGalerkinOperatorImplType;
230 typedef DiagonalAndNeighborStencil< DomainDiscreteFunctionSpaceType, RangeDiscreteFunctionSpaceType > DiagonalAndNeighborStencilType;
231 typedef DiagonalStencil< DomainDiscreteFunctionSpaceType, RangeDiscreteFunctionSpaceType > DiagonalStencilType;
233 typedef typename BaseType::GridPartType GridPartType;
235 template<
class... Args >
236 explicit MOLDifferentiableGalerkinOperator (
const DomainDiscreteFunctionSpaceType &dSpace,
237 const RangeDiscreteFunctionSpaceType &rSpace,
239 : BaseType( rSpace.gridPart(),
std::forward< Args >( args )... ),
242 domainSpaceSequence_(dSpace.sequence()),
243 rangeSpaceSequence_(rSpace.sequence()),
244 stencilDAN_(), stencilD_()
247 stencilDAN_.reset(
new DiagonalAndNeighborStencilType( dSpace_, rSpace_ ) );
249 stencilD_.reset(
new DiagonalStencilType( dSpace_, rSpace_ ) );
252 virtual void jacobian (
const DomainFunctionType &u, JacobianOperatorType &jOp )
const final override
258 template<
class Gr
idFunction >
259 void jacobian (
const GridFunction &u, JacobianOperatorType &jOp )
const
264 const DomainDiscreteFunctionSpaceType& domainSpace()
const
268 const RangeDiscreteFunctionSpaceType& rangeSpace()
const
273 const RangeDiscreteFunctionSpaceType& space()
const
278 using BaseType::gridPart;
279 using BaseType::localOperator;
283 using BaseType::iterators_;
284 using BaseType::gridSizeInterior_;
287 bool hasSkeleton()
const
289 std::tuple< const LocalGalerkinOperatorImplType& > integrands( localOperator() );
290 return op().hasSkeleton( integrands );
293 void prepare( JacobianOperatorType& jOp )
const
295 if ( domainSpaceSequence_ != domainSpace().sequence()
296 || rangeSpaceSequence_ != rangeSpace().sequence() )
298 domainSpaceSequence_ = domainSpace().sequence();
299 rangeSpaceSequence_ = rangeSpace().sequence();
302 assert( stencilDAN_ );
303 stencilDAN_->update();
313 jOp.reserve( *stencilDAN_ );
315 jOp.reserve( *stencilD_ );
320 template <
class Gr
idFunction >
321 void assemble(
const GridFunction &u, JacobianOperatorType &jOp )
const
326 bool singleThreadModeError =
false;
327 std::shared_mutex mutex;
329 auto doAssemble = [
this, &u, &jOp, &mutex] ()
331 std::tuple< const LocalGalerkinOperatorImplType& > integrands( localOperator() );
333 this->op().assemble( u, jOp, this->iterators_, integrands, mutex );
338 MPIManager :: run ( doAssemble );
341 gridSizeInterior_ = Impl::accumulateGridSize( this->opImpl_ );
343 catch (
const SingleThreadModeError& e )
345 singleThreadModeError =
true;
348 if (!singleThreadModeError)
350 GetSetLocalMatrix< JacobianOperatorType > getSet( jOp );
353 auto doInvMass = [
this, &getSet] ()
355 applyInverseMass( this->iterators_, getSet, this->hasSkeleton() );
360 MPIManager :: run ( doInvMass );
362 catch (
const SingleThreadModeError& e )
364 singleThreadModeError =
true;
368 if (singleThreadModeError)
372 std::tuple< const LocalGalerkinOperatorImplType& > integrands( localOperator() );
373 op().assemble( u, jOp, iterators_, integrands );
376 gridSizeInterior_ = Impl::accumulateGridSize( this->opImpl_ );
378 GetSetLocalMatrixImpl getSet( jOp );
381 applyInverseMass( iterators_, getSet, hasSkeleton() );
390 struct GetSetLocalMatrixImpl
392 JacobianOperatorType& jOp_;
393 GetSetLocalMatrixImpl( JacobianOperatorType& jOp ) : jOp_( jOp ) {}
395 template <
class Entity,
class LocalMatrix>
396 void getLocalMatrix(
const Entity& domainEntity,
const Entity& rangeEntity,
397 LocalMatrix& lop )
const
399 jOp_.getLocalMatrix( domainEntity, rangeEntity, lop );
402 template <
class Entity,
class LocalMatrix>
403 void setLocalMatrix(
const Entity& domainEntity,
const Entity& rangeEntity,
404 const LocalMatrix& lop )
406 jOp_.setLocalMatrix( domainEntity, rangeEntity, lop );
410 struct GetSetLocalMatrixImplLocked :
public GetSetLocalMatrixImpl
412 typedef GetSetLocalMatrixImpl BaseType;
413 typedef std::shared_mutex mutex_t;
414 mutable mutex_t mutex_;
416 GetSetLocalMatrixImplLocked( JacobianOperatorType &jOp ) : BaseType( jOp ) {}
418 template <
class Entity,
class LocalMatrix>
419 void getLocalMatrix(
const Entity& domainEntity,
const Entity& rangeEntity,
420 LocalMatrix& lop )
const
422 std::lock_guard< mutex_t > lock( mutex_ );
423 BaseType::getLocalMatrix( domainEntity, rangeEntity, lop );
426 template <
class Entity,
class LocalMatrix>
427 void setLocalMatrix(
const Entity& domainEntity,
const Entity& rangeEntity,
428 const LocalMatrix& lop )
430 std::lock_guard< mutex_t > lock( mutex_ );
431 BaseType::setLocalMatrix( domainEntity, rangeEntity, lop );
435 template <
class JacOp>
436 struct GetSetLocalMatrix :
public GetSetLocalMatrixImpl
438 typedef GetSetLocalMatrixImpl BaseType;
439 GetSetLocalMatrix( JacobianOperatorType &jOp ) : BaseType( jOp ) {}
446 template <
class DomainFunction,
class RangeFunction>
447 struct GetSetLocalMatrix< PetscLinearOperator< DomainFunction, RangeFunction > > :
public GetSetLocalMatrixImplLocked
449 typedef GetSetLocalMatrixImplLocked BaseType;
450 GetSetLocalMatrix( JacobianOperatorType &jOp ) : BaseType( jOp ) {}
454 template <
class Iterators,
class GetSetLocalMatrixOp >
455 void applyInverseMass (
const Iterators& iterators, GetSetLocalMatrixOp& getSet,
456 const bool hasSkeleton )
const
458 typedef typename BaseType::LocalMassMatrixType LocalMassMatrixType;
459 JacobianOperatorType& jOp = getSet.jOp_;
461 LocalMassMatrixType localMassMatrix( jOp.rangeSpace(), localOperator().interiorQuadratureOrder( jOp.rangeSpace().order() ) );
463 TemporaryLocalMatrix< DomainDiscreteFunctionSpaceType, RangeDiscreteFunctionSpaceType >
464 lop(jOp.domainSpace(), jOp.rangeSpace());
467 for(
const auto& inside : iterators )
471 auto guard = bindGuard( lop, inside,inside );
472 lop.bind(inside,inside);
473 getSet.getLocalMatrix( inside, inside, lop );
474 localMassMatrix.leftMultiplyInverse( lop );
475 getSet.setLocalMatrix( inside, inside, lop );
480 for(
const auto &intersection : intersections( gridPart(), inside ) )
483 if( intersection.neighbor() )
485 const auto& outside = intersection.outside();
486 auto guard = bindGuard( lop, outside,inside );
487 getSet.getLocalMatrix( outside, inside, lop );
488 localMassMatrix.leftMultiplyInverse( lop );
489 getSet.setLocalMatrix( outside, inside, lop );
496 const DomainDiscreteFunctionSpaceType &dSpace_;
497 const RangeDiscreteFunctionSpaceType &rSpace_;
498 mutable int domainSpaceSequence_, rangeSpaceSequence_;
500 mutable std::unique_ptr< DiagonalAndNeighborStencilType > stencilDAN_;
501 mutable std::unique_ptr< DiagonalStencilType > stencilD_;
509 template<
class Integrands,
class DomainFunction,
class RangeFunction >
510 class MOLAutomaticDifferenceGalerkinOperator
511 :
public MOLGalerkinOperator< Integrands, DomainFunction, RangeFunction >,
512 public AutomaticDifferenceOperator< DomainFunction, RangeFunction >
514 typedef MOLGalerkinOperator< Integrands, DomainFunction, RangeFunction > BaseType;
518 typedef typename BaseType::GridPartType GridPartType;
520 template<
class... Args >
521 explicit MOLAutomaticDifferenceGalerkinOperator (
const GridPartType &gridPart, Args &&... args )
522 : BaseType( gridPart,
std::forward< Args >( args )... ), AutomaticDifferenceOperatorType()
531 template <
class LinearOperator,
class ModelIntegrands >
532 struct MOLModelDifferentiableGalerkinOperator
533 :
public MOLDifferentiableGalerkinOperator< ModelIntegrands, LinearOperator >
535 typedef MOLDifferentiableGalerkinOperator< ModelIntegrands, LinearOperator > BaseType;
537 typedef typename ModelIntegrands::ModelType ModelType;
540 typedef typename LinearOperator::RangeSpaceType DiscreteFunctionSpaceType;
542 MOLModelDifferentiableGalerkinOperator ( ModelType &model,
const DiscreteFunctionSpaceType &dfSpace )
543 : BaseType( dfSpace.gridPart(), model )
546 template<
class Gr
idFunction >
547 void apply (
const GridFunction &u, RangeFunctionType &w )
const
552 template<
class Gr
idFunction >
553 void apply (
const GridFunction &u, LinearOperator &jOp )
const
555 (*this).jacobian( u, jOp );
563 template<
class Integrands,
class LinearOperator,
class InverseOperator,
bool addDirichletBC>
564 using MethodOfLinesScheme = Impl::GalerkinSchemeImpl< Integrands, LinearOperator, InverseOperator, addDirichletBC,
565 MOLDifferentiableGalerkinOperator >;
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
DomainFunction DomainFunctionType
type of discrete function in the operator's domain
Definition: operator.hh:36