LCOV - code coverage report
Current view: top level - src/fvbcs - NSFVFunctorHeatFluxBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #32971 (54bef8) with base c6cf66 Lines: 84 86 97.7 %
Date: 2026-05-29 20:37:52 Functions: 3 3 100.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 "NSFVFunctorHeatFluxBC.h"
      11             : #include "NS.h"
      12             : #include "NSEnums.h"
      13             : 
      14             : registerADMooseObject("NavierStokesApp", NSFVFunctorHeatFluxBC);
      15             : 
      16             : InputParameters
      17         228 : NSFVFunctorHeatFluxBC::validParams()
      18             : {
      19         228 :   InputParameters params = FVFluxBC::validParams();
      20             : 
      21         456 :   params.addRequiredParam<Real>("value", "total heat flux");
      22         456 :   params.addRequiredParam<MooseEnum>(
      23         456 :       "phase", getPhaseEnum(), "'fluid' or 'solid' phase to which this BC is applied.");
      24             : 
      25         456 :   params.addRequiredParam<MooseEnum>("splitting", getSplittingEnum(), "type of splitting");
      26             : 
      27         456 :   params.addRequiredParam<MooseEnum>(
      28             :       "locality",
      29         456 :       getLocalityEnum(),
      30             :       "whether to use local (at the boundary) or global (domain-averaged) "
      31             :       "parameter values");
      32             : 
      33         228 :   params.addParam<MooseFunctorName>(NS::porosity, "porosity");
      34         456 :   params.addParam<PostprocessorName>("average_porosity",
      35             :                                      "postprocessor that provides domain-averaged proosity");
      36             : 
      37             :   // Name of the material properties, useful if not following the NS namespace conventions
      38         228 :   params.addParam<MooseFunctorName>(NS::k, NS::k, "Fluid phase thermal conductivity");
      39         228 :   params.addParam<MooseFunctorName>(NS::k_s, NS::k_s, "Solid phase thermal conductivity");
      40         228 :   params.addParam<MooseFunctorName>(
      41             :       NS::kappa, NS::kappa, "Fluid phase effective thermal conductivity");
      42         228 :   params.addParam<MooseFunctorName>(
      43             :       NS::kappa_s, NS::kappa_s, "Solid phase effective thermal conductivity");
      44             : 
      45         456 :   params.addParam<PostprocessorName>(
      46             :       "average_k_fluid", "postprocessor that provides domain-averaged fluid thermal conductivity");
      47         456 :   params.addParam<PostprocessorName>(
      48             :       "average_kappa", "postprocessor that provides domain-averaged fluid thermal dispersion");
      49         456 :   params.addParam<PostprocessorName>(
      50             :       "average_k_solid", "postprocessor that provides domain-averaged solid thermal conductivity");
      51         456 :   params.addParam<PostprocessorName>(
      52             :       "average_kappa_solid",
      53             :       "postprocessor that provides domain-averaged solid effective thermal "
      54             :       "conductivity");
      55         228 :   params.addClassDescription("Constant heat flux boundary condition with phase splitting "
      56             :                              "for fluid and solid energy equations");
      57         228 :   return params;
      58           0 : }
      59             : 
      60         120 : NSFVFunctorHeatFluxBC::NSFVFunctorHeatFluxBC(const InputParameters & parameters)
      61             :   : FVFluxBC(parameters),
      62         120 :     _value(getParam<Real>("value")),
      63         240 :     _phase(getParam<MooseEnum>("phase").getEnum<NS::phase::PhaseEnum>()),
      64         240 :     _split_type(getParam<MooseEnum>("splitting").getEnum<NS::splitting::SplittingEnum>()),
      65         240 :     _locality(getParam<MooseEnum>("locality").getEnum<NS::settings::LocalityEnum>()),
      66             :     // quantities needed for global evaluations
      67         300 :     _average_eps(_locality == NS::settings::global &&
      68          60 :                          _split_type != NS::splitting::thermal_conductivity
      69         180 :                      ? &getPostprocessorValue("average_porosity")
      70             :                      : nullptr),
      71          60 :     _average_k_f(_locality == NS::settings::global && _split_type != NS::splitting::porosity
      72         180 :                      ? &getPostprocessorValue("average_k_fluid")
      73             :                      : nullptr),
      74         300 :     _average_k_s(_locality == NS::settings::global &&
      75          60 :                          _split_type == NS::splitting::thermal_conductivity
      76         180 :                      ? &getPostprocessorValue("average_k_solid")
      77             :                      : nullptr),
      78         300 :     _average_kappa_s(_locality == NS::settings::global &&
      79          60 :                              _split_type == NS::splitting::effective_thermal_conductivity
      80         180 :                          ? &getPostprocessorValue("average_kappa_solid")
      81             :                          : nullptr),
      82         300 :     _average_kappa(_locality == NS::settings::global &&
      83          60 :                            _split_type == NS::splitting::effective_thermal_conductivity
      84         180 :                        ? &getPostprocessorValue("average_kappa")
      85             :                        : nullptr),
      86             :     // quantities needed for local evaluations
      87          60 :     _eps(_locality == NS::settings::local && _split_type != NS::splitting::thermal_conductivity
      88         160 :              ? &getFunctor<ADReal>(NS::porosity)
      89             :              : nullptr),
      90          60 :     _k_f(_locality == NS::settings::local && _split_type != NS::splitting::porosity
      91         160 :              ? &getFunctor<ADReal>(NS::k)
      92             :              : nullptr),
      93          60 :     _k_s(_locality == NS::settings::local && _split_type == NS::splitting::thermal_conductivity
      94         140 :              ? &getFunctor<ADReal>(NS::k_s)
      95             :              : nullptr),
      96         300 :     _kappa(_locality == NS::settings::local &&
      97          60 :                    _split_type == NS::splitting::effective_thermal_conductivity
      98         140 :                ? &getFunctor<ADRealVectorValue>(NS::kappa)
      99             :                : nullptr),
     100         300 :     _kappa_s(_locality == NS::settings::local &&
     101          60 :                      _split_type == NS::splitting::effective_thermal_conductivity
     102         140 :                  ? &getFunctor<ADReal>(NS::kappa_s)
     103         120 :                  : nullptr)
     104             : {
     105         120 : }
     106             : 
     107             : ADReal
     108       36240 : NSFVFunctorHeatFluxBC::computeQpResidual()
     109             : {
     110             :   // we don't need default statements in the switch-case statements for
     111             :   // the SplittingEnum because we by default set the fraction to zero such that
     112             :   // all of the heat flux enters the solid phase (though this default is never
     113             :   // reached since the InputParameters class requires the MooseEnum to be
     114             :   // one of 'porosity', 'thermal_conductivity', or 'effective_thermal_conductivity'
     115       36240 :   ADReal fraction = 0.0;
     116       36240 :   ADReal tol = NS_DEFAULT_VALUES::k_epsilon;
     117             : 
     118             :   // Get the functor argument for the face
     119       36240 :   const auto face_arg = singleSidedFaceArg();
     120       36240 :   const auto state = determineState();
     121             : 
     122       36240 :   if (_locality == NS::settings::local)
     123             :   {
     124       18120 :     switch (_split_type)
     125             :     {
     126        6040 :       case NS::splitting::porosity:
     127             :       {
     128        6040 :         fraction = (*_eps)(face_arg, state);
     129        6040 :         break;
     130             :       }
     131        6040 :       case NS::splitting::thermal_conductivity:
     132             :       {
     133       12080 :         ADReal d = (*_k_f)(face_arg, state) + (*_k_s)(face_arg, state);
     134       18120 :         fraction = d > tol ? (*_k_f)(face_arg, state) / d : 0.5;
     135             :         break;
     136             :       }
     137             :       case NS::splitting::effective_thermal_conductivity:
     138             :       {
     139             :         // TODO: for the case of an anisotropic conductivity, we technically should
     140             :         // grab the component of kappa perpendicular to the boundary.
     141             : 
     142             :         // Need this logic to avoid AD failures when taking norms of zero. The
     143             :         // division by sqrt(3) ensures equivalence with a non-vector form of kappa with
     144             :         // 3 components
     145             :         ADReal kappa;
     146       12080 :         if ((MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(0), 0)) &&
     147       12080 :             (MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(1), 0)) &&
     148        6040 :             (MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(2), 0)))
     149           0 :           kappa = 1e-42;
     150             :         else
     151       12080 :           kappa = (*_kappa)(face_arg, state).norm() / std::sqrt(3.0);
     152             : 
     153       12080 :         ADReal d = (*_eps)(face_arg, state) * kappa + (*_kappa_s)(face_arg, state);
     154       24160 :         fraction = d > tol ? (*_eps)(face_arg, state) * kappa / d : 0.5;
     155             :         break;
     156             :       }
     157             :     }
     158             :   }
     159             :   else
     160             :   {
     161       18120 :     switch (_split_type)
     162             :     {
     163        6040 :       case NS::splitting::porosity:
     164             :       {
     165        6040 :         fraction = *_average_eps;
     166             :         break;
     167             :       }
     168        6040 :       case NS::splitting::thermal_conductivity:
     169             :       {
     170        6040 :         ADReal d = *_average_k_f + *_average_k_s;
     171        6040 :         fraction = d > tol ? *_average_k_f / d : 0.5;
     172             :         break;
     173             :       }
     174        6040 :       case NS::splitting::effective_thermal_conductivity:
     175             :       {
     176        6040 :         ADReal d = (*_average_eps) * (*_average_kappa) + (*_average_kappa_s);
     177        6040 :         fraction = d > tol ? (*_average_eps) * (*_average_kappa) / d : 0.5;
     178             :         break;
     179             :       }
     180             :     }
     181             :   }
     182             : 
     183       36240 :   if (_phase == NS::phase::solid)
     184       36240 :     return (1.0 - fraction) * -_value;
     185             :   else
     186       36240 :     return fraction * -_value;
     187             : }

Generated by: LCOV version 1.14