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


#include "Charge.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "CourbePolyLineaire1D.h"


#include "Charge.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "CourbePolyLineaire1D.h"
#include "CharUtil.h"
    
// avancement de la charge
// il peut y avoir plusieurs type d'avancement
// en fonction des donnees ( transparent pour l'utilisateur)
// mais aussi en fonction des parametres 
// retourne false par défaut, mais si le pas de temps a été modifié
// retourne true !!, car par exemple de la fin du chargement, d'où une modif du pas
// pour obtenir exactement la fin
bool Charge::Avance() // premier version
  { // appel de la fonction ad hoc
    return(this->*PtAvance)();
   };
    
    // retour de la charge au cas précédent, c'est à dire
    // avant le dernier ordre d'avancement
    // valeur par défaut de "exacte " 
    // si exacte n'est pas présent ou faux: le compteur_essai_increment d'appel de Avance(), n'est pas décrémenté
    // exacte=true:  le compteur_essai_increment d'appel est décrémenté, en fait on revient exactement au départ
    // ce qui permet d'utiliser plusieurs fois Avance() dans un même pas de temps
    // en comptabilisant par exemple qu'une seule fois un appel de Avance(), cas d'une intégration
    // temporelle par exemple
void Charge::Precedant(bool exacte)
  { // appel de la fonction ad hoc
    (this->*PtPrecedent)();
    if (exacte) compteur_essai_increment--;
   };
   
// diminution de l'incrément de charge dans le cas par exemple d'une non convergence
// ramène true si la diminution est effective, sinon false
bool Charge::Diminue_inc_charge(double diminue)
  { // si le type est 5, les temps de calcul sont bloqué
    if (nomtypeCharge == "TYPE5")
     { if (ParaGlob::NiveauImpression() > 4)
         cout << "\n TYPE5: pas de temps fige, pas de diminution permise ";
       return false;  
      };
    // autres cas: 
//    //on commence par revenir à la charge précédente
//    (this->*PtPrecedent)();
    // on divise l'incrément de temps
    double deltat_essai = paAlgo->Deltat() / diminue;
    // on diminue si possible
    return (!(paAlgo->Modif_Deltat(deltat_essai)));
  //-//  deltat /= diminue;
   };

// augmentation de l'incrément de charge dans le cas de bonne convergence
// ramène true si l'augmentation est effective, sinon false
bool Charge::Augmente_inc_charge(double augmente)
  { // si le type est 5, les temps de calcul sont bloqué
    if (nomtypeCharge == "TYPE5")
     { if (ParaGlob::NiveauImpression() > 4)
         cout << "\n TYPE5: pas de temps fige, pas d'augmentation permise ";
       return false;  
      };
    // on augmente l'incrément de temps si possible
    double deltat_essai = paAlgo->Deltat() * augmente;
    // on augmente si possible
    bool test_augmente = paAlgo->Modif_Deltat(deltat_essai);
    if (!test_augmente)
      { return true;} // si tout est ok on ramène true
    else
     // sinon on essaie d'augmenter dans les bornes
     {return   paAlgo->Modif_Detat_dans_borne(deltat_essai); };
//    return (!(paAlgo->Modif_Deltat(deltat_essai)));
   };

    // declaration de la fin en fonction du type de chargement
    //  0 : la fin n'est pas valide, on continue
    //  1 : temps fin dépassé
    //  2 : compteur_increment dépassé
    //  3 : compteur_essai_increment dépassé
    // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
    //     puis ensuite le compteur d'incréments
    //     puis le nombre d'essai maxi, puis enfin le cas normal
    // si affichage est true, affichage d'un message
int Charge::Fin(const int & icharge,bool affichage)
  { // appel de la fonction ad hoc
////---debug
//cout << "\n Charge::Fin(...affichage="
//     << affichage << endl;
////--fin debug
    return (this->*PtFin)(icharge,affichage);
   };
    
// affichage et definition interactive des commandes
void Charge::Info_commande_LesCharges1(UtilLecture & entreePrinc)
{  // ---------- définition des différents chargements ----------
   ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
   bool plusieurs_maillages = false;
   string rep;
   cout << "\n cas d'un seul maillage (par defaut) : rep o "
        << "\n cas de plusieurs maillages          : rep n ";
   // procédure de lecture avec prise en charge d'un retour chariot
   rep = lect_return_defaut(true,"o");
   if (rep == "n")
       { plusieurs_maillages = true;};
   rep="_"; // init
   
   //On va proposer un menu
   sort << "\n\n       charges #------------#        ";
   while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
      {
       try 
       {cout 
           << "\n (0 ou f)  (fin)               "
           << "\n (1)  ponctuelle                    (PONCTUELLE)"
           << "\n (2)  volumique                     (VOLUMIQUE) "
           << "\n (3)  lineique de direction fixe    (LINEIQUE) "
           << "\n (4)  lineique suiveuse             (LINEIC_SUIVEUSE) " 
           << "\n (5)  surfacique de direction fixe  (UNIFORME)"
           << "\n (6)  pression                      (PRESSION)"
           << "\n (7)  surfacique suiveuse           (PRESSDIR)"
           << "\n (8)  hydrostatique                 (PHYDRO)"
           << "\n (9)  aero - hydrodynamique         (P_HYDRODYNA)"
           << "\n (10) torseur d'efforts ponctuels   (TORSEUR_PONCT)"
           << "\n (11 ou ? ) informations  "
           << "\n  ";
        // procédure de lecture avec prise en charge d'un retour chariot
        rep = lect_return_defaut(false,"f");
        if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
          break;
        int num = ChangeEntier(rep);
        if (Minuscules(rep) == "?")
          num = 11;
        bool choix_valide=false;
        if ((num >= 0)&&(num<=11))
             { choix_valide=true; }
        else { cout << "\n Erreur on attendait un entier entre 0 et 11 !!, "
                    << "\n redonnez une bonne valeur"
                    << "\n ou taper f ou 0 pour arreter le programme"; 
               choix_valide=false;
             }
        switch (num)
         { case 0:  // sortie
             { break;} // normalement cela a déjà été filtré avant
           case 1:  // ponctuelle
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference de noeud ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'N')
                {cout << "\n *** erreur, la premiere lettre de la ref de noeud "
                      << " doit etre N et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PONCTUELLE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 2:  // volumique
              {string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'elements ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'E')
                {cout << "\n *** erreur, la premiere lettre de la ref d'element "
                      << " doit etre E et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               cout << "\n donner la charge volumique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " VOLUMIQUE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 3:  // lineique de direction fixe
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'arete ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'A')
                {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
                      << " doit etre A et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force lineique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " LINEIQUE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 4:  // lineique suiveuse
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'arete ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'A')
                {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
                      << " doit etre A et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force lineique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " LINEIC_SUIVEUSE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 5:  // surfacique de direction fixe
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force surfacique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " UNIFORME ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 6:  // pression
              {string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la charge surfacique (1 reels) ? ";
               double charge;
               charge=lect_double(); cout << " valeur lue ="<< charge;
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PRESSION "<< charge <<" ";
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 7:  // surfacique suiveuse
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force surfacique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PRESSDIR ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 8:  // hydrostatique
             { string nom_maillage="";               
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               int dim = ParaGlob::Dimension();
               Coordonnee dir(dim); // direction de la force
               cout << "\n donner la direction de la normale au plan de reference ("<<dim<<" reels) ? ";
               dir.Lecture();
               Coordonnee point_plan(dim); // normale au plan
               cout << "\n donner un point du plan de reference ("<<dim<<" reels) ? ";
               point_plan.Lecture();
               double rho_g=0.;
               cout << "\n donner la valeur de rho*g (1 reels) ? ";
               rho_g=lect_double();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort <<" " << nom_ref<<" ";
               sort << " PHYDRO ";
               dir.Affiche(sort,dim);
               point_plan.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               // le fait de passer la chaine "sans_limitation_" en paramètre
               // fait qu'il y aura interrogation pour savoir si l'on veut ou non
               // cet attribut en plus
               bloc.Info_commande_BlocCharge(sort,"sans_limitation_");
               sort << endl;
               break;
              }
           case 9:  // aero - hydrodynamique
             { string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               string nom_courbeToVt="NULL";
               cout << "\n nom de la courbe to(Vt),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbeToVt=lect_chaine();cout << " nom lu = "<< nom_courbeToVt;
               string nom_courbef_n="NULL";
               cout << "\n nom de la courbe f_n(V),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbef_n=lect_chaine();cout << " nom lu = "<< nom_courbef_n;
               string nom_courbef_t="NULL";
               cout << "\n nom de la courbe f_t(V),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbef_t=lect_chaine();cout << " nom lu = "<< nom_courbef_t;
               cout << "\n donner la masse volumique (1 reels) ? ";
               double charge;
               charge=lect_double(); cout << " valeur lue ="<< charge;
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref
                    << " P_HYDRODYNA " << " " << nom_courbeToVt << " "
                    << nom_courbef_n <<" " << nom_courbef_t << " "
                    << charge << " ";
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 10:  // torseur d'efforts ponctuels
              {string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};

               cout << "\n nom de la reference de noeuds ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'N')
                {cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
                      << " doit etre N et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
                sort << nom_ref ;
               // on définit un bloc arbitraire qui va permettre de
               // définir les paramètres spécifiques
               BlocCharge< BlocDdlLim<PTorseurPonct> > bloc_tors;
               bool ecriture = bloc_tors.Info_commande_Charges(plusieurs_maillages,entreePrinc);
               // maintenant on s'occupe du cas courbe de charge et bornes
               if (ecriture)
                 {bloc_tors.Info_commande_BlocCharge(sort);
                  sort << endl;
                 };
               break;
              }
           case 11:  // information
             { cout << "\n pour plus de details il faut se reporter a la documentation d'herezh++ ";
               break;
              }
           default:
             cout << "\n le cas "<<rep<<" n'est pas  traite !!, bizarre, il faut se plaindre !! ";
          };
        }    
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
        {  cout << "\n Erreur on attendait un des mots cles proposes !!, "
                << "\n redonnez une bonne valeur"
                << "\n ou taper f ou 0 pour sortir "; 
        };
      }; //-- fin du while
   sort << flush;

};
   
// affichage et definition interactive des commandes
void Charge::Info_commande_LesCharges2(UtilLecture & entreePrinc)
{  // ---------- définition des différents chargements ----------
   ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
   string rep;
   rep="_"; // init
   cout << "\n cas non implante pour l'instant mais c'est en cours ! "<<endl;
   return;
   bool plusieurs_maillages;
   
   //On va proposer un menu
   sort << "\n\n    typecharge #------------#        ";
   while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
      {
       try 
       {cout 
           << "\n (0 ou f)  (fin)               "
           << "\n (1)  TYPE1                                   (courbe: rampe + palier)"
           << "\n (2)  TYPE2                          (courbe: rampe + palier + arret) "
           << "\n (3)  TYPE3                               (courbe: palier uniquement) "
           << "\n (4)  TYPE4                                       (courbe quelconque) "
           << "\n (5)  TYPE5           (obligation de suivre une suite de points fixes)"
           << "\n (6)  TYPE6  (suite de pts fixes, possibilite de temps intermediaires)"
           << "\n (7 ou ? ) informations  "
           << "\n  ";
        // procédure de lecture avec prise en charge d'un retour chariot
        rep = lect_return_defaut(false,"f");
        if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
          break;
        int num = ChangeEntier(rep);
        if (Minuscules(rep) == "?")
          num = 7;
        bool choix_valide=false;
        if ((num >= 0)&&(num<=7))
             { choix_valide=true; }
        else { cout << "\n Erreur on attendait un entier entre 0 et 7 !!, "
                    << "\n redonnez une bonne valeur"
                    << "\n ou taper f ou 0 pour arreter le programme"; 
               choix_valide=false;
             }
        switch (num)
         { case 0:  // sortie
             { break;} // normalement cela a déjà été filtré avant
           case 1:  // (courbe: rampe + palier)
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference de noeud ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'N')
                {cout << "\n *** erreur, la premiere lettre de la ref de noeud "
                      << " doit etre N et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PONCTUELLE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 2:  // volumique
              {string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'elements ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'E')
                {cout << "\n *** erreur, la premiere lettre de la ref d'element "
                      << " doit etre E et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               cout << "\n donner la charge volumique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " VOLUMIQUE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 3:  // lineique de direction fixe
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'arete ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'A')
                {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
                      << " doit etre A et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force lineique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " LINEIQUE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 4:  // lineique suiveuse
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference d'arete ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'A')
                {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
                      << " doit etre A et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force lineique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " LINEIC_SUIVEUSE ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 5:  // surfacique de direction fixe
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force surfacique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " UNIFORME ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 6:  // pression
              {string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la charge surfacique (1 reels) ? ";
               double charge;
               charge=lect_double(); cout << " valeur lue ="<< charge;
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PRESSION "<< charge <<" ";
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 7:  // surfacique suiveuse
             { int dim = ParaGlob::Dimension();
               Coordonnee trans(dim);
               string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };

               cout << "\n donner la force surfacique ("<<dim<<" reels) ? ";
               trans.Lecture();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref << " PRESSDIR ";
               trans.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 8:  // hydrostatique
             { string nom_maillage="";               
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               int dim = ParaGlob::Dimension();
               Coordonnee dir(dim); // direction de la force
               cout << "\n donner la direction de la normale au plan de reference ("<<dim<<" reels) ? ";
               dir.Lecture();
               Coordonnee point_plan(dim); // normale au plan
               cout << "\n donner un point du plan de reference ("<<dim<<" reels) ? ";
               point_plan.Lecture();
               double rho_g=0.;
               cout << "\n donner la valeur de rho*g (1 reels) ? ";
               rho_g=lect_double();
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort <<" " << nom_ref<<" ";
               sort << " PHYDRO ";
               dir.Affiche(sort,dim);
               point_plan.Affiche(sort,dim);
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               // le fait de passer la chaine "sans_limitation_" en paramètre
               // fait qu'il y aura interrogation pour savoir si l'on veut ou non
               // cet attribut en plus
               bloc.Info_commande_BlocCharge(sort,"sans_limitation_");
               sort << endl;
               break;
              }
           case 9:  // aero - hydrodynamique
             { string nom_maillage="";
               if (plusieurs_maillages)
                 { cout << "\n nom du maillage ? ";
                   nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
                 };
              
               cout << "\n nom de la reference surfacique ? ";
               string nom_ref=" ";
               nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
               if (nom_ref.at(0) != 'F')
                {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
                      << " doit etre F et non "<< nom_ref.at(0)<< " !!";
                 break;
                };
               string nom_courbeToVt="NULL";
               cout << "\n nom de la courbe to(Vt),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbeToVt=lect_chaine();cout << " nom lu = "<< nom_courbeToVt;
               string nom_courbef_n="NULL";
               cout << "\n nom de la courbe f_n(V),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbef_n=lect_chaine();cout << " nom lu = "<< nom_courbef_n;
               string nom_courbef_t="NULL";
               cout << "\n nom de la courbe f_t(V),  ou NULL si l'on n'en veut pas  ? ";
               nom_courbef_t=lect_chaine();cout << " nom lu = "<< nom_courbef_t;
               cout << "\n donner la masse volumique (1 reels) ? ";
               double charge;
               charge=lect_double(); cout << " valeur lue ="<< charge;
               // écriture de la condition
               if (plusieurs_maillages)
                {sort <<"\n nom_mail= "<<nom_maillage<<" ";}
               else {sort <<"\n";};
               sort << nom_ref
                    << " P_HYDRODYNA " << " " << nom_courbeToVt << " "
                    << nom_courbef_n <<" " << nom_courbef_t << " "
                    << charge << " ";
               // maintenant on s'occupe du cas courbe de charge et bornes
               BlocCharge< BlocDdlLim<BlocVecType> > bloc;
               bloc.Info_commande_BlocCharge(sort);
               sort << endl;
               break;
              }
           case 10:  // information
             { cout << "\n pour plus de details il faut se reporter a la documentation d'herezh++ ";
               break;
              }
           default:
             cout << "\n le cas "<<rep<<" n'est pas  traite !!, bizarre, il faut se plaindre !! ";
          };
        }    
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
        {  cout << "\n Erreur on attendait un des mots cles proposes !!, "
                << "\n redonnez une bonne valeur"
                << "\n ou taper f ou 0 pour sortir "; 
        };
      }; //-- fin du while
   sort << flush;

};

//----------------------------- METHODES PROTEGEES : -------------------------

    // declaration des initialisations en fonction du type de chargement
void Charge::Debut1()
   {paAlgo->Modif_Temps(0.);//temps = 0.;
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment = 0;multi = 0.; coeff = 0.;
   } ;
void Charge::Debut2()
   {paAlgo->Modif_Temps(0.);//temps = 0.;
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment = 0;multi = 0.; coeff = 0.;
   } ;
void Charge::Debut3()
   {paAlgo->Modif_Temps(0.);//temps = 0.;
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment = 0;multi = 0.; coeff = 1.; // modif 9dec2008, car a priori dans le type 3
	 // on veut toujours un chargement, j'espère que cela sera ok pour la statique
   } ;
void Charge::Debut4()
   {paAlgo->Modif_Temps(0.);//temps = 0.;
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment = 0;multi = 0.; coeff = 0.;
   } ;
void Charge::Debut5()
   {// on commence par récupérer la courbe
    CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
    // s'il y a un nombre de point inférieur   à  2 -> erreur
    if (fconnue_charge->NombrePoint() < 2)
     { cout << "\n **** erreur, le nombre de point definissant la courbe de chargement avec  le TYPE5 "
            << " doit etre au minimum de 2 (cf. doc), ajoutez des points ou changez de type de chargement ";
          Sortie(1);
      };             
    // cas où il y a plusieurs points  
    // on récupère le premier point de la courbe
    Coordonnee2 poin = fconnue_charge->Pt_nbi(1);
    paAlgo->Modif_Temps(poin(1));//temps initial;
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment = 0;multi = 0.;
    coeff = paAlgo->Multiplicateur() * poin(2);
    num_pt_courant_type5=1; ancien_num_pt_type5 = 0;
    // on modifie si possible également le  deltat
    Coordonnee2 poin2 = fconnue_charge->Pt_nbi(2);
    double deltat= poin2(1)-poin(1);;
    if (deltat <= ConstMath::trespetit)
     { cout << "\n **** erreur, variation du temps nulle avec le TYPE5 de chargement"
               << " temps = " << poin(1) << " numero du point " << ancien_num_pt_type5
               << "\n evolution non permise !! modifiez votre fichier de points ";
       if (ParaGlob::NiveauImpression() >= 4){ cout << "\n Charge::Debut5() ";};
       Sortie(1);         
      };
    if (paAlgo->Modif_Deltat(deltat))
        { cout << "\n **** erreur, attention la variation de deltat a ete refusee avec le TYPE5 de chargement"
               << " deltat demandee = " << deltat
               << "\n erreur de coherence dans le fichier d'entree, il ne faut pas imposer de contrainte min max ou"
               << "  autre sur le pas de temps, non compatible avec le TYPE5 qui lui, necessite que le pas de temps"
               << " soit impose par les points de la courbe de chargement "
               << " modifiez vos donnees d'entree ! "; 
          if (ParaGlob::NiveauImpression() >= 4){ cout << "\n Charge::Debut5() ";};
          Sortie(1);         
         };
    };  
void Charge::Debut6()
  { cout << "\n methode non encore implantee \n";
    cout << "void Charge::Debut6()" << endl;
    Sortie (1);
   }; 
void Charge::Debut7()
  { cout << "\n methode non encore implantee \n";
    cout << "void Charge::Debut7()" << endl;
    Sortie (1);
   }; 
    // declaration de l'avancement en fonction du type de chargement
bool Charge::Avance1()
  { double vieuxcoef = coeff;
    bool retour = false; // init
    // sauvegarde des paramètres avant avancement
    double temps = paAlgo->Variables_de_temps().TempsCourant();//temps;
    temps_sauve = temps; 
    multi_sauve = multi;
    coeff_sauve = coeff;
    // traitement
    temps +=paAlgo->Deltat(); // cas courant
    // éventuellement limitation
    if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
        && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
        {// calcul du nouveau deltat
         double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
         // on recadre éventuellement dans les bornes le delta t
         paAlgo->Modif_Detat_dans_borne(nouveau_temps);
         // on modifie le deltat
         paAlgo->Modif_Deltat(nouveau_temps);
         // on calcul le temps courant : si tout c'est bien passé on est au maxi
         temps = temps_sauve + paAlgo->Deltat();
         retour = true;
        };
    // mise à jour du temps courant
    paAlgo->Modif_Temps(temps);
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment++;
    if (temps < tabType(1))
      {// fonction lineaire en fonction du temps
       multi = paAlgo->Multiplicateur() * paAlgo->Deltat()/tabType(1);
       coeff += multi;
      }
    else
      { // palier
        coeff = paAlgo->Multiplicateur();
        multi = coeff - vieuxcoef;
      };
    // retour
    return retour;
   }; 
bool Charge::Avance2()
  { double vieuxcoef = coeff;
    bool retour = false; // init
    // sauvegarde des paramètres avant avancement
    double temps = paAlgo->Variables_de_temps().TempsCourant();
    temps_sauve = temps; 
    multi_sauve = multi;
    coeff_sauve = coeff;
    // traitement
    temps +=paAlgo->Deltat();
    // éventuellement limitation
    if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
        && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
        {// calcul du nouveau deltat
         double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
         // on recadre éventuellement dans les bornes le delta t
         paAlgo->Modif_Detat_dans_borne(nouveau_temps);
         // on modifie le deltat
         paAlgo->Modif_Deltat(nouveau_temps);
         // on calcul le temps courant : si tout c'est bien passé on est au maxi
         temps = temps_sauve + paAlgo->Deltat();
         retour = true;
        };
    // mise à jour du temps courant
    paAlgo->Modif_Temps(temps);
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment++;
    if (temps < tabType(1))
      {// fonction lineaire en fonction du temps
       multi = paAlgo->Multiplicateur() * paAlgo->Deltat()/tabType(1);
       coeff += multi;
       }
    else if ((temps >= tabType(1)) && (temps <= tabType(2)))
     // phase de stabilisation c-a-dire le palier
      { // palier
        coeff = paAlgo->Multiplicateur();
        multi = coeff - vieuxcoef;
       }    
    else 
     // on a dépassé t2, les coef sont mis à zéro brutalement
      {
        coeff = 0.;
        multi = 0.;
      };
    // retour
    return retour;
   };
bool Charge::Avance3()
  { double vieuxcoef = coeff;
    bool retour = false; // init
    // sauvegarde des paramètres avant avancement
    double temps = paAlgo->Variables_de_temps().TempsCourant();
    temps_sauve = temps; 
    multi_sauve = multi;
    coeff_sauve = coeff;
    // traitement
    temps +=paAlgo->Deltat();
    // éventuellement limitation
    if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
        && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
        {// calcul du nouveau deltat
         double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
         // on recadre éventuellement dans les bornes le delta t
         paAlgo->Modif_Detat_dans_borne(nouveau_temps);
         // on modifie le deltat
         paAlgo->Modif_Deltat(nouveau_temps);
         // on calcul le temps courant : si tout c'est bien passé on est au maxi
         temps = temps_sauve + paAlgo->Deltat();
         retour = true;
        };
    // mise à jour du temps courant
    paAlgo->Modif_Temps(temps);
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment++;
    // ici le coefficient multiplicateur est 1 quelque soit le temps
    coeff = 1.;
    multi = coeff - vieuxcoef;; 
    // retour
    return retour;
   };

bool Charge::Avance4()
  { double vieuxcoef = coeff;
    bool retour = false; // init
    // sauvegarde des paramètres avant avancement
    double temps = paAlgo->Variables_de_temps().TempsCourant();
    temps_sauve = temps; 
    multi_sauve = multi;
    coeff_sauve = coeff;
    // traitement
    temps +=paAlgo->Deltat();
    // éventuellement limitation
    if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
        && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
        {// calcul du nouveau deltat
         double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
         // on recadre éventuellement dans les bornes le delta t
         paAlgo->Modif_Detat_dans_borne(nouveau_temps);
         // on modifie le deltat
         paAlgo->Modif_Deltat(nouveau_temps);
         // on calcul le temps courant : si tout c'est bien passé on est au maxi
         temps = temps_sauve + paAlgo->Deltat();
         retour = true;
        };
    // mise à jour du temps courant
    paAlgo->Modif_Temps(temps);
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    compteur_essai_increment++;
    coeff = paAlgo->Multiplicateur() * f_charge->Valeur(temps);
    multi = coeff - vieuxcoef;
    // retour
    return retour;
   };

bool Charge::Avance5()
  { double vieuxcoef = coeff;
    bool retour = false; // init
    // sauvegarde des paramètres avant avancement
    double temps = paAlgo->Variables_de_temps().TempsCourant();
    temps_sauve = temps; 
    multi_sauve = multi;
    coeff_sauve = coeff;
    // --- traitement
    // on commence par récupérer la courbe
    CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
    ancien_num_pt_type5 = num_pt_courant_type5;
    // on regarde si l'on peut incrémenter le temps
    if (num_pt_courant_type5 < fconnue_charge->NombrePoint())
     { // ok
       num_pt_courant_type5++; // incrémente le num de point
       // récup du point
       Coordonnee2 poin = fconnue_charge->Pt_nbi(num_pt_courant_type5);
       temps = poin(1);
       paAlgo->Modif_Temps(temps); // on affecte le temps
       ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
       // on modifie si possible également le  deltat
       double deltat= temps-temps_sauve;
       if (deltat <= ConstMath::trespetit)
        { cout << "\n **** erreur, variation du temps nulle avec le TYPE5 de chargement"
               << " temps = " << temps << " numero du point " << ancien_num_pt_type5
               << "\n evolution non permise !! modifiez votre fichier de points "; 
          Sortie(1);         
         }
       if (paAlgo->Modif_Deltat(deltat))
        { cout << "\n **** Erreur , attention la variation de deltat a ete refusee avec le TYPE5 de chargement"
               << " deltat demandee = " << deltat 
               << "\n erreur de coherence dans le fichier d'entree, il ne faut pas imposer de contrainte min max ou"
               << "  autre sur le pas de temps, non compatible avec le TYPE5 qui lui, necessite que le pas de temps"
               << " soit impose par les points de la courbe de chargement "
               << " modifiez vos donnees d'entree ! "; 
          Sortie(1);         
         }
       compteur_essai_increment++;
       coeff = paAlgo->Multiplicateur() * poin(2);
       multi = coeff - vieuxcoef;
       retour = true;
      };
    // sinon on ne fait rien, mais le calcul va s'arrêter  
    // retour
    return retour;
   }; 
bool Charge::Avance6()
  { cout << "\n methode non encore implantee \n";
    cout << "double Charge::Avance6()" << endl;
    Sortie (1);
    return false;
   }; 
bool Charge::Avance7()
  { cout << "\n methode non encore implantee \n";
    cout << "double Charge::Avance7()" << endl;
    Sortie (1);
    return false;
   };
    // declaration du retour à l'incrément précédent en fonction du type de chargement
void Charge::Precedent1()
  { // récupération des paramètres avant avancement
    paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve; 
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    multi = multi_sauve;
    coeff = coeff_sauve;
   }; 
void Charge::Precedent2()
  { // récupération des paramètres avant avancement
    paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve; 
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    multi = multi_sauve;
    coeff = coeff_sauve;
   }; 
void Charge::Precedent3()
  { // récupération des paramètres avant avancement
    paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve; 
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    multi = multi_sauve;
    coeff = coeff_sauve;
   }; 
void Charge::Precedent4()
  { // récupération des paramètres avant avancement
    paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve; 
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    multi = multi_sauve;
    coeff = coeff_sauve;
   }; 
void Charge::Precedent5()
  { // récupération des paramètres avant avancement
    paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve; 
    ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
    multi = multi_sauve;
    coeff = coeff_sauve;
    num_pt_courant_type5=ancien_num_pt_type5;
   }; 
void Charge::Precedent6()
  { cout << "\n methode non encore implantee \n";
    cout << "double Charge::Precedent6()" << endl;
    Sortie (1);
   }; 
void Charge::Precedent7()
  { cout << "\n methode non encore implantee \n";
    cout << "double Charge::Precedent7()" << endl;
    Sortie (1);
   }; 

    // declaration de la fin en fonction du type de chargement
    //  0 : la fin n'est pas valide, on continue
    //  1 : temps fin dépassé
    //  2 : compteur_increment dépassé
    //  3 : compteur_essai_increment dépassé
    // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
    //     puis ensuite le compteur d'incréments
    //     puis le nombre d'essai maxi, puis enfin le cas normal
    // si affichage est true, affichage d'un message

int Charge::Fin1(const int & icharge,bool affichage)
  { double temps = paAlgo->Variables_de_temps().TempsCourant();
    if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
         { cout << "\n       >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
       return  1;
      } 
//    else if (icharge >= paAlgo->Maxincre())
    else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
      if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
                          << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
                          << endl ;
      return  2;
      }
    else if (compteur_essai_increment > paAlgo->Max_essai_incre())
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
      if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
      return  3;
      }
    else
      return 0;
   }; 
int Charge::Fin2(const int & icharge,bool affichage)
  { double temps = paAlgo->Variables_de_temps().TempsCourant();
    if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
          { cout << "\n       >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
       return  1;
     }
//    else if (icharge >= paAlgo->Maxincre())
    else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
      if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
                          << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
                          << endl ;
      return  2;
     }
    else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
     {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
      return  3;
      }
    else
      return 0;
   }; 
int Charge::Fin3(const int & icharge,bool affichage)
  { double temps = paAlgo->Variables_de_temps().TempsCourant();
    if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
        if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
          { cout << "\n       >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps  << endl ;};
        return  1;
     }
//    else if (icharge >= paAlgo->Maxincre())
    else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
                          << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
                          << endl ;
       return  2;
      }
    else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
      if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
      return  3;
     }
    else
      return 0;
   }; 
int Charge::Fin4(const int & icharge,bool affichage)
  { double temps = paAlgo->Variables_de_temps().TempsCourant();
    if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
        if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
          { cout << "\n       >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps  << endl ;};
        return  1;
     }
//    else if (icharge >= paAlgo->Maxincre())
    else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
                          << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
                          << endl ;
       return  2;
     }
    else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
       return  3;
     }
    else
      return 0;
   }; 
int Charge::Fin5(const int & icharge,bool affichage)
  { // on commence par récupérer la courbe
    CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
    double temps = paAlgo->Variables_de_temps().TempsCourant(); // puis le temps
    if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
        if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
          { cout << "\n       >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps  << endl ;};
        return  1;
     }
    else if ( num_pt_courant_type5 == fconnue_charge->NombrePoint())
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n   >>>> dernier temps de la courbe de charge atteint <<<<<   " << endl ;
       return 1;
     }
//    else if (icharge >= paAlgo->Maxincre())
    else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
                          << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
                          << endl ;
       return  2;
      }
    else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
     {
     #ifdef UTILISATION_MPI
      if (ParaGlob::Monde()->rank() == 0)
     #endif
       if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
       return  3;
     }
    else
      return 0;
   }; 
int Charge::Fin6(const int & icharge,bool affichage)
  { cout << "\n methode non encore implantee \n";
    cout << "int Charge::Fin6()" << endl;
    Sortie (1);
    return 0;
   }; 
int Charge::Fin7(const int & icharge,bool affichage)
  { cout << "\n methode non encore implantee \n";
    cout << "int Charge::Fin7()" << endl;
    Sortie (1);
    return 0;
   };
   
   
    
