803 lines
40 KiB
C++
Executable file
803 lines
40 KiB
C++
Executable file
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
// fichier : Fonction_nD.h
|
|
// classe : Fonction_nD
|
|
|
|
|
|
/************************************************************************
|
|
* DATE: 01/06/2016 *
|
|
* $ *
|
|
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
|
|
* $ *
|
|
* PROJET: Herezh++ *
|
|
* $ *
|
|
************************************************************************
|
|
* BUT: Classe virtuelle permettant le calcul d'une fonction nD *
|
|
* ainsi qu'éventuellement un certain nombre d'information supplé- *
|
|
* mentaires telles que dérivées. *
|
|
* si le nom de la Fonction = "_" il s'agit d'une Fonction interne *
|
|
* à un objet, c'est-à-dire gérée seulement par l'entité qui la *
|
|
* contient, donc pas besoin de nom (elle n'est pas utilisée autre *
|
|
* part). Si le nom est différent de "_" c'est une Fonction qui est *
|
|
* gérée et référencée dans LesFonctions, donc à partir de son nom, *
|
|
* on peut la retrouver. *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* *
|
|
* VERIFICATION: *
|
|
* *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* ! ! ! ! *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* MODIFICATIONS: *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* $ *
|
|
************************************************************************/
|
|
|
|
#ifndef FONCTION_N_D_H
|
|
#define FONCTION_N_D_H
|
|
|
|
#include "UtilLecture.h"
|
|
#include "EnumFonction_nD.h"
|
|
#include "Enum_IO_XML.h"
|
|
#include "Tableau_T.h"
|
|
#include "Enum_GrandeurGlobale.h"
|
|
#include "Courbe1D.h"
|
|
#include "Coordonnee.h"
|
|
#include "Ddl_etendu.h"
|
|
#include "TypeQuelconque.h"
|
|
#include "Tenseur.h"
|
|
/** @defgroup Les_fonctions_nD Les_fonctions_nD
|
|
*
|
|
* \author Gérard Rio
|
|
* \version 1.0
|
|
* \date 01/06/2016
|
|
* \brief Def des fonctions nD
|
|
*
|
|
*/
|
|
|
|
|
|
/// @addtogroup Les_fonctions_nD
|
|
/// @{
|
|
///
|
|
|
|
/// gestion d'exception pour des erreurs d'appel de fonction nD
|
|
class ErrCalculFct_nD
|
|
{ public :
|
|
ErrCalculFct_nD () {} ; // CONSTRUCTEURS
|
|
~ErrCalculFct_nD () {};// DESTRUCTEUR :
|
|
};
|
|
/// @} // end of group
|
|
|
|
/// @addtogroup Les_fonctions_nD
|
|
/// @{
|
|
///
|
|
|
|
/**
|
|
*
|
|
* BUT: Classe virtuelle d'interface permettant le calcul d'une fonction nD
|
|
* ainsi qu'éventuellement un certain nombre d'informations supplé-
|
|
* mentaires telles que dérivées.
|
|
* si le nom de la Fonction = "_" il s'agit d'une Fonction interne
|
|
* à un objet, c'est-à-dire gérée seulement par l'entité qui la
|
|
* contient, donc pas besoin de nom (elle n'est pas utilisée autre
|
|
* part). Si le nom est différent de "_" c'est une Fonction qui est
|
|
* gérée et référencée dans LesFonctions, donc à partir de son nom,
|
|
* on peut la retrouver.
|
|
*
|
|
*
|
|
* \author Gérard Rio
|
|
* \version 1.0
|
|
* \date 01/06/2016
|
|
* \brief Classe virtuelle d'interface permettant le calcul d'une fonction nD ainsi qu'éventuellement un certain nombre d'informations supplémentaires telles que dérivées.
|
|
*
|
|
*/
|
|
|
|
class Fonction_nD
|
|
{
|
|
public :
|
|
|
|
// CONSTRUCTEURS :
|
|
// par défaut
|
|
Fonction_nD(string nom = "", EnumFonction_nD typ = AUCUNE_FONCTION_nD);
|
|
// constructeur avec plus d'info
|
|
// dans le cas ou les variables sont associées à des types quelconques, il
|
|
// s'agit que de conteneur d'un scalaire simple. Dans le cas contraire il y a erreur !
|
|
Fonction_nD(const Tableau <string >& var, string nom = "", EnumFonction_nD typ = AUCUNE_FONCTION_nD);
|
|
|
|
// def de tous les paramètres: utile pour être appelé par les classes dérivées
|
|
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
|
|
|
|
// de copie
|
|
Fonction_nD(const Fonction_nD& Co);
|
|
// DESTRUCTEUR :
|
|
virtual ~Fonction_nD();
|
|
|
|
// METHODES PUBLIQUES :
|
|
//
|
|
// // 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
|
|
// // la fonction nD ne doit pas pouvoir fonctionner s'il y a des types complexes
|
|
// // et que cette méthode n'a pas été appelé
|
|
// void Preparation_Grandeur_quelconque(const Tableau <TypeQuelconque >& tqi);
|
|
|
|
// --------- virtuelles ---------
|
|
|
|
// Surcharge de l'operateur = : realise l'egalite de deux fonctions
|
|
virtual Fonction_nD& operator= (const Fonction_nD& elt) = 0;
|
|
|
|
// affichage de la Fonction
|
|
// = 0, 1 ou 2 (le plus précis)
|
|
virtual void Affiche(int niveau = 0) const = 0;
|
|
// ramène le nom de la Fonction
|
|
const string& NomFonction() const {return nom_ref;};
|
|
// vérification que tout est ok, pres à l'emploi
|
|
// ramène true si ok, false sinon
|
|
virtual bool Complet_Fonction(bool affichage = true)const =0 ;
|
|
|
|
// ramène le nombre total de variables de la fonction
|
|
// c-a-dire locale et globales
|
|
virtual int NbVariable()const
|
|
{return nom_variables.Taille()+enu_variables_globale.Taille()
|
|
+ nom_variables_globales.Taille();
|
|
};
|
|
|
|
// ramène le nombre de variables locales
|
|
// c-a-dire à l'exclusion des variables globales
|
|
virtual int NbVariable_locale()const
|
|
{return nom_variables.Taille();
|
|
};
|
|
|
|
// ramène le nombre de variables globales
|
|
// c-a-dire à l'exclusion des variables locales
|
|
virtual int NbVariable_globale()const
|
|
{return (enu_variables_globale.Taille()+nom_variables_globales.Taille());
|
|
};
|
|
|
|
// ramène le noms des variables, indépendamment des variables globales
|
|
const Tableau <string >& Nom_variables() const {return nom_variables;};
|
|
|
|
// ramène les énumérés des variables globales éventuelles
|
|
const Tableau <Enum_GrandeurGlobale >& Enu_variables_globales() const {return enu_variables_globale;};
|
|
// ramène les noms string des variables globales éventuelles
|
|
const Tableau <string >& Nom_variables_globales() const {return nom_variables_globales;};
|
|
|
|
// ramène l'équivalent des nom_variables sous forme de Ddl_enum_etendu et
|
|
// d'EnumTypeQuelconque
|
|
// permet ensuite d'appeler la méthode Valeur(.. mais à la condition
|
|
// que l'ensemble des Nom_variables() sont représenté soit par des Ddl_enum_etendu
|
|
// et ou soit par des EnumTypeQuelconque
|
|
const Tableau <Ddl_enum_etendu>& Tab_enu_etendu()const {return tab_enu_etendu;};
|
|
const Tableau <EnumTypeQuelconque>& Tab_enu_quelconque() const {return tab_enu_quelconque;};
|
|
// un booléen pour noter l'équivalence parfaite ou non
|
|
bool Equivalence_nom_enu_etendu_et_enu_quelconque() const {return equivalence_nom_enu_etendu_et_enu_quelconque;};
|
|
|
|
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
|
|
const Tableau <int>& Iindex_enu_etendu() const {return index_enu_etendu;};
|
|
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
|
|
const Tableau <int>& Iindex_enu_quelconque() const {return index_enu_quelconque;};
|
|
|
|
// .. chaque type_des_variables tab_enu_etendu(i) est associé à :
|
|
// si type_des_variables(i) = 1 -> un scalaire
|
|
// si type_des_variables(i) = 2 -> des coordonnées de dim absolue
|
|
// si type_des_variables(i) = 3 -> un tenseur de dim absolue
|
|
// si type_des_variables(i) = 4 -> une grandeur quelconque
|
|
// retour du tableau des indicateurs
|
|
const Tableau <int>& Type_des_variables_locales() const {return type_des_variables;};
|
|
|
|
// retour du tableau posi_ddl_enum, qui est nécessaire pour l'appel de la fonction
|
|
// Val_FnD_Evoluee(Tableau <double >* xi_,Tableau <Coordonnee> * tab_coor_,Tableau <TenseurBB* >* tab_tensBB_
|
|
// Tableau <TypeQuelconque >* t_quelc_ )
|
|
// -> Pour le Ddl_enum_etendu (i) dont on récupère la liste via Tab_enu_etendu()
|
|
// si (i) est un scalaire alors: posi_ddl_enum(i) représente la position que doit
|
|
// avoir de Ddl_enum_etendu(i) dans xi_
|
|
// si (i) est de type Coordonnee -> position du ddl_enum_etendu(i) dans tab_coor_
|
|
// si (i) un tenseur -> position du ddl_enum_etendu(i) dans tab_tensBB_
|
|
// si (i) une grandeur quelconque -> position du ddl_enum_etendu(i) dans t_quelc_
|
|
const Tableau <int>& Index_dans_tableau() const {return posi_ddl_enum;};
|
|
|
|
|
|
// retour des tailles qu'ont les différents tableaux associés au ddl_enum
|
|
// tailles_tab(1) -> nb de scalaires
|
|
// (2) -> nb de Coordonnee
|
|
// (3) -> nb de tenseur
|
|
// (4) -> nb de grandeurs quelconques
|
|
const Tableau <int>& Tailles_tab() const {return tailles_tab;};
|
|
|
|
|
|
// ramène le nombre de composantes de la fonction
|
|
virtual int NbComposante() const =0;
|
|
|
|
// Lecture des donnees de la classe sur fichier
|
|
// le nom passé en paramètre est le nom de la Fonction
|
|
// s'il est vide c-a-d = "", la methode commence par lire le nom sinon
|
|
// ce nom remplace le nom actuel
|
|
virtual void LectDonnParticulieres_Fonction_nD(const string& nom, UtilLecture * ) = 0;
|
|
|
|
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
|
|
// globales en cours de calcul
|
|
virtual void Mise_a_jour_variables_globales() = 0;
|
|
|
|
// établir le lien entre la Fonction et des Fonctions déjà existantes dont
|
|
// on connait que le nom
|
|
// permet ainsi de complèter la Fonction
|
|
// 1) renseigne si la Fonction dépend d'autre Fonction ou non
|
|
virtual bool DependAutreFoncCourbes() const {return false;}; // par défaut non
|
|
// 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this
|
|
virtual list <string>& ListDependanceCourbes(list <string>& lico) const;
|
|
// 3) retourne une liste de nom correspondant aux noms de Fonction dont dépend *this
|
|
virtual list <string>& ListDependanceFonctions(list <string>& lico) const;
|
|
// 4) établit la connection entre la demande de *this et les Fonctions passées en paramètres
|
|
virtual void Lien_entre_fonc_courbe(list <Fonction_nD *>& liptfonc,list <Courbe1D *>& liptco) {};
|
|
|
|
// def info fichier de commande
|
|
virtual void Info_commande_Fonctions_nD(UtilLecture & entreePrinc) = 0;
|
|
|
|
|
|
// calcul des valeurs de la fonction, avec comme argument: uniquement des grandeurs
|
|
// scalaires simples
|
|
// retour d'un tableau de scalaires
|
|
Tableau <double> & Valeur_FnD_tab_scalaire(Tableau <double >* val_double)
|
|
{try
|
|
{
|
|
// #ifdef MISE_AU_POINT
|
|
if (permet_affichage > 4)
|
|
{
|
|
cout << "\n fonction: "<<nom_ref<<" : ";
|
|
if (permet_affichage > 5)
|
|
{cout << "\n parametres d'appel: ";
|
|
int nb_var = val_double->Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< (*val_double)(j);}
|
|
};
|
|
Tableau <double> & inter = Valeur_FnD_interne(val_double);
|
|
cout << "\n retour fonction: ";
|
|
int nb_val = inter.Taille();
|
|
for (int i=1;i<=nb_val;i++)
|
|
cout << " val("<<i<<")= "<<inter(i);
|
|
return inter;
|
|
}
|
|
else
|
|
// #endif
|
|
return Valeur_FnD_interne(val_double);
|
|
}
|
|
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_tab_scalaire(..."<<endl;
|
|
this->Affiche();
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
// on ne doit jamais arriver ici !
|
|
return Valeur_FnD_interne(val_double); // pour taire le compilo
|
|
};
|
|
|
|
// calcul des valeurs de la fonction, à l'aide de paramètres = grandeurs évoluées
|
|
// retour d'un tableau de scalaires
|
|
// les différents tableaux doivent contenir toutes les informations nécessaires pour l'appel
|
|
// NB: il peut y avoir plus d'info que nécessaire
|
|
// l'ordre des paramètres doit respecter celui donné par les fonctions Index_dans_tableau()
|
|
// il peut y avoir éventuellement des grandeurs quelconques et éventuellement des types non scalaire
|
|
// dans ce dernier cas il faut renseigner le tableau de numéro d'ordre t_num_ordre
|
|
Tableau <double> & Val_FnD_Evoluee(Tableau <double >* val_ddl_enum
|
|
,Tableau <Coordonnee> * coor_ddl_enum
|
|
,Tableau <TenseurBB* >* tens_ddl_enum
|
|
,Tableau <const TypeQuelconque * >* tqi = NULL
|
|
,Tableau <int> * t_num_ordre = NULL
|
|
)
|
|
{ if (equivalence_nom_enu_etendu_et_enu_quelconque)
|
|
{try
|
|
{ Vers_tab_double(t_inter_double,val_ddl_enum,coor_ddl_enum,tens_ddl_enum
|
|
,tqi,t_num_ordre);
|
|
// #ifdef MISE_AU_POINT
|
|
if (permet_affichage > 4)
|
|
{cout << "\n fonction: "<<nom_ref<<" : ";
|
|
if (permet_affichage > 5)
|
|
{cout << "\n parametres d'appel: ";
|
|
int nb_var = t_inter_double.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< t_inter_double(j);}
|
|
};
|
|
Tableau <double> & inter = Valeur_FnD_interne(&t_inter_double);
|
|
cout << "\n retour fonction: ";
|
|
int nb_val = inter.Taille();
|
|
for (int i=1;i<=nb_val;i++)
|
|
cout << " val("<<i<<")= "<<inter(i);
|
|
return inter;
|
|
}
|
|
else
|
|
// #endif
|
|
return Valeur_FnD_interne(&t_inter_double);
|
|
}
|
|
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_Evoluee(..."<<endl;
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
this->Affiche();Sortie(1);
|
|
};
|
|
}
|
|
else {cout << "\n erreur appel Val_FnD_Evoluee(, variables non definies ! ";
|
|
this->Affiche();
|
|
ErrCalculFct_nD toto;throw (toto);Sortie(1);
|
|
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilateur
|
|
};
|
|
// on ne doit jamais arriver ici !
|
|
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilo
|
|
};
|
|
|
|
// mise à disposition des conteneurs pour l'appel de Valeur_FnD sans paramètres
|
|
// il n'est pas autorisé de changer la taille du conteneur, c'est seulement les valeurs qui doivent
|
|
// être modifiées sinon il y aura des pb
|
|
// l'ordre des paramètres doit respecter celui donné par les fonctions Index_dans_tableau()
|
|
Tableau <double >& Val_ddl_enum() {return val_ddl_enum;} // valeur associé à l'enu_etendu(i) si scalaire
|
|
Tableau <Coordonnee >& Coor_ddl_enum() {return coor_ddl_enum;}; // idem si Coordonnées (en orthonormée)
|
|
// retourne le tableau de l'ensemble des grandeurs de type Coordonnee qui sont nécessaire pour l'appel
|
|
// chaque type est repéré par premier_famille_Coord(j) ce qui correspond à coor_ddl_enum(j)
|
|
Tableau <Ddl_enum_etendu>& Premier_famille_Coor() {return premier_famille_Coord;}
|
|
|
|
Tableau <TenseurBB* >& Tens_ddl_enum() {return tens_ddl_enum;}; // idem si Tenseur (en orthonormée !)
|
|
int Absolue() const {return absolue;} // indique si les tenseurs sont en absolue ou non
|
|
|
|
Tableau <Ddl_enum_etendu>& Premier_famille_tenseur() {return premier_famille_tenseur;}
|
|
|
|
// -- retourne une liste de grandeurs quelconques équivalentes aux types évoluées non scalaires
|
|
// li_equi_Quel_evolue : est l'équivalent des grandeurs évoluées: coor_ddl_enum et tens_ddl_enum
|
|
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
|
|
// non scalaires
|
|
// l'ordre l'apparition dans la liste est telle que l'on a:
|
|
// 1) tous les Coordonnees 2) puis tous les tenseurs
|
|
// dans le même ordre que pour les tableaux: coor_ddl_enum puis tens_ddl_enum
|
|
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
|
|
List_io <TypeQuelconque >& Li_equi_Quel_evolue() {return li_equi_Quel_evolue;};
|
|
|
|
// -- retourne une liste des grandeurs évoluées uniquement scalaire
|
|
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
|
|
// est équivalent à val_ddl_enum, l'ordre d'apparition est celui de val_ddl_enum
|
|
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
|
|
List_io <Ddl_enum_etendu>& Li_enu_etendu_scalaire() {return li_enu_etendu_scalaire;}
|
|
|
|
// calcul équivalent, cf. les paramètres de passage
|
|
// pour que l'appel à cette méthode soit correcte, il faut que les listes correspondent
|
|
// à celles de Li_equi_Quel_evolue(), et Li_enu_etendu_scalaire(),
|
|
// =>=>=> il faut donc utiliser ces listes en les récupérants auparavant !!
|
|
// Si t_num_ordre est Null cela signifie que tous les tqi sont de grandeurs scalaire
|
|
// dans le cas contraire t_num_ordre(i) donne le numéro d'ordre du scalaire dans tqi qui correspond à Nom_variable(i)
|
|
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
|
|
Tableau <double> & Valeur_FnD_Evoluee(Tableau <double >* val_ddl_enum
|
|
,List_io <Ddl_enum_etendu>* li_evolue_scalaire
|
|
,List_io <TypeQuelconque >* li_evoluee_non_scalaire
|
|
,Tableau <const TypeQuelconque * >* tqi
|
|
,Tableau <int> * t_num_ordre)
|
|
{ if (equivalence_nom_enu_etendu_et_enu_quelconque)
|
|
{ try
|
|
{Vers_tab_double(t_inter_double,val_ddl_enum,li_evolue_scalaire,li_evoluee_non_scalaire,tqi,t_num_ordre);
|
|
// #ifdef MISE_AU_POINT
|
|
if (permet_affichage > 4)
|
|
{cout << "\n fonction: "<<nom_ref<<" : ";
|
|
if (permet_affichage > 5)
|
|
{cout << "\n parametres d'appel: ";
|
|
int nb_var = t_inter_double.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< t_inter_double(j);}
|
|
};
|
|
Tableau <double> & inter = Valeur_FnD_interne(&t_inter_double);
|
|
cout << "\n retour fonction: ";
|
|
int nb_val = inter.Taille();
|
|
for (int i=1;i<=nb_val;i++)
|
|
cout << " val("<<i<<")= "<<inter(i);
|
|
return inter;
|
|
}
|
|
else
|
|
// #endif
|
|
return Valeur_FnD_interne(&t_inter_double);
|
|
}
|
|
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_Evoluee(..."<<endl;
|
|
this->Affiche();
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else {cout << "\n erreur appel Val_FnD_Evoluee(, variables non definies ! ";
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilateur
|
|
};
|
|
// on ne doit jamais arriver ici !
|
|
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilo
|
|
};
|
|
|
|
// 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
|
|
// Si t_num_ordre est Null cela signifie que tous les tqi sont de grandeurs scalaire
|
|
// dans le cas contraire t_num_ordre(i) donne le numéro d'ordre du scalaire dans tqi qui correspond à Nom_variable(i)
|
|
Tableau <double> & Valeur_FnD(Tableau <Ddl_etendu> * t_enu,Tableau <const TypeQuelconque * > * tqi
|
|
,Tableau <int> * t_num_ordre);
|
|
|
|
// indicateur permettant de connaître rapidement si
|
|
// la fonction dépend de la position d'un point M: ici au temps tdt
|
|
// 0 : la fonction ne dépend pas de la position d'un point M
|
|
// =i non nul : la fonction dépend de la position d'un point M
|
|
// et = le nombre de composantes demandés (ne sert pas vraiment)
|
|
// dans ce cas, une au moins des nom_variables a un nom de la même famille que le ddl X1
|
|
// si = -1 : cela signifie que la fonction dépend "que" de M
|
|
int Depend_M() const {return depend_M;}; // cas d'une position courante
|
|
int Depend_Mt() const {return depend_Mt;}; // cas de la position spécifiquement a t
|
|
int Depend_M0() const {return depend_M0;}; // cas de la position initiale
|
|
|
|
// calcul des valeurs de la fonction, dans le cas où les variables
|
|
// sont "tous" des grandeurs globales
|
|
Tableau <double> & Valeur_pour_variables_globales()
|
|
{ try
|
|
{
|
|
// #ifdef MISE_AU_POINT
|
|
if (permet_affichage > 4)
|
|
{cout << "\n fonction: "<<nom_ref<<" : ";
|
|
Tableau <double> & inter = Valeur_pour_variables_globales_interne();
|
|
cout << "\n retour fonction: ";
|
|
int nb_val = inter.Taille();
|
|
for (int i=1;i<=nb_val;i++)
|
|
cout << " val("<<i<<")= "<<inter(i);
|
|
return inter;
|
|
}
|
|
else
|
|
// #endif
|
|
return Valeur_pour_variables_globales_interne();
|
|
}
|
|
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 Valeur_pour_variables_globales(..."<<endl;
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
this->Affiche();Sortie(1);
|
|
};
|
|
// on ne doit jamais arriver ici !
|
|
return Valeur_pour_variables_globales_interne(); // pour taire le compilo
|
|
};
|
|
|
|
// ---- fonctions internes qui ne "doivent pas !!!" être utilisée directement ---
|
|
// elles sont mises en public, pour pouvoir être appelées par les classes dérivées
|
|
// sans avoir à déclarer en friend les classes dérivées, sinon cela fait une boucle
|
|
// sans fin, d'où la solution choisit pour éviter ce pb
|
|
|
|
// calcul des valeurs de la fonction, retour d'un tableau de scalaires
|
|
virtual Tableau <double> & Valeur_FnD_interne(Tableau <double >* val_ddl_enum) = 0;
|
|
|
|
// calcul des valeurs de la fonction, dans le cas où les variables
|
|
// sont "tous" des grandeurs globales
|
|
virtual Tableau <double> & Valeur_pour_variables_globales_interne() = 0;
|
|
|
|
//----- lecture écriture de restart -----
|
|
// 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)
|
|
virtual void Lecture_base_info(ifstream& ent,const int cas) = 0;
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
virtual void Ecriture_base_info(ofstream& sort,const int cas) = 0;
|
|
// sortie du schemaXML: en fonction de enu
|
|
virtual void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu) = 0;
|
|
|
|
// ---------- static ---------
|
|
|
|
// ramène un pointeur sur la Fonction correspondant au type de Fonction passé en paramètre
|
|
// IMPORTANT : il y a création d'une Fonction (utilisation d'un new)
|
|
static Fonction_nD* New_Fonction_nD(string& nom,EnumFonction_nD typeFonction);
|
|
// ramène un pointeur sur une Fonction copie de celle passée en paramètre
|
|
// IMPORTANT : il y a création d'une Fonction (utilisation d'un new)
|
|
static Fonction_nD* New_Fonction_nD(const Fonction_nD& Co);
|
|
|
|
// ramène la liste des identificateurs de Fonctions actuellement disponibles
|
|
static list <EnumFonction_nD> Liste_Fonction_disponible();
|
|
|
|
// ---------- non virtuelle ---------
|
|
|
|
// ramène le type de la Fonction
|
|
EnumFonction_nD Type_Fonction() const { return typeFonction;};
|
|
|
|
|
|
protected :
|
|
|
|
// VARIABLES PROTEGEES :
|
|
EnumFonction_nD typeFonction; // type de la fonction
|
|
string nom_ref; // nom de référence de la Fonction
|
|
|
|
Tableau <string > nom_variables; //variables de la fonction, vu de l'extérieur
|
|
Tableau <double > t_inter_double; // tableau de même dimension que nom_variable
|
|
// sert pour passer les infos à la méthode Valeur_FnD_interne(..
|
|
|
|
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 noms en string
|
|
// de variables globales
|
|
// éventuellement vide s'il ne sert pas
|
|
|
|
// *** important: les tableaux nom_variables, enu_variables_globales et
|
|
// nom_variables_globales s'ajoutent
|
|
// ils ne sont pas liés entre eux: le nombre total de variables est
|
|
// la somme des trois tableaux. En général c'est soit l'un , soit l'autre
|
|
// ou le dernier mais on peut avoir un mixte
|
|
|
|
// ---- tableaux de grandeurs équivalentes aux nom_variables (locales) -----
|
|
// un tableau tab_enu_etendu et un tableau tab_enu_quelconque:
|
|
// tab_enu_etendu.Taille()+tab_enu_quelconque.Taille() == nom_variables.Taille() -> grandeurs locales
|
|
Tableau <Ddl_enum_etendu> tab_enu_etendu;
|
|
|
|
// tab_enu_etendu peut se décomposer de deux manières équivalentes :
|
|
// 1) tableaux: val_ddl_enum (scalaires) , coor_ddl_enum (Coordonnees) , tens_ddl_enum (tenseur)
|
|
// permet aux utilisateurs d'obtenir un stockage et un appel avec des grandeurs évoluées, distinctes
|
|
// 2) list: li_enu_etendu_scalaire (scalaires) , li_equi_Quel_evolue (Coordonnees "et" tenseurs)
|
|
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
|
|
// et permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
|
|
// excluant les scalaire, et appels associés
|
|
// li_equi_Quel_evolue correspond à des grandeurs quelconques contenant Coordonnees et tenseur,
|
|
// est indépendant de tab_enu_quelconque, qui lui est complètement quelconque, on ne sait pas a priori
|
|
// ce qu'il y a dedans
|
|
|
|
// .. chaque grandeur quelconque doit être associé, lors de l'appel de la fonction, à un numéro d'ordre
|
|
// du coup, pour l'instant on n'utilise qu'un scalaire par grandeur quelconque, mais le conteneur
|
|
// peut en contenir plusieurs
|
|
Tableau <EnumTypeQuelconque> tab_enu_quelconque;
|
|
|
|
// ----- grandeurs évoluées y compris les grandeurs quelconques -------
|
|
// .. chaque nom_variables(j) est associé à :
|
|
Tableau <int> type_des_variables; // si type_des_variables(j) = 1 -> un scalaire
|
|
// si type_des_variables(j) = 2 -> des coordonnées de dim absolue
|
|
// si type_des_variables(j) = 3 -> un tenseur de dim absolue
|
|
// si type_des_variables(j) = 4 -> une grandeur quelconque
|
|
// si type_des_variables(j) = 0 -> une grandeur qui n'est pas reconnue en local
|
|
|
|
// .... dans le cas d'un Ddl_enum_etendu : donc c'est relatif au tableau: tab_enu_etendu
|
|
Tableau <double > val_ddl_enum; // valeur associé au ddl tab_enu_etendu(i) si scalaire
|
|
// tab_enu_etendu(i) <=> val_ddl_enum(posi_ddl_enum(i))
|
|
List_io <Ddl_enum_etendu> li_enu_etendu_scalaire; // est équivalent à val_ddl_enum,
|
|
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
|
|
|
|
Tableau <Ddl_enum_etendu> premier_famille_Coord; // les ddl du premier de famille
|
|
//coor_ddl_enum(j) est associé avec premier_famille_Coord(j)
|
|
Tableau <Coordonnee > coor_ddl_enum; // le vecteur Coordonnée associé au ddl tab_enu_etendu(i) si Coordonnées
|
|
Tableau <int > num_dans_coor; // le numéro dans le vecteur associé au ddl tab_enu_etendu(i)
|
|
// avec j = posi_ddl_enum(i)
|
|
// tab_enu_etendu(i) <=> coor_ddl_enum(j)(num_dans_coor(i))
|
|
// bien noter qu'un objet Coordonnee peut contenir plusieurs Ddl_enum_etendu
|
|
|
|
Tableau <Ddl_enum_etendu> premier_famille_tenseur; // les ddl du premier de famille
|
|
// (*tens_ddl_enum)(j) est associé avec premier_famille_tenseur(j)
|
|
Tableau <TenseurBB* > tens_ddl_enum; // tenseur associé au ddl tab_enu_etendu(i) si Tenseur
|
|
int absolue; // indique si les tenseurs sont en absolue ou non
|
|
Tableau <Deuxentiers_enu > ind_tens; // indice dans le tenseur de la grandeur
|
|
// avec j = posi_ddl_enum(i)
|
|
// avec k = ind_tens(i).i et l = ind_tens(i).j
|
|
// tab_enu_etendu(i) <=> (*tens_ddl_enum)(j)(k,l)
|
|
// bien noter qu'un objet Tenseur peut contenir plusieurs Ddl_enum_etendu
|
|
|
|
// li_equi_Quel_evolue : est l'équivalent des grandeurs évoluées: coor_ddl_enum et tens_ddl_enum
|
|
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
|
|
List_io <TypeQuelconque > li_equi_Quel_evolue; // non scalaires
|
|
|
|
// tab_equi_Coor(j) contient un Coordonnee équivalent à coor_ddl_enum(j)
|
|
Tableau <List_io<TypeQuelconque >::iterator > tab_equi_Coor;
|
|
//tab_equi_tens(j) contient un tenseur équivalent à tens_ddl_enum(j)
|
|
Tableau <List_io<TypeQuelconque >::iterator > tab_equi_tens;
|
|
|
|
|
|
// un système d'adressage indirect pour le passage : tab_enu_etendu(i) <-> grandeur évoluée
|
|
Tableau <int> posi_ddl_enum; // posi_ddl_enum(i) donne la position de tab_enu_etendu(i)
|
|
// dans le tableau :
|
|
// si scalaire : dans le tableau val_ddl_enum ->val_ddl_enum(posi_ddl_enum(i))
|
|
// si Coordonnées : dans le tableau coor_ddl_enum -> coor_ddl_enum(posi_ddl_enum(i))
|
|
// ici il s'agira de tous les ddl de la même famille,
|
|
// et c'est num_dans_coor qui permet de trouver la position
|
|
// si Tenseur : dans le tableau tens_ddl_enum -> tens_ddl_enum(posi_ddl_enum(i))
|
|
// et c'est ind_tens qui permettra de trouver les indices
|
|
|
|
// un système d'adressage indirect pour le passage : nom_variables(j) <-> grandeur évoluée
|
|
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
|
|
Tableau <int> index_enu_etendu;
|
|
|
|
// .... dans le cas d'une grandeur quelconque
|
|
// pour les grandeurs quelconques, l'utilisateur doit transmettre le numéro d'ordre correspondant à l'équivalence
|
|
// du ddl_etendu, du coup on ne s'occupe pas de gérer les numéros d'ordre pour les grandeurs quelconques
|
|
|
|
// un système d'adressage indirect pour le passage : nom_variables(j) <-> grandeur quelconque
|
|
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
|
|
Tableau <int> index_enu_quelconque;
|
|
|
|
|
|
// stockage des tailles qu'ont les différents tableaux associés
|
|
Tableau <int> tailles_tab; // tailles_tab(1) -> nb de scalaires
|
|
// (2) -> nb de Coordonnee
|
|
// (3) -> nb de tenseur
|
|
// (4) -> nb de grandeurs quelconques
|
|
// ----- fin grandeurs évoluées y compris les grandeurs quelconques-------
|
|
|
|
// ces deux tableaux permettent d'appeler la méthode Valeur(..
|
|
// un booléen pour noter l'équivalence parfaite ou non
|
|
bool equivalence_nom_enu_etendu_et_enu_quelconque;
|
|
|
|
// un tableau intermédiaire qui sert pour Valeur(Tableau <Ddl_etendu> ...
|
|
// c-a-d pour les variables non globales
|
|
Tableau <double > x_x_i;
|
|
// un tableau intermédiaire qui sert pour toutes les variables globales
|
|
Tableau <double > x_glob;
|
|
|
|
int depend_M; // indicateur permettant de connaître rapidement si
|
|
// la fonction dépend de la position courante d'un point M
|
|
// 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
|
|
int depend_Mt; // idem pour le temps t
|
|
int depend_M0; // idem pour le temps 0
|
|
|
|
bool depend_temps; // indicateur permettant de connaître rapidement si
|
|
// la fonction dépend du temps ou non
|
|
|
|
// ----- controle de la sortie des informations: utilisé par les classes dérivées
|
|
int permet_affichage; // pour permettre un affichage spécifique dans les méthodes, pour les erreurs et warning
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// METHODES PROTEGEES :
|
|
// ramène true si les variables de la classe mère sont complèté
|
|
bool Complet_var() const;
|
|
|
|
// définit le paramètre depend_M en fonction des nom_variables
|
|
void Definition_depend_M();
|
|
|
|
// définit le paramètre depend_temps en fonction des nom_variables
|
|
void Definition_depend_temps();
|
|
|
|
// construction à partir des noms de variables, des tableaux tab_enu_etendu et
|
|
// tab_enu_quelconque
|
|
// void Construction_enu_etendu_et_quelconque();
|
|
|
|
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
void Construction_index_conteneurs_evoluees();
|
|
|
|
// Passage des infos variables évoluées en tableau de réels
|
|
// I/O : d
|
|
Tableau <double > & 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 = NULL
|
|
,const Tableau <int> * t_num_ordre = NULL);
|
|
// idem, mais via les listes
|
|
// val_ddl_enum(k) correspond à li_evolue_scalaire de rang i
|
|
Tableau <double > & 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 = NULL
|
|
,const Tableau <int> * t_num_ordre = NULL);
|
|
|
|
// 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 Mise_a_jour_variables_globales_interne();
|
|
|
|
// 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
|
|
// ****** fonction a priori dangereuse, à éviter , pour l'instant ne sert pas !! ****
|
|
double Val_avec_nbArgVariable(double x,...);
|
|
|
|
// 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& Transfert_info(const Fonction_nD& elt);
|
|
|
|
// affichage des données internes, utilisée par les fonctions dérivées
|
|
// niveau donne le degré d'affichage
|
|
void Affiche_interne(int niveau) const;
|
|
|
|
//------ 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 Lect_base_info(ifstream& ent,const int cas);
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void Ecrit_base_info(ofstream& sort,const int cas);
|
|
// sortie du schemaXML: en fonction de enu
|
|
void SchemXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
|
|
|
|
// lecture d'une ou plusieurs variables
|
|
// peut-être appelée plusieurs fois,
|
|
// stockage des infos dans Fonction_nD
|
|
void Lecture_variables(string& nom_lu,UtilLecture * entreePrinc);
|
|
// méthode pour savoir si le nom_lu est un mot clé relatif à la lecture de variables
|
|
bool Est_relatif_a_lecture_variable(string& nom_lu)
|
|
{if ( (nom_lu == "un_argument=")
|
|
|| (nom_lu == "deb_list_var_")
|
|
)
|
|
return true;
|
|
else return false;
|
|
};
|
|
|
|
// affichage des variables de la fonction, dépend du niveau d'impression
|
|
void Affichage_variables() const;
|
|
|
|
// récupération des valeurs des variables globales et stockage dans le tableau
|
|
// interne x_glob
|
|
void Recup_Grandeurs_globales();
|
|
|
|
private :
|
|
|
|
// un tableau intermédiaire, en général vide, mais qui sert si on utilise
|
|
// la méthode Val_avec_nbArgVariable
|
|
Tableau <double >* xinter=NULL;
|
|
|
|
|
|
};
|
|
/// @} // end of group
|
|
|
|
#endif
|