<i>This program was contributed by Timo Heister. Parts of the results section
were contributed by Yuhan Zhou and Wolfgang Bangerth.</i>

<a name="Intro"></a>
<h1> Introduction </h1>
This tutorial is an extension to step-1 and demonstrates several ways to
obtain more involved meshes than the ones shown there.

Generating complex geometries is a challenging task, especially in three space
dimensions. We will discuss several ways to do this, but this list is not
exhaustive. Additionally, there is not one approach that fits all problems.

This example program shows some of ways to create and modify meshes for
computations and outputs them as <code>.eps</code> files in much the same way
as we do in step-1. No other computations or adaptive
refinements are done; the idea is that you can use the techniques used here as
building blocks in other, more involved simulators. Please note that the
example program does not show all the ways to generate meshes that are
discussed in this introduction.


<h3>General concerns about meshes</h3>

When you use adaptive mesh refinement, you definitely want the initial mesh to
be as coarse as possible. The reason is that you can make it as fine as you
want using adaptive refinement as long as you have memory and CPU time
available. However, this requires that you don't waste mesh cells in parts of
the domain where they don't pay off. As a consequence, you don't want to start
with a mesh that is too fine to start with, because that takes up a good part
of your cell budget already, and because you can't coarsen away cells that are
in the initial mesh.

That said, your mesh needs to capture the given geometry adequately.


<h3>How to create meshes</h3>

There are several ways to create an initial mesh. Meshes can be modified or
combined in many ways as discussed later on.

<h4>Using GridGenerator</h4>

The easiest way to generate meshes is to use the functions in namespace
GridGenerator, as already discussed in step-1.  There are many different
helper functions
available, including GridGenerator::hyper_cube(),
GridGenerator::hyper_shell(), GridGenerator::hyper_ball(),
GridGenerator::hyper_cube_with_cylindrical_hole(), ...


<h4>Constructing your own mesh programmatically</h4>

If there is no good fit in the GridGenerator namespace for what you want to
do, you can always create a
Triangulation in your program "by hand". For that, you need a list of vertices
with their coordinates and a list of cells referencing those vertices. You can
find an example in the function create_coarse_grid in step-14.
All the functions in GridGenerator are implemented in this fashion.

We are happy to accept more functions to be added to GridGenerator. So, if
you end up writing a function that might be useful for a larger audience,
please contribute it.


<h4>Importing from external programs</h4>

The class GridIn can read many different mesh formats from a file from
disk. How this is done is explained in step-5 and can be seen in the function
<code>grid_1</code> in this example, see the code below.

Meshes can be generated from different tools like <a
href="http://geuz.org/gmsh/" target="_top">gmsh</a>, <a
href="https://lagrit.lanl.gov/" target="_top">lagrit</a> and <a
href="http://cubit.sandia.gov/" target="_top">cubit</a>. See the
documentation of GridIn for more information. The problem is that deal.II
needs meshes that only consist of quads and hexas -- tetrahedral meshes won't
work (this means tools like tetgen can not be used directly).

We will describe a possible workflow using Gmsh. Gmsh is the smallest and
most quickly set up open source tool we are aware of. It can generate
unstructured 2d quad meshes, but in 3d it can only extrude 2d meshes to
get hexahedral meshes. 3D meshing of unstructured geometry into hexahedra is not
supported at the time of writing this tutorial (early 2013).

In gmsh, a mesh is described in a text based <code>.geo</code> file, that can
contain computations, loops, variables, etc. It is very flexible. The mesh is
generated from a surface representation, which is build from a list of line
loops, which is build from a list of lines, which are in turn built from
points. The <code>.geo</code> script can be written and edited by hand or it
can be generated automatically by creating objects graphically inside gmsh. In
many cases it is best to combine both approaches. The file can be easily
reloaded by pressing "reload" under the "Geometry" tab.

This tutorial contains an example <code>.geo</code> file, that describes a box
with two objects cut out in the interior. This is how
<code>untitled.geo</code> looks like in gmsh (displaying the boundary
indicators as well as the mesh discussed further down below):

<img src="http://www.dealii.org/images/steps/developer/step-49.gmsh_picture.png" alt="">

You might want to open the <code>untitled.geo</code> file in a text editor (it
is located in the same directory as the <code>step-49.cc</code> source file) to
see how it is structured. You can see how the boundary of the domain is
composed of a number of lines and how later on we combine several lines into
"physical lines" (or "physical surfaces") that list the logical lines'
numbers. "Physical" object are the ones that carry information about the
boundary indicator (see @ref GlossBoundaryIndicator "this glossary entry").

@note It is important that this file contain "physical lines" and "physical
surfaces". These give the boundary indicators and material ids for use
in deal.II. Without these physical entities, nothing will be imported into
deal.II.

deal.II's GridIn class can read the <code>.msh</code> format written by
gmsh and that contains a mesh created for the geometry described by the
<code>.geo</code> file. You generate the <code>.msh</code> from the
<code>.geo</code> by running the commands

@code
gmsh -2 untitled.geo
@endcode

on the command line, or by clicking "Mesh" and then "2D" inside Gmsh after
loading the file.  Now this is the mesh read from the <code>.msh</code> file
and saved again by deal.II as an image (see the <code>grid_1</code> function
of the current program):

<img src="http://www.dealii.org/images/steps/developer/step-49.grid-1.png" alt="">


<h3>Modifying a Mesh</h3>

After acquiring one (or several) meshes in the ways described above, there are
many ways to manipulate them before using them in a finite element
computation.


<h4>Transformations</h4>

The GridTools namespace contains a collection of small functions to transform
a given mesh in various ways. The usage of the functions GridTools::shift,
GridTools::rotate, GridTools::scale is fairly obvious, so we won't discuss
those functions here.

The function GridTools::transform allows you to transform the vertices of a
given mesh using a smooth function. An example of its use is also given in the
results section of step-38 but let us show a simpler example here:
In the function <code>grid_5()</code> of the current program, we perturb the y
coordinate of a mesh with a sine curve:

<TABLE WIDTH="60%" ALIGN="center">
  <tr>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-5a.png" alt=""> regular input mesh
    </td>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-5.png" alt=""> output mesh
    </td>
  </tr>
</TABLE>

Similarly, we can transform a regularly refined
unit square to a wall-adapted mesh in y direction using the formula
$(x,y) \mapsto (x,\tanh(2*y)/\tanh(2))$. This is done in <code>grid_6()</code>
of this tutorial:
<TABLE WIDTH="60%" ALIGN="center">
  <tr>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-6a.png" alt=""> regular input mesh
    </td>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-6.png" alt=""> wall-adapted output mesh
    </td>
  </tr>
</TABLE>

Finally, the function GridTools::distort_random allows you to move vertices in the
mesh (optionally ignoring boundary nodes) by a random amount. This is
demonstrated in <code>grid_7()</code> and the result is as follows:

<TABLE WIDTH="60%" ALIGN="center">
  <tr>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-7a.png" alt=""> regular input mesh
    </td>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-7.png" alt=""> perturbed output mesh
    </td>
  </tr>
</TABLE>

This function is primarily intended to negate some of the superconvergence
effects one gets when studying convergence on regular meshes, as well as to
suppress some optimizations in deal.II that can exploit the fact that cells
are similar in shape. In practice, it is of course always better to
work with a sequence of unstructured meshes (see possible extensions at the
end of the this section).


<h4>Merging Meshes</h4>

The function GridGenerator::merge_triangulations() allows you to merge two
given Triangulation objects into a single one.  For this to work, the vertices
of the shared edge or face have to match exactly.  Lining up the two meshes
can be achieved using GridTools::shift and GridTools::scale.  In the function
<code>grid_2()</code> of this tutorial, we merge a square with a round hole
(generated with GridGenerator::hyper_cube_with_cylindrical_hole()) and a
rectangle (generated with GridGenerator::subdivided_hyper_rectangle()). The
function GridGenerator::subdivided_hyper_rectangle() allows you to specify the
number of repetitions and the positions of the corners, so there is no need to
shift the triangulation manually here. You should inspect the mesh graphically
to make sure that cells line up correctly and no unpaired nodes exist in the
merged Triangulation.

These are the input meshes and the output mesh:

<table width="80%" align="center">
  <tr>
    <td ALIGN="center"><img src="http://www.dealii.org/images/steps/developer/step-49.grid-2a.png" alt="" height="200px">input mesh 1</td>
    <td ALIGN="center"><img src="http://www.dealii.org/images/steps/developer/step-49.grid-2b.png" alt="" height="200px">input mesh 2</td>
    <td ALIGN="center"><img src="http://www.dealii.org/images/steps/developer/step-49.grid-2.png" alt="" height="200px">merged mesh</td>
  </tr>
</table>


<h4>Moving Vertices</h4>

The function <code>grid_3()</code> demonstrates the ability to pick individual vertices and
move them around in an existing mesh. Note that this has the potential to produce degenerate
or inverted cells and you shouldn't expect anything useful to come of using
such meshes. Here, we create a box with a cylindrical hole that is not exactly
centered by moving the top vertices upwards:

<TABLE WIDTH="60%" ALIGN="center">
  <tr>
    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-3a.png" alt="" height="200px"> input mesh
    </td>

    <td ALIGN="center">
        <img src="http://www.dealii.org/images/steps/developer/step-49.grid-3.png" alt="" height="200px"> top vertices moved upwards
    </td>
  </tr>
</table>

For the exact way how this is done, see the code below.


<h4>Extruding Meshes</h4>

If you need a 3d mesh that can be created by extruding a given 2d mesh (that
can be created in any of the ways given above), you can use the function
GridGenerator::extrude_triangulation(). See the <code>grid_4()</code> function
in this tutorial for an example. Note that for this particular case, the given
result could also be achieved using the 3d version of
GridGenerator::hyper_cube_with_cylindrical_hole(). The main usage is a 2d
mesh, generated for example with gmsh, that is read in from a
<code>.msh</code> file as described above. This is the output from grid_4():

<TABLE WIDTH="60%" ALIGN="center">
  <tr>
    <td ALIGN="center">
      <img src="http://www.dealii.org/images/steps/developer/step-49.grid-4base.png" alt=""> input mesh
    </td>

    <td ALIGN="center">
      <img src="http://www.dealii.org/images/steps/developer/step-49.grid-4.png" alt=""> extruded output mesh
    </td>
  </tr>
</table>


<h3> After you have a coarse mesh </h3>

Creating a coarse mesh using the methods discussed above is only the first
step. When you have it, it will typically serve as the basis for further mesh
refinement. This is not difficult &mdash; in fact, there is nothing else to do
&mdash; if your geometry consists of only straight faces. However, this is
often not the case if you have a more complex geometry and more steps than
just creating the mesh are necessary. We will go over some of these steps in
the <a href="#Results">results section</a> below.


<!--

Possible Extensions

- Modify a mesh:
  - change boundary indicators
  - relax inner vertices
- Database of unstructured meshes for convergence studies
- discuss GridTools::extract_boundary_mesh
- how to remove or disable a cell inside a mesh
-->
