SmoothMeshGenerator

Utilizes the specified smoothing algorithm to attempt to improve mesh quality.

The SmoothMeshGenerator supports two mesh-smoothing algorithms, which are described below.

Laplace Algorithm

The Laplace smoothing algorithm utilizes a classical Laplacian smoother that iteratively relocates interior nodes to the average of their neighbors. It supports 1D/2D/3D meshes and tries to preserve exterior boundaries by fixing boundary nodes in place. Subdomain boundaries are not preserved. This implementation currently requires a replicated mesh.

Variational Algorithm

The variational smoothing algorithm is a Newton-based variational optimizer that minimizes a mixed distortion–dilation energy. It supports 1D/2D/3D meshes, preserves exterior boundaries by constraining nodes, can optionally preserve subdomain (block) boundaries, and can untangle some tangled meshes before smoothing. Exterior/subdomain boundaries are preserved by only allowing node movement that leaves the domain unchanged. Internally it builds a libMesh system that assembles the gradient (residual) and analytic Hessian (jacobian) of the energy and solves to a stationary point.

Mathematical Formulation

The Variational Mesh Smoother minimizes a distortion–dilation energy functional, , originally proposed by Branets (2005):

where:

  • is the vector of nodal coordinates

  • is the spatially-dependent jacobian matrix of the target-to-physical element mapping in element

  • is the spatially-dependent distortion-dilation energy density

  • is the target element corresponding to physical element

  • is the target space coordinate

The relationship between the target and reference elements is discussed below in the Notes & Limitations section. Note that for each element, integration is over the target space, not the physical space. Minimization is achieved using a damped Newton method with analytically derived gradient and Hessian of .

For each mesh element, the local energy density is

where:

  • is the dilation weight (dilation_weight in input)

  • , penalizes volumetric dilation from the target element

  • , penalizes shape distortion from the target element

The distortion metric is

and the dilation metric is

Definitions:

SymbolMeaning
spatial dimension of the mesh (1, 2, or 3)
jacobian determinant of the target-to-physical element mapping
trace of the specified matrix
reference (i.e., desired) , or "volume" for each element
smooth barrier ensuring well-defined metrics for degenerate or folded elements (i.e., )
small nonzero regularization constant

Notes & Limitations

Target Elements

The target element defines the "ideal" shape for a given element type. For some element types, the target element is the same as the reference element used by libMesh. For other types, the target element differs from the reference element. This is reflected in the table below.

Element TypeReference ElementTarget Element
EDGElineline
TRIright triangleequilateral triangle
Polygonregular polygonregular polygon
QUADsquaresquare
PRISMright triangular baseequilateral triangular base, equal face areas
HEXcubecube
PYRAMIDsquare base, isosceles triangular sidessquare base, equilateral triangular sides
TETright tetregular tet
Polyhedronnot supportednot supported
}","\\inactivepart":"{\\left< I \\right>}","\\Gc":"{\\mathcal{G}_c}","\\strain":"\\bs{\\varepsilon}","\\stress":"\\bs{\\sigma}","\\macaulay":"\\left<#1\\right>","\\body":"\\Omega","\\bodyboundary":"{\\partial\\body}","\\ep":"{\\varepsilon^p}","\\ep0":"{\\varepsilon_0^p}","\\epdot":"{\\dot{\\varepsilon}}^p","\\epdot0":"{\\dot{\\varepsilon}}_0^p","\\bfa":"\\boldsymbol{a}","\\bfb":"\\boldsymbol{b}","\\bfc":"\\boldsymbol{c}","\\bfd":"\\boldsymbol{d}","\\bfe":"\\boldsymbol{e}","\\bff":"\\boldsymbol{f}","\\bfg":"\\boldsymbol{g}","\\bfh":"\\boldsymbol{h}","\\bfi":"\\boldsymbol{i}","\\bfj":"\\boldsymbol{j}","\\bfk":"\\boldsymbol{k}","\\bfl":"\\boldsymbol{l}","\\bfm":"\\boldsymbol{m}","\\bfn":"\\boldsymbol{n}","\\bfo":"\\boldsymbol{o}","\\bfp":"\\boldsymbol{p}","\\bfq":"\\boldsymbol{q}","\\bfr":"\\boldsymbol{r}","\\bfs":"\\boldsymbol{s}","\\bft":"\\boldsymbol{t}","\\bfu":"\\boldsymbol{u}","\\bfv":"\\boldsymbol{v}","\\bfw":"\\boldsymbol{w}","\\bfx":"\\boldsymbol{x}","\\bfy":"\\boldsymbol{y}","\\bfz":"\\boldsymbol{z}","\\bfA":"\\boldsymbol{A}","\\bfB":"\\boldsymbol{B}","\\bfC":"\\boldsymbol{C}","\\bfD":"\\boldsymbol{D}","\\bfE":"\\boldsymbol{E}","\\bfF":"\\boldsymbol{F}","\\bfG":"\\boldsymbol{G}","\\bfH":"\\boldsymbol{H}","\\bfI":"\\boldsymbol{I}","\\bfJ":"\\boldsymbol{J}","\\bfK":"\\boldsymbol{K}","\\bfL":"\\boldsymbol{L}","\\bfM":"\\boldsymbol{M}","\\bfN":"\\boldsymbol{N}","\\bfO":"\\boldsymbol{O}","\\bfP":"\\boldsymbol{P}","\\bfQ":"\\boldsymbol{Q}","\\bfR":"\\boldsymbol{R}","\\bfS":"\\boldsymbol{S}","\\bfT":"\\boldsymbol{T}","\\bfU":"\\boldsymbol{U}","\\bfV":"\\boldsymbol{V}","\\bfW":"\\boldsymbol{W}","\\bfX":"\\boldsymbol{X}","\\bfY":"\\boldsymbol{Y}","\\bfZ":"\\boldsymbol{Z}"}});">

Reference Volume ()

The term reference "volume" is a bit misleading. A more descriptive, albeit longer, term is "reference target-to-physical jacobian determinant". Basically, is the jacobian determinant that we want the smoother to push our mesh elements towards. The term "volume" is used here because the jacobian determinant is proportional to the volume of an element. When a given mesh element has the element is considered to be "dilated" from an element with

The reference volume is automatically calculated as the volumetric average of for each element, averaged over the number of elements in the mesh:

Element Order

The variational smoother rejects mixed-order meshes; all active elements must share the same default order. Higher-order element types are supported.

Untangling

The mesh is considered tangled if, at any quadrature point, . If the mesh is initially tangled, the variational smoother runs an untangling stage using only the distortion term (temporarily sets the dilation weight to 0), then a smoothing stage with the requested weights. Not all tangled meshes can be untangled. The barrier term behaves like for , is nonzero at , and asymptotes to 0 as approaches . The use of this term in place of in denominators allows the smoother to untangle meshes with degenerate/folded elements.

Once the mesh has been untangled, is set to zero to prevent re-tangling during the smoothing solve.

Optimal Solutions

It can be shown that, for the smoothing solve, when and , the distortion metric is minimized by any constant-scaled special orthogonal matrix such that

The implication of this is that the distortion metric is minimized by a mesh element that is a scaled rotation of the target element. This makes sense because the target element is our definition of the "ideal" smooth element shape.

For untangled meshes, the dilation metric simplifies to

It can be shown that the dilation metric is minimized by any such that .

Boundary/Subdomain Control

Geometric constraints are automatically detected and applied to boundary nodes; if preserve_subdomain_boundaries = true, nodes along interfaces of differing block IDs are likewise constrained so subdomain boundaries do not drift. Boundary/subdomain interface nodes are allowed to slide along boundaries/interfaces, so long as those surfaces are linear (e.g., a line in 2D meshes or a plane in 3D meshes). No action is necessary to enable sliding boundary nodes as they are automatically detected.

If the surfaces are not linear, the boundary/subdomain nodes are constrained (i.e., fixed) to their original location. It has been observed in some cases that fixing boundary nodes on nonlinear boundaries significantly restricts the space of optimally smooth solutions. As a result, the original mesh may not change significantly. This is because fixing boundary nodes reduces the space of possible smooth boundary elements. These restrictions then propagate into the mesh interior. In the future, it will be useful to allow boundary nodes to slide along nonlinear boundaries. This is not currently possible because libMesh does not yet support nonlinear constraints.

For further theoretical background, see: Branets (2005)

References

  1. Larisa Vladimirovna Branets. A Variational Grid Optimization Method Based on a Local Cell Quality Metric. Ph.D. dissertation, The University of Texas at Austin, Austin, Texas, August 2005. URL: https://repositories.lib.utexas.edu/items/a4ec528e-1f03-4534-84ab-338e31e89e55.[BibTeX]

Examples

Example 1 — Laplacian smoothing

The iterations parameter controls the number of smoothing steps to do. Each smoothing step will iterate the mesh toward the “true” smoothed mesh (as measured by the Laplacian smoother). After a few iterations the mesh typically reaches a steady state.

As an example, here is an original mesh going through 12 iterations of this smoother:

12 iterations of Laplacian smoothing.  Coloring is by element quality (higher is better).

Figure 1: 12 iterations of Laplacian smoothing. Coloring is by element quality (higher is better).

Example 2 — Variational smoothing (fixed boundary nodes)

Here is an example of the variational smoother applied to a mesh with 3 subdomains and nonlinear boundaries. Note that the locations of the (subdomain) boundary nodes do not change.

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  [fmg]
    type = FileMeshGenerator<<<{"description": "Read a mesh from a file.", "href": "FileMeshGenerator.html"}>>>
    file<<<{"description": "The filename to read."}>>> = concentric_circle_mesh_in.e
  []

  [smooth]
    type = SmoothMeshGenerator<<<{"description": "Utilizes the specified smoothing algorithm to attempt to improve mesh quality.", "href": "SmoothMeshGenerator.html"}>>>
    input<<<{"description": "The mesh we want to smooth."}>>> = fmg
    algorithm<<<{"description": "The smoothing algorithm to use."}>>> = variational
  []
[]
(moose/test/tests/meshgenerators/smooth_mesh_generator/variational_mesh_smoother_generator.i)
Variational smoother applied to mesh with nonlinear boundary. The original mesh is shown on the left and the smoothed mesh is shown on the right.

Figure 2: Variational smoother applied to mesh with nonlinear boundary. The original mesh is shown on the left and the smoothed mesh is shown on the right.

Example 3 — Variational smoothing (sliding boundary nodes)

Here is an example of the variational smoother applied to a mesh with 2 subdomains and linear boundaries. Note that while the locations of the (subdomain) boundary nodes change, these boundaries are still preserved.

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  [gmg]
    type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "GeneratedMeshGenerator.html"}>>>
    dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
    nx<<<{"description": "Number of elements in the X direction"}>>> = 10
    ny<<<{"description": "Number of elements in the Y direction"}>>> = 10
    bias_x<<<{"description": "The amount by which to grow (or shrink) the cells in the x-direction."}>>> = 1.4
    bias_y<<<{"description": "The amount by which to grow (or shrink) the cells in the y-direction."}>>> = 1.4
    elem_type<<<{"description": "The type of element from libMesh to generate (default: linear element for requested dimension)"}>>> = TRI3
  []

  [add_block]
    type = ParsedSubdomainMeshGenerator<<<{"description": "Uses a parsed expression (`combinatorial_geometry`) to determine if an element (via its centroid) is inside the region defined by the expression and assigns a new block ID.", "href": "ParsedSubdomainMeshGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = gmg
    combinatorial_geometry<<<{"description": "Function expression encoding a combinatorial geometry"}>>> = 'x > 0.35 & y > 0.35 & y < 0.7'
    block_id<<<{"description": "Subdomain id to set for inside of the combinatorial"}>>> = 1
  []

  [smooth]
    type = SmoothMeshGenerator<<<{"description": "Utilizes the specified smoothing algorithm to attempt to improve mesh quality.", "href": "SmoothMeshGenerator.html"}>>>
    input<<<{"description": "The mesh we want to smooth."}>>> = add_block
    algorithm<<<{"description": "The smoothing algorithm to use."}>>> = variational
  []
[]
(moose/test/tests/meshgenerators/smooth_mesh_generator/variational_mesh_smoother_generator_sliding_nodes.i)
Original mesh.

Figure 3: Original mesh.

Input Parameters

  • inputThe mesh we want to smooth.

    C++ Type:MeshGeneratorName

    Controllable:No

    Description:The mesh we want to smooth.

Required Parameters

  • absolute_residual_tolerance1e-12Variational algorithm only: solver absolute residual tolerance.

    Default:1e-12

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Variational algorithm only: solver absolute residual tolerance.

  • algorithmvariationalThe smoothing algorithm to use.

    Default:variational

    C++ Type:MooseEnum

    Options:variational, laplace

    Controllable:No

    Description:The smoothing algorithm to use.

  • dilation_weight0.5Variational algorithm only: the weight of the dilation metric. The distortion metric is given weight 1 - dilation_weight.

    Default:0.5

    C++ Type:double

    Unit:(no unit assumed)

    Range:dilation_weight >= 0.0 & dilation_weight <= 1.0

    Controllable:No

    Description:Variational algorithm only: the weight of the dilation metric. The distortion metric is given weight 1 - dilation_weight.

  • iterations1Laplace algorithm only: the number of smoothing iterations to do.

    Default:1

    C++ Type:unsigned int

    Controllable:No

    Description:Laplace algorithm only: the number of smoothing iterations to do.

  • preserve_subdomain_boundariesTrueVariational algorithm only: whether the input mesh's subdomain boundaries should be preserved during the smoothing process.

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Variational algorithm only: whether the input mesh's subdomain boundaries should be preserved during the smoothing process.

  • relative_residual_tolerance1e-12Variational algorithm only: solver relative residual tolerance.

    Default:1e-12

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Variational algorithm only: solver relative residual tolerance.

  • verbosity1Variational algorithm only: verbosity level between 0 and 100.

    Default:1

    C++ Type:unsigned int

    Range:0 <= verbosity <= 100

    Controllable:No

    Description:Variational algorithm only: verbosity level between 0 and 100.

Optional Parameters

  • enableTrueSet the enabled status of the MooseObject.

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Set the enabled status of the MooseObject.

  • save_with_nameKeep the mesh from this mesh generator in memory with the name specified

    C++ Type:std::string

    Controllable:No

    Description:Keep the mesh from this mesh generator in memory with the name specified

Advanced Parameters

  • nemesisFalseWhether or not to output the mesh file in the nemesisformat (only if output = true)

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to output the mesh file in the nemesisformat (only if output = true)

  • outputFalseWhether or not to output the mesh file after generating the mesh

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to output the mesh file after generating the mesh

  • show_infoFalseWhether or not to show mesh info after generating the mesh (bounding box, element types, sidesets, nodesets, subdomains, etc)

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to show mesh info after generating the mesh (bounding box, element types, sidesets, nodesets, subdomains, etc)

Debugging Parameters