16#include <Domaine_dis_cache.h>
17#include <communications.h>
18#include <Comm_Group_MPI.h>
19#include <TRUST_2_CGNS.h>
20#include <unordered_set>
21#include <Domaine_VF.h>
30bool is_comm_group_mode(
const bool postraiter_domaine)
36void allgather_int_on_active_comm(
const int local_value, std::vector<int>& global_values,
const bool by_comm_grp)
41 MPI_Allgather(&local_value, 1, MPI_ENTIER, global_values.data(), 1, MPI_ENTIER, comm_loc.get_mpi_comm());
44 MPI_Allgather(&local_value, 1, MPI_ENTIER, global_values.data(), 1, MPI_ENTIER, MPI_COMM_WORLD);
47void compute_global_min_max(
const std::vector<int>& global_counts, std::vector<int>& global_min, std::vector<int>& global_max,
int& total)
49 const int nb_procs =
static_cast<int>(global_counts.size());
50 global_min.assign(nb_procs, -123);
51 global_max.assign(nb_procs, -123);
54 for (
int i = 0; i < nb_procs; i++)
56 global_min[i] = total + 1;
57 total += global_counts[i];
58 global_max[i] = total;
62void compute_global_max_only(
const std::vector<int>& global_counts, std::vector<int>& global_max,
int& total)
64 const int nb_procs =
static_cast<int>(global_counts.size());
65 global_max.assign(nb_procs, -123);
68 for (
int i = 0; i < nb_procs; i++)
70 total += global_counts[i];
71 global_max[i] = total;
77Motcle TRUST_2_CGNS::modify_field_name_for_post(
const Nom& id_du_champ,
const Nom& id_du_domaine,
const std::string& LOC,
int& fieldId_som,
int& fieldId_elem,
int& fieldId_faces)
79 Motcle id_du_champ_modifie(id_du_champ), iddomaine(id_du_domaine);
83 id_du_champ_modifie.prefix(id_du_domaine);
84 id_du_champ_modifie.prefix(iddomaine);
85 id_du_champ_modifie.prefix(
"_SOM_");
87 else if (LOC ==
"ELEM")
89 id_du_champ_modifie.prefix(id_du_domaine);
90 id_du_champ_modifie.prefix(iddomaine);
91 id_du_champ_modifie.prefix(
"_ELEM_");
93 else if (LOC ==
"FACES")
95 id_du_champ_modifie.prefix(id_du_domaine);
96 id_du_champ_modifie.prefix(iddomaine);
97 id_du_champ_modifie.prefix(
"_FACES_");
100 throw std::runtime_error(
"TRUST_2_CGNS::modify_field_name_for_post => Unsupported LOC : " + LOC);
102 (LOC ==
"SOM") ? fieldId_som++ : ( (LOC ==
"ELEM") ? fieldId_elem++ : fieldId_faces++);
109 const char * id_char = id_du_champ_modifie.getChar();
110 size_t sz = std::strlen(id_char);
111 if (sz > CGNS_STR_SIZE)
114 Cerr <<
"The field " << id_char <<
" contains " << sz <<
" chars & CGNS is limited to " << CGNS_STR_SIZE <<
" ==> renamed to ";
117 std::string new_id_du_champ_modifie(id_char);
119 auto replace_all = [](std::string& s,
const std::string& from,
const std::string& to)
122 while ((pos = s.find(from, pos)) != std::string::npos)
124 s.replace(pos, from.length(), to);
131 truncate_try_1.suffix(nom_du_cas.getChar());
132 truncate_try_1.suffix(
"_");
134 if (std::strlen(truncate_try_1.getChar()) <= CGNS_STR_SIZE)
135 new_id_du_champ_modifie = truncate_try_1.getChar();
139 if (new_id_du_champ_modifie.size() > CGNS_STR_SIZE)
141 replace_all(new_id_du_champ_modifie,
"VITESSE",
"VIT");
142 replace_all(new_id_du_champ_modifie,
"TEMPERATURE",
"TEMP");
143 replace_all(new_id_du_champ_modifie,
"CONCENTRATION",
"CONC");
144 replace_all(new_id_du_champ_modifie,
"CONVECTION",
"CONV");
145 replace_all(new_id_du_champ_modifie,
"DIFFUSION",
"DIFF");
146 replace_all(new_id_du_champ_modifie,
"VISQUEUSE",
"VISQ");
147 replace_all(new_id_du_champ_modifie,
"MASSE_VOLUMIQUE",
"RHO");
148 replace_all(new_id_du_champ_modifie,
"LIQUIDE",
"LIQ");
152 if (new_id_du_champ_modifie.size() > CGNS_STR_SIZE)
154 static constexpr size_t keep_first = 25;
155 static constexpr size_t keep_last = 5;
157 const size_t new_sz = new_id_du_champ_modifie.size();
158 const std::string prem = new_id_du_champ_modifie.substr(0, keep_first);
159 const std::string der = new_id_du_champ_modifie.substr(new_sz - keep_last, keep_last);
161 new_id_du_champ_modifie = prem +
"__" + der;
164 id_du_champ_modifie =
Motcle(new_id_du_champ_modifie.c_str());
167 Cerr << id_du_champ_modifie <<
" !!! " << finl;
171 return id_du_champ_modifie;
175std::string TRUST_2_CGNS::modify_domaine_name_for_post(
const Nom& nom_dom)
177 std::string nom_dom_modifie = nom_dom.
getString();
179 if (
static_cast<int>(nom_dom_modifie.size()) >= CGNS_STR_SIZE)
181 size_t found = nom_dom_modifie.find(
"boundaries_");
182 if (found != std::string::npos)
183 nom_dom_modifie.erase(found, 11);
187 if (
static_cast<int>(nom_dom_modifie.size()) >= CGNS_STR_SIZE)
188 nom_dom_modifie.erase(CGNS_STR_SIZE-1);
191 return nom_dom_modifie;
194void TRUST_2_CGNS::map_face_values(
const Domaine_VF& dom_vf,
const DoubleTab& val_src, DoubleTrav& val_trgt)
196 const auto& dual_m = dom_vf.get_mc_dual_mesh();
197 const int nb_cells =
static_cast<int>(dual_m->getNumberOfCells());
200 assert (val_src.
nb_dim() == 2);
202 val_trgt.
resize(nb_cells, nb_j);
204 for (
int f = 0; f < val_src.
dimension(0); f++)
206 const int e1 = face_voisins(f, 0), e2 = face_voisins(f, 1);
207 for (
int e: {e1, e2})
213 std::copy_n(&val_src(f, 0), nb_j, &val_trgt(e, 0));
218void TRUST_2_CGNS::associer_domaine_TRUST(
const Domaine * dom,
const Domaine_dis_base* dom_dis,
const DoubleTab& som,
const IntTab& elem,
const bool post_dom,
const std::string& discr_type)
220 if (dom) dom_trust_ = *dom;
221 if (dom_dis) domaine_dis_ = *dom_dis;
224 postraiter_domaine_ = post_dom;
225 discr_type_ = discr_type;
228void TRUST_2_CGNS::associer_connec_pour_dual(
const IntTab& fs,
const IntTab& ef)
234void TRUST_2_CGNS::fill_coords(std::vector<double>& xCoords, std::vector<double>& yCoords, std::vector<double>& zCoords)
const
237 const DoubleTab& sommets = sommets_.valeur();
238 assert (sommets_->dimension(1) > 1);
240 xCoords.resize(nb_som);
241 yCoords.resize(nb_som);
245 assert(sommets_->dimension(1) > 2);
246 zCoords.resize(nb_som);
253 for (
int i = 0; i < nb_som; ++i)
255 const double r = sommets(i, 0), theta = sommets(i, 1);
256 xCoords[i] = r * cos(theta);
257 yCoords[i] = r * sin(theta);
259 zCoords[i] = sommets(i, 2);
264 for (
int i = 0; i < nb_som; ++i)
266 xCoords[i] = sommets(i, 0);
267 yCoords[i] = sommets(i, 1);
269 zCoords[i] = sommets(i, 2);
277void TRUST_2_CGNS::clear_vectors()
281 proc_non_zero_elem_.clear();
282 global_nb_elem_.clear();
283 global_nb_som_.clear();
287 global_nb_face_som_.clear();
288 global_nb_face_som_offset_.clear();
289 global_nb_elem_face_.clear();
290 global_nb_elem_face_offset_.clear();
291 global_nb_elem_som_offset_.clear();
293 global_incr_min_face_som_.clear();
294 global_incr_max_face_som_.clear();
295 global_incr_min_elem_face_.clear();
296 global_incr_max_elem_face_.clear();
300 local_fs_offset_.clear();
302 local_ef_offset_.clear();
304 local_es_offset_.clear();
307void TRUST_2_CGNS::fill_global_infos()
310 assert (sommets_ && elems_);
312 const bool by_comm_grp = is_comm_group_mode(postraiter_domaine_);
330 const int nb_procs = by_comm_grp ? nb_proc_local_comm_ :
Process::nproc();
331 const int nb_som = sommets_->dimension(0), nb_elem = elems_->dimension(0);
335 global_nb_elem_.assign(nb_procs, -123 );
336 global_nb_som_.assign(nb_procs, -123 );
338 allgather_int_on_active_comm(nb_elem, global_nb_elem_, by_comm_grp);
339 allgather_int_on_active_comm(nb_som, global_nb_som_, by_comm_grp);
343 compute_global_min_max(global_nb_elem_, global_incr_min_elem_, global_incr_max_elem_, ne_tot_);
344 compute_global_min_max(global_nb_som_, global_incr_min_som_, global_incr_max_som_, ns_tot_);
347 const auto min_nb_elem = std::min_element(global_nb_elem_.begin(), global_nb_elem_.end());
348 nb_procs_writing_ = nb_procs;
350 if (*min_nb_elem <= 0)
353 for (
int i = 0; i < static_cast<int>(global_nb_elem_.size()); i++)
354 if (global_nb_elem_[i] > 0) proc_non_zero_elem_.push_back(i);
356 nb_procs_writing_ =
static_cast<int>(proc_non_zero_elem_.size());
357 all_procs_write_ =
false;
365 domaine_dis =
nullptr;
368 if (!fs_dual_ && !ef_dual_)
371 && domaine_dis_->domaine().le_nom() == dom_trust_->le_nom()
372 && domaine_dis_->face_sommets().size() > 0)
374 domaine_dis = &(domaine_dis_.valeur());
378 if (discr_type_ !=
"")
383 Nom type =
"Domaine_PolyMAC_MPFA";
392void TRUST_2_CGNS::fill_global_infos_poly(
const bool is_polyedre)
397 const bool by_comm_grp = is_comm_group_mode(postraiter_domaine_);
400 const int nb_procs = by_comm_grp ? nb_proc_local_comm_ :
Process::nproc();
408 get_domaine_dis_vf_if_poly(domaine_dis, vf);
410 const IntTab& fs = vf ? (*vf).
face_sommets() : fs_dual_.valeur();
411 const IntTab& ef = vf ? (*vf).
elem_faces() : ef_dual_.valeur();
414 global_nb_face_som_.assign(nb_procs, -123 );
415 global_nb_elem_face_.assign(nb_procs, -123 );
417 allgather_int_on_active_comm(nb_fs, global_nb_face_som_, by_comm_grp);
418 allgather_int_on_active_comm(nb_ef, global_nb_elem_face_, by_comm_grp);
422 compute_global_min_max(global_nb_face_som_, global_incr_min_face_som_, global_incr_max_face_som_, nfs_tot_);
423 compute_global_min_max(global_nb_elem_face_, global_incr_min_elem_face_, global_incr_max_elem_face_, nef_tot_);
428 decal = compute_shift(global_incr_max_som_);
430 nb_fs_ = convert_connectivity_ngon(local_fs_, local_fs_offset_, is_polyedre, decal);
434 decal = compute_shift(global_incr_max_face_som_);
436 nb_ef_ = convert_connectivity_nface(local_ef_, local_ef_offset_, decal);
439 const int nb_fs_offset =
static_cast<int>(local_fs_.size()), nb_ef_offset =
static_cast<int>(local_ef_.size());
441 global_nb_face_som_offset_.assign(nb_procs, -123 );
442 global_nb_elem_face_offset_.assign(nb_procs, -123 );
444 allgather_int_on_active_comm(nb_fs_offset, global_nb_face_som_offset_, by_comm_grp);
445 allgather_int_on_active_comm(nb_ef_offset, global_nb_elem_face_offset_, by_comm_grp);
450 std::vector<int> global_incr_max_face_som_offset, global_incr_max_elem_face_offset;
451 compute_global_max_only(global_nb_face_som_offset_, global_incr_max_face_som_offset, nfs_offset_tot_);
452 compute_global_max_only(global_nb_elem_face_offset_, global_incr_max_elem_face_offset, nef_offset_tot_);
454 decal = compute_shift(global_incr_max_face_som_offset);
455 for (
auto &itr : local_fs_offset_) itr += decal;
457 decal = compute_shift(global_incr_max_elem_face_offset);
458 for (
auto &itr : local_ef_offset_) itr += decal;
464 decal = compute_shift(global_incr_max_som_);
466 nb_es_ = convert_connectivity_ngon(local_es_, local_es_offset_, is_polyedre, decal);
468 const int nb_es_offset =
static_cast<int>(local_es_.size());
471 global_nb_elem_som_offset_.assign(nb_procs, -123 );
473 allgather_int_on_active_comm(nb_es_offset, global_nb_elem_som_offset_, by_comm_grp);
477 std::vector<int> global_incr_max_elem_som_offset;
478 compute_global_max_only(global_nb_elem_som_offset_, global_incr_max_elem_som_offset, nes_offset_tot_);
480 decal = compute_shift(global_incr_max_elem_som_offset);
481 for (
auto &itr : local_es_offset_) itr += decal;
487int TRUST_2_CGNS::compute_shift(
const std::vector<int>& vect_incr_max)
const
490 assert(par_in_zone_);
492 const bool by_comm_grp = is_comm_group_mode(postraiter_domaine_);
494 int proc_me = by_comm_grp ? proc_me_local_comm_ :
Process::me();
497 if (all_procs_write_)
500 decal = vect_incr_max[proc_me - 1];
504 for (
int i = 0; i < nb_procs_writing_; i++)
505 if (proc_non_zero_elem_[i] == proc_me)
508 decal = vect_incr_max[proc_non_zero_elem_[i] - 1];
518int TRUST_2_CGNS::convert_connectivity(
const CGNS_TYPE type, std::vector<cgsize_t>& conn_elem )
const
520 const int nb_elem = elems_->dimension(0);
521 const IntTab& les_elems = elems_.valeur();
522 int decal = par_in_zone_ ? compute_shift(global_incr_max_som_) : 0;
524 int nodes_per_elem = -1;
528 case CGNS_ENUMV(HEXA_8):
531 case CGNS_ENUMV(QUAD_4):
534 case CGNS_ENUMV(TETRA_4):
537 case CGNS_ENUMV(TRI_3):
540 case CGNS_ENUMV(BAR_2):
543 case CGNS_ENUMV(NODE):
547 Cerr <<
"Type not yet coded in TRUST_2_CGNS::convert_connectivity ! Call the 911 !" << finl;
552 if (nodes_per_elem != elems_->dimension(1))
554 Cerr <<
"Big issue in TRUST_2_CGNS::convert_connectivity !!!" << finl;
555 Cerr <<
" We have nodes_per_elem = " << nodes_per_elem <<
" while we have a connectivity of width = " << elems_->dimension(1) << finl;
560 conn_elem.resize(nb_elem * nodes_per_elem);
561 cgsize_t* data = conn_elem.data();
565 case CGNS_ENUMV(HEXA_8):
566 for (int i = 0; i < nb_elem; i++)
568 *data++ = les_elems(i, 0) + 1 + decal;
569 *data++ = les_elems(i, 1) + 1 + decal;
570 *data++ = les_elems(i, 3) + 1 + decal;
571 *data++ = les_elems(i, 2) + 1 + decal;
572 *data++ = les_elems(i, 4) + 1 + decal;
573 *data++ = les_elems(i, 5) + 1 + decal;
574 *data++ = les_elems(i, 7) + 1 + decal;
575 *data++ = les_elems(i, 6) + 1 + decal;
579 case CGNS_ENUMV(QUAD_4):
580 for (int i = 0; i < nb_elem; i++)
582 *data++ = les_elems(i, 0) + 1 + decal;
583 *data++ = les_elems(i, 1) + 1 + decal;
584 *data++ = les_elems(i, 3) + 1 + decal;
585 *data++ = les_elems(i, 2) + 1 + decal;
589 case CGNS_ENUMV(TETRA_4):
590 case CGNS_ENUMV(TRI_3):
591 case CGNS_ENUMV(BAR_2):
592 case CGNS_ENUMV(NODE):
593 for (int i = 0; i < nb_elem; i++)
594 for (
int j = 0; j < nodes_per_elem; j++)
595 *data++ = les_elems(i, j) + 1 + decal;
602 return nodes_per_elem;
605CGNS_TYPE TRUST_2_CGNS::convert_elem_type(
const Motcle& type)
const
608 const int nb_comp = elems_->dimension(1);
611 return CGNS_ENUMV(HEXA_8);
613 return CGNS_ENUMV(QUAD_4);
614 else if (type ==
"TETRAEDRE")
615 return CGNS_ENUMV(TETRA_4);
617 return CGNS_ENUMV(TRI_3);
618 else if (type ==
"POINT")
619 return CGNS_ENUMV(NODE);
621 return CGNS_ENUMV(NGON_n);
625 if (nb_comp == 1)
return CGNS_ENUMV(NODE);
626 if (nb_comp == 2)
return CGNS_ENUMV(BAR_2);
628 Cerr <<
"Unexpected SEGMENT connectivity of width = " << nb_comp << finl;
629 return CGNS_ENUMV(ElementTypeNull);
633 Cerr <<
"The type " << type <<
" is not yet available for the CGNS format ! Call the 911 !" << finl;
635 return CGNS_ENUMV(ElementTypeNull);
639int TRUST_2_CGNS::topo_dim_from_elem(CGNS_TYPE etype,
bool is_polyedre)
const
641 if (etype == CGNS_ENUMV(BAR_2) || etype == CGNS_ENUMV(NODE))
644 if (etype == CGNS_ENUMV(TRI_3) || etype == CGNS_ENUMV(QUAD_4))
647 if (etype == CGNS_ENUMV(NGON_n))
648 return is_polyedre ? 3 : 2;
654int TRUST_2_CGNS::convert_connectivity_nface(std::vector<cgsize_t>& econ, std::vector<cgsize_t>& eoff,
int decal)
660 get_domaine_dis_vf_if_poly(domaine_dis, vf);
662 const IntTab& ef = vf ? (*vf).
elem_faces() : ef_dual_.valeur();
666 econ.clear(), eoff.clear();
668 econ.reserve(
static_cast<size_t>(nElem) * maxDeg);
669 eoff.reserve(
static_cast<size_t>(nElem) + 1);
674 for (
int e = 0; e < nElem; ++e)
676 for (
int j = 0; j < maxDeg; ++j)
678 const int f = ef(e, j);
682 econ.push_back(
static_cast<cgsize_t
>(f + 1 + decal));
694 std::unordered_set<cgsize_t> seen;
695 for (
auto& itr : econ)
697 if (seen.find(itr) != seen.end())
706int TRUST_2_CGNS::convert_connectivity_ngon(std::vector<cgsize_t>& econ, std::vector<cgsize_t>& eoff,
const bool is_polyedre,
int decal)
713 get_domaine_dis_vf_if_poly(domaine_dis, vf);
715 const IntTab& fs = vf ? (*vf).
face_sommets() : fs_dual_.valeur();
719 econ.clear(), eoff.clear();
721 econ.reserve(
static_cast<size_t>(nFace) * maxDeg);
722 eoff.reserve(
static_cast<size_t>(nFace) + 1);
726 for (
int f = 0; f < nFace; ++f)
728 for (
int j = 0; j < maxDeg; ++j)
730 const int v = fs(f, j);
734 econ.push_back(
static_cast<cgsize_t
>(v + 1 + decal));
744 const IntTab& les_elems = dom_trust_->les_elems();
748 econ.clear(), eoff.clear();
750 econ.reserve(
static_cast<size_t>(nElem) * maxDeg);
751 eoff.reserve(
static_cast<size_t>(nElem) + 1);
755 for (
int e = 0; e < nElem; ++e)
757 for (
int j = 0; j < maxDeg; ++j)
759 const int v = les_elems(e, j);
762 econ.push_back(
static_cast<cgsize_t
>(v + 1 + decal));
: Classe Comm_Group_MPI, derivee de la classe abstraite Comm_Group.
const IntTab & get_face_voisins_dual() const
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
static Domaine_dis_base & Build_or_get_poly_post(const Nom &type, const Domaine &dom)
Une chaine de caractere (Nom) en majuscules.
int debute_par(const char *const n) const override
class Nom Une chaine de caractere pour nommer les objets de TRUST
const std::string & getString() const
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
static bool LINKED_FILES_PER_COMM_GROUP
static bool PARALLEL_OVER_ZONE
static bool SINGLE_FILE_PER_COMM_GROUP
static int enter_group(const Comm_Group &group)
Si le processeur local appartient au groupe, le groupe courant pour ce processeur devient "group" et ...
static const Comm_Group & get_user_defined_group()
Renvoie une reference au groupe sur defini par l'utilisateur.
static bool has_user_defined_group()
static void exit_group()
Retourne dans le groupe ou l'on etait avant le dernier enter_group() reussi (dont le resultat a ete 1...
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.
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const