// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

#include "F_nD_courbe1D.h"
#include "Sortie.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include "CharUtil.h"
#include "MotCle.h"
#include "TypeQuelconqueParticulier.h"


    // CONSTRUCTEURS :
F_nD_courbe1D::F_nD_courbe1D(string nom) :
 Fonction_nD(nom,FONCTION_COURBE1D)
 ,c_Fi(NULL),nom_courbe1(""),tab_ret(1)

  {};

    // de copie
F_nD_courbe1D::F_nD_courbe1D(const F_nD_courbe1D& Co) :
 Fonction_nD(Co)
  ,c_Fi(Co.c_Fi),nom_courbe1(Co.nom_courbe1),tab_ret(1)
  { // création de la courbe locale que si elle est déjà locale
    if (Co.c_Fi->NomCourbe() == "_")
       c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi));
  };
    
    // de copie à partir d'une instance générale
F_nD_courbe1D::F_nD_courbe1D(const Fonction_nD& Coo) :
 Fonction_nD(Coo),tab_ret(1)
  { if (Coo.Type_Fonction() != FONCTION_COURBE1D)
      { cout << "\n erreur dans le constructeur de copie pour une  F_nD_courbe1D "
             << " a partir d'une instance generale ";
        cout << "\n F_nD_courbe1D::F_nD_courbe1D(const Fonction_nD& Co) ";
        Sortie(1);
      };
    // définition des données
    F_nD_courbe1D & Co = (F_nD_courbe1D&) Coo;
    nom_courbe1 = Co.nom_courbe1;
    c_Fi = Co.c_Fi;
    // création de la courbe locale que si elle est déjà locale
    if (Co.c_Fi->NomCourbe() == "_")
       c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi));
  };

    // DESTRUCTEUR :
F_nD_courbe1D::~F_nD_courbe1D()
  { // on efface la courbe que si c'est une courbe locale
    if ((c_Fi != NULL)&&(nom_courbe1=="i_interne_i"))
       delete c_Fi;
  };
    
    // METHODES PUBLIQUES :
    
    // --------- virtuelles ---------

// Surcharge de l'operateur = : realise l'egalite de deux fonctions
Fonction_nD& F_nD_courbe1D::operator= (const Fonction_nD& elt)
{ // la suite ne peut fonctionner que s'il s'agit d'une fonction de même type
  if (typeFonction != elt.Type_Fonction())
   {cout << "\n *** erreur d'affectation entre fonction nD "
         << nom_ref << " et " << elt.NomFonction()
         << "\n F_nD_courbe1D::operator= (..."
         << endl;
    Sortie(1);
   };
  // on commence par appeler la méthode ad hoc pour la fonction Fonction_nD
  Fonction_nD::Transfert_info(elt);
  // puis on s'occupe des variables de la fonction
  const F_nD_courbe1D & Co = ((F_nD_courbe1D &) elt);
 
  nom_courbe1 = Co.nom_courbe1;
  c_Fi = Co.c_Fi;
  // création de la courbe locale que si elle est déjà locale
  if (Co.c_Fi->NomCourbe() == "_")
     c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi));
  tab_ret = Co.tab_ret;
  return *this;
};

    // affichage de la courbe
void F_nD_courbe1D::Affiche(int niveau) const
  { cout << "\n fonction composee a partir d'une courbe 1D: F_nD_courbe1D : nom_ref= " << nom_ref;
    // si c'est une courbe interne on l'affiche globalement
    // si c'est une courbe globale, on n'affiche que son nom
    cout << ", courbe de base: " ;
    if (c_Fi->NomCourbe() == "_")  {c_Fi->Affiche();}
    else  {cout << c_Fi->NomCourbe() << " ";};
    // affichage de la variable
    cout << "\n  argument= " ;
    if (nom_variables.Taille() == 1)
       cout << nom_variables(1) << " ";
    else if (enu_variables_globale.Taille() == 1)
       cout << Nom_GrandeurGlobale(enu_variables_globale(1)) << " ";
    else if (nom_variables_globales.Taille() == 1)
       cout << nom_variables_globales(1) << " ";
    else cout << " pas_de_variable_declare!! ";
    // appel de la méthode associée de la classe virtuelle
    Affiche_interne(niveau);
    if (niveau > 0)
     { cout << "\n dernieres valeurs de retour de la fonction: ";
       cout << tab_ret ;
     };
    cout << "\n ----- fin fonction F_nD_courbe1D ----- ";
   };

    // vérification que tout est ok, pres à l'emploi
    // ramène true si ok, false sinon
bool F_nD_courbe1D::Complet_Fonction(bool affichage)const
 { bool ret = false;
   // il faut au moins que la courbe existe
   if (c_Fi == NULL)
     {if (affichage && (ParaGlob::NiveauImpression() >0))
      { cout << "\n ***** la fonction n'est pas complete (aucune courbe de base n'existe) ";
        this->Affiche();
      }
     }
   else // on regarde du coté de la classe mère tout d'abord
    { ret = Complet_var();
      // puis la courbe interne
      ret = ret && c_Fi->Complet_courbe();
      if (!ret && (ParaGlob::NiveauImpression() >0) && affichage )
        { cout << "\n ***** la fonction n'est pas complete  ";
          this->Affiche();
        };
    };
   // retour
   return ret;
 };

   // Lecture des donnees de la classe sur fichier
    // le nom passé en paramètre est le nom de la courbe
    // s'il est vide c-a-d = "", la methode commence par lire le nom sinon
    // ce nom remplace le nom actuel
void F_nD_courbe1D::LectDonnParticulieres_Fonction_nD(const string& nom,UtilLecture * entreePrinc)
  { // entête de la fonction
    if (nom == "")  { *(entreePrinc->entree) >> nom_ref;}
    else {nom_ref=nom;};
    // lecture de la  courbe interne
    entreePrinc->NouvelleDonnee();  // lecture d'une nouvelle ligne

    // on lit tant que l'on ne rencontre pas la ligne contenant "fin_fonction_courbe1D_"
    // ou un nouveau mot clé global auquel cas il y a pb !!
    MotCle motCle; // ref aux mots cle
    string titi; bool lecture_variable_ok = false; // pour gérer une erreur éventuelle
    while (strstr(entreePrinc->tablcar,"fin_fonction_courbe1D_")==0)
     {
      // 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 F_nD_courbe1D : on n'a pas trouve le mot cle "
              << " fin_fonction_courbe1D_ et par contre la ligne courante contient un mot cle global  ";
         entreePrinc->MessageBuffer("** erreur des parametres d'une F_nD_courbe1D **");
         throw (UtilLecture::ErrNouvelleDonnee(-1));
         Sortie(1);     
       };
    
      // lecture d'un mot clé
      *(entreePrinc->entree) >> titi;
      
      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) >>titi;
               }
      #else
      else  if ((entreePrinc->entree)->eof())
               // la lecture est bonne mais on a atteind la fin de la ligne
               { if(titi != "fin_fonction_courbe1D_")
                   // on lit sans tenir compte des < éventuelles
                   {entreePrinc->NouvelleDonneeSansInf();
                    *(entreePrinc->entree) >> titi;
                   };
               } 
      #endif
      else // cas d'une erreur de lecture
       { cout << "\n erreur de lecture inconnue fonction:  "<< nom_ref;
         entreePrinc->MessageBuffer("** erreur2 des parametres d'une F_nD_courbe1D **");
         throw (UtilLecture::ErrNouvelleDonnee(-1));
         Sortie(1);     
       };
      
      // on traite en fonction du mot clé
      if (titi == "courbe=")
       { string nom_lu;
           *(entreePrinc->entree)  >> nom_lu;
           // on regarde si la courbe existe, si oui on récupère la référence
           if (Type_EnumCourbe1D_existe(nom_lu))
             // cas ou c'est un nom de type de courbe -> lecture directe
             { nom_courbe1 = "_"; // on signale que c'est une courbe interne
               c_Fi = Courbe1D::New_Courbe1D(nom_courbe1,Id_Nom_Courbe1D (nom_lu.c_str()));
               // lecture de la courbe
               c_Fi->LectDonnParticulieres_courbes (nom_courbe1,entreePrinc);
               nom_courbe1="i_interne_i";
              } 
           else
             // sinon on retiend le nom pour une complétion future   
             {nom_courbe1 = nom_lu;};
         }
      // cas de la lecture d'une variable
      else if(titi == "un_argument=")
       {if (lecture_variable_ok) // on n'a le droit qu'à 1 argument
         { cout << "\n erreur en lecture l'argument  est deja defini !! c'est ";
           if (nom_variables.Taille() == 1) cout <<nom_variables(1) << " ";
           else if (nom_variables_globales.Taille() == 1) cout << nom_variables_globales(1) << " ";
           else cout << Nom_GrandeurGlobale(enu_variables_globale(1)) << " ";
           entreePrinc->MessageBuffer("**erreur1 F_nD_courbe1D::LectureDonneesParticulieres**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);          
         };
        string truc; *(entreePrinc->entree) >> truc;
        // on regarde s'il s'agit d'une variable globale
        if (EstUneGrandeurGlobale(truc))
         {enu_variables_globale.Change_taille(1);
          enu_variables_globale(1) = (Id_nom_GrandeurGlobale (truc));
          nom_variables.Change_taille(0);
         }
        // idem mais sous forme d'un string
        else if (ParaGlob::param->GrandeurGlobal(truc) != NULL)
         {nom_variables_globales.Change_taille(1);
          nom_variables_globales(1) = truc;
          nom_variables.Change_taille(0);
         }
        else // sinon ce n'est pas une grandeur globale
         {nom_variables.Change_taille(1);
          nom_variables(1)=truc;
          enu_variables_globale.Change_taille(0);
          nom_variables_globales.Change_taille(0);
         };
        lecture_variable_ok = true;
       }
      // cas de la lecture du niveau d'impression pour les erreurs
      else if(titi == "permet_affichage_")
         {*(entreePrinc->entree) >> permet_affichage;
         }
      else // sinon la lecture est ok a priori
          ;
      
     }; //-- fin du while
       
    // on définit le paramètre depend_M de la classe maître en fonction des nom_variables
    Fonction_nD::Definition_depend_M();
    // idem pour le temps
    Fonction_nD::Definition_depend_temps();
    // idem pour la cohérence avec les enu
//    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();

   };
 
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
// globales en cours de calcul
void F_nD_courbe1D::Mise_a_jour_variables_globales()
 { // appel de la fonction interne pour modifier les noms de variables
   Fonction_nD::Mise_a_jour_variables_globales_interne();
   // comme ici il n'y a qu'une variable possible, normalement l'appel de fonction ne change pas
   // donc c'est ok
 };

// 1) renseigne si la courbe dépend d'autre courbe ou non
bool F_nD_courbe1D::DependAutreFoncCourbes() const
 { bool ret=false;
   if(c_Fi == NULL) {ret=true;}
   else if (nom_courbe1 != "i_interne_i") {ret=true;};
   return ret;
 };
  
// 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this
list <string>& F_nD_courbe1D::ListDependanceCourbes(list <string>& lico) const
 { // tout d'abord on vide la liste passée en paramètres
   if (lico.size() != 0)
      lico.clear();
   // on remplit en fonction de l'état
   if(c_Fi == NULL)  lico.push_back(nom_courbe1);
   return lico;
  };
   
// 4) établit la connection entre la demande de *this et les courbes et fonctions passées en paramètres
void F_nD_courbe1D::Lien_entre_fonc_courbe (list <Fonction_nD *>&  ,list <Courbe1D *>&  liptco)
 { Courbe1D* cc_Fi=NULL;
   list <Courbe1D *>::iterator ili,ilifin=liptco.end();
   if (c_Fi==NULL)
    { // on cherche la courbe correspondante
//      for (Courbe1D * ic : liptco)
//        if (ic->NomCourbe() == nom_courbe1) {cc_Fi=ic;break;};
      {list <Courbe1D *>::iterator kk,kkfin=liptco.end();
       for (kk=liptco.begin();kk != kkfin; kk++)
         if ((*kk)->NomCourbe() == nom_courbe1) {cc_Fi=(*kk);break;};
      };
     
     };
   // et on définit les courbes
   this->DefFoncCourbeMembre(cc_Fi);
  };

// def info fichier de commande
void F_nD_courbe1D::Info_commande_Fonctions_nD(UtilLecture & entreePrinc)
  {  
     ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
     sort << "\n#............................................"
          << "\n#   il s'agit d'une fonction qui utilise une courbe 1D "
          << "\n#   cette derniere peut soit deja exister, soit etre definie a la suite "
          << "\n#   exemple 1: cas d'une courbe qui existe deja sous le nom: cf1"
          << "\n    fct1_exemple    FONCTION_COURBE1D  "
          << "\n       courbe= cf1 "
          << "\n       un_argument= x "
          << "\n     fin_fonction_courbe1D_"
          << "\n#   "
          << "\n#   exemple 2: cas d'une courbe qui est definit a la suite"
          << "\n    fct2_exemple    FONCTION_COURBE1D  "
          << "\n       un_argument= x "
          << "\n       courbe= COURBE_EXPRESSION_LITTERALE_1D "
          << "\n          a= 0. b= 1. f(x)= (x^2+3.)/cos(x)+log((1.+x)/(1.+x^3))*23.-8.  "
          << "\n        fin_parametres_courbe_expression_litterale_  "
          << "\n     fin_fonction_courbe1D_"
          << "\n#       "
          << "\n#  NB: niveau d'impression: dans certain cas il peut-etre utile d'afficher    "
          << "\n#   les resultats intermediaires des calculs et egalement des erreurs intermediaires    "
          << "\n#   pour mettre en route ce fonctionnement il faut indiquer sur une ligne seule le mot cle     "
          << "\n#   permet_affichage_ suivi d'un chiffre donnant le niveau d'impression (entre 0 et 10)    "
          << "\n# ex: permet_affichage_ 5  "
          << "\n#   Remarques: 1) ceci ne fonction qu'avec la version non fast    "
          << "\n#      cependant, la lecture reste correcte avec le mot cle permet_affichage_ "
          << "\n#     mais la presence du mot cle n'entraine aucune action en fast  "
          << "\n#   2) le mot cle doit etre indique avant le dernier mot cle :     "
          << "\n#   fin_fonction_courbe1D_  "
          << "\n#   "
          << endl;
   };

// calcul  des valeurs de la fonction, retour d'un tableau de scalaires
Tableau <double> & F_nD_courbe1D::Valeur_FnD_interne(Tableau <double >* xi)
 {
  try
  {// comme il s'agit d'une courbe 1D, on n'utilise que le premier élément des tableaux
   // deux cas selon que l'on utilise une variable globale ou locale
   if (nom_variables.Taille() == 1) // pas de variable globale
    {if(xi!=NULL)
      {tab_ret(1) = c_Fi->Valeur((*xi)(1));}
//     else if (tab_coor != NULL) // sinon il ne reste plus que tab_coor
//      {tab_ret(1) = c_Fi->Valeur((*tab_coor)(1)(1));}
     else // sinon c'est une erreur
      { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
             << " pas de variable en entree !!  "
             << ", n'est pas disponible, on ne peut pas continuer  "
             << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<<endl;
        // on génère une interruption ce qui permettra de dépiler les appels
        this->Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1);
        Sortie(1);
      };
    }
   else if (enu_variables_globale.Taille() == 1) // il s'agit d'une variable globale enumere
    {
      // on récupère les grandeurs globales
      Fonction_nD::Recup_Grandeurs_globales();
      // on affecte les grandeurs
      tab_ret(1) = c_Fi->Valeur(x_glob(1));
    
/*
    // en debug on vérifie que les grandeurs globales sont présentent
      #ifdef MISE_AU_POINT
      try
       { // on récupère le pointeur correspondant à la grandeur
         const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
         if (pointe == NULL)
           { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
                  << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
                  << ", n'est pas disponible, on ne peut pas continuer  "
                  << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<<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(...)
       { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
         cout << " verifier la presence de la grandeur globale voulue "
              << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<<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
      // arrivée ici toutes la grandeur existe
      
      double x=0.;
      // on récupère le pointeur correspondant à la grandeur
      const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
      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 = *(gr.ConteneurEntier());
                      break;
                     }
                   case PARTICULIER_SCALAIRE_DOUBLE:
                     {Grandeur_scalaire_double& gr
                           = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      x = *(gr.ConteneurDouble());
                      break;
                     }
                    case PARTICULIER_DDL_ETENDU:
                      {Grandeur_Ddl_etendu& gr
                         = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
                       x = (gr.GrandeurNumOrdre(1));
                       break;
                      }
                    default:
                     { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
                            << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
                            << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                            << "\n F_nD_courbe1D::Valeur_FnD_interne(..."
                            <<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(1))
                      << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                      << "\n F_nD_courbe1D::Valeur_FnD_interne(..."
                      <<endl;
                 // on génère une interruption ce qui permettra de dépiler les appels
                 this->Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1);
               };
           };
      tab_ret(1) = c_Fi->Valeur(x);
*/
    }
   else  // il s'agit d'une variable globale en string
    { // en debug on vérifie que les grandeurs globales sont présentent
      #ifdef MISE_AU_POINT
      try
       { // on récupère le pointeur correspondant à la grandeur
         const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
         if (pointe == NULL)
           { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
                  << " la variable globale  "<< nom_variables_globales(1)
                  << ", n'est pas disponible, on ne peut pas continuer  "
                  << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<<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 de la grandeur globale voulue "
              << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<<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
      // arrivée ici toutes la grandeur existe
      
      double x=0.;
      // on récupère le pointeur correspondant à la grandeur
      const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
      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 = *(gr.ConteneurEntier());
                      break;
                     }
                   case PARTICULIER_SCALAIRE_DOUBLE:
                     {Grandeur_scalaire_double& gr
                           = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      x = *(gr.ConteneurDouble());
                      break;
                     }
                   case PARTICULIER_DDL_ETENDU:
                     {Grandeur_Ddl_etendu& gr
                           = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      x = (gr.GrandeurNumOrdre(1));
                      break;
                     }
                   case PARTICULIER_VECTEUR_NOMMER:
                     {Grandeur_Vecteur_Nommer& gr
                           = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      x = (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(1)
                                << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
                                << " compte pour l'intant, on ne peut pas continuer  "
                                << "\n F_nD_courbe1D::Valeur_FnD_interne(..."
                                <<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(1)
                            << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                            << "\n F_nD_courbe1D::Valeur_FnD_interne(..."
                            <<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(1)
                      << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                      << "\n F_nD_courbe1D::Valeur_FnD_interne(..."
                      <<endl;
                 // on génère une interruption ce qui permettra de dépiler les appels
                 this->Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1);
               };
           };
      tab_ret(1) = c_Fi->Valeur(x);
     };
    }
   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;
       this->Affiche();
       cout << "\n F_nD_courbe1D::Valeur_FnD_interne(...";
       // on génère une interruption ce qui permettra de dépiler les appels
       this->Affiche();ErrCalculFct_nD toto;throw (toto);
       Sortie(1);
     };
   // retour
   return tab_ret;
 };
 
//// 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> & F_nD_courbe1D::Valeur_FnD(Tableau <Ddl_etendu> * t_enu,Tableau <TypeQuelconque >* tqi)
// { // comme il s'agit d'une courbe 1D, on n'utilise que le premier élément des tableaux
//   // deux cas selon que l'on utilise une variable globale ou locale
//   if (nom_variables.Taille() == 1) // pas de variable globale
//    {if(t_enu!=NULL)
//      {
//       #ifdef MISE_AU_POINT
//       if ((*t_enu)(1).DdlEnumEtendu() != tab_enu_etendu(1))
//       { cout << "\n *** pb dans F_nD_courbe1D au niveau des parametres d'appel "
//              << " on demande un calcul pour le ddl "<< (*t_enu)(1).DdlEnumEtendu().Nom_plein()
//               << " ce qui est different du ddl prevu:  "<<tab_enu_etendu(1).Nom_plein()
//              << " ce n'est pas normal !!  "
//              << ",  il vaut mieux stopper le calcul   "
//              << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//         Sortie(1);
//       };
//       #endif
//       tab_ret(1) = c_Fi->Valeur((*t_enu)(1).Valeur());
//      }
//     else if (tqi != NULL) // sinon il ne reste plus que tab_coor
//      {
//       #ifdef MISE_AU_POINT
//       if ((*tqi)(1).EnuTypeQuelconque() != tab_enu_quelconque(1))
//       { cout << "\n *** pb dans F_nD_courbe1D au niveau des parametres d'appel "
//              << " on demande un calcul pour la grandeur quelconque "
//              << (*tqi)(1).EnuTypeQuelconque().NomPlein()
//              << " ce qui est different du type prevu:  "
//              << NomTypeQuelconque(tab_enu_quelconque(1))
//              << " ce n'est pas normal !!  "
//              << ",  il vaut mieux stopper le calcul   "
//              << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//         Sortie(1);
//       };
//       #endif
//       tab_ret(1) = c_Fi->Valeur((*tqi)(1).GrandeurNumOrdre(1));
//      }
//     else // sinon c'est une erreur
//      { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
//             << " pas de variable en entree !!  "
//             << ", n'est pas disponible, on ne peut pas continuer  "
//             << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//        Sortie(1);
//      };
//    }
//   else if (enu_variables_globale.Taille() == 1) // il s'agit d'une variable globale enumere
//    { // en debug on vérifie que les grandeurs globales sont présentent
//      #ifdef MISE_AU_POINT
//      try
//       { // on récupère le pointeur correspondant à la grandeur
//         const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
//         if (pointe == NULL)
//           { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
//                  << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
//                  << ", n'est pas disponible, on ne peut pas continuer  "
//                  << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//             Sortie(1);
//           };
//       }
//      catch(...)
//       { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
//         cout << " verifier la presence de la grandeur globale voulue "
//              << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//         Sortie(1);
//       };
//      #endif
//      // arrivée ici toutes la grandeur existe
//
//      double x=0.;
//      // on récupère le pointeur correspondant à la grandeur
//      const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
//      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 = *(gr.ConteneurEntier());
//                      break;
//                     }
//                   case PARTICULIER_SCALAIRE_DOUBLE:
//                     {Grandeur_scalaire_double& gr
//                           = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
//                      x = *(gr.ConteneurDouble());
//                      break;
//                     }
//                   default:
//                     { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
//                            << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
//                            << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
//                            << "\n F_nD_courbe1D::Valeur_FnD(..."
//                            <<endl;
//                       Sortie(1);
//                     };
//                  }
//
//                break;
//               }
//             default:
//               { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
//                      << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
//                      << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
//                      << "\n F_nD_courbe1D::Valeur_FnD(..."
//                      <<endl;
//                 Sortie(1);
//               };
//           };
//      tab_ret(1) = c_Fi->Valeur(x);
//    }
//   else  // il s'agit d'une variable globale en string
//    { // en debug on vérifie que les grandeurs globales sont présentent
//      #ifdef MISE_AU_POINT
//      try
//       { // on récupère le pointeur correspondant à la grandeur
//         const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
//         if (pointe == NULL)
//           { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
//                  << " la variable globale  "<< nom_variables_globales(1)
//                  << ", n'est pas disponible, on ne peut pas continuer  "
//                  << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//             Sortie(1);
//           };
//       }
//      catch(...)
//       { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
//         cout << " verifier la presence de la grandeur globale voulue "
//              << "\n F_nD_courbe1D::Valeur_FnD(..."<<endl;
//         Sortie(1);
//       };
//      #endif
//      // arrivée ici toutes la grandeur existe
//
//      double x=0.;
//      // on récupère le pointeur correspondant à la grandeur
//      const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
//      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 = *(gr.ConteneurEntier());
//                      break;
//                     }
//                   case PARTICULIER_SCALAIRE_DOUBLE:
//                     {Grandeur_scalaire_double& gr
//                           = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
//                      x = *(gr.ConteneurDouble());
//                      break;
//                     }
//                   case PARTICULIER_DDL_ETENDU:
//                     {Grandeur_Ddl_etendu& gr
//                           = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
//                      x = (gr.GrandeurNumOrdre(1));
//                      break;
//                     }
//                   case PARTICULIER_VECTEUR_NOMMER:
//                     {Grandeur_Vecteur_Nommer& gr
//                           = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
//                      x = (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(1)
//                                << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
//                                << " compte pour l'intant, on ne peut pas continuer  "
//                            << "\n F_nD_courbe1D::Valeur_FnD(..."
//                                <<endl;
//                           Sortie(1);
//                         };
//                      #endif
//                      break;
//                     }
//                   default:
//                     { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
//                            << " la variable globale  "<< nom_variables_globales(1)
//                            << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
//                            << "\n F_nD_courbe1D::Valeur_FnD(..."
//                            <<endl;
//                       Sortie(1);
//                     };
//                  }
//
//                break;
//               }
//             default:
//               { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
//                      << " la variable globale  "<< nom_variables_globales(1)
//                      << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
//                      << "\n F_nD_courbe1D::Valeur_FnD(..."
//                      <<endl;
//                 Sortie(1);
//               };
//           };
//      tab_ret(1) = c_Fi->Valeur(x);
//    };
//   // retour
//   return tab_ret;
// };

 
// calcul des valeurs de la fonction, dans le cas où les variables
// sont toutes des grandeurs globales: pour l'instant que pour des variables scalaires
Tableau <double> & F_nD_courbe1D::Valeur_pour_variables_globales_interne()
  {
  
/*    // en debug on vérifie que les grandeurs globales sont présentent
    #ifdef MISE_AU_POINT
    try
     { // on vérifie tout d'abord que toutes les variables sont globales
       if (nom_variables.Taille() != 0)
        { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
          cout << " toutes les variables ne sont pas globales !!  "
               << "\n F_nD_courbe1D::Valeur_pour_variables_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);
        };
       // on récupère le pointeur correspondant à la grandeur
       if (enu_variables_globale.Taille())
        {const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
         if (pointe == NULL)
          { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
                 << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
                 << ", n'est pas disponible, on ne peut pas continuer  "
                 << "\n F_nD_courbe1D::Valeur_pour_variables_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(...)
     { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
       cout << " verifier la presence des grandeurs globales voulues "
            << "\n F_nD_courbe1D::Valeur_pour_variables_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
    // idem pour les grandeurs indicées avec des string
    #ifdef MISE_AU_POINT
    try
     { // on récupère le pointeur correspondant à la grandeur
       if (nom_variables_globales.Taille())
        {const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
         if (pointe == NULL)
           { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! "
                  << " la variable globale  "<< nom_variables_globales(1)
                  << ", n'est pas disponible, on ne peut pas continuer  "
                  << "\n F_nD_courbe1D::Valeur_pour_variables_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(...)
     { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref;
       cout << " verifier la presence des grandeurs globales voulues "
            << "\n F_nD_courbe1D::Valeur_pour_variables_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
*/
    // arrivée ici toutes les grandeurs existent (normalement on n'utilise que la première !!)
    try
     {
     
/*      double argument = 0.; // init par défaut
      if (enu_variables_globale.Taille() == 1)
       { // cas d'une variable énuméré
         // on utilise les variables globales
         // on récupère le pointeur correspondant à la grandeur
         const void* pointe =  (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1)));
         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
                       argument = *(gr.ConteneurEntier());
                       break;
                      }
                    case PARTICULIER_SCALAIRE_DOUBLE:
                      {Grandeur_scalaire_double& gr
                            = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
                       argument = *(gr.ConteneurDouble());
                       break;
                      }
                    case PARTICULIER_DDL_ETENDU:
                      {Grandeur_Ddl_etendu& gr
                         = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
                       argument = (gr.GrandeurNumOrdre(1));
                       break;
                      }
                    default:
                      { cout << "\n *** pb dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! "
                             << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
                             << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                             << "\n F_nD_courbe1D::Valeur_pour_variables_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 dans F_nD_courbe1D " << nom_ref << " !! "
                       << " la variable globale  "<< Nom_GrandeurGlobale(enu_variables_globale(1))
                       << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                       << "\n F_nD_courbe1D::Valeur_pour_variables_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);
                };
          };
       }
      else // sinon il s'agit d'une grandeur indicée par un string
       { // on récupère le pointeur correspondant à la grandeur
         const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1)));
         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
                       argument = *(gr.ConteneurEntier());
                       break;
                      }
                    case PARTICULIER_SCALAIRE_DOUBLE:
                      {Grandeur_scalaire_double& gr
                            = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
                       argument = *(gr.ConteneurDouble());
                       break;
                      }
                   case PARTICULIER_DDL_ETENDU:
                     {Grandeur_Ddl_etendu& gr
                           = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      argument = (gr.GrandeurNumOrdre(1));
                      break;
                     }
                   case PARTICULIER_VECTEUR_NOMMER:
                     {Grandeur_Vecteur_Nommer& gr
                           = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
                      argument = (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(1)
                                << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
                                << " compte pour l'intant, on ne peut pas continuer  "
                                << "\n F_nD_courbe1D::Valeur_pour_variables_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 dans F_nD_courbe1D " << nom_ref << " !! "
                             << " la variable globale  "<< nom_variables_globales(1)
                             << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                             << "\n F_nD_courbe1D::Valeur_pour_variables_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 dans F_nD_courbe1D " << nom_ref << " !! "
                       << " la variable globale  "<< nom_variables_globales(1)
                       << ", n'est pas prise en compte actuellement , on ne peut pas continuer  "
                       << "\n F_nD_courbe1D::Valeur_pour_variables_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);
                };
          };
       };
*/
      // on récupère les grandeurs globales
      Fonction_nD::Recup_Grandeurs_globales();
      // on affecte les grandeurs
      int taille = x_glob.Taille();
      // maintenant on appelle la fonction
      tab_ret(1) = c_Fi->Valeur(x_glob(1));
////---- debug
//cout << "\n argument= "<<argument<<" f(x)= "<<tab_ret(1)<<endl;
//// ---- fin debug
     }
    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 non determinee dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! "
             << "\n F_nD_courbe1D::Valeur_pour_variables_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);
      };
    return tab_ret;
  };


	//----- 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)
void F_nD_courbe1D::Lecture_base_info(ifstream& ent,const int cas)
 {  // on n'a que des grandeurs constantes
    if (cas == 1)
      { string nom;
        // lecture et vérification de l'entête
        string type_courbe_a_lire('<'+Nom_Fonction_nD(this->Type_Fonction())+'>');
        if (nom != type_courbe_a_lire) //"F_nD_courbe1D")
         { cout << "\n erreur dans la verification du type de courbe lue ";
           cout << "\n courbe en lecture: " << type_courbe_a_lire;    
           cout << "\n F_nD_courbe1D::Lecture_base_info(... ";
           Sortie(1); 
         };
        // lecture des infos
        string nom1,nom2,nom3;
        // pour la courbe1
        ent >> nom1 >> nom2 >> nom3;
        if (nom1 != "courbe1=")
         { cout << "\n erreur dans la verification du type, on attendait le mot cle courbe1= "
                << " et on a lu " << nom1 << " ";
           cout << "\n F_nD_courbe1D::Lecture_base_info(... ";
           Sortie(1); 
           }
        else
         { if (nom2 == "COURBE_1D_INTERNE1")
            {// cas d'une courbe en interne
             // 1) on commence par effacer la courbe existante si nécessaire
             if (c_Fi != NULL) {if (c_Fi->NomCourbe() == "_") delete c_Fi;};
             // 2) on crée la courbe adoc
             nom2="_";
             c_Fi = Courbe1D::New_Courbe1D(nom2,Id_Nom_Courbe1D (nom3.c_str()));
             // 3) on lit les données particulières
             c_Fi->Lecture_base_info(ent,cas);
             nom_courbe1="i_interne_i";
             }
           else
            {// cas d'une courbe externe on lit le nom
             nom_courbe1 = nom2; 
            };
         };
        // lecture de la variable
        int choix=0;
        ent >> nom >> choix;
        switch (choix)
          {case 1: nom_variables.Change_taille(1); ent >> nom_variables(1);
            enu_variables_globale.Change_taille(0);nom_variables_globales.Change_taille(0);
            break;
           case 2: enu_variables_globale.Change_taille(1); ent >> nom;
            enu_variables_globale(1) = Id_nom_GrandeurGlobale(nom);
            nom_variables.Change_taille(0);nom_variables_globales.Change_taille(0);
            break;
           case 3: nom_variables_globales.Change_taille(1); ent >> nom_variables(1);
            enu_variables_globale.Change_taille(0);nom_variables.Change_taille(0);
           break;
           default: ent >> nom;
             cout << "\n *** attention aucun argument lu pour la fonction nD: FONCTION_COURBE1D ";
             this->Affiche();
           break;
          }
        // les arguments gérés par la classe mère
        Fonction_nD::Lect_base_info(ent,cas);

        // on lit le tag de fin de définition
        ent >> nom; //  </FONCTION_COURBE1D>
       
        // on définit le paramètre depend_M de la classe maître en fonction des nom_variables
        Fonction_nD::Definition_depend_M();
        // idem pour le temps
        Fonction_nD::Definition_depend_temps();
        // idem pour la cohérence avec les enu
//        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();
      };
 };

    // cas donne le niveau de sauvegarde
    // = 1 : on sauvegarde tout
    // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void F_nD_courbe1D::Ecriture_base_info(ofstream& sort,const int cas)
  { // on n'a que des grandeurs constantes
    if (cas == 1)
      { sort << "\n <FONCTION_COURBE1D>  ";
        if (nom_courbe1 == "i_interne_i")
         {// cas d'une courbe interne
          sort << "\n courbe1=  COURBE_1D_INTERNE1 " << c_Fi->Type_courbe();
          c_Fi->Ecriture_base_info(sort,cas);
          }
        else
          // cas d'une courbe externe
          {sort << "\n courbe1= " <<  c_Fi->NomCourbe() << " " << c_Fi->Type_courbe();;};
        // affichage de la variable
        sort << "  argument= " ;
        if (nom_variables.Taille() == 1)
           sort << " 1 " << nom_variables(1) << " ";
        else if (enu_variables_globale.Taille() == 1)
           sort << " 2 " << Nom_GrandeurGlobale(enu_variables_globale(1)) << " ";
        else if (nom_variables_globales.Taille() == 1)
           sort << " 3 " << nom_variables_globales(1) << " ";
        else sort << " 4 " <<  " pas_de_variable_declare!! ";
        // les arguments gérés par la classe mère
        Fonction_nD::Ecrit_base_info(sort,cas);

        sort << "\n </FONCTION_COURBE1D> \n ";
       };
   };

    // sortie du schemaXML: en fonction de enu 
void F_nD_courbe1D::SchemaXML_Fonctions_nD(ofstream& ,const Enum_IO_XML enu)
  {
	switch (enu)
	{ case XML_TYPE_GLOBAUX :
  	   {/*sort << "\n <!--  *************************** F_nD_courbe1D ***************************  -->"
  	         << "\n <!--  def d'un type contenant une valeur et un boolean  -->"
  	         << "\n    <xs:complexType name=\"valeurPlusBooleen\">"
  	         << "\n       <xs:simpleContent>"
  	         << "\n          <xs:extension base=\"xs:double\">" 
  	         << "\n              <xs:attribute name=\"present\" type=\"xs:boolean\"  />" 
  	         << "\n          </xs:extension>" 
  	         << "\n       </xs:simpleContent> "
  	         << "\n    </xs:complexType>"
  	         << "\n <!--  maintenant le type de la courbe  -->"
  	         << "\n<xs:complexType name=\"F_UNION_1D\" >"
  	         << "\n    <xs:annotation>"
  	         << "\n      <xs:documentation> courbe F_UNION_1D constituee de N points </xs:documentation>"
  	         << "\n    </xs:annotation>"
  	         << "\n    <xs:sequence>"
  	         << "\n        <xs:element  name=\"derivee_initiale_\"  type=\"valeurPlusBooleen\" />"
  	         << "\n        <xs:element  name=\"derivee_finale_\" type=\"valeurPlusBooleen\" />"
   	         << "\n        <xs:element  name=\"les_points\" type=\"COORDONNEE_2\"  minOccurs='0' maxOccurs=\"unbounded\" />"
  	         << "\n    </xs:sequence>"
  	         << "\n</xs:complexType>";*/
		 break;
		}
		case XML_IO_POINT_INFO :
		{
		 break;
		}
		case XML_IO_POINT_BI :
		{
		 break;
		}
		case XML_IO_ELEMENT_FINI :
		{
		 break;
		}
	};		
  };



  
 
// METHODES PROTEGEES :
// dans le cas où la courbe membre est une courbe externe
// méthode pour la définir
// la courbea est défini en interne que si la courbe argument est elle même
// une courbe locale. c'est-à-dire si c_Fi->NomCourbe() ="_" alors on recrée une courbe
// interne avec new pour c_Fi, sinon c_Fi=cc_Fi et pas de création;
// dans le cas où cc_Fi est NULL on passe, pas de traitement pour ce pointeur
void F_nD_courbe1D::DefFoncCourbeMembre(Courbe1D*  cc_Fi)
{ // création d'une courbe locale que si elle était déjà locales
  if (cc_Fi != NULL)
   {if (cc_Fi->NomCourbe() == "_") // cas où cc_Fi est une courbe non globale
      { if (c_Fi==NULL)
         { // cas où la courbe locale n'est pas défini mais on veut une courbe interne
           c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i";
          } 
        else if (c_Fi->NomCourbe() == "_")
          // cas où la courbe c_Fi est local et on veut la remplacer par une nouvelle locale
          { delete c_Fi;
            c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i";
           }
        else
          // cas où la courbe c_Fi est global et on veut la remplacer par une locale
          { c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i";
           };
       }
    else // cas ou cc_Fi est une courbe globale
      { if (c_Fi==NULL)
         { // cas où la courbe locale n'est pas définir
           c_Fi=cc_Fi;nom_courbe1="e_externe_e";
          } 
        else if (c_Fi->NomCourbe() == "_")
          // cas où la courbe c_Fi est local et on veut la remplacer par une globale
          { delete c_Fi;
            c_Fi=cc_Fi;nom_courbe1="e_externe_e";
           }
        else
          // cas où la courbe c_Fi est global et on veut la remplacer par une globale
          { c_Fi=cc_Fi;nom_courbe1="e_externe_e";
           };
       };
   };
};












