

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


/************************************************************************
 *           LABORATOIRE DE GENIE MECANIQUE ET MATERIAUX (LG2M)         *
 * Centre de Recherche Rue de Saint Maudé - 56325 Lorient cedex         *
 * tel. 02.97.87.45.70 fax. 02.97.87.45.72 http://www-lg2m.univ-ubs.fr  *
 ************************************************************************
 *     DATE:        29/2/2004                                           *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerard.rio@univ-ubs.fr)             *
 *                  Tel 0297874571   fax : 02.97.87.45.72               *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:   Definition d'une classe derivee de tenseur du 4ieme ordre *
 *            de dimension1, il s'agit ici d'une classe générale, sans  *
 *            particularités: c-a-d 1 composantes.  (car en 1D)         *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef TENSEURQ1GENE_H
#define TENSEURQ1GENE_H

#include <iostream> 
#include "Tenseur1_TroisSym.h"

// Du au fait qu'en une dimension, la classe générale est identique aux classes particulières
// on utilise des équivalences
//------------------------------------------------------------------
//          cas des composantes 4 fois contravariantes 3HHHH
//------------------------------------------------------------------  

typedef TenseurQ1_troisSym_HHHH TenseurQ1geneHHHH ;
 
//------------------------------------------------------------------
//          cas des composantes 4 fois covariantes
//------------------------------------------------------------------

typedef TenseurQ1_troisSym_BBBB TenseurQ1geneBBBB ;

//------------------------------------------------------------------
//          cas des composantes mixte inverse BHBH
//------------------------------------------------------------------

class TenseurQ1geneBHBH : public TenseurBHBH
{ // surcharge de l'operator de lecture
  friend istream & operator >> (istream &, TenseurQ1geneBHBH &);
  // surcharge de l'operator d'ecriture
  friend ostream & operator << (ostream &, const TenseurQ1geneBHBH &);
 
  public :
    // Constructeur
    TenseurQ1geneBHBH() ; // par défaut
    // initialisation de toutes les composantes (ici une seule) a une meme valeur val 
    TenseurQ1geneBHBH(const double& x1111);  

    // DESTRUCTEUR :
    ~TenseurQ1geneBHBH() ;
    // constructeur a partir d'une instance non differenciee 
    TenseurQ1geneBHBH (const  TenseurBHBH &); 
    // constructeur de copie  
    TenseurQ1geneBHBH (const  TenseurQ1geneBHBH &); 
    
   // METHODES PUBLIQUES :
//2)    virtuelles    
    // initialise toutes les composantes à val
    void Inita(double val) ;   
    // operations 
    TenseurBHBH & operator + ( const TenseurBHBH &) const ;
    void operator += ( const TenseurBHBH &);
    TenseurBHBH & operator - () const ;  // oppose du tenseur
    TenseurBHBH & operator - ( const TenseurBHBH &) const ;
    void  operator -= ( const TenseurBHBH &);
    TenseurBHBH & operator = ( const TenseurBHBH &);
    TenseurBHBH & operator * (const double &) const   ;
    void  operator *= ( const double &);
    TenseurBHBH & operator / ( const double &) const ;
    void  operator /= ( const double &);
    
    // produit deux fois contracte à droite avec un tenseur du second ordre
    // (différent de à gauche !!) def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche
    TenseurBH& operator && ( const TenseurBH & )  const ;

    // ATTENTION creation d'un tenseur transpose qui est supprime par Libere
    // les 2 premiers indices sont échangés avec les deux derniers indices
    // ici en fait c'est le même tenseur grace aux symétries constitutives
    TenseurHBHB & Transpose1et2avec3et4() const  ; 
    
    // affectation de B dans this,  plusZero = false: les données manquantes sont inchangées,
    // plusZero = true: les données manquantes sont mises à 0
    // si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
    // des données possibles
    virtual void Affectation_trans_dimension(const TenseurBHBH & B,bool plusZero) ;
 
    // test
    int operator == ( const TenseurBHBH &) const ;
    
    // change la composante i,j,k,l du tenseur
    // acces en  ecriture, 
 	  void Change (int i, int j, int k, int l,const double& val) ;
    // en cumul : équivalent de +=
    void ChangePlus (int i, int j, int k, int l,const double& val);

    // Retourne la composante i,j,k,l du tenseur
    // acces en lecture seule
	   double  operator () (int i, int j, int k, int l) const ;
        
    // calcul du maximum en valeur absolu des composantes du tenseur
    double MaxiComposante() const;
             	 
	   // lecture et écriture de données
    istream & Lecture(istream & entree);
    ostream & Ecriture(ostream & sort) const ;
       
  protected :
    // allocator dans la liste de data 
	   listdouble1Iter ipointe;
	
	   // fonction pour le produit contracté à gauche
    TenseurBH& Prod_gauche( const TenseurBH & F) const ; 
  }; 

//------------------------------------------------------------------
//          cas des composantes mixte inverse HBHB
//------------------------------------------------------------------

class TenseurQ1geneHBHB : public TenseurHBHB
{ // surcharge de l'operator de lecture
  friend istream & operator >> (istream &, TenseurQ1geneHBHB &);
  // surcharge de l'operator d'ecriture
  friend ostream & operator << (ostream &, const TenseurQ1geneHBHB &);
 
  public :
    // Constructeur
    TenseurQ1geneHBHB() ; // par défaut
    // initialisation de toutes les composantes (ici une seule) a une meme valeur val 
    TenseurQ1geneHBHB(const double& x1111);  

    // DESTRUCTEUR :
    ~TenseurQ1geneHBHB() ;
    // constructeur a partir d'une instance non differenciee 
    TenseurQ1geneHBHB (const  TenseurHBHB &); 
    // constructeur de copie  
    TenseurQ1geneHBHB (const  TenseurQ1geneHBHB &); 
    
   // METHODES PUBLIQUES :
//2)    virtuelles    
    // initialise toutes les composantes à val
    void Inita(double val) ;   
    // operations 
    TenseurHBHB & operator + ( const TenseurHBHB &) const ;
    void operator += ( const TenseurHBHB &);
    TenseurHBHB & operator - () const ;  // oppose du tenseur
    TenseurHBHB & operator - ( const TenseurHBHB &) const ;
    void  operator -= ( const TenseurHBHB &);
    TenseurHBHB & operator = ( const TenseurHBHB &);
    TenseurHBHB & operator * (const double &) const   ;
    void  operator *= ( const double &);
    TenseurHBHB & operator / ( const double &) const ;
    void  operator /= ( const double &);
    
    // produit deux fois contracte à droite avec un tenseur du second ordre
    // (différent de à gauche !!) def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche
    TenseurHB& operator && ( const TenseurHB & )  const ;

    // ATTENTION creation d'un tenseur transpose qui est supprime par Libere
    // les 2 premiers indices sont échangés avec les deux derniers indices
    // ici en fait c'est le même tenseur grace aux symétries constitutives
    TenseurBHBH & Transpose1et2avec3et4() const  ; 
    
    // affectation de B dans this,  plusZero = false: les données manquantes sont inchangées,
    // plusZero = true: les données manquantes sont mises à 0
    // si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
    // des données possibles
    virtual void Affectation_trans_dimension(const TenseurHBHB & B,bool plusZero);
 
    // test
    int operator == ( const TenseurHBHB &) const ;
    
    // change la composante i,j,k,l du tenseur
    // acces en  ecriture, 
 	  void Change (int i, int j, int k, int l,const double& val) ;
    // en cumul : équivalent de +=
    void ChangePlus (int i, int j, int k, int l,const double& val);

    // Retourne la composante i,j,k,l du tenseur
    // acces en lecture seule
	   double  operator () (int i, int j, int k, int l) const ;
        
    // calcul du maximum en valeur absolu des composantes du tenseur
    double MaxiComposante() const;
             	 
	   // lecture et écriture de données
    istream & Lecture(istream & entree);
    ostream & Ecriture(ostream & sort) const ;
       
  protected :
    // allocator dans la liste de data 
	   listdouble1Iter ipointe;
	
	   // fonction pour le produit contracté à gauche
    TenseurHB& Prod_gauche( const TenseurHB & F) const ; 
  }; 

//------------------------------------------------------------------
//          cas des composantes mixte inverse BHHB
//------------------------------------------------------------------

class TenseurQ1geneBHHB : public TenseurBHHB
{ // surcharge de l'operator de lecture
  friend istream & operator >> (istream &, TenseurQ1geneBHHB &);
  // surcharge de l'operator d'ecriture
  friend ostream & operator << (ostream &, const TenseurQ1geneBHHB &);
 
  public :
    // Constructeur
    TenseurQ1geneBHHB() ; // par défaut
    // initialisation de toutes les composantes (ici une seule) a une meme valeur val 
    TenseurQ1geneBHHB(const double& x1111);  

    // DESTRUCTEUR :
    ~TenseurQ1geneBHHB() ;
    // constructeur a partir d'une instance non differenciee 
    TenseurQ1geneBHHB (const  TenseurBHHB &); 
    // constructeur de copie  
    TenseurQ1geneBHHB (const  TenseurQ1geneBHHB &); 
    
   // METHODES PUBLIQUES :
//2)    virtuelles    
    // initialise toutes les composantes à val
    void Inita(double val) ;   
    // operations 
    TenseurBHHB & operator + ( const TenseurBHHB &) const ;
    void operator += ( const TenseurBHHB &);
    TenseurBHHB & operator - () const ;  // oppose du tenseur
    TenseurBHHB & operator - ( const TenseurBHHB &) const ;
    void  operator -= ( const TenseurBHHB &);
    TenseurBHHB & operator = ( const TenseurBHHB &);
    TenseurBHHB & operator * (const double &) const   ;
    void  operator *= ( const double &);
    TenseurBHHB & operator / ( const double &) const ;
    void  operator /= ( const double &);
    
    // produit deux fois contracte à droite avec un tenseur du second ordre
    // (différent de à gauche !!) def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche
    TenseurBH& operator && ( const TenseurHB & )  const ;

    // ATTENTION creation d'un tenseur transpose qui est supprime par Libere
    // les 2 premiers indices sont échangés avec les deux derniers indices
    // ici en fait c'est le même tenseur grace aux symétries constitutives
    TenseurHBBH & Transpose1et2avec3et4() const  ; 
    
    // affectation de B dans this,  plusZero = false: les données manquantes sont inchangées,
    // plusZero = true: les données manquantes sont mises à 0
    // si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
    // des données possibles
    virtual void Affectation_trans_dimension(const TenseurBHHB & B,bool plusZero) ;
 
    // test
    int operator == ( const TenseurBHHB &) const ;
    
    // change la composante i,j,k,l du tenseur
    // acces en  ecriture, 
 	  void Change (int i, int j, int k, int l,const double& val) ;
    // en cumul : équivalent de +=
    void ChangePlus (int i, int j, int k, int l,const double& val);

    // Retourne la composante i,j,k,l du tenseur
    // acces en lecture seule
	   double  operator () (int i, int j, int k, int l) const ;
        
    // calcul du maximum en valeur absolu des composantes du tenseur
    double MaxiComposante() const;
             	 
	   // lecture et écriture de données
    istream & Lecture(istream & entree);
    ostream & Ecriture(ostream & sort) const ;
       
  protected :
    // allocator dans la liste de data 
	   listdouble1Iter ipointe;
	
	   // fonction pour le produit contracté à gauche
    TenseurHB& Prod_gauche( const TenseurBH & F) const ; 
  }; 
   
//------------------------------------------------------------------
//          cas des composantes 2 fois mixtes HBBH
//------------------------------------------------------------------   
class TenseurQ1geneHBBH : public TenseurHBBH
{ // surcharge de l'operator de lecture
  friend istream & operator >> (istream &, TenseurQ1geneHBBH &);
  // surcharge de l'operator d'ecriture
  friend ostream & operator << (ostream &, const TenseurQ1geneHBBH &);
 
  public :
    // Constructeur
    TenseurQ1geneHBBH() ; // par défaut
    // initialisation de toutes les composantes (ici une seule) a une meme valeur val 
    TenseurQ1geneHBBH(const double& x1111);  

    // DESTRUCTEUR :
    ~TenseurQ1geneHBBH() ;
    // constructeur a partir d'une instance non differenciee 
    TenseurQ1geneHBBH (const  TenseurHBBH &); 
    // constructeur de copie  
    TenseurQ1geneHBBH (const  TenseurQ1geneHBBH &); 
    
   // METHODES PUBLIQUES :
//2)    virtuelles    
    // operations 
    // initialise toutes les composantes à val
    void Inita(double val) ;   
    TenseurHBBH & operator + ( const TenseurHBBH &) const ;
    void operator += ( const TenseurHBBH &);
    TenseurHBBH & operator - () const ;  // oppose du tenseur
    TenseurHBBH & operator - ( const TenseurHBBH &) const ;
    void  operator -= ( const TenseurHBBH &);
    TenseurHBBH & operator = ( const TenseurHBBH &);
    TenseurHBBH & operator * (const double &) const   ;
    void  operator *= ( const double &);
    TenseurHBBH & operator / ( const double &) const ;
    void  operator /= ( const double &);
    
    // produit deux fois contracte à droite avec un tenseur du second ordre
    // (différent de à gauche !!) def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche
    TenseurHB& operator && ( const TenseurBH & )  const ;

    // ATTENTION creation d'un tenseur transpose qui est supprime par Libere
    // les 2 premiers indices sont échangés avec les deux derniers indices
    // ici en fait c'est le même tenseur grace aux symétries constitutives
    TenseurBHHB & Transpose1et2avec3et4() const  ; 
    
    // affectation de B dans this,  plusZero = false: les données manquantes sont inchangées,
    // plusZero = true: les données manquantes sont mises à 0
    // si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
    // des données possibles
    virtual void Affectation_trans_dimension(const TenseurHBBH & B,bool plusZero) ;
 
    // test
    int operator == ( const TenseurHBBH &) const ;
    
    // change la composante i,j,k,l du tenseur
    // acces en  ecriture, 
 	  void Change (int i, int j, int k, int l,const double& val) ;
    // en cumul : équivalent de +=
    void ChangePlus (int i, int j, int k, int l,const double& val);

    // Retourne la composante i,j,k,l du tenseur
    // acces en lecture seule
	   double  operator () (int i, int j, int k, int l) const ;
        
    // calcul du maximum en valeur absolu des composantes du tenseur
    double MaxiComposante() const;
             	 
	   // lecture et écriture de données
    istream & Lecture(istream & entree);
    ostream & Ecriture(ostream & sort) const ;
       
  protected :
    // allocator dans la liste de data 
	   listdouble1Iter ipointe;
	
	   // fonction pour le produit contracté à gauche
    TenseurBH& Prod_gauche( const TenseurHB & F) const ; 
  }; 

     
#ifndef MISE_AU_POINT
  #include "TenseurQ1gene.cc"
  #define  TenseurQ1gene_H_deja_inclus
#endif
 
#endif  
