Example 05 : Automatic Mesh Adaptivity
MOOSE has support for mesh adaptivity that can automatically refine and coarsen the mesh in areas of higher/lower error when solving problems. This can improve the quality of your results in addition to reducing computation time. You don't need to write any C++ code to use mesh adaptivity. Instead, it can easily be enabled by filling out the Adaptivity
section in an input file:
[Adaptivity<<<{"href": "../../../syntax/Adaptivity/index.html"}>>>]
marker<<<{"description": "The name of the Marker to use to actually adapt the mesh."}>>> = errorfrac # this specifies which marker from 'Markers' subsection to use
steps<<<{"description": "The number of adaptive steps to use when doing a Steady simulation."}>>> = 2 # run adaptivity 2 times, recomputing solution, indicators, and markers each time
# Use an indicator to compute an error-estimate for each element:
[./Indicators<<<{"href": "../../../syntax/Adaptivity/Indicators/index.html"}>>>]
# create an indicator computing an error metric for the convected variable
[./error]
# arbitrary, use-chosen name
type = GradientJumpIndicator<<<{"description": "Compute the jump of the solution gradient across element boundaries.", "href": "../../../source/indicators/GradientJumpIndicator.html"}>>>
variable<<<{"description": "The name of the variable that this side indicator applies to"}>>> = convected
outputs<<<{"description": "Vector of output names where you would like to restrict the output of variables(s) associated with this object"}>>> = none
[../]
[../]
# Create a marker that determines which elements to refine/coarsen based on error estimates
# from an indicator:
[./Markers<<<{"href": "../../../syntax/Adaptivity/Markers/index.html"}>>>]
[./errorfrac]
# arbitrary, use-chosen name (must match 'marker=...' name above
type = ErrorFractionMarker<<<{"description": "Marks elements for refinement or coarsening based on the fraction of the min/max error from the supplied indicator.", "href": "../../../source/markers/ErrorFractionMarker.html"}>>>
indicator<<<{"description": "The name of the Indicator that this Marker uses."}>>> = error # use the 'error' indicator specified above
refine<<<{"description": "Elements within this percentage of the max error will be refined. Must be between 0 and 1!"}>>> = 0.5 # split/refine elements in the upper half of the indicator error range
coarsen<<<{"description": "Elements within this percentage of the min error will be coarsened. Must be between 0 and 1!"}>>> = 0 # don't do any coarsening
outputs<<<{"description": "Vector of output names where you would like to restrict the output of variables(s) associated with this object"}>>> = none
[../]
[../]
[]
(examples/ex05_amr/ex05.i)More details about this functionality are provided on the Adaptivity page. MOOSE includes multiple Indicators you can use to compute different error estimates in addition to a few Markers.
(examples/ex05_amr/ex05.i)
[Mesh]
file = cube-hole.e
[]
# This is where mesh adaptivity magic happens:
[Adaptivity]
marker = errorfrac # this specifies which marker from 'Markers' subsection to use
steps = 2 # run adaptivity 2 times, recomputing solution, indicators, and markers each time
# Use an indicator to compute an error-estimate for each element:
[./Indicators]
# create an indicator computing an error metric for the convected variable
[./error] # arbitrary, use-chosen name
type = GradientJumpIndicator
variable = convected
outputs = none
[../]
[../]
# Create a marker that determines which elements to refine/coarsen based on error estimates
# from an indicator:
[./Markers]
[./errorfrac] # arbitrary, use-chosen name (must match 'marker=...' name above
type = ErrorFractionMarker
indicator = error # use the 'error' indicator specified above
refine = 0.5 # split/refine elements in the upper half of the indicator error range
coarsen = 0 # don't do any coarsening
outputs = none
[../]
[../]
[]
[Variables]
[./convected]
order = FIRST
family = LAGRANGE
[../]
[./diffused]
order = FIRST
family = LAGRANGE
[../]
[]
[Kernels]
[./example_diff]
type = ExampleCoefDiffusion
variable = convected
coef = 0.125
[../]
[./conv]
type = ExampleConvection
variable = convected
some_variable = diffused
[../]
[./diff]
type = Diffusion
variable = diffused
[../]
[]
[BCs]
# convected=0 on all vertical sides except the right (x-max)
[./cylinder_convected]
type = DirichletBC
variable = convected
boundary = inside
value = 1
[../]
[./exterior_convected]
type = DirichletBC
variable = convected
boundary = 'left top bottom'
value = 0
[../]
[./left_diffused]
type = DirichletBC
variable = diffused
boundary = left
value = 0
[../]
[./right_diffused]
type = DirichletBC
variable = diffused
boundary = right
value = 10
[../]
[]
[Executioner]
type = Steady
solve_type = 'PJFNK'
l_tol = 1e-3
nl_rel_tol = 1e-12
[]
[Outputs]
execute_on = 'timestep_end'
exodus = true
[]
(examples/ex05_amr/ex05.i)
[Mesh]
file = cube-hole.e
[]
# This is where mesh adaptivity magic happens:
[Adaptivity]
marker = errorfrac # this specifies which marker from 'Markers' subsection to use
steps = 2 # run adaptivity 2 times, recomputing solution, indicators, and markers each time
# Use an indicator to compute an error-estimate for each element:
[./Indicators]
# create an indicator computing an error metric for the convected variable
[./error] # arbitrary, use-chosen name
type = GradientJumpIndicator
variable = convected
outputs = none
[../]
[../]
# Create a marker that determines which elements to refine/coarsen based on error estimates
# from an indicator:
[./Markers]
[./errorfrac] # arbitrary, use-chosen name (must match 'marker=...' name above
type = ErrorFractionMarker
indicator = error # use the 'error' indicator specified above
refine = 0.5 # split/refine elements in the upper half of the indicator error range
coarsen = 0 # don't do any coarsening
outputs = none
[../]
[../]
[]
[Variables]
[./convected]
order = FIRST
family = LAGRANGE
[../]
[./diffused]
order = FIRST
family = LAGRANGE
[../]
[]
[Kernels]
[./example_diff]
type = ExampleCoefDiffusion
variable = convected
coef = 0.125
[../]
[./conv]
type = ExampleConvection
variable = convected
some_variable = diffused
[../]
[./diff]
type = Diffusion
variable = diffused
[../]
[]
[BCs]
# convected=0 on all vertical sides except the right (x-max)
[./cylinder_convected]
type = DirichletBC
variable = convected
boundary = inside
value = 1
[../]
[./exterior_convected]
type = DirichletBC
variable = convected
boundary = 'left top bottom'
value = 0
[../]
[./left_diffused]
type = DirichletBC
variable = diffused
boundary = left
value = 0
[../]
[./right_diffused]
type = DirichletBC
variable = diffused
boundary = right
value = 10
[../]
[]
[Executioner]
type = Steady
solve_type = 'PJFNK'
l_tol = 1e-3
nl_rel_tol = 1e-12
[]
[Outputs]
execute_on = 'timestep_end'
exodus = true
[]
(examples/ex05_amr/include/kernels/ExampleCoefDiffusion.h)
// This file is part of the MOOSE framework
// https://mooseframework.inl.gov
//
// All rights reserved, see COPYRIGHT for full restrictions
// https://github.com/idaholab/moose/blob/master/COPYRIGHT
//
// Licensed under LGPL 2.1, please see LICENSE for details
// https://www.gnu.org/licenses/lgpl-2.1.html
#pragma once
#include "Kernel.h"
class ExampleCoefDiffusion : public Kernel
{
public:
ExampleCoefDiffusion(const InputParameters & parameters);
static InputParameters validParams();
protected:
virtual Real computeQpResidual() override;
virtual Real computeQpJacobian() override;
private:
Real _coef;
};
(examples/ex05_amr/src/kernels/ExampleCoefDiffusion.C)
// This file is part of the MOOSE framework
// https://mooseframework.inl.gov
//
// All rights reserved, see COPYRIGHT for full restrictions
// https://github.com/idaholab/moose/blob/master/COPYRIGHT
//
// Licensed under LGPL 2.1, please see LICENSE for details
// https://www.gnu.org/licenses/lgpl-2.1.html
#include "ExampleCoefDiffusion.h"
registerMooseObject("ExampleApp", ExampleCoefDiffusion);
InputParameters
ExampleCoefDiffusion::validParams()
{
InputParameters params = Kernel::validParams();
params.set<Real>("coef") = 0.0;
return params;
}
ExampleCoefDiffusion::ExampleCoefDiffusion(const InputParameters & parameters)
: Kernel(parameters), _coef(getParam<Real>("coef"))
{
}
Real
ExampleCoefDiffusion::computeQpResidual()
{
return _coef * _grad_test[_i][_qp] * _grad_u[_qp];
}
Real
ExampleCoefDiffusion::computeQpJacobian()
{
return _coef * _grad_test[_i][_qp] * _grad_phi[_j][_qp];
}