Herezh_dev/Resultats/Gid/Mail_initiale_Gid.cc
2023-05-03 17:23:49 +02:00

463 lines
24 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-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_Gid.h"
#include <iomanip>
#include "ReferenceNE.h"
// CONSTRUCTEURS :
// par defaut
Mail_initiale_Gid::Mail_initiale_Gid () :
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()
{};
// constructeur de copie
Mail_initiale_Gid::Mail_initiale_Gid (const Mail_initiale_Gid& 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)
{};
// DESTRUCTEUR :
Mail_initiale_Gid::~Mail_initiale_Gid ()
{};
// 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_Gid::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)
{ // initialisation des tableaux
int nb_maillage = lesmail->NbMaillage();
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
Mail_initiale_Gid::ChoixOrdre();
// 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);
};
};
// 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_Gid::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 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);
};
if (incre==0) // dans tous les cas on sort le maillage initiale au premier incrément
{ostream &sort = entreePrinc.Sort_initial_Gid();
// on boucle sur les maillages
int nbmail = tab_mail.Taille();
for (int im=1;im<=nbmail;im++)
{ int numMail=tab_mail(im);
// écriture d'une entete
sort << "\n // ========================================="
<< "\n // | definition du maillage initiale |"
<< "\n // =========================================";
int decal_noe=decal_noeud(numMail); // pour simplifier
int decal_ele =decal_element(numMail); // pour simplifier
// 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);
};
// 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);
// 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
tab_sous_mesh(num_type).erase(tab_sous_mesh(num_type).begin(),tab_sous_mesh(num_type).end());
// maintenant on sort la partie d'élément correspondante avec pour la première partie
//la liste de tous les noeuds
sort << "\n # maillage: " << lesMail->NomMaillage(numMail) << "\n";
// création du nom du sous maillage
ostrstream tab_out;
tab_out << lesMail->NomMaillage(numMail) << "_" << num_type << ends;
string nom_sous_maillage = tab_out.str() ; // le nom
tabli_sous_mesh(numMail).push_back(nom_sous_maillage); // sauvegarde
// sortie sur fichier
sort << "\n MESH \""<< nom_sous_maillage << "\" ";
int dim = ParaGlob::Dimension(); // récup de la dimension
if (dim != 1)
{sort <<" dimension " << ParaGlob::Dimension() << " ";}
else
// le cas dim = 1 ne semble pas fonctionner par contre avec 3 c'est ok
// on met donc 3, car de toute façon on rajoute des coordonnées nulles
{sort <<" dimension " << 3 << " ";};
// définition du type d'élément
sort << "Elemtype " ; bool erreur = false;
switch ((*ipos).id_geom)
{ case TRIANGLE : case TRIA_AXI:
{ sort << "Triangle ";
switch ((*ipos).id_interpol)
{ case LINEAIRE : {sort << " Nnode 3 "; break;}
case QUADRACOMPL :{ sort << " Nnode 6 "; break;}
case SFE3C: case SFE3 : case SFE2: case SFE1 : // on ne considère que les noeuds centraux
case SFE3C_3D: case SFE3_3D : case SFE2_3D: case SFE1_3D :{ sort << " Nnode 3 "; break;}
case QSFE1: case QSFE3: // on ne considère que les noeuds centraux
{ sort << " Nnode 6 "; break;}
default : erreur = true;
};
break;
}
case QUADRANGLE : case QUAD_AXI:
{ sort << "Quadrilateral ";
switch ((*ipos).id_interpol)
{ case LINEAIRE : {sort << " Nnode 4 "; break;}
case QUADRATIQUE : {sort << " Nnode 8 "; break;}
case QUADRACOMPL : {sort << " Nnode 9 "; break;}
default : erreur = true;
};
break;
}
case TETRAEDRE :
{ sort << "Tetrahedra ";
switch ((*ipos).id_interpol)
{ case LINEAIRE : {sort << " Nnode 4 "; break;}
case QUADRACOMPL : {sort << " Nnode 10 "; break;}
default : erreur = true;
};
break;
}
case HEXAEDRE :
{ sort << "Hexahedra ";
switch ((*ipos).id_interpol)
{ case LINEAIRE : {sort << " Nnode 8 "; break;}
case QUADRATIQUE : {sort << " Nnode 20 "; break;}
case QUADRACOMPL : {sort << " Nnode 27 "; break;}
default : erreur = true;
};
break;
}
case POUT : case SEGMENT : case SEG_AXI:
{ sort << "Linear ";
switch ((*ipos).id_interpol)
{ case BIE1 : sort << " Nnode 2 "; break;
case LINEAIRE : sort << " Nnode 2 "; break;
case QUADRATIQUE : case BIE2 : sort << " Nnode 3 "; break;
default : erreur = true;
};
break;
}
case POINT : sort << "Point Nnode 1 "; break;
case PENTAEDRE :
{ // il n'y a pas de pentaèdre dans gid, on modélise donc à l'aide d'hexaèdre dont deux arrêtes
// sont confondu
sort << "Hexahedra ";
switch ((*ipos).id_interpol)
{ case LINEAIRE : {sort << " Nnode 8 "; break;}
case QUADRATIQUE : {sort << " Nnode 20 "; break;}
case QUADRACOMPL : {sort << " Nnode 27 "; break;}
default : erreur = true;
};
break;
}
default :
cout << "\nErreur : cas d'element non traite par Gid ! " << Nom_geom((*ipos).id_geom)
<< " ********** attention, le fichier maillage initial ne sera pas exploitable !!!\n";
};
if (erreur)
cout << "\nErreur : cas d'element + interpolation non traite par Gid !" << Nom_geom((*ipos).id_geom)
<< " " << Nom_interpol((*ipos).id_interpol)
<< " ********** attention, le fichier de sortie ne sera pas exploitable !!!\n";
// maintenant on sort la liste de tous les noeuds dans le cas de la première partie
if (ipos == li_sig_elem.begin())
{ sort << "\n \n # tous les noeuds du maillage: " << lesMail->NomMaillage(numMail) << "\n";
int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
sort << "\n Coordinates ";
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. ";
};
};
sort << "\n end coordinates ";
};
// on sort les éléments
sort << "\n \n # tous les element du maillage: " << lesMail->NomMaillage(numMail)
<< " du meme type " << Nom_geom((*ipos).id_geom) << " " << Nom_interpol((*ipos).id_interpol)
<< "\n";
int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
sort << "\n Elements ";
int nbmaxiElement = lesMail->Nombre_element(numMail);
for (int numElem=1; numElem<= nbmaxiElement;numElem++)
{ // recup de l'élément
Element & elem = lesMail->Element_LesMaille(numMail,numElem);
// si c'est la bonne signature on sort l'élément
if (elem.Signature_element() == *ipos)
{sort << "\n" << elem.Num_elt() + decal_ele << " ";
Tableau<Noeud *>& tab_noeud = elem.Tab_noeud();
int nb_n = tab_noeud.Taille();
// dans le cas des pentaèdres on a un traitement spécial pour sortir sous forme d'hexaèdres
if ((*ipos).id_geom == PENTAEDRE)
{if ((*ipos).id_interpol == LINEAIRE)
{for (int j=1;j<=3;j++) // les 3 premiers noeuds
sort << tab_noeud(j)->Num_noeud()+decal_noe<< " " ;
sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
for (int j=4;j<=6;j++) // les 3 derniers noeuds
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
}
else if((*ipos).id_interpol == QUADRATIQUE)
{for (int j=1;j<=3;j++) // les 3 premiers noeuds
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
for (int j=4;j<=6;j++) // les 3 noeuds du dessus
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
for (int j=7;j<=9;j++) // les 3 noeuds intermédiaires du bas
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 12h = 9p
for (int j=10;j<=12;j++) // les 3 noeuds à mi-hauteur
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(12)->Num_noeud()+decal_noe << " " ; // le 16h = 12p
for (int j=13;j<=15;j++) // les 3 noeuds intermédiaires du dessus
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 20h = 15p
}
else if((*ipos).id_interpol == QUADRACOMPL)
{for (int j=1;j<=3;j++) // les 3 premiers noeuds
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
for (int j=4;j<=6;j++) // les 3 noeuds du dessus
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
for (int j=7;j<=9;j++) // les 3 noeuds intermédiaires du bas
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 12h = 9p
for (int j=10;j<=12;j++) // les 3 noeuds à mi-hauteur
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(12)->Num_noeud()+decal_noe << " " ; // le 16h = 12p
for (int j=13;j<=15;j++) // les 3 noeuds intermédiaires du dessus
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 20h = 15p
sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 21h = 9p
sort << tab_noeud(16)->Num_noeud()+decal_noe << " " ; // le 22h = 16p
sort << tab_noeud(17)->Num_noeud()+decal_noe << " " ; // le 23h = 17p
sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 24h = 18p
sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 25h = 18p idem
sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 21h = 15p
sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 27h = 18p
};
}
else if (ElementSfe((*ipos).id_interpol))
// dans le cas des sfe on ne sort que les noeuds du centre
{for (int j=1;j<=3;j++) // 3 noeuds centraux
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
}
else
// cas normal
{for (int j=1;j<=nb_n;j++)
sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
};
// le nb de matériau: pour l'instant on met le numéro de maillage
sort << numMail;
// et on sauvegarde la ref à l'élément
tab_sous_mesh(num_type).push_back(&elem);
};
};
sort << "\n end elements ";
// et on vide le buffer de sortie
sort << endl;
}; // -- fin de la boucle sur les types différents de signatures
//----------------------------------------------------------------
// cas des références
//----------------------------------------------------------------
int numero_reference=1;
// 1 -- cas des références de noeuds
ostream &sart = entreePrinc.Sort_resultat_Gid();
sart << "\n # ============================================="
<< "\n # | definition des references de noeuds |"
<< "\n # ============================================="
<< "\n # maillage : " << lesMail->NomMaillage(numMail) << "\n"
<< "\n # decalage des numeros de noeuds : " << decal_noe << " "
<< "\n # decalage des numeros d'elements : " << decal_ele << " ";
// on va boucler sur les références et sortir les références de noeuds
const Reference* reff =NULL; bool prempass = true;
do { if (prempass)
{ reff= lesRef->Init_et_Premiere();} // récup de la ref 1 et init
else
{ reff = lesRef->Reference_suivante();} // récup de la ref courante
// sortie de la ref si c'est le bon maillage, et si c'est une ref de noeud
if (reff != NULL)
if ((reff->Nbmaille() == numMail) && (reff->Indic() == 1))
{// on a récupérer une référence de noeud du maillage
ReferenceNE * refNE =((ReferenceNE*) reff);
// sortie sur fichier
sart << "\n\n Result \""<< reff->Nom() <<"_" << numMail << "_\" ";
sart <<" \"ref_de_noeud\" " << incre << " Scalar OnNodes ";
// définition du type d'élément
sart << "\n ComponentNames \"" << reff->Nom()<<"_" << numMail << "\" ";
// pas de coordonné car on utilise les coordonnées déjà données
sart << "\n Values ";
int reftaille = refNE->Taille();
for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
sart << "\n " << refNE->Numero(nn) + decal_noe << " "<< numero_reference <<" ";
sart << "\n End Values ";
};
prempass = false;
} while (reff != NULL);
};//-- fin de la boucle sur les maillages
}; //-- fin de if ((actif)&&(incre==0))
};
// 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_Gid::ChoixOrdre()
{ // demande de précision
// 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_Gid::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
// 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 (nom != "fin_maillage_initial")
{ (*entreePrinc.entCVisu) >> nom;
entreePrinc.NouvelleDonneeCVisu();
}
}
}
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_Gid::Lecture_parametres_OrdreVisu(..";
}
}
};
// écriture des paramètres de l'ordre dans un flux
void Mail_initiale_Gid::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);
// fin
sort << "\n fin_maillage_initial " << " # le mot cle de fin \n";
};