TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Sauvegarde_Reprise_Maillage_FT.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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#include <Sauvegarde_Reprise_Maillage_FT.h>
16#include <Maillage_FT_Disc.h>
17#include <Domaine_VF.h>
18#include <communications.h>
19#include <Array_tools.h>
20#include <Domaine.h>
21#include <EcrFicPartageMPIIO.h>
22
23void ecrire_tableau(Sortie& os, const DoubleTab& tab)
24{
25 const int dim0 = tab.dimension(0);
26 const int dimtot = Process::check_int_overflow(Process::mp_sum(dim0));
28 os << dimtot << tspace << tab.dimension(1) << finl;
29 os.put(tab.addr(), tab.size_array());
30 os.syncfile();
31}
32
33void put_generic(Sortie& os, const ArrOfInt& arr, const int dim0)
34{
35#ifdef INT_is_64_
36 Sortie * sort_ptr = &os;
37 if (dynamic_cast<EcrFicPartageMPIIO*>(sort_ptr))
38 {
39 // put() can not always be used directly (for example EcrFicPartageMPIIO doesn't support put()
40 // with cross bitness 32/64b). So upcast here if needed:
41 ArrOfTID arr2(dim0);
42 std::copy(arr.addr(), arr.addr()+dim0, arr2.addr());
43 os.put(arr2.addr(), arr2.size_array());
44 }
45 else
46#endif
47 os.put(arr.addr(), arr.size_array());
48 os.syncfile();
49}
50
51void ecrire_tableau(Sortie& os, const IntTab& tab)
52{
53 const int dim0 = tab.dimension(0);
54 const int dimtot = Process::check_int_overflow(Process::mp_sum(dim0));
56 os << dimtot << tspace << tab.dimension(1) << finl;
57 put_generic(os, tab, tab.size_array());
58}
59
60void ecrire_tableau(Sortie& os, const ArrOfInt& tab)
61{
62 const int dim0 = tab.size_array();
63 const int dimtot = Process::check_int_overflow(Process::mp_sum(dim0));
65 os << dimtot << finl;
66 put_generic(os, tab, tab.size_array());
67}
68
70{
72 fichier << mesh.temps_physique_ << finl;
73 // ========== ETAPE 1 : SOMMETS ===========
74 // Sauvegarde des sommets et valeurs associees.
75 // Pour chaque sommet, ecriture de :
76 // - coordonnees des coordonnees du centre de gravite des elements contenant le sommet
77 // - coordonnees des sommets
78 // - si le sommet est sur une face de bord, indice de la face dans l'element, sinon -1
79 const int nb_sommets = mesh.nb_sommets();
80 DoubleTab coord_elem;
81 DoubleTab coord_som;
82 ArrOfInt num_face_bord;
83 ArrOfIntFT indice_global_sommet(nb_sommets);
84 // On surdimensionne les tableaux, on fera resize a la fin
85 const int dim = mesh.sommets_.dimension(1);
86 coord_elem.resize(nb_sommets, dim);
87 coord_som.resize(nb_sommets, dim);
88 num_face_bord.resize_array(nb_sommets);
89 const DoubleTab& xp = domaine_vf.xp();
90 // Compteur de sommets reels
91 int nb_sommets_reels = 0;
92 int i, j;
93 for (i = 0; i < nb_sommets; i++)
94 {
95 if (mesh.sommet_virtuel(i))
96 {
97 indice_global_sommet[i] = -1;
98 continue;
99 }
100 const int indice_element = mesh.sommet_elem_[i];
101 for (j = 0; j < dim; j++)
102 coord_elem(nb_sommets_reels, j) = xp(indice_element, j);
103 for (j = 0; j < dim; j++)
104 coord_som(nb_sommets_reels, j) = mesh.sommets_(i, j);
105 const int face_bord = mesh.sommet_face_bord_[i];
106 int i_face_bord = -1;
107 if (face_bord >= 0)
108 {
109 i_face_bord = domaine_vf.numero_face_local(face_bord, indice_element);
110 assert(face_bord == domaine_vf.elem_faces(indice_element, i_face_bord));
111 }
112 num_face_bord[nb_sommets_reels] = i_face_bord;
113 indice_global_sommet[i] = nb_sommets_reels;
114 nb_sommets_reels++;
115 }
116 coord_elem.resize(nb_sommets_reels, dim);
117 coord_som.resize(nb_sommets_reels, dim);
118 num_face_bord.resize_array(nb_sommets_reels);
119 // Calcul de l'offset a ajouter pour avoir l'indice global du sommet:
120 const int offset = Process::check_int_overflow(Process::mppartial_sum(nb_sommets_reels));
121 for (i = 0; i < nb_sommets; i++)
122 if (indice_global_sommet[i] >= 0)
123 indice_global_sommet[i] += offset;
124 mesh.desc_sommets().echange_espace_virtuel(indice_global_sommet);
125
126 ecrire_tableau(fichier, coord_elem);
127 ecrire_tableau(fichier, coord_som);
128 ecrire_tableau(fichier, num_face_bord);
129
130 // ============== ETAPE 2 : FACETTES =============
131 // Sauvegarde des facettes : conversion des indices de sommets des facettes en indices globaux
132 // et sauvegarde des facettes reeles uniquement.
133 IntTab facettes_to_save;
134 const int nb_facettes = mesh.nb_facettes();
135 facettes_to_save.resize(nb_facettes, dim);
136 int nb_facettes_reeles = 0;
137 for (i = 0; i < nb_facettes; i++)
138 {
139 if (mesh.facette_virtuelle(i))
140 continue;
141 for (j = 0; j < dim; j++)
142 {
143 const int i_som = mesh.facettes_(i, j);
144 const int i_som_global = indice_global_sommet[i_som];
145 assert(i_som_global >= 0);
146 facettes_to_save(nb_facettes_reeles, j) = i_som_global;
147 }
148 nb_facettes_reeles++;
149 }
150 facettes_to_save.resize(nb_facettes_reeles, dim);
151 ecrire_tableau(fichier, facettes_to_save);
152}
153
154/*! @brief Remplissage du maillage mesh a partir d'un fichier de sauvegarde xyz (fichier) ou d'un domaine source (domaine_src pour importation d'une cao)
155 *
156 * domaine_vf est le domaine support du maillage (pour calcul de l'indice de l'element contenant chaque
157 * sommet du mesh. domaine_vf peut etre nul dans le cas d'une reprise xyz au cours de l'etape 'avancer'.
158 * Dans ce cas, on lit les coordonnees et les elements mais on ne remplit pas mesh.
159 *
160 */
162 const Domaine_VF * domaine_vf,
163 Entree * fichier,
164 const Domaine * domaine_src)
165{
166 // On doit donner un fichier OU un domaine_src, mais pas les deux !
167 assert((fichier && (!domaine_src)) || ((!fichier) && domaine_src));
168 const int moi = Process::me();
169 const int nproc = Process::nproc();
171 if (fichier)
172 (*fichier) >> mesh.temps_physique_;
173 // ============== ETAPE 1 : lecture des sommets reels ===============
174 // On lit les sommets, et on ne conserve que les sommets dont on est proprietaire
175 const int dim = Objet_U::dimension;
176 mesh.sommets_.resize(0, dim);
177
178 int nb_som_tot, dummy_int;
179 if (fichier)
180 {
181 // Reprise xyz : on lit le nombre de sommets
182 (*fichier) >> nb_som_tot >> dummy_int;
183 assert(dummy_int == dim);
184 }
185 else
186 {
187 // lecture cao : on utilise le domaine
188 nb_som_tot = domaine_src->nb_som();
189 if (domaine_src->coord_sommets().dimension(1) != dim)
190 {
191 Cerr << "Error in Sauvegarde_Reprise_Maillage_FT::lire_xyz : source domain has bad dimension" << finl;
193 }
194 }
195
196 const int chunk_size = 65536; // Lire les sommets par blocs
197 // Pour chaque sommet conserve, quel est son indice global
198 ArrOfInt indice_global_sommet;
199 const Domaine * const domaine = (domaine_vf ? &domaine_vf->domaine() : 0);
200 // Lecture des indices des elements contenant le sommet
201 int erreur_sommets_exterieurs = 0;
202 {
203 DoubleTab tmp;
204 // tmp2 : pour chaque sommet, -1 si je ne le garde pas, sinon numero de l'element qui contient le sommet
205 ArrOfInt tmp2;
206 // tmp3 : -1 ou numero du processeur qui garde le sommet.
207 ArrOfInt tmp3;
208 int i = 0;
209 const int nb_elements_reels = (domaine_vf ? domaine->nb_elem() : 0);
210 while (i < nb_som_tot)
211 {
212 const int n_to_read = std::min(chunk_size, nb_som_tot - i);
213 tmp.resize(n_to_read, dim);
214 tmp2.resize_array(n_to_read);
215 tmp3.resize_array(n_to_read);
216 if (fichier)
217 {
218 // Lecture des coordonnees des centres des elements dans le fichier
219 fichier->get(tmp.addr(), tmp.size_array());
220 }
221 else
222 {
223 // Copie des coordonnees des sommets dans le domaine
224 const DoubleTab& coord = domaine_src->coord_sommets();
225 for (int j = 0; j < n_to_read; j++)
226 for (int k = 0; k < dim; k++)
227 tmp(j, k) = coord(i+j, k);
228 }
229 if (domaine_vf)
230 {
231 domaine->chercher_elements(tmp, tmp2);
232 // Ne pas tenir compte des sommets dans les elements virtuels
233 for (int j = 0; j < n_to_read; j++)
234 if (tmp2[j] >= nb_elements_reels)
235 tmp2[j] = -1;
236 // Verifier qu'un processeur et un seul prend la main.
237 // Le premier processeur initialise tmp3 en mettant son numero
238 // pour les sommets qu'il possede et -1 pour les autres.
239 // Puis la liste est passee au processeur suivant qui la complete.
240 if (moi == 0)
241 {
242 // Preparer la premiere liste
243 for (int j = 0; j < n_to_read; j++)
244 if (tmp2[j] >= 0)
245 tmp3[j] = moi;
246 else
247 tmp3[j] = -1;
248 }
249 else
250 {
251 // Recevoir une liste d'attribution du processeur precedent
252 // et la completer
253 recevoir(tmp3, moi - 1, moi, 0 /* canal */);
254 for (int j = 0; j < n_to_read; j++)
255 if (tmp3[j] >= 0) // Le sommet a ete pris par un autre processeur
256 tmp2[j] = -1;
257 else if (tmp2[j] >= 0) // Le sommet n'a pas ete pris et est chez moi
258 tmp3[j] = moi;
259 }
260 if (moi < nproc - 1)
261 {
262 envoyer(tmp3, moi, moi + 1, 0 /* canal */);
263 }
264 else
265 {
266 // Le dernier processeur prend les sommets qui restent
267 for (int j = 0; j < n_to_read; j++)
268 if (tmp3[j] < 0)
269 {
270 tmp3[j] = moi;
271 // Pour l'instant on ne sait pas traiter des maillages qui depassent du
272 // domaine:
273 erreur_sommets_exterieurs=1;
274 }
275 }
276
277 for (int j = 0; j < n_to_read; j++)
278 {
279 // i+j est le rang de ce sommet dans le fichier lu
280 if (tmp3[j] == moi)
281 {
282 indice_global_sommet.append_array(i+j);
283 mesh.sommet_elem_.append_array(tmp2[j]);
284 }
285 }
286 }
287 i += n_to_read;
288 }
289 }
290
291// if (Process::check_int_overflow(Process::mp_sum(erreur_sommets_exterieurs))
292// GF bloque sinon dans avancer en // de plis c'est inutil
293 if (erreur_sommets_exterieurs)
294 {
295 Cerr << "Erreur a la lecture d'un maillage front-tracking :\n"
296 << " Certains sommets sont a l'exterieur du maillage eulerien.\n"
297 << " On ne sait pas encore traiter ce cas." << finl;
300 }
301
302 // Lecture des coordonnees des sommets
303 if (fichier)
304 {
305 int n;
306 (*fichier) >> n >> dummy_int;
307 }
308 const int nb_sommets_locaux = mesh.sommet_elem_.size_array();
309 {
310 int i = 0;
311 int i_sommet = 0;
312 DoubleTab tmp;
313 mesh.sommets_.resize(nb_sommets_locaux, dim);
314 while (i < nb_som_tot)
315 {
316 const int n_to_read = std::min(chunk_size, nb_som_tot - i);
317 tmp.resize(n_to_read, dim);
318 if (fichier)
319 {
320 fichier->get(tmp.addr(), tmp.size_array());
321 }
322 else
323 {
324 // Copie des coordonnees des sommets dans le domaine
325 const DoubleTab& coord = domaine_src->coord_sommets();
326 for (int j = 0; j < n_to_read; j++)
327 for (int k = 0; k < dim; k++)
328 tmp(j, k) = coord(i+j, k);
329 }
330 if (domaine_vf)
331 {
332 for (int j = 0; j < n_to_read; j++)
333 {
334 const int i_glob = i+j;
335 // Ce processeur possede-t-il ce sommet ?
336 if (i_sommet >= nb_sommets_locaux || i_glob != indice_global_sommet[i_sommet])
337 continue;
338 for (int k = 0; k < dim; k++)
339 mesh.sommets_(i_sommet, k) = tmp(j, k);
340 i_sommet++;
341 }
342 }
343 i += n_to_read;
344 }
345 assert(domaine_vf == 0 || i_sommet == mesh.nb_sommets());
346 }
347 // Lecture des faces de bord
348 if (fichier)
349 {
350 int dummy;
351 (*fichier) >> dummy;
352 int i = 0;
353 int i_sommet = 0;
354 ArrOfInt tmp;
355 mesh.sommet_face_bord_.resize_array(nb_sommets_locaux);
356 const IntTab * elem_faces = (domaine_vf ? &domaine_vf->elem_faces() : 0);
357 const int nb_faces_bord = (domaine ? domaine->nb_faces_frontiere() : 0);
358 while (i < nb_som_tot)
359 {
360 const int n_to_read = std::min(chunk_size, nb_som_tot - i);
361 tmp.resize_array(n_to_read);
362 fichier->get(tmp.addr(), tmp.size_array());
363 if (domaine_vf)
364 {
365 for (int j = 0; j < n_to_read; j++)
366 {
367 const int i_glob = i+j;
368 // Ce processeur possede-t-il ce sommet ?
369 if (i_sommet >= nb_sommets_locaux || i_glob != indice_global_sommet[i_sommet])
370 continue;
371 int i_face = -1;
372 const int i_face_local = tmp[j];
373 if (i_face_local >= 0)
374 {
375 const int elem = mesh.sommet_elem_[i_sommet];
376 i_face = (*elem_faces)(elem, i_face_local);
377 if (i_face >= nb_faces_bord)
378 {
379 // La face trouvee n'est pas une face de bord
380 // Seule explication possible: les faces des elements
381 // ont ete renumerotees.
382 Cerr << "Erreur a la relecture des faces de bord" << finl;
384 }
385 }
386 mesh.sommet_face_bord_[i_sommet] = i_face;
387 i_sommet++;
388 }
389 }
390 i += n_to_read;
391 }
392 assert(domaine_vf == 0 || i_sommet == mesh.nb_sommets());
393 }
394 else
395 {
396 // Pas de sommet au bord pour l'instant
397 mesh.sommet_face_bord_.resize_array(nb_sommets_locaux);
398 mesh.sommet_face_bord_ = -1;
399 }
400 // Lecture des facettes
401 // On lit dans itmp et on copie dans facettes les facettes
402 // qui appartiennent au processeur local.
403 IntTab facettes(0, dim);
404 int nb_faces_tot;
405 if (fichier)
406 {
407 (*fichier) >> nb_faces_tot >> dummy_int;
408 assert(dummy_int == dim);
409 }
410 else
411 {
412 // lecture cao : on utilise le domaine
413 nb_faces_tot = domaine_src->nb_elem();
414 if (domaine_src->les_elems().dimension(1) != dim)
415 {
416 Cerr << "Error in Sauvegarde_Reprise_Maillage_FT::lire_xyz : source domain elements have bad dimension" << finl;
418 }
419 }
420 {
421 IntTab tmp;
422 int i = 0;
423 while (i < nb_faces_tot)
424 {
425 const int n_to_read = std::min(chunk_size, nb_faces_tot - i);
426 tmp.resize(n_to_read, dim);
427 if (fichier)
428 fichier->get(tmp.addr(), tmp.size_array());
429 else
430 {
431 // Copie des elements dans le domaine
432 const IntTab& elems = domaine_src->les_elems();
433 for (int j = 0; j < n_to_read; j++)
434 for (int k = 0; k < dim; k++)
435 tmp(j, k) = elems(i+j, k);
436 }
437 if (domaine_vf)
438 {
439 for (int j = 0; j < n_to_read; j++)
440 {
441 // Indice global du premier sommet de la facette.
442 const int i_som = tmp(j, 0);
443 // Le processeur local possede-t-il ce sommet ?
444 const int i_som_loc = array_bsearch(indice_global_sommet, i_som);
445 if (i_som_loc >= 0)
446 {
447 // oui
448 const int n = facettes.dimension(0);
449 facettes.resize(n+1, dim);
450 for (int k = 0; k < dim; k++)
451 facettes(n, k) = tmp(j, k);
452 }
453 }
454 }
455 i += n_to_read;
456 }
457 }
458 if (!domaine_vf)
459 return;
460
461 {
462 const int n = mesh.nb_sommets();
466 for (int i = 0; i < n; i++)
467 {
468 mesh.sommet_PE_owner_[i] = moi;
469 mesh.sommet_num_owner_[i] = i;
470 mesh.drapeaux_sommets_[i] = 0;
471 }
474 }
475 // Recuperer les sommets manquants chez les autres processeurs:
476 // Chaque processeur envoie au processeur suivant les indices globaux des
477 // sommets qui lui manquent. Le processeur traite la liste qu'il
478 // a recu et envoie les sommets restants au processeur suivant.
479 {
480 // Liste d'indices de sommets locaux a envoyer
481 ArrOfIntFT liste_sommets_to_send;
482 // Pour chaque sommet de la liste precedente, numero du pe destination
483 ArrOfIntFT liste_pe_to_send;
484 // Liste d'indices des indices de sommets globaux a transmettre
485 // (au depart, la liste dont le processeur local a besoin, puis on
486 // fait passer la liste au processeur suivant en chaine).
487 ArrOfInt liste_sommets_globaux;
488 // Recherche des sommets inconnus parmi les sommets des facettes
489 {
490 // Tableau facettes, vu comme un tableau monodimensionnel:
491 const ArrOfInt& liste_tous_sommets = facettes;
492 mesh.facettes_.resize(facettes.dimension(0), dim);
493 ArrOfInt& liste_sommets_locaux = mesh.facettes_;
494 const int n = liste_tous_sommets.size_array();
495 for (int i = 0; i < n; i++)
496 {
497 const int som = liste_tous_sommets[i];
498 const int i_som_loc = array_bsearch(indice_global_sommet, som);
499 liste_sommets_locaux[i] = i_som_loc;
500 if (i_som_loc < 0)
501 liste_sommets_globaux.append_array(som);
502 }
503 array_trier_retirer_doublons(liste_sommets_globaux);
504 }
505 // Numero du processeur qui a genere la liste en cours de traitement
506 int pe_sender = moi;
507 int next_pe = (pe_sender + 1) % nproc;
508 int prec_pe = (pe_sender + nproc - 1) % nproc;
509 // Liste des processeurs a qui on envoie : un seul, le suivant
510 // Processeurs de qui on recoit : le precedent
511 const int send_list_size = (pe_sender == next_pe ? 0 : 1);
512 ArrOfInt send_list(send_list_size);
513 ArrOfInt recv_list(send_list_size);
514 if (send_list_size)
515 {
516 send_list[0] = next_pe;
517 recv_list[0] = prec_pe;
518 }
519 Schema_Comm schema_comm;
520 schema_comm.set_send_recv_pe_list(send_list, recv_list);
521 send_list.resize_array(0);
522 recv_list.resize_array(0);
523 ArrOfInt new_list;
524 for (int num_proc = 0; num_proc < nproc - 1; num_proc++)
525 {
526 // A chaque iteration, on transmet la liste au processeur suivant
527 // Le processeur qui a envoye la liste a l'origine est donc le
528 // precedent.
529 pe_sender = (pe_sender + nproc - 1) % nproc;
530 // Envoi de la liste de sommets au processeur suivant
531 schema_comm.begin_comm();
532 schema_comm.send_buffer(next_pe) << liste_sommets_globaux;
533 schema_comm.echange_taille_et_messages();
534 schema_comm.recv_buffer(prec_pe) >> liste_sommets_globaux;
535 schema_comm.end_comm();
536 // Pour chaque sommet de la liste, si je le possede,
537 // je l'envoie a pe_sender et je le retire de la liste
538 const int n = liste_sommets_globaux.size_array();
539 new_list.resize_array(0);
540 int flag = 0; // Va-on envoyer un sommet a pe_sender ?
541 for (int i = 0; i < n; i++)
542 {
543 const int som = liste_sommets_globaux[i];
544 const int i_som_loc = array_bsearch(indice_global_sommet, som);
545 if (i_som_loc >= 0)
546 {
547 liste_sommets_to_send.append_array(i_som_loc);
548 liste_pe_to_send.append_array(pe_sender);
549 flag = 1;
550 }
551 else
552 {
553 new_list.append_array(som);
554 }
555 }
556 liste_sommets_globaux = new_list;
557 if (flag)
558 send_list.append_array(pe_sender);
559 }
560 // A la fin, on doit avoir trouve tous les sommets
561 if (liste_sommets_globaux.size_array() > 0)
562 {
563 Cerr << "Erreur sur PE " << moi << " : les sommets d'indices suivants"
564 << " ne sont sur aucun processeur\n" << liste_sommets_globaux << finl;
566 }
567 // Creer les sommets virtuels
568 reverse_send_recv_pe_list(send_list, recv_list);
569 // TEMPORAIRE:
570 Schema_Comm sch;
571 sch.set_send_recv_pe_list(send_list, recv_list);
572 mesh.creer_sommets_virtuels(liste_sommets_to_send, liste_pe_to_send, sch);
573 }
574
575 // Echanger les indices globaux
576 const int nb_sommets_reels = indice_global_sommet.size_array();
577 indice_global_sommet.resize_array(mesh.nb_sommets());
578 mesh.desc_sommets().echange_espace_virtuel(indice_global_sommet);
579
580 // Traduire les indice globaux des sommets des facettes en indices locaux
581 {
582 const int nb_sommets_tot = indice_global_sommet.size_array();
583 // Tableau facettes, vu comme un tableau monodimensionnel:
584 const ArrOfInt& indices_globaux = facettes;
585 ArrOfInt& indices_locaux = mesh.facettes_;
586 const int n = indices_globaux.size_array();
587 for (int i = 0; i < n; i++)
588 {
589 if (indices_locaux[i] < 0)
590 {
591 const int indice_global = indices_globaux[i];
592 // Cherche l'indice local du sommet parmi les sommets virtuels
593 int indice_local;
594 for (indice_local = nb_sommets_reels; indice_local < nb_sommets_tot; indice_local++)
595 if (indice_global_sommet[indice_local] == indice_global)
596 break;
597 assert(indice_local < nb_sommets_tot);
598 indices_locaux[i] = indice_local;
599 }
600 }
601 }
603 {
604 const int n = mesh.facettes_.dimension(0);
606 for (int i = 0; i < n; i++)
607 mesh.facette_num_owner_[i] = i;
608 }
609}
void echange_espace_virtuel(ArrOfDouble &tab) const
void calcul_schema_comm(const int nb_items_tot)
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
class Domaine_VF
Definition Domaine_VF.h:44
int numero_face_local(int face, int elem) const
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
const Domaine & domaine() const
Class to use MPI-IO to write in a single file.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual int get(int *ob, std::streamsize n)
Definition Entree.cpp:222
: class Maillage_FT_Disc Cette classe decrit un maillage:
int nb_sommets() const
renvoie le nombre de sommets (reels et virtuels) (egal a sommets().
ArrOfIntFT sommet_PE_owner_
Desc_Structure_FT desc_facettes_
void creer_sommets_virtuels(const ArrOfInt &liste_sommets, const ArrOfInt &liste_pe, const Schema_Comm &comm)
Envoi des sommets dont le numero est donne dans liste_sommets au processeur dont le numero est donne ...
int nb_facettes() const
renvoie le nombre de facettes (reelles et virtuelles) (egal a facettes().
ArrOfIntFT sommet_face_bord_
ArrOfIntFT facette_num_owner_
Desc_Structure_FT desc_sommets_
int facette_virtuelle(int i) const
Renvoie 0 si la facette m'appartient, 1 sinon.
const Desc_Structure_FT & desc_sommets() const
renvoie le descripteur des sommets (espace_distant/virtuel)
ArrOfIntFT sommet_num_owner_
ArrOfIntFT drapeaux_sommets_
int sommet_virtuel(int i) const
Statut_Maillage statut_
static int dimension
Definition Objet_U.h:99
static int check_int_overflow(trustIdType)
Definition Process.cpp:428
static trustIdType mppartial_sum(trustIdType i)
Calul de la somme partielle de i sur les processeurs 0 a me()-1 (renvoie 0 sur le processeur 0).
Definition Process.cpp:396
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
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 void lire_xyz(Maillage_FT_Disc &mesh, const Domaine_VF *domaine_vf, Entree *fichier, const Domaine *domaine_src)
Remplissage du maillage mesh a partir d'un fichier de sauvegarde xyz (fichier) ou d'un domaine source...
static void ecrire_xyz(const Maillage_FT_Disc &mesh, const Domaine_VF &domaine_vf, Sortie &fichier)
void echange_taille_et_messages() const
Cette methode lance l'echange de donnees entre tous les processeurs.
Sortie & send_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y entasser des donnees a envoyer.
void end_comm() const
Vide les buffers et libere les ressources: on a fini de lire les donnees recues dans les buffers.
Entree & recv_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y lire les donnees recues.
void begin_comm() const
Reserve les buffers de comm pour une nouvelle communication.
void set_send_recv_pe_list(const ArrOfInt &send_pe_list, const ArrOfInt &recv_pe_list, const int me_to_me=0)
Definit la liste des processeurs a qui on va envoyer et de qui on va recevoir des donnees.
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual int put(const unsigned *ob, std::streamsize n, std::streamsize nb_colonnes=1)
Definition Sortie.cpp:101
virtual Sortie & syncfile()
Definition Sortie.cpp:187
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
_TYPE_ * addr()
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133