16#include <Static_Int_Lists.h>
17#include <Connectivite_som_elem.h>
18#include <Poly_geom_base.h>
19#include <Matrix_tools.h>
20#include <Matrice_Morse.h>
21#include <Array_tools.h>
22#include <communications.h>
23#include <Domain_Graph.h>
24#include <Partitionneur_base.h>
30template <
typename _SIZE_>
31void construire_connectivite_real_som_virtual_elem(
const _SIZE_ nb_sommets,
32 const IntTab_T<_SIZE_>& les_elems,
34 const IntTab_T<_SIZE_>& elem_virt_pe_num,
35 const SmallArrOfTID_T<_SIZE_>& offsets)
38 using ArrOfInt_t = ArrOfInt_T<_SIZE_>;
42 const int_t local_nb_elem = les_elems.
dimension(0);
44 const int nb_sommets_par_element = les_elems.
dimension_int(1);
48 ArrOfInt_t nb_elements_voisins(nb_sommets);
54 for (int_t elem = 0; elem < nb_elem; elem++)
56 for (
int i = 0; i < nb_sommets_par_element; i++)
58 int_t sommet = les_elems(elem, i);
59 if(sommet >= nb_sommets)
continue;
61 if (sommet==-1)
break;
62 nb_elements_voisins[sommet]++;
70 nb_elements_voisins = 0;
73 for (int_t elem = 0; elem < nb_elem; elem++)
75 for (
int i = 0; i < nb_sommets_par_element; i++)
77 int_t sommet = les_elems(elem, i);
78 if(sommet >= nb_sommets)
continue;
80 if (sommet==-1)
break;
81 int_t n = (nb_elements_voisins[sommet])++;
83 int_t elem_num_global = -1;
84 if(elem>= local_nb_elem)
86 int proc_of_elem =
static_cast<int>(elem_virt_pe_num(elem-local_nb_elem, 0));
87 int_t elem_number_on_local_proc = elem_virt_pe_num(elem-local_nb_elem, 1);
88 elem_num_global = elem_number_on_local_proc + offsets[proc_of_elem];
93 som_elem.
set_value(sommet, n, elem_num_global);
102template <
typename _SIZE_>
106 using int_t = _SIZE_;
107 using IntTab_t = IntTab_T<_SIZE_>;
109 const IntTab_t& liaisons = dom.
les_elems();
114 int_t nb_elem=liaisons.local_max_vect()+1;
116 assert(nb_elem < std::numeric_limits<_SIZE_>::max());
119 xadj.resize_array(nb_elem+1);
120 vwgts.resize_array(0);
124 ewgts.resize_array(0);
130 ewgts.resize_array(nb_edges);
134 IntTab_t stencil(0,2);
137 int_t nbl=liaisons.dimension(0);
138 for (
int i=0; i<nbl; i++)
140 stencil.resize(size+2,2);
141 int_t n1=liaisons(i,0);
142 int_t n2=liaisons(i,1);
154 tableau_trier_retirer_doublons(stencil);
158 tab1.resize(nb_elem+1);
160 tab1[nb_elem]=size+1;
165 nb_edges=tab2.size_array();
167 adjncy.resize_array(nb_edges);
169 assert(tab1.size_array()==
nvtxs+1);
171 for (int_t c=0; c<static_cast<_SIZE_>(
nvtxs+1); c++)
173 for (int_t c=0; c<static_cast<_SIZE_>(
nedges); c++)
180template<
typename _SIZE_>
185 using int_t = _SIZE_;
186 using IntTab_t = IntTab_T<_SIZE_>;
187 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
193 IntTab faces_element_reference;
197 ref_cast(Poly_geom_base_t, type_elem).get_tab_faces_sommets_locaux(faces_element_reference,0);
198 int nb_faces_par_element = faces_element_reference.
dimension(0);
199 const int nb_sommets_par_face = faces_element_reference.
dimension(1);
201 const IntTab_t& elem_som = dom.
les_elems();
202 const int_t nb_elem = dom.
nb_elem();
206 if (totsum > std::numeric_limits<_SIZE_>::max())
208 Cerr <<
"Are you trying to partition a Domain_64 with a non-64b 'Partitionneur'? Total number of elements is too big!" << finl;
211 offsets =
static_cast<_SIZE_
>(totsum);
212 envoyer_all_to_all(offsets, offsets);
215 Cerr <<
" Construction of the som_elem connectivity" << finl;
222 IntTab_t elem_virt_pe_num;
224 construire_connectivite_real_som_virtual_elem(dom.
nb_som(), elem_som, som_elem, elem_virt_pe_num, offsets);
227 construire_connectivite_som_elem(dom.
nb_som(), elem_som, som_elem,
231 int_t nb_connexions_perio = 0;
232 if (liste_bords_periodiques.size() > 0)
234 Cerr <<
" Construction of graph connectivity for periodic boundaries" << finl;
238 graph_elements_perio);
251 int_t nnn = nb_elem * nb_faces_par_element - nb_faces_bord + nb_connexions_perio;
252 if (sub_type(Poly_geom_base_t, dom.type_elem().valeur()))
254 const Poly_geom_base_t& poly=ref_cast(Poly_geom_base_t,dom.type_elem().valeur());
255 nnn= poly.get_somme_nb_faces_elem() - nb_faces_bord + nb_connexions_perio;
258 const int_t nb_edges = nnn + nb_faces_bord;
261 xadj.resize_array(nb_elem+1);
263 adjncy.resize_array(nb_edges+nb_faces_bord);
265 edgegsttab.resize_array(nb_edges+nb_faces_bord);
268 vwgts.resize_array(0);
272 ewgts.resize_array(0);
277 ewgts.resize_array(nb_edges + nb_faces_bord);
283 if(std::is_same<idx_t, int>::value)
289 Cerr <<
" Construction of the elem_elem connectivity" << finl;
297 SmallArrOfTID_t une_face(nb_sommets_par_face);
298 SmallArrOfTID_t voisins;
301 int_t edge_count = 0;
302 for (int_t i_elem = 0; i_elem < nb_elem; i_elem++)
304 xadj[i_elem] = edge_count;
308 ref_cast(Poly_geom_base_t,type_elem).get_tab_faces_sommets_locaux(faces_element_reference,i_elem);
309 int nb_faces_elem = faces_element_reference.
dimension(0);
310 while ( faces_element_reference(nb_faces_elem-1,0)==-1)
312 nb_faces_par_element= nb_faces_elem;
314 for (
int i_face = 0; i_face < nb_faces_par_element; i_face++)
319 for (
int i = 0; i < nb_sommets_par_face; i++)
321 const int i_som = faces_element_reference(i_face, i);
326 const int_t sommet = elem_som(i_elem, i_som);
327 une_face[i] = sommet;
333 find_adjacent_elements(som_elem, une_face, voisins);
335 const int nb_voisins = voisins.size_array();
336 int_t elem_voisin = -1;
348 const int_t elem = voisins[0];
349 if (elem != i_elem + my_offset)
358 const int_t elem0 = voisins[0];
359 const int_t elem1 = voisins[1];
360 if (elem0 == i_elem + my_offset)
362 else if (elem1 == i_elem + my_offset)
378 if (elem_voisin >= 0)
380 if (edge_count >= nb_edges)
385 adjncy[edge_count] = elem_voisin;
391 if( my_offset <= elem_voisin && elem_voisin < nb_elem+my_offset)
392 ewgts[edge_count] = 4;
394 ewgts[edge_count] = 1;
401 if (nb_connexions_perio > 0)
404 for (int_t i = 0; i < n; i++)
406 const int_t elem_voisin = graph_elements_perio(i_elem, i);
407 if (edge_count >= nb_edges)
412 adjncy[edge_count] = elem_voisin;
418 ewgts[edge_count] = 4;
422 else if (use_weights)
426 Cerr <<
"Warning: You specify use_weights option with Metis but you didn't use Periodique keyword" << finl;
427 Cerr <<
"to define the boundary where periodicity apply." << finl;
428 Cerr <<
"Either suppress use_weight or add Periodique keyword." << finl;
435 xadj[nb_elem] = edge_count;
438 std::map<int_t,int_t> global_to_local_index;
440 for(int_t e=0; e<nb_edges + nb_faces_bord; e++)
442 int_t vertex =
static_cast<_SIZE_
>(
adjncy[e]);
443 if( my_offset <= vertex && vertex < nb_elem+my_offset)
447 if(global_to_local_index.find(vertex) != global_to_local_index.end())
448 edgegsttab[e] = global_to_local_index[vertex];
451 global_to_local_index[vertex] =cnt++;
452 edgegsttab[e] = global_to_local_index[vertex];
459 Cerr <<
"Error in Domaine_Graph::construire_graph_elem_elem\n"
460 <<
" The number of element-element connections is greater than expected\n"
461 <<
" The number of boundary faces is wrong.\n"
462 <<
" You must discretize the domain to check." << finl;
467 Cerr <<
"Error in Domain_Graph::construire_graph_elem_elem\n"
468 <<
" Problem in the mesh: one internal face has more than two neighboring elements\n"
469 <<
" List of neighboring elements:" << voisins
470 <<
"\n Nodes of the face:" << une_face;
475 Cerr <<
"Internal error in Domain_Graph::construire_graph_elem_elem\n"
476 <<
" (error " << error <<
") Problem in neighborhood algorithms"
void construire_graph_elem_elem(const Domaine_32_64< _SIZE_ > &dom, bool use_weights, Static_Int_Lists_32_64< _SIZE_ > &graph_elements_perio)
void construire_graph_from_segment(const Domaine_32_64< _SIZE_ > &dom, bool use_weights)
classe Domaine_32_64 un Domaine est un maillage compose d'un ensemble d'elements geometriques de meme...
void construire_elem_virt_pe_num()
int_t nb_faces_frontiere() const
Renvoie le nombre de faces frontiere du domaine (somme des nombres de bords, de raccords et de bords ...
int_t nb_faces_joint() const
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
const Noms & bords_perio() const
Classe Elem_geom_base Cette classe est la classe de base pour la definition d'elements.
virtual int get_tab_faces_sommets_locaux(IntTab &faces_som_local) const
remplit le tableau faces_som_local(i,j) qui donne pour 0 <= i < nb_faces() et 0 <= j < nb_som_face(i)...
Un tableau de chaine de caracteres (VECT(Nom)).
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.
Base class for polyedrons and polygons. Connectivity is stored in descending mode:
static int check_int_overflow(trustIdType)
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).
static bool is_parallel()
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static void imprimer_ram_totale(int all_process=0)
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
static bool is_sequential()
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 trier_liste(int_t i)
tri par ordre croissant des valeurs de la i-ieme liste.
void set_list_sizes(const ArrOfInt_t &sizes)
detruit les listes existantes et en cree de nouvelles.
_SIZE_ size_array() const
int dimension_int(int d) const
_SIZE_ dimension_tot(int) const override
_SIZE_ dimension(int d) const