LCOV - code coverage report
Current view: top level - src/postprocessors - VolumetricFlowRate.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 75 85 88.2 %
Date: 2025-08-14 10:14:56 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          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 "VolumetricFlowRate.h"
      11             : #include "MathFVUtils.h"
      12             : #include "RhieChowInterpolatorBase.h"
      13             : #include "NSFVUtils.h"
      14             : 
      15             : #include <cmath>
      16             : 
      17             : registerMooseObject("NavierStokesApp", VolumetricFlowRate);
      18             : 
      19             : InputParameters
      20       11208 : VolumetricFlowRate::validParams()
      21             : {
      22       11208 :   InputParameters params = SideIntegralPostprocessor::validParams();
      23       11208 :   params.addClassDescription(
      24             :       "Computes the volumetric flow rate of an advected quantity through a sideset.");
      25       22416 :   params.addRequiredCoupledVar("vel_x", "The x-axis velocity");
      26       22416 :   params.addCoupledVar("vel_y", 0, "The y-axis velocity");
      27       22416 :   params.addCoupledVar("vel_z", 0, "The z-axis velocity");
      28       22416 :   params.addCoupledVar("advected_variable",
      29             :                        0,
      30             :                        "The advected variable quantity of which to study the flow; useful for "
      31             :                        "finite element simulations");
      32       22416 :   params.addParam<MooseFunctorName>("advected_mat_prop",
      33       22416 :                                     0,
      34             :                                     "The advected material property of which to study the flow; "
      35             :                                     "useful for finite element simulations");
      36       22416 :   params.addParam<MooseFunctorName>("advected_quantity",
      37             :                                     "The quantity to advect. This is the canonical parameter to "
      38             :                                     "set the advected quantity when finite volume is being used.");
      39       11208 :   params += Moose::FV::interpolationParameters();
      40       22416 :   params.addParam<UserObjectName>("rhie_chow_user_object", "The rhie-chow user-object");
      41       22416 :   params.addParam<bool>("subtract_mesh_velocity",
      42             :                         "To subtract the velocity of the potentially moving mesh. Defaults to true "
      43             :                         "if a displaced problem exists, else false.");
      44       11208 :   return params;
      45           0 : }
      46             : 
      47        6023 : VolumetricFlowRate::VolumetricFlowRate(const InputParameters & parameters)
      48             :   : SideIntegralPostprocessor(parameters),
      49        6023 :     _vel_x(coupledValue("vel_x")),
      50        6023 :     _vel_y(coupledValue("vel_y")),
      51        6023 :     _vel_z(coupledValue("vel_z")),
      52        6023 :     _advected_variable_supplied(parameters.isParamSetByUser("advected_variable")),
      53        6023 :     _advected_variable(coupledValue("advected_variable")),
      54        6023 :     _advected_mat_prop_supplied(parameters.isParamSetByUser("advected_mat_prop")),
      55       12046 :     _advected_material_property(getFunctor<ADReal>("advected_mat_prop")),
      56       20616 :     _adv_quant(isParamValid("advected_quantity") ? &getFunctor<ADReal>("advected_quantity")
      57             :                                                  : nullptr),
      58        6023 :     _rc_uo(isParamValid("rhie_chow_user_object")
      59       10308 :                ? &getUserObject<RhieChowFaceFluxProvider>("rhie_chow_user_object")
      60             :                : nullptr),
      61        6023 :     _subtract_mesh_velocity(isParamValid("subtract_mesh_velocity")
      62       12366 :                                 ? getParam<bool>("subtract_mesh_velocity")
      63       11726 :                                 : _fe_problem.haveDisplaced())
      64             : {
      65             :   // Check that at most one advected quantity has been provided
      66        6023 :   if (_advected_variable_supplied && _advected_mat_prop_supplied)
      67           0 :     mooseError("VolumetricFlowRatePostprocessor should be provided either an advected variable "
      68             :                "or an advected material property");
      69             : 
      70             :   // Check that the user isn't trying to get face values for material properties
      71       12046 :   if (parameters.isParamSetByUser("advected_interp_method") && _advected_mat_prop_supplied)
      72           0 :     mooseWarning("Advected quantity interpolation methods are currently unavailable for "
      73             :                  "advected material properties.");
      74             : 
      75        6023 :   _qp_integration = !getFieldVar("vel_x", 0)->isFV();
      76             : 
      77        6023 :   if (_advected_mat_prop_supplied)
      78         176 :     checkFunctorSupportsSideIntegration<ADReal>("advected_mat_prop", _qp_integration);
      79        6023 :   if (_adv_quant)
      80        8570 :     checkFunctorSupportsSideIntegration<ADReal>("advected_quantity", _qp_integration);
      81             : 
      82        6023 :   if (!_qp_integration)
      83             :   {
      84        4285 :     if (!_rc_uo)
      85           0 :       mooseError("We were instructed to use finite volume, but no Rhie-Chow user object is "
      86             :                  "supplied. Please make sure to set the 'rhie_chow_user_object' parameter");
      87        4285 :     if (!_adv_quant)
      88           0 :       mooseError("We were instructed to use finite volume, but no 'advected_quantity' parameter is "
      89             :                  "supplied.");
      90             : 
      91        4285 :     Moose::FV::setInterpolationMethods(*this, _advected_interp_method, _velocity_interp_method);
      92             :   }
      93             : 
      94        6023 :   if (_subtract_mesh_velocity && _rc_uo && !_rc_uo->supportMeshVelocity())
      95           0 :     paramError("subtract_mesh_velocity",
      96             :                "Rhie Chow user object does not support subtracting the mesh velocity");
      97        6023 :   if (_subtract_mesh_velocity && !_fe_problem.haveDisplaced())
      98           0 :     paramError(
      99             :         "subtract_mesh_velocity",
     100             :         "No displaced problem, thus the mesh velocity is 0 and does not need to be subtracted");
     101        6023 : }
     102             : 
     103             : void
     104        6001 : VolumetricFlowRate::initialSetup()
     105             : {
     106        6001 :   const auto * rc_base = dynamic_cast<const RhieChowInterpolatorBase *>(_rc_uo);
     107        4263 :   if (_rc_uo && rc_base &&
     108       10098 :       rc_base->velocityInterpolationMethod() == Moose::FV::InterpMethod::RhieChow &&
     109        4097 :       !rc_base->segregated())
     110             :   {
     111             :     // We must make sure the A coefficients in the Rhie Chow interpolator are present on
     112             :     // both sides of the boundaries so that interpolation coefficients may be computed
     113        8098 :     for (const auto bid : boundaryIDs())
     114        4049 :       const_cast<RhieChowInterpolatorBase *>(rc_base)->ghostADataOnBoundary(bid);
     115             : 
     116             :     // On INITIAL, we cannot compute Rhie Chow coefficients on internal surfaces because
     117             :     // - the time integrator is not ready to compute time derivatives
     118             :     // - the setup routine is called too early for porosity functions to be initialized
     119             :     // We must check that the boundaries requested are all external
     120        4049 :     if (getExecuteOnEnum().isValueSet(EXEC_INITIAL))
     121         266 :       for (const auto bid : boundaryIDs())
     122             :       {
     123         134 :         if (!_mesh.isBoundaryFullyExternalToSubdomains(bid, rc_base->blockIDs()))
     124           2 :           paramError(
     125             :               "execute_on",
     126             :               "Boundary '",
     127           2 :               _mesh.getBoundaryName(bid),
     128             :               "' (id=",
     129             :               bid,
     130             :               ") has been detected to be internal to the flow domain.\n"
     131             :               "Volumetric flow rates cannot be computed on internal flow boundaries on INITIAL");
     132             :       }
     133             :   }
     134        5999 : }
     135             : 
     136             : void
     137           0 : VolumetricFlowRate::meshChanged()
     138             : {
     139           0 :   initialSetup();
     140           0 : }
     141             : 
     142             : Real
     143       26605 : VolumetricFlowRate::computeFaceInfoIntegral(const FaceInfo * fi)
     144             : {
     145             :   mooseAssert(fi, "We should have a face info in " + name());
     146             :   mooseAssert(_adv_quant, "We should have an advected quantity in " + name());
     147       26605 :   const auto state = determineState();
     148             : 
     149             :   // Get face value for velocity
     150       26605 :   const auto face_flux = MetaPhysicL::raw_value(_rc_uo->getVolumetricFaceFlux(
     151       26605 :       _velocity_interp_method, *fi, state, _tid, _subtract_mesh_velocity));
     152             : 
     153       26605 :   const bool correct_skewness =
     154       26605 :       _advected_interp_method == Moose::FV::InterpMethod::SkewCorrectedAverage;
     155             : 
     156             :   mooseAssert(_adv_quant->hasFaceSide(*fi, true) || _adv_quant->hasFaceSide(*fi, false),
     157             :               "Advected quantity should be defined on one side of the face!");
     158             : 
     159       26605 :   const auto * elem = _adv_quant->hasFaceSide(*fi, true) ? fi->elemPtr() : fi->neighborPtr();
     160             : 
     161             :   const auto adv_quant_face = MetaPhysicL::raw_value(
     162       79815 :       (*_adv_quant)(Moose::FaceArg({fi,
     163       26605 :                                     Moose::FV::limiterType(_advected_interp_method),
     164       26605 :                                     face_flux > 0,
     165             :                                     correct_skewness,
     166             :                                     elem,
     167             :                                     nullptr}),
     168             :                     state));
     169       26605 :   return face_flux * adv_quant_face;
     170             : }
     171             : 
     172             : Real
     173       11256 : VolumetricFlowRate::computeQpIntegral()
     174             : {
     175       11256 :   if (_advected_variable_supplied)
     176        2916 :     return _advected_variable[_qp] * RealVectorValue(_vel_x[_qp], _vel_y[_qp], _vel_z[_qp]) *
     177        2916 :            _normals[_qp];
     178        8340 :   else if (_advected_mat_prop_supplied)
     179         648 :     return MetaPhysicL::raw_value(_advected_material_property(
     180         648 :                Moose::ElemQpArg{_current_elem, _qp, _qrule, _q_point[_qp]}, determineState())) *
     181         648 :            RealVectorValue(_vel_x[_qp], _vel_y[_qp], _vel_z[_qp]) * _normals[_qp];
     182             :   else
     183        7692 :     return RealVectorValue(_vel_x[_qp], _vel_y[_qp], _vel_z[_qp]) * _normals[_qp];
     184             : }

Generated by: LCOV version 1.14