17#include <DomaineCutter.h>
18#include <Format_Post_Lata.h>
22#include <communications.h>
23#include <Synonyme_info.h>
28Add_synonym(Decouper,
"Partition");
29Add_synonym(Decouper_64,
"Partition_64");
31template <
typename _SIZE_>
38template <
typename _SIZE_>
47template <
typename _SIZE_>
48void Decouper_32_64<_SIZE_>::lire_partitionneur(
Entree& is)
52 Nom type_partitionneur(
"Partitionneur_");
53 type_partitionneur += n;
54 Cerr <<
" Creation of a partitioner of type: " << type_partitionneur << finl;
55 deriv_partitionneur_.typer(type_partitionneur);
57 if (!deriv_partitionneur_)
66template <
typename _SIZE_>
67void Decouper_32_64<_SIZE_>::ecrire_fichier_decoupage()
const
69 Cerr <<
"Writing of the splitting array at the format IntVect ascii\n"
70 <<
" in the file " << nom_fichier_decoupage_
71 <<
"\n(for each element, number of the destination processor)" << finl;
73 if (! file.
ouvrir(nom_fichier_decoupage_))
75 Cerr <<
" Error in the opening of the file." << finl;
79 file << nb_parts_tot_;
82template <
typename _SIZE_>
83void Decouper_32_64<_SIZE_>::ecrire_fichier_decoupage_som()
const
85 Cerr <<
"Writing of the splitting array at the format IntVect ascii\n"
86 <<
" in the file " << nom_fichier_decoupage_sommets_
87 <<
"\n(for each node, list of the destination processors)" << finl;
89 if (! file.
ouvrir(nom_fichier_decoupage_sommets_))
92 const Domaine_t& domaine = this->domaine();
93 const IntTab_t& elems = domaine.les_elems();
94 int nbOfNodesPerElems = elems.dimension_int(1);
95 int_t nbSom = domaine.nb_som();
96 std::vector<std::set<int_t>> node_part(nbSom);
97 for(
int i=0; i<elem_part_.size(); i++)
99 for (
int j = 0; j < nbOfNodesPerElems; j++)
101 int_t node = elems(i, j);
102 node_part[node].insert(elem_part_[i]);
105 file << domaine.nb_som() << finl;
106 for(int_t i=0; i<nbSom; i++)
108 file << i <<
" " << node_part[i].size() <<
" ";
109 for(
const auto& set_elem: node_part[i])
110 file << set_elem <<
" ";
115template <
typename _SIZE_>
116void Decouper_32_64<_SIZE_>::postraiter_decoupage(
const Nom& nom_fichier)
const
118 if (!std::is_same<_SIZE_,int>::value)
119 Process::exit(
"Postprocessing of partitioning is not yet implemented for big (64b) domains!");
121 const Domaine& domaine =
reinterpret_cast<const Domaine&
>(this->domaine());
124 if (nom_fichier.finit_par(
".lata"))
126 basename = nom_fichier;
127 basename.prefix(
".lata");
129 else if (nom_fichier.finit_par(
".med"))
131 basename = nom_fichier;
132 basename.prefix(
".med");
135 Process::exit(
"Decouper: postraiter_decoupage(): the file name for postprocessing the domain should end with extension '.lata' or '.med' !!");
138 if (!std::is_same<_SIZE_,int>::value)
141 Cerr <<
"did you remove cast?" << finl;
144 const int n = (int)elem_part_.size_reelle();
147 for (
int i = 0; i < n; i++)
148 data(i) =
static_cast<double>(elem_part_[i]);
150 Noms units, noms_compo;
153 constexpr int IS_FIRST = 1;
155 if (nom_fichier.finit_par(
".lata"))
157 Cerr <<
"Postprocessing of the splitting at the lata (V2) format: " << nom_fichier << finl;
177 else if (nom_fichier.finit_par(
".med"))
179 Cerr <<
"Postprocessing of the splitting at the MED format: " << nom_fichier << finl;
181 post.typer(
"Format_Post_Med");
182 Nom filename(nom_fichier.getPrefix(
".med"));
202template <
typename _SIZE_>
203void Decouper_32_64<_SIZE_>::ecrire_sous_domaines(
const int nb_parties,
const Static_Int_Lists_t* som_raccord)
const
206 cutter.
initialiser(this->domaine(), elem_part_, nb_parties, epaisseur_joint_);
212 cutter.
ecrire_domaines(nom_domaines_decoup_, format_, reorder_, som_raccord);
258template <
typename _SIZE_>
261 Cerr <<
"Decouper: Splitting of a domain" << finl;
272 Cerr <<
"End of the interpreter Decouper" << finl;
276template <
typename _SIZE_>
281 Cerr <<
" Domain name to split : " <<
nom_domaine_ << finl;
284 const auto& dom = this->domaine();
287 Noms liste_bords_perio;
293 param.
ajouter_condition(
"value_of_larg_joint_ge_1",
"The joint thickness must greater or equal to 1.");
302 param.
ajouter(
"periodique",&liste_bords_perio);
307 if (liste_bords_perio.size() > 0)
309 Cerr << finl <<
"ERROR: Option 'periodique' in Decouper/Partition keyword is now obsolete! It must be removed." << finl;
310 Cerr <<
"Your periodic boundaries in the domain now only needs to be declared once using the 'Declarer_bord_perio|Corriger_frontiere_periodique' keyword." << finl << finl;
314 if (hdf)
format_ = DomainesFileOutputType::HDF5_SINGLE;
319template <
typename _SIZE_>
325 nb_parties =
static_cast<int>(max_array(
elem_part_)) + 1;
327 Cerr <<
"The partitioner has generated " << nb_parties <<
" parts." << finl;
334 Cerr <<
"Error: nb_parts_tot_ is less than the number of parts generated by the partitioner."
338 Cerr <<
"Number of parts requested : " <<
nb_parts_tot_ << finl
339 <<
"Generation of " <<
nb_parts_tot_ - nb_parties <<
" empty parts." << finl;
344 format_ = DomainesFileOutputType::HDF5_SINGLE;
347 ecrire_fichier_decoupage();
350 ecrire_fichier_decoupage_som();
353 ecrire_sous_domaines(nb_parties, som_raccord);
360 Cout << finl <<
"Quality of partitioning --------------------------------------------" << finl;
362 Cout <<
"\nTotal number of elements = " << total_elem << finl;
363 Cout <<
"Number of Domaines : " << nb_parties << finl;
367 DoubleVect A(nb_parties);
369 for (
int i = 0; i <
elem_part_.size_reelle(); i++)
376 DoubleVect tmp(nb_parties);
378 recevoir(tmp, proc, 0, proc+2005);
380 for(
int i_part=0; i_part<nb_parties; i_part++)
381 A(i_part) += tmp(i_part);
384 double mean_element_domaine =
static_cast<double>(total_elem/nb_parties);
385 if (mean_element_domaine>0)
387 double load_imbalance = double(local_max_vect(A) / mean_element_domaine);
388 Cout <<
"Number of cells per Domaine (min/mean/max) : " << local_min_vect(A) <<
" / " << mean_element_domaine <<
" / "
389 << local_max_vect(A) <<
" Load imbalance: " << load_imbalance <<
"\n" << finl;
400 Cerr <<
"End of the interpreter Decouper" << finl;
403 Cerr <<
"Performance tip: You could add \"reorder 1\" option to have less distance between communicating processes on the network." << finl;
404 Cerr <<
"Add also \"Ecrire_lata filename.lata\" to post-process the partition numeration and see the difference." << finl;
408template <
typename _SIZE_>
412 if (mot==
"partitionneur|partition_tool")
415 lire_partitionneur(is);
void ecrire(const Static_Int_Lists_t *som_raccord=nullptr)
static int print_more_infos_
Entree & lire(Entree &is)
Partitionneur_base_32_64< _SIZE_ > Partitionneur_base_t
Nom nom_fichier_decoupage_
Entree & interpreter(Entree &is) override
Static_Int_Lists_32_64< _SIZE_ > Static_Int_Lists_t
DomainesFileOutputType format_
Nom nom_fichier_decoupage_sommets_
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Classe outil permettant de generer des sous-domaines pour un calcul parallele a partir d'un domaine d...
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 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...
Class defining operators and methods for all reading operation in an input flow (file,...
: Classe de postraitement des champs euleriens au format lata
int ecrire_entete(const double temps_courant, const int reprise, const int est_le_premier_post) override
Ouvre le fichier maitre en mode ERASE et ecrit l'entete du fichier lata (sur le processeur maitre seu...
virtual int initialize_lata(const Nom &file_basename, const Format format=ASCII, const Options_Para options_para=SINGLE_FILE)
Initialisation de la classe, ouverture du fichier et ecriture de l'entete.
int ecrire_domaine(const Domaine &domaine, const int est_le_premier_post) override
voir Format_Post_base::ecrire_domaine On accepte l'ecriture d'un domaine dans un pas de temps,...
int ecrire_temps(const double temps) override
commence l'ecriture d'un nouveau pas de temps En l'occurence pour le format LATA:
int ecrire_champ(const Domaine &domaine, const Noms &unite_, const Noms &noms_compo, int ncomp, double temps_, const Nom &id_du_champ, const Nom &id_du_domaine, const Nom &localisation, const Nom &nature, const DoubleTab &data) override
voir Format_Post_base::ecrire_champ
int finir(const int est_le_dernier_post) override
int initialize(const Nom &file_basename, const int format, const Nom &option_para) override
Classe de base des formats de postraitements pour les champs (lata, med, cgns, lml,...
void associer_domaine(Nom &nom_dom)
Classe de base des objets "interprete".
Une chaine de caractere (Nom) en majuscules.
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
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.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
void ajouter_condition(const char *condition, const char *message, const char *name=0)
Declare a post-read logical condition that must hold on the parameter values.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Classe de base des partitionneurs de domaine (pour decouper un maillage avant un calcul parallele).
virtual void associer_domaine(const Domaine_t &domaine)=0
virtual void construire_partition(BigIntVect_ &elem_part, int &nb_parts_tot) const =0
static double mp_max(double)
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 bool force_single_file(const int ranks, const Nom &filename)
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...
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Classe de base des flux de sortie.