// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2021 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . #include "Mail_initiale_Gmsh.h" // pour le tableau de connection herezh -> gmsh #include "Visualisation_Gmsh.h" #include #include "ReferenceNE.h" #include "ReferenceAF.h" #include "CharUtil.h" #include "GeomPoint.h" // CONSTRUCTEURS : // par defaut Mail_initiale_Gmsh::Mail_initiale_Gmsh () : // OrdreVisu("","visualisation des maillages initiaux","") OrdreVisu(".................................maillage initiale" ,"visualisation des maillages initiaux","mi") ,tabtab_sous_mesh(),tabli_sig_elem(),tabli_sous_mesh() ,decal_noeud(),decal_element(),nb_total_noeud(0),nb_total_element(0) ,nb_total_ref(0),tab_nom_tag_ref(),lesRefInitiales(),tab_num_tag(),t_jonction_N_Nelem() ,nombre_noeud_ref_pti(0),nombre_ref_pti(0),t_jonction_N_NelemPti() ,t_Egmsh(),tab_dim_de_ref() ,considerer_homothetie(false),t_homothetie(),t_orig(),t_fact_mult() ,sortie_des_references(1) {}; // constructeur de copie Mail_initiale_Gmsh::Mail_initiale_Gmsh (const Mail_initiale_Gmsh& ord) : OrdreVisu(ord),tabtab_sous_mesh(ord.tabtab_sous_mesh) ,tabli_sig_elem(ord.tabli_sig_elem) ,tabli_sous_mesh(ord.tabli_sous_mesh) ,decal_noeud(ord.decal_noeud),decal_element(ord.decal_element) ,nb_total_noeud(ord.nb_total_noeud),nb_total_element(ord.nb_total_element) ,nb_total_ref(ord.nb_total_ref),lesRefInitiales(ord.lesRefInitiales),tab_nom_tag_ref(ord.tab_nom_tag_ref) ,tab_num_tag(ord.tab_num_tag) ,t_jonction_N_Nelem(ord.t_jonction_N_Nelem) ,nombre_noeud_ref_pti(ord.nombre_noeud_ref_pti),nombre_ref_pti(ord.nombre_ref_pti) ,t_jonction_N_NelemPti() ,tab_dim_de_ref(ord.tab_dim_de_ref) ,t_Egmsh(ord.t_Egmsh) ,considerer_homothetie(ord.considerer_homothetie) ,t_homothetie(ord.t_homothetie),t_orig(ord.t_orig),t_fact_mult(ord.t_fact_mult) ,sortie_des_references(ord.sortie_des_references) {}; // DESTRUCTEUR : Mail_initiale_Gmsh::~Mail_initiale_Gmsh () {}; // METHODES PUBLIQUES : // initialisation : permet d'initialiser les différents paramètres de l'ordre // lors d'un premier passage des différents incréments // en virtuelle, a priori est défini si nécessaire dans les classes dérivées void Mail_initiale_Gmsh::Initialisation(ParaGlob * paraGlob,LesMaillages * lesmail,LesReferences* lesRef ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage,Charge* charge ,LesCondLim* lesCondLim,LesContacts* lesContacts ,Resultats* resultats,EnumTypeIncre type_incre,int incre ,const map < string, const double * , std::less >& listeVarGlob ,const List_io < TypeQuelconque >& listeVecGlob ,bool fil_calcul) { int nb_maillage = lesmail->NbMaillage(); if (!fil_calcul) {// initialisation des tableaux tabtab_sous_mesh.Change_taille(nb_maillage); tabli_sig_elem.Change_taille(nb_maillage); tabli_sous_mesh.Change_taille(nb_maillage); }; //appel de l'ordre d'initialisation de la classe mère OrdreVisu::Initialisation(paraGlob,lesmail,lesRef,lesLoisDeComp,diversStockage,charge ,lesCondLim,lesContacts,resultats,type_incre,incre ,listeVarGlob,listeVecGlob,fil_calcul); // la sortie du maillage initial est a priori obligatoire donc on effectue le choix par défaut // de la classe mère, par contre on laisse l'interactif pour l'interne OrdreVisu::ChoixOrdre(); // appel de la méthode de la classe mère // Mail_initiale_Gmsh::ChoixOrdre(); if (!fil_calcul) {// on calcule le décalage de numéros de noeud, du au fait qu'il peut y avoir plusieurs maillages decal_noeud.Change_taille(nb_maillage); decal_element.Change_taille(nb_maillage); int decal_n = 0; int decal_e=0; // variables intermédiaires for (int nm=1;nm<=nb_maillage;nm++) {decal_noeud(nm)=decal_n; decal_element(nm)=decal_e; decal_n += lesmail->Nombre_noeud(nm); decal_e += lesmail->Nombre_element(nm); }; // on enregistre le nombre total de noeud et le nombre total d'éléments nb_total_noeud = decal_n; nb_total_element = decal_e; // on va également calculer le nombre maxi de référence qui existent nb_total_ref=0; // init const Reference* premref = lesRef->Init_et_Premiere(); if (premref != NULL) nb_total_ref++; while (lesRef->Reference_suivante() != NULL) nb_total_ref++; // def des homothétie éventuelles t_homothetie.Change_taille(nb_maillage); t_orig.Change_taille(nb_maillage); t_fact_mult.Change_taille(nb_maillage); int dim = ParaGlob::Dimension(); for(int i=1;i<= nb_maillage;i++) {t_orig(i).Change_dim(dim); t_fact_mult(i).Change_dim(dim);}; // on construit le tableau des noms de référence qui seront sorties éventuellement // on définit un numéro pour chaque référence lue, en fait le numéro d'ordre tab_nom_tag_ref.Change_taille(nb_total_ref); // stockage des noms // --on balaie les ref int itab=1; // donne un numéro d'ordre pour les références const Reference* refcourante = lesRef->Init_et_Premiere(); lesRefInitiales.Change_taille(nb_total_ref); while (refcourante != NULL) { // on définie un nom qui contient le nom de la ref + le nom du maillage (son num) string nom_mail = lesmail->NomMaillage(refcourante->Nbmaille()); tab_nom_tag_ref(itab) = refcourante->Nom()+" " +nom_mail+"("+ChangeEntierSTring(refcourante->Nbmaille())+")"; lesRefInitiales(itab)=refcourante; itab++; refcourante = lesRef->Reference_suivante(); }; }; }; // execution de l'ordre // tab_mail : donne les numéros de maillage concerné // incre : numéro d'incrément qui en cours // type_incre : indique si c'est le premier le dernier ou l'incrément courant a visualiser ou pas // animation : indique si l'on est en animation ou pas // unseul_incre : indique si oui ou non il y a un seul increment à visualiser void Mail_initiale_Gmsh::ExeOrdre(ParaGlob * ,const Tableau & tab_mail,LesMaillages * lesMail,bool ,LesReferences* lesRef,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim* // ,LesContacts*,Resultats*,ostream & sort,EnumTypeIncre type_incre,int incre ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre // ,bool animation) ,bool,const map < string, const double * , std::less >& ,const List_io < TypeQuelconque >& listeVecGlob) {// --- la partie qui suie est systématiquement exécutée, que ce soit actif, ou pas et quelque soit l'incrément -- // constitue une initialisation pour les autres ordres, mais que l'on ne peut pas mettre dans Mail_initiale_Gmsh::Initialisation // car dépend de tab_mail, qui dépend du choix de l'utilisateur // on recalcule les décalages de noeuds en fonction des maillages actifs, car c'est utilisé par les isovaleurs et autres // ordres, les maillages qui ne sont pas concerné, ont des décal_noe et éléments inchangé donc quelconques, ceci permet de garder les mêmes tailles int decal_n = 0; int decal_e=0; // variables intermédiaires int nbmail = tab_mail.Taille(); for (int nm=1;nm<=nbmail;nm++) {int numMail=tab_mail(nm); decal_noeud(numMail)=decal_n; decal_element(numMail)=decal_e; decal_n += lesMail->Nombre_noeud(numMail); decal_e += lesMail->Nombre_element(numMail); }; // on ré_enregistre le nombre total de noeud et le nombre total d'éléments nb_total_noeud = decal_n; nb_total_element = decal_e; if (incre==0) // dans tous les cas on sort le maillage initiale au premier incrément {ostream &sort = entreePrinc.Sort_initial_Gmsh(); // --- pour l'instant, on prend l'option de sortir comme avec Gid, tout dans un seul maillag // il est possible de lire plusieurs maillage avec gmsh, mais il faut qu'ils soient dans plusieurs fichiers, // comme la manip existe avec gid, de globaliser dans un seul fichier, par simplicité, on l'utilise // quelques rappels: pas de commentaires entre deux $quelquechoses, il peut y avoir // plusieurs jeux d'éléments, et entre deux couple $quelquechoses on peut avoir des commentaires // 1) on s'intéresse d'abord à la définition des tag de PhysicalNames // (sert pour la différentiation des maillages) if (sortie_des_references) SortieTagPhysicalNames(tab_mail,lesMail,sort); // 2) maintenant on s'intéresse aux coordonnées des noeuds pour le fichier principal sort SortieDesNoeuds(tab_mail,lesMail,sort); // 3) puis les éléments SortieDesElements(tab_mail,lesMail,sort); // 4) enfin les références if (sortie_des_references) SortieReferences(tab_mail,lesMail,entreePrinc); // et on vide le buffer de sortie sort << endl; // constitution des sous maillages, utilisé par les isovaleurs par exemple // on suit la même logique que dans gid, un sous maillage par type d'élément // ce n'est pas nécessaire, c'est pas simplicité, à modifier si nécessaire par la suite CreaSousMaillages(tab_mail,lesMail); }; //-- fin de if ((actif)&&(incre==0)) }; // sortie maillage initiale (sans références ni tag) avec le nouveau format void Mail_initiale_Gmsh::sortie_maillage_initial(const Tableau & tab_mail ,LesMaillages * lesMail, ostream &sort) { // écriture d'une entete locale sort << "\n // ============================================================" << "\n // | definition des noeuds des maillages |" << "\n // ============================================================"; sort << "\n$Nodes "; // mot clé de début des noeuds: sort << "\n " << nb_total_noeud ; // sortie sur le flot passé en paramètre, de la partie noeud du maillage sans entête ni fin Sortie_noeuds_initiaux(tab_mail,lesMail,sort); // fin des noeuds sort << "\n$EndNodes "; sort << "\n // ============================================================" << "\n // | definition des elements des maillages |" << "\n // ============================================================"; sort << "\n$Elements "; sort << "\n" << nb_total_element; // sortie sur le flot passé en paramètre, de la partie élément du maillage sans entête ni fin Sortie_element_initiaux(tab_mail,lesMail,sort); sort << "\n$EndElements"; // et on vide le buffer de sortie sort << endl; }; // sortie de la définition des tag de PhysicalNames (sert pour les références) void Mail_initiale_Gmsh::SortieTagPhysicalNames(const Tableau & tab_mail,LesMaillages * lesMail ,ostream &sort) { // au niveau des PhysicalNames qui seront utilisées pour les éléments, on en a trois disponibles // 1 -> the number of the physical entity : on s'en sert pour le numéro de maillage // 2 -> the number of the elementary geometrical entity : on s'en sert pour le numéro d'élément local // 3 -> the number of a mesh partition : = 0 on s'en sert pas pour l'instant, pourra servir éventuellement lorsque // on voudra faire du calcul // ?? // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas Tableau t_a_sortir(lesMail->NbMaillage(),false); int nb_a_sortir = tab_mail.Taille(); for (int isa = 1; isa <= nb_a_sortir; isa++) t_a_sortir(tab_mail(isa))=true; // on définit un numéro pour chaque référence lue, en fait le numéro d'ordre // modif le tableau tab_nom_tag: est définit dans l'initialisation, normalement il ne change // pas en cours de calcul // tab_nom_tag_ref.Change_taille(nb_total_ref); // stockage des noms tab_dim_de_ref.Change_taille(nb_total_ref); // stockage dimension des ref tab_num_tag.Change_taille(nb_total_ref); // stockage des numéros de maillages associés // --on balaie les ref int nbmail = tab_mail.Taille(); // le nombre de maillage à sortir int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); // on définie un nom qui contient le nom de la ref + le nom du maillage (son num) string nom_mail = lesMail->NomMaillage(refcourante->Nbmaille()); // modif: le tableau tab_nom_tag: est définit dans l'initialisation, normalement il ne change // pas en cours de calcul // tab_nom_tag_ref(itab) = refcourante->Nom()+" " // +nom_mail+"("+ChangeEntierSTring(refcourante->Nbmaille())+")"; tab_num_tag(itab) = itab+nbmail; // on décale de nbmail, car il y a un tag/maillage avant les références switch (refcourante->Indic()) { case 1: case 6: tab_dim_de_ref(itab) = 0; break ; // ref de point case 2: // ref d'élément: on récupère le premier élément pour voir le type { const ReferenceNE * refi = ((ReferenceNE *) refcourante); const Tableau& tt = refi->Tab_num (); if(tt.Taille() != 0) { const Element& ele = lesMail->Element_LesMaille_const(refi->Nbmaille(),refi->Numero(1)); switch (Type_geom_generique(ele.Id_geometrie())) { case LIGNE : tab_dim_de_ref(itab) = 1; break ; // ref de ligne case SURFACE : tab_dim_de_ref(itab) = 2; break ; // ref de surface case VOLUME : tab_dim_de_ref(itab) = 3; break ; // ref de volume default: tab_dim_de_ref(itab) = 0; break ;// autres cas pas pris en compte dans gmsh }; }; break; } case 3: tab_dim_de_ref(itab) = 2; break ; // ref de surface case 4: tab_dim_de_ref(itab) = 1; break ; // ref d'arrêtes default: tab_dim_de_ref(itab) = 0; break ;// autres cas pas pris en compte dans gmsh }; // on traite en fonction du type de référence switch (refcourante->Indic()) { case 5: // =5 -> des noeuds relatifs à des éléments { } break; // =6 -> de points d'intégrations relatifs à des éléments /* case 6: // indic = 6 : il s'agit de reference de point d'intégration { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); int num_maille = ref1->Nbmaille(); if (t_a_sortir(num_maille)) for (int i=1;i<=taille;i++) { int numElem = ref1->NumeroElem(i); // on redimentionne au cas où Element& elem = lesMail->Element_LesMaille(num_maille,numElem); // récup de l'élément const ElemGeomC0& elgeom = elem.ElementGeometrique_const(); t_ref_arete(num_maille)(numElem).Change_taille(elgeom.NonS().Taille()); // sauvegarde du numero d'arête t_ref_arete(num_maille)(numElem)(ref1->NumeroFA(i)).push_back(itab); }; break; }*/ // pas traiter par gmsh }; }; // fin A) // B) -- sortie des PhysicalNames // doc gmsh // $PhysicalNames // number-of-names // physical-dimension physical-number "physical-name" // ... // $EndPhysicalNames sort << "\n$PhysicalNames "; // def du nombre total de physical entity c'est-à-dire de maillage à sortir sort << "\n " << (nbmail+nb_total_ref); //// sort << "\n " << nbmail; for (int i=1;i<=nbmail;i++) // 3 c'est pour une dimension 3 par défaut, c'est possible que cela pose des pb dans le cas de maillages 2D sort << "\n 3 " << i << " \"" << lesMail->NomMaillage(tab_mail(i)) << "\" "; // maintenant on boucle sur les noms de référence for (int i=1;i<= nb_total_ref;i++) { sort << "\n " << tab_dim_de_ref(i) << " " << tab_num_tag(i) << " \"" << tab_nom_tag_ref(i) << "\" "; }; sort << "\n$EndPhysicalNames "; return; }; // sortie uniquement des noeuds avec éventuellement, def de noeud aux points d'intégration void Mail_initiale_Gmsh::SortieDesNoeuds(const Tableau & tab_mail,LesMaillages * lesMail , ostream &sort) { // --- pour l'instant, on prend l'option de sortir comme avec Gid, tout dans un seul maillage // il est possible de lire plusieurs maillage avec gmsh, mais il faut qu'ils soient dans plusieurs fichiers, // comme la manip existe avec gid, de globaliser dans un seul fichier, par simplicité, on l'utilise // par contre on met des ref différentes ce qui permettra de départager au moment de la visualisation // doc gmsh // $Nodes // number-of-nodes // node-number x-coord y-coord z-coord // ... // $EndNodes // ---- on s'intéresse tout d'abord aux références de points d'intégrations s'il en existe // la première étape étant de compter les noeuds // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas Tableau t_a_sortir(lesMail->NbMaillage(),false); int nb_a_sortir = tab_mail.Taille(); for (int isa = 1; isa <= nb_a_sortir; isa++) t_a_sortir(tab_mail(isa))=true; nombre_noeud_ref_pti = 0; nombre_ref_pti = 0; int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); if (t_a_sortir(numMail)) {Tableau enum_geo; // les énuméré de la géométrie des éléments à sortir Tableau tab_inter; // tableau de travail switch (refcourante->Indic()) { case 6: // on ne s'intéresse qu'aux références de points d'intégration { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); nombre_noeud_ref_pti += ref1->Taille(); nombre_ref_pti++; }; break; }; }; }; // écriture d'une entete locale sort << "\n // ============================================================" << "\n // | definition des noeuds des maillages |" << "\n // ============================================================"; sort << "\n$Nodes "; // mot clé de début des noeuds: if (sortie_des_references) {sort << "\n " << nb_total_noeud + nombre_noeud_ref_pti;} // nombre total de noeuds des éléments else {sort << "\n " << nb_total_noeud ;}; // sortie sur le flot passé en paramètre, de la partie noeud du maillage sans entête ni fin Sortie_noeuds_initiaux(tab_mail,lesMail,sort); // ---- on s'intéresse maintenant aux références de points d'intégrations s'il en existe // et si il est prévu de les sortir // on met la procédure dans un test, pour le cas où il y aurait des refs illicites donc qui ne pourraient pas se visualiser try { int dim = ParaGlob::Dimension(); // récup de la dimension if (sortie_des_references) {int num_courant_noeud_Pti = 1; int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); if (t_a_sortir(numMail)) {Tableau enum_geo; // les énuméré de la géométrie des éléments à sortir Tableau tab_inter; // tableau de travail switch (refcourante->Indic()) { case 6: // on ne s'intéresse qu'aux références de points d'intégration { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); for (int i=1;i<=taille;i++) // on parcours la liste { int numElem = ref1->NumeroElem(i); int numPti = ref1->NumeroFA(i); // on redimentionne au cas où Element& elem = lesMail->Element_LesMaille(numMail,numElem); // récup de l'élément // on récupère les coodonnées du point d'intégration bool erreur=false; Coordonnee co = elem.CoordPtInteg(TEMPS_0,SIG11,numPti,erreur); if (erreur) { cout << "\n erreur en recuperation des coordonnees du pt d'integ: " << numPti <<" de l'element "<Nom(); cout << "\n la sortie gmsh ne sera pas exploitable !! "; if(ParaGlob::NiveauImpression() > 2) { cout << "\n Mail_initiale_Gmsh::SortieDesNoeuds(...";}; cout << endl; } else // cas ok { sort << "\n" << num_courant_noeud_Pti+nb_total_noeud << " " ; // deux cas soit on applique une pseudo-homothetie ou non if (!(considerer_homothetie && t_homothetie(numMail))) { // cas sans homothetie : cas classique co.Affiche(sort,ParaGlob::NbdigdoGR()); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 1: sort << " 0. "; case 2: sort << " 0. "; }; } else // cas avec Homothetie {Coordonnee& orig = t_orig(numMail); // pour simplifier Coordonnee& fact_mult = t_fact_mult(numMail); // pour simplifier Coordonnee A(co-orig); int dim = A.Dimension(); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 3: A(3) *= fact_mult(3); case 2: A(2) *= fact_mult(2); case 1: A(1) *= fact_mult(1); }; A +=orig; A.Affiche(sort,ParaGlob::NbdigdoGR()); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 1: sort << " 0. "; case 2: sort << " 0. "; }; }; num_courant_noeud_Pti++; // cas ok }; }; }; break; }; }; }; }; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch (...) { cout << "\n **** erreur en sortie des references de noeud, l'operation a generee une erreur, sans doute une numerotation " << " dans le fichier d'entree de maillage ? le fichier resultat (maillage initiale) ne sera pas correct !! " << endl; if (ParaGlob::NiveauImpression() > 4 ) cout << "\n Mail_initiale_Gmsh::SortieDesNoeuds(... "; }; // fin des noeuds sort << "\n$EndNodes "; return; }; // sortie uniquement des éléments, y compris les éléments points éventuellement void Mail_initiale_Gmsh::SortieDesElements(const Tableau & tab_mail,LesMaillages * lesMail ,ostream &sort) { // --- pour l'instant, on prend l'option de sortir comme avec Gid, tout dans un seul maillage // il est possible de lire plusieurs maillage avec gmsh, mais il faut qu'ils soient dans plusieurs fichiers, // comme la manip existe avec gid, de globaliser dans un seul fichier, par simplicité, on l'utilise // par contre on met des ref différentes ce qui permettra de départager au moment de la visualisation //doc gmsh // $Elements // number-of-elements // elm-number elm-type number-of-tags < tag > ... node-number-list // ... // $EndElements // // number-of-tags // gives the number of integer tags that follow for the n-th element. By default, the first tag is the number // of the physical entity to which the element belongs; the second is the number of the elementary geometrical // entity to which the element belongs; the third is the number of mesh partitions to which the element belongs, // followed by the partition ids (negative partition ids indicate ghost cells). A zero tag is equivalent to no tag. // écriture d'une entete locale (sous maillage nb im) // (il n'est pas possible d'écrire des infos dans le corps de la liste des éléments) sort << "\n // ============================================================" << "\n // | definition des elements des maillages |" << "\n // ============================================================"; sort << "\n$Elements "; // ----- on s'occupe du tableau de liaison entre les éléments herezh des maillages et les numéros associés de gmsh // ce tableau est également utilisé par d'autre classes, il est donc initialisé ici // t_Egmsh(im)(ie): donne pour le maillage im, et pour l'élément ie, le numéro gmsh de l'élément int nbmail = tab_mail.Taille(); t_Egmsh.Change_taille(nbmail); // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas Tableau t_a_sortir(lesMail->NbMaillage(),false); int nb_a_sortir = tab_mail.Taille(); for (int isa = 1; isa <= nb_a_sortir; isa++) t_a_sortir(tab_mail(isa))=true; // -on commence par dénombrer l'ensemble des éléments des références, l'idée est ensuite de sortir des éléments correspondants // aux différentes références // pour les ref de noeuds, on définit un tableau de bool, de dimension le nombre de noeud permettant de savoir les noeuds // qui sont réellement utilisé dans les références, Tableau > t_no_utilise(lesMail->NbMaillage()); for (int i=1;i<=nbmail;i++) t_no_utilise(tab_mail(i)).Change_taille(lesMail->Nombre_noeud(tab_mail(i)),0); // a) on compte le nombre d'éléments de face et segment, qui servent dans les ref // et on remplit le tableau t_no_utilise int nb_total_elemRef = 0; {int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); Tableau & no_utilise= t_no_utilise(numMail); // pour simplifier if (t_a_sortir(numMail)) {switch (refcourante->Indic()) { case 3: case 4: // 3 et 4 -> surfaces et segments relatives à des éléments, { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); nb_total_elemRef += ref1->Taille(); break; } case 1: // ref de points: ici il s'agit uniquement de remplir le tableau t_no_utilise { const ReferenceNE * refi = ((ReferenceNE *) refcourante); const Tableau& tt = refi->Tab_num (); int taill_N = tt.Taille(); for (int i=1;i<=taill_N;i++) {no_utilise(tt(i))=1;}; break; } }; }; }; }; // b) maintenant on compte le nombre de noeud élément qu'il va falloir créer en plus int nb_point_elem = 0; Tableau t_tail(nbmail); // contiendra les tailles pour chaque maillage des noeuds ajouté for (int i=1;i<=nbmail;i++) { Tableau & no_utilise= t_no_utilise(tab_mail(i)); // pour simplifier int tail = no_utilise.Taille(); int t_tail_inter = 0; for (int j=1;j<=tail;j++) t_tail_inter += no_utilise(j); // on enregistre nb_point_elem += t_tail_inter; t_tail(i) = t_tail_inter; }; // -- sortie de l'entête -- if (sortie_des_references) // on sort le nombre total d'éléments (y compris les éléments de types noeuds, arêtes, faces etc.. {sort << "\n" << nb_total_element + nb_total_elemRef + nb_point_elem + nombre_noeud_ref_pti;} else {sort << "\n" << nb_total_element;}; //---------------------------------------------------------------- // cas des éléments originaux du maillage //---------------------------------------------------------------- // sortie sur le flot passé en paramètre, de la partie élément du maillage sans entête ni fin Sortie_element_initiaux(tab_mail,lesMail,sort); //---------------------------------------------------------------- // cas des références //---------------------------------------------------------------- // --maintenant on s'occupe des références qui conduisent à définir des éléments supplémentaires (ceux qui correspondent // --aux références d'arêtes, de faces: l'idée est de définir des step de visualisation: un par référence // pour cela on parcours l'ensemble des ref, et on sort les infos en conséquence // on met la procédure dans un test, pour le cas où il y aurait des refs illicites donc qui ne pourraient pas se visualiser try { if ( sortie_des_references) {// 1-- on s'occupe des ref de face, arrete dans la première passe int num_courant_element = 1; int decal_ele_sup = nb_total_element; // initialisation du décalage d'éléments supplémentaires, int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); bool modifier_t_Egmsh = false; // il s'agit d'éléments supplémentaire, donc on ne met pas à jour t_Egmsh // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); if (t_a_sortir(numMail)) {int decal_noe=decal_noeud(numMail); // pour simplifier Tableau enum_geo; // les énuméré de la géométrie des éléments à sortir Tableau tab_inter; // tableau de travail switch (refcourante->Indic()) {case 1: case 2: // cas d'une référence d'éléments et de noeud : on ne crée pas de nouveaux éléments break; // car ils existent déjà pour les éléments, on les utilisera tels quels // et pour les noeuds se sera l'opération 2 case 3: // 3 -> surfaces relatives à des éléments, {const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); for (int i=1;i<=taille;i++) // on parcours la liste { int numElem = ref1->NumeroElem(i); int numFace = ref1->NumeroFA(i); // on redimentionne au cas où Element& elem = lesMail->Element_LesMaille(numMail,numElem); // récup de l'élément const ElemGeomC0& elgeom = elem.ElementGeometrique_const(); // a) construction du tableau de noeud de l'élément Tableau& tab_noeud = elem.Tab_noeud(); // le tableau de connection local, c-a-d par rapport au tableau de noeud de l'élément const Tableau& tlocN = elgeom.Nonf()(numFace); int nbN = tlocN.Taille(); tab_inter.Change_taille(nbN); for (int e=1;e<= nbN;e++) tab_inter(e) = tab_noeud(tlocN(e)); // b) récup des énumérés et string décrivant la géométrie et l'interpolation const ElemGeomC0 & eleface = elgeom.ElemFace(numFace); SortieDunElements(true, i, sort, decal_ele_sup, tab_inter , decal_noe, eleface.TypeGeometrie(), eleface.TypeInterpolation() ,modifier_t_Egmsh, tab_num_tag(itab)); num_courant_element++; }; decal_ele_sup += taille; // on met à jour le décalage d'éléments pour les prochaines référence break; } case 4: // -> arrêtes relatives à des éléments, {const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); for (int i=1;i<=taille;i++) // on parcours la liste { int numElem = ref1->NumeroElem(i); int numArrete = ref1->NumeroFA(i); // on redimentionne au cas où Element& elem = lesMail->Element_LesMaille(numMail,numElem); // récup de l'élément const ElemGeomC0& elgeom = elem.ElementGeometrique_const(); // a) construction du tableau de noeud de l'élément Tableau& tab_noeud = elem.Tab_noeud(); // le tableau de connection local, c-a-d par rapport au tableau de noeud de l'élément const Tableau& tlocN = elgeom.NonS()(numArrete); int nbN = tlocN.Taille(); tab_inter.Change_taille(nbN); for (int e=1;e<= nbN;e++) tab_inter(e) = tab_noeud(tlocN(e)); // b) récup des énumérés et string décrivant la géométrie et l'interpolation const ElemGeomC0 & eleseg = elgeom.ElemSeg(numArrete); SortieDunElements(true, i, sort, decal_ele_sup, tab_inter , decal_noe, eleseg.TypeGeometrie(), eleseg.TypeInterpolation() ,modifier_t_Egmsh, tab_num_tag(itab)); num_courant_element++; }; decal_ele_sup += taille; // on met à jour le décalage d'éléments pour les prochaines référence break; } }; // on sort les éléments correspondants à la référence que l'on vient de parcourir } }; // 2-- on s'occupe maintenant des éléments points qu'il faut rajouter pour voir sous gmsh les références de noeud !! // on construit un tableau d'adressage indirecte : t_jonction_N_Nelem qui permettra d'utiliser ces noeuds éléments t_jonction_N_Nelem.Change_taille(lesMail->NbMaillage()); // t_jonction_N_Nelem(i)(j) donne le numéro de noeud_élément correspondant à l'ancien numéro j pour le maillage i // ne sera rempli que pour les noeuds ayant conduit à la création d'un noeud_élément // pour tous les noeud_element on utilise un numero de ref qui n'exite pas, c'est celui qui suit les ref enregistrée // il y a un pb sous gmsh au niveau des num de ref, il semblerait qu'il ne faut pas utiliser un trop grand nombre de // même valeurs donc on l'incrément dans la définition des éléments tous les 50 int num_ref_des_noeud_element = tab_num_tag.Taille() + tab_mail.Taille() + 1; for (int i=1;i<=nbmail;i++) t_jonction_N_Nelem(tab_mail(i)).Change_taille(lesMail->Nombre_noeud(tab_mail(i)),0); Tableau tab_inter(1); // tableau de travail // on parcours tous les noeuds // on crée l'élément géométrique adoc GeomPoint elpoint;int num_courant=1; bool modifier_t_Egmsh = false; for (int i=1;i<=nbmail;i++) { int num_mail = tab_mail(i); int decal_noe=decal_noeud(num_mail); // pour simplifier Tableau & no_utilise= t_no_utilise(num_mail); // pour simplifier int tail = no_utilise.Taille(); for (int j=1;j<=tail;j++) { if (no_utilise(j)) { if ((num_courant % 30) == 0) num_ref_des_noeud_element++; // pour palier un bug de gmsh tab_inter(1)= &(lesMail->Noeud_LesMaille(i,j)); SortieDunElements(true, num_courant, sort, decal_ele_sup, tab_inter , decal_noe, elpoint.TypeGeometrie(), elpoint.TypeInterpolation() ,modifier_t_Egmsh, num_ref_des_noeud_element); t_jonction_N_Nelem(num_mail)(j) = num_courant + decal_ele_sup; num_courant++; }; }; }; // 3 --- enfin on s'occupe des éléments points qu'il faut rajouter pour voir sous gmsh les références de pti // on construit un tableau d'adressage indirecte : tab_num_tag qui permettra d'utiliser ces noeuds éléments t_jonction_N_NelemPti.Change_taille(nombre_ref_pti); // t_jonction_N_NelemPti(i)(j) donne le numéro de noeud_élément correspondant au numéro de la référence // ne sera rempli que pour les noeuds ayant conduit à la création d'un noeud_élément for (int i=1;i<=nbmail;i++) { int num_courant_noeud_Pti = 1; int num_courant_ref_Pti = 0; Tableau tab_inter(1); // tableau de travail decal_ele_sup = nb_total_element + nb_total_elemRef + nb_point_elem; // on crée l'élément géométrique adoc GeomPoint elpoint; // on crée un noeud qui ne sert que pour son numéro de noeud Noeud noeu_inter(0,3,0); tab_inter(1) = &noeu_inter; bool modifier_t_Egmsh = false; // pour tous les noeud_element on utilise un numero de ref qui n'exite pas, c'est celui qui suit les ref enregistrée // int num_ref_des_noeud_element = tab_num_tag.Taille() + tab_mail.Taille() + 2; int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) { const Reference* refcourante = lesRefInitiales(itab); // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); if (t_a_sortir(numMail)) { Tableau enum_geo; // les énuméré de la géométrie des éléments à sortir switch (refcourante->Indic()) { case 6: // on ne s'intéresse qu'aux références de points d'intégration { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); num_courant_ref_Pti++; t_jonction_N_NelemPti(num_courant_ref_Pti).Change_taille(taille); for (int i=1;i<=taille;i++) // on parcours la liste { if ((num_courant_noeud_Pti % 30) == 0) num_ref_des_noeud_element++; // pour palier un bug de gmsh noeu_inter.Change_num_noeud(num_courant_noeud_Pti+nb_total_noeud); SortieDunElements(true, num_courant_noeud_Pti, sort, decal_ele_sup, tab_inter , 0, elpoint.TypeGeometrie(), elpoint.TypeInterpolation() ,modifier_t_Egmsh, num_ref_des_noeud_element); t_jonction_N_NelemPti(num_courant_ref_Pti)(i)=num_courant_noeud_Pti+decal_ele_sup; num_courant_noeud_Pti++; }; }; break; }; }; }; }; }; // fin de la sortie conditionelle sur les références } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch (...) { cout << "\n **** erreur en sortie des references d'elements, l'operation a generee une erreur, sans doute une numerotation " << " dans le fichier d'entree de maillage ? le fichier resultat (maillage initiale) ne sera pas correct !! " << endl; if (ParaGlob::NiveauImpression() > 4 ) cout << "\n Mail_initiale_Gmsh::SortieDesElements(... "; }; sort << "\n$EndElements"; // et on vide le buffer de sortie sort << endl; }; // sortie des références void Mail_initiale_Gmsh::SortieReferences(const Tableau & tab_mail,LesMaillages * lesMail ,UtilLecture & entreePrinc) { // en fait chaque référence est sortie sous forme d'un step de data // ostream &sort = entreePrinc.Sort_initial_Gmsh(); // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas Tableau t_a_sortir(lesMail->NbMaillage(),false); int nb_a_sortir = tab_mail.Taille(); for (int isa = 1; isa <= nb_a_sortir; isa++) t_a_sortir(tab_mail(isa))=true; // debug //fin debug int itab_pti=1; // donne un numéro d'ordre pour les références de pti int decal_eleRef = nb_total_element; int nbref = lesRefInitiales.Taille(); //itab=1 donne un numéro d'ordre pour les références for (int itab=1;itab<=nbref;itab++) {const Reference* refcourante = lesRefInitiales(itab); // on continu si le maillage est a sortir int numMail=refcourante->Nbmaille(); if (t_a_sortir(numMail)) {int decal_ele =decal_element(numMail); Tableau enum_geo; // les énuméré de la géométrie des éléments à sortir Tableau tab_inter; // tableau de travail // on commence par définir le fichier de sortie: soit un seul fichier, soit plusieurs fichiers ostream * sortinter=NULL; // variable intermédiaire de travail if (sortie_des_references==2) // cas de fichier indépendant {sortinter = &(entreePrinc.Sort_resultat_Gmsh(tab_nom_tag_ref(itab))); // on est obligé de sortir les noeuds et éléments pour définir le maillage à sortir en rajoutant des éléments noeuds SortieDesNoeuds(tab_mail,lesMail,*sortinter); SortieDesElements(tab_mail,lesMail,*sortinter); } else {sortinter = &(entreePrinc.Sort_initial_Gmsh());}; ostream &sort = *sortinter; // écriture d'une entete locale (sous maillage nb im) // (il n'est pas possible d'écrire des infos dans le corps de la liste des éléments) sort << "\n // ============================================================" << "\n // | references relies aux maillages |" << "\n // ============================================================"; switch (refcourante->Indic()) {case 1: // cas d'une référence de noeud { const ReferenceNE * refi = ((ReferenceNE *) refcourante); const Tableau& tt = refi->Tab_num (); int taill_N = tt.Taille(); sort << "\n // ============================================================" << "\n // | "< // ... // number-of-real-tags // < real-tag > // ... // number-of-integer-tags // < integer-tag > // ... // elm-number value ... // ... // $EndElementData sort << "\n1 \n\"" << tab_nom_tag_ref(itab)<<"\"" << "\n0 \n3 \n" << itab << "\n1 \n" << taill_N; for (int ine = 1;ine<=taill_N;ine++) sort << "\n" << t_jonction_N_Nelem(numMail)(tt(ine)) << " " << 1. << " "; sort << "\n$EndElementData "; // fin break; } case 2: // cas d'une référence d'élément { const ReferenceNE * refi = ((ReferenceNE *) refcourante); const Tableau& tt = refi->Tab_num (); int taill_N = tt.Taille(); sort << "\n // ============================================================" << "\n // | "< // ... // number-of-real-tags // < real-tag > // ... // number-of-integer-tags // < integer-tag > // ... // elm-number value ... // ... // $EndElementData sort << "\n1 \n\"" << tab_nom_tag_ref(itab)<<"\"" << "\n0 \n3 \n" << itab << "\n1 \n" << taill_N; for (int ine = 1;ine<=taill_N;ine++) sort << "\n" << tt(ine) + decal_ele << " " << 1. << " "; sort << "\n$EndElementData "; // fin break; } case 3: case 4: // cas d'une référence de face ou segment { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); sort << "\n // ============================================================" << "\n // | "< // ... // number-of-real-tags // < real-tag > // ... // number-of-integer-tags // < integer-tag > // ... // elm-number value ... // ... // $EndElementData sort << "\n1 \n\"" << tab_nom_tag_ref(itab)<<"\"" << "\n0 \n3 \n" << itab << "\n1 \n" << taille; for (int ine = 1;ine<=taille;ine++) sort << "\n" << ine + decal_eleRef << " " << 1. << " "; sort << "\n$EndElementData "; // fin decal_eleRef += taille; // on met à jour le décalage d'éléments pour les prochaines référence break; } case 6: // cas d'une référence de points d'intégration { const ReferenceAF * ref1 = ((ReferenceAF *) refcourante); int taille = ref1->Taille(); sort << "\n // ============================================================" << "\n // | "< // ... // number-of-real-tags // < real-tag > // ... // number-of-integer-tags // < integer-tag > // ... // elm-number value ... // ... // $EndElementData sort << "\n1 \n\"" << tab_nom_tag_ref(itab)<<"\"" << "\n0 \n3 \n" << itab << "\n1 \n" << taille; for (int ine = 1;ine<=taille;ine++) {sort << "\n" << t_jonction_N_NelemPti(itab_pti)(ine) << " " << 1. << " ";} sort << "\n$EndElementData "; // fin itab_pti++; // incrémente le nombre courant de ref pti pour la prochaine break; } }; }; }; }; // choix de l'ordre, cet méthode peut entraîner la demande d'informations // supplémentaires si nécessaire. qui sont ensuite gérer par la classe elle même void Mail_initiale_Gmsh::ChoixOrdre() { // demande de précision bool choix_valide = false; cout << "\n ----> preparation de la visualisation des coordonnees initiales " << "\n parametre par defaut ? : resultat brut du calcul elements finis ," << "\n pas d'homotheties sur les coordonnees initiales ," << "\n sortie des references dans un seul fichier," << "\n ---> (rep 'o') pour accepter ces parametres sinon autre "; string rep; cout << "\n reponse ? "; rep = lect_return_defaut(true,"o"); if (rep == "o") {considerer_homothetie=false; sortie_des_references=1;cout << "\n"; } else {// cas d'un choix autre que standart int nbmail = t_homothetie.Taille(); // le nombre de maillage for (int imail = 1; imail <= nbmail; imail++) { cout << "\n --- cas du maillage numero: "<< imail ; choix_valide=false; while (!choix_valide) {try { cout << "\n (0 ou f) fin modif" << "\n (1) isometries sur les coordonnees initiales ? " << "\n (2) sortie des references dans un seul fichier ou aucune ref ? " << "\n (3) sortie des ref dans des fichiers separes ou aucune ? "; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"f"); if (rep == "fin_prog") Sortie(1); // sinon int num = ChangeEntier(rep); if ((num == 0) || (rep == "f")){choix_valide=true;} else if ((num > 0)&&(num < 4)) { choix_valide=false; considerer_homothetie = true; switch (num) { case 1: // isometries sur les coordonnees initiales ? "; {bool choix_val = false; cout << "\n ---- definition d'une pseudo-homothetie sur les axes ---- "; string rep; while (!choix_val) { // on récupère la dimension int dim = ParaGlob::Dimension(); cout << "\n (0 ou f ou fin) fin modif" << "\n (1) def de l'origine de la pseudo-homothetie " << "\n (2) def des rapports d'homothetie selon les axes"; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"f"); // sinon if ((rep == "0")||(rep == "f")||(rep == "fin")) { choix_val=true; } else { // initialisation t_homothetie(imail)=true; t_orig(imail).Change_dim(dim);t_orig(imail).Zero(); t_fact_mult(imail).Change_dim(dim);t_fact_mult(imail).Zero(); t_fact_mult(imail).Ajout_meme_valeur(1.); // par défaut if (rep=="1") { cout << "\n donner l'origine de la pseudo-homothetie (" << dim << ") reels ? "; t_orig(imail).Lecture(); } else if (rep =="2") { cout << "\n donner les rapports d'homothetie selon les axes (" << dim << ") reels ? "; t_fact_mult(imail).Lecture(); } else { cout << "\n Erreur on attendait un entier entre 0 et 2 !!, " << "\n redonnez une bonne valeur"; choix_val=false; }; }; }; //-- fin du while break; } case 2: // sortie des références dans un seul fichier {bool choix_val = false; cout << "\n -- par defaut on sort les references, ce qui entraine la creation " << " de noeuds, elements (points, lignes et surfaces) supplementaires au " << " maillage initiale, ceci dans un seul fichier "; string rep; while (!choix_val) { cout << "\n (0 ou f ou fin) fin modif" << "\n (1) sortie des references dans un fichier unique, pour visualisation " << "\n (2) pas de sortie des references "; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"f"); // sinon int num = ChangeEntier(rep); if ((rep == "0")||(rep == "f")||(rep == "fin")) { choix_val=true; } else { // def du format if (num == 1) { sortie_des_references = 1;} else if (num == 2) { sortie_des_references = 0;} else { cout << "\n Erreur on attendait un entier entre 0 et 2 !!, " << "\n redonnez une bonne valeur"; choix_val=false; }; }; }; //-- fin du while break; } case 3: // sortie des références dans des fichiers sépararés {bool choix_val = false; cout << "\n -- par defaut on sort les references, ce qui entraine la creation " << " de noeuds, elements (points, lignes et surfaces) supplementaires au " << " maillage initiale, ceci dans un seul fichier "; string rep; while (!choix_val) { cout << "\n (0 ou f ou fin) fin modif" << "\n (1) sortie des references dans des fichiers separes, pour visualisation " << "\n (2) pas de sortie des references "; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"f"); // sinon int num = ChangeEntier(rep); if ((rep == "0")||(rep == "f")||(rep == "fin")) { choix_val=true; } else { // def du format if (num == 1) { sortie_des_references = 2;} else if (num == 2) { sortie_des_references = 0;} else { cout << "\n Erreur on attendait un entier entre 0 et 2 !!, " << "\n redonnez une bonne valeur"; choix_val=false; }; }; }; //-- fin du while break; } } // fin du switch (num) } // fin du else if ((num > 0)&&(num < 3)) else { cout << "\n Erreur on attendait un entier entre 0 et 3 (ou f) !!, " << "\n redonnez une bonne valeur" << "\n ou taper fin_prog pour arreter le programme"; choix_valide=false; }; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch (...)// erreur de lecture { cout << "\n Erreur on attendait un des mots cles proposés !!, " << "\n redonnez une bonne valeur" << "\n ou taper fin_prog pour arreter le programme"; choix_valide=false; }; }; //-- fin du while }; //-- fin du for(in imail }; //-- fin du if (rep != "o") du départ c'est-à-dire du cas non standart // appel de la méthode de la classe mère OrdreVisu::ChoixOrdre(); }; // lecture des paramètres de l'ordre dans un flux void Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(UtilLecture & entreePrinc) { // si dans le flot il existe l'identificateur adoc on lit sinon on passe if (strstr(entreePrinc.tablcarCVisu,"debut_maillage_initial")!=NULL) {// sauvegarde des paramètres actuelles pour l'homothetie bool considerer_homothetie_sauve = considerer_homothetie; Tableau < bool > t_homothetie_sauve(t_homothetie) ; Tableau t_orig_sauve(t_orig),t_fact_mult_sauve(t_fact_mult); int nb_maillage = t_orig.Taille(); // essaie de lecture try { string nom; (*entreePrinc.entCVisu) >> nom ; if (nom != "debut_maillage_initial") { cout << "\n Erreur en lecture des parametres du maillage initial a partir d'un fichier .CVisu," << " le premier enregistrement doit etre le mot clef: debut_maillage_initial " << " on ne tiens pas compte des parametres fournies !! "; } else { // appel de l'ordre de la classe mère OrdreVisu::Lect_para_OrdreVisu_general(entreePrinc); while (strstr(entreePrinc.tablcarCVisu,"fin_maillage_initial")==NULL) {if (strstr(entreePrinc.tablcarCVisu,"pseudo-homothetie_sur_les_maillages_")!=NULL) {(*entreePrinc.entCVisu) >> nom >> considerer_homothetie; if (nom != "pseudo-homothetie_sur_les_maillages_") { cout << "\n lecture de la pseudo-homothetie globale, on a lue ( "<< nom << " ) et on attendait pseudo-homothetie_sur_les_maillages_" << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; if (considerer_homothetie) { // cas où on veut considérer des homothétie entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement // lecture du numéro de maillage int imail = 0; // le numéro de maillage (*entreePrinc.entCVisu) >> nom >> imail; if (nom != "maillage_") { cout << "\n lecture du num de maillage, on a lue ( "<< nom << " ) et on attendait maillage_ " << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; if ((imail > nb_maillage)||(imail < 1)) // vérif de la validité du numéro de maillage // si nb maillage trop grand, erreur, on génère une erreur pour arrêter la lecture { cout << "\n erreur, le numero de maillage est errone !! nombre lu " << imail << " alors que nb_maillage enregistre: " << nb_maillage ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement // le fait qu'il y a une pseudo-homothétie pour ce maillage ou nom (*entreePrinc.entCVisu) >> nom >> t_homothetie(imail); if (nom != "pseudo-homothetie_") { cout << "\n lecture de la pseudo-homothetie, on a lue ( "<< nom << " ) et on attendait pseudo-homothetie_ " << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; // lecture conditionnelle des paramètres if (t_homothetie(imail)) { // lecture du centre entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement (*entreePrinc.entCVisu) >> nom >> t_orig(imail); if (nom != "centre_homothetie_") { cout << "\n lecture du centre de la pseudo-homothetie, on a lue ( "<< nom << " ) et on attendait centre_homothetie_ " << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; // lecture des coeffs entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement (*entreePrinc.entCVisu) >> nom >> t_fact_mult(imail); if (nom != "fact_mult_") { cout << "\n lecture du centre des facteurs, on a lue ( "<< nom << " ) et on attendait fact_mult_ " << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); }; }; entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement } else {entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement // break; }; } // fin du if existe pseudo-homothetie_sur_les_maillages_ else if (strstr(entreePrinc.tablcarCVisu,"visualisation_references_sur_les_maillages_")!=NULL) {(*entreePrinc.entCVisu) >> nom >> sortie_des_references; if (nom != "visualisation_references_sur_les_maillages_") { cout << "\n lecture de l'indicateur de visualisation des references, on a lue ( "<< nom << " ) et on attendait visualisation_references_sur_les_maillages_" << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); } else // sinon c'est ok {entreePrinc.NouvelleDonneeCVisu();}; // on passe un enregistrement // break; } // fin du if visualisation_references_sur_les_maillages_ else {entreePrinc.NouvelleDonneeCVisu();}; }; // fin du while entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement } // -- fin du if then else sur "debut_maillage_initial" } // -- fin du try catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch (...)// erreur de lecture { cout << "\n Erreur en lecture des parametres du maillage initial a partir d'un fichier .CVisu," << " on ne tiens pas compte des parametres fournies !! "; // récup des infos sauvées if (ParaGlob::NiveauImpression() >= 4) cout << "\n Mail_initiale_Gmsh::Lecture_parametres_OrdreVisu(.."; // récup des infos sauvées considerer_homothetie = considerer_homothetie_sauve ; t_homothetie = t_homothetie_sauve ; t_orig = t_orig_sauve,t_fact_mult = t_fact_mult_sauve; sortie_des_references=1; } } }; // écriture des paramètres de l'ordre dans un flux void Mail_initiale_Gmsh::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc) {// récup du flot ostream & sort = (*(entreePrinc.Sort_CommandeVisu())); // on commente le fonctionnement sort << "\n # ----------------------------- definition des parametres du maillage initial: ---------------- " << "\n debut_maillage_initial # un mot cle de debut de liste "; // appel de l'ordre de la classe mère OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc); // puis les paramètres sort << "\n pseudo-homothetie_sur_les_maillages_ " << considerer_homothetie << " # 0 = aucune homothetie, 1 = il y en a "; // --- partie relative à une pseudo-homotétie sur les coordonnées initiales sort << "\n # --- def eventuelle de la pseudo-homothetie: une par maillage, "; int nbmail = t_homothetie.Taille(); // le nombre de maillage for (int imail = 1; imail <= nbmail; imail++) { sort << "\n # pseudo-homothetie pour le maillage : " << imail; if (considerer_homothetie) {sort << "\n maillage_ "<< imail << "\n # mot cle: maillage_ puis le numero du maillage, " ;} else {sort << "\n# maillage_ "<< imail << "\n # mot cle: maillage_ puis le numero du maillage, " ;}; // puis y-a-t-il une pseudi-homothétie sur ce maillage ou non if (considerer_homothetie) {sort << "\n pseudo-homothetie_ " << t_homothetie(imail) << " # 0 = non active, 1 = active ";} else {sort << "\n# pseudo-homothetie_ " << t_homothetie(imail) << " # 0 = non active, 1 = active ";}; sort << "\n # ensuite si c'est active, on trouve : " << "\n # mot cle: centre_homothetie_ puis les coordonnees du centre d'homothetie " << "\n # puis mot cle: fact_mult_ puis les coordonnees donnant les coefs multiplicatifs selon les axes. "; if (considerer_homothetie) {if (t_homothetie(imail)) { sort << "\n centre_homothetie_ " << t_orig(imail); sort << "\n fact_mult_ " << t_fact_mult(imail); }; } else { sort << "\n# centre_homothetie_ " ; sort << "\n# fact_mult_ " ; }; }; // --- fin pseudo-homotétie sort << "\n visualisation_references_sur_les_maillages_ " << sortie_des_references << " # 0 = pas de visualisation des reference, 1 = sortie des ref dans fichier unique " << " 2= sortie des ref dans plusieurs fichiers "; // fin -- sortie des références sort << "\n fin_maillage_initial " << " # le mot cle de fin \n"; }; // constitution des sous maillages, utilisé par les isovaleurs par exemple // on suit la même logique que dans gid, un sous maillage par type d'élément // ce n'est pas nécessaire, c'est pas simplicité, à modifier si nécessaire par la suite void Mail_initiale_Gmsh::CreaSousMaillages(const Tableau & tab_mail,LesMaillages * lesMail) {// on boucle sur les maillages int nbmail = tab_mail.Taille(); for (int im=1;im<=nbmail;im++) { int numMail=tab_mail(im); // on cherche tout d'abord le nombre d'éléments différents dans le maillage List_io & li_sig_elem=tabli_sig_elem(numMail); li_sig_elem.erase(li_sig_elem.begin(),li_sig_elem.end()); // on initialise également tabli_sous_mesh(numMail) tabli_sous_mesh(numMail).erase(tabli_sous_mesh(numMail).begin(),tabli_sous_mesh(numMail).end()); // on balaie tous les éléments du maillage int nbmaxiElement = lesMail->Nombre_element(numMail); List_io ::iterator ipos; for (int numElem=1; numElem<= nbmaxiElement;numElem++) { // recup de la signature de l'élément Element::Signature sig_elem = lesMail->Element_LesMaille(numMail,numElem).Signature_element(); // on regarde s'il existe déjà ipos = find(li_sig_elem.begin(),li_sig_elem.end(),sig_elem); if (ipos == li_sig_elem.end()) // enregistrement s'il n'existe pas li_sig_elem.push_back(sig_elem); }; //cout << " fin du balaie de tous les éléments " << endl; // dimensionne le tableau de sous maillages tabtab_sous_mesh(numMail).Change_taille(li_sig_elem.size()); // simplification et préparation Tableau < List_io < Element* > >& tab_sous_mesh = tabtab_sous_mesh(numMail); //cout << " simplification et préparation " << endl; // maintenant on boucle sur les types d'éléments List_io ::iterator ifin=li_sig_elem.end(); int num_type = 1; for (ipos= li_sig_elem.begin();ipos!=ifin;ipos++,num_type++) { // initialisation //cout << " num_type= " << num_type << endl; tab_sous_mesh(num_type).erase(tab_sous_mesh(num_type).begin(),tab_sous_mesh(num_type).end()); //cout << " tab_sous_mesh(num_type).erase " << endl; // création du nom du sous maillage ostrstream tab_out; tab_out << lesMail->NomMaillage(numMail) << "_" << num_type << ends; //cout << " tab_out << lesMail->NomMaillage(numMail) " << endl; string nom_sous_maillage = tab_out.str() ; // le nom //cout << " nom_sous_maillage= " << nom_sous_maillage << endl; //cout << " numMail= " << numMail << " tabli_sous_mesh.Taille()= " << tabli_sous_mesh.Taille() << endl; //cout << " le tableau " << tabli_sous_mesh(1) << endl; //nom_sous_maillage="toto"; tabli_sous_mesh(numMail).push_back(nom_sous_maillage); // sauvegarde //cout << " tabli_sous_mesh(numMail).push_back(nom_sous_maillage) " << endl; // définition du type d'élément //cout << " définition du type d'élément " << endl; int nbmaxiElement = lesMail->Nombre_element(numMail); for (int numElem=1; numElem<= nbmaxiElement;numElem++) { // recup de l'élément //cout << " numElem= " << numElem << endl; Element & elem = lesMail->Element_LesMaille(numMail,numElem); // si c'est la bonne signature on sort l'élément if (elem.Signature_element() == *ipos) // on sauvegarde la ref à l'élément tab_sous_mesh(num_type).push_back(&elem); }; }; // -- fin de la boucle sur les types différents de signatures //cout << " fin de la boucle sur les types différents de signatures " << endl; };//-- fin de la boucle sur les maillages //cout << " fin de la boucle sur les maillages " << endl; }; // sortie éventuelle d'un seul élément au format gmsh // et modification éventuelle du tableau t_Egmsh // num_elem : numero initial de l'élément // decal_ele : décalage de numéro pour tenir compte de la présence de plusieurs maillages (ou sous maillages) // decal_noe : décalage de numéro de noeud, pour tenir compte de la présence de plusieurs maillages // tab_noeud : le tableau des noeuds de la connection // id_geom et id_interpol : permettent de repérer un type d'élément fini associé (donc pas seulement géométrique) // : il s'agit ici de la géométrie et interpolation "élément fini" // sort : flux de sortie // modifier_t_Egmsh : indique si pour l'élément considéré, on abonde le tableau t_Egmsh // si oui c'est un vrai élément, sinon, c'est un élément de référence, // l'indicateur est utiliser dans ce sens // im : si modifier_t_Egmsh est vrai : num du maillage ou sous maillage // si modifier_t_Egmsh est faux : numéro de la référence associée // elem_a_sortir : indique si pour l'élémen considéré, on le sort dans le fichier gmsh void Mail_initiale_Gmsh::SortieDunElements(bool elem_a_sortir, const int& num_elem , ostream &sort, const int& decal_ele, Tableau& tab_noeud , const int& decal_noe, Enum_geom id_geom, Enum_interpol id_interpol , bool modifier_t_Egmsh , int im) { // rappel des types d'éléments gérés par gmsh // 'rien pour le numero 0', # '0' // 'segment lineaire a 2 noeuds' , # '1' // 'triangle lineaire a 3 noeuds' , # '2' // 'quadrangle bilineaire a 4 noeuds' , # '3' // 'tetrahedre lineaire a 4 noeuds' , # '4' // 'hexahedre trilineaire a 8 noeuds' , # '5' // 'pentaedre bilineaire a 6 noeuds' , # '6' // 'pyramide a 5 noeuds' , # '7' // 'segment quadratique a 3 noeuds' , # '8' // 'triangle quadratique a 6 noeuds' , # '9' // 'quadrangle quadratique complet a 9 noeuds' , #'10' // 'tetraedre quadratique a 10 noeuds' , #'11' // 'hexaedre quadratique complet a 27 noeuds' , #'12' // 'pentaedre quadratique complet a 18 noeuds' , #'13' // 'pyramide quadratique a 14 noeuds' , #'14' // ' point a 1 noeud ' , #'15' // 'quadrangle quadratique incomplet a 8 noeuds' , #'16' // 'hexaedre quadratique incomplet a 20 noeuds' , #'17' // 'pentaedre quadratique incomplet a 15 noeuds' , #'18' // 'pyramide quadratique incomplete a 13 noeuds' #'19' // maintenant on sort le type d'élément bool erreur = false; // pas d'erreur par défaut int num_elem_gmsh = 0; // le numéro de numérotation gmsh int nb_noeud_centraux = 0; // ne sert que pour les SFE switch (id_geom) { case TRIANGLE : case TRIA_AXI: {switch (id_interpol) { case LINEAIRE : { num_elem_gmsh= 2 ; break;} case QUADRACOMPL :{ num_elem_gmsh= 9 ; break;} case SFE3C : case SFE3 : case SFE2: case SFE1 : case SFE3C_3D : case SFE3_3D : case SFE2_3D: case SFE1_3D : { num_elem_gmsh= 2 ;nb_noeud_centraux = 3; break;} // on ne considère que les noeuds centraux case QSFE1 : case QSFE3: { num_elem_gmsh= 9 ; nb_noeud_centraux = 6; break;} // on ne considère que les noeuds centraux default : erreur = true; } break; } case QUADRANGLE : case QUAD_AXI: {switch (id_interpol) { case LINEAIRE : {num_elem_gmsh= 3 ; break;} case QUADRATIQUE : {num_elem_gmsh= 16 ; break;} case QUADRACOMPL : {num_elem_gmsh= 10 ; break;} default : erreur = true; } break; } case TETRAEDRE : {switch (id_interpol) {case LINEAIRE : {num_elem_gmsh= 4 ; break;} case QUADRACOMPL : {num_elem_gmsh= 11 ; break;} default : erreur = true; } break; } case HEXAEDRE : {switch (id_interpol) {case LINEAIRE : {num_elem_gmsh= 5 ; break;} case QUADRATIQUE : {num_elem_gmsh= 17 ; break;} case QUADRACOMPL : {num_elem_gmsh= 12 ; break;} default : erreur = true; } break; } case POUT : case SEGMENT : case SEG_AXI: {switch (id_interpol) {case BIE1 : num_elem_gmsh= 1 ; break; case LINEAIRE : num_elem_gmsh= 1 ; break; case QUADRATIQUE : case BIE2 : num_elem_gmsh= 8 ; break; case QUADRACOMPL : num_elem_gmsh= 8 ; break; default : erreur = true; } break; } case POINT : num_elem_gmsh= 15 ; break; case PENTAEDRE : {switch (id_interpol) {case LINEAIRE : {num_elem_gmsh= 6 ; break;} case QUADRATIQUE : {num_elem_gmsh= 18 ; break;} case QUADRACOMPL : {num_elem_gmsh= 13 ; break;} default : erreur = true; } break; } default : cout << "\nErreur : cas d'element non traite par Gmsh !" << Nom_geom(id_geom) << " " << Nom_interpol(id_interpol) << " ********** attention, le fichier de sortie ne sera pas exploitable !!!\n"; }; if (erreur) cout << "\nErreur : cas d'element + interpolation non traite par Gmsh !" << Nom_geom(id_geom) << " " << Nom_interpol(id_interpol) << " ********** attention, le fichier de sortie ne sera pas exploitable !!!\n"; // --- traitement du tableau t_Egmsh if (modifier_t_Egmsh) // ne concerne que les vrais éléments, donc test pour différencier avec les elem de ref t_Egmsh(im)(num_elem)=num_elem_gmsh; // enreg pour construire le tableau t_Egmsh // utilisée pour la sortie d'isovaleur et la déformée // ---- sortie fichier gmsh // récup de la connection herezh->gmsh // t_GmshHer(i)(j) : donne pour le noeud j de l'élément i de gmsh, le numéro d'herezh const Tableau < Tableau < int > >& tGmshHer = Visualisation_Gmsh::Tab_GmshHer(); if (elem_a_sortir) { sort << "\n" << num_elem + decal_ele << " " // numéro d'élément << " " << num_elem_gmsh << " "; // sortie du type d'élément gmsh // sortie du nombre de tag et des deux premiers tags principaux if (modifier_t_Egmsh) { sort << " " << 3 << " " << im << " " << num_elem << " 0 " ;} else { sort << " " << 3 << " " << im << " " << im << " 0 " ;}; // on sort les éléments la connection int nb_n = tab_noeud.Taille(); if (ElementSfe(id_interpol)) // dans le cas des sfe on ne sort que les noeuds du centre {for (int j=1;j<=nb_noeud_centraux;j++) // les noeuds centraux { int num_her = tGmshHer(num_elem_gmsh)(j); sort << tab_noeud(num_her)->Num_noeud()+decal_noe << " "; }; } else // cas normal {for (int j=1;j<=nb_n;j++) // j = gmsh {int num_her = tGmshHer(num_elem_gmsh)(j); // num HZ correspondant sort << tab_noeud(num_her)->Num_noeud()+decal_noe << " "; }; }; }; }; // sortie sur le flot passé en paramètre, de la partie noeud du maillage sans entête ni fin void Mail_initiale_Gmsh::Sortie_noeuds_initiaux(const Tableau & tab_mail ,LesMaillages * lesMail, ostream &sort) { int dim = ParaGlob::Dimension(); // récup de la dimension // on boucle sur les maillages int nbmail = tab_mail.Taille(); // // on recalcule les décalages de noeuds en fonction des maillages actifs, car c'est utilisé par les isovaleurs et autres // // ordres, les maillages qui ne sont pas concerné, ont des décal_noe et éléments inchangé donc quelconques, ceci permet de garder les mêmes tailles // int decal_n = 0; // variables intermédiaires // for (int nm=1;nm<=nbmail;nm++) // {int numMail=tab_mail(nm); // decal_noeud(numMail)=decal_n; // decal_n += lesMail->Nombre_noeud(numMail); // }; // // on ré_enregistre le nombre total de noeud // nb_total_noeud = decal_n; for (int im=1;im<=nbmail;im++) { int numMail=tab_mail(im); int decal_noe=decal_noeud(numMail); // pour simplifier // maintenant on sort la liste de tous les noeuds int nbmaxinoeud = lesMail->Nombre_noeud(numMail); // deux cas soit on applique une pseudo-homothetie ou non if (!(considerer_homothetie && t_homothetie(numMail))) {// cas sans homothetie : cas classique for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) {// recup du noeud Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud); sort << "\n" << noe.Num_noeud()+decal_noe << " " ; const Coordonnee& co = noe.Coord0(); co.Affiche(sort,ParaGlob::NbdigdoGR()); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 1: sort << " 0. "; case 2: sort << " 0. "; }; }; } else // cas avec Homothetie {Coordonnee& orig = t_orig(numMail); // pour simplifier Coordonnee& fact_mult = t_fact_mult(numMail); // pour simplifier for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) {// recup du noeud Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud); sort << "\n" << noe.Num_noeud()+decal_noe << " " ; const Coordonnee& co = noe.Coord0(); Coordonnee A(co-orig); int dim = A.Dimension(); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 3: A(3) *= fact_mult(3); case 2: A(2) *= fact_mult(2); case 1: A(1) *= fact_mult(1); }; A +=orig; A.Affiche(sort,ParaGlob::NbdigdoGR()); switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0 { case 1: sort << " 0. "; case 2: sort << " 0. "; }; }; }; };//-- fin de la boucle sur les maillages }; // sortie sur le flot passé en paramètre, de la partie élément du maillage sans entête ni fin void Mail_initiale_Gmsh::Sortie_element_initiaux(const Tableau & tab_mail ,LesMaillages * lesMail, ostream &sort) { // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas Tableau t_a_sortir(lesMail->NbMaillage(),false); int nb_a_sortir = tab_mail.Taille(); for (int isa = 1; isa <= nb_a_sortir; isa++) t_a_sortir(tab_mail(isa))=true; // on boucle sur les maillages int nbmail = tab_mail.Taille(); // // // on recalcule les décalages de noeuds en fonction des maillages actifs, car c'est utilisé par les isovaleurs et autres // // ordres, les maillages qui ne sont pas concerné, ont des décal_noe et éléments inchangé donc quelconques, ceci permet de garder les mêmes tailles // int decal_n = 0; int decal_e=0; // variables intermédiaires // for (int nm=1;nm<=nbmail;nm++) // {int numMail=tab_mail(nm); // decal_noeud(numMail)=decal_n; decal_element(numMail)=decal_e; // decal_n += lesMail->Nombre_noeud(numMail); // decal_e += lesMail->Nombre_element(numMail); // }; // // on ré_enregistre le nombre total de noeud et le nombre total d'éléments // nb_total_noeud = decal_n; // nb_total_element = decal_e; // for (int im=1;im<=nbmail;im++) { int numMail=tab_mail(im); int decal_ele =decal_element(numMail); // pour simplifier int decal_noe=decal_noeud(numMail); // pour simplifier // on balaie tous les éléments du maillage int nbmaxiElement = lesMail->Nombre_element(numMail); t_Egmsh(im).Change_taille(nbmaxiElement); // dimensionement for (int numElem=1; numElem<= nbmaxiElement;numElem++) {Element& elem = lesMail->Element_LesMaille(numMail,numElem); // récup de l'élément // on appel la méthode pour sortir l'élément bool modifier_t_Egmsh = true; // il s'agit des vrais éléments donc on met à jour t_Egmsh SortieDunElements(t_a_sortir(numMail), elem.Num_elt(), sort,decal_ele, elem.Tab_noeud() ,decal_noe, elem.Id_geometrie(), elem.Id_interpolation() ,modifier_t_Egmsh, im); }; // -- fin de la boucle sur les éléments };//-- fin de la boucle sur les maillages };