ElementSubdomainModifier
Overview
The ElementSubdomainModifier
modifies an element subdomain ID. This class is inherited by other mesh modifiers, such as CoupledVarThresholdElementSubdomainModifier and TimedSubdomainModifier, which implement different criteria for a subdomain ID to be modified.
The ElementSubdomainModifier
can model
Element death (with applications in ablation, fracture, etc.);
Element activation (with applications in additive manufacturing, sintering, solidification, etc.);
Moving interface (with applications in metal oxidation, phase transformation, melt pool, etc.).
The ElementSubdomainModifier
only changes the element's subdomain. It inherits from ElementSubdomainModifierBase
, which handles the corresponding
Moving boundary/interface nodeset/sideset modification,
Solution reinitialization, and
Stateful material property reinitialization,
all of which are demonstrated below.
Consider a unit square domain decomposed by a vertical line . The elements on the left side of the vertical line have subdomain ID of 1, and the elements on the right side have subdomain ID of 2. The ElementSubdomainModifier
is used to change the subdomain ID from 2 to 1 for elements within a circle of radius 0.5 whose center moves along the bottom side towards the right.
Moving boundary/interface nodeset/sideset modification
If the moving boundary is defined completely around a subdomain, or between subdomains, then SidesetAroundSubdomainUpdater may be more useful to use in conjunction with the ElementSubdomainModifier
, rather than using the moving_boundaries
and moving_boundary_subdomain_pairs
parameters in ElementSubdomainModifier
.
The change of element subdomains will alter the definitions of certain sidesets and nodesets. The parameters moving_boundaries
and moving_boundary_subdomain_pairs
can optionally be used to modify the corresponding sidesets/nodesets over the elements that change subdomain. The names of the boundaries are specified in moving_boundaries
, and the pair of subdomains that each boundary in moving_boundaries
lies between must be specified in the corresponding moving_boundary_subdomain_pairs
. The element side from the first subdomain of the pair is added to the boundary.
If the boundaries provided through moving_boundaries
already exist, the modifier will attempt to modify the provided sidesets/nodesets whenever an element changes subdomain ID. If the boundaries do not exist, the modifier will create sidesets and nodesets with the provided names.
[moving_circle]
type = CoupledVarThresholdElementSubdomainModifier
coupled_var = 'phi'
criterion_type = 'BELOW'
threshold = 0
subdomain_id = 1
moving_boundaries = 'moving_boundary'
moving_boundary_subdomain_pairs = '1 2'
execute_on = 'INITIAL TIMESTEP_BEGIN'
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/moving_boundary.i)
The evolving nodeset (green) between subdomains 1 and 2, as created by the modifier without an existing boundary.
The modifier only creates and modifies boundaries over elements that change subdomain, so the vertical boundary between subdomains 1 and 2 at is not added to the created boundary.
If only one boundary is provided but multiple pairs of subdomains are specified, then all the pairs are applied to the one boundary. Element sides on a subdomain's external boundary can also be added by specifying only one subdomain.
[ext]
type = SideSetsAroundSubdomainGenerator
input = 'right'
block = 1
new_boundary = 'moving_boundary'
[]
[]
[MeshModifiers]
[moving_circle]
type = CoupledVarThresholdElementSubdomainModifier
coupled_var = 'phi'
criterion_type = 'BELOW'
threshold = 0
subdomain_id = 1
moving_boundaries = 'moving_boundary'
moving_boundary_subdomain_pairs = '1 2; 1'
execute_on = 'INITIAL TIMESTEP_BEGIN'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/external_moving_boundary.i)
The evolving sideset (green) around subdomain 1, including the external element sides, from an existing boundary.
Since the update of the moving boundary only occurs over elements that change subdomain, this can be used to update boundaries which do not cover the entirety of a subdomain:
[moving_circle]
type = CoupledVarThresholdElementSubdomainModifier
coupled_var = 'phi'
criterion_type = 'BELOW'
threshold = 0
subdomain_id = 1
moving_boundaries = 'right'
moving_boundary_subdomain_pairs = '1 2'
execute_on = 'INITIAL TIMESTEP_BEGIN'
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/partial_moving_boundary.i)
The evolving sideset (green) around subdomain 1, including the external element sides, from an existing boundary.
Even though the moving_boundary_subdomain_pairs
defines the moving boundary to be between subdomains 1 and 2 only, the right side of subdomain 2 remains throughout, as no element sides belong to elements that change subdomain.
Nodal and integrated BCs can be applied on the moving boundary.
Solution reinitialization
By default, all elements that change subdomain ID are reinitialized to the new subdomain's initial condition. Suppose the auxiliary variable has an initial variable value of in subdomain 1 and in subdomain 2, and the variable value doubles at each timestep in subdomain 1:
[ICs<<<{"href": "../../syntax/ICs/index.html"}>>>]
[u_1]
type = ConstantIC<<<{"description": "Sets a constant field value.", "href": "../ics/ConstantIC.html"}>>>
variable<<<{"description": "The variable this initial condition is supposed to provide values for."}>>> = 'u'
value<<<{"description": "The value to be set in IC"}>>> = 1
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 1
[]
[u_2]
type = ConstantIC<<<{"description": "Sets a constant field value.", "href": "../ics/ConstantIC.html"}>>>
variable<<<{"description": "The variable this initial condition is supposed to provide values for."}>>> = 'u'
value<<<{"description": "The value to be set in IC"}>>> = -0.5
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 2
[]
[]
[MeshModifiers<<<{"href": "../../syntax/MeshModifiers/index.html"}>>>]
[moving_circle]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 1
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[]
[AuxKernels<<<{"href": "../../syntax/AuxKernels/index.html"}>>>]
[phi]
type = ParsedAux<<<{"description": "Sets a field variable value to the evaluation of a parsed expression.", "href": "../auxkernels/ParsedAux.html"}>>>
variable<<<{"description": "The name of the variable that this object applies to"}>>> = 'phi'
expression<<<{"description": "Parsed function expression to compute"}>>> = '(x-t)^2+(y)^2-0.5^2'
use_xyzt<<<{"description": "Make coordinate (x,y,z) and time (t) variables available in the function expression."}>>> = true
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[double_u]
type = StatefulAux
variable = 'u'
coupled = 'u'
block = 1
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/initial_condition.i)
The auxiliary variable is reinitialized to , which doubles over the timestep to , for all the elements that change subdomain ID to 1
Stateful material property reinitialization
Similarly, all stateful material properties will be re-initialized when an element changes subdomain ID. Suppose initially the diffusivity is in subdomain 1 and in subdomain 2, and the diffusivity doubles at each time step in subdomain 1:
[Materials<<<{"href": "../../syntax/Materials/index.html"}>>>]
[stateful]
type = StatefulMaterial
initial_diffusivity = 0.5
multiplier = 2
block = 'left'
outputs = 'exodus'
[]
[non_stateful]
type = GenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../materials/GenericConstantMaterial.html"}>>>
prop_names<<<{"description": "The names of the properties this material will have"}>>> = 'diffusivity'
prop_values<<<{"description": "The values associated with the named properties"}>>> = '-1'
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 'right'
outputs<<<{"description": "Vector of output names where you would like to restrict the output of variables(s) associated with this object"}>>> = 'exodus'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/stateful_property.i)
The diffusivity is reinitialized to , which doubles over the timestep to , for all the elements that change subdomain ID to 1.
Reinitialization restrictions
Depending on the physics, one may or may not want to reinitialize the solution when an element and its related nodes change subdomain ID. For the below examples, consider a unit square domain decomposed by vertical lines and . The elements on the left have subdomain ID of 1, the elements in the middle have subdomain ID of 2, and the elements on the right have subdomain ID of 3.
The ElementSubdomainModifier
is used to change the subdomain ID to 1 for elements within a circle of radius 0.3 whose center moves along the bottom side towards the right, and to subdomain ID 2 for elements within a circle of radius 0.3 whose center moves along the top side towards the right.
An auxiliary variable is defined over the domain, with initial values of 1, 2, and 3 in subdomains 1, 2, and 3 respectively:
[MeshModifiers<<<{"href": "../../syntax/MeshModifiers/index.html"}>>>]
[moving_circle_bottom]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_1'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 1
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[moving_circle_top]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_2'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 2
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/reinitialization.i)
The default behaviour of the modifier is to reinitializate all elements that change subdomain ID.
However, if a list of subdomains (IDs or names) is provided through the parameter reinitialize_subdomains
, the reinitialization only occurs if the element's new subdomain ID is in the provided list:
[MeshModifiers<<<{"href": "../../syntax/MeshModifiers/index.html"}>>>]
[moving_circle_bottom]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_1'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 1
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[moving_circle_top]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_2'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 2
reinitialize_subdomains<<<{"description": "By default, any element which changes subdomain is reinitialized. If a list of subdomains (IDs or names) is provided, then only elements whose new subdomain is in the list will be reinitialized. If an empty list is set, then no elements will be reinitialized."}>>> = '1'
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/reinitialization_into.i)
Reinitialization of only the elements that change subdomain ID to 1.
If an empty list is given in reinitialize_subdomains
, then there is no reinitialization of any elements that change subdomain ID.
[MeshModifiers<<<{"href": "../../syntax/MeshModifiers/index.html"}>>>]
[moving_circle_bottom]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_1'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 1
reinitialize_subdomains<<<{"description": "By default, any element which changes subdomain is reinitialized. If a list of subdomains (IDs or names) is provided, then only elements whose new subdomain is in the list will be reinitialized. If an empty list is set, then no elements will be reinitialized."}>>> = ''
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[moving_circle_top]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_2'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 2
reinitialize_subdomains<<<{"description": "By default, any element which changes subdomain is reinitialized. If a list of subdomains (IDs or names) is provided, then only elements whose new subdomain is in the list will be reinitialized. If an empty list is set, then no elements will be reinitialized."}>>> = ''
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/no_reinitialization.i)
No reinitialization of any elements that change subdomain ID.
Reinitialization can be further restricted by setting the parameter old_subdomain_reinitialized
to false
. The modifier will then additionally check the element's old subdomain ID. Reinitialization then only occurs if the old subdomain ID was not in the list provided in the parameter reinitialize_subdomains
.
[MeshModifiers<<<{"href": "../../syntax/MeshModifiers/index.html"}>>>]
[moving_circle_bottom]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_1'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 1
reinitialize_subdomains<<<{"description": "By default, any element which changes subdomain is reinitialized. If a list of subdomains (IDs or names) is provided, then only elements whose new subdomain is in the list will be reinitialized. If an empty list is set, then no elements will be reinitialized."}>>> = '1 2'
old_subdomain_reinitialized<<<{"description": "This parameter must be set with a non-empty list in 'reinitialize_subdomains'. When set to the default true, the element's old subdomain is not considered when determining if an element should be reinitialized. If set to false, only elements whose old subdomain was not in 'reinitialize_subdomains' are reinitialized. "}>>> = false
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[moving_circle_top]
type = CoupledVarThresholdElementSubdomainModifier<<<{"description": "Modify the element subdomain ID if a coupled variable satisfies the criterion for the threshold (above, equal, or below)", "href": "CoupledVarThresholdElementSubdomainModifier.html"}>>>
coupled_var<<<{"description": "Coupled variable whose value is used in the criterion"}>>> = 'phi_2'
criterion_type<<<{"description": "Criterion to use for the threshold"}>>> = 'BELOW'
threshold<<<{"description": "The value above (or below) which to change the element subdomain"}>>> = 0
subdomain_id<<<{"description": "The subdomain ID of the element when the criterion is met"}>>> = 2
reinitialize_subdomains<<<{"description": "By default, any element which changes subdomain is reinitialized. If a list of subdomains (IDs or names) is provided, then only elements whose new subdomain is in the list will be reinitialized. If an empty list is set, then no elements will be reinitialized."}>>> = '1 2'
old_subdomain_reinitialized<<<{"description": "This parameter must be set with a non-empty list in 'reinitialize_subdomains'. When set to the default true, the element's old subdomain is not considered when determining if an element should be reinitialized. If set to false, only elements whose old subdomain was not in 'reinitialize_subdomains' are reinitialized. "}>>> = false
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'INITIAL TIMESTEP_BEGIN'
[]
[]
(moose/test/tests/meshmodifiers/element_subdomain_modifier/reinitialization_from_into.i)
Reinitialization of only the elements which change subdomain ID from 3, to subdomain IDs 1 or 2
Variable (re)initialization on the updated active domain
In element activation simulations (e.g., for additive manufacturing), the degrees of freedom (DoFs) on the updated active domain have no prior solution information when they are incorporated into the solution process. In moving interface problems, the DoFs on the updated active domain already exist but may need to be re-initialized depending on the physics. As a result, it is necessary to selectively impose appropriate initial conditions for these DoFs.
There are two strategies for (re)initializing variables on the updated active domain. The first, arguably the simplest, strategy is to project the initial condition of the variable onto the updated active domain.
However, directly imposing such initial conditions often poses significant challenges for the solution procedure. For nonlinear material models, a suboptimal initial guess could hinder convergence of the material model and/or that of the global solve. For evaluations on the deformed mesh, e.g., when geometric nonlinearity or mechanical contact is enabled, a bad initial condition of displacement could lead to ill-conditioned elements, and in extreme cases, could lead to highly skewed elements with inverted Jacobians.
The second strategy aims to address these challenges. The key idea is to initialize the solution on the updated active domain leveraging the solution information from the stationary active domain. In the current implementation, we adopt the Zienkiewicz–Zhu patch recovery technique to initialize the solution field for the DoFs on updated active elements.
The initialization algorithm starts with constructing a patch of elements from the stationary active domain. By definition, a solution to the variable of interest already exists on the patch. The solution is first interpolated onto the quadrature points on the stationary active domain, and a polynomial is fitted against the interpolated variable values using a least-squares fit. A complete set of monomials up to a given order is used as the basis of the polynomial. Let be a multi-index of dimension , where
(1)The monomial basis for degree can be written as:
(2)For example, in 2D () with , the complete monomial basis can be written as .
The monomial generation can be implemented recursively. Define as the constant term. Higher-order monomials are then constructed by augmenting with all combinations of such that .
That is,
(3)(4)The fitting process solves a least-squares problem. In matrix form, it can be expressed as
(5)where is the patch interpolation matrix, is the patch interpolation vector, and contains the fitted polynomial coefficients. These matrices are assembled over quadrature points on the patch:
(6)where is the interpolated variable value at the quadrature point .
For least-squares fitting with the same patch of elements, the computed coefficients can be cached and reused to reduce computational overhead.
Once the least-squares problem is solved, the fitted polynomial is used to extrapolate the solution onto the updated active domain by projecting the polynomial.