16#include <Connectivite_som_elem.h>
17#include <EcrFicCollecteBin.h>
18#include <Elem_geom_base.h>
19#include <Poly_geom_base.h>
20#include <communications.h>
21#include <NettoieNoeuds.h>
22#include <Faces_builder.h>
30template <
typename _SIZE_>
33 connectivite_som_elem_ptr_(0),
38template <
typename _SIZE_>
41 les_elements_ptr_ = 0;
42 connectivite_som_elem_ptr_ = 0;
43 faces_element_reference_old_.reset();
45 faces_sommets_.reset();
60template <
typename _SIZE_>
66 les_elements_ptr_ = & domaine.les_elems();
68 connectivite_som_elem_ptr_ = & connect_som_elem;
70 assert(connect_som_elem.
get_nb_lists() == domaine.nb_som_tot());
75 if (sub_type(Poly_geom_base,domaine.type_elem().valeur()))
80 domaine.type_elem()->get_tab_faces_sommets_locaux(faces_element_reference_old_);
94 faces_sommets_ = faces_sommets;
95 face_elem_ = faces_voisins;
96 ref_domaine_ = domaine;
105 const int_t nb_elements = les_elements().dimension(0);
106 const int nb_faces_par_element = faces_element_reference(0).dimension(0);
107 elem_faces.
resize(nb_elements, nb_faces_par_element);
110 const int nb_sommets_par_face = faces_element_reference(0).
dimension(1);
113 const int_t nb_faces_front = domaine.nb_faces_frontiere() + domaine.nb_faces_joint();
114 int_t nb_faces_prevision = (nb_elements * nb_faces_par_element + nb_faces_front) / 2;
124 faces_sommets.
resize(nb_faces_prevision, nb_sommets_par_face);
125 faces_sommets.
resize(0, nb_sommets_par_face);
127 faces_voisins.
resize(nb_faces_prevision, 2);
128 faces_voisins.
resize(0, 2);
135 Bords_t& bords = domaine.faces_bord();
136 const int n = bords.size();
137 for (
int i = 0; i < n; i++)
141 creer_faces_frontiere(1,
150 Raccords_t& raccords = domaine.faces_raccord();
151 const int n = raccords.size();
152 for (
int i = 0; i < n; i++)
155 creer_faces_frontiere(1,
166 const int n = faces_int.size();
167 for (
int i = 0; i < n; i++)
170 creer_faces_frontiere(2,
183 Cerr <<
"Faces_builder_32_64<_SIZE_>::creer_faces_reeles not coded for the internal faces of boundary" << finl;
191 Joints_t& joints = domaine.faces_joint();
192 const int n = joints.size();
193 for (
int i = 0; i < n; i++)
196 creer_faces_frontiere(2,
209 for (
int_t i2 = 0; i2 < nb_faces; i2++)
210 indices_faces[i2] = num_premiere_face + i2;
217 creer_faces_internes(faces_sommets,
225 const int n = groupes_faces.size();
226 for (
int i = 0; i < n; i++)
229 identification_groupe_faces(groupe_faces,
235 if (faces_sommets.
dimension(0) != nb_faces_prevision)
237 Cerr <<
"Error in Faces_builder_32_64<_SIZE_>::creer_faces_reeles:\n"
238 <<
" number of faces does not match predicted number of faces.\n"
239 <<
" (problem with faces_bords_internes ?)" << finl;
253template <
typename _SIZE_>
254void Faces_builder_32_64<_SIZE_>::check_erreur_faces(
const char * message,
255 const ArrOfInt_t& liste_faces)
const
257 const int nmax = 100;
258 int_t n = liste_faces.size_array();
261 Cerr <<
"==========================" << finl;
262 Cerr <<
"Error!" << finl << message
263 <<
"\nSee log file of this PE for detailed info."
266 J <<
"Error in Faces_builder_32_64<_SIZE_>::creer_faces_*\n"
270 J <<
"Too many faces to display (" << n <<
") display only " << nmax <<
" first faces" << finl;
274 J <<
"Display format:\n"
275 <<
" facenumber = face index in faces_sommet array\n"
276 <<
" som1..som4 = node index\n"
277 <<
" elem1 elem2 = neighbouring element number\n"
278 <<
"facenumber som1 (x1 y1 z1) som2 (x2 y2 z2) [som3 (x3 y3 z3)...] elem1 elem2" << finl;
280 const DoubleTab_t& coord = ref_domaine_->coord_sommets();
281 const IntTab_t& faces = faces_sommets_.valeur();
282 const IntTab_t& face_elem = face_elem_.valeur();
284 const int_t nb_som_faces = faces.dimension(1);
285 for (i = 0; i < n; i++)
288 const int_t iface = liste_faces[i];
289 sptr += snprintf(sptr, 100,
"%4ld ",(
long) iface);
290 for (
int j = 0; j < nb_som_faces; j++)
292 const int_t isom = faces(iface,j);
293 sptr += snprintf(sptr, 100,
"%5ld(", (
long)isom);
294 for (
int k = 0; k < dim; k++)
296 sptr += snprintf(sptr, 100,
"%10.6f", coord(isom, k));
297 sptr += snprintf(sptr, 100,
")");
299 sptr += snprintf(sptr, 100,
"%4ld %4ld", (
long)face_elem(iface,0),(
long) face_elem(iface,1));
302 NettoieNoeuds_t::verifie_noeuds(ref_domaine_.valeur());
310template <
typename _SIZE_>
311_SIZE_ Faces_builder_32_64<_SIZE_>::ajouter_une_face(
const SmallArrOfTID_t& une_face,
314 IntTab_t& faces_sommets,
315 IntTab_t& faces_voisins)
318 const int_t num_new_face = faces_sommets.dimension(0);
319 const int nb_sommets_par_face = (int)faces_sommets.dimension(1);
320 const int_t new_size = num_new_face + 1;
322 assert(une_face.size_array() == nb_sommets_par_face);
323 faces_sommets.resize(new_size, nb_sommets_par_face);
324 for (i = 0; i < nb_sommets_par_face; i++)
325 faces_sommets(num_new_face, i) = une_face[i];
327 faces_voisins.resize(new_size, 2);
328 faces_voisins(num_new_face, 0) = elem0;
329 faces_voisins(num_new_face, 1) = elem1;
334template <
typename _SIZE_>
336 const IntTab& faces_element_ref,
340 const int nb_faces_element = (int)faces_element_ref.
dimension(0);
341 const int nb_sommets_par_face = (int)faces_element_ref.
dimension(1);
343 int i_face, i_som2, i_som;
344 for (i_face = 0; i_face < nb_faces_element; i_face++)
346 for (i_som = 0; i_som < nb_sommets_par_face; i_som++)
348 const int sommet_elem_ref = faces_element_ref(i_face, i_som);
349 int_t sommet_domaine ;
350 if (sommet_elem_ref==-1)
353 sommet_domaine = elem_som(elem, sommet_elem_ref);
354 for (i_som2 = 0; i_som2 < nb_sommets_par_face; i_som2++)
355 if (une_face[i_som2] == sommet_domaine)
357 if (i_som2 == nb_sommets_par_face)
360 if (i_som == nb_sommets_par_face)
363 if (i_face == nb_faces_element)
369template <
typename _SIZE_>
370const IntTab& Faces_builder_32_64<_SIZE_>::faces_element_reference(int_t elem)
const
374 const Poly_geom_base_t& poly =ref_cast(Poly_geom_base_t,ref_domaine_->type_elem().valeur());
375 IntTab& elem_ref_mod=ref_cast_non_const(IntTab,faces_element_reference_old_);
376 poly.get_tab_faces_sommets_locaux(elem_ref_mod,elem);
381 return faces_element_reference_old_;
392template <
typename _SIZE_>
394 const int_t elem)
const
396 const IntTab_t& elem_som = les_elements();
397 const IntTab& faces_element_ref = faces_element_reference(elem);
398 int i_face = chercher_face_element(elem_som, faces_element_ref, une_face, elem);
412template <
typename _SIZE_>
413void Faces_builder_32_64<_SIZE_>::creer_faces_frontiere(
const int_t nb_voisins_attendus,
414 Frontiere_t& frontiere,
415 IntTab_t& faces_sommets,
416 IntTab_t& faces_voisins,
417 IntTab_t& elem_faces)
const
419 assert(nb_voisins_attendus == 1 || nb_voisins_attendus == 2);
421 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
422 const int nb_sommets_par_face = faces_element_reference(0).dimension(0) ? faces_element_reference(0).dimension(1) : 3;
423 const int_t num_premiere_face = faces_sommets.dimension(0);
424 const int_t nb_elem_reels = elem_faces.dimension(0);
425 frontiere.fixer_num_premiere_face(num_premiere_face);
427 const Faces_t& faces_frontiere = frontiere.faces();
428 const IntTab_t& sommets_faces_fr = faces_frontiere.les_sommets();
429 const int_t nb_faces = faces_frontiere.nb_faces();
430 SmallArrOfTID_t une_face(nb_sommets_par_face);
431 SmallArrOfTID_t voisins;
433 ArrOfInt_t liste_faces_erreur0;
435 ArrOfInt_t liste_faces_erreur1;
437 ArrOfInt_t liste_faces_erreur2;
439 ArrOfInt_t liste_faces_erreur3;
441 constexpr bool STOP_FIRST_ERR =
false;
444 for (i_face = 0; i_face < nb_faces; i_face++)
447 int nb_sommets_par_face_fr= (int)sommets_faces_fr.dimension(1);
448 for (
int i = 0; i < std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i++)
449 une_face[i] = sommets_faces_fr(i_face, i);
450 for (
int i = std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i < nb_sommets_par_face; i++)
454 find_adjacent_elements(som_elem, une_face, voisins);
455 const int_t nb_voisins = voisins.size_array();
456 const int_t elem0 = (nb_voisins > 0) ? voisins[0] : -1;
457 const int_t elem1 = (nb_voisins > 1) ? voisins[1] : -1;
458 const int_t indice_face =
459 ajouter_une_face(une_face, elem0, elem1, faces_sommets, faces_voisins);
466 liste_faces_erreur0.append_array(indice_face);
467 if(STOP_FIRST_ERR)
Process::exit(
"A least one face has no neighbor!");
473 if (nb_voisins_attendus == nb_voisins)
476 for (i_voisin = 0; i_voisin < nb_voisins; i_voisin++)
478 const int_t elem = voisins[i_voisin];
480 const int i_face_elem = chercher_face_element(une_face, elem);
481 if (i_face_elem >= 0)
484 if (elem < nb_elem_reels)
486 if (elem_faces(elem, i_face_elem) < 0)
487 elem_faces(elem, i_face_elem) = indice_face;
491 liste_faces_erreur3.append_array(indice_face);
492 if(STOP_FIRST_ERR)
Process::exit(
"A face already exists! Was found twice!");
499 liste_faces_erreur0.append_array(indice_face);
500 if(STOP_FIRST_ERR)
Process::exit(
"A face does not belong to any element!");
507 liste_faces_erreur1.append_array(indice_face);
508 if(STOP_FIRST_ERR)
Process::exit(
"A face has an unexpected number of neighbors!");
514 liste_faces_erreur2.append_array(indice_face);
515 if(STOP_FIRST_ERR)
Process::exit(
"A face has more than 2 neighbors!");
520 msg += frontiere.
le_nom();
521 msg +=
"\" contains faces which do not belong to any element.";
522 check_erreur_faces(msg, liste_faces_erreur0);
525 msg += frontiere.
le_nom();
526 msg +=
"\" contains faces that belong to ";
527 msg +=
Nom(3-nb_voisins_attendus);
528 msg +=
" elements.\n";
529 switch(nb_voisins_attendus)
532 msg +=
"These faces should have only 1 neighbouring element.";
535 msg +=
"These faces should have 2 neighbouring elements.";
538 msg =
"Internal error.";
540 if (sub_type(Joint, frontiere))
546 msg +=
"(Error in a Joint object: internal error in the mesh splitter or scatter ? )\n";
548 check_erreur_faces(msg, liste_faces_erreur1);
551 msg += frontiere.
le_nom();
552 msg +=
"\" contains faces that belong to more than 2 elements.\n";
553 check_erreur_faces(msg, liste_faces_erreur2);
556 msg += frontiere.
le_nom();
557 msg +=
"\" contains faces that already exist in another boundary or in this one.\n";
558 check_erreur_faces(msg, liste_faces_erreur3);
566template <
typename _SIZE_>
567void Faces_builder_32_64<_SIZE_>::creer_faces_internes(IntTab_t& faces_sommets,
568 IntTab_t& elem_faces,
569 IntTab_t& faces_voisins)
const
571 const IntTab_t& elem_som = les_elements();
572 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
574 const int_t nb_elem = elem_som.dimension(0);
575 const int nb_faces_par_element = faces_element_reference(0).dimension(0);
576 const int nb_sommets_par_face = nb_faces_par_element ? faces_element_reference(0).dimension(1) : 3;
580 SmallArrOfTID_t une_face(nb_sommets_par_face);
582 SmallArrOfTID_t voisins;
586 ArrOfInt_t liste_faces_frontiere_non_declarees;
588 ArrOfInt_t liste_faces_joint_non_declarees;
593 ArrOfInt_t liste_faces_erreurs_connectivite;
595 constexpr bool STOP_FIRST_ERR =
false;
599 for (i_elem = 0; i_elem < nb_elem; i_elem++)
603 for (i_face = 0; i_face < nb_faces_par_element; i_face++)
608 int_t indice_face = elem_faces(i_elem, i_face);
613 const IntTab& faces_elem_ref = faces_element_reference(i_elem);
615 for (i = 0; i < nb_sommets_par_face; i++)
618 const int i_som_ref = faces_elem_ref(i_face, i);
624 const int_t i_som = elem_som(i_elem, i_som_ref);
631 elem_faces(i_elem, i_face) = -1;
637 find_adjacent_elements(som_elem, une_face, voisins);
639 const int_t nb_voisins = voisins.size_array();
640 assert (nb_voisins > 0);
645 assert(voisins[0] == i_elem);
647 if (indice_face >= 0)
655 indice_face = ajouter_une_face(une_face, i_elem, -1,
656 faces_sommets, faces_voisins);
657 liste_faces_frontiere_non_declarees.append_array(indice_face);
662 else if (nb_voisins == 2)
665 const int_t elem0 = voisins[0];
666 const int_t elem1 = voisins[1];
667 assert(elem0 < elem1);
668 if (indice_face >= 0)
680 indice_face = ajouter_une_face(une_face, elem0, elem1,
681 faces_sommets, faces_voisins);
684 const int i_face_elem1 = chercher_face_element(une_face, elem1);
685 if (i_face_elem1 >= 0)
688 elem_faces(elem1, i_face_elem1) = indice_face;
695 liste_faces_erreurs_connectivite.append_array(indice_face);
696 if(STOP_FIRST_ERR)
Process::exit(
"Connectivity issue with face!");
698 if (elem1 >= nb_elem)
702 liste_faces_joint_non_declarees.append_array(indice_face);
703 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: its neighbor is virtual! Should not happen here.");
708 assert(elem1 == i_elem);
709 indice_face = ajouter_une_face(une_face, elem0, elem1,
710 faces_sommets, faces_voisins);
716 liste_faces_erreurs_connectivite.append_array(indice_face);
717 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: connectivity error.");
726 const int_t elem0 = voisins[0];
727 const int_t elem1 = voisins[1];
728 indice_face = ajouter_une_face(une_face, elem0, elem1,
729 faces_sommets, faces_voisins);
731 liste_faces_erreurs_connectivite.append_array(indice_face);
732 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: connectivity error 2.");
737 assert(indice_face >= 0);
738 elem_faces(i_elem, i_face) = indice_face;
745 const char *
const msg1 =
"We found faces which belong to one element/cell only and are not declared in any boundary ! You forgot to define at least one boundary in your mesh. Fix your mesh.\n";
746 const char *
const msg2 =
"Joint faces are incomplete: internal error in the mesh splitter\n";
747 const char *
const msg3 =
"Connectivity error in the mesh elements. Possible errors:\n- one face of one element belongs to more than 2 elements\n- two element have at least 3 common nodes but these nodes are not faces of these elements\n";
748 check_erreur_faces(msg1, liste_faces_frontiere_non_declarees);
749 check_erreur_faces(msg2, liste_faces_joint_non_declarees);
750 check_erreur_faces(msg3, liste_faces_erreurs_connectivite);
759template <
typename _SIZE_>
760void Faces_builder_32_64<_SIZE_>::identification_groupe_faces(Groupe_Faces_t& groupe_faces,
761 const IntTab_t& elem_faces)
const
763 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
764 const int nb_sommets_par_face = faces_element_reference(0).dimension(0) ? faces_element_reference(0).dimension(1) : 3;
766 const Faces_t& faces_specifiees = groupe_faces.faces();
767 const IntTab_t& sommets_faces_fr = faces_specifiees.les_sommets();
768 const int_t nb_faces = faces_specifiees.nb_faces();
769 ArrOfInt_t& indices_faces = groupe_faces.get_indices_faces();
770 indices_faces.resize_array(nb_faces);
772 SmallArrOfTID_t une_face(nb_sommets_par_face);
773 SmallArrOfTID_t voisins;
775 ArrOfInt_t liste_faces_erreur0;
777 ArrOfInt_t liste_faces_erreur1;
780 for (
int i_face = 0; i_face < nb_faces; i_face++)
783 int nb_sommets_par_face_fr= (int)sommets_faces_fr.dimension(1);
784 for (
int i = 0; i < std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i++)
785 une_face[i] = sommets_faces_fr(i_face, i);
786 for (
int i = std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i < nb_sommets_par_face; i++)
790 find_adjacent_elements(som_elem, une_face, voisins);
791 const int_t nb_voisins = voisins.size_array();
798 liste_faces_erreur0.append_array(i_face);
804 const int_t elem = voisins[0];
806 const int i_face_elem = chercher_face_element(une_face, elem);
808 if (i_face_elem >= 0)
810 indices_faces[i_face] = elem_faces(elem,i_face_elem);
815 liste_faces_erreur1.append_array(i_face);
820 msg =
"Group of Faces \"";
821 msg += groupe_faces.
le_nom();
822 msg +=
"\" contains faces which do not belong to any element or not virtual element.";
823 check_erreur_faces(msg, liste_faces_erreur0);
825 msg =
"Group of Faces \"";
826 msg += groupe_faces.
le_nom();
827 msg +=
"\" contains faces that belong to more than 2 elements.\n";
828 check_erreur_faces(msg, liste_faces_erreur1);
IntTab_t & voisins()
Renvoie le tableau des voisins (des faces).
const IntTab_t & les_sommets() const
Renvoie le tableau des sommets de toutes les faces.
classe outil pour construire les faces d'un domaine (utilisee uniquement pour creer les tableau des f...
Joints_32_64< _SIZE_ > Joints_t
IntTab_T< _SIZE_ > IntTab_t
Bords_32_64< _SIZE_ > Bords_t
Frontiere_32_64< _SIZE_ > Frontiere_t
SmallArrOfTID_T< _SIZE_ > SmallArrOfTID_t
Groupes_Faces_32_64< _SIZE_ > Groupes_Faces_t
static int chercher_face_element(const IntTab_t &elem_som, const IntTab &faces_element_ref, const SmallArrOfTID_t &une_face, const int_t elem)
Static_Int_Lists_32_64< _SIZE_ > Static_Int_Lists_t
Faces_32_64< _SIZE_ > Faces_t
Bords_Internes_32_64< _SIZE_ > Bords_Internes_t
ArrOfInt_T< _SIZE_ > ArrOfInt_t
Raccords_32_64< _SIZE_ > Raccords_t
Poly_geom_base_32_64< _SIZE_ > Poly_geom_base_t
Joint_32_64< _SIZE_ > Joint_t
Groupe_Faces_32_64< _SIZE_ > Groupe_Faces_t
void creer_faces_reeles(Domaine_t &domaine, const Static_Int_Lists_t &connect_som_elem, Faces_t &les_faces, IntTab_t &elem_faces)
A partir de la description des elements du domaine et des frontieres (bords, raccords,...
Domaine_32_64< _SIZE_ > Domaine_t
int_t num_premiere_face() const
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
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...
ArrOfInt_t & set_items_communs()
Renvoie le tableau items_communs_ pour le remplir.
class Nom Une chaine de caractere pour nommer les objets de TRUST
const Nom & le_nom() const override
Renvoie *this;.
virtual int_t get_somme_nb_faces_elem() const =0
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
int_t get_nb_lists() const
renvoie le nombre de listes stockees
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const