Herezh_dev/herezh_pp/Resultats/Gid/Deformees_Gid.cc

340 lines
16 KiB
C++
Executable file

// 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 "Deformees_Gid.h"
#include "CharUtil.h"
#include "ConstMath.h"
#include <iomanip>
// CONSTRUCTEURS :
// par defaut
Deformees_Gid::Deformees_Gid () :
OrdreVisu("..........................................deformee"
,"visualisation des deformee","de")
,isovaleurs_Gid(NULL)
,num_mail_incr(),noms_matiere(),choix_mail(NULL)
,noms_couleurs()
,li_bornes(),li_nom_bornes()
{};
// constructeur de copie
Deformees_Gid::Deformees_Gid (const Deformees_Gid& ord) :
OrdreVisu(ord)
,isovaleurs_Gid(ord.isovaleurs_Gid)
,num_mail_incr(ord.num_mail_incr)
,noms_matiere(),choix_mail(ord.choix_mail)
,noms_couleurs(ord.noms_couleurs)
,li_bornes(ord.li_bornes),li_nom_bornes(ord.li_nom_bornes)
{};
// DESTRUCTEUR :
Deformees_Gid::~Deformees_Gid ()
{};
// METHODES PUBLIQUES :
// 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 Deformees_Gid::ExeOrdre(ParaGlob * paraGlob,const Tableau <int>& tab_mail,LesMaillages * lesMail,bool ,LesReferences*
,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*
,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre
// ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre type_incre,int incre
,bool ,const map < string, const double * , std::less <string> >&
,const List_io < TypeQuelconque >& listeVecGlob)
{// visualisation du maillage pointé si actif
if (actif)
{ostream &sort = entreePrinc.Sort_resultat_Gid();
// pour boucler sur les maillages
int nbmail = tab_mail.Taille();
if (incre == 0)
{ // dans le cas du premier incrément on sort la table d'alertes
if (li_nom_bornes.size() != 0)
{sort << "\n # --- definition de la table d'alertes ---- ";
sort << "\n ResultRangesTable \"table_alertes_deformees\" ";
list <DeuxDoubles>::iterator idd_n,idd_fin=li_bornes.end();
list <string>::iterator ili,ili_fin=li_nom_bornes.end();
ili=li_nom_bornes.begin();int num=1;
for (idd_n=li_bornes.begin();idd_n!=idd_fin;idd_fin++,num++)
{ sort << "\n";
if ((*idd_n).un != -ConstMath::trespetit)
{sort << (*idd_n).un << " ";}
else {sort << " ";};
sort << " - ";
if ((*idd_n).deux != ConstMath::tresgrand) {sort << (*idd_n).deux << " : ";};
sort << " \"" << *ili << "\" ";
};
sort << "\n End ResultRangesTable \n";
};
};
// dans le cas où c'est l'incrément 0, c'est-à-dire le maillage initial, on ne sort rien
// au niveau des déplacements sinon on y va
if (incre != 0)
{ // on sort l'entête
sort << "\n Result \"deplacement_maillage\" \"calcul_mecanique\" "
<< incre << " Vector OnNodes \n";
if (li_nom_bornes.size() != 0) // sortie que si il y a des éléments dans la table
sort << "\n ResultRangesTable \"table_alertes_deformees\" ";
sort << "\n ComponentNames \"delta_X\", \"delta_Y\", \"delta_Z\" ";
sort << "\n Values ";
for (int im=1;im<=nbmail;im++)
{ int numMail=tab_mail(im);
// on sort les déplacements pour les différents noeuds
int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
// on balaie tous les noeuds du maillage
// on récupère le décalage de numéros
int decal_noe=mailInitial->DecalNumNoeud(numMail); // pour simplifier
for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++)
{ // recup du noeud
Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
Coordonnee dep(paraGlob->Dimension()); // init à zero par defaut
if (noe.ExisteCoord1())
{dep = (noe.Coord1() - noe.Coord0() );
sort << "\n" << noe.Num_noeud() + decal_noe << " " ;
dep.Affiche(sort,ParaGlob::NbdigdoGR());
switch (ParaGlob::Dimension()) // 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
sort << "\n End Values ";
};
// et on vide le buffer de sortie
sort << endl;
}; //-- fin du if actif
};
// 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 Deformees_Gid::ChoixOrdre()
{ // demande de précision
bool choix_valide = false;
cout << "\n ----> preparation de la visualisation des deformees"
<< "\n parametre par defaut ? : pas de limites d'alerte sur les deplacements ,"
<< " (rep 'o') pour accepter ces parametres sinon autre ";
string rep;
cout << "\n reponse ? "; rep = lect_return_defaut(true,"o");
if (rep != "o")
{// cas d'un choix autre que standart
while (!choix_valide)
{try
{ cout << "\n (0) fin modif"
<< "\n (1) nouvelle definition de limites d'alerte? "
<< "\n (2) effacer une limites d'alerte existante ? ";
cout << "\n \n reponse ? ";
rep = lect_return_defaut(false,"0");
if (rep == "fin_prog") Sortie(1);
// sinon
int num = ChangeEntier(rep);
if (num == 0) {choix_valide=true;}
else if ((num >= 1)&&(num<=2))
{ choix_valide=false;
switch (num)
{ case 1: // definition des limites d'alerte
{ cout << "\n donnez une borne inferieur "
<< "\n (rep un reel ou 'no' pour utiliser le minimum total des valeurs ";
string numinf;DeuxDoubles dd; string nom_bornes;
numinf= lect_chaine();
if (numinf == "no")
{dd.un= -ConstMath::trespetit;}
else
{dd.un=ChangeReel(numinf);};
if ( numinf == "no")
{ // il faut absolument donner une borne supérieur
cout << "\n donnez une borne superieur (rep un reel) ";
numinf= lect_chaine();
dd.deux=ChangeReel(numinf);
}
else
{cout << "\n donnez une borne superieur "
<< "\n (rep un reel ou 'no' pour utiliser le maximum total des valeurs ";
numinf= lect_chaine();
if (numinf == "no")
{dd.deux= ConstMath::tresgrand;}
else
{dd.deux=ChangeReel(numinf);};
};
// définition du nom
cout << "\n donnez le nom que vous voulez donner a ces limites: ";
numinf= lect_chaine();
// maintenant on valide
li_bornes.push_back(dd); li_nom_bornes.push_back(numinf);
break;
}
case 2: // "effacer une limites d'alerte existante")
{ cout << "\n liste actuelle des alertes enregistrees ";
list <DeuxDoubles>::iterator idd_n,idd_fin=li_bornes.end();
list <string>::iterator ili,ili_fin=li_nom_bornes.end();
ili=li_nom_bornes.begin();int num=1;
for (idd_n=li_bornes.begin();idd_n!=idd_fin;idd_fin++,num++)
{ cout << "\n(" << num << ") " << *ili << (*idd_n).un << " " << (*idd_n).deux <<" ";};
cout << "\n donnez le numero d'alerte a supprimer ";
string num_choix;
num_choix= lect_chaine(); int num_c=ChangeEntier(num_choix);
if ((num_c >=1)&&(num_c<=num))
{ili=li_nom_bornes.begin();int num=1;
for (idd_n=li_bornes.begin();idd_n!=idd_fin;idd_fin++,num++)
if (num==num_c)
{li_nom_bornes.erase(ili_fin);li_bornes.erase(idd_n);};
};
break;
}
};
}
else { cout << "\n Erreur on attendait un entier entre 0 et 2 !!, "
<< "\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 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 Deformees_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_deformee")!=NULL)
{// sauvegarde des paramètres actuelles
list <DeuxDoubles> li_bornes_sauve = li_bornes; // min max des alertes
list <string> li_nom_bornes_sauve = li_nom_bornes; // nom des alertes
// essaie de lecture
try
{ string nom;
(*entreePrinc.entCVisu) >> nom ;
if (nom != "debut_deformee")
{ cout << "\n Erreur en lecture des parametres de deformee a partir d'un fichier .CVisu,"
<< " le premier enregistrement doit etre le mot clef: debut_deformee "
<< " 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_deformee")==NULL)
{// lecture des alertes
if (strstr(entreePrinc.tablcarCVisu,"deb_list_alerte")!=NULL)
{ // lecture de la liste des alertes
entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement
// on efface éventuellement les listes actuelles s'il y a quelque chose à lire
if (strstr(entreePrinc.tablcarCVisu,"fin_list_alerte")==NULL)
{li_nom_bornes.erase(li_nom_bornes.begin(),li_nom_bornes.end());
li_bornes.erase(li_bornes.begin(),li_bornes.end());
// lecture des listes demandées
int compteur=0; // pour éviter une boucle infinie
DeuxDoubles dd_n; string nom_alerte,nom2;
while (compteur < 1000000)
{ (*entreePrinc.entCVisu) >> nom >> nom2 >> nom_alerte; compteur++;
if (nom != "fin_list_alerte")
{ dd_n.un=ChangeReel(nom); dd_n.deux=ChangeReel(nom2);
// on vérifie que le nom lu est acceptable
if (find(li_nom_bornes.begin(),li_nom_bornes.end(),nom_alerte) != li_nom_bornes.end())
{li_nom_bornes.push_back(nom_alerte);li_bornes.push_back(dd_n);}
else
cout << "\n lecture d'une alerte ( "<< nom << " ) errone ! on n'en tiens pas compte";
entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement
}
else break;
}
};
entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement
}; //-- on sort du cas où il y avait une liste d'alerte
} //-- on sort des paramètres de déformée
// on passe un enregistrement pour le prochain ordrevisu
entreePrinc.NouvelleDonneeCVisu();
}; // fin du cas d'une lecture de paramètre de dérivées
}
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 de deformee a partir d'un fichier .CVisu,"
<< " on ne tiens pas compte des parametres fournies !! ";
// récup des infos sauvées
li_bornes = li_bornes_sauve; // min max des alertes
li_nom_bornes = li_nom_bornes_sauve; // nom des alertes
if (ParaGlob::NiveauImpression() >= 4)
cout << "\n Deformees_Gid::Lecture_parametres_OrdreVisu(..";
}
}
};
// écriture des paramètres de l'ordre dans un flux
void Deformees_Gid::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc)
{ // récup du flot
ostream & sort = (*(entreePrinc.Sort_CommandeVisu()));
// on commente le fonctionnement
sort << "\n # ----------------------------- definition des parametres de deformee: ---------------- "
<< "\n debut_deformee # un mot cle de debut de liste";
// appel de l'ordre de la classe mère
OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc);
// on sort l'entête des paramètres
sort << "\n # definition des alertes: deb_list_alerte "
<< "\n # un mot clef de debut "
<< "\n # puis deux nombres: un mini et un maxi, et un nom "
<< "\n # un mot clef de fin: fin_list_alerte ";
// puis la liste des alertes
sort << "\n deb_list_alerte ";
list <DeuxDoubles>::iterator idd_n,idd_fin=li_bornes.end();
list <string>::iterator ili,ili_fin=li_nom_bornes.end();
ili=li_nom_bornes.begin();int num=1;
for (idd_n=li_bornes.begin();idd_n!=idd_fin;idd_fin++,num++)
{ sort << "\n" << (*idd_n).un << " " << (*idd_n).deux << " " << *ili << " ";};
sort << "\n fin_list_alerte ";
// fin
sort << "\n fin_deformee " << " # un mot cle de fin \n";
};