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)
82template <
typename _SIZE_>
84 const IntTab_T<_SIZE_>& faces,
86 ArrOfInt_T<_SIZE_>& elements)
89 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
91 const int_t nb_faces = faces.
dimension(0);
96 SmallArrOfTID_t une_face(nb_som_faces);
97 SmallArrOfTID_t voisins;
98 for (int_t i = 0; i < nb_faces; i++)
100 for (
int j = 0; j < nb_som_faces; j++)
101 une_face[j] = faces(i, j);
102 find_adjacent_elements(som_elem, une_face, voisins);
103 const int nb_voisins = voisins.size_array();
106 Cerr <<
"Error in chercher_elems_voisins_faces : the face " << i
107 <<
"\n of boundary " << nom_faces <<
" has " << nb_voisins
108 <<
" neighboring elements with the indices : " << voisins << finl;
111 elements[i] = voisins[0];
126template <
typename _SIZE_>
132 const Noms& liste_bords_periodiques = domaine.bords_perio();
133 const int_t nb_elem = domaine.nb_elem();
143 const int nb_bords = domaine.nb_bords();
144 for (
int i_bord = 0; i_bord < nb_bords; i_bord++)
146 const Bord_t& bord = domaine.bord(i_bord);
149 Cerr <<
" Checking of the boundary " << bord.
le_nom();
156 for (
int i = 0; i < d; i++) Cerr << delta[i] <<
" ";
158 for (
int i = 0; i < d; i++) Cerr << erreur[i] <<
" ";
162 Cerr <<
"You need to use the Declarer_bord_perio keyword on the periodic boundaries." << finl;
163 Cerr <<
"See the reference manual to use this keyword on your data file." << finl;
176 for (
int_t i = 0; i < nb_faces; i++)
179 int_t elem0 = elems_voisins[i];
180 int_t elem1 = elems_voisins[i+nb_faces];
182 ++nb_faces_perio[elem0 - my_offset*(elem0 >= my_offset)];
183 ++nb_faces_perio[elem1 - my_offset*(elem1 >= my_offset)];
186 Cerr <<
"Error in calculer_correspondance_faces_perio: the faces " << i
187 <<
" and " << i + nb_faces
188 <<
"\n of the boundary " << bord.
le_nom()
189 <<
" are neighbors of the same element " << elem0 << finl;
192 correspondances.
resize(n+1, 2);
193 correspondances(n, 0) = elem0;
194 correspondances(n, 1) = elem1;
205 for (
int_t i = 0; i < n; i++)
207 const int_t elem0 = correspondances(i, 0),
208 elem1 = correspondances(i, 1);
210 const int_t j0 = nb_faces_perio[elem0 - my_offset*(elem0 >= my_offset)]++;
211 graph.
set_value(elem0 - my_offset*(elem0 >= my_offset), j0, elem1);
212 const int_t j1 = nb_faces_perio[elem1 - my_offset*(elem1 >= my_offset)]++;
213 graph.
set_value(elem1 - my_offset*(elem1 >= my_offset), j1, elem0);
215 Cerr <<
" There is " << n*2 <<
" periodic connections." << finl;
234template <
typename _SIZE_>
243 const int_t nb_som_tot = domaine.nb_som_tot();
244 const int_t nb_elem = domaine.nb_elem();
245 const int_t nb_elem_tot = domaine.nb_elem_tot();
246 const Noms& liste_bords_perio = domaine.bords_perio();
250 ArrOfBit_t sommet_bord(nb_som_tot);
251 ArrOfBit_t sommet_bord_perio(nb_som_tot);
253 sommet_bord_perio = 0;
255 ArrOfBit_t element_bord(nb_elem_tot);
257 ArrOfBit_t element_bord_perio(nb_elem_tot);
259 element_bord_perio = 0;
261 const int nb_bords = domaine.nb_bords();
262 for (
int i_bord = 0; i_bord < nb_bords; i_bord++)
264 const Bord_t& bord = domaine.bord(i_bord);
271 chercher_elems_voisins_faces(som_elem, faces_sommets, bord.
le_nom(), elems_voisins);
276 for (
int_t i_face = 0; i_face < nb_faces_bord; i_face++)
278 const int_t elem_voisin = elems_voisins[i_face];
279 element_bord.setbit(elem_voisin);
281 element_bord_perio.setbit(elem_voisin);
282 for (
int i_som = 0; i_som < nb_som_face; i_som++)
284 const int_t som = faces_sommets(i_face, i_som);
285 sommet_bord.setbit(som);
287 sommet_bord_perio.setbit(som);
306 const IntTab_t& elements = domaine.les_elems();
308 for (
int_t elem = 0; elem < nb_elem; elem++)
311 bool has_som_perio =
false;
313 for (isom = 0; isom < nb_som_elem; isom++)
314 if (sommet_bord_perio[elements(elem, isom)])
315 has_som_perio =
true;
318 int nb_sommets_bord = 0;
319 for (isom = 0; isom < nb_som_elem; isom++)
321 const int_t som = elements(elem, isom);
324 if (has_som_perio && !sommet_bord_perio[som])
326 if (!sommet_bord[som])
333 const int_t renum_som = renum_som_perio[som];
335 for (
int_t i = 0; i < n; i++)
337 const int_t elem2 = som_elem(renum_som, i);
340 test = element_bord_perio[elem2];
342 test = element_bord[elem2];
345 const int p = elem_part[elem2];
349 array_trier_retirer_doublons(tmp);
353 array_calculer_intersection(parties_autorisees, tmp);
355 parties_autorisees = tmp;
357 if (nb_sommets_bord > 0)
363 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_sommets_bord : Error. No part authorized because of the periodicity for the mesh element " << elem << finl;
364 elem_part[elem] = -1;
369 const int p = elem_part[elem];
370 for (i = 0; i < n; i++)
371 if (parties_autorisees[i] == p)
376 elem_part[elem] = parties_autorisees[0];
382 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_sommets_bord : " << count <<
" modified elements" << finl;
393template <
typename _SIZE_>
400 const int_t nb_som = domaine.nb_som();
401 const int_t nb_elem = domaine.nb_elem();
402 const Noms& liste_bords_perio = domaine.bords_perio();
414 int deux_puissance_i_bord = 1;
415 for (
auto& itr : liste_bords_perio)
417 const Bord_t& bord = domaine.bord(itr);
422 chercher_elems_voisins_faces<_SIZE_>(som_elem, faces_sommets, bord.
le_nom(), elems_voisins);
423 for (
int_t i_face = 0; i_face < nb_faces_bord; i_face++)
425 const int_t elem_voisin = elems_voisins[i_face];
426 const int part = elem_part[elem_voisin];
427 for (
int i_som = 0; i_som < nb_som_face; i_som++)
429 const int_t som = faces_sommets(i_face, i_som);
430 const int old_part = partie_associee[som];
431 if (old_part < 0 || old_part > part)
432 partie_associee[som] = part;
433 marqueur_bord[som] |= deux_puissance_i_bord;
436 deux_puissance_i_bord *= 2;
437 if (deux_puissance_i_bord > 65536)
440 Cerr <<
"Error in Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : there is too many periodic boundaries." << finl;
448 for (
int_t sommet = 0; sommet < nb_som; sommet++)
451 const int marq = marqueur_bord[sommet];
453 for (
int x = 1; x < marq; x = x * 2)
459 marqueur_bord[sommet] = (n > 1);
463 const IntTab_t& les_elems = domaine.les_elems();
466 for (
int_t elem = 0; elem < nb_elem; elem++)
471 for (
int isom = 0; isom < nb_som_elem; isom++)
473 const int_t sommet = les_elems(elem, isom);
474 if (marqueur_bord[sommet])
477 const int_t renum = renum_som_perio[sommet];
478 const int part = partie_associee[renum];
479 assert(marqueur_bord[renum]);
481 if (new_part < 0 || new_part > part)
485 if (new_part >= 0 && new_part != elem_part[elem])
488 elem_part[elem] = new_part;
491 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : " << count <<
" modified elements" << finl;
495 SmallArrOfTID_T<_SIZE_> node(2);
496 int_t another_count=0;
498 for (
int_t som=0; som<nb_som; som++)
502 node[1]=renum_som_perio[som];
503 if (node[0]!=node[1])
507 for (
int i=0; i<2; i++)
511 int_t elem = som_elem(node[i],i_elem);
512 part[i].add_if_not(elem_part[elem]);
516 if (part[0].size()!=part[1].size())
518 Cerr <<
"Warning: Not the same number of parts around the periodic nodes " << node[0] <<
" and " << node[1] <<
" !" << finl;
519 Cerr <<
"We try to fix:" << finl;
520 int smaller = ( part[0].
size() < part[1].size() ? 0 : 1);
521 int bigger = 1 - smaller;
522 int first_part = part[smaller][0];
523 for (
int i=0; i<part[bigger].
size(); i++)
525 int i_part = part[bigger][i];
526 if (!part[smaller].contient(i_part))
531 int_t elem = som_elem(node[bigger],i_elem);
532 if (elem_part[elem] == i_part)
534 elem_part[elem] = first_part;
536 Cerr <<
"Element " << elem <<
" moved from part " << i_part <<
" to " << first_part << finl;
545 for (
int i=0; i<part[0].
size(); i++)
547 int i_part = part[0][i];
548 if (!part[1].contient(i_part))
551 Cerr <<
"Warning: different parts around the periodic nodes " << node[0] <<
" and " << node[1] <<
" !" << finl;
555 Cerr <<
"We try to fix:" << finl;
557 for (
int j=0; j<part[1].
size(); j++)
559 int j_part = part[1][j];
560 if (!part[0].contient(j_part))
566 int_t elem = som_elem(node[1],i_elem);
567 if (elem_part[elem] == j_part)
569 elem_part[elem] = i_part;
570 Cerr <<
"Element " << elem <<
" moved from part " << j_part <<
" to " << i_part << finl;
583 Cerr <<
"Error in Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique" << finl;
584 Cerr <<
"It will create possible problems for creation of renum_som_perio array." << finl;
585 Cerr <<
"Contact TRUST support or change the partition options." << finl;
588 count+=another_count;
589 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_multiperiodique : plus " << another_count <<
" another modified elements" << finl;
602template <
typename _SIZE_>
613 const Noms& liste_bords_periodiques = domaine.bords_perio();
617 for (
int_t i = 0; i < n; i++)
620 const int part = elem_part[i];
621 for (
int_t j = 0; j < m; j++)
623 const int_t elem2 = graph_elements_perio(i,j);
624 if (elem_part[elem2] != part)
626 elem_part[elem2] = part;
631 Cerr <<
"Partitionneur_base_32_64<_SIZE_>::corriger_bords_avec_graphe : " << count
632 <<
" modified periodic elements" << finl;
634 const int_t nb_sommets_reels = domaine.nb_som();
637 for (
int_t i = 0; i < nb_sommets_reels; i++)
638 renum_som_perio[i] = i;
643 if (liste_bords_periodiques.size() > 1)
655template <
typename _SIZE_>
657 const int_t my_offset,
660 Cerr <<
"Correction of the splitting for the periodicity" << finl;
662 Cerr <<
" Construction of the connectivity som_elem" << finl;
663 construire_connectivite_som_elem(dom.
nb_som_tot(),
667 Cerr <<
" Construction of graph connectivity for periodic elements" << finl;
672 graph_elements_perio);
677 Cerr <<
"corriger_bords_avec_liste : we have corrected " << count <<
" elements all in all." << finl;
int_t nb_som_tot() const
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
const IntTab_t & les_sommets() const
Returns the array of vertices of all faces.
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
int_t nb_faces() const
Returns the number of faces of the boundary.
const Faces_t & faces() const
class Nom: a character string for naming TRUST objects.
An array of character strings (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
Writes the object to an output stream. Virtual method to override.
Helper class to factorize the readOn method of Objet_U classes.
Base class for domain partitioners (for splitting a mesh before a parallel computation).
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)
Corrects elem_part so that element i is on the same partition elem_part[i] as all elements connected ...
static void corriger_bords_avec_liste(const Domaine_t &dom, const int_t my_offset, BigIntVect_ &elem_part)
Computes the periodic element connectivity graphs and calls corriger_periodique_avec_graphe.
static void corriger_elem0_sur_proc0(BigIntVect_ &elem_part)
Corrects the partition so that element 0 of the initial domain is on the first sub-domain of the part...
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)
Modifies elem_part to ensure the following properties: 1) Elements that have a boundary vertex are as...
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)
Applies corrections to elem_part so that multi-periodicity is 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)
Computes a connectivity graph between elements connected by periodic faces.
static bool is_parallel()
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
static int check_faces_periodiques(const Frontiere_32_64< _SIZE_ > &frontiere, ArrOfDouble &vecteur_delta, ArrOfDouble &erreur, bool verbose=false)
Tries to verify whether the faces on boundary num_bord are ordered according to the periodic face con...
static void renum_som_perio(const Domaine_32_64< _SIZE_ > &dom, ArrOfInt_T< _SIZE_ > &renum_som_perio, bool calculer_espace_virtuel)
Base class for output streams.
This class allows storing lists of integers accessible in constant time.
void set_value(int_t i_liste, int_t i_element, int_t valeur)
Assigns "valeur" to the j-th element of the i-th list with 0 <= i < get_nb_lists() and 0 <= j < get_l...
int_t get_list_size(int_t i_liste) const
Returns the number of elements in list i.
void set_list_sizes(const ArrOfInt_t &sizes)
Destroys existing lists and creates new ones.
int_t get_nb_lists() const
Returns the number of stored lists.
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