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 : #include "WeightedVelocitiesUserObject.h" 11 : #include "MooseVariableField.h" 12 : #include "SubProblem.h" 13 : #include "SystemBase.h" 14 : #include "MortarUtils.h" 15 : #include "MooseUtils.h" 16 : #include "MortarContactUtils.h" 17 : #include "libmesh/quadrature.h" 18 : 19 : InputParameters 20 1078 : WeightedVelocitiesUserObject::validParams() 21 : { 22 1078 : InputParameters params = WeightedGapUserObject::validParams(); 23 2156 : params.addRequiredParam<VariableName>("secondary_variable", 24 : "Primal variable on secondary surface."); 25 2156 : params.addParam<VariableName>( 26 : "primary_variable", 27 : "Primal variable on primary surface. If this parameter is not provided then the primary " 28 : "variable will be initialized to the secondary variable"); 29 1078 : return params; 30 0 : } 31 : 32 539 : WeightedVelocitiesUserObject::WeightedVelocitiesUserObject(const InputParameters & parameters) 33 : : WeightedGapUserObject(parameters), 34 1078 : _sys(*getCheckedPointerParam<SystemBase *>("_sys")), 35 539 : _secondary_var( 36 539 : isParamValid("secondary_variable") 37 1617 : ? _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("secondary_variable")) 38 539 : : _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("primary_variable"))), 39 539 : _primary_var( 40 539 : isParamValid("primary_variable") 41 539 : ? _sys.getActualFieldVariable<Real>(_tid, parameters.getMooseType("primary_variable")) 42 : : _secondary_var), 43 539 : _secondary_x_dot(_secondary_var.adUDot()), 44 539 : _primary_x_dot(_primary_var.adUDotNeighbor()), 45 539 : _secondary_y_dot(adCoupledDot("disp_y")), 46 539 : _primary_y_dot(adCoupledNeighborValueDot("disp_y")), 47 539 : _secondary_z_dot(_has_disp_z ? &adCoupledDot("disp_z") : nullptr), 48 539 : _primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot("disp_z") : nullptr), 49 539 : _3d(_has_disp_z) 50 : { 51 1078 : if (!getParam<bool>("use_displaced_mesh")) 52 0 : paramError("use_displaced_mesh", 53 : "'use_displaced_mesh' must be true for the WeightedVelocitiesUserObject object"); 54 539 : } 55 : 56 : void 57 2846662 : WeightedVelocitiesUserObject::computeQpProperties() 58 : { 59 : // Compute the value of _qp_gap 60 2846662 : WeightedGapUserObject::computeQpProperties(); 61 : 62 : // Trim derivatives 63 2846662 : const auto & primary_ip_lowerd_map = amg().getPrimaryIpToLowerElementMap( 64 2846662 : *_lower_primary_elem, *_lower_primary_elem->interior_parent(), *_lower_secondary_elem); 65 : const auto & secondary_ip_lowerd_map = 66 2846662 : amg().getSecondaryIpToLowerElementMap(*_lower_secondary_elem); 67 : 68 2846662 : std::array<const MooseVariable *, 3> var_array{{_disp_x_var, _disp_y_var, _disp_z_var}}; 69 : std::array<ADReal, 3> primary_disp_dot{ 70 2846662 : {_primary_x_dot[_qp], _primary_y_dot[_qp], _has_disp_z ? (*_primary_z_dot)[_qp] : 0}}; 71 : std::array<ADReal, 3> secondary_disp_dot{ 72 2846662 : {_secondary_x_dot[_qp], _secondary_y_dot[_qp], _has_disp_z ? (*_secondary_z_dot)[_qp] : 0}}; 73 : 74 2846662 : trimInteriorNodeDerivatives(primary_ip_lowerd_map, var_array, primary_disp_dot, false); 75 2846662 : trimInteriorNodeDerivatives(secondary_ip_lowerd_map, var_array, secondary_disp_dot, true); 76 : 77 : const ADReal & prim_x_dot = primary_disp_dot[0]; 78 : const ADReal & prim_y_dot = primary_disp_dot[1]; 79 : const ADReal * prim_z_dot = nullptr; 80 2846662 : if (_has_disp_z) 81 : prim_z_dot = &primary_disp_dot[2]; 82 : 83 : const ADReal & sec_x_dot = secondary_disp_dot[0]; 84 : const ADReal & sec_y_dot = secondary_disp_dot[1]; 85 : const ADReal * sec_z_dot = nullptr; 86 2846662 : if (_has_disp_z) 87 : sec_z_dot = &secondary_disp_dot[2]; 88 : 89 : // Build relative velocity vector 90 : ADRealVectorValue relative_velocity; 91 : 92 2846662 : if (_3d) 93 1973696 : relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, *sec_z_dot - *prim_z_dot}; 94 : else 95 1745932 : relative_velocity = {sec_x_dot - prim_x_dot, sec_y_dot - prim_y_dot, 0.0}; 96 : 97 : // Geometry is averaged and used at the nodes for constraint enforcement. 98 : _qp_real_tangential_velocity_nodal = relative_velocity; 99 8539986 : _qp_tangential_velocity_nodal = relative_velocity * (_JxW_msm[_qp] * _coord[_qp]); 100 2846662 : } 101 : 102 : void 103 9640716 : WeightedVelocitiesUserObject::computeQpIProperties() 104 : { 105 9640716 : WeightedGapUserObject::computeQpIProperties(); 106 : 107 9640716 : const auto & nodal_tangents = amg().getNodalTangents(*_lower_secondary_elem); 108 : // Get the _dof_to_weighted_tangential_velocity map 109 : const DofObject * const dof = 110 9640716 : _is_weighted_gap_nodal ? static_cast<const DofObject *>(_lower_secondary_elem->node_ptr(_i)) 111 0 : : static_cast<const DofObject *>(_lower_secondary_elem); 112 : 113 : _dof_to_weighted_tangential_velocity[dof][0] += 114 19281432 : (*_test)[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[0][_i]; 115 : _dof_to_real_tangential_velocity[dof][0] += 116 19281432 : (*_test)[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[0][_i]; 117 : 118 : // Get the _dof_to_weighted_tangential_velocity map for a second direction 119 9640716 : if (_3d) 120 : { 121 : _dof_to_weighted_tangential_velocity[dof][1] += 122 15789568 : (*_test)[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[1][_i]; 123 : 124 : _dof_to_real_tangential_velocity[dof][1] += 125 15789568 : (*_test)[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[1][_i]; 126 : } 127 9640716 : } 128 : 129 : void 130 100987 : WeightedVelocitiesUserObject::selfInitialize() 131 : { 132 : _dof_to_weighted_tangential_velocity.clear(); 133 : _dof_to_real_tangential_velocity.clear(); 134 100987 : } 135 : 136 : void 137 84574 : WeightedVelocitiesUserObject::initialize() 138 : { 139 : // Clear weighted gaps 140 84574 : WeightedGapUserObject::initialize(); 141 84574 : selfInitialize(); 142 84574 : } 143 : 144 : void 145 100987 : WeightedVelocitiesUserObject::finalize() 146 : { 147 100987 : WeightedGapUserObject::finalize(); 148 : 149 : // If the constraint is performed by the owner, then we don't need any data sent back; the owner 150 : // will take care of it. But if the constraint is not performed by the owner and we might have to 151 : // do some of the constraining ourselves, then we need data sent back to us 152 100987 : const bool send_data_back = !constrainedByOwner(); 153 : 154 100987 : Moose::Mortar::Contact::communicateVelocities(_dof_to_weighted_tangential_velocity, 155 100987 : _subproblem.mesh(), 156 100987 : _nodal, 157 : _communicator, 158 : send_data_back); 159 201974 : Moose::Mortar::Contact::communicateVelocities( 160 100987 : _dof_to_real_tangential_velocity, _subproblem.mesh(), _nodal, _communicator, send_data_back); 161 100987 : }