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();
64template <
typename _SIZE_>
70 les_elements_ptr_ = & domaine.les_elems();
72 connectivite_som_elem_ptr_ = & connect_som_elem;
74 assert(connect_som_elem.
get_nb_lists() == domaine.nb_som_tot());
79 if (sub_type(Poly_geom_base,domaine.type_elem().valeur()))
84 domaine.type_elem()->get_tab_faces_sommets_locaux(faces_element_reference_old_);
97 faces_sommets_ = faces_sommets;
98 face_elem_ = faces_voisins;
99 ref_domaine_ = domaine;
108 const int_t nb_elements = les_elements().dimension(0);
109 const int nb_faces_par_element = faces_element_reference(0).dimension(0);
110 elem_faces.
resize(nb_elements, nb_faces_par_element);
113 const int nb_sommets_par_face = faces_element_reference(0).
dimension(1);
116 const int_t nb_faces_front = domaine.nb_faces_frontiere() + domaine.nb_faces_joint();
117 int_t nb_faces_prevision = (nb_elements * nb_faces_par_element + nb_faces_front) / 2;
127 faces_sommets.
resize(nb_faces_prevision, nb_sommets_par_face);
128 faces_sommets.
resize(0, nb_sommets_par_face);
130 faces_voisins.
resize(nb_faces_prevision, 2);
131 faces_voisins.
resize(0, 2);
138 Bords_t& bords = domaine.faces_bord();
139 const int n = bords.size();
140 for (
int i = 0; i < n; i++)
144 creer_faces_frontiere(1,
153 Raccords_t& raccords = domaine.faces_raccord();
154 const int n = raccords.size();
155 for (
int i = 0; i < n; i++)
158 creer_faces_frontiere(1,
169 const int n = faces_int.size();
170 for (
int i = 0; i < n; i++)
173 creer_faces_frontiere(2,
186 Cerr <<
"Faces_builder_32_64<_SIZE_>::creer_faces_reeles not coded for the internal faces of boundary" << finl;
194 Joints_t& joints = domaine.faces_joint();
195 const int n = joints.size();
196 for (
int i = 0; i < n; i++)
199 creer_faces_frontiere(2,
212 for (
int_t i2 = 0; i2 < nb_faces; i2++)
213 indices_faces[i2] = num_premiere_face + i2;
220 creer_faces_internes(faces_sommets,
228 const int n = groupes_faces.size();
229 for (
int i = 0; i < n; i++)
232 identification_groupe_faces(groupe_faces,
238 if (faces_sommets.
dimension(0) != nb_faces_prevision)
240 Cerr <<
"Error in Faces_builder_32_64<_SIZE_>::creer_faces_reeles:\n"
241 <<
" number of faces does not match predicted number of faces.\n"
242 <<
" (problem with faces_bords_internes ?)" << finl;
260template <
typename _SIZE_>
261void Faces_builder_32_64<_SIZE_>::check_erreur_faces(
const char * message,
262 const ArrOfInt_t& liste_faces)
const
264 const int nmax = 100;
265 int_t n = liste_faces.size_array();
268 Cerr <<
"==========================" << finl;
269 Cerr <<
"Error!" << finl << message
270 <<
"\nSee log file of this PE for detailed info."
273 J <<
"Error in Faces_builder_32_64<_SIZE_>::creer_faces_*\n"
277 J <<
"Too many faces to display (" << n <<
") display only " << nmax <<
" first faces" << finl;
281 J <<
"Display format:\n"
282 <<
" facenumber = face index in faces_sommet array\n"
283 <<
" som1..som4 = node index\n"
284 <<
" elem1 elem2 = neighbouring element number\n"
285 <<
"facenumber som1 (x1 y1 z1) som2 (x2 y2 z2) [som3 (x3 y3 z3)...] elem1 elem2" << finl;
287 const DoubleTab_t& coord = ref_domaine_->coord_sommets();
288 const IntTab_t& faces = faces_sommets_.valeur();
289 const IntTab_t& face_elem = face_elem_.valeur();
291 const int_t nb_som_faces = faces.dimension(1);
292 for (i = 0; i < n; i++)
295 const int_t iface = liste_faces[i];
296 sptr += snprintf(sptr, 100,
"%4ld ",(
long) iface);
297 for (
int j = 0; j < nb_som_faces; j++)
299 const int_t isom = faces(iface,j);
300 sptr += snprintf(sptr, 100,
"%5ld(", (
long)isom);
301 for (
int k = 0; k < dim; k++)
303 sptr += snprintf(sptr, 100,
"%10.6f", coord(isom, k));
304 sptr += snprintf(sptr, 100,
")");
306 sptr += snprintf(sptr, 100,
"%4ld %4ld", (
long)face_elem(iface,0),(
long) face_elem(iface,1));
309 NettoieNoeuds_t::verifie_noeuds(ref_domaine_.valeur());
317template <
typename _SIZE_>
318_SIZE_ Faces_builder_32_64<_SIZE_>::ajouter_une_face(
const SmallArrOfTID_t& une_face,
321 IntTab_t& faces_sommets,
322 IntTab_t& faces_voisins)
325 const int_t num_new_face = faces_sommets.dimension(0);
326 const int nb_sommets_par_face = (int)faces_sommets.dimension(1);
327 const int_t new_size = num_new_face + 1;
329 assert(une_face.size_array() == nb_sommets_par_face);
330 faces_sommets.resize(new_size, nb_sommets_par_face);
331 for (i = 0; i < nb_sommets_par_face; i++)
332 faces_sommets(num_new_face, i) = une_face[i];
334 faces_voisins.resize(new_size, 2);
335 faces_voisins(num_new_face, 0) = elem0;
336 faces_voisins(num_new_face, 1) = elem1;
341template <
typename _SIZE_>
343 const IntTab& faces_element_ref,
347 const int nb_faces_element = (int)faces_element_ref.
dimension(0);
348 const int nb_sommets_par_face = (int)faces_element_ref.
dimension(1);
350 int i_face, i_som2, i_som;
351 for (i_face = 0; i_face < nb_faces_element; i_face++)
353 for (i_som = 0; i_som < nb_sommets_par_face; i_som++)
355 const int sommet_elem_ref = faces_element_ref(i_face, i_som);
356 int_t sommet_domaine ;
357 if (sommet_elem_ref==-1)
360 sommet_domaine = elem_som(elem, sommet_elem_ref);
361 for (i_som2 = 0; i_som2 < nb_sommets_par_face; i_som2++)
362 if (une_face[i_som2] == sommet_domaine)
364 if (i_som2 == nb_sommets_par_face)
367 if (i_som == nb_sommets_par_face)
370 if (i_face == nb_faces_element)
376template <
typename _SIZE_>
377const IntTab& Faces_builder_32_64<_SIZE_>::faces_element_reference(int_t elem)
const
381 const Poly_geom_base_t& poly =ref_cast(Poly_geom_base_t,ref_domaine_->type_elem().valeur());
382 IntTab& elem_ref_mod=ref_cast_non_const(IntTab,faces_element_reference_old_);
383 poly.get_tab_faces_sommets_locaux(elem_ref_mod,elem);
388 return faces_element_reference_old_;
398template <
typename _SIZE_>
400 const int_t elem)
const
402 const IntTab_t& elem_som = les_elements();
403 const IntTab& faces_element_ref = faces_element_reference(elem);
404 int i_face = chercher_face_element(elem_som, faces_element_ref, une_face, elem);
418template <
typename _SIZE_>
419void Faces_builder_32_64<_SIZE_>::creer_faces_frontiere(
const int_t nb_voisins_attendus,
420 Frontiere_t& frontiere,
421 IntTab_t& faces_sommets,
422 IntTab_t& faces_voisins,
423 IntTab_t& elem_faces)
const
425 assert(nb_voisins_attendus == 1 || nb_voisins_attendus == 2);
427 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
428 const int nb_sommets_par_face = faces_element_reference(0).dimension(0) ? faces_element_reference(0).dimension(1) : 3;
429 const int_t num_premiere_face = faces_sommets.dimension(0);
430 const int_t nb_elem_reels = elem_faces.dimension(0);
431 frontiere.fixer_num_premiere_face(num_premiere_face);
433 const Faces_t& faces_frontiere = frontiere.faces();
434 const IntTab_t& sommets_faces_fr = faces_frontiere.les_sommets();
435 const int_t nb_faces = faces_frontiere.nb_faces();
436 SmallArrOfTID_t une_face(nb_sommets_par_face);
437 SmallArrOfTID_t voisins;
439 ArrOfInt_t liste_faces_erreur0;
441 ArrOfInt_t liste_faces_erreur1;
443 ArrOfInt_t liste_faces_erreur2;
445 ArrOfInt_t liste_faces_erreur3;
447 constexpr bool STOP_FIRST_ERR =
false;
450 for (i_face = 0; i_face < nb_faces; i_face++)
453 int nb_sommets_par_face_fr= (int)sommets_faces_fr.dimension(1);
454 for (
int i = 0; i < std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i++)
455 une_face[i] = sommets_faces_fr(i_face, i);
456 for (
int i = std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i < nb_sommets_par_face; i++)
460 find_adjacent_elements(som_elem, une_face, voisins);
461 const int_t nb_voisins = voisins.size_array();
462 const int_t elem0 = (nb_voisins > 0) ? voisins[0] : -1;
463 const int_t elem1 = (nb_voisins > 1) ? voisins[1] : -1;
464 const int_t indice_face =
465 ajouter_une_face(une_face, elem0, elem1, faces_sommets, faces_voisins);
472 liste_faces_erreur0.append_array(indice_face);
473 if(STOP_FIRST_ERR)
Process::exit(
"A least one face has no neighbor!");
479 if (nb_voisins_attendus == nb_voisins)
482 for (i_voisin = 0; i_voisin < nb_voisins; i_voisin++)
484 const int_t elem = voisins[i_voisin];
486 const int i_face_elem = chercher_face_element(une_face, elem);
487 if (i_face_elem >= 0)
490 if (elem < nb_elem_reels)
492 if (elem_faces(elem, i_face_elem) < 0)
493 elem_faces(elem, i_face_elem) = indice_face;
497 liste_faces_erreur3.append_array(indice_face);
498 if(STOP_FIRST_ERR)
Process::exit(
"A face already exists! Was found twice!");
505 liste_faces_erreur0.append_array(indice_face);
506 if(STOP_FIRST_ERR)
Process::exit(
"A face does not belong to any element!");
513 liste_faces_erreur1.append_array(indice_face);
514 if(STOP_FIRST_ERR)
Process::exit(
"A face has an unexpected number of neighbors!");
520 liste_faces_erreur2.append_array(indice_face);
521 if(STOP_FIRST_ERR)
Process::exit(
"A face has more than 2 neighbors!");
526 msg += frontiere.
le_nom();
527 msg +=
"\" contains faces which do not belong to any element.";
528 check_erreur_faces(msg, liste_faces_erreur0);
531 msg += frontiere.
le_nom();
532 msg +=
"\" contains faces that belong to ";
533 msg +=
Nom(3-nb_voisins_attendus);
534 msg +=
" elements.\n";
535 switch(nb_voisins_attendus)
538 msg +=
"These faces should have only 1 neighbouring element.";
541 msg +=
"These faces should have 2 neighbouring elements.";
544 msg =
"Internal error.";
546 if (sub_type(Joint, frontiere))
551 msg +=
"(Error in a Joint object: internal error in the mesh splitter or scatter ? )\n";
553 check_erreur_faces(msg, liste_faces_erreur1);
556 msg += frontiere.
le_nom();
557 msg +=
"\" contains faces that belong to more than 2 elements.\n";
558 check_erreur_faces(msg, liste_faces_erreur2);
561 msg += frontiere.
le_nom();
562 msg +=
"\" contains faces that already exist in another boundary or in this one.\n";
563 check_erreur_faces(msg, liste_faces_erreur3);
571template <
typename _SIZE_>
572void Faces_builder_32_64<_SIZE_>::creer_faces_internes(IntTab_t& faces_sommets,
573 IntTab_t& elem_faces,
574 IntTab_t& faces_voisins)
const
576 const IntTab_t& elem_som = les_elements();
577 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
579 const int_t nb_elem = elem_som.dimension(0);
580 const int nb_faces_par_element = faces_element_reference(0).dimension(0);
581 const int nb_sommets_par_face = nb_faces_par_element ? faces_element_reference(0).dimension(1) : 3;
584 SmallArrOfTID_t une_face(nb_sommets_par_face);
586 SmallArrOfTID_t voisins;
589 ArrOfInt_t liste_faces_frontiere_non_declarees;
591 ArrOfInt_t liste_faces_joint_non_declarees;
596 ArrOfInt_t liste_faces_erreurs_connectivite;
598 constexpr bool STOP_FIRST_ERR =
false;
602 for (i_elem = 0; i_elem < nb_elem; i_elem++)
606 for (i_face = 0; i_face < nb_faces_par_element; i_face++)
611 int_t indice_face = elem_faces(i_elem, i_face);
616 const IntTab& faces_elem_ref = faces_element_reference(i_elem);
618 for (i = 0; i < nb_sommets_par_face; i++)
621 const int i_som_ref = faces_elem_ref(i_face, i);
627 const int_t i_som = elem_som(i_elem, i_som_ref);
634 elem_faces(i_elem, i_face) = -1;
640 find_adjacent_elements(som_elem, une_face, voisins);
642 const int_t nb_voisins = voisins.size_array();
643 assert (nb_voisins > 0);
648 assert(voisins[0] == i_elem);
650 if (indice_face >= 0)
658 indice_face = ajouter_une_face(une_face, i_elem, -1,
659 faces_sommets, faces_voisins);
660 liste_faces_frontiere_non_declarees.append_array(indice_face);
665 else if (nb_voisins == 2)
668 const int_t elem0 = voisins[0];
669 const int_t elem1 = voisins[1];
670 assert(elem0 < elem1);
671 if (indice_face >= 0)
683 indice_face = ajouter_une_face(une_face, elem0, elem1,
684 faces_sommets, faces_voisins);
687 const int i_face_elem1 = chercher_face_element(une_face, elem1);
688 if (i_face_elem1 >= 0)
691 elem_faces(elem1, i_face_elem1) = indice_face;
697 liste_faces_erreurs_connectivite.append_array(indice_face);
698 if(STOP_FIRST_ERR)
Process::exit(
"Connectivity issue with face!");
700 if (elem1 >= nb_elem)
704 liste_faces_joint_non_declarees.append_array(indice_face);
705 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: its neighbor is virtual! Should not happen here.");
710 assert(elem1 == i_elem);
711 indice_face = ajouter_une_face(une_face, elem0, elem1,
712 faces_sommets, faces_voisins);
717 liste_faces_erreurs_connectivite.append_array(indice_face);
718 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: connectivity error.");
727 const int_t elem0 = voisins[0];
728 const int_t elem1 = voisins[1];
729 indice_face = ajouter_une_face(une_face, elem0, elem1,
730 faces_sommets, faces_voisins);
732 liste_faces_erreurs_connectivite.append_array(indice_face);
733 if(STOP_FIRST_ERR)
Process::exit(
"Pb with face: connectivity error 2.");
738 assert(indice_face >= 0);
739 elem_faces(i_elem, i_face) = indice_face;
746 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";
747 const char *
const msg2 =
"Joint faces are incomplete: internal error in the mesh splitter\n";
748 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";
749 check_erreur_faces(msg1, liste_faces_frontiere_non_declarees);
750 check_erreur_faces(msg2, liste_faces_joint_non_declarees);
751 check_erreur_faces(msg3, liste_faces_erreurs_connectivite);
760template <
typename _SIZE_>
761void Faces_builder_32_64<_SIZE_>::identification_groupe_faces(Groupe_Faces_t& groupe_faces,
762 const IntTab_t& elem_faces)
const
764 const Static_Int_Lists_t& som_elem = connectivite_som_elem();
765 const int nb_sommets_par_face = faces_element_reference(0).dimension(0) ? faces_element_reference(0).dimension(1) : 3;
767 const Faces_t& faces_specifiees = groupe_faces.faces();
768 const IntTab_t& sommets_faces_fr = faces_specifiees.les_sommets();
769 const int_t nb_faces = faces_specifiees.nb_faces();
770 ArrOfInt_t& indices_faces = groupe_faces.get_indices_faces();
771 indices_faces.resize_array(nb_faces);
773 SmallArrOfTID_t une_face(nb_sommets_par_face);
774 SmallArrOfTID_t voisins;
776 ArrOfInt_t liste_faces_erreur0;
778 ArrOfInt_t liste_faces_erreur1;
781 for (
int i_face = 0; i_face < nb_faces; i_face++)
784 int nb_sommets_par_face_fr= (int)sommets_faces_fr.dimension(1);
785 for (
int i = 0; i < std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i++)
786 une_face[i] = sommets_faces_fr(i_face, i);
787 for (
int i = std::min(nb_sommets_par_face, nb_sommets_par_face_fr); i < nb_sommets_par_face; i++)
791 find_adjacent_elements(som_elem, une_face, voisins);
792 const int_t nb_voisins = voisins.size_array();
799 liste_faces_erreur0.append_array(i_face);
805 const int_t elem = voisins[0];
807 const int i_face_elem = chercher_face_element(une_face, elem);
809 if (i_face_elem >= 0)
811 indices_faces[i_face] = elem_faces(elem,i_face_elem);
816 liste_faces_erreur1.append_array(i_face);
821 msg =
"Group of Faces \"";
822 msg += groupe_faces.
le_nom();
823 msg +=
"\" contains faces which do not belong to any element or not virtual element.";
824 check_erreur_faces(msg, liste_faces_erreur0);
826 msg =
"Group of Faces \"";
827 msg += groupe_faces.
le_nom();
828 msg +=
"\" contains faces that belong to more than 2 elements.\n";
829 check_erreur_faces(msg, liste_faces_erreur1);
IntTab_t & voisins()
Returns the array of neighbors (of the faces).
const IntTab_t & les_sommets() const
Returns the array of vertices of all faces.
Helper class for building the faces of a domain. (used only to create the arrays of real faces).
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)
From the description of the domain elements and boundaries (borders, connections, face groups,...
Domaine_32_64< _SIZE_ > Domaine_t
int_t num_premiere_face() const
int_t nb_faces() const
Returns the number of faces of the boundary.
Joint_Items_t & set_joint_item(JOINT_ITEM type)
Returns the joint information for a given geometric item type, for filling the structures.
ArrOfInt_t & set_items_communs()
Returns the items_communs_ array for filling.
class Nom: a character string for naming TRUST objects.
const Nom & le_nom() const override
Returns *this.
virtual int_t get_somme_nb_faces_elem() const =0
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Base class for output streams.
int_t get_nb_lists() const
Returns the number of stored lists.
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