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

2079 lines
92 KiB
C++
Executable file

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "Fonction_nD.h"
#include <stdarg.h> /* va_list, va_start, va_copy, va_arg, va_end */
#include "Enum_ddl.h"
#include "NevezTenseur.h"
#include "TypeQuelconqueParticulier.h"
// les différentes fonctions existantes
#include "F_nD_courbe1D.h"
#include "Fonc_scal_combinees_nD.h"
#include "Fonction_expression_litterale_nD.h"
#include "Fonction_externe_nD.h"
#include "MotCle.h"
// CONSTRUCTEURS :
// par défaut
Fonction_nD::Fonction_nD(string nom, EnumFonction_nD typ)
: nom_variables(),t_inter_double()
,enu_variables_globale(),nom_ref(nom),typeFonction(typ)
,nom_variables_globales()
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{ // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
// non car au début il n'y a rien comme variable !!
// Fonction_nD::Construction_index_conteneurs_evoluees();
};
// constructeur avec plus d'info
// dans le cas ou les variables sont associées à des types quelconques, par défaut on considère qu'il
// s'agit de conteneur d'un scalaire simple. Dans le cas contraire il faut utiliser
// Preparation_Grandeur_quelconque( pour spécifier les tailles réelles
Fonction_nD::Fonction_nD(const Tableau <string >& var, string nom, EnumFonction_nD typ )
: nom_variables(var),t_inter_double(var.Taille())
,enu_variables_globale(),nom_ref(nom),typeFonction(typ)
,nom_variables_globales()
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{// comme on a le tableau de variables, on tente une équivalence éventuelle
// Fonction_nD::Construction_enu_etendu_et_quelconque();
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
};
// def de tous les paramètres: utile pour être appelé par les classes dérivées
Fonction_nD::Fonction_nD
( string nom_ref_ // nom de ref de la fonction
,Tableau <string >& nom_variables_non_globales // les variables non globales
,Tableau <Enum_GrandeurGlobale >& enu_variables_globale_ // enu globaux
,Tableau <string >& nom_variables_globales_ // idem sous forme de strings
,EnumFonction_nD typ ) // le type de fonction
: nom_variables(nom_variables_non_globales),t_inter_double(nom_variables_non_globales.Taille())
,enu_variables_globale(enu_variables_globale_),nom_ref(nom_ref_),typeFonction(typ)
,nom_variables_globales(nom_variables_globales_)
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{// comme on a le tableau de variables, on tente une équivalence éventuelle
// Fonction_nD::Construction_enu_etendu_et_quelconque();
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
};
// de copie
Fonction_nD::Fonction_nD(const Fonction_nD& Co) :
nom_variables(Co.nom_variables),t_inter_double(Co.t_inter_double)
,enu_variables_globale(Co.enu_variables_globale)
,nom_variables_globales(Co.nom_variables_globales)
,nom_ref(Co.nom_ref),typeFonction(Co.typeFonction)
,tab_enu_etendu(Co.tab_enu_etendu),tab_enu_quelconque(Co.tab_enu_quelconque)
,equivalence_nom_enu_etendu_et_enu_quelconque(Co.equivalence_nom_enu_etendu_et_enu_quelconque)
,index_enu_etendu(Co.index_enu_etendu),index_enu_quelconque(Co.index_enu_quelconque)
,x_x_i(Co.x_x_i),x_glob(Co.x_glob),xinter(NULL)
,depend_M(Co.depend_M),depend_Mt(Co.depend_Mt),depend_M0(Co.depend_M0)
,depend_temps(Co.depend_temps)
//------ grandeurs évoluées -------
,type_des_variables(Co.type_des_variables),val_ddl_enum(Co.val_ddl_enum)
,li_enu_etendu_scalaire() // reconstruit avec les index
,coor_ddl_enum(Co.coor_ddl_enum),num_dans_coor(Co.num_dans_coor)
,premier_famille_Coord(Co.premier_famille_Coord)
,tens_ddl_enum(Co.tens_ddl_enum),ind_tens(Co.ind_tens)
,premier_famille_tenseur(Co.premier_famille_tenseur)
,absolue(Co.absolue)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens() // est reconstruit ensuite
,posi_ddl_enum(Co.posi_ddl_enum),tailles_tab(Co.tailles_tab)
,permet_affichage(Co.permet_affichage)
{if (Co.xinter != NULL)
xinter = new Tableau <double >(*(Co.xinter));
// comme on a le tableau de variables, on tente une équivalence éventuelle
// Fonction_nD::Construction_enu_etendu_et_quelconque();
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
};
// DESTRUCTEUR :
Fonction_nD::~Fonction_nD()
{if (xinter != NULL)
delete xinter;
if (tens_ddl_enum.Taille() != 0)
{int taille = tens_ddl_enum.Taille();
for (int i=1; i<= taille; i++)
if (tens_ddl_enum(i) != NULL)
delete tens_ddl_enum(i);
};
};
// METHODES PUBLIQUES :
// ---------- non virtuelle ---------
//// complète les tableaux internes en fonction de la taille des conteneurs
//// associés aux types quelconques éventuelles
//// *** doit -être appelée s'il y a des grandeurs quelconque dont les conteneurs
//// sont associés à plusieurs scalaires
//void Fonction_nD::Preparation_Grandeur_quelconque(const Tableau <TypeQuelconque >& tqi)
// {// on parcourt la liste des enumérés de grandeurs quelconque
// int tail = tab_enu_quelconque.Taille();
// if (tqi.Taille() != tail)
// { cout << "\n *** pb dans Fonction_nD::Preparation_Grandeur_quelconque( "
// << " le tableau en parametre " << tqi.Taille()
// << " n'a pas la meme taille que le nombre de grandeur quelconque enregistrees "
// << tail
// << " on ne peut pas continuer " <<endl;
// Sortie(1);
// };
// // --- l'objectif est de dimensionner correctement le tableau de passage de réelles
// // x_x_i
// int nb_scalaire_type_quelconque = 0; // init
// for (int i=1;i<= tail; i++)
// {nb_scalaire_type_quelconque += tqi(i).NbMaxiNumeroOrdre();
// #ifdef MISE_AU_POINT
// if ((tqi)(i).EnuTypeQuelconque() != tab_enu_quelconque(i))
// { cout << "\n *** pb dans la preparation de l'utilisation de type quelconque "
// << " au niveau des parametres d'appel "
// << " la grandeur quelconque "<< i<< "correspondante a "
// << NomTypeQuelconque((tqi)(i).EnuTypeQuelconque())
// << " est differente de celle deja enregistree "
// << NomTypeQuelconque(tab_enu_quelconque(i))
// << " ce n'est pas normal !! , on arrete le calcul "
// << "\n Fonction_nD::Preparation_Grandeur_quelconque(..."<<endl;
// Sortie(1);
// };
// #endif
// };
// // on dimensionne le tableau de passage
// // chaque ddl est associé à un seul scalaire
// x_x_i.Change_taille(nb_scalaire_type_quelconque+tab_enu_etendu.Taille());
// };
// calcul équivalent, mais pour des paramètres de type ddl enum étendu et/ou type quelconque
// pour que l'appel à cette méthode soit correcte, il faut que la dimension de t_enu + celle de tqi
// soit identique à celle du tableau Nom_variables() : en fait t_enu et tqi doivent représenter les variables
Tableau <double> & Fonction_nD::Valeur_FnD(Tableau <Ddl_etendu> * t_enu,Tableau <const TypeQuelconque * > * t_qi
,Tableau <int> * t_num_ordre)
{// on se sert des tableaux d'adressage indirect pour remplir le tableau de passage
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
// un tableau intermédiaire qui sert pour Valeur(Tableau <Ddl_etendu> ...
// Tableau <double > x_x_i;
#ifdef MISE_AU_POINT
// on vérifie qu'il y a bien équivalence entre les variables
if (!equivalence_nom_enu_etendu_et_enu_quelconque)
{ cout << "\n *** pb dans les parametres de passage pour l'appel de la fonction nD "
<< " les variables de passage ne sont pas tous des ddl etendue ou des grandeurs "
<< " quelconque scalaire "
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Valeur(Tableau <Ddl_etendu>..."<<endl;
Sortie(1);
};
#endif
try
{int tail_tab_enu_etendu = tab_enu_etendu.Taille();
if (t_enu != NULL)
{Tableau <Ddl_etendu>& tenu = *t_enu; // pour simplifier l'appel
for (int i= 1; i<= tail_tab_enu_etendu;i++)
{x_x_i(index_enu_etendu(i)) = tenu(i).Valeur();
};
};
int tail_tab_enu_quelc = tab_enu_quelconque.Taille();
if (t_qi != NULL)
{Tableau <const TypeQuelconque * >& tqi = *t_qi; // pour simplifier l'appel
for (int i= 1; i<= tail_tab_enu_quelc;i++)
{ x_x_i(index_enu_quelconque(i)) = tqi(i)->GrandeurNumOrdre(1);
#ifdef MISE_AU_POINT
int nb_scalaire_type_quelconque = tqi(i)->NbMaxiNumeroOrdre();
if (nb_scalaire_type_quelconque != 1)
{ cout << "\n *** pb dans le nombre de parametre de passage pour l'appel de la fonction nD "
<< " au niveau des parametres d'appel "
<< " la grandeur quelconque "<< i<< "correspondante a "
<< (tqi)(i)->EnuTypeQuelconque().NomPlein()
<< " n'est pas une grandeur scalaire "
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Valeur(Tableau <Ddl_etendu>..."<<endl;
Sortie(1);
};
#endif
};
};
// on peut maintenant appeler la fonction de base
// avec que des scalaires
#ifdef MISE_AU_POINT
if (permet_affichage > 4)
{cout << "\n retour fonction: "<<nom_ref<<" : ";
Tableau <double> & inter = Valeur_FnD_interne(&x_x_i);
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = x_x_i.Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<<j<<")= "<< x_x_i(j);}
};
return inter;
}
else
#endif
return Valeur_FnD_interne(&x_x_i);
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch(...)
{ cout << "\n ** erreur \n Valeur_FnD(..."<<endl;
this->Affiche();Sortie(1);
};
};
// ramène un pointeur sur la fonction correspondant au type de fonction passé en paramètre
Fonction_nD* Fonction_nD::New_Fonction_nD(string& nom,EnumFonction_nD typeFonction)
{ // définition du pointeur de retour
Fonction_nD* fonction;
// choix en fonction du typeCourbe
switch (typeFonction)
{
case FONCTION_EXPRESSION_LITTERALE_nD :
fonction= new Fonction_expression_litterale_nD(nom); break;
case FONCTION_COURBE1D : fonction= new F_nD_courbe1D(nom); break;
case FONC_SCAL_COMBINEES_ND : fonction= new Fonc_scal_combinees_nD(nom); break;
case FONCTION_EXTERNE_ND : fonction= new Fonction_externe_nD(nom); break;
default :
{ cout << "\nErreur : valeur incorrecte du type de Fonction_nD : "
<< typeFonction << "\n";
cout << "\n New_Fonction_nD(EnumFonction_nD typeFonction) \n";
Sortie(1);
}
};
return fonction;
};
// ramène un pointeur sur une courbe copie de celle passée en paramètre
// IMPORTANT : il y a création d'une courbe (utilisation d'un new)
Fonction_nD* Fonction_nD::New_Fonction_nD(const Fonction_nD& Co)
{ // définition du pointeur de retour
Fonction_nD* fonction;
// choix en fonction du typeFonction
switch (Co.Type_Fonction())
{
case FONCTION_EXPRESSION_LITTERALE_nD : fonction= new Fonction_expression_litterale_nD( Co); break;
case FONCTION_COURBE1D : fonction= new F_nD_courbe1D(Co); break;
case FONC_SCAL_COMBINEES_ND : fonction= new Fonc_scal_combinees_nD(Co); break;
case FONCTION_EXTERNE_ND : fonction= new Fonction_externe_nD(Co); break;
default :
{ cout << "\nErreur : valeur incorrecte du type de Fonction_nD : "
<< Co.Type_Fonction() << "\n";
cout << "\n New_Fonction_nD(const Fonction_nD& Co) \n";
Sortie(1);
}
};
return fonction;
};
// ramène la liste des identificateurs de courbes actuellement disponibles
list <EnumFonction_nD> Fonction_nD::Liste_Fonction_disponible()
{ // définition de la liste de retour
list <EnumFonction_nD> list_ret;
// remplissage de la liste
list_ret.push_back(FONCTION_EXPRESSION_LITTERALE_nD);
list_ret.push_back(FONCTION_COURBE1D);
list_ret.push_back(FONC_SCAL_COMBINEES_ND);
list_ret.push_back(FONCTION_EXTERNE_ND);
// retour de la liste
return list_ret;
};
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
// globales en cours de calcul
// méthode interne: qui est utilisé par les fonctions dérivées pour la méthode:
// Mise_a_jour_variables_globales
// retourne false si rien n'a changé
bool Fonction_nD::Mise_a_jour_variables_globales_interne()
{// on passe en revue les variables normales et on regarde s'il s'agit de nouvelles variables globales
int taille = nom_variables.Taille();
list <string> li_variable; // liste de travail
list <string> li_globale; // ""
bool a_changer = false; // a priori rien ne change
// maintenant on parcours les variables
for (int i=1;i<=taille;i++)
{if (ParaGlob::param->GrandeurGlobal(nom_variables(i)) != NULL)
// il s'agit d'une variable globale
{// on n'ajoute que si elle n'est pas déjà présente
std::list <string>::iterator it
= find (li_globale.begin(), li_globale.end(),nom_variables(i));
if (it == li_globale.end())
{li_globale.push_back(nom_variables(i));
};
// quelque soit le cas il faut valider
a_changer=true;
}
else // sinon c'est toujours une variable
li_variable.push_back(nom_variables(i));
};
// on met à jour les tableaux
if (a_changer)
{// on ajoute maintenant les variables globales déjà existantes
int taille_globale = nom_variables_globales.Taille(); // Init_from_list
for (int j=1;j<= taille_globale;j++)
{// on n'ajoute que si elle n'est pas déjà présente
list <string>::iterator it
= find (li_globale.begin(), li_globale.end(),nom_variables_globales(j));
if (it == li_globale.end())
{li_globale.push_back(nom_variables_globales(j));}
};
// on met à jour les tableaux
nom_variables.Init_from_list(li_variable);
t_inter_double.Change_taille(nom_variables.Taille());
// pour les variables globales on considère les points suivants:
// leur nombre ne peut pas décroitre
// l'ordre n'a pas vraiment d'importance
// int taille_ajout = li_globale.size();
int taille_finale = li_globale.size();
if (taille_finale < nom_variables_globales.Taille())
{cout << "\n erreur changement de taille des variables globales "
<< "\n Fonction_nD::Mise_a_jour_variables_globales_interne() "
<< endl;
Sortie(1);
};
nom_variables_globales.Init_from_list(li_globale);
// int taille_ini = nom_variables_globales.Taille();
// nom_variables_globales.Change_taille(taille_ini+taille_ajout);
// nom_variables_globales.Change_taille(taille_finale);
// list <string>::iterator il,ilfin=li_globale.end();
// int ip = 1; //taille_ini+1;
// for (il = li_globale.begin();il != ilfin; il++,ip++)
// nom_variables_globales(ip) = (*il);
// nom_variables_globales.Init_from_list(li_globale);
};
// on met à jour le tableau d'échange interne : x_glob
int nb_tot_glob = enu_variables_globale.Taille() + nom_variables_globales.Taille();
x_glob.Change_taille(nb_tot_glob);
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
return a_changer;
};
// Tableau <string > nom_variables; //variables de la fonction, vu de l'extérieur
//
// Tableau <Enum_GrandeurGlobale > enu_variables_globale; //tableau des énumérés
// // de variables globales
// // éventuellement vide s'il ne sert pas
// Tableau <string > nom_variables_globales; //tableau des énumérés
// 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this
list <string>& Fonction_nD::ListDependanceCourbes(list <string>& lico) const
{ // par défaut, ne dépend pas de fonctions, donc on ramène une liste vide
// ce sera surchargé dans les classes qui elles éventuellement dépendent de quelque chose
if (lico.size() != 0)
lico.clear();
return lico;
};
// 3) retourne une liste de nom correspondant aux noms de fonctions dont dépend *this
list <string>& Fonction_nD::ListDependanceFonctions(list <string>& lico) const
{ // par défaut, ne dépend pas de fonctions, donc on ramène une liste vide
// ce sera surchargé dans les classes qui elles éventuellement dépendent de quelque chose
if (lico.size() != 0)
lico.clear();
return lico;
};
// ---------- METHODES PROTEGEES :-------------------
// ramène true si les variables de la classe mère sont complèté
bool Fonction_nD::Complet_var() const
{ bool ret = true;
if (typeFonction == AUCUNE_FONCTION_nD) ret = false;
if (nom_ref == "") ret = false;
return ret;
};
// définit le paramètre depend_M en fonction des nom_variables
// 3 indicateurs permettant de connaître rapidement si
// la fonction dépend de la position d'un point M à tdt, t et t=0
// 0 : la fonction ne dépend pas de la position d'un point M
// non nul : la fonction dépend de la position d'un point M
// dans ce cas, une au moins un des nom_variables
// a un nom de la même famille que le ddl X1
// et depend_M = nombre de composantes demandés (ne sert pas vraiment)
// si = -1 : cela signifie que la fonction dépend "que" de M
void Fonction_nD::Definition_depend_M()
{// on parcours les noms des variables
int taille = nom_variables.Taille();
depend_M=0; // init a priori
depend_Mt=0; // idem à t
depend_M0 = 0; // idem à 0
Ddl_enum_etendu d_X1_t = Ddl_enum_etendu(X1,"X1_t");
Ddl_enum_etendu d_X1_t0 = Ddl_enum_etendu(X1,"X1_t0");
if (permet_affichage > 6)
cout << "\n == >>> Fonction_nD::Definition_depend_M ( fct= " << nom_ref << ") ";
list<string> var_X_deja_enreg; // une liste de travail
list<string> var_independante; // une liste de travail
for (int i=1; i<= taille; i++)
{// on ne traite que si la variable n'a pas déjà été traité
if (find(var_independante.begin(),var_independante.end(),nom_variables(i)) == var_independante.end())
{var_independante.push_back(nom_variables(i));
if (ExisteEnum_ddl(nom_variables(i))) // on regarde s'il s'agit d'un ddl patenté
{if (permet_affichage > 7)
cout << "\n cas d'un ddl de base: nom_variables("<<i<<") = "<<nom_variables(i);
if ( Meme_famille(Id_nom_ddl(nom_variables(i)),X1))
// si c'est de la famille d'X1 c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_M += 1; // ok et la variable n'a pas été encore enregistrée
if (permet_affichage > 7)
cout << " depend_M += 1 ";
var_X_deja_enreg.push_back(nom_variables(i));
};
};
}
// sinon on regarde s'il s'agit d'un ddl étendu relatif à t = 0 ou t
else if (Ddl_enum_etendu::VerifExistence(nom_variables(i)))
{ if (permet_affichage > 7)
cout << "\n cas d'un ddl etendu relatif a t=0 ou t : nom_variables("<<i<<") = "<<nom_variables(i);
// on a un ddl enum
Ddl_enum_etendu dd_et = Ddl_enum_etendu::RecupDdl_enum_etendu(nom_variables(i));
if ( Ddl_enum_etendu::PremierDdlEnumEtenduFamille(dd_et) == d_X1_t)
// si c'est de la famille d'X1_t c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_Mt += 1;
if (permet_affichage > 7)
cout << " depend_Mt += 1 ";
var_X_deja_enreg.push_back(nom_variables(i)); // on peut utiliser la même liste de travail
}
};
if ( Ddl_enum_etendu::PremierDdlEnumEtenduFamille(dd_et) == d_X1_t0)
// si c'est de la famille d'X1_t0 c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_M0 += 1;
if (permet_affichage > 7)
cout << " depend_M0 += 1 ";
var_X_deja_enreg.push_back(nom_variables(i)); // on peut utiliser la même liste de travail
}
};
};
}
};
// le nombre de variables indépendantes, car nom_variables peut contenir plusieurs fois la même variable
int nb_var_inde = var_independante.size();
if (permet_affichage > 6)
cout << "\n nb de variables independantes : "<< nb_var_inde << " ";
// maintenant si depend_M est > à la dimension => il n'y a pas qu'une dépendance à M
// if ((depend_M <= ParaGlob::Dimension()) && (depend_M > 0))
if ((depend_M <= taille) && (depend_M > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_M <= ParaGlob::Dimension())
{if (depend_M == nb_var_inde)
depend_M = -1; // cas d'une dépendance stricte à M
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_tdt "<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if ((depend_Mt <= taille) && (depend_Mt > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_Mt <= ParaGlob::Dimension())
{if (depend_Mt == nb_var_inde)
depend_Mt = -1;// cas d'une dépendance stricte à Mt
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_t"<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if ((depend_M0 <= taille) && (depend_M0 > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_M0 <= ParaGlob::Dimension())
{if (depend_M0 == nb_var_inde)
depend_M0 = -1; // cas d'une dépendance stricte à M0
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_t=0 : "<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if (permet_affichage > 6)
{cout << "\n == >>> Fonction_nD::Definition_depend_M : valeur des indicateurs finaux "
<< "\n pour memoire: = 0 -> la fct ne depend pas de la position "
<< " = -1 : la fct depend que de la position "
<< " > 0 : la fct depend de la position mais pas seulement "
<< "\n depend_M = " << depend_M << ",depend_Mt = " << depend_Mt
<< ", depend_M0 = " << depend_M0 << " ";
};
};
// définit le paramètre depend_temps en fonction des nom_variables
void Fonction_nD::Definition_depend_temps()
{// on parcours les identifiants globaux
int taille = enu_variables_globale.Taille();
depend_temps=false; // init a priori
// le temps est une grandeurs globales
for (int i=1; i<= taille; i++)
if (enu_variables_globale(i) == TEMPS_COURANT) // on regarde s'il s'agit d'un ddl patenté
{depend_temps = true;
break;
};
};
//// construction à partir des noms de variables, des tableaux tab_enu_etendu et
//// tab_enu_quelconque
//void Fonction_nD::Construction_enu_etendu_et_quelconque()
// {// on parcours les noms des variables
// int taille = nom_variables.Taille();
// // a priori on considère qu'il y a équivalence
// equivalence_nom_enu_etendu_et_enu_quelconque = true;
// list <Ddl_enum_etendu> li_inter_enu; // une liste intermédiaire de travail
// list <int> li_index_enu;
// list <EnumTypeQuelconque> li_inter_tyQ; // idem
// list <int> li_index_quelc;
//
// // un conteneur de service: un réel par ddl
// Ddl_enum_etendu ddl_de_service;
// // par contre pour les grandeurs quelconques, on peut avoir plusieurs
// // réels par grandeur quelconque
//
//
// for (int i=1; i<= taille; i++)
// {if (ddl_de_service.VerifExistence(nom_variables(i)))
// {li_inter_enu.push_back(Ddl_enum_etendu(nom_variables(i)));
// li_index_enu.push_back(i);
// }
// else if (Existe_typeQuelconque(nom_variables(i)))
// {li_inter_tyQ.push_back(Id_nomTypeQuelconque(nom_variables(i)));
// li_index_quelc.push_back(i);
// }
// else equivalence_nom_enu_etendu_et_enu_quelconque = false ;
// };
// // maintenant on peut définir les tableaux
// int tail_enu_ddl = li_inter_enu.size();
// { tab_enu_etendu.Change_taille(tail_enu_ddl);
// index_enu_etendu.Change_taille(tail_enu_ddl);
// int i_enu=1; // un compteur pour le tableau
// list <Ddl_enum_etendu>::iterator il,ilfin=li_inter_enu.end();
// list <int>::iterator i_int=li_index_enu.begin();
// for (il=li_inter_enu.begin();il!=ilfin;il++,i_enu++,i_int++)
// {tab_enu_etendu(i_enu)=(*il);
// index_enu_etendu(i_enu)=(*i_int);
// };
// };
// int tail_enuquel = li_inter_tyQ.size();
// { tab_enu_quelconque.Change_taille(tail_enuquel);
// index_enu_quelconque.Change_taille(tail_enuquel);
// int i_enu=1; // un compteur pour le tableau
// list <EnumTypeQuelconque>::iterator il,ilfin=li_inter_tyQ.end();
// list <int>::iterator i_int=li_index_quelc.begin();
// for (il=li_inter_tyQ.begin();il!=ilfin;il++,i_enu++,i_int++)
// {tab_enu_quelconque(i_enu)=(*il);
// index_enu_quelconque(i_enu) = (*i_int);
// #ifdef MISE_AU_POINT
// EnumTypeQuelconque inter = (*il);
// if (NombreElementFoncDim(Type_de_grandeur_associee(inter)) != 1)
// { cout << "\n *** pb de dimensions d'argument non coherentes !! "
// << " la grandeur quelconque "<< NomTypeQuelconque(inter)
// << ", n'est pas un scalaire simple "
// << "\n Fonction_nD::Construction_enu_etendu_et_quelconque(..."<<endl;
// Sortie(1);
// };
// #endif
// };
// };
// // on met à jour le tableau de transfert
// // ici par défaut chaque type quelconque est associé à un conteneur scalaire
// // si ce n'est pas le cas, on considère que l'utilisateur utilisera la méthode
// // Preparation_Grandeur_quelconque( pour mettre les bonnes dimensions
// x_x_i.Change_taille(tail_enu_ddl+tail_enuquel);
// };
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
void Fonction_nD::Construction_index_conteneurs_evoluees()
{// on parcours les noms des variables
int taille = nom_variables.Taille();
t_inter_double.Change_taille(taille);
// on dimensionne le tableau des types de variables
type_des_variables.Change_taille(taille);
// on nettoie les listes
li_enu_etendu_scalaire.clear();
// on part avec l'idée que toutes les grandeurs seront reconnues localement
equivalence_nom_enu_etendu_et_enu_quelconque = true;
// def de listes intermédiaires
list <int> li_inter_posi_ddl_enum; // liste des positions
// --- cas des tenseurs
list <TenseurBB* > li_inter_tens_ddl_enum; // pour les tenseurs
// list <Deuxentiers_enu > li_ind_tens; // pour les indices dans les tenseurs
List_io <Ddl_enum_etendu> li_premier_famille_tenseur; // pour savoir si c'est déjà enregistré
// --- cas des coordonnées
list <Coordonnee > li_coor_ddl_enum;
// list <int > li_num_dans_coor;
List_io <Ddl_enum_etendu> li_premier_famille_Coord; // pour savoir si c'est déjà enregistré
// --- init de la liste équivalente de grandeurs quelconques évoluées
li_equi_Quel_evolue.clear(); // on remet à 0
// on défini des conteneurs ad hoc
int dim = ParaGlob::Dimension(); // la dimension globale
// ... cas des Coordonnees
Coordonnee v_rep(dim); // un vecteur de travail
Grandeur_coordonnee grand5(v_rep); // def d'une grandeur courante coordonnée
// ... cas des tenseurs
TenseurBB* tens = NevezTenseurBB(dim); // un tenseur typique
// maintenant on définit une grandeur typique de type tenseurBB
Grandeur_TenseurBB gtBB(*tens);
list < int > li_position; // liste de la position des variables dans les tableaux
// on parcours les noms de variables
list <Ddl_enum_etendu> li_inter_enu; // une liste intermédiaire de travail
list <int> li_index_enu;
list <EnumTypeQuelconque> li_inter_tyQ; // idem
list <int> li_index_quelc;
// def d'une liste qui permettra ensuite de construire tab_equi_Coor et tab_equi_tens
list <List_io <TypeQuelconque >::iterator > li_tab_equi;
// un conteneur de service: un réel par ddl
Ddl_enum_etendu ddl_de_service;
list <double> list_inter_val_ddl_enum; // inter qui donnera ensuite: val_ddl_enum
// par contre pour les grandeurs quelconques, on peut avoir plusieurs
// réels par grandeur quelconque
int indice_enu_ddl = 0; // init
int indice_t_quelconque = 0; // init
for (int i=1; i<= taille; i++) // on balaie les noms de variable
{// on sépare tout d'abord entre ddl_enum_etendu et type quelconque
if (ddl_de_service.VerifExistence(nom_variables(i)))
{ddl_de_service = Ddl_enum_etendu(nom_variables(i));
li_inter_enu.push_back(ddl_de_service);
li_index_enu.push_back(i);
// def de la position du ddl dans le tableau final des ddl (créé à la fin)
indice_enu_ddl++;li_inter_posi_ddl_enum.push_back(indice_enu_ddl);
// récup du type de grandeur auquel apartient l'énumération
// l'idée est de passer en revue le type de grandeur
EnumTypeGrandeur enu_type_grandeur = ddl_de_service.TypeDeGrandeur();
switch (enu_type_grandeur)
{case SCALAIRE : case SCALAIRE_ENTIER : case SCALAIRE_DOUBLE :
{// dans le cas d'un scalaire on a directement une équivalence à Ddl_enum_etendu
// quelque soit le scalaire, on le stocke en double
list_inter_val_ddl_enum.push_back(0.); // on ajoute une valeur 0. arbitraire
li_enu_etendu_scalaire.push_back(ddl_de_service);
type_des_variables(i)=1;
break;
}
case TENSEUR : case TENSEUR_NON_SYM : case TENSEURBB : case TENSEURHH :
case TENSEURBH : case TENSEURHB : case TENSEUR_NON_SYM_BB :
case TENSEUR_NON_SYM_HH :
{ // on considère que c'est toujours un tenseur en absolu et par défaut c'est un tenseur BB
type_des_variables(i)=3;
// maintenant il faut savoir si on a déjà enregistré un tenseur qui contiend la composante
if (!(Ddl_enum_etendu::Existe_dans_la_liste(li_premier_famille_tenseur,Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service))))
// s'il n'existe pas on rajoute le premier de la famille
{ TenseurBB * pt_tens= NevezTenseurBB(dim);
li_inter_tens_ddl_enum.push_back(pt_tens);
li_premier_famille_tenseur.push_back
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service));
// on s'occupe de la grandeur quelconque équivalente
EnumTypeQuelconque enuQ = Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(ddl_de_service);
TypeQuelconque typQ6(enuQ,ddl_de_service.Enum(),gtBB);
li_equi_Quel_evolue.push_back(typQ6);
};
// // maintenant il faut récupérer la position = l'indice, de l'enu dans le tenseur
// Deuxentiers_enu deux = IJind(ddl_de_service.Enum(),dim);
// li_ind_tens.push_back(deux);
break;
}
case COORDONNEE : case COORDONNEEB : case COORDONNEEH :
{// on considère que c'est toujours un type coordonnée en absolu et par défaut c'est un Coordonnee
type_des_variables(i)=2;
// maintenant il faut savoir si on a déjà enregistré un Coordonnee qui contiend la composante
if (!(Ddl_enum_etendu::Existe_dans_la_liste(li_premier_famille_Coord,Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service))))
// s'il n'existe pas on rajoute le premier de la famille
{ Coordonnee pt_coor(dim);
// //--- debug
// if (permet_affichage > 9)
// {cout << "\n debug Fonction_nD::Construction_index_conteneurs_evoluees() "
// << "\n mise en place de coordonnees arbitraire pour " ;
// pt_coor(1)=i*10+1.; pt_coor(2) = i*10+2.;pt_coor(3) = i*10+4.;
// cout << "\n grandeur= "<<nom_variables(i);
// };
// //-- fin debug
li_coor_ddl_enum.push_back(pt_coor);
li_premier_famille_Coord.push_back(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service));
// on s'occupe de la grandeur quelconque équivalente
EnumTypeQuelconque enuQ = Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(ddl_de_service);
TypeQuelconque typQ6(enuQ,ddl_de_service.Enum(),grand5);
// //--- debug
// if (permet_affichage > 9)
// {cout << "\n debug Fonction_nD::Construction_index_conteneurs_evoluees() ";
// Grandeur_coordonnee& coo = *((Grandeur_coordonnee*) typQ6.Grandeur_pointee());
// *(coo.ConteneurCoordonnee()) = pt_coor;
// cout << "\n idem pour le conteneur quelconque ";
// }
li_equi_Quel_evolue.push_back(typQ6);
};
// // maintenant il faut récupérer la position = l'indice, de l'enu dans Coordonnee
// int indice_coor = Indice_coor(ddl_de_service.Enum(),dim);
// li_num_dans_coor.push_back(indice_coor);
break;
}
default : // pour l'instant les autres cas, par exemple Vecteur, ne sont pas pris en compte
cout << "\nErreur : la grandeur " << nom_variables(i)
<< " n'est pas pris en compte pour les fonctions nD !\n";
cout << "\n Fonction_nD::Construction_index_conteneurs_evoluees(.. \n";
Sortie(1);
}; // fin du switch
} // fin du cas où c'est un ddl_enum_etendu
else if (Existe_typeQuelconque(nom_variables(i)))
{li_inter_tyQ.push_back(Id_nomTypeQuelconque(nom_variables(i)));
li_index_quelc.push_back(i);
type_des_variables(i)=4;
}
else
{// il y a des variables qui ne rentrent pas dans le cadre dd enu étendu et grandeur quelconque
// on ne pourra pas utiliser l'appel via des grandeurs évoluées: on le sauvegarde
// pour signaler des erreurs mais cela peut changer ensuite
// par exemple via la transformation de variables locales en variables globales qui sont
// dynamiquement créés, du coup on laisse l'algo
equivalence_nom_enu_etendu_et_enu_quelconque = false ;
type_des_variables(i)=0;
};
};
// on poursuit même s'il n'y a pas équivalence parfaite
// de manière a remplacer la méthode : Construction_enu_etendu_et_quelconque()
// cependant s'il y a une équivalence parfaite
// on ne pourra pas utiliser l'appel évolué
// donc certains indexes ne seront pas utilisables
// if (equivalence_nom_enu_etendu_et_enu_quelconque)
{// maintenant on va construire les tableaux qui sont équivalent aux listes
tailles_tab.Change_taille(4);
tailles_tab(1)=list_inter_val_ddl_enum.size();
tailles_tab(2)=li_coor_ddl_enum.size();
tailles_tab(3)=li_inter_tens_ddl_enum.size();
tailles_tab(4)=li_inter_tyQ.size();
// .... pour les ddl étendue
// le tableau global de ddl étendu
tab_enu_etendu.Init_from_list(li_inter_enu);
posi_ddl_enum.Init_from_list(li_inter_posi_ddl_enum);
val_ddl_enum.Init_from_list(list_inter_val_ddl_enum);
coor_ddl_enum.Init_from_list(li_coor_ddl_enum);
premier_famille_Coord.Init_from_list(li_premier_famille_Coord);
// num_dans_coor.Init_from_list(li_num_dans_coor);
num_dans_coor.Change_taille(tab_enu_etendu.Taille());
tens_ddl_enum.Init_from_list(li_inter_tens_ddl_enum);
premier_famille_tenseur.Init_from_list(li_premier_famille_tenseur);
// ind_tens.Init_from_list(li_ind_tens);
ind_tens.Change_taille(tab_enu_etendu.Taille());
index_enu_etendu.Init_from_list(li_index_enu);
// .... pour les grandeurs quelconques
// le tableau global de grandeurs quelconque
tab_enu_quelconque.Init_from_list(li_inter_tyQ);
index_enu_quelconque.Init_from_list(li_index_quelc);
// il faut maintenant revoir le tableau posi_ddl_enum dans le cas
// ou un tenseur et/ou un Coordonnee contient plusieurs Ddl_enum_etendu
// on fait systématiquement le test
// if (tab_enu_etendu.Taille() > (tailles_tab(1)+tailles_tab(2)+tailles_tab(3)))
{// on utilise les premiers de famille dont l'indice est le même que les
// tableau de tenseur et de Coordonnee
int nb_enu = tab_enu_etendu.Taille();
for (int i=1;i<=nb_enu;i++)
{// récup du type de grandeur auquel apartient l'énumération
// l'idée est de passer en revue le type de grandeur
Ddl_enum_etendu & ddenumetendu = tab_enu_etendu(i); // pour simplifier
EnumTypeGrandeur enu_type_grandeur = ddenumetendu.TypeDeGrandeur();
//TypeGrandeur(ddenumetendu.Enum());
switch (enu_type_grandeur)
{case TENSEUR : case TENSEUR_NON_SYM : case TENSEURBB : case TENSEURHH :
case TENSEURBH : case TENSEURHB : case TENSEUR_NON_SYM_BB :
case TENSEUR_NON_SYM_HH :
{ // on récupère la position dans le tableau de tenseur
int position = premier_famille_tenseur.Contient
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddenumetendu));
posi_ddl_enum(i)=position;
// maintenant il faut récupérer la position = l'indice, de l'enu dans le tenseur
// erreur : 18 mars 2023 Deuxentiers_enu deux = IJind(ddl_de_service.Enum(),dim);
Deuxentiers_enu deux = IJind(ddenumetendu.Enum(),dim);
ind_tens(i) = deux;
break;
}
case COORDONNEE : case COORDONNEEB : case COORDONNEEH :
{ // on récupère la position dans le tableau de Coordonnee
int position = premier_famille_Coord.Contient
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddenumetendu));
posi_ddl_enum(i)=position;
// maintenant il faut récupérer la position = l'indice, de l'enu dans Coordonnee
int indice_coor = Indice_coor(ddenumetendu.Enum(),dim);
num_dans_coor(i) = indice_coor;
break;
}
default : break;// sinon c'est des scalaires
}; // fin du switch
};
}; // fin du if (tab_enu_etendu.Taille() > (tailles_tab(1)+tailles_tab(2)+tailles_tab(3)))
////------- debug
//cout << "\n\n debug Fonction_nD::Construction_index_conteneurs_evoluees() : FCT= " << nom_ref
// << "\n les variables: "<< nom_variables
// << "\n li_equi_Quel_evolue= " << li_equi_Quel_evolue
// << " num_dans_coor= "<<num_dans_coor;
////------- fin debug
// .... pour les grandeurs quelconques équivalentes aux grandeurs
// évoluées non scalaires
// l'ordre d'apparition dans la liste est le même que celui dans les tableaux
// donc on parcours deux fois la liste des grandeurs, une fois pour les coordonnées et
// une fois pour les tenseurs
int nb_etendu = tab_enu_etendu.Taille();
int nb_coor = coor_ddl_enum.Taille();
tab_equi_Coor.Change_taille(nb_coor);
int nb_tenseur = tens_ddl_enum.Taille();
tab_equi_tens.Change_taille(nb_tenseur);
List_io <TypeQuelconque >::iterator iqc,iqc_fin=li_equi_Quel_evolue.end();
// cout << "\n posi_ddl_enum= " << posi_ddl_enum << endl;
for (int i=1;i<=nb_etendu;i++)
if ((type_des_variables(index_enu_etendu(i)) == 2)
|| (type_des_variables(index_enu_etendu(i)) == 3))
{EnumTypeQuelconque enuQ =
Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(tab_enu_etendu(i));
TypeQuelconque tq(enuQ);
// on cherche dans la liste enregistrée
List_io <TypeQuelconque >::iterator result1 =
std::find(li_equi_Quel_evolue.begin(),li_equi_Quel_evolue.end(), tq);
if (result1 == li_equi_Quel_evolue.end())
{cout << "\n *** erreur d'adressage dans "
<< "Fonction_nD::Construction_index_conteneurs_evoluees()";
this->Affiche();
Sortie(1);
};
if (type_des_variables(index_enu_etendu(i)) == 2) // cas de coordonnées
tab_equi_Coor(posi_ddl_enum(i))=result1;
else if (type_des_variables(index_enu_etendu(i)) == 3) // cas des tenseurs
tab_equi_tens(posi_ddl_enum(i))=result1;
};
delete tens; // car on n'en a plus besoin
// //--- debug
// if (permet_affichage > 9)
// {cout << "\n debug Fonction_nD::Construction_index_conteneurs_evoluees() ";
// List_io <TypeQuelconque >::iterator i_evol = li_equi_Quel_evolue.begin();
// int nb_enu = index_enu_etendu.Taille();
// // qui a la même taille que tab_enu_etendu, et dans le même ordre
// for (int ienu=1;ienu <= nb_enu; ienu++)
// {int num_variable = index_enu_etendu(ienu); // le numéro de nom_variable
// switch (type_des_variables(num_variable))
// { case 2: // Coordonnee
// {int j = posi_ddl_enum(ienu);
// // pour simplifier l'écriture
// List_io<TypeQuelconque >::iterator& il = tab_equi_Coor(j);
// Grandeur_coordonnee& coo = *((Grandeur_coordonnee*) (*il).Grandeur_pointee());
// Coordonnee& coord = *(coo.ConteneurCoordonnee());
// double valeur = coord(num_dans_coor(ienu));
// cout << "\n version type quelconque :";
// cout << "\n Coordonnee: num_variable= "<<num_variable
// << " di (num_variable)= "<<valeur
// << " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
// << " num_dans_coor("<<ienu<<")= "<<num_dans_coor(ienu)
// << "\n coord= "<<coord ;
//
// cout << "\n version tableau de coordonnées :";
// cout << "\n Coordonnee: num_variable= "<<num_variable
// << " di (num_variable)= "<<coor_ddl_enum(j)(num_dans_coor(ienu))
// << " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
// << " num_dans_coor("<<ienu<<")= "<<num_dans_coor(ienu)
// << "\n coord= "<<coor_ddl_enum(j) ;
// i_evol++;
// break;}
// default:
// break;
// };
// }; // fin de la boucle sur les enum
// Sortie(1);
// };
// //-- fin debug
// on met à jour le tableau de transfert
// ici par défaut chaque type quelconque est associé à un conteneur scalaire
// si ce n'est pas le cas, on considère que l'utilisateur utilisera la méthode
// Preparation_Grandeur_quelconque( pour mettre les bonnes dimensions
x_x_i.Change_taille(tab_enu_etendu.Taille()+tab_enu_quelconque.Taille());
}; // fin du cas où il y a une équivalence parfaite
};
// Passage des infos variables évoluées en tableau de réels
// I/O : di
Tableau <double > & Fonction_nD::Vers_tab_double(Tableau <double > & di
,const Tableau <double >* val_ddl_enum
,const Tableau <Coordonnee> * coor_ddl_enum
,const Tableau <TenseurBB* >* tens_ddl_enum
,const Tableau <const TypeQuelconque * >* tqi
,const Tableau <int> * t_num_ordre)
{
#ifdef MISE_AU_POINT
{
if (di.Taille() != (tab_enu_etendu.Taille() + tab_enu_quelconque.Taille()))
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " tab_enu_etendu.Taille()= " << tab_enu_etendu.Taille()
<< " tab_enu_quelconque.Taille()= "<< tab_enu_quelconque.Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (tailles_tab(1) != 0) // cas où il existe des scalaires
{if (val_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des scalaires purs !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else
{if (val_ddl_enum->Taille() != tailles_tab(1))
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " taille val_ddl_enum = " << val_ddl_enum->Taille()
<< " est different du nombre prevu !" << tailles_tab(1)
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
if (tailles_tab(2) != 0)
{if (coor_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " coor_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des coordonnees !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(3) != 0)
{if (tens_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " tens_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des tenseurs !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(4) != 0)
{if (tqi == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " tqi pointe sur NULL "
<< " et il est prevu d'avoir des grandeurs quelconques !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else if (t_num_ordre != NULL)
{if (t_num_ordre->Taille() != tqi->Taille())
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " taille tqi = " << tqi->Taille()
<< " est different du nombre de numero d'ordre prevu !" << t_num_ordre->Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
}
#endif
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n\n detail pour Fonction_nD::Vers_tab_double( AVEC DES TABLEAUX : FCT= " << nom_ref
<< "\n les variables: "<< nom_variables;
#endif
// on va boucler sur les arguments:
// on utilise les index, pour un adressage indirect, pour le tableau de retour "et"
// la grandeur, normalement, cela devrait être ok
// 1) sur les enum
int nb_enu = index_enu_etendu.Taille();
for (int ienu=1;ienu <= nb_enu; ienu++)
{int num_variable = index_enu_etendu(ienu); // le numéro de nom_variable
switch (type_des_variables(num_variable))
{ case 1: // scalaire
{di(num_variable) = val_ddl_enum->operator()(posi_ddl_enum(ienu));
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n scalaire: num_variable= "<<num_variable
<< " di(num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu);
#endif
break;}
case 2: // Coordonnee
{int j = posi_ddl_enum(ienu);
di(num_variable) = (*coor_ddl_enum)(j)(num_dans_coor(ienu));
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n Coordonnee: num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
<< " num_dans_coor("<<ienu<<")= "<<num_dans_coor(ienu)
<< "\n coord= "<<(*coor_ddl_enum)(j) ;
#endif
break;}
case 3: // tenseur
{int j = posi_ddl_enum(ienu);
int k = ind_tens(ienu).i; int l = ind_tens(ienu).j;
di(num_variable) = (*(*tens_ddl_enum)(j))(k,l);
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
<< " indices dans tenseur: (k,l)= ("<<k<<","<<l<<")"
<< "\n tensBB= ";(*tens_ddl_enum)(j)->Ecriture(cout) ;
#endif
break;}
default:
break;
};
}; // fin de la boucle sur les enum
// 2) sur les grandeurs quelconques
int nb_quelc = index_enu_quelconque.Taille();
for (int ieq = 1; ieq <= nb_quelc; ieq++)
{ int num_variable = index_enu_quelconque(ieq);
int nb_ordre = 1; // init par défaut
if (t_num_ordre != NULL)
nb_ordre = (*t_num_ordre)(ieq);
di(num_variable) = (*tqi)(ieq)->GrandeurNumOrdre(nb_ordre);
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " nb_ordre= "<<nb_ordre
<< "\n grandeur: " << (*tqi)(ieq)->Const_Grandeur_pointee();
#endif
}; // fin de la boucle sur les enu quelconques
// retour
return di;
};
// idem, mais via les listes
// val_ddl_enum(k) correspond à li_evolue_scalaire de rang i
Tableau <double > & Fonction_nD::Vers_tab_double(Tableau <double > & di
,const Tableau <double >* val_ddl_enum
,List_io <Ddl_enum_etendu>* li_evolue_scalaire
,List_io <TypeQuelconque >* li_evoluee_non_scalaire
,const Tableau <const TypeQuelconque * >* tqi
,const Tableau <int> * t_num_ordre)
{
#ifdef MISE_AU_POINT
{
// on vérifie qu'il s'agit bien des mêmes listes
if ((&li_enu_etendu_scalaire) != li_evolue_scalaire)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " la liste des enum etendu scalaires n'est pas celle fournie par la fonction"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if ((&li_equi_Quel_evolue) != li_evoluee_non_scalaire)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " la liste des grandeurs evoluees non scalaire n'est pas celle fournie par la fonction"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (li_enu_etendu_scalaire.size() != 0)
{if (val_ddl_enum==NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir "<< li_enu_etendu_scalaire.size() << " grandeurs scalaires !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (val_ddl_enum->Taille() != li_enu_etendu_scalaire.size())
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum est de taille " << val_ddl_enum->Taille()
<< " alors qu'il est prevu d'avoir "<< li_enu_etendu_scalaire.size() << " grandeurs scalaires !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(4) != 0)
{if (tqi == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " tqi pointe sur NULL "
<< " et il est prevu d'avoir des grandeurs quelconques !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else if (t_num_ordre != NULL)
{if (t_num_ordre->Taille() != tqi->Taille())
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " taille tqi = " << tqi->Taille()
<< " est different du nombre de numero d'ordre prevu !" << t_num_ordre->Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
}
#endif
// on va boucler sur les arguments:
List_io <Ddl_enum_etendu>::iterator i_scal = li_enu_etendu_scalaire.begin();
List_io <TypeQuelconque >::iterator i_evol = li_equi_Quel_evolue.begin();
int indice_scal=1; // init : indice dans le tableau val_ddl_enum
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
{cout << "\n\n detail pour Fonction_nD::Vers_tab_double( AVEC DES LISTES : FCT= " << nom_ref
<< "\n les variables: "<< nom_variables;
cout << "\n li_evoluee_non_scalaire ";
cout << *li_evoluee_non_scalaire ;
};
//-- fin debug
#endif
// 1) sur les enum
int nb_enu = index_enu_etendu.Taille();
// qui a la même taille que tab_enu_etendu, et dans le même ordre
for (int ienu=1;ienu <= nb_enu; ienu++)
{int num_variable = index_enu_etendu(ienu); // le numéro de nom_variable
switch (type_des_variables(num_variable))
{ case 1: // scalaire
{di(num_variable) = (*val_ddl_enum)(posi_ddl_enum(ienu));
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n scalaire: num_variable= "<<num_variable
<< " di(num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu);
#endif
break;}
case 2: // Coordonnee
{int j = posi_ddl_enum(ienu);
// pour simplifier l'écriture
List_io<TypeQuelconque >::iterator& il = tab_equi_Coor(j);
Grandeur_coordonnee& coo = *((Grandeur_coordonnee*) (*il).Grandeur_pointee());
Coordonnee& coord = *(coo.ConteneurCoordonnee());
di(num_variable) = coord(num_dans_coor(ienu));
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n Coordonnee: num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
<< " num_dans_coor("<<ienu<<")= "<<num_dans_coor(ienu)
<< "\n coord= "<<coord ;
#endif
i_evol++;
break;}
case 3: // tenseur
{int j = posi_ddl_enum(ienu);
int k = ind_tens(ienu).i; int l = ind_tens(ienu).j;
// pour simplifier l'écriture
List_io<TypeQuelconque >::iterator& il = tab_equi_tens(j);
Grandeur_TenseurBB& ten = *((Grandeur_TenseurBB*) (*il).Grandeur_pointee());
TenseurBB& tensBB = ten.RefConteneurTenseur();
di(num_variable) = tensBB(k,l);
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " posi_ddl_enum(ienu)= "<<posi_ddl_enum(ienu)
<< " indices dans tenseur: (k,l)= ("<<k<<","<<l<<")"
<< "\n tensBB= ";tensBB.Ecriture(cout) ;
#endif
i_evol++;
break;}
default:
break;
};
}; // fin de la boucle sur les enum
// 2) sur les grandeurs quelconques
int nb_quelc = index_enu_quelconque.Taille();
for (int ieq = 1; ieq <= nb_quelc; ieq++)
{ int num_variable = index_enu_quelconque(ieq);
int nb_ordre = 1; // init par défaut
if (t_num_ordre != NULL)
nb_ordre = (*t_num_ordre)(ieq);
di(num_variable) = (*tqi)(ieq)->GrandeurNumOrdre(nb_ordre);
#ifdef MISE_AU_POINT
if (permet_affichage > 9)
cout << "\n num_variable= "<<num_variable
<< " di (num_variable)= "<<di(num_variable)
<< " nb_ordre= "<<nb_ordre
<< "\n grandeur: " << (*tqi)(ieq)->Const_Grandeur_pointee();
#endif
}; // fin de la boucle sur les enu quelconques
////------ debug
//cout << "\n debug Fonction_nD::Vers_tab_double( ";
//cout << di << endl;
//
////------ fin debug
// retour
return di;
};
// appel de la fonction sous forme d'une méthode avec un nombre non limité
// de paramètres: en fait utilise Valeur
// c'est une méthode avec retour uniquement en scalaire, sinon -> erreur
// calcul des valeurs de la fonction
double Fonction_nD::Val_avec_nbArgVariable(double x,...)
{
// un certain nombre de variables utilisée pour gérer
// http://www.cplusplus.com/reference/cstdarg/va_copy/
// cf. variadic function
int count = 0;
double val = x;
va_list vl,vl_count;
va_start(vl,x);
// on va remplir le tableau xinter, pour faire un appel classique
int nb_var = this->NbVariable();
if (xinter == NULL)
xinter = new Tableau <double >(nb_var);
if (nb_var != 0)
{(*xinter)(count+1)=val;
/* count number of arguments: */
va_copy(vl_count,vl);
while (val != 0)
{if (count < nb_var) // cas normal
{val=va_arg(vl_count,double);
++count;
(*xinter)(count+1)=val;
}
else // sinon il y a plus d'argument que prévu, on génère une erreur
{ cout << "\n *** erreur dans l'appel de la fonction " << nom_ref
<< " le nombre d'argument est superieur a "<< nb_var
<< " ce qui n'est pas prevu dans la definition de la fonction "
<< "\n Fonction_nD::Val_avec_nbArgVariable( ";
if (ParaGlob::NiveauImpression() > 1)
this->Affiche();
cout << endl;
Sortie(1);
};
};
va_end(vl_count);
};
// maintenant on peut utiliser la méthode classique
Tableau <double> & ret = this->Valeur_FnD_interne(xinter);
return ret(1);
};
// méthode utilisée par les classes dérivées, pour transférer les infos qui sont
// gérées au niveau de Fonction_nD
Fonction_nD& Fonction_nD::Transfert_info(const Fonction_nD& elt)
{ // on reprend toutes les données gérées par Fonction_nD
typeFonction = elt.typeFonction;
nom_ref = elt.nom_ref;
nom_variables = elt.nom_variables;
t_inter_double = elt.t_inter_double;
enu_variables_globale = elt.enu_variables_globale;
nom_variables_globales = elt.nom_variables_globales;
tab_enu_etendu = elt.tab_enu_etendu;
type_des_variables = elt.type_des_variables;
val_ddl_enum = elt.val_ddl_enum;
li_enu_etendu_scalaire = elt.li_enu_etendu_scalaire;
coor_ddl_enum = elt.coor_ddl_enum;
num_dans_coor = elt.num_dans_coor;
tens_ddl_enum = elt.tens_ddl_enum;
premier_famille_tenseur = elt.premier_famille_tenseur;
ind_tens = elt.ind_tens;
posi_ddl_enum = elt.posi_ddl_enum;
tailles_tab = elt.tailles_tab;
tab_enu_quelconque = elt.tab_enu_quelconque;
equivalence_nom_enu_etendu_et_enu_quelconque = elt.equivalence_nom_enu_etendu_et_enu_quelconque;
index_enu_etendu = elt.index_enu_etendu;
index_enu_quelconque = elt.index_enu_quelconque;
// les listes pour les appels via les listes
li_enu_etendu_scalaire = elt.li_enu_etendu_scalaire;
li_equi_Quel_evolue = elt.li_equi_Quel_evolue;
tab_equi_Coor = elt.tab_equi_Coor;
tab_equi_tens = elt.tab_equi_tens;
x_x_i = elt.x_x_i;
x_glob = elt.x_glob;
depend_M = elt.depend_M;
depend_Mt = elt.depend_Mt;
depend_M0 = elt.depend_M0;
depend_temps = elt.depend_temps;
};
// affichage des données internes, utilisée par les fonctions dérivées
// niveau donne le degré d'affichage
void Fonction_nD::Affiche_interne(int niveau) const
{ if (niveau > 0)
{ cout << "\n type_de_fonction: "<< Nom_Fonction_nD(typeFonction)
<< " nom_ref= " << nom_ref
<< "\n les_variables_lues: " << nom_variables ;
if (niveau > 1)
{ // les énumérés globaux éventuels
int taille_enu_variables_globale= enu_variables_globale.Taille();
if (taille_enu_variables_globale != 0)
{ cout << "\n enumeres_globaux:_taille " << enu_variables_globale.Taille();
for (int i=1;i<= taille_enu_variables_globale;i++)
cout << " " << Nom_GrandeurGlobale(enu_variables_globale(i));
};
// les noms de variables globales éventuelles
int taille_nom_variables_globales= nom_variables_globales.Taille();
if (taille_nom_variables_globales != 0)
{ cout << "\n noms_variables_globales:_taille " << nom_variables_globales.Taille();
for (int i=1;i<= taille_nom_variables_globales;i++)
cout << " " << nom_variables_globales(i);
};
// enu étendu équivalent aux variables non globales
int taille_tab_enu_etendu= tab_enu_etendu.Taille();
if (taille_tab_enu_etendu != 0)
{ cout << "\n enum_etendu_locaux:_taille " << tab_enu_etendu.Taille();
for (int i=1;i<= taille_tab_enu_etendu;i++)
{cout << " " << tab_enu_etendu(i).Nom_plein();
int j = posi_ddl_enum(i);
switch (type_des_variables(i))
{case 1: cout << " type scalaire: valeur actuelle= "
<< val_ddl_enum(j) ;
break;
case 2: cout << " type coordonnees: valeur actuelle= "
<< coor_ddl_enum(j)(num_dans_coor(j));
break;
case 3: cout << " type tenseur: valeur actuelle= "
<< (*tens_ddl_enum(j))(ind_tens(j).i,ind_tens(j).j) ;
break;
default: cout << "\n type non reconnue= " << type_des_variables(i)
<< "\n Fonction_nD::Affiche_interne( ";
Sortie(1);
};
};
// bilan des variables évoluées
cout << "\n il y a: "
<< tailles_tab(1) << " scalaire(s) "
<< tailles_tab(2) << " coordonnee(s) "
<< tailles_tab(3) << " composante(s) de tenseur "
<< endl;
};
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque= tab_enu_quelconque.Taille();
if (taille_tab_enu_quelconque != 0)
{ cout << "\n enum_quelconque:_taille " << tab_enu_quelconque.Taille()
<< "\n liste: ";
for (int i=1;i<= taille_tab_enu_quelconque;i++)
cout << NomTypeQuelconque(tab_enu_quelconque(i)) << ", ";
};
};
// autres infos
cout << "\n il y a " << this->NbComposante() << " valeur(s) en retour de la fonction ";
if (depend_temps || depend_M || depend_Mt ||depend_M0 )
{ cout << "\n ";
if (depend_temps)
cout << " la fonction depend du temps, ";
if (depend_M || depend_Mt ||depend_M0 )
cout << " la fonction depend du point M : ";
if (depend_M)
cout << " courant, ";
if (depend_Mt)
cout << " a t, ";
if (depend_M0)
cout << " a 0, ";
};
};
};
//------ méthodes appelée par les classes dérivées ----
// relatives aux données gérées par Fonction_nD
// 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 Fonction_nD::Lect_base_info(ifstream& ent,const int cas)
{
if (cas == 1)
{ string toto; string nom;
// lecture des arguments
ent >> nom >> nom_variables;
t_inter_double.Change_taille(nom_variables.Taille());
// les énumérés des variables globales
ent >> nom;
int nb_enu=0;
ent >> nom >> nb_enu;
enu_variables_globale.Change_taille(nb_enu);
for (int i=1;i<= nb_enu;i++)
{ ent >> nom;
enu_variables_globale(i) = Id_nom_GrandeurGlobale(nom);
};
// les nom des variables globales indicées en string
ent >> nom;
int nb_nom=0;
ent >> nom >> nb_nom;
nom_variables_globales.Change_taille(nb_nom);
for (int i=1;i<= nb_nom;i++)
{ ent >> nom;
nom_variables_globales(i) = nom;
};
// enu étendu équivalent aux variables non globales
ent >> nom >> tab_enu_etendu;
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque; // init
ent >> nom >> taille_tab_enu_quelconque >> toto;
tab_enu_quelconque.Change_taille(taille_tab_enu_quelconque);
for (int i=1;i<= taille_tab_enu_quelconque;i++)
{ent >> nom;
tab_enu_quelconque(i) = Id_nomTypeQuelconque(nom);
};
// bilan des variables évoluées (on lit pour passer les infos
// dans le .BI, mais cela va être recalculé au moment de la fabrication
// des index
tailles_tab.Change_taille(4);
ent >> nom
>> tailles_tab(1) >> nom
>> tailles_tab(2) >> nom
>> tailles_tab(3) >> nom
>> tailles_tab(4) >> nom;
ent >> nom >> permet_affichage ;
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Fonction_nD::Ecrit_base_info(ofstream& sort,const int cas)
{
if (cas == 1)
{ // les variables
sort << " \n arguments= " << nom_variables
<< " \n variables_globales_en_enumere= " ;
int nb_enu = enu_variables_globale.Taille();
sort << "taille " << nb_enu << " ";
for (int i=1;i<= nb_enu;i++)
sort << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
sort << " \n variables_globales_en_string= " ;
int nb_str = nom_variables_globales.Taille();
sort << "taille " << nb_str << " ";
for (int i=1;i<= nb_str;i++)
sort << nom_variables_globales(i) << " ";
// enu étendu équivalent aux variables non globales
int taille_tab_enu_etendu= tab_enu_etendu.Taille();
sort << "\n enum_etendu_locaux: " << tab_enu_etendu;
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque= tab_enu_quelconque.Taille();
sort << "\n enum_quelconque:_taille " << tab_enu_quelconque.Taille()
<< "\n liste: ";
for (int i=1;i<= taille_tab_enu_quelconque;i++)
sort << NomTypeQuelconque(tab_enu_quelconque(i)) << " ";
// bilan des variables évoluées
sort << "\n bilan_var_evolue_il_y_a: "
<< tailles_tab(1) << " scalaire(s) "
<< tailles_tab(2) << " coordonnee(s) "
<< tailles_tab(3) << " composante(s)_de_tenseur "
<< tailles_tab(4) << " grandeur_quelconque "
;
sort << "\n permet_affichage_ "<<permet_affichage << " ";
};
};
// sortie du schemaXML: en fonction de enu
void Fonction_nD::SchemXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu)
{
switch (enu)
{ case XML_TYPE_GLOBAUX :
{
break;
}
case XML_IO_POINT_INFO :
{
break;
}
case XML_IO_POINT_BI :
{
break;
}
case XML_IO_ELEMENT_FINI :
{
break;
}
};
};
// lecture d'une ou plusieurs variables
// peut-être appelée plusieurs fois,
// stockage des infos dans Fonction_nD
void Fonction_nD::Lecture_variables(string& nom_lu,UtilLecture * entreePrinc)
{
// on lit tant que l'on ne rencontre pas une ligne contenant
// une info ne correspondant pas à des variables // ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle; // ref aux mots cle
// on utilise des listes pour éviter les doublons
list <Enum_GrandeurGlobale > list_enu_variables_glob; // enum glob
// on transvase le tableau dans la liste
enu_variables_globale.Init_list(list_enu_variables_glob);
// idem pour les noms globaux
list < string> list_de_variables_nom_globales; // string glob
nom_variables_globales.Init_list(list_de_variables_nom_globales);
// puis les variables qui ne sont pas globales
list < string> list_de_variables; // liste
nom_variables.Init_list(list_de_variables);
bool lecture_effective = false; // init
while (( (strstr(entreePrinc->tablcar,"un_argument=")==0)
&& (strstr(entreePrinc->tablcar,"deb_list_var_")==0)
)
|| (nom_lu == "un_argument=")
|| (nom_lu == "deb_list_var_")
)
{
// si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur
if ( motCle.SimotCle(entreePrinc->tablcar))
{ cout << "\n erreur de lecture des parametre de definition d'une fonction nD : on n'a pas trouve de mot cle relatif a une variable"
<< " et par contre la ligne courante contient un mot cle global "
<< " *** a priori il y a une erreur de mise en donnees ! " ;
entreePrinc->MessageBuffer("** erreur des parametres d'une fonction nD **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture d'un mot clé éventuellement
if (( (nom_lu != "un_argument=")
&& (nom_lu != "deb_list_var_")
)
|| lecture_effective
)
*(entreePrinc->entree) >> nom_lu;
// sinon cela veut dire que nom_lu a déjà été lu et repéré
// relatif à une variable
// ou que l'on vient de terminer une lecture de variabl
if ((entreePrinc->entree)->rdstate() == 0)
{} // lecture normale
#ifdef ENLINUX
else if ((entreePrinc->entree)->fail())
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ // on lit sans tenir compte des < éventuelles
entreePrinc->NouvelleDonneeSansInf();
*(entreePrinc->entree) >>nom_lu;
}
#else
else if ((entreePrinc->entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ if (nom_lu.find("fin_parametres_fonction_") == std::string::npos)
//if(nom_lu != "fin_parametres_fonction_expression_litterale_")
// on lit sans tenir compte des < éventuelles
{entreePrinc->NouvelleDonneeSansInf();
*(entreePrinc->entree) >> nom_lu;
};
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc->MessageBuffer("** erreur2 des parametres d'une fonction nD **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// cas de la lecture d'une variable
if(nom_lu == "un_argument=")
{*(entreePrinc->entree) >> nom_lu;
// on regarde s'il s'agit d'une variable globale correspondant à un énuméré global
if (EstUneGrandeurGlobale(nom_lu))
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (nom_lu));}
// idem mais sous forme d'un string
else if (ParaGlob::param->GrandeurGlobal(nom_lu) != NULL)
{ list_de_variables_nom_globales.push_back(nom_lu);}
else // sinon ce n'est pas une grandeur globale
{list_de_variables.push_back(nom_lu);};
// on signale que la lecture a été effective
lecture_effective = true;
}
else if(nom_lu == "deb_list_var_") // lecture d'une liste d'argument
{// on va lire juqu'au mot clé fin_list_var_
int nb_boucle = 0; // indicateur pour éviter une boucle infinie
do
{*(entreePrinc->entree) >> nom_lu;
if (nom_lu == "fin_list_var_")
break;
// on regarde s'il s'agit d'une variable globale
if (EstUneGrandeurGlobale(nom_lu))
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (nom_lu));}
// idem mais sous forme d'un string
else if (ParaGlob::param->GrandeurGlobal(nom_lu) != NULL)
{ list_de_variables_nom_globales.push_back(nom_lu);}
else // sinon ce n'est pas une grandeur globale
{list_de_variables.push_back(nom_lu);};
nb_boucle++;
} while (nb_boucle < 200);
if (nb_boucle > 199)
{ cout << "\n erreur de lecture au niveau d'une liste de variable "
<< " deb_list_var_ nom1 nom2 ... fin_list_var_";
entreePrinc->MessageBuffer("** erreur lecture parametre d'une d'une fonction nD ** **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else // sinon c'est ok
// on signale que la lecture a été effective
lecture_effective = true;
}
; // sinon rien, ce n'est plus une variable, on va donc sortir
// du while à la suite
}; // fin du while
// nom_lu contient la dernière information lue qui ne correspond pas à une variable
//--- maintenant on va gérer les variables lues
// on supprime les doublons dans les variables globales
list_enu_variables_glob.sort();
list_enu_variables_glob.unique();
list_de_variables_nom_globales.sort();
list_de_variables_nom_globales.unique();
// on remet à jour le tableau des énumérés globaux
enu_variables_globale.Init_from_list(list_enu_variables_glob);
// idem pour les noms de reférence globaux
nom_variables_globales.Init_from_list(list_de_variables_nom_globales);
// puis pour les variables qui ne sont pas globales
nom_variables.Init_from_list(list_de_variables);
// on met à jour les tableaux internes de passage de valeurs
x_x_i.Change_taille(nom_variables.Taille());
x_glob.Change_taille(enu_variables_globale.Taille()+nom_variables_globales.Taille());
};
// affichage des variables de la fonction, dépend du niveau d'impression
void Fonction_nD::Affichage_variables() const
{
if (permet_affichage > 5)
{ cout << "\n ---- Fonction_nD " << nom_ref ;
cout << " \n arguments_specifiques= " << nom_variables
<< " \n variables_globales_en_enumere= " ;
int nb_enu = enu_variables_globale.Taille();
cout << "taille " << nb_enu << " ";
for (int i=1;i<= nb_enu;i++)
cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
cout << " \n variables_globales_en_string= " ;
int nb_str = nom_variables_globales.Taille();
cout << "taille " << nb_str << " ";
for (int i=1;i<= nb_str;i++)
cout << nom_variables_globales(i) << " ";
};
};
// récupération des valeurs des variables globales et stockage dans le tableau
// interne x_glob
void Fonction_nD::Recup_Grandeurs_globales()
{ // --- on parcours les variables globales:
// 1) les énumérés
int index_glob=1;
int tail_enu = enu_variables_globale.Taille();
if (tail_enu>0)
{
// en debug on vérifie que les grandeurs globales sont présentent
#ifdef MISE_AU_POINT
try
{ int taille = enu_variables_globale.Taille();
for (int i=1;i<= taille;i++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
if (pointe == NULL)
{ cout << "\n *** pb dans l'appel de la fonction " << nom_ref << " !! "
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch(...)
{ cout << "\n ** erreur dans l'appel de la fonction "
<< nom_ref ;
cout << " verifier la presence des grandeurs globales voulues "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
for (int i=1;i<= tail_enu;i++,index_glob++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
{ case TYPE_SIMPLE:
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
{case PARTICULIER_SCALAIRE_ENTIER:
{Grandeur_scalaire_entier& gr
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurEntier());
break;
}
case PARTICULIER_SCALAIRE_DOUBLE:
{Grandeur_scalaire_double& gr
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_DDL_ETENDU:
{Grandeur_Ddl_etendu& gr
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
break;
}
case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER:
{Grandeur_Double_Nommer_indicer& gr
= *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
if (permet_affichage > 5)
{cout << "\n " << Nom_GrandeurGlobale(enu_variables_globale(i))
<< " " << x_glob(index_glob);
};
};
};
// 2) idem pour les globaux en nom c-a-d typées sous forme de string
int tail_nom = nom_variables_globales.Taille();
if (tail_nom>0)
{
// en debug on vérifie que les grandeurs globales sont présentent
#ifdef MISE_AU_POINT
try
{ for (int i=1;i<= tail_nom;i++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
if (pointe == NULL)
{ cout << "\n *** pb dans Fonction_expression_litterale_nD " << nom_ref << " !! "
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch(...)
{ cout << "\n ** erreur dans l'appel de la fonction "
<< nom_ref ;
cout << " verifier la presence des grandeurs globales voulues "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
// on parcours les variables globales
int taille = nom_variables_globales.Taille();
for (int i=1;i<= taille;i++,index_glob++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
{ case TYPE_SIMPLE:
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
{case PARTICULIER_SCALAIRE_ENTIER:
{Grandeur_scalaire_entier& gr
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurEntier());
break;
}
case PARTICULIER_SCALAIRE_DOUBLE:
{Grandeur_scalaire_double& gr
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_DDL_ETENDU:
{Grandeur_Ddl_etendu& gr
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
break;
}
case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER:
{Grandeur_Double_Nommer_indicer& gr
= *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_VECTEUR_NOMMER:
{Grandeur_Vecteur_Nommer& gr
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
#ifdef MISE_AU_POINT
// on vérifie qu'une seule grandeur est stockée
if (gr.NbMaxiNumeroOrdre() > 1)
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
<< " compte pour l'intant, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
case TABLEAU_T: // valable uniquement pour les vecteur nommer
// dans ce cas on n'utilise pour l'instant que la première valeur
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
{ case PARTICULIER_VECTEUR_NOMMER:
{Grandeur_Vecteur_Nommer& gr
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
#ifdef MISE_AU_POINT
// on vérifie qu'une seule grandeur est stockée
if (gr.NbMaxiNumeroOrdre() > 1)
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
<< " compte pour l'intant, on ne peut pas continuer "
<< "\n grandeur= "<<gr<< " NbMaxiNumeroOrdre()= "<< gr.NbMaxiNumeroOrdre()
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
if (permet_affichage > 5)
{cout << "\n " << nom_variables_globales(i)
<< " " << x_glob(index_glob);
};
};
};
};