# Gridap.Adaptivity

The adaptivity module provides a framework to work with adapted (refined/coarsened/mixed) meshes.

It provides

- A generic interface to represent adapted meshes and a set of tools to work with Finite Element spaces defined on them. In particular, moving
`CellFields`

between parent and child meshes. - Particular implementations for conformally refining/coarsening 2D/3D meshes using several well-known strategies. In particular, Red-Green refinement and longest-edge bisection.

## Interface

The following types are defined in the module:

`Gridap.Adaptivity.RefinementRule`

— TypeStructure representing the map between a single parent cell and its children.

Contains:

- T ::
`RefinementRuleType`

, indicating the refinement method. - poly ::
`Polytope`

, representing the geometry of the parent cell. - ref_grid ::
`DiscreteModel`

defined on`poly`

, giving the parent-to-children cell map.

`Gridap.Adaptivity.AdaptivityGlue`

— TypeGlue containing the map between two nested triangulations. The contained datastructures will depend on the type of glue. There are two types of `AdaptivityGlue`

:

`RefinementGlue`

:: All cells in the new mesh are children of cells in the old mesh. I.e given a new cell, it is possible to find a single old cell containing it (the new cell might be exactly the old cell if no refinement).`MixedGlue`

:: Some cells in the new mesh are children of cells in the old mesh, while others are parents of cells in the old mesh.

Contains:

`n2o_faces_map`

:: Given a new face gid, returns- if fine, the gid of the old face containing it.
- if coarse, the gids of its children (in child order)

`n2o_cell_to_child_id`

:: Given a new cell gid, returns- if fine, the local child id within the (old) coarse cell containing it.
- if coarse, a list of local child ids of the (old) cells containing it.

`refinement_rules`

:: Array conatining the`RefinementRule`

used for each coarse cell.

`Gridap.Adaptivity.AdaptedDiscreteModel`

— Type`DiscreteModel`

created by refining/coarsening another `DiscreteModel`

.

The refinement/coarsening hierarchy can be traced backwards by following the `parent`

pointer chain. This allows the transfer of dofs between `FESpaces`

defined on this model and its ancestors.

`Gridap.Adaptivity.AdaptedTriangulation`

— TypeTriangulation produced from an AdaptedDiscreteModel.

Contains:

- adapted_model ::
`AdaptedDiscreteModel`

for the triangulation. - trian ::
`Triangulation`

extracted from the background model, i.e`get_model(adapted_model)`

.

The high-level interface is provided by the following methods:

`Gridap.Adaptivity.refine`

— Functionfunction refine(model::DiscreteModel,args...;kwargs...) :: AdaptedDiscreteModel

Returns an `AdaptedDiscreteModel`

that is the result of refining the given `DiscreteModel`

.

`Gridap.Adaptivity.coarsen`

— Functionfunction coarsen(model::DiscreteModel,args...;kwargs...) :: AdaptedDiscreteModel

Returns an `AdaptedDiscreteModel`

that is the result of coarsening the given `DiscreteModel`

.

`Gridap.Adaptivity.adapt`

— Functionfunction adapt(model::DiscreteModel,args...;kwargs...) :: AdaptedDiscreteModel

Returns an `AdaptedDiscreteModel`

that is the result of adapting (mixed coarsening and refining) the given `DiscreteModel`

.

## Edge-Based refinement

The module provides a `refine`

method for `UnstructuredDiscreteModel`

. The method takes a string `refinement_method`

that determines the refinement strategy to be used. The following strategies are available:

`"red_green"`

:: Red-Green refinement, default.`"nvb"`

:: Longest-edge bisection (only for meshes of TRIangles)

Additionally, the method takes a kwarg `cells_to_refine`

that determines which cells will be refined. Possible input types are:

`Nothing`

:: All cells get refined.`AbstractArray{<:Bool}`

of size`num_cells(model)`

:: Only cells such that`cells_to_refine[iC] == true`

get refined.`AbstractArray{<:Integer}`

:: Cells for which`gid ∈ cells_to_refine`

get refined

The algorithms try to respect the `cells_to_refine`

input as much as possible, but some additional cells might get refined in order to guarantee that the mesh remains conforming.

```
function refine(model::UnstructuredDiscreteModel;refinement_method="red_green",kwargs...)
[...]
end
```

## CartesianDiscreteModel refining

The module provides a `refine`

method for `CartesianDiscreteModel`

. The method takes a `Tuple`

of size `Dc`

(the dimension of the model cells) that will determine how many times cells will be refined in each direction. For example, for a 2D model, `refine(model,(2,3))`

will refine each QUAD cell into a 2x3 grid of cells.

```
function refine(model::CartesianDiscreteModel{Dc}, cell_partition::Tuple) where Dc
[...]
end
```

## Notes for users

Most of the tools provided by this module are showcased in the tests of the module itself, as well as the following tutorial (coming soon).

However, we want to stress a couple of key performance-critical points:

The refining/coarsening routines are not optimized for performance. In particular, they are not parallelized. If you require an optimized/parallel implementation, please consider leveraging specialised meshing libraries. For instance, we provide an implementation of

`refine/coarsen`

using P4est in the GridapP4est.jl library.Although the toolbox allows you to evaluate

`CellFields`

defined on both fine/coarse meshes on their parent/children mesh, both directions of evaluation are not equivalent. As a user, you should always try to evaluate/integrate on the finest mesh for maximal performance. Evaluating a fine`CellField`

on a coarse mesh relies on local tree searches, and is therefore a very expensive operation that should be avoided whenever possible.

## Notes for developers

### RefinementRule API

Given a `RefinementRule`

, the library provides a set of methods to compute the mappings between parent (coarse) face ids and child (fine) face ids (and vice-versa). The ids are local to the `RefinementRule`

.

`Gridap.Adaptivity.get_d_to_face_to_child_faces`

— FunctionGiven a `RefinementRule`

, returns for each parent/coarse face the child/fine faces of the same dimension that it contains. Therefore, only fine faces at the coarse cell boundary are listed in the returned structure.

Returns: [Face dimension][Coarse Face id] -> [Fine faces]

`Gridap.Adaptivity.get_d_to_face_to_parent_face`

— FunctionGiven a `RefinementRule`

, returns for each fine/child face the parent/coarse face containing it. The parent face can have higher dimension.

Returns the tuple (A,B) with

- A = [Face dimension][Fine Face id] -> [Parent Face]
- B = [Face dimension][Fine Face id] -> [Parent Face Dimension]

`Gridap.Adaptivity.get_face_subface_ldof_to_cell_ldof`

— FunctionGiven a `RefinementRule`

of dimension Dc and a Dc-Tuple `fine_orders`

of approximation orders, returns a map between the fine nodal dofs of order `fine_orders`

in the reference grid and the coarse nodal dofs of order `2⋅fine_orders`

in the coarse parent cell.

The result is given for each coarse/parent face of dimension `D`

as a list of the corresponding fine dof lids, i.e

- [coarse face][coarse dof lid] -> fine dof lid

### AdaptivityGlue API

`Gridap.Adaptivity.get_n2o_reference_coordinate_map`

— FunctionFor each fine cell, returns the map Φ st. x*coarse = ϕ(x*fine)

`Gridap.Adaptivity.get_old_cell_refinement_rules`

— FunctionGiven a `RefinementGlue`

, returns an array containing the refinement rules for each cell in the old mesh.

`Gridap.Adaptivity.get_new_cell_refinement_rules`

— FunctionGiven a `RefinementGlue`

, returns an array containing the refinement rules for each cell in the new mesh.

`Gridap.Adaptivity.get_d_to_fface_to_cface`

— FunctionFor each child/fine face, returns the parent/coarse face containing it. The parent face might have higher dimension.

Returns two arrays:

- [dimension][fine face gid] -> coarse parent face gid
- [dimension][fine face gid] -> coarse parent face dimension

`Gridap.Adaptivity.n2o_reindex`

— Function`function n2o_reindex(new_data,g::AdaptivityGlue) -> old_data`

Reindexes a cell-wise array from the new mesh to the old mesh.

`Gridap.Adaptivity.o2n_reindex`

— Function`function o2n_reindex(old_data,g::AdaptivityGlue) -> new_data`

Reindexes a cell-wise array from the old mesh to the new mesh.

### New-to-old field evaluations

When a cell is refined, we need to be able to evaluate the fields defined on the children cells on the parent cell. To do so, we bundle the fields defined on the children cells into a new type of `Field`

called `FineToCoarseField`

. When evaluated on a `Point`

, a `FineToCoarseField`

will select the child cell that contains the `Point`

and evaluate the mapped point on the corresponding child field.

`Gridap.Adaptivity.FineToCoarseField`

— TypeGiven a domain and a non-overlapping refined cover, a `FineToCoarseField`

is a `Field`

defined in the domain and constructed by a set of fields defined on the subparts of the covering partition. The refined cover is represented by a `RefinementRule`

.

`Gridap.Adaptivity.FineToCoarseDofBasis`

— Type`Gridap.Adaptivity.FineToCoarseRefFE`

— TypeWrapper for a ReferenceFE which is specialised for efficiently evaluating FineToCoarseFields.