TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_Face_VDF.cpp
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#include <Dirichlet_entree_fluide_leaves.h>
17#include <Dirichlet_paroi_defilante.h>
18#include <Champ_Uniforme_Morceaux.h>
19#include <Dirichlet_paroi_fixe.h>
20#include <Modele_turbulence_hyd_base.h>
21#include <Champ_Uniforme.h>
22#include <Champ_Face_VDF.h>
23#include <Domaine_Cl_VDF.h>
24#include <distances_VDF.h>
25#include <Equation_base.h>
26#include <Champ_Don_lu.h>
27#include <Fluide_base.h>
28#include <Periodique.h>
29#include <Option_VDF.h>
30#include <Navier.h>
31
32// XXX : Elie Saikali : keeping Champ_Face as well, otherwise typer and reprise would need to be changed in many places ...
33Implemente_instanciable(Champ_Face_VDF,"Champ_Face|Champ_Face_VDF",Champ_Face_base);
34
35Sortie& Champ_Face_VDF::printOn(Sortie& s) const { return s << que_suis_je() << " " << le_nom(); }
36
38{
39 lire_donnees (s) ;
40 return s ;
41}
42
44{
45 assert(nb_noeuds == domaine_vdf().nb_faces());
47 // Problem: nb_comp equals 2 but only one dimension is wanted !!!
48 // HACK :
49 int old_nb_compo = nb_compo_;
52 nb_compo_ = old_nb_compo;
53 return nb_noeuds;
54}
55
57{
58 tau_diag_.resize(domaine_vdf().nb_elem(), dimension);
59 tau_croises_.resize(domaine_vdf().nb_aretes(), 2);
60}
61
63{
64 DoubleTab& val = valeurs();
65 const Domaine_VDF& domaine_VDF = domaine_vdf();
66 const IntVect& orientation = domaine_VDF.orientation();
67 const int N = val.dimension(1), unif = sub_type(Champ_Uniforme, ch), D = dimension;
68
69 if ((sub_type(Champ_Uniforme_Morceaux, ch)) || (sub_type(Champ_Don_lu, ch)))
70 {
71 const DoubleTab& v = ch.valeurs();
72 int ndeb_int = domaine_VDF.premiere_face_int();
73 const IntTab& f_e = domaine_VDF.face_voisins();
74
75 for (int f = 0; f < ndeb_int; f++)
76 {
77 const int ori = orientation(f);
78 const int e = f_e(f, f_e(f, 0) == -1);
79 for (int n = 0; n < N; n++)
80 val(f, n) = v(e, N * ori + n);
81 }
82
83 for (int f = ndeb_int; f < domaine_VDF.nb_faces(); f++)
84 {
85 const int ori = orientation(f);
86 for (int n = 0; n < N; n++)
87 val(f, n) = 0.5 * (v(f_e(f, 0), N * ori + n) + v(f_e(f, 1), N * ori + n));
88 }
89 }
90 else
91 {
92
93 DoubleTab eval;
94 if (unif) eval = ch.valeurs();
95 else eval.resize(val.dimension(0), N * D), ch.valeur_aux(domaine_VDF.xv(), eval);
96
97 for (int f = 0; f < domaine_VDF.nb_faces(); f++)
98 for (int n = 0; n < N; n++)
99 val(f, n) = eval(unif ? 0 : f, N * orientation(f) + n);
100 }
102 return *this;
103}
104
105const Champ_Proto& Champ_Face_VDF::affecter(const double x1, const double x2)
106{
107 const IntVect& orientation = domaine_vdf().orientation();
108 DoubleTab& val = valeurs();
109 for (int num_face = 0; num_face < val.size(); num_face++)
110 {
111 int ori = orientation(num_face);
112 switch(ori)
113 {
114 case 0:
115 val(num_face) = x1;
116 break;
117 case 1:
118 val(num_face) = x2;
119 break;
120 }
121 }
122 return *this;
123}
124
125const Champ_Proto& Champ_Face_VDF::affecter(const double x1, const double x2, const double x3)
126{
127 const IntVect& orientation = domaine_vdf().orientation();
128 DoubleTab& val = valeurs();
129 for (int num_face = 0; num_face < val.size(); num_face++)
130 {
131 int ori = orientation(num_face);
132 switch(ori)
133 {
134 case 0:
135 val(num_face) = x1;
136 break;
137 case 1:
138 val(num_face) = x2;
139 break;
140 case 2:
141 val(num_face) = x3;
142 break;
143 }
144 }
145 return *this;
146}
147
148const Champ_Proto& Champ_Face_VDF::affecter(const DoubleTab& v)
149{
150 const IntVect& orientation = domaine_vdf().orientation();
151 DoubleTab& val = valeurs();
152
153 if (v.nb_dim() == 2)
154 {
155 if (v.dimension(1) == dimension)
156 {
157 if (v.dimension(0) == val.size())
158 for (int num_face = 0; num_face < val.size(); num_face++)
159 val(num_face) = v(num_face, orientation(num_face));
160 else
161 {
162 Cerr << "TRUST error in Champ_Face_VDF::affecter(const DoubleTab& )" << finl;
163 Cerr << "The dimensions of the DoubleTab passed as parameter are incompatible with those of Champ_Face_VDF " << finl;
165 }
166 }
167 else
168 {
169 Cerr << "TRUST error in Champ_Face_VDF::affecter(const DoubleTab& )" << finl;
170 Cerr << "The dimensions of the DoubleTab passed as parameter are incompatible with those of Champ_Face_VDF " << finl;
172 }
173 }
174 return *this;
175}
176
177// Periodic BC case: ensures that values on periodic faces facing each other are identical. For this we take the half-sum of the two values.
179{
180 const Domaine_Cl_dis_base& zcl = domaine_Cl_dis();
181 int nb_cl = zcl.nb_cond_lim();
182 DoubleTab& ch_tab = valeurs();
183 int ndeb, nfin, num_face;
184
185 for (int i = 0; i < nb_cl; i++)
186 {
187 const Cond_lim_base& la_cl = zcl.les_conditions_limites(i).valeur();
188 if (sub_type(Periodique, la_cl))
189 {
190 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl);
191 const Front_VF& le_bord = ref_cast(Front_VF, la_cl.frontiere_dis());
192 ndeb = le_bord.num_premiere_face();
193 nfin = ndeb + le_bord.nb_faces();
194 int voisine;
195 double moy;
196
197 for (num_face = ndeb; num_face < nfin; num_face++)
198 {
199 voisine = la_cl_perio.face_associee(num_face - ndeb) + ndeb;
200 if (ch_tab[num_face] != ch_tab[voisine])
201 {
202 moy = 0.5 * (ch_tab[num_face] + ch_tab[voisine]);
203 ch_tab[num_face] = moy;
204 ch_tab[voisine] = moy;
205 }
206 }
207 }
208 }
209 ch_tab.echange_espace_virtuel();
210}
211
212/*! @brief Returns the value the field should have on a boundary face, according to the boundary conditions.
213 *
214 * @brief The index is counted in the list of real boundary faces. The time considered is the
215 * current time of the Champ_Face.
216 * The implementation has changed: these values are no longer stored in the field.
217 *
218 */
219double Champ_Face_VDF::val_imp_face_bord_private(int face, int comp) const
220{
221 const Domaine_Cl_VDF& zclo = ref_cast(Domaine_Cl_VDF, equation().domaine_Cl_dis());
222 return Champ_Face_get_val_imp_face_bord_sym(valeurs(), temps(), face, comp, zclo);
223}
224
225// WEC : never called !!
226double Champ_Face_VDF::val_imp_face_bord_private(int face, int comp1, int comp2) const
227{
228 Cerr << "Champ_Face_VDF::val_imp_face_bord(,,) exit" << finl;
230 return 0; // For compilers
231}
232
233// This function returns:
234// 1 if the fluid is outgoing on face num_face
235// 0 if the face corresponds to a fluid re-entry
237{
238 int signe = 1;
239 double vit_norm;
240 // signe is -1 if face_voisins(num_face,0) is on the outside
241 // signe is 1 if face_voisins(num_face,1) is on the outside
242 if (domaine_vdf().face_voisins(num_face, 0) == -1)
243 signe = -1;
244 vit_norm = valeurs()(num_face) * signe;
245 return (vit_norm > 0);
246}
247
248DoubleTab& Champ_Face_VDF::trace(const Frontiere_dis_base& fr, DoubleTab& x, double tps, int distant) const
249{
250 return Champ_Face_VDF_implementation::trace(fr, valeurs(tps), x, distant);
251}
252
253void Champ_Face_VDF::mettre_a_jour(double un_temps)
254{
256}
257
259{
260 const DoubleTab& val = valeurs();
261 const Domaine_VDF& domaine_VDF = domaine_vdf();
262 int nb_elem = domaine_VDF.nb_elem();
263 const IntTab& face_voisins = domaine_VDF.face_voisins();
264 const IntTab& elem_faces = domaine_VDF.elem_faces();
265
266 if (dimension == 2)
267 calrotord2centelemdim2(rot, val, domaine_VDF, nb_elem, face_voisins, elem_faces);
268 else if (dimension == 3)
269 calrotord2centelemdim3(rot, val, domaine_VDF, nb_elem, face_voisins, elem_faces);
270}
271
272int Champ_Face_VDF::imprime(Sortie& os, int ncomp) const
273{
274 imprime_Face(os, ncomp);
275 return 1;
276}
277
278void Champ_Face_VDF::calcul_critere_Q(DoubleTab& Q, const Domaine_Cl_VDF& domaine_Cl_VDF)
279{
280 // Q=0.5*(\Omega_{ij}*\Omega_{ij}-S_{ij}*S_{ij})=-0.25*du_i/dx_j*du_j/dx_i
281
282 const Domaine_VDF& domaine_VDF = domaine_vdf();
283 Champ_Face_VDF& vit = *this;
284 const DoubleTab& vitesse = valeurs();
285 const int nb_elem = domaine_VDF.nb_elem();
286 const int nb_elem_tot = domaine_VDF.nb_elem_tot();
287 int num_elem, i, j, N = vitesse.line_size();
288 double crit, deriv1, deriv2;
289
290 if (N!=1) Process::exit(que_suis_je() + "::calcul_critere_Q : the velocity field must be single phase !!");
291
292 DoubleTab gradient_elem(nb_elem_tot, dimension, dimension, N);
293 gradient_elem = 0.;
294
295 vit.calcul_duidxj(vitesse, gradient_elem, domaine_Cl_VDF);
296
297 for (num_elem = 0; num_elem < nb_elem; num_elem++)
298 {
299 crit = 0.;
300 for (i = 0; i < dimension; i++)
301 for (j = 0; j < dimension; j++)
302 {
303 deriv1 = gradient_elem(num_elem, i, j, 0);
304 deriv2 = gradient_elem(num_elem, j, i, 0);
305
306 crit += -0.25 * deriv1 * deriv2;
307 }
308 Q[num_elem] = crit;
309 }
310}
311
312void Champ_Face_VDF::calcul_y_plus(DoubleTab& y_plus, const Domaine_Cl_VDF& domaine_Cl_VDF)
313{
314 // Initialize the y_plus field with a negative value,
315 // so that when visualizing the field near the wall,
316 // one only needs to remove negative values and only
317 // wall values remain.
318
319 int ndeb, nfin, elem, ori, l_unif;
320 double norm_tau, u_etoile, norm_v = 0, dist, val0, val1, val2, d_visco = 0, visco = 1.;
321 y_plus = -1.;
322
323 const Champ_Face_VDF& vit = *this;
324 const Domaine_VDF& domaine_VDF = domaine_vdf();
325 const IntTab& face_voisins = domaine_VDF.face_voisins();
326 const IntVect& orientation = domaine_VDF.orientation();
327 const Equation_base& eqn_hydr = equation();
328 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
329 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
330 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
331 //DoubleTab& tab_visco = ch_visco_cin.valeurs();
332
333 if (sub_type(Champ_Uniforme, ch_visco_cin))
334 {
335 visco = tab_visco(0, 0);
336 l_unif = 1;
337 }
338 else
339 l_unif = 0;
340
341 // Only change values < DMINFLOAT (the old code is not parallel)
342 /* GF we should not change tab_visco here!
343 if (!l_unif)
344 {
345 const int n = tab_visco.size_array();
346 ArrOfDouble& v = tab_visco;
347 for (int i = 0; i < n; i++)
348 if (v[i] < DMINFLOAT)
349 v[i] = DMINFLOAT;
350 }
351 */
352
353 DoubleTab yplus_faces(1, 1); // will contain yplus values if available
354 int yplus_already_computed = 0; // flag
355
356 const RefObjU& modele_turbulence = eqn_hydr.get_modele(TURBULENCE);
357 if (modele_turbulence && sub_type(Modele_turbulence_hyd_base, modele_turbulence.valeur()))
358 {
359 const Modele_turbulence_hyd_base& mod_turb = ref_cast(Modele_turbulence_hyd_base, modele_turbulence.valeur());
360 const Turbulence_paroi_base& loipar = mod_turb.loi_paroi();
361 if (loipar.use_shear())
362 {
363 yplus_faces.resize(domaine_vdf().nb_faces_tot());
364 yplus_faces.ref(loipar.tab_d_plus());
365 yplus_already_computed = 1;
366 }
367 }
368
369 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
370 {
371 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
372
373 if (sub_type(Dirichlet_paroi_fixe, la_cl.valeur()))
374 {
375 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
376 ndeb = le_bord.num_premiere_face();
377 nfin = ndeb + le_bord.nb_faces();
378
379 for (int num_face = ndeb; num_face < nfin; num_face++)
380 {
381
382 if (face_voisins(num_face, 0) != -1)
383 elem = face_voisins(num_face, 0);
384 else
385 elem = face_voisins(num_face, 1);
386
387 if (yplus_already_computed)
388 {
389 // y+ is only defined on faces so we take the face value to put in the element
390 y_plus(elem) = yplus_faces(num_face);
391 }
392 else
393 {
394 if (dimension == 2)
395 {
396 ori = orientation(num_face);
397 norm_v = norm_2D_vit(vit.valeurs(), elem, ori, domaine_VDF, val0);
398 }
399 else if (dimension == 3)
400 {
401 ori = orientation(num_face);
402 norm_v = norm_3D_vit(vit.valeurs(), elem, ori, domaine_VDF, val1, val2);
403 } // dim 3
404
405 if (axi)
406 dist = domaine_VDF.dist_norm_bord_axi(num_face);
407 else
408 dist = domaine_VDF.dist_norm_bord(num_face);
409 if (l_unif)
410 d_visco = visco;
411 else
412 d_visco = tab_visco[elem];
413
414 // PQ : 01/10/03 : corrections relative to the original version
415 norm_tau = d_visco * norm_v / dist;
416
417 u_etoile = sqrt(norm_tau);
418 y_plus(elem) = dist * u_etoile / d_visco;
419
420 } // else yplus already computed
421 } // loop on faces
422 } // End fixed wall
423 } // End loop over boundaries
424}
425
426/*! @brief Returns gij at elements from the face velocity (gij represents the partial derivative dui/dxj).
427 *
428 * @brief From gij, one can compute Sij = 0.5(gij(i,j)+gij(j,i)).
429 *
430 * @param vitesse Velocity field at faces.
431 * @param gij Output velocity gradient tensor at elements.
432 * @param domaine_Cl_VDF Boundary condition domain.
433 * @return Reference to gij.
434 */
435DoubleTab& Champ_Face_VDF::calcul_duidxj(const DoubleTab& vitesse, DoubleTab& gij, const Domaine_Cl_VDF& domaine_Cl_VDF) const
436{
437 const Champ_Face_VDF& vit = ref_cast(Champ_Face_VDF, mon_equation->inconnue());
438 const Domaine_Cl_VDF& dclvdf = ref_cast(Domaine_Cl_VDF, vit.domaine_Cl_dis());
439 const Domaine_VDF& domaine_VDF = domaine_vdf();
440 const int nb_elem = domaine_VDF.domaine().nb_elem_tot(), N = vitesse.line_size();
441 const IntTab& face_voisins = domaine_VDF.face_voisins(), &elem_faces = domaine_VDF.elem_faces(), &Qdm = domaine_VDF.Qdm();
442 const IntVect& orientation = domaine_VDF.orientation();
443
444 const int prem_am = domaine_VDF.premiere_arete_mixte(), dern_am = prem_am + domaine_VDF.nb_aretes_mixtes();
445 const int prem_ai = domaine_VDF.premiere_arete_interne(), dern_ai = prem_ai + domaine_VDF.nb_aretes_internes();
446 IntVect element(4);
447 gij = 0.;
448
449 // Loop over all edges that allow computing the cross terms du_i/dx_j
450 // (the non-cross terms are computed by looping over elements)
451
452
453 // Start with the boundary edges
454 int ndeb = domaine_VDF.premiere_arete_bord(), nfin = ndeb + domaine_VDF.nb_aretes_bord();
455 for (int num_arete = ndeb; num_arete < nfin; num_arete++)
456 for (int n=0; n<N; n++)
457 {
458 const int n_type = domaine_Cl_VDF.type_arete_bord(num_arete - ndeb);
459
460 if (n_type == 4) // periodic edge type
461 {
462 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
463 const int i = orientation(num0), j = orientation(num2);
464
465 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
466 const double temp2 = (vitesse(num3, n) - vitesse(num2, n)) / domaine_VDF.dist_face_period(num2, num3, i); // du_j / dx_i
467
468 element(0) = face_voisins(num0, 0);
469 element(1) = face_voisins(num0, 1);
470 element(2) = face_voisins(num1, 0);
471 element(3) = face_voisins(num1, 1);
472
473 for (int k = 0; k < 4; k++)
474 {
475 // 1) 0.5 : for periodicity, because we will distribute twice over elements touching this edge since it exists twice.
476 // 2) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
477 gij(element(k), i, j, n) += temp1 * 0.5 * 0.25;
478 gij(element(k), j, i, n) += temp2 * 0.5 * 0.25;
479 }
480 }
481 else if (n_type == 3 && Option_VDF::traitement_gradients) /* NAVIER - NAVIER */
482 {
483 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
484 const int i = orientation(num0), j = orientation(num2);
485
486 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
487 const double coeff_frot = (Champ_Face_coeff_frottement_grad_face_bord(num0, n, dclvdf)+Champ_Face_coeff_frottement_grad_face_bord(num1, n, dclvdf))/2.;
488 const double temp2 = -signe * coeff_frot * vitesse(num2, n);
489
490 element(0) = face_voisins(num2, 0);
491 element(1) = face_voisins(num2, 1);
492
493 for (int k = 0; k < 2; k++)
494 {
495 // 1) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
496 gij(element(k), i, j, n) += temp1 * 0.25;
497 gij(element(k), j, i, n) += temp2 * 0.25;
498 }
499 }
500 else if (Option_VDF::traitement_gradients && (n_type == 5 || n_type == 6))
501 Process::exit("Issue in Champ_Face_VDF::calcul_duidxj ... This case is not yet considered. Contact the TRUST team.");
502 else /* other boundary edges ... */
503 {
504 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
505 const int i = orientation(num0), j = orientation(num2);
506
507 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
508 const double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, N*j+n) + vit.val_imp_face_bord_private(num1, N*j+n)); // tangential velocity
509
510 //In this part, we keep the coding of Hyd_SGE_Wale_VDF (num1 not num2) to compute the distance between the cell center and the boundary.
511 const double temp2 = -signe * (vitesse(num2, n) - vit_imp) / domaine_VDF.dist_norm_bord(num1);
512
513 element(0) = face_voisins(num2, 0);
514 element(1) = face_voisins(num2, 1);
515
516 for (int k = 0; k < 2; k++)
517 {
518 // 1) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
519 gij(element(k), i, j, n) += temp1 * 0.25;
520 gij(element(k), j, i, n) += temp2 * 0.25;
521 }
522 }
523 }
524
525 // Continue with corners
526 ndeb = domaine_VDF.premiere_arete_coin(), nfin = ndeb + domaine_VDF.nb_aretes_coin();
527
528 for (int num_arete = ndeb; num_arete < nfin; num_arete++)
529 for (int n=0; n<N; n++)
530 {
531 const int n_type = domaine_Cl_VDF.type_arete_coin(num_arete - ndeb);
532
533 if (n_type == 0) // perio-perio edge type
534 {
535 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
536 const int i = orientation(num0), j = orientation(num2);
537
538 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
539 const double temp2 = (vitesse(num3, n) - vitesse(num2, n)) / domaine_VDF.dist_face_period(num2, num3, i); // du_j / dx_i
540
541 element(0) = face_voisins(num0, 0);
542 element(1) = face_voisins(num0, 1);
543 element(2) = face_voisins(num1, 0);
544 element(3) = face_voisins(num1, 1);
545
546 for (int k = 0; k < 4; k++)
547 {
548 // 1) 0.5 : for periodicity, because we will distribute twice over elements touching this edge since it exists twice.
549 // 2) 0.5 : same as above, because this is a perio-perio corner.
550 // 3) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
551 gij(element(k), i, j, n) += temp1 * 0.5 * 0.5 * 0.25;
552 gij(element(k), j, i, n) += temp2 * 0.5 * 0.5 * 0.25;
553 }
554 }
555
556 if (n_type == 1) // perio-wall edge type
557 {
558 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
559 const int i = orientation(num1), j = orientation(num2);
560
561 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
562 const double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, N*j+n) + vit.val_imp_face_bord_private(num1, N*j+n)); // tangential velocity
563
564 const double temp2 = -signe * (vitesse(num2, n) - vit_imp) / domaine_VDF.dist_norm_bord(num1);
565
566 element(0) = face_voisins(num2, 0);
567 element(1) = face_voisins(num2, 1);
568
569 for (int k = 0; k < 2; k++)
570 {
571 // 1) 0.5 : for periodicity, because we will distribute twice over elements touching this edge since it exists twice.
572 // 2) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
573 gij(element(k), i, j, n) += temp1 * 0.5 * 0.25;
574 gij(element(k), j, i, n) += temp2 * 0.5 * 0.25;
575 }
576 }
577
578 // XXX : Elie Saikali : adding this for corners only if option_vdf is active for now ...
579
581 {
582 if (n_type == 14 || n_type == 15) // fluid-wall or wall-fluid edge type
583 {
584 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
585 const int i = orientation(num1), j = orientation(num2);
586
587 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
588 const double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, N*j+n) + vit.val_imp_face_bord_private(num1, N*j+n)); // tangential velocity
589
590 const double temp2 = -signe * (vitesse(num2, n) - vit_imp) / domaine_VDF.dist_norm_bord(num1);
591
592 element(0) = face_voisins(num2, 0);
593 element(1) = face_voisins(num2, 1);
594
595 for (int k = 0; k < 2; k++)
596 if (element(k) != -1)
597 {
598 gij(element(k), i, j, n) += temp1 * 0.25;
599 gij(element(k), j, i, n) += temp2 * 0.25;
600 }
601 }
602 else if (n_type == 3 || n_type == 4 || n_type == 8) // fluid-navier edge type
603 {
604 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
605 const int f1 = num0 > -1 ? num0 : num1, f2 = num2 > -1 ? num2 : num3;
606 const int i = orientation(f1), j = orientation(f2);
607
608 const double coeff_frot1 = Champ_Face_coeff_frottement_grad_face_bord(f1, n, dclvdf), coeff_frot2 = Champ_Face_coeff_frottement_grad_face_bord(f2, n, dclvdf);
609
610// int signe = f2 == num3 ? -1 : 1;
611// const double temp1 = coeff_frot2 * signe * vitesse(f1, n);
612// const double temp2 = coeff_frot1 * signe * vitesse(f2, n);
613 const double temp1 = coeff_frot2 * (face_voisins(f2, 0)==-1 ? 1:-1)* vitesse(f1, n);
614 const double temp2 = coeff_frot1 * (face_voisins(f1, 0)==-1 ? 1:-1)* vitesse(f2, n);
615
616
617 element(0) = face_voisins(f1, 0);
618 element(1) = face_voisins(f1, 1);
619
620 for (int k = 0; k < 2; k++)
621 if (element(k) != -1)
622 {
623 gij(element(k), i, j, n) += temp1 * 0.25;
624 gij(element(k), j, i, n) += temp2 * 0.25;
625 }
626 }
627 }
628 }
629
630 // Continue with mixed edges
631
632 for (int num_arete = prem_am; num_arete < dern_am; num_arete++)
633 for (int n=0; n<N; n++)
634 {
635 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
636 const int i = orientation(num0), j = orientation(num2);
637
638 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
639 const double temp2 = (vitesse(num3, n) - vitesse(num2, n)) / domaine_VDF.dist_face_period(num2, num3, i); // du_j / dx_i
640
641 element(0) = face_voisins(num0, 0);
642 element(1) = face_voisins(num0, 1);
643 element(2) = face_voisins(num1, 0);
644 element(3) = face_voisins(num1, 1);
645
646 for (int k = 0; k < 4; k++)
647 if (element(k) != -1)
648 {
649 // 1) 0.25 : distribute the velocity gradient over the 3 surrounding elements.
650 // We check element(k)!=-1 because in that case it is the "missing cell"!
651 gij(element(k), i, j, n) += temp1 * 0.25;
652 gij(element(k), j, i, n) += temp2 * 0.25;
653 }
654 }
655
656 // Continue with internal edges
657
658 for (int num_arete = prem_ai; num_arete < dern_ai; num_arete++)
659 for (int n=0; n<N; n++)
660 {
661 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
662 const int i = orientation(num0), j = orientation(num2);
663
664 const double temp1 = (vitesse(num1, n) - vitesse(num0, n)) / domaine_VDF.dist_face_period(num0, num1, j); // du_i / dx_j
665 assert(est_egal(domaine_VDF.dist_face_period(num0, num1, j), domaine_VDF.dist_face(num0, num1, j)));
666
667 const double temp2 = (vitesse(num3, n) - vitesse(num2, n)) / domaine_VDF.dist_face_period(num2, num3, i); // du_j / dx_i
668 assert(est_egal(domaine_VDF.dist_face_period(num2, num3, j), domaine_VDF.dist_face(num2, num3, j)));
669
670 element(0) = face_voisins(num0, 0);
671 element(1) = face_voisins(num0, 1);
672 element(2) = face_voisins(num1, 0);
673 element(3) = face_voisins(num1, 1);
674
675 for (int k = 0; k < 4; k++)
676 {
677 // 1) 0.25 : distribute the velocity gradient over the 4 surrounding elements.
678 gij(element(k), i, j, n) += temp1 * 0.25;
679 gij(element(k), j, i, n) += temp2 * 0.25;
680 }
681 }
682
683
684 // XXX : Elie Saikali : HACK for fluid-fluid corners
685 // for this case (admittedly rare), beware of issues with velocity values at corners ... e.g. a champ_fonc_xyz x+y+z does not give the correct value at corners
686
687 // Continue with corners
688
689 ndeb = domaine_VDF.premiere_arete_coin(), nfin = ndeb + domaine_VDF.nb_aretes_coin();
690
691 for (int num_arete = ndeb; num_arete < nfin; num_arete++)
692 for (int n=0; n<N; n++)
693 {
694 const int n_type = domaine_Cl_VDF.type_arete_coin(num_arete - ndeb);
695
697 if (n_type == 16 ) // fluid-fluid edge type
698 {
699 const int num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2);
700 const int i = orientation(num1), j = orientation(num2);
701
702 element(0) = face_voisins(num2, 0);
703 element(1) = face_voisins(num2, 1);
704
705 for (int k = 0; k < 2; k++)
706 if (element(k) != -1)
707 {
708 // XXX : 1/3 because we want something like: (a+b+c+d)/4 = (a+b+c)/3 => d = (a+b+c)/3
709 gij(element(k), i, j, n) += gij(element(k), i, j, n) / 3.;
710 gij(element(k), j, i, n) += gij(element(k), j, i, n) / 3.;
711 }
712 }
713 }
714
715 // 2nd part: loop over elements and fill Sij for the non-cross derivatives (du_i / dx_i).
716 // In these cases, the gradient is computed directly within the element and not redistributed.
717
718 for (int elem = 0; elem < nb_elem; elem++)
719 for (int n=0; n<N; n++)
720 for (int i = 0; i < dimension; i++)
721 {
722 double temp1 = (vitesse(elem_faces(elem, i), n) - vitesse(elem_faces(elem, i + dimension), n)) / domaine_VDF.dim_elem(elem, orientation(elem_faces(elem, i)));
723 gij(elem, i, i, n) = -temp1;
724 }
725
726 return gij;
727}
728
729/*! @brief Returns gij at elements from the element velocity (gij represents the partial derivative dui/dxj).
730 *
731 * @brief From gij, one can compute Sij = 0.5(gij(i,j)+gij(j,i)).
732 *
733 * @param in_vel Input velocity field at elements.
734 * @param gij Output velocity gradient tensor at elements.
735 * @return Reference to gij.
736 */
737DoubleTab& Champ_Face_VDF::calcul_duidxj(const DoubleTab& in_vel, DoubleTab& gij) const
738{
739
740 const Domaine_VDF& domaine_VDF = domaine_vdf();
741 int nb_elem_tot = domaine_VDF.domaine().nb_elem_tot(), N = in_vel.line_size()/dimension;
742 const IntTab& face_voisins = domaine_VDF.face_voisins();
743 const IntTab& elem_faces = domaine_VDF.elem_faces();
744
745 int num0, num1, num2, num3, num4, num5;
746 int f0, f1, f2, f3, f4, f5;
747
748 //
749 // Calculate the Sij tensor
750 //
751 if (dimension == 2)
752 {
753 for (int element_number = 0; element_number < nb_elem_tot; element_number++)
754 for (int n=0; n<N; n++)
755 {
756 f0 = elem_faces(element_number, 0);
757 num0 = face_voisins(f0, 0);
758 if (num0 == -1)
759 num0 = element_number;
760 f1 = elem_faces(element_number, 1);
761 num1 = face_voisins(f1, 0);
762 if (num1 == -1)
763 num1 = element_number;
764 f2 = elem_faces(element_number, 2);
765 num2 = face_voisins(f2, 1);
766 if (num2 == -1)
767 num2 = element_number;
768 f3 = elem_faces(element_number, 3);
769 num3 = face_voisins(f3, 1);
770 if (num3 == -1)
771 num3 = element_number;
772
773 gij(element_number, 0, 0, n) = 0.5 * ((in_vel(num2, N*0+n) - in_vel(num0, N*0+n)) / domaine_VDF.dim_elem(element_number, 0));
774 gij(element_number, 0, 1, n) = 0.5 * ((in_vel(num3, N*0+n) - in_vel(num1, N*0+n)) / domaine_VDF.dim_elem(element_number, 1));
775 gij(element_number, 1, 0, n) = 0.5 * ((in_vel(num2, N*1+n) - in_vel(num0, N*1+n)) / domaine_VDF.dim_elem(element_number, 0));
776 gij(element_number, 1, 1, n) = 0.5 * ((in_vel(num3, N*1+n) - in_vel(num1, N*1+n)) / domaine_VDF.dim_elem(element_number, 1));
777 }
778 }
779 else
780 {
781 for (int element_number = 0; element_number < nb_elem_tot; element_number++)
782 for (int n=0; n<N; n++)
783 {
784 f0 = elem_faces(element_number, 0);
785 num0 = face_voisins(f0, 0);
786 if (num0 == -1)
787 num0 = element_number;
788 f1 = elem_faces(element_number, 1);
789 num1 = face_voisins(f1, 0);
790 if (num1 == -1)
791 num1 = element_number;
792 f2 = elem_faces(element_number, 2);
793 num2 = face_voisins(f2, 0);
794 if (num2 == -1)
795 num2 = element_number;
796 f3 = elem_faces(element_number, 3);
797 num3 = face_voisins(f3, 1);
798 if (num3 == -1)
799 num3 = element_number;
800 f4 = elem_faces(element_number, 4);
801 num4 = face_voisins(f4, 1);
802 if (num4 == -1)
803 num4 = element_number;
804 f5 = elem_faces(element_number, 5);
805 num5 = face_voisins(f5, 1);
806 if (num5 == -1)
807 num5 = element_number;
808
809 gij(element_number, 0, 0, n) = 0.5 * ((in_vel(num3, N*0+n) - in_vel(num0, N*0+n)) / domaine_VDF.dim_elem(element_number, 0));
810
811 gij(element_number, 0, 1, n) = 0.5 * ((in_vel(num4, N*0+n) - in_vel(num1, N*0+n)) / domaine_VDF.dim_elem(element_number, 1));
812 gij(element_number, 1, 0, n) = 0.5 * ((in_vel(num3, N*1+n) - in_vel(num0, N*1+n)) / domaine_VDF.dim_elem(element_number, 0));
813
814 gij(element_number, 0, 2, n) = 0.5 * ((in_vel(num5, N*0+n) - in_vel(num2, N*0+n)) / domaine_VDF.dim_elem(element_number, 2));
815
816 gij(element_number, 2, 0, n) = 0.5 * ((in_vel(num3, N*2+n) - in_vel(num0, N*2+n)) / domaine_VDF.dim_elem(element_number, 0));
817
818 gij(element_number, 1, 1, n) = 0.5 * ((in_vel(num4, N*1+n) - in_vel(num1, N*1+n)) / domaine_VDF.dim_elem(element_number, 1));
819
820 gij(element_number, 1, 2, n) = 0.5 * ((in_vel(num5, N*1+n) - in_vel(num2, N*1+n)) / domaine_VDF.dim_elem(element_number, 2));
821 gij(element_number, 2, 1, n) = 0.5 * ((in_vel(num4, N*2+n) - in_vel(num1, N*2+n)) / domaine_VDF.dim_elem(element_number, 1));
822
823 gij(element_number, 2, 2, n) = 0.5 * ((in_vel(num5, N*2+n) - in_vel(num2, N*2+n)) / domaine_VDF.dim_elem(element_number, 2));
824
825 }
826 }
827
828 return gij;
829
830}
831
832/*! @brief Returns SMA_barre at elements from the face velocity.
833 *
834 * @brief SMA_barre = Sij*Sij (summation over indices i and j).
835 *
836 * S_barre(num_elem) is computed directly.
837 * The contribution_paroi parameter (here fixed to 0) allows excluding the wall contribution from the product SMA_barre = Sij*Sij.
838 *
839 */
840DoubleVect& Champ_Face_VDF::calcul_S_barre_sans_contrib_paroi(const DoubleTab& vitesse, DoubleVect& SMA_barre, const Domaine_Cl_VDF& domaine_Cl_VDF) const
841{
842 const int contribution_paroi = 0;
843
844 const Champ_Face_VDF& vit = ref_cast(Champ_Face_VDF, mon_equation->inconnue());
845 const Domaine_VDF& domaine_VDF = domaine_vdf();
846 const IntTab& face_voisins = domaine_VDF.face_voisins(), &elem_faces = domaine_VDF.elem_faces(), &Qdm = domaine_VDF.Qdm();
847 const IntVect& orientation = domaine_VDF.orientation();
848
849 const int nb_elem = domaine_VDF.domaine().nb_elem();
850 const int prem_am = domaine_VDF.premiere_arete_mixte(), dern_am = prem_am + domaine_VDF.nb_aretes_mixtes();
851 const int prem_ai = domaine_VDF.premiere_arete_interne(), dern_ai = prem_ai + domaine_VDF.nb_aretes_internes();
852
853 ArrOfInt element(4);
854
855 int ndeb = domaine_VDF.premiere_arete_bord(), nfin = ndeb + domaine_VDF.nb_aretes_bord();
856
857 for (int num_arete = ndeb; num_arete < nfin; num_arete++)
858 {
859 int n_type = domaine_Cl_VDF.type_arete_bord(num_arete - ndeb);
860
861 if (n_type == 4) // periodic edge type
862 {
863 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
864 const int i = orientation(num0), j = orientation(num2);
865
866 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
867 const double temp2 = (vitesse[num3] - vitesse[num2]) / domaine_VDF.dist_face_period(num2, num3, i); // du/dy
868
869 element[0] = face_voisins(num0, 0);
870 element[1] = face_voisins(num0, 1);
871 element[2] = face_voisins(num1, 0);
872 element[3] = face_voisins(num1, 1);
873
874 // compute the sum of cross terms: 2*( (0.5*Sij)^2+(0.5*Sji)^2)
875 // Since we are on edges distributing over elements, multiply by 0.25: 0.25*(2*(2*0.5^2))=0.25*4*0.25=0.25
876 // The 0.5 factor comes from traversing periodic faces: periodic edges are "the same", so we add twice what is needed -> 0.5
877 for (int k = 0; k < 4; k++)
878 SMA_barre[element[k]] += 0.5 * (temp1 + temp2) * (temp1 + temp2) * 0.25;
879 }
880 else
881 {
882 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
883 const int j = orientation(num2);
884
885 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
886 double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, j) + vit.val_imp_face_bord_private(num1, j)); // tangential velocity
887
888 double temp2;
889
890 if (n_type == 0 && contribution_paroi == 0)
891 temp2 = 0;
892 else
893 temp2 = -signe * (vitesse[num2] - vit_imp) / domaine_VDF.dist_norm_bord(num1);
894
895 element[0] = face_voisins(num2, 0);
896 element[1] = face_voisins(num2, 1);
897
898 // compute the sum of cross terms: 2*( (0.5*Sij)^2+(0.5*Sji)^2)
899 // Since we are on edges distributing over elements, multiply by 0.25: 0.25*(2*(2*0.5^2))=0.25*4*0.25=0.25
900 // Account for both symmetric terms: SijSij+SjiSji
901 for (int k = 0; k < 2; k++)
902 SMA_barre[element[k]] += (temp1 + temp2) * (temp1 + temp2) * 0.25;
903 }
904 }
905
906 ndeb = domaine_VDF.premiere_arete_coin(), nfin = ndeb + domaine_VDF.nb_aretes_coin();
907
908 for (int num_arete = ndeb; num_arete < nfin; num_arete++)
909 {
910 int n_type = domaine_Cl_VDF.type_arete_coin(num_arete - ndeb);
911
912 if (n_type == 0) // perio-perio edge type
913 {
914 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
915 const int i = orientation(num0), j = orientation(num2);
916
917 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
918 const double temp2 = (vitesse[num3] - vitesse[num2]) / domaine_VDF.dist_face_period(num2, num3, i); // du/dy
919
920 element[0] = face_voisins(num0, 0);
921 element[1] = face_voisins(num0, 1);
922 element[2] = face_voisins(num1, 0);
923 element[3] = face_voisins(num1, 1);
924
925 // compute the sum of cross terms: 2*( (0.5*Sij)^2+(0.5*Sji)^2)
926 // Since we are on edges distributing over elements, multiply by 0.25: 0.25*(2*(2*0.5^2))=0.25*4*0.25=0.25
927 // The 0.5 factor comes from traversing periodic faces: periodic edges are "the same", so we add twice what is needed -> 0.5
928 // another *0.5 because these are perio-perio edges traversed 4 times
929 for (int k = 0; k < 4; k++)
930 SMA_barre[element[k]] += 0.5 * 0.5 * (temp1 + temp2) * (temp1 + temp2) * 0.25;
931 }
932
933 if (n_type == 1) // perio-wall edge type
934 {
935 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
936 const int j = orientation(num2);
937
938 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
939 const double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, j) + vit.val_imp_face_bord_private(num1, j)); // tangential velocity
940
941 double temp2;
942
943 if (contribution_paroi == 0)
944 temp2 = 0;
945 else
946 temp2 = -signe * (vitesse[num2] - vit_imp) / domaine_VDF.dist_norm_bord(num1);
947
948 element[0] = face_voisins(num2, 0);
949 element[1] = face_voisins(num2, 1);
950
951 for (int k = 0; k < 2; k++)
952 SMA_barre[element[k]] += 0.5 * (temp1 + temp2) * (temp1 + temp2) * 0.25;
953 }
954
956 if (n_type == 14 || n_type == 15 || n_type == 16) // fluid-wall, wall-fluid or fluid-fluid edge type
957 {
958 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), signe = Qdm(num_arete, 3);
959 const int j = orientation(num2);
960
961 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
962 const double vit_imp = 0.5 * (vit.val_imp_face_bord_private(num0, j) + vit.val_imp_face_bord_private(num1, j)); // tangential velocity
963
964 double temp2;
965
966 if (n_type == 0 && contribution_paroi == 0)
967 temp2 = 0;
968 else
969 temp2 = -signe * (vitesse[num2] - vit_imp) / domaine_VDF.dist_norm_bord(num1);
970
971 element[0] = face_voisins(num2, 0);
972 element[1] = face_voisins(num2, 1);
973
974 for (int k = 0; k < 2; k++)
975 if (element[k] != -1)
976 SMA_barre[element[k]] += (temp1 + temp2) * (temp1 + temp2) * 0.25;
977 }
978 }
979
980 for (int num_arete = prem_am; num_arete < dern_am; num_arete++)
981 {
982 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
983 const int i = orientation(num0), j = orientation(num2);
984
985 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
986 const double temp2 = (vitesse[num3] - vitesse[num2]) / domaine_VDF.dist_face_period(num2, num3, i); // du/dy
987
988 element[0] = face_voisins(num0, 0);
989 element[1] = face_voisins(num0, 1);
990 element[2] = face_voisins(num1, 0);
991 element[3] = face_voisins(num1, 1);
992
993 for (int k = 0; k < 4; k++)
994 if (element[k] != -1)
995 SMA_barre[element[k]] += (temp1 + temp2) * (temp1 + temp2) * 0.25;
996 }
997
998 for (int num_arete = prem_ai; num_arete < dern_ai; num_arete++)
999 {
1000 const int num0 = Qdm(num_arete, 0), num1 = Qdm(num_arete, 1), num2 = Qdm(num_arete, 2), num3 = Qdm(num_arete, 3);
1001 const int i = orientation(num0), j = orientation(num2);
1002
1003 const double temp1 = (vitesse[num1] - vitesse[num0]) / domaine_VDF.dist_face_period(num0, num1, j); // dv/dx
1004 const double temp2 = (vitesse[num3] - vitesse[num2]) / domaine_VDF.dist_face_period(num2, num3, i); // du/dy
1005
1006 element[0] = face_voisins(num0, 0);
1007 element[1] = face_voisins(num0, 1);
1008 element[2] = face_voisins(num1, 0);
1009 element[3] = face_voisins(num1, 1);
1010
1011 for (int k = 0; k < 4; k++)
1012 SMA_barre[element[k]] += (temp1 + temp2) * (temp1 + temp2) * 0.25;
1013 }
1014
1015 // 2nd part: loop over elements and fill Sij for the non-cross derivatives (du/dx and dv/dy)
1016
1017 for (int elem = 0; elem < nb_elem; elem++)
1018 {
1019 for (int i = 0; i < dimension; i++)
1020 {
1021 double temp1 = (vitesse[elem_faces(elem, i)] - vitesse[elem_faces(elem, i + dimension)]) / domaine_VDF.dim_elem(elem, orientation(elem_faces(elem, i)));
1022 SMA_barre(elem) += 2.0 * temp1 * temp1;
1023 }
1024 }
1025
1026 // We take the square root!!!!! WARNING SMA_barre=squared invariant!!!
1027 // racine_carree(SMA_barre)
1028 return SMA_barre;
1029}
1030
1031DoubleVect& Champ_Face_VDF::calcul_S_barre(const DoubleTab& vitesse, DoubleVect& SMA_barre, const Domaine_Cl_VDF& domaine_Cl_VDF) const
1032{
1033 const Domaine_VDF& domaine_VDF = domaine_vdf();
1034 const int nb_elem_tot = domaine_VDF.nb_elem_tot();
1035 const int nb_elem = domaine_VDF.nb_elem(), N = vitesse.line_size();
1036
1037 int i, j;
1038 int elem;
1039 double Sij, temp;
1040
1041 DoubleTab duidxj(nb_elem_tot, dimension, dimension, N);
1042
1043 calcul_duidxj(vitesse, duidxj, domaine_Cl_VDF);
1044
1045 for (elem = 0; elem < nb_elem; elem++)
1046 for (int n=0; n<N; n++)
1047 {
1048 temp = 0.;
1049 for (i = 0; i < dimension; i++)
1050 for (j = 0; j < dimension; j++)
1051 {
1052 Sij = 0.5 * (duidxj(elem, i, j, n) + duidxj(elem, j, i, n));
1053 temp += Sij * Sij;
1054 }
1055 SMA_barre(elem) = 2. * temp;
1056 }
1057
1058 return SMA_barre;
1059
1060}
1061
1062DoubleTab& Champ_Face_VDF::calcul_S_barre_Multiphase(const DoubleTab& vitesse, DoubleTab& SMA_barre, const Domaine_Cl_VDF& domaine_Cl_VDF) const
1063{
1064 const Domaine_VDF& domaine_VDF = domaine_vdf();
1065 const int nb_elem_tot = domaine_VDF.nb_elem_tot();
1066 const int nb_elem = domaine_VDF.nb_elem();
1067 const int N = vitesse.line_size();
1068
1069 int i, j;
1070 int elem;
1071 double Sij, temp;
1072
1073 DoubleTab duidxj(nb_elem_tot, dimension, dimension, N);
1074
1075 calcul_duidxj(vitesse, duidxj, domaine_Cl_VDF);
1076
1077 for (elem = 0; elem < nb_elem; elem++)
1078 for (int n=0; n<N; n++)
1079 {
1080 temp = 0.;
1081 for (i = 0; i < dimension; i++)
1082 for (j = 0; j < dimension; j++)
1083 {
1084 Sij = 0.5 * (duidxj(elem, i, j, n) + duidxj(elem, j, i, n));
1085 temp += Sij * Sij;
1086 }
1087 SMA_barre(elem,n) = 2. * temp;
1088 }
1089
1090 return SMA_barre;
1091
1092}
1093
1094void Champ_Face_VDF::calcul_grad_u(const DoubleTab& vitesse, DoubleTab& grad_u, const Domaine_Cl_VDF& domaine_Cl_VDF)
1095{
1096 const Domaine_VDF& domaine_VDF = domaine_vdf();
1097 const int nb_elem = domaine_VDF.nb_elem();
1098 const int nb_elem_tot = domaine_VDF.nb_elem_tot(), N = vitesse.line_size();
1099
1100 DoubleTab gradient_elem(nb_elem_tot, dimension, dimension, N);
1101 gradient_elem = 0.;
1102
1103 calcul_duidxj(vitesse, gradient_elem, domaine_Cl_VDF);
1104
1105 for (int elem = 0; elem < nb_elem; elem++)
1106 for (int n=0; n<N; n++)
1107 for (int i = 0; i < dimension; i++)
1108 for (int j = 0; j < dimension; j++)
1109 grad_u(elem, N * ( dimension*i+j ) + n) = gradient_elem(elem, i, j, n);
1110}
1111
1113{
1114 const DoubleTab& val = valeurs();
1115 const Domaine_VDF& domaine_VDF = domaine_vdf();
1116 int nb_elem = domaine_VDF.nb_elem();
1117 const IntTab& face_voisins = domaine_VDF.face_voisins();
1118 const IntTab& elem_faces = domaine_VDF.elem_faces();
1119
1120 if (dimension == 2)
1121 caldscaldcentelemdim2(dscald, val, domaine_VDF, nb_elem, face_voisins, elem_faces);
1122 else if (dimension == 3)
1123 caldscaldcentelemdim3(dscald, val, domaine_VDF, nb_elem, face_voisins, elem_faces);
1124}
1125
1126// Functions to compute the components of the GradU tensor (covariant velocity derivatives)
1127// in the cylindrical coordinate frame
1129{
1130 const Domaine_VDF& domaine_VDF = domaine_vdf();
1131 const DoubleTab& inco = valeurs();
1132 const IntVect& orientation = domaine_VDF.orientation();
1133 const IntTab& elem_faces = domaine_VDF.elem_faces();
1134 const IntTab& Qdm = domaine_VDF.Qdm();
1135 const DoubleTab& xv = domaine_VDF.xv();
1136 const DoubleTab& xp = domaine_VDF.xp();
1137 const IntVect& type_arete_bord = domaine_Cl_VDF.type_arete_bord();
1138
1139 double d_teta, R;
1140 double deux_pi = M_PI * 2.0;
1141
1142 // Fill tau_diag_: diagonal terms of the GradU tensor
1143
1144 int fx0, fx1, fy0, fy1;
1145 int num_elem;
1146 for (num_elem = 0; num_elem < domaine_VDF.nb_elem(); num_elem++)
1147 {
1148 fx0 = elem_faces(num_elem, 0);
1149 fx1 = elem_faces(num_elem, dimension);
1150 fy0 = elem_faces(num_elem, 1);
1151 fy1 = elem_faces(num_elem, 1 + dimension);
1152
1153 // Compute tau11
1154 tau_diag_(num_elem, 0) = (inco[fx1] - inco[fx0]) / (xv(fx1, 0) - xv(fx0, 0));
1155
1156 // Compute tau22
1157 R = xp(num_elem, 0);
1158 d_teta = xv(fy1, 1) - xv(fy0, 1);
1159 if (d_teta < 0)
1160 d_teta += deux_pi;
1161 tau_diag_(num_elem, 1) = (inco[fy1] - inco[fy0]) / (R * d_teta) + 0.5 * (inco[fx0] + inco[fx1]) / R;
1162 }
1163
1164 if (dimension == 3)
1165 {
1166 int fz0, fz1;
1167 for (num_elem = 0; num_elem < domaine_VDF.nb_elem(); num_elem++)
1168 {
1169 fz0 = elem_faces(num_elem, 2);
1170 fz1 = elem_faces(num_elem, 2 + dimension);
1171
1172 // Compute tau33
1173 tau_diag_(num_elem, 2) = (inco[fz1] - inco[fz0]) / (xv(fz1, 2) - xv(fz0, 2));
1174
1175 }
1176 }
1177
1178 // Fill tau_croises_: off-diagonal terms of the GradU tensor
1179 // The cross derivatives of the velocity (off-diagonal terms of the
1180 // GradU tensor) are computed on edges.
1181 // There are two derivatives per edge:
1182 // For an XY edge: tau12 and tau21
1183 // For a YZ edge: tau23 and tau32
1184 // For an XZ edge: tau13 and tau31
1185
1186 // Loop over boundary edges
1187
1188 int n_arete;
1189 int ndeb = domaine_VDF.premiere_arete_bord();
1190 int nfin = ndeb + domaine_VDF.nb_aretes_bord();
1191 int ori1, ori3;
1192 int fac1, fac2, fac3, fac4, signe;
1193 double dist3;
1194
1195 int n_type;
1196
1197 for (n_arete = ndeb; n_arete < nfin; n_arete++)
1198 {
1199 n_type = type_arete_bord(n_arete - ndeb);
1200
1201 switch(n_type)
1202 {
1204 // wall-wall
1206 // fluid-fluid
1208 // wall-fluid
1209 {
1210 fac1 = Qdm(n_arete, 0);
1211 fac2 = Qdm(n_arete, 1);
1212 fac3 = Qdm(n_arete, 2);
1213 signe = Qdm(n_arete, 3);
1214 ori1 = orientation(fac1);
1215 ori3 = orientation(fac3);
1216 int rang1 = fac1 - domaine_VDF.premiere_face_bord();
1217 int rang2 = fac2 - domaine_VDF.premiere_face_bord();
1218 double vit_imp;
1219
1220 if (n_type == TypeAreteBordVDF::PAROI_FLUIDE)
1221 // wall-fluid edge: need to determine which is the fluid face
1222 {
1223 if (est_egal(inco[fac1], 0))
1224 vit_imp = val_imp_face_bord_private(rang2, ori3);
1225 else
1226 vit_imp = val_imp_face_bord_private(rang1, ori3);
1227 }
1228 else
1229 vit_imp = 0.5 * (val_imp_face_bord_private(rang1, ori3) + val_imp_face_bord_private(rang2, ori3));
1230
1231 if (ori1 == 0) // boundary with equation R = const
1232 {
1233 dist3 = xv(fac3, 0) - xv(fac1, 0);
1234 if (n_type != TypeAreteBordVDF::PAROI_PAROI)
1235 dist3 *= 2;
1236
1237 if (ori3 == 1)
1238 {
1239 // compute tau12
1240 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3;
1241
1242 // compute tau21
1243 R = xv(fac1, 0);
1244 d_teta = xv(fac2, 1) - xv(fac1, 1);
1245 if (d_teta < 0)
1246 d_teta += deux_pi;
1247 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (R * d_teta);
1248 }
1249 else if (ori3 == 2)
1250 {
1251 // compute tau13
1252 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3;
1253 // compute tau31
1254 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (xv(fac2, 2) - xv(fac1, 2));
1255 }
1256 }
1257 else if (ori1 == 1) // boundary with equation theta = const
1258 {
1259 R = xv(fac3, 0);
1260 d_teta = xv(fac3, 1) - xv(fac1, 1);
1261 if (d_teta < 0)
1262 d_teta += deux_pi;
1263 dist3 = R * d_teta;
1264 if (n_type != TypeAreteBordVDF::PAROI_PAROI)
1265 dist3 *= 2;
1266
1267 if (ori3 == 0)
1268 {
1269 // compute tau21
1270 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3 - 0.5 * (inco[fac1] + inco[fac2]) / R;
1271 // compute tau12
1272 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (xv(fac2, 0) - xv(fac1, 0));
1273 }
1274 else if (ori3 == 2)
1275 {
1276 // compute tau23
1277 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3;
1278 // compute tau32
1279 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (xv(fac2, 2) - xv(fac1, 2));
1280 }
1281 }
1282 else // (ori1 == 2) boundary with equation Z = const
1283 {
1284 dist3 = xv(fac3, 2) - xv(fac1, 2);
1285 if (n_type != TypeAreteBordVDF::PAROI_PAROI)
1286 dist3 *= 2;
1287
1289 {
1290 // compute tau31
1291 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3;
1292 // compute tau13
1293 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (xv(fac2, 0) - xv(fac1, 0));
1294 }
1295 else if (ori3 == 1)
1296 {
1297 // compute tau32
1298 tau_croises_(n_arete, 0) = signe * (vit_imp - inco[fac3]) / dist3;
1299
1300 // compute tau23
1301 R = xv(fac1, 0);
1302 d_teta = xv(fac2, 1) - xv(fac1, 1);
1303 if (d_teta < 0)
1304 d_teta += deux_pi;
1305 tau_croises_(n_arete, 1) = (inco[fac2] - inco[fac1]) / (R * d_teta);
1306 }
1307 }
1308 break;
1309 }
1310 case 3:
1311 {
1312 // symmetry-symmetry
1313 // no diffusive flux computed
1314 break;
1315 }
1316 default:
1317 {
1318 Cerr << "An unexpected edge type was encountered\n";
1319 Cerr << "edge number: " << n_arete;
1320 Cerr << " type : " << n_type;
1321 exit();
1322 break;
1323 }
1324 }
1325 }
1326
1327 // Loop over mixed and internal edges
1328 ndeb = domaine_VDF.premiere_arete_mixte();
1329 nfin = domaine_VDF.nb_aretes();
1330 for (n_arete = ndeb; n_arete < nfin; n_arete++)
1331 {
1332 fac1 = Qdm(n_arete, 0);
1333 fac2 = Qdm(n_arete, 1);
1334 fac3 = Qdm(n_arete, 2);
1335 fac4 = Qdm(n_arete, 3);
1336 ori1 = orientation(fac1);
1337 ori3 = orientation(fac3);
1338 if (ori1 == 1) // (only possibility: ori3 = 0) XY edge
1339 {
1340 // Compute tau21
1341 R = xv(fac3, 0);
1342 d_teta = xv(fac4, 1) - xv(fac3, 1);
1343 if (d_teta < 0)
1344 d_teta += deux_pi;
1345 tau_croises_(n_arete, 1) = (inco(fac4) - inco(fac3)) / (R * d_teta) - 0.5 * (inco[fac1] + inco[fac2]) / R;
1346 // Compute tau12
1347 tau_croises_(n_arete, 0) = (inco(fac2) - inco(fac1)) / (xv(fac2, 0) - xv(fac1, 0));
1348 }
1349 else if (ori3 == 1) // (only possibility: ori1 = 2) YZ edge
1350 {
1351 // Compute tau32
1352 tau_croises_(n_arete, 1) = (inco(fac4) - inco(fac3)) / (xv(fac4, 2) - xv(fac3, 2));
1353 // Compute tau23
1354 R = xv(fac1, 0);
1355 d_teta = xv(fac2, 1) - xv(fac1, 1);
1356 if (d_teta < 0)
1357 d_teta += deux_pi;
1358 tau_croises_(n_arete, 0) = (inco(fac2) - inco(fac1)) / (R * d_teta);
1359 }
1360 else // only possibility: ori1 = 2 and ori3 = 0: XZ edge
1361 {
1362 // Compute tau31
1363 tau_croises_(n_arete, 1) = (inco(fac4) - inco(fac3)) / (xv(fac4, 2) - xv(fac3, 2));
1364 // Compute tau13
1365 tau_croises_(n_arete, 0) = (inco(fac2) - inco(fac1)) / (xv(fac2, 0) - xv(fac1, 0));
1366 }
1367 }
1368}
1369
1370/* ***************************************************** */
1371/* USEFUL METHODS OUTSIDE THE CLASS */
1372/* ***************************************************** */
1373
1374double Champ_Face_get_val_imp_face_bord_sym(const DoubleTab& tab_valeurs, const double temp, int face, int comp, const Domaine_Cl_VDF& zclo)
1375{
1376 const Domaine_VDF& domaine_vdf = zclo.domaine_VDF();
1377 int face_locale = -123;
1378 const int face_globale = face + domaine_vdf.premiere_face_bord(); // Now index in the global face array.
1379 const Domaine_Cl_dis_base& zcl = zclo; //equation().domaine_Cl_dis();
1380 // Retrieve the BC associated with the face and the local face index within the boundary.
1381 //assert(equation().domaine_Cl_dis()==zclo);
1382
1383 const Cond_lim_base& cl = (face < domaine_vdf.nb_faces()) ? zcl.condition_limite_de_la_face_reelle(face_globale, face_locale) :
1384 zcl.condition_limite_de_la_face_virtuelle(face_globale, face_locale);
1385
1386 const IntTab& face_voisins = domaine_vdf.face_voisins();
1387 const IntTab& elem_faces = domaine_vdf.elem_faces();
1388 const DoubleVect& porosite = zclo.equation().milieu().porosite_face();
1389 const int ori = domaine_vdf.orientation()(face_globale);
1390
1391 if (sub_type(Navier, cl))
1392 {
1393 const int N = tab_valeurs.line_size();
1394 const int n=comp%N, comploc = (comp-n)/N;
1395 if (comploc == ori)
1396 return 0;
1397 else
1398 {
1399 int elem = 0;
1400 if (face_voisins(face_globale, 0) != -1)
1401 elem = face_voisins(face_globale, 0);
1402 else
1403 elem = face_voisins(face_globale, 1);
1404 const int comp2 = comploc + Objet_U::dimension;
1405 return (tab_valeurs(elem_faces(elem, comploc), n) * porosite[elem_faces(elem, comploc)] + tab_valeurs(elem_faces(elem, comp2), n) * porosite[elem_faces(elem, comp2)])
1406 / (porosite[elem_faces(elem, comploc)] + porosite[elem_faces(elem, comp2)]);
1407 }
1408 }
1409
1410 if (!cl.champ_front().has_valeurs_au_temps(temp)) // not yet initialized
1411 return 0.;
1412
1413 const DoubleTab& vals = cl.champ_front().valeurs_au_temps(temp);
1414 const int face_de_vals = vals.dimension(0) == 1 ? 0 : face_locale;
1415
1416 if (sub_type(Dirichlet_entree_fluide, cl))
1417 return vals(face_de_vals, comp);
1418 else if (sub_type(Dirichlet_paroi_fixe, cl))
1419 return 0.;
1420 else if (sub_type(Dirichlet_paroi_defilante, cl))
1421 return vals(face_de_vals, comp);
1422
1423 return 0.; // All other cases
1424}
1425
1426double Champ_Face_get_val_imp_face_bord(const double temp, int face, int comp, const Domaine_Cl_VDF& zclo)
1427{
1428 const Domaine_VDF& domaine_vdf = zclo.domaine_VDF();
1429 int face_locale = -123;
1430 const int face_globale = face + domaine_vdf.premiere_face_bord(); // Now index in the global face array.
1431 const Domaine_Cl_dis_base& zcl = zclo; //equation().domaine_Cl_dis();
1432 // Retrieve the BC associated with the face and the local face index within the boundary.
1433 //assert(equation().domaine_Cl_dis()==zclo);
1434
1435 const Cond_lim_base& cl = (face < domaine_vdf.nb_faces()) ? zcl.condition_limite_de_la_face_reelle(face_globale, face_locale) :
1436 zcl.condition_limite_de_la_face_virtuelle(face_globale, face_locale);
1437 const int ori = domaine_vdf.orientation()(face_globale);
1438
1439 if (sub_type(Navier, cl))
1440 {
1441 if (comp == ori)
1442 return 0.;
1443 else
1444 {
1445 Process::exit("You should call Champ_Face_get_val_imp_face_bord_sym and not Champ_Face_get_val_imp_face_bord\n");
1446 return 1.e9;
1447 }
1448 }
1449
1450 if (!cl.champ_front().has_valeurs_au_temps(temp)) // not yet initialized
1451 return 0.;
1452
1453 const DoubleTab& vals = cl.champ_front().valeurs_au_temps(temp);
1454 int face_de_vals = vals.dimension(0) == 1 ? 0 : face_locale;
1455
1456 if (sub_type(Dirichlet_entree_fluide, cl))
1457 return vals(face_de_vals, comp);
1458 else if (sub_type(Dirichlet_paroi_fixe, cl))
1459 return 0.;
1460 else if (sub_type(Dirichlet_paroi_defilante, cl))
1461 return vals(face_de_vals, comp);
1462
1463 return 0.; // All other cases
1464}
1465
1466double Champ_Face_get_val_imp_face_bord(const double temp, int face, int comp, int comp2, const Domaine_Cl_VDF& zclo)
1467{
1468 Process::exit("Champ_Face_VDF::val_imp_face_bord(,,) exit\n");
1469 return 0.; // For compilers
1470}
1471
1472double Champ_Face_coeff_frottement_face_bord(const int f, const int n, const Domaine_Cl_VDF& zclo)
1473{
1474 const Domaine_VDF& domaine_vdf = zclo.domaine_VDF();
1475 const Domaine_Cl_dis_base& zcl = zclo;
1476 const int face_globale = f + domaine_vdf.premiere_face_bord(); // Now index in the global face array.
1477
1478 int face_locale = -123;
1479 const Cond_lim_base& cl = (f < domaine_vdf.nb_faces()) ? zcl.condition_limite_de_la_face_reelle(face_globale, face_locale) :
1480 zcl.condition_limite_de_la_face_virtuelle(face_globale, face_locale);
1481
1482 return sub_type(Navier, cl) ? ref_cast(Navier, cl).coefficient_frottement(face_locale,n) : 0.;
1483}
1484
1485double Champ_Face_coeff_frottement_grad_face_bord(const int f, const int n, const Domaine_Cl_VDF& zclo)
1486{
1487 const Domaine_VDF& domaine_vdf = zclo.domaine_VDF();
1488 const Domaine_Cl_dis_base& zcl = zclo;
1489 const int face_globale = f + domaine_vdf.premiere_face_bord(); // Now index in the global face array.
1490
1491 int face_locale = -123;
1492 const Cond_lim_base& cl = (f < domaine_vdf.nb_faces()) ? zcl.condition_limite_de_la_face_reelle(face_globale, face_locale) :
1493 zcl.condition_limite_de_la_face_virtuelle(face_globale, face_locale);
1494
1495 return sub_type(Navier, cl) ? ref_cast(Navier, cl).coefficient_frottement_grad(face_locale,n) : 0.;
1496}
class Champ_Don_base base class of Given Fields (not calculated)
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
: class Champ_Don_lu This class represents a data field read from a file with the following conventio...
DoubleTab & trace(const Frontiere_dis_base &fr, const DoubleTab &y, DoubleTab &x, int distant) const
class Champ_Face_VDF
DoubleVect & calcul_S_barre(const DoubleTab &, DoubleVect &, const Domaine_Cl_VDF &) const
int imprime(Sortie &, int) const override
int compo_normale_sortante(int) const
void calcul_critere_Q(DoubleTab &, const Domaine_Cl_VDF &)
DoubleVect & calcul_S_barre_sans_contrib_paroi(const DoubleTab &, DoubleVect &, const Domaine_Cl_VDF &) const
Returns SMA_barre at elements from the face velocity.
void calculer_dercov_axi(const Domaine_Cl_VDF &)
void mettre_a_jour(double temps) override
Update of the base class Champ_base: does nothing!
void calculer_dscald_centre_element(DoubleTab &) const
void calcul_y_plus(DoubleTab &, const Domaine_Cl_VDF &)
void verifie_valeurs_cl() override
void calcul_grad_u(const DoubleTab &, DoubleTab &, const Domaine_Cl_VDF &)
virtual const Champ_Proto & affecter(const double x1, const double x2)
const Domaine_VDF & domaine_vdf() const override
int fixer_nb_valeurs_nodales(int) override
DoubleTab & calcul_duidxj(const DoubleTab &, DoubleTab &) const
Returns gij at elements from the element velocity (gij represents the partial derivative dui/dxj).
void calculer_rotationnel_ordre2_centre_element(DoubleTab &) const
DoubleTab & trace(const Frontiere_dis_base &, DoubleTab &, double, int distant) const override
Computes the trace of a field on a boundary at time tps.
Champ_base & affecter_(const Champ_base &) override
DoubleTab & calcul_S_barre_Multiphase(const DoubleTab &, DoubleTab &, const Domaine_Cl_VDF &) const
void dimensionner_tenseur_Grad()
virtual void creer_tableau_distribue(const MD_Vector &, RESIZE_OPTIONS=RESIZE_OPTIONS::COPY_INIT)
int lire_donnees(Entree &)
Reads the field values from an input stream.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
void mettre_a_jour(double temps) override
Performs a time update of the unknown field.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
class Champ_Proto Class representing a Field prototype.
Definition Champ_Proto.h:37
virtual DoubleTab & valeurs()=0
Champ_Uniforme_Morceaux This class represents a piecewise constant-in-space field.
Champ_Uniforme Represents a field that is constant in space and time.
Champ_base()
Default constructor of a Champ_base.
double temps() const
Returns the time of the field.
virtual DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const
Causes an error! Must be overridden by derived classes.
virtual DoubleTab & valeurs_au_temps(double temps)=0
virtual bool has_valeurs_au_temps(double temps) const
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
Champ_front_base & champ_front()
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
Dirichlet_entree_fluide This class represents a boundary condition imposing a quantity.
Dirichlet_paroi_defilante Imposes the wall velocity in an equation of type Navier_Stokes.
Dirichlet_paroi_fixe Represents a fixed wall in a Navier-Stokes type equation.
int_t nb_elem_tot() const
Definition Domaine.h:132
int_t nb_elem() const
Definition Domaine.h:131
class Domaine_Cl_VDF
int type_arete_bord(int num_arete) const
Domaine_VDF & domaine_VDF()
const int & type_arete_coin(int num_arete) const
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
int nb_cond_lim() const
Returns the number of boundary conditions.
const Cond_lim_base & condition_limite_de_la_face_reelle(int face_globale, int &face_locale) const
Returns the boundary condition associated with a given real face.
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
const Cond_lim_base & condition_limite_de_la_face_virtuelle(int face_globale, int &face_locale) const
Returns the boundary condition associated with a given virtual face.
class Domaine_VDF
Definition Domaine_VDF.h:61
int nb_aretes_coin() const
double dist_norm_bord_axi(int num_face) const
Returns the normal distance for a boundary face (cylindrical coordinates).
double dist_face_period(int, int, int) const
int nb_aretes() const
double dim_elem(int, int) const
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int premiere_arete_bord() const
int premiere_arete_coin() const
int nb_aretes_internes() const
int premiere_arete_interne() const
int nb_aretes_bord() const
int nb_aretes_mixtes() const
double dist_face(int, int, int k) const
Returns the distance between two face centers in direction k (Cartesian only).
int premiere_arete_mixte() const
int Qdm(int num_arete, int) const
double dist_norm_bord(int num_face) const override
Returns the normal distance for a boundary face (Cartesian coordinates).
int premiere_face_bord() const
Returns the index of the first face on which boundary conditions are applied:
Definition Domaine_VF.h:522
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
const MD_Vector & md_vector_faces() const
Definition Domaine_VF.h:158
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Milieu_base & milieu() const =0
virtual const RefObjU & get_modele(Type_modele type) const
const Nom & le_nom() const override
Returns the name of the field.
int nb_compo_
Definition Field_base.h:95
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
const Champ_Don_base & viscosite_cinematique() const
Definition Fluide_base.h:56
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
class Frontiere_dis_base Class representing a discretized boundary.
: This class is an OWN_PTR but the pointed object is shared among multiple
Definition MD_Vector.h:48
DoubleVect & porosite_face()
Definition Milieu_base.h:62
Base class for the turbulence model hierarchy for Navier-Stokes equations.
const Turbulence_paroi_base & loi_paroi() const
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
Navier Velocity boundary condition of type "Navier":
Definition Navier.h:31
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static int axi
Definition Objet_U.h:96
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static int traitement_coins
Definition Option_VDF.h:30
static int traitement_gradients
Definition Option_VDF.h:30
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
virtual void ref(const TRUSTTab &)
Definition TRUSTTab.tpp:308
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int line_size() const
Definition TRUSTVect.tpp:67
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
const Objet_U & valeur() const
Definition TRUST_Ref.h:134
Base class for the hierarchy of wall-law models computing turbulent quantities near walls....
const DoubleVect & tab_d_plus() const
virtual bool use_shear() const