KASKADE 7 development version
residual_errorest.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 RESIDUAL_ERROREST_HH
14#define RESIDUAL_ERROREST_HH
15
16#include "fem/assemble.hh"
17
18namespace Kaskade
19{
20 template <class LocalInd, class Evaluators, class RT, class TestFunctions, class Cache>
22 {
23 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
24
25 GradientJumpsTimesTestFunction(LocalInd& localInd_,
26 Dune::FieldVector<RT,dim>const & outernormal_,
27 Evaluators const& evaluators_,
28 TestFunctions const& tf_,
29 Cache const& cache_,
30 Cache const& cacheNeigh_):
31 localInd(localInd_), evaluators(evaluators_), tf(tf_), cache(cache_), cacheNeigh(cacheNeigh_)
32 {
33 modarg.value=0;
34 modarg.gradient[0]=outernormal_;
35 }
36
37 template <class Variable>
38 void operator()(Variable const& ) const
39 {
40 localInd[Variable::id] -= 0.5*(cache.template d1<Variable::id>(modarg)-cacheNeigh.template d1<Variable::id>(modarg))*
41 boost::fusion::at_c<Variable::id>(tf.vars).value(boost::fusion::at_c<Variable::spaceIndex>(evaluators));
42 }
43
45 LocalInd& localInd;
47 TestFunctions const& tf;
48 Cache const& cache;
49 Cache const& cacheNeigh;
50 };
51
52 template <class LocalInd, class Evaluators, class RT, class TestFunctions, class Cache, class BoundaryCache>
54 {
55 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
56
57 BoundaryJumpsTimesTestFunction(LocalInd& localInd_,
58 Dune::FieldVector<RT,dim>const & outernormal_,
59 RT const & integrationElement_,
60 Evaluators const& evaluators_,
61 TestFunctions const& tf_,
62 Cache const& cache_,
63 BoundaryCache const& cacheBoundary_):
64 localInd(localInd_), evaluators(evaluators_), tf(tf_), cache(cache_), cacheBoundary(cacheBoundary_)
65 {
66 modarg.value=0;
67 modarg.gradient[0]=outernormal_;
68 modargB.value=integrationElement_;
69 modargB.gradient[0]=0;
70 }
71
72 template <class Variable>
73 void operator()(Variable const& ) const
74 {
75 if(cacheBoundary.template d2<Variable::pdeid,Variable::id>(modargB,modargB) < 1e5)
76 localInd[Variable::id] -=
77 (cache.template d1<Variable::id>(modarg)+cacheBoundary.template d1<Variable::id>(modargB))*
78 boost::fusion::at_c<Variable::id>(tf.vars).value(boost::fusion::at_c<Variable::spaceIndex>(evaluators));
79 }
80
82 LocalInd& localInd;
84 TestFunctions const& tf;
85 Cache const& cache;
86 BoundaryCache const& cacheBoundary;
87 };
88
89 template <class LocalInd, class Evaluators, class RT, class TestFunctions, class Cache>
91 {
92 static const int dim = boost::fusion::result_of::value_at_c<Evaluators,0>::type::Space::dim;
93
95 RT const & integrationElement,
96 Evaluators const& evaluators_,
97 TestFunctions const& tf_,
98 Cache const& cache_):
99 localInd(localInd_), evaluators(evaluators_), tf(tf_), cache(cache_)
100 {
101 modarg.value=integrationElement;
102 modarg.gradient[0]=0;
103 }
104
105 template <class Variable>
106 void operator()(Variable const& ) const
107 {
108 localInd[Variable::id] += cache.template d1<Variable::id>(modarg)*
109 boost::fusion::at_c<Variable::id>(tf.vars).value(boost::fusion::at_c<Variable::spaceIndex>(evaluators));
110 }
111
113 LocalInd& localInd;
115 TestFunctions const& tf;
116 Cache const& cache;
117 };
118
119
131 template <class ErrorDescriptions, class F, class FS, class TestFunctions, class Spaces, class TestSpaces>
133 boost::fusion::result_of::size<ErrorDescriptions>::type::value> >& ind,
134 ErrorDescriptions const& varDesc,
135 F const& f,
136 FS const& fs,
137 TestFunctions const& tf,
138 Spaces const& spaces,
139 TestSpaces const& testSpaces)
140 {
141 using namespace boost::fusion;
142 using namespace Dune;
143
144
145 typedef typename SpaceType<Spaces,0>::type::Grid Grid;
146 typedef typename SpaceType<Spaces,0>::type::IndexSet IndexSet;
147 typedef typename SpaceType<Spaces,0>::type::RT RT;
148 typedef typename Grid::ctype CoordType;
149 int const dim = Grid::dimension;
150
151 IndexSet const& indexSet = at_c<0>(spaces)->grid().leafIndexSet();
152
153 ind.resize(indexSet.size(0));
154
155 for(int i=0; i<ind.size(); ++i)
156 for(int j=0; j<ind[i].N(); ++j)
157 ind[i][j]=0.0;
158
159 // Shape function cache. Remember that every thread has to use its own cache!
160 typedef ShapeFunctionCache<Grid,RT> SfCache;
161 SfCache sfCache,sfCacheN,sfCacheT;
162
163 // Evaluators for shape functions of all FE spaces. Remember that
164 // every thread has to use its own collection of evaluators!
165 typedef typename result_of::as_vector<
166 typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type
167 >::type Evaluators;
168
169 typedef typename result_of::as_vector<
170 typename result_of::transform<TestSpaces, GetEvaluators<SfCache> >::type
171 >::type TestEvaluators;
172
173 Evaluators evaluators(transform(spaces,GetEvaluators<SfCache>(&sfCache)));
174 TestEvaluators testEvaluators(transform(testSpaces,GetEvaluators<SfCache>(&sfCacheT)));
175 Evaluators evaluatorsNeigh(transform(spaces,GetEvaluators<SfCache>(&sfCacheN)));
176
177 // Define iterator and entity type for stepping through all cells of the grid.
178 typedef typename IndexSet::template Codim<0>::template Partition<All_Partition>::Iterator CellIterator;
179 typedef typename CellIterator::Entity::LeafIntersectionIterator LII;
180 typedef typename CellIterator::Entity Entity;
181
182 typename F::DomainCache domainCache(f.createDomainCache(2)); // 2 means RHS
183 typename FS::DomainCache domainCacheSimpl(fs.createDomainCache(2+8));
184 typename FS::DomainCache domainCacheNeigh(fs.createDomainCache(2+8));
185 typename FS::BoundaryCache boundaryCache(fs.createBoundaryCache(6));
187
188 // Iterate over all cells.
189 CellIterator end = indexSet.template end<0,All_Partition>();
190 for (CellIterator ci=indexSet.template begin<0,All_Partition>(); ci!=end; ++ci) {
191
192 domainCache.moveTo(*ci);
193 domainCacheSimpl.moveTo(*ci);
194
195 moveEvaluatorsToCell(evaluators,*ci);
196 moveEvaluatorsToCell(testEvaluators,*ci);
197 int shapeFunctionMaxOrder = maxOrder(evaluators);
198 shapeFunctionMaxOrder = std::max(shapeFunctionMaxOrder,maxOrder(testEvaluators));
199 int p = f.integrationOrder(*ci,shapeFunctionMaxOrder,false);
200 int pb = f.integrationOrder(*ci,shapeFunctionMaxOrder,true);
201 pb=shapeFunctionMaxOrder+2;
202 p = pb+1;
203
204 GeometryType gti = ci->type();
205
206 QuadratureRule<CoordType, dim> const& qri=QuadratureRules<CoordType,dim>::rule(gti,p);
207
208 size_t nQuadPosi = qri.size();
209 for (size_t g=0; g<nQuadPosi; ++g) {
210 FieldVector<CoordType,dim> const& quadPos = qri[g].position();
211
212 moveEvaluatorsToIntegrationPoint(evaluators,quadPos,qri,g,0);
213 moveEvaluatorsToIntegrationPoint(testEvaluators,quadPos,qri,g,0);
214 domainCache.evaluateAt(quadPos,evaluators);
215 CoordType weightTimesDetJac(ci->geometry().integrationElement(quadPos)); // determinant of jacobian
216 weightTimesDetJac *= qri[g].weight();
218 (ind[indexSet.index(*ci)],weightTimesDetJac,testEvaluators, tf,domainCache));
219 }
220
221 LII faceEnd = ci->ileafend();
222 for (LII face=ci->ileafbegin(); face!=faceEnd; ++face) {
223 if(face.neighbor()) {
224
225 typename LII::EntityPointer o=face.outside();
226 domainCacheNeigh.moveTo(*o);
227 moveEvaluatorsToCell(evaluatorsNeigh,*o);
228
229 } else if(face.boundary())
230 {
231 boundaryCache.moveTo(face);
232 }
233 GeometryType gt=face.intersectionSelfLocal().type();
234 QuadratureRule<CoordType, dim-1> const& qr=QuadratureRules<CoordType,dim-1>::rule(gt,pb);
235 size_t nQuadPos=qr.size();
236 for(size_t g=0; g<nQuadPos; ++g){
237 FieldVector<CoordType, dim-1> const& quadPos = qr[g].position();
238 FieldVector<CoordType, dim> const& quadPosInSelf = face.intersectionSelfLocal().global(quadPos);
239 moveEvaluatorsToIntegrationPoint(evaluators,quadPosInSelf,qr,g,face.numberInSelf());
240 moveEvaluatorsToIntegrationPoint(testEvaluators,quadPosInSelf,qr,g,face.numberInSelf());
241 domainCacheSimpl.evaluateAt(quadPosInSelf,evaluators);
242 FieldVector<RT, dim> outerNormal = face.integrationOuterNormal(quadPos);
243 outerNormal *= qr[g].weight();
244 if(face.neighbor())
245 {
246 Dune::FieldVector<typename Grid::ctype, Grid::dimension> const& quadPosInNeigh = face.intersectionNeighborLocal().global(quadPos);
247
248 moveEvaluatorsToIntegrationPoint(evaluators,Neigh,quadPosInNeigh,qr,g,face.numberInNeighbor());
249 domainCacheNeigh.evaluateAt(quadPosInNeigh,evaluatorsNeigh);
250
251 for_each(varDesc,GradientJumpsTimesTestFunction<LocalInd,TestEvaluators,RT, TestFunctions,
252 typename FS::DomainCache>(ind[indexSet.index(*ci)],outerNormal,testEvaluators, tf,domainCacheSimpl,domainCacheNeigh));
253
254 } else if(face.boundary())
255 {
256 boundaryCache.evaluateAt(quadPos,evaluators);
257
258 CoordType weightTimesDetJac = face.intersectionGlobal().integrationElement(quadPos); // determinant of jacobian
259 weightTimesDetJac *= qr[g].weight();
260
261 for_each(varDesc,BoundaryJumpsTimesTestFunction<LocalInd,TestEvaluators,RT, TestFunctions,
262 typename FS::DomainCache, typename FS::BoundaryCache>(ind[indexSet.index(*ci)],outerNormal, weightTimesDetJac,
263 testEvaluators, tf,domainCacheSimpl,boundaryCache));
264 }
265 }
266 }
267 }
268 };
269} // end of namespace Kaskade
270#endif
A boost::fusion functor for creating an evaluator from the space, using a shape function cache that i...
This class caches values and derivatives of shape functions at quadrature points.
void residualTimesTestFunction(std::vector< Dune::FieldVector< typename SpaceType< Spaces, 0 >::type::RT, boost::fusion::result_of::size< ErrorDescriptions >::type::value > > &ind, ErrorDescriptions const &varDesc, F const &f, FS const &fs, TestFunctions const &tf, Spaces const &spaces, TestSpaces const &testSpaces)
Evaluates strong residual, applied to some test-function <f(x), tf>
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.
void operator()(Variable const &) const
BoundaryJumpsTimesTestFunction(LocalInd &localInd_, Dune::FieldVector< RT, dim >const &outernormal_, RT const &integrationElement_, Evaluators const &evaluators_, TestFunctions const &tf_, Cache const &cache_, BoundaryCache const &cacheBoundary_)
GradientJumpsTimesTestFunction(LocalInd &localInd_, Dune::FieldVector< RT, dim >const &outernormal_, Evaluators const &evaluators_, TestFunctions const &tf_, Cache const &cache_, Cache const &cacheNeigh_)
void operator()(Variable const &) const
Extracts the type of FE space with given index from set of spaces.
StrongResidualsTimesTestFunction(LocalInd &localInd_, RT const &integrationElement, Evaluators const &evaluators_, TestFunctions const &tf_, Cache const &cache_)
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