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 : }
|