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 "LinearFVScalarAdvection.h" 11 : #include "MooseLinearVariableFV.h" 12 : #include "NS.h" 13 : 14 : registerMooseObject("NavierStokesApp", LinearFVScalarAdvection); 15 : 16 : InputParameters 17 224 : LinearFVScalarAdvection::validParams() 18 : { 19 224 : InputParameters params = LinearFVFluxKernel::validParams(); 20 224 : params.addClassDescription("Represents the matrix and right hand side contributions of an " 21 : "advection term for a passive scalar."); 22 448 : params.addRequiredParam<UserObjectName>( 23 : "rhie_chow_user_object", 24 : "The rhie-chow user-object which is used to determine the face velocity."); 25 448 : params.addRequiredParam<InterpolationMethodName>( 26 : "advected_interp_method_name", 27 : "Name of the FVInterpolationMethod to use for the advected quantity."); 28 448 : params.addParam<MooseFunctorName>("u_slip", "The slip-velocity in the x direction."); 29 448 : params.addParam<MooseFunctorName>("v_slip", "The slip-velocity in the y direction."); 30 448 : params.addParam<MooseFunctorName>("w_slip", "The slip-velocity in the z direction."); 31 224 : return params; 32 0 : } 33 : 34 125 : LinearFVScalarAdvection::LinearFVScalarAdvection(const InputParameters & params) 35 : : LinearFVFluxKernel(params), 36 : FVInterpolationMethodInterface(this), 37 125 : _mass_flux_provider(getUserObject<RhieChowMassFlux>("rhie_chow_user_object")), 38 250 : _adv_interp_method(getFVAdvectedInterpolationMethod( 39 : getParam<InterpolationMethodName>("advected_interp_method_name"))), 40 125 : _volumetric_face_flux(0.0), 41 300 : _u_slip(isParamValid("u_slip") ? &getFunctor<ADReal>("u_slip") : nullptr), 42 300 : _v_slip(isParamValid("v_slip") ? &getFunctor<ADReal>("v_slip") : nullptr), 43 250 : _w_slip(isParamValid("w_slip") ? &getFunctor<ADReal>("w_slip") : nullptr), 44 375 : _add_slip_model(isParamValid("u_slip") ? true : false) 45 : { 46 125 : if (_adv_interp_method.needsGradients()) 47 24 : _var.computeCellGradients(_adv_interp_method.gradientLimiter()); 48 125 : } 49 : 50 : Real 51 2032850 : LinearFVScalarAdvection::computeElemMatrixContribution() 52 : { 53 : const auto & coeffs = _adv_interp_result.weights_matrix; 54 2032850 : return coeffs.first * _volumetric_face_flux * _current_face_area; 55 : } 56 : 57 : Real 58 2032850 : LinearFVScalarAdvection::computeNeighborMatrixContribution() 59 : { 60 : const auto & coeffs = _adv_interp_result.weights_matrix; 61 2032850 : return coeffs.second * _volumetric_face_flux * _current_face_area; 62 : } 63 : 64 : Real 65 2032850 : LinearFVScalarAdvection::computeElemRightHandSideContribution() 66 : { 67 2032850 : return _adv_interp_result.rhs_face_value * _volumetric_face_flux * _current_face_area; 68 : } 69 : 70 : Real 71 2032850 : LinearFVScalarAdvection::computeNeighborRightHandSideContribution() 72 : { 73 2032850 : return -_adv_interp_result.rhs_face_value * _volumetric_face_flux * _current_face_area; 74 : } 75 : 76 : Real 77 234540 : LinearFVScalarAdvection::computeBoundaryMatrixContribution(const LinearFVBoundaryCondition & bc) 78 : { 79 : const auto * const adv_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc); 80 : mooseAssert(adv_bc, "This should be a valid BC!"); 81 : 82 234540 : const auto boundary_value_matrix_contrib = adv_bc->computeBoundaryValueMatrixContribution(); 83 : 84 : // We support internal boundaries too so we have to make sure the normal points always outward 85 234540 : const auto factor = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) ? 1.0 : -1.0; 86 : 87 234540 : return boundary_value_matrix_contrib * factor * _volumetric_face_flux * _current_face_area; 88 : } 89 : 90 : Real 91 234540 : LinearFVScalarAdvection::computeBoundaryRHSContribution(const LinearFVBoundaryCondition & bc) 92 : { 93 : const auto * const adv_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc); 94 : mooseAssert(adv_bc, "This should be a valid BC!"); 95 : 96 : // We support internal boundaries too so we have to make sure the normal points always outward 97 234540 : const auto factor = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0); 98 : 99 234540 : const auto boundary_value_rhs_contrib = adv_bc->computeBoundaryValueRHSContribution(); 100 234540 : return -boundary_value_rhs_contrib * factor * _volumetric_face_flux * _current_face_area; 101 : } 102 : 103 : void 104 2569718 : LinearFVScalarAdvection::setupFaceData(const FaceInfo * face_info) 105 : { 106 2569718 : LinearFVFluxKernel::setupFaceData(face_info); 107 : 108 : // Caching the velocity on the face which will be reused in the advection term's matrix and right 109 : // hand side contributions 110 2569718 : _volumetric_face_flux = _mass_flux_provider.getVolumetricFaceFlux(*face_info); 111 : 112 : // Adjust volumetric face flux using the slip velocity 113 : // TODO: add boundaries 114 4015478 : if (_u_slip && face_info->neighborPtr()) 115 : { 116 1445760 : const auto state = determineState(); 117 : Moose::FaceArg face_arg; 118 : // TODO Add boundary treatment to be able select two-term expansion if desired 119 1445760 : face_arg = Moose::FaceArg{face_info, 120 : Moose::FV::LimiterType::CentralDifference, 121 : true, 122 : false, 123 : face_info->neighborPtr(), 124 : nullptr}; 125 : 126 : RealVectorValue velocity_slip_vel_vec; 127 : if (_u_slip) 128 1445760 : velocity_slip_vel_vec(0) = (*_u_slip)(face_arg, state).value(); 129 1445760 : if (_v_slip) 130 1445760 : velocity_slip_vel_vec(1) = (*_v_slip)(face_arg, state).value(); 131 1445760 : if (_w_slip) 132 0 : velocity_slip_vel_vec(2) = (*_w_slip)(face_arg, state).value(); 133 1445760 : _volumetric_face_flux += velocity_slip_vel_vec * face_info->normal(); 134 : } 135 : 136 : // Only internal faces need advected interpolation results; boundary contributions are handled 137 : // through the linear FV boundary conditions. 138 2569718 : if (_current_face_type != FaceInfo::VarFaceNeighbors::BOTH) 139 536868 : return; 140 : 141 2032850 : const auto state = determineState(); 142 2032850 : const auto & elem_info = *_current_face_info->elemInfo(); 143 : const auto & neighbor_info = *_current_face_info->neighborInfo(); 144 : 145 2032850 : const Real elem_value = _var.getElemValue(elem_info, state); 146 2032850 : const Real neighbor_value = _var.getElemValue(neighbor_info, state); 147 2032850 : if (_adv_interp_method.needsGradients()) 148 : { 149 272000 : const auto limiter_type = _adv_interp_method.gradientLimiter(); 150 272000 : _elem_grad_storage = _var.gradSln(elem_info, state, limiter_type); 151 272000 : _neighbor_grad_storage = _var.gradSln(neighbor_info, state, limiter_type); 152 : } 153 : 154 2032850 : _adv_interp_result = _adv_interp_method.advectedInterpolate(*_current_face_info, 155 : elem_value, 156 : neighbor_value, 157 2032850 : &_elem_grad_storage, 158 2032850 : &_neighbor_grad_storage, 159 : _volumetric_face_flux); 160 : }