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 "LinearFVAdvection.h" 11 : #include "Assembly.h" 12 : #include "SubProblem.h" 13 : #include "LinearFVAdvectionDiffusionBC.h" 14 : 15 : registerMooseObject("MooseApp", LinearFVAdvection); 16 : 17 : InputParameters 18 4203 : LinearFVAdvection::validParams() 19 : { 20 4203 : InputParameters params = LinearFVFluxKernel::validParams(); 21 8406 : params.addClassDescription("Represents the matrix and right hand side contributions of an " 22 : "advection term in a partial differential equation."); 23 16812 : params.addRequiredParam<RealVectorValue>("velocity", "Constant advection velocity"); 24 12609 : params.addRequiredParam<InterpolationMethodName>( 25 : "advected_interp_method_name", 26 : "Name of the FVInterpolationMethod to use for the advected quantity."); 27 4203 : return params; 28 0 : } 29 : 30 571 : LinearFVAdvection::LinearFVAdvection(const InputParameters & params) 31 : : LinearFVFluxKernel(params), 32 : FVInterpolationMethodInterface(this), 33 571 : _velocity(getParam<RealVectorValue>("velocity")), 34 1142 : _adv_interp_method(getFVAdvectedInterpolationMethod( 35 1142 : getParam<InterpolationMethodName>("advected_interp_method_name"))) 36 : 37 : { 38 571 : if (_adv_interp_method.needsGradients()) 39 189 : _var.computeCellGradients(_adv_interp_method.gradientLimiter()); 40 571 : } 41 : 42 : void 43 57768861 : LinearFVAdvection::setupFaceData(const FaceInfo * face_info) 44 : { 45 57768861 : LinearFVFluxKernel::setupFaceData(face_info); 46 57768861 : _adv_face_flux = _velocity * _current_face_info->normal(); 47 : 48 : // Only internal faces need advected interpolation results; boundary contributions are handled 49 : // through the linear FV boundary conditions. 50 57768861 : if (_current_face_type != FaceInfo::VarFaceNeighbors::BOTH) 51 1334010 : return; 52 : 53 56434851 : const auto state = determineState(); 54 56434851 : const auto & elem_info = *_current_face_info->elemInfo(); 55 56434851 : const auto & neighbor_info = *_current_face_info->neighborInfo(); 56 : 57 56434851 : const Real elem_value = _var.getElemValue(elem_info, state); 58 56434851 : const Real neighbor_value = _var.getElemValue(neighbor_info, state); 59 56434851 : if (_adv_interp_method.needsGradients()) 60 : { 61 35257485 : const auto limiter_type = _adv_interp_method.gradientLimiter(); 62 35257485 : _elem_grad_storage = _var.gradSln(elem_info, state, limiter_type); 63 35257485 : _neighbor_grad_storage = _var.gradSln(neighbor_info, state, limiter_type); 64 : } 65 : 66 56434851 : _adv_interp_result = _adv_interp_method.advectedInterpolate(*_current_face_info, 67 : elem_value, 68 : neighbor_value, 69 56434851 : &_elem_grad_storage, 70 56434851 : &_neighbor_grad_storage, 71 56434851 : _adv_face_flux); 72 : } 73 : 74 : void 75 569 : LinearFVAdvection::initialSetup() 76 : { 77 2455 : for (const auto bc : _var.getBoundaryConditionMap()) 78 1886 : if (!dynamic_cast<const LinearFVAdvectionDiffusionBC *>(bc.second)) 79 0 : mooseError( 80 0 : bc.second->type(), " is not a compatible boundary condition with ", this->type(), "!"); 81 569 : } 82 : 83 : Real 84 56434851 : LinearFVAdvection::computeElemMatrixContribution() 85 : { 86 56434851 : const auto & coeffs = _adv_interp_result.weights_matrix; 87 56434851 : return coeffs.first * _adv_face_flux * _current_face_area; 88 : } 89 : 90 : Real 91 56434851 : LinearFVAdvection::computeNeighborMatrixContribution() 92 : { 93 56434851 : const auto & coeffs = _adv_interp_result.weights_matrix; 94 56434851 : return coeffs.second * _adv_face_flux * _current_face_area; 95 : } 96 : 97 : Real 98 56434851 : LinearFVAdvection::computeElemRightHandSideContribution() 99 : { 100 56434851 : return _adv_interp_result.rhs_face_value * _adv_face_flux * _current_face_area; 101 : } 102 : 103 : Real 104 56434851 : LinearFVAdvection::computeNeighborRightHandSideContribution() 105 : { 106 56434851 : return -_adv_interp_result.rhs_face_value * _adv_face_flux * _current_face_area; 107 : } 108 : 109 : Real 110 1334010 : LinearFVAdvection::computeBoundaryMatrixContribution(const LinearFVBoundaryCondition & bc) 111 : { 112 1334010 : const auto * const adv_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc); 113 : mooseAssert(adv_bc, "This should be a valid BC!"); 114 : 115 1334010 : const auto boundary_value_matrix_contrib = adv_bc->computeBoundaryValueMatrixContribution(); 116 : 117 : // We support internal boundaries too so we have to make sure the normal points always outward 118 1334010 : const auto factor = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) ? 1.0 : -1.0; 119 : 120 1334010 : return boundary_value_matrix_contrib * factor * _adv_face_flux * _current_face_area; 121 : } 122 : 123 : Real 124 1334010 : LinearFVAdvection::computeBoundaryRHSContribution(const LinearFVBoundaryCondition & bc) 125 : { 126 1334010 : const auto * const adv_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc); 127 : mooseAssert(adv_bc, "This should be a valid BC!"); 128 : 129 : // We support internal boundaries too so we have to make sure the normal points always outward 130 1334010 : const auto factor = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0); 131 : 132 1334010 : const auto boundary_value_rhs_contrib = adv_bc->computeBoundaryValueRHSContribution(); 133 1334010 : return -boundary_value_rhs_contrib * factor * _adv_face_flux * _current_face_area; 134 : }