# Grids and Discrete Functions

A grid is a partitioning of a domain $\Omega\subset\mathbf{R}^d$ into simple geometric elements, like triangles or quads in 2d and tetrahedra, cubes, pyramids, or prisms in 3d. The grid data structure manages the various entities (vertices, edges, faces, and cells) that are part of the grid and its connectivity.

Several grid implementations are available for different puroses. Some are optimized for very structured domain discretizations, some are build for unstructured grids. Some grid managers are shipped with the Dune core modules, others need to be installed separately, as an extra Dune module or external library.

All grid implementations have a common interface defined in `dune-grid`

. But each
module may have some extended features not shared with other grid managers.

Some standard grid modules are

`OneDGrid`

: an*unstructured*one-dimensional grid`YaspGrid`

: a structured 2/3 dimensional cube grid`UGGrid`

: an unstructured 2/3 dimensional grid with mixed element types (requires the`dune-uggrid`

module)`AlbertaGrid`

: wrapper for the 1/2/3 dimensional simplex grid of the external Alberta FEM library. Allows for surface grids, i.e.`dim != dow`

.

## Grid Construction

There are several ways to create a grid. Each grid provides some construtors
for individual creation. A common approach is to use a `GridFactory`

that
allows to insert vertices and element connectivity directly. For rectangular
domains a `StructuredGridFactory`

can be used that discretizes a box-partitioning
of the domain into cubes or simplices. And there are some file readers that allow
to read a grid description from a common file format, like `GMsh`

, `AmiraMesh`

, or
`AlbertaGrid`

files.

```
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/uggrid.hh>
// direct creation of [0.0, 1.0]^2 with 4 elements in each coordinate direction
Dune::YaspGrid<2> grid1({1.0, 1.0}, {4,4});
// using a StructuredGridFactory
using Factory = Dune::StructuredGridFactory<Dune::YaspGrid<2>>;
std::array<unsigned int, 2> numCells{4,4};
std::unique_ptr<Dune::YaspGrid<2>> grid2( Factory::createCubeGrid({0.0, 0.0}, {1.0, 1.0}, numCells) );
// using a file reader
using Reader = Dune::GmshReader<Dune::UGGrid<2>>;
std::unique_ptr<Dune::UGGrid<2>> grid3( Reader::read("gridfile.msh") );
```

AMDiS provides a way to construct a grid by inspecting some initfile parameters.
Therefore, we have implemented the `MeshCreator`

. It expects in the constructor the
base name of a parameter that defines how to construct the grid given as template
type:

```
#include <dune/grid/albertagrid.hh>
using Grid = Dune::AlbertaGrid<2>;
std::unique_ptr<Grid> grid4( MeshCreator<Grid>("mesh").create() );
```

where `"mesh"`

defines a key that can be used in the parameter file to describe the grid:

```
% structured rectangular grid
mesh->structured: [cube|simplex]
mesh->min corner: 0.0 0.0
mesh->max corner: 1.0 1.0
mesh->num cells: 4 4
% read grid from file
mesh->macro file name: gridfile.msh
```

At first, the `MeshCreator`

looks for the parameter `macro file name`

, if found,
it tries to determine from the file extension which file format to read. `GMsh`

files use the extension `.msh`

, `AlbertaGrid`

files one of `.2d`

, `.3d`

, or `.amc`

and
the Dune DGF files have the extension `.dgf`

.

If no filename is given, it looks for the `structured`

parameter to determine
which elements (cubes or simplices) to use for the construction of a structured
rectangular grid described by the bounding box `min corner`

- `max corner`

and
the number of subdivisions in each coordinate direction `num cells`

.

If no `structured`

parameter is given, the MeshCreator tries to create the grid
directly. This may allow to pass more grid specific parameters, e.g. the `YaspGrid`

allows to specify in addition to `min corner`

, `max corner`

, and `num cells`

:

`overlap`

: the number of overlapping elements in a partitioned grid`periodic`

: a bitfield characterizing the periodicity of the grid

## Global Basis and Function Spaces

A discrete function is described by a set of (global) basis functions and a coefficient
vector. This pair is called a `DOFVector`

in AMDiS. The global basis is thereby
a class implementing the interface of the `GlobalBasis`

in the dune-functions module.

The simplest global bases are build of a composition of local basis functions associated to grid elements. The connectivity of these basis functions, i.e. a global numbering of all the local functions, defines the set of global basis functions restricted to each grid element. Details about this interface and mathematical background can be found on dune-project and in the publication The interface for functions in the dune-functions module.

Construction of a global basis can be done using directly the factory functions of dune-functions:

```
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <amdis/functions/GlobalBasis.hpp>
// the factory functions are defined in this namespace
using namespace Dune::Functions::BasisFactory;
// create a power basis of 3 lagrange bases with local polynomial degree 2
// on the leaf elements of the grid
GlobalBasis basis1{grid2->leafGridView(), power<3>(lagrange<2>())};
```

or by using some predefined wrappers:

```
#include <amdis/ProblemStatTraits.hpp>
// use the wrapper provided in AMDiS to create a power basis of 3 lagrange bases
// of local polynomial degree 2
using BasisCreator = LagrangeBasis<Dune::YaspGrid<2>, 2,2,2>;
auto basis2 = BasisCreator::create(grid2->leafGridView());
```

Note

Different to dune-functions, we have introduced a (Parallel) GlobalBasis that has a direct connection to the underlying Grid and can thus react on grid changes by grid refinement or by repartitioning. Additionally, it stores a communication object to construct global DOFMappings for distributed data structured.

This `GlobalBasis`

can be converted from a `DefaultGlobalBasis`

of dune-functions.

A `DOFVector`

takes a global basis and provides the coefficient vector as data member.
This defines a discrete function that can be evaluated in local and global coordinates
and can be used as `GridFunction`

in the operators, see below.

```
// use a generator function
auto vec1 = makeDOFVector(basis1);
// provide the type of the basis directly
DOFVector<typename BasisCreator::GlobalBasis> vec2(basis2);
// with c++17 class template argument deduction
DOFVector vec3(basis2);
```

Note

DOFVectors allow to specify the underlying data type, e.g. to use quad-precision coefficients or (maybe in the future) to use complex-valued data.

This coefficient type can be specified as additional template parameter to `makeDOFVector<double>(...)`

or in the class templates `DOFVector<GB, double>`

.