evolve.hh
Go to the documentation of this file.
1 #include <dune/common/version.hh>
2 #include<dune/geometry/referenceelements.hh>
3 
4 template<class G, class M, class V>
5 void evolve(const G& grid, const M& mapper, V& c, double t, double& dt)
6 {
7  // first we extract the dimensions of the grid
8  const int dim = G::dimension;
9  const int dimworld = G::dimensionworld;
10 
11  // type used for coordinates in the grid
12  typedef typename G::ctype ct;
13 
14  // type of grid view on leaf part
15  typedef typename G::LeafGridView GridView;
16 
17  // element iterator type
18  typedef typename GridView::template Codim<0>::Iterator LeafIterator;
19 
20  // intersection iterator type
21  typedef typename GridView::IntersectionIterator IntersectionIterator;
22 
23  // entity pointer type
24  typedef typename G::template Codim<0>::EntityPointer EntityPointer;
25 
26  // get grid view on leaf part
27  GridView gridView = grid.leafGridView();
28 
29  // allocate a temporary vector for the update
30  V update(c.size()); /*@\label{evh:update}@*/
31  for (typename V::size_type i=0; i<c.size(); i++) update[i] = 0;
32 
33  // initialize dt very large
34  dt = 1E100;
35 
36  // compute update vector and optimum dt in one grid traversal
37  LeafIterator endit = gridView.template end<0>(); /*@\label{evh:loop0}@*/
38  for (LeafIterator it = gridView.template begin<0>(); it!=endit; ++it) {
39  // cell geometry type
40  Dune::GeometryType gt = it->type();
41 
42  // cell center in reference element
43  const Dune::FieldVector<ct,dim>&
44 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
45  local = Dune::ReferenceElements<ct,dim>::general(gt).position(0,0);
46 #else
47  local = Dune::GenericReferenceElements<ct,dim>::general(gt).position(0,0);
48 #endif
49 
50  // cell center in global coordinates
51  /* Dune::FieldVector<ct,dimworld>
52  global = it->geometry().center(); */
53 
54  // cell volume, assume linear map here
55 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
56  double volume = it->geometry().integrationElement(local)
57  *Dune::ReferenceElements<ct,dim>::general(gt).volume();
58 #else
59  double volume = it->geometry().integrationElement(local)
60  *Dune::GenericReferenceElements<ct,dim>::general(gt).volume();
61 #endif
62  // double volume = it->geometry().volume();
63 
64 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 4)
65  // cell index
66  int indexi = mapper.index(*it);
67 #else
68  // cell index
69  int indexi = mapper.map(*it);
70 #endif
71 
72  // variable to compute sum of positive factors
73  double sumfactor = 0.0;
74  // run through all intersections with neighbors and boundary
75  IntersectionIterator isend = gridView.iend(*it); /*@\label{evh:flux0}@*/
76  for (IntersectionIterator is = gridView.ibegin(*it); is!=isend; ++is) {
77 
78  // get geometry type of face
79  // Dune::GeometryType gtf = is->intersectionSelfLocal().type();
80  Dune::GeometryType gtf = is->type();
81 
82  // center in face's reference element
83  const Dune::FieldVector<ct,dim-1>&
84 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
85  facelocal = Dune::ReferenceElements<ct,dim-1>::general(gtf).position(0,0);
86 #else
87  facelocal = Dune::GenericReferenceElements<ct,dim-1>::general(gtf).position(0,0);
88 #endif
89 
90  // get normal vector scaled with volume
91  Dune::FieldVector<ct,dimworld> integrationOuterNormal
92  = is->integrationOuterNormal(facelocal);
93  integrationOuterNormal
94 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
95  *= Dune::ReferenceElements<ct,dim-1>::general(gtf).volume();
96 #else
97  *= Dune::GenericReferenceElements<ct,dim-1>::general(gtf).volume();
98 #endif
99 
100  // center of face in global coordinates
101  Dune::FieldVector<ct,dimworld>
102  faceglobal = is->geometry().center();
103 
104 
105  // evaluate velocity at face center
106  Dune::FieldVector<double,dim> velocity = u(faceglobal,t);
107 
108  // compute factor occuring in flux formula
109  double factor = velocity*integrationOuterNormal/volume;
110 
111  // for time step calculation
112  if (factor>=0) sumfactor += factor;
113 
114  // handle interior face
115  if (is->neighbor()) // "correct" version /*@\label{evh:neighbor}@*/
116  {
117  // access neighbor
118  EntityPointer outside = is->outside();
119 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 4)
120  int indexj = mapper.index(*outside);
121 #else
122  int indexj = mapper.map(*outside);
123 #endif
124 
125  // compute flux from one side only
126  // this should become easier with the new IntersectionIterator functionality!
127  if (it->level()>outside->level() ||
128  (it->level()==outside->level() && indexi<indexj))
129  {
130  // compute factor in neighbor
131  Dune::GeometryType nbgt = outside->type();
132  const Dune::FieldVector<ct,dim>&
133 #if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
134  nblocal = Dune::ReferenceElements<ct,dim>::general(nbgt).position(0,0);
135  double nbvolume = outside->geometry().integrationElement(nblocal)
136  *Dune::ReferenceElements<ct,dim>::general(nbgt).volume();
137 #else
138  nblocal = Dune::GenericReferenceElements<ct,dim>::general(nbgt).position(0,0);
139  double nbvolume = outside->geometry().integrationElement(nblocal)
140  *Dune::GenericReferenceElements<ct,dim>::general(nbgt).volume();
141 #endif
142  double nbfactor = velocity*integrationOuterNormal/nbvolume;
143 
144  if (factor<0) // inflow
145  {
146  update[indexi] -= c[indexj]*factor;
147  update[indexj] += c[indexj]*nbfactor;
148  } else // outflow
149  {
150  update[indexi] -= c[indexi]*factor;
151  update[indexj] += c[indexi]*nbfactor;
152  }
153  }
154  }
155 
156  // handle boundary face
157  if (is->boundary()) /*@\label{evh:bndry}@*/
158  {
159  if (factor<0) // inflow, apply boundary condition
160  update[indexi] -= b(faceglobal,t)*factor;
161  else // outflow
162  update[indexi] -= c[indexi]*factor;
163  }
164  } // end all intersections /*@\label{evh:flux1}@*/
165  // compute dt restriction
166  dt = std::min(dt,1.0/sumfactor); /*@\label{evh:dt}@*/
167 
168  } // end grid traversal /*@\label{evh:loop1}@*/
169 
170  // scale dt with safety factor
171  dt *= 0.99; /*@\label{evh:.99}@*/
172 
173  // update the concentration vector
174  for (unsigned int i=0; i<c.size(); ++i)
175  c[i] += dt*update[i]; /*@\label{evh:updc}@*/
176 
177  return;
178 }
Dune::FieldVector< double, dimworld > u(const Dune::FieldVector< ct, dimworld > &, double)
Definition: transportproblem2.hh:36
void evolve(const G &grid, const M &mapper, V &c, double t, double &dt)
Definition: evolve.hh:5
double b(const Dune::FieldVector< ct, dimworld > &x, double t)
Definition: transportproblem2.hh:25