TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Domaine_VEF.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 <Connectivite_som_elem.h>
17#include <Check_espace_virtuel.h>
18#include <MD_Vector_composite.h>
19#include <VEF_discretisation.h>
20#include <EcrFicPartageBin.h>
21#include <Static_Int_Lists.h>
22#include <MD_Vector_tools.h>
23#include <Domaine_Cl_VEF.h>
24#include <Quadrangle_VEF.h>
25#include <Octree_Double.h>
26#include <Hexaedre_VEF.h>
27#include <Domaine_VEF.h>
28#include <EFichierBin.h>
29#include <Quadri_VEF.h>
30#include <Periodique.h>
31#include <TRUSTLists.h>
32#include <Periodique.h>
33#include <Rectangle.h>
34#include <Tetra_VEF.h>
35#include <Conds_lim.h>
36#include <Tetraedre.h>
37#include <ArrOfBit.h>
38#include <Hexaedre.h>
39#include <Hexa_VEF.h>
40#include <Triangle.h>
41#include <Tri_VEF.h>
42#include <Domaine.h>
43#include <Debog.h>
44
45Implemente_instanciable(Domaine_VEF, "Domaine_VEF", Domaine_VF);
46
47Sortie& Domaine_VEF::ecrit(Sortie& os) const
48{
50 os << "____ h_carre " << finl;
51 os << h_carre << finl;
52 os << "____ type_elem_ " << finl;
53 os << type_elem_.valeur() << finl;
54 os << "____ nb_elem_std_ " << finl;
55 os << nb_elem_std_ << finl;
56 os << "____ volumes_entrelaces_ " << finl;
57 volumes_entrelaces_.ecrit(os);
58 os << "____ face_normales_ " << finl;
59 face_normales_.ecrit(os);
60 os << "____ facette_normales_ " << finl;
61 facette_normales_.ecrit(os);
62 os << "____ nb_faces_std_ " << finl;
63 os << nb_faces_std_ << finl;
64 os << "____ rang_elem_non_std_ " << finl;
65 rang_elem_non_std_.ecrit(os);
66 return os;
67}
68
70{
72
73 os << h_carre << finl;
74 os << type_elem_.valeur() << finl;
75 os << nb_elem_std_ << finl;
76 os << volumes_entrelaces_ << finl;
77 os << face_normales_ << finl;
78 os << facette_normales_ << finl;
79 os << xp_ << finl;
80 os << xv_ << finl;
81 os << nb_faces_std_ << finl;
82 os << rang_elem_non_std_ << finl;
83 return os;
84}
85
87{
89 is >> h_carre;
90
91 /* read type_elem */
92 {
93 Nom type;
94 is >> type;
95 if (type == "Tri_VEF")
96 type_elem_ = Tri_VEF();
97 else if (type == "Tetra_VEF")
98 type_elem_ = Tetra_VEF();
99 else if (type == "Quadri_VEF")
100 type_elem_ = Quadri_VEF();
101 else if (type == "Hexa_VEF")
102 type_elem_ = Hexa_VEF();
103 else
104 {
105 Cerr << type << " n'est pas un Elem_VEF !" << finl;
107 }
108 }
109
110 is >> nb_elem_std_;
112 is >> face_normales_;
113 is >> facette_normales_;
114 is >> xp_;
115 is >> xv_;
116 is >> nb_faces_std_;
117 is >> rang_elem_non_std_;
118 return is;
119}
120
121void exemple_champ_non_homogene(const Domaine_VEF& domaine_VEF, DoubleTab& tab)
122{
123 const DoubleTab& xp = domaine_VEF.xp();
124 const Domaine& domaine=domaine_VEF.domaine();
125 const DoubleTab& coord=domaine.coord_sommets();
126 const DoubleTab& xa=domaine_VEF.xa();
127 const ArrOfInt& renum_arete_perio=domaine_VEF.get_renum_arete_perio();
128 // Verification du tableau xa des coordonnees arete
129 if (xa.size_array()) Debog::verifier("xa=",xa);
130 int nb_elem=domaine.nb_elem();
131 int nb_elem_tot=domaine.nb_elem_tot();
132 int nb_som=domaine.nb_som();
133 int nb_som_tot=domaine.nb_som_tot();
134 int nb_aretes=domaine.nb_aretes();
135 for (int I=0 ; I<nb_elem; I++)
136 {
137 tab(I)=(1.1+xp(I,0))*(1.1+2*xp(I,1));
138 if (Objet_U::dimension==3) tab(I)*=(1.1+3*xp(I,2));
139 }
140 for (int I=0; I<nb_som; I++)
141 {
142 tab(nb_elem_tot+I)=(1.1+coord(I,0))*(1.1+2*coord(I,1));
143 if (Objet_U::dimension==3) tab(nb_elem_tot+I)*=(1.1+3*coord(I,2));
144 // On applique la periodicite:
145 tab(nb_elem_tot+I)=tab(nb_elem_tot+domaine.get_renum_som_perio(I));
146 }
147
148#ifndef NDEBUG
149 const IntVect& ok_arete = domaine_VEF.get_ok_arete();
150#endif
151 for (int I=0; I<nb_aretes; I++)
152 {
153 tab(nb_elem_tot+nb_som_tot+I)=(1.1+xa(I,0))*(1.1+2*xa(I,1))*(1.1+3*xa(I,2));
154 // On applique la periodicite:
155 tab(nb_elem_tot+nb_som_tot+I)=tab[nb_elem_tot+nb_som_tot+renum_arete_perio[I]];
156 // On verifie ok_arete au passage
157 assert(ok_arete(I)==ok_arete(renum_arete_perio[I]));
158 }
160}
161
162void Domaine_VEF::swap(int fac1, int fac2, int nb_som_faces)
163{
164
165}
166
168{
169 Domaine& domaine_geom = domaine();
170 typer_elem(domaine_geom);
171 Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
173
174 // Correction du tableau face_voisins:
175 // A l'issue de Domaine_VF::discretiser(), les elements voisins 0 et 1 d'une
176 // face sont les memes sur tous les processeurs qui possedent la face.
177 // Si la face est virtuelle et qu'un des deux elements voisins n'est
178 // pas connu (il n'est pas dans l'epaisseur du joint), l'element voisin
179 // vaut -1. Cela peut etre un voisin 0 ou un voisin 1.
180 // On corrige les faces virtuelles pour que, si un element voisin n'est
181 // pas connu, alors il est voisin1. Le voisin0 est donc toujours valide.
182 {
183 IntTab& face_vois = face_voisins();
184 const int debut = nb_faces();
185 const int fin = nb_faces_tot();
186 for (int i = debut; i < fin; i++)
187 {
188 if (face_voisins(i, 0) == -1)
189 {
190 face_vois(i, 0) = face_vois(i, 1);
191 face_vois(i, 1) = -1;
192 }
193 }
194 }
195
196 // Verification de la coherence entre l'element geometrique et
197 //l'elemnt de discretisation
198
199 if (sub_type(Tri_VEF, type_elem_.valeur()))
200 {
201 if (!sub_type(Triangle, elem_geom))
202 {
203 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
204 Cerr << " Seul le type Triangle est compatible avec la discretisation VEF en dimension 2" << finl;
205 Cerr << " Il faut trianguler le domaine lorsqu'on utilise le mailleur interne";
206 Cerr << " en utilisant l'instruction: Trianguler nom_dom" << finl;
207 exit();
208 }
209 }
210 else if (sub_type(Tetra_VEF, type_elem_.valeur()))
211 {
212 if (!sub_type(Tetraedre, elem_geom))
213 {
214 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
215 Cerr << " Seul le type Tetraedre est compatible avec la discretisation VEF en dimension 3" << finl;
216 Cerr << " Il faut tetraedriser le domaine lorsqu'on utilise le mailleur interne";
217 Cerr << " en utilisant l'instruction: Tetraedriser nom_dom" << finl;
218 exit();
219 }
220 }
221
222 else if (sub_type(Quadri_VEF, type_elem_.valeur()))
223 {
224
225 if (!sub_type(Quadrangle_VEF, elem_geom))
226 {
227 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
228 exit();
229 }
230 }
231 else if (sub_type(Hexa_VEF, type_elem_.valeur()))
232 {
233
234 if (!sub_type(Hexaedre_VEF, elem_geom))
235 {
236 Cerr << " Le type de l'element geometrique " << elem_geom.que_suis_je() << " est incorrect" << finl;
237 exit();
238 }
239 }
240
241 // On remplit le tableau face_normales_;
242 // Attention : le tableau face_voisins n'est pas exactement un
243 // tableau distribue. Une face n'a pas ses deux voisins dans le
244 // meme ordre sur tous les processeurs qui possedent la face.
245 // Donc la normale a la face peut changer de direction d'un
246 // processeur a l'autre, y compris pour les faces de joint.
247 {
248 const int n = nb_faces();
249 face_normales_.resize(n, dimension);
250 creer_tableau_faces(face_normales_, RESIZE_OPTIONS::NOCOPY_NOINIT);
251 const IntTab& face_som = face_sommets();
252 const IntTab& face_vois = face_voisins();
253 const IntTab& elem_face = elem_faces();
254 type_elem_->creer_face_normales(face_normales_, face_som, face_vois, elem_face, domaine_geom);
255 }
256
257 // Calcul de facette_normales_
258 type_elem_->creer_facette_normales(*this, rang_elem_non_std());
259
261 Cerr << "Informations of the Domaine VEF of the domain " << domaine().le_nom() << " : " << finl;
262
264
265 domaine().creer_tableau_sommets(volumes_som_, RESIZE_OPTIONS::NOCOPY_NOINIT);
266
267 double coeff=1./3.;
268 if (dimension==3)
269 coeff=1./4.;
270
271 const IntTab& elements = domaine().les_elems();
272 const int nb_som_elem = elements.dimension(1);
273 // Boucle sur tous les elements car on ajoute des contributions aux sommets de joints:
274 const int n = nb_elem_tot();
275 // On a besoin de l'espace virtuel des volumes
276 const DoubleVect& volume_elem = volumes();
277 assert_espace_virtuel_vect(volume_elem);
278
279 // Annule tout le tableau car on va faire += sur des items virtuels
280 // (sinon acces a des cases non initialisees)
281 operator_egal(volumes_som_, 0., VECT_ALL_ITEMS);
282 for(int k=0; k<n; k++)
283 {
284 double volume = coeff * volume_elem(k);
285 for(int isom=0; isom<nb_som_elem; isom++)
286 {
287 int som = elements(k, isom);
288 volumes_som_(som)+=volume;
289 }
290 }
291 volumes_som_.echange_espace_virtuel();
292}
293
295{
296 // Recuperation des parametres de la discretisation
297 alphaE = discr.get_alphaE();
298 alphaS = discr.get_alphaS();
299 alphaA = discr.get_alphaA();
300 alphaRT = discr.get_alphaRT();
301 P1Bulle = discr.get_P1Bulle();
302 modif_div_face_dirichlet= discr.get_modif_div_face_dirichlet();
303 cl_pression_sommet_faible = discr.get_cl_pression_sommet_faible();
304
305
306 if (alphaA)
308
309 // Construction du descripteur pour les tableaux p1bulle
310 {
311 MD_Vector_composite md_p1b;
312 if (alphaE)
313 {
314 const MD_Vector& md = domaine().md_vector_elements();
315 md_p1b.add_part(md, 0, "P0");
316 }
317 if (alphaS)
318 {
319 const MD_Vector& md = domaine().md_vector_sommets();
320 md_p1b.add_part(md, 0, "P1");
321 }
322 if (alphaA)
323 {
324 const MD_Vector& md = md_vector_aretes();
325 md_p1b.add_part(md, 0, "Pa");
326 }
327 md_vector_p1b_.copy(md_p1b);
328 }
329 Cerr << "le Domaine_VEF a ete rempli avec succes" << finl;
330}
331
332/*
333 static int arete(const IntTab& som_aretes,
334 const IntTab& aretes_som,
335 int S1, int S2, const Domaine& dom)
336 {
337 //Cout << "S1,S2 = " << S1 << " " << S2 << finl;
338 for(int i=0; i<nb_max_aretes_som; i++)
339 {
340 const int& a=som_aretes(S1,i);
341 if( (dom.get_renum_som_perio(aretes_som(a,0))==S2)
342 ||
343 (dom.get_renum_som_perio(aretes_som(a,1))==S2) )
344 return a;
345 }
346 {
347 Cerr << "arete pas Trouvee!!" << finl;
348 Cout << "S1,S2 = " << S1 << " " << S2 << finl;
349 Cout << "som_aretes " << som_aretes << finl;
350 Cout << "aretes_som " << aretes_som << finl;
351 Process::exit();
352 }
353 return -1;
354 } */
355
356static int next(int S,
357 const ArrOfInt& contenu)
358{
359 int nb_som=contenu.size_array();
360 int i=S+1;
361 while(i<nb_som)
362 if(contenu[i]==1)
363 return i;
364 else i++;
365 i=0;
366 while(i<S)
367 if(contenu[i]==1)
368 return i;
369 else i++;
370 return -1;
371}
372
374{
375 const Domaine& dom = domaine();
376
377 // Creation des aretes reelles (informations geometriques construites et stockees dans le domaine)
380
381 // Calcul des centres de gravite des aretes xa_ stockes dans le Domaine_VF
382 const IntTab& aretes_som = domaine().aretes_som();
383 const int nb_aretes = aretes_som.dimension(0);
384 const DoubleTab& coord = dom.les_sommets();
385 const int dim = coord.dimension(1);
386 xa_.resize(0, dim);
387 creer_tableau_aretes(xa_, RESIZE_OPTIONS::NOCOPY_NOINIT);
388 for (int i = 0; i < nb_aretes; i++)
389 {
390 const int s0 = aretes_som(i, 0);
391 const int s1 = aretes_som(i, 1);
392 for (int j = 0; j < dim; j++)
393 xa_(i, j) = (coord(s0, j) + coord(s1, j)) * 0.5;
394 }
395 xa_.echange_espace_virtuel();
396
397 const IntTab& elem_aretes = domaine().elem_aretes();
398
399 // Calcul du volume des aretes
400 // Creation d'un tableau initialise a zero:
401 creer_tableau_aretes(volumes_aretes);
402
403 const int nbr_elem = domaine().nb_elem();
404 const int nb_aretes_elem = elem_aretes.dimension(1);
405 // facteur 6 pour le calcul des volumes des aretes, est-ce correct pour autre chose qu'un tetra ?
406 assert(nb_aretes_elem == 6);
407 // Essai d'une autre facon de coder: calcul des contributions aux aretes par les elements reels,
408 // puis sommation des contributions des aretes partagees:
409 for (int elem = 0; elem < nbr_elem; elem++)
410 {
411 double vol = volumes(elem) / 6.0;
412 for(int j = 0; j < nb_aretes_elem; j++)
413 {
414 int arete = elem_aretes(elem, j);
415 volumes_aretes[arete] += vol;
416 }
417 }
418 // Sommation des contributions des aretes joint et echange des espaces virtuels
420}
421
423{
424 Cerr << "Build array ok_arete..." << finl;
425 const Domaine& dom=domaine();
426 const IntTab& aretes_som=domaine().aretes_som();
427 const int nb_som_reel=nb_som();
428
429 // Connectivite sommets-aretes (pour chaque sommet, liste des aretes adjacentes)
430 // B.M.: je remplace IntTab(n, 64) par une Static_Int_List et je reutilise
431 // la methode de calcul des connectivites... plus econome en memoire !
432 // som_aretes contient une connectivite modifiee pour les sommets periodiques
433 // (les aretes sont toujours rattachees au sommet get_renum_som_perio(),
434 // les aretes periodiques opposees sont remplacees par une arete [nb_som_reel,nb_som_reel]
435 // fictive, et les sommets perio opposes ne sont rattaches a aucune arete)
436 const int nb_aretes = aretes_som.dimension(0);
437 Static_Int_Lists som_aretes;
438 {
439 // Creation d'un tableau d'aretes ou les sommets sont remplaces par le sommet
440 // periodique associe et sans les aretes periodiques opposees
441 IntTab aretes_som2;
442 aretes_som2.copy(aretes_som, RESIZE_OPTIONS::NOCOPY_NOINIT);
443
444 for (int i = 0; i < nb_aretes; i++)
445 {
446 if (renum_arete_perio[i] == i)
447 {
448 aretes_som2(i, 0) = dom.get_renum_som_perio(aretes_som(i,0));
449 aretes_som2(i, 1) = dom.get_renum_som_perio(aretes_som(i,1));
450 }
451 else
452 {
453 // arete periodique opposee, non conservee, on cree une arete fictive pour
454 // construire_connectivite_som_elem: le sommet d'indice nb_som_reel
455 // sera connecte a toutes les aretes periodiques supprimees
456 aretes_som2(i, 0) = nb_som_reel;
457 aretes_som2(i, 1) = nb_som_reel;
458 }
459 }
460 // On donne un sommet de plus (le sommet fictif connecte aux aretes supprimees)
461 construire_connectivite_som_elem(nb_som_reel+1, aretes_som2, som_aretes, 0 /* do not include virtual items */);
462 }
463
464 // Creation et initialisation du tableau contenu, initialise a zero par defaut
465 ArrOfInt contenu(nb_som_reel);
466
467 // Initialisation pour le parallele: contenu est mis a 2
468 // pour les sommets communs recus d'un autre processeur
469 {
470 ArrOfBit flags;
472 for (int i = 0; i < nb_som_reel; i++)
473 {
474 if (!flags[i])
475 {
476 // Ce sommet est recu d'un autre processeur
477 const int i2 = dom.get_renum_som_perio(i);
478 contenu[i] = 2;
479 if (i2 != i)
480 contenu[i2] = 2;
481 }
482 }
483 }
484
485 // Estimation du nombre d'aretes superflues a trouver sur le domaine
486 // en comptant les sommets reels non periodiques dont le contenu vaut 0
487 int nombre_aretes_superflues_prevues_sur_le_dom=0;
488 for (int i=0; i<nb_som_reel; i++)
489 if (i==dom.get_renum_som_perio(i) && contenu[i]==0)
490 nombre_aretes_superflues_prevues_sur_le_dom++;
491
492 ok_arete = -1;
493
494 // On boucle tant qu'il y'a des sommets avec le contenu 0
495 while (min_array(contenu)==0)
496 {
497 // On cherche le premier sommet avec contenu 0 en bouclant sur les aretes
498 int Aroot=-1,Sroot=-1;
499 int S0,S1;
500 do
501 {
502 while (ok_arete(++Aroot)==0) {};
503 S0=dom.get_renum_som_perio(aretes_som(Aroot,0));
504 S1=dom.get_renum_som_perio(aretes_som(Aroot,1));
505 }
506 while (Aroot<nb_aretes && contenu[S0]!=0 && contenu[S1]!=0);
507
508 assert(Aroot<nb_aretes);
509
510 Aroot=renum_arete_perio[Aroot];
511
512 ok_arete(Aroot)=0; // lockee
513 if (!contenu[S0])
514 {
515 contenu[S0]=1;
516 Sroot=S0;
517 }
518 else if (!contenu[S1])
519 {
520 contenu[S1]=1;
521 Sroot=S1;
522 }
523
524 // Boucle sur les sommets
525 do
526 {
527 const int nb_aretes_voisines = som_aretes.get_list_size(Sroot);
528 for(int i=0; i<nb_aretes_voisines; i++)
529 {
530 int A=renum_arete_perio[som_aretes(Sroot,i)];
531 if(ok_arete(A)==-1)
532 {
533 int S=dom.get_renum_som_perio(aretes_som(A,0));
534 if(S==Sroot)
535 {
536 S=dom.get_renum_som_perio(aretes_som(A,1));
537 }
538 if(!contenu[S])
539 {
540 ok_arete(A)=0; // lockee
541 contenu[S]=1;
542 }
543 else
544 {
545 ok_arete(A)=1; // libre
546 }
547 }
548 }
549 contenu[Sroot]=2;
550 }
551 while((Sroot=next(Sroot, contenu))!=-1);
552
553 // Correction pour des tableaux ok_arete et contenu pour la periodicite
554 for(int i=0; i<nb_aretes; i++)
555 ok_arete(i)=ok_arete[renum_arete_perio[i]];
556 for(int i=0; i<nb_som_reel; i++)
557 contenu[i]=contenu[dom.get_renum_som_perio(i)];
558 }
559
560 // Mise a jour des parties virtuelles du tableau ok_arete
561 ok_arete.echange_espace_virtuel();
562
563 // Verification des aretes superflues
564 verifie_ok_arete(nombre_aretes_superflues_prevues_sur_le_dom);
565
566 // Ecriture des aretes superflues dans un fichier nom_du_cas.ok_arete afin de le relire la fois suivante
567 Nom fichier(nom_du_cas());
568 fichier+="_";
569 fichier+=domaine().le_nom()+".ok_arete";
570
571 Cerr << "Writing file " << fichier << finl;
572 EcrFicPartageBin fic_ok_arete_;
573 if (!fic_ok_arete_.ouvrir(fichier,ios::out))
574 {
575 Cerr << "Error: cannot open file " << fichier << " for writing." << finl;
576 exit();
577 }
578
579 ArrOfBit marqueurs_aretes;
580 const MD_Vector& md_aretes = md_vector_aretes();
581 md_aretes->get_sequential_items_flags(marqueurs_aretes);
582 const trustIdType nb_aretes_seq = md_aretes->nb_items_seq_tot();
583
585 fic_ok_arete_ << nb_aretes_seq << finl;
586
587 // Chaque processeur ecrit ses aretes non communes:
588 const int n = marqueurs_aretes.size_array();
589 for (int i = 0; i < n; i++)
590 {
591 if (marqueurs_aretes[i])
592 fic_ok_arete_ << xa_(i,0) << tspace << xa_(i,1) << tspace << xa_(i,2) << tspace << ok_arete(i) << finl;
593 }
594 fic_ok_arete_.syncfile();
595 fic_ok_arete_.close();
596}
597
599{
600 Cerr << "Build array renum_arete_perio..." << finl;
601 const IntTab& aretes_som=domaine().aretes_som();
602 const int nb_aretes_tot = static_cast<int>(domaine().nb_aretes_tot()); // domain is already discretised, so already split, so we're just working with a small part
603 const Domaine& dom=domaine();
604
605 // Initialisation de renum_arete_perio
606 renum_arete_perio.resize_array(nb_aretes_tot);
607 for (int i=0; i<nb_aretes_tot; i++)
608 renum_arete_perio[i]=i;
609
610 const IntTab& elem_aretes=domaine().elem_aretes();
611 ArrOfInt aretes1(6);
612 ArrOfInt aretes2(6);
613 // Premiere etape: faire pointer tous les aretes periodiques liees entre elles vers la meme arete
614 for (auto& itr : conds_lim)
615 {
616 //for cl
617
618 const Cond_lim_base& cl = itr.valeur();
619 if (sub_type(Periodique, cl))
620 {
621 //if Perio
622 const Periodique& la_cl_perio = ref_cast(Periodique,cl);
623 const Front_VF& le_bord = ref_cast(Front_VF,cl.frontiere_dis());
624
625 int nf_bord_tot = le_bord.nb_faces_tot();
626 IntVect fait(nf_bord_tot);
627 fait = 0;
628 for(int ind_face=0; ind_face<nf_bord_tot; ind_face++)
629 if(!fait(ind_face))
630 {
631 int face=le_bord.num_face(ind_face);
632 int ind_faassociee=la_cl_perio.face_associee(ind_face);
633 int face_assciee=le_bord.num_face(ind_faassociee);
634 fait(ind_faassociee)=fait(ind_face)=1;
635
636 int elem1 = face_voisins_(face,0);
637 int elem2 = face_voisins_(face,1);
638
639 for(int j=0; j<6; j++)
640 {
641 aretes1[j]=elem_aretes(elem1,j);
642 aretes2[j]=elem_aretes(elem2,j);
643 }
644
645 for(int j1=0; j1<6; j1++)
646 {
647 int ar1=aretes1[j1];
648 int& ar1_perio = renum_arete_perio[ar1];
649 // On verifie que l'arete appartient a la face (ok==2)
650 int som11=aretes_som(ar1, 0);
651 int som12=aretes_som(ar1, 1);
652 int ok=0;
653 int nbf = domaine().type_elem()->nb_som_face();
654 const IntTab& sommet = face_sommets();
655 for (int k=0; k<nbf; k++)
656 if (sommet(face,k)==som11 || sommet(face,k)==som12) ok++;
657 assert(ok>0);
658 if (ok==2)
659 {
660 int s11=dom.get_renum_som_perio(som11);
661 int s12=dom.get_renum_som_perio(som12);
662 for(int j2=0; j2<6; j2++)
663 {
664 int ar2=aretes2[j2];
665 int& ar2_perio = renum_arete_perio[ar2];
666 int som21=aretes_som(ar2, 0);
667 int som22=aretes_som(ar2, 1);
668 ok=0;
669 // On verifie que l'arete appartient a la face_assciee (ok==2)
670 for (int k=0; k<nbf; k++)
671 if (sommet(face_assciee,k)==som21 || sommet(face_assciee,k)==som22) ok++;
672 assert(ok>0);
673 if (ok==2)
674 {
675 int s21=dom.get_renum_som_perio(som21);
676 int s22=dom.get_renum_som_perio(som22);
677 assert(ar1!=ar2);
678 //Les aretes sont donc periodiques si on rentre dans le "if"
679 if ( ( (s21==s11)||(s22==s11) ) && ( (s22==s12)||(s21==s12) ) )
680 {
681 // Critere I : choix de l'arete perio en fonction d'un critere geometrique
682 int dir_perio = la_cl_perio.direction_periodicite();
683 int arete_perio = (xa(ar1_perio,dir_perio)<=xa(ar2_perio,dir_perio)) ? ar1_perio : ar2_perio;
684 /*
685 // Critere II : choix de l'arete perio en fonction des sommets periodiques
686 int arete_perio;
687 if (som11!=s11 && som12!=s12) // Les sommets de l'arete 1 sont periodiques
688 arete_perio = ar2_perio;
689 else if (som21!=s21 && som22!=s22) // Les sommets de l'arete 2 sont periodiques
690 arete_perio = ar1_perio;
691 else
692 {
693 Cerr << "Cas non prevu." << finl;
694 exit();
695 } */
696 ar2_perio = arete_perio;
697 ar1_perio = arete_perio;
698 volumes_aretes(ar2)+=volumes_aretes(ar1);
699 volumes_aretes(ar1)+=volumes_aretes(ar2);
700 }//fin du if sur "s21==s11"
701 }
702 }//fin du for sur "j2"
703 }
704 }//fin du if sur "renum_arete_perio(aretes1)" et du for sur "j1"
705 }//fin du if sur "fait"
706 }//fin if Perio
707 }// fin for cl
708
709 // Deuxieme etape: faire pointer tous les aretes periodiques liees entre elles vers la meme arete
710 for (int i = 0; i < nb_aretes_tot; i++)
711 {
712 int j = renum_arete_perio[i];
713 // Parcourir les aretes reliees pour cette chaine:
714 while (j != renum_arete_perio[j])
715 j = renum_arete_perio[j];
716 renum_arete_perio[i] = j;
717 }
718
719 if (Debog::active())
720 {
721 IntVect tmp;
722 creer_tableau_aretes(tmp, RESIZE_OPTIONS::NOCOPY_NOINIT);
723 const int n = tmp.size_array();
724 for (int i=0; i<n; i++)
725 tmp[i] = renum_arete_perio[i];
726 Debog::verifier_indices_items("renum_arete_perio",tmp.get_md_vector(),tmp);
727 }
728}
729
730void Domaine_VEF::verifie_ok_arete(int nombre_aretes_superflues_prevues_sur_le_dom) const
731{
732 Cerr << "Check array ok_arete..." << finl;
733 // Algorithme de verification du tableau des aretes superflues
734 // ok_arete(i)==0 : i arete superflue
735 // ok_arete(i)==2 : i arete necessaire
736 // ...
737 // contenu doit contenir uniquement 2 ce qui implique que tous les
738 // sommets ont ete analyses.
739 const Domaine& dom=domaine();
740 const int nb_som_reel=nb_som();
741 const IntTab& aretes_som=domaine().aretes_som();
742 int nb_aretes_pour_verbose=60; // Pour verbose
743 ArrOfInt sommet_relie_arete_superflue(nb_som_reel);
744 sommet_relie_arete_superflue=0;
745 for (int i=0; i<nb_som_reel; i++) // Si i est un sommet periodique:
746 if (dom.get_renum_som_perio(i)!=i) // il suffit de faire la verification sur le sommet dom.get_renum_som_perio(i)
747 sommet_relie_arete_superflue[i]=1; // donc on ne verifie pas i
748
749 double nombre_aretes_reelles_superflues=0;
750 // On parcourt toutes les aretes mais on ne regarde que les sommets reels
751 int nb_aretes_tot=domaine().nb_aretes_tot();
752 int nb_aretes_reelles=domaine().nb_aretes();
753 for (int i=0; i<nb_aretes_tot; i++)
754 {
755 if (!ok_arete(i)) // arete superflue
756 {
757 int S0=aretes_som(i,0);
758 if (S0<nb_som_reel)
759 {
760 sommet_relie_arete_superflue[S0]=1;
761 sommet_relie_arete_superflue[dom.get_renum_som_perio(S0)]=1;
762 }
763 int S1=aretes_som(i,1);
764 if (S1<nb_som_reel)
765 {
766 sommet_relie_arete_superflue[S1]=1;
767 sommet_relie_arete_superflue[dom.get_renum_som_perio(S1)]=1;
768 }
769 if (renum_arete_perio[i]==i) // Pour ne compter les aretes periodiques qu'une fois
770 {
771 if (nb_aretes_tot<nb_aretes_pour_verbose)
772 {
773 if (renum_arete_perio[i]==i) Cerr << "[" << Process::me() << "] Arete " << i << " superflue non perio: " << S0 << " " << S1 << finl;
774 else Cerr << "[" << Process::me() << "] Arete " << i << " superflue perio: " << S0 << " " << S1 << " Periodique avec " << renum_arete_perio[i] << finl;
775 }
776 int aretes_superflues_communes=1;
777 // Si l'arete superflue est commune on en tient compte
778 for (int j=0; j<dom.faces_joint().size(); j++)
779 {
780 int nb_aretes_sur_le_joint = dom.faces_joint()(j).joint_item(JOINT_ITEM::ARETE).items_communs().size_array();
781 for (int k=0; k<nb_aretes_sur_le_joint; k++)
782 if (dom.faces_joint()(j).joint_item(JOINT_ITEM::ARETE).items_communs()[k]==i) aretes_superflues_communes++;
783 }
784 // On compte les aretes reelles superflues
785 if (i<nb_aretes_reelles)
786 nombre_aretes_reelles_superflues+=1./aretes_superflues_communes;
787 }
788 }
789 }
790
791 if (nb_som_reel > 0 && min_array(sommet_relie_arete_superflue)==0)
792 {
793 Cerr << finl << "[" << Process::me() << "] Il y'a au moins un sommet qui n'est pas relie a une arete superflue :" << finl;
794 for (int i=0; i<sommet_relie_arete_superflue.size_array(); i++)
795 if (sommet_relie_arete_superflue[i]==0) Cerr << "Sommet " << i << finl;
797 }
798 Cerr << "[" << Process::me() << "] Verification que chaque sommet non periodique est bien relie a au moins une arete superflue: OK!" << finl;
799 // On compte le nombre total de sommets en tenant compte de la periodicite et des sommets communs
800 double nb_sommets_non_periodiques=0;
801 for (int i=0; i<nb_som_reel; i++)
802 if (dom.get_renum_som_perio(i)==i) // Sommet non periodique
803 {
804 int sommets_communs=1;
805 // On tient compte des sommets communs
806 for (int j=0; j<dom.faces_joint().size(); j++)
807 for (int k=0; k<dom.faces_joint()(j).joint_item(JOINT_ITEM::SOMMET).items_communs().size_array(); k++)
808 if (dom.faces_joint()(j).joint_item(JOINT_ITEM::SOMMET).items_communs()[k]==i) sommets_communs++;
809 nb_sommets_non_periodiques+=1./sommets_communs;
810 }
811 double total_nombre_aretes_superflues = mp_sum(nombre_aretes_reelles_superflues);
812 double somme_nombre_aretes_superflues_prevues_par_domaine = mp_sum_as_double(nombre_aretes_superflues_prevues_sur_le_dom);
813 double total_nb_sommets_non_periodiques = mp_sum(nb_sommets_non_periodiques);
814
815
816 // Cerr << "Nombre de sommets non periodiques = " << total_nb_sommets_non_periodiques << finl;
817 // Cerr << "Nombre de sommets periodiques = " << nb_som_reel-total_nb_sommets_non_periodiques << finl;
818 //int nb_aretes_periodiques=0;
819 //int nb_aretes_perio_superflues=0;
820 for (int i=0; i<nb_aretes_tot; i++)
821 {
822 if (renum_arete_perio[i]!=i)
823 {
824 //nb_aretes_periodiques++;
825 assert(ok_arete(i)==ok_arete(renum_arete_perio[i]));
826 //if (!ok_arete(i)) nb_aretes_perio_superflues++;
827 }
828 }
829 // Cerr << "Nombre d'aretes non periodiques = " << nb_aretes_tot-nb_aretes_periodiques << finl;
830 // Cerr << "Nombre d'aretes periodiques = " << nb_aretes_periodiques << finl;
831
832 // Cerr << "Nombre d'aretes superflues = " << total_nombre_aretes_superflues << finl;
833 // Cerr << "Nombre d'aretes superflues periodiques = " << nb_aretes_perio_superflues << finl;
834 // Cerr << "Nombre d'aretes non superflues periodiques = " << nb_aretes_periodiques-nb_aretes_perio_superflues << finl;
835
836 if (Process::is_sequential()) // On se limite au sequentiel car il y'a un soucis pour le calcul de total_nombre_aretes_superflues (les items communs pour les aretes n'est pas construit!)
837 if (!est_egal(somme_nombre_aretes_superflues_prevues_par_domaine,total_nombre_aretes_superflues) && je_suis_maitre())
838 {
839 Cerr << "La somme des aretes superflues prevues par domaine n'est pas egale au nombre d'aretes superflues trouvees sur le domaine." << finl;
840 Cerr << somme_nombre_aretes_superflues_prevues_par_domaine << " != " << total_nombre_aretes_superflues << finl;
842 }
843 Cerr << "Nombre total d'aretes superflues: " << somme_nombre_aretes_superflues_prevues_par_domaine << finl;
844 Cerr << "Nombre total de sommets non periodiques = " << total_nb_sommets_non_periodiques << finl;
845 Cerr << "Verification de l'egalite du nombre total d'aretes superflues et du nombre total de sommets: ";
846 // Verification que le nombre d'aretes superflues et egal au nombre de sommets
847 if (!est_egal(somme_nombre_aretes_superflues_prevues_par_domaine,total_nb_sommets_non_periodiques) && je_suis_maitre())
848 {
849 Cerr << "Non correspondance. Echec de l'algorithme de recherche des aretes superflues." << finl;
851 }
852 Cerr << "OK!" << finl << "Verification correcte des aretes superflues." << finl;
853}
854
855// Valeur de retour:
856// 1: ok
857// 0: fichier inexistant
858// -1: fichier existe mais pas le bon nombre d'aretes
860{
861 Nom fichier(nom_du_cas());
862 fichier+="_";
863 fichier+=domaine().le_nom()+".ok_arete";
864
865 Cerr << "Trying to read file " << fichier << " (edges to remove from the set of degrees of freedom)" << finl;
866 EFichierBin fic_ok_arete_;
867 // Lecture de ok_arete dans un fichier pour comparaison sequentiel-parallele
868 if (!fic_ok_arete_.ouvrir(fichier,ios::out))
869 {
870 Cerr << "File " << fichier << " does not exist." << finl;
871 return 0;
872 }
873
874 int n;
875 fic_ok_arete_ >> n;
876 if (n != md_vector_aretes()->nb_items_seq_tot())
877 {
878 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
879 return 0;
880 }
881
882 Octree_Double octree;
883 octree.build_nodes(xa_, 1 /* include virtual nodes */);
884 const double eps = precision_geom;
885 ArrOfInt liste_aretes;
886
887
888 IntVect marqueurs;
889 creer_tableau_aretes(marqueurs); // initialise a zero par defaut
890
891 for (int i = 0; i < n; i++)
892 {
893 double x, y, z;
894 int flag;
895 fic_ok_arete_ >> x >> y >> z >> flag;
896 octree.search_elements_box(x-eps, y-eps, z-eps, x+eps, y+eps, z+eps, liste_aretes);
897 octree.search_nodes_close_to(x, y, z, xa_, liste_aretes, eps);
898 const int m = liste_aretes.size_array();
899 if (m > 1)
900 {
901 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
902 return 0;
903 }
904 if (m == 1)
905 {
906 const int arete = liste_aretes[0];
907 ok_arete[arete] = flag;
908 marqueurs[arete]++;
909 }
910 else
911 {
912 // Normal en parallele: on n'a pas toutes les aretes sur tous les procs...
913 }
914 }
915
916 // On doit avoir trouve exactement une fois toutes les aretes:
917 if (max_array(marqueurs) > 1 || min_array(marqueurs) < 1)
918 {
919 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
920 return 0;
921 }
922 else
923 Cerr << "File " << fichier << " is OK." << finl;
924 fic_ok_arete_.close();
925 assert_espace_virtuel_vect(ok_arete);
926
927 return 1;
928}
929
930void Domaine_VEF::creer_tableau_p1bulle(Array_base& x, RESIZE_OPTIONS opt) const
931{
932 const MD_Vector& md = md_vector_p1b();
934}
935
937{
938 const int nbe = nb_elem();
939 // Calcul de h_carre
940 h_carre = 1.e30;
941 h_carre_.resize(nbe);
942 // Calcul des surfaces
943 const int nb_faces_elem = domaine().nb_faces_elem();
944 CDoubleArrView face_surfaces_v = face_surfaces().view_ro();
945 CDoubleArrView volumes_v = volumes().view_ro();
946 CIntTabView elem_faces_v = elem_faces().view_ro();
947 DoubleArrView h_carre_v = h_carre_.view_rw();
948 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nbe),
949 KOKKOS_LAMBDA(const int num_elem, double& h_carre_local)
950 {
951 double surf_max = 0;
952 for (int i = 0; i < nb_faces_elem; i++)
953 {
954 double surf = face_surfaces_v(elem_faces_v(num_elem, i));
955 surf_max = (surf > surf_max) ? surf : surf_max;
956 }
957 double vol = volumes_v(num_elem) / surf_max;
958 vol *= vol;
959 h_carre_v(num_elem) = vol;
960 if (vol < h_carre_local) h_carre_local = vol;
961 }, Kokkos::Min<double>(h_carre));
962 end_gpu_timer(__KERNEL_NAME__);
963 h_carre = mp_min(h_carre);
964 Cerr << "Lowest cell size h=(Volume/max(Surface))= " << sqrt(h_carre) << finl;
965 double moyenne = 0.;
966 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nbe),
967 KOKKOS_LAMBDA(const int i, double& sum)
968 {
969 sum += h_carre_v(i);
970 }, moyenne);
971 end_gpu_timer(__KERNEL_NAME__);
972 moyenne = mp_sum(moyenne);
973 double h_carre_moyen = moyenne / mp_sum((double) nbe);
974 Cerr << "Average cell size <h>= " << sqrt(h_carre_moyen) << finl;
975 if (h_carre * 1e6 < h_carre_moyen)
976 Cerr << "Warning, a cell size is more than 1000 times smaller than the average cell size of the domain. Check your mesh." << finl;
977 Cerr << "==============================================" << finl;
978}
979
981{
982 // Cerr << "les normales aux faces " << face_normales() << finl;
983 // On calcule les volumes entrelaces;
984
985 // Si domaine dynamique, le tableau peut eventuellement deja avoir la bonne structure, ou pas.
986 // S'il n'est pas deformable, on n'est pas cense passer ici deux fois.
987 assert(domaine().deformable() || !(volumes_entrelaces_.get_md_vector()));
988 if (!(volumes_entrelaces_.get_md_vector() == md_vector_faces()))
989 {
990 volumes_entrelaces_.reset();
991 creer_tableau_faces(volumes_entrelaces_, RESIZE_OPTIONS::NOCOPY_NOINIT);
992 }
993 int nb_faces_elem = domaine().nb_faces_elem();
994 int num_face;
995 int nmax = premiere_face_int();
996 const double facteur = 1. / nb_faces_elem;
997 for (num_face = 0; num_face < nmax; num_face++)
998 {
999 int elem1 = face_voisins_(num_face, 0);
1000 volumes_entrelaces_[num_face] = volumes(elem1) * facteur;
1001 }
1002 nmax = nb_faces();
1003 for (; num_face < nmax; num_face++)
1004 {
1005 int elem1 = face_voisins_(num_face, 0);
1006 int elem2 = face_voisins_(num_face, 1);
1007 volumes_entrelaces_[num_face] = (volumes(elem1) + volumes(elem2)) * facteur;
1008 }
1009 volumes_entrelaces_.echange_espace_virtuel();
1010}
1011
1013{
1014 Journal() << "Domaine_VEF::Modifier_pour_Cl" << finl;
1015 for (auto &itr : conds_lim)
1016 {
1017 const Cond_lim_base& cl = itr.valeur();
1018 if (sub_type(Periodique, cl))
1019 {
1020 const Periodique& la_cl_period = ref_cast(Periodique, cl);
1021 int nb_faces_elem = domaine().nb_faces_elem();
1022 const Front_VF& la_front_dis = ref_cast(Front_VF, cl.frontiere_dis());
1023 // Modification des tableaux face_voisins_ , face_normales_ , volumes_entrelaces_
1024 // On change l'orientation de certaines normales
1025 // de sorte que les normales aux faces de periodicite soient orientees
1026 // de face_voisins(la_face_en_question,0) vers face_voisins(la_face_en_question,1)
1027 // comme le sont les faces internes d'ailleurs
1028 ToDo_Kokkos("critical");
1029 for (int ind_face = 0; ind_face < la_front_dis.nb_faces_tot(); ind_face++)
1030 {
1031 int face = la_front_dis.num_face(ind_face);
1032 if ((face_voisins_(face, 0) == -1) || (face_voisins_(face, 1) == -1))
1033 {
1034 int faassociee = la_front_dis.num_face(la_cl_period.face_associee(ind_face));
1035 int elem1 = face_voisins_(face, 0);
1036 int elem2 = face_voisins_(faassociee, 0);
1037 double vol = (volumes(elem1) + volumes(elem2)) / nb_faces_elem;
1038 volumes_entrelaces_[face] = vol;
1039 volumes_entrelaces_[faassociee] = vol;
1040 face_voisins_(face, 1) = elem2;
1041 face_voisins_(faassociee, 0) = elem1;
1042 face_voisins_(faassociee, 1) = elem2;
1043 double psc = 0;
1044 for (int k = 0; k < dimension; k++)
1045 psc += face_normales_(face, k) * (xv_(face, k) - xp_(face_voisins_(face, 0), k));
1046
1047 if (psc < 0)
1048 for (int k = 0; k < dimension; k++)
1049 face_normales_(face, k) *= -1;
1050
1051 for (int k = 0; k < dimension; k++)
1052 face_normales_(faassociee, k) = face_normales_(face, k);
1053 }
1054 }
1055 }
1056 }
1057
1058 // PQ : 10/10/05 : les faces periodiques etant a double contribution
1059 // l'appel a marquer_faces_double_contrib s'effectue dans cette methode
1060 // afin de pouvoir beneficier de conds_lim.
1062 // Construction du tableau num_fac_loc_
1064
1065 static DoubleVect* ptr=0;
1066 if(ptr!=&volumes_som_)
1067 {
1068 const Domaine& dom=domaine();
1069 const int ns = nb_som();
1070 CIntArrView renum_som_perio = dom.get_renum_som_perio().view_ro();
1071 DoubleArrView volumes_som = volumes_som_.view_rw();
1072 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, ns), KOKKOS_LAMBDA(const int i)
1073 {
1074 int j = renum_som_perio(i);
1075 if (i != j)
1076 Kokkos::atomic_add(&volumes_som(j), volumes_som(i));
1077 });
1078 end_gpu_timer(__KERNEL_NAME__);
1079 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, ns), KOKKOS_LAMBDA(const int i)
1080 {
1081 int j = renum_som_perio(i);
1082 if (i != j)
1083 volumes_som(i) = volumes_som(j);
1084 });
1085 end_gpu_timer(__KERNEL_NAME__);
1086 volumes_som_.echange_espace_virtuel();
1087 ptr = &volumes_som_;
1088 }
1089
1090 // Verification du tableau renum_som_perio
1091 if (Debog::active())
1092 {
1093 IntVect tmp;
1094 const Domaine& dom = domaine();
1095 dom.creer_tableau_sommets(tmp, RESIZE_OPTIONS::NOCOPY_NOINIT);
1096 const int n = tmp.size_array();
1097 for (int i=0; i<n; i++)
1098 tmp[i] = dom.get_renum_som_perio(i);
1099 Debog::verifier_indices_items("renum_som_perio",tmp.get_md_vector(),tmp);
1100 }
1101
1102 if(get_alphaA())
1103 {
1104 // Construction de renum_arete_perio
1106
1107 // Creation d'un tableau distribue pour ok_arete
1108 creer_tableau_aretes(ok_arete, RESIZE_OPTIONS::NOCOPY_NOINIT);
1109
1110 // Si P1 alors on doit trouver les aretes superflues:
1111 if (get_alphaS())
1112 {
1113 // On essaie de lire un fichier .ok_arete d'un precedant calcul
1114 // S'il n'existe pas ou est incoherent avec le maillage, on reconstruit ok_arete
1115 if (!lecture_ok_arete())
1117 }
1118 else
1119 {
1120 // Toutes les aretes sont necessaires si pas support P1
1121 ok_arete=1;
1122 }
1123 Debog::verifier_getref("ok_arete", ok_arete, ok_arete);
1124
1125 //Debog::verifier("ok_arete (identique seulement si ok_arete relu dans le fichier .ok_arete):",ok_arete);
1126 }// fin if 3D
1127}
1128
1129void Domaine_VEF::typer_elem(Domaine& domaine_geom)
1130{
1131 const Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
1132 if (sub_type(Rectangle, elem_geom))
1133 domaine_geom.typer("Quadrangle");
1134 else if (sub_type(Hexaedre, elem_geom))
1135 domaine_geom.typer("Hexaedre_VEF");
1136
1137 const Nom& type_elem_geom = domaine_geom.type_elem()->que_suis_je();
1138
1139 if (Motcle(type_elem_geom) != "Segment")
1140 {
1141 Nom type;
1142 if (type_elem_geom == "Triangle")
1143 type = "Tri_VEF";
1144 else if (type_elem_geom == "Tetraedre")
1145 type = "Tetra_VEF";
1146 else if (type_elem_geom == "Quadrangle")
1147 type = "Quadri_VEF";
1148 else if (type_elem_geom == "Hexaedre_VEF")
1149 type = "Hexa_VEF";
1150 else
1151 {
1152 Cerr << "probleme de typage dans Elem_VEF::typer" << finl;
1153 Process::exit();
1154 }
1155 type_elem_.typer(type);
1156 }
1157}
1158
1160{
1161 // On construit si de taille nul
1162 // ou si le maillage est deformable
1163 if (vecteur_face_facette_.size() == 0 || domaine().deformable())
1164 {
1165 // Taille 8*n*4*3*2=192n
1166 const int nfa7 = type_elem().nb_facette();
1167 const int nb_poly_tot = nb_elem_tot();
1168 vecteur_face_facette_.resize(nb_poly_tot, nfa7, dimension, 2);
1169 const IntTab& KEL = type_elem().KEL();
1170 const IntTab& les_Polys = domaine().les_elems();
1171 const DoubleTab& coord = domaine().coord_sommets();
1172 const DoubleTab& xg = xp();
1173 int nb_som_facette=dimension;
1174 for (int poly = 0; poly < nb_poly_tot; poly++)
1175 {
1176 // Boucle sur les facettes du polyedre non standard:
1177 for (int fa7 = 0; fa7 < nfa7; fa7++)
1178 {
1179 int num1 = elem_faces(poly, KEL(0, fa7));
1180 int num2 = elem_faces(poly, KEL(1, fa7));
1181
1182 // Calcul des rx0 et rx1 :
1183 for (int i = 0; i < dimension; i++)
1184 {
1185 // Calcul de la ieme coordonnee du centre de la fa7
1186 double coord_centre_fa7 = xg(poly, i);
1187 for (int num_som_fa7 = 0; num_som_fa7 < nb_som_facette - 1; num_som_fa7++)
1188 {
1189 int isom_loc = KEL(num_som_fa7 + 2, fa7);
1190 int isom_glob = les_Polys(poly, isom_loc);
1191 coord_centre_fa7 += coord(isom_glob, i);
1192 }
1193 coord_centre_fa7 /= nb_som_facette;
1194 // Fin calcul de la ieme coordonnee du centre de la fa7
1195 vecteur_face_facette_(poly,fa7,i,0) = coord_centre_fa7 - xv_(num1,i);
1196 vecteur_face_facette_(poly,fa7,i,1) = coord_centre_fa7 - xv_(num2,i);
1197 }
1198 // Fin de Calcul des rx0 et rx1
1199 }
1200 }
1201 Cerr << "Build of vecteur_face_facette() size:" << vecteur_face_facette_.size_array() << finl;
1202 }
1203 return vecteur_face_facette_;
1204}
int_t size_array() const
Renvoie la taille du tableau en bits.
Definition ArrOfBit.h:45
Empty class used as a base for all the arrays.
Definition Array_base.h:41
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
static void verifier_indices_items(const char *const msg, const MD_Vector &, const IntVect &)
teste le contenu du vecteur v en supposant qu'il contient des indices d'items associes au descripteur...
Definition Debog.cpp:58
static void verifier_getref(const char *const msg, double val, double &refval)
like verifier(), but, in "read&compare" mode, put the reference value found in the file in the ref va...
Definition Debog.cpp:74
static int active()
renvoie 1 si on est en mode Debog, 0 sinon
Definition Debog.cpp:66
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
int_t nb_aretes_tot() const
renvoie le nombre d'aretes total (reelles+virtuelles).
Definition Domaine.h:145
virtual const MD_Vector & md_vector_sommets() const
Definition Domaine.h:369
void creer_aretes()
Definition Domaine.cpp:2122
const IntTab_t & aretes_som() const
renvoie le tableau de connectivite aretes/sommets.
Definition Domaine.h:156
DoubleTab_t & les_sommets()
Definition Domaine.h:113
int_t get_renum_som_perio(int_t i) const
Definition Domaine.h:281
IntTab_t & les_elems()
Definition Domaine.h:129
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_aretes() const
Renvoie le nombre d'aretes reelles.
Definition Domaine.h:143
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
Definition Domaine.h:457
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
virtual void creer_tableau_sommets(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Cree un tableau ayant une "ligne" par sommet du maillage.
Definition Domaine.cpp:1000
virtual const MD_Vector & md_vector_elements() const
renvoie le descripteur parallele des tableaux aux elements du domaine
Definition Domaine.cpp:860
int_t elem_aretes(int_t i, int j) const
renvoie le numero de la jeme arete du ieme element.
Definition Domaine.h:154
Joints_t & faces_joint()
Definition Domaine.h:265
class Domaine_VEF
Definition Domaine_VEF.h:54
virtual void creer_tableau_p1bulle(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
void verifie_ok_arete(int) const
void construire_ok_arete()
const IntVect & get_ok_arete() const
Definition Domaine_VEF.h:99
IntVect & rang_elem_non_std()
Definition Domaine_VEF.h:86
void modifier_pour_Cl(const Conds_lim &) override
void swap(int, int, int)
DoubleTab & vecteur_face_facette()
void calculer_volumes_entrelaces()
void calculer_h_carre()
void typer_elem(Domaine &) override
const Elem_VEF_base & type_elem() const
Definition Domaine_VEF.h:75
int lecture_ok_arete()
int get_alphaA() const
Definition Domaine_VEF.h:94
const ArrOfInt & get_renum_arete_perio() const
Definition Domaine_VEF.h:98
virtual void discretiser_suite(const VEF_discretisation &)
void discretiser_arete()
virtual const MD_Vector & md_vector_p1b() const
int get_alphaS() const
Definition Domaine_VEF.h:93
void construire_renum_arete_perio(const Conds_lim &)
void discretiser() override
class Domaine_VF
Definition Domaine_VF.h:44
IntVect rang_elem_non_std_
Definition Domaine_VF.h:252
void creer_tableau_aretes(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
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
DoubleTab xp_
Definition Domaine_VF.h:218
IntTab & face_sommets() override
renvoie le tableau de connectivite faces/sommets.
Definition Domaine_VF.h:591
DoubleVect volumes_entrelaces_
Definition Domaine_VF.h:210
const MD_Vector & md_vector_faces() const
Definition Domaine_VF.h:158
const MD_Vector & md_vector_aretes() const
Definition Domaine_VF.h:160
DoubleTab xa_
Definition Domaine_VF.h:225
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
double xa(int num_arete, int k) const
Definition Domaine_VF.h:78
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
DoubleTab xv_
Definition Domaine_VF.h:219
int nb_elem_std_
Definition Domaine_VF.h:250
int nb_faces_std_
Definition Domaine_VF.h:251
DoubleTab & xa()
Definition Domaine_VF.h:97
void discretiser() override
Genere les faces construits les frontieres.
IntTab & elem_faces()
renvoie le tableau de connectivite element/faces
Definition Domaine_VF.h:551
IntTab face_voisins_
Definition Domaine_VF.h:216
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
DoubleVect & volumes()
Definition Domaine_VF.h:119
DoubleTab face_normales_
Definition Domaine_VF.h:212
void construire_num_fac_loc()
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
MD_Vector md_vector_aretes_
Definition Domaine_VF.h:233
DoubleTab & xp()
Definition Domaine_VF.h:95
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 &)
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
int nb_elem_tot() const
const Domaine & domaine() const
Lecture dans un fichier d'objets ecrits au format binaire.
Definition EFichierBin.h:30
Ecriture dans un fichier partage Cette classe derive de Ecr_Fic_Par, en utilisant une sortie en binai...
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out) override
Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la met...
Sortie & syncfile() override
Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernie...
const IntTab & KEL() const
virtual int nb_facette() const =0
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Front_VF
Definition Front_VF.h:36
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
int get_sequential_items_flags(ArrOfBit &flags, int line_size=1) const
virtual trustIdType nb_items_seq_tot() const
Metadata for a distributed composite vector.
void add_part(const MD_Vector &part, int shape=0, Nom name="")
Append the "part" descriptor to the composite vector.
static void creer_tableau_distribue(const MD_Vector &, Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
transforme v en un tableau parallele ayant la structure md.
static void echange_espace_virtuel(IntVect &, Operations_echange opt=ECHANGE_EV, IsExchangeBlocking is_exchange_blocking=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
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 const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static int_t search_nodes_close_to(double x, double y, double z, const DoubleTab_t &coords, ArrOfInt_t &node_list, double epsilon)
Methode hors classe Cherche parmi les sommets de la liste node_list ceux qui sont a une.
void build_nodes(const DoubleTab_t &coords, const bool include_virtual, const double epsilon=0.)
construit un octree contenant les points de coordonnees coords.
int_t search_elements_box(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, ArrOfInt_t &elements) const
cherche tous les elements ou points ayant potentiellement une intersection non vide avec la boite don...
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
int direction_periodicite() const
static double mp_min(double)
Definition Process.cpp:386
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static double mp_sum_as_double(int v)
Definition Process.h:99
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
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
static bool is_sequential()
Definition Process.cpp:115
Classe de base des flux de sortie.
Definition Sortie.h:52
int_t get_list_size(int_t i_liste) const
renvoie le nombre d'elements de la liste i
_SIZE_ size_array() const
void copy(const TRUSTTab &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:622
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
int get_modif_div_face_dirichlet() const
int get_cl_pression_sommet_faible() const