16#include <Reordonner_faces_periodiques.h>
17#include <Connectivite_som_elem.h>
18#include <Partitionneur_base.h>
19#include <communications.h>
20#include <Array_tools.h>
21#include <TRUSTLists.h>
31template <
typename _SIZE_>
38template <
typename _SIZE_>
48template <
typename _SIZE_>
51 Cerr <<
"Correction of the splitting to put the element 0 on processor 0." << finl;
52 int pe_to_xchange = elem_part[0];
53 envoyer_broadcast(pe_to_xchange, 0);
54 if (pe_to_xchange == 0)
56 Cerr <<
" No correction to be made" << finl;
60 Cerr <<
" Exchange of parts 0 and " << pe_to_xchange << finl;
62 for (
int_t i = 0; i < n; i++)
64 const int pe = elem_part[i];
66 elem_part[i] = pe_to_xchange;
67 else if (pe == pe_to_xchange)
84template <
typename _SIZE_>
86 const IntTab_T<_SIZE_>& faces,
88 ArrOfInt_T<_SIZE_>& elements)
91 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
93 const int_t nb_faces = faces.
dimension(0);
98 SmallArrOfTID_t une_face(nb_som_faces);
99 SmallArrOfTID_t voisins;
100 for (int_t i = 0; i < nb_faces; i++)
102 for (
int j = 0; j < nb_som_faces; j++)
103 une_face[j] = faces(i, j);
104 find_adjacent_elements(som_elem, une_face, voisins);
105 const int nb_voisins = voisins.size_array();
108 Cerr <<
"Error in chercher_elems_voisins_faces : the face " << i
109 <<
"\n of boundary " << nom_faces <<
" has " << nb_voisins
110 <<
" neighboring elements with the indices : " << voisins << finl;
113 elements[i] = voisins[0];
128template <
typename _SIZE_>
134 const Noms& liste_bords_periodiques = domaine.bords_perio();
135 const int_t nb_elem = domaine.nb_elem();
145 const int nb_bords = domaine.nb_bords();
146 for (
int i_bord = 0; i_bord < nb_bords; i_bord++)
148 const Bord_t& bord = domaine.bord(i_bord);
151 Cerr <<
" Checking of the boundary " << bord.
le_nom();
158 for (
int i = 0; i < d; i++) Cerr << delta[i] <<
" ";
160 for (
int i = 0; i < d; i++) Cerr << erreur[i] <<
" ";
164 Cerr <<
"You need to use the Declarer_bord_perio keyword on the periodic boundaries." << finl;
165 Cerr <<
"See the reference manual to use this keyword on your data file." << finl;
178 for (
int_t i = 0; i < nb_faces; i++)
181 int_t elem0 = elems_voisins[i];
182 int_t elem1 = elems_voisins[i+nb_faces];
184 ++nb_faces_perio[elem0 - my_offset*(elem0 >= my_offset)];
185 ++nb_faces_perio[elem1 - my_offset*(elem1 >= my_offset)];
188 Cerr <<
"Error in calculer_correspondance_faces_perio: the faces " << i
189 <<
" and " << i + nb_faces
190 <<
"\n of the boundary " << bord.
le_nom()
191 <<
" are neighbors of the same element " << elem0 << finl;
194 correspondances.
resize(n+1, 2);
195 correspondances(n, 0) = elem0;
196 correspondances(n, 1) = elem1;
207 for (
int_t i = 0; i < n; i++)
209 const int_t elem0 = correspondances(i, 0),
210 elem1 = correspondances(i, 1);
212 const int_t j0 = nb_faces_perio[elem0 - my_offset*(elem0 >= my_offset)]++;
213 graph.
set_value(elem0 - my_offset*(elem0 >= my_offset), j0, elem1);
214 const int_t j1 = nb_faces_perio[elem1 - my_offset*(elem1 >= my_offset)]++;
215 graph.
set_value(elem1 - my_offset*(elem1 >= my_offset), j1, elem0);
217 Cerr <<
" There is " << n*2 <<
" periodic connections." << finl;
236template <
typename _SIZE_>
245 const int_t nb_som_tot = domaine.nb_som_tot();
246 const int_t nb_elem = domaine.nb_elem();
247 const int_t nb_elem_tot = domaine.nb_elem_tot();
248 const Noms& liste_bords_perio = domaine.bords_perio();
252 ArrOfBit_t sommet_bord(nb_som_tot);
253 ArrOfBit_t sommet_bord_perio(nb_som_tot);
255 sommet_bord_perio = 0;
257 ArrOfBit_t element_bord(nb_elem_tot);
259 ArrOfBit_t element_bord_perio(nb_elem_tot);
261 element_bord_perio = 0;
263 const int nb_bords = domaine.nb_bords();
264 for (
int i_bord = 0; i_bord < nb_bords; i_bord++)
266 const Bord_t& bord = domaine.bord(i_bord);
273 chercher_elems_voisins_faces(som_elem, faces_sommets, bord.
le_nom(), elems_voisins);
278 for (
int_t i_face = 0; i_face < nb_faces_bord; i_face++)
280 const int_t elem_voisin = elems_voisins[i_face];
281 element_bord.setbit(elem_voisin);
283 element_bord_perio.setbit(elem_voisin);
284 for (
int i_som = 0; i_som < nb_som_face; i_som++)
286 const int_t som = faces_sommets(i_face, i_som);
287 sommet_bord.setbit(som);
289 sommet_bord_perio.setbit(som);
309 const IntTab_t& elements = domaine.les_elems();
311 for (
int_t elem = 0; elem < nb_elem; elem++)
314 bool has_som_perio =
false;
316 for (isom = 0; isom < nb_som_elem; isom++)
317 if (sommet_bord_perio[elements(elem, isom)])
318 has_som_perio =
true;
321 int nb_sommets_bord = 0;
322 for (isom = 0; isom < nb_som_elem; isom++)
324 const int_t som = elements(elem, isom);
327 if (has_som_perio && !sommet_bord_perio[som])
329 if (!sommet_bord[som])
336 const int_t renum_som = renum_som_perio[som];
338 for (
int_t i = 0; i < n; i++)
340 const int_t elem2 = som_elem(renum_som, i);
343 test = element_bord_perio[elem2];
345 test = element_bord[elem2];
348 const int p = elem_part[elem2];
352 array_trier_retirer_doublons(tmp);
356 array_calculer_intersection(parties_autorisees, tmp);
358 parties_autorisees = tmp;
360 if (nb_sommets_bord > 0)
366 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_sommets_bord : Error. No part authorized because of the periodicity for the mesh element " << elem << finl;
367 elem_part[elem] = -1;
372 const int p = elem_part[elem];
373 for (i = 0; i < n; i++)
374 if (parties_autorisees[i] == p)
379 elem_part[elem] = parties_autorisees[0];
385 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_sommets_bord : " << count <<
" modified elements" << finl;
396template <
typename _SIZE_>
403 const int_t nb_som = domaine.nb_som();
404 const int_t nb_elem = domaine.nb_elem();
405 const Noms& liste_bords_perio = domaine.bords_perio();
417 int deux_puissance_i_bord = 1;
418 for (
auto& itr : liste_bords_perio)
420 const Bord_t& bord = domaine.bord(itr);
425 chercher_elems_voisins_faces<_SIZE_>(som_elem, faces_sommets, bord.
le_nom(), elems_voisins);
426 for (
int_t i_face = 0; i_face < nb_faces_bord; i_face++)
428 const int_t elem_voisin = elems_voisins[i_face];
429 const int part = elem_part[elem_voisin];
430 for (
int i_som = 0; i_som < nb_som_face; i_som++)
432 const int_t som = faces_sommets(i_face, i_som);
433 const int old_part = partie_associee[som];
434 if (old_part < 0 || old_part > part)
435 partie_associee[som] = part;
436 marqueur_bord[som] |= deux_puissance_i_bord;
439 deux_puissance_i_bord *= 2;
440 if (deux_puissance_i_bord > 65536)
443 Cerr <<
"Error in Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : there is too many periodic boundaries." << finl;
451 for (
int_t sommet = 0; sommet < nb_som; sommet++)
454 const int marq = marqueur_bord[sommet];
456 for (
int x = 1; x < marq; x = x * 2)
462 marqueur_bord[sommet] = (n > 1);
466 const IntTab_t& les_elems = domaine.les_elems();
469 for (
int_t elem = 0; elem < nb_elem; elem++)
474 for (
int isom = 0; isom < nb_som_elem; isom++)
476 const int_t sommet = les_elems(elem, isom);
477 if (marqueur_bord[sommet])
480 const int_t renum = renum_som_perio[sommet];
481 const int part = partie_associee[renum];
482 assert(marqueur_bord[renum]);
484 if (new_part < 0 || new_part > part)
488 if (new_part >= 0 && new_part != elem_part[elem])
491 elem_part[elem] = new_part;
494 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : " << count <<
" modified elements" << finl;
498 SmallArrOfTID_T<_SIZE_> node(2);
499 int_t another_count=0;
501 for (
int_t som=0; som<nb_som; som++)
505 node[1]=renum_som_perio[som];
506 if (node[0]!=node[1])
510 for (
int i=0; i<2; i++)
514 int_t elem = som_elem(node[i],i_elem);
515 part[i].add_if_not(elem_part[elem]);
519 if (part[0].size()!=part[1].size())
521 Cerr <<
"Warning: Not the same number of parts around the periodic nodes " << node[0] <<
" and " << node[1] <<
" !" << finl;
522 Cerr <<
"We try to fix:" << finl;
523 int smaller = ( part[0].
size() < part[1].size() ? 0 : 1);
524 int bigger = 1 - smaller;
525 int first_part = part[smaller][0];
526 for (
int i=0; i<part[bigger].
size(); i++)
528 int i_part = part[bigger][i];
529 if (!part[smaller].contient(i_part))
534 int_t elem = som_elem(node[bigger],i_elem);
535 if (elem_part[elem] == i_part)
537 elem_part[elem] = first_part;
539 Cerr <<
"Element " << elem <<
" moved from part " << i_part <<
" to " << first_part << finl;
548 for (
int i=0; i<part[0].
size(); i++)
550 int i_part = part[0][i];
551 if (!part[1].contient(i_part))
554 Cerr <<
"Warning: different parts around the periodic nodes " << node[0] <<
" and " << node[1] <<
" !" << finl;
558 Cerr <<
"We try to fix:" << finl;
560 for (
int j=0; j<part[1].
size(); j++)
562 int j_part = part[1][j];
563 if (!part[0].contient(j_part))
569 int_t elem = som_elem(node[1],i_elem);
570 if (elem_part[elem] == j_part)
572 elem_part[elem] = i_part;
573 Cerr <<
"Element " << elem <<
" moved from part " << j_part <<
" to " << i_part << finl;
586 Cerr <<
"Error in Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique" << finl;
587 Cerr <<
"It will create possible problems for creation of renum_som_perio array." << finl;
588 Cerr <<
"Contact TRUST support or change the partition options." << finl;
591 count+=another_count;
592 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : plus " << another_count <<
" another modified elements" << finl;
603template <
typename _SIZE_>
614 const Noms& liste_bords_periodiques = domaine.bords_perio();
618 for (
int_t i = 0; i < n; i++)
621 const int part = elem_part[i];
622 for (
int_t j = 0; j < m; j++)
624 const int_t elem2 = graph_elements_perio(i,j);
625 if (elem_part[elem2] != part)
627 elem_part[elem2] = part;
632 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_bords_avec_graphe : " << count
633 <<
" modified periodic elements" << finl;
635 const int_t nb_sommets_reels = domaine.nb_som();
638 for (
int_t i = 0; i < nb_sommets_reels; i++)
639 renum_som_perio[i] = i;
644 if (liste_bords_periodiques.size() > 1)
657template <
typename _SIZE_>
659 const int_t my_offset,
662 Cerr <<
"Correction of the splitting for the periodicity" << finl;
664 Cerr <<
" Construction of the connectivity som_elem" << finl;
665 construire_connectivite_som_elem(dom.
nb_som_tot(),
669 Cerr <<
" Construction of graph connectivity for periodic elements" << finl;
674 graph_elements_perio);
679 Cerr <<
"corriger_bords_avec_liste : we have corrected " << count <<
" elements all in all." << finl;
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
const Faces_t & faces() const
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
int contient_(const char *const ch) const
Inherits from Objet_U, adds the very common method set_param for the Objet_U hierarchy.
virtual void set_param(Param &) const
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Helper class to factorize the readOn method of Objet_U classes.
Classe de base des partitionneurs de domaine (pour decouper un maillage avant un calcul parallele).
TRUSTArray< int, _SIZE_ > BigArrOfInt_
static int_t corriger_bords_avec_graphe(const Static_Int_Lists_t &graph_elements_perio, const Static_Int_Lists_t &som_elem, const Domaine_t &domaine, BigIntVect_ &elem_part)
corrige la partition elem_part pour qu'un element i se trouve sur la meme partition elem_part[i] que ...
static void corriger_bords_avec_liste(const Domaine_t &dom, const int_t my_offset, BigIntVect_ &elem_part)
Calcul des graphes de connectivite elements periodiques et appel a corriger_periodique_avec_graphe.
static void corriger_elem0_sur_proc0(BigIntVect_ &elem_part)
corrige la partition pour que l'element 0 du domaine initial se trouve sur le premier sous-domaine de...
ArrOfInt_T< _SIZE_ > ArrOfInt_t
static int_t corriger_sommets_bord(const Domaine_t &domaine, const ArrOfInt_t &renum_som_perio, const Static_Int_Lists_t &som_elem, BigIntVect_ &elem_part)
Modifie elem_part pour assurer les proprietes suivantes : 1) Les elements possedant un sommet de bord...
TRUSTVect< int, _SIZE_ > BigIntVect_
Domaine_32_64< _SIZE_ > Domaine_t
Bord_32_64< _SIZE_ > Bord_t
static int_t corriger_multiperiodique(const Domaine_t &domaine, const ArrOfInt_t &renum_som_perio, const Static_Int_Lists_t &som_elem, BigIntVect_ &elem_part)
applique des corrections a elem_part pour que le multi-periodique soit correct :
IntTab_T< _SIZE_ > IntTab_t
Static_Int_Lists_32_64< _SIZE_ > Static_Int_Lists_t
static int_t calculer_graphe_connexions_periodiques(const Domaine_t &domaine, const Static_Int_Lists_t &som_elem, const int_t my_offset, Static_Int_Lists_t &graph)
Calcul d'un graphe de connectivite entre les elements lies par des faces periodiques.
static bool is_parallel()
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
static int check_faces_periodiques(const Frontiere_32_64< _SIZE_ > &frontiere, ArrOfDouble &vecteur_delta, ArrOfDouble &erreur, bool verbose=false)
essaie de verifier si les faces du bord num_bord sont ordonnees suivant la convention des faces perio...
static void renum_som_perio(const Domaine_32_64< _SIZE_ > &dom, ArrOfInt_T< _SIZE_ > &renum_som_perio, bool calculer_espace_virtuel)
Classe de base des flux de sortie.
Cette classe permet de stocker des listes d'entiers accessibles en temps constant.
void set_value(int_t i_liste, int_t i_element, int_t valeur)
affecte la "valeur" au j-ieme element de la i-ieme liste avec 0 <= i < get_nb_lists() et 0 <= j < get...
int_t get_list_size(int_t i_liste) const
renvoie le nombre d'elements de la liste i
void set_list_sizes(const ArrOfInt_t &sizes)
detruit les listes existantes et en cree de nouvelles.
int_t get_nb_lists() const
renvoie le nombre de listes stockees
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
int dimension_int(int d) const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
_SIZE_ size_reelle() const