KASKADE 7 development version
bank_weiser_est.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2015 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef BANK_WEISER_EST_HH
14#define BANK_WEISER_EST_HH
15
16#include "dune/grid/common/quadraturerules.hh"
17
18#include "fem/functionviews.hh"
19#include "fem/assemble.hh"
20#include "fem/fetransfer.hh"
21#include "fem/celldata.hh"
22#include "fem/gridscanner.hh"
25
26namespace Kaskade
27{
38 template <int Id, int PDEId, int SpaceId, int components>
40 {
41 static int const id = Id;
42 static int const pdeid = PDEId;
43 static int const spaceIndex = SpaceId;
44 static int const m = components;
45 };
46
47
48 // Construction of an error representation function...
49
50 static int const indQ[10] = {0,1,2,3,4,5,6,7,8,9};
51 static int const indQFull[10] = {0,1,2,3,4,5,6,7,8,9};
52
53 static bool normalize = true;
54
55 //static int const indQ[6] = {1,3,4,6,7,8};
56
57 //template<int dim>
58 //struct SystDim
59 //{
60 // static const int value = 3*(dim-1);
61 //};
62
63 template<int dim>
64 struct SystDim
65 {
66 static const int value = (dim+1)+3*(dim-1);
67 };
68
69 template<int dim>
71 {
72 static const int value = (dim+1)+3*(dim-1);
73 };
74
75 template <class LocalInd, class RT, class Cache, int dim,class Evaluators>
77 {
78
79 HalfGradientJump(LocalInd& localInd_,
80 Dune::FieldVector<RT,dim>const & outernormal,
81 Cache const& cache_,
82 Cache const& cacheNeigh_,
83 Evaluators const& evaluators_):
84 localInd(localInd_), cache(cache_), cacheNeigh(cacheNeigh_), evaluators(evaluators_)
85 {
86 modarg.value=0;
87 modarg.gradient[0]=outernormal;
88 }
89
90 template <class Variable>
91 void operator()(Variable const& ) const
92 {
93 for(int row=0; row< localInd[Variable::id].size; ++row)
94 localInd[Variable::id][row] += 0.5*(cacheNeigh.template d1<Variable::pdeid>(modarg)-cache.template d1<Variable::pdeid>(modarg))
95 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].value[0];
96 }
97
99 LocalInd& localInd;
100 Cache const& cache;
101 Cache const& cacheNeigh;
103 };
104
105
106 template <class LocalInd, class RT, class Cache, class BoundaryCache, int dim, class Evaluators>
108 {
109 StrongBoundaryValues(LocalInd& localInd_,
110 RT& integrationElement,
111 Dune::FieldVector<RT,dim>const & outernormal,
112 Cache const& cache_,
113 BoundaryCache const& cacheBoundary_,
114 Evaluators const& evaluators_):
115 localInd(localInd_), cache(cache_), boundaryCache(cacheBoundary_),evaluators(evaluators_)
116 {
117 modargB.value=integrationElement;
118 modargB.gradient[0]=0;
120 modargTest.gradient[0]=0;
121 modarg.value=0;
122 modarg.gradient[0]=outernormal;
123 }
124
125 template <class Variable>
126 void operator()(Variable const& ) const
127 {
128 if(boundaryCache.template d2<Variable::pdeid,Variable::id>(modargTest,modargTest) < 1e5)
129 for(int row=0; row< localInd[Variable::id].size; ++row)
130 {
131 localInd[Variable::id][row] -=
132 (cache.template d1<Variable::pdeid>(modarg)+boundaryCache.template d1<Variable::pdeid>(modargB))
133 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].value[0];
134 }
135 }
136
138 LocalInd& localInd;
139 Cache const& cache;
140 BoundaryCache const& boundaryCache;
142 };
143
144 template <class LocalRHS, class RT, class Cache, class Evaluators>
146 {
147 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
148 WeakResiduum(LocalRHS& localRHS_, RT intEl_,Cache const& cache_, Evaluators const& evaluators_):
149 localRHS(localRHS_), intEl(intEl_), evaluators(evaluators_), cache(cache_)
150 {
151 }
152
153 template <class Variable>
154 void operator()(Variable const& ) const
155 {
156 size_t n = (localRHS[Variable::id]).N();
157 for(int row=0; row<n; ++row)
158 {
159 (localRHS[Variable::id])[row]
160 -= intEl * cache.template d1<Variable::pdeid>(boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[row]);
161 }
162 }
163
164 LocalRHS& localRHS;
167 Cache const& cache;
168 };
169
170
171 template <class LocalRHS, class RT, class Cache, class Evaluators>
173 {
174 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
175 WeakResiduumMainPart(LocalRHS& localRHS_, RT intEl_,Cache const& cache_, Evaluators const& evaluators_):
176 localRHS(localRHS_), intEl(intEl_), evaluators(evaluators_), cache(cache_)
177 {
178 }
179
180 template <class Variable>
181 void operator()(Variable const& ) const
182 {
184 modarg1.value[0]=0;
185 size_t n = (localRHS[Variable::id]).N();
186 for(int row=0; row<n; ++row)
187 {
188 modarg1.gradient[0]=boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].gradient[0];
189 (localRHS[Variable::id])[row] -= intEl * cache.template d1<Variable::pdeid>(modarg1);
190 }
191 }
192
193 LocalRHS& localRHS;
196 Cache const& cache;
197 };
198
199
200 template <class LocalInd, class RT, class Cache, int dim,class Evaluators>
202 {
203
204 GradientAverage(LocalInd& localInd_,
205 Dune::FieldVector<RT,dim>const & outernormal,
206 Cache const& cache_,
207 Cache const& cacheNeigh_,
208 Evaluators const& evaluators_):
209 localInd(localInd_), cache(cache_), cacheNeigh(cacheNeigh_), evaluators(evaluators_)
210 {
211 modarg.value=0;
212 modarg.gradient[0]=outernormal;
213 }
214
215 template <class Variable>
216 void operator()(Variable const& ) const
217 {
218 for(int row=0; row< localInd[Variable::id].size; ++row)
219 localInd[Variable::id][row] += 0.5*(cache.template d1<Variable::pdeid>(modarg)+cacheNeigh.template d1<Variable::pdeid>(modarg))
220 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].value[0];
221 }
222
224 LocalInd& localInd;
225 Cache const& cache;
226 Cache const& cacheNeigh;
228 };
229
230
231
232 template <class LocalInd, class RT, class Cache, class BoundaryCache, int dim, class Evaluators>
234 {
235 WeakBoundaryValues(LocalInd& localInd_,
236 RT& integrationElement,
237 Dune::FieldVector<RT,dim>const & outernormal,
238 Cache const& cache_,
239 BoundaryCache const& cacheBoundary_,
240 Evaluators const& evaluators_):
241 localInd(localInd_), cache(cache_), boundaryCache(cacheBoundary_),evaluators(evaluators_)
242 {
243 modargB.value=integrationElement;
244 modargB.gradient[0]=0;
246 modargTest.gradient[0]=0;
247 modarg.value=0;
248 modarg.gradient[0]=outernormal;
249 }
250
251 template <class Variable>
252 void operator()(Variable const& ) const
253 {
254 if(boundaryCache.template d2<Variable::pdeid,Variable::id>(modargTest,modargTest) < 1e5)
255 for(int row=0; row< localInd[Variable::id].size; ++row)
256 {
257 localInd[Variable::id][row] +=
258 boundaryCache.template d1<Variable::pdeid>(modargB)
259 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].value[0];
260 }
261 else
262 for(int row=0; row< localInd[Variable::id].size; ++row)
263 {
264 localInd[Variable::id][row] +=
265 cache.template d1<Variable::pdeid>(modarg)
266 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQ[row]].value[0];
267 }
268 }
269
271 LocalInd& localInd;
272 Cache const& cache;
273 BoundaryCache const& boundaryCache;
275 };
276
277 template <class LocalVector, class LocalMatrix>
279 {
281 LocalMatrix & A_,
282 LocalVector& b_):
283 c(c_), A(A_), b(b_)
284 {
285 }
286
287 template <class Variable>
288 void operator()(Variable const& ) const
289 {
290 //Since Neumann problems are solved, achieve sum_i b_i = 0
291 if(normalize)
292 {
293 int n(b[Variable::id].N());
294 double sum(0.0);
295 for(int i=0; i<n; ++i) sum+=b[Variable::id][i];
296 sum /= n;
297 for(int i=0; i<n; ++i) b[Variable::id][i]-=sum;
298 }
299 try
300 {
301 A.solve(c[Variable::id],b[Variable::id]);
302 }
303 catch(...)
304 {
305 std::cout << "Warning: Factorization failed: setting indicator to zero!" << std::endl;
306 for(int i =0; i<c[Variable::id].N();++i)
307 c[Variable::id][i]=0.0;
308 }
309 }
310
314 };
315
316
317 template <class LocalMatrix, class Evaluators, class RT, class Cache>
318 void localNormalMatrix(LocalMatrix& localmatrix, RT intEl, Evaluators const& evaluators,Cache const& cache)
319 {
320 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
321 VariationalArg<RT,dim> modarg1,modarg2;
322 modarg1.value[0]=0;
323 modarg2.value[0]=0;
324 size_t n = (localmatrix[0]).N();
325 for(int row=0; row<n; ++row)
326 for (size_t i=0; i<n; ++i)
327 {
328 modarg1.gradient[0]=boost::fusion::at_c<0>(evaluators).evalData[indQ[row]].gradient[0];
329 modarg2.gradient[0]=boost::fusion::at_c<0>(evaluators).evalData[indQ[i]].gradient[0];
330
331 localmatrix[row][i]
332 += 1e-3*intEl*boost::fusion::at_c<0>(evaluators).evalData[indQ[row]].value[0]*
333 boost::fusion::at_c<0>(evaluators).evalData[indQ[i]].value[0];
334 localmatrix[row][i]+= intEl*cache.template d2<0,1>(modarg1,modarg2);
335 }
336 }
337
338
339
340
341 template <class LocalVector, class Evaluators, class RT>
342 void rank1KernelVector(LocalVector& localvector, RT intEl, Evaluators const& evaluators)
343 {
344 size_t n = (localvector).N();
345 for (size_t i=0; i<n; ++i)
346 {
347 (localvector)[i]
348 += intEl*boost::fusion::at_c<0>(evaluators).evalData[indQ[i]].value[0];
349 }
350 }
351
352 template <class LocalSolution, class Evaluators, class GlobalSolution>
354 {
355 ScatterLocalSolution(LocalSolution const& localSolution_, Evaluators const& evaluators_, GlobalSolution& globalSolution_):
356 localSolution(localSolution_), eval(evaluators_), globalSolution(globalSolution_)
357 {}
358
359 template <class Variable>
360 void operator()(Variable const& ) const
361 {
362 using namespace boost::fusion;
363 typename result_of::value_at_c<Evaluators,Variable::spaceIndex>::type const& reval = at_c<Variable::spaceIndex>(eval);
364 assert(indQ[localSolution[Variable::id].N()-1]<reval.size());
365 for (size_t i=0; i<localSolution[Variable::id].N(); i++)
366 (*at_c<Variable::id>(globalSolution))[reval.globalIndices()[indQ[i]]] += (localSolution)[Variable::id][i];
367 }
368
369 LocalSolution const& localSolution;
371 GlobalSolution& globalSolution;
372 };
373
375
384 template <class VariableDescriptions, int sysdim, class Result, class F, class Spaces, class ExtendedSpaces>
385 void edgeAveraging(Result& result,
386 F const& f,
387 Spaces const& spaces,
388 ExtendedSpaces const& extendedSpaces)
389 {
390 using namespace boost::fusion;
391 using namespace Dune;
392
393 VariableDescriptions const varDesc;
394
395 typedef typename SpaceType<Spaces,0>::type::Grid Grid;
396 typedef typename SpaceType<Spaces,0>::type::IndexSet IndexSet;
397 typedef typename SpaceType<Spaces,0>::type::RT RT;
398 typedef typename Grid::ctype CoordType;
399 int const dim = Grid::dimension;
400
401 IndexSet const& indexSet = at_c<0>(spaces)->grid().leafIndexSet();
402
403
404 // Shape function cache. Remember that every thread has to use its own cache!
405 typedef ShapeFunctionCache<Grid,RT> SfCache;
406 SfCache sfCache,sfCacheN, sfCacheT;
407
408 // Evaluators for shape functions of all FE spaces. Remember that
409 // every thread has to use its own collection of evaluators!
410 typedef typename result_of::as_vector<
411 typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type
412 >::type Evaluators;
413
414 typedef typename result_of::as_vector<typename result_of::transform<ExtendedSpaces, GetEvaluators<SfCache> >::type>::type ExtendedEvaluators;
415
416 Evaluators evaluators(transform(spaces,GetEvaluators<SfCache>(&sfCache)));
417 ExtendedEvaluators extendedEvaluators(transform(extendedSpaces,GetEvaluators<SfCache>(&sfCacheT)));
418 Evaluators evaluatorsNeigh(transform(spaces,GetEvaluators<SfCache>(&sfCacheN)));
419
420 // Define iterator and entity type for stepping through all cells of the grid.
421 typedef typename IndexSet::template Codim<0>::template Partition<All_Partition>::Iterator CellIterator;
422 typedef typename CellIterator::Entity::LeafIntersectionIterator LII;
423 typedef typename CellIterator::Entity Entity;
424
425 typename F::DomainCache domainCache(f.createDomainCache(6+8)); // 6 means RHS+Op
426 typename F::DomainCache domainCacheNeigh(f.createDomainCache(6+8));
427 typename F::BoundaryCache boundaryCache(f.createBoundaryCache(6+8));
428
429 const int ssize = result_of::size<VariableDescriptions>::type::value;
430
433
434 LocalMatrix A;
435 LocalVector b,c;
437 // Iterate over all cells.
438 CellIterator end = indexSet.template end<0,All_Partition>();
439 for (CellIterator ci=indexSet.template begin<0,All_Partition>(); ci!=end; ++ci) {
440
441 domainCache.moveTo(*ci);
442
443 moveEvaluatorsToCell(evaluators,*ci);
444 moveEvaluatorsToCell(extendedEvaluators,*ci);
445 int const shapeFunctionMaxOrder = maxOrder(evaluators);
446 shapeFunctionMaxOrder = std::max(shapeFunctionMaxOrder,maxOrder(extendedEvaluators));
447 int const p = f.integrationOrder(*ci,shapeFunctionMaxOrder,false);
448 int const pb = f.integrationOrder(*ci,shapeFunctionMaxOrder,true);
449
450 LII faceEnd = ci->ileafend();
451
452 A=0;
453 rk1=0;
454 for(int i=0; i<ssize; ++i) { b[i]=0; c[i]=0; }
455
456 GeometryType gti = ci->type();
457
458 QuadratureRule<CoordType, dim> const& qri=QuadratureRules<CoordType,dim>::rule(gti,p);
459
460 size_t nQuadPosi = qri.size();
461 for (size_t g=0; g<nQuadPosi; ++g) {
462 FieldVector<CoordType,dim> const& quadPos = qri[g].position();
463
464 moveEvaluatorsToIntegrationPoint(evaluators,quadPos,qri,g,0);
465 moveEvaluatorsToIntegrationPoint(extendedEvaluators,quadPos,qri,g,0);
466 domainCache.evaluateAt(quadPos,evaluators);
467 CoordType weightTimesDetJac(ci->geometry().integrationElement(quadPos)); // determinant of jacobian
468 weightTimesDetJac *= qri[g].weight();
469 rank1KernelVector(rk1,weightTimesDetJac, extendedEvaluators);
470 localNormalMatrix(A,weightTimesDetJac, extendedEvaluators, domainCache);
471
473 (b, weightTimesDetJac,domainCache, extendedEvaluators));
474 }
475
476 for (LII face=ci->ileafbegin(); face!=faceEnd; ++face) {
477 if(face.neighbor()) {
478
479 typename LII::EntityPointer o=face.outside();
480 domainCacheNeigh.moveTo(*o);
481 moveEvaluatorsToCell(evaluatorsNeigh,*o);
482
483 } else if(face.boundary())
484 {
485 boundaryCache.moveTo(face);
486 }
487 GeometryType gt=face.intersectionSelfLocal().type();
488 QuadratureRule<CoordType, dim-1> const& qr=QuadratureRules<CoordType,dim-1>::rule(gt,pb);
489 size_t nQuadPos=qr.size();
490 for(size_t g=0; g<nQuadPos; ++g){
491 FieldVector<CoordType, dim-1> const& quadPos = qr[g].position();
492 FieldVector<CoordType, dim> const& quadPosInSelf = face.intersectionSelfLocal().global(quadPos);
493 moveEvaluatorsToIntegrationPoint(evaluators,quadPosInSelf,qr,g,face.numberInSelf());
494 moveEvaluatorsToIntegrationPoint(extendedEvaluators,quadPosInSelf,qr,g,face.numberInSelf());
495 domainCache.evaluateAt(quadPosInSelf,evaluators);
496 FieldVector<RT, dim> outerNormal = face.integrationOuterNormal(quadPos);
497 outerNormal *= qr[g].weight();
498 if(face.neighbor())
499 {
500 Dune::FieldVector<typename Grid::ctype, Grid::dimension> const& quadPosInNeigh = face.intersectionNeighborLocal().global(quadPos);
501
502 moveEvaluatorsToIntegrationPoint(evaluatorsNeigh,quadPosInNeigh,qr,g,face.numberInNeighbor());
503 domainCacheNeigh.evaluateAt(quadPosInNeigh,evaluatorsNeigh);
505 (b,outerNormal,domainCache,domainCacheNeigh, extendedEvaluators));
506
507 } else if(face.boundary())
508 {
509 boundaryCache.evaluateAt(quadPos,evaluators);
510
511 CoordType weightTimesDetJac = face.intersectionGlobal().integrationElement(quadPos); // determinant of jacobian
512 weightTimesDetJac *= qr[g].weight();
514 (b, weightTimesDetJac, outerNormal, domainCache, boundaryCache, extendedEvaluators));
515 }
516 }
517 }
518 for(int i=0; i<sysdim; ++i) for(int j=0; j<sysdim; ++j) A[i][j] += rk1[i]*rk1[j];
519 for_each(varDesc, SolveLocalSystem<LocalVector, LocalMatrix>(c,A,b));
520 for_each(varDesc, ScatterLocalSolution<LocalVector, ExtendedEvaluators,typename Result::Functions>(c,extendedEvaluators,result.vars));
521 }
522 };
523
524 template <class LocalMatrix, class Evaluators, class RT, class Cache, class Row>
526 {
527 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
528 LocalNormalMatrixBlock(LocalMatrix& localmatrix_, RT intEl_, Evaluators const& evaluators_,Cache const& cache_):
529 localmatrix(localmatrix_), intEl(intEl_), evaluators(evaluators_), cache(cache_)
530 {
531 }
532
533 template <class Col>
534 void operator()(Col const& ) const
535 {
536 size_t n = localmatrix.N()/2;
537 for(int row=0; row<n; ++row)
538 for (size_t col=0; col<n; ++col)
539 {
540
541 (localmatrix)[(Row::id)*n+row][(Col::id)*n+col]
542 += intEl*cache.template d2<Row::id,Col::id>(boost::fusion::at_c<Row::spaceIndex>(evaluators).evalData[indQFull[row]],
543 boost::fusion::at_c<Col::spaceIndex>(evaluators).evalData[indQFull[col]]);
544 }
545 }
546
550 Cache const& cache;
551 };
552
553 template <class LocalMatrix, class Evaluators, class RT, class Cache, class VarDesc>
555 {
556 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
557 LocalNormalMatrixRow(LocalMatrix& localmatrix_, RT intEl_, Evaluators const& evaluators_,Cache const& cache_):
558 localmatrix(localmatrix_), intEl(intEl_), evaluators(evaluators_), cache(cache_)
559 {
560 }
561
562 template <class Row>
563 void operator()(Row const&) const
564 {
565 using namespace boost::fusion;
568 }
569
570 VarDesc varDesc;
574 Cache const& cache;
575 };
576
577 template <class LocalVector, class LocalMatrix>
579 LocalMatrix & A,
580 LocalVector& b)
581 {
582 double sum;
583 //Since Neumann problems are solved, achieve sum_i b_i = 0
584 int n = b.N()/2;
585 for(int row=0; row < 2; ++row)
586 {
587 sum=0.0;
588 for(int i=0; i<n; ++i) sum+=b[i+n*row];
589 sum /= n;
590 for(int i=0; i<n; ++i) b[i+n*row]-=sum;
591 }
592 A.solve(c,b);
593 }
594
595 template <class LocalRHS, class RT, class Cache, class Evaluators>
597 {
598 WeakResiduumFull(LocalRHS& localRHS_, RT intEl_,Cache const& cache_, Evaluators const& evaluators_):
599 localRHS(localRHS_), intEl(intEl_), evaluators(evaluators_), cache(cache_)
600 {
601 }
602
603 template <class Variable>
604 void operator()(Variable const& ) const
605 {
606 size_t n = localRHS.N()/2;
607 for(int row=0; row<n; ++row)
608 {
609 localRHS[row+(Variable::id)*n]
610 -= intEl * cache.template d1<Variable::id>(boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQFull[row]]);
611 }
612 }
613 LocalRHS& localRHS;
616 Cache const& cache;
617 };
618
619 template <class LocalSolution, class Evaluators, class GlobalSolution>
621 {
622 ScatterFullLocalSolution(LocalSolution const& localSolution_, Evaluators const& evaluators_, GlobalSolution& globalSolution_):
623 localSolution(localSolution_), eval(evaluators_), globalSolution(globalSolution_)
624 {}
625
626 template <class Variable>
627 void operator()(Variable const& ) const
628 {
629 using namespace boost::fusion;
630 typename result_of::value_at_c<Evaluators,Variable::spaceIndex>::type const& reval = at_c<Variable::spaceIndex>(eval);
631 int n=localSolution.N()/2;
632 for (size_t i=0; i<n; i++)
633 (*at_c<Variable::id>(globalSolution))[reval.globalIndices()[indQFull[i]]] += (localSolution)[i+(Variable::id)*n];
634 }
635
636 LocalSolution const& localSolution;
638 GlobalSolution& globalSolution;
639 };
640
641
642 template <class LocalInd, class RT, class Cache, int dim,class Evaluators>
644 {
645
646 GradientAverageFull(LocalInd& localInd_,
647 Dune::FieldVector<RT,dim>const & outernormal,
648 Cache const& cache_,
649 Cache const& cacheNeigh_,
650 Evaluators const& evaluators_):
651 localInd(localInd_), cache(cache_), cacheNeigh(cacheNeigh_), evaluators(evaluators_)
652 {
653 modarg.value=0;
654 modarg.gradient[0]=outernormal;
655 }
656
657 template <class Variable>
658 void operator()(Variable const& ) const
659 {
660 int n=localInd.N()/2;
661
662 for(int row=0; row<n; ++row)
663 localInd[row+(Variable::id)*n] +=0.5*(cache.template d1<Variable::id>(modarg)+cacheNeigh.template d1<Variable::id>(modarg))
664 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQFull[row]].value[0];
665 }
666
668 LocalInd& localInd;
669 Cache const& cache;
670 Cache const& cacheNeigh;
672 };
673
674 template <class LocalInd, class RT, class Cache, class BoundaryCache, int dim, class Evaluators>
676 {
677 WeakBoundaryValuesFull(LocalInd& localInd_,
678 RT& integrationElement,
679 Dune::FieldVector<RT,dim>const & outernormal,
680 Cache const& cache_,
681 BoundaryCache const& cacheBoundary_,
682 Evaluators const& evaluators_):
683 localInd(localInd_), cache(cache_), boundaryCache(cacheBoundary_),evaluators(evaluators_)
684 {
685 modargB.value=integrationElement;
686 modargB.gradient[0]=0;
688 modargTest.gradient[0]=0;
689 modarg.value=0;
690 modarg.gradient[0]=outernormal;
691 }
692
693 template <class Variable>
694 void operator()(Variable const& ) const
695 {
696 int n=localInd.size/2;
697 if(boundaryCache.template d2<Variable::pdeid,Variable::id>(modargTest,modargTest) < 1e5)
698 for(int row=0; row< n; ++row)
699 {
700 localInd[row+(Variable::id)*n] +=
701 boundaryCache.template d1<Variable::id>(modargB)
702 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQFull[row]].value[0];
703 }
704 else
705 for(int row=0; row< n; ++row)
706 {
707 localInd[row+(Variable::id)*n] +=
708 cache.template d1<Variable::id>(modarg)
709 *boost::fusion::at_c<Variable::spaceIndex>(evaluators).evalData[indQFull[row]].value[0];
710 }
711
712 }
713
715 LocalInd& localInd;
716 Cache const& cache;
717 BoundaryCache const& boundaryCache;
719 };
720
721
723
732 template <class VariableDescriptions, int sysdim, class Result, class F, class FS, class Spaces, class ExtendedSpaces>
733 void edgeAveragingFull(Result& result,
734 F const& f,
735 FS const& fs,
736 Spaces const& spaces,
737 ExtendedSpaces const& extendedSpaces)
738 {
739 using namespace boost::fusion;
740 using namespace Dune;
741
742 VariableDescriptions const varDesc;
743
744 typedef typename SpaceType<Spaces,0>::type::Grid Grid;
745 typedef typename SpaceType<Spaces,0>::type::IndexSet IndexSet;
746 typedef typename SpaceType<Spaces,0>::type::RT RT;
747 typedef typename Grid::ctype CoordType;
748 int const dim = Grid::dimension;
749
750 IndexSet const& indexSet = at_c<0>(spaces)->grid().leafIndexSet();
751
752
753 // Shape function cache. Remember that every thread has to use its own cache!
754 typedef ShapeFunctionCache<Grid,RT> SfCache;
755 SfCache sfCache,sfCacheN, sfCacheT;
756
757 // Evaluators for shape functions of all FE spaces. Remember that
758 // every thread has to use its own collection of evaluators!
759 typedef typename result_of::as_vector<
760 typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type
761 >::type Evaluators;
762
763 typedef typename result_of::as_vector<typename result_of::transform<ExtendedSpaces, GetEvaluators<SfCache> >::type>::type ExtendedEvaluators;
764
765 Evaluators evaluators(transform(spaces,GetEvaluators<SfCache>(&sfCache)));
766 ExtendedEvaluators extendedEvaluators(transform(extendedSpaces,GetEvaluators<SfCache>(&sfCacheT)));
767 Evaluators evaluatorsNeigh(transform(spaces,GetEvaluators<SfCache>(&sfCacheN)));
768
769 // Define iterator and entity type for stepping through all cells of the grid.
770 typedef typename IndexSet::template Codim<0>::template Partition<All_Partition>::Iterator CellIterator;
771 typedef typename CellIterator::Entity::LeafIntersectionIterator LII;
772 typedef typename CellIterator::Entity Entity;
773
774 typename F::DomainCache domainCache(f.createDomainCache(6+8)); // 6 means RHS+Op
775 typename FS::DomainCache domainCacheNeigh(fs.createDomainCache(6+8));
776 typename FS::DomainCache domainCacheSimpl(fs.createDomainCache(6+8));
777 typename FS::BoundaryCache boundaryCache(fs.createBoundaryCache(6+8));
778
781
782 LocalMatrix A;
783 LocalVector b,c;
784
785
786 // Iterate over all cells.
787 CellIterator end = indexSet.template end<0,All_Partition>();
788 for (CellIterator ci=indexSet.template begin<0,All_Partition>(); ci!=end; ++ci) {
789
790 A=0; b=0; c=0;
791 domainCache.moveTo(*ci);
792 domainCacheSimpl.moveTo(*ci);
793
794 moveEvaluatorsToCell(evaluators,*ci);
795 moveEvaluatorsToCell(extendedEvaluators,*ci);
796 int const shapeFunctionMaxOrder = maxOrder(evaluators);
797 shapeFunctionMaxOrder = std::max(shapeFunctionMaxOrder,maxOrder(extendedEvaluators));
798 int const p = f.integrationOrder(*ci,shapeFunctionMaxOrder,false);
799 int const pb = f.integrationOrder(*ci,shapeFunctionMaxOrder,true);
800
801 LII faceEnd = ci->ileafend();
802
803 GeometryType gti = ci->type();
804
805 QuadratureRule<CoordType, dim> const& qri=QuadratureRules<CoordType,dim>::rule(gti,p);
806
807 size_t nQuadPosi = qri.size();
808 for (size_t g=0; g<nQuadPosi; ++g) {
809 FieldVector<CoordType,dim> const& quadPos = qri[g].position();
810
811 moveEvaluatorsToIntegrationPoint(evaluators,quadPos,qri,g,0);
812 moveEvaluatorsToIntegrationPoint(extendedEvaluators,quadPos,qri,g,0);
813 domainCache.evaluateAt(quadPos,evaluators);
814 CoordType weightTimesDetJac(ci->geometry().integrationElement(quadPos)); // determinant of jacobian
815 weightTimesDetJac *= qri[g].weight();
817 (A,weightTimesDetJac, extendedEvaluators, domainCache));
819 (b, weightTimesDetJac,domainCache, extendedEvaluators));
820 }
821
822 for (LII face=ci->ileafbegin(); face!=faceEnd; ++face) {
823 if(face.neighbor()) {
824
825 typename LII::EntityPointer o=face.outside();
826 domainCacheNeigh.moveTo(*o);
827 moveEvaluatorsToCell(evaluatorsNeigh,*o);
828
829 } else if(face.boundary())
830 {
831 boundaryCache.moveTo(face);
832 }
833 GeometryType gt=face.intersectionSelfLocal().type();
834 QuadratureRule<CoordType, dim-1> const& qr=QuadratureRules<CoordType,dim-1>::rule(gt,pb);
835 size_t nQuadPos=qr.size();
836 for(size_t g=0; g<nQuadPos; ++g){
837 FieldVector<CoordType, dim-1> const& quadPos = qr[g].position();
838 FieldVector<CoordType, dim> const& quadPosInSelf = face.intersectionSelfLocal().global(quadPos);
839 moveEvaluatorsToIntegrationPoint(evaluators,quadPosInSelf,qr,g,face.numberInSelf());
840 moveEvaluatorsToIntegrationPoint(extendedEvaluators,quadPosInSelf,qr,g,face.numberInSelf());
841 domainCacheSimpl.evaluateAt(quadPosInSelf,evaluators);
842 FieldVector<RT, dim> outerNormal = face.integrationOuterNormal(quadPos);
843 outerNormal *= qr[g].weight();
844 if(face.neighbor())
845 {
846 Dune::FieldVector<typename Grid::ctype, Grid::dimension> const& quadPosInNeigh = face.intersectionNeighborLocal().global(quadPos);
847
848 moveEvaluatorsToIntegrationPoint(evaluatorsNeigh,quadPosInNeigh,qr,g,face.numberInNeighbor());
849 domainCacheNeigh.evaluateAt(quadPosInNeigh,evaluatorsNeigh);
851 (b,outerNormal,domainCacheSimpl,domainCacheNeigh, extendedEvaluators));
852
853 } else if(face.boundary())
854 {
855 boundaryCache.evaluateAt(quadPos,evaluators);
856
857 CoordType weightTimesDetJac = face.intersectionGlobal().integrationElement(quadPos); // determinant of jacobian
858 weightTimesDetJac *= qr[g].weight();
860 (b, weightTimesDetJac, outerNormal, domainCacheSimpl, boundaryCache, extendedEvaluators));
861 }
862 }
863 }
865 for_each(varDesc, ScatterFullLocalSolution<LocalVector, ExtendedEvaluators,typename Result::Functions>(c,extendedEvaluators,result.vars));
866 }
867 };
868
870 template< class Description, class Grid, class Functional, class FunctionalSimpl>
872 {
873
874 public:
875
877 typedef boost::fusion::vector<RecoverySpace const*> RecoverySpaces;
882
884 typedef boost::fusion::vector<ContRecoverySpace const*> ContRecoverySpaces;
887
888 template<class Spaces>
889 void getErrorFunction(RecoveryRepresentation & recovery, Spaces const& spaces, FunctionalSimpl const& vf)
890 {
891 edgeAveraging<Description,syst>(recovery, vf, spaces, recovery.descriptions.spaces);
892 }
893
894 template<class Spaces>
895 void getFullErrorFunction(RecoveryRepresentation & recovery, Spaces const& spaces, Functional const& vf, FunctionalSimpl const& vfs)
896 {
897 edgeAveragingFull<Description,systFull>(recovery, vf, vfs, spaces, recovery.descriptions.spaces);
898 }
899 };
900
902 template< class Description, class Function, class Functional>
904 BWErrorIndicator(Function const& f, Functional const& vf)
905 {
906 typedef typename Function::Grid Grid;
908
909 using namespace FunctionViews;
910 using namespace boost::fusion;
912 RecoverySpace rspace(at_c<0>(f.vars).space().gridManager(),at_c<0>(f.vars).space().indexSet(),2);
913 RecoverySpace r1space(at_c<0>(f.vars).space().gridManager(),at_c<0>(f.vars).space().indexSet(),1);
914 typedef boost::fusion::vector<RecoverySpace const*> RecoverySpaces;
915 RecoverySpaces rspaces(&rspace);
916
918
919 VariableSet variableSet(rspaces);
920
921 typedef typename VariableSet::VariableSet RecoveryRepresentation;
922
923 RecoveryRepresentation recovery(variableSet);
924 int const dim(Space::dim);
925 static int const syst = SystDim<RecoverySpace::dim>::value;
926
927 edgeAveraging<Description,syst>(recovery, vf, f.descriptions.spaces, rspaces);
928
929
930 typename RecoverySpace::template Element<dim>::type gradientFkt(r1space);
931 interpolateGloballyWeak<PlainAverage>(gradientFkt,makeView<Gradient>(at_c<0>(recovery.vars)));
932
933 LocalIntegral<Space> localIntegral;
935 errorIndicator(localIntegral(
936 makeView<AbsSquare>(gradientFkt)
937 ,at_c<0>(f.vars).space())
938 );
939 return errorIndicator;
940 }
941} /* end of namespace Kaskade */
946#endif
947
948
Function is the interface for evaluatable functions .
Definition: concepts.hh:324
Obtain an error function by solving local Neumann problems in the flavour of Bank/Weiser.
std::vector< CellDataPair > CellDataVector
Definition: celldata.hh:44
A representation of a finite element function space defined over a domain covered by a grid.
A boost::fusion functor for creating an evaluator from the space, using a shape function cache that i...
Create a CellData by computing local integrals over each Cell.
Providing a matrix or array interface to LAPACK-ordered entries.
Providing a vector interface for contiguously stored entries.
Definition: localVectors.hh:31
This class caches values and derivatives of shape functions at quadrature points.
A class that stores information about a set of variables.
Definition: variables.hh:537
A class for storing a heterogeneous collection of FunctionSpaceElement s.
Definition: variables.hh:341
VariableSet(Self const &vs)
Copy constructor.
Definition: variables.hh:362
Descriptions const & descriptions
Descriptions of variable set, of type VariableSetDescription (lots of useful infos)
Definition: variables.hh:510
Tools for transfer of data between grids.
Some useful views on FunctionSpaceElement s.
Two classes for the visualization of higher order grid functions.
GradientAverage(LocalInd &localInd_, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, Cache const &cacheNeigh_, Evaluators const &evaluators_)
VariationalArg< RT, dim > modargTest
RecoveryVariableSet::VariableSet RecoveryRepresentation
boost::fusion::vector< RecoverySpace const * > RecoverySpaces
void edgeAveragingFull(Result &result, F const &f, FS const &fs, Spaces const &spaces, ExtendedSpaces const &extendedSpaces)
Computes an error representation function, which is useful for goal oriented adaptivity.
VariationalArg< RT, dim > modarg
LocalNormalMatrixRow(LocalMatrix &localmatrix_, RT intEl_, Evaluators const &evaluators_, Cache const &cache_)
GradientAverageFull(LocalInd &localInd_, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, Cache const &cacheNeigh_, Evaluators const &evaluators_)
VariableSetDescription< RecoverySpaces, Description > RecoveryVariableSet
VariationalArg< RT, dim > modarg
void operator()(Row const &) const
WeakBoundaryValuesFull(LocalInd &localInd_, RT &integrationElement, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, BoundaryCache const &cacheBoundary_, Evaluators const &evaluators_)
void operator()(Variable const &) const
HalfGradientJump(LocalInd &localInd_, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, Cache const &cacheNeigh_, Evaluators const &evaluators_)
void operator()(Variable const &) const
void operator()(Variable const &) const
LocalSolution const & localSolution
VariationalArg< RT, dim > modargTest
void operator()(Variable const &) const
void operator()(Variable const &) const
void getErrorFunction(RecoveryRepresentation &recovery, Spaces const &spaces, FunctionalSimpl const &vf)
CellData< typenameFunction::Grid >::CellDataVector BWErrorIndicator(Function const &f, Functional const &vf)
Construct an error indicator in the flavour of Bank/Weiser.
VariationalArg< RT, dim > modargB
VariationalArg< RT, dim > modargB
Evaluators const & evaluators
static const int dim
VariationalArg< RT, dim > modargB
VariationalArg< RT, dim > modargTest
FEFunctionSpace< DiscontinuousLagrangeMapper< double, Grid > > RecoverySpace
StrongBoundaryValues(LocalInd &localInd_, RT &integrationElement, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, BoundaryCache const &cacheBoundary_, Evaluators const &evaluators_)
LocalNormalMatrixBlock(LocalMatrix &localmatrix_, RT intEl_, Evaluators const &evaluators_, Cache const &cache_)
void operator()(Col const &) const
LocalSolution const & localSolution
Evaluators const & evaluators
Evaluators const & evaluators
void operator()(Variable const &) const
void rank1KernelVector(LocalVector &localvector, RT intEl, Evaluators const &evaluators)
ScatterFullLocalSolution(LocalSolution const &localSolution_, Evaluators const &evaluators_, GlobalSolution &globalSolution_)
void operator()(Variable const &) const
static const int value
WeakResiduum(LocalRHS &localRHS_, RT intEl_, Cache const &cache_, Evaluators const &evaluators_)
BoundaryCache const & boundaryCache
void operator()(Variable const &) const
VariationalArg< RT, dim > modarg
VariationalArg< RT, dim > modarg
VariationalArg< RT, dim > modarg
ScatterLocalSolution(LocalSolution const &localSolution_, Evaluators const &evaluators_, GlobalSolution &globalSolution_)
void operator()(Variable const &) const
FEFunctionSpace< ContinuousLagrangeMapper< double, Grid > > ContRecoverySpace
void operator()(Variable const &) const
WeakResiduumMainPart(LocalRHS &localRHS_, RT intEl_, Cache const &cache_, Evaluators const &evaluators_)
VariableSetDescription< ContRecoverySpaces, Description > ContRecoveryVariableSet
BoundaryCache const & boundaryCache
BoundaryCache const & boundaryCache
WeakBoundaryValues(LocalInd &localInd_, RT &integrationElement, Dune::FieldVector< RT, dim >const &outernormal, Cache const &cache_, BoundaryCache const &cacheBoundary_, Evaluators const &evaluators_)
Evaluators const & evaluators
WeakResiduumFull(LocalRHS &localRHS_, RT intEl_, Cache const &cache_, Evaluators const &evaluators_)
void operator()(Variable const &) const
Evaluators const & evaluators
void solveLocalFullSystem(LocalVector &c, LocalMatrix &A, LocalVector &b)
ContRecoveryVariableSet::VariableSet ContRecoveryRepresentation
void edgeAveraging(Result &result, F const &f, Spaces const &spaces, ExtendedSpaces const &extendedSpaces)
Computes an error representation function, which is useful for goal oriented adaptivity.
void localNormalMatrix(LocalMatrix &localmatrix, RT intEl, Evaluators const &evaluators, Cache const &cache)
void getFullErrorFunction(RecoveryRepresentation &recovery, Spaces const &spaces, Functional const &vf, FunctionalSimpl const &vfs)
void operator()(Variable const &) const
static const int value
VariationalArg< RT, dim > modarg
SolveLocalSystem(LocalVector &c_, LocalMatrix &A_, LocalVector &b_)
boost::fusion::vector< ContRecoverySpace const * > ContRecoverySpaces
void moveEvaluatorsToIntegrationPoint(Evaluators &evals, Dune::FieldVector< CoordType, dim > const &x, Dune::QuadratureRule< CoordType, subDim > const &qr, int ip, int subId)
Moves all provided evaluators to the given integration point, evaluating the shape functions there.
int maxOrder(Evaluators const &evals)
Computes the maximum ansatz order used in a collection of evaluators.
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
Extracts the type of FE space with given index from set of spaces.
A class defining elementary information about a single variable.
Definition: variables.hh:128
ValueType value
The shape function's value, a vector of dimension components