# Dune-CurvedGrid - A Dune module for geometry parametrization
This Dune module provides a meta-grid for wrapping other grid implementations and providing
a curved geometry on each element, parametrized by a [Dune-CurvedGeometry](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgeometry)
class.
For an overview about the CurvedGrid and the CurvedGeometry, see also the presentation
[Dune-CurvedGrid - A Dune module for surface parametrization](http://wwwpub.zih.tu-dresden.de/~praetori/presentations/dune-curvedgrid).
## Installation Instructions
`dune-curvedgrid` requires the DUNE core modules, version 2.7 or later.
Please see the [general instructions for building DUNE modules](https://www.dune-project.org/doc/installation)
for detailed instructions on how to build the module.
## Initial Example
(See [example1.cc](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgrid/-/blob/master/src/example1.cc))
```c++
// 1. Construct a reference grid
auto refGrid = GmshReader< FoamGrid<2,3> >::read("sphere.msh");
// 2. Define the geometry mapping
auto sphere = [](const auto& x) { return x / x.two_norm(); };
auto sphereGF = analyticDiscreteFunction(sphere, *refGrid, order);
// 3. Wrap the reference grid to build a curved grid
CurvedGrid grid{*refGrid, sphereGF};
```
At first, we have to create a reference grid that acts as a parametrization domain for the
target curved grid. In the example, we use [Dune-FoamGrid](https://gitlab.dune-project.org/extensions/dune-foamgrid)
and read a piece-wise flat grid from a GMsh file [`sphere.msh`](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgrid/-/blob/master/doc/grids/sphere.msh).
In a second step, we describe the parametrization of the curved surface by a closest-point
projection to the sphere with radius 1. This projection is given by a callable `sphere` and
the wrapped into a grid-function by a call to `analyticDiscreteFunction`. This grid-function
wrapper associated the lambda-expression with a grid and a polynomial order for the local
interpolation of the projection into a Lagrange basis. This interpolation allows to obtain
values and derivatives of the geometry mapping.
Finally, the reference grid and the parametrization together build the curved grid. This
meta-grid `CurvedGrid` implements the Dune grid interface and can thus be used as
replacement for, e.g., the reference grid.
## Two Different Geometry Mappings
The [Dune-CurvedGeometry](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgeometry) module
provides two different geometry implementations that differ in the input and in the
representation of the parametrization.
### Parametrized-Geometry
The first one, `ParametrizedGeometry`, provides a geometry that locally interpolates a given
projection function into a (Lagrange) basis on the reference element. This requires from the
projection mapping just that it allows to map local coordinates in the reference element to
global coordinates on the surface.
The `CurvedGrid` constructs on request of the element geometry a LocalFiniteElement
of Lagrange basis functions for the internal parametrization of the geometry. The `ParametrizedGeometry`
is constructed, if the grid gets a polynomial order `k > 0`.
(See [example2.cc](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgrid/-/blob/master/src/example2.cc))
```c++
// Construct a reference grid
auto refGrid = GmshReader< FoamGrid<2,3> >::read("sphere.msh");
// Define the geometry mapping
auto sphere = [](const auto& x) { return x / x.two_norm(); };
template
using Order_t = std::integral_constant;
// Wrap the reference grid to build a curved grid
CurvedGrid grid{*refGrid, sphere, Order_t{}};
```
### LocalFunction-Geometry
In case the projection is given as a differentiable mapping `f`, i.e., there exists a
function `derivative(f)` returning a callable that gives the Jacobian of the mapping, the
grid constructs a `LocalFunctionGeometry` on each element. This geometry is exactly parametrized
with the mapping and its derivative, i.e., no additional interpolation is performed.
(See [example3.cc](https://gitlab.mn.tu-dresden.de/iwr/dune-curvedgrid/-/blob/master/src/example3.cc))
```c++
auto gv = refGrid->leafGridView();
// Define a discrete grid-function on the reference grid
// with dim(range) = 3 and polynomial order k
auto f = discreteGridViewFunction<3>(gv, k);
// Interpolate the parametrization into the grid-function
Functions::interpolate(f.basis(), f.coefficients(), sphere);
// Wrap the reference grid and the grid-function
CurvedGrid grid{*refGrid, f};
```