19 #include "libmesh/quadrature.h" 30 "AugmentSparsityOnInterface",
34 rm_params.
set<
bool>(
"use_displaced_mesh") = obj_params.
get<
bool>(
"use_displaced_mesh");
35 rm_params.
set<BoundaryName>(
"secondary_boundary") =
36 obj_params.
get<BoundaryName>(
"secondary_boundary");
37 rm_params.
set<BoundaryName>(
"primary_boundary") =
38 obj_params.
get<BoundaryName>(
"primary_boundary");
39 rm_params.
set<SubdomainName>(
"secondary_subdomain") =
40 obj_params.
get<SubdomainName>(
"secondary_subdomain");
41 rm_params.
set<SubdomainName>(
"primary_subdomain") =
42 obj_params.
get<SubdomainName>(
"primary_subdomain");
43 rm_params.
set<
bool>(
"ghost_point_neighbors") =
44 obj_params.
get<
bool>(
"ghost_point_neighbors");
45 rm_params.
set<
bool>(
"ghost_higher_d_neighbors") =
46 obj_params.
get<
bool>(
"ghost_higher_d_neighbors");
50 "The name of the primary boundary sideset.");
52 "The name of the secondary boundary sideset.");
53 params.
addRequiredParam<SubdomainName>(
"primary_subdomain",
"The name of the primary subdomain.");
55 "The name of the secondary subdomain.");
59 "Whether this constraint is going to be used to enforce a periodic condition. This has the " 60 "effect of changing the normals vector for projection from outward to inward facing");
65 "Whether this constraint is going to enable mortar segment mesh debug information. An exodus" 66 "file will be generated if the user sets this flag to true");
69 "correct_edge_dropping",
71 "Whether to enable correct edge dropping treatment for mortar constraints. When disabled " 72 "any Lagrange Multiplier degree of freedom on a secondary element without full primary " 73 "contributions will be set (strongly) to 0.");
76 "interpolate_normals",
78 "Whether to interpolate the nodal normals (e.g. classic idea of evaluating field at " 79 "quadrature points). If this is set to false, then non-interpolated nodal normals will be " 80 "used, and then the _normals member should be indexed with _i instead of _qp");
82 params.
addParam<
bool>(
"ghost_point_neighbors",
84 "Whether we should ghost point neighbors of secondary face elements, and " 85 "consequently also their mortar interface couples.");
87 "minimum_projection_angle",
89 "Parameter to control which angle (in degrees) is admissible for the creation of mortar " 90 "segments. If set to a value close to zero, very oblique projections are allowed, which " 91 "can result in mortar segments solving physics not meaningfully, and overprojection of " 92 "primary nodes onto the mortar segment mesh in extreme cases. This parameter is mostly " 93 "intended for mortar mesh debugging purposes in two dimensions.");
96 "ghost_higher_d_neighbors",
98 "Whether we should ghost higher-dimensional neighbors. This is necessary when we are doing " 99 "second order mortar with finite volume primal variables, because in order for the method to " 100 "be second order we must use cell gradients, which couples in the neighbor cells.");
107 : _mci_fe_problem(*moose_object->getCheckedPointerParam<
FEProblemBase *>(
"_fe_problem_base")),
108 _mci_subproblem(*moose_object->getCheckedPointerParam<
SubProblem *>(
"_subproblem")),
109 _mci_tid(moose_object->getParam<
THREAD_ID>(
"_tid")),
110 _mci_mesh(_mci_subproblem.
mesh()),
112 _mci_assembly(_mci_subproblem.assembly(_mci_tid, 0)),
113 _mortar_data(_mci_fe_problem.mortarData()),
115 _mci_mesh.
getBoundaryID(moose_object->getParam<BoundaryName>(
"secondary_boundary"))),
116 _primary_id(_mci_mesh.
getBoundaryID(moose_object->getParam<BoundaryName>(
"primary_boundary"))),
117 _secondary_subdomain_id(
118 _mci_mesh.
getSubdomainID(moose_object->getParam<SubdomainName>(
"secondary_subdomain"))),
119 _primary_subdomain_id(
120 _mci_mesh.
getSubdomainID(moose_object->getParam<SubdomainName>(
"primary_subdomain"))),
122 _interpolate_normals(moose_object->getParam<
bool>(
"interpolate_normals")),
123 _phys_points_secondary(_mci_assembly.qPointsFace()),
124 _phys_points_primary(_mci_assembly.qPointsFaceNeighbor()),
125 _qrule_msm(_mci_assembly.qRuleMortar()),
126 _qrule_face(_mci_assembly.qRuleFace()),
127 _lower_secondary_elem(_mci_assembly.lowerDElem()),
128 _lower_primary_elem(_mci_assembly.neighborLowerDElem()),
129 _JxW_msm(_mci_assembly.jxWMortar()),
130 _msm_elem(_mci_assembly.msmElem())
132 const bool displaced = moose_object->isParamValid(
"use_displaced_mesh")
133 ? moose_object->getParam<
bool>(
"use_displaced_mesh")
137 _mci_fe_problem.createMortarInterface(
138 std::make_pair(_primary_id, _secondary_id),
139 std::make_pair(_primary_subdomain_id, _secondary_subdomain_id),
141 moose_object->getParam<
bool>(
"periodic"),
142 moose_object->getParam<
bool>(
"debug_mesh"),
143 moose_object->getParam<
bool>(
"correct_edge_dropping"),
144 moose_object->getParam<Real>(
"minimum_projection_angle"));
146 _amg = &_mci_fe_problem.getMortarInterface(
147 std::make_pair(_primary_id, _secondary_id),
148 std::make_pair(_primary_subdomain_id, _secondary_subdomain_id),
151 const auto & secondary_set = _mortar_data.getHigherDimSubdomainIDs(_secondary_subdomain_id);
152 const auto & primary_set = _mortar_data.getHigherDimSubdomainIDs(_primary_subdomain_id);
154 std::set_union(secondary_set.begin(),
158 std::inserter(_higher_dim_subdomain_ids, _higher_dim_subdomain_ids.begin()));
159 _boundary_ids = {_secondary_id, _primary_id};
175 auto md_it = dual_number.derivatives().nude_data().begin();
176 auto mi_it = dual_number.derivatives().nude_indices().begin();
178 auto d_it = dual_number.derivatives().nude_data().begin();
180 for (
auto i_it = dual_number.derivatives().nude_indices().begin();
181 i_it != dual_number.derivatives().nude_indices().end();
183 if (*i_it != remove_derivative_index)
191 std::size_t n_indices = md_it - dual_number.derivatives().nude_data().begin();
192 dual_number.derivatives().nude_indices().resize(n_indices);
193 dual_number.derivatives().nude_data().resize(n_indices);
const BoundaryID _secondary_id
Boundary ID for the secondary surface.
MortarConsumerInterface(const MooseObject *moose_object)
const libMesh::QBase *const & _qrule_face
The arbitrary quadrature rule on the lower dimensional secondary face.
std::vector< Point > getNodalNormals(const Elem &secondary_elem) const
DualNumber< Real, DNDerivativeType, true > ADReal
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name, const MeshBase &mesh)
Gets the subdomain ID associated with the given SubdomainName.
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
Elem const *const & _lower_secondary_elem
The secondary face lower dimensional element (not the mortar element!).
const AutomaticMortarGeneration & amg() const
Retrieve the automatic mortar generation object associated with this constraint.
Every object that can be built by the factory should be derived from this class.
std::vector< Point > _normals
the normals
bool interpolateNormals() const
Whether to interpolate the nodal normals (e.g.
static void trimDerivative(dof_id_type remove_derivative_index, ADReal &dual_number)
Get rid of AD derivative entries by dof index.
void setNormals()
Set the normals vector.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Generic class for solving transient nonlinear problems.
const std::vector< Point > & get_points() const
static InputParameters validParams()
std::vector< Point > getNormals(const Elem &secondary_elem, const std::vector< Point > &xi1_pts) const
Compute the normals at given reference points on a secondary element.