16#include <Marching_Cubes.h>
17#include <TRUST_Deriv.h>
18#include <Marching_Cubes_data.h>
21#include <Domaine_VF.h>
24#include <Rectangle_2D_axi.h>
29#include <Comm_Group.h>
30#include <communications.h>
31#include <Array_tools.h>
38 Cerr <<
"Erreur : Marching_Cubes::readOn n'est pas code." << finl;
45 Cerr <<
"Erreur : Marching_Cubes::printOn n'est pas code." << finl;
52 const Domaine& domaine = domaine_vf.
domaine();
53 ref_domaine_vf_ = domaine_vf;
73 DoubleVect& indicatrice_approchee,
75 int ignorer_collision)
const
109 if (!ref_domaine_vf_)
111 Cerr <<
"Marching_Cubes::construire_iso : Erreur :" << finl;
112 Cerr <<
" Aucun domaine n'a ete associe a Marching_Cubes" << finl;
144 DoubleTab& coord_noeuds = maillage.
sommets_;
149 indicatrice_approchee, phase);
151 if (resultat_ok || ignorer_collision)
172 def_noeud, maillage);
191 for (
int i = 0; i < nb_sommets; i++)
195 const int elem = (pe_owner == moi) ? def_noeud(i, 3) : -1;
196 const int face = def_noeud(i, 4);
212 Journal() <<
"Marching_Cubes::construire_iso" << finl;
220 Journal() <<
"Marching_Cubes::construire_iso erreur: collision avec une interface existante" << finl;
252 DoubleVect& indicatrice_approchee,
254 DoubleTab& eval_expression_sommets,
255 int ignorer_collision)
const
259 if (!ref_domaine_vf_)
261 Cerr <<
"Marching_Cubes::construire_iso : Erreur :" << finl;
262 Cerr <<
" Aucun domaine n'a ete associe a Marching_Cubes" << finl;
267 std::string expr_chaine(expression);
276 const Domaine& domaine = ref_domaine_vf_->domaine();
277 const int nb_sommets = domaine.nb_som();
279 for (
int i = 0; i < nb_sommets; i++)
282 x = domaine.coord(i, 0);
283 y = domaine.coord(i, 1);
285 z = domaine.coord(i, 2);
290 double valeur = parser.
eval();
291 eval_expression_sommets(i) = valeur;
296 const int ok =
construire_iso(eval_expression_sommets, isovaleur, maillage, indicatrice_approchee, phase,
312 const Elem_geom_base& elem_geom = domaine.type_elem().valeur();
314 const int (*def_aretes)[2]=0;
315 const int (*def_aretes_faces)[2]=0;
316 const int *nb_facettes=0;
317 const int *facettes=0;
319 int nb_cas_marching_cubes=0;
325 if (sub_type(Rectangle, elem_geom))
333 nb_cas_marching_cubes = 16;
335 def_aretes = mcubes_def_aretes_vdf_2d;
336 def_aretes_faces = mcubes_def_aretes_faces_vdf_2d;
337 nb_facettes = mcubes_nb_facettes_vdf_2d;
338 facettes = mcubes_facettes_vdf_2d;
341 else if (sub_type(Triangle, elem_geom))
349 nb_cas_marching_cubes = 8;
351 def_aretes = mcubes_def_aretes_vef_2d;
352 def_aretes_faces = mcubes_def_aretes_faces_vef_2d;
353 nb_facettes = mcubes_nb_facettes_vef_2d;
354 facettes = mcubes_facettes_vef_2d;
357 else if (sub_type(Tetraedre, elem_geom))
365 nb_cas_marching_cubes = 16;
367 def_aretes = mcubes_def_aretes_vef_3d;
368 def_aretes_faces = mcubes_def_aretes_faces_vef_3d;
369 nb_facettes = mcubes_nb_facettes_vef_3d;
370 facettes = mcubes_facettes_vef_3d;
373 else if (sub_type(Hexaedre, elem_geom))
381 nb_cas_marching_cubes = 256;
383 def_aretes = mcubes_def_aretes_vdf_3d;
384 def_aretes_faces = mcubes_def_aretes_faces_vdf_3d;
385 nb_facettes = mcubes_nb_facettes_vdf_3d;
386 facettes = mcubes_facettes_vdf_3d;
391 Cerr <<
"Erreur dans Marching_Cubes::remplir_data_marching_cubes :" << finl;
392 Cerr <<
" l'element geometrique " << elem_geom.
que_suis_je();
393 Cerr <<
" n'est pas pris en charge." << finl;
419 for (i = 0; i < nb_cas_marching_cubes ; i++)
422 int n = nb_facettes[i];
431 for (i = 0; i < index; i++)
433 assert(facettes[i] == -1);
445 const int nb_joints = domaine.nb_joints();
446 renum_virt_loc_.dimensionner(nb_joints);
450 for (
int num_joint = 0; num_joint < nb_joints; num_joint++)
457 const Joint& joint = domaine.joint(num_joint);
459 IntTab& renum_sorted = renum_virt_loc_[num_joint];
460 const int nb_sommets_joint = renum_unsorted.
dimension(0);
464 renum_sorted = renum_unsorted;
466 using pair = std::array<int, 2>;
467 pair* ptr =
reinterpret_cast<pair*
>(renum_sorted.
addr());
468 std::sort(ptr, ptr+nb_sommets_joint, [&](
const pair& p1,
const pair& p2)
470 return (p1[0]<p2[0]);
473 const int PE_voisin = joint.
PEvoisin();
487 ArrOfInt& num_sommets)
const
491 assert(indice_joint >= 0);
493 const IntTab& renum_virt_loc = renum_virt_loc_[indice_joint];
494 const int dernier_sommet_joint = renum_virt_loc.
dimension(0) - 1;
495 const int nb_sommets = num_sommets.
size_array();
497 for(
int i = 0; i < nb_sommets; i++)
499 const int numero_distant = num_sommets[i];
502 int max = dernier_sommet_joint;
507 milieu = (min + max) >> 1;
508 valeur = renum_virt_loc(milieu, 0);
509 if (numero_distant > valeur)
511 else if (numero_distant < valeur)
517 assert(renum_virt_loc(min, 0) == numero_distant);
518 const int numero_local = renum_virt_loc(min, 1);
519 num_sommets[i] = numero_local;
529 const double isovaleur,
530 ArrOfBit& signe)
const
534 const int nb_sommets = ref_domaine_vf_->nb_som();
535 assert(valeurs_sommets.
size() == nb_sommets);
539 for(i = 0; i < nb_sommets; i++)
540 if (valeurs_sommets[i] - isovaleur > 0.)
560 DoubleVect& indicatrice_approchee,
564 int arete, elem, sommet;
566 const Domaine& domaine = ref_domaine_vf_->domaine();
568 const IntTab& elem_virt_pe_num = domaine.elem_virt_pe_num();
570 const IntTab& elem_sommets = domaine.les_elems();
571 const int nb_elements_reels = domaine.nb_elem();
572 const int nb_elem_tot = domaine.nb_elem_tot();
573 const int nb_sommets_reels = domaine.nb_som();
581 numero_noeud_arete = -1;
600 for (elem = 0; elem < nb_elem_tot; elem++)
603 int cas_marching_cubes = 0;
608 const int n = elem_sommets(elem, sommet);
609 numero_sommet[sommet] = n;
611 if (n < nb_sommets_reels)
616 cas_marching_cubes += s * facteur;
622 cas_marching_cubes = -1;
626 signe_sommet[sommet] = s;
629 if (elem < nb_elements_reels)
631 assert(cas_marching_cubes >= 0);
633 if (cas_marching_cubes == 0)
635 else if (cas_marching_cubes == numero_dernier_cas)
643 indicatrice_approchee[elem] = indic;
648 if (indic == (1. - (
double)phase))
652 else if (indicatrice_approchee[elem] != (1. - (
double)phase))
660 indicatrice_approchee[elem] = indic;
666 cas_marching_cubes = -1;
671 if (cas_marching_cubes == 0 || cas_marching_cubes == numero_dernier_cas)
674 int numero_element_a_stocker = elem;
675 int PE_element = mon_PE;
676 if (elem >= nb_elements_reels)
679 numero_element_a_stocker = -1;
680 PE_element = elem_virt_pe_num(elem - nb_elements_reels,
692 numero_noeud_arete[arete] = -1;
695 const int signe1 = signe_sommet[s1];
696 const int signe2 = signe_sommet[s2];
700 if (signe1 != signe2 && signe1 >= 0 && signe2 >= 0)
702 numero_noeud_arete[arete] = nb_noeuds;
703 int n1 = numero_sommet[s1];
704 int n2 = numero_sommet[s2];
713 def_noeud.
resize(nb_noeuds+1, 5);
714 def_noeud(nb_noeuds, 0) = n1;
715 def_noeud(nb_noeuds, 1) = n2;
716 def_noeud(nb_noeuds, 2) = PE_element;
717 def_noeud(nb_noeuds, 3) = nb_noeuds;
718 def_noeud(nb_noeuds, 4) = numero_element_a_stocker;
724 if (elem < nb_elements_reels)
737 for (j = 0; j < dim; j++)
740 const int numero_noeud = numero_noeud_arete[larete];
741 assert(numero_noeud >= 0);
742 facettes(nb_facettes, j) = numero_noeud;
762 const IntTab& faces_sommets,
763 const int nb_faces_a_traiter,
765 IntTab& def_noeud)
const
771 static ArrOfInt numero_noeud_arete;
773 numero_noeud_arete = -1;
775 static ArrOfInt numero_sommet;
778 static ArrOfInt signe_sommet;
783 for (
int face = 0; face < nb_faces_a_traiter; face++)
789 const int n = faces_sommets(face, sommet);
790 const int s = signe[n];
791 numero_sommet[sommet] = n;
792 signe_sommet[sommet] = s;
806 const int signe1 = signe_sommet[s1];
807 const int signe2 = signe_sommet[s2];
808 if (signe1 != signe2)
810 const int nb_noeuds = def_noeud.
dimension(0);
811 numero_noeud_arete[arete] = nb_noeuds;
812 int n1 = numero_sommet[s1];
813 int n2 = numero_sommet[s2];
822 def_noeud.
resize(nb_noeuds+1, 5);
823 def_noeud(nb_noeuds, 0) = n1;
824 def_noeud(nb_noeuds, 1) = n2;
825 def_noeud(nb_noeuds, 2) = numero_PE;
826 def_noeud(nb_noeuds, 3) = nb_noeuds;
827 if (numero_PE == nb_procs)
829 def_noeud(nb_noeuds, 4) = face;
832 def_noeud(nb_noeuds, 4) = -1;
839 IntTab& def_noeud)
const
841 const Domaine_VF& domaine_vf = ref_domaine_vf_.valeur();
846 const IntTab& faces_sommets = domaine_vf.
face_sommets();
869 tri_lexicographique_tableau(def_noeud);
873 using quintuplet = std::array<int, 5>;
874 quintuplet* ptr =
reinterpret_cast<quintuplet*
>(def_noeud.
addr());
875 std::sort(ptr, ptr+nb_noeuds);
879 Cerr <<
"Marching_Cubes::trier_les_noeuds wrong dimension" << finl;
902 const Domaine_VF& domaine_vf = ref_domaine_vf_.valeur();
904 const int nb_noeuds = def_noeud.
dimension(0);
905 ArrOfInt renumerotation(nb_noeuds);
917 int dernier_som0 = -1;
918 int dernier_som1 = -1;
919 int dernier_PEvoisin_ajoute = -1;
922 enum {NOEUD_REEL, NOEUD_VIRTUEL} type_noeud = NOEUD_REEL;
929 int keep_last_node = 1;
931 for (noeud = 0; noeud < nb_noeuds; noeud++)
933 const int noeud_som0 = def_noeud(noeud, 0);
934 const int noeud_som1 = def_noeud(noeud, 1);
935 const int noeud_PE = def_noeud(noeud, 2);
936 const int noeud_ancien_numero = def_noeud(noeud, 3);
937 const int noeud_ligne_contact = (noeud_PE == nb_procs);
938 const int noeud_elem_ou_face = def_noeud(noeud, 4);
940 const int noeud_face = noeud_ligne_contact ? noeud_elem_ou_face : -1;
943 if (noeud_ligne_contact)
946 assert(face_voisins(noeud_face, 0) == -1
947 || face_voisins(noeud_face, 1) == -1);
949 face_voisins(noeud_face, 0) + face_voisins(noeud_face, 1) + 1;
953 noeud_element = noeud_elem_ou_face;
957 if (noeud_som0 != dernier_som0 || noeud_som1 != dernier_som1)
963 if (dernier >= 0 && type_noeud == NOEUD_VIRTUEL)
966 const int pe_owner = def_noeud(dernier, 2);
974 def_noeud(dernier, 0) = dernier_som0 = noeud_som0;
975 def_noeud(dernier, 1) = dernier_som1 = noeud_som1;
976 def_noeud(dernier, 2) = noeud_PE;
977 def_noeud(dernier, 3) = noeud_element;
978 def_noeud(dernier, 4) = noeud_face;
980 if (noeud_PE != mon_PE)
984 type_noeud = NOEUD_VIRTUEL;
991 type_noeud = NOEUD_REEL;
992 dernier_PEvoisin_ajoute = noeud_PE;
1000 if (type_noeud == NOEUD_REEL)
1002 if (noeud_PE == nb_procs)
1006 def_noeud(dernier, 3) = noeud_element;
1007 def_noeud(dernier, 4) = noeud_face;
1009 else if (noeud_PE != dernier_PEvoisin_ajoute)
1014 dernier_PEvoisin_ajoute = noeud_PE;
1019 if (noeud_PE == mon_PE)
1022 renumerotation[noeud_ancien_numero] = dernier;
1026 if (dernier >= 0 && type_noeud == NOEUD_VIRTUEL)
1029 const int pe_owner = def_noeud(dernier, 2);
1040 def_noeud.
resize(dernier, 5);
1049 ArrOfInt& tab = facettes;
1053 for (i = 0; i < nb_sommets; i++)
1055 int num_sommet = tab[i];
1056 num_sommet = renumerotation[num_sommet];
1057 assert(num_sommet > -1);
1058 tab[i] = num_sommet;
1098 IntTab cles(def_noeud);
1105 const ArrOfInt& pe_voisins = esp_virtuel.
pe_voisins();
1106 const int nb_pe_voisins = pe_voisins.
size_array();
1109 IntTabFT temp_renum;
1111 ArrOfIntFT nouvel_espace_virtuel;
1113 for(index_pe = 0; index_pe < nb_pe_voisins; index_pe++)
1116 const int pe_voisin = pe_voisins[index_pe];
1117 const ArrOfInt& elements = esp_virtuel.
elements(pe_voisin);
1118 const int nb_elements = elements.
size_array();
1120 cles_pe.
resize(nb_elements, 3);
1121 temp_renum.
resize(nb_elements, 2);
1128 for (
int i = 0; i < nb_elements; i++)
1130 const int n = elements[i];
1131 temp_renum(i, 0) = cles(n, 0);
1132 temp_renum(i, 1) = cles(n, 1);
1139 for (
int i = 0; i < nb_elements; i++)
1142 int s0 = temp_renum(i, 0);
1143 int s1 = temp_renum(i, 1);
1160 tri_lexicographique_tableau(cles_pe);
1165 for (
int i = 0; i < nb_elements; i++)
1167 const int element = elements[i];
1170 assert(cles_pe(i, 0) == def_noeud(element, 0));
1171 assert(cles_pe(i, 1) == def_noeud(element, 1));
1174 int position = cles_pe(i, 2);
1175 nouvel_espace_virtuel[position] = element;
1178 esp_virtuel.
set_elements(pe_voisin, nouvel_espace_virtuel);
1193 const double isovaleur,
1194 const IntTab& def_noeud,
1198 const DoubleTab& coord_ = ref_domaine_vf_->domaine().coord_sommets();
1199 const int nb_noeuds = def_noeud.
dimension(0);
1200 DoubleTab& coord_noeuds = maillage.
sommets_;
1205 for (noeud = 0; noeud < nb_noeuds; noeud++)
1208 int s0 = def_noeud(noeud, 0);
1209 int s1 = def_noeud(noeud, 1);
1210 double valeur0 = valeurs_sommets(s0);
1211 double valeur1 = valeurs_sommets(s1);
1213 double alpha = (isovaleur - valeur0) / (valeur1 - valeur0);
1215 if (alpha < 0.) alpha = 0.;
1216 if (alpha > 1.) alpha = 1.;
1218 coord_noeuds(noeud, 0) = coord_(s0,0)*(1.-alpha)+coord_(s1,0)*alpha;
1219 coord_noeuds(noeud, 1) = coord_(s0,1)*(1.-alpha)+coord_(s1,1)*alpha;
1221 coord_noeuds(noeud, 2) = coord_(s0,2)*(1.-alpha)+coord_(s1,2)*alpha;
ArrOfBit_32_64 & resize_array(int_t n)
Change la taille du tableau et copie les donnees existantes.
void setbit(int_t i) const
Met le bit e a 1.
: class Desc_Structure_FT
void echange_espace_virtuel(ArrOfDouble &tab) const
Descripteur_FT & espace_virtuel()
Renvoie une reference non-const a l'espace virtuel.
Descripteur_FT & espace_distant()
Renvoie une reference non-const a l'espace distant.
void calcul_schema_comm(const int nb_items_tot)
void remplir_element_pe(ArrOfInt &element_pe) const
remplit le tableau qui donne pour chaque element le numero du pe proprietaire.
: class Descripteur_FT Descripteur_FT stocke pour chaque PE une liste de numeros d'elements.
void set_elements(int PE_voisin, const ArrOfInt &elements)
Remplace la liste des elements par celle en parametre.
int ajoute_element(int PE_voisin, int element)
Ajoute l'element au tableau du PE_voisin.
const ArrOfInt & elements(int pe_voisin) const
Renvoie la liste des elements distants/virtuels du pe en parametre.
const ArrOfInt & pe_voisins() const
Renvoie la liste des PE pour lesquels la liste d'elements est non vide, dans l'ordre croissant des nu...
void calcul_liste_pe_voisins()
Calcule la liste des PEs dont la liste d'elements est non vide, tries dans l'ordre croissant de numer...
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
const IntTab_t & renum_virt_loc() const
: class Maillage_FT_Disc Cette classe decrit un maillage:
void corriger_proprietaires_facettes()
Sans changer les sommets existants ni la numerotation des facettes, on change le proprietaire des fac...
ArrOfIntFT sommet_PE_owner_
Desc_Structure_FT desc_facettes_
ArrOfIntFT sommet_face_bord_
Desc_Structure_FT desc_sommets_
void maillage_modifie(Statut_Maillage nouveau_statut)
Cette methode change le statut du maillage et invalide le cache de valeurs calculees (surface,...
ArrOfIntFT sommet_num_owner_
ArrOfIntFT drapeaux_sommets_
void reset()
vide toutes les structures du maillage, le statut passe a RESET.
int construire_noeuds_et_facettes(const ArrOfBit &signe, IntTab &def_noeud, IntTab &facettes, DoubleVect &indicatrice_approchee, const Maillage_FT_Disc::AjoutPhase phase) const
void construire_noeuds_uniques(IntTab &def_noeud, Maillage_FT_Disc &maillage) const
ArrOfIntFT mcubes_nb_facettes
void remplir_data_marching_cubes(const Domaine &domaine)
void calculer_coord_noeuds(const DoubleVect &valeurs_sommets, const double isovaleur, const IntTab &def_noeud, Maillage_FT_Disc &maillage) const
void correspondance_espaces_distant_virtuel(const IntTab &def_noeud, Desc_Structure_FT &desc) const
void remplir_renum_virt_loc(const Domaine &domaine)
void trier_les_noeuds(IntTab &def_noeud) const
int construire_iso(const DoubleVect &valeurs_sommets, double isovaleur, Maillage_FT_Disc &maillage, DoubleVect &indicatrice_approchee, const Maillage_FT_Disc::AjoutPhase phase, int ignorer_collision=0) const
Construction d'un maillage en segments ou en triangles comme l'isovaleur d'une fonction discretisee a...
void renum_sommets_dist_loc(const int pe_voisin, ArrOfInt &num_sommets) const
void construire_noeuds_joints(const ArrOfBit &signe, IntTab &def_noeud) const
void construire_noeuds_liste_faces(const ArrOfBit &signe, const IntTab &faces_sommets, const int nb_faces_a_traiter, const int numero_PE, IntTab &def_noeud) const
Ajout des sommets situes sur des faces (bords ou joints) dans le tableau def_noeud.
void calculer_signe(const DoubleVect &valeurs_sommets, const double isovaleur, ArrOfBit &signe) const
IntTabFT mcubes_def_aretes_faces
ArrOfIntFT mcubes_facettes
void associer_domaine_vf(const Domaine_VF &domaine_vf)
ArrOfIntFT mcubes_index_facettes
IntTabFT mcubes_def_aretes
class Nom Une chaine de caractere pour nommer les objets de TRUST
classe Objet_U Cette classe est la classe de base des Objets de TRUST
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.
Representation des donnees de la classe Parser.
void addVar(const char *)
void setVar(const char *sv, double val)
virtual void parseString()
static double mp_min(double)
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
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.
Classe de base des flux de sortie.
_SIZE_ size_array() const
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_tot(int) const override
_SIZE_ dimension(int d) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")