1<a name="Intro"></a>
2<h1>Introduction</h1>
3
4@dealiiVideoLecture{15,16,17,17.25,17.5,17.75}
5
6This program is finally about one of the main features of deal.II:
7the use of adaptively (locally) refined meshes. The program is still
8based on step-4 and step-5, and, as you will see, it does not actually
9take very much code to enable adaptivity. Indeed, while we do a great
10deal of explaining, adaptive meshes can be added to an existing program
11with barely a dozen lines of additional code. The program shows what
12these lines are, as well as another important ingredient of adaptive
13mesh refinement (AMR): a criterion that can be used to determine whether
14it is necessary to refine a cell because the error is large on it,
15whether the cell can be coarsened because the error is particularly
16small on it, or whether we should just leave the cell as it is. We
17will discuss all of these issues in the following.
18
19
20<h3> What adaptively refined meshes look like </h3>
21
22There are a number of ways how one can adaptively refine meshes. The
23basic structure of the overall algorithm is always the same and consists
24of a loop over the following steps:
25- Solve the PDE on the current mesh;
26- Estimate the error on each cell using some criterion that is indicative
27  of the error;
28- Mark those cells that have large errors for refinement, mark those that have
29  particularly small errors for coarsening, and leave the rest alone;
30- Refine and coarsen the cells so marked to obtain a new mesh;
31- Repeat the steps above on the new mesh until the overall error is
32  sufficiently small.
33
34For reasons that are probably lost to history (maybe that these functions
35used to be implemented in FORTRAN, a language that does not care about
36whether something is spelled in lower or UPPER case letters, with programmers
37often choosing upper case letters habitually), the loop above is often
38referenced in publications about mesh adaptivity as the
39SOLVE-ESTIMATE-MARK-REFINE loop (with this spelling).
40
41Beyond this structure, however, there are a variety of ways to achieve
42this. Fundamentally, they differ in how exactly one generates one mesh
43from the previous one.
44
45If one were to use triangles (which deal.II does not do), then there are
46two essential possibilities:
47- Longest-edge refinement: In this strategy, a triangle marked for refinement
48  is cut into two by introducing one new edge from the midpoint of the longest
49  edge to the opposite vertex. Of course, the midpoint from the longest edge
50  has to somehow be balanced by *also* refining the cell on the other side of
51  that edge (if there is one). If the edge in question is also the longest
52  edge of the neighboring cell, then we can just run a new edge through the
53  neighbor to the opposite vertex; otherwise a slightly more involved
54  construction is necessary that adds more new vertices on at least one
55  other edge of the neighboring cell, and then may propagate to the neighbors
56  of the neighbor until the algorithm terminates. This is hard to describe
57  in words, and because deal.II does not use triangles not worth the time here.
58  But if you're curious, you can always watch video lecture 15 at the link
59  shown at the top of this introduction.
60- Red-green refinement: An alternative is what is called "red-green refinement".
61  This strategy is even more difficult to describe (but also discussed in the
62  video lecture) and has the advantage that the refinement does not propagate
63  beyond the immediate neighbors of the cell that we want to refine. It is,
64  however, substantially more difficult to implement.
65
66There are other variations of these approaches, but the important point is
67that they always generate a mesh where the lines where two cells touch
68are entire edges of both adjacent cells. With a bit of work, this strategy
69is readily adapted to three-dimensional meshes made from tetrahedra.
70
71Neither of these methods works for quadrilaterals in 2d and hexahedra in 3d,
72or at least not easily. The reason is that the transition elements created
73out of the quadrilateral neighbors of a quadrilateral cell that is to be refined
74would be triangles, and we don't want this. Consequently,
75the approach to adaptivity chosen in deal.II is to use grids in which
76neighboring cells may differ in refinement level by one. This then
77results in nodes on the interfaces of cells which belong to one
78side, but are unbalanced on the other. The common term for these is
79&ldquo;hanging nodes&rdquo;, and these meshes then look like this in a very
80simple situation:
81
82@image html hanging_nodes.png "A simple mesh with hanging nodes"
83
84A more complicated two-dimensional mesh would look like this (and is
85discussed in the "Results" section below):
86
87<img src="https://www.dealii.org/images/steps/developer/step_6_grid_5_ladutenko.svg"
88     alt="Fifth adaptively refined Ladutenko grid: the cells are clustered
89          along the inner circle."
90     width="300" height="300">
91
92Finally, a three-dimensional mesh (from step-43) with such hanging nodes is shown here:
93
94<img src="https://www.dealii.org/images/steps/developer/step-43.3d.mesh.png" alt=""
95     width="300" height="300">
96
97The first and third mesh are of course based on a square and a cube, but as the
98second mesh shows, this is not necessary. The important point is simply that we
99can refine a mesh independently of its neighbors (subject to the constraint
100that a cell can be only refined once more than its neighbors), but that we end
101up with these &ldquo;hanging nodes&rdquo; if we do this.
102
103
104<h3> Why adapatively refined meshes? </h3>
105
106Now that you have seen what these adaptively refined meshes look like,
107you should ask <i>why</i> we would want to do this. After all, we know from
108theory that if we refine the mesh globally, the error will go down to zero
109as
110@f{align*}{
111  \|\nabla(u-u_h)\|_{\Omega} \le C h_\text{max}^p \| \nabla^{p+1} u \|_{\Omega},
112@f}
113where $C$ is some constant independent of $h$ and $u$,
114$p$ is the polynomial degree of the finite element in use, and
115$h_\text{max}$ is the diameter of the largest cell. So if the
116<i>largest</i> cell is important, then why would we want to make
117the mesh fine in some parts of the domain but not all?
118
119The answer lies in the observation that the formula above is not
120optimal. In fact, some more work shows that the following
121is a better estimate (which you should compare to the square of
122the estimate above):
123@f{align*}{
124  \|\nabla(u-u_h)\|_{\Omega}^2 \le C \sum_K h_K^{2p} \| \nabla^{p+1} u \|^2_K.
125@f}
126(Because $h_K\le h_\text{max}$, this formula immediately implies the
127previous one if you just pull the mesh size out of the sum.)
128What this formula suggests is that it is not necessary to make
129the <i>largest</i> cell small, but that the cells really only
130need to be small <i>where $\| \nabla^{p+1} u \|_K$ is large</i>!
131In other words: The mesh really only has to be fine where the
132solution has large variations, as indicated by the $p+1$st derivative.
133This makes intuitive sense: if, for example, we use a linear element
134$p=1$, then places where the solution is nearly linear (as indicated
135by $\nabla^2 u$ being small) will be well resolved even if the mesh
136is coarse. Only those places where the second derivative is large
137will be poorly resolved by large elements, and consequently
138that's where we should make the mesh small.
139
140Of course, this <i>a priori estimate</i> is not very useful
141in practice since we don't know the exact solution $u$ of the
142problem, and consequently, we cannot compute $\nabla^{p+1}u$.
143But, and that is the approach commonly taken, we can compute
144numerical approximations of $\nabla^{p+1}u$ based only on
145the discrete solution $u_h$ that we have computed before. We
146will discuss this in slightly more detail below. This will then
147help us determine which cells have a large $p+1$st derivative,
148and these are then candidates for refining the mesh.
149
150
151<h3> How to deal with hanging nodes in theory </h3>
152
153The methods using triangular meshes mentioned above go to great
154lengths to make sure that each vertex is a vertex of all adjacent
155cells -- i.e., that there are no hanging nodes. This then
156automatically makes sure that we can define shape functions in such a
157way that they are globally continuous (if we use the common $Q_p$
158Lagrange finite element methods we have been using so far in the
159tutorial programs, as represented by the FE_Q class).
160
161On the other hand, if we define shape functions on meshes with hanging
162nodes, we may end up with shape functions that are not continuous. To
163see this, think about the situation above where the top right cell is
164not refined, and consider for a moment the use of a bilinear finite
165element. In that case, the shape functions associated with the hanging
166nodes are defined in the obvious way on the two small cells adjacent
167to each of the hanging nodes. But how do we extend them to the big
168adjacent cells? Clearly, the function's extension to the big cell
169cannot be bilinear because then it needs to be linear along each edge
170of the large cell, and that means that it needs to be zero on the
171entire edge because it needs to be zero on the two vertices of the
172large cell on that edge. But it is not zero at the hanging node itself
173when seen from the small cells' side -- so it is not continuous. The
174following three figures show three of the shape functions along the
175edges in question that turn out to not be continuous when defined in
176the usual way simply based on the cells they are adjacent to:
177
178<div class="threecolumn" style="width: 80%">
179  <div class="parent">
180    <div class="img" align="center">
181      @image html hanging_nodes_shape_functions_1.png "A discontinuous shape function adjacent to a hanging node"
182    </div>
183  </div>
184  <div class="parent">
185    <div class="img" align="center">
186      @image html hanging_nodes_shape_functions_2.png "A discontinuous shape function at a hanging node"
187    </div>
188  </div>
189  <div class="parent">
190    <div class="img" align="center">
191      @image html hanging_nodes_shape_functions_3.png "A discontinuous shape function adjacent to a hanging node"
192    </div>
193  </div>
194</div>
195
196
197But we do want the finite element solution to be continuous so that we
198have a &ldquo;conforming finite element method&rdquo; where the
199discrete finite element space is a proper subset of the $H^1$ function
200space in which we seek the solution of the Laplace equation.
201To guarantee that the global solution is continuous at these nodes as well, we
202have to state some additional constraints on the values of the solution at
203these nodes. The trick is to realize that while the shape functions shown
204above are discontinuous (and consequently an <i>arbitrary</i> linear combination
205of them is also discontinuous), that linear combinations in which the shape
206functions are added up as $u_h(\mathbf x)=\sum_j U_j \varphi_j(\mathbf x)$
207can be continuous <i>if the coefficients $U_j$ satisfy certain relationships</i>.
208In other words, the coefficients $U_j$ can not be chosen arbitrarily
209but have to satisfy certain constraints so that the function $u_h$ is in fact
210continuous.
211What these constraints have to look is relatively easy to
212understand conceptually, but the implementation in software is
213complicated and takes several thousand lines of code. On the other
214hand, in user code, it is only about half a dozen lines you have to
215add when dealing with hanging nodes.
216
217In the program below, we will show how we can get these
218constraints from deal.II, and how to use them in the solution of the
219linear system of equations. Before going over the details of the program
220below, you may want to take a look at the @ref constraints documentation
221module that explains how these constraints can be computed and what classes in
222deal.II work on them.
223
224
225<h3> How to deal with hanging nodes in practice </h3>
226
227The practice of hanging node constraints is rather simpler than the
228theory we have outlined above. In reality, you will really only have to
229add about half a dozen lines of additional code to a program like step-4
230to make it work with adaptive meshes that have hanging nodes. The
231interesting part about this is that it is entirely independent of the
232equation you are solving: The algebraic nature of these constraints has nothing
233to do with the equation and only depends on the choice of finite element.
234As a consequence, the code to deal with these constraints is entirely
235contained in the deal.II library itself, and you do not need to worry
236about the details.
237
238The steps you need to make this work are essentially like this:
239- You have to create an AffineConstraints object, which (as the name
240  suggests) will store all constraints on the finite element space. In
241  the current context, these are the constraints due to our desire to
242  keep the solution space continuous even in the presence of hanging
243  nodes. (Below we will also briefly mention that we will also put
244  boundary values into this same object, but that is a separate matter.)
245- You have to fill this object using the function
246  DoFTools::make_hanging_node_constraints() to ensure continuity of
247  the elements of the finite element space.
248- You have to use this object when you copy the local contributions to
249  the matrix and right hand side into the global objects, by using
250  AffineConstraints::distribute_local_to_global(). Up until
251  now, we have done this ourselves, but now with constraints, this
252  is where the magic happens and we apply the constraints to the
253  linear system. What this function does is make sure that the
254  degrees of freedom located at hanging nodes are not, in fact,
255  really free. Rather, they are factually eliminated from the
256  linear system by setting their rows and columns to zero and putting
257  something on the diagonal to ensure the matrix remains invertible.
258  The matrix resulting from this process remains symmetric and
259  positive definite for the Laplace equation we solve here, so we can
260  continue to use the Conjugate Gradient method for it.
261- You then solve the linear system as usual, but at the end of this
262  step, you need to make sure that the degrees of "freedom" located
263  on hanging nodes get their correct (constrained) value so that the
264  solution you then visualize or evaluate in other ways is in
265  fact continuous. This is done by calling
266  AffineConstraints::distribute() immediately after solving.
267
268These four steps are really all that is necessary -- it's that simple
269from a user perspective. The fact that, in the function calls mentioned
270above, you will run through several thousand lines of not-so-trivial
271code is entirely immaterial to this: In user code, there are really
272only four additional steps.
273
274
275<h3> How we obtain locally refined meshes </h3>
276
277The next question, now that we know how to <i>deal</i> with meshes that
278have these hanging nodes is how we <i>obtain</i> them.
279
280A simple way has already been shown in step-1: If you <i>know</i> where
281it is necessary to refine the mesh, then you can create one by hand. But
282in reality, we don't know this: We don't know the solution of the PDE
283up front (because, if we did, we wouldn't have to use the finite element
284method), and consequently we do not know where it is necessary to
285add local mesh refinement to better resolve areas where the solution
286has strong variations. But the discussion above shows that maybe we
287can get away with using the discrete solution $u_h$ on one mesh to
288estimate the derivatives $\nabla^{p+1} u$, and then use this to determine
289which cells are too large and which already small enough. We can then
290generate a new mesh from the current one using local mesh refinement.
291If necessary, this step is then repeated until we are happy with our
292numerical solution -- or, more commonly, until we run out of computational
293resources or patience.
294
295So that's exactly what we will do.
296The locally refined grids are produced using an <i>error estimator</i>
297which estimates the energy error for numerical solutions of the Laplace
298operator. Since it was developed by Kelly and
299co-workers, we often refer to it as the &ldquo;Kelly refinement
300indicator&rdquo; in the library, documentation, and mailing list. The
301class that implements it is called
302KellyErrorEstimator, and there is a great deal of information to
303be found in the documentation of that class that need not be repeated
304here. The summary, however, is that the class computes a vector with
305as many entries as there are @ref GlossActive "active cells", and
306where each entry contains an estimate of the error on that cell.
307This estimate is then used to refine the cells of the mesh: those
308cells that have a large error will be marked for refinement, those
309that have a particularly small estimate will be marked for
310coarsening. We don't have to do this by hand: The functions in
311namespace GridRefinement will do all of this for us once we have
312obtained the vector of error estimates.
313
314It is worth noting that while the Kelly error estimator was developed
315for Laplace's equation, it has proven to be a suitable tool to generate
316locally refined meshes for a wide range of equations, not even restricted
317to elliptic only problems. Although it will create non-optimal meshes for other
318equations, it is often a good way to quickly produce meshes that are
319well adapted to the features of solutions, such as regions of great
320variation or discontinuities.
321
322
323
324<h3> Boundary conditions </h3>
325
326It turns out that one can see Dirichlet boundary conditions as just another
327constraint on the degrees of freedom. It's a particularly simple one,
328indeed: If $j$ is a degree of freedom on the boundary, with position
329$\mathbf x_j$, then imposing the boundary condition $u=g$ on $\partial\Omega$
330simply yields the constraint $U_j=g({\mathbf x}_j)$.
331
332The AffineConstraints class can handle such constraints as well, which makes it
333convenient to let the same object we use for hanging node constraints
334also deal with these Dirichlet boundary conditions.
335This way, we don't need to apply the boundary conditions after assembly
336(like we did in the earlier steps).
337All that is necessary is that we call the variant of
338VectorTools::interpolate_boundary_values() that returns its information
339in an AffineConstraints object, rather than the `std::map` we have used
340in previous tutorial programs.
341
342
343 <h3> Other things this program shows </h3>
344
345
346Since the concepts used for locally refined grids are so important,
347we do not show much other material in this example. The most
348important exception is that we show how to use biquadratic elements
349instead of the bilinear ones which we have used in all previous
350examples. In fact, the use of higher order elements is accomplished by
351only replacing three lines of the program, namely the initialization of
352the <code>fe</code> member variable in the constructor of the main
353class of this program, and the use of an appropriate quadrature formula
354in two places. The rest of the program is unchanged.
355
356The only other new thing is a method to catch exceptions in the
357<code>main</code> function in order to output some information in case the
358program crashes for some reason. This is discussed below in more detail.
359