4.1.9. Spatial adaptivity
The previous example has a very steep source function and due to the boundary conditions, also steep gradients in the solution \(u\) can be expected near the corners due to the different types of imposed boundary conditions. Pyoomph offers a simple way to automatically refine the mesh where necessary by adding a SpatialErrorEstimator object to the equations. We could either modify the previous example directly or use inheritance to re-use the previous example and just add the SpatialErrorEstimator object to the equation system. The latter approach reads:
# Load the previous code
from poisson_2d import *
# Inherit from the previous problem
class AdaptivePoissonProblem2d(PoissonProblem2d):
def define_problem(self):
# define the previous problem
super(AdaptivePoissonProblem2d, self).define_problem()
# add a spatial error estimator for u (errors weighted by the coefficient 1.0)
additional_equations = SpatialErrorEstimator(u=1.0)
self.add_equations(additional_equations @ "domain")
if __name__=="__main__":
with AdaptivePoissonProblem2d() as problem:
# Maximum refinement level
problem.max_refinement_level = 5
# Refine elements with error larger than that
problem.max_permitted_error = 0.0005
# Unrefine elements with elements smaller than that
problem.min_permitted_error = 0.00005
# Solve with full refinement
problem.solve(spatial_adapt=problem.max_refinement_level)
problem.output()
By using the super call, the original non-adaptive problem is defined. Then, the SpatialErrorEstimator is applied on the field u with a weighting factor of 1.0. If you have multiple fields, you can weight the estimated errors of the individual fields differently. Finally, the solve() call has to be augmented with a spatial_adapt keyword to specify the number of spatial adaption steps. However, the problem will never refine to a level finer than max_refinement_level. To check whether any element has to be refined, the estimated error is compared to the max_permitted_error value. If this threshold is exceeded, the element is refined. When any element got refined, the solution has to be recalculated and the next adaption step starts. If neighboring previously refined elements have an error lower than min_permitted_error, they also might be recombined to a coarser element within these adaption routine.
The result is depicted in Fig. 4.7. Obviously, the adaption is done near the corners and in the center, where the source function is prominent.
Fig. 4.7 Automatic spatial adaptivity based or error estimation in the Poisson problem.
Tip
More details on how the error is estimated can be found e.g. in the oomph-lib documentation, e.g. here: https://oomph-lib.github.io/oomph-lib/doc/the_data_structure/html/classoomph_1_1Z2ErrorEstimator.html