forked from idaholab/moose
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unify element activation, element death and moving interface
Generalize the existing ActivateElementUserObjects, add ElementSubdomainModifiers, and fix some parallel bugs. close idaholab#17100
- Loading branch information
1 parent
c20d3af
commit 2a4817f
Showing
44 changed files
with
1,232 additions
and
3 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions
70
...rk/doc/content/source/userobject/CoupledVarThresholdElementSubdomainModifier.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# CoupledVarThresholdElementSubdomainModifier | ||
|
||
!syntax description /UserObjects/CoupledVarThresholdElementSubdomainModifier | ||
|
||
## Overview | ||
|
||
The `CoupledVarThresholdElementSubdomainModifier` 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 `CoupledVarThresholdElementSubdomainModifier` changes the element subdomain based on the given criterion. It also handles the corresponding | ||
|
||
- Moving boundary/interface nodeset/sideset modification, | ||
- Solution initialization, and | ||
- Stateful material property initialization, | ||
|
||
all of which are demonstrated using the following example. | ||
|
||
Consider a unit square domain, and an auxiliary variable defined by the function $\phi(x,y,t) = (x-t)^2+y^2-0.5^2$. The function represents a signed-distance function of a circle of radius $0.5$ whose center is moving along the x-axis towards right. | ||
|
||
Initially, the domain is decomposed by a vertical line $x=0.25$. 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 `CoupledVarThresholdElementSubdomainModifier` is used to change the subdomain ID from 2 to 1 for elements within the circle. | ||
|
||
## Reversible vs. irreversible modification | ||
|
||
If the `CoupledVarThresholdElementSubdomainModifier` is applied onto the entire domain, and the parameter `complement_subdomain_id` is set to 2, then the subdomain ID of all elements outside the circle will be set to 2: | ||
|
||
!listing test/tests/userobjects/element_subdomain_modifier/reversible.i start=[moving_circle] end=[] include-end=true | ||
|
||
!media media/userobjects/esm_reversible.jpg style=float:center;width:100%; caption=The result of a reversible element subdomain modifier at three different time steps | ||
|
||
However, in many applications, e.g. element death and activation, the equivalent movement of element subdomains is not reversible. In this case, omitting the parameter `complement_subdomain_id` will make the subdomain modification irreversible: | ||
|
||
!listing test/tests/userobjects/element_subdomain_modifier/block_restricted.i start=[moving_circle] end=[] include-end=true | ||
|
||
!media media/userobjects/esm_irreversible.jpg style=float:center;width:100%; caption=The result of an irreversible element subdomain modifier at three different time steps | ||
|
||
## Moving boundary/interface nodeset/sideset modification | ||
|
||
The change of element subdomains will alter the definition of certain sidesets and nodesets. The `CoupledVarThresholdElementSubdomainModifier` optionally takes the parameter `moving_boundary_name` to help modify the corresponding sideset/nodeset. If the boundary provided through the `moving_boundary_name` parameter already exists, the modifier will attempt to modify the provided sideset/nodeset whenever an element changes subdomain. If the boundary does not exist, the modifier will create a sideset and a nodeset with the provided name. | ||
|
||
!media media/userobjects/esm_sideset.jpg style=float:center;width:100%; caption=The evolving sideset (green) at three different time steps | ||
|
||
!media media/userobjects/esm_nodeset.jpg style=float:center;width:100%; caption=The evolving nodeset (green) at three different time steps | ||
|
||
Nodal and integrated BCs can be applied on the moving boundary. | ||
|
||
## Solution initialization | ||
|
||
Depending on the physics, one may or may not want to initialize the solution when an element and its related nodes change subdomain. | ||
The parameter `apply_initial_conditions` defaults to true and determines whether the initial conditions should be re-evaluated. | ||
|
||
Suppose initially there is an auxiliary variable $u=1$ everywhere inside the domain, and the variable value in subdomain 1 (blue) doubles at each time step: | ||
|
||
!listing test/tests/userobjects/element_subdomain_modifier/initial_condition.i start=[AuxVariables] end=[Executioner] | ||
|
||
!media media/userobjects/esm_ic.jpg style=float:center;width:100%; caption=The auxiliary variable $u$ at three different time steps | ||
|
||
## Stateful material property initialization | ||
|
||
Similarly, all stateful material properties will be re-initialized when an element changes subdomain. Suppose initially the diffusivity is $0.5$ everywhere, and the diffusivity doubles at each time step: | ||
|
||
!listing test/tests/userobjects/element_subdomain_modifier/stateful_property.i start=[Materials] end=[Executioner] | ||
|
||
!media media/userobjects/esm_material.jpg style=float:center;width:100%; caption=The diffusivity at three different time steps | ||
|
||
!syntax parameters /UserObjects/CoupledVarThresholdElementSubdomainModifier | ||
|
||
!syntax inputs /UserObjects/CoupledVarThresholdElementSubdomainModifier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
framework/include/userobject/CoupledVarThresholdElementSubdomainModifier.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* 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 "ThresholdElementSubdomainModifier.h" | ||
|
||
class CoupledVarThresholdElementSubdomainModifier : public ThresholdElementSubdomainModifier | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
CoupledVarThresholdElementSubdomainModifier(const InputParameters & parameters); | ||
|
||
protected: | ||
virtual Real computeValue() override; | ||
|
||
private: | ||
/// The coupled variable used in the criterion | ||
const VariableValue & _v; | ||
}; |
116 changes: 116 additions & 0 deletions
116
framework/include/userobject/ElementSubdomainModifier.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* 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 "ElementUserObject.h" | ||
#include "NonlinearSystemBase.h" | ||
#include "AuxiliarySystem.h" | ||
|
||
class ElementSubdomainModifier : public ElementUserObject | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
ElementSubdomainModifier(const InputParameters & parameters); | ||
|
||
virtual void initialSetup() override; | ||
virtual void initialize() override; | ||
virtual void execute() override; | ||
virtual void threadJoin(const UserObject & /*uo*/) override{}; | ||
virtual void finalize() override; | ||
|
||
protected: | ||
// Compute the subdomain ID of the current element | ||
virtual SubdomainID computeSubdomainID() = 0; | ||
|
||
// The ID of the moving boundary that this object creates/modifies. | ||
BoundaryID movingBoundaryID() const | ||
{ | ||
if (!_moving_boundary_specified) | ||
mooseError("no moving boundary specified"); | ||
return _moving_boundary_id; | ||
} | ||
|
||
// The name of the moving boundary that this object creates/modifies. | ||
const BoundaryName movingBoundaryName() const | ||
{ | ||
if (!_moving_boundary_specified) | ||
mooseError("no moving boundary specified"); | ||
return _moving_boundary_name; | ||
} | ||
|
||
// Range of the elements who changed their subdomain ID | ||
ConstElemRange & movedElemsRange() const { return *_moved_elems_range; } | ||
|
||
// Range of the boundary nodes on moved elements | ||
ConstBndNodeRange & movedBndNodesRange() const { return *_moved_bnd_nodes_range; } | ||
|
||
// Pointer to the displaced problem | ||
DisplacedProblem * _displaced_problem; | ||
|
||
private: | ||
// Set the name of the moving boundary. Create the nodeset/sideset if not exist. | ||
void setMovingBoundaryName(MooseMesh & mesh); | ||
|
||
// Update the moving boundary (both the underlying sideset and nodeset) | ||
void updateBoundaryInfo(MooseMesh & mesh, const std::vector<const Elem *> & moved_elems); | ||
|
||
// Helper function to add nodes on a side of an element to a set | ||
void recordNodeIdsOnElemSide(const Elem * elem, | ||
const unsigned short int side, | ||
std::set<dof_id_type> & node_ids); | ||
|
||
// Remove ghosted element sides | ||
void pushBoundarySideInfo( | ||
MooseMesh & mesh, | ||
std::unordered_map<processor_id_type, std::vector<std::pair<dof_id_type, unsigned int>>> & | ||
elems_to_push); | ||
|
||
// Remove ghosted boundary nodes | ||
void pushBoundaryNodeInfo( | ||
MooseMesh & mesh, | ||
std::unordered_map<processor_id_type, std::vector<dof_id_type>> & nodes_to_push); | ||
|
||
// Helper function to build the range of moved elements | ||
void buildMovedElemsRange(); | ||
|
||
// Helper function to build the range of boundary nodes on moved elements | ||
void buildMovedBndNodesRange(); | ||
|
||
// Set old and older solutions to be the same as the current solution | ||
void setOldAndOlderSolutionsForMovedNodes(SystemBase & sys); | ||
|
||
// Elements on the undisplaced mesh whose subdomain IDs have changed | ||
std::vector<const Elem *> _moved_elems; | ||
|
||
// Elements on the displaced mesh whose subdomain IDs have changed | ||
std::vector<const Elem *> _moved_displaced_elems; | ||
|
||
// Nodes on the moved elements | ||
std::set<dof_id_type> _moved_nodes; | ||
|
||
// Range of the moved elements | ||
std::unique_ptr<ConstElemRange> _moved_elems_range; | ||
|
||
// Range of the boundary nodes on the moved elements | ||
std::unique_ptr<ConstBndNodeRange> _moved_bnd_nodes_range; | ||
|
||
// Whether to re-apply ICs on moved elements and moved nodes | ||
const bool _apply_ic; | ||
|
||
/// Whether a moving boundary name is provided | ||
const bool _moving_boundary_specified; | ||
|
||
/// The name of the moving boundary | ||
BoundaryName _moving_boundary_name; | ||
|
||
/// The Id of the moving boundary | ||
BoundaryID _moving_boundary_id; | ||
}; |
38 changes: 38 additions & 0 deletions
38
framework/include/userobject/ThresholdElementSubdomainModifier.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* 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 "ElementSubdomainModifier.h" | ||
#include "MooseEnum.h" | ||
|
||
class ThresholdElementSubdomainModifier : public ElementSubdomainModifier | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
ThresholdElementSubdomainModifier(const InputParameters & parameters); | ||
|
||
protected: | ||
virtual SubdomainID computeSubdomainID() override; | ||
|
||
/// Compute the value used in the criterion | ||
virtual Real computeValue() = 0; | ||
|
||
private: | ||
/// Threshold to modify the element subdomain ID | ||
const Real _threshold; | ||
|
||
/// Criterion type | ||
const enum class CriterionType { Below, Equal, Above } _criterion_type; | ||
|
||
/// Target subdomain ID | ||
const SubdomainID _subdomain_id; | ||
const SubdomainID _complement_subdomain_id; | ||
}; |
41 changes: 41 additions & 0 deletions
41
framework/src/userobject/CoupledVarThresholdElementSubdomainModifier.C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* 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 "CoupledVarThresholdElementSubdomainModifier.h" | ||
|
||
#include "libmesh/quadrature.h" | ||
|
||
registerMooseObject("MooseApp", CoupledVarThresholdElementSubdomainModifier); | ||
|
||
InputParameters | ||
CoupledVarThresholdElementSubdomainModifier::validParams() | ||
{ | ||
InputParameters params = ThresholdElementSubdomainModifier::validParams(); | ||
params.addRequiredCoupledVar("coupled_var", | ||
"Coupled variable whose value is used in the criterion"); | ||
return params; | ||
} | ||
|
||
CoupledVarThresholdElementSubdomainModifier::CoupledVarThresholdElementSubdomainModifier( | ||
const InputParameters & parameters) | ||
: ThresholdElementSubdomainModifier(parameters), _v(coupledValue("coupled_var")) | ||
{ | ||
} | ||
|
||
Real | ||
CoupledVarThresholdElementSubdomainModifier::computeValue() | ||
{ | ||
Real avg_val = 0; | ||
|
||
for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp) | ||
avg_val += _v[qp]; | ||
avg_val /= _qrule->n_points(); | ||
|
||
return avg_val; | ||
} |
Oops, something went wrong.