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
Reads non-simple-type parameters of an Objet_U from an input stream.
Tool class to generate sub-domains for a parallel computation from a starting domain (domaine_global)...
void ecrire_domaines(const Nom &basename, const DomainesFileOutputType format, const int reorder, const Static_Int_Lists_t *som_raccord=nullptr)
Generation of all sub-domains of the computation and writing to disk of the files 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)
Prepares the data structures for building sub-domains based on a partitioning provided in elem_part.
Class defining operators and methods for all reading operation in an input flow (file,...
: Post-processing class for Eulerian fields in LATA format.
int ecrire_entete(const double temps_courant, const int reprise, const int est_le_premier_post) override
Opens the master file in ERASE mode and writes the lata file header (on the master processor only).
virtual int initialize_lata(const Nom &file_basename, const Format format=ASCII, const Options_Para options_para=SINGLE_FILE)
Initializes the class, opens the file and writes the header.
int ecrire_domaine(const Domaine &domaine, const int est_le_premier_post) override
See Format_Post_base::ecrire_domaine. Writing a domain within a time step is accepted,...
int ecrire_temps(const double temps) override
Starts writing a new time step. For the LATA format specifically:
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
Base class for post-processing output formats for fields (lata, med, cgns, lml, single_lata).
void associer_domaine(Nom &nom_dom)
Base class for "interpreter" objects.
A character string (Nom) in uppercase.
class Nom: a character string for naming TRUST objects.
An array of character strings (VECT(Nom)).
const Nom & que_suis_je() const
Returns the string identifying the class.
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
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.
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.
Base class for domain partitioners (for splitting a mesh before a parallel computation).
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()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
static bool force_single_file(const int ranks, const Nom &filename)
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Base class for output streams.