Herezh_dev/Resultats/Gmsh/Mail_initiale_Gmsh.cc

1656 lines
84 KiB
C++
Raw Normal View History

// 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) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
2023-05-03 17:23:49 +02:00
// Copyright (C) 1997-2022 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 <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "Mail_initiale_Gmsh.h"
// pour le tableau de connection herezh -> gmsh
#include "Visualisation_Gmsh.h"
#include <iomanip>
#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 <string> >& 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 <int>& 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 <string> >&
,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 <int>& 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 <int>& 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 <bool> 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<int>& 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 <int>& 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 <bool> 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_geom > enum_geo; // les énuméré de la géométrie des éléments à sortir
Tableau <Noeud *> 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_geom > enum_geo; // les énuméré de la géométrie des éléments à sortir
Tableau <Noeud *> 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 "<<numElem<<" du maillage "<< numMail;
cout << "\n concerne la reference de pti : " << refcourante->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 <int>& 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 <bool> 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 <Tableau <int > > 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 <int >& 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<int>& 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 <int > t_tail(nbmail); // contiendra les tailles pour chaque maillage des noeuds ajouté
for (int i=1;i<=nbmail;i++)
{ Tableau <int >& 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_geom > enum_geo; // les énuméré de la géométrie des éléments à sortir
Tableau <Noeud *> 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<Noeud *>& 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<int>& 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<Noeud *>& 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<int>& 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 <Noeud *> 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 <int >& 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 <Noeud *> 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_geom > 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 <int>& 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 <bool> 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_geom > enum_geo; // les énuméré de la géométrie des éléments à sortir
Tableau <Noeud *> 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<int>& tt = refi->Tab_num ();
int taill_N = tt.Taille();
sort << "\n // ============================================================"
<< "\n // | "<<tab_nom_tag_ref(itab) << " |"
<< "\n // ============================================================";
sort << "\n$ElementData "; // l'entête
// $ElementData
// number-of-string-tags
// < "string-tag" >
// ...
// 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<int>& tt = refi->Tab_num ();
int taill_N = tt.Taille();
sort << "\n // ============================================================"
<< "\n // | "<<tab_nom_tag_ref(itab) << " |"
<< "\n // ============================================================";
sort << "\n$ElementData "; // l'entête
// $ElementData
// number-of-string-tags
// < "string-tag" >
// ...
// 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 // | "<<tab_nom_tag_ref(itab) << " |"
<< "\n // ============================================================";
sort << "\n$ElementData "; // l'entête
// $ElementData
// number-of-string-tags
// < "string-tag" >
// ...
// 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 // | "<<tab_nom_tag_ref(itab) << " |"
<< "\n // ============================================================";
sort << "\n$ElementData "; // l'entête
// $ElementData
// number-of-string-tags
// < "string-tag" >
// ...
// 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 <Coordonnee > 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 <int>& 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 <Element::Signature>& 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 <Element::Signature>::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 <Element::Signature>::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<Noeud *>& 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 <int>& 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 <int>& tab_mail
,LesMaillages * lesMail, ostream &sort)
{ // on construit un tableau de bool, pour savoir si le maillage est à sortir ou pas
Tableau <bool> 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
};