15 #include "metaphysicl/metaphysicl_version.h" 16 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 17 #include "metaphysicl/parallel_dualnumber.h" 18 #if METAPHYSICL_MAJOR_VERSION < 2 19 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 21 #include "metaphysicl/parallel_dynamic_array_wrapper.h" 23 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 31 assignVarsInParamsCartesianWeightedGap(
const InputParameters & params_in)
34 const auto & disp_x_name = ret.
get<std::vector<VariableName>>(
"disp_x");
35 if (disp_x_name.size() != 1)
36 mooseError(
"We require that the disp_x parameter have exactly one coupled name");
39 ret.
set<VariableName>(
"secondary_variable") = disp_x_name[0];
40 ret.
set<VariableName>(
"primary_variable") = disp_x_name[0];
50 params.
addClassDescription(
"Computes the weighted gap that will later be used to enforce the " 51 "zero-penetration mechanical contact conditions");
56 params.
addCoupledVar(
"disp_z",
"The z displacement variable");
58 "c", 1e6,
"Parameter for balancing the size of the gap and contact pressure");
60 "Mechanical contact Lagrange multiplier along the x Cartesian axis");
62 "lm_y",
"Mechanical contact Lagrange multiplier along the y Cartesian axis.");
64 "Mechanical contact Lagrange multiplier along the z Cartesian axis.");
65 params.
set<
bool>(
"interpolate_normals") =
false;
69 "Whether to normalize c by weighting function norm. When unnormalized " 70 "the value of c effectively depends on element size since in the constraint we compare nodal " 71 "Lagrange Multiplier values to integrated gap values (LM nodal value is independent of " 72 "element size, where integrated values are dependent on element size).");
73 params.
set<
bool>(
"use_displaced_mesh") =
true;
80 _secondary_disp_x(adCoupledValue(
"disp_x")),
81 _primary_disp_x(adCoupledNeighborValue(
"disp_x")),
82 _secondary_disp_y(adCoupledValue(
"disp_y")),
83 _primary_disp_y(adCoupledNeighborValue(
"disp_y")),
84 _has_disp_z(isCoupled(
"disp_z")),
85 _secondary_disp_z(_has_disp_z ? &adCoupledValue(
"disp_z") : nullptr),
86 _primary_disp_z(_has_disp_z ? &adCoupledNeighborValue(
"disp_z") : nullptr),
87 _c(getParam<
Real>(
"c")),
88 _normalize_c(getParam<bool>(
"normalize_c")),
89 _nodal(getVar(
"disp_x", 0)->feType().family ==
LAGRANGE),
90 _disp_x_var(getVar(
"disp_x", 0)),
91 _disp_y_var(getVar(
"disp_y", 0)),
92 _disp_z_var(_has_disp_z ? getVar(
"disp_z", 0) : nullptr)
99 "In three-dimensions, both the Z Lagrange multiplier and the Z displacement need to " 105 if (!getParam<bool>(
"use_displaced_mesh"))
107 "use_displaced_mesh",
108 "'use_displaced_mesh' must be true for the ComputeWeightedGapLMMechanicalContact object");
112 if (
_lm_vars[i]->feType().order != static_cast<Order>(0))
113 mooseError(
"Normal contact constraints only support elemental variables of CONSTANT order");
119 mooseError(
"We should never call computeQpResidual for ComputeWeightedGapLMMechanicalContact");
128 const auto & secondary_ip_lowerd_map =
132 std::array<ADReal, 3> primary_disp{
141 const ADReal & prim_x = primary_disp[0];
142 const ADReal & prim_y = primary_disp[1];
143 const ADReal * prim_z =
nullptr;
145 prim_z = &primary_disp[2];
147 const ADReal & sec_x = secondary_disp[0];
148 const ADReal & sec_y = secondary_disp[1];
149 const ADReal * sec_z =
nullptr;
151 sec_z = &secondary_disp[2];
156 gap_vec(0).derivatives() = prim_x.derivatives() - sec_x.derivatives();
157 gap_vec(1).derivatives() = prim_y.derivatives() - sec_y.derivatives();
159 gap_vec(2).derivatives() = prim_z->derivatives() - sec_z->derivatives();
172 "Making sure that _normals is the expected size");
175 const DofObject * dof =
_lm_vars[0]->isNodal()
216 mooseAssert(
_lm_vars[i],
"LM variable is null");
228 const DofObject * dof =
273 const std::unordered_set<const Node *> & inactive_lm_nodes)
280 if ((inactive_lm_nodes.find(static_cast<const Node *>(pr.first)) != inactive_lm_nodes.end()) ||
299 const Real scaling_factor_x =
_lm_vars[0]->scalingFactor();
300 const Real scaling_factor_y =
_lm_vars[1]->scalingFactor();
301 Real scaling_factor_z = 1;
316 scaling_factor_z =
_lm_vars[2]->scalingFactor();
319 ADReal normal_pressure_value =
321 ADReal tangential_pressure_value =
324 ADReal tangential_pressure_value_dir;
335 ADReal normal_dof_residual = std::min(normal_pressure_value, weighted_gap *
c);
336 ADReal tangential_dof_residual = tangential_pressure_value;
354 unsigned int component_normal = 0;
355 if (std::abs(ny) > 0.57735)
356 component_normal = 1;
357 else if (std::abs(nz) > 0.57735)
358 component_normal = 2;
364 std::array<ADReal, 1>{{normal_dof_residual}},
365 std::array<dof_id_type, 1>{{component_normal == 0
367 : (component_normal == 1 ? dof_index_y : dof_index_z)}},
368 component_normal == 0 ? scaling_factor_x
369 : (component_normal == 1 ? scaling_factor_y : scaling_factor_z));
373 std::array<ADReal, 1>{{tangential_dof_residual}},
374 std::array<dof_id_type, 1>{
375 {(component_normal == 0 || component_normal == 2) ? dof_index_y : dof_index_x}},
376 (component_normal == 0 || component_normal == 2) ? scaling_factor_y : scaling_factor_x);
381 std::array<ADReal, 1>{{tangential_pressure_value_dir}},
382 std::array<dof_id_type, 1>{
383 {(component_normal == 0 || component_normal == 1) ? dof_index_z : dof_index_x}},
384 (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 paramError(const std::string ¶m, Args... args) const
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
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
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)
bool isParamValid(const std::string &name) const
const MooseArray< Real > & _coord
processor_id_type processor_id() const
auto index_range(const T &sizable)