// 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/>.

/************************************************************************
 *     DATE:        26/11/2006                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT: Classe pour stocker les informations aux points             *
 *          d'intégration mécanique (plutôt puissance interne)          *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef PTINTEGMECAINTERNE_H
#define PTINTEGMECAINTERNE_H

#include "Tenseur.h"
#include "Vecteur.h"
#include "Temps_CPU_HZpp.h"


/** @defgroup Groupe_concernant_les_points_integration
*
*     BUT:   groupe relatif aux points d'intégration
*
*
* \author      Gérard Rio
* \version     1.0
* \date        26/11/2006
* \brief       groupe relatif aux points d'intégration
*
*/

/// @addtogroup Groupe_concernant_les_points_integration
///  @{
///


class  PtIntegMecaInterne

{   // surcharge de l'operator de lecture
    friend istream & operator >> (istream &, PtIntegMecaInterne &);
    // surcharge de l'operator d'ecriture
    friend ostream & operator << (ostream &, const PtIntegMecaInterne &);

  public :
    // CONSTRUCTEURS :
    // contructeur par défaut
    PtIntegMecaInterne(); 
    // contructeur fonction de la dimension de tenseurs
    PtIntegMecaInterne(int dimtens);     
    // contructeur de copie
    PtIntegMecaInterne(const PtIntegMecaInterne& pti);     
    
    // DESTRUCTEUR :
    ~PtIntegMecaInterne();
    
    // METHODES PUBLIQUES :
	   // Surcharge de l'operateur = 
    PtIntegMecaInterne& operator= ( const PtIntegMecaInterne& pti);
    
    // deformation finale
    TenseurBB * EpsBB() {return epsBB;}; 
	   // vitesse finale de deformation
	   TenseurBB * DepsBB() {return  depsBB;};
	   // variation de deformation entre t et t + delta t
	   TenseurBB * DeltaEpsBB() {return  deltaEpsBB;};
	   // contrainte finale
	   TenseurHH * SigHH() {return  sigHH;};
	   // contrainte en début d'incrément
	   TenseurHH * SigHH_t() {return  sigHH_t;};
	   // module de compressibilité
	   // si = -1, cela veut dire que le module n'a pas été mis à jour
	   double& ModuleCompressibilite() {return module_compressibilite;};
	   // module de cisaillement
	   // si = -1, cela veut dire que le module n'a pas été mis à jour
	   double& ModuleCisaillement() { return module_cisaillement;};
	   // volume élémentaire au pti
	   // si = -1, cela veut dire que le volume élémentaire n'a pas été mis à jour
	   double& Volume_pti() { return volume_pti;};
	   // tableau relatif aux différentes grandeurs de type def scalaires équivalentes
	   // def_equi(1) = deformation cumulée = somme des sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)) ;
	   // def_equi(2) = deformation duale de la contrainte de mises = sqrt(2./3. * (eps_barre_BH && eps_barre_BH)) ;
	   // def_equi(3) = niveau maxi atteind par def_equi(2)
	   // def_equi(4) = delta def cumulée = sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH));
	   Tableau <double>& Deformation_equi() { return def_equi;};
	   Tableau <double>& Deformation_equi_t() { return def_equi_t;};
    
    // idem coté contrainte
    // (1) = contrainte_mises, (2) = contrainte_tresca
    Tableau <double>& Sig_equi() { return sig_equi;};
    Tableau <double>& Sig_equi_t() { return sig_equi_t;};

    // les positions modifiables
    Coordonnee& M_0()   {return M0;};
    Coordonnee& M_t()   {return Mt;};
    Coordonnee& M_tdt() {return Mtdt;};
    // repérage dans maillage
    int Nb_mail() const {return mail;};
    int Nb_ele() const {return nele;};
    int Nb_pti() const {return npti;};
    void Change_Nb_mail(int nb) {mail=nb;};
    void Change_Nb_ele(int nb) {nele=nb;};
    void Change_Nb_pti(int nb) {npti=nb;};
    void Signature() const
      {cout << " mail: " << mail << ", ele= "<< nele <<", pti=" << npti <<" ";};

    // --- temps cpu
    // tps cpu relatif à la métrique uniquement
    Temps_CPU_HZpp& TpsMetrique() {return tpsMetrique;};
    // temps cumulé relatif à la loi de comportement
    Temps_CPU_HZpp& Tps_cpu_loi_comp() {return  tps_cpu_loi_comp;};
	
	// ---- acces idem en constants 
    // deformation finale
    const TenseurBB &  EpsBB_const() const {return *epsBB;};
	   // vitesse finale de deformation
	   const TenseurBB & DepsBB_const() const {return  *depsBB;};
	   // variation de deformation entre t et t + delta t
	   const TenseurBB & DeltaEpsBB_const() const {return  *deltaEpsBB;};
	   // contrainte finale
	   const TenseurHH & SigHH_const() const {return  *sigHH;};
	   // contrainte en début d'incrément
	   const TenseurHH & SigHH_t_const() const {return  *sigHH_t;};
	   // module de compressibilité
	   // si = -1, cela veut dire que le module n'a pas été mis à jour
	   const double& ModuleCompressibilite_const() const {return module_compressibilite;};
	   // module de cisaillement
	   // si = -1, cela veut dire que le module n'a pas été mis à jour
	   const double& ModuleCisaillement_const() const { return module_cisaillement;};
	   // volume élémentaire au pti
	   // si = -1, cela veut dire que le volume élémentaire n'a pas été mis à jour
	   const double& Volume_pti_const() { return volume_pti;};

	   // tableau constant relatif aux différentes grandeurs de type def scalaires équivalentes
	   // def_equi(1) = deformation cumulée = somme des sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)) ;
	   // def_equi(2) = deformation duale de la contrainte de mises = sqrt(2./3. * (eps_barre_BH && eps_barre_BH)) ;
	   // def_equi(3) = niveau maxi atteind par def_equi(2)
	   // def_equi(4) = delta def cumulée = sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH));
	   const Tableau <double>& Deformation_equi_const () const { return def_equi;};
	   const Tableau <double>& Deformation_equi_t_const () const { return def_equi_t;};
    
    // idem coté contrainte
    // (1) = contrainte_mises, (2) = contrainte_tresca
    const Tableau <double>& Sig_equi_const() const { return sig_equi;};
    const Tableau <double>& Sig_equi_t_const() const { return sig_equi_t;};

    // les positions en const
    const Coordonnee& M0_const() const {return M0;};
    const Coordonnee& Mt_const() const {return Mt;};
    const Coordonnee& Mtdt_const() const {return Mtdt;};
    // --- temps cpu
    // tps cpu relatif à la métrique uniquement
    const Temps_CPU_HZpp& TpsMetrique_const() const {return tpsMetrique;};
    // temps cumulé relatif à la loi de comportement
    const Temps_CPU_HZpp& Tps_cpu_loi_comp_const() const {return  tps_cpu_loi_comp;};
	
	// --- cas des invariants: a priori non-activé, pour les utiliser il faut les activer avant
	   // le statut: activé ou pas activé
	   bool Statut_Invariants_deformation () const {return ((epsInvar!=NULL) ? true :false);};
	   bool Statut_Invariants_vitesseDeformation () const {return ((depsInvar!=NULL) ? true :false);};
	   bool Statut_Invariants_contrainte () const {return ((sigInvar!=NULL) ? true :false);};
	   // le changement de statut, si c'est déjà ok, on ne fait rien
	   // nevez_statut: indique si l'on veut activer ou au contraire désactiver
	   void Change_statut_Invariants_deformation (bool nevez_statut);
	   void Change_statut_Invariants_vitesseDeformation (bool nevez_statut);
	   void Change_statut_Invariants_contrainte (bool nevez_statut);
	
	   // la récupération des invariants (s'ils sont actifs !!) en lecture écriture
	   // rappel sur la signification des différentes composantes des vecteurs "invariant":
    //     (3)   ===>  Det();
    //     (2)   ===>  II() = A:A;
    //     (1)   ===>  Trace();

	   // invariants de déformations
	   Vecteur&  EpsInvar() {return  *epsInvar;}; 
	   const Vecteur&  EpsInvar_const() const {return  *epsInvar;};
	   // invariants des vitesses de déformations
	   Vecteur&  DepsInvar() {return  *depsInvar;};
	   const Vecteur&  DepsInvar_const() const {return  *depsInvar;};
	   // invariants des contraintes
	   Vecteur&  SigInvar() {return  *sigInvar;};
	   const Vecteur&  SigInvar_const() const {return  *sigInvar;};
	 
    // actualisation des grandeurs actives de t+dt vers t, pour celles qui existent 
    // sous ces deux formes    
    void TdtversT();
    // actualisation des grandeurs actives de t vers tdt, pour celles qui existent 
    // sous ces deux formes          
    void TversTdt();
	 
	//========= méthode particulière pour un passage de l'ordre 2D à 3D des tenseurs et l'inverse ===========
	   // plusZero: = true: indique qu'il faut complèter les grandeurs manquantes avec des 0
	   //           = false: on ne complète pas
	   // il faut que ptintmec comporte des tenseurs d'ordre 2 et this des tenseurs 3D
	   void Affectation_2D_a_3D(const PtIntegMecaInterne& ptintmec,bool plusZero);
	   // l'inverse: comme le conteneur d'arrivée est plus petit, il n'y a pas de complétion
	   // il faut que ptintmec comporte des tenseurs d'ordre 3 et this des tenseurs 2D
	   void Affectation_3D_a_2D(const PtIntegMecaInterne& ptintmec); 

	//========= méthode particulière pour un passage de l'ordre 1D à 3D des tenseurs et l'inverse ===========
	   // plusZero: = true: indique qu'il faut complèter les grandeurs manquantes avec des 0
	   //           = false: on ne complète pas
	   // il faut que ptintmec comporte des tenseurs d'ordre 1 et this des tenseurs 3D
	   void Affectation_1D_a_3D(const PtIntegMecaInterne& ptintmec,bool plusZero);
	   // l'inverse: comme le conteneur d'arrivée est plus petit, il n'y a pas de complétion
	   // il faut que ptintmec comporte des tenseurs d'ordre 3 et this des tenseurs 1D
	   void Affectation_3D_a_1D(const PtIntegMecaInterne& ptintmec);

	//============= 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)
	   void Lecture_base_info (istream& ent,const int cas);
    // cas donne le niveau de sauvegarde
    // = 1 : on sauvegarde tout
    // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
	   void Ecriture_base_info(ostream& sort,const int cas);
    		
    
	protected :

   // VARIABLES PROTÉGÉES :    
    
    TenseurBB * epsBB; // deformation finale
    TenseurBB * depsBB; // vitesse finale de deformation 
    TenseurBB * deltaEpsBB; // variation de deformation entre t et t + delta t
    TenseurHH * sigHH; // contrainte finale		
    TenseurHH * sigHH_t; // contrainte en début d'incrément
    double module_compressibilite, module_cisaillement;
    double volume_pti; // volume élémentaire au pti
    // tableau relatif aux différentes grandeurs de type def scalaires équivalentes
    // def_equi(1) = deformation cumulée = somme des sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)) ;
    // def_equi(2) = deformation duale de la contrainte de mises = sqrt(2./3. * (eps_barre_BH && eps_barre_BH)) ;
    // def_equi(3) = niveau maxi atteind par def_equi(2) 
    // def_equi(4) = delta def cumulée = sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH));
    Tableau <double>  def_equi_t, def_equi;
    
    // idem coté contrainte
    // (1) = contrainte_mises, (2) = contrainte_tresca
    Tableau <double> sig_equi_t, sig_equi;
 
    // positions du point d'intégration
    Coordonnee M0,Mt,Mtdt;
    // repérage dans éléments, maillage, nb pti
    int mail,nele,npti;
 
    //peut contenir éventuellement un tableau de base rattachée
 
//    Tableau < BaseB_0_t_tdt>* tab_baseB_0_t_tdt;

	
	// ---- les invariants éventuels (cas où les pointeurs ne sont pas nuls)
		  // rappel sur la signification des différentes composantes des vecteurs "invariant":
		  //     (3)   ===>  Det();
    //     (2)   ===>  II() = A:A;
    //     (1)   ===>  Trace();
	   Vecteur * epsInvar	; // invariants de déformations
	   Vecteur * depsInvar	; // invariants des vitesses de déformations
	   Vecteur * sigInvar	; // invariants des contraintes
    // --- temps cpu
    Temps_CPU_HZpp tpsMetrique;       // tps cpu relatif à la métrique uniquement
    Temps_CPU_HZpp tps_cpu_loi_comp;  // temps cumulé relatif à la loi de comportement

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

#endif