// 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) . // // 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 . // // For more information, please consult: . /************************************************************************ * 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: 8/6/2003 * * $ * * 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 dimension 3 . Il s'agit ici de classes * * très particulières. Les tenseurs possèdes les trois * * symétrie: (ijkl) = (jikl) = (ijlk) = (klij) * * Ainsi en composantes 4 fois covariantes ou 4 fois * * contravariantes, en 3D il y a 21 composantes indépendantes.* * La classe est plutôt à considérer comme un conteneur, * * ainsi seules les méthodes principales sont utilisables. * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * * VERIFICATION: * * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * ! ! ! ! * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * MODIFICATIONS: * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * $ * ************************************************************************/ #ifndef TENSEURQ3_TROIS_SYM_H #define TENSEURQ3_TROIS_SYM_H #include #include "TenseurQ.h" #include "PtTabRel.h" # include "Tableau2_T.h" # include "Tableau4_T.h" #include "Tenseur.h" //------------------------------------------------------------------ // cas des composantes 4 fois contravariantes HHHH //------------------------------------------------------------------ class TenseurQ3_troisSym_HHHH : public TenseurHHHH { // surcharge de l'operator de lecture friend istream & operator >> (istream &, TenseurQ3_troisSym_HHHH &); // surcharge de l'operator d'ecriture friend ostream & operator << (ostream &, const TenseurQ3_troisSym_HHHH &); public : // Constructeur TenseurQ3_troisSym_HHHH() ; // par défaut // initialisation de toutes les composantes a une meme valeur val TenseurQ3_troisSym_HHHH(const double& val); // initialisation à partir des 21 coefficients indépendants // (1111) (2222) (3333) (1122) (1133) (2233) // (1211) (1222) (1233) (1311) (1322) (1333) (2311) (2322) (2333) // (1212) (1313) (2323) (1213) (1223) (1323) TenseurQ3_troisSym_HHHH ( const double& x1111,const double& x2222,const double& x3333,const double& x1122,const double& x1133,const double& x2233 ,const double& x1211,const double& x1222,const double& x1233,const double& x1311,const double& x1322,const double& x1333 ,const double& x2311,const double& x2322,const double& x2333 ,const double& x1212,const double& x1313,const double& x2323,const double& x1213,const double& x1223,const double& x1323); // DESTRUCTEUR : ~TenseurQ3_troisSym_HHHH() ; // constructeur a partir d'une instance non differenciee // il n'y a pas de vérification des symétries seules les grandeurs suivantes sont utilisés: // (1111) (2222) (3333) (1122) (1133) (2233) // (1211) (1222) (1233) (1311) (1322) (1333) (2311) (2322) (2333) // (1212) (1313) (2323) (1213) (1223) (1323) TenseurQ3_troisSym_HHHH (const TenseurHHHH &); // constructeur de copie TenseurQ3_troisSym_HHHH (const TenseurQ3_troisSym_HHHH &); // METHODES PUBLIQUES : //2) virtuelles // initialise toutes les composantes à val void Inita(double val) ; // operations TenseurHHHH & operator + ( const TenseurHHHH &) const ; void operator += ( const TenseurHHHH &); TenseurHHHH & operator - () const ; // oppose du tenseur TenseurHHHH & operator - ( const TenseurHHHH &) const ; void operator -= ( const TenseurHHHH &); TenseurHHHH & operator = ( const TenseurHHHH &); TenseurHHHH & operator * (const double &) const ; void operator *= ( const double &); TenseurHHHH & operator / ( const double &) const ; void operator /= ( const double &); // produit deux fois contracte à droite avec un tenseur du second ordre // différent à gauche !! def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche TenseurHH& operator && ( const TenseurBB & ) const ; // produit deux fois contracte à droite avec un tenseur du quatrième ordre // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurHHHH& operator && ( const TenseurBBHH & ) const { cout << "\n non implante !! , TenseurHHHH& TenseurQ3_troisSym_HHHH::operator && ( const TenseurBBHH & ) const "; Sortie(1); TenseurHHHH* toto; return *toto; /* toto pour eviter un warning*/ }; TenseurHHBB& operator && ( const TenseurBBBB & ) const { cout << "\n non implante !! , TenseurHHBB& TenseurQ3_troisSym_HHHH::operator && ( const TenseurBBBB & ) const "; Sortie(1); TenseurHHBB* toto; return *toto; /* toto pour eviter un warning*/ }; // 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 TenseurHHHH & 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 void Affectation_trans_dimension(const TenseurHHHH & B,bool plusZero); // test int operator == ( const TenseurHHHH &) 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 listdouble21Iter ipointe; // --- gestion d'index ---- class ChangementIndex { public: ChangementIndex(); // passage pour les index de la forme i,j,k,l à la forme vecteur Tableau4 odVect; }; static const ChangementIndex cdex; // fonction pour le produit contracté à gauche TenseurHH& Prod_gauche( const TenseurBB & F) const { return ((*this) && F); }; // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurBBHH& Prod_gauche( const TenseurBBBB & ) const { cout << "\n non implante !! , TenseurBBHH& TenseurQ3_troisSym_HHHH::Prod_gauche( const TenseurBBBB & ) const "; Sortie(1); TenseurBBHH* toto; return *toto; /* toto pour eviter un warning*/ }; // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurHHHH& Prod_gauche( const TenseurHHBB & ) const { cout << "\n non implante !! , TenseurHHHH& TenseurQ3_troisSym_HHHH::Prod_gauche( const TenseurHHBB & ) const "; Sortie(1); TenseurHHHH* toto; return *toto; /* toto pour eviter un warning*/ }; }; // //------------------------------------------------------------------ // cas des composantes 4 fois covariantes BBBB //------------------------------------------------------------------ class TenseurQ3_troisSym_BBBB : public TenseurBBBB { // surcharge de l'operator de lecture friend istream & operator >> (istream &, TenseurQ3_troisSym_BBBB &); // surcharge de l'operator d'ecriture friend ostream & operator << (ostream &, const TenseurQ3_troisSym_BBBB &); public : // Constructeur TenseurQ3_troisSym_BBBB() ; // par défaut // initialisation de toutes les composantes a une meme valeur val TenseurQ3_troisSym_BBBB(const double& val); // initialisation à partir des 21 coefficients indépendants // (1111) (2222) (3333) (1122) (1133) (2233) // (1211) (1222) (1233) (1311) (1322) (1333) (2311) (2322) (2333) // (1212) (1313) (2323) (1213) (1223) (1323) TenseurQ3_troisSym_BBBB ( const double& x1111,const double& x2222,const double& x3333,const double& x1122,const double& x1133,const double& x2233 ,const double& x1211,const double& x1222,const double& x1233,const double& x1311,const double& x1322,const double& x1333 ,const double& x2311,const double& x2322,const double& x2333 ,const double& x1212,const double& x1313,const double& x2323,const double& x1213,const double& x1223,const double& x1323); // DESTRUCTEUR : ~TenseurQ3_troisSym_BBBB() ; // constructeur a partir d'une instance non differenciee // il n'y a pas de vérification des symétries seules les grandeurs // (1111) (2222) (3333) (1122) (1133) (2233) // (1211) (1222) (1233) (1311) (1322) (1333) (2311) (2322) (2333) // (1212) (1313) (2323) (1213) (1223) (1323) TenseurQ3_troisSym_BBBB (const TenseurBBBB &); // constructeur de copie TenseurQ3_troisSym_BBBB (const TenseurQ3_troisSym_BBBB &); // METHODES PUBLIQUES : //2) virtuelles // initialise toutes les composantes à val void Inita(double val) ; // operations TenseurBBBB & operator + ( const TenseurBBBB &) const ; void operator += ( const TenseurBBBB &); TenseurBBBB & operator - () const ; // oppose du tenseur TenseurBBBB & operator - ( const TenseurBBBB &) const ; void operator -= ( const TenseurBBBB &); TenseurBBBB & operator = ( const TenseurBBBB &); TenseurBBBB & operator * (const double &) const ; void operator *= ( const double &); TenseurBBBB & operator / ( const double &) const ; void operator /= ( const double &); // produit deux fois contracte à droite avec un tenseur du second ordre // différent à gauche !! def dans TenseurQ.h à l'aide de la fonction privée Prod_gauche TenseurBB& operator && ( const TenseurHH & ) const ; // produit deux fois contracte à droite avec un tenseur du quatrième ordre // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurBBHH& operator && ( const TenseurHHHH & ) const { cout << "\n non implante !! , TenseurBBHH& TenseurQ3_troisSym_BBBB::operator && ( const TenseurHHHH & ) const "; Sortie(1); TenseurBBHH* toto; return *toto; /* toto pour eviter un warning*/ }; TenseurBBBB& operator && ( const TenseurHHBB & ) const { cout << "\n non implante !! , TenseurBBBB& TenseurQ3_troisSym_BBBB::operator && ( const TenseurHHBB & ) const "; Sortie(1); TenseurBBBB* toto; return *toto; /* toto pour eviter un warning*/ }; // 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 TenseurBBBB & 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 void Affectation_trans_dimension(const TenseurBBBB & B,bool plusZero); // test int operator == ( const TenseurBBBB &) 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 listdouble21Iter ipointe; // --- gestion d'index ---- class ChangementIndex { public: ChangementIndex(); // passage pour les index de la forme i,j,k,l à la forme vecteur Tableau4 odVect; }; static const ChangementIndex cdex; // fonction pour le produit contracté à gauche TenseurBB& Prod_gauche( const TenseurHH & F) const { return ((*this) && F); }; // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurHHBB& Prod_gauche( const TenseurHHHH & ) const { cout << "\n non implante !! , TenseurHHBB& TenseurQ3_troisSym_BBBB::Prod_gauche( const TenseurHHHH & ) const "; Sortie(1); TenseurHHBB* toto; return *toto; /* toto pour eviter un warning*/ }; // a priori pas intéressant pour cette classe de tenseur car cela donne un tenseur qui n'a plus de symétrie TenseurBBBB& Prod_gauche( const TenseurBBHH & ) const { cout << "\n non implante !! , TenseurBBBB& TenseurQ3_troisSym_BBBB::Prod_gauche( const TenseurBBHH & ) const "; Sortie(1); TenseurBBBB* toto; return *toto; /* toto pour eviter un warning*/ }; }; #ifndef MISE_AU_POINT #include "Tenseur3_TroisSym.cc" #define TenseurQ3_TroisSym_H_deja_inclus #endif #endif