14 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 15 #include "metaphysicl/parallel_dualnumber.h" 16 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 17 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 25 assignVarsInParamsCartesianWeightedGap(
const InputParameters & params_in)
28 const auto & disp_x_name = ret.
get<std::vector<VariableName>>(
"disp_x");
29 if (disp_x_name.size() != 1)
30 mooseError(
"We require that the disp_x parameter have exactly one coupled name");
33 ret.
set<VariableName>(
"secondary_variable") = disp_x_name[0];
34 ret.
set<VariableName>(
"primary_variable") = disp_x_name[0];
44 params.
addClassDescription(
"Computes the weighted gap that will later be used to enforce the " 45 "zero-penetration mechanical contact conditions");
50 params.
addCoupledVar(
"disp_z",
"The z displacement variable");
52 "c", 1e6,
"Parameter for balancing the size of the gap and contact pressure");
54 "Mechanical contact Lagrange multiplier along the x Cartesian axis");
56 "lm_y",
"Mechanical contact Lagrange multiplier along the y Cartesian axis.");
58 "Mechanical contact Lagrange multiplier along the z Cartesian axis.");
59 params.
set<
bool>(
"interpolate_normals") =
false;
63 "Whether to normalize c by weighting function norm. When unnormalized " 64 "the value of c effectively depends on element size since in the constraint we compare nodal " 65 "Lagrange Multiplier values to integrated gap values (LM nodal value is independent of " 66 "element size, where integrated values are dependent on element size).");
67 params.
set<
bool>(
"use_displaced_mesh") =
true;
74 _secondary_disp_x(adCoupledValue(
"disp_x")),
75 _primary_disp_x(adCoupledNeighborValue(
"disp_x")),
76 _secondary_disp_y(adCoupledValue(
"disp_y")),
77 _primary_disp_y(adCoupledNeighborValue(
"disp_y")),
78 _has_disp_z(isCoupled(
"disp_z")),
79 _secondary_disp_z(_has_disp_z ? &adCoupledValue(
"disp_z") : nullptr),
80 _primary_disp_z(_has_disp_z ? &adCoupledNeighborValue(
"disp_z") : nullptr),
81 _c(getParam<
Real>(
"c")),
82 _normalize_c(getParam<bool>(
"normalize_c")),
83 _nodal(getVar(
"disp_x", 0)->feType().family ==
LAGRANGE),
84 _disp_x_var(getVar(
"disp_x", 0)),
85 _disp_y_var(getVar(
"disp_y", 0)),
86 _disp_z_var(_has_disp_z ? getVar(
"disp_z", 0) : nullptr)
93 "In three-dimensions, both the Z Lagrange multiplier and the Z displacement need to " 99 if (!getParam<bool>(
"use_displaced_mesh"))
101 "use_displaced_mesh",
102 "'use_displaced_mesh' must be true for the ComputeWeightedGapLMMechanicalContact object");
106 if (
_lm_vars[i]->feType().order != static_cast<Order>(0))
107 mooseError(
"Normal contact constraints only support elemental variables of CONSTANT order");
112 mooseError(
"We should never call computeQpResidual for ComputeWeightedGapLMMechanicalContact");
121 const auto & secondary_ip_lowerd_map =
125 std::array<ADReal, 3> primary_disp{
134 const ADReal & prim_x = primary_disp[0];
135 const ADReal & prim_y = primary_disp[1];
136 const ADReal * prim_z =
nullptr;
138 prim_z = &primary_disp[2];
140 const ADReal & sec_x = secondary_disp[0];
141 const ADReal & sec_y = secondary_disp[1];
142 const ADReal * sec_z =
nullptr;
144 sec_z = &secondary_disp[2];
149 gap_vec(0).derivatives() = prim_x.derivatives() - sec_x.derivatives();
150 gap_vec(1).derivatives() = prim_y.derivatives() - sec_y.derivatives();
152 gap_vec(2).derivatives() = prim_z->derivatives() - sec_z->derivatives();
165 "Making sure that _normals is the expected size");
168 const DofObject * dof =
_lm_vars[0]->isNodal()
209 mooseAssert(
_lm_vars[i],
"LM variable is null");
221 const DofObject * dof =
266 const std::unordered_set<const Node *> & inactive_lm_nodes)
273 if ((inactive_lm_nodes.find(static_cast<const Node *>(pr.first)) != inactive_lm_nodes.end()) ||
292 const Real scaling_factor_x =
_lm_vars[0]->scalingFactor();
293 const Real scaling_factor_y =
_lm_vars[1]->scalingFactor();
294 Real scaling_factor_z = 1;
309 scaling_factor_z =
_lm_vars[2]->scalingFactor();
312 ADReal normal_pressure_value =
314 ADReal tangential_pressure_value =
317 ADReal tangential_pressure_value_dir;
328 ADReal normal_dof_residual = std::min(normal_pressure_value, weighted_gap *
c);
329 ADReal tangential_dof_residual = tangential_pressure_value;
347 unsigned int component_normal = 0;
348 if (std::abs(ny) > 0.57735)
349 component_normal = 1;
350 else if (std::abs(nz) > 0.57735)
351 component_normal = 2;
357 std::array<ADReal, 1>{{normal_dof_residual}},
358 std::array<dof_id_type, 1>{{component_normal == 0
360 : (component_normal == 1 ? dof_index_y : dof_index_z)}},
361 component_normal == 0 ? scaling_factor_x
362 : (component_normal == 1 ? scaling_factor_y : scaling_factor_z));
366 std::array<ADReal, 1>{{tangential_dof_residual}},
367 std::array<dof_id_type, 1>{
368 {(component_normal == 0 || component_normal == 2) ? dof_index_y : dof_index_x}},
369 (component_normal == 0 || component_normal == 2) ? scaling_factor_y : scaling_factor_x);
374 std::array<ADReal, 1>{{tangential_pressure_value_dir}},
375 std::array<dof_id_type, 1>{
376 {(component_normal == 0 || component_normal == 1) ? dof_index_z : dof_index_x}},
377 (component_normal == 0 || component_normal == 1) ? scaling_factor_z : scaling_factor_x);
virtual const NumericVector< Number > *const & currentSolution() const=0
void addResidualsAndJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void mooseError(Args &&... args)
std::map< unsigned int, unsigned int > getPrimaryIpToLowerElementMap(const Elem &primary_elem, const Elem &primary_elem_ip, const Elem &lower_secondary_elem) const
const MooseArray< Point > & _phys_points_primary
Elem const *const & _lower_primary_elem
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
const std::vector< Real > & _JxW_msm
const Parallel::Communicator & _communicator
DualNumber< Real, DNDerivativeType, true > ADReal
virtual void computeResidual() override
const libMesh::QBase *const & _qrule_msm
const VariableTestValue & _test
bool isParamValid(const std::string &name) const
Elem const *const & _lower_secondary_elem
void libmesh_ignore(const Args &...)
const AutomaticMortarGeneration & amg() const
static void trimInteriorNodeDerivatives(const std::map< unsigned int, unsigned int > &primary_ip_lowerd_map, const Variables &moose_var, DualNumbers &ad_vars, const bool is_secondary)
std::vector< Point > _normals
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
unsigned int n_points() const
std::map< unsigned int, unsigned int > getSecondaryIpToLowerElementMap(const Elem &lower_secondary_elem) const
void paramError(const std::string ¶m, Args... args) const
unsigned int number() const
const MooseArray< Point > & _phys_points_secondary
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void computeJacobian() override
void mooseError(Args &&... args) const
static InputParameters validParams()
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N >> &derivs, libMesh::dof_id_type index, Real value)
const MooseArray< Real > & _coord
processor_id_type processor_id() const
auto index_range(const T &sizable)