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 492 : NSFVFunctorHeatFluxBC::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.addParam<MooseFunctorName>(NS::porosity, "porosity");
34 984 : 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 492 : params.addParam<MooseFunctorName>(NS::k, NS::k, "Fluid phase thermal conductivity");
39 492 : params.addParam<MooseFunctorName>(NS::k_s, NS::k_s, "Solid phase thermal conductivity");
40 492 : params.addParam<MooseFunctorName>(
41 : NS::kappa, NS::kappa, "Fluid phase effective thermal conductivity");
42 492 : params.addParam<MooseFunctorName>(
43 : NS::kappa_s, NS::kappa_s, "Solid phase effective thermal conductivity");
44 :
45 984 : params.addParam<PostprocessorName>(
46 : "average_k_fluid", "postprocessor that provides domain-averaged fluid thermal conductivity");
47 984 : params.addParam<PostprocessorName>(
48 : "average_kappa", "postprocessor that provides domain-averaged fluid thermal dispersion");
49 984 : params.addParam<PostprocessorName>(
50 : "average_k_solid", "postprocessor that provides domain-averaged solid thermal conductivity");
51 984 : params.addParam<PostprocessorName>(
52 : "average_kappa_solid",
53 : "postprocessor that provides domain-averaged solid effective thermal "
54 : "conductivity");
55 492 : params.addClassDescription("Constant heat flux boundary condition with phase splitting "
56 : "for fluid and solid energy equations");
57 492 : return params;
58 0 : }
59 :
60 264 : NSFVFunctorHeatFluxBC::NSFVFunctorHeatFluxBC(const InputParameters & parameters)
61 : : FVFluxBC(parameters),
62 264 : _value(getParam<Real>("value")),
63 528 : _phase(getParam<MooseEnum>("phase").getEnum<NS::phase::PhaseEnum>()),
64 528 : _split_type(getParam<MooseEnum>("splitting").getEnum<NS::splitting::SplittingEnum>()),
65 528 : _locality(getParam<MooseEnum>("locality").getEnum<NS::settings::LocalityEnum>()),
66 : // quantities needed for global evaluations
67 660 : _average_eps(_locality == NS::settings::global &&
68 132 : _split_type != NS::splitting::thermal_conductivity
69 396 : ? &getPostprocessorValue("average_porosity")
70 : : nullptr),
71 132 : _average_k_f(_locality == NS::settings::global && _split_type != NS::splitting::porosity
72 396 : ? &getPostprocessorValue("average_k_fluid")
73 : : nullptr),
74 660 : _average_k_s(_locality == NS::settings::global &&
75 132 : _split_type == NS::splitting::thermal_conductivity
76 396 : ? &getPostprocessorValue("average_k_solid")
77 : : nullptr),
78 660 : _average_kappa_s(_locality == NS::settings::global &&
79 132 : _split_type == NS::splitting::effective_thermal_conductivity
80 396 : ? &getPostprocessorValue("average_kappa_solid")
81 : : nullptr),
82 660 : _average_kappa(_locality == NS::settings::global &&
83 132 : _split_type == NS::splitting::effective_thermal_conductivity
84 396 : ? &getPostprocessorValue("average_kappa")
85 : : nullptr),
86 : // quantities needed for local evaluations
87 132 : _eps(_locality == NS::settings::local && _split_type != NS::splitting::thermal_conductivity
88 352 : ? &getFunctor<ADReal>(NS::porosity)
89 : : nullptr),
90 132 : _k_f(_locality == NS::settings::local && _split_type != NS::splitting::porosity
91 352 : ? &getFunctor<ADReal>(NS::k)
92 : : nullptr),
93 132 : _k_s(_locality == NS::settings::local && _split_type == NS::splitting::thermal_conductivity
94 308 : ? &getFunctor<ADReal>(NS::k_s)
95 : : nullptr),
96 660 : _kappa(_locality == NS::settings::local &&
97 132 : _split_type == NS::splitting::effective_thermal_conductivity
98 308 : ? &getFunctor<ADRealVectorValue>(NS::kappa)
99 : : nullptr),
100 660 : _kappa_s(_locality == NS::settings::local &&
101 132 : _split_type == NS::splitting::effective_thermal_conductivity
102 308 : ? &getFunctor<ADReal>(NS::kappa_s)
103 264 : : nullptr)
104 : {
105 264 : }
106 :
107 : ADReal
108 63120 : 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 63120 : ADReal fraction = 0.0;
116 63120 : ADReal tol = NS_DEFAULT_VALUES::k_epsilon;
117 :
118 : // Get the functor argument for the face
119 63120 : const auto face_arg = singleSidedFaceArg();
120 63120 : const auto state = determineState();
121 :
122 63120 : if (_locality == NS::settings::local)
123 : {
124 31560 : switch (_split_type)
125 : {
126 10520 : case NS::splitting::porosity:
127 : {
128 10520 : fraction = (*_eps)(face_arg, state);
129 10520 : break;
130 : }
131 10520 : case NS::splitting::thermal_conductivity:
132 : {
133 21040 : ADReal d = (*_k_f)(face_arg, state) + (*_k_s)(face_arg, state);
134 31560 : 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 21040 : if ((MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(0), 0)) &&
147 21040 : (MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(1), 0)) &&
148 10520 : (MooseUtils::absoluteFuzzyEqual((*_kappa)(face_arg, state)(2), 0)))
149 0 : kappa = 1e-42;
150 : else
151 21040 : kappa = (*_kappa)(face_arg, state).norm() / std::sqrt(3.0);
152 :
153 21040 : ADReal d = (*_eps)(face_arg, state) * kappa + (*_kappa_s)(face_arg, state);
154 42080 : fraction = d > tol ? (*_eps)(face_arg, state) * kappa / d : 0.5;
155 : break;
156 : }
157 : }
158 : }
159 : else
160 : {
161 31560 : switch (_split_type)
162 : {
163 10520 : case NS::splitting::porosity:
164 : {
165 10520 : fraction = *_average_eps;
166 : break;
167 : }
168 10520 : case NS::splitting::thermal_conductivity:
169 : {
170 10520 : ADReal d = *_average_k_f + *_average_k_s;
171 10520 : fraction = d > tol ? *_average_k_f / d : 0.5;
172 : break;
173 : }
174 10520 : case NS::splitting::effective_thermal_conductivity:
175 : {
176 10520 : ADReal d = (*_average_eps) * (*_average_kappa) + (*_average_kappa_s);
177 10520 : fraction = d > tol ? (*_average_eps) * (*_average_kappa) / d : 0.5;
178 : break;
179 : }
180 : }
181 : }
182 :
183 63120 : if (_phase == NS::phase::solid)
184 63120 : return (1.0 - fraction) * -_value;
185 : else
186 63120 : return fraction * -_value;
187 : }
|