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

Generated by: LCOV version 1.14