15 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 16 #include "metaphysicl/parallel_dualnumber.h" 17 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 18 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 29 const auto & disp_x_name = ret.
get<std::vector<VariableName>>(
"disp_x");
30 if (disp_x_name.size() != 1)
31 mooseError(
"We require that the disp_x parameter have exactly one coupled name");
34 ret.
set<VariableName>(
"secondary_variable") = disp_x_name[0];
35 ret.
set<VariableName>(
"primary_variable") = disp_x_name[0];
45 "Computes the normal contact mortar constraints for dynamic simulations");
48 "capture_tolerance>=0",
49 "Parameter describing a gap threshold for the application of " 50 "the persistency constraint in dynamic simulations.");
52 "The name of the mortar auxiliary variable that is used to modify the " 53 "weighted gap definition");
55 "newmark_beta",
"newmark_beta > 0",
"Beta parameter for the Newmark time integrator");
57 "newmark_gamma",
"newmark_gamma >= 0.0",
"Gamma parameter for the Newmark time integrator");
62 params.
addCoupledVar(
"disp_z",
"The z displacement variable");
64 "c", 1e6,
"Parameter for balancing the size of the gap and contact pressure");
68 "Whether to normalize c by weighting function norm. When unnormalized " 69 "the value of c effectively depends on element size since in the constraint we compare nodal " 70 "Lagrange Multiplier values to integrated gap values (LM nodal value is independent of " 71 "element size, where integrated values are dependent on element size).");
72 params.
set<
bool>(
"use_displaced_mesh") =
true;
73 params.
set<
bool>(
"interpolate_normals") =
false;
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),
93 _capture_tolerance(getParam<
Real>(
"capture_tolerance")),
94 _secondary_x_dot(adCoupledDot(
"disp_x")),
95 _primary_x_dot(adCoupledNeighborValueDot(
"disp_x")),
96 _secondary_y_dot(adCoupledDot(
"disp_y")),
97 _primary_y_dot(adCoupledNeighborValueDot(
"disp_y")),
98 _secondary_z_dot(_has_disp_z ? &adCoupledDot(
"disp_z") : nullptr),
99 _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot(
"disp_z") : nullptr),
100 _has_wear(isParamValid(
"wear_depth")),
101 _wear_depth(_has_wear ? coupledValueLower(
"wear_depth") : _zero),
102 _newmark_beta(getParam<
Real>(
"newmark_beta")),
103 _newmark_gamma(getParam<
Real>(
"newmark_gamma"))
106 mooseError(
"Dynamic mortar contact constraints requires the use of Lagrange multipliers dual " 116 const auto & secondary_ip_lowerd_map =
120 std::array<ADReal, 3> primary_disp{
129 const ADReal & prim_x = primary_disp[0];
130 const ADReal & prim_y = primary_disp[1];
131 const ADReal * prim_z =
nullptr;
133 prim_z = &primary_disp[2];
135 const ADReal & sec_x = secondary_disp[0];
136 const ADReal & sec_y = secondary_disp[1];
137 const ADReal * sec_z =
nullptr;
139 sec_z = &secondary_disp[2];
141 std::array<ADReal, 3> primary_disp_dot{
143 std::array<ADReal, 3> secondary_disp_dot{
149 const ADReal & prim_x_dot = primary_disp_dot[0];
150 const ADReal & prim_y_dot = primary_disp_dot[1];
151 const ADReal * prim_z_dot =
nullptr;
153 prim_z_dot = &primary_disp_dot[2];
155 const ADReal & sec_x_dot = secondary_disp_dot[0];
156 const ADReal & sec_y_dot = secondary_disp_dot[1];
157 const ADReal * sec_z_dot =
nullptr;
159 sec_z_dot = &secondary_disp_dot[2];
163 gap_vec(0).derivatives() = prim_x.derivatives() - sec_x.derivatives();
164 gap_vec(1).derivatives() = prim_y.derivatives() - sec_y.derivatives();
170 gap_vec(2).derivatives() = prim_z->derivatives() - sec_z->derivatives();
189 "We should never call computeQpResidual for ComputeDynamicWeightedGapLMMechanicalContact");
196 "Making sure that _normals is the expected size");
222 mooseError(
"This object does not support recovering");
294 const std::unordered_set<const Node *> & inactive_lm_nodes)
304 if ((inactive_lm_nodes.find(static_cast<const Node *>(pr.first)) != inactive_lm_nodes.end()) ||
342 using Datum = std::pair<dof_id_type, ADReal>;
343 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
347 const auto *
const dof_object = pr.first;
348 const auto proc_id = dof_object->processor_id();
352 push_data[proc_id].push_back(std::make_pair(dof_object->id(), std::move(pr.second)));
357 auto action_functor = [
this, &lm_mesh](
const processor_id_type libmesh_dbg_var(pid),
358 const std::vector<Datum> & sent_data)
360 mooseAssert(pid != this->
processor_id(),
"We do not send messages to ourself here");
361 for (
auto & pr : sent_data)
363 const auto dof_id = pr.first;
364 const auto *
const dof_object =
365 _nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
366 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
367 mooseAssert(dof_object,
"This should be non-null");
385 const ADReal dof_residual = std::min(lm_value, weighted_gap *
c);
388 std::array<ADReal, 1>{{dof_residual}},
389 std::array<dof_id_type, 1>{{dof_index}},
399 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)