Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MortarUserObject.h" 13 : 14 : /** 15 : * Creates dof object to weighted gap map 16 : */ 17 : class WeightedGapUserObject : public MortarUserObject 18 : { 19 : public: 20 : static InputParameters validParams(); 21 : 22 : WeightedGapUserObject(const InputParameters & parameters); 23 : 24 : virtual void initialize() override; 25 : virtual void execute() override; 26 : virtual void finalize() override; 27 : virtual void initialSetup() override; 28 : 29 : /** 30 : * Get the degree of freedom to weighted gap information 31 : */ 32 : const std::unordered_map<const DofObject *, std::pair<ADReal, Real>> & dofToWeightedGap() const; 33 : 34 : /** 35 : * @return The contact force at quadrature points on the mortar segment 36 : */ 37 : virtual const ADVariableValue & contactPressure() const = 0; 38 : 39 : /** 40 : * @param node Node pointer 41 : * @return The normal contact pressure at the node 42 : */ 43 : virtual Real getNormalContactPressure(const Node * const /*node*/) const = 0; 44 : 45 : /** 46 : * @param node Node pointer 47 : * @return The normal gap at the node 48 : */ 49 : virtual Real getNormalGap(const Node * const /*node*/) const; 50 : 51 : /// Whether this user object includes derivatives of the secondary nodal normals 52 : bool usesNodalNormalDerivatives() const; 53 : 54 : /// Enable derivatives during construction of a supported quasistatic contact constraint. 55 : /// Dynamic contact uses the same user object classes and intentionally leaves this disabled. 56 : void includeNodalNormalDerivatives() const; 57 : 58 : /** 59 : * Return the cached contact normal for the supplied lower-dimensional secondary element node. 60 : * The raw value is the stored normalized secondary nodal normal. Coordinate derivatives are 61 : * included while this object's formulation and the current assembly mode require them. 62 : */ 63 : const ADRealVectorValue & contactNormal(const Elem & lower_secondary_elem, 64 : unsigned int nodal_index) const; 65 : 66 : /** 67 : * Compute physical gap from integration gap quantity 68 : */ 69 : Real physicalGap(const std::pair<ADReal, Real> & gap) const 70 : { 71 24586 : return MetaPhysicL::raw_value(gap.first) / gap.second; 72 : } 73 : 74 88864 : ADReal adPhysicalGap(const std::pair<ADReal, Real> & gap) const { return gap.first / gap.second; } 75 : 76 : /** 77 : * @param node Node pointer 78 : * @param component Component of the frictional pressure vector 79 : * @return The frictional contact pressure at the node 80 : */ 81 0 : virtual Real getFrictionalContactPressure(const Node * const /*node*/, 82 : const unsigned int /*component*/) const 83 : { 84 0 : mooseError("Not available in base class."); 85 : } 86 : 87 : /** 88 : * @param node Node pointer 89 : * @param component Component of the local slip vector 90 : * @return The accumulated slip at the node 91 : */ 92 0 : virtual Real getAccumulatedSlip(const Node * const /*node*/, 93 : const unsigned int /*component*/) const 94 : { 95 0 : mooseError("Not available in base class."); 96 : } 97 : 98 : /** 99 : * @param node Node pointer 100 : * @param component Component of the local slip vector 101 : * @return The tangential velocity at the node with local components 102 : */ 103 0 : virtual Real getTangentialVelocity(const Node * const /*node*/, 104 : const unsigned int /*component*/) const 105 : { 106 0 : mooseError("Not available in base class."); 107 : } 108 : 109 : protected: 110 : /** 111 : * Computes properties that are functions only of the current quadrature point (\p _qp), e.g. 112 : * indepedent of shape functions 113 : */ 114 : virtual void computeQpProperties(); 115 : 116 : /** 117 : * Computes properties that are functions both of \p _qp and \p _i, for example the weighted gap 118 : */ 119 : virtual void computeQpIProperties(); 120 : 121 : /** 122 : * @return The test function associated with the weighted gap 123 : */ 124 : virtual const VariableTestValue & test() const = 0; 125 : 126 : /** 127 : * @return Whether the gap constraint will be enforced solely by the owner of the weighted gap or 128 : * will be enforced in a distributed way (like in a penalty method) 129 : */ 130 : virtual bool constrainedByOwner() const = 0; 131 : 132 : /** 133 : * Find a value in a map or return a default if the key doesn't exist 134 : */ 135 : template <typename K, typename V> 136 : V 137 410110 : findValue(const std::unordered_map<K, V> & map, const K & key, const V & default_value = 0) const 138 : { 139 : const auto it = map.find(key); 140 410110 : if (it == map.end()) 141 367670 : return default_value; 142 42440 : return it->second; 143 : } 144 : 145 : /** 146 : * Add displacement derivatives to the coordinate used for the stored mortar nodal geometry. 147 : */ 148 : ADPoint nodalCoordinate(const Node & node, const Point & geometry_coordinate) const; 149 : 150 : /// The base finite element problem 151 : FEProblemBase & _fe_problem; 152 : 153 : /// The value of the gap at the current quadrature point 154 : ADReal _qp_gap; 155 : 156 : /// The value of the LM at the current quadrature point 157 : Real _qp_factor; 158 : 159 : /// Whether the dof objects are nodal; if they're not, then they're elemental 160 : const bool _nodal; 161 : 162 : /// The x displacement variable 163 : const MooseVariable * const _disp_x_var; 164 : /// The y displacement variable 165 : const MooseVariable * const _disp_y_var; 166 : /// For 2D mortar contact no displacement will be specified, so const pointers used 167 : const bool _has_disp_z; 168 : /// The z displacement variable 169 : const MooseVariable * const _disp_z_var; 170 : 171 : /// x-displacement on the secondary face 172 : const ADVariableValue & _secondary_disp_x; 173 : /// x-displacement on the primary face 174 : const ADVariableValue & _primary_disp_x; 175 : /// y-displacement on the secondary face 176 : const ADVariableValue & _secondary_disp_y; 177 : /// y-displacement on the primary face 178 : const ADVariableValue & _primary_disp_y; 179 : /// z-displacement on the secondary face 180 : const ADVariableValue * const _secondary_disp_z; 181 : /// z-displacement on the primary face 182 : const ADVariableValue * const _primary_disp_z; 183 : 184 : /// Member for handling change of coordinate systems (xyz, rz, spherical) 185 : const MooseArray<Real> & _coord; 186 : 187 : /// Vector for computation of weighted gap with nodal normals 188 : ADRealVectorValue _qp_gap_nodal; 189 : 190 : /// Vector for computation of relative displacement (determines mixity ratio in interface problems) 191 : ADRealVectorValue _qp_displacement_nodal; 192 : 193 : /// A map from node to weighted gap and normalization (if requested) 194 : std::unordered_map<const DofObject *, std::pair<ADReal, Real>> _dof_to_weighted_gap; 195 : 196 : /// A map from node to weighted displacements 197 : std::unordered_map<const DofObject *, ADRealVectorValue> _dof_to_weighted_displacements; 198 : 199 : /// A pointer members that can be used to help avoid copying ADReals 200 : const ADReal * _weighted_gap_ptr = nullptr; 201 : const Real * _normalization_ptr = nullptr; 202 : 203 : /// A pointer to the test function associated with the weighted gap. We have this member so that 204 : /// we don't do virtual calls during inner quadrature-point/test-function loops 205 : const VariableTestValue * _test = nullptr; 206 : 207 : /// AD nodal normals computed from the secondary face one-ring 208 : mutable std::unordered_map<const Node *, ADRealVectorValue> _ad_nodal_normals; 209 : 210 : /// Whether this concrete user object supports nodal-normal derivatives 211 : const bool _allow_nodal_normal_derivatives; 212 : 213 : /// Set once while supported contact constraints are constructed, before user object execution 214 : mutable bool _use_nodal_normal_derivatives; 215 : 216 : /// Whether the weighted gap is associated with nodes or elements (like for a CONSTANT MONOMIAL 217 : /// Lagrange multiplier). We have this member so that we don't do virtual calls during inner 218 : /// quadrature-point/test-function loops 219 : bool _is_weighted_gap_nodal = true; 220 : 221 : /// Quadrature point index for the mortar segments 222 : unsigned int _qp = 0; 223 : 224 : /// Test function index 225 : unsigned int _i = 0; 226 : }; 227 : 228 : inline const std::unordered_map<const DofObject *, std::pair<ADReal, Real>> & 229 : WeightedGapUserObject::dofToWeightedGap() const 230 : { 231 18533 : return _dof_to_weighted_gap; 232 : }