16#include <DomaineCutter.h>
19#include <Connectivite_som_elem.h>
20#include <SFichierBin.h>
21#include <Array_tools.h>
23#include <TRUSTArrays.h>
24#include <Sous_Domaine.h>
26#include <Poly_geom_base.h>
27#include <Sortie_Brute.h>
29#include <FichierHDFPar.h>
30#include <communications.h>
34template<
typename _SIZE_>
37 Process::exit(
"Error : DomaineCutter_32_64<_SIZE_>::printOn should not be used.");
41template<
typename _SIZE_>
44 Process::exit(
"Error : DomaineCutter_32_64<_SIZE_>::readOn should not be used.");
64template<
typename _SIZE_>
65void construire_liste_sommets_sousdomaine(
const _SIZE_ nb_sommets,
66 const IntTab_T<_SIZE_>& les_elems,
67 const ArrOfInt_T<_SIZE_>& liste_elements,
70 SmallArrOfTID_T<_SIZE_>& liste_sommets,
71 BigArrOfInt_T<_SIZE_>& liste_inverse_sommets)
76 const int_t nb_sommets_par_element = les_elems.
dimension(1);
89 int nb_sommets_part = 0;
90 for (
int i_elem = 0; i_elem < nb_elem_part; i_elem++)
92 const int_t elem = liste_elements[i_elem];
93 for (
int j = 0; j < nb_sommets_par_element; j++)
95 int_t sommet = les_elems(elem, j);
98 int bit = drapeau_sommet.testsetbit(sommet);
109 if ((*som_raccord)(s, i) == i_part && !drapeau_sommet.testsetbit(s))
117 liste_inverse_sommets.
resize_array(nb_sommets,RESIZE_OPTIONS::NOCOPY_NOINIT);
118 liste_inverse_sommets = -1;
121 for (int_t i = 0; i < nb_sommets; i++)
123 if (drapeau_sommet[i])
125 liste_sommets[n] = i;
126 liste_inverse_sommets[i] = n;
145template<
typename _SIZE_>
146void remplir_coordsommets_sous_domaine(
const DoubleTab_T<_SIZE_>& sommets_glob,
147 const SmallArrOfTID_T<_SIZE_>& liste_sommets,
148 DoubleTab& sommets_loc)
150 using int_t = _SIZE_;
151 const int nb_som = liste_sommets.
size_array();
153 sommets_loc.
resize(nb_som, dim);
155 for (
int i = 0; i < nb_som; i++)
157 int_t indice = liste_sommets[i];
158 for (
int j = 0; j < dim; j++)
159 sommets_loc(i, j) = sommets_glob(indice, j);
170template<
typename _SIZE_>
171void construire_elems_sous_domaine(
const IntTab_T<_SIZE_>& elems_domaine_globale,
172 const ArrOfInt_T<_SIZE_>& liste_elements,
173 const BigArrOfInt_T<_SIZE_>& liste_inverse_sommets,
174 IntTab& elems_domaine_locale,
175 BigArrOfInt_T<_SIZE_>& liste_inverse_elements)
177 using int_t = _SIZE_;
179 const int_t nb_elem_tot = elems_domaine_globale.
dimension_tot(0);
180 const int nb_sommets_par_element = elems_domaine_globale.
dimension_int(1);
182 liste_inverse_elements.
resize(nb_elem_tot,RESIZE_OPTIONS::NOCOPY_NOINIT);
183 liste_inverse_elements = -1;
187 elems_domaine_locale.
resize(nb_elem_part, nb_sommets_par_element);
190 for (
int i_elem = 0; i_elem < nb_elem_part; i_elem++)
192 int_t elem = liste_elements[i_elem];
195 liste_inverse_elements[elem] = i_elem;
198 for (
int i = 0; i < nb_sommets_par_element; i++)
200 int_t sommet = elems_domaine_globale(elem, i);
203 assert(sommet == -1);
204 elems_domaine_locale(i_elem, i) = -1;
208 int new_num = liste_inverse_sommets[sommet];
209 assert(new_num >= 0);
210 elems_domaine_locale(i_elem, i) = new_num;
229template<
typename _SIZE_>
230void construire_liste_faces_sous_domaine(
const ArrOfInt_T<_SIZE_>& elements_voisins,
231 const BigIntVect_T<_SIZE_>& elem_part,
233 const IntTab_T<_SIZE_>& faces_sommets,
234 const BigArrOfInt_T<_SIZE_>& liste_inverse_sommets,
235 IntTab& faces_sommets_partie)
237 using int_t = _SIZE_;
239 const int_t nb_faces = faces_sommets.
dimension(0);
240 const int nb_sommets_par_face = faces_sommets.
dimension_int(1);
242 assert(elements_voisins.
size_array() == nb_faces);
244 ArrOfInt_T<_SIZE_> liste_faces;
248 for (int_t i = 0; i < nb_faces; i++)
250 int_t elem = elements_voisins[i];
251 const int part = elem_part[elem];
258 faces_sommets_partie.
resize(nb_faces_part, nb_sommets_par_face);
262 for (
int i = 0; i < nb_faces_part; i++)
264 const int_t i_face = liste_faces[i];
265 for (
int j = 0; j < nb_sommets_par_face; j++)
267 int_t sommet = faces_sommets(i_face, j);
270 int new_num = liste_inverse_sommets[sommet];
271 assert(new_num >= 0);
272 faces_sommets_partie(i, j) = new_num;
275 faces_sommets_partie(i, j) = -1;
285template <
typename _SIZE_>
286void DomaineCutter_32_64<_SIZE_>::ajouter_joints(Domaine32& domaine,
const ArrOfInt& voisins)
const
288 Joints& joints = domaine.faces_joint();
291 for (
int i = 0; i < n; i++)
293 const int pe = voisins[i];
295 const int nb_joints = joints.size();
296 for (; j < nb_joints; j++)
297 if (joints[j].PEvoisin() == pe)
301 Cerr <<
" Adding of a new joint : " << pe << finl;
302 Joint& joint = joints.add(Joint());
322template <
typename _SIZE_>
323void DomaineCutter_32_64<_SIZE_>::parcourir_epaisseurs_elements(SmallArrOfTID_t liste_sommets_depart,
324 const int partie_a_ignorer,
325 SmallArrOfTID_t& liste_elements_trouves)
const
327 const Domaine_t& domaine = ref_domaine_.valeur();
328 const IntTab_t& elements = domaine.les_elems();
329 const BigIntVect_t& elem_part = ref_elem_part_.valeur();
330 const int_t nb_sommets = som_elem_.get_nb_lists();
332 const int nb_som_elem = elements.dimension_int(1);
334 liste_elements_trouves.resize_array(0);
338 SmallArrOfTID_t new_liste;
340 sommets_parcourus = 0;
341 elements_parcourus = 0;
345 const int sz_liste = liste_sommets_depart.size_array();
346 for (
int i = 0; i < sz_liste; i++)
348 const int_t sommet = liste_sommets_depart[i];
350 if (!sommets_parcourus.testsetbit(sommet))
351 new_liste.append_array(sommet);
356 for (
int ep = 1; ep <= epaisseur_joint_; ep++)
358 liste_sommets_depart = new_liste;
359 new_liste.resize_array(0);
360 const int sz_liste = liste_sommets_depart.size_array();
361 for (
int i_sommet = 0; i_sommet < sz_liste; i_sommet++)
363 const int_t sommet = liste_sommets_depart[i_sommet];
366 for (
int i_elem = 0; i_elem < nb_elems_voisins; i_elem++)
368 const int_t elem = som_elem_(sommet, i_elem);
369 if (elements_parcourus[elem])
372 const int part = elem_part[elem];
373 if (part == partie_a_ignorer)
376 liste_elements_trouves.append_array(elem);
377 elements_parcourus.setbit(elem);
380 for (
int i = 0; i < nb_som_elem; i++)
382 const int_t sommet2 = elements(elem, i);
385 if (sommets_parcourus.testsetbit(sommet2) == 0)
386 new_liste.append_array(sommet2);
398template<
typename _SIZE_>
399void DomaineCutter_32_64<_SIZE_>::construire_faces_bords_ssdom(
const BigArrOfInt_T<_SIZE_>& liste_inverse_sommets,
401 Domaine32& domaine_partie)
const
403 const Domaine_t& domaine = ref_domaine_.valeur();
405 ArrOfInt_t elements_voisins;
406 for(
const auto& itr: domaine.faces_bord())
408 const Frontiere_t& frontiere = itr;
409 Frontiere& front_partie = domaine_partie.faces_bord().add(Bord());
410 front_partie.
nommer(frontiere.le_nom());
412 front_partie.
faces().
typer(frontiere.faces().type_face());
413 voisins_bords_.copy_list_to_array(i_fr, elements_voisins);
414 construire_liste_faces_sous_domaine(elements_voisins,
415 ref_elem_part_.valeur(),
417 frontiere.faces().les_sommets(),
418 liste_inverse_sommets,
428template<
typename _SIZE_>
429void DomaineCutter_32_64<_SIZE_>::construire_faces_raccords_ssdom(
const BigArrOfInt_t& liste_inverse_sommets,
431 Domaine32& domaine_partie)
const
433 const Domaine_t& domaine = ref_domaine_.valeur();
434 int i_fr = domaine.nb_bords();
435 ArrOfInt_t elements_voisins;
436 for(
const auto& itr: domaine.faces_raccord())
438 const Frontiere_t& frontiere = itr;
439 Raccord& raccord_partie = domaine_partie.faces_raccord().add(Raccord());
442 type_raccord.
prefix(
"_64");
443 if (type_raccord ==
"Raccord_local_homogene")
444 type_raccord =
"Raccord_distant_homogene";
445 raccord_partie.typer(type_raccord);
446 Frontiere& front_partie = raccord_partie.valeur();
447 front_partie.
nommer(frontiere.le_nom());
449 front_partie.
faces().
typer(frontiere.faces().type_face());
450 voisins_bords_.copy_list_to_array(i_fr, elements_voisins);
451 construire_liste_faces_sous_domaine(elements_voisins,
452 ref_elem_part_.valeur(),
454 frontiere.faces().les_sommets(),
455 liste_inverse_sommets,
461template<
typename _SIZE_>
462void DomaineCutter_32_64<_SIZE_>::construire_frontieres_internes_ssdom(
const BigArrOfInt_t& liste_inverse_sommets,
464 Domaine32& domaine_partie)
const
468 const Domaine_t& domaine = ref_domaine_.valeur();
469 int i_fr = domaine.nb_bords()+domaine.nb_raccords();
470 ArrOfInt_t elements_voisins;
471 for(
const auto& itr: domaine.bords_int())
473 const Frontiere_t& frontiere = itr;
474 Frontiere& front_partie = domaine_partie.bords_int().
add(Bord_Interne());
475 front_partie.
nommer(frontiere.le_nom());
477 front_partie.
faces().
typer(frontiere.faces().type_face());
478 voisins_bords_.copy_list_to_array(i_fr, elements_voisins);
479 construire_liste_faces_sous_domaine(elements_voisins,
480 ref_elem_part_.valeur(),
482 frontiere.faces().les_sommets(),
483 liste_inverse_sommets,
489template<
typename _SIZE_>
490void DomaineCutter_32_64<_SIZE_>::construire_groupe_faces_ssdom(
const BigArrOfInt_t& liste_inverse_sommets,
492 Domaine32& domaine_partie)
const
496 const Domaine_t& domaine = ref_domaine_.valeur();
497 Static_Int_Lists_t voisins;
498 const int nb_groupe_faces = domaine.nb_groupes_faces();
499 ArrOfInt_T<_SIZE_> nb_faces(nb_groupe_faces);
500 for (
int i = 0; i < nb_groupe_faces; i++)
501 nb_faces[i] = domaine.groupe_faces(i).nb_faces();
502 voisins.set_list_sizes(nb_faces);
503 const int nb_som_face = domaine.frontiere(0).faces().nb_som_faces();
504 SmallArrOfTID_t une_face(nb_som_face), elements_voisins;
506 const BigIntVect_t& elem_part = ref_elem_part_.valeur();
508 for (
int grp = 0; grp < nb_groupe_faces; grp++)
510 const Groupe_Faces_t& groupe_faces = domaine.groupe_faces(grp);
511 Groupe_Faces& groupe_partie = domaine_partie.groupes_faces().add(Groupe_Faces());
512 groupe_partie.
nommer(groupe_faces.le_nom());
514 groupe_partie.
faces().
typer(groupe_faces.faces().type_face());
515 const IntTab_t& faces_sommets = groupe_faces.faces().les_sommets();
518 ArrOfInt_t liste_faces;
520 const IntTab_t& faces = groupe_faces.les_sommets_des_faces();
521 const int_t n = nb_faces[grp];
522 for (int_t j = 0; j < n; j++)
524 for (
int k = 0; k < nb_som_face; k++)
525 une_face[k] = faces(j, k);
526 find_adjacent_elements(som_elem_, une_face, elements_voisins);
528 if (elements_voisins.size_array() == 1 && elem_part[elements_voisins[0]] == partie) liste_faces.append_array(j);
530 if (elements_voisins.size_array() == 2)
531 if (elem_part[elements_voisins[0]] == partie || elem_part[elements_voisins[1]] == partie)
532 liste_faces.append_array(j);
536 faces_sommets_partie.
resize(nb_faces_part, nb_som_face);
540 for (
int i = 0; i < nb_faces_part; i++)
542 const int_t i_face = liste_faces[i];
543 for (
int j = 0; j < nb_som_face; j++)
545 int_t sommet = faces_sommets(i_face, j);
548 int new_num = liste_inverse_sommets[sommet];
549 assert(new_num >= 0);
550 faces_sommets_partie(i, j) = new_num;
553 faces_sommets_partie(i, j) = -1;
572template<
typename _SIZE_>
573void DomaineCutter_32_64<_SIZE_>::construire_elements_distants_ssdom(
const int partie,
574 const SmallArrOfTID_t& liste_sommets,
575 const BigArrOfInt_t& liste_inverse_elements,
576 Domaine32& domaine_partie)
const
578 const Domaine_t& domaine = ref_domaine_.valeur();
579 const IntTab_t& elements = domaine.les_elems();
580 const BigIntVect_t& elem_part = ref_elem_part_.valeur();
581 const int_t nb_elem = elements.dimension(0);
582 const int_t nb_som_elem = elements.dimension(1);
587 SmallArrOfTID_t elements_virtuels;
590 SmallArrOfTID_t sommets_joint;
592 const int nb_joints = domaine_partie.nb_joints();
593 for (
int i_joint = 0; i_joint < nb_joints; i_joint++)
595 const ArrOfInt& sommets = domaine_partie.joint(i_joint).joint_item(JOINT_ITEM::SOMMET).items_communs();
597 for (
int i = 0; i < n; i++)
599 const int sommet_local = sommets[i];
600 const int_t sommet_global = liste_sommets[sommet_local];
605 parcourir_epaisseurs_elements(sommets_joint,
609 const int nb_elements_virtuels = elements_virtuels.size_array();
611 ArrOfInt parties_voisines;
613 for (
int i = 0; i < nb_elements_virtuels; i++)
615 const int_t elem = elements_virtuels[i];
616 const int part = elem_part[elem];
619 array_trier_retirer_doublons(parties_voisines);
620 ajouter_joints(domaine_partie, parties_voisines);
624 const int nb_parties_voisines = parties_voisines.
size_array();
625 SmallArrOfTID_t sommets_depart;
627 for (
int i_part = 0; i_part < nb_parties_voisines; i_part++)
629 const int partie_voisine = parties_voisines[i_part];
632 for (
int i_elem = 0; i_elem < nb_elements_virtuels; i_elem++)
634 const int_t elem = elements_virtuels[i_elem];
635 if (elem_part(elem) == partie_voisine)
637 for (
int i = 0; i < nb_som_elem; i++)
639 const int_t som = elements(elem, i);
640 sommets_depart.append_array(som);
646 SmallArrOfTID_t elements_distants;
647 parcourir_epaisseurs_elements(sommets_depart,
654 const int n = elements_distants.size_array();
655 for (
int i = 0; i < n; i++)
657 const int_t elem = elements_distants[i];
658 if (elem_part[elem] == partie && elem < nb_elem)
659 elements_distants[count++] = elem;
661 elements_distants.resize_array(count);
664 const int n = elements_distants.size_array();
665 ArrOfInt elem_dist_loc(n);
667 for (
int i = 0; i < n; i++)
669 const int_t elem = elements_distants[i];
670 const int renum = liste_inverse_elements[elem];
671 elem_dist_loc[i] = renum;
675 elements_distants.ordonne_array();
677 Joint& joint = domaine_partie.joint_of_pe(partie_voisine);
694template<
typename _SIZE_>
695void DomaineCutter_32_64<_SIZE_>::construire_sommets_joints_ssdom(
const SmallArrOfTID_t& liste_sommets,
696 const BigArrOfInt_t& liste_inverse_sommets,
698 const Static_Int_Lists_t* som_raccord,
699 Domaine32& domaine_partie)
const
701 Joints& les_joints = domaine_partie.faces_joint();
703 const int parts = nb_parties_;
704 const BigIntVect_t& elem_part = ref_elem_part_.valeur();
709 ArrsOfInt_T<_SIZE_> joints_sommets(parts);
716 const int nb_sommets = liste_sommets.size_array();
719 for (
int i_sommet = 0; i_sommet < nb_sommets; i_sommet++)
722 int_t sommet = liste_sommets[i_sommet];
725 for (
int i = 0; i < nb_elements_voisins; i++)
727 int_t elem = som_elem_(sommet, i);
728 int PEvoisin = elem_part[elem];
730 if (PEvoisin != partie)
731 joints_sommets[PEvoisin].append_array(sommet);
735 for (int_t i = 0; i < som_raccord->get_list_size(sommet); i++)
738 if (part_num != partie)
739 joints_sommets[part_num].append_array(sommet);
744 for (
int PEvoisin = 0; PEvoisin < parts; PEvoisin++)
746 ArrOfInt_t& sommets = joints_sommets[PEvoisin];
747 if (sommets.size_array() > 0)
752 array_trier_retirer_doublons(sommets);
756 Joint& joint = les_joints.add(Joint());
757 Nom nom_joint(
"Joint_");
758 Nom nom_numero(PEvoisin);
759 nom_joint+=nom_numero;
767 for (
int i = 0; i < nb_sommets2; i++)
769 const int_t indice_global = sommets[i];
770 const int indice_local = liste_inverse_sommets[indice_global];
771 assert(indice_local >= 0);
772 sommets_locaux[i] = indice_local;
782template<
typename _SIZE_>
783void DomaineCutter_32_64<_SIZE_>::construire_faces_joints_ssdom(
const int partie,
784 const DomaineCutter_Correspondance_t& correspondance,
785 Domaine32& domaine_partie)
const
787 const int nb_sommets_ssdom = domaine_partie.nb_som();
788 const int nb_elem_ssdom = domaine_partie.nb_elem();
789 const SmallArrOfTID_t& liste_sommets = correspondance.liste_sommets_;
790 const BigArrOfInt_t& liste_inverse_elements = correspondance.liste_inverse_elements_;
794 SmallArrOfTID_t liste_elements_joint;
795 ArrOfBit drapeaux_sommets_joints(nb_sommets_ssdom);
798 const Joints& joints_partie = domaine_partie.faces_joint();
799 drapeaux_sommets_joints = 0;
802 ArrOfBit drapeaux_elements(nb_elem_ssdom);
803 drapeaux_elements = 0;
805 const int nb_joints = joints_partie.size();
806 for (
int i_joint = 0; i_joint < nb_joints; i_joint++)
808 const Joint& joint = joints_partie[i_joint];
811 for (
int i = 0; i < n; i++)
813 const int i_sommet_local = sommets_du_joint[i];
814 const int_t i_sommet_global = liste_sommets[i_sommet_local];
817 drapeaux_sommets_joints.setbit(i_sommet_local);
818 for (
int j = 0; j < nb_elem_voisins; j++)
820 const int_t i_elem_global = som_elem_(i_sommet_global, j);
821 const int i_elem_local = liste_inverse_elements[i_elem_global];
824 if (i_elem_local >= 0)
825 if (! drapeaux_elements.testsetbit(i_elem_local))
826 liste_elements_joint.append_array(i_elem_global);
840 ArrOfInt faces_pe_voisins;
843 ArrOfInt nb_faces_joints(nb_parties_);
846 IntTab faces_element_reference;
847 const Elem_geom_base& type_elem = domaine_partie.type_elem().valeur();
851 ref_cast(Poly_geom_base,type_elem).get_tab_faces_sommets_locaux(faces_element_reference,0);
853 int nb_faces_elem = faces_element_reference.
dimension(0);
854 const int nb_sommets_par_face = faces_element_reference.
dimension(1);
855 faces_joints.
resize(0, nb_sommets_par_face);
856 const BigArrOfInt_t& liste_inverse_sommets = correspondance.liste_inverse_sommets_;
857 const BigIntVect_t& elem_part = ref_elem_part_.valeur();
859 const Domaine_t& domaine = ref_domaine_.valeur();
860 const IntTab_t& elem_som = domaine.les_elems();
861 SmallArrOfTID_t une_face(nb_sommets_par_face);
862 SmallArrOfTID_t elements_voisins;
865 const int nb_elem_joints = liste_elements_joint.size_array();
866 for (
int i_elem_joint = 0; i_elem_joint < nb_elem_joints; i_elem_joint++)
869 const int_t i_elem_global = liste_elements_joint[i_elem_joint];
873 int loc_idx = liste_inverse_elements[i_elem_global];
874 ref_cast(Poly_geom_base,type_elem).get_tab_faces_sommets_locaux(faces_element_reference, loc_idx);
875 nb_faces_elem = faces_element_reference.
dimension(0);
876 while ( faces_element_reference(nb_faces_elem-1,0) == -1)
879 for (
int i_face = 0; i_face < nb_faces_elem; i_face++)
883 for (
int i = 0; i < nb_sommets_par_face; i++)
885 const int i_ref = faces_element_reference(i_face, i);
890 const int_t i_som = elem_som(i_elem_global, i_ref);
896 const int i_som_local = liste_inverse_sommets[i_som];
900 if (drapeaux_sommets_joints[i_som_local] == 0)
911 find_adjacent_elements(som_elem_, une_face, elements_voisins);
913 const int nb_elem_voisins = elements_voisins.size_array();
914 int PEvoisin = -1, i=0;
915 for (; i < nb_elem_voisins; i++)
917 const int_t i_elem_glob = elements_voisins[i];
918 PEvoisin = elem_part[i_elem_glob];
919 if (PEvoisin != partie)
922 if (i < nb_elem_voisins)
927 faces_joints.
resize(n+1, nb_sommets_par_face);
928 for (
int j = 0; j < nb_sommets_par_face; j++)
930 const int_t i_som_global = une_face[j];
933 const int i_som_local = liste_inverse_sommets[i_som_global];
934 faces_joints(n, j) = i_som_local;
937 faces_joints(n, j) = -1;
939 nb_faces_joints[PEvoisin]++;
949 const Domaine_t& domaine_globale = ref_domaine_.valeur();
950 const Type_Face& type_face_joint = domaine_globale.type_elem()->type_face();
952 Joints& joints_partie = domaine_partie.faces_joint();
953 const int nb_joints = joints_partie.size();
954 const int nb_faces_joints_tot = faces_joints.
dimension(0);
956 const int nb_sommets_par_face = faces_joints.
dimension(1);
958 for (
int i_joint = 0; i_joint < nb_joints; i_joint++)
961 Joint& joint = joints_partie[i_joint];
964 const int PE_voisin = joint.
PEvoisin();
965 const int nb_faces = nb_faces_joints[PE_voisin];
970 for (
int i = 0; i < nb_faces_joints_tot; i++)
972 const int face_pe = faces_pe_voisins[i];
973 if (face_pe == PE_voisin)
975 for (
int j = 0; j < nb_sommets_par_face; j++)
976 faces(k, j) = faces_joints(i,j);
986template<
typename _SIZE_>
989 ref_domaine_.reset();
990 ref_elem_part_.reset();
992 epaisseur_joint_ = -1;
999template<
typename _SIZE_>
1000void calculer_listes_elements_sous_domaines(
const BigIntVect_T<_SIZE_>& elem_part,
1002 const _SIZE_ nbelem,
1005 using int_t = _SIZE_;
1007 ArrOfInt_T<_SIZE_> sizes(nb_parts);
1009 for (int_t i = 0; i < nbelem; i++)
1011 const int part = elem_part[i];
1017 for (int_t i = 0; i < nbelem; i++)
1019 const int part = elem_part[i];
1020 const int_t index = sizes[part]++;
1021 liste_elems_sous_domaines.
set_value(part, index, i);
1025template<
typename _SIZE_>
1029 const bool permissif,
Noms& bords_a_pb_)
1031 using int_t = _SIZE_;
1032 using ArrOfInt_t = ArrOfInt_T<_SIZE_>;
1033 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
1035 const int nb_front = domaine.nb_front_Cl();
1036 ArrOfInt_t nb_faces(nb_front);
1037 for (
int i = 0; i < nb_front; i++)
1038 nb_faces[i] = domaine.frontiere(i).nb_faces();
1040 const int nb_som_face = domaine.frontiere(0).faces().nb_som_faces();
1041 SmallArrOfTID_t une_face(nb_som_face);
1042 SmallArrOfTID_t elems_voisins;
1044 for (
int i = 0; i < nb_front; i++)
1047 const IntTab_T<_SIZE_>& faces = domaine.frontiere(i).les_sommets_des_faces();
1048 const int_t n = nb_faces[i];
1049 for (int_t j = 0; j < n; j++)
1051 for (
int k = 0; k < nb_som_face; k++)
1052 une_face[k] = faces(j, k);
1053 find_adjacent_elements(som_elem, une_face, elems_voisins);
1054 const int n_voisins = elems_voisins.size_array();
1060 Cerr <<
"Message from DomaineCutter.cpp : calculer_elements_voisins_bords\n"
1061 <<
" boundary face "<< domaine.frontiere(i).le_nom()<<
" with " << n_voisins <<
" neighbors." << finl;
1063 Cerr <<
"Error in DomaineCutter.cpp : calculer_elements_voisins_bords\n"
1064 <<
" boundary face "<< domaine.frontiere(i).le_nom()<<
" with " << n_voisins <<
" neighbors." << finl;
1065 bords_a_pb_.add( domaine.frontiere(i).le_nom());
1069 if (elem_part[elems_voisins[1]]==1)
1070 elems_voisins[0]=elems_voisins[1];
1074 voisins.
set_value(i, j, elems_voisins[0]);
1086void construire_nom_fichier_sous_domaine(
const Nom& basename,
1087 const int partie,
const int nb_parties_,
1088 const int original_proc,
1093 if (partie > 100000)
1095 Cerr <<
"Error while generating filename: nb_parties_ too large" << finl;
1104 if (nb_parties_ > 10000)
1105 snprintf(s, 30,
"_p%05d.Zones", (
int)nb_parties_);
1107 snprintf(s, 30,
"_p%04d.Zones",(
int) nb_parties_);
1111 if (nb_parties_ > 10000)
1113 if(original_proc < 0)
1114 snprintf(s, 30,
"_%05d.Zones", (
int)partie);
1116 snprintf(s, 30,
"_%05d_%d.Zones", (
int)partie, (
int)original_proc);
1120 if(original_proc < 0)
1121 snprintf(s, 30,
"_%04d.Zones", (
int)partie);
1123 snprintf(s, 30,
"_%04d_%d.Zones", (
int)partie, (
int)original_proc);
1140template<
typename _SIZE_>
1144 const int epaisseur_joint,
1145 const bool permissif)
1147 assert(nb_parts >= 0);
1149 assert(max_array(elem_part) < nb_parts);
1150 if (min_array(elem_part)<0)
1152 Cerr <<
"Error in DomaineCutter_32_64<_SIZE_>::initialiser" << finl;
1153 Cerr <<
"The built partition has a default." << finl;
1154 Cerr <<
"Try to change the partition tool or try changing some partitioning options." << finl;
1155 Cerr <<
"Contact TRUST support if you are still unsuccessful with your tries." << finl;
1160 ref_domaine_ = domaine_global;
1161 ref_elem_part_ = elem_part;
1162 nb_parties_ = nb_parts;
1163 epaisseur_joint_ = epaisseur_joint;
1167 construire_connectivite_som_elem(nb_som, elems, som_elem_,
1170 Cerr <<
"Search of neighboring elements of boundary faces" << finl;
1171 calculer_elements_voisins_bords(domaine_global, som_elem_, voisins_bords_,elem_part,permissif,bords_a_pb_);
1172 Cerr <<
"Construction of lists of elements per subdomain" << finl;
1173 calculer_listes_elements_sous_domaines(elem_part, nb_parts, elems.
dimension(0), liste_elems_sous_domaines_);
1185template<
typename _SIZE_>
1192 assert(nb_parties_ >= 0);
1194 assert(sous_domain.
nb_elem() == 0);
1196 assert(part >= 0 && part < nb_parties_);
1198 correspondance.
partie_ = part;
1200 const Domaine_t& domain = ref_domaine_.valeur();
1203 liste_elems_sous_domaines_.copy_list_to_array(part, elements_sous_partie);
1208 if (sub_type(Poly_geom_base_t, domain.type_elem().valeur()))
1210 const Poly_geom_base_t& dom_as_poly = ref_cast(Poly_geom_base_t,domain.type_elem().valeur());
1211 dom_as_poly.build_reduced(sous_domain.type_elem(), elements_sous_partie);
1218 sous_domain.
typer(el_nam);
1220 sous_domain.type_elem()->associer_domaine(sous_domain);
1225 construire_liste_sommets_sousdomaine(domain.
nb_som_tot(), domain.
les_elems(), elements_sous_partie, part,
1235 construire_faces_bords_ssdom(l_inv_som, part, sous_domain);
1236 construire_faces_raccords_ssdom(l_inv_som, part, sous_domain);
1237 construire_frontieres_internes_ssdom(l_inv_som, part, sous_domain);
1238 construire_groupe_faces_ssdom(l_inv_som, part, sous_domain);
1239 construire_sommets_joints_ssdom(l_som, l_inv_som, part, som_raccord, sous_domain);
1240 construire_faces_joints_ssdom(part, correspondance, sous_domain);
1245 if (compute_items_distants)
1255 for (
int ij = 0; ij < sous_domain.
nb_joints(); ij++)
1257 Joint& joint = sous_domain.
joint(ij);
1265template<
typename _SIZE_>
1266void DomaineCutter_32_64<_SIZE_>::writeData(
const Domaine& sous_domaine,
Sortie& os)
const
1279template<
typename _SIZE_>
1283 assert(nb_parties_ >= 0);
1285 const Domaine_t& domaine = ref_domaine_.valeur();
1286 const int_t nbelem = domaine.nb_elem();
1295 Nom nom_fichier_hdf5(basename);
1296 nom_fichier_hdf5+=
Nom(
".Zones");
1297 nom_fichier_hdf5 = nom_fichier_hdf5.
nom_me(nb_parties_,
"p", 1);
1300 ArrOfInt ia(nb_parties_+1), ja;
1306 ArrOfInt myDomaines(nb_parties_);
1317 ArrOfInt domaines_index(nb_parties_);
1318 domaines_index = -2;
1320 Cerr <<
"Generation of " << nb_parties_ <<
" parts:" << finl;
1321 IntVect EdgeCut(nb_parties_);
1322 ArrsOfInt Neighbours(nb_parties_);
1324 for (
int loop=0; loop<1+reorder; loop++)
1328 Cerr <<
"====================================" << finl;
1330 Cerr <<
"FIRST PASS, analyzing the partition:" << finl;
1332 Cerr <<
"SECOND PASS, after reordering the partition:" << finl;
1333 Cerr <<
"====================================" << finl;
1345 for(
int_t i=0; i < nbelem; i++)
1347 const int part = elem_part[i];
1348 myDomaines[part] = 1;
1354 otherProcDomaines[p] = myDomaines;
1357 otherProcDomaines[p].resize_array(nb_parties_);
1358 otherProcDomaines[p] = 0;
1365 domaines_indices[p].resize_array(nb_parties_);
1366 domaines_indices[p] = -2;
1368 recevoir(otherProcDomaines[p], p, 0, p+2001);
1371 for(
int part=0; part<nb_parties_; part++)
1376 if(otherProcDomaines[proc][part])
1377 domaines_indices[proc][part] = s++;
1383 myDomaines[part] = 1;
1387 domaines_indices[proc][part] = -1;
1394 domaines_index = domaines_indices[p];
1396 envoyer(domaines_indices[p], 0, p, p+2002);
1405 if (format == DomainesFileOutputType::HDF5_SINGLE)
1407 fic_hdf.
create(nom_fichier_hdf5);
1414 for(
int part=0; part<nb_parties_; part++)
1416 if(domaines_index[part] == -1)
1418 std::string dname =
"/zone_" + std::to_string(part);
1419 Nom dataset_name(dname);
1420 dataset_names.add(dataset_name);
1426 if(domaines_indices[proc][part] >=0)
1428 std::string dname =
"/zone_" + std::to_string(part) +
"_" + std::to_string(domaines_indices[proc][part]);
1429 Nom dataset_name(dname);
1430 dataset_names.add(dataset_name);
1439 while(!myDomaines[ipart]) ipart++;
1443 writeData(dom_tmp, os_tmp);
1444 double sz_ = (double)os_tmp.
get_size();
1447 envoyer_broadcast(dataset_names,0);
1448 long sz_l = lround(sz_);
1453 for (
int i_part = 0; i_part < nb_parties_; i_part++)
1455 if(!myDomaines[i_part])
1458 assert(domaines_index[i_part] > -2);
1459 Cerr <<
" Construction of part number " << i_part << finl;
1460 if(domaines_index[i_part] >= 0)
1461 Cerr <<
"This part is shared between multiple processors" << finl;
1467 const Joints& joints = sous_domaine.
faces_joint();
1468 const int nb_joints = joints.size();
1469 Cerr <<
" Number of nodes : " << sous_domaine.
nb_som() << finl;
1470 Cerr <<
" Number of elements : " << sous_domaine.
nb_elem() << finl;
1471 Cerr <<
" Number of joints : " << nb_joints << finl;
1473 int nbfaces_total=0;
1474 int nbelemdist_total=0;
1476 Neighbours[i_part].resize_array(0);
1477 Neighbours[i_part].resize_array(nb_joints);
1478 for (
int i = 0; i < nb_joints; i++)
1480 const Joint& joint = joints[i];
1482 Neighbours[i_part][i] = pe;
1485 const int nbfaces = joint.
nb_faces();
1486 nbfaces_total+=nbfaces;
1488 nbelemdist_total+=nbelemdist;
1489 Cerr<<
" Joint "<<i<<
" PeVoisin "<<pe<<
" NbSommets "<<nbsom<<
" NbFaces "<<nbfaces;
1493 Cerr<<
" Total: NbSommets "<<nbsom_total<<
" NbFaces "<<nbfaces_total;
1495 EdgeCut(i_part)=nbfaces_total;
1499 if (reorder && loop==0)
1501 const Joints& joints = sous_domaine.
faces_joint();
1502 const int nb_joints = joints.size();
1508 ia[i_part+1]=ia[i_part]+1;
1509 for (
int i = 0; i < nb_joints; i++)
1511 const int pe = joints[i].PEvoisin();
1520 if (format == DomainesFileOutputType::BINARY_MULTIPLE)
1522 Nom nom_fichier(basename);
1523 nom_fichier+=
Nom(
".Zones");
1525 construire_nom_fichier_sous_domaine(basename,i_part, nb_parties_, domaines_index[i_part], nom_fichier);
1526 Cerr <<
"Writing part " << i_part <<
" into the "
1527 << (format == DomainesFileOutputType::BINARY_MULTIPLE ?
"binary" :
"ascii")
1528 <<
" file " << nom_fichier << finl;
1537 const int ok = os.ouvrir(nom_fichier);
1539 Process::exit(
"DomaineCutter_32_64<_SIZE_>::ecrire_domaines : Error while opening file!");
1540 writeData(sous_domaine, os);
1542 else if (format == DomainesFileOutputType::HDF5_SINGLE)
1545 writeData(sous_domaine, os_hdf);
1547 std::string dname =
"/zone_" + std::to_string(i_part);
1548 if(domaines_index[i_part] >=0)
1549 dname += std::string(
"_") + std::to_string(domaines_index[i_part]);
1550 Nom datasetname(dname);
1558 Cerr <<
"DomaineCutter_32_64<_SIZE_>::ecrire_domaines : Unsupported output file type!" << finl;
1564 const LIST(OBS_PTR(
Sous_Domaine_t)) & liste_sous_domaines = domaine.ss_domaines();
1565 const int nb_sous_domaines = liste_sous_domaines.size();
1566 if (nb_sous_domaines>0)
1568 Cerr <<
" Writing of files .ssz ..." << finl;
1575 mode = (ios::out | ios::app);
1580 for (
int i_sous_domaine = 0; i_sous_domaine < nb_sous_domaines; i_sous_domaine++)
1583 const Sous_Domaine_t& sous_dom = liste_sous_domaines[i_sous_domaine];
1588 const int_t i_elem_global = sous_dom[i];
1589 const int i_elem_local = liste_inverse_elements[i_elem_global];
1590 if (i_elem_local >= 0)
1595 Cerr <<
" Subarea " << i_sous_domaine
1596 <<
" file_name " << nom_fichier
1597 <<
" nb_elements in this part " << elements.
size_array()
1601 const int ok = os.
ouvrir(nom_fichier, mode);
1604 Cerr <<
"DomaineCutter_32_64<_SIZE_>::ecrire_domaines :\n Error while opening file"
1605 << nom_fichier << finl;
1612 if (reorder && loop==0)
1616 ArrOfInt riord(nb_parties_+1);
1617 ArrOfInt levels(nb_parties_+1);
1618 ArrOfInt mask(nb_parties_+1);
1620 for (
int i_part=0 ; i_part<nb_parties_+1; i_part++)
1621 mask[i_part] = maskval;
1624 F77NAME(PERPHN)(&nb_parties_, ja.
addr(), ia.addr(), &init, mask.
addr(), &maskval, &nlev, riord.
addr(), levels.
addr());
1627 ArrOfInt renum(nb_parties_);
1628 for (
int i_part=0; i_part < nb_parties_; i_part++)
1629 renum[riord[i_part]-1]=i_part;
1631 for (
int_t i=0; i<size; i++)
1632 elem_part[i]=renum[elem_part[i]];
1635 liste_elems_sous_domaines_.reset();
1636 calculer_listes_elements_sous_domaines(elem_part, nb_parties_, nbelem, liste_elems_sous_domaines_);
1673 for(
int i_part=0; i_part<nb_parties_; i_part++)
1675 if(otherProcDomaines[proc][i_part])
1677 ArrOfInt tmp_neighbours;
1678 recevoir(tmp_neighbours, proc, 0, proc+2003);
1679 for(
int i=0; i<tmp_neighbours.
size_array(); i++)
1680 Neighbours[i_part].append_array(tmp_neighbours[i]);
1683 ArrOfInt tmp_edge_cut(nb_parties_);
1685 recevoir(tmp_edge_cut, proc, 0, proc+2008);
1687 for(
int i_part=0; i_part<nb_parties_; i_part++)
1688 EdgeCut(i_part) += tmp_edge_cut[i_part];
1691 Cout <<
"\nQuality of partitioning --------------------------------------------" << finl;
1692 int total_edge_cut = 0;
1693 for (
int i_part=0; i_part<nb_parties_; i_part++)
1694 total_edge_cut+=EdgeCut(i_part);
1695 Cout <<
"Total number of edge-cut (faces shared by processes) : " << total_edge_cut << finl;
1696 if (total_edge_cut>0)
1698 double mean_edgecut_domaine = total_edge_cut / nb_parties_;
1699 int max_edgecut_domaine = local_min_vect(EdgeCut);
1700 int min_edgecut_domaine = local_max_vect(EdgeCut);
1702 double load_imbalance = double(max_edgecut_domaine / mean_edgecut_domaine);
1703 Cout <<
"Number of edge-cut per Domaine (min/mean/max) : " << min_edgecut_domaine <<
" / "
1704 << (int) (mean_edgecut_domaine) <<
" / " << max_edgecut_domaine <<
" Load imbalance: " << load_imbalance
1708 int mean_neighbours = 0;
1709 int min_neighbours = nb_parties_;
1710 int max_neighbours = 0;
1711 for (
int i_part = 0; i_part < nb_parties_; i_part++)
1713 array_trier_retirer_doublons(Neighbours[i_part]);
1714 int nb_neighbours = Neighbours[i_part].size_array();
1715 mean_neighbours += nb_neighbours;
1716 if(nb_neighbours < min_neighbours) min_neighbours = nb_neighbours;
1717 if(nb_neighbours > max_neighbours) max_neighbours = nb_neighbours;
1720 mean_neighbours/=nb_parties_;
1721 if (mean_neighbours>0)
1723 double load_imbalance = double(max_neighbours / mean_neighbours);
1724 Cout <<
"Number of neighbours per Domaine (min/mean/max) : " << min_neighbours <<
" / "
1725 << (int) (mean_neighbours) <<
" / " <<max_neighbours <<
" Load imbalance: " << load_imbalance
1731 for(
int i_part=0; i_part < nb_parties_; i_part++)
1732 if(myDomaines[i_part])
1738 if (format == DomainesFileOutputType::HDF5_SINGLE)
static int print_more_infos_
Classe outil permettant de generer des sous-domaines pour un calcul parallele a partir d'un domaine d...
Domaine_32_64< _SIZE_ > Domaine_t
BigArrOfInt_T< _SIZE_ > BigArrOfInt_t
BigIntVect_T< _SIZE_ > BigIntVect_t
void ecrire_domaines(const Nom &basename, const DomainesFileOutputType format, const int reorder, const Static_Int_Lists_t *som_raccord=nullptr)
Generation de tous les sous-domaines du calcul et ecriture sur disque des fichiers basename_000n.
void reset()
annule toutes les references et vide les tableaux
IntTab_T< _SIZE_ > IntTab_t
void initialiser(const Domaine_t &domaine_global, const BigIntVect_t &elem_part, const int nb_parts, const int epaisseur_joint, const bool permissif=false)
Prepare les structures de donnees pour la construction des sous-domaines en fonction d'un decoupage f...
Domaine_32_64< int > Domaine32
void construire_sous_domaine(const int part, DomaineCutter_Correspondance_t &correspondance, Domaine32 &sous_domaine, const Static_Int_Lists_t *som_raccord=nullptr) const
Remplit la structure "correspondance" et le "sous_domaine" pour la partie "part".
SmallArrOfTID_T< _SIZE_ > SmallArrOfTID_t
Static_Int_Lists_32_64< _SIZE_ > Static_Int_Lists_t
DomaineCutter_Correspondance_32_64< _SIZE_ > DomaineCutter_Correspondance_t
TRUSTArray< _SIZE_, _SIZE_ > ArrOfInt_t
Sous_Domaine_32_64< _SIZE_ > Sous_Domaine_t
SmallArrOfTID_t liste_sommets_
BigArrOfInt_t liste_inverse_sommets_
BigArrOfInt_t liste_inverse_elements_
classe Domaine_32_64 un Domaine est un maillage compose d'un ensemble d'elements geometriques de meme...
int_t nb_elem_tot() const
DoubleTab_t & les_sommets()
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
const DoubleTab_t & coord_sommets() const
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...
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
const Noms & bords_perio() const
void nommer(const Nom &nom) override
Donne un nom a l'Objet_U Methode virtuelle a surcharger.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
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)...
Class defining operators and methods for all reading operation in an input flow (file,...
void typer(const Motcle &)
Type les faces.
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
Parallel collective version of FichierHDF, to be used for all concurrent reading/writing on HDF files...
This abstract class provides all the functionalities to open and manipulate HDF files and related con...
void fill_dataset(Nom dataset_name, Sortie_Brute &sortie)
virtual void create_and_fill_dataset_SW(Nom datasetname, Sortie_Brute &sortie)
void create_datasets(Noms dataset_names, long length)
virtual void create(Nom filename)
void nommer(const Nom &) override
Donne un nom a la frontiere.
void typer_faces(const Motcle &)
Type les faces de la frontiere.
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
void associer_domaine(const Domaine_t &)
Associe la frontiere au domaine dont elle depend.
const Faces_t & faces() const
void add(const Frontiere_32_64 &)
Ajoute les sommets (et faces) de la frontiere passee en parametre a l'objet (Frontiere_32_64).
Classe Groupe_Face La classe sert a representer une selection de faces lu dans le fichier med.
void affecte_epaisseur(int ep)
const Joint_Items_t & joint_item(JOINT_ITEM type) const
Renvoie les informations de joint pour le type demande.
void affecte_PEvoisin(int num)
Joint_Items_t & set_joint_item(JOINT_ITEM type)
Renvoie les informations de joint pour un type d'item geometrique donne, pour remplissage des structu...
const ArrOfInt_t & items_communs() const
ArrOfInt_t & set_items_communs()
Renvoie le tableau items_communs_ pour le remplir.
const ArrOfInt_t & items_distants() const
Voir items_distants_.
ArrOfInt_t & set_items_distants()
Renvoie le tableau items_distants_ pour le remplir Voir Scatter::calculer_espace_distant,...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Nom nom_me(int, const char *prefix=0, int without_padding=0) const
Insere _prefix000n (n=me() ou nproc()) dans un nom de fichier (par ex:toto.
Nom & prefix(const char *const)
Un tableau de chaine de caracteres (VECT(Nom)).
classe Objet_U Cette classe est la classe de base des Objets de TRUST
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Base class for polyedrons and polygons. Connectivity is stored in descending mode:
static int check_int_overflow(trustIdType)
static double mp_max(double)
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 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 int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
static void trier_les_joints(Joints &joints)
Sort joints by increasing neighbor proc number.
This derived class of Sortie stacks whatever it receives in an internal binary buffer.
unsigned get_size() const
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Classe de base des flux de sortie.
void set_bin(bool bin) override
Change le mode d'ecriture du fichier.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
int_t nb_elem_tot() const
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)
virtual _SIZE_ dimension_tot(int) const
void resize(_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_tot(int) const override
_SIZE_ dimension(int d) const
_SIZE_ size_reelle() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")