TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Flux_parietal_Kommajosyula.cpp
1/****************************************************************************
2* Copyright (c) 2021, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Flux_parietal_Kommajosyula.h>
17#include <Hibiki_Ishii_nucleation_site_density.h>
18#include <Flux_parietal_adaptatif.h>
19#include <Loi_paroi_adaptative.h>
20#include <Pb_Multiphase.h>
21
22#include <Domaine_VF.h>
23#include <TRUSTTrav.h>
24#include <Milieu_composite.h>
25#include <Saturation_base.h>
26#include <cmath>
27
28Implemente_instanciable(Flux_parietal_Kommajosyula, "Flux_parietal_Kommajosyula", Flux_parietal_base);
29
31{
33}
34
36{
37 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, pb_.valeur());
38 Correlation_base::typer_lire_correlation(correlation_monophasique_, pbm, "Flux_parietal", is);
39 Cout << que_suis_je() << " : single-phase wall heat flux is " << correlation_monophasique_->que_suis_je() << finl;
40
41 Param param(que_suis_je());
42 param.ajouter("contact_angle_deg", &theta_, Param::REQUIRED);
43 param.ajouter("molar_mass", &molar_mass_, Param::REQUIRED);
44 param.lire_avec_accolades(is);
45
46 if (!sub_type(Milieu_composite, pb_->milieu()))
47 Process::exit("Flux_parietal_Kommajosyula::readOn: the medium must be composite!");
48
49 if (!pbm.nom_phase(0).debute_par("liquide"))
50 Process::exit("Flux_parietal_Kommajosyula::readOn: the first phase must be liquid!");
51
52 const Milieu_composite& milc = ref_cast(Milieu_composite, pb_->milieu());
53 int n_g = -1;
54 for (int k = 1; k < pbm.nb_phases() ; k++)
55 if (milc.has_saturation(0, k))
56 n_g += 1;
57
58 if (n_g > 0)
59 Process::exit("Flux_parietal_Kommajosyula::readOn: there can only be one evaporating phase for the carrying liquid for now! Please feel free to update the code if you need.");
60
61 return is;
62}
63
65{
66 correlation_monophasique_->completer();
67}
68
70{
71 // Set everything to zero (or one)
72 if (out.qpk) (*out.qpk) = 0.;
73 if (out.da_qpk) (*out.da_qpk) = 0.;
74 if (out.dp_qpk) (*out.dp_qpk) = 0.;
75 if (out.dv_qpk) (*out.dv_qpk) = 0.;
76 if (out.dTf_qpk) (*out.dTf_qpk) = 0.;
77 if (out.dTp_qpk) (*out.dTp_qpk) = 0.;
78 if (out.qpi) (*out.qpi) = 0.;
79 if (out.da_qpi) (*out.da_qpi) = 0.;
80 if (out.dp_qpi) (*out.dp_qpi) = 0.;
81 if (out.dv_qpi) (*out.dv_qpi) = 0.;
82 if (out.dTf_qpi) (*out.dTf_qpi) = 0.;
83 if (out.dTp_qpi) (*out.dTp_qpi) = 0.;
84 if (out.nonlinear) (*out.nonlinear) = 1;
85
86 // Single phase, no interfacial flux
87 ref_cast(Flux_parietal_base, correlation_monophasique_.valeur()).qp(in, out);
88
89 // The liquid phase is necessarily phase 0 because the single-phase correlation only fills phase 0
90 int n_l = 0;
91 const Milieu_composite& milc = ref_cast(Milieu_composite, pb_->milieu());
92
93 for (int k = 0; k < in.N; k++)
94 if (n_l != k)
95 if (milc.has_saturation(n_l, k))
96 {
97 const int ind_sat = k < n_l
98 ? (k * (in.N - 1) - (k - 1) * k / 2) + (n_l - k - 1)
99 : (n_l * (in.N - 1) - (n_l - 1) * n_l / 2) + (k - n_l - 1);
100
101 const double Delta_T_sup = in.Tp - in.Tsat[ind_sat]; // Wall superheat
102
103 if (Delta_T_sup > 0) // No wall superheat => no nucleation => single phase heat transfer only
104 {
105 const double Delta_T_sub = std::max(in.Tsat[ind_sat] - in.T[n_l], 1.e-8); // Subcooling (non-negative for numerical reasons)
106
107 double u_bulk = 0;
108 if (sub_type(Flux_parietal_adaptatif, correlation_monophasique_.valeur()))
109 {
110 const Loi_paroi_adaptative& corr_loi_paroi = ref_cast(Loi_paroi_adaptative, ref_cast(Pb_Multiphase, pb_.valeur()).get_correlation("Loi_paroi"));
111 const double u_tau = corr_loi_paroi.get_utau(in.f);
112 u_bulk = 20. * u_tau; // WARNING: Big approximation...
113 }
114 else
115 Cerr << "Flux_parietal_Kommajosyula::qp isn't adapted to a single-phase " << correlation_monophasique_->que_suis_je() << " heat flux for now !\n", Process::exit();
116
117 // Single phase heat transfer coefficient
118 const double h_fc = (*out.dTp_qpk)(n_l);
119
120 // Compute nucleation parameters (diameters, frequencies, site density)
121 const NucleationParams nuc = compute_nucleation_params(in, n_l, k, ind_sat, Delta_T_sup, Delta_T_sub, u_bulk);
122
123 // Thermal boundary layer reformation time (page 61 Kommajosyula PhD; error in equation 4.5 of the manuscript)
124 const double t_star = in.lambda[n_l] * in.rho[n_l] * in.Cp[n_l] / (h_fc * h_fc * M_PI);
125
126 // Compute sliding area and surface fraction
127 const SlidingAreaParams sa = compute_sliding_area(nuc, h_fc, t_star);
128
129 DoubleTrav qpk_loc, da_qpk_loc, dp_qpk_loc, dv_qpk_loc, dTf_qpk_loc, dTp_qpk_loc;
130
131 if (out.qpk) qpk_loc = *out.qpk;
132 if (out.da_qpk) da_qpk_loc = *out.da_qpk;
133 if (out.dp_qpk) dp_qpk_loc = *out.dp_qpk;
134 if (out.dv_qpk) dv_qpk_loc = *out.dv_qpk;
135 if (out.dTf_qpk) dTf_qpk_loc = *out.dTf_qpk;
136 if (out.dTp_qpk) dTp_qpk_loc = *out.dTp_qpk;
137
138 // Correct the single phase heat flux
139 if (out.qpk) (*out.qpk) *= (1 - sa.S_sl);
140 if (out.da_qpk) (*out.da_qpk) *= (1 - sa.S_sl);
141 if (out.dp_qpk) (*out.dp_qpk) *= (1 - sa.S_sl);
142 if (out.dv_qpk) (*out.dv_qpk) *= (1 - sa.S_sl);
143 if (out.dTf_qpk)
144 {
145 (*out.dTf_qpk) *= (1 - sa.S_sl);
146 (*out.dTf_qpk)(n_l,n_l) += -sa.dTl_S_sl * qpk_loc(n_l);
147 (*out.dTf_qpk)(n_l, k ) += -sa.dTk_S_sl * qpk_loc( k );
148 }
149 if (out.dTp_qpk)
150 {
151 (*out.dTp_qpk) *= (1 - sa.S_sl);
152 (*out.dTp_qpk)(n_l) += -sa.dTp_S_sl * qpk_loc(n_l);
153 }
154
155 // Bubble sliding
156 if (out.qpk) (*out.qpk)(n_l) += sa.S_sl * 2. * h_fc * (in.Tp - in.T[n_l]);
157 if (out.dTf_qpk) (*out.dTf_qpk)(n_l, n_l) += -sa.S_sl * 2. * h_fc + sa.dTl_S_sl * 2. * h_fc * (in.Tp - in.T[n_l]);
158 if (out.dTf_qpk) (*out.dTf_qpk)(n_l, k) += sa.dTk_S_sl * 2. * h_fc * (in.Tp - in.T[n_l]);
159 if (out.dTp_qpk) (*out.dTp_qpk)( k ) += sa.S_sl * 2. * h_fc + sa.dTp_S_sl * 2. * h_fc * (in.Tp - in.T[n_l]);
160
161 // Evaporation
162 if (out.qpi) (*out.qpi)(n_l, k) = 1./6. * M_PI * in.rho[k] * in.Lvap[ind_sat] * std::pow(nuc.D_lo, 3.) * nuc.f_dep * sa.N_active;
163 if (out.dTp_qpi) (*out.dTp_qpi)(n_l, k) = 1./6. * M_PI * in.rho[k] * in.Lvap[ind_sat] * (3. * nuc.dTp_D_lo * std::pow(nuc.D_lo, 2.) * nuc.f_dep * sa.N_active
164 + std::pow(nuc.D_lo, 3.) * nuc.dTp_f_dep * sa.N_active
165 + std::pow(nuc.D_lo, 3.) * nuc.f_dep * sa.dTp_N_active);
166 if (out.dTf_qpi) (*out.dTf_qpi)(n_l, k, n_l) = 1./6. * M_PI * in.rho[k] * in.Lvap[ind_sat] * (3. * nuc.dTl_D_lo * std::pow(nuc.D_lo, 2.) * nuc.f_dep * sa.N_active
167 + std::pow(nuc.D_lo, 3.) * nuc.dTl_f_dep * sa.N_active
168 + std::pow(nuc.D_lo, 3.) * nuc.f_dep * sa.dTl_N_active);
169 if (out.dTf_qpi) (*out.dTf_qpi)(n_l, k, k) = 1./6. * M_PI * in.rho[k] * in.Lvap[ind_sat] * (std::pow(nuc.D_lo, 3.) * nuc.f_dep * sa.dTk_N_active);
170
171 if (out.d_nuc) (*out.d_nuc)(k) = nuc.D_lo;
172
173 }
174 }
175}
176
177Flux_parietal_Kommajosyula::NucleationParams
178Flux_parietal_Kommajosyula::compute_nucleation_params(const input_t& in, int n_l, int k, int ind_sat,
179 double Delta_T_sup, double Delta_T_sub, double u_bulk) const
180{
181 NucleationParams nuc {};
182
183 const double dTp_Delta_T_sup = 1.;
184 const double dTl_Delta_T_sub = -1.;
185 const double Ja_sup = in.rho[n_l] * in.Cp[n_l] * Delta_T_sup / (in.rho[k] * in.Lvap[ind_sat]);
186 const double Ja_sub = in.rho[n_l] * in.Cp[n_l] * Delta_T_sub / (in.rho[k] * in.Lvap[ind_sat]);
187 const double dTp_Ja_sup = in.rho[n_l] * in.Cp[n_l] / (in.rho[k] * in.Lvap[ind_sat]);
188 const double dTl_Ja_sub = -in.rho[n_l] * in.Cp[n_l] / (in.rho[k] * in.Lvap[ind_sat]);
189
190 // Nucleation site density (Hibiki Ishii 2003) — T_ref = Tp (wall temperature)
191 nuc.N_sites = Hibiki_Ishii_site_density(in.rho[k], in.rho[n_l], in.Tp, in.p, in.Lvap[ind_sat], in.Tsat[ind_sat], in.Sigma[ind_sat], theta_, molar_mass_);
192 nuc.dTp_N_sites = dT_ref_Hibiki_Ishii_site_density(in.rho[k], in.rho[n_l], in.Tp, in.p, in.Lvap[ind_sat], in.Tsat[ind_sat], in.Sigma[ind_sat], theta_, molar_mass_);
193 nuc.dTl_N_sites = 0.;
194 nuc.dTk_N_sites = 0.;
195
196 // Departure diameter (page 47 Kommajosyula PhD)
197 const double rho_ratio_pow = std::pow((in.rho[n_l] - in.rho[k]) / in.rho[k], 0.27);
198 const double u_bulk_pow = std::pow(u_bulk, -0.26);
199 nuc.D_d =
200 18.9e-6 * rho_ratio_pow * std::pow(Ja_sup, 0.75) * std::pow(1 + Ja_sub, -0.3) * u_bulk_pow;
201 nuc.dTp_D_d = 18.9e-6 * rho_ratio_pow * 0.75 * dTp_Ja_sup * std::pow(Ja_sup, -0.25) *
202 std::pow(1 + Ja_sub, -0.3) * u_bulk_pow;
203 nuc.dTl_D_d = 18.9e-6 * rho_ratio_pow * std::pow(Ja_sup, 0.75) * -0.3 * dTl_Ja_sub *
204 std::pow(1 + Ja_sub, -1.3) * u_bulk_pow;
205
206 // Liftoff diameter (page 47 Kommajosyula PhD)
207 nuc.D_lo = 1.2 * nuc.D_d;
208 nuc.dTp_D_lo = 1.2 * nuc.dTp_D_d;
209 nuc.dTl_D_lo = 1.2 * nuc.dTl_D_d;
210
211 // Bubble growth constant (page 42 Kommajosyula PhD) excluding microlayer contribution
212 const double chi = 1.55 - 0.05 * Delta_T_sub / Delta_T_sup;
213 const double dTp_chi = 0.05 * Delta_T_sub * dTp_Delta_T_sup / std::pow(Delta_T_sup, 2);
214 const double dTl_chi = -0.05 * dTl_Delta_T_sub / Delta_T_sup;
215 const double thermal_diff = in.lambda[n_l] / (in.rho[n_l] * in.Cp[n_l]);
216 const double growth_factor = 2. * std::sqrt(3. / M_PI) * thermal_diff;
217
218 const double K = chi * growth_factor * Ja_sup;
219 const double dTp_K = dTp_chi * growth_factor * Ja_sup + chi * growth_factor * dTp_Ja_sup;
220 const double dTl_K = dTl_chi * growth_factor * Ja_sup;
221
222 // Bubble growth time (page 44 Kommajosyula PhD)
223 nuc.t_g = nuc.D_d * nuc.D_d / (16. * K * K);
224 nuc.dTp_t_g = 2 * nuc.dTp_D_d * nuc.D_d / (16. * K * K)
225 + nuc.D_d * nuc.D_d * -2. * dTp_K / (16. * K * K * K);
226 nuc.dTl_t_g = 2 * nuc.dTl_D_d * nuc.D_d / (16. * K * K)
227 + nuc.D_d * nuc.D_d * -2. * dTl_K / (16. * K * K * K);
228
229 // Bubble wait time (page 56 Kommajosyula PhD)
230 const double t_w = 0.0061 * std::pow(Ja_sub, 0.63) / Delta_T_sup;
231 const double dTp_t_w = 0.0061 * std::pow(Ja_sub, 0.63) * -dTp_Delta_T_sup / std::pow(Delta_T_sup, 2);
232 const double dTl_t_w = 0.0061 * .63 * dTl_Ja_sub * std::pow(Ja_sub, -.37) / Delta_T_sup;
233
234 // Bubble departure frequency (page 51 Kommajosyula PhD)
235 nuc.f_dep = 1 / (nuc.t_g + t_w);
236 nuc.dTp_f_dep = -(nuc.dTp_t_g + dTp_t_w) / std::pow(nuc.t_g + t_w, 2);
237 nuc.dTl_f_dep = -(nuc.dTl_t_g + dTl_t_w) / std::pow(nuc.t_g + t_w, 2);
238
239 return nuc;
240}
241
242Flux_parietal_Kommajosyula::SlidingAreaParams
243Flux_parietal_Kommajosyula::compute_sliding_area(const NucleationParams& nuc, double h_fc, double t_star) const
244{
245 SlidingAreaParams sa {};
246
247 // Active nucleation site density (page 66 Kommajosyula PhD)
248 const double N_0 = nuc.f_dep * nuc.t_g * M_PI * nuc.D_d * nuc.D_d / 4.;
249 const double dTp_N_0 = nuc.dTp_f_dep * nuc.t_g * M_PI * nuc.D_d * nuc.D_d / 4.
250 + nuc.f_dep * nuc.dTp_t_g * M_PI * nuc.D_d * nuc.D_d / 4.
251 + nuc.f_dep * nuc.t_g * M_PI * 2. * nuc.dTp_D_d * nuc.D_d / 4.;
252 const double dTl_N_0 = nuc.dTl_f_dep * nuc.t_g * M_PI * nuc.D_d * nuc.D_d / 4.
253 + nuc.f_dep * nuc.dTl_t_g * M_PI * nuc.D_d * nuc.D_d / 4.
254 + nuc.f_dep * nuc.t_g * M_PI * 2. * nuc.dTl_D_d * nuc.D_d / 4.;
255
256 const double W_val = Lambert_W_function(N_0 * nuc.N_sites);
257 const double dLoc_Lambert = dx_Lambert_W_function(N_0 * nuc.N_sites);
258
259 sa.N_active = W_val / N_0;
260 sa.dTp_N_active = (dTp_N_0 * nuc.N_sites + N_0 * nuc.dTp_N_sites) * dLoc_Lambert / N_0
261 + W_val * -dTp_N_0 / std::pow(N_0, 2);
262 sa.dTl_N_active = (dTl_N_0 * nuc.N_sites + N_0 * nuc.dTl_N_sites) * dLoc_Lambert / N_0
263 + W_val * -dTl_N_0 / std::pow(N_0, 2);
264 sa.dTk_N_active = N_0 * nuc.dTk_N_sites * dLoc_Lambert / N_0;
265
266 if (sa.N_active < 0)
267 Cerr << "nsite " << nuc.N_sites << "N0 " << N_0 << "\n";
268
269 // Single bubble sliding area
270 const double A_sl = std::pow(sa.N_active, -.5) * (nuc.D_d + nuc.D_lo) / 2.;
271 const double dTp_A_sl =
272 -.5 * sa.dTp_N_active * std::pow(sa.N_active, -1.5) * (nuc.D_d + nuc.D_lo) / 2. +
273 std::pow(sa.N_active, -.5) * (nuc.dTp_D_d + nuc.dTp_D_lo) / 2.;
274 const double dTl_A_sl =
275 -.5 * sa.dTl_N_active * std::pow(sa.N_active, -1.5) * (nuc.D_d + nuc.D_lo) / 2. +
276 std::pow(sa.N_active, -.5) * (nuc.dTl_D_d + nuc.dTl_D_lo) / 2.;
277 const double dTk_A_sl =
278 -.5 * sa.dTk_N_active * std::pow(sa.N_active, -1.5) * (nuc.D_d + nuc.D_lo) / 2.;
279
280 // Percentage of the surface occupied by sliding bubbles
281 const double product = A_sl * sa.N_active * nuc.f_dep * t_star;
282 const bool saturated = (1. < product);
283 sa.S_sl = std::min(1., product);
284 sa.dTp_S_sl = saturated ? 0. :
285 dTp_A_sl * sa.N_active * nuc.f_dep * t_star
286 + A_sl * sa.dTp_N_active * nuc.f_dep * t_star
287 + A_sl * sa.N_active * nuc.dTp_f_dep * t_star;
288 sa.dTl_S_sl = saturated ? 0. :
289 dTl_A_sl * sa.N_active * nuc.f_dep * t_star
290 + A_sl * sa.dTl_N_active * nuc.f_dep * t_star
291 + A_sl * sa.N_active * nuc.dTl_f_dep * t_star;
292 sa.dTk_S_sl = saturated ? 0. :
293 dTk_A_sl * sa.N_active * nuc.f_dep * t_star
294 + A_sl * sa.dTk_N_active * nuc.f_dep * t_star;
295
296 return sa;
297}
298
300{
301 if (x < 1/M_E)
302 return x;
303 else if (x > M_E)
304 return std::log(x) - std::log(std::log(x));
305 else
306 return 0.2689*x + 0.2690;
307}
308
310{
311 if (x < 1/M_E)
312 return 1.;
313 else if (x > M_E)
314 return 1./x - 1./(x*std::log(x));
315 else
316 return 0.2689;
317}
static void typer_lire_correlation(OWN_PTR(Correlation_base)&, const Probleme_base &, const Nom &, Entree &)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Wall heat flux correlation for subcooled boiling using the Kommajosyula model.
double theta_
Contact angle on the surface [degrees].
void qp(const input_t &input, output_t &output) const override
double molar_mass_
Molar mass [kg/mol].
classe Flux_parietal_adaptatif classe qui implemente une correlation de flux parietal monophasique
classe Flux_parietal_base correlations de flux parietal de la forme
classe Loi_paroi_adaptative correlation pour une loi de paroi adaptative qui calcule u_tau et du y_pl...
double get_utau(int f) const
Classe Milieu_composite Cette classe represente un fluide reel ainsi que.
bool has_saturation(int k, int l) const
virtual int debute_par(const char *const n) const
Definition Nom.cpp:319
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
@ REQUIRED
Definition Param.h:115
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
const Nom & nom_phase(int i) const
int nb_phases() const
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52