Herezh_dev/Maillage/LesMaillages2.cc
Gérard Rio ece68c42db V 7.012 : résolution du pb de l'utilisation de l'accélération dans une fonction nD
Introduction du calcul de l'accélération interpolée, au niveau de la métrique
Intro de nouveaux affichages au niveau des fonctions nD
2023-06-01 08:47:54 +02:00

2952 lines
150 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 "LesMaillages.h"
#include "ElemMeca.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "MathUtil.h"
#include "ConstMath.h"
#include "CharUtil.h"
#include "TypeQuelconqueParticulier.h"
#ifndef SYSTEM_MAC_OS_X_unix
#include "Frontier.h"
#endif
// --------- calcul dynamique ---------
// ajout des ddl de vitesse pour tous les maillages
// pour tous les noeuds qui ont un ddl de déplacement
// val_fixe indique si l'on veut des ddl libres ou pas
void LesMaillages::Plus_Les_ddl_Vitesse(Enum_boolddl val_fixe)
{ // recup de la dimension
int dimen = ParaGlob::Dimension();
// recup de la position de VI-1
int posi = Id_nom_ddl("V1") -1;
// création du tableau de ddl de travail
Tableau <Ddl> ta(dimen);
for (int ii=1; ii<= dimen; ii++)
{//ta(ii) = Enum_ddl(ii+posi); // ERREUR D'AFFECTATION, À VOIRE EN DEBUG OU IL VA
ta(ii) = Ddl (Enum_ddl(ii+posi),0.,val_fixe); // bonne version
};
// dans le cas où le calcul est axisymétrique
// le dernier ddl en z est mis en HSLIBRE, car on ne le prend pas en compte dans le calcul
// axisymétrique
if (ParaGlob::AxiSymetrie())
ta(3) = Ddl (Enum_ddl(3+posi),0.,HSLIBRE); // bonne version;
// maintenant on passe en revu les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
// on regarde si le déplacement existe
if (noo->Existe_ici(X1))
noo->PlusTabDdl(ta);
}
};
};
// ajout des ddl d'accélération pour tous les maillages
// pour tous les noeuds qui ont un ddl de déplacement
// val_fixe indique si l'on veut des ddl libres ou pas
void LesMaillages::Plus_Les_ddl_Acceleration(Enum_boolddl val_fixe)
{ // recup de la dimension
int dimen = ParaGlob::Dimension();
// recup de la position de GAMMA1-1
int posi = Id_nom_ddl("GAMMA1") -1;
// création du tableau de ddl de travail
Tableau <Ddl> ta(dimen);
for (int ii=1; ii<= dimen; ii++)
ta(ii) = Ddl (Enum_ddl(ii+posi),0.,val_fixe); // bonne version
// dans le cas où le calcul est axisymétrique
// le dernier ddl en z est mis en HSLIBRE, car on ne le prend pas en compte dans le calcul
// axisymétrique
if (ParaGlob::AxiSymetrie())
ta(3) = Ddl (Enum_ddl(3+posi),0.,HSLIBRE); // bonne version;
// maintenant on passe en revu les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
// on regarde si le déplacement existe
if (noo->Existe_ici(X1))
noo->PlusTabDdl(ta);
}
}
// on va passer en revue les éléments pour initialiser si nécessaire les conteneurs
// d'accélération si on est en mécanique
// on balaie les maillages et les éléments
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbelementmax = tabMaillage(i1)->Nombre_element();
for (int i2 = 1; i2 <= nbelementmax; i2++)
{ Element & elem = Element_LesMaille(i1,i2);
if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
((ElemMeca&) elem).Active_conteneurs_metrique_acceleration();
};
};
};
// calcul de la longueur d'arrête d'élément minimal
// divisé par la célérité dans le matériau
double LesMaillages::Longueur_arrete_mini_sur_c(Enum_dure temps)
{ double dist_ret = ConstMath::tresgrand; // def de la distance de retour
// on balaie les maillages et les éléments
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbelementmax = tabMaillage(i1)->Nombre_element();
for (int i2 = 1; i2 <= nbelementmax; i2++)
{ Element & elem = Element_LesMaille(i1,i2);
if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
{ double dist = ((ElemMeca&) elem).Long_arrete_mini_sur_c(temps);
dist_ret = MiN(dist_ret,dist);
}
}
}
return dist_ret;
};
// initialisation éventuelle du bulk viscosity
void LesMaillages::Init_bulk_viscosity(int choix,const DeuxDoubles & coef)
{ // on renseigne la classe générique d'éléments mécanique si besoin
// choix peut-être égale à 0, 1 ou 2
if (choix)
{ ElemMeca::ActiveBulkViscosity(choix); // activation du bulk viscosity
ElemMeca::ChangeCoefsBulkViscosity(coef); // passage des coeffs
}
};
// -- encore plus générique
// changement de toutes les conditions données (service, variable, fixage ..)
// selon le tableau de ddl passé en paramètre
// par contre les valeurs de ta ne sont pas utilisé donc les valeurs actuelles restent inchangé
void LesMaillages::ChangeToutesLesConditions(const Tableau<Ddl>& ta)
{ // création d'une liste qui contiendra tous les ddl à passer aux noeuds
list <Ddl> liddl;
// on boucle sur le tableau
int taTaille = ta.Taille();
for (int ita=1;ita<=taTaille;ita++)
{ Ddl& taa=ta(ita);Enum_boolddl enub=taa.Retour_Fixe();
Tableau<Enum_ddl> tenu = TableauTypeDdl(taa.Id_nom()); // récup du tableau d'enum
int tenuTaille = tenu.Taille();
for (int i=1;i<=tenuTaille;i++) liddl.push_back(Ddl(tenu(i),0.,enub));
};
// création du tableau de travail que l'on passera aux noeuds
Tableau<Ddl> tddl(liddl.size());
list<Ddl>::iterator il,ifin=liddl.end();int iii=1;
for (il=liddl.begin();il!=ifin;il++,iii++) tddl(iii)=(*il);
// maintenant on passe en revue les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
noo->ChangeToutesLesConditions(tddl);
}
}
};
// changement de statu des ddl d'une combinaison, en fonction du statut
// de enuta dans chaque noeud, les ddl de la combinaison, prennent le même statut que celui
// de enuta dans chaque noeud.
// cas est la combinaison,
void LesMaillages::ChangeStatut(int cas,Enum_ddl enuta)
{// on passe en revue les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
noo->ChangeStatut(cas,enuta);
}
}
};
// changement de statu des ddl d'une combinaison dans chaque noeud, en fonction
// de enubold, les ddl de la combinaison, prennent le même statut que enubold
// cas est la combinaison,
void LesMaillages::ChangeStatut(int cas,Enum_boolddl enubold)
{// on passe en revue les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
noo->ChangeStatut(cas,enubold);
}
}
};
//change le statut de tous les ddl liés à la physique en cours
//par exemple: met à libre ou bloque les ddl liés à la physique en cours
void LesMaillages::Libere_Ddl_representatifs_des_physiques(Enum_boolddl enubold)
{ // ddl_representatifs_des_physiques représentent tous les ddl de la physique
if (ddl_representatifs_des_physiques.size()) // on ne continue que si c'est diff de 0
{list <Enum_ddl >::iterator il,ilfin= ddl_representatifs_des_physiques.end();
list <Enum_ddl >::iterator ildebut = ddl_representatifs_des_physiques.begin();
// on fait un premier balayage, car il s'agit des "types" de ddl mais pas de la liste
// qui elle dépend de la dimension éventuellement
int nbddl = 0; // init
for (il = ildebut;il != ilfin; il++)
nbddl += TableauTypeDdl(*il).Taille();
// on définit un tableau "ta" pour appeler les noeuds
// qui contient tous les ddl (et pas seulement les types)
Ddl enu((*ildebut),0.0,enubold); // def du premier ddl
Tableau<Ddl> ta(nbddl,enu); int ita=1;
for (il = ildebut;il != ilfin; il++)
{Tableau<Enum_ddl> tddl = TableauTypeDdl(*il);
int ndPlus1 = tddl.Taille() + 1;
for (int i=1;i< ndPlus1;i++,ita++)
ta(ita).Change_nom(tddl(i));
};
// on passe en revue les noeuds
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
// on change les conditions données par ta
noo->ChangeToutesLesConditions(ta);
};
};
};
};
//----- lecture écriture base info -----
// lecture base info
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void LesMaillages::Lecture_base_info(ifstream& ent,const int cas)
{ string toto;
// cout << "\n debug **** LesMaillages::Lecture_base_info\n"
// << "\n entr.rdstate() " << ent.rdstate() << flush;
// lecture du nombre de maillage total
ent >> toto >> nbMaillageTotal;
// cout << "\n debug **** LesMaillages::Lecture_base_info\n"
// << " toto= "<< toto << nbMaillageTotal
// << "\n entr.rdstate() " << ent.rdstate() << flush;
switch (cas)
{ case 1 : // ------- on récupère tout -------------------------
{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ // tout d'abord création du maillage
tabMaillage(i1) = new Maillage (mapNomMail,i1,paraGlob->Dimension());
// puis lecture
tabMaillage(i1)->Lecture_base_info(ent,cas);
};
// on s'occupe de mettre à jour les types de pb et les ddl types associés
Mise_a_jour_type_pb_type_associe_ddl();
break;
}
case 2 : // ----------- on ne récupère que ce qui varie
{ for (int i1 = 1; i1<= nbMaillageTotal; i1++)
tabMaillage(i1)->Lecture_base_info(ent,cas);
// ----- cas des grandeurs intégrés éventuelles-----
// utile pour pouvoir post-traiter et également pour le cumul sur le temps
ent >> toto;
if (toto != "int_vol_mail")
{ cout << "\nErreur : en lecture de l'entete de l'integration de volume eventuelle"
<< " on attendait le mot cle int_vol_mail et on a lu "<< toto <<" !\n";
cout << "LesMaillages::Lecture_base_info(....)" << flush;
Sortie(1);
};
int integ_vol_typeQuel_taille = 0;
ent >> integ_vol_typeQuel_taille;
// on boucle sur les grandeurs à lire
// si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
// mais dans ce cas elle ne changera plus pendant le calcul
for (int i=1;i<= integ_vol_typeQuel_taille;i++)
{ // on lit l'entête d'un type quelconque
// -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
// lecture de l'entête et récup d'enu
// on utilise: avec création, car il peut s'agir d'une intégrale qui n'est plus active
// du coup le tableau existant ne contient pas cette intégrale
EnuTypeQuelParticulier enu_t =
pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
int indice_t = integ_vol_typeQuel_t.Contient(pour_lire_t);
if (indice_t)
{// là il suffit de lire la grandeur associée
ent >> (*integ_vol_typeQuel_t(indice_t).Grandeur_pointee());
};
// normalement le cas a tdt est identique
EnuTypeQuelParticulier enu =
pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
// là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
// le test se fait uniquement sur le TypeQuelconque_enum_etendu
// qui est supposé suffisant comme signature
int indice = integ_vol_typeQuel.Contient(pour_lire);
if (indice)
{// là il suffit de lire la grandeur associée
ent >> (*integ_vol_typeQuel(indice).Grandeur_pointee());
};
if (!indice)
{ // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
// figée, dont la valeur ne changera pas pendant le calcul
// création d'une grandeur associée et lecture des information sur le flot
TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
// création du type quelconque
TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
delete grandeur_t; // car il ne sert plus à rien
TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
// création du type quelconque
TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
delete grandeur; // car il ne sert plus à rien
// maintenant on va mettre à jour le stockage interne
// ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
// à l'initialisation du .info
indice_t = integ_vol_typeQuel_t.Taille()+1;
indice = integ_vol_typeQuel.Taille()+1;
integ_vol_typeQuel_t.Change_taille(indice_t);
integ_vol_typeQuel.Change_taille(indice);
integ_vol_typeQuel(indice) = typQ;
integ_vol_typeQuel_t(indice_t) = typQ_t;
ref_integ_vol.Change_taille(indice);// normalement c'est le même qu'indice_t
// par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
// figé, car aucun domaine d'intégration n'a été définit
ref_integ_vol(indice) = NULL;
};
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ_t = integ_vol_typeQuel_t(indice); // pour simplifier
// cas des grandeurs à t: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
const string* nom_de_ref = g_TG_t->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_typeQuel_t(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
};
};
// idem pour la grandeur courante
{TypeQuelconque& TQ = integ_vol_typeQuel(indice); // pour simplifier
// cas des grandeurs à tdt: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_typeQuel(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
// la valeur passée en paramétre est celle de t !!
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
};
};
}; // boucle sur les grandeurs lues
// maintenant les intégrales de volume et en temps
ent >> toto;
if (toto != "int_vol_temps_mail")
{ cout << "\nErreur : en lecture de l'entete de l'integration de volume et en temps eventuelle"
<< " on attendait le mot cle int_vol_temps_mail et on a lu "<< toto <<" !\n";
cout << "LesMaillages::Lecture_base_info(....)" << flush;
Sortie(1);
};
int integ_vol_t_typeQuel_taille = 0;
ent >> integ_vol_t_typeQuel_taille;
// on boucle sur les grandeurs à lire
// si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
// mais dans ce cas elle ne changera plus pendant le calcul
for (int i=1;i<= integ_vol_t_typeQuel_taille;i++)
{ // on lit l'entête d'un type quelconque
// -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
// lecture de l'entête et récup d'enu
// on utilise: avec création, car il peut s'agire d'une intégrale qui n'est plus active
// du coup le tableau exitant ne contient pas cette intégrale
EnuTypeQuelParticulier enu_t =
pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
// là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
// le test se fait uniquement sur le TypeQuelconque_enum_etendu
// qui est supposé suffisant comme signature
int indice_t = integ_vol_t_typeQuel_t.Contient(pour_lire_t);
if (indice_t)
{// là il suffit de lire la grandeur associée
ent >> (*integ_vol_t_typeQuel_t(indice_t).Grandeur_pointee());
};
// idem à t
EnuTypeQuelParticulier enu =
pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
int indice = integ_vol_t_typeQuel.Contient(pour_lire);
if (indice)
{// là il suffit de lire la grandeur associée
ent >> (*integ_vol_t_typeQuel(indice).Grandeur_pointee());
};
if (!indice)
{ // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
// figée, dont la valeur ne changera pas pendant le calcul
// création d'une grandeur associée et lecture des information sur le flot
TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
// création du type quelconque
TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
delete grandeur_t; // car il ne sert plus à rien
TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
// création du type quelconque
TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
delete grandeur; // car il ne sert plus à rien
// maintenant on va mettre à jour le stockage interne
// ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
// à l'initialisation du .info
indice = integ_vol_t_typeQuel_t.Taille()+1;
integ_vol_t_typeQuel_t.Change_taille(indice);
integ_vol_t_typeQuel.Change_taille(indice);
integ_vol_t_typeQuel(indice) = typQ;
integ_vol_t_typeQuel_t(indice) = typQ_t;
ref_integ_vol_t.Change_taille(indice);
// par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
// figé, car aucun domaine d'intégration n'a été définit
ref_integ_vol_t(indice) = NULL;
};
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ_t = integ_vol_t_typeQuel_t(indice); // pour simplifier
TypeQuelconque& TQ = integ_vol_t_typeQuel(indice); // pour simplifier
// transfert des intégrales finalisées
// on considère que les grandeurs à tdt doivent être initialisées à celles de t
(TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
// cas des grandeurs à t: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
const string* nom_de_ref = g_TG_t->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_t_typeQuel_t(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
};
};
// cas des grandeurs à tdt
// integ_vol_t_typeQuel(i) = integ_vol_t_typeQuel_t(i);
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ = integ_vol_t_typeQuel(indice); // pour simplifier
// cas des grandeurs à tdt: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_t_typeQuel(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
};
};
}; // boucle sur les grandeurs lues
// déjà fait
// integ_vol_t_typeQuel = integ_vol_t_typeQuel_t; // init
// ----- cas des statistiques éventuelles-----
// utile pour pouvoir post-traiter et également pour le cumul sur le temps
ent >> toto;
if (toto != "statistique_mail")
{ cout << "\nErreur : en lecture de l'entete de statistique eventuelle"
<< " on attendait le mot cle statistique_mail et on a lu "<< toto <<" !\n";
cout << "LesMaillages::Lecture_base_info(....)" << flush;
Sortie(1);
};
int statistique_typeQuel_taille = 0;
ent >> statistique_typeQuel_taille;
// on boucle sur les grandeurs à lire
// si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
// mais dans ce cas elle ne changera plus pendant le calcul
for (int i=1;i<= statistique_typeQuel_taille;i++)
{ // on lit l'entête d'un type quelconque
// -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
// lecture de l'entête et récup d'enu
// on utilise: avec création, car il peut s'agir d'une statistique qui n'est plus active
// du coup le tableau existant ne contient pas cette statistique
EnuTypeQuelParticulier enu_t =
pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
int indice_t = statistique_typeQuel_t.Contient(pour_lire_t);
if (indice_t)
{// là il suffit de lire la grandeur associée
ent >> (*statistique_typeQuel_t(indice_t).Grandeur_pointee());
};
// normalement le cas a tdt est identique
EnuTypeQuelParticulier enu =
pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
// là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
// le test se fait uniquement sur le TypeQuelconque_enum_etendu
// qui est supposé suffisant comme signature
int indice = statistique_typeQuel.Contient(pour_lire);
if (indice)
{// là il suffit de lire la grandeur associée
ent >> (*statistique_typeQuel(indice).Grandeur_pointee());
};
if (!indice)
{ // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
// figée, dont la valeur ne changera pas pendant le calcul
// création d'une grandeur associée et lecture des information sur le flot
TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
// création du type quelconque
TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
delete grandeur_t; // car il ne sert plus à rien
TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
// création du type quelconque
TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
delete grandeur; // car il ne sert plus à rien
// maintenant on va mettre à jour le stockage interne
// ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
// à l'initialisation du .info
indice_t = statistique_typeQuel_t.Taille()+1;
indice = statistique_typeQuel.Taille()+1;
statistique_typeQuel_t.Change_taille(indice_t);
statistique_typeQuel.Change_taille(indice);
statistique_typeQuel(indice) = typQ;
statistique_typeQuel_t(indice_t) = typQ_t;
ref_statistique.Change_taille(indice);// normalement c'est le même qu'indice_t
// par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
// figé, car aucune ref de statistique n'a été définie
ref_statistique(indice) = NULL;
};
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ_t = statistique_typeQuel_t(indice); // pour simplifier
// cas des grandeurs à t: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
const string* nom_de_ref = g_TG_t->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans statistique !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&statistique_typeQuel_t(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
};
};
// idem pour la grandeur courante
{TypeQuelconque& TQ = statistique_typeQuel(indice); // pour simplifier
// cas des grandeurs à tdt: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans statistique !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&statistique_typeQuel(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
// la valeur passée en paramétre est celle de t !!
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
};
};
}; // boucle sur les grandeurs lues
// maintenant les statistiques avec cumul en temps
ent >> toto;
if (toto != "statistique_temps_mail")
{ cout << "\nErreur : en lecture de l'entete de la statistique avec cumul en temps eventuelle"
<< " on attendait le mot cle statistique_temps_mail et on a lu "<< toto <<" !\n";
cout << "LesMaillages::Lecture_base_info(....)" << flush;
Sortie(1);
};
int statistique_t_typeQuel_taille = 0;
ent >> statistique_t_typeQuel_taille;
// on boucle sur les grandeurs à lire
// si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
// mais dans ce cas elle ne changera plus pendant le calcul
for (int i=1;i<= statistique_t_typeQuel_taille;i++)
{ // on lit l'entête d'un type quelconque
// -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
// lecture de l'entête et récup d'enu
// on utilise: avec création, car il peut s'agir d'une statistique qui n'est plus active
// du coup le tableau exitant ne contient pas cette statistique
EnuTypeQuelParticulier enu_t =
pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
// là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
// le test se fait uniquement sur le TypeQuelconque_enum_etendu
// qui est supposé suffisant comme signature
int indice_t = statistique_t_typeQuel_t.Contient(pour_lire_t);
if (indice_t)
{// là il suffit de lire la grandeur associée
ent >> (*statistique_t_typeQuel_t(indice_t).Grandeur_pointee());
};
// idem à t
EnuTypeQuelParticulier enu =
pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
int indice = statistique_t_typeQuel.Contient(pour_lire);
if (indice)
{// là il suffit de lire la grandeur associée
ent >> (*statistique_t_typeQuel(indice).Grandeur_pointee());
};
if (!indice)
{ // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
// figée, dont la valeur ne changera pas pendant le calcul
// création d'une grandeur associée et lecture des information sur le flot
TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
// création du type quelconque
TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
delete grandeur_t; // car il ne sert plus à rien
TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
// création du type quelconque
TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
delete grandeur; // car il ne sert plus à rien
// maintenant on va mettre à jour le stockage interne
// ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
// à l'initialisation du .info
indice = statistique_t_typeQuel_t.Taille()+1;
statistique_t_typeQuel_t.Change_taille(indice);
statistique_t_typeQuel.Change_taille(indice);
statistique_t_typeQuel(indice) = typQ;
statistique_t_typeQuel_t(indice) = typQ_t;
ref_statistique_t.Change_taille(indice);
// par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
// figé, car aucune ref de noeuds n'a été définie
ref_statistique_t(indice) = NULL;
};
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ_t = statistique_t_typeQuel_t(indice); // pour simplifier
TypeQuelconque& TQ = statistique_t_typeQuel(indice); // pour simplifier
// transfert des statistiques finalisées
// on considère que les grandeurs à tdt doivent être initialisées à celles de t
(TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
// cas des grandeurs à t: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
const string* nom_de_ref = g_TG_t->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&statistique_t_typeQuel_t(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
};
};
// on va créer ou mettre à jour une grandeur globale associée
{TypeQuelconque& TQ = statistique_t_typeQuel(indice); // pour simplifier
// cas des grandeurs à tdt: on alimente les grandeurs globales
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans statistique avec cuml en temps !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Lecture_base_info(..."<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur éventuel
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
if (pointe == NULL)
// la grandeur n'existe pas on la définie
ParaGlob::param->Ajout_grandeur_consultable(&statistique_t_typeQuel(indice),*nom_de_ref);
else // sinon on affecte
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
(gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
};
};
}; // boucle sur les grandeurs lues
break;
}
default :
{ cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
cout << "LesMaillages::Lecture_base_info(....)"
<< " cas= " << cas << flush;
Sortie(1);
};
};
};
// écriture base info
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LesMaillages::Ecriture_base_info(ofstream& sort,const int cas)
{ sort << "\n ****les_maillages:_nombre= " << nbMaillageTotal ;
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
tabMaillage(i1)->Ecriture_base_info(sort,cas);
switch (cas)
{ case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
{ // ----- cas des grandeurs intégrés éventuelles-----
// utile pour pouvoir post-traiter et également pour le cumul sur le temps
// 1) les intégrales de volume
sort << "\n\n int_vol_mail ";
int integ_vol_typeQuel_taille = integ_vol_typeQuel.Taille();
if (integ_vol_typeQuel_taille == 0)
sort << 0; else sort << integ_vol_typeQuel_taille;
sort << " ";
for (int i=1;i<= integ_vol_typeQuel_taille;i++)
// il faut que l'on sauvegarde à t et tdt sinon au restart les grandeurs à tdt n'existe pas
sort << "\n" << integ_vol_typeQuel_t(i) << " "<<integ_vol_typeQuel(i);
// 2) les intégrales de volume et de temps
sort << "\n int_vol_temps_mail ";
int integ_vol_t_typeQuel_taille = integ_vol_t_typeQuel.Taille();
if (integ_vol_t_typeQuel_taille == 0) sort << 0; else sort <<integ_vol_t_typeQuel_taille;
sort << " ";
for (int i=1;i<= integ_vol_t_typeQuel_taille;i++)
sort << "\n" << integ_vol_t_typeQuel_t(i)<< " "<<integ_vol_t_typeQuel(i);
// ----- cas des grandeurs statistique éventuelles-----
// utile pour pouvoir post-traiter et également pour le cumul sur le temps
// 1) les statistiques sur des ref de noeuds
sort << "\n\n statistique_mail ";
int statistique_typeQuel_taille = statistique_typeQuel.Taille();
if (statistique_typeQuel_taille == 0)
sort << 0; else sort << statistique_typeQuel_taille;
sort << " ";
for (int i=1;i<= statistique_typeQuel_taille;i++)
// il faut que l'on sauvegarde à t et tdt sinon au restart les grandeurs à tdt n'existe pas
sort << "\n" << statistique_typeQuel_t(i) << " "<<statistique_typeQuel(i);
// 2) les statistiques avec cumul sur le temps
sort << "\n statistique_temps_mail ";
int statistique_t_typeQuel_taille = statistique_t_typeQuel.Taille();
if (statistique_t_typeQuel_taille == 0) sort << 0; else sort <<statistique_t_typeQuel_taille;
sort << " ";
for (int i=1;i<= statistique_t_typeQuel_taille;i++)
sort << "\n" << statistique_t_typeQuel_t(i)<< " "<<statistique_t_typeQuel(i);;
}
};
};
// sortie du schemaXML: en fonction de enu
void LesMaillages::SchemaXML_LesMaillages(ofstream& sort,const Enum_IO_XML enu) const
{ switch (enu)
{case XML_TYPE_GLOBAUX:
{ // cas des classes de base
DeuxEntiers toto;
toto.SchemaXML_DeuxEntiers(sort,enu);
Maillage::SchemaXML_Maillages(sort,enu) ;
break;
}
case XML_IO_POINT_INFO:
{// cas de def de LesMaillages
sort << "\n <xs:element name=\"LesMaillages\" >"
<< "\n <xs:complexType>"
<< "\n <xs:annotation>"
<< "\n <xs:documentation> une suite de maillages </xs:documentation>"
<< "\n </xs:annotation>"
<< "\n <xs:sequence>"
<< "\n <xs:element name=\"Maillage\" type=\"Maillage\" "
<< "\n minOccurs=\"1\" maxOccurs=\"unbounded\" />"
<< "\n </xs:sequence>"
<< "\n </xs:complexType>"
<< "\n </xs:element>";
// def de Maillage
// SchemaXML_Maillage(sort,niveau);
break;
}
};
};
// ------ informations utiles par exemples pour la visualisation
// retourne les dimensions minis et maxi suivant les axes du repère
// absolu du maillage numéro nbmail (en faite le calcul est fondé
// uniquement sur la position des noeuds du maillage
// le premier vecteur contient les minimums
// le deuxième vecteur contient les maximums
Tableau <Vecteur> LesMaillages::Taille_boite(int nbmail)
{
#ifdef MISE_AU_POINT
// vérification que le numéro de maillage est correcte
if (( nbmail <= 0) || (nbmail > nbMaillageTotal))
{ cout << "\n erreur, le numéro de maillage demandé est érroné,"
<< " nbmail = " << nbmail
<< " \n LesMaillages::Taille_boite(int nbmail) " ;
Sortie(1);
}
#endif
return tabMaillage(nbmail)->Taille_boiteMail();
};
// dans le cas ou aucun numéro de maillage n'est fournis
// c'est l'encombrement de tous les maillages qui est fourni
Tableau <Vecteur> LesMaillages::Taille_boite()
{ if (nbMaillageTotal == 0)
// cas particulier ou aucun maillage n'est définit
{ Tableau <Vecteur> toto(2);
return toto;
}
// l'objectif est de balayer tous les maillages
// tout d'abord initialisation du tableau de retour sur le premier
// maillage
Tableau <Vecteur> tabsortie = tabMaillage(1)->Taille_boiteMail();
for (int i1 = 2; i1<= nbMaillageTotal; i1++)
{ // récupération du tableau calculé
Tableau <Vecteur> tabinter = tabMaillage(i1)->Taille_boiteMail();
// différent tests
int dima = tabsortie(1).Taille();
for (int it=1;it<=dima;it++)
{ if (tabsortie(1)(it) > tabinter(1)(it))
tabsortie(1)(it) = tabinter(1)(it);
if (tabsortie(2)(it) < tabinter(2)(it))
tabsortie(2)(it) = tabinter(2)(it);
}
}
// retour
return tabsortie;
};
// mise à jour des boites d'encombrements des éléments, qui contiennent des éléments frontières
// et des éléments frontières eux-même
void LesMaillages::Mise_a_jour_boite_encombrement_elem_front(Enum_dure temps)
{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ // tout d'abord les boites des éléments: on passe en revue tous les éléments
int nbelmax = Nombre_element(i1);
for (int jel = 1; jel <= nbelmax; jel++)
{ // récup de l'élément
Element& elem = tabMaillage(i1)->Element_mail(jel);
// on regarde si l'élément contient des éléments frontières
if (elem.Existe_frontiere())
elem.Boite_encombre_element(temps);
};
// maintenant on s'occupe des frontières
LaLIST <Front>* lisfrontmail = listFrontiere(i1); // pour simplifier
LaLIST <Front>::iterator il,ilfin=lisfrontmail->end();
for (il=lisfrontmail->begin();il != ilfin; il++)
(*il).Boite_encombrement_frontiere(temps);
};
};
// crée et ramene pour tous les maillages, la liste des éléments qui contiennent chaque noeud
// mis à jour lorsque lors de la création des frontières
const Tableau < const Tableau <List_io < Element* > > *>& LesMaillages::Indice()
{ tous_indices.Change_taille(nbMaillageTotal);
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ tous_indices(i1)= &(tabMaillage(i1)->Maillage::Indice());};
return tous_indices;
};
// -----------------------------------------------------
// | utilitaires de manipulation de maillage |--
// -----------------------------------------------------
// création de maillage quadratiques incomplets à partir de maillages linéaires.
// En fait il y création de maillages identiques aux maillages déjà existants, les éléments qui sont de types
// linéaires sont remplacés par des éléments quadratiques incomplets correspondants.
// Il y a création de références correspondantes
void LesMaillages::CreeMaillagesQuadratiques_a_partir_des_lineaires(LesReferences* lesRef)
{ // création de la liste qui sert pour repérer les maillages créés
list <DeuxEntiers> tab_lin_vers_comp;
// tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
for (int im=1;im<=nbMaillageTotal;im++)
if (tabMaillage(im)->Contient_lineaire())
{ nb_final_maillage++;
tab_lin_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
};
// dans le cas où des maillages linéaires existent, création de nouveaux maillages
nbMaillageTotal = nb_final_maillage;
// on vérifie et augmente éventuellement la taille du nombre de maillage
while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// maintenant on passe en revue les maillages candidats
list<DeuxEntiers>::iterator il,ifin= tab_lin_vers_comp.end();
for (il=tab_lin_vers_comp.begin();il!=ifin;il++)
{ // on commence par créé le futur maillage quadratique à l'identique du maillage linéaire
// original, il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == (*il).un)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille((*il).deux);
list_inter_ref.push_back(ref_nv);
// on intègre la référence dans lesRéférences
// lesRef->Ajout_reference(ref_nv);
}
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
// complets. Les références sont également transformés en cohérence.
tabMaillage((*il).deux)->Transfo_lin_quadraIncomp(*lesRef);
}
};
// création de maillage quadratiques complets à la place des maillages incomplet
// les éléments qui sont de types quadratiques incomplets sont remplacés par des éléments
// quadratiques complets correspondants.
// Il y a création de références correspondantes
void LesMaillages::CreeMaillagesQuadratiquesComplets_a_partir_des_incomplets(LesReferences* lesRef)
{ // création de la liste qui sert pour repérer les maillages complets créés
list <DeuxEntiers> tab_quadra_inc_vers_comp;
// tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
for (int im=1;im<=nbMaillageTotal;im++)
if (tabMaillage(im)->Contient_quadratique_incomplet())
{ nb_final_maillage++;
tab_quadra_inc_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
}
// dans le cas où des maillages de quadratiques incomplet existent, création de nouveaux maillages
nbMaillageTotal = nb_final_maillage;
while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// maintenant on passe en revue les maillages candidats
list<DeuxEntiers>::iterator il,ifin= tab_quadra_inc_vers_comp.end();
for (il=tab_quadra_inc_vers_comp.begin();il!=ifin;il++)
{ // on commence par créé le futur maillage complet à l'identique du maillage incomplet
// original, il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == (*il).un)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille((*il).deux);
list_inter_ref.push_back(ref_nv);
// on intègre la référence dans lesRéférences
// lesRef->Ajout_reference(ref_nv);
}
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
// complets. Les références sont également transformés en cohérence.
tabMaillage((*il).deux)->Transfo_quadraIncomp_quadraComp(*lesRef);
}
};
// Affiche les donnees des maillages dans des fichiers dont le nom est construit à partir du nom de
// chaque maillage au format ".her" et ".lis"
// le paramètre optionnel indique le numéro du maillage à afficher, s'il vaut -1, on affiche tous les maillages
void LesMaillages::Affiche_maillage_dans_her_lis(Enum_dure temps,LesReferences &lesRef,int imail)
{ if (imail == -1)
{// cas de l'affichage de tous les maillages, on passe en revue les différents maillages
for (int im=1;im<=nbMaillageTotal;im++)
tabMaillage(im)->Affiche_dans_her_lis(lesRef,temps);
}
else
{// cas de l'affichage d'un maillage particulier
if ((imail < 1)||(imail > nbMaillageTotal))
{ cout << "\n erreur dans l'affichage d'un maillage en format .her et .lis"
<< "\n le numero propose: " << imail << " de maillage n'existe pas !! "
<< "\n LesMaillages::Affiche_maillage_dans_her_lis(LesReferences &lesRef,int imail)";
Sortie(1);
}
tabMaillage(imail)->Affiche_dans_her_lis(lesRef,temps);
}
};
// relocalisation des points milieux des arrêtes des éléments quadratiques
void LesMaillages::RelocPtMilieuMailleQuadra()
{ // on passe en revue les différents maillages
for (int im=1;im<=nbMaillageTotal;im++)
tabMaillage(im)->RelocPtMilieuMailleQuadra();
};
// création et ajout d'un nouveau maillage en fonction d'un nom et d'une liste
// d'éléments et de noeuds
// *** il n'y a pas de création de nouveaux noeuds et de nouveaux éléments,
// ce sont les éléments et noeuds passés en paramètres qui sont ceux du maillage créé
// >> ramène le numéro du nouveau maillage
int LesMaillages::Creation_nouveau_maillage
(list <Noeud*>& li_noeud,list <Element*>& list_elem,const string& nom_maillage)
{ if (ParaGlob::NiveauImpression() >= 4)
cout << " debut de l'ajout d'un nouveau maillage " << flush;
// recherche d'un numéro du maillage
nbMaillageTotal++;
if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
int nbElem= list_elem.size();
tabMaillage(nbMaillageTotal) = new Maillage (mapNomMail,paraGlob->Dimension()
,li_noeud,list_elem
,nbMaillageTotal,nom_maillage);
// indique le nb de maillage pour l'enregistrement des prochaines references
lesRef->NbMaille(nbMaillageTotal);
if (ParaGlob::NiveauImpression() >= 4)
cout << " fin de l'ajout d'un nouveau maillage " << flush;
// retour du numéro de maillage
return nbMaillageTotal;
};
// suppression d'un maillage existant
// par défaut, tous les noeuds et éléments du maillage sont supprimés
// si sans_conservation_noeuds_elements est false: les noeuds et les éléments ne sont pas supprimés
// mais ils ne sont plus référencés dans ce maillage !
void LesMaillages::Suppression_maillage( const string& nom_maillage,const bool sans_conservation_noeuds_elements)
{ // on commence par récupérer le numéro du maillage
int num_mail = NumMaillage(nom_maillage);
if (num_mail != 0 ) // sinon il n'y a rien n'a supprimer
{ if (ParaGlob::NiveauImpression() >= 4)
cout << " delet of the mesh " << nom_maillage << flush ;
// on supprime le maillage
// Dans le cas particulier où l'on veut garder les noeuds et éléments, on l'indique au maillage
// avant sa suppression
if(!sans_conservation_noeuds_elements)
tabMaillage(num_mail)->Preparation_destruction_avec_conservation_noeuds_elements();
delete tabMaillage(num_mail);
// 1) il faut également supprimer les références qui sont relative au maillage que l'on vient de supprimer
// on commence par stocker la liste des ref à supprimer, on ne les supprime pas à la volée
// de manière à ne pas modifier les bornes de l'algo de parcours
// 2) il faut changer de numéro de maillage, toutes les ref qui sont pour les maillages après le maillage supprimé
bool avec_diminution_num_maillage = true;
lesRef->Supprime_tour_lesRef_un_maillage(num_mail,avec_diminution_num_maillage);
// la map des noms
mapNomMail.erase(nom_maillage);
// -- maintenant il faut que l'on gère tous les tableaux internes qui sont relatifs aux maillages
// on retasse les tableaux
nbMaillageTotal--;
// le tableau de maillage
for (int i = num_mail;i<= nbMaillageTotal;i++)
{tabMaillage(i) = tabMaillage(i+1);
tabMaillage(i)->Change_numero_maillage(i); // changement du numéro de maillage
};
tabMaillage(nbMaillageTotal+1)=NULL;
// les frontières si elles ont été construite
if (listFrontiere.Taille() != 0)
{for (int i = num_mail;i<= nbMaillageTotal;i++)
{tabMaillage(i) = tabMaillage(i+1);
listFrontiere(i) = listFrontiere(i+1);
tt_noeud_front(i) = tt_noeud_front(i+1);
};
listFrontiere.Change_taille(nbMaillageTotal);
tt_noeud_front.Change_taille(nbMaillageTotal);
};
// le nombre de domaine esclave
if (num_mail <= domEsclave )
// il faut diminuer le nombre d'esclave
domEsclave--;
};
};
// création de maillage par extrusion
// Il y a création de références correspondantes
void LesMaillages::CreeMaillageExtrusion2D3D(LesReferences* lesRef)
{ // création de la liste qui sert pour repérer les maillages complets créés
list <DeuxEntiers> tab_quadra_inc_vers_comp;
// tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
for (int im=1;im<=nbMaillageTotal;im++)
if (tabMaillage(im)->Contient_quadratique_incomplet())
{ nb_final_maillage++;
tab_quadra_inc_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
}
// dans le cas où des maillages de quadratiques incomplet existent, création de nouveaux maillages
nbMaillageTotal = nb_final_maillage;
while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// maintenant on passe en revue les maillages candidats
list<DeuxEntiers>::iterator il,ifin= tab_quadra_inc_vers_comp.end();
for (il=tab_quadra_inc_vers_comp.begin();il!=ifin;il++)
{ // on commence par créé le futur maillage complet à l'identique du maillage incomplet
// original, il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == (*il).un)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille((*il).deux);
list_inter_ref.push_back(ref_nv);
// on intègre la référence dans lesRéférences
// lesRef->Ajout_reference(ref_nv);
}
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
// complets. Les références sont également transformés en cohérence.
tabMaillage((*il).deux)->Transfo_quadraIncomp_quadraComp(*lesRef);
}
};
// définition interactive de listes de références
void LesMaillages::CreationInteractiveListesRef(LesReferences* lesRef)
{ // on récupère le nombre de maillage actuellement actif
int nb_maillages_actifs_initiaux = nbMaillageTotal;
cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
// on va boucler sur les maillages et définir des ref pour chaque maillages
for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
tabMaillage(imail)->CreationInteractiveListesRef(lesRef);
};
// modification de l'orientation d'éléments
void LesMaillages::Modif_orientation_element(int cas_orientation,LesReferences* lesRef)
{ // on récupère le nombre de maillage actuellement actif
int nb_maillages_actifs_initiaux = nbMaillageTotal;
cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
switch(cas_orientation)
{ case 1: case 2: case 3: // cas d'une orientation automatique des maillages:
{ // on vérifie et augmente éventuellement la taille du nombre de maillage
while (nbMaillageTotal > nbPortion)
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// on va boucler sur les maillages et définir de nouveaux maillages identiques
for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
{ // il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
int imailnew = imail+nb_maillages_actifs_initiaux;
string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == imail)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille(imailnew);
list_inter_ref.push_back(ref_nv);
};
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// on modifie l'orientation du nouveau maillage en fonction du cas
tabMaillage(imailnew)->Modif_orientation_element(cas_orientation,lesRef);
};
break;
}
case -1: // uniquement vérification
{ // on va boucler sur les maillages
for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
tabMaillage(imail)->Modif_orientation_element(cas_orientation,lesRef);
break;
}
default:
cout << "\n erreur le cas : " << cas_orientation
<< " n'est pas actuellement pris en compte"
<< "\n LesMaillages::Modif_orientation_element(...";
Sortie(1);
};
};
// Collapse des éléments supperposés, c-a-d identiques, dans le cas où il en existe
void LesMaillages::Collapse_element_supperpose(LesReferences* lesRef)
{ // on récupère le nombre de maillage actuellement actif
int nb_maillages_actifs_initiaux = nbMaillageTotal;
cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
// on vérifie et augmente éventuellement la taille du nombre de maillage
while (nbMaillageTotal > nbPortion)
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// on va boucler sur les maillages et définir de nouveaux maillages identiques
for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
{ // il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
int imailnew = imail+nb_maillages_actifs_initiaux;
string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == imail)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille(imailnew);
list_inter_ref.push_back(ref_nv);
};
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// on fusionne les noeuds
tabMaillage(imailnew)->Collapse_element_superpose(lesRef);
};
};
// collapse de noeuds très proche: appartenant à des éléments différents
// rayon : donne la distance maxi entre les noeuds qui doivent être collapsé
void LesMaillages::Collapse_noeuds_proches(double rayon, LesReferences* lesRef)
{ // on récupère le nombre de maillage actuellement actif
int nb_maillages_actifs_initiaux = nbMaillageTotal;
cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
// on vérifie et augmente éventuellement la taille du nombre de maillage
while (nbMaillageTotal > nbPortion)
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// on va boucler sur les maillages et définir de nouveaux maillages identiques
for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
{ // il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
int imailnew = imail+nb_maillages_actifs_initiaux;
string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez";
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == imail)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille(imailnew);
list_inter_ref.push_back(ref_nv);
};
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// on fusionne les noeuds
tabMaillage(imailnew)->Collapse_noeuds_proches(rayon,lesRef);
};
};
// création d'un nouveau maillage issue de la fusion de maillages existants
// nom_mails_a_fusionner : la liste des maillages à fusionner
// new_mail : le nom du nouveau maillage à construire
// NB: si new_mail correspond à un maillage déjà existant, il y a fusion de ce maillage
// avec les autres, sans création d'un nouveau maillage
void LesMaillages::Fusion_maillages(List_io < string >& nom_mails_a_fusionner,const string& new_mail
,LesReferences* lesRef)
{ // on va commencer par créer un nouveau maillage
if (ParaGlob::NiveauImpression() >= 4)
cout << " debut d'une operation de fusion de maillage " << flush;
// on regarde s'il s'agit d'une fusion avec un maillage existant ou non:
Maillage* nevez_mail_ = NULL; // est renseigné dans le if suivant
bool creation_nouveau_maillage = false;
if (NumMaillage(new_mail) == 0)
{ // le retour est nulle: cas d'un nouveau maillage, on va créer un nouveau maillage
// recherche d'un numéro du maillage
nbMaillageTotal++;
if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// le premier maillage est vide
int dim = ParaGlob::Dimension();
tabMaillage(nbMaillageTotal) = new Maillage(mapNomMail,nbMaillageTotal,dim,new_mail);
nevez_mail_ = (tabMaillage(nbMaillageTotal)); // pour simplifier
creation_nouveau_maillage = true;
}
else
{ // il s'agit ici d'un maillage qui existe déjà
nevez_mail_ = (tabMaillage(NumMaillage(new_mail)));
};
// on récupère le maillage de base, qui intègrera les autres
Maillage& nevez_mail = *nevez_mail_;
// avant de faire l'opération de fusion, on va faire un traitement spécial pour les
// références automatiques E_tout, N_tout, F_tout, A_tout, P_tout, G_tout
{Tableau <string> tab_tout(6);
tab_tout(1) = "E_tout";tab_tout(2) = "N_tout"; tab_tout(3) = "F_tout";
tab_tout(4) = "A_tout";tab_tout(5) = "P_tout"; tab_tout(6) = "G_tout";
int idmail = NumMaillage(new_mail);
for (int i=1;i<= 6; i++)
{string& nreftout= tab_tout(i);
if (lesRef->Existe(nreftout,idmail))
{ const Reference& ref1 = lesRef->Trouve(nreftout,idmail); // récup de la ref
Reference* ref2 = ref1.Nevez_Ref_copie(); // on crée une ref identique
string nevez_nom=nreftout+"_1";int num=1; // on cherche un nom qui n'existe pas encore
while (lesRef->Existe(nevez_nom,idmail))
{nevez_nom += "_"+ChangeEntierSTring(num);num++;};
ref2->Change_nom(nevez_nom); // change le nom de la nouvelle ref
lesRef->Ajout_reference(ref2); // ajout de la ref
if (ParaGlob::NiveauImpression() > 0)
cout << "\n >>> attention la reference " << nreftout << " du maillage "
<< nevez_mail.NomDuMaillage() << " a un nouveau nom "<< nevez_nom;
};
};
};
// maintenant on va passer en revue tous les maillages à fusionner
List_io < string >::iterator il,ilfin=nom_mails_a_fusionner.end();
for (il = nom_mails_a_fusionner.begin();il != ilfin;il++)
{ // récup du numéro de maillage,
// et éventuellement on passe le maillage identique à new_mail
// debug
//cout << "\n maillage de la liste à fusionner " << (*il) << " newmail= "<<new_mail << flush;
// fin debug
if (*(il) != new_mail)
{ int num_mail_a_fusion = NumMaillage(*(il));
Maillage& mail_a_fusion = *(tabMaillage(num_mail_a_fusion));
// debug
//cout << "\n *il " << (*il) << " newmail= "<<new_mail
// << " num_mail_a_fusion= "<<num_mail_a_fusion << " NomDuMaillage() " << mail_a_fusion.NomDuMaillage() << flush;
// fin debug
// constitution de la liste de noeuds
Tableau<Noeud *>& tabN = mail_a_fusion.Tab_noeud();
int nbN = tabN.Taille();list <Noeud *> li_Noe;
for (int i=1;i<=nbN;i++)
li_Noe.push_back(tabN(i));
// constitution de la liste d'éléments
Tableau<Element *>& tabE = mail_a_fusion.Tab_element();
int nbE = tabE.Taille();list <Element *> li_Elem;
for (int i=1;i<=nbE;i++)
li_Elem.push_back(tabE(i));
// on récupère les références associées à ce maillage
list <const Reference*> lref; // la liste qui contiendra les ref recherchées
const Reference* ref1 = lesRef->Init_et_Premiere();
// on parcours la liste pour récupérer les ref appartenant au maillage
do { if(ref1->Nbmaille() == num_mail_a_fusion)
// on a trouvé une référence à considérer
{// si l'on est dans le cas de la fusion avec un maillage existant
// on regarde s'il y a déjà une ref avec le même nom dans le maillage
// si oui on change le nom de la ref à ajouter
string ajout="";int num=0;
if (!creation_nouveau_maillage)
{while (lesRef->Existe((ref1->Nom()+ajout),NumMaillage(new_mail)))
{num++;ajout = "_"+ChangeEntierSTring(num);
// debug
//cout << "\n (ref1->Nom()+ajout)" << (ref1->Nom()+ajout) << flush;
// fin debug
};
};
// on crée la référence à ajouter
Reference* ref2 = ref1->Nevez_Ref_copie(); // on crée une ref identique
ref2->Change_nom(ref1->Nom()+ajout);
lref.push_back(ref2);
// on averti que le nom de la référence a changé
if ((ParaGlob::NiveauImpression() > 0) && (ajout != ""))
cout << "\n >>> attention la reference "<<ref1->Nom()<<" du maillage "
<< mail_a_fusion.NomDuMaillage() << " a un nouveau nom "<< (ref1->Nom()+ajout);
// debug
//cout << "\n ref2= " << ref2->Nom() << " num maille "<< ref2->Nbmaille() << flush;
// fin debug
};
// debug
//cout << "\n " << ref1->Nom() << " num maille "<< ref1->Nbmaille() << flush;
// fin debug
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// appel de la méthode de fusion
nevez_mail.Ajout_elements_et_noeuds(li_Noe,li_Elem,&lref,lesRef);
};
};
if (ParaGlob::NiveauImpression() >= 4)
cout << "\n fin de l'operation de fusion de maillage " << flush;
};
// création d'un nouveau maillage issue d'un maillages existants et d'une ref d'éléments
// le nouveau maillage = les éléments de la ref
void LesMaillages::Cree_sous_maillage(int num_mail,LesReferences* lesRef, string nom_ref,const string& new_mail)
{ // on va commencer par créer un nouveau maillage
if (ParaGlob::NiveauImpression() >= 4)
cout << " debut d'une operation de creation de sous-maillage " << flush;
// on va créer un nouveau maillage
// recherche d'un numéro du maillage
nbMaillageTotal++;
if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// le premier maillage est vide
int dim = ParaGlob::Dimension();
// si le nom du nouveau maillage existe déjà, on met nevez en suffixe
string nvnom(new_mail); // init
while (NumMaillage(nvnom))
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
// on commence par créé le futur maillage à l'identique du maillage contenant la ref
// originale, il y a ici création de nouveaux noeuds et éléments
// tabMaillage(nbMaillageTotal) = new Maillage(mapNomMail,nbMaillageTotal,dim,nvnom);
tabMaillage(nbMaillageTotal) = new Maillage (mapNomMail,nbMaillageTotal,nvnom,*tabMaillage(nbMaillageTotal-1));
Maillage* nevez_mail_ = (tabMaillage(nbMaillageTotal)); // pour simplifier
// pour simplifier
Maillage& nevez_mail = *nevez_mail_;
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille(nbMaillageTotal);
list_inter_ref.push_back(ref_nv);
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// puis, pour le nouveau maillage,
// on restreint le maillage aux seuls éléments de la référence passée en paramètre
// toutes les infos relatives à des éléments supprimés, sont également supprimés
nevez_mail.Restreint_sous_maillage(lesRef, nom_ref);
if (ParaGlob::NiveauImpression() >= 4)
cout << "\n fin de l'operation de creation de sous-maillage " << flush;
};
// création d'éléments SFE en fonction d'éléments classiques
void LesMaillages::CreationMaillageSFE() // on passe en revue les différents maillages
{ // création de la liste qui sert pour repérer les maillages créés
list <DeuxEntiers> tab_tri_vers_sfe;
// tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
for (int im=1;im<=nbMaillageTotal;im++)
if (tabMaillage(im)->OKPourTransSfe())
{ nb_final_maillage++;
tab_tri_vers_sfe.push_back(DeuxEntiers(im,nb_final_maillage));
};
// dans le cas où des maillages candidats existent, création de nouveaux maillages
nbMaillageTotal = nb_final_maillage;
// on vérifie et augmente éventuellement la taille du nombre de maillage
while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
{ nbPortion = nbPortion+nbEnreg;
tabMaillage.Change_taille(nbPortion);
};
// maintenant on passe en revue les maillages candidats
list<DeuxEntiers>::iterator il,ifin= tab_tri_vers_sfe.end();
for (il=tab_tri_vers_sfe.begin();il!=ifin;il++)
{ // on commence par créer le futur maillage SFE à l'identique du maillage triangulaire
// original, il y a ici création de nouveau noeud et élément
// on utilise un nouveau nom de maillage construit a partir de l'ancien
string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez"; // init
while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
// on utilise un nouveau nom de maillage construit a partir de l'ancien
nvnom += "_nevez";
tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
// création de références identiques aux cas du maillage initial
const Reference* ref1 = lesRef->Init_et_Premiere();
list <Reference * > list_inter_ref; // une liste intermédiaire de travail
// l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
// des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
// 1) donc premier temps on enregistre
do { if(ref1->Nbmaille() == (*il).un)
// on a trouvé une référence à considérer
{ // on crée une référence identique
Reference* ref_nv = ref1->Nevez_Ref_copie();
// on met à jour le numéro de maillage associé
ref_nv->Change_Nbmaille((*il).deux);
list_inter_ref.push_back(ref_nv);
};
ref1 = lesRef->Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 2) deuxième temps on enregistre
list <Reference * >::iterator kl,klfin=list_inter_ref.end();
for (kl=list_inter_ref.begin();kl != klfin; kl++)
lesRef->Ajout_reference((*kl));
// On transforme les éléments triangulaire du nouveau maillage en SFE
// Les références sont conservées, car a priori identiques
tabMaillage((*il).deux)->CreationMaillageSFE();
}
};
// renumérotation des noeuds de tous les maillages en même temps, + prise en compte
// des conditions linéaires qui existent entre les noeuds
// attention, ne peut fonctionner que si les maillages ont des relations entre eux,
//sinon l'arbre de descendance ne sera pas complet !!
// ramène false si rien n'a changé, vrai sinon
// si le pointeur d'assemblage est non nulle, cela veut dire que l'on veut également une mise à jour
// globale des pointeurs d'assemblages (ce qui est différent de la méthode : MiseAJourPointeurAssemblage(
// qui agit maillage après maillage)
// si le pointeur d'assemblage est non nulle et le drapeau: sans_changement_num_noeud = true
// cela signifie que l'on désire uniquement une renumérotation de pointeur sans celle des noeuds
// ramène dans tous les cas les nouvelles largeurs en ddl
// nouvelles_largeur_en_ddl.un = la largeur totale
// nouvelles_largeur_en_ddl.deux = la demie largeur
// nouvelles_largeur_en_ddl.trois = la demie largeur maximale pour la partie éléments finis
// uniquement (sans les CLL)
bool LesMaillages::Renumerotation(LesReferences& lesRef,const Tableau <Tableau <Condilineaire> >& tab_condCLL
,TroisEntiers& nouvelles_largeur_en_ddl
,const Nb_assemb* nb_casAssemb,bool sans_changement_num_noeud)
{ // pour effectuer la renumérotation il est nécessaire de créer un tableau global de tous les noeuds et
// de tous les éléments, de manière à pouvoir les gérer en même temps
// a1) on calcul les nombres maxi
int nb_noeud = 0; int nb_element = 0;
for (int imail=1;imail<=nbMaillageTotal;imail++)
{ nb_noeud += tabMaillage(imail)->Nombre_noeud();
nb_element += tabMaillage(imail)->Nombre_element();
};
// a2) on crée maintenant les éléments frontières car cela utilise les numéros des noeuds, qui vont être changé
// mais ce n'est pas toujours bien de recréer les frontières, car on peut avoir des grandeurs qui dépendent des frontières
// comme par exemple les éléments de contact: si on refait les frontières, il faut refaire les éléments de contact
// or la renumérotation n'a pas à changer les frontières en elles-mêmes
// donc on adopte une création conditionnelle
if ((listFrontiere.Taille() == 0) || (tt_noeud_front.Taille() == 0))
LesMaillages::CreeElemFront(); // on crée les éléments frontières
// b) on crée les tableaux
Tableau <Noeud *> t_noe(nb_noeud); // le tableau global de noeuds
Tableau <int > t_oldNumNoeud(nb_noeud); // tableau des anciens numéros de noeuds
Tableau<Element *> t_elem(nb_element); // le tableau global des éléments
// c) on rempli les tableaux en changeant les numéros des noeuds (pour avoir une seule numérotation)
// normalement cela n'influe pas sur les éléments car eux ils contiennent des tableaux de pointeur de noeuds
{int numGlobNoeud=1; int numGlobEle = 1;
for (int imil=1;imil<=nbMaillageTotal;imil++)
{ int nbn = tabMaillage(imil)->Nombre_noeud();
Tableau<Noeud *>& tab_noeud = tabMaillage(imil)->Tab_noeud();
for (int inoe = 1; inoe <= nbn; inoe++,numGlobNoeud++)
{ t_noe(numGlobNoeud) = tab_noeud(inoe);
t_oldNumNoeud(numGlobNoeud) = tab_noeud(inoe)->Num_noeud();
t_noe(numGlobNoeud)->Change_num_noeud(numGlobNoeud);
};
int nb_ele = tabMaillage(imil)->Nombre_element();
Tableau<Element *>& tab_element = tabMaillage(imil)->Tab_element();
for (int iel = 1; iel <= nb_ele; iel++,numGlobEle++)
{ t_elem(numGlobEle) = tab_element(iel);
};
};
}; // on encapsule pour isoler les variables numGlobNoeud et numGlobEle qui ne
// doivent exister que dans la boucle
// avant tout changement on calcul la largeur initiale due aux conditions linéaires
// celle-ci n'est valide que dans le cas où tous les noeuds ont des numéros différents
// ce qui est le cas maintenant
int taille_tab_cll = tab_condCLL.Taille();
int largeur_initiale_CLL = 0; // init
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
largeur_initiale_CLL=MaX(largeur_initiale_CLL,condCLL(j).DiffMaxiNumeroNoeud());
};
if ((ParaGlob::NiveauImpression() > 4)
|| ((nb_casAssemb == NULL)&&(ParaGlob::NiveauImpression() > 0))
)
{ cout << "\n pour l'ensemble des conditions linaires: via une numerotation unique pour tous les maillages, "
<< " la 1/2 largeur de bande en noeud initiale est "
<< largeur_initiale_CLL << flush;
};
bool nouvelle_numerotation = false; // pour le contrôle de la fin
// on calcul le point de départ
Tableau < LaLIST_io <Noeud* > > t_voisin; // def du tableau des voisins des noeuds
list < list < Maillage::Noeud_degre > > lis_descent; // stockage des descendants
bool calcul_ok = false; // init par défaut
Noeud* noe_dep = Maillage::Point_de_depart(t_elem,t_noe,tt_noeud_front,t_voisin,lis_descent,tab_condCLL,calcul_ok);
if (calcul_ok) // on ne continue que si c'est ok
{// on appelle l'algorithme de Cuthill Mac Kee
Tableau <Noeud* > tab_N_final = Maillage::Cuthill_Mac_Kee(nb_noeud,noe_dep,t_voisin,lis_descent);
// --- maintenant on regarde l'évolution de la largeur de bande en noeud
// tout d'abord la largeur initiale
int largeur_initiale = Maillage::LargeurBandeEnNoeuds(t_elem);
// on change la numérotation
for (int ia=1;ia <= nb_noeud; ia++)
tab_N_final(ia)->Change_num_noeud(ia);
// nouvelle largeur de bande
int largeur_Cuthill = Maillage::LargeurBandeEnNoeuds(t_elem);
// idem pour les CLL
int largeur_Cuthill_CLL = 0; // init
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
largeur_Cuthill_CLL=MaX(largeur_Cuthill_CLL,condCLL(j).DiffMaxiNumeroNoeud());
};
// on change en numérotation inverse : Cuthill Mac Kee inverse
// car on pense qu'a priori c'est celle-là qui sera la meilleur
///// Tableau <Noeud* > tab_N_inverse(tab_N_final);
for (int ia=1;ia <= nb_noeud; ia++)
{tab_N_final(ia)->Change_num_noeud(1+nb_noeud-ia);
// avec les modifs que j'ai fait après la ligne qui suit ne sert plus ???
///// tab_N_inverse(1+nb_noeud-ia) = tab_N_final(ia);
};
int largeur_Cuthill_inverse = Maillage::LargeurBandeEnNoeuds(t_elem);
// idem pour les CLL
int largeur_Cuthill_inverse_CLL = 0; // init
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
largeur_Cuthill_inverse_CLL=MaX(largeur_Cuthill_inverse_CLL,condCLL(j).DiffMaxiNumeroNoeud());
};
if ((ParaGlob::NiveauImpression() > 3)
|| ((nb_casAssemb == NULL)&&(ParaGlob::NiveauImpression() > 0))
)
{ cout << "\n $$ Premiere etape: optimisation sur l'ensemble des maillages sous forme d'un seul groupe $$ ";
cout << "\n pour l'ensemble des maillages: 1/2 largeur de bande en noeud, initiale= " << largeur_initiale
<< "\n partie conditions lineaires initiales : " << largeur_initiale_CLL
<< " --> maxi des deux: " << MaX(largeur_initiale_CLL, largeur_initiale)
<< " \n apres l'algo de Cuthill Mac Kee= " << largeur_Cuthill
<< ", conditions lineaires : " << largeur_Cuthill_CLL
<< " --> maxi des deux: " << MaX(largeur_Cuthill_CLL, largeur_Cuthill)
<< " \n en Cuthill Mac Kee inverse= " << largeur_Cuthill_inverse
<< ", conditions lineaires : " << largeur_Cuthill_inverse_CLL
<< " --> maxi des deux: " << MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse)<< flush ;
};
// normalement le dernier est le meilleur, en tout cas il est meilleur que le cas 2
// ----- dernières opérations: on regarde si effectivement il faut appliquer la nouvelle
// ----- numérotation
int demi_largeur_totale=MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse);
if (MaX(largeur_initiale_CLL, largeur_initiale)
< MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse))
// if (largeur_initiale < largeur_Cuthill_inverse)
// bizarre, cela veut dire qu'il faut revenir à la forme initiale
{ for (int ia=1;ia <= nb_noeud; ia++)
t_noe(ia)->Change_num_noeud(t_oldNumNoeud(ia));
demi_largeur_totale = MaX(largeur_initiale_CLL, largeur_initiale);
}
else if (MaX(largeur_Cuthill_CLL, largeur_Cuthill)
< MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse) )
// else if (largeur_Cuthill < largeur_Cuthill_inverse )
// bizarre, cela veut dire qu'il faut revenir à la forme de Cuthill directe
{ nouvelle_numerotation = true;
// on met la numérotation définitive relativement au tableau directe
Tableau <int> num_courant(nbMaillageTotal); // tableau des numéros courant de noeud
// pour chaque maillage
for (int ia=1;ia <= nb_noeud; ia++)
// je ne comprend pas ce que j'ai fait. je modifie en faisant ce que je pense être bon ???
////modifié { Noeud* noe = tab_N_final(ia); // pour simplifier
////modifié int num = (num_courant(noe->Num_Mail())++);
////modifié noe->Change_num_noeud(num);
////modifié };
tab_N_final(ia)->Change_num_noeud(ia);
demi_largeur_totale = MaX(largeur_Cuthill_CLL, largeur_Cuthill);
}
else
// c'est le cas normale
{ nouvelle_numerotation=true;
// on met la numérotation définitive relativement au tableau inverse
// là je ne comprend pas ce que j'ai fait, car la numérotation inverse a déjà été faite donc il n'y a rien
// à faire, je comment donc la suite
//// Tableau <int> num_courant(nbMaillageTotal); // tableau des numéros courant de noeud
//// // pour chaque maillage
//// for (int ia=1;ia <= nb_noeud; ia++)
//// { Noeud* noe = tab_N_inverse(ia); // pour simplifier
//// int num = (num_courant(noe->Num_Mail())++);
//// noe->Change_num_noeud(num);
//// };
};
// on calcule si demandé, la largeur de bande en ddl qui résulte de la nouvelle numérotation
// avant de changer les numéros de noeuds
// et la mise à jour des pointeurs d'assemblages
Tableau <Noeud*> tab_N_final_final;// ne sert que pour le cas nb_casAssemb != NULL
if (nouvelle_numerotation && (nb_casAssemb != NULL))
{ // on garde en mémoire la numérotation des noeuds, dans l'ordre de tab_N_final
// car on ne connait pas exactement le cheminement précédent de ce qui est retenue au final
tab_N_final_final.Change_taille(nb_noeud);
for (int i=1;i<=nb_noeud;i++)
tab_N_final_final(tab_N_final(i)->Num_noeud()) = tab_N_final(i);
// on met à jour les pointeurs d'assemblage en suivant le nouvel ordre de noeud
MiseAJourPointeurAssemblage_interne(*nb_casAssemb,tab_N_final_final,false);
// on calcul la largeur finale
int demi = 0; int total = 0;
int cumule = 0;
// cas des CLL:
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
condCLL(j).Largeur_Bande(demi,total,*nb_casAssemb);
};
// on s'occupe des maillages
int demi_pour_mail=0; int total_pour_mail=0;
for (int imil=1;imil<=nbMaillageTotal;imil++)
{int demi_inter=0; int total_inter=0;
tabMaillage(imil)->Largeur_Bande(demi_inter,total_inter,*nb_casAssemb);
demi_pour_mail = MaX(demi_pour_mail,demi_inter);
total_pour_mail =MaX(total_pour_mail,total_inter);
};
// on garde les maxi
demi = MaX(demi,demi_pour_mail);
total =MaX(total,total_pour_mail);
// enregistrement
nouvelles_largeur_en_ddl.deux = demi;
nouvelles_largeur_en_ddl.un = total;
nouvelles_largeur_en_ddl.trois = demi_pour_mail;
if (ParaGlob::NiveauImpression() > 2)
cout << "\n $$$ ==>> opti. glob. numerot. $$$ "
<< " 1/2 larg. ddl ==> " << demi
<< " larg. totale ==> " << total;
//cout << "\n entrer une valeur pour continuer ";
//int toto; cin >> toto;
};
// dans le cas d'une nouvelle numérotation + dans le cas où on veut un changement
// de numérotation effectif dans les noeuds
// ->> introduction de la nouvelle numérotation dans les noeuds et mise à jour des reférences
if ((nouvelle_numerotation) && (!sans_changement_num_noeud))
// il faut donc redéfinir une numérotation pour chaque maillage. Celle-ci
// ne sera pas aussi optimum que dans le cas d'un seul maillage, mais elle devrait
// être meilleure
// -- un tableau d'indice qui donne le nouveau numéro en cours pour chaque maillage
{ Tableau<int> num_noeu_par_maillage(nbMaillageTotal,0);
// un nouveau tableau intermédiaire tel que le noeud t_noe_ordonnee(i), a le numéro i
Tableau <Noeud *> t_noe_ordonnee(nb_noeud); // le tableau global de noeuds
for (int ia=1;ia <= nb_noeud; ia++)
{ Noeud* noe = t_noe(ia); // pour simplifier
t_noe_ordonnee(noe->Num_noeud()) = noe;
};
// si nouvelle numérotation est vrai, on parcourt le tableau et on renumérote à la volée
// la méthode revient à compresser la numérotation pour chaque maillage de manière a
// rester dans les limites du nombre de noeud pour chaque maillage
for (int ia=1;ia <= nb_noeud; ia++)
{ Noeud* noe = t_noe_ordonnee(ia); // pour simplifier
int num_mail = noe->Num_Mail();
num_noeu_par_maillage(num_mail)++;
////--debug
//cout << "\n debug LesMaillages::Renumerotation( "
// << "\n num_noeu_par_maillage("<<num_mail<<")= "<< num_noeu_par_maillage(num_mail)<<flush;
////--- fin debug
noe->Change_num_noeud(num_noeu_par_maillage(num_mail));
};
// Maintenant on s'occupe des références et de la numérotation définitive
// si on a introduit une nouvelle numérotation
// -- on s'occupe des numéros de référence
// 1) on définit un tableau par maillage qui contient les nouveaux numéros
// t_nv_num(j)(i) est pour le maillage j, le nouveau numéro du noeud
// qui avait auparavant le numéro "i"
Tableau <Tableau <int> > t_nv_num(nbMaillageTotal); // nouveau num/ au ancien
for (int iml=1; iml<= nbMaillageTotal;iml++)
t_nv_num(iml).Change_taille(tabMaillage(iml)->Nombre_noeud()); // init
for (int ia=1;ia <= nb_noeud; ia++)
{ Noeud* noe = t_noe(ia); // pour simplifier, on utilise t_noe et non t_noe_ordonnee
// car ensuite on utilise t_oldNumNoeud qui suit le même ordre que t_noe
// //--debug
// cout << "\n debug LesMaillages::Renumerotation( "
// << "\n noe->Num_Mail()= "<<noe->Num_Mail() <<", ia= "<< ia
// << " noe->Num_noeud()= "<<noe->Num_noeud()
// << " t_oldNumNoeud(ia)= "<< t_oldNumNoeud(ia) << flush;
////--- fin debug
t_nv_num(noe->Num_Mail())(t_oldNumNoeud(ia))=noe->Num_noeud();
};
// 2) maintenant on change les références
for (int idmail=1;idmail<=nbMaillageTotal;idmail++)
lesRef.Mise_a_jour_ref_noeud(t_nv_num(idmail),idmail);
// --- on reconstruit les tableaux de pointeurs de noeuds dans chaque maillage
// a) on crée un tableau intermédiaire de tous les tableaux de noeuds
Tableau <Tableau <Noeud *> *> t_t_noeud(nbMaillageTotal);
for (int iml=1; iml<= nbMaillageTotal;iml++)
t_t_noeud(iml) = &(tabMaillage(iml)->Tab_noeud()); // init
// b) on le remplit
for (int ia=1;ia <= nb_noeud; ia++)
{ Noeud* noe = t_noe_ordonnee(ia); // pour simplifier
(*t_t_noeud(noe->Num_Mail()))(noe->Num_noeud()) = noe;
};
};
// affichage du résultat et éventuellement deuxième étape concernant le
// changement des pointeurs d'assemblage
if (nouvelle_numerotation)
{if (nb_casAssemb == NULL) // cas sans changement des pointeurs
// si on ne veut pas changer les pointeurs d'assemblage dans la foulée
// on met une information sur la largeur de bande nouvelle, en noeud,
// qui découle de la nouvelle numérotation (et non de l'assemblage)
{
int largeur_finale_CLL = 0; // init
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
largeur_finale_CLL=MaX(largeur_finale_CLL,condCLL(j).DiffMaxiNumeroNoeud());
};
if (ParaGlob::NiveauImpression() > 0)
{ cout << "\n pour l'ensemble des conditions linaires: la 1/2 largeur de bande en noeud, finale est "
<< largeur_finale_CLL << flush;
};
// non c'est débile, car on n'a pas fait de nouvelle numérotation en ddl, donc cela ne sert à rien de les imprimer
// et au niveau de la numérotation en noeud, c'est déja visualisé
/*
int demi = 0; int total = 0;
int cumule = 0;
// on est quand même obligé de considérer un cas d'assemblage, on prend le dernier
// par défaut
// on récupère le nombre actuel de cas d'assemblage
int nb_actuel = tab_nb_assemb;
#ifdef MISE_AU_POINT
if (nb_actuel == 0)
{cout << "\n erreur Renumerotation : pas de cas d'assemblage encore defini !! "
<< " la renumerotation n'est pas possible ....";
Sortie(1);
};
#endif
Nb_assemb nbAssemble(nb_actuel);
// cas des CLL:
for (int i = 1; i<= taille_tab_cll;i++)
{ Tableau <Condilineaire>& condCLL = tab_condCLL(i);
int taille = condCLL.Taille();
for (int j=1;j<= taille;j++)
condCLL(j).Largeur_Bande(demi,total,nbAssemble);
};
// on s'occupe des maillages
int demi_pour_mail=0; int total_pour_mail=0;
for (int imil=1;imil<=nbMaillageTotal;imil++)
{int demi_inter=0; int total_inter=0;
tabMaillage(imil)->Largeur_Bande(demi_inter,total_inter,nbAssemble);
demi_pour_mail = MaX(demi_pour_mail,demi_inter);
total_pour_mail =MaX(total_pour_mail,total_inter);
};
// on garde les maxi
demi = MaX(demi,demi_pour_mail);
total =MaX(total,total_pour_mail);
// enregistrement
nouvelles_largeur_en_ddl.deux = demi;
nouvelles_largeur_en_ddl.un = total;
nouvelles_largeur_en_ddl.trois = demi_pour_mail;
// affichage du résultat
if (ParaGlob::NiveauImpression() >= 3)
cout << "\n $$$ =>> opti. glob. numerot. $$$ "
<< " 1/2 larg. ddl => " << demi
<< " larg. totale => " << total
<< flush;
*/
}
else // sinon c'est le cas où on veut changer les pointeurs d'assemblage
{// deuxième partie pour les pointeurs d'assemblage:
// on doit mettre à jour le tableau t_i_n pour les pointeurs d'assemblage
// concernant uniquement les numéros de noeuds
// --> deux cas suivant que l'on ne veut pas enregistrer la nouvelle numérotation
// des noeuds ou non
if (sans_changement_num_noeud)
{ // mise à jour des numéros de noeud, on revient aux numéros initiaux
// on revient au numéro initiaux
for (int i=1;i<=nb_noeud;i++)
t_noe(i)->Change_num_noeud(t_oldNumNoeud(i));
// pour chaque noeud, tab_N_final(i) correspond au noeud qui avait le numéro i ancien
// et qui a maintenant le numéro tab_N_final(i)->Num_noeud()
// mise à jour de t_i_n
MiseAJourTableau_t_i_n(*nb_casAssemb,tab_N_final_final);
}
else
{MiseAJourTableau_t_i_n(*nb_casAssemb,tab_N_final_final);
};
};
}
else
{// on remet néanmoins l'ancienne numérotation, car elle a changé
int nbN = t_noe.Taille();
for (int i=1;i<=nbN;i++)
t_noe(i)->Change_num_noeud(t_oldNumNoeud(i));
if (ParaGlob::NiveauImpression() >= 3)
cout << "\n $$$ au final numerot. idem $$$ " << flush;
nouvelle_numerotation = false;
calcul_ok = true;
};
}
else
{// si Maillage::Point_de_depart n'a pas fonctionné correctement il faut remettre l'ancienne numérotation
if (ParaGlob::NiveauImpression() > 2)
cout << "\n calcul du demarrage infructeux de l'algorithme de Gibbs (voisins, descendance etc.) "
<< " on conserve l'ancienne renumerotation ";
for (int nue =1; nue<= nb_noeud; nue++)
t_noe(nue)->Change_num_noeud(t_oldNumNoeud(nue));
};
// retour
return (calcul_ok && nouvelle_numerotation);
};
// renumérotation des noeuds maillages par maillage,
// === sans prise en compte de conditions linéaires ===
// en sortie les maillages sont mis à jour si la nouvelle numérotation conduit à une largeur de bande
// plus faible que la largeur initiale: en noeuds
// ramène: false si rien n'a changé (à cause d'un pb ou parce que la renumérotation n'est pas meilleure)
// vrai sinon
bool LesMaillages::Renumerotation(LesReferences& lesRef)
{ // on crée les éléments frontières car cela utilise les numéros des noeuds, qui vont être changé
// mais ce n'est pas toujours bien de recréer les frontières, car on peut avoir des grandeurs
// qui dépendent des frontières
// comme par exemple les éléments de contact: si on refait les frontières,
// il faut refaire les éléments de contact
// or la renumérotation n'a pas à changer les frontières en elles-mêmes
// donc on adopte une création conditionnelle
if ((listFrontiere.Taille() == 0) || (tt_noeud_front.Taille() == 0))
LesMaillages::CreeElemFront(); // on crée les éléments frontières
// on passe en revue tous les maillages pour une renumérotation individuelle
bool calcul_ok = false; // init par défaut
Tableau <Tableau <Condilineaire> > condCLL; // un tableau vide pour l'appel
for (int imail=1;imail<=nbMaillageTotal;imail++)
{ if (ParaGlob::NiveauImpression() > 2)
cout << "\n ===>> traitement du maillage: " << tabMaillage(imail)->NomDuMaillage();
bool inter = tabMaillage(imail)->Renumerotation(lesRef,condCLL);
calcul_ok = calcul_ok || inter;
};
// retour
return calcul_ok ;
};
// indique aux éléments un niveau de précision de calcul désiré pour les prochains calculs
// precision = 0 : aucune précision demandée, precision >=0 : précision maximale demandée
void LesMaillages::Drapeau_preparation_calcul_precis(int precision)
{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbelmax = Nombre_element(i1);
Maillage* maillage = tabMaillage(i1); // pour simplifier
for (int jel = 1; jel <= nbelmax; jel++)
{ maillage->Element_mail(jel).Drapeau_preparation_calcul_precis(precision);};
};
};
// on s'occupe de mettre à jour les types de pb et les ddl types associés
void LesMaillages::Mise_a_jour_type_pb_type_associe_ddl()
{ types_de_problemes.clear();
ddl_representatifs_des_physiques.clear();
for (int i = 1; i<= nbMaillageTotal; i++)
{
{//const list <EnumElemTypeProblem >& type_pb = (tabMaillage(i))->Types_de_problemes(); // pour simplifier
const Tableau <EnumElemTypeProblem >& type_pb = (tabMaillage(i))->Types_de_problemes(); // pour simplifier
// list <EnumElemTypeProblem>::const_iterator il,ilfin=type_pb.end();
// for (il=type_pb.begin();il != ilfin;il++)
int taill = type_pb.Taille();
for (int j=1;j<=taill;j++)
if (find(types_de_problemes.begin(),types_de_problemes.end(),type_pb(j)) == types_de_problemes.end())
types_de_problemes.push_back(type_pb(j));//(*il);
};
{//const list <Enum_ddl >& type_ddl = (tabMaillage(i))->Ddl_representatifs_des_physiques(); // pour simplifier
//list <Enum_ddl>::const_iterator il,ilfin=type_ddl.end();
//for (il=type_ddl.begin();il != ilfin;il++)
const Tableau <Enum_ddl >& type_ddl = (tabMaillage(i))->Ddl_representatifs_des_physiques(); // pour simplifier
int taill = type_ddl.Taille();
for (int j=1;j<=taill;j++)
if (find(ddl_representatifs_des_physiques.begin(),ddl_representatifs_des_physiques.end()
,type_ddl(j)) == ddl_representatifs_des_physiques.end())
ddl_representatifs_des_physiques.push_back(type_ddl(j));
};
};
types_de_problemes.sort(); types_de_problemes.unique();
ddl_representatifs_des_physiques.sort(); ddl_representatifs_des_physiques.unique();
};
// --- utilitaires pour calculs particuliers-------
// Tableau <TypeQuelconque> integ_vol_typeQuel, integ_vol_typeQuel_t;
// Tableau <const Reference*> ref_integ_vol; // les références associées
// // 2) intégration de volume et en temps: donc on commule le delta
// Tableau <TypeQuelconque> integ_vol_t_typeQuel, integ_vol_t_typeQuel_t;
// Tableau <const Reference*> ref_integ_vol_t; // les références associées
// LesReferences* lesRef; // references
// calcul des diverses intégrations: volume et volume + temps,
// alimentation des grandeurs globales associées
void LesMaillages::Integration()
{ // on passe en revue les références de volumes a intégrer
// Tableau <const Reference*> ref_integ_vol; // les références associées
// les références sont ordonnées par apparition dans le fichier .info
// des intégrales, ceci permet de repérer les bonnes grandeurs à cummuler
int taill = ref_integ_vol.Taille();
for (int rang_integ =1;rang_integ<= taill;rang_integ++)
if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas
// l'intégrale stockée reste fixe pendant le calcul
{ const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol(rang_integ));
// initialisation du conteneur relatif à chaque ref
TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
g_TG->InitParDefaut(); // on initialise le conteneur
// cumule des valeurs: on récupère les infos à partir des éléments concernés
int ref_Taille=ref->Taille();
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage
int nnn = ref->Nbmaille(); // le numero du maillage
// recup de l'element
Element * poi = & Element_LesMaille(nnn,nbb);
// demande a l'element des infos
const Tableau <TypeQuelconque>* tab_Q = poi->Integ_vol_typeQuel();
const Tableau <int>& index_integ = *(poi->Index_Integ_vol_typeQuel());
// la grandeur à cumuler c'est celle qui a le bon indexe
int indice = index_integ.Contient(rang_integ);
*(g_TG) += *((*tab_Q)(indice).Grandeur_pointee());
// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent
// int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer
// for (int iteg = 1;iteg <= nb_integ;iteg++)
// {if ((index_integ)(iteg)==rang_integ) // si l'index est négatif, on ne cumule pas
// // cela veut aussi dire que l'intégrale est figée
// // sinon si on a le bon index: on cumule l'intégrale
// {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee());
// break;
// };
// };
};
// maintenant il s'agit d'alimenter les grandeurs globales
// on récupère le pointeur correspondant à la grandeur correspondant au nom
// de référence
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Integration()"<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
#ifdef MISE_AU_POINT
if (pointe == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " la variable globale "<< (*nom_de_ref)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n LesMaillages::Integration()"<<flush;
Sortie(1);
};
#endif
// on l'affecte
//// --- debug
//cout << "\n debug LesMaillages::Integration() "
// << " \n valeur de l'integral: " << g_TG->Nom_ref()
// << " :: " << *(g_TG) << flush;
//
//// -- fin debug
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
};
// même chose pour les intégrales en volume et en temps
int taill1 = ref_integ_vol_t.Taille();
for (int rang_integ =1;rang_integ<= taill1;rang_integ++)
if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas
// l'intégrale stockée reste fixe pendant le calcul
{ const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol_t(rang_integ));
// initialisation du conteneur relatif à chaque ref
TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
g_TG->InitParDefaut(); // on initialise le conteneur
// cumule des valeurs: on récupère les infos à partir des éléments concernés
int ref_Taille=ref->Taille();
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage
int nnn = ref->Nbmaille(); // le numero du maillage
// recup de l'element
Element * poi = & Element_LesMaille(nnn,nbb);
// demande a l'element des infos
const Tableau <TypeQuelconque>* tab_Q = poi->Integ_vol_t_typeQuel();
const Tableau <int>& index_integ = *(poi->Index_Integ_vol_t_typeQuel());
// la grandeur à cumuler c'est celle qui a le bon indexe
int indice = index_integ.Contient(rang_integ);
*(g_TG) += *((*tab_Q)(indice).Grandeur_pointee());
// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent
// int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer
// for (int iteg = 1;iteg <= nb_integ;iteg++)
// {if ((index_integ)(iteg)==rang_integ)
// // sinon si on a le bon index: on cumule l'intégrale
// {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee());
// break;
// };
// };
};
// maintenant il s'agit d'alimenter les grandeurs globales
// on récupère le pointeur correspondant à la grandeur correspondant au nom
// de référence
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::Integration()"<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
#ifdef MISE_AU_POINT
if (pointe == NULL)
{ cout << "\n *** pb dans l'integration !! "
<< " la variable globale "<< (*nom_de_ref)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n LesMaillages::Integration()"<<flush;
Sortie(1);
};
#endif
// on l'affecte
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
};
};
// calcul des diverses statistiques sur des ref de noeuds et avec éventuellement
// cumul sur le temps
// alimentation des grandeurs globales associées
void LesMaillages::CalStatistique()
{ // on passe en revue les références de noeud des statistiques
{// Tableau <const Reference*> ref_statistique; // les références associées
int NB_ref = ref_statistique.Taille();
if (NB_ref)
{// on boucle sur les ref
for (int i_ref =1;i_ref<= NB_ref;i_ref++)
if (ref_statistique(i_ref) != NULL) // si null cela veut que l'on ne fait rien
// la statistique stockée reste fixe pendant le calcul
{ const ReferenceNE * ref = ((ReferenceNE *) ref_statistique(i_ref));
// initialisation du conteneur relatif à chaque ref
TypeQuelconque& TQ = statistique_typeQuel(i_ref); // pour simplifier
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
g_TG->InitParDefaut(); // on initialise le conteneur
int ref_Taille=ref->Taille();
int i_mail = ref->Nbmaille(); // le numero du maillage
Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
Fonction_nD* fct = gr.Fct(); // récupération d'un pointeur de fonction nD
// différent choix
if (fct == NULL)
{ // cas d'un stockage pour ddl_etendu
Ddl_enum_etendu& ddl_enu_eten = pour_statistique_de_ddl(i_ref);// récup du ddl
// on veut : (1) la somme, (2) la moyenne, (3) le max, (4) le min, (5) le max des | | , (6) le min des | |
// tab_val(k) : la grandeur k
// tab_index(k) : k= 1 -> le numéro du noeud pour le max
// k= 2 -> le numéro du noeud pour le min
// k= 3 -> le numéro du noeud pour le max des | |
// k= 4 -> le numéro du noeud pour le min des | |
// t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
Vecteur& t10 = (gr.ConteneurVecteur());
t10(4)=t10(6)=ConstMath::tresgrand; // on met les mini très grand
// t10(i), i=7 à 10 --> correspond aux numéros de noeud, stockés en double au lieu de int
// == tab_index(k)
// ceci pour utiliser uniquement un seul conteneur global
double& tab_pour_MAXI_1 = t10(7);
double& tab_pour_MAXI_2 = t10(8);
double& tab_pour_MAXI_3 = t10(9);
double& tab_pour_MAXI_4 = t10(10);
// on regarde s'il s'agit d'un ddl pur ou étendu
if (ddl_enu_eten.Nom_vide())
// cas d'un ddl pur
{// récup de l'énumération
Enum_ddl enu = ddl_enu_eten.Enum();
// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récup de la valeur du ddl
double val_du_ddl = 0.; // init
if (noe.Existe_ici(enu))
{val_du_ddl = noe.Ddl_noeud_tdt(enu).Valeur();}
#ifdef MISE_AU_POINT
else
{if (ParaGlob::NiveauImpression() >= 4)
{if (ParaGlob::Francais())
{cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
<< " n'est pas disponible pour statistique, on met 0 a la place";}
else
{cout << "\n Warning the quantity " << ddl_enu_eten.Nom_plein()
<< " is not available for statistic, the value will be 0 ";};
};
};
#endif
// le calcul des grandeurs
t10(1) += val_du_ddl;
t10(2) += 1.; // on s'en sert ici comme compteur
int num_noeud = noe.Num_noeud();
if (t10(3) < val_du_ddl)
{ t10(3) = val_du_ddl;
tab_pour_MAXI_1 = num_noeud;
};
if (t10(4) > val_du_ddl)
{ t10(4) = val_du_ddl;
tab_pour_MAXI_2 = num_noeud;
};
if (Dabs(t10(5)) < Dabs(val_du_ddl))
{ t10(5) = val_du_ddl;
tab_pour_MAXI_3 = num_noeud;
};
if (Dabs(t10(6)) > Dabs(val_du_ddl))
{ t10(6) = val_du_ddl;
tab_pour_MAXI_4 = num_noeud;
};
};
// calcul de la moyenne
t10(2) = t10(1) / t10(2);
}
else // cas d'un ddl étendu
{// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récup de la valeur du ddl
double val_du_ddl = 0.; // init
// on examine tout d'abord le cas particulier des positions
bool trouver = false;
// on regarde d'abord s'il s'agit d'une info spécifique au contact
int posi = ddl_enu_eten.Position()-NbEnum_ddl();
switch (posi)
{ case 123: // "X1_t"
{ val_du_ddl = noe.Coord1()(1);trouver=true; break;}
case 124: // "X2_t"
{ val_du_ddl = noe.Coord1()(2);trouver=true; break;}
case 125: // X3_t
{ val_du_ddl = noe.Coord1()(3);trouver=true; break;}
case 126: // X1_t0
{ val_du_ddl = noe.Coord0()(1);trouver=true; break;}
case 127: // X2_t0
{ val_du_ddl = noe.Coord0()(2);trouver=true; break;}
case 128: // X3_t0
{ val_du_ddl = noe.Coord0()(3);trouver=true; break;}
default: ;// rien
};
// si ce n'était pas un cas particulier on continue la recherche
if (!trouver)
// on regarde si la grandeur existe
{if (noe.Existe_ici_ddlEtendu(ddl_enu_eten))
{val_du_ddl = noe.DdlEtendue(ddl_enu_eten).ConstValeur();}
#ifdef MISE_AU_POINT
else
{if (ParaGlob::NiveauImpression() >= 4)
{if (ParaGlob::Francais())
{cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
<< " n'est pas disponible pour statistique, on met 0 a la place";}
else
{cout << "\n Warning the quantity " << ddl_enu_eten.Nom_plein()
<< " is not available for statistic, the value will be 0 ";};
};
};
#endif
};
// le calcul des grandeurs
t10(1) += val_du_ddl;
t10(2) += 1.; // on s'en sert ici comme compteur
int num_noeud = noe.Num_noeud();
if (t10(3) < val_du_ddl)
{ t10(3) = val_du_ddl;
tab_pour_MAXI_1 = num_noeud;
};
if (t10(4) > val_du_ddl)
{ t10(4) = val_du_ddl;
tab_pour_MAXI_2 = num_noeud;
};
if (Dabs(t10(5)) < Dabs(val_du_ddl))
{ t10(5) = val_du_ddl;
tab_pour_MAXI_3 = num_noeud;
};
if (Dabs(t10(6)) > Dabs(val_du_ddl))
{ t10(6) = val_du_ddl;
tab_pour_MAXI_4 = num_noeud;
};
};
// calcul de la moyenne
t10(2) = t10(1) / t10(2);
}
////------- debug ---------
// cout << "\n debug statistique: ";
// cout << t10;
//
//
////------- fin debug --------
}
else // cas d'un stockage pour fonction nD
{ Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
Fonction_nD* fct = gr.Fct(); // récupération de la fonction nD
// supposons que la fonction nD ramène n valeurs,
// pour chaque valeur on va avoir pour la valeur i :
// ((6*(i-1)+1) la somme, ((6*(i-1)+2) la moyenne, ((6*(i-1)+3) le max, ((6*(i-1)+4) le min,
// ((6*(i-1)+5) -> le numéro du noeud pour le max, ((6*(i-1)+6) -> le numéro du noeud pour le min,
// donc en tout cela donne 6*n valeurs
// ensuite on a:
// (6*n + 1) le max des | |, (6*n + 2) le min des | |,
// (6*n + 3) -> le numéro du noeud pour le max des | |
// (6*n + 4) -> le numéro du noeud pour le min des | |
// d'où un vecteur de taille (6*n + 4)
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = fct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = fct->Li_equi_Quel_evolue();
int nb_composante = fct->NbComposante();
// t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
Vecteur& t6 = (gr.ConteneurVecteur());
t6(4)=t6(6)=ConstMath::tresgrand; // on met les mini très grand
// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récupération d'une liste d'info
// le tableau de retour à la taille de li_enu_scal et contient
// les valeurs correspondantes aux Ddl_enum_etendu stockées au noeud
// en fait ici on cumule les ddl pur "et" les ddl_étendue,
// li_quelc : est modifié par les valeurs contenues au noeud
Tableau <double> tab = noe.Valeur_multi_et_Tensorielle(li_enu_scal,li_quelc);
// récup des valeurs de la fonction
Tableau <double> & t_ret = fct->Valeur_FnD_Evoluee(&tab,&li_enu_scal,&li_quelc,NULL,NULL);
int num_noeud = noe.Num_noeud();
// le calcul des grandeurs sur chaque composante
double norme=0;
for (int i=1;i<= nb_composante;i++)
{ int decal = 6*(i-1);
double val_composante = t_ret(i);
t6(decal+1) += val_composante;
t6(decal+2) += 1.; // on s'en sert ici comme compteur
if (t6(decal+3) < val_composante)
{ t6(decal+3) = val_composante;
t6(decal+5) = num_noeud;
};
if (t6(decal+4) > val_composante)
{ t6(decal+4) = val_composante;
t6(decal+6) = num_noeud;
};
norme +=val_composante*val_composante;
};
// on traite la norme
int decal = 6*nb_composante;
norme = sqrt(norme);
if (t6(decal+1) < norme)
{ t6(decal+1) = norme;
t6(decal+3) = num_noeud;
};
if (t6(decal+2) > norme)
{ t6(decal+2) = norme;
t6(decal+4) = num_noeud;
};
};
// on calcule les moyennes
for (int i=1;i<= nb_composante;i++)
{ int decal = 6*(i-1);
t6(decal+2) = t6(decal+1)/t6(decal+2);
};
};
// maintenant il s'agit d'alimenter les grandeurs globales
// on récupère le pointeur correspondant à la grandeur correspondant au nom
// de référence
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans le transfert d'une statistique !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::CalStatistique()"<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
#ifdef MISE_AU_POINT
if (pointe == NULL)
{ cout << "\n *** pb dans le transfert d'une statistique !! "
<< " la variable globale "<< (*nom_de_ref)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n LesMaillages::CalStatistique()"<<flush;
Sortie(1);
};
#endif
// on l'affecte
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
};
}; // fin de la boucle sur les ref
};
// idem pour l'accumulation en temps
{// Tableau <const Reference*> ref_statistique_t; // les références associées
int NB_ref = ref_statistique_t.Taille();
if (NB_ref)
{// on boucle sur les ref
for (int i_ref =1;i_ref<= NB_ref;i_ref++)
if (ref_statistique_t(i_ref) != NULL) // si null cela veut que l'on ne fait rien
// la statistique stockée reste fixe pendant le calcul
{ const ReferenceNE * ref = ((ReferenceNE *) ref_statistique_t(i_ref));
// initialisation du conteneur relatif à chaque ref
TypeQuelconque& TQ = statistique_t_typeQuel(i_ref); // pour simplifier
TypeQuelconque& TQ_t = statistique_t_typeQuel_t(i_ref); // le précédent
// le conteneur qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
g_TG->InitParDefaut(); // on initialise le conteneur
int ref_Taille=ref->Taille();
int i_mail = ref->Nbmaille(); // le numero du maillage
Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
Fonction_nD* fct = gr.Fct(); // récupération d'un pointeur de fonction nD
// le conteneur à t qui contient le résultat globalisé
TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
Grandeur_Vecteur_Nommer& gr_t = *((Grandeur_Vecteur_Nommer*) g_TG_t);
// différent choix
if (fct == NULL)
{ // cas d'un stockage pour ddl_etendu
Ddl_enum_etendu& ddl_enu_eten = pour_statistique_t_de_ddl(i_ref);// récup du ddl
// on veut : (1) la somme, (2) la moyenne, (3) le max, (4) le min, (5) le max des | | , (6) le min des | |
// tab_val(k) : la grandeur k
// tab_index(k) : k= 1 -> le numéro du noeud pour le max
// k= 2 -> le numéro du noeud pour le min
// k= 3 -> le numéro du noeud pour le max des | |
// k= 4 -> le numéro du noeud pour le min des | |
// t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
Vecteur& t10 = (gr.ConteneurVecteur());
t10(4)=t10(6)=ConstMath::tresgrand; // on met les mini très grand
// t10(i), i=7 à 10 --> correspond aux numéros de noeud, stockés en double au lieu de int
// == tab_index(k)
// ceci pour utiliser uniquement un seul conteneur global
double& tab_pour_MAXI_1 = t10(7);
double& tab_pour_MAXI_2 = t10(8);
double& tab_pour_MAXI_3 = t10(9);
double& tab_pour_MAXI_4 = t10(10);
// on regarde s'il s'agit d'un ddl pur ou étendu
if (ddl_enu_eten.Nom_vide())
// cas d'un ddl pur
{// récup de l'énumération
Enum_ddl enu = ddl_enu_eten.Enum();
// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récup de la valeur du ddl
double val_du_ddl = 0.; // init
// on regarde si la grandeur existe
if (noe.Existe_ici(enu))
{val_du_ddl = noe.Ddl_noeud_tdt(enu).Valeur();}
#ifdef MISE_AU_POINT
else
{if (ParaGlob::NiveauImpression() >= 4)
{if (ParaGlob::Francais())
{cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
<< " n'est pas disponible pour statistique cumulee, on met 0 a la place";}
else
{cout << "\n Warning the quantity " << ddl_enu_eten.Nom_plein()
<< " is not available for statistic cumuled, the value will be 0 ";};
};
};
#endif
// le calcul des grandeurs
t10(1) += val_du_ddl;
t10(2) += 1.; // on s'en sert ici comme compteur
int num_noeud = noe.Num_noeud();
if (t10(3) < val_du_ddl)
{ t10(3) = val_du_ddl;
tab_pour_MAXI_1 = num_noeud;
};
if (t10(4) > val_du_ddl)
{ t10(4) = val_du_ddl;
tab_pour_MAXI_2 = num_noeud;
};
if (Dabs(t10(5)) < Dabs(val_du_ddl))
{ t10(5) = val_du_ddl;
tab_pour_MAXI_3 = num_noeud;
};
if (Dabs(t10(6)) > Dabs(val_du_ddl))
{ t10(6) = val_du_ddl;
tab_pour_MAXI_4 = num_noeud;
};
};
// calcul de la moyenne
t10(2) = t10(1) / t10(2);
// cumule sur le temps
Vecteur& t10_t = (gr_t.ConteneurVecteur());
t10(1) += t10_t(1); t10(2) += t10_t(2);
t10(3) += t10_t(3); t10(4) += t10_t(4);
t10(5) += t10_t(5); t10(6) += t10_t(6);
}
else // cas d'un ddl étendu
{// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récup de la valeur du ddl
double val_du_ddl = 0.; // init
// on examine tout d'abord le cas particulier des positions
bool trouver = false;
// on regarde d'abord s'il s'agit d'une info spécifique au contact
int posi = ddl_enu_eten.Position()-NbEnum_ddl();
switch (posi)
{ case 123: // "X1_t"
{ val_du_ddl = noe.Coord1()(1);trouver=true; break;}
case 124: // "X2_t"
{ val_du_ddl = noe.Coord1()(2);trouver=true; break;}
case 125: // X3_t
{ val_du_ddl = noe.Coord1()(3);trouver=true; break;}
case 126: // X1_t0
{ val_du_ddl = noe.Coord0()(1);trouver=true; break;}
case 127: // X2_t0
{ val_du_ddl = noe.Coord0()(2);trouver=true; break;}
case 128: // X3_t0
{ val_du_ddl = noe.Coord0()(3);trouver=true; break;}
default: ;// rien
};
// si ce n'était pas un cas particulier on continue la recherche
if (!trouver)
{if (noe.Existe_ici_ddlEtendu(ddl_enu_eten))
{val_du_ddl = noe.DdlEtendue(ddl_enu_eten).ConstValeur();}
#ifdef MISE_AU_POINT
else
{if (ParaGlob::NiveauImpression() >= 4)
{if (ParaGlob::Francais())
{cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
<< " n'est pas disponible pour statistique cumulee, on met 0 a la place";}
else
{cout << "\n Warning the quantity " << ddl_enu_eten.Nom_plein()
<< " is not available for statistic cumuled, the value will be 0 ";};
};
};
#endif
};
// le calcul des grandeurs
t10(1) += val_du_ddl;
t10(2) += 1.; // on s'en sert ici comme compteur
int num_noeud = noe.Num_noeud();
if (t10(3) < val_du_ddl)
{ t10(3) = val_du_ddl;
tab_pour_MAXI_1 = num_noeud;
};
if (t10(4) > val_du_ddl)
{ t10(4) = val_du_ddl;
tab_pour_MAXI_2 = num_noeud;
};
if (Dabs(t10(5)) < Dabs(val_du_ddl))
{ t10(5) = val_du_ddl;
tab_pour_MAXI_3 = num_noeud;
};
if (Dabs(t10(6)) > Dabs(val_du_ddl))
{ t10(6) = val_du_ddl;
tab_pour_MAXI_4 = num_noeud;
};
};
// calcul de la moyenne
t10(2) = t10(1) / t10(2);
// cumule sur le temps
Vecteur& t10_t = (gr_t.ConteneurVecteur());
t10(1) += t10_t(1); t10(2) += t10_t(2);
t10(3) += t10_t(3); t10(4) += t10_t(4);
t10(5) += t10_t(5); t10(6) += t10_t(6);
};
// ensuite on cumule sur le temps
////------- debug ---------
//cout << "\n debug statistique: ";
//cout << t10;
//
//
////------- fin debug --------
}
else // cas d'un stockage pour fonction nD
{ Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
Fonction_nD* fct = gr.Fct(); // récupération de la fonction nD
// supposons que la fonction nD ramène n valeurs,
// pour chaque valeur on va avoir pour la valeur i :
// ((6*(i-1)+1) la somme, ((6*(i-1)+2) la moyenne, ((6*(i-1)+3) le max, ((6*(i-1)+4) le min,
// ((6*(i-1)+5) -> le numéro du noeud pour le max, ((6*(i-1)+6) -> le numéro du noeud pour le min,
// donc en tout cela donne 6*n valeurs
// ensuite on a:
// (6*n + 1) le max des | |, (6*n + 2) le min des | |,
// (6*n + 3) -> le numéro du noeud pour le max des | |
// (6*n + 4) -> le numéro du noeud pour le min des | |
// d'où un vecteur de taille (6*n + 4)
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = fct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = fct->Li_equi_Quel_evolue();
int nb_composante = fct->NbComposante();
// t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
Vecteur& t6 = (gr.ConteneurVecteur());
t6(4)=t6(6)=ConstMath::tresgrand; // on met les mini très grand
// cumule des valeurs: on récupère les infos à partir des noeuds concernés
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
// récupération du Noeud
Noeud& noe = Noeud_LesMaille(i_mail,nbb);
// récupération d'une liste d'info
// le tableau de retour à la taille de li_enu_scal et contient
// les valeurs correspondantes aux Ddl_enum_etendu stockées au noeud
// en fait ici on cumule les ddl pur "et" les ddl_étendue,
// li_quelc : est modifié par les valeurs contenues au noeud
Tableau <double> tab = noe.Valeur_multi_et_Tensorielle(li_enu_scal,li_quelc);
// récup des valeurs de la fonction
Tableau <double> & t_ret = fct->Valeur_FnD_tab_scalaire(&tab);
int num_noeud = noe.Num_noeud();
// le calcul des grandeurs sur chaque composante
double norme=0;
for (int i=1;i<= nb_composante;i++)
{ int decal = 6*(i-1);
double val_composante = t_ret(i);
t6(decal+1) += val_composante;
t6(decal+2) += 1.; // on s'en sert ici comme compteur
if (t6(decal+3) < val_composante)
{ t6(decal+3) = val_composante;
t6(decal+5) = num_noeud;
};
if (t6(decal+4) > val_composante)
{ t6(decal+4) = val_composante;
t6(decal+6) = num_noeud;
};
norme +=val_composante*val_composante;
};
// on traite la norme
int decal = 6*nb_composante;
norme = sqrt(norme);
if (t6(decal+1) < norme)
{ t6(decal+1) = norme;
t6(decal+3) = num_noeud;
};
if (t6(decal+2) > norme)
{ t6(decal+2) = norme;
t6(decal+4) = num_noeud;
};
};
// on calcule les moyennes et on cumule dans le temps
// pour les composantes i
Vecteur& t6_t = (gr_t.ConteneurVecteur());
for (int i=1;i<= nb_composante;i++)
{ int decal = 6*(i-1);
t6(decal+2) = t6(decal+1)/t6(decal+2);
// le cumul dans le temps
t6(decal+1) += t6_t(decal+1);t6(decal+2) += t6_t(decal+2);
t6(decal+3) += t6_t(decal+3);t6(decal+4) += t6_t(decal+4);
};
// idem pour les normes
int decal = 6*nb_composante;
t6(decal+1) += t6_t(decal+1) ; t6(decal+2) += t6_t(decal+2);
};
// maintenant il s'agit d'alimenter les grandeurs globales
// on récupère le pointeur correspondant à la grandeur correspondant au nom
// de référence
const string* nom_de_ref = g_TG->Nom_ref();
#ifdef MISE_AU_POINT
if (nom_de_ref == NULL)
{ cout << "\n *** pb dans le transfert d'une statistique cumulee !! "
<< " nom_de_ref est nul, on ne peut pas continuer "
<< "\n LesMaillages::CalStatistique()"<<flush;
Sortie(1);
};
#endif
// récup du pointeur de conteneur
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
#ifdef MISE_AU_POINT
if (pointe == NULL)
{ cout << "\n *** pb dans le transfert d'une statistique cumulee !! "
<< " la variable globale "<< (*nom_de_ref)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n LesMaillages::CalStatistique()"<<flush;
Sortie(1);
};
#endif
// on l'affecte
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
};
}; // fin de la boucle sur les ref
};
};
// mise à jour des repères d'anisotropie
void LesMaillages::Mise_a_jour_repere_anisotropie
(DiversStockage* divers,LesFonctions_nD* lesFonctionsnD)
{ // l'idée est d'éviter de stocker les infos déjà présentes dans DiversStockage ...
// on reprend le caneva de la méthode LesMaillages::Completer
// par contre on considère que tous les dimensionnements sont corrects
// cas de la définition de repère d'anisotropie
int divers_TabRepAnisotrope_Taille=divers->TabRepAnisotrope().Taille();
for (int ii=1;ii<= divers_TabRepAnisotrope_Taille;ii++)
{ string nomRepAnisotrope = (divers->TabRepAnisotrope())(ii).NomRef(); // recup du nom de la ref
const BlocDdlLim<BlocGen_6_0>& div_TabRepAnisotrope = (divers->TabRepAnisotrope())(ii);
const Reference & refG = lesRef->Trouve(nomRepAnisotrope,div_TabRepAnisotrope.NomMaillage()); // recup de la reference
const ReferenceNE & ref = (ReferenceNE &) refG;
int ref_Taille=ref.Taille();
// creation d'un bloc general contenant des informations
// n= nombre de string, m nombre de double
BlocGen bloc(5,0) ; // par defaut
string nom_inter("repere_anisotropie_");
bloc.Change_nom(1,nom_inter); // le mot clé
// ensuite le type l'identificateur de repere
bloc.Change_nom(2,div_TabRepAnisotrope.Nom(2));
// ensuite le type de repere
bloc.Change_nom(3,div_TabRepAnisotrope.Nom(3));
// puis la méthode de définition du repère
bloc.Change_nom(4,div_TabRepAnisotrope.Nom(4));
// un string qui contient le nom de la fonction nD
bloc.Change_nom(5,div_TabRepAnisotrope.Nom(6));
// puis on alimente les éléments concernés par ces calculs
////--- debug
//cout << "\n -- debug LesMaillages::Completer( ";
//bloc.Affiche(); cout << endl;
////--- fin debug
for (int jj= 1; jj<= ref_Taille; jj++)
{int nbb = ref.Numero(jj) ; // le numero de l'element dans le maillage
int nnn = ref.Nbmaille(); // le numero du maillage
// recup de l'element
Element * poi = & Element_LesMaille(nnn,nbb);
// demande a l'element de se completer
poi->Mise_a_jour_repere_anisotropie(bloc,lesFonctionsnD);
};
};
};
// initialisation par défaut de tous les conteneurs aux noeuds
// de tous les maillages
// contenant li_restreinte_TQ et li_restreinte_ddl
// ces conteneurs sont supposés déjà existés
// typiquement si le conteneurs est un scalaire, on met 0
void LesMaillages::Init_par_defaut_conteneurs(List_io < TypeQuelconque >& li_restreinte_TQ
)
{List_io < TypeQuelconque >::iterator il,ilfin=li_restreinte_TQ.end();
for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
// on parcours la liste
for (il = li_restreinte_TQ.begin(); il != ilfin;il++)
{TypeQuelconque_enum_etendu enuTypeQuelconque = (*il).EnuTypeQuelconque();
TypeQuelconque& tyqN = noo->ModifGrandeur_quelconque(enuTypeQuelconque);
tyqN.Grandeur_pointee()->InitParDefaut();
};
}
}
};
// idem pour une seule grandeur
void LesMaillages::Init_par_defaut_conteneurs(TypeQuelconque_enum_etendu enuTypeQuelconque)
{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
{ int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
for (int i2 = 1; i2 <= nbnoeudmax; i2++)
{ // recup du noeud
Noeud * noo = & Noeud_LesMaille(i1,i2);
TypeQuelconque& tyqN = noo->ModifGrandeur_quelconque(enuTypeQuelconque);
tyqN.Grandeur_pointee()->InitParDefaut();
};
};
};