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 "LinearFVRZViscousSource.h" 11 : #include "FEProblemBase.h" 12 : #include "MooseLinearVariableFV.h" 13 : #include "NS.h" 14 : 15 : #include "libmesh/utility.h" 16 : 17 : registerMooseObject("NavierStokesApp", LinearFVRZViscousSource); 18 : 19 : InputParameters 20 108 : LinearFVRZViscousSource::validParams() 21 : { 22 108 : InputParameters params = LinearFVElementalKernel::validParams(); 23 108 : params.addClassDescription( 24 : "Adds the axisymmetric viscous source term mu * u_r / r^2 to the FV momentum equations."); 25 108 : params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity functor."); 26 216 : MooseEnum component("x=0 y=1 z=2"); 27 216 : params.addRequiredParam<MooseEnum>( 28 : "momentum_component", component, "Momentum component this kernel contributes to."); 29 216 : params.addParam<SolverVariableName>("u", "The velocity in the x direction."); 30 216 : params.addParam<SolverVariableName>("v", "The velocity in the y direction."); 31 216 : params.addParam<bool>( 32 : "use_deviatoric_terms", 33 216 : false, 34 : "Include the deviatoric correction (-2/3 div(u)) in the axisymmetric term."); 35 108 : return params; 36 108 : } 37 : 38 54 : LinearFVRZViscousSource::LinearFVRZViscousSource(const InputParameters & params) 39 : : LinearFVElementalKernel(params), 40 108 : _mu(getFunctor<Real>(NS::mu)), 41 108 : _component(getParam<MooseEnum>("momentum_component")), 42 54 : _rz_radial_coord(_subproblem.getAxisymmetricRadialCoord()), 43 54 : _dim(_subproblem.mesh().dimension()), 44 108 : _use_deviatoric_terms(getParam<bool>("use_deviatoric_terms")), 45 54 : _coord_type(getBlockCoordSystem()), 46 54 : _stress_multiplier(_use_deviatoric_terms ? 2.0 : 1.0), 47 54 : _velocity_vars{nullptr, nullptr} 48 : { 49 54 : if (_coord_type != Moose::CoordinateSystemType::COORD_RZ) 50 0 : paramError("block", "LinearFVRZViscousSource is only valid on RZ coordinate systems."); 51 : 52 54 : if (_component != _rz_radial_coord) 53 0 : paramError("momentum_component", "LinearFVRZViscousSource must act on the radial component."); 54 : 55 54 : if (_use_deviatoric_terms) 56 24 : _var.computeCellGradients(); 57 : 58 : const auto get_velocity_var = 59 48 : [this](const std::string & param_name) -> MooseLinearVariableFVReal * 60 : { 61 48 : auto & var = _fe_problem.getVariable(_tid, getParam<SolverVariableName>(param_name)); 62 48 : auto ptr = dynamic_cast<MooseLinearVariableFVReal *>(&var); 63 48 : if (!ptr) 64 0 : paramError(param_name, "The supplied variable must be a MooseLinearVariableFVReal."); 65 48 : return ptr; 66 54 : }; 67 : 68 54 : if (_use_deviatoric_terms) 69 : { 70 48 : if (isParamValid("u")) 71 24 : _velocity_vars[0] = get_velocity_var("u"); 72 48 : if (isParamValid("v")) 73 24 : _velocity_vars[1] = get_velocity_var("v"); 74 : 75 24 : if (!_velocity_vars[0]) 76 0 : paramError("u", "The x-velocity must be provided when using deviatoric terms."); 77 24 : if (!_velocity_vars[1]) 78 0 : paramError("v", "The y-velocity must be provided when using deviatoric terms."); 79 : 80 72 : for (const auto dir : make_range(_dim)) 81 48 : _velocity_vars[dir]->computeCellGradients(); 82 : } 83 54 : } 84 : 85 : Real 86 800724 : LinearFVRZViscousSource::computeMatrixContribution() 87 : { 88 800724 : const Real r = _current_elem_info->centroid()(_rz_radial_coord); 89 : mooseAssert(r > 0, "Axisymmetric control volumes should not sit on the axis (r = 0)."); 90 : 91 800724 : const Real mu = _mu(makeElemArg(_current_elem_info->elem()), determineState()); 92 800724 : return mu * _stress_multiplier * _current_elem_volume / (r * r); 93 : } 94 : 95 : Real 96 800724 : LinearFVRZViscousSource::computeRightHandSideContribution() 97 : { 98 800724 : if (!_use_deviatoric_terms) 99 : return 0.0; 100 : 101 63804 : const auto state = determineState(); 102 : Real divergence = 0.0; 103 191412 : for (const auto dir : make_range(_dim)) 104 127608 : divergence += velocityVar(dir).gradSln(*_current_elem_info, state)(dir); 105 : 106 63804 : const Real r = _current_elem_info->centroid()(_rz_radial_coord); 107 : mooseAssert(r > 0, "Axisymmetric control volumes should not sit on the axis (r = 0)."); 108 : 109 63804 : const Real radial_value = velocityVar(_rz_radial_coord).getElemValue(*_current_elem_info, state); 110 63804 : divergence += radial_value / r; 111 : 112 63804 : const auto elem_arg = makeElemArg(_current_elem_info->elem()); 113 63804 : const Real mu = _mu(elem_arg, state); 114 : 115 63804 : return (2.0 / 3.0) * mu * divergence * _current_elem_volume / r; 116 : } 117 : 118 : const MooseLinearVariableFVReal & 119 191412 : LinearFVRZViscousSource::velocityVar(unsigned int dir) const 120 : { 121 : mooseAssert(dir < _velocity_vars.size() && _velocity_vars[dir], 122 : "Velocity variable for requested direction is not available."); 123 191412 : return *_velocity_vars[dir]; 124 : }