2021-09-07 09:39:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-07 09:39:21 +02:00
|
|
|
// 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: 23/01/97 *
|
|
|
|
* $ *
|
|
|
|
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
|
|
|
|
* $ *
|
|
|
|
* PROJET: Herezh++ *
|
|
|
|
* $ *
|
|
|
|
************************************************************************
|
|
|
|
* BUT: Definition des classes derivees de dimension 3. *
|
|
|
|
* $ *
|
|
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef Tenseur3_H
|
|
|
|
#define Tenseur3_H
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include "Tenseur.h"
|
|
|
|
#include "PtTabRel.h"
|
|
|
|
#include "Tableau2_T.h"
|
|
|
|
|
|
|
|
|
|
|
|
/** @defgroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
*
|
|
|
|
* BUT: Definir les tenseurs d'ordre 2 de differentes composantes,
|
|
|
|
* spécifiquement à la dimension 3.
|
|
|
|
* L'objectif principal est de surcharger les differentes operations
|
|
|
|
* classiques.
|
|
|
|
*
|
|
|
|
* concernant le produit contracte un fois, en particulier pour les tenseurs mixtes
|
|
|
|
* il y a contraction du 2ieme indice du premier tenseur avec le premier indice du second
|
|
|
|
* tenseur : Aij * Bjk = C ik <-> A * B = C
|
|
|
|
* le tenseur inverse par rapport au produit contracte est defini de la maniere suivante
|
|
|
|
* Inverse(A) * A = Id, ainsi l'inverse d'un tenseur BH est un BH idem pour les HB
|
|
|
|
* mais l'inverse d'un BB est un HH, et l'inverse d'un HH est un BB
|
|
|
|
*
|
|
|
|
* NB: lorsque les tenseurs mixtes sont issues de tenseurs HH ou BB symetrique, l'ordre
|
|
|
|
* de contraction des indices n'a pas d'importance sur le resultat !!
|
|
|
|
*
|
|
|
|
* le produit contracte de deux tenseurs symetriques quelconques ne donne pas un tenseur
|
|
|
|
* symetrique !!, donc par exemple la contraction d'un tenseur HB avec HH n'est pas forcement
|
|
|
|
* symetrique. Le resultat est symetrique SEULEMENT lorsque ces operations sont effectues
|
|
|
|
* avec le tenseur metrique.
|
|
|
|
*
|
|
|
|
* \author Gérard Rio
|
|
|
|
* \version 1.0
|
|
|
|
* \date 23/01/97
|
|
|
|
* \brief Définition des classes de dimension 3 de type Tenseur d'ordre 2, en coordonnées avec différentes variances.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
class Tenseur_ns3HH;class Tenseur2HH;
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes deux fois contravariantes
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
|
|
|
|
class Tenseur3HH : public TenseurHH
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur3HH &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur3HH &);
|
|
|
|
friend class Tenseur2HH; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
friend class Tenseur3BB;
|
|
|
|
|
|
|
|
public :
|
|
|
|
// Constructeur
|
|
|
|
Tenseur3HH() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur3HH(const double val);
|
|
|
|
// initialisation avec 6 valeurs différentes correspondantes a
|
|
|
|
// (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
Tenseur3HH
|
|
|
|
(const double val1,const double val2,const double val3,const double val4,
|
|
|
|
const double val5,const double val6) ;
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur3HH() ;
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur3HH (const TenseurHH &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur3HH (const Tenseur3HH &);
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurHH & operator + (const TenseurHH &) const ;
|
|
|
|
void operator += ( const TenseurHH &);
|
|
|
|
TenseurHH & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurHH & operator - ( const TenseurHH &) const ;
|
|
|
|
void operator -= ( const TenseurHH &);
|
|
|
|
TenseurHH & operator = ( const TenseurHH &);
|
|
|
|
TenseurHH & operator = ( const Tenseur3HH & B)
|
|
|
|
{ return this->operator=((TenseurHH &) B); };
|
|
|
|
TenseurHH & operator = ( const Tenseur_ns3HH & B)
|
|
|
|
{ return this->operator=((TenseurHH &) B); };
|
|
|
|
TenseurHH & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurHH & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur2HH & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurHH & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte avec un vecteur
|
|
|
|
CoordonneeH operator * ( const CoordonneeB & ) const ;
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
TenseurHH & operator * ( const TenseurBH &) const ;
|
|
|
|
TenseurHB & operator * ( const TenseurBB &) const ;
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
double operator && ( const TenseurBB &) const ;
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurHH &) const ;
|
|
|
|
int operator != ( const TenseurHH &) const ;
|
|
|
|
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurBB & Inverse() const ;
|
|
|
|
|
|
|
|
// ATTENTION creation d'un tenseur transpose qui est supprime par Libere
|
|
|
|
TenseurHH & Transpose() const ;
|
|
|
|
|
|
|
|
// ---- manipulation d'indice ---- -> création de nouveaux tenseurs
|
|
|
|
virtual TenseurBB& Baisse2Indices() const;
|
|
|
|
virtual TenseurBH& BaissePremierIndice() const;
|
|
|
|
virtual TenseurHB& BaisseDernierIndice() const;
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
|
|
// si les vecteurs sont égaux le tenseur est symétrique sinon il est non symétrique
|
|
|
|
static TenseurHH & Prod_tensoriel(const CoordonneeH & aH, const CoordonneeH & bH);
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre: (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur3HH::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre: (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur3HH::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur3HH::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
listdouble6Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
class Tenseur_ns2HH;
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes deux fois contravariantes non symetriques
|
|
|
|
/// pour les differencier la dimension = -3
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
class Tenseur_ns3HH : public TenseurHH
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur_ns3HH &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur_ns3HH &);
|
|
|
|
friend class Tenseur_ns2HH; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
friend class Tenseur_ns3BB;
|
|
|
|
public :
|
|
|
|
// constructeur
|
|
|
|
Tenseur_ns3HH() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur_ns3HH (double val) ;
|
|
|
|
// initialisation avec 9 valeurs différentes correspodantes aux trois
|
|
|
|
// lignes : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
// car le tableau n'est pas symetrique !!!!
|
|
|
|
// le premier indice = ligne, le second = colonne
|
|
|
|
Tenseur_ns3HH
|
|
|
|
( const double val1, const double val2, const double val3, // 1ere ligne
|
|
|
|
const double val4, const double val5, const double val6, // 2ieme ligne
|
|
|
|
const double val7, const double val8, const double val9) ; // 3ieme ligne
|
|
|
|
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur_ns3HH();
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur_ns3HH ( const TenseurHH &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur_ns3HH ( const Tenseur_ns3HH &);
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurHH & operator + ( const TenseurHH &) const ;
|
|
|
|
void operator += ( const TenseurHH &);
|
|
|
|
TenseurHH & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurHH & operator - ( const TenseurHH &) const ;
|
|
|
|
void operator -= ( const TenseurHH &);
|
|
|
|
TenseurHH & operator = ( const TenseurHH &);
|
|
|
|
TenseurHH & operator = ( const Tenseur3HH & B)
|
|
|
|
{ return this->operator=((TenseurHH &) B); };
|
|
|
|
TenseurHH & operator = ( const Tenseur_ns3HH & B)
|
|
|
|
{ return this->operator=((TenseurHH &) B); };
|
|
|
|
TenseurHH & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurHH & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur_ns2HH & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurHH & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte avec un vecteur
|
|
|
|
CoordonneeH operator * ( const CoordonneeB & ) const ;
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
TenseurHH & operator * ( const TenseurBH &) const ;
|
|
|
|
TenseurHB & operator * ( const TenseurBB &) const ;
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
double operator && ( const TenseurBB &) const ;
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurHH &) const ;
|
|
|
|
int operator != ( const TenseurHH &) const ;
|
|
|
|
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurBB & Inverse() const ;
|
|
|
|
|
|
|
|
// ATTENTION creation d'un tenseur transpose qui est supprime par Libere
|
|
|
|
TenseurHH & Transpose() const ;
|
|
|
|
|
|
|
|
// ---- manipulation d'indice ---- -> création de nouveaux tenseurs
|
|
|
|
virtual TenseurBB& Baisse2Indices() const;
|
|
|
|
virtual TenseurBH& BaissePremierIndice() const;
|
|
|
|
virtual TenseurHB& BaisseDernierIndice() const;
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur_ns3HH::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur_ns3HH::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur_ns3HH::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
// static list <Reels4> listdouble4;
|
|
|
|
listdouble9Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
class Tenseur_ns3BB;class Tenseur2BB;
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes deux fois covariantes
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
class Tenseur3BB : public TenseurBB
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur3BB &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur3BB &);
|
|
|
|
friend class Tenseur2BB; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
friend class Tenseur3HH;
|
|
|
|
public :
|
|
|
|
// constructeur
|
|
|
|
Tenseur3BB() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur3BB( const double val);
|
|
|
|
// initialisation avec 6 valeurs différentes correspondantes a
|
|
|
|
// (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
Tenseur3BB
|
|
|
|
( const double val1, const double val2, const double val3,
|
|
|
|
const double val4, const double val5, const double val6) ;
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur3BB() ;
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur3BB ( const TenseurBB &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur3BB ( const Tenseur3BB &);
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurBB & operator + ( const TenseurBB &) const ;
|
|
|
|
void operator += ( const TenseurBB &);
|
|
|
|
TenseurBB & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurBB & operator - ( const TenseurBB &) const ;
|
|
|
|
void operator -= ( const TenseurBB &);
|
|
|
|
TenseurBB & operator = ( const TenseurBB &) ;
|
|
|
|
TenseurBB & operator = ( const Tenseur3BB & B)
|
|
|
|
{ return this->operator=((TenseurBB &) B); };
|
|
|
|
TenseurBB & operator = ( const Tenseur_ns3BB & B)
|
|
|
|
{ return this->operator=((TenseurBB &) B); };
|
|
|
|
TenseurBB & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurBB & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur2BB & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurBB & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte avec un vecteur
|
|
|
|
CoordonneeB operator * ( const CoordonneeH & ) const ;
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
TenseurBB & operator * ( const TenseurHB &) const ;
|
|
|
|
TenseurBH & operator * ( const TenseurHH &) const ;
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
double operator && ( const TenseurHH &) const ;
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurBB &) const ;
|
|
|
|
int operator != ( const TenseurBB &) const ;
|
|
|
|
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurHH & Inverse() const ;
|
|
|
|
|
|
|
|
// ATTENTION creation d'un tenseur transpose qui est supprime par Libere
|
|
|
|
TenseurBB & Transpose() const ;
|
|
|
|
|
|
|
|
// ---- manipulation d'indice ---- -> création de nouveaux tenseurs
|
|
|
|
virtual TenseurHH& Monte2Indices() const ;
|
|
|
|
virtual TenseurHB& MontePremierIndice() const ;
|
|
|
|
virtual TenseurBH& MonteDernierIndice() const ;
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
|
|
// si les vecteurs sont égaux le tenseur est symétrique sinon il est non symétrique
|
|
|
|
static TenseurBB & Prod_tensoriel(const CoordonneeB & aB, const CoordonneeB & bB);
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre: (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur3BB::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre: (1,1) (2,2) (3,3) (2,1)=(1,2) (3,2)=(2,3) (3,1)=(1,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur3BB::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur3BB::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
listdouble6Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
class Tenseur_ns2BB;
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes deux fois covariantes non symetriques
|
|
|
|
/// pour les differencier la dimension = -3
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
class Tenseur_ns3BB : public TenseurBB
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur_ns3BB &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur_ns3BB &);
|
|
|
|
friend class Tenseur_ns2BB; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
friend class Tenseur_ns3HH;
|
|
|
|
public :
|
|
|
|
// Constructeur
|
|
|
|
Tenseur_ns3BB() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur_ns3BB ( const double val) ;
|
|
|
|
// initialisation avec 9 valeurs différentes correspodantes aux trois
|
|
|
|
// lignes : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
// car le tableau n'est pas symetrique !!!!
|
|
|
|
// le premier indice = ligne, le second = colonne
|
|
|
|
Tenseur_ns3BB
|
|
|
|
( const double val1, const double val2, const double val3, // 1ere ligne
|
|
|
|
const double val4, const double val5, const double val6, // 2ieme ligne
|
|
|
|
const double val7, const double val8, const double val9) ; // 3ieme ligne
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur_ns3BB ( const TenseurBB &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur_ns3BB ( const Tenseur_ns3BB &);
|
|
|
|
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur_ns3BB();
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurBB & operator + ( const TenseurBB &) const ;
|
|
|
|
void operator += ( const TenseurBB &);
|
|
|
|
TenseurBB & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurBB & operator - ( const TenseurBB &) const ;
|
|
|
|
void operator -= ( const TenseurBB &);
|
|
|
|
TenseurBB & operator = ( const TenseurBB &);
|
|
|
|
TenseurBB & operator = ( const Tenseur3BB & B)
|
|
|
|
{ return this->operator=((TenseurBB &) B); };
|
|
|
|
TenseurBB & operator = ( const Tenseur_ns3BB & B)
|
|
|
|
{ return this->operator=((TenseurBB &) B); };
|
|
|
|
TenseurBB & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurBB & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur_ns2BB & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurBB & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte avec un vecteur
|
|
|
|
CoordonneeB operator * ( const CoordonneeH & ) const ;
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
TenseurBB & operator * ( const TenseurHB &) const ;
|
|
|
|
TenseurBH & operator * ( const TenseurHH &) const ;
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
double operator && ( const TenseurHH &) const ;
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurBB &) const ;
|
|
|
|
int operator != ( const TenseurBB &) const ;
|
|
|
|
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurHH & Inverse() const ;
|
|
|
|
|
|
|
|
// ATTENTION creation d'un tenseur transpose qui est supprime par Libere
|
|
|
|
TenseurBB & Transpose() const ;
|
|
|
|
|
|
|
|
// ---- manipulation d'indice ---- -> création de nouveaux tenseurs
|
|
|
|
virtual TenseurHH& Monte2Indices() const ;
|
|
|
|
virtual TenseurHB& MontePremierIndice() const ;
|
|
|
|
virtual TenseurBH& MonteDernierIndice() const ;
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur_ns3BB::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur_ns3BB::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur_ns3BB::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
listdouble9Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
class Tenseur2BH;
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes mixtes BH
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
class Tenseur3BH : public TenseurBH
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur3BH &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur3BH &);
|
|
|
|
friend class Tenseur2BH; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
public :
|
|
|
|
// constructeur
|
|
|
|
Tenseur3BH() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur3BH ( const double val) ;
|
|
|
|
// initialisation avec 9 valeurs différentes correspodantes aux trois
|
|
|
|
// lignes : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
// car le tableau n'est pas symetrique !!!!
|
|
|
|
// le premier indice = ligne, le second = colonne
|
|
|
|
Tenseur3BH
|
|
|
|
( const double val1, const double val2, const double val3, // 1ere ligne
|
|
|
|
const double val4, const double val5, const double val6, // 2ieme ligne
|
|
|
|
const double val7, const double val8, const double val9) ; // 3ieme ligne
|
|
|
|
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur3BH();
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur3BH ( const TenseurBH &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur3BH ( const Tenseur3BH &);
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurBH & operator + ( const TenseurBH &) const ;
|
|
|
|
void operator += ( const TenseurBH &);
|
|
|
|
TenseurBH & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurBH & operator - ( const TenseurBH &) const ;
|
|
|
|
void operator -= ( const TenseurBH &);
|
|
|
|
TenseurBH & operator = ( const TenseurBH &);
|
|
|
|
TenseurBH & operator = ( const Tenseur3BH & B)
|
|
|
|
{ return this->operator=((TenseurBH &) B); };
|
|
|
|
TenseurBH & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurBH & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur2BH & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurBH & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
CoordonneeB operator * ( const CoordonneeB & ) const ;
|
|
|
|
TenseurBB & operator * ( const TenseurBB &) const ; // produit une fois contracte
|
|
|
|
TenseurBH & operator * ( const TenseurBH &) const ; // produit une fois contracte
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B c-c-d : A_i^{.k} * B_k^{.i}
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
// cela permet d'utiliser les mêmes variances pour les deux tenseurs
|
|
|
|
|
|
|
|
double operator && ( const TenseurBH &) const ; // produit deux fois contracte
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurBH &) const ;
|
|
|
|
int operator != ( const TenseurBH &) const ;
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurBH & Inverse() const ;
|
|
|
|
|
|
|
|
double Trace() const ; // trace du tenseur ou premier invariant
|
|
|
|
double II() const ; // second invariant = trace (A*A)
|
|
|
|
double III() const ; // troisieme invariant = trace ((A*A)*A)
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// valeurs propre dans le vecteur de retour, classée par ordres "décroissants"
|
|
|
|
// cas indique le cas de valeur propre:
|
|
|
|
// cas = -1, si l'extraction des valeurs propres n'a pas pu se faire
|
|
|
|
// dans ce cas les valeurs propres de retour sont nulles par défaut
|
|
|
|
// dim = 3 , cas = 1 si 3 val propres différentes, cas = 0 si les 3 sont identiques,
|
|
|
|
// cas = 2 si val(1)=val(2), cas = 3 si val(2)=val(3)
|
|
|
|
virtual Coordonnee ValPropre(int& cas) const ;
|
|
|
|
// idem met en retour la matrice mat contiend par colonne les vecteurs propre
|
|
|
|
// elle doit avoir la dimension du tenseur
|
|
|
|
// les vecteurs propre sont exprime dans le repere dual (contrairement au HB)
|
|
|
|
virtual Coordonnee ValPropre(int& cas, Mat_pleine& mat) const ;
|
|
|
|
|
|
|
|
// ici il s'agit uniquement de calculer les vecteurs propres, les valeurs propres
|
|
|
|
// étant déjà connues
|
|
|
|
// en retour VP les vecteurs propre: doivent avoir la dimension du tenseur
|
|
|
|
// les vecteurs propre sont exprime dans le repere naturel (pour les tenseurs dim 3
|
|
|
|
// pour dim=2:le premier vecteur propre est exprime dans le repere naturel
|
|
|
|
// le second vecteur propre est exprimé dans le repère dual
|
|
|
|
// pour dim=1 le vecteur est dans la base naturelle (mais ça importe pas)
|
|
|
|
// en sortie cas = -1 s'il y a eu un problème, dans ce cas, V_P est quelconque
|
|
|
|
// sinon si tout est ok, cas est identique en sortie avec l'entrée
|
|
|
|
virtual void VecteursPropres(const Coordonnee& Val_P,int& cas, Tableau <Coordonnee>& V_P) const;
|
|
|
|
|
|
|
|
// tenseur transpose
|
|
|
|
TenseurHB & Transpose() const ;
|
|
|
|
// permute Bas Haut, mais reste dans le même tenseur
|
|
|
|
void PermuteHautBas();
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
|
|
static TenseurBH & Prod_tensoriel(const CoordonneeB & aB, const CoordonneeH & bH);
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur3BH::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur3BH::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur3BH::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
listdouble9Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
class Tenseur2HB;
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_tenseurs_dim3_ordre2
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Definition des tenseur derivees de dimension 3.
|
|
|
|
/// cas des composantes mixtes HB
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// \author Gérard Rio
|
|
|
|
/// \version 1.0
|
|
|
|
/// \date 23/01/97
|
|
|
|
class Tenseur3HB : public TenseurHB
|
|
|
|
{
|
|
|
|
// surcharge de l'operator de lecture
|
|
|
|
friend istream & operator >> (istream &, Tenseur3HB &);
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
|
|
friend ostream & operator << (ostream &, const Tenseur3HB &);
|
|
|
|
friend class Tenseur2HB; // pour le passage 2D 3D: méthode Affectation_2D_a_3D(..
|
|
|
|
public :
|
|
|
|
// Constructeur
|
|
|
|
Tenseur3HB() ; // par défaut
|
|
|
|
// initialisation de toutes les composantes a une meme valeur val
|
|
|
|
Tenseur3HB ( const double val) ;
|
|
|
|
// initialisation avec 9 valeurs différentes correspodantes aux trois
|
|
|
|
// lignes : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
// car le tableau n'est pas symetrique !!!!
|
|
|
|
// le premier indice = ligne, le second = colonne
|
|
|
|
Tenseur3HB
|
|
|
|
( const double val1, const double val2, const double val3, // 1ere ligne
|
|
|
|
const double val4, const double val5, const double val6, // 2ieme ligne
|
|
|
|
const double val7, const double val8, const double val9) ; // 3ieme ligne
|
|
|
|
// constructeur a partir d'une instance non differenciee
|
|
|
|
Tenseur3HB ( const TenseurHB &);
|
|
|
|
// constructeur de copie
|
|
|
|
Tenseur3HB ( const Tenseur3HB &);
|
|
|
|
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
~Tenseur3HB();
|
|
|
|
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// initialise toutes les composantes à val
|
|
|
|
void Inita(double val);
|
|
|
|
// operations
|
|
|
|
TenseurHB & operator + ( const TenseurHB &) const ;
|
|
|
|
void operator += ( const TenseurHB &);
|
|
|
|
TenseurHB & operator - () const ; // oppose du tenseur
|
|
|
|
TenseurHB & operator - ( const TenseurHB &) const ;
|
|
|
|
void operator -= ( const TenseurHB &);
|
|
|
|
TenseurHB & operator = ( const TenseurHB &);
|
|
|
|
TenseurHB & operator = ( const Tenseur3HB & B)
|
|
|
|
{ return this->operator=((TenseurHB &) B); };
|
|
|
|
TenseurHB & operator * ( const double &) const ;
|
|
|
|
void operator *= ( const double &);
|
|
|
|
TenseurHB & operator / ( const double &) const ;
|
|
|
|
void operator /= ( const double &);
|
|
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
|
|
void Affectation_2D_a_3D(const Tenseur2HB & B,bool plusZero);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void Affectation_trans_dimension(const TenseurHB & B,bool plusZero);
|
|
|
|
|
|
|
|
// produit contracte avec un vecteur
|
|
|
|
CoordonneeH operator * ( const CoordonneeH & ) const ;
|
|
|
|
|
|
|
|
// produit contracte contracté une fois A(i,j)*B(j,k)=A.B
|
|
|
|
// -> donc c'est l'indice du milieu qui est contracté
|
|
|
|
TenseurHH & operator * ( const TenseurHH &) const ;
|
|
|
|
TenseurHB & operator * ( const TenseurHB &) const ; // produit une fois contracte
|
|
|
|
// produit contracte contracté deux fois A(i,j)*B(j,i)=A..B c-c-d : A^i_{.k} * B^k_{.i}
|
|
|
|
// -> on contracte d'abord l'indice du milieu puis l'indice externe
|
|
|
|
// cela permet d'utiliser les mêmes variances pour les deux tenseurs
|
|
|
|
double operator && ( const TenseurHB &) const ; // produit deux fois contracte
|
|
|
|
|
|
|
|
// test
|
|
|
|
int operator == ( const TenseurHB &) const ;
|
|
|
|
int operator != ( const TenseurHB &) const ;
|
|
|
|
|
|
|
|
// calcul du tenseur inverse par rapport au produit contracte
|
|
|
|
TenseurHB & Inverse() const ;
|
|
|
|
|
|
|
|
double Trace() const ; // trace du tenseur ou premier invariant
|
|
|
|
double II() const ; // second invariant = trace (A*A)
|
|
|
|
double III() const ; // troisieme invariant = trace ((A*A)*A)
|
|
|
|
double Det() const ; // determinant de la matrice des coordonnees
|
|
|
|
|
|
|
|
// valeurs propre dans le vecteur de retour, classée par ordres "décroissants"
|
|
|
|
// cas indique le cas de valeur propre:
|
|
|
|
// cas = -1, si l'extraction des valeurs propres n'a pas pu se faire
|
|
|
|
// dans ce cas les valeurs propres de retour sont nulles par défaut
|
|
|
|
// dim = 3 , cas = 1 si 3 val propres différentes, cas = 0 si les 3 sont identiques,
|
|
|
|
// cas = 2 si val(1)=val(2), cas = 3 si val(2)=val(3)
|
|
|
|
virtual Coordonnee ValPropre(int& cas) const ;
|
|
|
|
// idem met en retour la matrice mat contiend par colonne les vecteurs propre
|
|
|
|
// elle doit avoir la dimension du tenseur
|
|
|
|
// les vecteurs propre sont exprime dans le repere naturel
|
|
|
|
virtual Coordonnee ValPropre(int& cas, Mat_pleine& mat) const ;
|
|
|
|
|
|
|
|
// ici il s'agit uniquement de calculer les vecteurs propres, les valeurs propres
|
|
|
|
// étant déjà connues
|
|
|
|
// en retour VP les vecteurs propre: doivent avoir la dimension du tenseur
|
|
|
|
// les vecteurs propre sont exprime dans le repere naturel (pour les tenseurs dim 3
|
|
|
|
// pour dim=2:le premier vecteur propre est exprime dans le repere naturel
|
|
|
|
// le second vecteur propre est exprimé dans le repère dual
|
|
|
|
// pour dim=1 le vecteur est dans la base naturelle (mais ça importe pas)
|
|
|
|
// en sortie cas = -1 s'il y a eu un problème, dans ce cas, V_P est quelconque
|
|
|
|
// sinon si tout est ok, cas est identique en sortie avec l'entrée
|
|
|
|
virtual void VecteursPropres(const Coordonnee& Val_P,int& cas, Tableau <Coordonnee>& V_P) const;
|
|
|
|
|
|
|
|
// tenseur transpose
|
|
|
|
TenseurBH & Transpose() const ;
|
|
|
|
// permute Bas Haut, mais reste dans le même tenseur
|
|
|
|
void PermuteHautBas();
|
|
|
|
|
|
|
|
// calcul du maximum en valeur absolu des composantes du tenseur
|
|
|
|
double MaxiComposante() const;
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture et écriture
|
|
|
|
double& Coor( const int i, const int j);
|
|
|
|
|
|
|
|
// retourne la composante i,j en lecture seulement
|
|
|
|
double operator () ( const int i, const int j) const ;
|
|
|
|
|
|
|
|
// inline operator TenseurHB & (void)
|
|
|
|
// { return *this;};
|
|
|
|
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
|
|
static TenseurHB & Prod_tensoriel(const CoordonneeH & aH, const CoordonneeB & bB);
|
|
|
|
|
|
|
|
// lecture et écriture de données
|
|
|
|
istream & Lecture(istream & entree);
|
|
|
|
ostream & Ecriture(ostream & sort) const ;
|
|
|
|
|
|
|
|
// transformation 2 indices -> 1 indice (c-a-d vecteur unicolonne)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int OdVect(const int i, const int j) {return Tenseur3HB::cdex.odVect(i,j);};
|
|
|
|
// transformation 1 indice -> 2 indices
|
|
|
|
// en retour 2 indices : (k)(1) et (k)(2) -> les indices (i,j)
|
|
|
|
// dans l'ordre : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3)
|
|
|
|
static int idx_i(const int k) {return Tenseur3HB::cdex.idx_i(k);};
|
|
|
|
static int idx_j(const int k) {return Tenseur3HB::cdex.idx_j(k);};
|
|
|
|
|
|
|
|
protected :
|
|
|
|
// allocator dans la liste de data
|
|
|
|
listdouble9Iter ipointe;
|
|
|
|
// --- gestion d'index ----
|
|
|
|
class ChangementIndex
|
|
|
|
{ public:
|
|
|
|
ChangementIndex();
|
|
|
|
// passage pour les index de la forme vecteur à la forme i,j
|
|
|
|
Tableau <int> idx_i,idx_j;
|
|
|
|
// passage pour les index de la forme i,j à la forme vecteur
|
|
|
|
Tableau2 <int> odVect;
|
|
|
|
};
|
|
|
|
static const ChangementIndex cdex;
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
#include "Tenseur2.h"
|
|
|
|
|
|
|
|
#ifndef MISE_AU_POINT
|
|
|
|
#include "Tenseur3-1.cc"
|
|
|
|
#include "Tenseur3-2.cc"
|
|
|
|
#include "Tenseur3_ns.cc"
|
|
|
|
#define Tenseur3_H_deja_inclus
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|