2021-09-18 09:47:14 +02:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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"
|
|
|
|
|
2023-06-12 17:30:26 +02:00
|
|
|
//#ifndef SYSTEM_MAC_OS_X_unix
|
|
|
|
// #include "Frontier.h"
|
|
|
|
//#endif
|
2021-09-18 09:47:14 +02:00
|
|
|
|
|
|
|
// --------- 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);
|
|
|
|
}
|
2023-06-01 08:47:54 +02:00
|
|
|
}
|
|
|
|
// 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();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2021-09-18 09:47:14 +02:00
|
|
|
|
|
|
|
// 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
|
2023-05-03 17:23:49 +02:00
|
|
|
// cela signifie que l'on désire uniquement une renumérotation de pointeur sans celle des noeuds
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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)
|
2023-05-03 17:23:49 +02:00
|
|
|
{ // pour effectuer la renumérotation il est nécessaire de créer un tableau global de tous les noeuds et
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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
|
2023-05-03 17:23:49 +02:00
|
|
|
{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
|
|
|
|
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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
|
2023-05-03 17:23:49 +02:00
|
|
|
MiseAJourPointeurAssemblage_interne(*nb_casAssemb,tab_N_final_final,false);
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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;
|
|
|
|
};
|
|
|
|
|
2023-05-03 17:23:49 +02:00
|
|
|
}
|
|
|
|
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));
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
|
|
|
// 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
|
|
|
|
|
2024-01-30 20:55:48 +01:00
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
int taill_v = 0; // pour le dimensionnement du transfert
|
|
|
|
#endif
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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
|
2024-01-30 20:55:48 +01:00
|
|
|
{const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol(rang_integ));
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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
|
2024-01-30 20:55:48 +01:00
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
taill_v += g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
// en calcul parallèle, seule les proc i calculent les intégrales
|
|
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
|
|
{
|
|
|
|
#endif
|
|
|
|
// 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 num_elem = ref->Numero(jj) ; // le numero de l'element dans le maillage
|
|
|
|
int num_mail = ref->Nbmaille(); // le numero du maillage
|
|
|
|
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
// on regarde si le proc i est concerné
|
|
|
|
if (ParaGlob::param->Element_concerner(num_mail,num_elem) )
|
|
|
|
#endif
|
|
|
|
{// recup de l'element
|
|
|
|
Element * poi = & Element_LesMaille(num_mail,num_elem);
|
|
|
|
// 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;
|
|
|
|
// };
|
|
|
|
// };
|
2021-09-18 09:47:14 +02:00
|
|
|
|
2024-01-30 20:55:48 +01:00
|
|
|
};
|
|
|
|
// 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);
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
2024-01-30 20:55:48 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
|
|
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
// 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
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
taill_v += g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
// en calcul parallèle, seule les proc i calculent les intégrales
|
|
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
|
|
{
|
2021-09-18 09:47:14 +02:00
|
|
|
#endif
|
2024-01-30 20:55:48 +01:00
|
|
|
// 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 num_elem = ref->Numero(jj) ; // le numero de l'element dans le maillage
|
|
|
|
int num_mail = ref->Nbmaille(); // le numero du maillage
|
|
|
|
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
// on regarde si le proc i est concerné
|
|
|
|
if (ParaGlob::param->Element_concerner(num_mail,num_elem) )
|
|
|
|
#endif
|
|
|
|
{// recup de l'element
|
|
|
|
Element * poi = & Element_LesMaille(num_mail,num_elem);
|
|
|
|
// 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());
|
|
|
|
};
|
2021-09-18 09:47:14 +02:00
|
|
|
|
2024-01-30 20:55:48 +01:00
|
|
|
|
|
|
|
// -- 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);
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
|
|
{temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
// on va transmettre au proc 0 les résultats pour que celui-ci globalise les informations
|
|
|
|
// on va utiliser un conteneur intermédiaire pour un unique transfert:
|
|
|
|
// 1) on commence par le re dimensionnner
|
|
|
|
v_integ.Change_taille(taill_v);
|
|
|
|
// on rempli le conteneur : c-a-d sérialisation uniquement des valeurs
|
|
|
|
int indice_v=1; // init
|
|
|
|
// 2) récup résultats intégrales de volumes
|
|
|
|
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
|
|
|
|
{ // 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
v_integ(indice_v) = g_TG->GrandeurNumOrdre(i);
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
2024-01-30 20:55:48 +01:00
|
|
|
// 3) récup résultats intégrales en volume et en temps
|
|
|
|
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
|
|
|
|
{ // 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
v_integ(indice_v) = g_TG->GrandeurNumOrdre(i);
|
|
|
|
};
|
|
|
|
temps_serialisation.Arret_du_comptage(); // fin comptage cpu
|
|
|
|
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
// 4) transfert sans attente au proc 0
|
|
|
|
mpi::request reqs1 = ParaGlob::Monde()->isend(0, 50, v_integ);
|
|
|
|
temps_transfert_long.Arret_du_comptage(); // comptage cpu
|
|
|
|
}
|
|
|
|
else // cas du proc 0
|
|
|
|
{// on récupère les infos
|
|
|
|
// les conteneurs ont déjà été initialisé pendant le calcul de taill_v
|
|
|
|
|
|
|
|
// on commence par le re dimensionnner le conteneur de transfert
|
|
|
|
v_integ.Change_taille(taill_v);
|
|
|
|
int nb_proc_terminer = 0; // permettra de terminer
|
|
|
|
while (nb_proc_terminer < (ParaGlob::Monde()->size()-1)) // gérer par les valeurs de tyfront
|
|
|
|
{ // on récupère un résultat de cpu i
|
|
|
|
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
mpi::request reqs2 = v_integ.Irecup_MPI(mpi::any_source, 50);
|
|
|
|
reqs2.wait(); // on attend que le conteneur soit rempli
|
|
|
|
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
|
|
|
|
temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
// désérialisation et ajout pour globaliser
|
|
|
|
int indice_v=1; // init
|
|
|
|
// 1) cas des intégrales de volumes
|
|
|
|
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
|
|
|
|
{ // désérialisation 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
{double val_modifier = g_TG->GrandeurNumOrdre(i)+v_integ(indice_v);
|
|
|
|
g_TG->Change_GrandeurNumOrdre(i,val_modifier); // modification
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// 2) cas des intégrales en volume et temps
|
|
|
|
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
|
|
|
|
{ // désérialisation 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
{double val_modifier = g_TG->GrandeurNumOrdre(i)+v_integ(indice_v);
|
|
|
|
g_TG->Change_GrandeurNumOrdre(i,val_modifier); // modification
|
|
|
|
};
|
|
|
|
};
|
|
|
|
nb_proc_terminer++;
|
|
|
|
temps_serialisation.Arret_du_comptage(); // fin comptage cpu
|
|
|
|
};
|
|
|
|
|
|
|
|
// maintenant on alimente les grandeurs globales, et on rempli le conteneur de transfert
|
|
|
|
// pour passer les infos aux proc i
|
|
|
|
// on rempli le conteneur : c-a-d sérialisation uniquement des valeurs
|
|
|
|
int indice_v=1; // init
|
|
|
|
// 1) cas des intégrales de volumes
|
|
|
|
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
|
|
|
|
{ TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier
|
|
|
|
// le conteneur qui contient le résultat globalisé
|
|
|
|
TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
v_integ(indice_v) = g_TG->GrandeurNumOrdre(i);
|
|
|
|
// 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();
|
|
|
|
// récup du pointeur de conteneur
|
|
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
|
|
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
|
|
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
2024-01-30 20:55:48 +01:00
|
|
|
|
|
|
|
// 2) cas des intégrales en volume et temps
|
|
|
|
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
|
|
|
|
{ // désérialisation 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
v_integ(indice_v) = g_TG->GrandeurNumOrdre(i);
|
|
|
|
// 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();
|
|
|
|
// récup du pointeur de conteneur
|
|
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
|
|
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
|
|
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
2024-01-30 20:55:48 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// le proc 0 transmet aux proc i
|
|
|
|
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
v_integ.Broadcast(0);
|
|
|
|
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
|
|
|
|
|
|
|
|
// pour les proc i, il faut mettre à jour les variables globales
|
|
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
|
|
{temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu
|
|
|
|
// on désérialise uniquement les valeurs
|
|
|
|
// désérialisation
|
|
|
|
int indice_v=1; // init
|
|
|
|
// 1) cas des intégrales de volumes
|
|
|
|
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
|
|
|
|
{ // désérialisation 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
g_TG->Change_GrandeurNumOrdre(i,v_integ(indice_v)); // modification
|
|
|
|
// 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();
|
|
|
|
// récup du pointeur de conteneur
|
|
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
|
|
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
|
|
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
|
|
|
|
};
|
|
|
|
// 2) cas des intégrales en volume et temps
|
|
|
|
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
|
|
|
|
{ // désérialisation 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();
|
|
|
|
int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres
|
|
|
|
for (int i=1;i<= nb_ordre;i++,indice_v++)
|
|
|
|
g_TG->Change_GrandeurNumOrdre(i,v_integ(indice_v)); // modification
|
|
|
|
// 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();
|
|
|
|
// récup du pointeur de conteneur
|
|
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
|
|
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
|
|
*(gr_quelc->Grandeur_pointee()) = *(g_TG);
|
|
|
|
};
|
|
|
|
temps_serialisation.Arret_du_comptage(); // fin comptage cpu
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2021-09-18 09:47:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|