// 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 "Ponderation.h"

#include "CharUtil.h"

// ============ cas de la class Ponderation_temps ===============
Ponderation_Consultable::Ponderation_Consultable() : // le constructeur par défaut
     type_grandeur_Consultable(),c_proport(),tab_nom_fonction()
  {};
Ponderation_Consultable::Ponderation_Consultable(const Ponderation_Consultable& a) : // le constructeur de copie
			    c_proport(a.c_proport),type_grandeur_Consultable(a.type_grandeur_Consultable)
       ,tab_nom_fonction(a.tab_nom_fonction)
  {// cas des  courbes
   int taille = a.c_proport.Taille();
   for (int i=1;i<=taille;i++)
    {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
     if (c_proport(i) != NULL)
	     if (c_proport(i)->NomCourbe() == "_")
         {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi)
          string non_courbe("_");   
          c_proport(i) = Courbe1D::New_Courbe1D(*a.c_proport(i));
         };
    }
  };

Ponderation_Consultable::~Ponderation_Consultable () // destructeur
  {// cas des courbes
   int taille = c_proport.Taille();
   for (int i=1;i<=taille;i++)
    {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
     if (c_proport(i) != NULL)
       if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
    };
  };

// -------- affectation des fonctions à partir des noms sauvegardés
// intéressant quand cette affectation à lieu longtemps après la lecture
void Ponderation_Consultable::Affectation_fonctions(LesCourbes1D& lesCourbes1D)
 { // tout d'abord on regarde si ce n'est pas déjà effectué correctement
   int taille = tab_nom_fonction.Taille();
   // on réajuste les tailles si besoin est
   if (c_proport.Taille() > taille)
     // là il faut diminuer. Avant il faut supprimer les fonctions si nécessaire
     {for (int i=taille+1;i<= c_proport.Taille();i++)
        if (c_proport(i) != NULL)
          if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
     };
   // maintenant on peut changer la taille dans tous les cas
   c_proport.Change_taille(taille);
   // on boucle pour l'affectation
   for (int i=1;i<=taille;i++)
    { // premier cas: courbe déjà affectée
      if (c_proport(i) != NULL)
        // on regarde s'il s'agit de la même courbe
       {if (tab_nom_fonction(i) != c_proport(i)->NomCourbe())
          {// cas où c'est différent: on commence éventuellement par supprimer
           if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
           // puis on affecte
           if (lesCourbes1D.Existe(tab_nom_fonction(i)))
             { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));}
           else
             { cout << "\n **** erreur1 Ponderation_Consultable::Affectation_fonctions(..."
                    << "\n on ne trouve pas la courbe "<<tab_nom_fonction(i)
                    << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
               Sortie(1);
             };
          };
        // sinon les courbes sont déjà identique, on ne fait rien
       }
      else // pas d'affectation, on affecte donc
       {if (lesCourbes1D.Existe(tab_nom_fonction(i)))
          { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));}
        else
          { cout << "\n **** erreur2 Ponderation_Consultable::Affectation_fonctions(..."
                 << "\n on ne trouve pas la courbes "<<tab_nom_fonction(i)
                 << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
            Sortie(1);
          };
       };
    };
 };
     
//-- vérification que tout est ok pour le calcul ------
void Ponderation_Consultable::Verif_complet() const
{ // on vérifie que les tailles sont identiques
  if (type_grandeur_Consultable.Taille() != c_proport.Taille())
     { cout << "\n **** erreur1 Ponderation_Consultable::Verif_complet(..."
            << "\n le nombre de grandeur consultable "<<type_grandeur_Consultable.Taille()
            << " est different du nombre de courbes " << c_proport.Taille()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
  if (tab_nom_fonction.Taille() != c_proport.Taille())
     { cout << "\n **** erreur2 Ponderation_Consultable::Verif_complet(..."
            << "\n le nombre de noms de fonction "<<tab_nom_fonction.Taille()
            << " est different du nombre de courbes " << c_proport.Taille()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
  // on vérifie que les fonctions sont bien instanciées
  int taille = c_proport.Taille();
  for (int i=1;i<= taille;i++)
   {if (c_proport(i) == NULL)
     { cout << "\n **** erreur3 Ponderation_Consultable::Verif_complet(..."
            << "\n la fonction "<< i
            << " n'est pas definie on ne peut pas continuer " << endl;
       Sortie(1);
     };
   };
};

//----- 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 Ponderation_Consultable::Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> tab_nom_fonction;
     int taille = tab_nom_fonction.Taille();
     c_proport.Change_taille(taille); // ne change rien si la dimension est déjà bonne
     for (int i=1;i<=taille;i++)
      {ent >> nom;
       if (nom == "pointeur_null ")
        // cas où il n'y a rien à lire
        { if (c_proport != NULL)
           if (c_proport(i)->NomCourbe() == "_")
            delete c_proport(i);
        }
       else
        { c_proport(i) = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport(i));
        };
      };
   };
};

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ponderation_Consultable::Ecriture_base_info(ofstream& sort,const int cas)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  if (cas == 1)
   { sort << "\n Ponderation_Consultable " << tab_nom_fonction ;
     int taille = c_proport.Taille();
     for (int i=1;i<= taille;i++)
      {sort << type_grandeur_Consultable(i);
       if (c_proport(i) == NULL)
         { sort << "pointeur_null " ;}
       else
         { sort << "courbe= ";
           LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport(i));
         };
      };
   };
};

//============== fin de la classe Ponderation_Consultable ===============
// ============ cas de la class Ponderation_GGlobal ===============

// défaut
Ponderation_GGlobal::Ponderation_GGlobal() : // le constructeur par défaut
			    c_proport(NULL),nom_fonction("..")
  {};
Ponderation_GGlobal::Ponderation_GGlobal(const Ponderation_GGlobal& a) : // le constructeur de copie
			    c_proport(a.c_proport),nom_fonction(a.nom_fonction)
  {// cas de la fonction
   // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale
	  if (c_proport != NULL)
	   if (c_proport->NomFonction() == "_")
       {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
        string non_courbe("_");   
        c_proport = Fonction_nD::New_Fonction_nD(*a.c_proport);
       };
  };

     
// lecture sur le flot d'entrée
// on part du principe que les grandeurs transmises doivent faire partie des grandeurs
// gérées par la fonction nD, mais il peut y en avoir plus dans la fonction
// dans ce cas, on sort un warning
// NB: si aucune grandeur n'est passée en argument, on ne vérifie rien
// ce qui représente une lecture brut
void Ponderation_GGlobal::LecturePonderation(const List_io <string>& grandeurs
                      , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD)
{

  // lecture du nom de la loi d'évolution
  *(entreePrinc->entree) >>  nom_fonction;
 
  // premier cas: courbe déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même fonction
    {if (nom_fonction != c_proport->NomFonction())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomFonction() == "_") delete c_proport;
        // puis on affecte
        if (lesFonctionsnD.Existe(nom_fonction))
          { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
        else
          { // sinon il faut la lire maintenant
            string non_fonction("_");
            c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str()));
            // lecture de la fonction
            c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc);
          };
       };
     // sinon la fonction est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {
     // on regarde si la fonction existe, si oui on récupère la référence
     if (lesFonctionsnD.Existe(nom_fonction))
      { c_proport = lesFonctionsnD.Trouve(nom_fonction);
      }
     else
      { // sinon il faut la lire maintenant
        string non_fonction("_");
        c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str()));
        // lecture de la fonction
        c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc);
      };
    };
 
  // maintenant on s'intéresse aux grandeurs
  // on part du principe que les grandeurs transmises doivent faire partie des grandeurs
  // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction
  // dans ce cas, on sort un warning
  // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien
  // ce qui représente une lecture brut
  int nb_grandeurs_globales = grandeurs.size();
  if (nb_grandeurs_globales != 0)
    {// on vérifie tout d'abord que la fonction est utilisable
     if (c_proport->NbVariable_globale() < nb_grandeurs_globales )
      { cout << "\n erreur en lecture, la fonction nD " << nom_fonction
             << " utilise  " << c_proport->NbVariable_globale()
             << " variables alors qu'il en faut "
             << nb_grandeurs_globales << " elle n'est donc pas utilisable !! ";
        string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(...");
        entreePrinc->MessageBuffer(message);
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);
      };
     if (c_proport->NbVariable_locale() != 0 )
      { cout << "\n erreur en lecture, la fonction nD " << nom_fonction
             << " utilise  " << c_proport->NbVariable_locale()
             << " variables locales alors qu'elle ne doit utiliser que des variables globales "
             << " elle n'est donc pas utilisable !! ";
        string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(...");
        entreePrinc->MessageBuffer(message);
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);
      };
     if (c_proport->NbComposante() != 1 )
      { cout << "\n erreur en lecture, la fonction " << nom_fonction
             << " est une fonction vectorielle a   "
             << c_proport->NbComposante()
             << " composante alors qu'elle devrait etre scalaire ! "
             << " elle n'est donc pas utilisable !! ";
        string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(...");
        entreePrinc->MessageBuffer(message);
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);
      };
     
     // on vérifie que les grandeurs transmises font quand même partie des variables utilisées
     // par la fonction nD
     const Tableau <Enum_GrandeurGlobale >& enu_glob = c_proport->Enu_variables_globales();
     const Tableau <string >& nom_glob = c_proport->Nom_variables_globales();

     List_io <string>::const_iterator ili,ilifin=grandeurs.end();
     for (ili=grandeurs.begin();ili != ilifin; ili++)
        { if (!(nom_glob.Contient(*ili) || enu_glob.Contient(Id_nom_GrandeurGlobale(Minuscules(*ili)))))
            { cout << "\n erreur en lecture, la fonction " << nom_fonction
                   << " devrait contenir la grandeur globale  " << (*ili)
                   << " et ce n'est pas le cas !  "
                   << " elle n'est donc pas utilisable !! ";
              string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(...");
              entreePrinc->MessageBuffer(message);
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie(1);
            };
        }
    };

 
};

Ponderation_GGlobal::~Ponderation_GGlobal () // destructeur
  {// cas des courbes
   // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale
   if (c_proport != NULL)
       if (c_proport->NomFonction() == "_") delete c_proport;
  };

// -------- affectation de la fonction à partir du nom sauvegardé
// intéressant quand cette affectation à lieu longtemps après la lecture
//        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
//                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
//			     List_io <Enum_GrandeurGlobale>  type_grandeur_GGlob; // les arguments de la fonction
//        Tableau <double> tab_argument; //argument pour la fonction
//			     Fonction_nD* c_proport; // la fonction multidimentionnel
void Ponderation_GGlobal::Affectation_fonctions(LesFonctions_nD& lesFonctionsnD)
 { // tout d'abord on regarde si ce n'est pas déjà effectué correctement
   // premier cas: courbe déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même courbe
    {if (nom_fonction != c_proport->NomFonction())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomFonction() == "_") delete c_proport;
        // puis on affecte
        if (lesFonctionsnD.Existe(nom_fonction))
          { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
        else
          { cout << "\n **** erreur1 Ponderation_GGlobal::Affectation_fonctions(..."
                 << "\n on ne trouve pas la fonction " << nom_fonction
                 << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
            Sortie(1);
          };
       };
     // sinon la fonction est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {if (lesFonctionsnD.Existe(nom_fonction))
       { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
     else
       { cout << "\n **** erreur2 Ponderation_GGlobal::Affectation_fonctions(..."
              << "\n on ne trouve pas la courbes "<< nom_fonction
              << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
         Sortie(1);
       };
    };
 };

//-- vérification que tout est ok pour le calcul ------
void Ponderation_GGlobal::Verif_complet() const
{  // on vérifie que la fonction est bien instanciée
   if (c_proport == NULL)
     { cout << "\n **** erreur1 Ponderation_GGlobal::Verif_complet(..."
            << "\n la fonction "
            << " n'est pas definie on ne peut pas continuer " << endl;
       Sortie(1);
     };
 
};
     
// affichage
void Ponderation_GGlobal::Affiche()
 { cout << "\n Ponderation_GGlobal " << nom_fonction;
   if (c_proport == NULL)
    { cout << "pointeur_null " ;}
   else 
    { cout << "fonction ";
      c_proport->Affiche();
    };
 };

//----- 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 Ponderation_GGlobal::Lecture_base_info(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
     ent >> nom;
     if (nom == "pointeur_null ")
      // cas où il n'y a rien à lire
      { if (c_proport != NULL)
           if (c_proport->NomFonction() == "_")
              delete c_proport;
      }
     else 
      { c_proport = lesFonctionsnD.Lecture_pour_base_info(ent,cas,c_proport);
      };
   };
};

// idem mais sans définition de la courbe:
// correspond au cas de la sauvegarde avec san_courbe = true
void Ponderation_GGlobal::Lecture_base_info(ifstream& ent,const int cas)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
     ent >> nom;
   };
};

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
// sans_courbe: indique si on sauve oui ou non la courbe elle-même
// true: on sauve la courbe
// false : on sauve uniquement le nom de la courbe
void Ponderation_GGlobal::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  if (cas == 1)
   { sort << "\n Ponderation_GGlobal " << nom_fonction;
     if (!sans_courbe)
      {if (c_proport == NULL)
        { sort << "pointeur_null " ;}
       else 
        { sort << "fonction ";
          LesFonctions_nD::Ecriture_pour_base_info(sort,cas,c_proport);
        };
      };
   };
};

// sortie du schemaXML: en fonction de enu
void Ponderation_GGlobal::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu)
{
};

//============== fin de la classe Ponderation_GGlobal ===============




// ============ cas de la class Ponderation_TypeQuelconque ===============

// défaut
Ponderation_TypeQuelconque::Ponderation_TypeQuelconque() : // le constructeur par défaut
			    type_grandeur_Quelconque(),tab_argument(),c_proport(NULL),nom_fonction("..")
  {};
Ponderation_TypeQuelconque::Ponderation_TypeQuelconque(const Ponderation_TypeQuelconque& a) : // le constructeur de copie
			    type_grandeur_Quelconque(a.type_grandeur_Quelconque)
       ,tab_argument(a.tab_argument),c_proport(a.c_proport),nom_fonction(a.nom_fonction)
  {// cas de la fonction
   // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale
	  if (c_proport != NULL)
	   if (c_proport->NomFonction() == "_")
       {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
        string non_courbe("_");   
        c_proport = Fonction_nD::New_Fonction_nD(*a.c_proport);
       };
  };

Ponderation_TypeQuelconque::~Ponderation_TypeQuelconque () // destructeur
  {// cas des courbes
   // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale
   if (c_proport != NULL)
       if (c_proport->NomFonction() == "_") delete c_proport;
  };

// lecture sur le flot d'entrée
// on part du principe que les grandeurs transmises doivent faire partie des grandeurs
// gérées par la fonction nD, mais il peut y en avoir plus dans la fonction
// dans ce cas, on sort un warning
// NB: si aucune grandeur n'est passée en argument, on ne vérifie rien
// ce qui représente une lecture brut
void Ponderation_TypeQuelconque::LecturePonderation(const List_io <string>& grandeurs
                      , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD)
{

  // lecture du nom de la loi d'évolution
  *(entreePrinc->entree) >>  nom_fonction;
 
  // premier cas: fonction déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même fonction
    {if (nom_fonction != c_proport->NomFonction())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomFonction() == "_") delete c_proport;
        // puis on affecte
        if (lesFonctionsnD.Existe(nom_fonction))
          { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
        else
          { // sinon il faut la lire maintenant
            string non_fonction("_");
            c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str()));
            // lecture de la fonction
            c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc);
          };
       };
     // sinon la fonction est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {
     // on regarde si la fonction existe, si oui on récupère la référence
     if (lesFonctionsnD.Existe(nom_fonction))
      { c_proport = lesFonctionsnD.Trouve(nom_fonction);
      }
     else
      { // sinon il faut la lire maintenant
        string non_fonction("_");
        c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str()));
        // lecture de la fonction
        c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc);
      };
    };
 
  // maintenant on s'intéresse aux grandeurs
  // on part du principe que les grandeurs transmises doivent faire partie des grandeurs
  // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction
  // dans ce cas, on sort un warning
  // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien
  // ce qui représente une lecture brut
  int nb_grandeurs = grandeurs.size();
  if (nb_grandeurs != 0)
    {// on vérifie tout d'abord que la fonction est utilisable
     if (c_proport->NbVariable() < nb_grandeurs )
      { cout << "\n erreur en lecture, la fonction nD " << nom_fonction
             << " utilise  " << c_proport->NbVariable()
             << " variables alors qu'il en faut "
             << nb_grandeurs << " elle n'est donc pas utilisable !! ";
        string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(...");
        entreePrinc->MessageBuffer(message);
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);
      };
     if (c_proport->NbComposante() != 1 )
      { cout << "\n erreur en lecture, la fonction " << nom_fonction
             << " est une fonction vectorielle a   "
             << c_proport->NbComposante()
             << " composante(s) alors qu'elle devrait etre scalaire ! "
             << " elle n'est donc pas utilisable !! ";
        string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(...");
        entreePrinc->MessageBuffer(message);
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);
      };
     
     // on vérifie que les grandeurs transmises font quand même partie des variables utilisées
     // par la fonction nD
     const Tableau <Enum_GrandeurGlobale >& enu_glob = c_proport->Enu_variables_globales();
     const Tableau <string >& nom_glob = c_proport->Nom_variables_globales();
     
     // récup des noms des variables locales, indépendamment des variables globales
     const Tableau <string >& nom_loc = c_proport->Nom_variables();
     


     List_io <string>::const_iterator ili,ilifin=grandeurs.end();
     for (ili=grandeurs.begin();ili != ilifin; ili++)
        {
         if (!(nom_glob.Contient(*ili)
             || (EstUneGrandeurGlobale(*ili) // on ne peut tester que si c'est réellement une grandeur patentée
                 ? enu_glob.Contient(Id_nom_GrandeurGlobale(Minuscules(*ili))) : false
                )
             || nom_glob.Contient(*ili) || nom_loc.Contient(*ili)))
            { cout << "\n erreur en lecture, la fonction " << nom_fonction
                   << " devrait contenir la grandeur   " << (*ili)
                   << " et ce n'est pas le cas !  "
                   << " elle n'est donc pas utilisable !! ";
              string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(...");
              entreePrinc->MessageBuffer(message);
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie(1);
            };
        }
    };
 
};
// -------- affectation de la fonction à partir du nom sauvegardé
// intéressant quand cette affectation à lieu longtemps après la lecture
//        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
//                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
//			     List_io <EnumTypeQuelconque>  type_grandeur_Quelconque; // les arguments de la fonction
//        Tableau <double> tab_argument; //argument pour la fonction
//			     Fonction_nD* c_proport; // la fonction multidimentionnel
void Ponderation_TypeQuelconque::Affectation_fonctions(LesFonctions_nD& lesFonctionsnD)
 { // tout d'abord on regarde si ce n'est pas déjà effectué correctement
   // premier cas: courbe déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même courbe
    {if (nom_fonction != c_proport->NomFonction())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomFonction() == "_") delete c_proport;
        // puis on affecte
        if (lesFonctionsnD.Existe(nom_fonction))
          { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
        else
          { cout << "\n **** erreur1 Ponderation_TypeQuelconque::Affectation_fonctions(..."
                 << "\n on ne trouve pas la fonction " << nom_fonction
                 << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
            Sortie(1);
          };
       };
     // sinon la fonction est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {if (lesFonctionsnD.Existe(nom_fonction))
       { c_proport = lesFonctionsnD.Trouve(nom_fonction);}
     else
       { cout << "\n **** erreur2 Ponderation_TypeQuelconque::Affectation_fonctions(..."
              << "\n on ne trouve pas la courbes "<< nom_fonction
              << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
         Sortie(1);
       };
    };
 };

//-- vérification que tout est ok pour le calcul ------
void Ponderation_TypeQuelconque::Verif_complet() const
{  // on vérifie que la fonction est bien instanciée
   if (c_proport == NULL)
     { cout << "\n **** erreur1 Ponderation_TypeQuelconque::Verif_complet(..."
            << "\n la fonction "
            << " n'est pas definie on ne peut pas continuer " << endl;
       Sortie(1);
     };

  // on vérifie que les tailles sont correctes
  if (c_proport->NbVariable_locale() != type_grandeur_Quelconque.size())
     { cout << "\n **** erreur2 Ponderation_TypeQuelconque::Verif_complet(..."
            << "\n le nombre d'argument de la fonction "<<c_proport->NbVariable_locale()
            << " est different du nombre de grandeurs quelconques " << type_grandeur_Quelconque.size()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
  // on vérifie la taille des argument
  if (tab_argument.Taille() != type_grandeur_Quelconque.size())
     { cout << "\n **** erreur3 Ponderation_TypeQuelconque::Verif_complet(..."
            << "\n la taille du tableau d'argument de la fonction "<<tab_argument.Taille()
            << " est different du nombre de grandeurs quelconques " << type_grandeur_Quelconque.size()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
 
};

//----- 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 Ponderation_TypeQuelconque::Lecture_base_info(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
     ent >> nom;
     if (nom == "pointeur_null ")
      // cas où il n'y a rien à lire
      { if (c_proport != NULL)
           if (c_proport->NomFonction() == "_")
              delete c_proport;
      }
     else 
      { c_proport = lesFonctionsnD.Lecture_pour_base_info(ent,cas,c_proport);
      };
     // les arguments:
     type_grandeur_Quelconque.clear(); // au cas où
     ent >> nom; // l'identificateur
     ent >> nom; // le premier argument
     while (nom != "fin_argu")
       { type_grandeur_Quelconque.push_back(Id_nomTypeQuelconque(nom));
         ent >> nom;
       };
     // on met à jour le tableau des arguments pour l'appel des fonctions
     tab_argument.Change_taille(type_grandeur_Quelconque.size());
   };
};

// idem mais sans définition de la courbe:
// correspond au cas de la sauvegarde avec san_courbe = true
void Ponderation_TypeQuelconque::Lecture_base_info(ifstream& ent,const int cas)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
     ent >> nom;
     // les arguments:
     type_grandeur_Quelconque.clear(); // au cas où
     ent >> nom; // l'identificateur
     ent >> nom; // le premier argument
     while (nom != "fin_argu")
       { type_grandeur_Quelconque.push_back(Id_nomTypeQuelconque(nom));
         ent >> nom;
       };
     // on met à jour le tableau des arguments pour l'appel des fonctions
     tab_argument.Change_taille(type_grandeur_Quelconque.size());
   };
};

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
// sans_courbe: indique si on sauve oui ou non la courbe elle-même
// true: on sauve la courbe
// false : on sauve uniquement le nom de la courbe
void Ponderation_TypeQuelconque::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  if (cas == 1)
   { sort << "\n Ponderation_TypeQuelconque " << nom_fonction;
     if (!sans_courbe)
      {if (c_proport == NULL)
        { sort << "pointeur_null " ;}
       else 
        { sort << "fonction ";
          LesFonctions_nD::Ecriture_pour_base_info(sort,cas,c_proport);
        };
      };
     // les arguments:
     List_io <EnumTypeQuelconque>::iterator ili,iliend=type_grandeur_Quelconque.end();
     sort << "\n argument(s): ";
     for (ili = type_grandeur_Quelconque.begin(); ili != iliend; ili++)
       sort << NomTypeQuelconque(*ili) << " ";
     sort << " fin_argu";
   };
};

// sortie du schemaXML: en fonction de enu
void Ponderation_TypeQuelconque::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu)
{
};

//============== fin de la classe Ponderation_TypeQuelconque ===============



// ============ cas de la class Ponderation ===============
Ponderation::Ponderation() : // le constructeur par défaut
			    type_grandeur(),valeur_aux_noeuds(),c_proport(),tab_nom_fonction()
  {};
Ponderation::Ponderation(const Ponderation& a) : // le constructeur de copie
			    type_grandeur(a.type_grandeur),valeur_aux_noeuds(a.valeur_aux_noeuds)
       ,c_proport(a.c_proport),tab_nom_fonction(a.tab_nom_fonction)
  {// cas des courbes
   int tail = c_proport.Taille();
	  for (int i=1;i<= tail;i++)
	   {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
	    if (c_proport(i) != NULL)
	     if (c_proport(i)->NomCourbe() == "_")
         {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi)
          string non_courbe("_");   
          c_proport(i) = Courbe1D::New_Courbe1D(*a.c_proport(i));
         };
	   };
  };

Ponderation::~Ponderation () // destructeur
  {// cas des courbes
   int tail = c_proport.Taille();
	  for (int i=1;i<= tail;i++)
	   {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
     if (c_proport(i) != NULL)
       if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
	   };
  };
        // -------- opération de lecture sur le flot d'entrée ------
     

// lecture d'une courbe: intéressant si on lit courbe par courbe
// le dimensionnement est mis à jour à chaque appel
void Ponderation::LectureDonneesPonderation_uneCourbe
       (Ddl_enum_etendu ddl,UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D)
{
     string st1;
     // on lit la courbe
     *(entreePrinc->entree) >>  st1;
     Courbe1D* inter=NULL;
     // on regarde si la courbe existe, si oui on récupère la référence
     if (lesCourbes1D.Existe(st1))
      { inter = lesCourbes1D.Trouve(st1);
      }
     else
      { // sinon il faut la lire maintenant
        string non_courbe("_");
        inter = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str()));
        // lecture de la courbe
        inter->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
      };
     // maintenant on redimensionne les tableaux
     // ce n'est pas performant, mais normalement cela n'arrive pas souvent (?)
 
     int taille = type_grandeur.Taille() +1 ;
     type_grandeur.Change_taille(taille);type_grandeur(taille)=ddl;
     c_proport.Change_taille(taille);c_proport(taille)=inter;
     tab_nom_fonction.Change_taille(taille);tab_nom_fonction(taille)=st1;
 
     // et il faut lire en plus le fait que ce soit au noeud ou au pti
     string st2;
     *(entreePrinc->entree) >> st2;
     valeur_aux_noeuds.Change_taille(taille);

     if (st2 == "AuxNoeuds_")  {valeur_aux_noeuds(taille)=true;}
     else if (st2 == "AuPti_") {valeur_aux_noeuds(taille)=false;}
     else
       { cout << "\n erreur en lecture, de positionnement de la grandeur: "
              << ddl.Nom() << " qui doit etre AuxNoeuds_ ou AuPti_ "
              << " et on a  lu" << st2 << " qui n'est pas acceptable  "
              << "\nPonderation::LectureDonneesPonderation_uneCourbe(...";
         entreePrinc->MessageBuffer("**erreur**");
         throw (UtilLecture::ErrNouvelleDonnee(-1));
         Sortie(1);
       };

};
        
// lecture de l'ensemble de la pondération
void Ponderation::LectureDonneesPonderation
                      (const List_io <string> & list_id_ddl_etendu
                      , UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D)
 {  // on commence par tout redimensionner et initialiser si les tailles ne sont pas identiques
    int nb_fonc = list_id_ddl_etendu.size();
    if (type_grandeur.Taille() != nb_fonc)
     { type_grandeur.Change_taille(nb_fonc);
       valeur_aux_noeuds.Change_taille(nb_fonc);
       // on supprime les fonctions et on redimensionne le tableau
       int tail = c_proport.Taille();
       for (int i=1;i<= tail;i++)
        {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
         if (c_proport(i) != NULL)
           if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
        };
       c_proport.Change_taille(nb_fonc);
       tab_nom_fonction.Change_taille(nb_fonc);
      };
  
    // on boucle sur les ddl pour lire les fonctions individuelles
    List_io <string>::const_iterator ili,ilifin = list_id_ddl_etendu.end();
    int i_tab=1; // indice de tableau
    for (ili=list_id_ddl_etendu.begin();ili != ilifin; ili++,i_tab++)
      { string st1;
        // on lit la courbe
        *(entreePrinc->entree) >>  st1;
        Courbe1D* inter=NULL;
        // on regarde si la courbe existe, si oui on récupère la référence
        if (lesCourbes1D.Existe(st1))
         { inter = lesCourbes1D.Trouve(st1);
         }
        else
         { // sinon il faut la lire maintenant
           string non_courbe("_");
           inter = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str()));
           // lecture de la courbe
           inter->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
         };
        // maintenant on alimente les tableaux
        type_grandeur(i_tab)=Ddl_enum_etendu(*ili);
        c_proport(i_tab)=inter;
        tab_nom_fonction(i_tab)=st1;
 
        // et il faut lire en plus le fait que ce soit au noeud ou au pti
        string st2;
        *(entreePrinc->entree) >> st2;
        valeur_aux_noeuds.Change_taille(i_tab);

        if (st2 == "AuxNoeuds_")  {valeur_aux_noeuds(i_tab)=true;}
        else if (st2 == "AuPti_") {valeur_aux_noeuds(i_tab)=false;}
        else
          { cout << "\n erreur en lecture, de positionnement de la grandeur: "
                 << (*ili) << " qui doit etre AuxNoeuds_ ou AuPti_ "
                 << " et on a  lu" << st2 << " qui n'est pas acceptable  "
                 << "\nPonderation::LectureDonneesPonderation_uneCourbe(...";
            entreePrinc->MessageBuffer("**erreur**");
            throw (UtilLecture::ErrNouvelleDonnee(-1));
            Sortie(1);
          };
      
      };
  
 };

// -------- affectation des fonctions à partir des noms sauvegardés
// intéressant quand cette affectation à lieu longtemps après la lecture
void Ponderation::Affectation_fonctions(LesCourbes1D& lesCourbes1D)
 { // tout d'abord on regarde si ce n'est pas déjà effectué correctement
   int taille = tab_nom_fonction.Taille();
   // on réajuste les tailles si besoin est
   if (c_proport.Taille() > taille)
     // là il faut diminuer. Avant il faut supprimer les fonctions si nécessaire
     {for (int i=taille+1;i<= c_proport.Taille();i++)
        if (c_proport(i) != NULL)
          if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
     };
   // maintenant on peut changer la taille dans tous les cas
   c_proport.Change_taille(taille);
   // on boucle pour l'affectation
   for (int i=1;i<=taille;i++)
    { // premier cas: courbe déjà affectée
      if (c_proport(i) != NULL)
        // on regarde s'il s'agit de la même courbe
       {if (tab_nom_fonction(i) != c_proport(i)->NomCourbe())
          {// cas où c'est différent: on commence éventuellement par supprimer
           if (c_proport(i)->NomCourbe() == "_") delete c_proport(i);
           // puis on affecte
           if (lesCourbes1D.Existe(tab_nom_fonction(i)))
             { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));}
           else
             { cout << "\n **** erreur1 Ponderation_Consultable::Affectation_fonctions(..."
                    << "\n on ne trouve pas la courbe "<<tab_nom_fonction(i)
                    << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
               Sortie(1);
             };
          };
        // sinon les courbes sont déjà identique, on ne fait rien
       }
      else // pas d'affectation, on affecte donc
       {if (lesCourbes1D.Existe(tab_nom_fonction(i)))
          { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));}
        else
          { cout << "\n **** erreur2 Ponderation_Consultable::Affectation_fonctions(..."
                 << "\n on ne trouve pas la courbes "<<tab_nom_fonction(i)
                 << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
            Sortie(1);
          };
       };
    };
 };

//-- vérification que tout est ok pour le calcul ------
void Ponderation::Verif_complet() const
{ // on vérifie que les fonctions sont bien instanciées
  int taille = c_proport.Taille();
  for (int i=1;i<= taille;i++)
   {if (c_proport(i) == NULL)
     { cout << "\n **** erreur1 Ponderation::Verif_complet(..."
            << "\n la fonction "<< i
            << " n'est pas definie on ne peut pas continuer " << endl;
       Sortie(1);
     };
   };
  // on vérifie que les tailles sont correctes
  if (type_grandeur.Taille() != valeur_aux_noeuds.Taille())
     { cout << "\n **** erreur2 Ponderation::Verif_complet(..."
            << "\n le nombre de grandeur "<< type_grandeur.Taille()
            << " est different du nombre de la taille d'indication : au noeud ou au pti "
            << valeur_aux_noeuds.Taille()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
  // on vérifie la taille des argument
  if (type_grandeur.Taille() != c_proport.Taille())
     { cout << "\n **** erreur3 Ponderation::Verif_complet(..."
            << "\n la taille du tableau des grandeurs "<<type_grandeur.Taille()
            << " est different du nombre de fonctions " << c_proport.Taille()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
  // on vérifie la taille des nom de fonction
  if (tab_nom_fonction.Taille() != c_proport.Taille())
     { cout << "\n **** erreur4 Ponderation::Verif_complet(..."
            << "\n la taille du tableau des noms de fonction "<<tab_nom_fonction.Taille()
            << " est different du nombre de fonctions " << c_proport.Taille()
            << " on ne peut pas continuer " << endl;
       Sortie(1);
     };
 
};
     
// affichage
void Ponderation::Affiche()
{ cout << "\n Ponderation " << "nom_courbes " << tab_nom_fonction;
  cout << "\n type_grandeur "<< type_grandeur << " valeur_aux_noeuds "<< valeur_aux_noeuds;
  int taille = c_proport.Taille(); // normalement = la même que celle de type_grandeur
  for (int i=1;i<= taille ; i++)
   {if (c_proport(i) == NULL)
      { cout << "pointeur_null " ;}
    else
      { cout << "courbe("<<i<<")= ";
        c_proport(i)->Affiche();
      };
   };
 
};


// activation des données des noeuds et/ou elements nécessaires au fonctionnement
// exemple: mise en service des ddl de température aux noeuds
void Ponderation::Activation_donnees
     (Tableau <Noeud *>& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt)
{ // on boucle sur le tableau de valeurs aux noeuds
  int taille = valeur_aux_noeuds.Taille();
  for (int iv1=1;iv1<=taille;iv1++)
     { // dans le cas d'une proportion venant des noeuds par interpolation
       // on active les ddl correspondant à la grandeur qui règle la proportion
       if (valeur_aux_noeuds(iv1))
        { int nbnoeud = tabnoeud.Taille();
          for (int i=1;i<=nbnoeud;i++)
           { // on vérifie que la variable type_grandeur existe sinon erreur
             if (tabnoeud(i)->Existe_ici(type_grandeur(iv1).Enum()))
                 {tabnoeud(i)->Met_en_service(type_grandeur(iv1).Enum());}
             else
                 { cout << "\n erreur: la grandeur " << type_grandeur(iv1) << " n'existe pas "
                        << " il n'est pas possible d'utiliser une loi des melanges avec cette grandeur "
                        << " il manque sans doute des donnees !!! "
                        << "\n Ponderation::Activation_donnees(...";
                   Sortie(1);
                 };
           }
        }
       else
        {// cas d'un vrai ddl étendue
         // on commence par regarder si les pt meca int existent
         if ( ((LesPtIntegMecaInterne*) &lesPtMecaInt) == NULL)
          { cout << "\n *** erreur la loi des melanges ne peut pas s'utiliser ici telle quelle ***"
                 << " demander une modification ! ";
            cout << "\n 	Ponderation::Activation_donnees(.. " << endl;
            Sortie(1);
          };
         // cas normal
         switch (type_grandeur(iv1).Position()-NbEnum_ddl())
          {case 77: case 78: case 87: case 88: // cas de "def_duale_mises", cas de "Spherique_eps", cas de "def_duale_mises_maxi"
             {// il faut que l'on active le calcul des invariants de déformations
              int nbpti = lesPtMecaInt.NbPti();
              for (int i= 1;i<= nbpti;i++)
                lesPtMecaInt(i).Change_statut_Invariants_deformation (true);
              break;
             }
           case 81: // cas de "Spherique_sig"
             {// il faut que l'on active le calcul des invariants des contraintes
              int nbpti = lesPtMecaInt.NbPti();
              for (int i= 1;i<= nbpti;i++)
                lesPtMecaInt(i).Change_statut_Invariants_contrainte (true);
              break;
             }
           default:
              cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible "
                   << " pour l'instant au point d'integration ! "
                   << "\n Ponderation::Activation_donnees(.... ";
              break;
          };
        };
     };
};

// calcul global de la pondération, sous forme d'un produit
// NB: ar défaut ramène 1. si toutes les fonctions sont inactives
// sinon ramène le produit :
// 1) des fonctions de Ddl_enum_etendu accessibles
//    soit au pti méca et ou soit par interpolation via def
// 2) d'une fonction éventuelle du temps
// 3) d'une fonction éventuelle de thermodonnee
double Ponderation::CalculPonderMultiplicatif(const PtIntegMecaInterne& ptintmeca
                              ,const Deformation & def
                              ,Enum_dure temps,const ThermoDonnee& dTP)
  { double proportion = 1.; // init du retour
    int taille = type_grandeur.Taille();
    for (int i=1;i<= taille; i++)
      { // calcul des pondérations
        if (valeur_aux_noeuds(i)) // pour l'instant que des ddl patentés !
          // cas d'une proportion provenant d'une interpolation aux noeuds
          { double grand = def.DonneeInterpoleeScalaire(type_grandeur(i).Enum(),temps);
            double fonc = c_proport(i)->Valeur(grand);
            proportion *= fonc; // on accumule multiplicativement
          }
        else
          // sinon il s'agit d'une grandeur directement accessible au point d'intégration
          // pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers
          { 
           // deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu
           if (type_grandeur(i).Nom_vide())
            {switch (type_grandeur(i).Enum())
             { case PROP_CRISTA:
                 { const double* taux_crita = dTP.TauxCrista();
                   if (taux_crita != NULL)
                     {	double fonc = c_proport(i)->Valeur(*taux_crita);
                       proportion *= fonc; // on accumule multiplicativement
                     }
                   else
                     {cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration "
                           << " il n'est pas possible de calculer le niveau_declenchement_critere "
                           << "\n Ponderation::CalculPonderMultiplicatif(.... ";
                     }; 	
                   break;
                 }
               default:
                  cout << "\n erreur, le type  " << type_grandeur(i) << " n'est pas disponible "
                       << " pour l'instant au point d'integration ! "
                       << "\n Ponderation::CalculPonderMultiplicatif(.... ";
             };
            }
           else
            {// cas d'un vrai ddl étendue
            
             Ddl_enum_etendu enu_etendu = type_grandeur(i); // pour simplifier
             switch (enu_etendu.Position()-NbEnum_ddl())
             {case 87: // cas de "def_equivalente"
                {const double def_equivalente  =  ptintmeca.Deformation_equi_const()(1); // recup de la def equi
                 double fonc = c_proport(i)->Valeur(def_equivalente);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              case 88: // cas de "def_duale_mises_maxi"
                {const double def_duale_mises_maxi  =  ptintmeca.Deformation_equi_const()(3); // recup de la def equi
                 double fonc = c_proport(i)->Valeur(def_duale_mises_maxi);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              case 89: // cas de "vitesse_def_equivalente"
                {const double delta_def_equivalente  =  ptintmeca.Deformation_equi_const()(4); // recup du delta def equi
                 // recup de l'incrément de temps
                 double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
                 double unSurDeltat=0;    
                 if (Abs(deltat) >= ConstMath::trespetit)
                   {unSurDeltat = 1./deltat;}
                 else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
                   { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
                     if (unSurDeltat < 0)
                     { cout << "\n le pas de temps est négatif !! "; };
                     unSurDeltat = ConstMath::tresgrand;
                   };
                 double vitesse_def_equi = 	delta_def_equivalente * unSurDeltat;
                 double fonc = c_proport(i)->Valeur(vitesse_def_equi);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              case 77: // cas de "def_duale_mises"
                {const double def_duale_mises  =  ptintmeca.Deformation_equi_const()(2); // recup de la def equi
                 double fonc = c_proport(i)->Valeur(def_duale_mises);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              case 78: // cas de "Spherique_eps"
                {const Vecteur &  epsInvar   = ptintmeca.EpsInvar_const(); // recup des invariants
                 double spherique_eps = epsInvar(1); 
                 double fonc = c_proport(i)->Valeur(spherique_eps);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              case 81: // cas de "Spherique_sig"
                {const Vecteur &  sigInvar   = ptintmeca.SigInvar_const(); // recup des invariants
                 double spherique_sig = sigInvar(1); 
                 double fonc = c_proport(i)->Valeur(spherique_sig);
                 proportion *= fonc; // on accumule multiplicativement
                 break;
                }
              default:
                 cout << "\n erreur, le type  " << enu_etendu
                      << " n'est pas disponible "
                      << " pour l'instant au point d'integration ! "
                      << "\n Ponderation::CalculPonderMultiplicatif(.... ";
              break;
             };
            };			  	
          };
      };
    return proportion; // retour de la proportion calculée
  };


//----- 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 Ponderation::Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom >> tab_nom_fonction;
     ent >> nom >> type_grandeur >> nom >> valeur_aux_noeuds;
     int taille = type_grandeur.Taille();
     c_proport.Change_taille(taille); // ne change rien si la taille est déjà bonne
     for (int i=1;i<= taille;i++)
      {ent >> nom;
       if (nom == "pointeur_null ")
        // cas où il n'y a rien à lire
        { if (c_proport(i) != NULL)
           if (c_proport(i)->NomCourbe() == "_")
              delete c_proport(i);
        }
       else
        { c_proport(i) = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport(i));
        };
      };
   };
};

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ponderation::Ecriture_base_info(ofstream& sort,const int cas)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  if (cas == 1)
   { sort << "\n Ponderation " << "nom_courbes " << tab_nom_fonction;
     sort << "\n type_grandeur "<< type_grandeur << " valeur_aux_noeuds "<< valeur_aux_noeuds;
     int taille = c_proport.Taille(); // normalement = la même que celle de type_grandeur
     for (int i=1;i<= taille ; i++)
      {if (c_proport(i) == NULL)
         { sort << "pointeur_null " ;}
       else
         { sort << "courbe= ";
           LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport(i));
         };
      };
   };
};

// sortie du schemaXML: en fonction de enu
void Ponderation::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu)
{
};

//============== fin de la classe Ponderation ===============
// ============ cas de la class Ponderation_temps ===============
Ponderation_temps::Ponderation_temps() : // le constructeur par défaut
     c_proport(NULL),nom_fonction("..")
  {};
Ponderation_temps::Ponderation_temps(const Ponderation_temps& a) : // le constructeur de copie
			    c_proport(a.c_proport),nom_fonction(a.nom_fonction)
  {// cas de la courbe
   // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
   if (c_proport != NULL)
	     if (c_proport->NomCourbe() == "_")
         {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi)
          string non_courbe("_");   
          c_proport = Courbe1D::New_Courbe1D(*a.c_proport);
         };
  };

Ponderation_temps::~Ponderation_temps () // destructeur
  {// cas de la courbe
   // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
   if (c_proport != NULL)
       if (c_proport->NomCourbe() == "_") delete c_proport;
  };

//        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
//                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
//			     Courbe1D* c_proport; // la fonctions 1D, fonction du temps

// lecture sur le flot d'entrée
void Ponderation_temps::LectureDonneesPonderation
      (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D)
{
  // lecture du nom de la loi d'évolution
  *(entreePrinc->entree) >>  nom_fonction;
 
  // premier cas: courbe déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même courbe
    {if (nom_fonction != c_proport->NomCourbe())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomCourbe() == "_") delete c_proport;
        // puis on affecte
        if (lesCourbes1D.Existe(nom_fonction))
          { c_proport = lesCourbes1D.Trouve(nom_fonction);}
        else
          { // sinon il faut la lire maintenant
            string non_courbe("_");
            c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom_fonction.c_str()));
            // lecture de la courbe
            c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
          };
       };
     // sinon la courbe est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {
     // on regarde si la courbe existe, si oui on récupère la référence
     if (lesCourbes1D.Existe(nom_fonction))
      { c_proport = lesCourbes1D.Trouve(nom_fonction);
      }
     else
      { // sinon il faut la lire maintenant
        string non_courbe("_");
        c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom_fonction.c_str()));
        // lecture de la courbe
        c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
      };
    };
};

// -------- affectation des fonctions à partir des noms sauvegardés
// intéressant quand cette affectation à lieu longtemps après la lecture
void Ponderation_temps::Affectation_fonctions(LesCourbes1D& lesCourbes1D)
 { // premier cas: courbe déjà affectée
   if (c_proport != NULL)
     // on regarde s'il s'agit de la même courbe
    {if (nom_fonction != c_proport->NomCourbe())
       {// cas où c'est différent: on commence éventuellement par supprimer
        if (c_proport->NomCourbe() == "_") delete c_proport;
        // puis on affecte
        if (lesCourbes1D.Existe(nom_fonction))
          { c_proport = lesCourbes1D.Trouve(nom_fonction);}
        else
          { cout << "\n **** erreur1 Ponderation_temps::Affectation_fonctions(..."
                 << "\n on ne trouve pas la courbe "<< nom_fonction
                 << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
            Sortie(1);
          };
       };
     // sinon la courbe est déjà identique, on ne fait rien
    }
   else // pas d'affectation, on affecte donc
    {if (lesCourbes1D.Existe(nom_fonction))
       { c_proport = lesCourbes1D.Trouve(nom_fonction);}
     else
       { cout << "\n **** erreur2 Ponderation_temps::Affectation_fonctions(..."
              << "\n on ne trouve pas la courbes "<< nom_fonction
              << " il vaut mieux s'arreter !! car il manque des donnees " << endl;
         Sortie(1);
       };
    };
  
 };

//-- vérification que tout est ok pour le calcul ------
void Ponderation_temps::Verif_complet() const
{ // on vérifie que la fonction est bien instanciée
  if (c_proport == NULL)
   { cout << "\n **** erreur1 Ponderation_temps::Verif_complet(..."
          << "\n la fonction "
          << " n'est pas definie on ne peut pas continuer " << endl;
     Sortie(1);
   };
};
     
// affichage
void Ponderation_temps::Affiche()
{ cout << "\n Ponderation_temps "  << nom_fonction;
  if (c_proport == NULL)
    { cout << "pointeur_null " ;}
  else
    { cout << "courbe= ";
      c_proport->Affiche();
    };
};

// calcul de la pondération
// par défaut ramène 1. si la fonction du temps est inactive par exemple
// sinon ramène la valeur de la fonction du temps actuel
double Ponderation_temps::CalculPonder()
{ const VariablesTemps& var_temps = ParaGlob::Variables_de_temps();
  double fonc = c_proport->Valeur(var_temps.TempsCourant());
  return fonc;
};

//----- 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 Ponderation_temps::Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
     ent >> nom;
     if (nom == "pointeur_null ")
      // cas où il n'y a rien à lire
      { if (c_proport != NULL)
         if (c_proport->NomCourbe() == "_")
            delete c_proport;
      }
     else
      { c_proport = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport);
      };
   };
};

// idem mais sans définition de la courbe
void Ponderation_temps::Lecture_base_info(ifstream& ent,const int cas)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  string nom;
  if (cas == 1)
   { ent >> nom >> nom_fonction;
   };
};

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
// sans_courbe: indique si on sauve oui ou non la courbe elle-même
// true: on sauve la courbe
// false : on sauve uniquement le nom de la courbe
void Ponderation_temps::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe)
{ // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs
  if (cas == 1)
   { sort << "\n Ponderation_temps "  << nom_fonction;
     if (!sans_courbe)
      {if (c_proport == NULL)
         { sort << "pointeur_null " ;}
       else
         { sort << "courbe= ";
           LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport);
         };
      };
   };
};


