// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-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 . // // For more information, please consult: . #include "Mail_initiale_Gid.h" #include #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 >& 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 & tab_mail,LesMaillages * lesMail,bool ,LesReferences* lesRef,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim* // ,LesContacts*,Resultats*,ostream & sort,EnumTypeIncre type_incre,int incre ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre // ,bool animation) ,bool,const map < string, const double * , std::less >& ,const List_io < TypeQuelconque >& listeVecGlob) { // --- la partie qui suie est systématiquement exécutée, que ce soit actif, ou pas et quelque soit l'incrément -- // constitue une initialisation pour les autres ordres, mais que l'on ne peut pas mettre dans 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 & li_sig_elem=tabli_sig_elem(numMail); li_sig_elem.erase(li_sig_elem.begin(),li_sig_elem.end()); // on initialise également tabli_sous_mesh(numMail) tabli_sous_mesh(numMail).erase(tabli_sous_mesh(numMail).begin(),tabli_sous_mesh(numMail).end()); // on balaie tous les éléments du maillage int nbmaxiElement = lesMail->Nombre_element(numMail); List_io ::iterator ipos; for (int numElem=1; numElem<= nbmaxiElement;numElem++) { // recup de la signature de l'élément Element::Signature sig_elem = lesMail->Element_LesMaille(numMail,numElem).Signature_element(); // on regarde s'il existe déjà ipos = find(li_sig_elem.begin(),li_sig_elem.end(),sig_elem); if (ipos == li_sig_elem.end()) // enregistrement s'il n'existe pas li_sig_elem.push_back(sig_elem); }; // 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 ::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& 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"; };