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 "LMWeightedGapUserObject.h" 11 : #include "MooseVariableFE.h" 12 : #include "SystemBase.h" 13 : 14 : registerMooseObject("ContactApp", LMWeightedGapUserObject); 15 : 16 : InputParameters 17 1308 : LMWeightedGapUserObject::newParams() 18 : { 19 1308 : auto params = emptyInputParameters(); 20 2616 : params.addRequiredCoupledVar( 21 : "lm_variable", "The Lagrange multiplier variable representing the contact pressure."); 22 2616 : params.addParam<bool>( 23 2616 : "use_petrov_galerkin", false, "Whether to use the Petrov-Galerkin approach."); 24 2616 : params.addCoupledVar("aux_lm", 25 : "Auxiliary Lagrange multiplier variable that is utilized together with the " 26 : "Petrov-Galerkin approach."); 27 1308 : return params; 28 0 : } 29 : 30 : InputParameters 31 830 : LMWeightedGapUserObject::validParams() 32 : { 33 830 : InputParameters params = WeightedGapUserObject::validParams(); 34 830 : params.addClassDescription( 35 : "Provides the mortar normal Lagrange multiplier for constraint enforcement."); 36 830 : params.set<bool>("allow_nodal_normal_derivatives") = true; 37 830 : params += LMWeightedGapUserObject::newParams(); 38 830 : return params; 39 0 : } 40 : 41 656 : LMWeightedGapUserObject::LMWeightedGapUserObject(const InputParameters & parameters) 42 : : WeightedGapUserObject(parameters), 43 652 : _lm_var(getVar("lm_variable", 0)), 44 1304 : _use_petrov_galerkin(getParam<bool>("use_petrov_galerkin")), 45 1350 : _aux_lm_var(isCoupled("aux_lm") ? getVar("aux_lm", 0) : nullptr) 46 : { 47 652 : checkInput(_lm_var, "lm_variable"); 48 652 : verifyLagrange(*_lm_var, "lm_variable"); 49 : 50 736 : if (_use_petrov_galerkin && ((!isParamValid("aux_lm")) || _aux_lm_var == nullptr)) 51 0 : paramError("use_petrov_galerkin", 52 : "We need to specify an auxiliary variable `aux_lm` while using the Petrov-Galerkin " 53 : "approach"); 54 : 55 652 : if (_use_petrov_galerkin && _aux_lm_var->useDual()) 56 0 : paramError("aux_lm", 57 : "Auxiliary LM variable needs to use standard shape function, i.e., set `use_dual = " 58 : "false`."); 59 652 : } 60 : 61 : void 62 964 : LMWeightedGapUserObject::checkInput(const MooseVariable * const var, 63 : const std::string & var_param_name) const 64 : { 65 964 : if (isCoupledConstant(var_param_name)) 66 0 : paramError(var_param_name, 67 : "The Lagrange multiplier variable must be an actual variable and not a constant."); 68 964 : else if (!var) 69 0 : paramError(var_param_name, 70 : "The Lagrange multiplier variables must be provided and be actual variables."); 71 964 : } 72 : 73 : void 74 964 : LMWeightedGapUserObject::verifyLagrange(const MooseVariable & var, 75 : const std::string & var_param_name) const 76 : { 77 964 : if (var.feType().family != LAGRANGE) 78 0 : paramError(var_param_name, "The Lagrange multiplier variables must be of Lagrange type"); 79 964 : } 80 : 81 : const VariableTestValue & 82 629 : LMWeightedGapUserObject::test() const 83 : { 84 629 : return _use_petrov_galerkin ? _aux_lm_var->phiLower() : _lm_var->phiLower(); 85 : } 86 : 87 : const ADVariableValue & 88 203356868 : LMWeightedGapUserObject::contactPressure() const 89 : { 90 203356868 : return _lm_var->adSlnLower(); 91 : } 92 : 93 : Real 94 11269 : LMWeightedGapUserObject::getNormalContactPressure(const Node * const node) const 95 : { 96 11269 : const auto sys_num = _lm_var->sys().number(); 97 11269 : const auto var_num = _lm_var->number(); 98 11269 : if (!node->n_dofs(sys_num, var_num)) 99 0 : mooseError("No degrees of freedom for the Lagrange multiplier at the node. If this is being " 100 : "called from an aux kernel make sure that your aux variable has the same order as " 101 : "your Lagrange multiplier"); 102 : 103 11269 : const auto dof_number = node->dof_number(sys_num, var_num, /*component=*/0); 104 11269 : return (*_lm_var->sys().currentSolution())(dof_number); 105 : }