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