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