

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

/************************************************************************
 *     DATE:        19/6/2005                                           *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:   La classe Hyper_W_gene_3D permet de calculer              *
 *            les grandeurs générales nécessaires pour exploiter une    *
 *            loi hyper-élastique utilisant un potentiel W défini       *
 *            a partir des élongations.                                 *
 *     Il s'agit d'une classe de travail.                               *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef HYPER_W_GENE_3D_H
#define HYPER_W_GENE_3D_H


#include "LesReferences.h"
#include "LesCourbes1D.h"
#include "Tenseur.h"
#include "Tenseur3.h"
#include "TenseurQ-3.h"
#include "TenseurQ3gene.h" 
#include "Loi_comp_abstraite.h"


/// @addtogroup Les_lois_hyperelastiques
///  @{
///

class Hyper_W_gene_3D : public Loi_comp_abstraite
{


	public :
	
	
		// CONSTRUCTEURS :
		
		// Constructeur par defaut
		Hyper_W_gene_3D ();
 
		// Constructeur utile si l'identificateur du nom de la loi
		// de comportement et la dimension sont connus
		// vit_def indique si oui ou non la loi utilise la vitesse de déformation
		Hyper_W_gene_3D (Enum_comp id_compor,Enum_categorie_loi_comp categorie_comp
		                    ,int dimension,bool vit_def = false);
 
		// Constructeur de copie
		Hyper_W_gene_3D (const Hyper_W_gene_3D& loi) ;
		
		// DESTRUCTEUR :
		
		virtual ~Hyper_W_gene_3D ();
	  
		

  // classe permettant le stockage de grandeurs de post-traitement
  class Invariantpost3D
   { public :
     Invariantpost3D() : potentiel(0.) {}; // constructeur par défaut
     Invariantpost3D(const double& potent)
        : potentiel(potent) {};
     Invariantpost3D(const Invariantpost3D & a)
        : potentiel(a.potentiel) {};
     // Surcharge de l'operateur = : realise l'affectation
     Invariantpost3D& operator= (const Invariantpost3D& a)
        {potentiel=a.potentiel; return *this;};
     // surcharge de l'operator de lecture
     friend  istream & operator >> (istream & ent, Invariantpost3D  & a)
      { string toto;
        ent >> toto >>  a.potentiel; return ent;
      };
     // surcharge de l'operator d'ecriture
     friend  ostream & operator << (ostream & sort , const Invariantpost3D & a)
      { sort << " potent= "<< a.potentiel << " "; return sort;
      };
     // data
     double potentiel;
   };

  class SaveResulHyper_W_gene_3D: public Loi_comp_abstraite::SaveResul//HyperD
   { public : 
        // constructeur 
        SaveResulHyper_W_gene_3D(); // par défaut
        SaveResulHyper_W_gene_3D(int sortie_post); // avec init ou pas
        SaveResulHyper_W_gene_3D(const SaveResulHyper_W_gene_3D& sav); // de copie
        virtual ~SaveResulHyper_W_gene_3D(); // destructeur
    
        // définition d'une nouvelle instance identique
        // appelle du constructeur via new 
        SaveResul * Nevez_SaveResul() const {return (new SaveResulHyper_W_gene_3D(*this));};
        // affectation
        virtual SaveResul & operator = ( const SaveResul & a);
        //============= lecture écriture dans base info ==========
        // 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)
        virtual void Lecture_base_info (ifstream& ,const int ) ;
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        virtual void Ecriture_base_info(ofstream& ,const int ) ;
           
        // mise à jour des informations transitoires 
        void TdtversT() { if (invP != NULL) { (*invP_t) = (*invP);};};
        void TversTdt() { if (invP != NULL) { (*invP) = (*invP_t);};};
    
        // affichage à l'écran des infos
        void Affiche() const  ;
    
        //changement de base de toutes les grandeurs internes tensorielles stockées
        // beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB
        // gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
        // ici il ne s'agit que de grandeurs scalaires donc rien n'a faire
        // gpH(i) = gamma(i,j) * gH(j)
        virtual void ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma){};
    
        // procedure permettant de completer éventuellement les données particulières
        // de la loi stockées
        // au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie
        // completer est appelé apres sa creation avec les donnees du bloc transmis
        // peut etre appeler plusieurs fois
        SaveResul* Complete_SaveResul(const BlocGen & bloc, const Tableau <Coordonnee>& tab_coor
                                       ,const Loi_comp_abstraite* loi){};


        // des grandeurs qui sont éventuellement crééent si on le demande
        Hyper_W_gene_3D::Invariantpost3D * invP, * invP_t;
   };

  SaveResul * New_et_Initialise() { return (new SaveResulHyper_W_gene_3D(this->sortie_post));};
 
  // 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
  virtual void Grandeur_particuliere
        (bool absolue,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const;
  // 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
  virtual void ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const;
        
 
		
		// calcul des invariants et de leurs variations premières
		void Invariants_et_var1(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien)
     {InvariantsEtVar1(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
            // vérification numérique de la dérivée	 
     //          Calcul_derivee_numerique(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
     };
		// calcul des invariants et de leurs variations premières et secondes
		void Invariants_et_var2(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien)
     {InvariantsEtVar2(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
     //          Calcul_derivee_numerique2(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
     };
 
		// --- acces en lectures  aux différentes grandeurs calculées 
		// par Invariants_et_var1 et Invariants_et_var2
		const double& I__B() const {return I_B;};
		const double& I__BB() const {return I_BB;};
//		const double& I__BBB() const {return I_BBB;};
		const double& II__B() const {return II_B;};
		const Vecteur& JJ_r() const {return J_r;}; 
	//	const Tenseur3HH& D_I_B_epsBB_HH() const {return d_I_B_epsBB_HH;};
	//	const Tenseur3HH& D_II_B_epsBB_HH() const {return d_II_B_epsBB_HH;};
	//	const Tenseur3HH& D_III_B_epsBB_HH() const {return d_III_B_epsBB_HH;};
		const Tableau <Tenseur3HH>& D_J_r_epsBB_HH() const {return d_J_r_epsBB_HH;};
		// --- acces en lectures  aux différentes grandeurs calculées 
		// uniquemenent par  Invariants_et_var2
  //	const Tenseur3HHHH&  D_I_B_eps2BB_HHHH () const {return d_I_B_eps2BB_HHHH;};
  //	const Tenseur3HHHH&  D_II_B_eps2BB_HHHH () const {return d_II_B_eps2BB_HHHH;};
  //	const Tenseur3HHHH&  D_III_B_eps2BB_HHHH () const {return d_III_B_eps2BB_HHHH;};
		const Tenseur3HHHH&  D_J_1_eps2BB_HHHH () const {return d_J_1_eps2BB_HHHH;};
		const Tenseur3HHHH&  D_J_2_eps2BB_HHHH () const {return d_J_2_eps2BB_HHHH;};
		const Tenseur3HHHH&  D_J_3_eps2BB_HHHH () const {return d_J_3_eps2BB_HHHH;};
		                                 
		  	       
	protected :
	   // données
    int sortie_post; // permet de stocker et ensuite d'accéder en post-traitement à certaines données
        // = 0 par défaut,
        // = 1 : on stocke toutes les grandeurs et elles sont disponibles en sortie
        // lecture dans les classes dérivées !!

	   double I_B,I_BB;//,I_BBB; // les 3 invariants primaires de B c'est-à-dire les trois traces
	                // I_B, I_{B.B}, I_{B.B.B}, en fait on ne se sert pas de I_BBB
	   double II_B,III_B; // les 3 invariants en I de B: I_1=I_B, I_2=II_B,I_3=III_B
	   Vecteur J_r ; // les 3 invariants en J
	   // variation des I II III par rapport aux composantes covariantes de la déformation
	   Tenseur3HH d_I_B_epsBB_HH,d_II_B_epsBB_HH,d_III_B_epsBB_HH;
	   // variation des J_r par rapport aux composantes covariantes de la déformation
	   Tableau <Tenseur3HH> d_J_r_epsBB_HH;
	   // variation seconde des I_r par rapport aux composantes covariantes de la déformation
	//   Tenseur3HHHH d_I_B_eps2BB_HHHH,d_II_B_eps2BB_HHHH,d_III_B_eps2BB_HHHH;
	   // variation seconde des J_r par rapport aux composantes covariantes de la déformation
	   Tenseur3HHHH d_J_1_eps2BB_HHHH,d_J_2_eps2BB_HHHH,d_J_3_eps2BB_HHHH;
	   // autres variables utiles pour la loi de comportement
	   double V; // variation relative de volume
	   Tenseur3HH BB_HH; // B . B
	   Tenseur3HB B_HB; // B en mixte
	   Tenseur3HB BB_HB; // B . B en mixte
	   
	   // variables tensorielles du second ordre intermédiaires 
	   Tenseur3HHHH IxI_HHHH,IxbarreI_HHHH,IxB_HHHH,BxI_HHHH;

	   
	   // grandeurs de travail
	   double J3_puiss_untiers // J3 puissance 1/3
	          ,unSurJ3_puissuntiers // 1/(J3^{1/3})
	          ,unSurJ3_puissuntiers2 // (1/(J3^{1/3})^2
	          ,unSurJ3_puissuntiers4; // (1/(J3^{1/3})^4
	   
	  
	   
	   // --------méthodes internes

    // affichage et definition interactive des commandes particulières ici = une partie générique
    // pour les lois, utilisée par les classes dérivées
    void Info_commande_LoisDeComp_hyper3D(UtilLecture& lec);

    // calcul des invariants et de leurs variations premières
    void InvariantsEtVar1(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien);
			
    // calcul des invariants et de leurs variations premières et secondes
    void InvariantsEtVar2(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien);
	   // vérification de la dérivée avec une dérivée numérique 
    // calcul des dérivées numériques premières
    void   Calcul_derivee_numerique(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                            ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                            ,const double& jacobien_0,const double& jacobien); 
    // calcul des dérivées numériques premières et secondes
    void   Calcul_derivee_numerique2(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                             ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                             ,const double& jacobien_0,const double& jacobien); 
    // --- pour le débug ----
    // calcul des invariants et de leurs variations premières en numérique
	   void Invariants_et_var1_deb(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien)
           {InvariantsEtVar1(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
                  // vérification numérique de la dérivée	 
                     Calcul_derivee_numerique(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
           };
		  // calcul des invariants et de leurs variations premières et secondes
		  void Invariants_et_var2_deb(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
		                       ,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
		                       ,const double& jacobien_0,const double& jacobien)
          {InvariantsEtVar2(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
                    Calcul_derivee_numerique2(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
          };

};
/// @}  // end of group


#endif		

		

