grids-and-discretefunctions.md 6.91 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Grids and Discrete Functions

[TOC]

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.

```c++
#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:

```c++
#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`](../reference/DOFVector.md) 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](https://www.dune-project.org/modules/dune-functions/) and
in the publication [The interface for functions in the dune-functions module](https://journals.ub.uni-heidelberg.de/index.php/ans/article/view/27683).

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

```c++
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
115
#include <amdis/functions/GlobalBasis.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
116
117
118
119
120
121

// 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
122
GlobalBasis basis1{grid2->leafGridView(), power<3>(lagrange<2>())};
Praetorius, Simon's avatar
Praetorius, Simon committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
```

or by using some predefined wrappers:

```c++
#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.

142
    This `GlobalBasis` can be converted from a `DefaultGlobalBasis` of dune-functions.
Praetorius, Simon's avatar
Praetorius, Simon committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165


A [`DOFVector`](../reference/DOFVector.md) 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.

```c++
// 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>`.