LCOV - code coverage report
Current view: top level - src/postprocessors - SideAdvectiveFluxIntegral.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 67 72 93.1 %
Date: 2025-07-17 01:28:37 Functions: 6 10 60.0 %
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 "SideAdvectiveFluxIntegral.h"
      11             : #include "MathFVUtils.h"
      12             : 
      13             : #include "metaphysicl/raw_type.h"
      14             : 
      15             : registerMooseObject("MooseApp", SideAdvectiveFluxIntegral);
      16             : registerMooseObject("MooseApp", ADSideAdvectiveFluxIntegral);
      17             : 
      18             : template <bool is_ad>
      19             : InputParameters
      20       28760 : SideAdvectiveFluxIntegralTempl<is_ad>::validParams()
      21             : {
      22       28760 :   InputParameters params = SideIntegralPostprocessor::validParams();
      23       28760 :   MooseEnum component("x y z normal");
      24             : 
      25       28760 :   params.addRequiredParam<MooseEnum>("component", component, "The desired component of flux.");
      26       28760 :   params.addRequiredParam<MooseFunctorName>("vel_x", "x-component of the velocity vector");
      27       28760 :   params.addParam<MooseFunctorName>("vel_y", "y-component of the velocity vector");
      28       28760 :   params.addParam<MooseFunctorName>("vel_z", "z-component of the velocity vector");
      29       28760 :   params.addCoupledVar(
      30             :       "advected_variable",
      31             :       "The advected variable quantity of which to compute advection flux; useful for "
      32             :       "finite element simulations");
      33       86280 :   params.addParam<MaterialPropertyName>(
      34             :       "advected_mat_prop",
      35       57520 :       0,
      36             :       "The advected material property of which to compute advection flux; "
      37             :       "useful for finite element simulations");
      38       28760 :   params.addParam<MooseFunctorName>("advected_quantity",
      39             :                                     "The quantity to advect. This is the canonical parameter to "
      40             :                                     "set the advected quantity when finite volume is being used.");
      41             : 
      42       28760 :   params.addClassDescription("Computes the volumetric advected quantity through a sideset.");
      43             : 
      44       57520 :   return params;
      45       28760 : }
      46             : 
      47             : template <bool is_ad>
      48         120 : SideAdvectiveFluxIntegralTempl<is_ad>::SideAdvectiveFluxIntegralTempl(
      49             :     const InputParameters & parameters)
      50             :   : SideIntegralPostprocessor(parameters),
      51         120 :     _use_normal(getParam<MooseEnum>("component") == "normal"),
      52         120 :     _component(getParam<MooseEnum>("component")),
      53         120 :     _advected_variable_supplied(isParamValid("advected_variable")),
      54         120 :     _advected_variable(_advected_variable_supplied ? coupledValue("advected_variable") : _zero),
      55         120 :     _advected_mat_prop_supplied(parameters.isParamSetByUser("advected_mat_prop")),
      56         120 :     _advected_material_property(getGenericMaterialProperty<Real, is_ad>("advected_mat_prop")),
      57         120 :     _adv_quant(isParamValid("advected_quantity") ? &getFunctor<Real>("advected_quantity")
      58             :                                                  : nullptr),
      59         120 :     _vel_x(getFunctor<Real>("vel_x")),
      60         120 :     _vel_y(_mesh.dimension() >= 2 ? &getFunctor<Real>("vel_y") : nullptr),
      61         240 :     _vel_z(_mesh.dimension() == 3 ? &getFunctor<Real>("vel_z") : nullptr)
      62             : {
      63             :   // Check that at most one advected quantity has been provided
      64         120 :   if (_advected_mat_prop_supplied)
      65             :   {
      66          52 :     if (_advected_variable_supplied || _adv_quant)
      67           0 :       mooseError(
      68             :           "SideAdvectiveFluxIntegralPostprocessor should be provided either an advected quantity "
      69             :           "or an advected material property");
      70             :   }
      71             : 
      72             :   // Check whether a finite element or finite volume variable is provide
      73         120 :   _qp_integration = !_adv_quant;
      74             : 
      75         120 :   checkFunctorSupportsSideIntegration<Real>("vel_x", _qp_integration);
      76         120 :   if (_vel_y)
      77         120 :     checkFunctorSupportsSideIntegration<Real>("vel_y", _qp_integration);
      78         120 :   if (_vel_z)
      79           0 :     checkFunctorSupportsSideIntegration<Real>("vel_z", _qp_integration);
      80         120 : }
      81             : 
      82             : template <bool is_ad>
      83             : Real
      84          64 : SideAdvectiveFluxIntegralTempl<is_ad>::computeFaceInfoIntegral(const FaceInfo * const fi)
      85             : {
      86             :   mooseAssert(fi, "We should have a face info in " + name());
      87             :   mooseAssert(_adv_quant, "We should have an advected quantity in " + name());
      88             : 
      89          64 :   const auto state = determineState();
      90             : 
      91             :   // Get face value for velocity
      92          64 :   const auto vel_x =
      93          64 :       (_vel_x)(Moose::FaceArg(
      94             :                    {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
      95             :                state);
      96          64 :   const auto vel_y =
      97          64 :       _vel_y
      98         128 :           ? ((*_vel_y)(
      99          64 :                 Moose::FaceArg(
     100             :                     {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
     101             :                 state))
     102             :           : 0;
     103          64 :   const auto vel_z =
     104          64 :       _vel_z
     105          64 :           ? ((*_vel_z)(
     106           0 :                 Moose::FaceArg(
     107             :                     {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
     108             :                 state))
     109             :           : 0;
     110             : 
     111          64 :   auto fi_normal = _current_elem == fi->elemPtr() ? fi->normal() : Point(-fi->normal());
     112          64 :   const bool elem_is_upwind = RealVectorValue(vel_x, vel_y, vel_z) * fi_normal >= 0;
     113             : 
     114         128 :   const auto adv_quant_face = (*_adv_quant)(
     115          64 :       Moose::FaceArg(
     116             :           {fi, Moose::FV::LimiterType::CentralDifference, elem_is_upwind, false, nullptr, nullptr}),
     117             :       state);
     118             : 
     119          64 :   return fi_normal * adv_quant_face * RealVectorValue(vel_x, vel_y, vel_z);
     120             : }
     121             : 
     122             : template <bool is_ad>
     123             : Real
     124         387 : SideAdvectiveFluxIntegralTempl<is_ad>::computeQpIntegral()
     125             : {
     126             :   using MetaPhysicL::raw_value;
     127             : 
     128         387 :   const auto state = determineState();
     129         387 :   const Moose::ElemSideQpArg side_arg = {_current_elem, _current_side, _qp, _qrule, _q_point[_qp]};
     130         387 :   const auto vel_x = raw_value(_vel_x(side_arg, state));
     131         387 :   const auto vel_y = _vel_y ? raw_value((*_vel_y)(side_arg, state)) : 0;
     132         387 :   const auto vel_z = _vel_z ? raw_value((*_vel_z)(side_arg, state)) : 0;
     133             : 
     134         387 :   if (_advected_variable_supplied)
     135             :   {
     136             : 
     137         131 :     auto & variable = getCoupledMooseVars();
     138         262 :     if (std::any_of(variable.begin(), variable.end(), [](auto & var) { return !var->isNodal(); }))
     139           3 :       mooseError("Trying to use a non-nodal variable 'advected_variable' for side advection "
     140             :                  "integral calculation, which is currently not supported.");
     141             : 
     142         128 :     return (_use_normal
     143         128 :                 ? _advected_variable[_qp] * RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
     144         128 :                 : _advected_variable[_qp] * RealVectorValue(vel_x, vel_y, vel_z)(_component));
     145             :   }
     146         256 :   else if (_advected_mat_prop_supplied)
     147         384 :     return (_use_normal ? raw_value(_advected_material_property[_qp]) *
     148         256 :                               RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
     149         256 :                         : raw_value(_advected_material_property[_qp]) *
     150         384 :                               RealVectorValue(vel_x, vel_y, vel_z)(_component));
     151             :   else
     152           0 :     return (_use_normal ? RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
     153           0 :                         : RealVectorValue(vel_x, vel_y, vel_z)(_component));
     154             : }
     155             : 
     156             : template class SideAdvectiveFluxIntegralTempl<false>;
     157             : template class SideAdvectiveFluxIntegralTempl<true>;

Generated by: LCOV version 1.14