16 #include "metaphysicl/metaphysicl_version.h" 17 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 18 #include "metaphysicl/parallel_dualnumber.h" 19 #if METAPHYSICL_MAJOR_VERSION < 2 20 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 22 #include "metaphysicl/parallel_dynamic_array_wrapper.h" 24 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 35 const auto & disp_x_name = ret.
get<std::vector<VariableName>>(
"disp_x");
36 if (disp_x_name.size() != 1)
37 mooseError(
"We require that the disp_x parameter have exactly one coupled name");
40 ret.
set<VariableName>(
"secondary_variable") = disp_x_name[0];
41 ret.
set<VariableName>(
"primary_variable") = disp_x_name[0];
51 "Computes the normal contact mortar constraints for dynamic simulations");
54 "capture_tolerance>=0",
55 "Parameter describing a gap threshold for the application of " 56 "the persistency constraint in dynamic simulations.");
58 "The name of the mortar auxiliary variable that is used to modify the " 59 "weighted gap definition");
61 "newmark_beta",
"newmark_beta > 0",
"Beta parameter for the Newmark time integrator");
63 "newmark_gamma",
"newmark_gamma >= 0.0",
"Gamma parameter for the Newmark time integrator");
68 params.
addCoupledVar(
"disp_z",
"The z displacement variable");
70 "c", 1e6,
"Parameter for balancing the size of the gap and contact pressure");
74 "Whether to normalize c by weighting function norm. When unnormalized " 75 "the value of c effectively depends on element size since in the constraint we compare nodal " 76 "Lagrange Multiplier values to integrated gap values (LM nodal value is independent of " 77 "element size, where integrated values are dependent on element size).");
78 params.
set<
bool>(
"use_displaced_mesh") =
true;
79 params.
set<
bool>(
"interpolate_normals") =
false;
86 _secondary_disp_x(adCoupledValue(
"disp_x")),
87 _primary_disp_x(adCoupledNeighborValue(
"disp_x")),
88 _secondary_disp_y(adCoupledValue(
"disp_y")),
89 _primary_disp_y(adCoupledNeighborValue(
"disp_y")),
90 _has_disp_z(isCoupled(
"disp_z")),
91 _secondary_disp_z(_has_disp_z ? &adCoupledValue(
"disp_z") : nullptr),
92 _primary_disp_z(_has_disp_z ? &adCoupledNeighborValue(
"disp_z") : nullptr),
93 _c(getParam<
Real>(
"c")),
94 _normalize_c(getParam<bool>(
"normalize_c")),
95 _nodal(getVar(
"disp_x", 0)->feType().family ==
LAGRANGE),
96 _disp_x_var(getVar(
"disp_x", 0)),
97 _disp_y_var(getVar(
"disp_y", 0)),
98 _disp_z_var(_has_disp_z ? getVar(
"disp_z", 0) : nullptr),
99 _capture_tolerance(getParam<
Real>(
"capture_tolerance")),
100 _secondary_x_dot(adCoupledDot(
"disp_x")),
101 _primary_x_dot(adCoupledNeighborValueDot(
"disp_x")),
102 _secondary_y_dot(adCoupledDot(
"disp_y")),
103 _primary_y_dot(adCoupledNeighborValueDot(
"disp_y")),
104 _secondary_z_dot(_has_disp_z ? &adCoupledDot(
"disp_z") : nullptr),
105 _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot(
"disp_z") : nullptr),
106 _has_wear(isParamValid(
"wear_depth")),
107 _wear_depth(_has_wear ? coupledValueLower(
"wear_depth") : _zero),
108 _newmark_beta(getParam<
Real>(
"newmark_beta")),
109 _newmark_gamma(getParam<
Real>(
"newmark_gamma"))
112 mooseError(
"Dynamic mortar contact constraints requires the use of Lagrange multipliers dual " 122 const auto & secondary_ip_lowerd_map =
126 std::array<ADReal, 3> primary_disp{
135 const ADReal & prim_x = primary_disp[0];
136 const ADReal & prim_y = primary_disp[1];
137 const ADReal * prim_z =
nullptr;
139 prim_z = &primary_disp[2];
141 const ADReal & sec_x = secondary_disp[0];
142 const ADReal & sec_y = secondary_disp[1];
143 const ADReal * sec_z =
nullptr;
145 sec_z = &secondary_disp[2];
147 std::array<ADReal, 3> primary_disp_dot{
149 std::array<ADReal, 3> secondary_disp_dot{
155 const ADReal & prim_x_dot = primary_disp_dot[0];
156 const ADReal & prim_y_dot = primary_disp_dot[1];
157 const ADReal * prim_z_dot =
nullptr;
159 prim_z_dot = &primary_disp_dot[2];
161 const ADReal & sec_x_dot = secondary_disp_dot[0];
162 const ADReal & sec_y_dot = secondary_disp_dot[1];
163 const ADReal * sec_z_dot =
nullptr;
165 sec_z_dot = &secondary_disp_dot[2];
169 gap_vec(0).derivatives() = prim_x.derivatives() - sec_x.derivatives();
170 gap_vec(1).derivatives() = prim_y.derivatives() - sec_y.derivatives();
176 gap_vec(2).derivatives() = prim_z->derivatives() - sec_z->derivatives();
195 "We should never call computeQpResidual for ComputeDynamicWeightedGapLMMechanicalContact");
202 "Making sure that _normals is the expected size");
228 mooseError(
"This object does not support recovering");
300 const std::unordered_set<const Node *> & inactive_lm_nodes)
310 if ((inactive_lm_nodes.find(static_cast<const Node *>(pr.first)) != inactive_lm_nodes.end()) ||
348 using Datum = std::pair<dof_id_type, ADReal>;
349 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
353 const auto *
const dof_object = pr.first;
354 const auto proc_id = dof_object->processor_id();
358 push_data[proc_id].push_back(std::make_pair(dof_object->id(), std::move(pr.second)));
363 auto action_functor = [
this, &lm_mesh](
const processor_id_type libmesh_dbg_var(pid),
364 const std::vector<Datum> & sent_data)
366 mooseAssert(pid != this->
processor_id(),
"We do not send messages to ourself here");
367 for (
auto & pr : sent_data)
369 const auto dof_id = pr.first;
370 const auto *
const dof_object =
371 _nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
372 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
373 mooseAssert(dof_object,
"This should be non-null");
391 const ADReal dof_residual = std::min(lm_value, weighted_gap *
c);
394 std::array<ADReal, 1>{{dof_residual}},
395 std::array<dof_id_type, 1>{{dof_index}},
405 mooseAssert(
_var,
"LM variable is null");
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)
unsigned int number() const
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
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
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
uint8_t processor_id_type
Elem const *const & _lower_secondary_elem
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
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
bool isNodal() const override
MooseVariable *const _var
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
bool isRecovering() const
void scalingFactor(const std::vector< Real > &factor)