TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Domaine_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 <Domaine_VDF.h>
17#include <Domaine_Cl_VDF.h>
18#include <Rectangle.h>
19#include <Hexaedre.h>
20#include <Faces_VDF.h>
21#include <Aretes.h>
22#include <Periodique.h>
23#include <Dirichlet_entree_fluide_leaves.h>
24#include <Neumann_sortie_libre.h>
25#include <EcrFicCollecte.h>
26#include <math.h>
27#include <TRUSTTrav.h>
28
29Implemente_instanciable(Domaine_VDF,"Domaine_VDF",Domaine_VF);
30
31//#define SORT_POUR_DEBOG
32
34{
36 os << "orientation_" << orientation_ << finl;
37 os << "nb_faces_X_" << nb_faces_X_ << finl;
38 os << "nb_faces_Y_" << nb_faces_Y_ << finl;
39 os << "nb_faces_Z_" << nb_faces_Z_ << finl;
40 os << "nb_aretes_" << nb_aretes_ << finl;
41 os << "nb_aretes_joint_" << nb_aretes_joint_ << finl;
42 os << "nb_aretes_coin_" << nb_aretes_coin_ << finl;
43 os << "nb_aretes_bord_" << nb_aretes_bord_ << finl;
44 os << "nb_aretes_mixtes_" << nb_aretes_mixtes_ << finl;
45 os << "nb_aretes_internes_" << nb_aretes_internes_ << finl;
46 Qdm_.ecrit(os << "Qdm : ");
47 os << h_x_ << " " << h_y_ << " " << h_z_ << finl;
48 return os;
49}
50
52{
54 is >> orientation_;
55 is >> nb_faces_X_;
56 is >> nb_faces_Y_;
57 is >> nb_faces_Z_;
58 is >> nb_aretes_;
59 is >> nb_aretes_joint_;
60 is >> nb_aretes_coin_;
61 is >> nb_aretes_bord_;
62 is >> nb_aretes_mixtes_;
63 is >> nb_aretes_internes_;
64 Qdm_.lit(is);
65 is >> h_x_ >> h_y_ >> h_z_;
66 return is;
67}
68/*! @brief renvoie un Faces_VDF* !
69 *
70 */
72{
73 Faces_VDF* les_faces_vdf=new(Faces_VDF);
74 return les_faces_vdf;
75}
76
77/*! Override to do nothing. Not necessary for VDF.
78 */
82
83/*! @brief Override. Compute sorting key so that internal faces are sorted by their orientation first (X, Y, Z)
84 */
85void Domaine_VDF::compute_sort_key(Faces& les_faces, IntTab& sort_key)
86{
87 // Calcul de l'orientation des faces reeles
88 Faces_VDF& les_faces_vdf=ref_cast(Faces_VDF, les_faces);
89 les_faces_vdf.calculer_orientation(orientation_, nb_faces_X_, nb_faces_Y_, nb_faces_Z_);
90
91 const int nb_faces_front = domaine().nb_faces_frontiere();
92
93 // Construction d'un int selon lequel on va trier les faces:
94 // orientation * nb_faces + indice_face
95 // Quand on trie par ordre croissant de cet int, on trie selon l'orientation
96 // en preservant l'ordre initial des faces de meme orientation
97 const int nb_faces = les_faces_vdf.nb_faces();
98
99 nb_faces_std_ = 0;
100 sort_key.resize(nb_faces, 2);
101 // On ne trie pas les faces de bord, qui restent au debut:
102 for (int i = 0; i < nb_faces_front; i++)
103 {
104 sort_key(i, 0) = i;
105 sort_key(i, 1) = i;
106 }
107
108 for (int i=nb_faces_front; i < nb_faces; i++)
109 {
110 const int ori = orientation_[i];
111 sort_key(i, 0) = ori * nb_faces + i;
112 sort_key(i, 1) = i;
113 }
114 nb_faces_std_ = nb_faces - nb_faces_front; // not as funny as in VEF ... :-)
115}
116
117/*! @brief Override to also renumber orientation_ member.
118 */
119void Domaine_VDF::renumber_faces(Faces& les_faces, IntTab& sort_key)
120{
121 Domaine_VF::renumber_faces(les_faces, sort_key);
122
123 const int nb_faces_front = domaine().nb_faces_frontiere();
124 const int nb_faces = les_faces.nb_faces();
125
126 IntVect old_orien(orientation_);
127 for (int i=nb_faces_front; i < nb_faces; i++)
128 {
129 const int idx = sort_key(i, 1);
130 orientation_[i] = old_orien[idx];
131 }
132}
133
134
135/*! @brief appel a Domaine_VF::discretiser() calcul des centres de gravite des elements
136 *
137 * remplissage des connectivites elements/faces
138 * on reordonne les connectivites faces/elements
139 * de sorte que el1 est a gauche et el2 a droite.
140 * calcul des porosites volumiques et surfaciques
141 * generation des aretes
142 * calcul des pas du maillage
143 *
144 */
146{
148
149 Domaine& domaine_geom=domaine();
150
151 // Verification de la coherence entre l'element geometrique et la discretisation
152
153 const Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
154
155 if (dimension == 2)
156 {
157 if (!sub_type(Rectangle,elem_geom))
158 {
159 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
160 Cerr << " Seul le type Rectangle et Rectangle_Axi sont compatibles avec la discretisation VDF en dimension 2" << finl;
161 exit();
162 }
163 }
164 else if (dimension == 3)
165 {
166 if (!sub_type(Hexaedre,elem_geom))
167 {
168 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
169 Cerr << " Seul le type Hexaedre ou Hexadre_Axi sont compatibles avec la discretisation VDF en dimension 3" << finl;
170 exit();
171 }
172 }
173 // Calcul de l'orientation des faces virtuelles
174 // Note BM: pour compatibilite avec la version 1.5, orientation_
175 // n'a pas d'espace virtuel.
176 MD_Vector md_nul;
177 creer_tableau_faces(orientation_);
178 orientation_.echange_espace_virtuel();
179 orientation_.set_md_vector(md_nul); // Detache la structure parallele
180
181 // Application de la convention VDF sur face_voisin:
182 // L'element face_voisin(i,0) doit avoir une coordonnee "ori" plus petite que la face
183 // et l'element face_voisin(i,1) doit avoir une coordonnee plus grande.
184 {
185 const int nbr_faces_tot = face_voisins_.dimension_tot(0);
186 for (int i_face = 0; i_face < nbr_faces_tot; i_face++)
187 {
188 const int elem0 = face_voisins_(i_face, 0);
189 const int elem1 = face_voisins_(i_face, 1);
190 const int ori = orientation_[i_face];
191 const double x_face = xv(i_face, ori);
192 double delta = 0.;
193 // L'element 0 doit avoir une coordonnee "ori" plus petite que la face
194 // et l'element 1 doit avoir une coordonnee plus grande.
195 if (elem0 >= 0)
196 {
197 delta = x_face - xp(elem0, ori);
198 }
199 else
200 {
201 assert(elem1 >= 0); // Sinon, grosse erreur: elements voisins non renseignes
202 delta = xp(elem1, ori) - x_face;
203 }
204 if (delta < 0)
205 {
206 // On inverse les deux elements
207 face_voisins_(i_face, 0) = elem1;
208 face_voisins_(i_face, 1) = elem0;
209 }
210 }
211 }
212
214 genere_aretes();
215 calcul_h();
216 remplir_face_normales();
217 Cerr << "L'objet de type Domaine_VDF a ete rempli avec succes " << finl;
218
219}
220
221void Domaine_VDF::remplir_face_normales()
222{
223 // On remplit le tableau face_normales_;
224 // Attention : le tableau face_voisins n'est pas exactement un tableau distribue. Une face n'a pas ses deux voisins dans le
225 // meme ordre sur tous les processeurs qui possedent la face.
226 // Donc la normale a la face peut changer de direction d'un processeur a l'autre, y compris pour les faces de joint.
227 face_normales_ = xv_; // already has // structure
228 face_normales_ = 0.;
229
230 for (int f = 0; f < nb_faces_tot(); f++)
231 {
232 int ori = orientation(f);
233 face_normales_(f,ori) = face_surfaces(f);
234 }
235}
236
237/*! @brief remplissage des volumes entrelaces
238 *
239 */
241{
242 Cerr << "On calcule les volumes entrelaces" << finl;
246
247 const int nb_faces_front = premiere_face_int();
248 const int nbf = nb_faces();
249 for (int num_face = 0; num_face<nbf; num_face++)
250 {
251 const double f = (num_face < nb_faces_front) ? 2. : 1.;
252 for (int dir = 0; dir < 2; dir ++)
253 {
254 int elem = face_voisins_(num_face, dir);
255 if (elem != -1)
256 {
257 if ((axi) && (orientation_[num_face]==0))
258 volumes_entrelaces_dir_(num_face, dir) = f * 0.5 * xv_(num_face, 0) * volumes(elem) / xp(elem, 0);
259 else if ((bidim_axi) && (orientation_[num_face]==0))
260 volumes_entrelaces_dir_(num_face, dir) = volume_entrelace_axi(std::fabs(xv(num_face, 0)), std::fabs(xp(elem, 0)), dim_elem(elem, 1));
261 else
262 volumes_entrelaces_dir_(num_face, dir) = f * 0.5 * volumes(elem);
263
264 volumes_entrelaces_[num_face] += volumes_entrelaces_dir_(num_face, dir);
265 }
266 }
267 }
268 volumes_entrelaces_.echange_espace_virtuel();
269 volumes_entrelaces_dir_.echange_espace_virtuel();
270}
271
272static inline int face_vois(const Domaine_VDF& zvdf, const Domaine& domaine, int face, int i)
273{
274 int elem=zvdf.face_voisins(face,i);
275 if(elem==-1)
276 {
277 face=domaine.face_bords_interne_conjuguee(face);
278 if(face!=-1)
279 {
280 elem=zvdf.face_voisins(face,i);
281 assert(elem!=-1);
282 }
283 }
284 return elem;
285}
286
287/*! @brief generation des aretes
288 *
289 */
290void Domaine_VDF::genere_aretes()
291{
292 Cerr << "On genere les aretes" << finl;
293
294 Domaine& mon_dom=domaine();
295 // int nb_poly = le_dom.nb_elem();
296 int nb_poly_tot = mon_dom.nb_elem_tot();
297 // Estimation avec majoration du nombre d'aretes : nb_aretes_plus
298 nb_aretes_=-1; // cf Aretes::affecter
299 int nb_aretes_plus=-1;
300 if (dimension == 2)
301 nb_aretes_plus = mon_dom.nb_som();
302 else if (dimension == 3)
303 nb_aretes_plus = mon_dom.nb_som()*3;
304 Cerr << "Creation des aretes " << finl;
305 Aretes les_aretes(nb_aretes_plus);
306
307 // On balaie les elements :
308 int el1, el2, el3, el4;
309 int face12, face13, face34, face24;
310
311 int nb_dir;
312 if(dimension==2) nb_dir=1;
313 else nb_dir=3;
314 IntVect gauche(nb_dir);
315 gauche(0)=0;
316 if(dimension==3)
317 {
318 gauche(1)=0;
319 gauche(2)=1;
320 }
321 IntVect droite(nb_dir);
322 droite(0)=dimension;
323 if(dimension==3)
324 {
325 droite(1)=dimension;
326 droite(2)=dimension+1;
327 }
328 IntVect haut(nb_dir);
329 haut(0)=dimension+1;
330 if(dimension==3)
331 {
332 haut(1)=dimension+2;
333 haut(2)=dimension+2;
334 }
335 IntVect bas(nb_dir);
336 bas(0)=1;
337 if(dimension==3)
338 {
339 bas(1)=2;
340 bas(2)=2;
341 }
342
343 int coin=-1;
344 int bord=0;
345 int mixte=1;
346 int interne=2;
347 // Detection des plaques (2 faces frontieres se superposent):
348 IntVect est_une_plaque(nb_faces());
349 creer_tableau_faces(est_une_plaque);
350 est_une_plaque=0;
351 // Boucles sur les faces frontieres
352 ArrOfDouble P1(3), P2(3);
353 P1=0;
354 P2=0;
355 double eps = 10.0*Objet_U::precision_geom;
356 for (int face=0; face<premiere_face_int(); face++)
357 {
358 int ori = orientation(face);
359 for (int i = 0; i < dimension; i++)
360 {
361 P1[i] = xv(face, i) + (ori == i ? eps : 0);
362 P2[i] = xv(face, i) - (ori == i ? eps : 0);
363 }
364 int elem1 = domaine().chercher_elements(P1[0], P1[1], P1[2]);
365 int elem2 = domaine().chercher_elements(P2[0], P2[1], P2[2]);
366 if (elem1 >= 0 && elem2 >= 0 && elem1 != elem2)
367 {
368 // Find 2 points P1 and P2 in cells so:
369 est_une_plaque(face) = 1;
370 //Journal() << "We detect an internal boundary on face " << face << " between elements " << elem1 << " and " << elem2 << finl;
371 }
372 }
373 est_une_plaque.echange_espace_virtuel();
374
375 for(int dir=0; dir<nb_dir; dir++)
376 for (el1=0; el1<nb_poly_tot; el1++)
377 {
378 // On doit generer l'arete en haut a droite de el1
379 face12=elem_faces(el1,droite(dir));
380 face13=elem_faces(el1,haut(dir));
381
382 el2=face_vois(*this, mon_dom, face12, 1);
383
384 if(el2>-1)
385 face24=elem_faces(el2,haut(dir));
386 else
387 face24=-1;
388
389 el3=face_vois(*this, mon_dom, face13, 1);
390
391 if(el3>-1)
392 face34=elem_faces(el3,droite(dir));
393 else
394 face34=-1;
395
396 if( (el2>-1) && (el3>-1))
397 el4=face_vois(*this, mon_dom, face24, 1);
398 else if((el2>-1))
399 el4=face_vois(*this, mon_dom, face24, 1);
400 else if((el3>-1))
401 el4=face_vois(*this, mon_dom, face34, 1);
402 else
403 el4=-1;
404
405 if ( (el2==-1) && (el4>=0) )
406 face24=elem_faces(el4,bas(dir));
407 if ( (el3==-1) && (el4>=0) )
408 face34=elem_faces(el4,gauche(dir));
409
410 const int nb_f = nb_faces();
411 if (el2 > -1 && el3 > -1 && el4 > -1) // arete interne
412 les_aretes.affecter(nb_aretes_, dir, interne, nb_f, face13, face24, face12, face34, est_une_plaque);
413 else if ( (el3 > -1 && el4 > -1) ||
414 (el2 > -1 && el4 > -1) ||
415 (el2 > -1 && el3 > -1) ) // arete mixte
416 les_aretes.affecter(nb_aretes_, dir, mixte, nb_f, face13, face24, face12, face34, est_une_plaque);
417 else if (el2 > -1) // arete bord
418 les_aretes.affecter(nb_aretes_, dir, bord, nb_f, face13, face24, face12, 1, est_une_plaque);
419 else if (el3 > -1) // arete bord
420 les_aretes.affecter(nb_aretes_, dir, bord, nb_f, face12, face34, face13, 1, est_une_plaque);
421 else // arete coin
422 les_aretes.affecter(nb_aretes_, dir, coin, nb_f, face13, face24, face12, face34, est_une_plaque);
423 //Cerr << "elements_haut_droit " << el1 << " " << el2 << " " << el3 << " " << el4 << finl;
424 //Journal() << "Provisoire faces arete: " << face12 << " " << face13 << " " << face24 << " " << face34 << finl;
425
426 // Pour les coins ou bords :
427 face13 = elem_faces(el1, bas(dir));
428 el3 = face_vois(*this, mon_dom, face13, 0);
429 if (el3 < 0) // On doit generer l'arete en bas a droite de el1
430 // si la maille en bas de el1 n'existe pas
431 {
432 if (el2 >= 0)
433 {
434 face24 = elem_faces(el2, bas(dir));
435 el4 = face_vois(*this, mon_dom, face24, 0);
436 if (el4 < 0) // arete bord
437 les_aretes.affecter(nb_aretes_, dir, bord, nb_f, face13, face24, face12, -1, est_une_plaque);
438 else // arete mixte
439 {
440 face34 = elem_faces(el4, gauche(dir));
441 if (face_vois(*this, mon_dom, face34, 0) == -1)
442 les_aretes.affecter(nb_aretes_, dir, mixte, nb_f, face13, face24, face34, face12, est_une_plaque);
443 }
444 }
445 else // arete coin
446 les_aretes.affecter(nb_aretes_, dir, coin, nb_f, face13, -1, -1, face12, est_une_plaque);
447 //Cerr << "elements_bas_droit " << el1 << " " << el2 << " " << el3 << " " << el4 << finl;
448 }
449
450
451 face13 = elem_faces(el1, gauche(dir));
452 el3 = face_vois(*this, mon_dom, face13, 0);
453 if (el3 < 0) // On doit generer l'arete en haut a gauche de el1
454 // si la maille en haut a gauche n'existe pas
455 {
456 face12 = elem_faces(el1, haut(dir));
457 el2 = face_vois(*this, mon_dom, face12, 1);
458 if (el2 >= 0)
459 {
460 face24 = elem_faces(el2, gauche(dir));
461 el4 = face_vois(*this, mon_dom, face24, 0);
462 if (el4 < 0) // arete bord
463 les_aretes.affecter(nb_aretes_, dir, bord, nb_f, face13, face24, face12, -1, est_une_plaque);
464 }
465 else // arete coin
466 les_aretes.affecter(nb_aretes_, dir, coin, nb_f, -1, face12, -1, face13, est_une_plaque);
467 //Cerr << "elements_haut_gauche " << el1 << " " << el2 << " " << el3 << " " << el4 << finl;
468 }
469
470 // On doit generer l'arete en bas a gauche de el1
471 face12 = elem_faces(el1, gauche(dir));
472 el2 = face_vois(*this, mon_dom, face12, 0);
473 face13 = elem_faces(el1, bas(dir));
474 el3 = face_vois(*this, mon_dom, face13, 0);
475 if ((el2 < 0) && (el3 < 0)) // arete coin
476 {
477 les_aretes.affecter(nb_aretes_, dir, coin, nb_f, face13, -1, face12, -1, est_une_plaque);
478 //Cerr << "elements_bas_gauche " << el1 << " " << el2 << " " << el3 << " " << el4 << finl;
479 }
480 }
481 nb_aretes_++;
482 les_aretes.dimensionner(nb_aretes_);
483 // Cerr << "Tri des aretes " << finl;
484 les_aretes.trier(nb_aretes_coin_,
485 nb_aretes_bord_,
486 nb_aretes_mixtes_,
487 nb_aretes_internes_);
488#ifdef SORT_POUR_DEBOG
489
490 les_aretes.trier_pour_debog(nb_aretes_coin_,
491 nb_aretes_bord_,
492 nb_aretes_mixtes_,
493 nb_aretes_internes_,xv());
494#endif
495 nb_aretes_joint_=0;
496 assert(nb_aretes_==nb_aretes_coin_+nb_aretes_bord_+nb_aretes_mixtes_
497 +nb_aretes_internes_+nb_aretes_joint_);
498 Qdm_.ref(les_aretes.faces());
499 /*
500 // Boucle pour verifier ou sont les parois internes
501 for (int i=0; i<Qdm_.dimension(0); i++)
502 {
503 int nb_plaques = 0;
504 for (int j = 0; j < Qdm_.dimension(1); j++)
505 nb_plaques += Qdm_(i, j) >= 0 ? est_une_plaque(Qdm_(i, j)) : 0;
506 if (nb_plaques > 0)
507 Journal() << "Provisoire arete " << i << " a " << nb_plaques << " paroi internes." << finl;
508 }
509 Journal() << "Aretes coin = " << nb_aretes_coin_ << finl;
510 Journal() << "Aretes bord = " << nb_aretes_bord_ << finl;
511 Journal() << "Aretes mixte = " << nb_aretes_mixtes_ << finl;
512 Journal() << "Aretes interne= " << nb_aretes_internes_ << finl;
513 Journal() << "Aretes joint = " << nb_aretes_joint_ << finl;
514 */
515 //Cerr << "Qdm : " << Qdm_ << finl;
516}
517
518/*! @brief calcul des pas du maillage
519 *
520 */
521void Domaine_VDF::calcul_h()
522{
523 Domaine& domaine_geom=domaine();
524 IntVect numfa(domaine_geom.nb_faces_elem());
525 const double deux_pi = M_PI * 2.0;
526 const int D = dimension;
527
528 for (int e = 0; e < domaine_geom.nb_elem(); e++)
529 {
530 for (int j = 0; j < domaine_geom.nb_faces_elem(); j++)
531 numfa[j] = elem_faces(e, j);
532
533 h_x_ = std::min(h_x_, xv_(numfa[D], 0) - xv_(numfa[0], 0));
534 double hy_loc;
535 if (axi)
536 {
537 double d_teta = xv_(numfa[D + 1], 1) - xv_(numfa[1], 1);
538 if (d_teta < 0) d_teta += deux_pi;
539 hy_loc = d_teta * xv_(numfa[1], 0);
540 }
541 else hy_loc = xv_(numfa[D + 1], 1) - xv_(numfa[1], 1);
542 h_y_ = std::min(h_y_, hy_loc);
543 if (dimension == 3) h_z_ = std::min(h_z_, xv_(numfa[5], 2) - xv_(numfa[2], 2));
544 }
545 h_x_ = mp_min(h_x_);
546 h_y_ = mp_min(h_y_);
547 h_z_ = mp_min(h_z_);
548}
549
551{
552 // Cerr << "Domaine_VDF::Modifier_pour_Cl" << finl;
554
555 int fac3;
556 int nb_cond_lim=conds_lim.size();
557 IntTab aretes_coin_traitees(nb_aretes_coin());
558 aretes_coin_traitees = -1;
559
560 for (int num_cond_lim=0; num_cond_lim<nb_cond_lim; num_cond_lim++)
561 {
562 // for cl ...
563 //Journal() << "On traite la cl num : " << num_cond_lim << finl;
564 const Cond_lim_base& cl = conds_lim[num_cond_lim].valeur();
565 if (sub_type(Periodique, cl))
566 {
567 // if cl perio
568
569 // Modification du tableau Qdm_ pour les aretes de type periodicite
570
571 const Domaine_Cl_VDF& domaine_Cl_VDF = ref_cast(Domaine_Cl_VDF,cl.domaine_Cl_dis());
572
573 int ndeb_arete = premiere_arete_bord();
574 int fac1,fac2,sign,num_face,elem1,n_type;
575 for (int n_arete=ndeb_arete; n_arete<ndeb_arete+nb_aretes_bord(); n_arete++)
576 {
577 // for n_arete
578 n_type=domaine_Cl_VDF.type_arete_bord(n_arete-ndeb_arete);
579
580 if (n_type == TypeAreteBordVDF::PERIO_PERIO) // arete de type periodicite
581 {
582 //if arete perio
583 fac1 = Qdm_(n_arete,0);
584 fac2 = Qdm_(n_arete,1);
585 fac3 = Qdm_(n_arete,2);
586 sign = Qdm_(n_arete,3);
587
588 const Front_VF& la_frontiere_dis = ref_cast(Front_VF,cl.frontiere_dis());
589 int ndeb = la_frontiere_dis.num_premiere_face();
590 int nfin = ndeb + la_frontiere_dis.nb_faces();
591 if ( ( ( ndeb <= fac1) && (fac1 < nfin) ) ||
592 ( ( ndeb <= fac2) && (fac2 < nfin) )
593 )
594 {
595 if (sign == 1)
596 elem1 = face_voisins(fac1,1);
597 else
598 elem1 = face_voisins(fac1,0);
599 num_face = dimension+orientation_[fac3];
600
601 if (sign == -1)
602 {
603 Qdm_(n_arete,3) = fac3;
604 Qdm_(n_arete,2) = elem_faces(elem1,num_face);
605 }
606 else
607 Qdm_(n_arete,3) = elem_faces(elem1,num_face);
608 }
609 }
610 }
611 // prise en compte des aretes coin
612 int ndeb_arete_coin = premiere_arete_coin();
613 Cerr << "Modifications de Qdm pour les aretes coins num_cond_lim=" << num_cond_lim << finl;
614 int fac4;
615
616 for (int n_arete=ndeb_arete_coin; n_arete<ndeb_arete_coin+nb_aretes_coin(); n_arete++)
617 {
618 if (aretes_coin_traitees[n_arete] != 1)
619 {
620 fac1 = Qdm_(n_arete,0);
621 fac2 = Qdm_(n_arete,1);
622 fac3 = Qdm_(n_arete,2);
623 fac4 = Qdm_(n_arete,3);
624
625 // On recupere le numero des faces qui ne sont pas egales a -1
626 IntVect f(2);
627 f = -2;
628 int i=0;
629 if (fac1 != -1)
630 {
631 f(i) = fac1;
632 i++;
633 }
634 if (fac2 != -1)
635 {
636 f(i) = fac2;
637 i++;
638 }
639 if (fac3 != -1)
640 {
641 f(i) = fac3;
642 i++;
643 }
644 if (fac4 != -1)
645 {
646 f(i) = fac4;
647 i++;
648 }
649
650 // On regarde si la face est une face de periodicite
651
652 const Front_VF& la_frontiere_dis = ref_cast(Front_VF,cl.frontiere_dis());
653 int ndeb = la_frontiere_dis.num_premiere_face();
654 int nfin = ndeb + la_frontiere_dis.nb_faces();
655 int elem, fac,dim0,dim1,indic_f0=-100,indic_f1=-100;
656
657 n_type=domaine_Cl_VDF.type_arete_coin(n_arete-ndeb_arete_coin);
658 dim1 = orientation_[f(1)];
659 dim0 = orientation_[f(0)];
660
661 for (int j=0; j<2; j++)
662 for (int k=0; k<2; k++)
663 if ((face_voisins(f(0),j) == face_voisins(f(1),k)) && (face_voisins(f(0),j)!=-1) )
664 {
665 indic_f0 = j;
666 indic_f1 = k;
667 }
668
669 if ((n_type == TypeAreteCoinVDF::PERIO_PAROI) || (n_type == TypeAreteCoinVDF::PERIO_FLUIDE))// arete coin perio-paroi
670 {
671 if ((f(0) >= ndeb)&&(f(0) < nfin))
672 {
673 Qdm_(n_arete,2)=f(0);
674 Qdm_(n_arete,indic_f0)=f(1);
675
676 elem = face_voisins(f(0),1-indic_f0);
677 fac = elem_faces(elem,dim1+(1-indic_f1)*dimension);
678 Qdm_(n_arete,1-indic_f0)=fac;
679
680 Qdm_(n_arete,3)=1-2*indic_f1;
681
682 // Cerr << "n_arete=" << n_arete << " OK!!" << finl;
683 aretes_coin_traitees[n_arete] = 1;
684 }
685 else
686 {
687 if ((f(1) >= ndeb)&&(f(1) < nfin))
688 {
689 Qdm_(n_arete,2)=f(1);
690 Qdm_(n_arete,indic_f1)=f(0);
691
692 elem = face_voisins(f(1),1-indic_f1);
693 fac = elem_faces(elem,dim0+(1-indic_f0)*dimension);
694 Qdm_(n_arete,1-indic_f1)=fac;
695
696 Qdm_(n_arete,3)=1-2*indic_f0;
697
698 // Cerr << "n_arete=" << n_arete << " OK!!" << finl;
699 aretes_coin_traitees[n_arete] = 1;
700 }
701 else
702 {
703 // Cerr<<"Attention cas non traite lors du remplissage du tableau Qdm"<<finl;
704 // exit();
705 ;
706 }
707 }
708 }
709 else if (n_type == TypeAreteCoinVDF::PERIO_PERIO) // arete coin perio-perio
710 {
711 if ((f(0) >= ndeb)&&(f(0) < nfin))
712 {
713 Qdm_(n_arete,2+indic_f1)=f(0);
714 Qdm_(n_arete,indic_f0)=f(1);
715
716 elem = face_voisins(f(0),1-indic_f0);
717 fac = elem_faces(elem,dim1+(1-indic_f1)*dimension);
718 Qdm_(n_arete,1-indic_f0)=fac;
719
720 elem = face_voisins(f(1),1-indic_f1);
721 fac = elem_faces(elem,dim0+(1-indic_f0)*dimension);
722 Qdm_(n_arete,3-indic_f1)=fac;
723
724 // Cerr << "n_arete=" << n_arete << " OK!!" << finl;
725 aretes_coin_traitees[n_arete] = 1;
726 }
727 else
728 {
729 if ((f(1) >= ndeb)&&(f(1) < nfin))
730 {
731 Qdm_(n_arete,2+indic_f0)=f(1);
732 Qdm_(n_arete,indic_f1)=f(0);
733
734 elem = face_voisins(f(1),1-indic_f1);
735 fac = elem_faces(elem,dim0+(1-indic_f0)*dimension);
736 Qdm_(n_arete,1-indic_f1)=fac;
737
738 elem = face_voisins(f(0),1-indic_f0);
739 fac = elem_faces(elem,dim1+(1-indic_f1)*dimension);
740 Qdm_(n_arete,3-indic_f0)=fac;
741
742 // Cerr << "n_arete=" << n_arete << " OK!!" << finl;
743 aretes_coin_traitees[n_arete] = 1;
744 }
745 }
746 }
747
748 else
749 {
750 Cerr << "Attention : les cas concernant d autres types d aretes coin " << finl;
751 Cerr << "que perio-perio ou perio-paroi ne sont pas traites!!" << finl;
752 }
753 }
754 }
755 }
756
757 // Modif OC 01/2005 pour traiter les coins de type paroi/fluide
758 else if (sub_type(Dirichlet_entree_fluide, cl) || sub_type(Neumann_sortie_libre, cl) )
759 {
760 // if cl de type paroi
761
762 const Domaine_Cl_VDF& domaine_Cl_VDF = ref_cast(Domaine_Cl_VDF,cl.domaine_Cl_dis());
763
764 int fac1,fac2,n_type;
765 int ndeb_arete_coin = premiere_arete_coin();
766 Cerr << "Modifications de Qdm pour les aretes coins touchant une paroi num_cond_lim=" << num_cond_lim << finl;
767 int fac4;
768
769 for (int n_arete=ndeb_arete_coin; n_arete<ndeb_arete_coin+nb_aretes_coin(); n_arete++)
770 {
771 if (aretes_coin_traitees[n_arete] != 1)
772 {
773 fac1 = Qdm_(n_arete,0);
774 fac2 = Qdm_(n_arete,1);
775 fac3 = Qdm_(n_arete,2);
776 fac4 = Qdm_(n_arete,3);
777
778 // On recupere le numero des faces qui ne sont pas egales a -1
779 IntVect f(2);
780 f = -2;
781 int i=0;
782 if (fac1 != -1)
783 {
784 f(i) = fac1;
785 i++;
786 }
787 if (fac2 != -1)
788 {
789 f(i) = fac2;
790 i++;
791 }
792 if (fac3 != -1)
793 {
794 f(i) = fac3;
795 i++;
796 }
797 if (fac4 != -1)
798 {
799 f(i) = fac4;
800 i++;
801 }
802
803 // On regarde si la face est une face de type paroi
804
805 const Front_VF& la_frontiere_dis = ref_cast(Front_VF,cl.frontiere_dis());
806 int ndeb = la_frontiere_dis.num_premiere_face();
807 int nfin = ndeb + la_frontiere_dis.nb_faces();
808 int indic_f0=-100,indic_f1=-100;
809
810 n_type=domaine_Cl_VDF.type_arete_coin(n_arete-ndeb_arete_coin);
811
812 for (int j=0; j<2; j++)
813 for (int k=0; k<2; k++)
814 if ((face_voisins(f(0),j) == face_voisins(f(1),k)) && (face_voisins(f(0),j)!=-1) )
815 {
816 indic_f0 = j;
817 indic_f1 = k;
818 }
819
820 if ((n_type == TypeAreteCoinVDF::PAROI_FLUIDE) || (n_type == TypeAreteCoinVDF::FLUIDE_PAROI) || (n_type == TypeAreteCoinVDF::FLUIDE_FLUIDE))// arete coin paroi-fluide
821 {
822 if ((f(0) >= ndeb)&&(f(0) < nfin))
823 {
824 Qdm_(n_arete,0)=f(1);
825 Qdm_(n_arete,1)=f(1);
826 Qdm_(n_arete,2)=f(0);
827 Qdm_(n_arete,3)=1-2*indic_f1;
828 aretes_coin_traitees[n_arete] = 1;
829 }
830 else
831 {
832 if ((f(1) >= ndeb)&&(f(1) < nfin))
833 {
834 Qdm_(n_arete,0)=f(0);
835 Qdm_(n_arete,1)=f(0);
836 Qdm_(n_arete,2)=f(1);
837 Qdm_(n_arete,3)=1-2*indic_f0;
838 aretes_coin_traitees[n_arete] = 1;
839 }
840 else
841 {
842 // Cerr<<"Attention cas non traite lors du remplissage du tableau Qdm"<<finl;
843 // exit();
844 ;
845 }
846 }
847 }
848 }
849 }
850 }
851
852 // Cerr << "Qdm : " << Qdm_ << finl;
853 // Cerr << "aretes_coin_traitees : " << aretes_coin_traitees << finl;
854 }
855 //Journal() << "le_dom apres modif pour Cl : " << *this << finl;
856
857
858 // PQ : 10/10/05 : les faces periodiques etant a double contribution
859 // l'appel a marquer_faces_double_contrib s'effectue dans cette methode
860 // afin de pouvoir beneficier de conds_lim.
861
862
864}
865
866/*! @brief remplit le tableau face_voisins_fictifs_ ne CREE PAS d elts fictifs!!!
867 *
868 */
869
871{
872 Cerr << "Domaine_VDF::creer_elements_fictifs()" << finl;
873 const Domaine_Cl_VDF& zclvdf = ref_cast(Domaine_Cl_VDF,zcldisbase);
874 if (face_voisins_fictifs_.size() == 0)
875 {
878 int compteur = nb_elem_tot();
879 int face,ndeb,nfin;
880
881 for (int n_bord=0; n_bord<nb_front_Cl(); n_bord++)
882 {
883 const Cond_lim& la_cl = zclvdf.les_conditions_limites(n_bord);
884 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
885 if ( (sub_type(Dirichlet_entree_fluide,la_cl.valeur())) ||
886 (sub_type(Neumann_sortie_libre,la_cl.valeur())) )
887 {
888 ndeb = le_bord.num_premiere_face();
889 nfin = ndeb + le_bord.nb_faces();
890 for (face=ndeb; face<nfin; face++)
891 if (face_voisins(face,0) != -1)
892 face_voisins_fictifs_(face,1) = compteur++;
893 else
894 face_voisins_fictifs_(face,0) = compteur++ ;
895 }
896 }
897 }
898 Cerr << "taille "<<face_voisins_fictifs_.size()-nb_elem()<<finl;
899}
900
901// Remplit le tableau dist avec les valeurs des distances normales
902// au bord des faces du bord de nom nom_bord
903// Le tableau dist est dimensionne par la methode
904DoubleVect& Domaine_VDF::dist_norm_bord(DoubleVect& dist, const Nom& nom_bord) const
905{
906 if (axi)
907 {
908 for (int n_bord=0; n_bord<les_bords_.size(); n_bord++)
909 {
910 const Front_VF& fr_vf = front_VF(n_bord);
911 if (fr_vf.le_nom() == nom_bord)
912 {
913 dist.resize(fr_vf.nb_faces());
914 int ndeb = fr_vf.num_premiere_face();
915 for (int face=ndeb; face<ndeb+fr_vf.nb_faces(); face++)
916 dist(face-ndeb) = dist_norm_bord_axi(face);
917 }
918 }
919 }
920 else
921 {
922 for (int n_bord=0; n_bord<les_bords_.size(); n_bord++)
923 {
924 const Front_VF& fr_vf = front_VF(n_bord);
925 if (fr_vf.le_nom() == nom_bord)
926 {
927 dist.resize(fr_vf.nb_faces());
928 int ndeb = fr_vf.num_premiere_face();
929 for (int face=ndeb; face<ndeb+fr_vf.nb_faces(); face++)
930 dist(face-ndeb) = dist_norm_bord(face);
931 }
932 }
933 }
934 return dist;
935}
936
938{
939 IntTrav p_e(0, 2);
941 for (int e = 0; e < nb_elem() ; e++) p_e(e, 0) = Process::me(), p_e(e, 1) = e;
943 for (int e = nb_elem() ; e < nb_elem_tot() ; e++) virt_e_map[ {{ p_e(e, 0), p_e(e, 1) }}] = e;
944}
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limites discretisee dont l'objet fait partie.
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
classe Dirichlet_entree_fluide Cette classe represente une condition aux limite imposant une grandeur
int_t nb_elem_tot() const
Definition Domaine.h:132
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
Definition Domaine.cpp:405
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
Definition Domaine.cpp:851
int_t nb_faces_frontiere() const
Renvoie le nombre de faces frontiere du domaine (somme des nombres de bords, de raccords et de bords ...
Definition Domaine.h:488
int_t nb_elem() const
Definition Domaine.h:131
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
class Domaine_Cl_VDF
int type_arete_bord(int num_arete) const
const int & type_arete_coin(int num_arete) const
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VDF
Definition Domaine_VDF.h:64
int nb_aretes_coin() const
void compute_sort_key(Faces &, IntTab &sort_key) override
Override. Compute sorting key so that internal faces are sorted by their orientation first (X,...
double dist_norm_bord_axi(int num_face) const
IntVect & orientation()
inline double Domaine_VDF::porosite_face(int i) const {
Faces * creer_faces() override
renvoie un Faces_VDF* !
void prepare_elem_non_std(Faces &) override
double dim_elem(int, int) const
std::map< std::array< int, 2 >, int > virt_e_map
void creer_elements_fictifs(const Domaine_Cl_dis_base &) override
remplit le tableau face_voisins_fictifs_ ne CREE PAS d elts fictifs!!!
int premiere_arete_bord() const
void discretiser() override
appel a Domaine_VF::discretiser() calcul des centres de gravite des elements
int premiere_arete_coin() const
int nb_aretes_bord() const
void modifier_pour_Cl(const Conds_lim &cl) override
void init_virt_e_map() const
void renumber_faces(Faces &les_faces, IntTab &sort_key) override
Override to also renumber orientation_ member.
void calculer_volumes_entrelaces()
remplissage des volumes entrelaces
double dist_norm_bord(int num_face) const override
class Domaine_VF
Definition Domaine_VF.h:44
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect volumes_entrelaces_
Definition Domaine_VF.h:210
double volume_entrelace_axi(double r_face, double r_elem, double axis_length) const
Definition Domaine_VF.h:703
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
DoubleTab xv_
Definition Domaine_VF.h:219
int nb_faces_std_
Definition Domaine_VF.h:251
void discretiser() override
Genere les faces construits les frontieres.
void modifier_pour_Cl(const Conds_lim &) override
DoubleTab & xv()
Definition Domaine_VF.h:93
IntTab & elem_faces()
renvoie le tableau de connectivite element/faces
Definition Domaine_VF.h:551
IntTab face_voisins_
Definition Domaine_VF.h:216
DoubleVect & volumes()
Definition Domaine_VF.h:119
virtual void renumber_faces(Faces &les_faces, IntTab &sort_key)
Re-index faces according to the new order given by 'sort_key'.
DoubleTab face_normales_
Definition Domaine_VF.h:212
IntTab face_voisins_fictifs_
Definition Domaine_VF.h:217
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
DoubleTab volumes_entrelaces_dir_
Definition Domaine_VF.h:211
DoubleTab & xp()
Definition Domaine_VF.h:95
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
Definition Domaine_VF.h:513
const Front_VF & front_VF(int i) const
Definition Domaine_VF.h:112
IntTab & face_voisins() override
renvoie le tableaux des volumes des connectivites face elements cf au dessus.
Definition Domaine_VF.h:426
void marquer_faces_double_contrib(const Conds_lim &)
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
int_t nb_faces() const
Definition Faces.h:66
void calculer_orientation(IntVect &, int &, int &, int &)
Definition Faces_VDF.cpp:38
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
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
static double precision_geom
Definition Objet_U.h:86
static int bidim_axi
Definition Objet_U.h:102
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
static double mp_min(double)
Definition Process.cpp:386
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")