1655 lines
84 KiB
C++
1655 lines
84 KiB
C++
|
|
// 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.
|
|
//
|
|
// 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 <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
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|