evolve.hh
Go to the documentation of this file.
1#include <dune/common/version.hh>
2#include<dune/geometry/referenceelements.hh>
3
4template<class G, class M, class V>
5void 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
24 // get grid view on leaf part
25 GridView gridView = grid.leafGridView();
26
27 // allocate a temporary vector for the update
28 V update(c.size()); /*@\label{evh:update}@*/
29 for (typename V::size_type i=0; i<c.size(); i++) update[i] = 0;
30
31 // initialize dt very large
32 dt = 1E100;
33
34 // compute update vector and optimum dt in one grid traversal
35 LeafIterator endit = gridView.template end<0>(); /*@\label{evh:loop0}@*/
36 for (LeafIterator it = gridView.template begin<0>(); it!=endit; ++it) {
37 // cell geometry type
38 Dune::GeometryType gt = it->type();
39
40 // cell center in reference element
41 const Dune::FieldVector<ct,dim>&
42 local = Dune::ReferenceElements<ct,dim>::general(gt).position(0,0);
43
44 // cell center in global coordinates
45 /* Dune::FieldVector<ct,dimworld>
46 global = it->geometry().center(); */
47
48 // cell volume, assume linear map here
49 double volume = it->geometry().integrationElement(local)
50 *Dune::ReferenceElements<ct,dim>::general(gt).volume();
51 // double volume = it->geometry().volume();
52
53 // cell index
54 int indexi = mapper.index(*it);
55
56 // variable to compute sum of positive factors
57 double sumfactor = 0.0;
58 // run through all intersections with neighbors and boundary
59 IntersectionIterator isend = gridView.iend(*it); /*@\label{evh:flux0}@*/
60 for (IntersectionIterator is = gridView.ibegin(*it); is!=isend; ++is) {
61
62 // get geometry type of face
63 // Dune::GeometryType gtf = is->intersectionSelfLocal().type();
64 Dune::GeometryType gtf = is->type();
65
66 // center in face's reference element
67 const Dune::FieldVector<ct,dim-1>&
68 facelocal = Dune::ReferenceElements<ct,dim-1>::general(gtf).position(0,0);
69
70 // get normal vector scaled with volume
71 Dune::FieldVector<ct,dimworld> integrationOuterNormal
72 = is->integrationOuterNormal(facelocal);
73 integrationOuterNormal
74 *= Dune::ReferenceElements<ct,dim-1>::general(gtf).volume();
75
76 // center of face in global coordinates
77 Dune::FieldVector<ct,dimworld>
78 faceglobal = is->geometry().center();
79
80
81 // evaluate velocity at face center
82 Dune::FieldVector<double,dim> velocity = u(faceglobal,t);
83
84 // compute factor occuring in flux formula
85 double factor = velocity*integrationOuterNormal/volume;
86
87 // for time step calculation
88 if (factor>=0) sumfactor += factor;
89
90 // handle interior face
91 if (is->neighbor()) // "correct" version /*@\label{evh:neighbor}@*/
92 {
93 // access neighbor
94 const auto& outside = is->outside();
95 int indexj = mapper.index(outside);
96
97 // compute flux from one side only
98 // this should become easier with the new IntersectionIterator functionality!
99 if (it->level()>outside.level() ||
100 (it->level()==outside.level() && indexi<indexj))
101 {
102 // compute factor in neighbor
103 Dune::GeometryType nbgt = outside.type();
104 const Dune::FieldVector<ct,dim>&
105 nblocal = Dune::ReferenceElements<ct,dim>::general(nbgt).position(0,0);
106 double nbvolume = outside.geometry().integrationElement(nblocal)
107 *Dune::ReferenceElements<ct,dim>::general(nbgt).volume();
108
109 double nbfactor = velocity*integrationOuterNormal/nbvolume;
110
111 if (factor<0) // inflow
112 {
113 update[indexi] -= c[indexj]*factor;
114 update[indexj] += c[indexj]*nbfactor;
115 } else // outflow
116 {
117 update[indexi] -= c[indexi]*factor;
118 update[indexj] += c[indexi]*nbfactor;
119 }
120 }
121 }
122
123 // handle boundary face
124 if (is->boundary()) /*@\label{evh:bndry}@*/
125 {
126 if (factor<0) // inflow, apply boundary condition
127 update[indexi] -= b(faceglobal,t)*factor;
128 else // outflow
129 update[indexi] -= c[indexi]*factor;
130 }
131 } // end all intersections /*@\label{evh:flux1}@*/
132 // compute dt restriction
133 dt = std::min(dt,1.0/sumfactor); /*@\label{evh:dt}@*/
134
135 } // end grid traversal /*@\label{evh:loop1}@*/
136
137 // scale dt with safety factor
138 dt *= 0.99; /*@\label{evh:.99}@*/
139
140 // update the concentration vector
141 for (unsigned int i=0; i<c.size(); ++i)
142 c[i] += dt*update[i]; /*@\label{evh:updc}@*/
143
144 return;
145}
void evolve(const G &grid, const M &mapper, V &c, double t, double &dt)
Definition: evolve.hh:5
T volume(const Point< T, 3 > *c)
Computes the volume of a 3D simplex (embedded i 3D space).
Definition: Volumes.hpp:137
double b(const Dune::FieldVector< ct, dimworld > &x, double t)
Definition: transportproblem2.hh:25
Dune::FieldVector< double, dimworld > u(const Dune::FieldVector< ct, dimworld > &, double)
Definition: transportproblem2.hh:36