DUNE-FEM (unstable)

elliptic.hh
1/**************************************************************************
2
3 The dune-fem module is a module of DUNE (see www.dune-project.org).
4 It is based on the dune-grid interface library
5 extending the grid interface by a number of discretization algorithms
6 for solving non-linear systems of partial differential equations.
7
8 Copyright (C) 2003 - 2015 Robert Kloefkorn
9 Copyright (C) 2003 - 2010 Mario Ohlberger
10 Copyright (C) 2004 - 2015 Andreas Dedner
11 Copyright (C) 2005 Adrian Burri
12 Copyright (C) 2005 - 2015 Mirko Kraenkel
13 Copyright (C) 2006 - 2015 Christoph Gersbacher
14 Copyright (C) 2006 - 2015 Martin Nolte
15 Copyright (C) 2011 - 2015 Tobias Malkmus
16 Copyright (C) 2012 - 2015 Stefan Girke
17 Copyright (C) 2013 - 2015 Claus-Justus Heine
18 Copyright (C) 2013 - 2014 Janick Gerstenberger
19 Copyright (C) 2013 Sven Kaulman
20 Copyright (C) 2013 Tom Ranner
21 Copyright (C) 2015 Marco Agnese
22 Copyright (C) 2015 Martin Alkaemper
23
24
25 The dune-fem module is free software; you can redistribute it and/or
26 modify it under the terms of the GNU General Public License as
27 published by the Free Software Foundation; either version 2 of
28 the License, or (at your option) any later version.
29
30 The dune-fem module is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 GNU General Public License for more details.
34
35 You should have received a copy of the GNU General Public License along
36 with this program; if not, write to the Free Software Foundation, Inc.,
37 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38
39**************************************************************************/
40#ifndef DUNE_FEM_SCHEMES_ELLIPTIC_HH
41#define DUNE_FEM_SCHEMES_ELLIPTIC_HH
42
43#include <cstddef>
44
45#include <dune/common/timer.hh>
47
48#include <dune/fem/quadrature/cachingquadrature.hh>
49#include <dune/fem/operator/common/operator.hh>
50#include <dune/fem/operator/common/stencil.hh>
51
52#include <dune/fem/common/bindguard.hh>
53#include <dune/fem/function/common/localcontribution.hh>
54#include <dune/fem/function/localfunction/const.hh>
55
56#include <dune/fem/operator/common/differentiableoperator.hh>
57#include <dune/fem/operator/common/temporarylocalmatrix.hh>
58
59
60// include parameter handling
61#include <dune/fem/io/parameter.hh>
62#include <dune/fem/io/file/dataoutput.hh>
63
64// fempy includes
65#include <dune/fempy/quadrature/fempyquadratures.hh>
66
67// EllipticOperator
68// ----------------
69
71template< class DomainDiscreteFunction, class RangeDiscreteFunction, class Model>
73: public virtual Dune::Fem::Operator< DomainDiscreteFunction, RangeDiscreteFunction >
75{
76 typedef DomainDiscreteFunction DomainFunctionType;
77 typedef RangeDiscreteFunction RangeFunctionType;
78 typedef Model ModelType;
79 typedef Model DirichletModelType;
80
81 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
82 typedef typename DomainFunctionType::LocalFunctionType DomainLocalFunctionType;
83 typedef typename DomainLocalFunctionType::RangeType DomainRangeType;
84 typedef typename DomainLocalFunctionType::JacobianRangeType DomainJacobianRangeType;
85 typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
86 typedef typename RangeFunctionType::LocalFunctionType RangeLocalFunctionType;
87 typedef typename RangeLocalFunctionType::RangeType RangeRangeType;
88 typedef typename RangeLocalFunctionType::JacobianRangeType RangeJacobianRangeType;
89
90 // the following types must be identical for domain and range
91 typedef typename RangeDiscreteFunctionSpaceType::IteratorType IteratorType;
92 typedef typename IteratorType::Entity EntityType;
93 typedef typename EntityType::Geometry GeometryType;
94 typedef typename RangeDiscreteFunctionSpaceType::DomainType DomainType;
95 typedef typename RangeDiscreteFunctionSpaceType::GridPartType GridPartType;
96 typedef typename GridPartType::IntersectionIteratorType IntersectionIteratorType;
97 typedef typename IntersectionIteratorType::Intersection IntersectionType;
98
101
102 EllipticOperator ( const RangeDiscreteFunctionSpaceType &rangeSpace,
103 ModelType &model,
104 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
105 : model_( model ),
106 dSpace_(rangeSpace), rSpace_(rangeSpace)
107 {}
108 EllipticOperator ( const DomainDiscreteFunctionSpaceType &dSpace,
109 const RangeDiscreteFunctionSpaceType &rSpace,
110 ModelType &model,
111 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
112 : model_( model ),
113 dSpace_(dSpace), rSpace_(rSpace),
114 interiorOrder_(-1), surfaceOrder_(-1)
115 {}
116
118 virtual void operator() ( const DomainFunctionType &u, RangeFunctionType &w ) const
119 { apply(u,w); }
120 template <class GF>
121 void operator()( const GF &u, RangeFunctionType &w ) const
122 { apply(u,w); }
123 template <class GF>
124 void apply( const GF &u, RangeFunctionType &w ) const;
125
126 const DomainDiscreteFunctionSpaceType& domainSpace() const
127 {
128 return dSpace_;
129 }
130 const RangeDiscreteFunctionSpaceType& rangeSpace() const
131 {
132 return rSpace_;
133 }
134 const ModelType &model () const { return model_; }
135 ModelType &model () { return model_; }
136
137 void setQuadratureOrders(unsigned int interior, unsigned int surface)
138 {
139 interiorOrder_ = interior;
140 surfaceOrder_ = surface;
141 }
142
143protected:
144 int interiorOrder_, surfaceOrder_;
145private:
146 ModelType &model_;
147 const DomainDiscreteFunctionSpaceType &dSpace_;
148 const RangeDiscreteFunctionSpaceType &rSpace_;
149};
150
151
152
153// DifferentiableEllipticOperator
154// ------------------------------
155
157template< class JacobianOperator, class Model >
159: public EllipticOperator< typename JacobianOperator::DomainFunctionType, typename JacobianOperator::RangeFunctionType, Model >,
160 public Dune::Fem::DifferentiableOperator< JacobianOperator >
162{
164
165 typedef JacobianOperator JacobianOperatorType;
166
167 typedef typename BaseType::DomainFunctionType DomainFunctionType;
168 typedef typename BaseType::RangeFunctionType RangeFunctionType;
169 typedef typename BaseType::ModelType ModelType;
170
171 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainDiscreteFunctionSpaceType;
172 typedef typename DomainFunctionType::LocalFunctionType DomainLocalFunctionType;
173 typedef typename DomainLocalFunctionType::RangeType DomainRangeType;
174 typedef typename DomainLocalFunctionType::JacobianRangeType DomainJacobianRangeType;
175 typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeDiscreteFunctionSpaceType;
176 typedef typename RangeFunctionType::LocalFunctionType RangeLocalFunctionType;
177 typedef typename RangeLocalFunctionType::RangeType RangeRangeType;
178 typedef typename RangeLocalFunctionType::JacobianRangeType RangeJacobianRangeType;
179
180 // the following types must be identical for domain and range
181 typedef typename RangeDiscreteFunctionSpaceType::IteratorType IteratorType;
182 typedef typename IteratorType::Entity EntityType;
183 typedef typename EntityType::Geometry GeometryType;
184 typedef typename RangeDiscreteFunctionSpaceType::DomainType DomainType;
185 typedef typename RangeDiscreteFunctionSpaceType::GridPartType GridPartType;
186 typedef typename GridPartType::IntersectionIteratorType IntersectionIteratorType;
187 typedef typename IntersectionIteratorType::Intersection IntersectionType;
188
189 typedef typename BaseType::QuadratureType QuadratureType;
190 // quadrature for faces - used for Neuman b.c.
191 typedef typename BaseType::FaceQuadratureType FaceQuadratureType;
192
194 DifferentiableEllipticOperator ( const RangeDiscreteFunctionSpaceType &space,
195 ModelType &model,
196 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
197 : BaseType( space, space, model, parameter )
198 {}
200 DifferentiableEllipticOperator ( const DomainDiscreteFunctionSpaceType &dSpace,
201 const RangeDiscreteFunctionSpaceType &rSpace,
202 ModelType &model,
203 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
204 : BaseType( dSpace, rSpace, model, parameter )
205 {}
206
209 { assemble(u,jOp); }
210 template <class GridFunctionType>
211 void jacobian ( const GridFunctionType &u, JacobianOperatorType &jOp ) const
212 { assemble(u,jOp); }
213 template <class GridFunctionType>
214 void assemble ( const GridFunctionType &u, JacobianOperatorType &jOp ) const;
215 using BaseType::operator();
216
217 using BaseType::model;
218 using BaseType::interiorOrder_;
219 using BaseType::surfaceOrder_;
220};
221
222
223
224// Implementation of EllipticOperator
225// ----------------------------------
226
227template< class DomainDiscreteFunction, class RangeDiscreteFunction, class Model >
228template<class GF>
230 ::apply( const GF &u, RangeFunctionType &w ) const
231{
232 w.clear();
233 // get discrete function space
234 const RangeDiscreteFunctionSpaceType &dfSpace = w.space();
235
236 // get local representation of the discrete functions
237 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
238 Dune::Fem::AddLocalContribution< RangeFunctionType > wLocal( w );
239
240 // iterate over grid
241 for( const EntityType &entity : dfSpace )
242 {
243 if( !model().init( entity ) )
244 continue;
245
246 // get elements geometry
247 const GeometryType &geometry = entity.geometry();
248
249 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
250 auto wGuard = Dune::Fem::bindGuard( wLocal, entity );
251
252 // obtain quadrature order
253 const int quadOrder = interiorOrder_==-1?
254 uLocal.order() + wLocal.order() : interiorOrder_;
255
256 { // element integral
257 QuadratureType quadrature( entity, quadOrder );
258 const size_t numQuadraturePoints = quadrature.nop();
259 for( size_t pt = 0; pt < numQuadraturePoints; ++pt )
260 {
262 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
263 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
264
265 DomainRangeType vu;
266 uLocal.evaluate( quadrature[ pt ], vu );
267 DomainJacobianRangeType du;
268 uLocal.jacobian( quadrature[ pt ], du );
269
270 // compute mass contribution (studying linear case so linearizing around zero)
271 RangeRangeType avu( 0 );
272 model().source( quadrature[ pt ], vu, du, avu );
273 avu *= weight;
274 // add to local functional wLocal.axpy( quadrature[ pt ], avu );
275
276 RangeJacobianRangeType adu( 0 );
277 // apply diffusive flux
278 model().flux( quadrature[ pt ], vu, du, adu );
279 adu *= weight;
280
281 // add to local function
282 wLocal.axpy( quadrature[ pt ], avu, adu );
284 }
285 }
286
287 if( model().hasNeumanBoundary() && entity.hasBoundaryIntersections() )
288 {
289 const IntersectionIteratorType iitend = dfSpace.gridPart().iend( entity );
290 for( IntersectionIteratorType iit = dfSpace.gridPart().ibegin( entity ); iit != iitend; ++iit )
291 {
292 const IntersectionType &intersection = *iit;
293 if( !intersection.boundary() )
294 continue;
295
296 std::array<int,RangeRangeType::dimension> components(0);
297
298 const bool hasDirichletComponent = model().isDirichletIntersection( intersection, components );
299
300 const auto &intersectionGeometry = intersection.geometry();
301 const int quadOrder = surfaceOrder_==-1?
302 uLocal.order() + wLocal.order() : surfaceOrder_;
303 FaceQuadratureType quadInside( dfSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
304 const std::size_t numQuadraturePoints = quadInside.nop();
305 for( std::size_t pt = 0; pt < numQuadraturePoints; ++pt )
306 {
307 const auto &x = quadInside.localPoint( pt );
308 double weight = quadInside.weight( pt ) * intersectionGeometry.integrationElement( x );
309 DomainRangeType vu;
310 uLocal.evaluate( quadInside[ pt ], vu );
311 RangeRangeType alpha( 0 );
312 model().alpha( quadInside[ pt ], vu, alpha );
313 alpha *= weight;
314 for( int k = 0; k < RangeRangeType::dimension; ++k )
315 if( hasDirichletComponent && components[ k ] )
316 alpha[ k ] = 0;
317 wLocal.axpy( quadInside[ pt ], alpha );
318 }
319 }
320 }
321 }
322
323 w.communicate();
324}
325
326
327
328// Implementation of DifferentiableEllipticOperator
329// ------------------------------------------------
330
331template< class JacobianOperator, class Model >
332template<class GF>
334 ::assemble ( const GF &u, JacobianOperator &jOp ) const
335{
336 // std::cout << "starting assembly\n";
337 // Dune::Timer timer;
338 typedef typename DomainDiscreteFunctionSpaceType::BasisFunctionSetType DomainBasisFunctionSetType;
339 typedef typename RangeDiscreteFunctionSpaceType::BasisFunctionSetType RangeBasisFunctionSetType;
341
342 const DomainDiscreteFunctionSpaceType &domainSpace = jOp.domainSpace();
343 const RangeDiscreteFunctionSpaceType &rangeSpace = jOp.rangeSpace();
344
346 jOp.reserve(stencil);
347 jOp.clear();
348 TmpLocalMatrixType jLocal( domainSpace, rangeSpace );
349
350 const int domainBlockSize = domainSpace.localBlockSize; // is equal to 1 for scalar functions
351 std::vector< typename DomainLocalFunctionType::RangeType > phi( domainSpace.blockMapper().maxNumDofs()*domainBlockSize );
352 std::vector< typename DomainLocalFunctionType::JacobianRangeType > dphi( domainSpace.blockMapper().maxNumDofs()*domainBlockSize );
353 const int rangeBlockSize = rangeSpace.localBlockSize; // is equal to 1 for scalar functions
354 std::vector< typename RangeLocalFunctionType::RangeType > rphi( rangeSpace.blockMapper().maxNumDofs()*rangeBlockSize );
355 std::vector< typename RangeLocalFunctionType::JacobianRangeType > rdphi( rangeSpace.blockMapper().maxNumDofs()*rangeBlockSize );
356
357 Dune::Fem::ConstLocalFunction< GF > uLocal( u );
358 // std::cout << " in assembly: start element loop size=" << rangeSpace.gridPart().grid().size(0) << " time= " << timer.elapsed() << std::endl;;
359 for( const EntityType &entity : rangeSpace )
360 {
361 if( !model().init( entity ) )
362 continue;
363
364 const GeometryType &geometry = entity.geometry();
365
366 auto uGuard = Dune::Fem::bindGuard( uLocal, entity );
367 jLocal.bind( entity, entity );
368 jLocal.clear();
369
370 const DomainBasisFunctionSetType &domainBaseSet = jLocal.domainBasisFunctionSet();
371 const RangeBasisFunctionSetType &rangeBaseSet = jLocal.rangeBasisFunctionSet();
372 const std::size_t domainNumBasisFunctions = domainBaseSet.size();
373
374 const int quadOrder = interiorOrder_==-1?
375 domainSpace.order() + rangeSpace.order() : interiorOrder_;
376 QuadratureType quadrature( entity, quadOrder );
377 const size_t numQuadraturePoints = quadrature.nop();
378 for( size_t pt = 0; pt < numQuadraturePoints; ++pt )
379 {
381 const typename QuadratureType::CoordinateType &x = quadrature.point( pt );
382 const double weight = quadrature.weight( pt ) * geometry.integrationElement( x );
383
384 // evaluate all basis functions at given quadrature point
385 domainBaseSet.evaluateAll( quadrature[ pt ], phi );
386 rangeBaseSet.evaluateAll( quadrature[ pt ], rphi );
387
388 // evaluate jacobians of all basis functions at given quadrature point
389 domainBaseSet.jacobianAll( quadrature[ pt ], dphi );
390 rangeBaseSet.jacobianAll( quadrature[ pt ], rdphi );
391
392 // get value for linearization
393 DomainRangeType u0;
394 DomainJacobianRangeType jacU0;
395 uLocal.evaluate( quadrature[ pt ], u0 );
396 uLocal.jacobian( quadrature[ pt ], jacU0 );
397
398 RangeRangeType aphi( 0 );
399 RangeJacobianRangeType adphi( 0 );
400 for( std::size_t localCol = 0; localCol < domainNumBasisFunctions; ++localCol )
401 {
402 // if mass terms or right hand side is present
403 model().linSource( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[localCol], aphi );
404
405 // if gradient term is present
406 model().linFlux( u0, jacU0, quadrature[ pt ], phi[ localCol ], dphi[ localCol ], adphi );
407
408 // get column object and call axpy method
409 jLocal.column( localCol ).axpy( rphi, rdphi, aphi, adphi, weight );
410 }
412 }
413
414 if( model().hasNeumanBoundary() && entity.hasBoundaryIntersections() )
415 {
416 const IntersectionIteratorType iitend = rangeSpace.gridPart().iend( entity );
417 for( IntersectionIteratorType iit = rangeSpace.gridPart().ibegin( entity ); iit != iitend; ++iit ) // looping over intersections
418 {
419 const IntersectionType &intersection = *iit;
420 if( !intersection.boundary() )
421 continue;
422
423 std::array<int,RangeRangeType::dimension> components(0);
424 bool hasDirichletComponent = model().isDirichletIntersection( intersection, components );
425
426 const auto &intersectionGeometry = intersection.geometry();
427 const int quadOrder = surfaceOrder_==-1?
428 domainSpace.order() + rangeSpace.order() : surfaceOrder_;
429 FaceQuadratureType quadInside( rangeSpace.gridPart(), intersection, quadOrder, FaceQuadratureType::INSIDE );
430 const std::size_t numQuadraturePoints = quadInside.nop();
431 for( std::size_t pt = 0; pt < numQuadraturePoints; ++pt )
432 {
433 const auto &x = quadInside.localPoint( pt );
434 const double weight = quadInside.weight( pt ) * intersectionGeometry.integrationElement( x );
435 DomainRangeType u0;
436 uLocal.evaluate( quadInside[ pt ], u0 );
437 domainBaseSet.evaluateAll( quadInside[ pt ], phi );
438 for( std::size_t localCol = 0; localCol < domainNumBasisFunctions; ++localCol )
439 {
440 RangeRangeType alpha( 0 );
441 model().linAlpha( u0,quadInside[ pt ], phi[ localCol ], alpha );
442 for( int k = 0; k < RangeRangeType::dimension; ++k )
443 if( hasDirichletComponent && components[ k ] )
444 alpha[ k ] = 0;
445 jLocal.column( localCol ).axpy( phi, alpha, weight );
446 }
447 }
448 }
449 }
450 jOp.addLocalMatrix( entity, entity, jLocal );
451 jLocal.unbind();
452 } // end grid traversal
453 // std::cout << " in assembly: final " << timer.elapsed() << std::endl;;
454 jOp.flushAssembly();
455}
456#endif // #ifndef DUNE_FEM_SCHEMES_ELLIPTIC_HH
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
BaseType::RangeFunctionType RangeFunctionType
type of discrete function in the operator's range
Definition: differentiableoperator.hh:40
JacobianOperator JacobianOperatorType
type of linear operator modelling the operator's Jacobian
Definition: differentiableoperator.hh:35
BaseType::DomainFunctionType DomainFunctionType
type of discrete function in the operator's domain
Definition: differentiableoperator.hh:38
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
Implements a matrix constructed from a given type representing a field and compile-time given number ...
constexpr Interior interior
PartitionSet for the interior partition.
Definition: partitionset.hh:271
[Class for linearizable elliptic operator]
Definition: elliptic.hh:162
DifferentiableEllipticOperator(const DomainDiscreteFunctionSpaceType &dSpace, const RangeDiscreteFunctionSpaceType &rSpace, ModelType &model, const Dune::Fem::ParameterReader &parameter=Dune::Fem::Parameter::container())
contructor
Definition: elliptic.hh:200
DifferentiableEllipticOperator(const RangeDiscreteFunctionSpaceType &space, ModelType &model, const Dune::Fem::ParameterReader &parameter=Dune::Fem::Parameter::container())
contructor
Definition: elliptic.hh:194
void jacobian(const DomainFunctionType &u, JacobianOperatorType &jOp) const
method to setup the jacobian of the operator for storage in a matrix
Definition: elliptic.hh:208
Stencil contaning the entries (en,en) for all entities in the space. Defailt for an operator over a L...
Definition: stencil.hh:349
abstract operator
Definition: operator.hh:34
JacobianOperator::RangeFunctionType RangeFunctionType
type of discrete function in the operator's range
Definition: operator.hh:38
[Class for elliptic operator]
Definition: elliptic.hh:75
void apply(const GF &u, RangeFunctionType &w) const
Definition: elliptic.hh:230
virtual void operator()(const DomainFunctionType &u, RangeFunctionType &w) const
application operator
Definition: elliptic.hh:118
A simple timing class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)