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 "BoundsBase.h" 11 : #include "SystemBase.h" 12 : #include "PetscSupport.h" 13 : #include "AuxiliarySystem.h" 14 : 15 : InputParameters 16 58176 : BoundsBase::validParams() 17 : { 18 58176 : InputParameters params = AuxKernel::validParams(); 19 58176 : MooseEnum type_options("upper=0 lower=1", "upper"); 20 58176 : params.addParam<MooseEnum>( 21 : "bound_type", 22 : type_options, 23 : "Type of bound. 'upper' refers to the upper bound. 'lower' refers to the lower value."); 24 58176 : params.addRequiredParam<NonlinearVariableName>("bounded_variable", "The variable to be bounded"); 25 58176 : params.registerBase("Bounds"); 26 116352 : return params; 27 58176 : } 28 : 29 572 : BoundsBase::BoundsBase(const InputParameters & parameters) 30 : : AuxKernel(parameters), 31 572 : _type((BoundType)(int)parameters.get<MooseEnum>("bound_type")), 32 1144 : _bounded_vector(_type == 0 ? _nl_sys.getVector("upper_bound") 33 572 : : _nl_sys.getVector("lower_bound")), 34 572 : _bounded_var(_nl_sys.getVariable(_tid, getParam<NonlinearVariableName>("bounded_variable"))), 35 572 : _bounded_var_name(parameters.get<NonlinearVariableName>("bounded_variable")), 36 572 : _fe_var(_bounded_var.isFV() ? nullptr 37 1092 : : &_subproblem.getStandardVariable(_tid, _bounded_var_name)) 38 : { 39 : // Check that the bounded variable is of a supported type 40 572 : if (!_bounded_var.isNodal() && (_bounded_var.feType().order != libMesh::CONSTANT)) 41 4 : paramError("bounded_variable", "Bounded variable must be nodal or of a CONSTANT order!"); 42 : 43 : const auto & dummy = 44 568 : _aux_sys.getActualFieldVariable<Real>(_tid, parameters.get<AuxVariableName>("variable")); 45 : 46 : // Check that the dummy variable matches the bounded variable 47 568 : if (dummy.feType() != _bounded_var.feType()) 48 4 : paramError("variable", 49 : "Dummy bounds aux variable and bounded variable must use the same finite element " 50 : "order and family"); 51 564 : } 52 : 53 : void 54 564 : BoundsBase::initialSetup() 55 : { 56 564 : if (!Moose::PetscSupport::isSNESVI(*dynamic_cast<FEProblemBase *>(&_c_fe_problem))) 57 44 : mooseDoOnce( 58 : mooseWarning("A variational inequalities solver must be used in conjunction with Bounds")); 59 564 : } 60 : 61 : Real 62 1207616 : BoundsBase::computeValue() 63 : { 64 1207616 : dof_id_type dof = getDoFIndex(); 65 : 66 1207616 : if (dof != std::numeric_limits<dof_id_type>::max()) 67 : { 68 1207616 : Real bound = getBound(); 69 1207616 : _bounded_vector.set(dof, bound); 70 : } 71 : 72 1207616 : return 0.0; 73 : } 74 : 75 : dof_id_type 76 1207616 : BoundsBase::getDoFIndex() const 77 : { 78 1207616 : if (isNodal()) 79 : { 80 1201816 : if (_current_node->n_dofs(_nl_sys.number(), _bounded_var.number()) > 0) 81 : { 82 : mooseAssert(_current_node->n_dofs(_nl_sys.number(), _bounded_var.number()) == 1, 83 : "Bounds are only set on one DOF value per node currently"); 84 : // The zero is for the component, this will only work for Lagrange variables 85 1201816 : return _current_node->dof_number(_nl_sys.number(), _bounded_var.number(), 0); 86 : } 87 : } 88 5800 : else if (_current_elem->n_dofs(_nl_sys.number(), _bounded_var.number()) > 0) 89 : { 90 : mooseAssert(_current_elem->n_dofs(_nl_sys.number(), _bounded_var.number()) == 1, 91 : "Bounds are only set on one DOF value per element currently"); 92 : // The zero is for the component, this will only work for CONSTANT variables 93 5800 : return _current_elem->dof_number(_nl_sys.number(), _bounded_var.number(), 0); 94 : } 95 : // No local dof for the bounded variable. This can happen for example if: 96 : // - block restriction of dummy is different from bounded variable 97 : // - we have a first order variable on a second order mesh 98 0 : return std::numeric_limits<dof_id_type>::max(); 99 : }