dune-fem 2.12-git
Loading...
Searching...
No Matches
masslumping.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_SCHEMES_MASSLUMPING_HH
2#define DUNE_FEM_SCHEMES_MASSLUMPING_HH
3
4// fem includes
9
10namespace Dune
11{
12
13 namespace Fem
14 {
15
16#if HAVE_PETSC
17 //forward declaration of PetscLinearOperator
18 template <typename DomainFunction, typename RangeFunction >
19 class PetscLinearOperator ;
20#endif
21
22 // MassLumpingOperator
23 // -------------------
24
25 template< class Integrands, class MassIntegrands, class DomainFunction, class RangeFunction = DomainFunction >
27 : public virtual Operator< DomainFunction, RangeFunction >
28 {
29 typedef DomainFunction DomainFunctionType;
30 typedef RangeFunction RangeFunctionType;
31
32
33 static_assert( std::is_same< typename DomainFunctionType::GridPartType, typename RangeFunctionType::GridPartType >::value, "DomainFunction and RangeFunction must be defined on the same grid part." );
34
35 typedef typename RangeFunctionType::GridPartType GridPartType;
37
38 typedef Impl::GalerkinOperator< GridPartType > GalerkinOperatorImplType;
39 typedef Impl::LocalGalerkinOperator< Integrands > LocalGalerkinOperatorImplType;
40
41 template <class Space>
43 {
44 typedef typename Space :: GridPartType GridPartType;
46
47 // not needed, since lumping is only on element terms
49 };
50
51 // define Galerkin operator with different quadratures (i.e. LumpingQuadrature)
52 typedef Impl::LocalGalerkinOperator< MassIntegrands, LumpingQuadratureSelector > MassOperatorImplType;
53
54 typedef typename RangeFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
55
56 template< class... Args >
58 const Integrands& integrands,
59 const MassIntegrands& massIntegrands,
60 Args &&... args )
63 localOp_( gridPart, std::move( integrands ), std::forward< Args >( args )... ),
64 mass_( gridPart, std::move( massIntegrands ), std::forward< Args >( args )... ),
66 communicate_( true )
67 {
68 if( mass().hasSkeleton() )
69 DUNE_THROW(InvalidStateException,"MassLumpingOperator: Mass model cannot have a skeleton term");
70
71 // volume order (same as space for lumping)
72 auto interiorOrder = [] (const int order) { return order; };
73 // surface order does not matter for this part
74 auto surfaceOrder = [] (const int order) { return 0; };
75
76 // set quadrature orders mass part to be fixed!
77 size_t size = mass_.size();
78 for( size_t i=0; i<size; ++i )
79 mass_[ i ].setQuadratureOrderFunctions( interiorOrder, surfaceOrder );
80 }
81
82 void setCommunicate( const bool communicate )
83 {
86 {
87 std::cout << "MassLumpingOperator::setCommunicate: communicate was disabled!" << std::endl;
88 }
89 }
90
91 void setQuadratureOrders(unsigned int interior, unsigned int surface)
92 {
93 // only set quadrature orders for Galerkin part, lumping quadratures are fixed
94 size_t size = localOp_.size();
95 for( size_t i=0; i<size; ++i )
96 localOp_[ i ].setQuadratureOrders(interior,surface);
97 }
98
99 virtual void operator() ( const DomainFunctionType &u, RangeFunctionType &w ) const final override
100 {
101 evaluate( u, w );
102 }
103
104 template< class GridFunction >
105 void operator() ( const GridFunction &u, RangeFunctionType &w ) const
106 {
107 evaluate( u, w );
108 }
109
110 const GridPartType &gridPart () const { return op().gridPart(); }
111
112 typedef Integrands ModelType;
113 typedef Integrands DirichletModelType;
114 ModelType &model() const { return localOperator().model(); }
115
116 [[deprecated("Use localOperator instead!")]]
118
121 const MassOperatorImplType& mass() const { return (*mass_); }
122
124
125 protected:
126 const GalerkinOperatorImplType& op() const { return (*opImpl_); }
127
128 template< class GridFunction >
129 void evaluate( const GridFunction &u, RangeFunctionType &w ) const
130 {
132 w.clear();
133
134 std::shared_mutex mutex;
135
136 auto doEval = [this, &u, &w, &mutex] ()
137 {
138 // version with locking
140 const MassOperatorImplType& > integrands( localOperator(), mass() );
141
142
143 // add galerkin and mass lumped part
144 this->op().evaluate( u, w, this->iterators_, integrands, mutex );
145 };
146
147 bool singleThreadModeError = false ;
148
149 try {
150 // execute in parallel
151 MPIManager :: run ( doEval );
152
153 // update number of interior elements as sum over threads
154 gridSizeInterior_ = Impl::accumulateGridSize( opImpl_ );
155 }
156 catch ( const SingleThreadModeError& e )
157 {
158 singleThreadModeError = true;
159 }
160
161 // if error occurred, redo the whole evaluation
162 if( singleThreadModeError )
163 {
164 // reset w from previous entries
165 w.clear();
166
167 // re-run in single thread mode if previous attempt failed
169 const MassOperatorImplType& > integrands( localOperator(), mass() );
170 // add galerkin part and mass part
171 op().evaluate( u, w, iterators_, integrands );
172
173 // update number of interior elements as sum over threads
174 gridSizeInterior_ = op().gridSizeInterior();
175
176 }
177
178 // synchronize data
179 if( communicate_ )
180 w.communicate();
181 }
182
183 // GalerkinOperator implementation (see galerkin.hh)
188
191 };
192
193
194
195 // DifferentiableMassLumpingOperator
196 // ---------------------------------
197
198 template< class Integrands, class MassIntegrands, class JacobianOperator >
200 : public MassLumpingOperator< Integrands, MassIntegrands, typename JacobianOperator::DomainFunctionType, typename JacobianOperator::RangeFunctionType >,
201 public DifferentiableOperator< JacobianOperator >
202 {
204
205 public:
206 typedef typename BaseType :: LocalGalerkinOperatorImplType LocalGalerkinOperatorImplType;
207 typedef typename BaseType :: MassOperatorImplType MassOperatorImplType;
208
209 typedef JacobianOperator JacobianOperatorType;
210
213 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
214 typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
215
218
220
221 template< class... Args >
223 const RangeDiscreteFunctionSpaceType &rSpace,
224 Args &&... args )
225 : BaseType( rSpace.gridPart(), std::forward< Args >( args )... ),
226 dSpace_(dSpace),
227 rSpace_(rSpace),
228 domainSpaceSequence_(dSpace.sequence()),
229 rangeSpaceSequence_(rSpace.sequence()),
231 {
232 if( hasSkeleton() )
234 else
236 }
237
238 virtual void jacobian ( const DomainFunctionType &u, JacobianOperatorType &jOp ) const final override
239 {
240 // assemble Jacobian, same as GalerkinOperator
241 assemble( u, jOp );
242 }
243
244 template< class GridFunction >
245 void jacobian ( const GridFunction &u, JacobianOperatorType &jOp ) const
246 {
247 assemble( u, jOp );
248 }
249
251 {
252 return dSpace_;
253 }
255 {
256 return rSpace_;
257 }
258 // needed for DGHelmholtz operator
260 {
261 return rangeSpace();
262 }
263
264 using BaseType::gridPart;
266
267 protected:
268 bool hasSkeleton() const
269 {
271 return op().hasSkeleton( integrands );
272 }
273
274 using BaseType::op;
275 using BaseType::mass;
278
279 void prepare( JacobianOperatorType& jOp ) const
280 {
281 if ( domainSpaceSequence_ != domainSpace().sequence()
282 || rangeSpaceSequence_ != rangeSpace().sequence() )
283 {
284 domainSpaceSequence_ = domainSpace().sequence();
285 rangeSpaceSequence_ = rangeSpace().sequence();
286 if( hasSkeleton() )
287 {
288 assert( stencilDAN_ );
289 stencilDAN_->update();
290 }
291 else
292 {
293 assert( stencilD_ );
294 stencilD_->update();
295 }
296 }
297
298 if( hasSkeleton() )
299 jOp.reserve( *stencilDAN_ );
300 else
301 jOp.reserve( *stencilD_ );
302 // set all entries to zero
303 jOp.clear();
304 }
305
306 template < class GridFunction >
307 void assemble( const GridFunction &u, JacobianOperatorType &jOp ) const
308 {
309 prepare( jOp );
311
312 bool singleThreadModeError = false;
313 std::shared_mutex mutex;
314
315 auto doAssemble = [this, &u, &jOp, &mutex] ()
316 {
317 // assemble Jacobian, same as GalerkinOperator
319 this->op().assemble( u, jOp, this->iterators_, integrands, mutex );
320 };
321
322 try {
323 // execute in parallel
324 MPIManager :: run ( doAssemble );
325
326 // update number of interior elements as sum over threads
327 gridSizeInterior_ = Impl::accumulateGridSize( this->opImpl_ );
328 }
329 catch ( const SingleThreadModeError& e )
330 {
331 singleThreadModeError = true;
332 }
333
334 if (singleThreadModeError)
335 {
336 // redo matrix assembly since it failed
337 jOp.clear();
338 // add galerkin terms
340 op().assemble( u, jOp, iterators_, integrands );
341
342 // update number of interior elements as sum over threads
343 gridSizeInterior_ = op().gridSizeInterior();
344 }
345
346 // note: assembly done without local contributions so need
347 // to call flush assembly
348 jOp.flushAssembly();
349 }
350
354
357 };
358
359
360
361 // AutomaticDifferenceMassLumpingOperator
362 // --------------------------------------
363
364 template< class Integrands, class DomainFunction, class RangeFunction >
366 : public MassLumpingOperator< Integrands, DomainFunction, RangeFunction >,
367 public AutomaticDifferenceOperator< DomainFunction, RangeFunction >
368 {
371
372 public:
374
375 template< class... Args >
377 : BaseType( gridPart, std::forward< Args >( args )... ), AutomaticDifferenceOperatorType()
378 {}
379 };
380
381
382
383 namespace Impl
384 {
385
386 // MassLumpingSchemeImpl
387 // ---------------------
388 template< class Integrands, class MassIntegrands,
389 class LinearOperator, bool addDirichletBC,
390 template <class,class,class> class DifferentiableGalerkinOperatorImpl >
391 struct MassLumpingSchemeTraits
392 {
393 template <class O, bool addDBC>
394 struct DirichletBlockSelector { using type = void; };
395 template <class O>
396 struct DirichletBlockSelector<O,true> { using type = typename O::DirichletBlockVector; };
397
398 using DifferentiableOperatorType = std::conditional_t< addDirichletBC,
400 DifferentiableGalerkinOperatorImpl< Integrands, MassIntegrands, LinearOperator > >;
401
402 using DirichletBlockVector = typename DirichletBlockSelector<
404 DifferentiableGalerkinOperatorImpl< Integrands, MassIntegrands, LinearOperator >>,
405 addDirichletBC>::type;
406
407 typedef DifferentiableOperatorType type;
408 };
409
410
411 // MassLumpingSchemeImpl
412 // ---------------------
413 template< class Integrands, class MassIntegrands,
414 class LinearOperator, class LinearInverseOperator, bool addDirichletBC,
415 template <class,class,class> class DifferentiableGalerkinOperatorImpl = MassLumpingDifferentiableOperator >
416 struct MassLumpingSchemeImpl : public FemScheme<
417 typename MassLumpingSchemeTraits< Integrands, MassIntegrands, LinearOperator,
418 addDirichletBC, DifferentiableGalerkinOperatorImpl
419 > :: type, // Operator
420 LinearInverseOperator > // LinearInverseOperator
421 {
422 typedef FemScheme< typename MassLumpingSchemeTraits< Integrands, MassIntegrands, LinearOperator,
423 addDirichletBC, DifferentiableGalerkinOperatorImpl>::type, // Operator
424 LinearInverseOperator > // LinearInverseOperator
425 BaseType;
426
427 // type of discrete function space used with this scheme
428 typedef typename BaseType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
429
430 // needed for registerSchemeConstructor (Python export)
431 typedef MassIntegrands MassModelType;
432
433 MassLumpingSchemeImpl ( const DiscreteFunctionSpaceType &dfSpace,
434 const Integrands &integrands,
435 const MassIntegrands& massIntegrands,
436 const ParameterReader& parameter = Parameter::container() )
437 : BaseType( dfSpace,
438 parameter,
439 std::move(integrands),
440 std::move(massIntegrands) )
441 {}
442 };
443
444 } // end namespace Impl
445
446 // MassLumpingScheme
447 // -----------------
448
449 template< class Integrands, class MassIntegrands, class LinearOperator, class InverseOperator, bool addDirichletBC >
450 using MassLumpingScheme = Impl::MassLumpingSchemeImpl< Integrands, MassIntegrands, LinearOperator, InverseOperator, addDirichletBC,
452
453 } // namespace Fem
454
455} // namespace Dune
456
457#endif // #ifndef DUNE_FEM_SCHEMES_MOLGALERKIN_HH
void communicate(CC &cc)
int size() const
virtual void operator()()=0
#define DUNE_THROW(E,...)
STL namespace.
Impl::MassLumpingSchemeImpl< Integrands, MassIntegrands, LinearOperator, InverseOperator, addDirichletBC, MassLumpingDifferentiableOperator > MassLumpingScheme
Definition masslumping.hh:451
BasicParameterReader< std::function< const std::string *(const std::string &, const std::string *) > > ParameterReader
Definition reader.hh:316
static ParameterContainer & container()
Definition io/parameter.hh:199
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition io/parameter.hh:466
Exception thrown when a code segment that is supposed to be only accessed in single thread mode is ac...
Definition mpimanager.hh:43
void update()
update internal list of iterators
Definition threaditerator.hh:93
size_t size() const
return number of threads
Definition threadsafevalue.hh:62
operator providing a Jacobian through automatic differentiation
Definition automaticdifferenceoperator.hh:86
abstract differentiable operator
Definition differentiableoperator.hh:29
abstract operator
Definition operator.hh:34
abstract affine-linear operator
Definition operator.hh:90
Stencil contaning the entries (en,en) for all entities in the space. Defailt for an operator over a L...
Definition stencil.hh:349
Stencil contaning the entries (en,en) and (en,nb) for all entities en in the space and neighbors nb o...
Definition stencil.hh:387
quadrature class supporting base function caching
Definition cachingquadrature.hh:106
Definition defaultquadratures.hh:40
Definition dirichletwrapper.hh:31
DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType
Definition femscheme.hh:44
FemScheme(const DiscreteFunctionSpaceType &space, ModelType &model, const Dune::Fem::ParameterReader &parameter=Dune::Fem::Parameter::container())
constructor with one model
Definition femscheme.hh:82
static constexpr bool addDirichletBC
Definition femscheme.hh:74
Definition masslumping.hh:28
std::size_t gridSizeInterior() const
Definition masslumping.hh:123
RangeFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType
Definition masslumping.hh:54
Integrands ModelType
Definition masslumping.hh:112
const GalerkinOperatorImplType & op() const
Definition masslumping.hh:126
Impl::LocalGalerkinOperator< MassIntegrands, LumpingQuadratureSelector > MassOperatorImplType
Definition masslumping.hh:52
ThreadSafeValue< GalerkinOperatorImplType > opImpl_
Definition masslumping.hh:185
bool communicate_
Definition masslumping.hh:190
RangeFunction RangeFunctionType
Definition masslumping.hh:30
ThreadIteratorType iterators_
Definition masslumping.hh:184
const GridPartType & gridPart() const
Definition masslumping.hh:110
Impl::GalerkinOperator< GridPartType > GalerkinOperatorImplType
Definition masslumping.hh:38
void evaluate(const GridFunction &u, RangeFunctionType &w) const
Definition masslumping.hh:129
MassLumpingOperator(const GridPartType &gridPart, const Integrands &integrands, const MassIntegrands &massIntegrands, Args &&... args)
Definition masslumping.hh:57
const LocalGalerkinOperatorImplType & impl() const
Definition masslumping.hh:117
RangeFunctionType::GridPartType GridPartType
Definition masslumping.hh:35
ThreadSafeValue< MassOperatorImplType > mass_
Definition masslumping.hh:187
void setCommunicate(const bool communicate)
Definition masslumping.hh:82
Integrands DirichletModelType
Definition masslumping.hh:113
ThreadSafeValue< LocalGalerkinOperatorImplType > localOp_
Definition masslumping.hh:186
Impl::LocalGalerkinOperator< Integrands > LocalGalerkinOperatorImplType
Definition masslumping.hh:39
ThreadIterator< GridPartType > ThreadIteratorType
Definition masslumping.hh:36
ModelType & model() const
Definition masslumping.hh:114
const LocalGalerkinOperatorImplType & localOperator() const
return local operator holding instance of integrands
Definition masslumping.hh:120
const MassOperatorImplType & mass() const
Definition masslumping.hh:121
void setQuadratureOrders(unsigned int interior, unsigned int surface)
Definition masslumping.hh:91
DomainFunction DomainFunctionType
Definition masslumping.hh:29
std::size_t gridSizeInterior_
Definition masslumping.hh:189
CachingQuadrature< GridPartType, 1, Capabilities::DefaultQuadrature< Space >::template DefaultQuadratureTraits > SurfaceQuadratureType
Definition masslumping.hh:48
Space::GridPartType GridPartType
Definition masslumping.hh:44
CachingLumpingQuadrature< GridPartType, 0 > InteriorQuadratureType
Definition masslumping.hh:45
std::unique_ptr< DiagonalAndNeighborStencilType > stencilDAN_
Definition masslumping.hh:355
const RangeDiscreteFunctionSpaceType & space() const
Definition masslumping.hh:259
JacobianOperator JacobianOperatorType
Definition masslumping.hh:209
int domainSpaceSequence_
Definition masslumping.hh:353
const RangeDiscreteFunctionSpaceType & rSpace_
Definition masslumping.hh:352
const GalerkinOperatorImplType & op() const
Definition masslumping.hh:126
int rangeSpaceSequence_
Definition masslumping.hh:353
ThreadIteratorType iterators_
Definition masslumping.hh:184
void prepare(JacobianOperatorType &jOp) const
Definition masslumping.hh:279
RangeFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType
Definition masslumping.hh:214
void jacobian(const GridFunction &u, JacobianOperatorType &jOp) const
Definition masslumping.hh:245
const GridPartType & gridPart() const
Definition masslumping.hh:110
const RangeDiscreteFunctionSpaceType & rangeSpace() const
Definition masslumping.hh:254
virtual void jacobian(const DomainFunctionType &u, JacobianOperatorType &jOp) const final override
obtain linearization
Definition masslumping.hh:238
DiagonalStencil< DomainDiscreteFunctionSpaceType, RangeDiscreteFunctionSpaceType > DiagonalStencilType
Definition masslumping.hh:217
DiagonalAndNeighborStencil< DomainDiscreteFunctionSpaceType, RangeDiscreteFunctionSpaceType > DiagonalAndNeighborStencilType
Definition masslumping.hh:216
DomainFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType
Definition masslumping.hh:213
BaseType::MassOperatorImplType MassOperatorImplType
Definition masslumping.hh:207
const DomainDiscreteFunctionSpaceType & dSpace_
Definition masslumping.hh:351
const DomainDiscreteFunctionSpaceType & domainSpace() const
Definition masslumping.hh:250
MassLumpingDifferentiableOperator(const DomainDiscreteFunctionSpaceType &dSpace, const RangeDiscreteFunctionSpaceType &rSpace, Args &&... args)
Definition masslumping.hh:222
BaseType::RangeFunctionType RangeFunctionType
Definition masslumping.hh:212
std::unique_ptr< DiagonalStencilType > stencilD_
Definition masslumping.hh:356
const LocalGalerkinOperatorImplType & localOperator() const
return local operator holding instance of integrands
Definition masslumping.hh:120
const MassOperatorImplType & mass() const
Definition masslumping.hh:121
void assemble(const GridFunction &u, JacobianOperatorType &jOp) const
Definition masslumping.hh:307
BaseType::LocalGalerkinOperatorImplType LocalGalerkinOperatorImplType
Definition masslumping.hh:206
BaseType::GridPartType GridPartType
Definition masslumping.hh:219
BaseType::DomainFunctionType DomainFunctionType
Definition masslumping.hh:211
bool hasSkeleton() const
Definition masslumping.hh:268
std::size_t gridSizeInterior_
Definition masslumping.hh:189
MassLumpingAutomaticDifferenceGalerkinOperator(const GridPartType &gridPart, Args &&... args)
Definition masslumping.hh:376
BaseType::GridPartType GridPartType
Definition masslumping.hh:373
T endl(T... args)
T move(T... args)