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 : // MOOSE includes 11 : #include "PenetrationAux.h" 12 : #include "PenetrationLocator.h" 13 : #include "DisplacedProblem.h" 14 : #include "MooseEnum.h" 15 : #include "MooseMesh.h" 16 : 17 : #include "libmesh/string_to_enum.h" 18 : 19 : registerMooseObject("MooseApp", PenetrationAux); 20 : 21 : InputParameters 22 38140 : PenetrationAux::validParams() 23 : { 24 38140 : MooseEnum orders("FIRST SECOND THIRD FOURTH", "FIRST"); 25 : 26 38140 : InputParameters params = AuxKernel::validParams(); 27 38140 : params.addClassDescription("Auxiliary Kernel for computing several geometry related quantities " 28 : "between two contacting bodies."); 29 : 30 38140 : params.addRequiredParam<BoundaryName>("paired_boundary", "The boundary to be penetrated"); 31 38140 : params.addParam<Real>("tangential_tolerance", 32 : "Tangential distance to extend edges of contact surfaces"); 33 38140 : params.addParam<Real>( 34 : "normal_smoothing_distance", 35 : "Distance from edge in parametric coordinates over which to smooth contact normal"); 36 38140 : params.addParam<std::string>("normal_smoothing_method", 37 : "Method to use to smooth normals (edge_based|nodal_normal_based)"); 38 38140 : params.addParam<MooseEnum>("order", orders, "The finite element order"); 39 38140 : params.addCoupledVar("secondary_gap_offset", "offset to the gap distance from secondary side"); 40 38140 : params.addCoupledVar("mapped_primary_gap_offset", 41 : "offset to the gap distance mapped from primary side"); 42 : 43 38140 : params.set<bool>("use_displaced_mesh") = true; 44 : 45 : // To avoid creating a conversion routine we will list the enumeration options in the same order 46 : // as the class-based enum. 47 : // Care must be taken to ensure that this list stays in sync with the enum in the .h file. 48 : MooseEnum quantity( 49 : "distance tangential_distance normal_x normal_y normal_z closest_point_x closest_point_y " 50 : "closest_point_z element_id side incremental_slip_magnitude incremental_slip_x " 51 : "incremental_slip_y incremental_slip_z accumulated_slip force_x force_y force_z " 52 : "normal_force_magnitude normal_force_x normal_force_y normal_force_z " 53 : "tangential_force_magnitude " 54 : "tangential_force_x tangential_force_y tangential_force_z frictional_energy " 55 : "lagrange_multiplier " 56 : "mechanical_status", 57 38140 : "distance"); 58 : 59 38140 : params.addParam<MooseEnum>( 60 : "quantity", quantity, "The quantity to recover from the available penetration information"); 61 76280 : return params; 62 38140 : } 63 : 64 12420 : PenetrationAux::PenetrationAux(const InputParameters & parameters) 65 : : AuxKernel(parameters), 66 : 67 : // Here we cast the value of the MOOSE enum to an integer to the class-based enum. 68 12420 : _quantity(getParam<MooseEnum>("quantity").getEnum<PenetrationAux::PA_ENUM>()), 69 12420 : _penetration_locator( 70 49569 : _nodal ? getPenetrationLocator( 71 962 : parameters.get<BoundaryName>("paired_boundary"), 72 12383 : boundaryNames()[0], 73 12383 : Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order"))) 74 12457 : : getQuadraturePenetrationLocator( 75 3 : parameters.get<BoundaryName>("paired_boundary"), 76 37 : boundaryNames()[0], 77 12457 : Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")))), 78 12420 : _has_secondary_gap_offset(isCoupled("secondary_gap_offset")), 79 12420 : _secondary_gap_offset_var(_has_secondary_gap_offset ? getVar("secondary_gap_offset", 0) 80 : : nullptr), 81 12420 : _has_mapped_primary_gap_offset(isCoupled("mapped_primary_gap_offset")), 82 12420 : _mapped_primary_gap_offset_var( 83 24840 : _has_mapped_primary_gap_offset ? getVar("mapped_primary_gap_offset", 0) : nullptr) 84 : { 85 12420 : if (parameters.isParamValid("tangential_tolerance")) 86 512 : _penetration_locator.setTangentialTolerance(getParam<Real>("tangential_tolerance")); 87 : 88 12420 : if (parameters.isParamValid("normal_smoothing_distance")) 89 304 : _penetration_locator.setNormalSmoothingDistance(getParam<Real>("normal_smoothing_distance")); 90 : 91 12420 : if (parameters.isParamValid("normal_smoothing_method")) 92 104 : _penetration_locator.setNormalSmoothingMethod( 93 8 : parameters.get<std::string>("normal_smoothing_method")); 94 12420 : } 95 : 96 : Real 97 8124902 : PenetrationAux::computeValue() 98 : { 99 8124902 : const Node * current_node = nullptr; 100 : 101 8124902 : if (_nodal) 102 8116882 : current_node = _current_node; 103 : else 104 8020 : current_node = _mesh.getQuadratureNode(_current_elem, _current_side, _qp); 105 : 106 8124902 : PenetrationInfo * pinfo = _penetration_locator._penetration_info[current_node->id()]; 107 : 108 : // A node that doesn't project has zero force, closest point (i.e. not computed), slip, and its 109 : // mechanical status is not in contact. 110 8124902 : Real retVal(0); 111 : 112 8124902 : if (pinfo) 113 4175219 : switch (_quantity) 114 : { 115 481141 : case PA_DISTANCE: 116 481141 : retVal = 117 962282 : pinfo->_distance - 118 481141 : (_has_secondary_gap_offset ? _secondary_gap_offset_var->getNodalValue(*current_node) 119 : : 0) - 120 481141 : (_has_mapped_primary_gap_offset 121 481141 : ? _mapped_primary_gap_offset_var->getNodalValue(*current_node) 122 : : 0); 123 481141 : break; 124 452917 : case PA_TANG_DISTANCE: 125 452917 : retVal = pinfo->_tangential_distance; 126 452917 : break; 127 452826 : case PA_NORMAL_X: 128 452826 : retVal = pinfo->_normal(0); 129 452826 : break; 130 452826 : case PA_NORMAL_Y: 131 452826 : retVal = pinfo->_normal(1); 132 452826 : break; 133 380904 : case PA_NORMAL_Z: 134 380904 : retVal = pinfo->_normal(2); 135 380904 : break; 136 452917 : case PA_CLOSEST_POINT_X: 137 452917 : retVal = pinfo->_closest_point(0); 138 452917 : break; 139 452917 : case PA_CLOSEST_POINT_Y: 140 452917 : retVal = pinfo->_closest_point(1); 141 452917 : break; 142 380995 : case PA_CLOSEST_POINT_Z: 143 380995 : retVal = pinfo->_closest_point(2); 144 380995 : break; 145 214950 : case PA_ELEM_ID: 146 214950 : retVal = static_cast<Real>(pinfo->_elem->id() + 1); 147 214950 : break; 148 452826 : case PA_SIDE: 149 452826 : retVal = static_cast<Real>(pinfo->_side_num); 150 452826 : break; 151 0 : case PA_INCREMENTAL_SLIP_MAG: 152 0 : retVal = pinfo->isCaptured() ? pinfo->_incremental_slip.norm() : 0; 153 0 : break; 154 0 : case PA_INCREMENTAL_SLIP_X: 155 0 : retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(0) : 0; 156 0 : break; 157 0 : case PA_INCREMENTAL_SLIP_Y: 158 0 : retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(1) : 0; 159 0 : break; 160 0 : case PA_INCREMENTAL_SLIP_Z: 161 0 : retVal = pinfo->isCaptured() ? pinfo->_incremental_slip(2) : 0; 162 0 : break; 163 0 : case PA_ACCUMULATED_SLIP: 164 0 : retVal = pinfo->_accumulated_slip; 165 0 : break; 166 0 : case PA_FORCE_X: 167 0 : retVal = pinfo->_contact_force(0); 168 0 : break; 169 0 : case PA_FORCE_Y: 170 0 : retVal = pinfo->_contact_force(1); 171 0 : break; 172 0 : case PA_FORCE_Z: 173 0 : retVal = pinfo->_contact_force(2); 174 0 : break; 175 0 : case PA_NORMAL_FORCE_MAG: 176 0 : retVal = -pinfo->_contact_force * pinfo->_normal; 177 0 : break; 178 0 : case PA_NORMAL_FORCE_X: 179 0 : retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(0); 180 0 : break; 181 0 : case PA_NORMAL_FORCE_Y: 182 0 : retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(1); 183 0 : break; 184 0 : case PA_NORMAL_FORCE_Z: 185 0 : retVal = (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(2); 186 0 : break; 187 0 : case PA_TANGENTIAL_FORCE_MAG: 188 : { 189 0 : RealVectorValue contact_force_normal((pinfo->_contact_force * pinfo->_normal) * 190 0 : pinfo->_normal); 191 0 : RealVectorValue contact_force_tangential(pinfo->_contact_force - contact_force_normal); 192 0 : retVal = contact_force_tangential.norm(); 193 0 : break; 194 : } 195 0 : case PA_TANGENTIAL_FORCE_X: 196 0 : retVal = 197 0 : pinfo->_contact_force(0) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(0); 198 0 : break; 199 0 : case PA_TANGENTIAL_FORCE_Y: 200 0 : retVal = 201 0 : pinfo->_contact_force(1) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(1); 202 0 : break; 203 0 : case PA_TANGENTIAL_FORCE_Z: 204 0 : retVal = 205 0 : pinfo->_contact_force(2) - (pinfo->_contact_force * pinfo->_normal) * pinfo->_normal(2); 206 0 : break; 207 0 : case PA_FRICTIONAL_ENERGY: 208 0 : retVal = pinfo->_frictional_energy; 209 0 : break; 210 0 : case PA_LAGRANGE_MULTIPLIER: 211 0 : retVal = pinfo->_lagrange_multiplier; 212 0 : break; 213 0 : case PA_MECH_STATUS: 214 0 : retVal = pinfo->_mech_status; 215 0 : break; 216 0 : default: 217 0 : mooseError("Unknown penetration info quantity in auxiliary kernel."); 218 : } // switch 219 : 220 8124902 : return retVal; 221 : }