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 228 : NSFVHeatFluxBC::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.addCoupledVar(NS::porosity, "porosity"); 34 456 : params.addParam<PostprocessorName>("average_porosity", 35 : "postprocessor that provides domain-averaged porosity"); 36 456 : params.addParam<PostprocessorName>( 37 : "average_k_fluid", "postprocessor that provides domain-averaged fluid thermal conductivity"); 38 456 : params.addParam<PostprocessorName>( 39 : "average_kappa", "postprocessor that provides domain-averaged fluid thermal dispersion"); 40 456 : params.addParam<PostprocessorName>( 41 : "average_k_solid", "postprocessor that provides domain-averaged solid thermal conductivity"); 42 456 : params.addParam<PostprocessorName>( 43 : "average_kappa_solid", 44 : "postprocessor that provides domain-averaged solid effective thermal " 45 : "conductivity"); 46 228 : params.addClassDescription("Constant heat flux boundary condition with phase splitting " 47 : "for fluid and solid energy equations"); 48 228 : return params; 49 0 : } 50 : 51 120 : NSFVHeatFluxBC::NSFVHeatFluxBC(const InputParameters & parameters) 52 : : FVFluxBC(parameters), 53 120 : _value(getParam<Real>("value")), 54 240 : _phase(getParam<MooseEnum>("phase").getEnum<NS::phase::PhaseEnum>()), 55 240 : _split_type(getParam<MooseEnum>("splitting").getEnum<NS::splitting::SplittingEnum>()), 56 240 : _locality(getParam<MooseEnum>("locality").getEnum<NS::settings::LocalityEnum>()), 57 : // quantities needed for global evaluations 58 300 : _average_eps(_locality == NS::settings::global && 59 60 : _split_type != NS::splitting::thermal_conductivity 60 180 : ? &getPostprocessorValue("average_porosity") 61 : : nullptr), 62 60 : _average_k_f(_locality == NS::settings::global && _split_type != NS::splitting::porosity 63 180 : ? &getPostprocessorValue("average_k_fluid") 64 : : nullptr), 65 300 : _average_k_s(_locality == NS::settings::global && 66 60 : _split_type == NS::splitting::thermal_conductivity 67 180 : ? &getPostprocessorValue("average_k_solid") 68 : : nullptr), 69 300 : _average_kappa_s(_locality == NS::settings::global && 70 60 : _split_type == NS::splitting::effective_thermal_conductivity 71 180 : ? &getPostprocessorValue("average_kappa_solid") 72 : : nullptr), 73 300 : _average_kappa(_locality == NS::settings::global && 74 60 : _split_type == NS::splitting::effective_thermal_conductivity 75 180 : ? &getPostprocessorValue("average_kappa") 76 : : nullptr), 77 : // quantities needed for local evaluations 78 60 : _eps(_locality == NS::settings::local && _split_type != NS::splitting::thermal_conductivity 79 180 : ? coupledValue(NS::porosity) 80 : : _zero), 81 60 : _k_f(_locality == NS::settings::local && _split_type != NS::splitting::porosity 82 160 : ? &getADMaterialProperty<Real>(NS::k) 83 : : nullptr), 84 60 : _k_s(_locality == NS::settings::local && _split_type == NS::splitting::thermal_conductivity 85 140 : ? &getADMaterialProperty<Real>(NS::k_s) 86 : : nullptr), 87 300 : _kappa(_locality == NS::settings::local && 88 60 : _split_type == NS::splitting::effective_thermal_conductivity 89 140 : ? &getADMaterialProperty<RealVectorValue>(NS::kappa) 90 : : nullptr), 91 300 : _kappa_s(_locality == NS::settings::local && 92 60 : _split_type == NS::splitting::effective_thermal_conductivity 93 140 : ? &getADMaterialProperty<Real>(NS::kappa_s) 94 120 : : nullptr) 95 : { 96 120 : } 97 : 98 : ADReal 99 36240 : 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 36240 : ADReal fraction = 0.0; 107 36240 : ADReal tol = NS_DEFAULT_VALUES::k_epsilon; 108 : 109 36240 : if (_locality == NS::settings::local) 110 : { 111 18120 : switch (_split_type) 112 : { 113 6040 : case NS::splitting::porosity: 114 : { 115 6040 : fraction = _eps[_qp]; 116 : break; 117 : } 118 6040 : case NS::splitting::thermal_conductivity: 119 : { 120 6040 : ADReal d = (*_k_f)[_qp] + (*_k_s)[_qp]; 121 12080 : 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 12080 : if ((MooseUtils::absoluteFuzzyEqual((*_kappa)[_qp](0), 0)) && 134 12080 : (MooseUtils::absoluteFuzzyEqual((*_kappa)[_qp](1), 0)) && 135 6040 : (MooseUtils::absoluteFuzzyEqual((*_kappa)[_qp](2), 0))) 136 0 : kappa = 1e-42; 137 : else 138 12080 : kappa = (*_kappa)[_qp].norm() / std::sqrt(3.0); 139 : 140 12080 : ADReal d = _eps[_qp] * kappa + (*_kappa_s)[_qp]; 141 18120 : fraction = d > tol ? _eps[_qp] * kappa / d : 0.5; 142 : break; 143 : } 144 : } 145 : } 146 : else 147 : { 148 18120 : switch (_split_type) 149 : { 150 6040 : case NS::splitting::porosity: 151 : { 152 6040 : fraction = *_average_eps; 153 : break; 154 : } 155 6040 : case NS::splitting::thermal_conductivity: 156 : { 157 6040 : ADReal d = *_average_k_f + *_average_k_s; 158 6040 : fraction = d > tol ? *_average_k_f / d : 0.5; 159 : break; 160 : } 161 6040 : case NS::splitting::effective_thermal_conductivity: 162 : { 163 6040 : ADReal d = (*_average_eps) * (*_average_kappa) + (*_average_kappa_s); 164 6040 : fraction = d > tol ? (*_average_eps) * (*_average_kappa) / d : 0.5; 165 : break; 166 : } 167 : } 168 : } 169 : 170 36240 : if (_phase == NS::phase::solid) 171 36240 : return (1.0 - fraction) * -_value; 172 : else 173 36240 : return fraction * -_value; 174 : }