TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Eval_Diff_VDF_Elem_Gen.tpp
1/****************************************************************************
2* Copyright (c) 2026, 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#ifndef Eval_Diff_VDF_Elem_Gen_TPP_included
17#define Eval_Diff_VDF_Elem_Gen_TPP_included
18
19#include <T_paroi_Champ_P0_VDF.h>
20
21template <typename DERIVED_T> template <typename Type_Double>
22inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab& val_b, const int face, const Dirichlet_entree_fluide& la_cl, const int num1, Type_Double& flux) const
23{
24 // Olga avait mis : double dist = 2*Dist_norm_bord(face);
25 // Pierre dit que :
26 const double dist = Dist_norm_bord(face);
27 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
28
29 for (int k = 0; k < ncomp; k++)
30 {
31 if (DERIVED_T::IS_QUASI)
32 {
33 const double T_imp = la_cl.val_imp(face - num1, k);
34 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
35 flux[k] = (i != -1) ? (T_imp - inco(i, k)) / dv_mvol(i) * surface(face) * porosite(face) * nu_1(i, ori) / dist :
36 (inco(j, k) - T_imp) / dv_mvol(j) * surface(face) * porosite(face) * nu_1(j, ori) / dist;
37 }
38 else if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
39 {
40 flux[k] = 0.0;
41 for (int l = 0; l < ncomp; l++)
42 {
43 const double T_imp = la_cl.val_imp(face - num1, l);
44 const int ori = ncomp * k + l;
45
46 flux[k] += (i != -1) ? (T_imp - inco(i, l)) * surface(face) * porosite(face) * nu_1(i, ori) / dist :
47 (inco(j, l) - T_imp) * surface(face) * porosite(face) * nu_1(j, ori) / dist;
48 }
49 }
50 else
51 {
52 const double T_imp = la_cl.val_imp(face - num1, k);
53 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
54
55 flux[k] = (i != -1) ? (T_imp - inco(i, k)) * surface(face) * porosite(face) * nu_1(i, ori) / dist :
56 (inco(j, k) - T_imp) * surface(face) * porosite(face) * nu_1(j, ori) / dist;
57 }
58 }
59}
60
61template <typename DERIVED_T> template <typename Type_Double>
62inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab& val_b, const int face, const Scalaire_impose_paroi& la_cl, const int num1, Type_Double& flux) const
63{
64 const double dist = Dist_norm_bord(face);
65 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
66
67 for (int k = 0; k < ncomp; k++)
68 {
69 if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
70 {
71 flux[k] = 0.0;
72 for (int l = 0; l < ncomp; l++)
73 {
74 const double T_imp = la_cl.val_imp(face-num1, l);
75 const int ori = ncomp * k + l;
76 flux[k] += (i != -1) ? (T_imp-inco(i,l))*surface(face)*porosite(face)*nu_1(i,ori)/dist :
77 (inco(j,l)-T_imp)*surface(face)*porosite(face)*nu_1(j,ori)/dist;
78 }
79 }
80 else
81 {
82 const double T_imp = la_cl.val_imp(face-num1,k);
83 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
84 flux[k] = (i != -1) ? (T_imp-inco(i,k))*surface(face)*porosite(face)*nu_1(i,ori)/dist :
85 (inco(j,k)-T_imp)*surface(face)*porosite(face)*nu_1(j,ori)/dist;
86 }
87 }
88}
89
90template <typename DERIVED_T> template <typename Type_Double>
91inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab& val_b, const int face, const Dirichlet_loi_paroi& la_cl, const int num1, Type_Double& flux) const
92{
93 if (DERIVED_T::IS_MULTI_SCALAR_DIFF) throw;
94
95 const double dist = Dist_norm_bord(face);
96 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
97
98 for (int k = 0; k < ncomp; k++)
99 {
100 const double T_imp = la_cl.val_imp(face-num1,k);
101 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
102 flux[k] = (i != -1) ? (T_imp-inco(i,k))*surface(face)*porosite(face)*nu_1(i,ori)/dist : (inco(j,k)-T_imp)*surface(face)*porosite(face)*nu_1(j,ori)/dist;
103 }
104}
105
106template <typename DERIVED_T> template <typename Type_Double>
107inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& , const DoubleTab& val_b, const int face, const Neumann_paroi& la_cl, const int num1, Type_Double& flux) const
108{
109 const int i = elem_(face,0), ncomp = flux.size_array();
110
111 // XXX LUIS : Note : Pas de distinguo entre MULTISCALAR_DIFF et une diffusion normale pour des CL de Neumann
112 for (int k = 0; k < ncomp; k++)
113 flux[k] = ((i != -1) ? 1 : -1) * la_cl.flux_impose(face - num1, k) * surface(face);
114}
115
116template <typename DERIVED_T> template <typename Type_Double>
117inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab&, const int face, const Periodique& la_cl, const int , Type_Double& flux) const
118{
119 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
120 const double d0 = le_dom->dist_face_elem0_period(face,i,la_cl.distance()), d1 = le_dom->dist_face_elem1_period(face,j,la_cl.distance());
121
122 for (int k = 0; k < ncomp; k++)
123 {
124 if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
125 {
126
127 if (DERIVED_T::IS_ANISO) throw; // XXX LUIS : pas d'anisotropie pour l'instant
128
129 flux[k] = 0.0;
130 for (int l = 0; l < ncomp; l++)
131 {
132 const int comp_diff = ncomp * k + l;
133 double heq = 0.;
134
135 if (nu_1(i,comp_diff) == 0.0 || nu_1(j,comp_diff) == 0.0) heq = 0.;
136 else
137 {
138 assert(nu_1(i,comp_diff) != 0.0 && nu_1(j,comp_diff) != 0.0);
139 heq = compute_heq(d0, i, d1, j, comp_diff);
140 }
141 flux[k] += DERIVED_T::IS_QUASI ? heq*(inco(j,l)/dv_mvol(j) - inco(i,l)/dv_mvol(i))*surface(face)*porosite(face) : heq*(inco(j,l) - inco(i,l))*surface(face)*porosite(face);
142 }
143
144 }
145 else
146 {
147 double heq = -123.;
148 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
149 if (nu_1(i,ori) == 0.0 || nu_1(j,ori) == 0.0) heq = 0.;
150 else
151 {
152 assert(nu_1(i,ori) != 0.0 && nu_1(j,ori) != 0.0);
153 heq = compute_heq(d0,i, d1,j,ori);
154 }
155 flux[k] = DERIVED_T::IS_QUASI ? heq*(inco(j,k)/dv_mvol(j) - inco(i,k)/dv_mvol(i))*surface(face)*porosite(face) : heq*(inco(j,k) - inco(i,k))*surface(face)*porosite(face);
156 }
157 }
158}
159
160template <typename DERIVED_T> template <typename Type_Double>
161inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab& val_b, const int face, const Dirichlet_paroi_fixe&, const int num1, Type_Double& flux ) const
162{
163 if (DERIVED_T::IS_MULTI_SCALAR_DIFF) throw;
164
165 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
166 const double dist = Dist_norm_bord(face);
167
168 if (DERIVED_T::IS_QUASI)
169 for (int k = 0; k < ncomp; k++) flux[k] = (i != -1) ? -inco(i,k)*surface(face)*porosite(face)*nu_1(i,k)/dv_mvol(i)/dist : inco(j,k)*surface(face)*porosite(face)*nu_1(j,k)/dv_mvol(j)/dist;
170 else
171 for (int k = 0; k < ncomp; k++) flux[k] = (i != -1) ? -inco(i,k)*surface(face)*porosite(face)*nu_1(i,k)/dist : inco(j,k)*surface(face)*porosite(face)*nu_1(j,k)/dist;
172}
173
174template <typename DERIVED_T> template <typename Type_Double>
175inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const DoubleTab&, const int face , const Echange_global_impose& la_cl, const int num1, Type_Double& flux) const
176{
177 if (DERIVED_T::IS_MULTI_SCALAR_DIFF) throw;
178 if (DERIVED_T::IS_QUASI) not_implemented_k_eps(__func__);
179
180 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
181
182 for (int k = 0; k < ncomp; k++)
183 {
184 const double h = la_cl.h_imp(face-num1,k), T_ext = la_cl.T_ext(face-num1,k);
185 const double phi_ext = la_cl.has_phi_ext() ? la_cl.flux_exterieur_impose(face-num1,k) : 0;
186 flux[k] = (i != -1) ? (phi_ext+h*(T_ext-inco(i,k)))*surface(face) : (-phi_ext+h*(inco(j,k)-T_ext))*surface(face);
187 }
188}
189
190template <typename DERIVED_T> template <typename Type_Double>
191inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_face(const DoubleTab& inco, const int boundary_index, const int face, const int local_face, const Echange_externe_impose& la_cl, const int num1, Type_Double& flux) const
192{
193 /**
194 * Approach to computing the equivalent heat transfer coefficient and heat flux.
195 *
196 * The problem consists of a solid exchanging heat with an external medium. Heat transfer
197 * occurs via conduction within the solid and convection at the surface. Our objective
198 * is to express the total heat flux in terms of an equivalent heat transfer coefficient `h_eq`.
199 *
200 * ### Step-by-step Demonstration:
201 * 1. **Expression for convective flux at the surface**:
202 * \f[
203 * \phi = h_{imp} (T_b - T_{ext})
204 * \f]
205 * where:
206 * - `h_{imp}` is the convective heat transfer coefficient (W/m2.K),
207 * - `T_b` is the temperature at the solid's surface,
208 * - `T_{ext}` is the external temperature.
209 *
210 * 2. **Expression for conductive flux inside the solid**:
211 * \f[
212 * \phi = \frac{\lambda}{e} (T_{elem} - T_b)
213 * \f]
214 * where:
215 * - `\lambda` is the thermal conductivity of the solid (W/m.K),
216 * - `e` is the distance between the reference point inside the solid and the surface,
217 * - `T_{elem}` is the internal temperature of the solid element.
218 *
219 * 3. **Equating the two flux expressions** (continuity of heat transfer):
220 * \f[
221 * h_{imp} (T_b - T_{ext}) = \frac{\lambda}{e} (T_{elem} - T_b)
222 * \f]
223 *
224 * 4. **Solving for \‍( T_b \‍)**:
225 * \f[
226 * T_b - T_{ext} = \frac{1}{h_{imp}} \phi
227 * \f]
228 * \f[
229 * T_{elem} - T_b = \frac{e}{\lambda} \phi
230 * \f]
231 * By adding these two equations:
232 * \f[
233 * (T_{elem} - T_{ext}) = \frac{1}{h_{imp}} \phi + \frac{e}{\lambda} \phi
234 * \f]
235 *
236 * 5. **Extracting \‍( \phi \‍)**:
237 * \f[
238 * \phi \left( \frac{1}{h_{imp}} + \frac{e}{\lambda} \right) = T_{elem} - T_{ext}
239 * \f]
240 * \f[
241 * \phi = \frac{T_{elem} - T_{ext}}{\frac{1}{h_{imp}} + \frac{e}{\lambda}}
242 * \f]
243 *
244 * 6. **Defining the equivalent heat transfer coefficient \‍( h_{eq} \‍)**:
245 * \f[
246 * h_{eq} = \frac{1}{\frac{1}{h_{imp}} + \frac{e}{\lambda}}
247 * \f]
248 *
249 * 7. **Final flux expression**:
250 * \f[
251 * \phi = h_{eq} (T_{elem} - T_{ext})
252 * \f]
253 *
254 * This demonstrates that the system can be treated as a single equivalent convection
255 * problem with `h_eq`, which accounts for both conduction inside the solid and convection
256 * at the surface, involving the VDF unknown `T_{elem}`
257 *
258 * ### Case of Convection + Radiative Transfer:
259 * When radiative heat transfer is also present, the substitution method used above is
260 * no longer valid because the radiative flux depends non-linearly on the surface temperature
261 * \‍( T_b \‍). The total flux at the surface then becomes:
262 * \f[
263 * \phi = h_{imp} (T_b - T_{ext}) + \sigma \varepsilon (T_b^4 - T_{ext}^4)
264 * \f]
265 * where:
266 * - \‍( \sigma \‍) is the Stefan-Boltzmann constant,
267 * - \‍( \varepsilon \‍) is the emissivity of the surface,
268 * - \‍( T_{ext} \‍) is the effective radiative temperature of the surroundings.
269 *
270 * Since this equation is non-linear in \‍( T_b \‍), we cannot directly substitute it
271 * as in the purely convective case. Instead, we solve for \‍( T_b \‍) using an iterative
272 * method such as Newton-Raphson. Once \‍( T_b \‍) is found, we use it to determine the heat flux.
273 */
274
275 if (DERIVED_T::IS_QUASI) not_implemented_k_eps(__func__);
276 double e;
277 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
278
279 if (DERIVED_T::IS_MODIF_DEQ) e = ind_Fluctu_Term()==1 ? Dist_norm_bord_externe_(face) : equivalent_distance(boundary_index,local_face);
280 else e = DERIVED_T::IS_DEQUIV ? equivalent_distance(boundary_index,local_face) : Dist_norm_bord_externe_(face);
281
282 int elem_opp = -1;
283 if (sub_type(Echange_interne_impose, la_cl))
284 {
285 // In this case, T_ext might change within the timestep (e.g. Newton's algorithm used for the
286 // variable gap model). Make sure we get the most up-to-date value.
287 const Echange_interne_impose& cl = ref_cast(Echange_interne_impose, la_cl);
288 const Champ_front_calc_interne& Text = ref_cast(Champ_front_calc_interne, cl.T_ext());
289 const IntVect& fmap = Text.face_map();
290 int opp_face = fmap[face-num1]+num1; // num1 is the index of the first face
291 int elem1 = le_dom->face_voisins(opp_face, 0);
292 elem_opp = (elem1 != -1) ? elem1 : le_dom->face_voisins(opp_face, 1);
293 }
294
295 const bool is_radiatif = la_cl.has_emissivite();
296
297 // XXX : E. Saikali 08/03/2021 : The test of a zero diffusion was not done before. I think it should be like that
298 // Attention for DIFT OPERATORS : nu_2 and not nu_1 (only laminar part)
299 if (i != -1)
300 {
301 for (int k = 0; k < ncomp; k++)
302 {
303 flux[k] = 0.0;
304 for (int l = (DERIVED_T::IS_MULTI_SCALAR_DIFF ? 0 : k); l < (DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp : k + 1); l++)
305 {
306 const int ori = DERIVED_T::IS_MULTI_SCALAR_DIFF ? (ncomp * k + l) : (DERIVED_T::IS_ANISO ? orientation(face) : k);
307 const double h_imp = la_cl.h_imp(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k), T_ext = (elem_opp == -1) ? la_cl.T_ext(face - num1, l) : inco(elem_opp, l);
308
309 if (is_radiatif)
310 {
311 const double eps = la_cl.emissivite(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
312 const double Tb = newton_T_paroi_VDF(eps, h_imp, T_ext, nu_2(i, ori), e, inco(i, l));
313 flux[k] += (COEFF_STEFAN_BOLTZMANN * eps * (T_ext * T_ext * T_ext * T_ext - Tb * Tb * Tb * Tb) + h_imp * (T_ext - Tb)) * surface(face);
314 }
315 else
316 {
317 const double heq = (nu_2(i, ori) == 0.0 || h_imp == 0.0) ? 0.0 : 1.0 / (1.0 / h_imp + e / nu_2(i, ori));
318 flux[k] += heq * (T_ext - inco(i, l)) * surface(face);
319 }
320 }
321 }
322 }
323 else // j != -1
324 {
325 for (int k = 0; k < ncomp; k++)
326 {
327 flux[k] = 0.0;
328 for (int l = (DERIVED_T::IS_MULTI_SCALAR_DIFF ? 0 : k); l < (DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp : k + 1); l++)
329 {
330 const int ori = DERIVED_T::IS_MULTI_SCALAR_DIFF ? (ncomp * k + l) : (DERIVED_T::IS_ANISO ? orientation(face) : k);
331 const double h_imp = la_cl.h_imp(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k), T_ext = (elem_opp == -1) ? la_cl.T_ext(face - num1, l) : inco(elem_opp, l);
332
333 if (is_radiatif)
334 {
335 const double eps = la_cl.emissivite(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
336 const double Tb = newton_T_paroi_VDF(eps, h_imp, T_ext, nu_2(j, ori), e, inco(j, l));
337 flux[k] += (COEFF_STEFAN_BOLTZMANN * eps * (Tb * Tb * Tb * Tb - T_ext * T_ext * T_ext * T_ext) + h_imp * (Tb - T_ext)) * surface(face);
338 }
339 else
340 {
341 const double heq = (nu_2(j, ori) == 0.0 || h_imp == 0.0) ? 0.0 : 1.0 / (1.0 / h_imp + e / nu_2(j, ori));
342 flux[k] += heq * (inco(j, l) - T_ext) * surface(face);
343 }
344 }
345 }
346 }
347}
348
349template <typename DERIVED_T> template <typename Type_Double>
350inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::flux_faces_interne(const DoubleTab& inco, const int face, Type_Double& flux) const
351{
352 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
353 double heq, d0 = Dist_face_elem0(face,i), d1 = Dist_face_elem1(face,j);
354 for (int k = 0; k < ncomp; k++)
355 {
356 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
357 if (DERIVED_T::IS_RANS)
358 {
359 heq = compute_heq(d0,i, d1,j,ori); // pas d'assert pour k-eps !
360 flux[k] = DERIVED_T::IS_QUASI ? heq*(inco(j,k)/dv_mvol(j) - inco(i,k)/dv_mvol(i))*surface(face)*porosite(face) :
361 heq*(inco(j,k)-inco(i,k))*surface(face)*porosite(face);
362 }
363 else if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
364 {
365 flux[k] = 0.0;
366 for (int l = 0; l < ncomp; l++)
367 {
368 const int comp_diff = ncomp * k + l;
369 if (nu_1(i,comp_diff) == 0.0 || nu_1(j,comp_diff) == 0.0) heq = 0.;
370 else
371 {
372 assert(nu_1(i,comp_diff) != 0.0 && nu_1(j,comp_diff) != 0.0);
373 heq = compute_heq(d0, i, d1, j, comp_diff);
374 }
375 flux[k] += heq * (inco(j, l) - inco(i, l)) * surface(face) * porosite(face);
376 }
377 }
378 else
379 {
380 if (nu_1(i,ori) == 0.0 || nu_1(j,ori) == 0.0) heq = 0.;
381 else
382 {
383 assert(nu_1(i,ori) != 0.0 && nu_1(j,ori) != 0.0);
384 heq = compute_heq(d0,i, d1,j,ori);
385 }
386 flux[k] = heq*(inco(j,k)-inco(i,k))*surface(face)*porosite(face);
387 }
388 }
389}
390
391/* ************************************** *
392 * ********* POUR L'IMPLICITE ********** *
393 * ************************************** */
394
395template <typename DERIVED_T> template <typename Type_Double>
396inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int, const Dirichlet_entree_fluide& la_cl, Type_Double& aii, Type_Double& ajj) const
397{
398 assert (aii.size_array() == ajj.size_array());
399 const int i = elem_(face,0), j = elem_(face,1),
400 ncomp = DERIVED_T::IS_MULTI_SCALAR_DIFF ? static_cast<int>(std::sqrt(aii.size_array())) : aii.size_array();
401
402 const double dist = Dist_norm_bord(face);
403
404 for (int k = 0; k < ncomp; k++)
405 if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
406 {
407 for (int l = 0; l < ncomp; l++)
408 {
409 const int ori = ncomp * k + l;
410 aii[ori] = (i != -1) ? porosite(face) * nu_1(i, ori) * surface(face) / dist : 0.;
411 ajj[ori] = (i != -1) ? 0. : porosite(face) * nu_1(j, ori) * surface(face) / dist;
412 }
413 }
414 else
415 {
416 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
417 aii[k] = (i != -1) ? porosite(face) * nu_1(i, ori) * surface(face) / dist : 0.;
418 ajj[k] = (i != -1) ? 0. : porosite(face) * nu_1(j, ori) * surface(face) / dist;
419 }
420}
421
422template <typename DERIVED_T> template <typename Type_Double>
423inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int, const Scalaire_impose_paroi& la_cl, Type_Double& aii, Type_Double& ajj) const
424{
425 assert (aii.size_array() == ajj.size_array());
426 const int i = elem_(face,0), j = elem_(face,1),
427 ncomp = DERIVED_T::IS_MULTI_SCALAR_DIFF ? static_cast<int>(std::sqrt(aii.size_array())) : aii.size_array();
428
429 const double dist = Dist_norm_bord(face);
430
431 for (int k = 0; k < ncomp; k++)
432 if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
433 {
434 for (int l = 0; l < ncomp; l++)
435 {
436 const int ori = ncomp * k + l;
437 aii[ori] = (i != -1) ? porosite(face) * nu_1(i, ori) * surface(face) / dist : 0.;
438 ajj[ori] = (i != -1) ? 0. : porosite(face) * nu_1(j, ori) * surface(face) / dist;
439 }
440 }
441 else
442 {
443 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
444 aii[k] = (i != -1) ? porosite(face) * nu_1(i, ori) * surface(face) / dist : 0.;
445 ajj[k] = (i != -1) ? 0. : porosite(face) * nu_1(j, ori) * surface(face) / dist;
446 }
447}
448
449template <typename DERIVED_T> template <typename Type_Double>
450inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int, const Dirichlet_loi_paroi& la_cl, Type_Double& aii, Type_Double& ajj) const
451{
452 assert (aii.size_array() == ajj.size_array());
453 const int i = elem_(face,0), j = elem_(face,1), ncomp = aii.size_array();
454 const double dist = Dist_norm_bord(face);
455 for (int k = 0; k < ncomp; k++)
456 {
457 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
458 aii[k] = (i != -1) ? porosite(face)*nu_1(i,ori)*surface(face) / dist : 0.;
459 ajj[k] = (i != -1) ? 0. : porosite(face)*nu_1(j,ori)*surface(face) / dist;
460 }
461}
462
463template <typename DERIVED_T> template <typename Type_Double>
464inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int, const Periodique& la_cl, Type_Double& aii, Type_Double& ajj ) const
465{
466 assert (aii.size_array() == ajj.size_array());
467 const int i = elem_(face,0), j = elem_(face,1), ncomp = DERIVED_T::IS_MULTI_SCALAR_DIFF ? int(sqrt(aii.size_array())) : aii.size_array();
468 const double d0 = le_dom->dist_face_elem0_period(face,i,la_cl.distance()), d1 = le_dom->dist_face_elem1_period(face,j,la_cl.distance());
469 for (int k = 0; k < ncomp; k++)
470 {
471 if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
472 {
473 for (int l = 0; l < ncomp; l++)
474 {
475 const int ori = ncomp * k + l;
476 double heq;
477 if (nu_1(i,ori) == 0.0 || nu_1(j,ori) == 0.0) heq = 0.;
478 else
479 {
480 assert(nu_1(i,ori) != 0.0 && nu_1(j,ori) != 0.0);
481 heq = compute_heq(d0, i, d1, j, ori);
482 }
483 aii[ori] = heq * surface(face) * porosite(face);
484 ajj[ori] = heq * surface(face) * porosite(face);
485 }
486 }
487 else
488 {
489 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
490 double heq;
491 if (nu_1(i,ori) == 0.0 || nu_1(j,ori) == 0.0) heq = 0.;
492 else
493 {
494 assert(nu_1(i,ori) != 0.0 && nu_1(j,ori) != 0.0);
495 heq = compute_heq(d0, i, d1, j, ori);
496 }
497 aii[k] = ajj[k] = heq*surface(face)*porosite(face); // On peut faire ca !
498 }
499 }
500}
501
502template <typename DERIVED_T> template <typename Type_Double>
503inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int num1, const Dirichlet_paroi_fixe&, Type_Double& aii , Type_Double& ajj) const
504{
505 assert (aii.size_array() == ajj.size_array());
506 const int i = elem_(face,0), j = elem_(face,1), ncomp = aii.size_array();
507 const double dist = Dist_norm_bord(face);
508 if (DERIVED_T::IS_QUASI)
509 {
510 for (int k = 0; k < ncomp; k++)
511 {
512 aii[k] = (i != -1) ? surface(face)*porosite(face)*nu_1(i,k)/dv_mvol(i)/dist : 0.;
513 ajj[k] = (i != -1) ? 0. : surface(face)*porosite(face)*nu_1(j,k)/dv_mvol(j)/dist;
514 }
515 }
516 else
517 for (int k = 0; k < ncomp; k++)
518 {
519 aii[k] = (i != -1) ? surface(face)*porosite(face)*nu_1(i,k)/dist : 0.;
520 ajj[k] = (i != -1) ? 0. : surface(face)*porosite(face)*nu_1(j,k)/dist;
521 }
522}
523
524template <typename DERIVED_T> template <typename Type_Double>
525inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const int face, const int num1, const Echange_global_impose& la_cl, Type_Double& aii, Type_Double& ajj ) const
526{
527 assert (aii.size_array() == ajj.size_array());
528 const int i = elem_(face,0), ncomp = aii.size_array();
529 for (int k = 0; k < ncomp; k++)
530 {
531 const double h = la_cl.h_imp(face-num1,k);
532 const double dphi_dT = la_cl.has_phi_ext() ? la_cl.derivee_flux_exterieur_imposee(face-num1,k) : 0;
533 aii[k] = (i != -1) ? (dphi_dT + h)*surface(face) : 0.;
534 ajj[k] = (i != -1) ? 0. : (dphi_dT + h)*surface(face);
535 }
536}
537
538template <typename DERIVED_T> template <typename Type_Double>
539inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_face(const DoubleTab& inco ,const int boundary_index, const int face, const int local_face, const int num1, const Echange_externe_impose& la_cl, Type_Double& aii, Type_Double& ajj) const
540{
541 // C.L de type Echange_externe_impose : 1/h_total = (1/h_imp) + (e/diffusivite) : La C.L fournit h_imp ; il faut calculer e/diffusivite
542 assert (aii.size_array() == ajj.size_array());
543 const int i = elem_(face,0), j = elem_(face,1), ncomp = DERIVED_T::IS_MULTI_SCALAR_DIFF ? int(sqrt(aii.size_array())) : aii.size_array();
544 double e, heq, h_total_inv;
545
546 if (DERIVED_T::IS_MODIF_DEQ) e = ind_Fluctu_Term() == 1 ? Dist_norm_bord_externe_(face) : equivalent_distance(boundary_index,local_face);
547 else e = DERIVED_T::IS_DEQUIV ? equivalent_distance(boundary_index,local_face) : Dist_norm_bord_externe_(face);
548
549 const bool is_internal = sub_type(Echange_interne_impose, la_cl), is_radiatif = la_cl.has_emissivite();
550
551 if (i != -1)
552 for (int k = 0; k < ncomp; k++)
553 for (int l = (DERIVED_T::IS_MULTI_SCALAR_DIFF ? 0 : k); l < (DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp : k + 1); l++)
554 {
555 const int ori = DERIVED_T::IS_MULTI_SCALAR_DIFF ? (ncomp * k + l) : (DERIVED_T::IS_ANISO ? orientation(face) : k);
556 const double h_imp = la_cl.h_imp(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
557 if (nu_2(i, ori) == 0.0 || h_imp == 0.0)
558 heq = 0.0;
559 else
560 {
561 h_total_inv = 1.0 / h_imp + e / nu_2(i, ori);
562 heq = 1.0 / h_total_inv;
563 }
564 aii[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] = heq * surface(face);
565 ajj[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] = is_internal ? heq * surface(face) : 0.;
566
567 if (is_radiatif)
568 {
569 const double eps = la_cl.emissivite(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
570 const double T = inco(i, l);
571 aii[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] += 4 * COEFF_STEFAN_BOLTZMANN * eps * T * T * T * surface(face);
572 }
573 }
574 else
575 for (int k = 0; k < ncomp; k++)
576 for (int l = (DERIVED_T::IS_MULTI_SCALAR_DIFF ? 0 : k); l < (DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp : k + 1); l++)
577 {
578 const int ori = DERIVED_T::IS_MULTI_SCALAR_DIFF ? (ncomp * k + l) : (DERIVED_T::IS_ANISO ? orientation(face) : k);
579 const double h_imp = la_cl.h_imp(face - num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
580 if (nu_2(j, ori) == 0.0 || h_imp == 0.0)
581 heq = 0.0;
582 else
583 {
584 h_total_inv = 1.0 / h_imp + e / nu_2(j, ori);
585 heq = 1.0 / h_total_inv;
586 }
587 ajj[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] = heq * surface(face);
588 aii[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] = is_internal ? heq * surface(face) : 0.;
589
590 if (is_radiatif)
591 {
592 const double eps = la_cl.emissivite(face-num1, DERIVED_T::IS_MULTI_SCALAR_DIFF ? ori : k);
593 const double T = inco(j, l);
594 ajj[DERIVED_T::IS_MULTI_SCALAR_DIFF ? ncomp * k + l : k] += 4 * COEFF_STEFAN_BOLTZMANN * eps * T * T * T * surface(face);
595 }
596 }
597}
598
599template <typename DERIVED_T> template <typename Type_Double>
600inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::coeffs_faces_interne(const int face, Type_Double& aii, Type_Double& ajj ) const
601{
602 assert (aii.size_array() == ajj.size_array());
603 const int i = elem_(face,0), j = elem_(face,1), ncomp = DERIVED_T::IS_MULTI_SCALAR_DIFF ? int(sqrt(aii.size_array())) : aii.size_array();
604 double heq, d0 = Dist_face_elem0(face,i), d1 = Dist_face_elem1(face,j);
605 for (int k = 0; k < ncomp; k++)
606 {
607 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
608 if (DERIVED_T::IS_RANS)
609 {
610 heq = compute_heq(d0,i,d1,j,ori);
611 aii[k] = ajj[k] = heq*surface(face)*porosite(face); // On peut faire ca !
612 }
613 else if (DERIVED_T::IS_MULTI_SCALAR_DIFF)
614 {
615 for (int l = 0; l < ncomp; l++)
616 {
617 const int comp_diff = ncomp * k + l;
618 if (nu_1(i,comp_diff) == 0.0 || nu_1(j,comp_diff) == 0.0) heq = 0.;
619 else
620 {
621 assert(nu_1(i,comp_diff) != 0.0 && nu_1(j,comp_diff) != 0.0);
622 heq = compute_heq(d0,i,d1,j,comp_diff);
623 }
624 aii[comp_diff] = heq * surface(face) * porosite(face);
625 ajj[comp_diff] = heq * surface(face) * porosite(face);
626 }
627 }
628 else
629 {
630 if (nu_1(i,ori) == 0.0 || nu_1(j,ori) == 0.0) heq = 0.;
631 else
632 {
633 assert(nu_1(i,ori) != 0.0 && nu_1(j,ori) != 0.0);
634 heq = compute_heq(d0,i,d1,j,ori);
635 }
636 aii[k] = ajj[k] = heq*surface(face)*porosite(face); // On peut faire ca !
637 }
638 }
639}
640
641///////////////////////////////////////////////////////////////
642// A virer un jour .. voir avec le baltik Rayonnement
643template <typename DERIVED_T> template <typename Type_Double>
644inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::secmem_face(const int face, const Dirichlet_entree_fluide& la_cl, const int num1, Type_Double& flux) const
645{
646 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
647 double dist = Dist_norm_bord(face);
648 for (int k = 0; k < ncomp; k++)
649 {
650 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
651 const double T_imp = la_cl.val_imp(face-num1,k);
652 flux[k] = (i != -1) ? T_imp*surface(face)*porosite(face)*nu_1(i,ori) / dist : -T_imp*surface(face)*(porosite(face)*nu_1(j,ori)) / dist;
653 }
654}
655
656template <typename DERIVED_T> template <typename Type_Double>
657inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::secmem_face(const int face, const Neumann_paroi& la_cl, const int num1, Type_Double& flux) const
658{
659 const int i = elem_(face,0), ncomp = flux.size_array();
660 for (int k = 0; k < ncomp; k++) flux[k] = ((i != -1) ? 1 : -1) * la_cl.flux_impose(face-num1,k)*surface(face);
661}
662
663template <typename DERIVED_T> template <typename Type_Double>
664inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::secmem_face(const int face, const Echange_global_impose& la_cl, const int num1, Type_Double& flux) const
665{
666 const int i = elem_(face,0), ncomp = flux.size_array();
667 for (int k = 0; k < ncomp; k++)
668 {
669 const double h = la_cl.h_imp(face-num1,k), T_ext = la_cl.T_ext(face-num1,k);
670 const double phi_ext = la_cl.has_phi_ext() ? la_cl.flux_exterieur_impose(face-num1, k) : 0.;
671 flux[k] = ((i != -1) ? 1.0 : -1.0) * (phi_ext + h * T_ext) * surface(face);
672 }
673}
674
675template <typename DERIVED_T> template <typename Type_Double>
676inline void Eval_Diff_VDF_Elem_Gen<DERIVED_T>::secmem_face(const int boundary_index, const int face, const int local_face, const Echange_externe_impose& la_cl, const int num1, Type_Double& flux) const
677{
678 // C.L de type Echange_externe_impose : 1/h_total = (1/h_imp) + (e/diffusivite) : La C.L fournit h_imp ; il faut calculer e/diffusivite
679 double e, h_total_inv, heq;
680 const int i = elem_(face,0), j = elem_(face,1), ncomp = flux.size_array();
681
682 if (DERIVED_T::IS_MODIF_DEQ) e = (ind_Fluctu_Term() == 1) ? Dist_norm_bord_externe_(face) : equivalent_distance(boundary_index,local_face);
683 else e = DERIVED_T::IS_DEQUIV ? equivalent_distance(boundary_index,local_face) : Dist_norm_bord_externe_(face);
684
685 if (i != -1)
686 {
687 for (int k = 0; k < ncomp; k++)
688 {
689 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
690 const double h_imp = la_cl.h_imp(face-num1,k), T_ext = la_cl.T_ext(face-num1, k);
691 if (nu_2(i,ori) == 0.0) heq = 0.0;
692 else
693 {
694 h_total_inv = 1.0/h_imp + e/nu_2(i,ori);
695 heq = 1.0 / h_total_inv;
696 }
697 flux[k] = heq*T_ext*surface(face);
698 }
699 }
700 else
701 {
702 for (int k = 0; k < ncomp; k++)
703 {
704 const int ori = DERIVED_T::IS_ANISO ? orientation(face) : k;
705 const double h_imp = la_cl.h_imp(face-num1,k), T_ext = la_cl.T_ext(face-num1, k);
706 if (nu_2(j,ori) == 0.0) heq = 0.0;
707 else
708 {
709 h_total_inv = 1.0/h_imp + e/nu_2(j,ori);
710 heq = 1.0 / h_total_inv;
711 }
712 flux[k] = -heq*T_ext*surface(face);
713 }
714 }
715}
716
717#endif /* Eval_Diff_VDF_Elem_Gen_TPP_included */
classe Champ_front_calc_interne Classe derivee de Champ_front_calc qui represente
const IntVect & face_map() const
classe Dirichlet_entree_fluide Cette classe represente une condition aux limite imposant une grandeur
Classe Dirichlet_loi_paroi Classe de base pour les valeurs impose pour une condition aux limites des ...
virtual double val_imp(int i) const override
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
classe Dirichlet_paroi_fixe Represente une paroi immobile dans une equation de type Navier_Stokes.
virtual double val_imp(int i) const
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
Definition Dirichlet.cpp:35
Classe Echange_externe_impose: Cette classe represente le cas particulier de la classe.
Classe Echange_global_impose Cette classe represente le cas particulier de la classe.
virtual double flux_exterieur_impose(int i) const
const bool & has_phi_ext() const
virtual double derivee_flux_exterieur_imposee(int i) const
virtual double h_imp(int num) const
Renvoie la valeur du coefficient d'echange de chaleur impose sur la i-eme composante.
virtual double T_ext(int num) const
Renvoie la valeur de la temperature imposee sur la i-eme composante du champ de frontiere.
double emissivite(int num) const
Renvoie la valeur de l'emissivite impose sur la i-eme composante.
Classe Echange_interne_impose: Cette classe represente le cas particulier de la classe.
void flux_face(const DoubleTab &, const DoubleTab &, const int, const BC &, int, Type_Double &) const
void coeffs_face(const int, const int, const BC &, Type_Double &, Type_Double &) const
void secmem_face(const int, const BC &, const int, Type_Double &) const
void coeffs_faces_interne(const int, Type_Double &, Type_Double &) const
void flux_faces_interne(const DoubleTab &, const int, Type_Double &) const
DoubleVect porosite
DoubleVect surface
Classe Neumann_paroi Cette condition limite correspond a un flux impose pour l'equation de.
virtual double flux_impose(int i) const
Renvoie la valeur du flux impose sur la i-eme composante du champ representant le flux a la frontiere...
Definition Neumann.cpp:35
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
double distance() const
Definition Periodique.h:37
classe Scalaire_impose_paroi Impose un scalaire a la paroi dans une equation de type Convection-Difus...