Run this tutorial

Click here to run this tutorial on mybinder.org: try on mybinder.org
Please note that starting the notebook server may take a couple of minutes.

Example: Grid adaptation#

# wurlitzer: display dune's output in the notebook
%load_ext wurlitzer
%matplotlib notebook

import numpy as np
np.warnings.filterwarnings('ignore') # silence numpys warnings
from dune.xt.grid import Dim, Simplex, make_cube_grid, visualize_grid

grid = make_cube_grid(Dim(2), Simplex(), [-1, -1], [1, 1], [1, 1])
print('initial grid')
_ = visualize_grid(grid)
print(f'grid has {grid.size(0)} elements')

# we require one global refinement for simlexgrids to obtain a symmetric grid
grid.global_refine(1)

print('once refined to obtain a symmetric grid')
_ = visualize_grid(grid)

print(f'grid has {grid.size(0)} elements')
initial grid
GridParameterBlock: Parameter 'refinementedge' not specified, defaulting to 'ARBITRARY'.
grid has 2 elements
once refined to obtain a symmetric grid
grid has 4 elements
from dune.gdt import ContinuousLagrangeSpace, DiscreteFunction, AdaptationHelper

V_h = ContinuousLagrangeSpace(grid, order=1)
u_h = DiscreteFunction(V_h, name='u_h')

print(f'space has {V_h.num_DoFs} DoFs')
space has 5 DoFs
adaptation_helper = AdaptationHelper(grid)
adaptation_helper.append(V_h, u_h)
markers = np.array(adaptation_helper.markers, copy=False) # direct access to dune vector without copy
centers = np.array(grid.centers(0), copy=False)

elements_in_the_left_half = np.where(centers[:, 0] < 0)[0]
markers[elements_in_the_left_half] = 1
adaptation_helper.mark()

Lets have a look at the markers:

print(markers)
[0 0 1 0]
adaptation_helper.pre_adapt()
adaptation_helper.adapt()
adaptation_helper.post_adapt()
print(f'grid has {grid.size(0)} elements')

_ = visualize_grid(grid)

print(f'space has {V_h.num_DoFs} DoFs')
grid has 5 elements
space has 6 DoFs

Let us now have another look at the markers:

print(markers)
print(len(markers))
print(grid.size(0))
[140416815390832      4294967297  94154167554784  94154167554784]
4
5

Since the vector of markers has been resized along with the grid, the wrapped numpy array now contains garbage and/or is of wrong size.

So after each adapt, we need to wrap it anew!

markers = np.array(adaptation_helper.markers, copy=False)

print(markers)
[0 0 0 0 0]

keeping track of refined elements#

We can also tell the helper to keep track of those elements which have been refined. Therefore we mark the elements in the left half again. Note that we also need to wrap the centers again!

centers = np.array(grid.centers(0), copy=False)

elements_in_the_left_half = np.where(centers[:, 0] > 0)[0]
markers[elements_in_the_left_half] = 1
print(markers)
adaptation_helper.mark()
[1 0 0 0 0]

After marking we adapt the grid as before, but use the optional indicate_new_elements parameter.

adaptation_helper.pre_adapt()
adaptation_helper.adapt()
adaptation_helper.post_adapt(indicate_new_elements=True)
_ = visualize_grid(grid)

The grid was adapted as expected, but in addition …

markers = np.array(adaptation_helper.markers, copy=False)

print(markers)
[1 1 0 0 0 0]

adaptation_helper.markers has not been cleared after adaptation but rather indicates the indices of those elements that have been created newly during the last call to adapt(). In particular, we can use this to refine the same elements again:

adaptation_helper.mark()
adaptation_helper.pre_adapt()
adaptation_helper.adapt()
adaptation_helper.post_adapt(indicate_new_elements=True)
_ = visualize_grid(grid)

Download the code: example__simple_grid_adaptation.md example__simple_grid_adaptation.ipynb