// FICHIER : Loi_maxwell3D.cp
// CLASSE : Loi_maxwell3D


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

# include <iostream>
using namespace std;  //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "TypeConsTens.h"
#include "ParaGlob.h"
#include "ConstMath.h"
#include "CharUtil.h"


#include "Loi_maxwell3D.h"

#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"


Loi_maxwell3D::Loi_maxwell3D () :  // Constructeur par defaut
  Loi_comp_abstraite(MAXWELL3D,CAT_THERMO_MECANIQUE,3),E(-ConstMath::trespetit),nu(-2.*ConstMath::trespetit)
  ,mu(-ConstMath::trespetit),mu_p(-ConstMath::trespetit),existe_mu_p(false),depend_de_D(0)
  ,E_temperature(NULL),mu_temperature(NULL),mu_p_temperature(NULL),fac_mu_cissionD(NULL),fac_E_cissionD(NULL)
  ,depend_de_eps(0),fac_mu_Mises_Eps(NULL),fac_E_Mises_Eps(NULL)
  ,type_derive(-1),seule_deviatorique(false)
  // --- dépendance éventuelle à la cristalinité
  ,depend_cristalinite(false),nc(0.),tauStar(0.),D1(0.),D2(0.),D3(0.),A1(0.),At2(0.),C1(0.)
  ,taux_crista(0.),volumique_visqueux(false),crista_aux_noeuds(false)
  ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),I_x_D_HHHH(),I_xbarre_D_HHHH(),d_sig_t_HHHH()
  ,d_spherique_sig_t_HHHH()
   { };
	

// Constructeur de copie
Loi_maxwell3D::Loi_maxwell3D (const Loi_maxwell3D& loi) :
	Loi_comp_abstraite(loi),E(loi.E),nu(loi.nu)
	,mu(loi.mu),mu_p(loi.mu_p),existe_mu_p(loi.existe_mu_p)
	,type_derive(loi.type_derive),depend_de_D(loi.depend_de_D)
 ,E_temperature(loi.E_temperature),mu_temperature(loi.mu_temperature)
 ,mu_p_temperature(loi.mu_p_temperature)
 ,fac_mu_cissionD(loi.fac_mu_cissionD),fac_E_cissionD(loi.fac_E_cissionD)
 ,depend_de_eps(loi.depend_de_eps)
 ,fac_mu_Mises_Eps(loi.fac_mu_Mises_Eps),fac_E_Mises_Eps(loi.fac_E_Mises_Eps)
 ,seule_deviatorique(loi.seule_deviatorique)
 // --- dépendance éventuelle à la cristalinité
 ,depend_cristalinite(loi.depend_cristalinite),nc(loi.nc),tauStar(loi.tauStar)
 ,D1(loi.D1),D2(loi.D2),D3(loi.D3),A1(loi.A1),At2(loi.At2),C1(loi.C1)
 ,taux_crista(0.),volumique_visqueux(loi.volumique_visqueux),crista_aux_noeuds(loi.crista_aux_noeuds)
  ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),I_x_D_HHHH(),I_xbarre_D_HHHH(),d_sig_t_HHHH()
  ,d_spherique_sig_t_HHHH()

	 {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
   //--- dependance à la température éventuelle
   if (E_temperature != NULL)
	  	if (E_temperature->NomCourbe() == "_") 
	  		E_temperature = Courbe1D::New_Courbe1D(*(loi.E_temperature));
	  if (mu_temperature != NULL)	
      	if (mu_temperature->NomCourbe() == "_") 
      	  mu_temperature = Courbe1D::New_Courbe1D(*(loi.mu_temperature));
   if (mu_p_temperature != NULL)
       if (mu_p_temperature->NomCourbe() == "_") 
           mu_p_temperature = Courbe1D::New_Courbe1D(*(loi.mu_p_temperature));
   //--- dependance à D éventuelle
   if (fac_mu_cissionD != NULL)  
        if (fac_mu_cissionD->NomCourbe() == "_") 
          fac_mu_cissionD = Courbe1D::New_Courbe1D(*(loi.fac_mu_cissionD));;
   if (fac_E_cissionD != NULL)  
        if (fac_E_cissionD->NomCourbe() == "_") 
          fac_E_cissionD = Courbe1D::New_Courbe1D(*(loi.fac_E_cissionD));;
   //--- dependance à epsilon éventuelle
   if (fac_mu_Mises_Eps != NULL)  
        if (fac_mu_Mises_Eps->NomCourbe() == "_") 
          fac_mu_Mises_Eps = Courbe1D::New_Courbe1D(*(loi.fac_mu_Mises_Eps));;
   if (fac_E_Mises_Eps != NULL)  
        if (fac_E_Mises_Eps->NomCourbe() == "_") 
          fac_E_Mises_Eps = Courbe1D::New_Courbe1D(*(loi.fac_E_Mises_Eps));;
  };

Loi_maxwell3D::~Loi_maxwell3D ()
// Destructeur 
{ 
      //--- dependance à la température éventuelle
  if (E_temperature != NULL)
      if (E_temperature->NomCourbe() == "_") delete E_temperature;
  if (mu_temperature != NULL)
      if (mu_temperature->NomCourbe() == "_") delete mu_temperature;
  if (mu_p_temperature != NULL)
      if (mu_p_temperature->NomCourbe() == "_") delete mu_p_temperature;
      //--- dependance à D éventuelle
  if (fac_mu_cissionD != NULL)
      if (fac_mu_cissionD->NomCourbe() == "_") delete fac_mu_cissionD;
  if (fac_E_cissionD != NULL)
      if (fac_E_cissionD->NomCourbe() == "_") delete fac_E_cissionD;
      //--- dependance à epsilon éventuelle
  if (fac_mu_Mises_Eps != NULL)
      if (fac_mu_Mises_Eps->NomCourbe() == "_") delete fac_mu_Mises_Eps;
  if (fac_E_Mises_Eps != NULL)
      if (fac_E_Mises_Eps->NomCourbe() == "_") delete fac_E_Mises_Eps;
};

// Lecture des donnees de la classe sur fichier
void Loi_maxwell3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
                                             ,LesFonctions_nD& lesFonctionsnD)
  { // module d'young
    string nom;*(entreePrinc->entree) >> nom; 
    if (nom != "E=") 
         { cout << "\n erreur en lecture du module d'young, on aurait du lire le mot E=";
           entreePrinc->MessageBuffer("**erreur1 Loi_maxwell3D::LectureDonneesParticulieres (...**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);     
          }
    // on regarde si le module d'young est thermo dépendant
    if(strstr(entreePrinc->tablcar,"E_thermo_dependant_")!=0)
     { thermo_dependant=true;
       *(entreePrinc->entree) >> nom;
       if (nom != "E_thermo_dependant_") 
         { cout << "\n erreur en lecture de la thermodependance de E, on aurait du lire le mot cle E_thermo_dependant_"
                << " suivi du nom d'une courbe de charge ou de la courbe elle meme et on a lue: " << nom;
           entreePrinc->MessageBuffer("**erreur2 Loi_maxwell3D::LectureDonneesParticulieres (...**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);     
         };
       // lecture de la loi d'évolution du module d'young en fonction de la température
       *(entreePrinc->entree) >>  nom;    
       // on regarde si la courbe existe, si oui on récupère la référence 
       if (lesCourbes1D.Existe(nom)) 
         { E_temperature = lesCourbes1D.Trouve(nom);
         }
       else
        { // sinon il faut la lire maintenant
          string non_courbe("_");   
          E_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
          // lecture de la courbe
          E_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
        };
       entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
     }
    else
     { // lecture du module d'young 
       *(entreePrinc->entree) >> E ;
     }; 
      
    // lecture du coefficient de poisson 
    *(entreePrinc->entree) >> nom; 
    if (nom != "nu=") 
         { cout << "\n erreur en lecture du coefficient de poisson, on aurait du lire le mot nu="
                << "  et on a lue: " << nom;
           entreePrinc->MessageBuffer("**erreur3 Loi_maxwell3D::LectureDonneesParticulieres (...**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);     
         }
     else
      { *(entreePrinc->entree) >> nu;}; // lecture de la valeur     

    // lecture de la viscosité 
    *(entreePrinc->entree) >> nom; 
    if ((nom != "mu=") && (nom != "depend_cristalinite_"))
      { cout << "\n erreur en lecture de la viscosite, on aurait du lire le mot mu= ou depend_cristalinite_ "
             << " et on a lue: " << nom;
        entreePrinc->MessageBuffer("**erreur4 Loi_maxwell3D::LectureDonneesParticulieres (...**");
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);     
      };
    // maintenant deux cas suivant que l'on a une dépendance à la cristalinité ou non      
    if (nom == "mu=")
    {depend_cristalinite = false; 
     // on regarde si la viscosité est thermo dépendante
     if(strstr(entreePrinc->tablcar,"mu_thermo_dependant_")!=0)
     { thermo_dependant=true;
       *(entreePrinc->entree) >> nom;
       if (nom != "mu_thermo_dependant_") 
         { cout << "\n erreur en lecture de la thermodependance de mu, on aurait du lire le mot "
                << " cle mu_thermo_dependant_ suivi du nom d'une courbe de charge ou de la courbe "
                << " elle meme  et on a lue: " << nom;
           entreePrinc->MessageBuffer("**erreur5 Loi_maxwell3D::LectureDonneesParticulieres (...**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);     
         };
       // lecture de la loi d'évolution en fonction de la température
       *(entreePrinc->entree) >>  nom;    
       // on regarde si la courbe existe, si oui on récupère la référence 
       if (lesCourbes1D.Existe(nom)) 
         { mu_temperature = lesCourbes1D.Trouve(nom);
         }
       else
        { // sinon il faut la lire maintenant
          string non_courbe("_");   
          mu_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
          // lecture de la courbe
          mu_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
        };
       // prepa du flot de lecture
       entreePrinc->NouvelleDonnee(); 
     }
     else
     { // lecture de mu 
       *(entreePrinc->entree) >> mu ;
     };
     // on regarde si éventuellement il y a une viscosité sur la trace du tenseur des contraintes  
     if(strstr(entreePrinc->tablcar,"mu_p=")!=0)
     {// lecture de la viscosité pour la trace 
      existe_mu_p=true;
      *(entreePrinc->entree) >> nom; 
      if (nom != "mu_p=") 
         { cout << "\n erreur en lecture de la viscosite pour la trace, on aurait du lire le mot mu_p="
                << "  et on a lue: " << nom
                << "\n la viscosite pour la trace de sigma doit se trouver apres celle pour la partie"
                << " deviatoire ";
           entreePrinc->MessageBuffer("**erreur6 Loi_maxwell3D::LectureDonneesParticulieres (...**");
           throw (UtilLecture::ErrNouvelleDonnee(-1));
           Sortie(1);     
         };
      // on regarde si la viscosité est thermo dépendante
      if(strstr(entreePrinc->tablcar,"mu_p_thermo_dependant_")!=0)
       { thermo_dependant=true;
         *(entreePrinc->entree) >> nom;
         if (nom != "mu_p_thermo_dependant_") 
           { cout << "\n erreur en lecture de la thermodependance de mu_p, on aurait du lire le mot cle"
                  << "  mu_p_thermo_dependant_  (et on a lue: " << nom
                  << " ) suivi du nom d'une courbe de charge ou de la courbe elle meme ";
             entreePrinc->MessageBuffer("**erreur7 Loi_maxwell3D::LectureDonneesParticulieres (...**");
             throw (UtilLecture::ErrNouvelleDonnee(-1));
             Sortie(1);     
           };
         // lecture de la loi d'évolution en fonction de la température
         *(entreePrinc->entree) >>  nom;    
         // on regarde si la courbe existe, si oui on récupère la référence 
         if (lesCourbes1D.Existe(nom)) 
           { mu_p_temperature = lesCourbes1D.Trouve(nom);
           }
         else
          { // sinon il faut la lire maintenant
            string non_courbe("_");   
            mu_p_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
            // lecture de la courbe
            mu_p_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
          };
        // prepa du flot de lecture
        entreePrinc->NouvelleDonnee(); 
       }
      else
       { // lecture de mu_p 
         *(entreePrinc->entree) >> mu_p ;
       };
     }; 
    }
    else // venant du if (nom == "mu=")
    {// ici on est forcément dans le cas où nom == depend_cristalinite_
     depend_cristalinite = true;
     thermo_dependant=true; 
     entreePrinc->NouvelleDonnee(); // on passe une ligne
     // lecture exhaustive de tous les paramètres
     string nom1,nom2,nom3,nom4,nom5,nom6,nom7,nom8;
     *(entreePrinc->entree) >> nom1 >> nc >> nom2 >> tauStar >> nom3  >> D1 
                            >> nom4 >> D2 ;
     entreePrinc->NouvelleDonnee(); // on passe une ligne
     *(entreePrinc->entree) >> nom5 >> D3 >> nom6 >> A1
                            >> nom7 >> At2 >> nom8 >> C1;
     // gestion des erreurs éventuelles                       
     if ((nom1 != "nc=")||(nom2 != "tauStar=")||(nom3 != "D1=")||(nom4 != "D2=")
       ||(nom5 != "D3=")||(nom6 != "A1=")||(nom7 != "At2=")||(nom8 != "C1=") )                      
       { cout << "\n **** lecture incorecte pour les parametres de dependance de la cristalinite "
              << " un (ou plusieurs) identificateur de parametre est errone !! , ceux-ci sont: "
              << " nc= tauStar= D1= D2= D3= A1= At2= C1= , et on a lue: " 
              << nom1 << " " << nom2 << " " << nom3 << " " << nom4 << " "
              << nom5 << " " << nom6 << " " << nom7 << " " << nom8 << " ";
         entreePrinc->MessageBuffer("**erreur9 Loi_maxwell3D::LectureDonneesParticulieres (...**");
         throw (UtilLecture::ErrNouvelleDonnee(-1));
         Sortie(1);     
       };
     // on regarde si la partie volumique est visqueuse ou pas
     if(strstr(entreePrinc->tablcar,"volumique_visqueux_")!=0)
       { volumique_visqueux=true;};
     // on regarde si la cristalinité provient des noeuds ou des points d'intégration
     if(strstr(entreePrinc->tablcar,"crista_aux_noeuds_")!=0)
       { crista_aux_noeuds=true;};
     
     // prépa du flot
     entreePrinc->NouvelleDonnee(); // on passe une ligne
    };
       
    // on regarde ensuite si le type de dérivée est indiqué
    string toto;
    if (strstr(entreePrinc->tablcar,"type_derivee")!=NULL)
     { // lecture du type
       *(entreePrinc->entree) >> toto >> type_derive;
       if ((type_derive!=0)&&(type_derive!=-1)&&(type_derive!=1))
         { cout << "\n le type de derivee indique pour la loi de maxwell3D:  "<< type_derive
                << " n'est pas acceptable (uniquement -1 ou 0 ou 1), on utilise le type par defaut (-1 -> Jauman)"
                << " qui correspond à la derivee mixte de Lie deux fois covariantes, deux fois contravariantes";
           type_derive = -1;
         };
     };
    // on regarde s'il y a un coefficient multiplicateur de la viscosité de cission
	   // 1) ---- facteur  fonction de D ----
    depend_de_D = 0;   // par défaut
    if (strstr(entreePrinc->tablcar,"fac_mu_cissionD=")!=NULL)
      { *(entreePrinc->entree) >> toto ; //>> fac_mu_cissionD= ;
        depend_de_D = 1;
        #ifdef MISE_AU_POINT
          if (toto != "fac_mu_cissionD=")
             { cout << "\n erreur en lecture de la loi de maxwell3D, on attendait fac_mu_cissionD=  ";
               entreePrinc->MessageBuffer("**erreur8 Loi_maxwell3D::LectureDonneesParticulieres (...**");
               throw (UtilLecture::ErrNouvelleDonnee(-1));
               Sortie(1);
             };
          // on regarde également la cohérence
          if (depend_cristalinite)
            { cout << "\n **** utilisation d'une viscosite non lineaire (fac_mu_cissionD= ) qui est "
                   << " incoherente avec l'utilisation de la cristalinite, il faut utiliser l'un ou l'autre !!! ";
              entreePrinc->MessageBuffer("**erreur10 Loi_maxwell3D::LectureDonneesParticulieres (...**");
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie(1);     
            };
        #endif
        // lecture de la loi d'évolution du facteur multiplicatif en fonction de Sqrt(D_barre:D_barre)
        *(entreePrinc->entree) >>  nom;    
        // on regarde si la courbe existe, si oui on récupère la référence 
        if (lesCourbes1D.Existe(nom))  { fac_mu_cissionD = lesCourbes1D.Trouve(nom);}
        else { // sinon il faut la lire maintenant
             string non_courbe("_");   
             fac_mu_cissionD = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
             // lecture de la courbe
             fac_mu_cissionD->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
               } 
        // prepa du flot de lecture
        entreePrinc->NouvelleDonnee(); 
      }; 
    if (strstr(entreePrinc->tablcar,"fac_E_cissionD=")!=NULL)
      { *(entreePrinc->entree) >> toto ; //>> fac_E_cissionD= ;
        if (depend_de_D==1) {depend_de_D = 3;}else{depend_de_D =2;};
        #ifdef MISE_AU_POINT
          if (toto != "fac_E_cissionD=")
             { cout << "\n erreur en lecture de la loi de maxwell3D, on attendait fac_E_cissionD=  ";
               entreePrinc->MessageBuffer("**erreur8 Loi_maxwell3D::LectureDonneesParticulieres (...**");
               throw (UtilLecture::ErrNouvelleDonnee(-1));
               Sortie(1);
             };
        #endif
        // lecture de la loi d'évolution du facteur multiplicatif en fonction de Sqrt(D_barre:D_barre)
        *(entreePrinc->entree) >>  nom;    
        // on regarde si la courbe existe, si oui on récupère la référence 
        if (lesCourbes1D.Existe(nom))  { fac_E_cissionD = lesCourbes1D.Trouve(nom);}
        else { // sinon il faut la lire maintenant
               string non_courbe("_");
               fac_E_cissionD = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
               // lecture de la courbe
               fac_E_cissionD->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
             };
        // prepa du flot de lecture
        entreePrinc->NouvelleDonnee(); 
      };  
	 
    // 2) ----- facteur fonction de eps -----
    depend_de_eps = 0;   // par défaut
    if (strstr(entreePrinc->tablcar,"fac_mu_Mises_Eps=")!=NULL)
      { *(entreePrinc->entree) >> toto ; //>> fac_mu_Mises_Eps= ;
        depend_de_eps = 1;
        #ifdef MISE_AU_POINT
          if (toto != "fac_mu_Mises_Eps=")
             { cout << "\n erreur en lecture de la loi de maxwell3D, on attendait fac_mu_Mises_Eps=  ";
               entreePrinc->MessageBuffer("**erreur9 Loi_maxwell3D::LectureDonneesParticulieres (...**");
               throw (UtilLecture::ErrNouvelleDonnee(-1));
               Sortie(1);
             };
          // on regarde également la cohérence
          if (depend_cristalinite)
            { cout << "\n **** utilisation d'une viscosite non lineaire (fac_mu_Mises_Eps= ) qui est "
                   << " incoherente avec l'utilisation de la cristalinite, il faut utiliser l'un ou l'autre !!! ";
              entreePrinc->MessageBuffer("**erreur10 Loi_maxwell3D::LectureDonneesParticulieres (...**");
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie(1);     
            };
        #endif
        // lecture de la loi d'évolution du facteur multiplicatif en fonction de Sqrt(D_barre:D_barre)
        *(entreePrinc->entree) >>  nom;    
        // on regarde si la courbe existe, si oui on récupère la référence 
        if (lesCourbes1D.Existe(nom))  { fac_mu_Mises_Eps = lesCourbes1D.Trouve(nom);}
        else { // sinon il faut la lire maintenant
               string non_courbe("_");
               fac_mu_Mises_Eps = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
               // lecture de la courbe
               fac_mu_Mises_Eps->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
             };
        // prepa du flot de lecture
        entreePrinc->NouvelleDonnee(); 
      }; 
							 
    if (strstr(entreePrinc->tablcar,"fac_E_Mises_Eps=")!=NULL)
      { *(entreePrinc->entree) >> toto ; //>> fac_E_Mises_Eps= ;
        if (depend_de_eps==1) {depend_de_eps = 3;}else{depend_de_eps =2;};
        #ifdef MISE_AU_POINT
          if (toto != "fac_E_Mises_Eps=")
             { cout << "\n erreur en lecture de la loi de maxwell3D, on attendait fac_E_Mises_Eps=  ";
               entreePrinc->MessageBuffer("**erreur10 Loi_maxwell3D::LectureDonneesParticulieres (...**");
               throw (UtilLecture::ErrNouvelleDonnee(-1));
               Sortie(1);
             };
        #endif
        // lecture de la loi d'évolution du facteur multiplicatif en fonction de sqrt(2/3*Eps_barre:Eps_barre)
        *(entreePrinc->entree) >>  nom;    
        // on regarde si la courbe existe, si oui on récupère la référence 
        if (lesCourbes1D.Existe(nom))  { fac_E_Mises_Eps = lesCourbes1D.Trouve(nom);}
        else { // sinon il faut la lire maintenant
               string non_courbe("_");   
               fac_E_Mises_Eps = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
               // lecture de la courbe
               fac_E_Mises_Eps->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
             };
        // prepa du flot de lecture
        entreePrinc->NouvelleDonnee(); 
      }; 

	 // on regarde si le calcul est éventuellement uniquement déviatorique
    seule_deviatorique = false;   // par défaut
    if (strstr(entreePrinc->tablcar,"seule_deviatorique")!=NULL)
                 {seule_deviatorique=true;};    
    
    // prepa du flot de lecture
    if(strstr(entreePrinc->tablcar,"fin_coeff_MAXWELL3D")==0) 
     {entreePrinc->NouvelleDonnee();}
//    else
//     { cout << "\n erreur finale en lecture de la loi de maxwell3D, on attendait fin_coeff_MAXWELL3D, "
//            << " certaines grandeur on ete mal lues: on affiche les grandeurs actuellement lues";
//       Affiche();     
//       entreePrinc->MessageBuffer("**erreur7 Loi_maxwell3D::LectureDonneesParticulieres (...**");
//       throw (UtilLecture::ErrNouvelleDonnee(-1));
//       Sortie(1);
//      };

    // lecture éventuelle d'un niveau d'affichage
    string nom_class_methode("Loi_maxwell3D::LectureDonneesParticulieres (");
    if(strstr(entreePrinc->tablcar,"permet_affichage_")!=0)
     {// on lit le niveau de commentaire
//      string mot_cle("permet_affichage_");
//      entreePrinc->Lecture_un_parametre_int(0,nom_class_methode
//                   ,0, 10,mot_cle,permet_affichage);
      *(entreePrinc->entree) >> nom;
      Lecture_permet_affichage(entreePrinc,lesFonctionsnD);
      entreePrinc->NouvelleDonnee();// préparation du flot
     };

    // appel au niveau de la classe mère
    Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
                 (*entreePrinc,lesFonctionsnD);

  };
	 
// affichage de la loi
void Loi_maxwell3D::Affiche() const 
  { cout << " \n loi de comportement maxwell 3D ";
    if ( E_temperature != NULL) { cout << " module d'young thermo dependant " 
                                       << " courbe E=f(T): " << E_temperature->NomCourbe() <<" ";}
    else                        { cout << " module d'young  E = " << E ;};
    // coeff de poisson
    cout << " nu= " << nu << endl; 
    // viscosité déviatorique        
    if ( mu_temperature != NULL) { cout << " viscosite deviatorique thermo dependante " 
                                        << " courbe mu=f(T): " << mu_temperature->NomCourbe() <<" ";}
    else                         { cout << " viscosite deviatorique mu= " << mu ;} 
    // viscosité sphérique       
    if ( mu_p_temperature != NULL) { cout << " viscosite spherique thermo dependante " 
                                          << " courbe mu_p=f(T): " << mu_p_temperature->NomCourbe() <<" ";}
    else                           { cout << " viscosite spherique mu_p= " << mu_p ;} 
    switch (type_derive)
     { case -1: cout << ", et derivee de jauman pour la contrainte" << endl;break;
       case  0: cout << ", et derivee de Lie deux fois covariantes (Rivlin) pour la contrainte" << endl; break;
       case  1: cout << ", et derivee de Lie deux fois contravariantes (Oldroyd) pour la contrainte" << endl; break;
     };
    //--- facteur multiplicatif dépendant de D ----
    if ((depend_de_D==1)||(depend_de_D==3)) 
     { cout << " coef multiplicatif de la viscosite (pour une evolution non lineaire) " 
            << " courbe fac_mu_cissionD=f(D_barre:D_barre): " << fac_mu_cissionD->NomCourbe() <<" ";
     };
    if ((depend_de_D==2)||(depend_de_D==3)) 
     { cout << " coef multiplicatif du module d'young (pour une evolution non lineaire) " 
            << " courbe fac_E_cissionD=f(D_barre:D_barre): " << fac_E_cissionD->NomCourbe() <<" ";
     };
    //--- facteur multiplicatif dépendant de eps ----
    if ((depend_de_eps==1)||(depend_de_eps==3)) 
     { cout << " coef multiplicatif de la viscosite (pour une evolution non lineaire) " 
            << " courbe fac_mu_Mises_Eps=f(sqrt(2/3*Eps_barre:Eps_barre)): " << fac_mu_Mises_Eps->NomCourbe() <<" ";
     };
    if ((depend_de_eps==2)||(depend_de_eps==3)) 
     { cout << " coef multiplicatif du module d'young (pour une evolution non lineaire) " 
            << " courbe fac_E_Mises_Eps=f(sqrt(2/3*Eps_barre:Eps_barre)): " << fac_E_Mises_Eps->NomCourbe() <<" ";
     };

    cout << " seule_deviatorique= " << seule_deviatorique << " ";
    //------- cas éventuel de dépendance à la cristalinité ----------
    if (depend_cristalinite)
     { cout << "\n dependance a la cristalinite: parametres de la dependance= "
            << "nc=" << nc << "tauStar=" << tauStar << "D1=" << D1 << "D2=" << D2
            << "D3=" << D3 << "A1=" << A1 << "At2=" << At2 << "C1=" << C1 
            << " volumique_visqueux= " << volumique_visqueux << " " << crista_aux_noeuds << " ";
     };
    //------- niveau d'affichage -----
    cout << " niveau_affichage_local: ";
    Affiche_niveau_affichage();

    cout << endl;
    // appel de la classe mère
    Loi_comp_abstraite::Affiche_don_classe_abstraite();
  };
            
// affichage et definition interactive des commandes particulières à chaques lois
void Loi_maxwell3D::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
 {  ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
	   cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
	   string rep = "_";
    // procédure de lecture avec prise en charge d'un retour chariot
    rep = lect_return_defaut(true,"o");
    if (E == -ConstMath::trespetit) 
      { // on initialise à une valeur arbitraire
        E = 110000;}
    if (nu == -2.*ConstMath::trespetit)  { nu = 0.3;}; // valeur arbitraire   
    if (mu == -ConstMath::trespetit)  { mu = 0.15; }// on initialise à une valeur arbitraire
    if (mu_p == -ConstMath::trespetit)  { mu_p = 0.15; }// on initialise à une valeur arbitraire
    fac_mu_cissionD = NULL;  // pas de facteur multiplicatif de non linéarité pour mu en fonction de D
	   fac_E_cissionD = NULL; // pas de facteur multiplicatif de non linéarité pour E en fonction de D
    fac_mu_Mises_Eps = NULL;  // pas de facteur multiplicatif de non linéarité pour mu en fonction de Eps
	   fac_E_Mises_Eps = NULL; // pas de facteur multiplicatif de non linéarité pour E en fonction de Eps
    //-------- cristalinité éventuelle ------
    nc=0.3452; tauStar = 1.128e4; D1=2.780e14; D2= -15.; D3= 1.4e-7; A1= 29.94; At2 = 51.6; C1= 2171;
    volumique_visqueux = false;
     
    sort << "\n# .......  loi de comportement maxwell 3D ................................................................................"
         << "\n# |  module d'Young | coeff   |viscosite sur Dbarre| type de derivee objective utilisee |et eventuellement une fonction  |"
         << "\n# |                 |  de     | mu(obligatoire)    |  pour le calcul de la contrainte   | multiplicative de la viscosite |"
         << "\n# |       E         |Poisson  |puis sur trace(D)   |  type_derivee  (facultatif)        | pour une evolution non lineaire|"
         << "\n# |                 |         |mu_p(optionnelle)   |                                    | f(D) ou f(eps)                 |"
         << "\n#........................................................................................................................."
         << "\n# de maniere independante des parametres deja cites: il est possible d'indiquer que l'on souhaite"
         << "\n# un calcul uniquement deviatorique: pour cela il suffit de mettre a la fin des donnees le mot cle : seule_deviatorique "
         << "\n    E= "<< setprecision(8) << E << " nu= " << setprecision(8) << nu 
         << "    mu=   " << setprecision(8) << mu << "    mu_p=   " << setprecision(8) << mu_p 
         << " type_derivee  " << type_derive << " fac_mu_cissionD= " << "courbe_fac_mu_cissionD "   
         << "\n                fin_coeff_MAXWELL3D         " << endl;
	   if ((rep != "o") && (rep != "O" ) && (rep != "0") )
      { sort << "\n# le type de derivee est optionnel: = -1 -> derivee de jauman (valeur par defaut), "
         << "\n# = 0 -> derivee deux fois covariantes (ou de Rivlin), "
         << "\n# = 1 -> derivee deux fois contravariantes (ou d'Oldroyd)"
         << "\n# dans le cas ou l'on veut une valeur differente de la valeur par defaut il faut mettre le mot cle"
         << "\n# <type_derivee> suivi de la valeur -1 ou 0 ou 1"
         << "\n# \n# chaque parametre peut etre remplace par une fonction dependante de la temperature " 
         << "\n# pour ce faire on utilise un mot cle puis une nom de courbe ou la courbe directement comme avec "
         << "\n# les autre loi de comportement "
         << "\n# exemple pour le module d'young:             E=   E_thermo_dependant_   courbe1  "
         << "\n# exemple pour la viscosite sur Dbarre:       mu=   mu_thermo_dependant_   courbe2  "
         << "\n# exemple pour la viscosite sur trace(D):     mu_p=   mu_p_thermo_dependant_   courbe2  "
         << "\n# dans le cas d'une thermo-dependance et d'une dependance a D : mu = mu(T) * fac_mu_cissionD  "
         << "\n# idem pour E dependant de T et de D : E = E(T) * fac_E_cissionD  "
         << "\n# dans le cas ou on a une viscosite sur la partie spherique et une dependance a D et a T, la dependance "
			      << "\n# pour mu_p est la meme que pour mu a savoir: mu_p = mu_p(T) * fac_mu_cissionD  "
         << "\n# IMPORTANT: a chaque fois qu'il y a une thermodependence, il faut passer une ligne apres la description"
         << "\n# de la grandeur thermodependante, mais pas de passage à la ligne si se n'est pas thermo dependant "
         << "\n# Noter que la dependance a D est en fait une dependance a sqrt(D_barre:D_barre)  "
         << "\n# D'une maniere equivalente on peut avoir une dependance a sqrt(2/3*Eps_barre:Eps_barre)  "
         << "\n# Le fonctionnement est identique a la dependance a D, les mots cles associes sont:   "
         << "\n#  fac_E_Mises_Eps  fac_mu_Mises_Eps"
         << "\n#   "
         << "\n# --- dependance a la cristalinite ----"
         << "\n# Il est egalement possible de definir une viscosite dependante de la cristalinite, de la pression et de la"
         << "\n# temperature selon une evolution proposee par Hieber, S.Han et K.K.Wang (voir doc pour plus d'info)"
         << "\n# Dans le cas ou on veut activer cette option,  en lieu et place du mot cle mu= il faut indiquer "
         << "\n# le mot cle: depend_cristalinite_ , puis passer une ligne et sur la ligne qui suit, la liste exhaustive de tous "
         << "\n# les parametres demandes a savoir 8 grandeurs:"
         << "\n#  nc  tauStar  D1  D2  D3  A1  At2  C1  ensuite on passe une nouvelle ligne et on continue avec "
         << "\n# les parametres : type_derivee et eventuellement seule_deviatorique, "
         << "\n# par contre il est incoherent de definir avec la cristalinie, le parametre fac_mu_cissionD ou fac_mu_Mises_Eps !"
         << "\n# "
         << "\n# exemple d'utilisation: "
         << "\n#    E= "<< setprecision(8) << E << " nu= " << setprecision(8) << nu 
         <<         "depend_cristalinite_ "   
         << "\n#   nc=" << nc << "tauStar=" << tauStar << "D1="  << D1  << "D2=" << D2
         << "\n#   D3=" << D3 << "A1="      << A1      << "At2=" << At2 << "C1=" << C1 << " "
         <<       " volumique_visqueux_ # crista_aux_noeuds_ " 
         << "\n type_derivee  " << type_derive << " seule_deviatorique  "
         << "\n# Remarques importantes: dans le cas de l'utilisation de la cristalinite"
         << "\n# 1) par defaut seule la partie deviatorique depend de la viscosite."
         << "\n# 2) il n'est pas possible d'utiliser les mots cles: mu= ,  mu_p= , fac_mu_cissionD ou fac_mu_Mises_Eps"
         << "\n# 3) il est possible d'indiquer que l'on veut egalement de la  viscosite sur la partie volumique"
         << "\n#  pour cela, apres le dernier parametre (c-a-d C1) on indique le mot cle volumique_visqueux_ "
         << "\n# 4) dans le cas ou les parametres volumique_visqueux_ et seule_deviatorique existent"
         << "\n# conjointement, on ne tient pas compte de la viscosite volumique  !"
         << "\n# 5) Par defaut, la cristalinite est suppose connue au point d'integration (celui qui sert pour le "
         << "\n#   calcul de la loi). Il doit donc etre calcule par ailleurs, par exemple via la loi de"
         << "\n#   Hoffman (cf. documentation). Mais il est possible d'utiliser une cristalinite connue aux"
         << "\n#   noeuds (donc pouvant etre lue en entree. Pour ce faire il faut utiliser le mot cle "
         << "\n#   crista_aux_noeuds_ (a la suite ou avant le mot cle volumique_visqueux_) "
         << "\n# "
         << "\n# enfin il est possible de definir un niveau local d'affichage avec le mo cle : "
         << "\n# permet_affichage_ suivi d'un niveau entre 0 et 10"
         << "\n# ex: "
         << "\n# permet_affichage_ 3 "
         << "\n# "
         << "\n#   la derniere ligne doit contenir uniquement le mot cle:     fin_coeff_MAXWELL3D "
         << endl;
       };
    // appel de la classe mère
    Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);     
 };  		  	  

// test si la loi est complete
int Loi_maxwell3D::TestComplet()
    { int ret = LoiAbstraiteGeneral::TestComplet();
      if (E_temperature == NULL)
       {if (E == -ConstMath::trespetit) 
        { cout << " \n le module d'young n'est pas defini pour  la loi " << Nom_comp(id_comp)
               << '\n';
          ret = 0;
        };
       }                       
      if (nu == -2.*ConstMath::trespetit) 
       { cout << " \n le coefficient de poisson n'est pas défini pour  la loi " << Nom_comp(id_comp)
              << '\n';
         ret = 0;
       };
      if (!depend_cristalinite) 
       if ((mu_temperature == NULL) && (mu == -ConstMath::trespetit)) 
        { cout << " \n la viscosite n'est pas defini pour  la loi " << Nom_comp(id_comp)
               << '\n';
          ret = 0;
        };                       
      return ret; 
    }; 

// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_maxwell3D::Grandeur_particuliere
              (bool absolue, List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
 { // tout d'abord on récupère le conteneur
   SaveResulLoi_maxwell3D & save_resul = *((SaveResulLoi_maxwell3D*) saveDon);
   // ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas
   // on passe en revue la liste
   List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
   list<int>::iterator idecal=decal.begin();
   for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
     {TypeQuelconque& tipParticu = (*itq); // pour simplifier
      if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
       switch (tipParticu.EnuTypeQuelconque().EnumTQ())
       {  case E_YOUNG:
           // a) ----- cas du module d'Young actuelle
            { Tab_Grandeur_scalaire_double& tyTQ
                   = *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
              tyTQ(1+(*idecal))=save_resul.E;
              (*idecal)++; break;
            }
          case NU_YOUNG:
           // b) ----- cas du coef de Poisson actuel
            { Tab_Grandeur_scalaire_double& tyTQ
                  = *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
              tyTQ(1+(*idecal))=save_resul.nu;
              (*idecal)++; break;
            }
          case MU_VISCO:
           // b) ----- cas du coefficient de viscosité actuel
            { Tab_Grandeur_scalaire_double& tyTQ
                  = *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
              tyTQ(1+(*idecal))=save_resul.mu;
              (*idecal)++; break;
            }
          case MU_VISCO_SPHERIQUE:
           // b) ----- cas du coefficient de viscosité sphérique actuel
            { Tab_Grandeur_scalaire_double& tyTQ
                  = *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
              tyTQ(1+(*idecal))=save_resul.mu_p;
              (*idecal)++; break;
            }

          default: ;// on ne fait rien
       };

     };
};

// récupération de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_maxwell3D::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
 { // ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas
   Tableau <double> tab_1(1);
   Tab_Grandeur_scalaire_double grand_courant(tab_1);
   // def d'un type quelconque représentatif à chaque grandeur
   // a priori ces grandeurs sont défini aux points d'intégration identique à la contrainte par exemple
   // enu_ddl_type_pt est définit dans la loi Abtraite générale
   //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
   // a) $$$ cas du module d'Young actuelle
   {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
    for (itq=liTQ.begin();itq!=itqfin;itq++)
      if ((*itq).EnuTypeQuelconque() == E_YOUNG)
       { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
         int taille = tyTQ.Taille()+1;
         tyTQ.Change_taille(taille); nexistePas = false;
       };
    if (nexistePas)
      {TypeQuelconque typQ1(E_YOUNG,enu_ddl_type_pt,grand_courant);
       liTQ.push_back(typQ1);
      };
   };
   // b) $$$ cas du coefficient de Poisson actuel
   {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
    for (itq=liTQ.begin();itq!=itqfin;itq++)
      if ((*itq).EnuTypeQuelconque() == NU_YOUNG)
       { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
         int taille = tyTQ.Taille()+1;
         tyTQ.Change_taille(taille); nexistePas = false;
       };
    if (nexistePas)
      {TypeQuelconque typQ1(NU_YOUNG,enu_ddl_type_pt,grand_courant);
       liTQ.push_back(typQ1);
      };
   };
   // c) $$$ cas du coefficient de viscosité actuel
   {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
    for (itq=liTQ.begin();itq!=itqfin;itq++)
      if ((*itq).EnuTypeQuelconque() == MU_VISCO)
       { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
         int taille = tyTQ.Taille()+1;
         tyTQ.Change_taille(taille); nexistePas = false;
       };
    if (nexistePas)
      {TypeQuelconque typQ1(MU_VISCO,enu_ddl_type_pt,grand_courant);
       liTQ.push_back(typQ1);
      };
   };
   // d) $$$ cas du coefficient de viscosité sphérique actuel
   {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
    for (itq=liTQ.begin();itq!=itqfin;itq++)
      if ((*itq).EnuTypeQuelconque() == MU_VISCO_SPHERIQUE)
       { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
         int taille = tyTQ.Taille()+1;
         tyTQ.Change_taille(taille); nexistePas = false;
       };
    if (nexistePas)
      {TypeQuelconque typQ1(MU_VISCO_SPHERIQUE,enu_ddl_type_pt,grand_courant);
       liTQ.push_back(typQ1);
      };
   };

 };

// calcul d'un module d'young équivalent à la loi
double Loi_maxwell3D::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * )
 { if (seule_deviatorique) 
       return 0.; // dans le cas d'un calcul uniquement déviatorique, E équivalent = 0
   double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
   if (thermo_dependant) temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps);

   // intégration du coeff multiplicateur de la viscosité si nécessaire
   // ***** mais ici on considère que la vitesse et la déformation sont nulle *****
   double coe_mu=1.; // coeff multiplicateur par défaut
   double coe_E=1.; // coeff multiplicateur par défaut
   double II_D_barre = 0.; // init
   if ((depend_de_D!=0) || depend_cristalinite)
     { switch (depend_de_D) 
		     { case 1:coe_mu=fac_mu_cissionD->Valeur(sqrt(II_D_barre));break;
			      case 2:coe_E=fac_E_cissionD->Valeur(sqrt(II_D_barre));break;
			      case 3:coe_mu=fac_mu_cissionD->Valeur(sqrt(II_D_barre));
			             coe_E=fac_E_cissionD->Valeur(sqrt(II_D_barre));break;
		     };
     };
	  // idem dans le cas d'une dépendance à eps	
   double II_eps_barre = 0.;double eps_mises = 0.; // init
   if (depend_de_eps!=0)
    { switch (depend_de_eps) 
		     { case 1:coe_mu *= fac_mu_Mises_Eps->Valeur(eps_mises);break;
			      case 2:coe_E *= fac_E_Mises_Eps->Valeur(eps_mises);break;
			      case 3:coe_mu *= fac_mu_Mises_Eps->Valeur(eps_mises);
			             coe_E *= fac_E_Mises_Eps->Valeur(eps_mises);break;
		     };
    };
 // --- cas de la thermo dépendance, on calcul les grandeurs matérielles -----
   if (E_temperature != NULL) E = E_temperature->Valeur(*temperature);
   if (depend_cristalinite) // cas d'une dépendance à la température via la cristalinité, 
	  // ici on considère que la pression est nulle
      { double P = 0.;
        // gamma = 2 D_12, si on a un essai de cisaillement pur en 1 2: II_D_barre = 2*(D^1_2)**2
        // d'où gamm_point  
        double gamma_point =  0.; 
        mu = mu_p = ViscositeCristaline(P,gamma_point);
      }
   else // sinon c'est le cas classique de dépendance ou non à la température 
      {if (mu_temperature != NULL) mu = mu_temperature->Valeur(*temperature);
       if (mu_p_temperature != NULL) mu_p = mu_p_temperature->Valeur(*temperature);
      };

   double mu_coe = mu * coe_mu; // pour simplifier
   double E_coe = E * coe_E; // pour simplifier

   // module d'young équivalent
	  double E_equi = (E_coe*mu_coe/(mu_coe+E_coe*deltat));
	  return E_equi; 
//   return (E*mu/(mu+E*deltat)); 
 };
  
//----- 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 Loi_maxwell3D::Lecture_base_info_loi(istream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
                                             ,LesFonctions_nD& lesFonctionsnD)
{ string nom; 
	 if (cas == 1)
	  { ent >> nom; 
	    if (nom != "maxwell3D")
	     { cout << "\n erreur en lecture de la loi : maxwell3D, on attendait le mot cle : maxwell3D "
	            << "\n Loi_maxwell3D::Lecture_base_info_loi(...";
	       Sortie(1);
      };
	    // ensuite normalement il n'y a pas de pb de lecture puisque c'est écrit automatiquement (sauf en debug)        
	    ent >> nom >> type_derive >> nom >> seule_deviatorique;
	    ent >> nom; // module_d_young
	    bool test; ent >> test;
	    if (!test)
	     { ent >> E;
	       if (E_temperature != NULL) {if (E_temperature->NomCourbe() == "_") delete E_temperature; E_temperature = NULL;};
      }
	    else
	     { ent >> nom; E_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,E_temperature); };
     // le coeff de poisson
     ent >> nom >> nu;    
     // viscosité déviatoire
	    ent >> nom >> test;
	    if (!test)
	     { ent >> mu;
	       if (mu_temperature != NULL) {if (mu_temperature->NomCourbe() == "_") delete mu_temperature; mu_temperature = NULL;};
      }
	    else
	     { ent >> nom; mu_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,mu_temperature); };
	    // viscosité sphérique
	    ent >> nom >> test >> existe_mu_p;
	    if (!test)
	     { ent >> mu_p;
	       if (mu_p_temperature != NULL) {if (mu_p_temperature->NomCourbe() == "_") delete mu_p_temperature; mu_p_temperature = NULL;};
      }
	    else
	     { ent >> nom; mu_p_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,mu_p_temperature); };
	     
	    // la fonction multiplicative de la viscosité de cission
		   // --- dépendance à D
	    ent >> nom >> depend_de_D ;  
	    if ((depend_de_D==1)||(depend_de_D==3))
	     { ent >> nom; fac_mu_cissionD = lesCourbes1D.Lecture_pour_base_info(ent,cas,fac_mu_cissionD); };
	    // la fonction multiplicative de E fonction dans ce cas de D
	    if ((depend_de_D==2)||(depend_de_D==3))
	     { ent >> nom; fac_E_cissionD = lesCourbes1D.Lecture_pour_base_info(ent,cas,fac_E_cissionD); };
       // --- dépendance à eps
	    ent >> nom >> depend_de_eps ;  
	    if ((depend_de_eps==1)||(depend_de_eps==3))
	     { ent >> nom; fac_mu_Mises_Eps = lesCourbes1D.Lecture_pour_base_info(ent,cas,fac_mu_Mises_Eps); };
	    // la fonction multiplicative de E fonction dans ce cas de eps
	    if ((depend_de_eps==2)||(depend_de_eps==3))
	     { ent >> nom; fac_E_Mises_Eps = lesCourbes1D.Lecture_pour_base_info(ent,cas,fac_E_Mises_Eps); };

     // --- cas éventuel de la cristalinité ---
     ent >> nom >> depend_cristalinite;
     if (depend_cristalinite)
      { ent >> nom >>  nc >> nom >>  tauStar >> nom >>  D1 >> nom >>  D2
              >> nom >>  D3 >> nom >>  A1 >> nom >>  At2 >> nom >>  C1
              >> volumique_visqueux >> crista_aux_noeuds ;
      };
     //------- niveau d'affichage -----
     Lecture_permet_affichage(ent,cas,lesFonctionsnD);
	  };
	 Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); 
};
	     
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_maxwell3D::Ecriture_base_info_loi(ostream& sort,const int cas)
{ if (cas == 1)
   { sort << " maxwell3D " << " type_derivee " << type_derive 
          << " seule_deviatorique= " << seule_deviatorique << " ";
	    sort << "\n  module_d_young ";             
     if (E_temperature == NULL)
      { sort << false << " " << E << " ";}
     else 
      { sort << true << " fonction_E_temperature ";
        LesCourbes1D::Ecriture_pour_base_info(sort,cas,E_temperature);
      }; 
     sort << " nu " << nu << " ";  
	    sort << "\n  viscosite_deviatoire ";             
     if (mu_temperature == NULL)
      { sort << false << " " << mu << " ";}
     else 
      { sort << true << " fonction_mu_temperature ";
        LesCourbes1D::Ecriture_pour_base_info(sort,cas,mu_temperature);
      }; 
	    sort << "\n  viscosite_spherique " << existe_mu_p << " ";
     if (mu_p_temperature == NULL)
      { sort << false << " " << mu_p << " ";}
     else 
      { sort << true << " fonction_mu_p_temperature ";
        LesCourbes1D::Ecriture_pour_base_info(sort,cas,mu_p_temperature);
      }; 
   // --- dépendance à D 	 
	    sort << "\n   depend_de_D " << depend_de_D << " ";  
	    if ((depend_de_D==1)||(depend_de_D==3)) // cas ou il y a une fonction multiplicative           
      {  sort << " fonction_fac_mu_cissionD ";
          LesCourbes1D::Ecriture_pour_base_info(sort,cas,fac_mu_cissionD);
      };
	    if ((depend_de_D==2)||(depend_de_D==3)) // cas ou il y a une fonction multiplicative pour E           
      {  sort << " fonction_fac_E_cissionD ";
          LesCourbes1D::Ecriture_pour_base_info(sort,cas,fac_E_cissionD);
      };
   // --- dépendance à Eps
	    sort << "\n   depend_de_Eps " << depend_de_eps << " ";  
	    if ((depend_de_eps==1)||(depend_de_eps==3)) // cas ou il y a une fonction multiplicative           
      {  sort << " fonction_fac_mu_Mises_Eps ";
          LesCourbes1D::Ecriture_pour_base_info(sort,cas,fac_mu_Mises_Eps);
      };
	    if ((depend_de_eps==2)||(depend_de_eps==3)) // cas ou il y a une fonction multiplicative pour E           
      {  sort << " fonction_fac_E_Mises_Eps ";
          LesCourbes1D::Ecriture_pour_base_info(sort,cas,fac_E_Mises_Eps);
      };
     // --- cas éventuel de la cristalinité ---
     if (depend_cristalinite)
     	{ sort << "\n cristalinite  1 ";
          sort << "nc=" << nc << "tauStar=" << tauStar << "D1=" << D1 << "D2=" << D2
               << "D3=" << D3 << "A1=" << A1 << "At2=" << At2 << "C1=" << C1 << " " 
               << " volumique_visqueux= " << volumique_visqueux << " " << crista_aux_noeuds << " ";
     	}
     else
     	{ sort << "\n cristalinite  0 ";
     	};
     //------- niveau d'affichage -----
     Affiche_niveau_affichage(sort,cas);

   };  
  // appel de la classe mère
  Loi_comp_abstraite::Ecriture_don_base_info(sort,cas);
};

 // ========== codage des METHODES VIRTUELLES  protegees:================
        // calcul des contraintes a t+dt
void Loi_maxwell3D::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& DepsBB_,DdlElement & ,
             TenseurBB & gijBB_t_,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_ ,
             TenseurBB& , TenseurBB& gijBB_ ,
		  	 TenseurHH & gijHH_,Tableau <TenseurBB *>& ,double& ,double& ,TenseurHH & sigHH_
		  	,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double&  module_cisaillement
		  	,const Met_abstraite::Expli_t_tdt& )
 {   
   #ifdef MISE_AU_POINT	 	 
	   if (DepsBB_.Dimension() != 3)
	    { cout << "\nErreur : la dimension devrait etre 3 !\n";
		     cout << " Loi_maxwell3D::Calcul_SigmaHH\n";
		     Sortie(1);
     };
   #endif
    const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_); // passage en dim 3
    const Tenseur3BB & DepsBB = *((Tenseur3BB*) &DepsBB_); // passage en dim 3
    const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_); //   "      "  "  "
    const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_); //   "      "  "  "
    const Tenseur3BB & gijBB_t = *((Tenseur3BB*) &gijBB_t_); //   "      "  "  "
    Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_);  //   "      "  "  "
    Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t);  //   "      "  "  "
 // --- opération de transport du tenseur sigma(t), de t à tdt
    // tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
    Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
    switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
     {case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
        {sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
         sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
         sigHH_n = gijHH * sigBH_n ; 
         sigBB_n = sigBH_n * gijBB; break;}
      case 0: // cas d'une dérivée de Lie deux fois covariantes
        {sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
         sigBH_n = sigBB_n * gijHH ;
         sigHH_n = gijHH * sigBH_n ; break;}
      case 1: // cas d'une dérivée de Lie deux fois contravariantes
        {sigHH_n = sigHH_nn;
         sigBH_n = gijBB * sigHH_n;
         sigBB_n = sigBH_n * gijBB; 
         break;}
     };    
 // ---- calcul relatif aux déviateurs : déformations et vitesse de déformation -----
    static const double untier=1./3.;
    Tenseur3BH  DepsBH =  DepsBB * gijHH;
    double IDeps=DepsBH.Trace();
    Tenseur3BH Deps_barre_BH = DepsBH - (untier * IDeps) * IdBH3;
    // 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;
     }; 
    // le calcul de la contrainte correspond à l'intégration d'une équation différencielle
    // D_barre=1/2G dS/dt +S/mu pour la partie déviatoire
    // dans le cas ou m_p est alimentée on a également une partie sphérique visqueuse
    // I_D = 1/(E/(1-2nu)) dI_Sig/dt + I_sig / mu_p     
    //ou alors seule la partie déviatoire comprend une partie visqueuse; l'équation devient
    // Pour la partie sphérique: Isigma = K Iepsilon
    Tenseur3BH  epsBH = epsBB * gijHH;  // deformation en mixte
    double Ieps = epsBH.Trace();
    Tenseur3BH  eps_barre_BH = epsBH - (untier * Ieps) * IdBH3; 
    // intégration du coeff multiplicateur de la viscosité si nécessaire
    double coe_mu=1.; // coeff multiplicateur par défaut
    double coe_E=1.; // coeff multiplicateur par défaut
    double II_D_barre = 0.; // init
    if ((depend_de_D!=0) || depend_cristalinite)
     { II_D_barre = Deps_barre_BH.II();
	      switch (depend_de_D) 
		      { case 1:coe_mu=fac_mu_cissionD->Valeur(sqrt(II_D_barre));break;
			       case 2:coe_E=fac_E_cissionD->Valeur(sqrt(II_D_barre));break;
			       case 3:coe_mu=fac_mu_cissionD->Valeur(sqrt(II_D_barre));
			              coe_E=fac_E_cissionD->Valeur(sqrt(II_D_barre));break;
		      };
     };
	   // idem dans le cas d'une dépendance à eps	
    double II_eps_barre = 0.;double eps_mises = 0.; // init
    if (depend_de_eps!=0)
     { II_eps_barre = eps_barre_BH.II();
	      eps_mises = sqrt(2./3. * II_eps_barre);
	      switch (depend_de_eps) 
		      { case 1:coe_mu *= fac_mu_Mises_Eps->Valeur(eps_mises);break;
			       case 2:coe_E *= fac_E_Mises_Eps->Valeur(eps_mises);break;
			       case 3:coe_mu *= fac_mu_Mises_Eps->Valeur(eps_mises);
			              coe_E *= fac_E_Mises_Eps->Valeur(eps_mises);break;
		      };
     };
 // --- cas de la thermo dépendance, on calcul les grandeurs matérielles -----
    if (E_temperature != NULL) E = E_temperature->Valeur(*temperature);
    if (depend_cristalinite) // cas d'une dépendance à la température via la cristalinité
      { double P = untier * (gijBB && sigHH); // pour la pression on utilise la trace de sig de l'iter précédent
        // gamma = 2 D_12, si on a un essai de cisaillement pur en 1 2: II_D_barre = 2*(D^1_2)**2
        // d'où gamm_point  
        double gamma_point =  sqrt(2.*II_D_barre); 
        mu = mu_p = ViscositeCristaline(P,gamma_point);
      }
    else // sinon c'est le cas classique de dépendance ou non à la température 
      {if (mu_temperature != NULL) mu = mu_temperature->Valeur(*temperature);
       if (mu_p_temperature != NULL) mu_p = mu_p_temperature->Valeur(*temperature);
      };

    double mu_coe = mu * coe_mu; // pour simplifier
    double mu_p_coe = mu_p * coe_mu; // pour simplifier
    double E_coe = E * coe_E; // pour simplifier
    double troisK=E_coe/(1-2.*nu);
    double deuxG=E_coe/(1.+nu);   
    double unSurmu_coe = 1./mu_coe;
    double co1 = deltat * deuxG * mu_coe /(mu_coe + deuxG * deltat);
    double co3 = unSurDeltat/deuxG;
  
    // sauvegarde des paramètres matériau
    SaveResulLoi_maxwell3D & save_resul = *((SaveResulLoi_maxwell3D*) saveResul);
    save_resul.E = E_coe;
    save_resul.nu = nu;
    save_resul.mu = mu_coe;
    save_resul.mu_p = mu_p_coe;

    // cas d'une viscosité sur la partie sphérique et le fait que la partie sphérique est prise en compte
    double co2=0.; double co4=0.;
    if (((existe_mu_p) ||(volumique_visqueux)) && (!seule_deviatorique))
     { co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat); // ne sert pas toujours
       co4 = unSurDeltat/troisK;
     };
     
  // ---- calcul de la partie sphérique du tenseur des contraintes -----
    double Isig_n = sigBH_n.Trace();
    Tenseur3BH SBH_n = sigBH_n - (untier * Isig_n) * IdBH3;
    // cas de la partie sphérique
    double Isigma=0;module_compressibilite=0.;
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
         { Isigma = troisK * Ieps;
           module_compressibilite = troisK * untier;
         } // cas où il n'y a pas de viscosité sphérique
       else
         { // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
// erreur       Isigma = co2 * (Isig_n/(troisK*deltat) + IDeps); 
           Isigma = co2 * (IDeps + co4 * Isig_n);
           if (Ieps > ConstMath::petit) {module_compressibilite = Isigma / 3. / Ieps;}
           else {module_compressibilite = troisK * mu_p_coe /(mu_p_coe + troisK * deltat);};	
         };
     };
  
  // --- calcul de la partie déviatorique du tenseur des contraintes ----    
    // puis du tenseur total 
    // en fait dans le cas d'une linéarisation seul le transport de la contrainte à de l'importance
    Tenseur3HH SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
    if (seule_deviatorique)
     { sigHH = SHH; }
    else 
     { sigHH = SHH + (untier * Isigma) * gijHH ;};
    
  // ---- traitement des énergies ----
    energ.Inita(0.); double ener_elas=0.; double ener_visqueux = energ_t.DissipationVisqueuse();
    // on peut raisonner en supposant une décomposition de la vitesse de déformation
    //  ... partie sphérique
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
         // cas où il n'y a pas de viscosité sphérique => élasticité linéaire
         // 0.5 car on considère que sur le pas sig augmente proportionnellement
         { ener_elas = 0.5 * (Isigma * Ieps); }
       else if (!seule_deviatorique)
         // cas où on a une partie sphérique et qu'elle contient une partie  visqueuse
         // I_{D_vis}=I_sig / mu*f; I_{D_elas} = I_sig / (3*K);
         { ener_elas = 0.5 * (Isigma * Isigma) / troisK; // partie élastique
           if (Dabs(mu_p_coe) > ConstMath::trespetit)         // partie visqueuse
            {ener_visqueux += (Isigma * Isigma) * deltat / mu_p_coe;};
         };
     };
    //  ... partie déviatorique    
    // {si mu_coe = 0} => {SHH = 0} d'où une énergie visqueuse nulle, sinon
    // on calcul D_barre_visqueux = SHH/mu_coe d'où le calcul de l'énergie qui suit
    Tenseur3BH SBH = IdBB3 * SHH;  
    double S2= (SBH && SBH); // pour simplifier  
    ener_elas += 0.5 * S2 /deuxG;                       // partie élastique  
    if (Dabs(mu_coe) > ConstMath::trespetit)         // partie visqueuse
       {ener_visqueux += S2 * deltat / mu_coe;};
////debug
//double toto = S2 * deltat / mu_coe;
//if (toto < 0.)
// { cout << "\n debug: Loi_maxwell3D::Calcul_SigmaHH "
//        << " d visqueux = "<< toto << endl;
// 
// };
////fin debug
    // ...  mise à jour de energ
    energ.ChangeEnergieElastique(ener_elas); 
    energ.ChangeDissipationVisqueuse(ener_visqueux);
    
    // on libère les tenseurs intermédiaires        
    LibereTenseur();        
 };
        
        // calcul des contraintes a t+dt et de ses variations  
void Loi_maxwell3D::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB_,DdlElement & tab_ddl
            ,BaseB& ,TenseurBB & gijBB_t_,TenseurHH &
            ,BaseB& ,Tableau <BaseB> & ,BaseH& ,Tableau <BaseH> &
            ,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>& d_epsBB,TenseurBB & delta_epsBB_tdt
		          ,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt
		          ,Tableau <TenseurBB *>& d_gijBB_tdt
		  	       ,Tableau <TenseurHH *>& d_gijHH_tdt,double& , double&
		  	       ,Vecteur& ,TenseurHH& sigHH_tdt,Tableau <TenseurHH *>& d_sigHH
		  	       ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double&  module_cisaillement
		  	       ,const Met_abstraite::Impli& )
 {
    #ifdef MISE_AU_POINT
    if (DepsBB_.Dimension() != 3)
       { cout << "\nErreur : la dimension devrait etre 3 !\n";
         cout << " Loi_maxwell3D::Calcul_DsigmaHH_tdt\n";
         Sortie(1);
       };
    if (tab_ddl.NbDdl() != d_gijBB_tdt.Taille())
       { cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_tdt  !\n";
         cout << " Loi_maxwell3D:Tenseur3Calcul_SDsigmaHH_tdt\n";
         Sortie(1);
       };
    #endif
    const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_tdt); // passage en dim 3
    const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
    const Tenseur3BB & DepsBB = *((Tenseur3BB*) &DepsBB_); // passage en dim 3
    const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); //   "      "  "  "
    const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); //   "      "  "  "
    const Tenseur3BB & gijBB_t = *((Tenseur3BB*) &gijBB_t_); //   "      "  "  "
    Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt);  //   "      "  "  "
    Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t);  //   "      "  "  "
 // --- opération de transport du tenseur sigma(t), de t à tdt
    // tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
    Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
    switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
     {case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
        {sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
         sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
         sigHH_n = gijHH * sigBH_n ; 
         sigBB_n = sigBH_n * gijBB; break;}
      case 0: // cas d'une dérivée de Lie deux fois covariantes
        {sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
         sigBH_n = sigBB_n * gijHH ;
         sigHH_n = gijHH * sigBH_n ; break;}
      case 1: // cas d'une dérivée de Lie deux fois contravariantes
        {sigHH_n = sigHH_nn;
         sigBH_n = gijBB * sigHH_n;
         sigBB_n = sigBH_n * gijBB; 
         break;}
      };    

 // ---- calcul relatif aux déviateurs : déformations et vitesse de déformation -----
    static const double untier=1./3.;
    Tenseur3BH  DepsBH =  DepsBB * gijHH;
    double IDeps=DepsBH.Trace();
    Tenseur3BH Deps_barre_BH = DepsBH - (untier * IDeps) * IdBH3;
    // 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;
     };
    // le calcul de la contrainte correspond à l'intégration d'une équation différencielle
    // D_barre=1/2G dS/dt +S/mu  
    // dans le cas ou m_p est alimentée on a également une partie sphérique visqueuse
    // I_D = 1/(E/(1-2nu)) dI_Sig/dt + I_sig / mu_p     
    //ou alors seule la partie déviatoire comprend une partie visqueuse; l'équation devient
    // Pour la partie sphérique: Isigma = K Iepsilon
    Tenseur3BH  epsBH = epsBB * gijHH;  // deformation en mixte
    double Ieps = epsBH.Trace();
    Tenseur3BH  eps_barre_BH = epsBH - (untier * Ieps) * IdBH3; 
    // intégration du coeff multiplicateur de la viscosité si nécessaire
    double II_D_barre=0; 
    double Q_Deps = 0.;
    // preparation variable
    double mu_coef_final  = 1.;
    double E_coef_final = 1.;
    double d_mu_coef_final__d_D = 0.;
    double d_mu_coef_final__d_eps = 0.;
    double d_E_coef_final__d_D = 0.;
    double d_E_coef_final__d_eps = 0.;
    double II_eps_barre = 0.;double eps_mises = 0.; // init
    // on encapsule la suite pour être sûr de ne pas utiliser les variables intermédiaires
    { Courbe1D::ValDer valder_mu_D;Courbe1D::ValDer valder_E_D;
      valder_mu_D.valeur = 1.; valder_mu_D.derivee = 0.;// initialisation par défaut
      valder_E_D.valeur = 1.; valder_E_D.derivee = 0.;// initialisation par défaut

      if ((depend_de_D!=0) || depend_cristalinite)
       {  II_D_barre = Deps_barre_BH.II();
	         Q_Deps = sqrt(II_D_barre);
	         switch (depend_de_D)
		         { case 1:valder_mu_D =fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);break;
			          case 2:valder_E_D=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
			          case 3:valder_mu_D=fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);
			                 valder_E_D=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
		         };
        };
	     // idem dans le cas d'une dépendance à eps
      Courbe1D::ValDer valder_mu_eps;Courbe1D::ValDer valder_E_eps;
      valder_mu_eps.valeur = 1.; valder_mu_eps.derivee = 0.;// initialisation par défaut
      valder_E_eps.valeur = 1.; valder_E_eps.derivee = 0.;// initialisation par défaut
      if (depend_de_eps!=0)
        { II_eps_barre = eps_barre_BH.II();
	         eps_mises = sqrt(2./3. * II_eps_barre);
	         switch (depend_de_eps)
		         { case 1:valder_mu_eps = fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
			          case 2:valder_E_eps = fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
			          case 3:valder_mu_eps =fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);
			                 valder_E_eps =fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
		         };
        };
      // calcul du résultat combiné
      // pour la valeur finale et pour les dérivées partielles
      mu_coef_final  = valder_mu_D.valeur * valder_mu_eps.valeur;
      E_coef_final = valder_E_D.valeur * valder_E_eps.valeur;
      d_mu_coef_final__d_D = valder_mu_D.derivee * valder_mu_eps.valeur;
      d_mu_coef_final__d_eps = valder_mu_D.valeur * valder_mu_eps.derivee;
      d_E_coef_final__d_D = valder_E_D.derivee * valder_E_eps.valeur;
      d_E_coef_final__d_eps = valder_E_D.valeur * valder_E_eps.derivee;
    }; // fin de l'encapsulation du calcul des coefficients

 // --- cas de la thermo dépendance, on calcul les grandeurs matérielles -----
    if (E_temperature != NULL) E = E_temperature->Valeur(*temperature);
    if (depend_cristalinite) // cas d'une dépendance à la température via la cristalinité
      { double P = untier * (gijBB && sigHH); // pour la pression on utilise la trace de sig de l'iter précédent
        // gamma = 2 D_12, si on a un essai de cisaillement pur en 1 2: II_D_barre = 2*(D^1_2)**2
        // d'où gamm_point  
        double gamma_point =  sqrt(2.*II_D_barre); 
        mu = mu_p = ViscositeCristaline(P,gamma_point);
//---- debug        
//        cout << " " << mu << endl;
//---- debug        
      }
    else // sinon c'est le cas classique de dépendance ou non à la température 
      {if (mu_temperature != NULL) mu = mu_temperature->Valeur(*temperature);
       if (mu_p_temperature != NULL) mu_p = mu_p_temperature->Valeur(*temperature);
      };

    double E_coe = E * E_coef_final; // pour simplifier
    double troisK=E_coe/(1-2.*nu);
    double deuxG=E_coe/(1.+nu);   
    double mu_coe = mu * mu_coef_final; // pour simplifier
    double mu_p_coe = mu_p * mu_coef_final; // pour simplifier
    double unSurmu_coe = 1./mu_coe;
    double co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
    double co3 = unSurDeltat/deuxG;
  
    // sauvegarde des paramètres matériau
    SaveResulLoi_maxwell3D & save_resul = *((SaveResulLoi_maxwell3D*) saveResul);
    save_resul.E = E_coe;
    save_resul.nu = nu;
    save_resul.mu = mu_coe;
    save_resul.mu_p = mu_p_coe;

//-- debug
//   cout << "\n E= " << E_coe << " mu= " << mu_coe << " valder_E.valeur" << valder_E.valeur << " valder_mu.valeur " << valder_mu.valeur;	
//-- fin debug	 
    
    // cas d'une viscosité sur la partie sphérique et le fait que la partie sphérique est prise en compte
    double co2=0.; double co4=0.;
    if (((existe_mu_p) ||(volumique_visqueux)) && (!seule_deviatorique))
     { co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat); // ne sert pas toujours
       co4 = unSurDeltat/troisK;
     };
     
  // ---- calcul de la partie sphérique du tenseur des contraintes -----
    double Isig_n = sigBH_n.Trace();
    Tenseur3BH SBH_n = sigBH_n - (untier * Isig_n) * IdBH3;
    module_compressibilite = 0.; // init par défaut
    // cas de la partie sphérique
    double Isigma=0;double unsur3Kdeltat = unSurDeltat/troisK;
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
         { Isigma = troisK * Ieps;
           module_compressibilite = troisK * untier;
         } // cas où il n'y a pas de viscosité sphérique
       else // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
         {
// erreur       Isigma = co2 * (Isig_n/(troisK*deltat) + IDeps); 
           Isigma = co2 * (IDeps + co4 * Isig_n); 
           if (Ieps > ConstMath::petit) {module_compressibilite = Isigma /(3. * Ieps);}
           else {module_compressibilite = troisK * mu_p_coe /(mu_p_coe + troisK * deltat);};	
         };
     };
  
  // --- calcul de la partie déviatorique du tenseur des contraintes ----    
    // e puis du tenseur total 
    // en fait dans le cas d'une linéarisation seul le transport de la contrainte à de l'importance
    Tenseur3HH SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
    if (seule_deviatorique)
     { sigHH = SHH; }
    else 
     { sigHH = SHH + (untier * Isigma) * gijHH ;};
  // ---- maintenant calcul de l'opérateur tangent -----
    // remarque : même dans le cas d'une cristalinité, on ne tiens pas compte de la variation de mu
    // par rapport aux ddl
    int nbddl = d_gijBB_tdt.Taille();
    Tenseur3BH d_DepsBH,d_Deps_barre_BH; // tenseurs de travail  
    Tenseur3BH dsigBH_n,d_SBH_n; // tenseurs de travail 
    Tenseur_ns3HH d_SHH; // tenseurs de travail 
    double racine_2tier = sqrt(2./3.);
    for (int i = 1; i<= nbddl; i++)
      {// on fait uniquement une égalité d'adresse pour ne pas utiliser
       // le constructeur d'ou la profusion d'* et de ()
       Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i)));  // passage en dim 1
       const Tenseur3BB & dgijBB =  *((Tenseur3BB*)(d_gijBB_tdt(i)));  // passage en dim 1
       const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture
       const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); //    "
       // variation de la vitesse de déformation
       d_DepsBH = ( unSurDeltat) * depsBB * gijHH + DepsBB * dgijHH;
       // variation de la trace de la vitesse de def
       double d_IDeps = d_DepsBH.Trace();
       // variation du déviateur
       d_Deps_barre_BH =  d_DepsBH - (d_IDeps/3.) * IdBH3; 

       // variation de sigma_n
       switch (type_derive) 
        { case -1: // // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
           {// pour info sigBH_n = 0.5*(gijBB * sigHH_n + (gijBB_t * sigHH_n * gijBB_t) * gijHH) 
            dsigBH_n = 0.5*(sig_interBB_n * dgijHH + dgijBB * sigHH_nn ); 
            break;}
          case 0: // cas d'une dérivée de Lie deux fois covariantes
           {// pour info sigBH_n = (gijBB_t * sigHH_n * gijBB_t) * gijHH
            dsigBH_n = sigBB_n * dgijHH;  
            break;}
          case 1: // cas d'une dérivée de Lie deux fois contravariantes
           {// pour info sigBH_n = gijBB * sigHH_n
            dsigBH_n = dgijBB * sigHH_n; break;}
        };
       // variation de la trace de sigma_n du au transport
       double dIsig_n = dsigBH_n.Trace();
       // variation de la trace de sigma actuel
       double dIsigma = 0; // initialisation
       if (!seule_deviatorique)
        { if (!(existe_mu_p || volumique_visqueux ))
              { dIsigma = troisK * d_IDeps * deltat;} // cas où il n'y a pas de viscosité sphérique
          else // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
              { dIsigma = co2 * (d_IDeps + co4 *dIsig_n);}
        };
       // variation du déviateur due au transport
       d_SBH_n = dsigBH_n - (untier * dIsig_n) * IdBH3;
       // variation du déviateur des contraintes
       d_SHH = co1 * dgijHH * (Deps_barre_BH + co3 *  SBH_n )
              +co1 * gijHH * (d_Deps_barre_BH + co3 *  d_SBH_n);
                     
       // -- si la viscosité et/ou le module d'young est dépendant de D, il faut tenir compte de la variation des coefs
       // si la vitesse de déformation est nulle on aura une division par zéro dans les formules de dérivation
       // du au fait que Q_Deps = à la racine carré de (Deps:Deps), d'où le test
       if ((Q_Deps > ConstMath::pasmalpetit)&&(depend_de_D != 0))
           { double d_Q_Deps = ((d_Deps_barre_BH && Deps_barre_BH) + (Deps_barre_BH && d_Deps_barre_BH)) / (2.*Q_Deps);
             double d_coe_mu = 0.;
             // préparation du cas où il y a de la viscosité dépendante de Q_Deps
             if ((depend_de_D == 1) || (depend_de_D == 3)) 
                  d_coe_mu = d_mu_coef_final__d_D * d_Q_Deps;
             double un_sur_mu_plus_deuxG_foic_deltat = 1./(mu_coe + deuxG * deltat); // pour simplifier
             
             // cas ou mu et/ou mu_p dépend de D
             if ((depend_de_D==1)||(depend_de_D==3))
               { // == tout d'abord la partie déviatorique
                 // variation du coef multiplicatif de la viscosité
                 // co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
                 double d_co1 = deltat * deuxG *  mu * d_coe_mu *
                                ( 1. - mu_coe * un_sur_mu_plus_deuxG_foic_deltat) * un_sur_mu_plus_deuxG_foic_deltat;
                 // l'élément à ajouter est proportionnel à SHH, donc au lieu de recalculer le tenseur on divise par co1
                 // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
                 d_SHH += (d_co1/co1) * SHH;
                 // == maintenant éventuellement la partie sphérique si elle est visqueuse
                 if (!seule_deviatorique && (existe_mu_p || volumique_visqueux ))
                   { double d_mu_p_coe = mu_p * d_coe_mu;
                             //Isigma = co2 * (IDeps + co4 * Isig_n); 
                     //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
                     double d_co2 =  deltat * troisK * d_mu_p_coe * (1. - mu_p_coe / (mu_p_coe + troisK * deltat)) 
                                           /(mu_p_coe + troisK * deltat);
                             //Isigma = co2 * (IDeps + co4 * Isig_n); 
                     dIsigma += d_co2 * (IDeps + co4 * Isig_n);
                    };
               };
             
             // cas variation du coef multiplicatif de E
             if (((depend_de_D==2)||(depend_de_D==3))&&(!seule_deviatorique))
                { double d_coe_E = d_E_coef_final__d_D * d_Q_Deps;
                  double d_troisK=E * d_coe_E /(1.-2.*nu);
                  double d_deuxG = E / (1.+nu) * d_coe_E;
                  // == tout d'abord la partie déviatorique
                  // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
                  // co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
                  double d_co1 = deltat * d_deuxG * mu_coe *
                            (1.- troisK * un_sur_mu_plus_deuxG_foic_deltat ) * un_sur_mu_plus_deuxG_foic_deltat;
                  // l'élément à ajouter est proportionnel à SHH, donc au lieu de recalculer le tenseur on divise par co1            
                  d_SHH += (d_co1/co1) * SHH;           
                  // on a également G donc deuxG donc co3 qui dépend de E; co3 = unSurDeltat/deuxG
                  double d_co3 = -d_deuxG*unSurDeltat/deuxG/deuxG;
                  d_SHH += (co1 * d_co3) * gijHH * SBH_n;

                  // == maintenant  la partie sphérique si elle existe
                  if (!seule_deviatorique)
                   // on choisit entre non visqueux et visqueux
                   { if (!(existe_mu_p || volumique_visqueux ))
                       //Isigma = troisK * Ieps;
                       { dIsigma += d_troisK * Ieps;}
                     else // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
                         //Isigma = co2 * (IDeps + co4 * Isig_n);
                       { //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
                         double d_co2 = deltat * d_troisK * mu_p_coe * (1. - deltat*troisK / (mu_p_coe + troisK * deltat))
                                    /(mu_p_coe + troisK * deltat);
                         //co4 = unSurDeltat/troisK;
                         double d_co4 = - unSurDeltat * d_troisK / (troisK*troisK);
                         dIsigma += d_co2 * (IDeps + co4 * Isig_n)
                              + co2 * d_co4 * Isig_n;
                       };
                   };

                };
		      };

       // -- si la viscosité et/ou le module d'young est dépendant de eps, il faut tenir compte de la variation des coefs 
		     // si la déformation est nulle on aura une division par zéro dans les formules de dérivation
		     // du au fait que eps_mises = à la racine carré de (eps:eps), d'où le test
		     if ((eps_mises > ConstMath::pasmalpetit)&&(depend_de_eps != 0))
         { // on calcul la variation en fonction de eps, via d_Deps, et on multipli par delta_t
			        double d_eps_mises = racine_2tier * deltat * 0.5 /eps_mises *
			                    ((d_Deps_barre_BH && eps_barre_BH) + (eps_barre_BH && d_Deps_barre_BH)) ;
		         double d_coe_mu = 0.;
			        // préparation du cas où il y a de la viscosité dépendante de eps_mises
			        if ((depend_de_eps == 1) || (depend_de_eps == 3))
		           d_coe_mu = d_mu_coef_final__d_eps * d_eps_mises;
		         double un_sur_mu_plus_deuxG_foic_deltat = 1./(mu_coe + deuxG * deltat); // pour simplifier
		 
           // cas ou mu et/ou mu_p dépend de eps_mises
			        if ((depend_de_eps==1)||(depend_de_eps==3))
            { // == tout d'abord la partie déviatorique
			           // variation du coef multiplicatif de la viscosité
				          // co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
              double d_co1 = deltat * deuxG *  mu * d_coe_mu *
                      ( 1. - mu_coe * un_sur_mu_plus_deuxG_foic_deltat) * un_sur_mu_plus_deuxG_foic_deltat;
              // l'élément à ajouter est proportionnel à SHH, donc au lieu de recalculer le tenseur on divise par co1
              // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
              d_SHH += (d_co1/co1) * SHH;
				          // == maintenant éventuellement la partie sphérique si elle est visqueuse
              if (!seule_deviatorique && (existe_mu_p || volumique_visqueux ))
				           { double d_mu_p_coe = mu_p * d_coe_mu;
                 //Isigma = co2 * (IDeps + co4 * Isig_n);
				             //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
				             double d_co2 =  deltat * troisK * d_mu_p_coe * (1. - mu_p_coe / (mu_p_coe + troisK * deltat))
															             /(mu_p_coe + troisK * deltat);
                 //Isigma = co2 * (IDeps + co4 * Isig_n);
				             dIsigma += d_co2 * (IDeps + co4 * Isig_n);
				           };
            };
           // cas variation du coef multiplicatif de E
		         if (((depend_de_eps==2)||(depend_de_eps==3))&&(!seule_deviatorique))
            { double d_coe_E = d_E_coef_final__d_eps * d_eps_mises;
              double d_troisK=E * d_coe_E /(1.-2.*nu);
				          double d_deuxG = E / (1.+nu) * d_coe_E;
				          // == tout d'abord la partie déviatorique
				          // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
			           // co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
              double d_co1 = deltat * d_deuxG * mu_coe *
                      (1.- troisK * un_sur_mu_plus_deuxG_foic_deltat ) * un_sur_mu_plus_deuxG_foic_deltat;
              // l'élément à ajouter est proportionnel à SHH, donc au lieu de recalculer le tenseur on divise par co1
              d_SHH += (d_co1/co1) * SHH;
			           // on a également G donc deuxG donc co3 qui dépend de E; co3 = unSurDeltat/deuxG
				          double d_co3 = -d_deuxG*unSurDeltat/deuxG/deuxG;
				          d_SHH += (co1 * d_co3) * gijHH * SBH_n;

				          // == maintenant  la partie sphérique si elle existe
              if (!seule_deviatorique)
				           // on choisit entre non visqueux et visqueux
               { if (!(existe_mu_p || volumique_visqueux ))
                    //Isigma = troisK * Ieps;
					             { dIsigma += d_troisK * Ieps;}
                 else // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
                    //Isigma = co2 * (IDeps + co4 * Isig_n);
					             { //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
				                double d_co2 = deltat * d_troisK * mu_p_coe * (1. - deltat*troisK / (mu_p_coe + troisK * deltat))
															             /(mu_p_coe + troisK * deltat);
                    //co4 = unSurDeltat/troisK;
                    double d_co4 = - unSurDeltat * d_troisK / (troisK*troisK);
                    dIsigma += d_co2 * (IDeps + co4 * Isig_n)
                               + co2 * d_co4 * Isig_n;
                  };
               };
            };
		       };

       if (seule_deviatorique)   { dsigHH = d_SHH; }
       else 
                                 { dsigHH = d_SHH + (untier * dIsigma) * gijHH 
                                            + (untier * Isigma) * dgijHH ;};
      };  
        
  // ---- traitement des énergies ----
    energ.Inita(0.); double ener_elas=0.; double ener_visqueux = energ_t.DissipationVisqueuse();
    // on peut raisonner en supposant une décomposition de la vitesse de déformation
    //  ... partie sphérique
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
       // cas où il n'y a pas de viscosité sphérique => élasticité linéaire
       // 0.5 car on considère que sur le pas sig augmente proportionnellement
         { ener_elas = 0.5 * (Isigma * Ieps); }
       else if (!seule_deviatorique)
       // cas où on a une partie sphérique et qu'elle contient une partie  visqueuse
       // I_{D_vis}=I_sig / mu*f; I_{D_elas} = I_sig / (3*K);
         { ener_elas = 0.5 * (Isigma * Isigma) / troisK; // partie élastique
           if (Dabs(mu_p_coe) > ConstMath::trespetit)         // partie visqueuse
            {ener_visqueux += (Isigma * Isigma) * deltat / mu_p_coe;};
         };
     };
    //  ... partie déviatorique    
       // {si mu_coe = 0} => {SHH = 0} d'où une énergie visqueuse nulle, sinon
       // on calcul D_barre_visqueux = SHH/mu_coe d'où le calcul de l'énergie qui suit
    Tenseur3BH SBH = IdBB3 * SHH;  
    double S2= (SBH && SBH); // pour simplifier  
    ener_elas += 0.5 * S2 /deuxG;                       // partie élastique  
    if (Dabs(mu_coe) > ConstMath::trespetit)         // partie visqueuse
       {ener_visqueux += S2 * deltat / mu_coe;};

//II_D_barre = Deps_barre_BH.II();
//Q_Deps = sqrt(II_D_barre);
////cout << " " <<Q_Deps << " " << S2 << " "<< ener_visqueux << "; ";
//if (Q_Deps > 400.)
//{
//  cout << "\n deltat= " << deltat << " unSurDeltat= " <<  unSurDeltat ;
//  cout << "\n Deps_barre_BH "; Deps_barre_BH.Ecriture(cout);
//  cout << "\n eps_barre_BH "; eps_barre_BH.Ecriture(cout);
//  cout << "\n delta_epsBB "; delta_epsBB.Ecriture(cout);
//  cout << "\n epsBB "; epsBB.Ecriture(cout);
//  cout << "\n DepsBB "; DepsBB.Ecriture(cout);
//  cout << endl;
//  Sortie(1);
//   
//};
    // ... mise à jour de energ
    energ.ChangeEnergieElastique(ener_elas); 
    energ.ChangeDissipationVisqueuse(ener_visqueux);
    
    // on libère les tenseurs intermédiaires        
    LibereTenseur(); // LibereTenseurQ();
    
 };
		 
		 // s'il y a également de la viscosité sphérique il faut tenir compte de la variation du coef co2
//il faut mettre à jour la doc
//il faut faire un test


// calcul des contraintes et ses variations  par rapport aux déformations a t+dt
// en_base_orthonormee:  le tenseur de contrainte en entrée est  en orthonormee
//                  le tenseur de déformation et son incrémentsont également en orthonormees
//                 si = false: les bases transmises sont utilisées
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void Loi_maxwell3D::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB_
     ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB_,double& ,double&
		  	,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps_
		  	,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite
     ,double&  module_cisaillement
		  	,const Met_abstraite::Umat_cont& ex)
 {
    #ifdef MISE_AU_POINT
	   if (epsBB_tdt.Dimension() != 3)
	    { cout << "\nErreur : la dimension devrait etre 3 !\n";
		     cout << " Loi_maxwell3D::Calcul_dsigma_deps\n";
		     Sortie(1);
		   };
    #endif
    const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
    const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_);
    const Tenseur3BB & DepsBB = *((Tenseur3BB*) &DepsBB_); // passage en dim 3
    Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt);  //   "      "  "  "
    Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t);  //   "      "  "  "
    const Tenseur3HH & gijHH = *((Tenseur3HH*) ex.gijHH_tdt); //   "      "  "  "
    const Tenseur3BB & gijBB = *((Tenseur3BB*) ex.gijBB_tdt); //   "      "  "  "
    const Tenseur3HH & gijHH_t = *((Tenseur3HH*) ex.gijHH_t); //   "      "  "  "
    const Tenseur3BB & gijBB_t = *((Tenseur3BB*) ex.gijBB_t); //   "      "  "  "

 // --- opération de transport du tenseur sigma(t), de t à tdt
    // tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
    Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
    if (en_base_orthonormee)
      {// pour l'instant le transport s'effectue dans la base orthonormee!! ce qui est peut-être
       // mauvais dans le cas de grandes transformations !!
       sigBH_n = IdBB3 * sigHH_nn;
      }  // deformation en mixte
    else
      { switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
         {case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
            {sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
             sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
             sigHH_n = gijHH * sigBH_n ; 
             sigBB_n = sigBH_n * gijBB; break;}
          case 0: // cas d'une dérivée de Lie deux fois covariantes
            {sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
             sigBH_n = sigBB_n * gijHH ;
             sigHH_n = gijHH * sigBH_n ; break;}
          case 1: // cas d'une dérivée de Lie deux fois contravariantes
            {sigHH_n = sigHH_nn;
             sigBH_n = gijBB * sigHH_n;
             sigBB_n = sigBH_n * gijBB; 
             break;}
          };
      };


 // ---- calcul relatif aux déviateurs : déformations et vitesse de déformation -----
    static const double untier=1./3.;
  
    Tenseur3BH  DepsBH; Tenseur3BB  Deps_barre_BB;Tenseur3HH  Deps_barre_HH; // init
    Tenseur3BH Deps_barre_BH;
    double IDeps=0.;     // "
    Tenseur3BH  epsBH;

    if (en_base_orthonormee)
      {DepsBH =  DepsBB.MonteDernierIndice();
       IDeps=DepsBH.Trace();
       Deps_barre_BH = DepsBH - (untier * IDeps) * IdBH3;
       Deps_barre_BB = Deps_barre_BH * IdBB3;
       Deps_barre_HH = IdHH3 * Deps_barre_BH ;
       epsBH = epsBB.MonteDernierIndice();  // deformation en mixte
      }
    else
      {DepsBH =  DepsBB * gijHH;
       IDeps=DepsBH.Trace();
       Deps_barre_BH = DepsBH - (untier * IDeps) * IdBH3;
       Deps_barre_BB = Deps_barre_BH * gijBB;
       Deps_barre_HH = gijHH * Deps_barre_BH ;
       epsBH = epsBB * gijHH;  // deformation en mixte
      };
    double Ieps = epsBH.Trace();
    Tenseur3BH  eps_barre_BH = epsBH - (untier * Ieps) * IdBH3;
    // 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;
     };
    // le calcul de la contrainte correspond à l'intégration d'une équation différencielle
    // D_barre=1/2G dS/dt +S/mu  
    // dans le cas ou m_p est alimentée on a également une partie sphérique visqueuse
    // I_D = 1/(E/(1-2nu)) dI_Sig/dt + I_sig / mu_p     
    //ou alors seule la partie déviatoire comprend une partie visqueuse; l'équation devient
    // Pour la partie sphérique: Isigma = K Iepsilon
    // intégration du coeff multiplicateur de la viscosité si nécessaire
    double II_D_barre=0; 
	   double Q_Deps = 0.;
    // preparation variable
    double mu_coef_final  = 1.;
    double E_coef_final = 1.;
    double d_mu_coef_final__d_D = 0.;
    double d_mu_coef_final__d_eps = 0.;
    double d_E_coef_final__d_D = 0.;
    double d_E_coef_final__d_eps = 0.;
    double II_eps_barre = 0.;double eps_mises = 0.; // init
    // on encapsule la suite pour être sûr de ne pas utiliser les variables intermédiaires
    { Courbe1D::ValDer valder_mu_D;Courbe1D::ValDer valder_E_D;
      valder_mu_D.valeur = 1.; valder_mu_D.derivee = 0.;// initialisation par défaut
      valder_E_D.valeur = 1.; valder_E_D.derivee = 0.;// initialisation par défaut

      if ((depend_de_D!=0) || depend_cristalinite)
       {  II_D_barre = Deps_barre_BH.II();
          Q_Deps = sqrt(II_D_barre);
          switch (depend_de_D)
           { case 1:valder_mu_D =fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);break;
             case 2:valder_E_D=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
             case 3:valder_mu_D=fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);
                    valder_E_D=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
           };
        };
      // idem dans le cas d'une dépendance à eps
      Courbe1D::ValDer valder_mu_eps;Courbe1D::ValDer valder_E_eps;
      valder_mu_eps.valeur = 1.; valder_mu_eps.derivee = 0.;// initialisation par défaut
      valder_E_eps.valeur = 1.; valder_E_eps.derivee = 0.;// initialisation par défaut
      if (depend_de_eps!=0)
        { II_eps_barre = eps_barre_BH.II();
          eps_mises = sqrt(2./3. * II_eps_barre);
          switch (depend_de_eps)
           { case 1:valder_mu_eps = fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
             case 2:valder_E_eps = fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
             case 3:valder_mu_eps =fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);
                    valder_E_eps =fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
           };
        };
      // calcul du résultat combiné
      // pour la valeur finale et pour les dérivées partielles
      mu_coef_final  = valder_mu_D.valeur * valder_mu_eps.valeur;
      E_coef_final = valder_E_D.valeur * valder_E_eps.valeur;
      d_mu_coef_final__d_D = valder_mu_D.derivee * valder_mu_eps.valeur;
      d_mu_coef_final__d_eps = valder_mu_D.valeur * valder_mu_eps.derivee;
      d_E_coef_final__d_D = valder_E_D.derivee * valder_E_eps.valeur;
      d_E_coef_final__d_eps = valder_E_D.valeur * valder_E_eps.derivee;
    }; // fin de l'encapsulation du calcul des coefficients

/*
 
	   Courbe1D::ValDer valder_mu_QDeps;Courbe1D::ValDer valder_E_QDeps;
    valder_mu_QDeps.valeur = 1.; valder_mu_QDeps.derivee = 0.;// initialisation par défaut
    valder_E_QDeps.valeur = 1.; valder_E_QDeps.derivee = 0.;// initialisation par défaut

    if ((depend_de_D!=0) || depend_cristalinite)
     { II_D_barre = Deps_barre_BH.II();
	      Q_Deps = sqrt(II_D_barre);
	      switch (depend_de_D)
        { case 1:valder_mu_QDeps=fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);break;
          case 2:valder_E_QDeps=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
          case 3:valder_mu_QDeps=fac_mu_cissionD->Valeur_Et_derivee(Q_Deps);
                 valder_E_QDeps=fac_E_cissionD->Valeur_Et_derivee(Q_Deps);break;
        };
     };
	   // idem dans le cas d'une dépendance à eps
    Courbe1D::ValDer valder_mu_mises_eps;Courbe1D::ValDer valder_E_mises_eps;
    valder_mu_mises_eps.valeur = 1.; valder_mu_mises_eps.derivee = 0.;// initialisation par défaut
    valder_E_mises_eps.valeur = 1.; valder_E_mises_eps.derivee = 0.;// initialisation par défaut
    double II_eps_barre = 0.;double eps_mises = 0.; // init
    if (depend_de_eps!=0)
     { II_eps_barre = eps_barre_BH.II();
	      eps_mises = sqrt(2./3. * II_eps_barre);
        valder_mu_mises_eps.valeur = 1.; valder_mu_mises_eps.derivee = 0.;// initialisation par défaut
        valder_E_mises_eps.valeur = 1.; valder_E_mises_eps.derivee = 0.;// initialisation par défaut
	      switch (depend_de_eps)
		      { case 1:valder_mu_mises_eps=fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
			       case 2:valder_E_mises_eps=fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
			       case 3:valder_mu_mises_eps=fac_mu_Mises_Eps->Valeur_Et_derivee(eps_mises);
			              valder_E_mises_eps=fac_E_Mises_Eps->Valeur_Et_derivee(eps_mises);break;
		      };
     };
    double mu_valeur = valder_mu_QDeps.valeur * valder_mu_mises_eps.valeur;
    double E_valeur = valder_E_QDeps.valeur * valder_E_mises_eps.valeur;
 */
    // --- cas de la thermo dépendance, on calcul les grandeurs matérielles -----
    if (E_temperature != NULL) E = E_temperature->Valeur(*temperature);
    if (depend_cristalinite) // cas d'une dépendance à la température via la cristalinité
      { double P = (sigHH.BaisseDernierIndice()).Trace(); // pour la pression on utilise la trace de sig de l'iter précédent
        // gamma = 2 D_12, si on a un essai de cisaillement pur en 1 2: II_D_barre = 2*(D^1_2)**2
        // d'où gamm_point  
        double gamma_point =  sqrt(2.*II_D_barre); 
        mu = mu_p = ViscositeCristaline(P,gamma_point);
      }
    else // sinon c'est le cas classique de dépendance ou non à la température 
      {if (mu_temperature != NULL) mu = mu_temperature->Valeur(*temperature);
       if (mu_p_temperature != NULL) mu_p = mu_p_temperature->Valeur(*temperature);
      };

    double E_coe = E * E_coef_final; // pour simplifier
    double K = E_coe/(3.*(1.-2.*nu));
    double troisK=3.*K;
    double deuxG=E_coe/(1.+nu);   
    double mu_coe = mu * mu_coef_final; // pour simplifier
    double mu_p_coe = mu_p * mu_coef_final; // pour simplifier
    double unSurmu_coe = 1./mu_coe;
    double co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
    double co3 = unSurDeltat/deuxG;
    double deuxGdeltat = deuxG * deltat;
    double troisKdeltat = troisK * deltat;
    double alpa = troisKdeltat * mu_p_coe/(mu_p_coe+ troisKdeltat);
    double betaa = deuxGdeltat * mu_coe / (mu_coe+ deuxGdeltat);
  
    // sauvegarde des paramètres matériau
    SaveResulLoi_maxwell3D & save_resul = *((SaveResulLoi_maxwell3D*) saveResul);
    save_resul.E = E_coe;
    save_resul.nu = nu;
    save_resul.mu = mu_coe;
    save_resul.mu_p = mu_p_coe;

    // cas d'une viscosité sur la partie sphérique et le fait que la partie sphérique est prise en compte
    double co2=0.; double co4=0.;
    if (((existe_mu_p) ||(volumique_visqueux)) && (!seule_deviatorique))
     { co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat); // ne sert pas toujours
       co4 = unSurDeltat/troisK;
     };
        
     
  // ---- calcul de la partie sphérique du tenseur des contraintes -----
    double Isig_n = sigBH_n.Trace();
    Tenseur3BH SBH_n = sigBH_n - (untier * Isig_n) * IdBH3;

    // cas de la partie sphérique
    double Isigma=0;double unsur3Kdeltat = unSurDeltat/troisK;
    module_compressibilite = 0.; // init par défaut
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
         { Isigma = troisK * Ieps;
           module_compressibilite = troisK * untier;
         }// cas où il n'y a pas de viscosité sphérique
       else // cas ou la partie sphérique est visqueuse, comme c'est un scalaire pas de pb de type de derivée
         { 
// erreur       Isigma = co2 * (Isig_n/(troisK*deltat) + IDeps); 
           Isigma = co2 * (IDeps + co4 * Isig_n); 
           if (Ieps > ConstMath::petit) {module_compressibilite = Isigma / (3.* Ieps);}
           else {module_compressibilite = troisK * mu_p_coe /(mu_p_coe + troisK * deltat);};	
         };
     };
       
  // --- calcul de la partie déviatorique du tenseur des contraintes ----    
    // puis du tenseur total 
    // cas de la partie déviatoire puis du tenseur total 
    Tenseur3HH SHH; // init
    if (en_base_orthonormee)
      {SHH = co1 * IdHH3 * (Deps_barre_BH + co3 *  SBH_n );}
    else
      {SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );};
      
    if (seule_deviatorique)
     { sigHH = SHH; }
    else 
     { if (en_base_orthonormee) {sigHH = SHH + (untier * Isigma) * IdHH3;}
       else { sigHH = SHH + (untier * Isigma) * gijHH ;};
     };
  
//  // --- debug
//  {Tenseur3HH gogo(SHH);Tenseur3BH sig_tr(sigBH_n);Tenseur3BB epsabso(epsBB);
//   Tenseur3BH SBH_nyy(SBH_n); Tenseur3BH D_abs(Deps_barre_BH);
//  if (!en_base_orthonormee) {gogo = SHH.BaseAbsolue(gogo,*(ex.giB_tdt));
//  //cout << "\n sig tr1 = "<< sig_tr;
//     sig_tr = sigBH_n.BaseAbsolue(sig_tr,(*(ex.giB_tdt)),(*(ex.giH_tdt)));
//     SBH_nyy = SBH_n.BaseAbsolue(SBH_nyy,(*(ex.giB_tdt)),(*(ex.giH_tdt)));
//     D_abs = Deps_barre_BH.BaseAbsolue(D_abs,(*(ex.giB_tdt)),(*(ex.giH_tdt)));
//  //cout << "\n sig tr1 = "<< sig_tr;
//     epsabso = epsBB.BaseAbsolue(epsabso,*(ex.giH_tdt));
//     };
//  cout << "\n debug Loi_maxwell3D::Calcul_dsigma_deps "
//       << "\n deltat = " << deltat << " co1= "<<co1 << " co3= "<< co3
//       << "\n eps = "<< epsabso
//       << "\n DepsBB brut = "<<DepsBB
//       << "\n delta_epsBB brut = "<<delta_epsBB
//       << "\n Deps = "<< D_abs
//       << "\n sigHH_t= " << sigHH_nn
//       << "\n SBH_n= " << SBH_nyy
//       << "\n sig transporte = "<< sig_tr
//       << "\n sigma = " << gogo << endl;
//  //cout << "\n giB_tdt= "<<*(ex.giB_tdt) << "\n giH_tdt= "<< (*(ex.giH_tdt)) << endl;
//  }
//   
// // --- fin debug
  
        
    // ---- cas le la variation du tenseur des contraintes par rapport aux déformations---
	   // -- tout d'abord on s'occupe de la variation en considérant E et les mup fixe par rapport à la déformation
    Tenseur3HHHH & d_sigma_depsHHHH =  *((Tenseur3HHHH*) &d_sigma_deps_);
  
    if (en_base_orthonormee)
     { // on commence par calculer la variation de la vitesse de déformation barre / à eps
       // en toute rigueur la formule suivante n'est vrai qu'en mixte c-a-d on a (toujours)
       // (d_D_i^j)barre / d_eps_k^l = 1/deltat (delta_i^k * delta^j_l
       //                                       - 1/3 * delta_l^k * delta_i^j )
       // mais on évolue dans une base ortho-normée donc la position des indices n'importe pas
       // (d_D_ij)barre / d_eps_kl = 1/deltat (delta_i^k * delta_j^l 
       //                                       - 1/3 * delta_ij * g^nm * delta_m^k * delta_n^l)
       // ici g^nm = delta^nm, et g^nm * delta_m^k * delta_n^l = id * id = id = delta^kl
       Tenseur3HHHH d_D_barre_deps_HHHH =
           ((Tenseur3BBBB*) &(unSurDeltat * (PIdBBBB3 - untier * IdBBBB3)))->Monte4Indices();
       // opérateur tangent de la partie déviatorique
       d_sigma_depsHHHH = co1 * d_D_barre_deps_HHHH; // SBH_n est fixe dans le transport ici 

       // puis ajout de la partie sphérique si nécessaire
       if (!seule_deviatorique)
        { if (!(existe_mu_p || volumique_visqueux ))
            // cas où il n'y a pas de viscosité sphérique
            { d_sigma_depsHHHH +=  troisK * IdHHHH3;}
          else // cas ou la partie sphérique est visqueuse (linéaire), c'est un scalaire 
            { d_sigma_depsHHHH +=  (unSurDeltat * co2) * IdHHHH3;};
        };
     }
    else // sinon cas où les bases sont curvilignes
     { // calcul de variables intermédiaires
       I_x_I_HHHH=Tenseur3HHHH::Prod_tensoriel(gijHH,gijHH);
       I_xbarre_I_HHHH=Tenseur3HHHH::Prod_tensoriel_barre(gijHH,gijHH);
       Tenseur3HH epsHH(gijHH * epsBH);
       I_x_eps_HHHH=Tenseur3HHHH::Prod_tensoriel(gijHH,epsHH);
       Tenseur3HH Deps_HH(gijHH * DepsBH);
       I_x_D_HHHH=Tenseur3HHHH::Prod_tensoriel(gijHH,Deps_HH);
       I_xbarre_D_HHHH=Tenseur3HHHH::Prod_tensoriel_barre(gijHH,Deps_HH);
      
       // variation de sigma_n et de la trace en fonction du transport
       switch (type_derive) 
        { case -1: // // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
           {// pour info sigBH_n = 0.5*(gijBB * sigHH_n + (gijBB_t * sigHH_n * gijBB_t) * gijHH) 
            d_sig_t_HHHH = Tenseur3HHHH::Prod_tensoriel_barre(gijHH,sigHH_n);
            d_spherique_sig_t_HHHH = (1. /6.) *
                   (Tenseur3HHHH::Prod_tensoriel(gijHH,sigHH_n)+ Isig_n * I_xbarre_I_HHHH);
            break;
           }
          case 0: // cas d'une dérivée de Lie deux fois covariantes
           {// pour info sigBH_n = (gijBB_t * sigHH_n * gijBB_t) * gijHH
            d_sig_t_HHHH = 2.*Tenseur3HHHH::Prod_tensoriel_barre(gijHH,sigHH_n);
            d_spherique_sig_t_HHHH = untier *
                   (Tenseur3HHHH::Prod_tensoriel(gijHH,sigHH_n)+ Isig_n * I_xbarre_I_HHHH);
            break;
           }
          case 1: // cas d'une dérivée de Lie deux fois contravariantes
           {// pour info sigBH_n = gijBB * sigHH_n, ici il n'y a aucune conséquence
            // sur sigma(t), par contre il y en a une sur la trace
            d_sig_t_HHHH.Inita(0.);
            d_spherique_sig_t_HHHH = untier *
                   (Tenseur3HHHH::Prod_tensoriel(gijHH,sigHH_n)+ Isig_n * I_xbarre_I_HHHH);
            break;
           }
        };
      
       // on choisit entre les différents cas
       double e01,e02;e01=e02=0.; // les coefficients pour la partie transportée
       double b01,b02,b03,b04,b05;b01=b02=b03=b04=b05=0.; // les coefficients pour le reste de l'équation
       // l'expression générique est:
       // d_sigma_depsHHHH =  b01 * I_x_I_HHHH + b02 * I_x_eps_HHHH + b03 * I_xbarre_I_HHHH
       //                  + b04 * I_x_D_HHHH + b05 * I_xbarre_D_HHHH
       //                  + e01 * d_sig_t_HHHH + e02 * d_spherique_sig_t_HHHH;
       // en fonction des coefficients nuls on simplifie
      
       if (seule_deviatorique)
        {if (!(existe_mu_p || volumique_visqueux ))
            // cas où il n'y a pas de viscosité sphérique
          { b01= -betaa * untier * unSurDeltat;
            b02= 0.;
            b03= betaa * unSurDeltat-betaa * untier;
            b04= 2.*betaa * untier;
            b05= -4.*betaa;
            e01=-betaa/mu_coe;
            e02= 0.;
            d_sigma_depsHHHH =  b01 * I_x_I_HHHH + b03 * I_xbarre_I_HHHH
                                + b04 * I_x_D_HHHH + b05 * I_xbarre_D_HHHH
                                + e01 * d_sig_t_HHHH ;
            #ifdef MISE_AU_POINT
            if (Permet_affichage() > 5)
             { cout << "\n Loi_maxwell3D::Calcul_dsigma_deps(.. ";
               cout << "\n b01= "<<b01 << " b02= " << b02 << " b03= " << b03 << " b04= " << b04
                     << " b05= " << b05 << " e01= " << e01 << " e02= " << e02 ;
             };
            #endif
          }
         else // cas avec de la viscosité sphérique
          { b01=-betaa * untier * unSurDeltat;
            b02= 0.;
            b03= betaa * unSurDeltat-betaa * untier*IDeps;
            b04= 2.*betaa * untier;
            b05= -4.*betaa;
            e01=-betaa/mu_coe;
            e02= 0.;
            d_sigma_depsHHHH =  b01 * I_x_I_HHHH + b03 * I_xbarre_I_HHHH
                                + b04 * I_x_D_HHHH + b05 * I_xbarre_D_HHHH
                                + e01 * d_sig_t_HHHH;
            #ifdef MISE_AU_POINT
            if (Permet_affichage() > 5)
             { cout << "\n Loi_maxwell3D::Calcul_dsigma_deps(.. ";
               cout << "\n b01= "<<b01 << " b02= " << b02 << " b03= " << b03 << " b04= " << b04
                     << " b05= " << b05 << " e01= " << e01 << " e02= " << e02 ;
             };
            #endif
          };
        }
       else // cas complet
        {if (!(existe_mu_p || volumique_visqueux ))
            // cas où il n'y a pas de viscosité sphérique
          { b01= K-betaa * untier * unSurDeltat;
            b02= -2.*K;
            b03= K*Ieps+betaa * unSurDeltat-betaa * untier;
            b04= 2.*betaa * untier;
            b05= -4.*betaa;
            e01=-betaa/mu_coe;
            e02= 0.;
            d_sigma_depsHHHH =  b01 * I_x_I_HHHH + b02 * I_x_eps_HHHH + b03 * I_xbarre_I_HHHH
                                + b04 * I_x_D_HHHH + b05 * I_xbarre_D_HHHH
                                + e01 * d_sig_t_HHHH ;
            #ifdef MISE_AU_POINT
            if (Permet_affichage() > 5)
             { cout << "\n Loi_maxwell3D::Calcul_dsigma_deps(.. ";
               cout << "\n b01= "<<b01 << " b02= " << b02 << " b03= " << b03 << " b04= " << b04
                     << " b05= " << b05 << " e01= " << e01 << " e02= " << e02 ;
             };
            #endif
          }
         else // cas avec de la viscosité sphérique
          { b01= (alpa-betaa) * untier * unSurDeltat;
            b02= 0.;
            b03= alpa*IDeps*untier+betaa * unSurDeltat-betaa * untier*IDeps;
            b04= -2.*(alpa-betaa) * untier;
            b05= -4.*betaa;
            e01=-betaa/mu_coe;
            e02= alpa  * unsur3Kdeltat;
            d_sigma_depsHHHH =  b01 * I_x_I_HHHH  + b03 * I_xbarre_I_HHHH
                         + b04 * I_x_D_HHHH + b05 * I_xbarre_D_HHHH
                         + e01 * d_sig_t_HHHH + e02 * d_spherique_sig_t_HHHH;
            #ifdef MISE_AU_POINT
            if (Permet_affichage() > 5)
             { cout << "\n Loi_maxwell3D::Calcul_dsigma_deps(.. ";
               cout << "\n b01= "<<b01 << " b02= " << b02 << " b03= " << b03 << " b04= " << b04
                     << " b05= " << b05 << " e01= " << e01 << " e02= " << e02 ;
             };
            #endif
          };
        };
     };
     
     
	    
	   // ----- maintenant on s'occupe du cas où E et les mu éventuelles peuvent dépendre de D
    // -- on part du principe que d_D = d_eps/deltat, d'où les dérivées / eps = 1/deltat * dérivées / D 



    // si la viscosité est une fonction de D il faut tenir compte de la variation des coefs
    if ((Q_Deps > ConstMath::pasmalpetit)&&(depend_de_D != 0))
    // si la vitesse de déformation est nulle on aura une division par zéro dans les formules de dérivation
    // du au fait que Q_Deps =  racine carré de (Dbarre_eps:Dbarre_eps)
       { // partie commune
// erreur ?		   Tenseur3BH d_Q_Deps_depsBH = (2./deltat)*Deps_barre_BH; // ça c'est toujours vrai, quelque soit la métrique
         Tenseur3HH d_Q_Deps_depsBB; // def et init par défaut
         if (en_base_orthonormee)
          {// d_Q_Deps = 1/deltat * 1/(2*Q_Deps) * (d_eps: Deps_barre_BH + Deps_barre_BH : d_eps)
           // puis on tient compte de 0.5 (d_eps: Deps_barre_BH + Deps_barre_BH : d_eps) = Deps_barre_BH
           Tenseur3BH d_Q_Deps_depsBH = (1./deltat/Q_Deps)*Deps_barre_BH; // ça c'est toujours vrai, quelque soit la métrique
           // par contre maintenant on tiend compte du fait que l'on est en orthonormé:
           d_Q_Deps_depsBB = IdHH3 * d_Q_Deps_depsBH;
           //Tenseur3HH d_undemi_II_deps_HH = d_D_barre_deps_HHHH && Deps_barre_BB;
          }
         else // cas d'une base non orthonormée
          {Tenseur3HH d_II_D_depsBB =  (unSurDeltat * (2.+2.*untier * IDeps)) * Deps_barre_HH
                                      - (unSurDeltat * IDeps *untier) * gijHH
                                      - 4 * (Deps_barre_HH * Deps_barre_BH);
           d_Q_Deps_depsBB = (1./ Q_Deps) * d_II_D_depsBB;
          };
        
         Tenseur3HH d_co1_deps_HH; // init à 0
         Tenseur3HH d_co2_deps_HH; //  "
         Tenseur3HH d_co3_deps_HH; //  "
         Tenseur3HH d_co4_deps_HH; //  "
         bool use_dco3_dco4=false;
         bool use_dco2=false;

         // =====  cas ou mu et/ou mu_p dépend de Q_Deps
         if ((depend_de_D==1)||(depend_de_D==3))
          { // variation du coef multiplicatif de la viscosité
	           // il faut tenir compte de la variation du coef co1
	           // en notant co1=(alpha*f)/(mu*f + beta); avec f = f(Q_Deps) et Q_Deps = sqrt(Dbarre:Dbarre)
				        // d_Q_Deps = 1/(2*Q_Deps) * (d_Dbarre:Dbarre + Dbarre:d_Dbarre) = d_Dbarre:Dbarre
            // on a: (d_co1/d_eps) = ((alpha*f')/(mu*f+beta))*(1-(mu*f)/(mu*f+beta)) 
            //                          /Q_Deps * 0.5 *  (d_Dbarre:Dbarre + Dbarre:d_Dbarre)
	           // on tiens compte ensuite que  0.5*(d_Dbarre:Dbarre + Dbarre:d_Dbarre) = d_Dbarre:Dbarre
		          double alph = deltat * deuxG * mu ;
			         double beta = deuxG * deltat;
            d_co1_deps_HH = 
                 (((alph * d_mu_coef_final__d_D)/(mu_coe + beta))*(1. - mu_coe/(mu_coe + beta)))
                 /Q_Deps * d_Q_Deps_depsBB;
				        // == maintenant éventuellement la partie sphérique si elle est visqueuse
            if (!seule_deviatorique && (existe_mu_p || volumique_visqueux ))
				         { //Isigma = co2 * (IDeps + co4 * Isig_n);
				           //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
				           use_dco2=true;
				           d_co2_deps_HH =
				              (deltat * troisK * mu_p * d_mu_coef_final__d_D
                    * (1. - mu_p_coe / (mu_p_coe + troisK * deltat))
				                /(mu_p_coe + troisK * deltat)
						            )/Q_Deps  * d_Q_Deps_depsBB;
				         };
          };

         // ==== cas ou E dépend de Q_Deps
		       if (((depend_de_D==2)||(depend_de_D==3))&&(!seule_deviatorique))
          { // il faut tenir compte de la variation des coefs co1 co2 co3 co4
				        // == tout d'abord la partie déviatorique
				        // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
			         // A)   co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
				        // on a dco1/deps =
            d_co1_deps_HH += 
				             (deltat * E/(1.+nu) * d_E_coef_final__d_D * mu_coe
					             *(1.- deuxG * deltat / (mu_coe + deuxG * deltat))
						            /(mu_coe + deuxG * deltat)
					            )/Q_Deps * d_Q_Deps_depsBB;

            // B) co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
            d_co2_deps_HH += 
				             (deltat * E/(1.-2.*nu) * d_E_coef_final__d_D * mu_p_coe
					             *(1.- troisK * deltat / (mu_p_coe + troisK * deltat))
						            /(mu_p_coe + troisK * deltat)
					            )/Q_Deps  * d_Q_Deps_depsBB;
	
				        // C) co3 = unSurDeltat/deuxG
				        use_dco3_dco4=true;
				        d_co3_deps_HH = (- E/(1.+nu) * d_E_coef_final__d_D * unSurDeltat /(deuxG*deuxG)
					              )/Q_Deps  * d_Q_Deps_depsBB;
				        // D) co4  = unSurDeltat/troisK;
				        d_co4_deps_HH = (- E/(1.-2.*nu) * d_E_coef_final__d_D * unSurDeltat /(troisK*troisK)
					                       )/Q_Deps  * d_Q_Deps_depsBB;
			       };

         // ==== maintenant on s'occupe de reconstituer la matrice tangente
		       // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
			      //tout d'abord en considérant le co3 est fixe, et gijHH * Deps_barre_BH = Deps_barre_HH, d'où:
         d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(SHH/co1,d_co1_deps_HH);
			      // puis si co3 dépend de D
			      if (use_dco3_dco4)
             d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(co1*(IdHH3*SBH_n),d_co3_deps_HH);
			      // maintenant le cas de co2 qui dépend de D
			      if (use_dco2)
			        {//Isigma = co2 * (IDeps + co4 * Isig_n); donc en appelant sig_s_HH la partie sphérique associée
            Tenseur3HH d_Isigma_deps_HH = (IDeps + co4 * Isig_n) * d_co2_deps_HH;
				        // si co4 dépend de D
				        if (use_dco3_dco4)
				        d_Isigma_deps_HH += (co2 * Isig_n) * d_co4_deps_HH ;
				        // et maintenant l'opérateur tangent résultant
            //Isigma = co2 * (IDeps + co4 * Isig_n); donc en appelant sig_s_HH la partie sphérique associée
            // sig_s_HH = Isigma * gijHH; d'où
            // d_sig_s_HH_deps_HH = gijHH tensoriel d_Isigma_deps_HH
            d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(IdHH3,d_Isigma_deps_HH);                         
           }
         else if(use_dco3_dco4)
          // cas où co2 ne varie pas mais co4 varie
          { Tenseur3HH d_Isigma_deps_HH = (co2 * Isig_n) * d_co4_deps_HH ;
            // et maintenant l'opérateur tangent résultant
            // sig_s_HH = Isigma * gijHH; d'où
            // d_sig_s_HH_deps_HH = gijHH tensoriel d_Isigma_deps_HH
            d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(IdHH3,d_Isigma_deps_HH);
          };
       };

    // si la viscosité est une fonction de eps_mises il faut tenir compte de la variation des coefs 
	   if ((eps_mises > ConstMath::pasmalpetit)&&(depend_de_eps != 0))
		  // si la déformation est nulle on aura une division par zéro dans les formules de dérivation
		  // du au fait que eps_mises =  sqrt(2/3*Eps_barre:Eps_barre)
       { // partie commune
			      // d_eps_mises = sqrt(2/3)/(2*eps_mises) * (d_eps: eps_barre_BH + eps_barre_BH : d_eps)
			      // puis on tient compte de 0.5 (d_eps: eps_barre_BH + eps_barre_BH : d_eps) = eps_barre_BH
				     //  d_eps_mises = sqrt(2./3.) * 0.5 / eps_mises *  (d_epsbarre:epsbarre + epsbarre:d_epsbarre)
 
         Tenseur3HH d_eps_mises_depsBB; // def et init par défaut
         if (en_base_orthonormee)
          {// on tiens compte ensuite que  0.5*(d_epsbarre:epsbarre + epsbarre:d_epsbarre) = d_epsbarre:epsbarre
           Tenseur3BH d_eps_mises_depsBH = (sqrt(2./3.)/eps_mises)*eps_barre_BH; // ça c'est toujours vrai, quelque soit la métrique
           // par contre maintenant on tiend compte du fait que l'on est en orthonormé:
           Tenseur3HH d_eps_mises_depsBB = IdHH3 * d_eps_mises_depsBH;
          }
         else // cas d'une base non orthonormée
          {Tenseur3HH eps_barre_HH(gijHH * eps_barre_BH);
           Tenseur3HH d_II_eps_depsBB =  ((2.+2.*untier * Ieps)) * eps_barre_HH
                                      - ( Ieps * untier) * gijHH
                                      - 4 * (eps_barre_HH * eps_barre_BH);
           d_eps_mises_depsBB = (sqrt(2./3.)/eps_mises) * d_II_eps_depsBB;
          };
 
         Tenseur3HH d_co1_deps_HH; // init à 0
         Tenseur3HH d_co2_deps_HH; //  "
         Tenseur3HH d_co3_deps_HH; //  "
         Tenseur3HH d_co4_deps_HH; //  "
         bool use_dco3_dco4=false;
         bool use_dco2=false;

         // =====  cas ou mu et/ou mu_p dépend de eps_mise
         if ((depend_de_eps==1)||(depend_de_eps==3))
          { // variation du coef multiplicatif de la viscosité
	           // il faut tenir compte de la variation du coef co1
	           // en notant co1=(alpha*f)/(mu*f + beta); avec f = f(eps_mises) et eps_mises = sqrt(2./3. * epsbarre:epsbarre)
            // on a: (d_co1/d_eps) = ((alpha*f')/(mu*f+beta))*(1-(mu*f)/(mu*f+beta)) 
            //                          /eps_mises * d_eps_mises
		          double alph = deltat * deuxG * mu ;
			         double beta = deuxG * deltat;
            d_co1_deps_HH = 
                 (((alph * d_mu_coef_final__d_eps)/(mu_coe + beta))*(1. - mu_coe/(mu_coe + beta)))
                 / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;
				        // == maintenant éventuellement la partie sphérique si elle est visqueuse
            if (!seule_deviatorique && (existe_mu_p || volumique_visqueux ))
				         { //Isigma = co2 * (IDeps + co4 * Isig_n);
				           //co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
				           use_dco2=true;
				           d_co2_deps_HH =
				                   (deltat * troisK * mu_p * d_mu_coef_final__d_eps
                         * (1. - mu_p_coe / (mu_p_coe + troisK * deltat))
				                     /(mu_p_coe + troisK * deltat)
						                 ) / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;
				         };
          };

         // ==== cas ou E dépend de Q_Deps
		       if (((depend_de_D==2)||(depend_de_D==3))&&(!seule_deviatorique))
          { // il faut tenir compte de la variation des coefs co1 co2 co3 co4
				        // == tout d'abord la partie déviatorique
				        // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
			         // A)   co1 = deltat * deuxG * mu_coe/(mu_coe + deuxG * deltat);
            d_co1_deps_HH += 
                       (deltat * E/(1.+nu) * d_E_coef_final__d_eps * mu_coe
					                   *(1.- deuxG * deltat / (mu_coe + deuxG * deltat))
						                  /(mu_coe + deuxG * deltat)
					                  ) / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;

            // B) co2=deltat * troisK * mu_p_coe /(mu_p_coe + troisK * deltat);
            d_co2_deps_HH += 
				                   (deltat * E/(1.-2.*nu) * d_E_coef_final__d_eps * mu_p_coe
					                   *(1.- troisK * deltat / (mu_p_coe + troisK * deltat))
						                  /(mu_p_coe + troisK * deltat)
					                  ) / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;
	
				        // C) co3 = unSurDeltat/deuxG
				        use_dco3_dco4=true;
				        d_co3_deps_HH = (- E/(1.+nu) * d_E_coef_final__d_eps * unSurDeltat /(deuxG*deuxG)
					              ) / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;
				        // D) co4  = unSurDeltat/troisK;
				        d_co4_deps_HH = (- E/(1.-2.*nu) * d_E_coef_final__d_eps * unSurDeltat /(troisK*troisK)
					              ) / eps_mises * sqrt(2./3.) * d_eps_mises_depsBB;
			       };

         // ==== maintenant on s'occupe de reconstituer la matrice tangente
		       // SHH = co1 * gijHH * (Deps_barre_BH + co3 *  SBH_n );
			      //tout d'abord en considérant le co3 est fixe, et gijHH * Deps_barre_BH = Deps_barre_HH, d'où:
         d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(SHH/co1,d_co1_deps_HH);
			      // puis si co3 dépend de eps_mises
			      if (use_dco3_dco4)
             d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(co1*(IdHH3*SBH_n),d_co3_deps_HH);
			      // maintenant le cas de co2 qui dépend de eps_mises
			      if (use_dco2)
          { //Isigma = co2 * (IDeps + co4 * Isig_n); donc en appelant sig_s_HH la partie sphérique associée
            Tenseur3HH d_Isigma_deps_HH = (IDeps + co4 * Isig_n) * d_co2_deps_HH;
            // si co4 dépend de eps_mises
				        if (use_dco3_dco4)
				          d_Isigma_deps_HH += (co2 * Isig_n) * d_co4_deps_HH ;
				        // et maintenant l'opérateur tangent résultant
            //Isigma = co2 * (IDeps + co4 * Isig_n); donc en appelant sig_s_HH la partie sphérique associée
            // sig_s_HH = Isigma * gijHH; d'où
            // d_sig_s_HH_deps_HH = gijHH tensoriel d_Isigma_deps_HH
            d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(IdHH3,d_Isigma_deps_HH);                         
			       }
			      else if(use_dco3_dco4)
			        // cas où co2 ne varie pas mais co4 varie
			       { Tenseur3HH d_Isigma_deps_HH = (co2 * Isig_n) * d_co4_deps_HH ;
				        // et maintenant l'opérateur tangent résultant
            // sig_s_HH = Isigma * gijHH; d'où
            // d_sig_s_HH_deps_HH = gijHH tensoriel d_Isigma_deps_HH
            d_sigma_depsHHHH += Tenseur3HHHH::Prod_tensoriel(IdHH3,d_Isigma_deps_HH);                         
			       };
       }; 
	 


  // ---- traitement des énergies ----
    energ.Inita(0.); double ener_elas=0.; double ener_visqueux = energ_t.DissipationVisqueuse();
    // on peut raisonner en supposant une décomposition de la vitesse de déformation
    //  ... partie sphérique
    if (!seule_deviatorique)
     { if (!(existe_mu_p || volumique_visqueux ))
         // cas où il n'y a pas de viscosité sphérique => élasticité linéaire
         // 0.5 car on considère que sur le pas sig augmente proportionnellement
         { ener_elas = 0.5 * (Isigma * Ieps); }
       else if (!seule_deviatorique)
         // cas où on a une partie sphérique et qu'elle contient une partie  visqueuse
         // I_{D_vis}=I_sig / mu*f; I_{D_elas} = I_sig / (3*K);
         { ener_elas += 0.5 * (Isigma * Isigma) / troisK; // partie élastique
           if (Dabs(mu_p) > ConstMath::trespetit)         // partie visqueuse
            {ener_visqueux += (Isigma * Isigma) * deltat / mu_p;};
         };
     };
    //  ... partie déviatorique    
       // {si mu_coe = 0} => {SHH = 0} d'où une énergie visqueuse nulle, sinon
       // on calcul D_barre_visqueux = SHH/mu_coe d'où le calcul de l'énergie qui suit
    Tenseur3BH SBH; // def init
    if (en_base_orthonormee)
      {SBH = IdBB3 * SHH;}
    else
      {SBH = gijBB * SHH;};
    double S2= (SBH && SBH); // pour simplifier  
    ener_elas += 0.5 * S2 /deuxG;                       // partie élastique  
    if (Dabs(mu_coe) > ConstMath::trespetit)         // partie visqueuse
       {ener_visqueux += S2 * deltat / mu_coe;};
    // ... mise à jour de energ
    energ.ChangeEnergieElastique(ener_elas); 
    energ.ChangeDissipationVisqueuse(ener_visqueux);
    
    // on libère les tenseurs intermédiaires        
    LibereTenseur(); LibereTenseurQ();
//----- debug
    #ifdef MISE_AU_POINT
    if (Permet_affichage() > 5)
     { cout << "\n Loi_maxwell3D::Calcul_dsigma_deps(.. ";
       cout << "\n sigmaHH: "<<sigHH;
       cout << "\n d_sigma_depsHHHH: "<<d_sigma_depsHHHH;
     };
    #endif
 };
		  	
// activation des données des noeuds et/ou elements nécessaires au fonctionnement de la loi
//  ici concerne de la vérification d'existence, mais c'est appelé une fois, c'est ça l'intérêt
void Loi_maxwell3D::Activation_donnees(Tableau<Noeud *>& tabnoeud,bool ,LesPtIntegMecaInterne& lesPtMecaInt)
  { // on vérifie l'existance de la critallinité au noeud si nécessaire
    if (depend_cristalinite)
     { if (crista_aux_noeuds)
        { 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(PROP_CRISTA)))
              {tabnoeud(i)->Met_en_service(PROP_CRISTA);}
             else
              { cout << "\n erreur: la grandeur " << Nom_ddl(PROP_CRISTA) << " n'existe pas "
                     << " il n'est pas possible d'utiliser une loi de maxwell avec cette grandeur supposee"
                     << " definie aux noeuds. Il manque sans doute des donnees !!! "
                     << "\n Loi_maxwell3D::Activation_donnees(...";
                Sortie(1);
              };
           };
        };
     };
    // appel de la méthode de la classe mère
    Loi_comp_abstraite::Activ_donnees(tabnoeud,dilatation,lesPtMecaInt);    
  };

//---------------------------------------- méthodes internes ----------------------------------
		  	
// calcul récup de la cristalinité si besoin est
void Loi_maxwell3D::CalculGrandeurTravail
             (const PtIntegMecaInterne&
             ,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP
             ,const Met_abstraite::Impli* ex_impli
             ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
             ,const Met_abstraite::Umat_cont* ex_umat
             ,const List_io<Ddl_etendu>* exclure_dd_etend
             ,const List_io<const TypeQuelconque *>* exclure_Q
             )
 { // récupération éventuelle de la cristalinité
   if (depend_cristalinite)
     { if (crista_aux_noeuds)
        // cas d'une proportion provenant d'une interpolation aux noeuds
        { taux_crista = def.DonneeInterpoleeScalaire(PROP_CRISTA,temps); }
       else
       {
        #ifdef MISE_AU_POINT
     	   if (dTP.TauxCrista() == NULL)
          {cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration "
                << " il n'est pas possible de calculer la viscosite dependante de la cristalinite "
                << "\n Loi_maxwell3D::CalculGrandeurTravail(.... ";
           Sortie(1); 
          };
        #endif
        taux_crista= *dTP.TauxCrista();
       }
     };
 };
 
// calcul de la viscosité dépendante de la cristalinité
double Loi_maxwell3D::ViscositeCristaline(double & P, double & gamma_point)
  { double A2p= At2 + D3 * P;
    double TmoinsTstar = (*temperature)-(D2+D3);
    double mu0_TP = D1 * exp(-(A1*TmoinsTstar)/(A2p + TmoinsTstar));
// on essaie de limiter l'exponentiel    
//    double mu0_TP_alpha = mu0_TP * exp(C1*taux_crista*taux_crista);
// on choisit limite maxi exp() à exp(20)
    double mu0_TP_alpha = mu0_TP * exp(20.*tanh(C1*taux_crista*taux_crista/20.));
    
    
    double mu_TP_alpha = mu0_TP_alpha / (1.+ pow((mu0_TP_alpha * gamma_point/tauStar),(1.-nc)));
//---- debug
//    if (mu_TP_alpha > 1.e10)        
//        cout << " " << mu << " " << taux_crista << " " << endl;
//---- debug        
    return mu_TP_alpha;
	};