
// 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 "Met_abstraite.h"   
#include "Util.h"
#include "Coordonnee3.h"

using namespace std;  //introduces namespace std
                      // a priori on n'en n'a pas besoin mais c'est pour que l'éditeur reconnaisse les différentes
                      // fonctions ??
 

//  =========================================================================================
//  vu la taille des executables le fichier est decompose en trois
// le premier : Met_abstraite1s2.cp concerne les constructeurs, destructeur et 
//              la gestion des variables
// le deuxième :  Met_abstraite2s2.cp concerne  le calcul des méthodes publiques
// le troisième:  Met_abstraite2s2.cp concerne  le calcul des méthodes privées
//  =========================================================================================

// ***********$ il faut utiliser des références pour optimiser l'opérateur parenthèse
/// ceci dans la plupart des routines gourmandes !!!!!!!!!!!!!!!!!!!!
 
 //==================== METHODES PROTEGEES===============================

// calcul des points
	// calcul du point a t0
void Met_abstraite::Calcul_M0
		   ( const Tableau<Noeud *>& tab_noeud, const  Vecteur& phi, int nombre_noeud)
  {     
    #ifdef MISE_AU_POINT	 	 
	  if  (M0 == NULL)
			{ cout << "\nErreur : le point a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_M0 \n";
			  Sortie(1);
			};
    #endif
	int amax = M0->Dimension();
	for (int a=1;a<= amax;a++)
		 { double & M0a=(*(M0))(a); 
		   M0a=0.; // (*(M0))(a)= 0.;
		   for (int r=1;r<=nombre_noeud;r++)
			{ M0a +=tab_noeud(r)->Coord0()(a) * phi(r);
			};
		};
   };		   
	// calcul du point a t
void Met_abstraite::Calcul_Mt
		   ( const  Tableau<Noeud *>& tab_noeud,  const Vecteur& phi, int nombre_noeud)
  { 
    #ifdef MISE_AU_POINT	 	 
	  if  (Mt == NULL)
			{ cout << "\nErreur : le point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_Mt \n";
			  Sortie(1);
			};
    #endif
	int amax = Mt->Dimension();
	for (int a=1;a<= amax;a++)
		 { double & Mta=(*(Mt))(a); 
		   Mta=0.; // (*(Mt))(a)= 0.;
		   for (int r=1;r<=nombre_noeud;r++)
			{ Mta +=tab_noeud(r)->Coord1()(a) * phi(r);
			};
		};
   };
   		   
// calcul des variations du point a t
void Met_abstraite::Calcul_d_Mt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nbnoeu)
  { 
    #ifdef MISE_AU_POINT	 	 
	  if  (d_Mt == NULL)
			{ cout << "\nErreur : le de variation du point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Mt \n";
			  Sortie(1);
			};
    #endif
    int indice;       
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nbnoeu; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Mt_indice=(*d_Mt)(indice);
           d_Mt_indice.Zero();
           d_Mt_indice(b)=phi(r);
          }              
   };

	// calcul du point a tdt
void Met_abstraite::Calcul_Mtdt      
		   ( const  Tableau<Noeud *>& tab_noeud, const  Vecteur& phi, int nombre_noeud)
  {
    #ifdef MISE_AU_POINT	 	 
	   if  (Mtdt == NULL)
      { cout << "\nErreur : le point a t+dt n'est pas dimensionne !\n";
        cout << "void Met_abstraite::Calcul_Mtdt \n";
        Sortie(1);
      };
    #endif
    int amax = Mtdt->Dimension();
    for (int a=1;a<= amax;a++)
      { double & Mtdta=(*(Mtdt))(a); 
        Mtdta=0.; // (*(Mtdt))(a)= 0.;
        for (int r=1;r<=nombre_noeud;r++)
         { Mtdta +=tab_noeud(r)->Coord2()(a) * phi(r);
         };
     };
   };
   		   
// calcul des variations du point a tdt
void Met_abstraite::Calcul_d_Mtdt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nbnoeu)
  { 
    #ifdef MISE_AU_POINT	 	 
	  if  (d_Mtdt == NULL)
			{ cout << "\nErreur : le de variation du point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Mtdt \n";
			  Sortie(1);
			};
    #endif
    int indice;       
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nbnoeu; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Mtdt_indice=(*d_Mtdt)(indice);
           d_Mtdt_indice.Zero();
           d_Mtdt_indice(b)=phi(r);
          }              
   };

// calcul de la base  naturel a t0  -- calcul classique
void Met_abstraite::Calcul_giB_0
 (  const Tableau<Noeud *>& tab_noeud,  const Mat_pleine& dphi, int nombre_noeud,const Vecteur&)
   { 
    #ifdef MISE_AU_POINT	 	 
	  if  (giB_0 == NULL)
			{ cout << "\nErreur : la base a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_giB_0 \n";
			  Sortie(1);
			};
    #endif
	for (int i=1;i<= nbvec_base;i++)
	  {for (int a=1;a<= dim_base;a++)	  
		 { double & gib0_i_a = giB_0->CoordoB(i)(a);
		   gib0_i_a = 0.;
		   for (int r=1;r<=nombre_noeud;r++)
			{ gib0_i_a += tab_noeud(r)->Coord0()(a) * dphi(i,r);
			};
		};
	};
   };
// calcul de la base  naturel a t  -- calcul classique
void Met_abstraite::Calcul_giB_t
 (  const Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi, int nombre_noeud,const Vecteur&)
   {	
    #ifdef MISE_AU_POINT	 	 
	  if  (giB_t == NULL)
			{ cout << "\nErreur : la base a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_giB_t \n";
			  Sortie(1);
			};
    #endif
	for (int i=1;i<= nbvec_base;i++)
	  {for (int a=1;a<= dim_base;a++)
		 { double & gibt_i_a = giB_t->CoordoB(i)(a);
		   gibt_i_a = 0.;
		   for (int r=1;r<=nombre_noeud;r++)
			   { gibt_i_a += tab_noeud(r)->Coord1()(a) * dphi(i,r);
			};
		};
	};
   };
// calcul de la base  naturel a tdt  -- calcul classique
void Met_abstraite::Calcul_giB_tdt
 (  const Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi, int nombre_noeud,const Vecteur&)
   {
    #ifdef MISE_AU_POINT	 	 
	  if  (giB_tdt == NULL)
			{ cout << "\nErreur : la base a t+dt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_giB_tdt \n";
			  Sortie(1);
			};
    #endif
	for (int i=1;i<= nbvec_base;i++)
	  {for (int a=1;a<= dim_base;a++)
		 { double & gibtdt_i_a = giB_tdt->CoordoB(i)(a);
		   gibtdt_i_a = 0.;
		   for (int r=1;r<=nombre_noeud;r++)
			{ gibtdt_i_a += tab_noeud(r)->Coord2()(a) * dphi(i,r);
			};
		};
	};
   };

// calcul des metriques
        // Calcul des composantes covariantes de la metrique d'une base naturelle:
void  Met_abstraite::Calcul_gijBB (BaseB & giB,TenseurBB & gijBB)
  { int giBnbVecteur = giB.NbVecteur();
    for (int i = 1; i<= giBnbVecteur; i++)
       for (int j=1; j<= i; j++)
           gijBB.Coor(i,j) = (giB(i)).ScalBB(giB(j));
  };
	// Calcul des composantes covariantes de la metrique de la base naturelle a 0 :
void Met_abstraite::Calcul_gijBB_0 () 
 { 
   #ifdef MISE_AU_POINT	 	 
	if  ((giB_0 == NULL) || (gijBB_0 == NULL))
			{ cout << "\nErreur : la base et/ou metrique a t=0 n'est pas defini !\n";
			  cout << "Calcul_gijBB_0 \n";
			  Sortie(1);
			};
   #endif
   Calcul_gijBB(*(giB_0),*(gijBB_0));
  };   
	// Calcul des composantes covariantes de la metrique de la base naturelle a t :
void Met_abstraite::Calcul_gijBB_t () 
 { 
   #ifdef MISE_AU_POINT	 	 
	if  ((giB_t == NULL) || (gijBB_t == NULL))
			{ cout << "\nErreur : la base et/ou metrique a t n'est pas defini !\n";
			  cout << "Calcul_gijBB_t \n";
			  Sortie(1);
			};
   #endif
   Calcul_gijBB(*(giB_t),*(gijBB_t));
  };  
	// Calcul des composantes covariantes de la metrique de la base naturelle a tdt :
void Met_abstraite::Calcul_gijBB_tdt () 
 {  
   #ifdef MISE_AU_POINT	 	 
	if  ((giB_tdt == NULL) || (gijBB_tdt == NULL))
			{ cout << "\nErreur : la base et/ou metrique a t+dt n'est pas defini !\n";
			  cout << "Calcul_gijBB_tdt \n";
			  Sortie(1);
			};
   #endif   
   Calcul_gijBB(*(giB_tdt),*(gijBB_tdt));
  };  

  // calcul du gradient de vitesse à t
void Met_abstraite::Calcul_gradVBB_t
		   (const  Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi,int nombre_noeud)
 {  
  #ifdef MISE_AU_POINT	 	 
	if  ((giB_t == NULL) || (gradVBB_t == NULL))
			{ cout << "\nErreur : la base et/ou le gradient de vitesse a t n'est pas defini !\n";
			  cout << "\nMet_abstraite::Calcul_gradVBB_t \n";
			  Sortie(1);
			};
  #endif 
  // Vi|j = V^{ar} \phi_{r,j} \vec I_a . \vec g_i   
  for (int i=1;i<= nbvec_base;i++)
   {CoordonneeB & giBt = giB_t->CoordoB(i);
    for (int j=1;j<= nbvec_base;j++)
     {double& gradVij=(*gradVBB_t).Coor(i,j);
      gradVij = 0.;
	  for (int r=1;r<=nombre_noeud;r++)
       {switch (dim_base)
        {case 3:
			 gradVij += tab_noeud(r)->Valeur_t(V3) * dphi(j,r) * giBt(3);
         case 2:
			 gradVij += tab_noeud(r)->Valeur_t(V2) * dphi(j,r) * giBt(2);
         case 1:
			 gradVij += tab_noeud(r)->Valeur_t(V1) * dphi(j,r) * giBt(1);      
        } //-- fin du switch
       } // -- fin du for sur r 
     } // -- fin du for sur j
    }// -- fin du for sur i   
  };  
		                         
  // calcul gradient de vitesse à t+dt
void Met_abstraite::Calcul_gradVBB_tdt
		   (const Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi,int nombre_noeud)
 {  
  #ifdef MISE_AU_POINT	 	 
	if  ((giB_tdt == NULL) || (gradVBB_tdt == NULL))
			{ cout << "\nErreur : la base et/ou le gradient de vitesse a t+dt n'est pas defini !\n";
			  cout << "\nMet_abstraite::Calcul_gradVBB_tdt \n";
			  Sortie(1);
			};
  #endif
  // Vi|j = V^{ar} \phi_{r,j} \vec I_a . \vec g_i   
  for (int i=1;i<= nbvec_base;i++)
   {CoordonneeB & giBtdt = giB_tdt->CoordoB(i);
    for (int j=1;j<= nbvec_base;j++)
     {double& gradVij=(*gradVBB_tdt).Coor(i,j);
      gradVij = 0.;
	  for (int r=1;r<=nombre_noeud;r++)
       {switch (dim_base)
        {case 3:
			 gradVij += tab_noeud(r)->Valeur_tdt(V3) * dphi(j,r) * giBtdt(3);
         case 2:
			 gradVij += tab_noeud(r)->Valeur_tdt(V2) * dphi(j,r) * giBtdt(2);
         case 1:
			 gradVij += tab_noeud(r)->Valeur_tdt(V1) * dphi(j,r) * giBtdt(1);      
        } //-- fin du switch
       } // -- fin du for sur r 
     } // -- fin du for sur j
    }// -- fin du for sur i   
  };  

// calcul du gradient de vitesse moyen en utilisant delta x^ar/delta t
// dans le cas où les ddl à tdt n'existent pas -> utilisation de la  vitesse sécante entre 0 et t !!
void Met_abstraite::Calcul_gradVBB_moyen_t
		   (const  Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi,int nombre_noeud) 
 {  
  #ifdef MISE_AU_POINT
	if  ((giB_t == NULL) || (gradVmoyBB_t == NULL))
			{ cout << "\nErreur : la base et/ou le gradient de vitesse a t+dt n'est pas defini !\n";
			  cout << "\nMet_abstraite::Calcul_gradVBB_moyen_t \n";
			  Sortie(1);
			};
  #endif
  // on pose V^{ar} = delta X^{ar} / delta t
  // on choisit une vitesse de déformation pour l'instant identique à deltaeps/t
  const VariablesTemps& vartemps = ParaGlob::Variables_de_temps();
  // dans le cas où l'incrément de temps est nul la vitesse est nulle
  double deltat=vartemps.IncreTempsCourant();double unsurdeltat;
  double temps =vartemps.TempsCourant(); 
  // on regarde le premier noeud pour savoir s'il y a des coordonnées à t+dt
  if (tab_noeud(1)->ExisteCoord2())
   {// dans ce cas on utilise l'incrément de temps
    if (deltat >= ConstMath::trespetit)
        {unsurdeltat = 1./deltat;}
    else
        {unsurdeltat = 0.;} // o car on veut une vitesse nulle 
    }
  else // sinon on utilise la variation totale de 0 à t, le delta t vaudra le temps actuel      
   { if (temps >= ConstMath::trespetit)
       {unsurdeltat = 1./temps;}
     else
       {unsurdeltat = 0.;} // o car on veut une vitesse nulle
     }   
      // Vi|j = V^{ar} \phi_{r,j} \vec I_a . \vec g_i 
  gradVmoyBB_t->Inita(0.);
  for (int iv=1;iv<=nbvec_base;iv++)
    dmatV_moy_t->CoordoB(iv).Zero();
  for (int r=1;r<=nombre_noeud;r++)
    { // on construit d'abord le vecteur vitesse
      Coordonnee & V = V_moy_t(r);
      if (tab_noeud(r)->ExisteCoord2())
         V = (tab_noeud(r)->Coord2() - tab_noeud(r)->Coord1())*unsurdeltat; 
      else   // sinon utilisation des coordonnées sécantes !!!  
         V = (tab_noeud(r)->Coord1() - tab_noeud(r)->Coord0())*unsurdeltat;  
      for (int i=1;i<= nbvec_base;i++)
        {CoordonneeB & giBt = giB_t->CoordoB(i);
         // calcul de gradVij
         for (int j=1;j<= nbvec_base;j++)
          {double& gradVij=(*gradVmoyBB_t).Coor(i,j);
           switch (dim_base)
            {case 3:
              gradVij += V(3) * dphi(j,r) * giBt(3);
                     case 2:
              gradVij += V(2) * dphi(j,r) * giBt(2);
                     case 1:
              gradVij += V(1) * dphi(j,r) * giBt(1);
             } //-- fin du switch
           } // -- fin du for sur j
         // calcul des vecteurs V,i moyens
         CoordonneeB & dmatV_moy_t_i= dmatV_moy_t->CoordoB(i);
           switch (dim_base)
            {case 3:
               dmatV_moy_t_i(3) += V(3) * dphi(i,r);
             case 2:
               dmatV_moy_t_i(2) += V(2) * dphi(i,r);
             case 1:
               dmatV_moy_t_i(1) += V(1) * dphi(i,r);
             } //-- fin du switch
         }// -- fin du for sur i   
      } // -- fin du for sur r 
  };  

// calcul du gradient de vitesse moyen en utilisant delta x^ar/delta t
void Met_abstraite::Calcul_gradVBB_moyen_tdt
		   (const  Tableau<Noeud *>& tab_noeud, const  Mat_pleine& dphi,int nombre_noeud) 
 {  
  #ifdef MISE_AU_POINT
	if  ((giB_tdt == NULL) || (gradVmoyBB_tdt == NULL))
			{ cout << "\nErreur : la base et/ou le gradient de vitesse a t+dt n'est pas defini !\n";
			  cout << "\nMet_abstraite::Calcul_gradVBB_moyen_tdt \n";
			  Sortie(1);
			};
  #endif
  // on pose V^{ar} = delta X^{ar} / delta t
  // on choisit une vitesse de déformation pour l'instant identique à deltaeps/t
  const VariablesTemps& vartemps = ParaGlob::Variables_de_temps();
  // dans le cas où l'incrément de temps est nul la vitesse est nulle
  double deltat=vartemps.IncreTempsCourant();
  double unsurdeltat;
  if (deltat >= ConstMath::trespetit)
     {unsurdeltat = 1./deltat;}
  else
     {unsurdeltat = 0.;} // o car on veut une vitesse nulle 
      // Vi|j = V^{ar} \phi_{r,j} \vec I_a . \vec g_i 
  gradVmoyBB_tdt->Inita(0.);
  for (int iv=1;iv<=nbvec_base;iv++)
    dmatV_moy_tdt->CoordoB(iv).Zero();
  for (int r=1;r<=nombre_noeud;r++)
    { // on construit d'abord le vecteur vitesse
      Coordonnee & V = V_moy_t(r);
      V = (tab_noeud(r)->Coord2() - tab_noeud(r)->Coord1())*unsurdeltat;  
      for (int i=1;i<= nbvec_base;i++)
        {CoordonneeB & giBtdt = giB_tdt->CoordoB(i);
         for (int j=1;j<= nbvec_base;j++)
          {double& gradVij=(*gradVmoyBB_tdt).Coor(i,j);
           switch (dim_base)
            {case 3:
              gradVij += V(3) * dphi(j,r) * giBtdt(3);
                     case 2:
              gradVij += V(2) * dphi(j,r) * giBtdt(2);
                     case 1:
              gradVij += V(1) * dphi(j,r) * giBtdt(1);
             } //-- fin du switch
           } // -- fin du for sur j
         // calcul des vecteurs V,i moyens
         CoordonneeB & dmatV_moy_tdt_i= dmatV_moy_tdt->CoordoB(i);
           switch (dim_base)
            {case 3:
               dmatV_moy_tdt_i(3) += V(3) * dphi(i,r);
             case 2:
               dmatV_moy_tdt_i(2) += V(2) * dphi(i,r);
             case 1:
               dmatV_moy_tdt_i(1) += V(1) * dphi(i,r);
             } //-- fin du switch
         }// -- fin du for sur i   
      }; // -- fin du for sur r 
  };  

   // Calcul des composantes contravariantes de la metrique de la base naturelle a 0 :
void Met_abstraite::Calcul_gijHH_0 () 
  {
     #ifdef MISE_AU_POINT
      if  ((giB_0 == NULL) || (gijBB_0 == NULL) || (gijHH_0 == NULL))
			{ cout << "\nErreur : la base ou la metrique cov ou contra ne sont   definis !\n";
			  cout << "Calcul_gijHH_0 \n";
			  Sortie(1);
			};
     #endif
     *gijHH_0 = gijBB_0->Inverse();
   }; 
   // Calcul des composantes contravariantes de la metrique de la base naturelle a t :
void Met_abstraite::Calcul_gijHH_t () 
  {
     #ifdef MISE_AU_POINT
      if  ((giB_t == NULL) || (gijBB_t == NULL))
			{ cout << "\nErreur : la base et la metrique n'est pas defini !\n";
			  cout << "Calcul_gijHH_t \n";
			  Sortie(1);
			};
     #endif
     *gijHH_t = gijBB_t->Inverse();
   }; 

   // Calcul des composantes contravariantes de la metrique de la base naturelle a tdt :
void Met_abstraite::Calcul_gijHH_tdt () 
  {
     #ifdef MISE_AU_POINT
       if  ((giB_tdt == NULL) || (gijBB_tdt == NULL))
			{ cout << "\nErreur : la base et la metrique n'est pas defini !\n";
			  cout << "Calcul_gijHH_tdt \n";
			  Sortie(1);
			};
     #endif
     *gijHH_tdt = gijBB_tdt->Inverse();
   }; 
// calcul des bases duales
void Met_abstraite::Calcul_giH(BaseB* giB, TenseurHH* gijHH, BaseH * giH)
  {
    #ifdef MISE_AU_POINT	 	 
	 if  ((giB == NULL) || (gijHH == NULL))
			{ cout << "\nErreur : la base naturelle  n'existe pas !\n";
			  cout << "Erreur : la base metrique contravariante  n'existe pas !\n";
			  cout << "Calcul_giH \n";
			  Sortie(1);
			};
    #endif
    int nb = giB->NbVecteur();
    for (int i=1; i<= nb; i++)
     {CoordonneeH & giH_i= giH->CoordoH(i);
      giH_i.Zero(); //(*giH)(i).Zero(); // mise a zero du vecteur
      for (int j=1; j<= nb; j++)
       { CoordonneeB & giB_j=  giB->CoordoB(j);
         for (int k=1;k<= dim_base; k++)
          giH_i(k) +=  (*gijHH)(i,j) * giB_j(k);
//         (*giH)(i)(k) +=  gijHH(i,j) * giB(j)(k);
        }
      }    	          
  };    
void Met_abstraite::Calcul_giH_0()
  { Calcul_giH( giB_0, gijHH_0,giH_0);};
void Met_abstraite::Calcul_giH_t()
  { Calcul_giH( giB_t, gijHH_t,giH_t);};
void Met_abstraite::Calcul_giH_tdt()
  { Calcul_giH( giB_tdt, gijHH_tdt,giH_tdt);};
// calcul des Jacobiens-----------------------------------------  
void Met_abstraite::Jacobien_0()
  { 
     #ifdef MISE_AU_POINT
       if  (gijBB_0 == NULL) 
         { cout << "\nErreur : la  metrique n'est pas defini a t=0 !\n";
           cout << "Met_abstraite::Jacobien_0 \n";
           Sortie(1);
         };
     #endif
     //  jacobien_0 = sqrt (gijBB_0->Det()); toujours positif donc pb donc calcul en produit mixte
     jacobien_0 = Util::ProduitMixte(*giB_0);
   }; 
void Met_abstraite::Jacobien_t()
  {
     #ifdef MISE_AU_POINT
       if  (gijBB_t == NULL) 
         { cout << "\nErreur : la  metrique n'est pas defini a t !\n";
           cout << "Met_abstraite::Jacobien_t \n";
           Sortie(1);
         };
     #endif
//   jacobien_t = sqrt (gijBB_t->Det());  toujours positif donc pb donc calcul en produit mixte
     jacobien_t = Util::ProduitMixte(*giB_t);
   };  
void Met_abstraite::Jacobien_tdt()
  { 
     #ifdef MISE_AU_POINT
       if  (gijBB_tdt == NULL) 
         { cout << "\nErreur : la  metrique n'est pas defini a tdt !\n";
           cout << "Met_abstraite::Jacobien_tdt \n";
           Sortie(1);
         };
     #endif
//  jacobien_tdt = sqrt (gijBB_tdt->Det());  toujours positif donc pb donc calcul en produit mixte
    jacobien_tdt = Util::ProduitMixte(*giB_tdt);    
   };   
//==  calcul de la variation des bases
 void Met_abstraite::D_giB_t( const  Mat_pleine& dphi, int nbnoeu,const  Vecteur & )
  { int indice; 
    // derivees de gBi par rapport a XHbr      
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nbnoeu; r++)
         { indice = (r-1)*dim_base + b;
           BaseB & d_giB_t_indice=(*d_giB_t)(indice);
           for (int i =1;i<=nbvec_base;i++)
              { d_giB_t_indice.CoordoB(i).Zero();
                d_giB_t_indice.CoordoB(i)(b)=dphi(i,r);
               }
          }              
   };
 void Met_abstraite::D_giB_tdt(  const Mat_pleine& dphi, int nbnoeu,const  Vecteur &)
  { int indice;       
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nbnoeu; r++)
         { indice = (r-1)*dim_base + b;
           BaseB & d_giB_tdt_indice=(*d_giB_tdt)(indice);
           for (int i =1;i<=nbvec_base;i++)
              { d_giB_tdt_indice.CoordoB(i).Zero();
                d_giB_tdt_indice.CoordoB(i)(b)=dphi(i,r);
               }
          }              
   };

 void Met_abstraite::D_giH_t()
  { int nbddl = d_giH_t->Taille();
    for ( int indice = 1; indice <= nbddl; indice ++)
      for (int j =1;j<=nbvec_base;j++)
       { ((*d_giH_t)(indice).CoordoH(j)).Zero();
        for (int i =1;i<=nbvec_base;i++)
           (*d_giH_t)(indice).CoordoH(j) += (-((*d_giB_t)(indice)(i))
                                   * (*giH_t)(j)) * (*giH_t)(i);
        }                           
   };
 
 void Met_abstraite::D_giH_tdt()
  { int nbddl = d_giH_tdt->Taille();
    for (int indice = 1; indice <= nbddl; indice ++)
      for (int j =1;j<=nbvec_base;j++)
       { CoordonneeH & d_giH_tdt_indice_j = (*d_giH_tdt)(indice).CoordoH(j);
         BaseB & d_giB_tdt_indice = (*d_giB_tdt)(indice);
         CoordonneeH & giH_tdt_j = (*giH_tdt).CoordoH(j);
         d_giH_tdt_indice_j.Zero();//((*d_giH_tdt)(indice)(j)).Zero();
         for (int i =1;i<=nbvec_base;i++)
           d_giH_tdt_indice_j += (-(d_giB_tdt_indice(i)) 
                                     * giH_tdt_j) * (*giH_tdt)(i);
        }                           
   };
        
 //==  calcul de la variation des metriques
void Met_abstraite::D_gijBB_t()
  { int nbddl = d_gijBB_t.Taille();
    for ( int indice = 1; indice <= nbddl; indice ++)
     { TenseurBB & d_gijBB_t_indice = (*(d_gijBB_t(indice)));
       BaseB & d_giB_t_indice = (*d_giB_t)(indice);
       for (int j =1;j<=nbvec_base;j++)
        for (int i =1;i<=nbvec_base;i++)
          d_gijBB_t_indice.Coor(i,j) = (d_giB_t_indice(i).ScalBB((*giB_t)(j)))
                                  + (d_giB_t_indice(j).ScalBB((*giB_t)(i)));
       }                             
  };
void Met_abstraite::D_gijBB_tdt()
  { int nbddl = d_gijBB_tdt.Taille();
    for ( int indice = 1; indice <= nbddl; indice ++)
     { TenseurBB & d_gijBB_tdt_indice = (*(d_gijBB_tdt(indice)));
       BaseB & d_giB_tdt_indice = (*d_giB_tdt)(indice);
       for (int j =1;j<=nbvec_base;j++)
        for (int i =1;i<=nbvec_base;i++)
          d_gijBB_tdt_indice.Coor(i,j) = (d_giB_tdt_indice(i).ScalBB((*giB_tdt)(j)))
                                    + (d_giB_tdt_indice(j).ScalBB((*giB_tdt)(i)));
       }
  };
  
void Met_abstraite::D_gijHH_t()
  { int nbddl = d_gijHH_t.Taille();
    for ( int indice = 1; indice <=  nbddl; indice ++)
     { TenseurHH & d_gijHH_t_indice = (*(d_gijHH_t(indice)));
       BaseH & d_giH_t_indice = (*d_giH_t)(indice);
       for (int j =1;j<=nbvec_base;j++)
        for (int i =1;i<=nbvec_base;i++)
          d_gijHH_t_indice.Coor(i,j) = (d_giH_t_indice(i).ScalHH((*giH_t)(j)))
                                 + (d_giH_t_indice(j).ScalHH((*giH_t)(i)));
       }
  };

void Met_abstraite::D_gijHH_tdt()  
  { int nbddl = d_gijHH_tdt.Taille();
    for ( int indice = 1; indice <= nbddl; indice ++)
     { TenseurHH & d_gijHH_tdt_indice = (*(d_gijHH_tdt(indice)));
       BaseH & d_giH_tdt_indice = (*d_giH_tdt)(indice);
       for (int j =1;j<=nbvec_base;j++)
        for (int i =1;i<=nbvec_base;i++)
          d_gijHH_tdt_indice.Coor(i,j) = (d_giH_tdt_indice(i).ScalHH((*giH_tdt)(j)))
                                        + (d_giH_tdt_indice(j).ScalHH((*giH_tdt)(i)));
       }
  };

//==  calcul de la variation seconde des metriques
void Met_abstraite::D2_gijBB_tdt()
  // ici on ne considère que la variation première des vecteurs de base, c-a-d que
  // l'on considère que leurs variations secondes sont nulles
  // ce qui est vrai dans le cas d'une cinématique simple
  { int nbddl = d_giB_tdt->Taille();
    for ( int indice = 1; indice <= nbddl; indice ++)
      for ( int jndice = 1; jndice <= indice; jndice ++)
       {TenseurBB & d2_gijBB_tdt_indice_jndice = (*(d2_gijBB_tdt(indice,jndice)));
        TenseurBB & d2_gijBB_tdt_jndice_indice = (*(d2_gijBB_tdt(jndice,indice)));
        BaseB & d_giB_tdt_indice = (*d_giB_tdt)(indice);
        BaseB & d_giB_tdt_jndice = (*d_giB_tdt)(jndice);
        for (int j =1;j<=nbvec_base;j++)
          for (int i =1;i<=j;i++)
            { d2_gijBB_tdt_indice_jndice.Coor(i,j) = d_giB_tdt_indice(i).ScalBB(d_giB_tdt_jndice(j))
                                                +d_giB_tdt_indice(j).ScalBB(d_giB_tdt_jndice(i)) ;
               // on utilise les symétries i<->j et indice<->jndice  
               d2_gijBB_tdt_indice_jndice.Coor(j,i) = d2_gijBB_tdt_indice_jndice(i,j);
               d2_gijBB_tdt_jndice_indice.Coor(i,j) = d2_gijBB_tdt_indice_jndice(i,j);
               d2_gijBB_tdt_jndice_indice.Coor(j,i) = d2_gijBB_tdt_indice_jndice(i,j);
              }   
        }
  };

//==  calcul de la variation des jacobiens
// pas valable dans le cas à une dimension
void Met_abstraite::Djacobien_t()
   { int nbddl = d_giB_t->Taille();
     switch (nbvec_base)
       { case 1 :
           cout << "\n **** erreur le calcul de la variation du jacobien n'est pas définit "
                << " dans le cas d'une métrique à un vecteur "
                << "\n Met_abstraite::Djacobien_t()";
           Sortie(1);     
           break;
         case 2 : 
// pour 2 vecteurs le jacobien est calculé 
// soit comme la norme du produit vectoriel de deux vecteurs en dim 3
// soit comme le produit en croix des composantes des deux vecteurs en dim 2 
// il faut donc calculer la dérivée en conséquence 			  
			 { if (ParaGlob::Dimension() == 2)
				  { for ( int indice = 1; indice <= nbddl; indice ++)			  
						d_jacobien_t(indice) = 
							( Util::DeterminantB((*d_giB_t)(indice)(1),(*giB_t)(2))
							+ Util::DeterminantB((*giB_t)(1),(*d_giB_t)(indice)(2)) );
// je pense erreur car pas commutatif		+ Util::DeterminantB((*d_giB_t)(indice)(2),(*giB_t)(1)) );
					}
				 else // sinon cela veut dire que l'on est en dim 3
				  { Coordonnee3B g1vecg2(Util::ProdVec_coorB((*giB_t)(1),(*giB_t)(2)));
				    for ( int indice = 1; indice <= nbddl; indice ++)			  
						{ Coordonnee3B D_g1vecg2(Util::ProdVec_coorB((*d_giB_t)(indice)(1),(*giB_t)(2)) +
					                   Util::ProdVec_coorB((*giB_t)(1),(*d_giB_t)(indice)(2)));
						  d_jacobien_t(indice) = 0.5 * (D_g1vecg2.ScalBB(g1vecg2)+ g1vecg2.ScalBB(D_g1vecg2))
						                         / jacobien_t;
						 };
					}
			  }
           break;  
         case 3 : 
           for ( int indice = 1; indice <= nbddl; indice ++)
              d_jacobien_t(indice) = 
                 ( Util::DeterminantB((*d_giB_t)(indice)(1),(*giB_t)(2),(*giB_t)(3))
                 + Util::DeterminantB((*giB_t)(1),(*d_giB_t)(indice)(2),(*giB_t)(3))
                 + Util::DeterminantB((*giB_t)(1),(*giB_t)(2),(*d_giB_t)(indice)(3)) 
                 );
           break; 
         default : cout << "\n taille incorecte,Met_abstraite::Djacobien_t() \n";
                   Sortie(1);
       }                       
   };
void Met_abstraite::Djacobien_tdt()   
{ int nbddl = d_giB_tdt->Taille();
  switch (nbvec_base)
   {case 1 : 
     {cout << "\n **** erreur le calcul de la variation du jacobien n'est pas définit "
           << " dans le cas d'une métrique à un vecteur "
           << "\n Met_abstraite::Djacobien_tdt()";
      Sortie(1);     
      break;
     }
    case 2 : 
// pour 2 vecteurs le jacobien est calculé 
// soit comme la norme du produit vectoriel de deux vecteurs en dim 3
// soit comme le produit en croix des composantes des deux vecteurs en dim 2 
// il faut donc calculer la dérivée en conséquence 			  
			  { if (ParaGlob::Dimension() == 2)
				    { for ( int indice = 1; indice <= nbddl; indice ++)
						     d_jacobien_tdt(indice) = 
							        ( Util::DeterminantB((*d_giB_tdt)(indice)(1),(*giB_tdt)(2))
							       + Util::DeterminantB((*giB_tdt)(1),(*d_giB_tdt)(indice)(2)) );
					   }
				   else // sinon cela veut dire que l'on est en dim 3
				    { Coordonnee3B g1vecg2(Util::ProdVec_coorB((*giB_tdt)(1),(*giB_tdt)(2)));
				      for ( int indice = 1; indice <= nbddl; indice ++)			  
						     { Coordonnee3B D_g1vecg2(Util::ProdVec_coorB((*d_giB_tdt)(indice)(1),(*giB_tdt)(2)) 
					                          + Util::ProdVec_coorB((*giB_tdt)(1),(*d_giB_tdt)(indice)(2)));
						  					 
						       d_jacobien_tdt(indice) = 0.5 * (D_g1vecg2.ScalBB(g1vecg2)+ g1vecg2.ScalBB(D_g1vecg2))
						                              / jacobien_tdt;
						     };
        };
      break;  
     }
    case 3 :
     {
      for ( int indice = 1; indice <= nbddl; indice ++)
         d_jacobien_tdt(indice) = 
            ( Util::DeterminantB((*d_giB_tdt)(indice)(1),(*giB_tdt)(2),(*giB_tdt)(3))
            + Util::DeterminantB((*giB_tdt)(1),(*d_giB_tdt)(indice)(2),(*giB_tdt)(3))
            + Util::DeterminantB((*giB_tdt)(1),(*giB_tdt)(2),(*d_giB_tdt)(indice)(3)) 
            );
      break;
     }
    default : cout << "\n taille incorecte,Met_abstraite::Djacobien_t() \n";
              Sortie(1);
   };
};

   //== calcul de la variation du gradient instantannée
   // par rapport aux composantes de la vitesse (et non les X^ar)	
void Met_abstraite::DgradVBB_t(const  Mat_pleine& dphi)
  { int indice; 
    // derivees par rapport a VHbr      
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nomb_noeud; r++)
         { indice = (r-1)*dim_base + b;
           TenseurBB & d_gradVBB_t_indice = (*(d_gradVBB_t(indice)));
           for (int j =1;j<=nbvec_base;j++)
             for (int i =1;i<=nbvec_base;i++)
               // grad(i,j) = Vi|j = gj_point * gi
               d_gradVBB_t_indice.Coor(i,j) = dphi(j,r) * (*giB_t)(i)(b);
          }              
   }; 

   //== calcul de la variation du gradient	
void Met_abstraite::DgradVBB_tdt(const  Mat_pleine& dphi)
   // par rapport aux composantes de la vitesse (et non les X^ar)	
  { int indice; 
    // derivees par rapport a VHbr      
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nomb_noeud; r++)
         { indice = (r-1)*dim_base + b;
           TenseurBB & d_gradVBB_tdt_indice = (*(d_gradVBB_tdt(indice)));
           for (int j =1;j<=nbvec_base;j++)
             for (int i =1;i<=nbvec_base;i++)
               // grad(i,j) = Vi|j = gj_point * gi
               d_gradVBB_tdt_indice.Coor(i,j) = dphi(j,r) * (*giB_tdt)(i)(b);
          }              
   }; 
    
// calcul de la variation du gradient moyen à t
// par rapport ici aux composantes X^ar (et non les V^ar )	
void Met_abstraite::DgradVmoyBB_t(const  Mat_pleine& dphi,const  Tableau<Noeud *>& tab_noeud)
  { // récup de delta t
    const VariablesTemps& vartemps = ParaGlob::Variables_de_temps();
    // dans le cas où l'incrément de temps est nul la vitesse est nulle
    double deltat=vartemps.IncreTempsCourant();double unsurdeltat;
    double temps =vartemps.TempsCourant(); 
    // on regarde le premier noeud pour savoir s'il y a des coordonnées à t+dt
    if (tab_noeud(1)->ExisteCoord2())
     {// dans ce cas on utilise l'incrément de temps
      if (deltat >= ConstMath::trespetit)
          {unsurdeltat = 1./deltat;}
      else
          {unsurdeltat = 0.;} // o car on veut une vitesse nulle 
       }
    else // sinon on utilise la variation totale de 0 à t, le delta t vaudra le temps actuel      
     { if (temps >= ConstMath::trespetit)
         {unsurdeltat = 1./temps;}
       else
         {unsurdeltat = 0.;} // o car on veut une vitesse nulle
       }       
    int indice; 
    // derivees par rapport a XHbr      
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nomb_noeud; r++)
         { indice = (r-1)*dim_base + b;
           TenseurBB & d_gradVmoyBB_t_indice = (*(d_gradVmoyBB_t(indice)));
           BaseB & d_giB_t_indice=(*d_giB_t)(indice);
           for (int j =1;j<=nbvec_base;j++)
             for (int i =1;i<=nbvec_base;i++)
               // grad(i,j) = Vi|j = gj_point * gi
               d_gradVmoyBB_t_indice.Coor(i,j) = dphi(j,r) *( unsurdeltat * (*giB_t)(i)(b)
                                            + (*dmatV_moy_t)(j).ScalBB(d_giB_t_indice(i)) );
          }              
   }; 
// calcul de la variation du gradient à t dt
// par rapport ici aux composantes X^ar (et non les V^ar )	
void Met_abstraite::DgradVmoyBB_tdt(const  Mat_pleine& dphi)
  { // récup de delta t
    const VariablesTemps& vartemps = ParaGlob::Variables_de_temps();
    // dans le cas où l'incrément de temps est nul la vitesse est nulle
    double deltat=vartemps.IncreTempsCourant();
    double unsurdeltat;
    if (deltat >= ConstMath::trespetit)
       {unsurdeltat = 1./deltat;}
    else
       {unsurdeltat = 0.;} // o car on veut une vitesse nulle 
    
    int indice; 
    // derivees par rapport a XHbr      
    for (int b = 1; b<= dim_base; b++)
      for (int r = 1; r <= nomb_noeud; r++)
         { indice = (r-1)*dim_base + b;
           TenseurBB & d_gradVmoyBB_tdt_indice = (*(d_gradVmoyBB_tdt(indice)));
           BaseB & d_giB_tdt_indice=(*d_giB_tdt)(indice);
           for (int j =1;j<=nbvec_base;j++)
             for (int i =1;i<=nbvec_base;i++)
               // grad(i,j) = Vi|j = gj_point * gi
               d_gradVmoyBB_tdt_indice.Coor(i,j) = dphi(j,r) *( unsurdeltat * (*giB_tdt)(i)(b)
                                            + (*dmatV_moy_tdt)(j).ScalBB(d_giB_tdt_indice(i)) );
          }              
   }; 

// ---------------- calcul de données interpolées aux même points d'integ que  la mécanique -------- 
//       et utilisées par la mécanique (ex: température, taux de cristalinité, vecteur,  etc..)    
double Met_abstraite::DonneeInterpoleeScalaire
           (const  Tableau<Noeud *>& tab_noeud,const Vecteur& phi,int nombre_noeud
           ,Enum_ddl enu,Enum_dure temps) const
   { double resultat=0.;
     #ifdef MISE_AU_POINT
     if (!(tab_noeud(1)->Existe_ici(enu)))
      {cout << "\n\n *** erreur, la grandeur " << Nom_ddl(enu)
            << " n'existe pas aux noeuds  on ne peut pas l'interpoler ";
       Sortie(1);
      };
            
     #endif
     switch (temps)
      { case TEMPS_0:
         { for (int r=1;r<=nombre_noeud;r++)
             resultat += tab_noeud(r)->Valeur_0(enu) * phi(r);
           break;
          }
        case TEMPS_t:
         { for (int r=1;r<=nombre_noeud;r++)
             resultat += tab_noeud(r)->Valeur_t(enu) * phi(r);
           break;
          }
        case TEMPS_tdt:
         { for (int r=1;r<=nombre_noeud;r++)
             resultat += tab_noeud(r)->Valeur_tdt(enu) * phi(r);
           break;
          }
        };
     return resultat;
    };

// --------- calcul de la variation d'une donnée interpolée par rapport aux ddl de la donnée ------
//       aux même points d'integ que  la mécanique --------
//       et utilisées par la mécanique (ex: température, taux de cristalinité, vitesse, etc..)
// en sortie : d_A
Tableau <double >&  Met_abstraite::DerDonneeInterpoleeScalaire
             (Tableau <double >& d_A, const  Tableau<Noeud *>& ,const Vecteur& phi
             ,int nombre_noeud,Enum_ddl enu) const
  { d_A.Change_taille(nombre_noeud);
    for (int r=1;r<=nombre_noeud;r++)
      d_A(r) = phi(r);
    return d_A;
  };

// ---------------- calcul du gradient d'une donnée interpolée aux même points d'integ que  la mécanique --------
//       et utilisées par la mécanique (ex: température, taux de cristalinité, vitesse, etc..)
// en sortie : gradB
CoordonneeB& Met_abstraite::GradDonneeInterpoleeScalaire
                  (CoordonneeB& gradA_B,const  Tableau<Noeud *>& tab_noeud,const  Mat_pleine& dphi
                  ,int nombre_noeud,Enum_ddl enu,Enum_dure temps) const
 {  
  //gradA_B_i = A^{r} \phi_{r,i}
  gradA_B.Zero();
  switch (temps)
    { case TEMPS_0:
        { for (int i=1;i<= nbvec_base;i++)
            { double & gradA_B_i = gradA_B(i);
              gradA_B_i = 0.;
	             for (int r=1;r<=nombre_noeud;r++)
			             gradA_B_i += tab_noeud(r)->Valeur_0(enu) * dphi(i,r);
            };
           break;
        }
       case TEMPS_t:
        { for (int i=1;i<= nbvec_base;i++)
            { double & gradA_B_i = gradA_B(i);
              gradA_B_i = 0.;
	             for (int r=1;r<=nombre_noeud;r++)
			             gradA_B_i += tab_noeud(r)->Valeur_t(enu) * dphi(i,r);
            };
           break;
        }
       case TEMPS_tdt:
        { for (int i=1;i<= nbvec_base;i++)
            { double & gradA_B_i = gradA_B(i);
              gradA_B_i = 0.;
	             for (int r=1;r<=nombre_noeud;r++)
			             gradA_B_i += tab_noeud(r)->Valeur_tdt(enu) * dphi(i,r);
            };
           break;
        }
    };
  // retour du gradient
  return gradA_B;
 };

// --------- calcul de la variation du gradient d'une donnée interpolée par rapport aux ddl de la donnée ------
//       aux même points d'integ que  la mécanique --------
//       et utilisées par la mécanique (ex: température, taux de cristalinité, vitesse, etc..)
// en sortie : d_gradB
Tableau <CoordonneeB >& Met_abstraite::DerGradDonneeInterpoleeScalaire
             (Tableau <CoordonneeB >& d_gradB,const  Tableau<Noeud *>&
              ,const Vecteur& ,const  Mat_pleine& dphi,int nombre_noeud,Enum_ddl ) const
 {// ici dans la version de base, il s'agit uniquement d'un transfert de dphi dans d_gradB
  // par contre pour une interpolation plus sophistiquée, ça pourrait -être très différent
  // d'où l'intérêt d'avoir une différenciation entre la variation et dphi
  //gradA_B_i = A^{r} \phi_{r,i}
  d_gradB.Change_taille(nombre_noeud);
  for (int i=1;i<= nbvec_base;i++)
    { for (int r=1;r<=nombre_noeud;r++)
		      d_gradB(r)(i) = dphi(i,r);
    };
  // retour du gradient
  return d_gradB;
 };

// --------- calcul de la variation seconde du gradient d'une donnée interpolée par rapport aux ddl de la donnée ------
//       aux même points d'integ que  la mécanique --------
//       et utilisées par la mécanique (ex: température, taux de cristalinité, vitesse, etc..)
// en sortie : d2_gradB
//  si d2_gradB est NULL cela signifie qu'il ne faut pas considérer cette grandeur
Tableau2 <CoordonneeB>*  Met_abstraite::Der2GradDonneeInterpoleeScalaire
               (Tableau2 <CoordonneeB>* d2_gradB,const  Tableau<Noeud *>& tab_noeud
              ,const Vecteur& phi,const  Mat_pleine& dphi,int nombre_noeud,Enum_ddl enu) const
 { // par défaut avec une interpolation simple la dérivée seconde est nulle
   return NULL;
 };


		// calcul de la vitesse du point a t0 en fonction des ddl existants de vitesse
void Met_abstraite::Calcul_V0
		   ( const Tableau<Noeud *>& tab_noeud,const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (V0 == NULL)
			{ cout << "\nErreur : la vitesse au  point a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V0 \n";
			  Sortie(1);
			};
    #endif
	int amax = V0->Dimension();
	V0->Zero();
    for (int r=1;r<=nombre_noeud;r++)
     {switch (amax)
        {case 3: (*(V0))(3) += tab_noeud(r)->Valeur_0(V3) * phi(r) ;
         case 2: (*(V0))(2) += tab_noeud(r)->Valeur_0(V2) * phi(r) ;
         case 1: (*(V0))(1) += tab_noeud(r)->Valeur_0(V1) * phi(r) ; 
	    }; 
	  };       
  };  
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_V0 (const Noeud* noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (V0 == NULL)
			{ cout << "\nErreur : la vitesse au  point a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V0(const Noeud* \n";
			  Sortie(1);
			};
    #endif
	int amax = V0->Dimension();  V0->Zero();
    switch (amax)
        {case 3: (*(V0))(3) += noeud->Valeur_0(V3) ;
         case 2: (*(V0))(2) += noeud->Valeur_0(V2) ;
         case 1: (*(V0))(1) += noeud->Valeur_0(V1) ; 
	    };
  };  
		   
		// calcul de la vitesse du point a t en fonction des ddl existants de vitesse
void Met_abstraite::Calcul_Vt
		   (const  Tableau<Noeud *>& tab_noeud, const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_Vt \n";
			  Sortie(1);
			};
    #endif
	int amax = Vt->Dimension();   Vt->Zero();
    for (int r=1;r<=nombre_noeud;r++)
     {switch (amax)
        {case 3: (*(Vt))(3) += tab_noeud(r)->Valeur_t(V3) * phi(r) ;
         case 2: (*(Vt))(2) += tab_noeud(r)->Valeur_t(V2) * phi(r) ;
         case 1: (*(Vt))(1) += tab_noeud(r)->Valeur_t(V1) * phi(r) ; 
	    }; 
	  };       
  };  
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_Vt (const Noeud* noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_Vt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
	int amax = Vt->Dimension();  Vt->Zero();
    switch (amax)
        {case 3: (*(Vt))(3) += noeud->Valeur_t(V3) ;
         case 2: (*(Vt))(2) += noeud->Valeur_t(V2) ;
         case 1: (*(Vt))(1) += noeud->Valeur_t(V1) ; 
	    };
  };  
		// calcul des variations de la vitesse du point a t en fonction des ddl existants de vitesse
void Met_abstraite::Calcul_d_Vt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vt == NULL)
			{ cout << "\nErreur : la variation de vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Vt \n";
			  Sortie(1);
			};
    #endif
	int indice;
    for (int b = 1; b<= dim_base; b++)
      {for (int r = 1; r <= nombre_noeud; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Vt_indice=(*d_Vt)(indice);
           d_Vt_indice.Zero();
           d_Vt_indice(b)=phi(r);
          };
       };                 
  }; 
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_d_Vt (const Noeud* )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vt == NULL)
			{ cout << "\nErreur : la variation de vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Vt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
    for (int b = 1; b<= dim_base; b++)
      { Coordonnee & d_Vt_indice=(*d_Vt)(b);
           d_Vt_indice.Zero();
           d_Vt_indice(b)=1;
        };
  }; 

		// calcul de la vitesse du point a tdt en fonction des ddl existants de vitesse
void Met_abstraite::Calcul_Vtdt
		   (const Tableau<Noeud *>& tab_noeud,const  Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vtdt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t+dt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_Vtdt \n";
			  Sortie(1);
			};
    #endif
	int amax = Vtdt->Dimension();   Vtdt->Zero();
    for (int r=1;r<=nombre_noeud;r++)
     {switch (amax)
        {case 3: (*(Vtdt))(3) += tab_noeud(r)->Valeur_tdt(V3) * phi(r) ;
         case 2: (*(Vtdt))(2) += tab_noeud(r)->Valeur_tdt(V2) * phi(r) ;
         case 1: (*(Vtdt))(1) += tab_noeud(r)->Valeur_tdt(V1) * phi(r) ; 
	    }; 
	  };       
  };  
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_Vtdt (const Noeud* noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vtdt == NULL)
			{ cout << "\nErreur : la vitesse au  point a tdt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_Vtdt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
	int amax = Vtdt->Dimension();  Vtdt->Zero();
    switch (amax)
        {case 3: (*(Vtdt))(3) += noeud->Valeur_tdt(V3) ;
         case 2: (*(Vtdt))(2) += noeud->Valeur_tdt(V2) ;
         case 1: (*(Vtdt))(1) += noeud->Valeur_tdt(V1) ; 
	    };
  };  
		// calcul des variations de la vitesse du point a tdt en fonction des ddl existants de vitesse
void Met_abstraite::Calcul_d_Vtdt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vtdt == NULL)
			{ cout << "\nErreur : la variation de vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Vtdt \n";
			  Sortie(1);
			};
    #endif
	int indice;
    for (int b = 1; b<= dim_base; b++)
      {for (int r = 1; r <= nombre_noeud; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Vtdt_indice=(*d_Vtdt)(indice);
           d_Vtdt_indice.Zero();
           d_Vtdt_indice(b)=phi(r);
          };
       };                 
  }; 
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_d_Vtdt (const Noeud* )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vtdt == NULL)
			{ cout << "\nErreur : la variation de vitesse au  point a tdt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_Vtdt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
    for (int b = 1; b<= dim_base; b++)
      { Coordonnee & d_Vtdt_indice=(*d_Vtdt)(b);
           d_Vtdt_indice.Zero();
           d_Vtdt_indice(b)=1;
        };
  }; 
	    	    	         
		// calcul de la vitesse moyenne du point a t0 en fonction des ddl de position
void Met_abstraite::Calcul_V_moy0
		   ( const Tableau<Noeud *>& ,const Vecteur& , int )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (V0 == NULL)
			{ cout << "\nErreur : la vitesse au  point a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moy0 \n";
			  Sortie(1);
			};
    #endif
  // a priori lorsque l'on calcul la vitesse moyenne initiale, on n'a pas d'élément pour la déterminer
  // on la fige donc à 0
  V0->Zero();
  };  
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_V_moy0 (const Noeud* )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (V0 == NULL)
			{ cout << "\nErreur : la vitesse au  point a t=0 n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moy0(const Noeud* \n";
			  Sortie(1);
			};
    #endif
  // a priori lorsque l'on calcul la vitesse moyenne initiale, on n'a pas d'élément pour la déterminer
  // on la fige donc à 0
  V0->Zero();
  };  
		   
		// calcul de la vitesse moyenne du point a t en fonction des ddl de position 
void Met_abstraite::Calcul_V_moyt
		   (const  Tableau<Noeud *>& tab_noeud, const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moyt \n";
			  Sortie(1);
			};
    #endif
  // la vitesse est calculée selon  (M(t)-M(0)) / t
  // dans le cas où le temps est nul on pose que la vitesse est nulle et non infinie !
  double temps = ParaGlob::Variables_de_temps().TempsCourant(); double unsurt;
  if (temps >= ConstMath::trespetit)  {unsurt = 1./temps;}
  else                                {unsurt = 0.;} // o car on veut une vitesse nulle
  Vt->Zero();
  for (int r=1;r<=nombre_noeud;r++)
    { (*Vt) += (tab_noeud(r)->Coord1() - tab_noeud(r)->Coord0()) * (unsurt * phi(r));} ;		   
 };	

// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_V_moyt (const Noeud* noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moyt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
  // la vitesse est calculée selon  (M(t)-M(0)) / t
  // dans le cas où le temps est nul on pose que la vitesse est nulle et non infinie !
  double temps = ParaGlob::Variables_de_temps().TempsCourant(); double unsurt;
  if (temps >= ConstMath::trespetit)  {unsurt = 1./temps;}
  else                                {unsurt = 0.;} // o car on veut une vitesse nulle
  Vt->Zero();
  (*Vt) += (noeud->Coord1() - noeud->Coord0()) * unsurt;		   
 };	

// calcul des variations de la vitesse moyenne du point a t en fonction des ddl de position 
void Met_abstraite::Calcul_d_V_moyt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vt == NULL)
			{ cout << "\nErreur : la variation de vitesse moyenne au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_V_moyt \n";
			  Sortie(1);
			};
    #endif
    // la vitesse est calculée selon  (M(t)-M(0)) / t, ici on se réfère par rapport au ddl de M(t)
    // dans le cas où le temps est nul on pose que la vitesse est nulle et non infinie !
    double temps = ParaGlob::Variables_de_temps().TempsCourant(); double unsurt;
    if (temps >= ConstMath::trespetit)  {unsurt = 1./temps;}
    else                                {unsurt = 0.;} // o car on veut une vitesse nulle
	int indice;
    for (int b = 1; b<= dim_base; b++)
      {for (int r = 1; r <= nombre_noeud; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Vt_indice=(*d_Vt)(indice);
           d_Vt_indice.Zero();
           d_Vt_indice(b)=unsurt * phi(r);
          };
       };                 
  }; 
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_d_V_moyt(const Noeud* )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vt == NULL)
			{ cout << "\nErreur : la variation de vitesse moyenne au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_V_moyt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
    // la vitesse est calculée selon  (M(t)-M(0)) / t, ici on se réfère par rapport au ddl de M(t)
    // dans le cas où le temps est nul on pose que la vitesse est nulle et non infinie !
    double temps = ParaGlob::Variables_de_temps().TempsCourant(); double unsurt;
    if (temps >= ConstMath::trespetit)  {unsurt = 1./temps;}
    else                                {unsurt = 0.;} // o car on veut une vitesse nulle
    for (int b = 1; b<= dim_base; b++)
      {Coordonnee & d_Vt_indice=(*d_Vt)(b);
       d_Vt_indice.Zero();
       d_Vt_indice(b)=unsurt;
       };                 
  }; 
		   
		// calcul de la vitesse moyenne du point a tdt en fonction des ddl de position 
void Met_abstraite::Calcul_V_moytdt
		   (const Tableau<Noeud *>& tab_noeud,const  Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vtdt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t+dt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moytdt \n";
			  Sortie(1);
			};
    #endif
  // la vitesse est calculée selon  (M(tdt)-M(t)) / deltat
  // dans le cas où l'incrément de temps est nul on pose que la vitesse est nulle et non infinie !
  double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();double unsurdeltat;
  if (deltat >= ConstMath::trespetit)  {unsurdeltat = 1./deltat;}
  else                                {unsurdeltat = 0.;} // o car on veut une vitesse nulle
  Vtdt->Zero();
  for (int r=1;r<=nombre_noeud;r++)
    { (*Vtdt) += (tab_noeud(r)->Coord2() - tab_noeud(r)->Coord1()) * (unsurdeltat * phi(r));} ;		   
 };

// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_V_moytdt(const Noeud* noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (Vtdt == NULL)
			{ cout << "\nErreur : la vitesse au  point a t+dt n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_V_moytdt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
  // la vitesse est calculée selon  (M(tdt)-M(t)) / deltat
  // dans le cas où l'incrément de temps est nul on pose que la vitesse est nulle et non infinie !
  double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();double unsurdeltat;
  if (deltat >= ConstMath::trespetit)  {unsurdeltat = 1./deltat;}
  else                                {unsurdeltat = 0.;} // o car on veut une vitesse nulle
  Vtdt->Zero();
  (*Vtdt) += (noeud->Coord2() - noeud->Coord1()) * unsurdeltat ;		   
 };
 
 // calcul des variations de la vitesse moyenne du point a tdt en fonction des ddl de position
void Met_abstraite::Calcul_d_V_moytdt
		   (const  Tableau<Noeud *>& , const Vecteur& phi, int nombre_noeud)
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vtdt == NULL)
			{ cout << "\nErreur : la variation de vitesse moyenne au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_V_moytdt \n";
			  Sortie(1);
			};
    #endif
    // la vitesse est calculée selon  (M(tdt)-M(t)) / deltat, les ddl sont ceux de M(tdt)
    // dans le cas où l'incrément de temps est nul on pose que la vitesse est nulle et non infinie !
    double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();double unsurdeltat;
    if (deltat >= ConstMath::trespetit)  {unsurdeltat = 1./deltat;}
    else                                 {unsurdeltat = 0.;} // o car on veut une vitesse nulle
	int indice;
    for (int b = 1; b<= dim_base; b++)
      {for (int r = 1; r <= nombre_noeud; r++)
         { indice = (r-1)*dim_base + b;
           Coordonnee & d_Vtdt_indice=(*d_Vtdt)(indice);
           d_Vtdt_indice.Zero();
           d_Vtdt_indice(b)=phi(r) * unsurdeltat;
          };
       };                 
  }; 
		// idem mais au noeud passé en paramètre  
void Met_abstraite::Calcul_d_V_moytdt(const Noeud* )
{  
   #ifdef MISE_AU_POINT	 	 
	  if  (d_Vtdt == NULL)
			{ cout << "\nErreur : la variation de vitesse moyenne au  point a t n'est pas dimensionne !\n";
			  cout << "void Met_abstraite::Calcul_d_V_moytdt(const Noeud* \n";
			  Sortie(1);
			};
    #endif
    // la vitesse est calculée selon  (M(tdt)-M(t)) / deltat, les ddl sont ceux de M(tdt)
    // dans le cas où l'incrément de temps est nul on pose que la vitesse est nulle et non infinie !
    double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();double unsurdeltat;
    if (deltat >= ConstMath::trespetit)  {unsurdeltat = 1./deltat;}
    else                                 {unsurdeltat = 0.;} // o car on veut une vitesse nulle
    for (int b = 1; b<= dim_base; b++)
      { Coordonnee & d_Vtdt_indice=(*d_Vtdt)(b);
        d_Vtdt_indice.Zero();
        d_Vtdt_indice(b)= unsurdeltat;
       };                 
  }; 
		    

//--- cas des accélérations
// calcul de l'accélération du point a t0 en fonction des ddl existants d'accélération

void Met_abstraite::Calcul_gamma0
   ( const Tableau<Noeud *>& tab_noeud,const Vecteur& phi, int nombre_noeud)
{
  #ifdef MISE_AU_POINT
  if  (gamma0 == NULL)
  { cout << "\nErreur : l'acceleration au  point a t=0 n'est pas dimensionne !\n";
    cout << "void Met_abstraite::Calcul_gamma0 \n";
    Sortie(1);
  };
  if (!(tab_noeud(1)->Existe_ici(GAMMA1)))
    {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
          << "\n Met_abstraite::Calcul_gamma0(..)";
     Sortie(1);
    };
  #endif
  int amax = gamma0->Dimension();
  gamma0->Zero();
  for (int r=1;r<=nombre_noeud;r++)
    {switch (amax)
       {case 3: (*(gamma0))(3) += tab_noeud(r)->Valeur_0(GAMMA3) * phi(r) ;
        case 2: (*(gamma0))(2) += tab_noeud(r)->Valeur_0(GAMMA2) * phi(r) ;
        case 1: (*(gamma0))(1) += tab_noeud(r)->Valeur_0(GAMMA1) * phi(r) ;
       };
    };
};
// idem mais au noeud passé en paramètre
void Met_abstraite::Calcul_gamma0 (const Noeud* noeud)
{
  #ifdef MISE_AU_POINT
  if  (gamma0 == NULL)
  { cout << "\nErreur : l'acceleration au  point a t=0 n'est pas dimensionne !\n";
    cout << "void Met_abstraite::Calcul_gamma0(const Noeud* )\n";
    Sortie(1);
  };
  if (!(noeud->Existe_ici(GAMMA1)))
     {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
           << "\n Met_abstraite::Calcul_gamma0(..)";
      Sortie(1);
     };
  #endif
  int amax = gamma0->Dimension();  gamma0->Zero();
  switch (amax)
       {case 3: (*(gamma0))(3) += noeud->Valeur_0(GAMMA3) ;
        case 2: (*(gamma0))(2) += noeud->Valeur_0(GAMMA2) ;
        case 1: (*(gamma0))(1) += noeud->Valeur_0(GAMMA1) ;
    };
 };

// idem a t
void Met_abstraite::Calcul_gammat
   ( const Tableau<Noeud *>& tab_noeud,const Vecteur& phi, int nombre_noeud)
   {
    #ifdef MISE_AU_POINT
    if  (gammat == NULL)
    { cout << "\nErreur : l'acceleration au  point a t n'est pas dimensionne !\n";
      cout << "void Met_abstraite::Calcul_gammat \n";
      Sortie(1);
    };
    if (!(tab_noeud(1)->Existe_ici(GAMMA1)))
      {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
            << "\n Met_abstraite::Calcul_gammat(..)";
       Sortie(1);
      };
    #endif
    int amax = gammat->Dimension();
    gammat->Zero();
    for (int r=1;r<=nombre_noeud;r++)
      {switch (amax)
         {case 3: (*(gammat))(3) += tab_noeud(r)->Valeur_t(GAMMA3) * phi(r) ;
          case 2: (*(gammat))(2) += tab_noeud(r)->Valeur_t(GAMMA2) * phi(r) ;
          case 1: (*(gammat))(1) += tab_noeud(r)->Valeur_t(GAMMA1) * phi(r) ;
         };
      };
   };
// idem mais au noeud passé en paramètre
void Met_abstraite::Calcul_gammat (const Noeud* noeud)
{
  #ifdef MISE_AU_POINT
  if  (gammat == NULL)
  { cout << "\nErreur : l'acceleration au  point a t n'est pas dimensionne !\n";
    cout << "void Met_abstraite::Calcul_gammat(const Noeud* )\n";
    Sortie(1);
  };
  if (!(noeud->Existe_ici(GAMMA1)))
      {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
            << "\n Met_abstraite::Calcul_gamma0(..)";
       Sortie(1);
      };
  #endif
  int amax = gammat->Dimension();  gammat->Zero();
  switch (amax)
       {case 3: (*(gammat))(3) += noeud->Valeur_t(GAMMA3) ;
        case 2: (*(gammat))(2) += noeud->Valeur_t(GAMMA2) ;
        case 1: (*(gammat))(1) += noeud->Valeur_t(GAMMA1) ;
    };
 };
// idem à tdt
void Met_abstraite::Calcul_gammatdt
     ( const Tableau<Noeud *>& tab_noeud,const Vecteur& phi, int nombre_noeud)
     {
      #ifdef MISE_AU_POINT
      if  (gammatdt == NULL)
      { cout << "\nErreur : l'acceleration au  point a tdt n'est pas dimensionne !\n";
        cout << "void Met_abstraite::Calcul_gammatdt \n";
        Sortie(1);
      };
      if (!(tab_noeud(1)->Existe_ici(GAMMA1)))
        {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
              << "\n Met_abstraite::Calcul_gammatdt(..)";
         Sortie(1);
        };
      #endif
      int amax = gammatdt->Dimension();
      gammatdt->Zero();
      for (int r=1;r<=nombre_noeud;r++)
        {switch (amax)
           {case 3: (*(gammatdt))(3) += tab_noeud(r)->Valeur_tdt(GAMMA3) * phi(r) ;
            case 2: (*(gammatdt))(2) += tab_noeud(r)->Valeur_tdt(GAMMA2) * phi(r) ;
            case 1: (*(gammatdt))(1) += tab_noeud(r)->Valeur_tdt(GAMMA1) * phi(r) ;
        };
      };
     };
// idem mais au noeud passé en paramètre
void Met_abstraite::Calcul_gammatdt (const Noeud* noeud)
{
  #ifdef MISE_AU_POINT
  if  (gammatdt == NULL)
  { cout << "\nErreur : l'acceleration au  point a tdt n'est pas dimensionne !\n";
    cout << "void Met_abstraite::Calcul_gammatdt(const Noeud* )\n";
    Sortie(1);
  };
  if (!(noeud->Existe_ici(GAMMA1)))
     {cout << "\n *** erreur l'acceleration nest pas definie aux noeuds !! "
           << "\n Met_abstraite::Calcul_gamma0(..)";
      Sortie(1);
     };
  #endif
  int amax = gammatdt->Dimension();  gammatdt->Zero();
  switch (amax)
       {case 3: (*(gammatdt))(3) += noeud->Valeur_tdt(GAMMA3) ;
        case 2: (*(gammatdt))(2) += noeud->Valeur_tdt(GAMMA2) ;
        case 1: (*(gammatdt))(1) += noeud->Valeur_tdt(GAMMA1) ;
    };
 };


