2021-09-23 11:21:15 +02:00
// FICHIER : Loi_ortho2D_C_entrainee.cc
// CLASSE : Loi_ortho2D_C_entrainee
// 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-23 11:21:15 +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/>.
//#include "Debug.h"
# include <iostream>
using namespace std ; //introduces namespace std
# include <math.h>
# include <stdlib.h>
# include "Sortie.h"
# include "TypeConsTens.h"
# include "ConstMath.h"
# include "Loi_ortho2D_C_entrainee.h"
# include "NevezTenseur.h"
# include "MathUtil.h"
# include "Util.h"
# include "Enum_TypeQuelconque.h"
# include "TypeQuelconqueParticulier.h"
# include "TenseurQ2gene.h"
# include "MathUtil.h"
# include "MathUtil2.h"
# include "CharUtil.h"
# include "Coordonnee2.h"
// ========== fonctions pour la classe de sauvegarde des résultats =========
// constructeur par défaut
Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee ( const int type_transport ) :
O_B ( NULL ) , O_H ( NULL ) , Op_H ( 2 , 2 ) , Op_H_t ( 2 , 2 ) , eps_loc_HH ( NULL ) , sig_loc_HH ( NULL )
, para_loi ( NULL )
{
} ;
// constructeur de copie
Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee ( const SaveResulLoi_ortho2D_C_entrainee & sav ) :
O_B ( NULL ) , O_H ( NULL ) , Op_H ( 2 , 2 ) , Op_H_t ( 2 , 2 ) , eps_loc_HH ( NULL ) , sig_loc_HH ( NULL )
, para_loi ( NULL )
{
// partie repère d'orthotropie
if ( sav . O_B ! = NULL )
O_B = new BaseB ( * sav . O_B ) ;
if ( sav . O_H ! = NULL )
O_H = new BaseH ( * sav . O_H ) ;
if ( sav . eps_loc_HH ! = NULL )
eps_loc_HH = NevezTenseurHH ( * sav . eps_loc_HH ) ;
if ( sav . sig_loc_HH ! = NULL )
sig_loc_HH = NevezTenseurHH ( * sav . sig_loc_HH ) ;
if ( sav . para_loi ! = NULL )
para_loi = new Vecteur ( * sav . para_loi ) ;
} ;
// destructeur
Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : ~ SaveResulLoi_ortho2D_C_entrainee ( )
{
// partie repère d'orthotropie
if ( O_B ! = NULL )
delete O_B ;
if ( O_H ! = NULL )
delete O_H ;
if ( eps_loc_HH ! = NULL )
delete eps_loc_HH ;
if ( sig_loc_HH ! = NULL )
delete sig_loc_HH ;
if ( para_loi ! = NULL )
delete para_loi ;
} ;
// affectation
Loi_comp_abstraite : : SaveResul & Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : operator = ( const Loi_comp_abstraite : : SaveResul & a )
{ Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee & sav = * ( ( Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee * ) & a ) ;
eps33 = sav . eps33 ; eps33_t = sav . eps33_t ;
// partie repère d'orthotropie
if ( sav . O_B ! = NULL )
{ if ( O_B = = NULL ) { O_B = new BaseB ( * sav . O_B ) ; }
else { * O_B = * sav . O_B ; } ;
}
else // sinon cas NULL
{ if ( O_B ! = NULL ) { delete O_B ; O_B = NULL ; } } ;
if ( sav . O_H ! = NULL )
{ if ( O_H = = NULL ) { O_H = new BaseH ( * sav . O_H ) ; }
else { * O_H = * sav . O_H ; } ;
}
else // sinon cas NULL
{ if ( O_H ! = NULL ) { delete O_H ; O_H = NULL ; } } ;
if ( sav . eps_loc_HH ! = NULL )
{ if ( eps_loc_HH = = NULL ) { eps_loc_HH = NevezTenseurHH ( * sav . eps_loc_HH ) ; }
else { * eps_loc_HH = * sav . eps_loc_HH ; } ;
}
else // sinon cas NULL
{ if ( eps_loc_HH ! = NULL ) { delete eps_loc_HH ; eps_loc_HH = NULL ; } } ;
if ( sav . sig_loc_HH ! = NULL )
{ if ( sig_loc_HH = = NULL ) { sig_loc_HH = NevezTenseurHH ( * sav . sig_loc_HH ) ; }
else { * sig_loc_HH = * sav . sig_loc_HH ; } ;
}
else // sinon cas NULL
{ if ( sig_loc_HH ! = NULL ) { delete sig_loc_HH ; sig_loc_HH = NULL ; } ;
} ;
if ( sav . para_loi ! = NULL )
{ if ( para_loi = = NULL ) para_loi = new Vecteur ( * sav . para_loi ) ;
else { * para_loi = * sav . para_loi ; } ;
}
else // sinon cas NULL
{ if ( para_loi ! = NULL ) { delete para_loi ; para_loi = NULL ; } } ;
// et la base
Op_H = sav . Op_H ;
Op_H_t = sav . Op_H_t ;
return * this ;
} ;
//------- 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)
2024-06-20 15:42:40 +02:00
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : Lecture_base_info ( istream & ent , const int cas )
2021-09-23 11:21:15 +02:00
{ string nom ;
ent > > nom ;
# ifdef MISE_AU_POINT
if ( nom ! = " S_Ortho_2D_C " )
{ cout < < " \n Erreur : on attendait le mot cle: S_Ortho_2D_C "
< < " et on a lue " < < nom ;
cout < < " Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Lecture_base_info \n " ;
Sortie ( 1 ) ;
} ;
# endif
// on lit que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail
switch ( cas )
{ case 1 :
{
// la base initiale
if ( O_B ! = NULL )
{ ent > > nom > > * O_B ; }
else if ( O_H ! = NULL )
{ ent > > nom > > * O_H ; }
// la base convectée
ent > > nom > > Op_H_t ;
Op_H = Op_H_t ;
// les stockages conditionnels
int test ;
ent > > nom > > test ;
if ( test = = 0 )
{ if ( eps_loc_HH ! = NULL )
{ delete eps_loc_HH ; eps_loc_HH = NULL ; }
if ( sig_loc_HH ! = NULL )
{ delete sig_loc_HH ; sig_loc_HH = NULL ; }
if ( para_loi ! = NULL )
{ delete para_loi ; para_loi = NULL ; }
}
else // sinon cas où on a des données additionnelles
{ if ( eps_loc_HH = = NULL ) eps_loc_HH = NevezTenseurHH ( 2 ) ;
ent > > nom ; eps_loc_HH - > Lecture ( ent ) ;
if ( sig_loc_HH = = NULL ) sig_loc_HH = NevezTenseurHH ( 2 ) ;
ent > > nom ; sig_loc_HH - > Lecture ( ent ) ;
if ( para_loi = = NULL ) para_loi = new Vecteur ( 7 ) ;
ent > > * para_loi ;
} ;
break ;
}
case 2 :
{
// la base convectée
ent > > nom > > Op_H_t ;
// les stockages conditionnels
int test ;
ent > > nom > > test ;
if ( test = = 0 )
{ if ( eps_loc_HH ! = NULL )
{ delete eps_loc_HH ; eps_loc_HH = NULL ; }
if ( sig_loc_HH ! = NULL )
{ delete sig_loc_HH ; sig_loc_HH = NULL ; }
if ( para_loi ! = NULL )
{ delete para_loi ; para_loi = NULL ; }
}
else // sinon cas où on a des données additionnelles
{ if ( eps_loc_HH = = NULL ) eps_loc_HH = NevezTenseurHH ( 2 ) ;
ent > > nom ; eps_loc_HH - > Lecture ( ent ) ;
if ( sig_loc_HH = = NULL ) sig_loc_HH = NevezTenseurHH ( 2 ) ;
ent > > nom ; sig_loc_HH - > Lecture ( ent ) ;
if ( para_loi = = NULL ) para_loi = new Vecteur ( 7 ) ;
ent > > nom > > * para_loi ;
} ;
break ;
}
default :
cout < < " \n cas non considere !!: cas= " < < cas
< < " \n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(... " ;
Sortie ( 1 ) ;
} ;
} ;
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables
//(supposées comme telles)
2024-06-20 15:42:40 +02:00
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : Ecriture_base_info ( ostream & sort , const int cas )
2021-09-23 11:21:15 +02:00
{ sort < < " \n S_Ortho_2D_C " ;
// on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail
switch ( cas )
{ case 1 :
{
// la base initiale
if ( O_B ! = NULL )
{ sort < < " O_B: " < < * O_B ; }
else if ( O_H ! = NULL )
{ sort < < " O_H: " < < * O_H ; }
// la base convectée
sort < < " Op_H_t: " < < Op_H_t < < " " ;
// les stockages conditionnels
if ( eps_loc_HH ! = NULL )
{ sort < < " addi: 1 " < < " \n eps_loc_HH: " ;
eps_loc_HH - > Ecriture ( sort ) ;
sort < < " \n sig_loc_HH: " ;
sig_loc_HH - > Ecriture ( sort ) ;
sort < < " \n para_loi: " < < * para_loi < < " " ;
}
else
{ sort < < " addi: 0 " ; } ;
break ;
}
case 2 :
{
// la base convectée
sort < < " Op_H_t: " < < Op_H_t < < " " ;
// les stockages conditionnels
if ( eps_loc_HH ! = NULL )
{ sort < < " \n addi: 1 " < < " \n eps_loc_HH: " ;
eps_loc_HH - > Ecriture ( sort ) ;
sort < < " \n sig_loc_HH: " ;
sig_loc_HH - > Ecriture ( sort ) ;
sort < < " \n para_loi: " < < * para_loi < < " " ;
}
else
{ sort < < " \n addi: 0 " ; } ;
break ;
}
default :
cout < < " \n cas non considere !!: cas= " < < cas
< < " \n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(... " ;
Sortie ( 1 ) ;
} ;
} ;
// mise à jour des informations transitoires
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : TdtversT ( )
{ Op_H_t = Op_H ;
eps33_t = eps33 ;
} ;
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : TversTdt ( )
{ Op_H = Op_H_t ;
eps33 = eps33_t ;
} ;
// affichage à l'écran des infos
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : Affiche ( ) const
{ cout < < " \n SaveResulLoi_ortho2D_C_entrainee: " ;
if ( O_B ! = NULL )
{ cout < < " \n O_B= " ; O_B - > Affiche ( ) ;
} ;
if ( O_H ! = NULL )
{ cout < < " \n O_H= " ; O_H - > Affiche ( ) ;
} ;
cout < < " \n Op_H= " ; Op_H . Affiche ( ) ;
// les tenseurs intermédiaires
if ( eps_loc_HH ! = NULL )
{ cout < < " \n eps_loc_HH= " ; eps_loc_HH - > Ecriture ( cout ) ;
} ;
if ( sig_loc_HH ! = NULL )
{ cout < < " \n sig_loc_HH= " ; sig_loc_HH - > Ecriture ( cout ) ;
} ;
// paramètre variables éventuelles de la loi
if ( para_loi ! = NULL )
{ cout < < " \n para_loi: " ;
for ( int i = 1 ; i < 8 ; i + + )
cout < < " coef( " < < i < < " )= " < < ( * para_loi ) ( i ) ;
cout < < " " ;
} ;
cout < < " \n .. fin SaveResulLoi_ortho2D_C_entrainee ... " ;
} ;
//changement de base de toutes les grandeurs internes tensorielles stockées
// b(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB
// gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
// gpH(i) = gamma(i,j) * gH(j)
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : ChBase_des_grandeurs ( const Mat_pleine & beta , const Mat_pleine & gamma )
{ // on ne s'intéresse qu'aux grandeurs tensorielles
// il faut que l'on exprime le repère d'orthotropie dans le nouveau repère
// !!! on travaille ici en 2D -> dans un plan
# ifdef MISE_AU_POINT
if ( ( beta . Nb_colonne ( ) ! = 2 ) | | ( beta . Nb_ligne ( ) ! = 2 ) )
{ cout < < " \n Erreur : la dimension devrait etre 2 pour la matrice de changement de base = beta! "
< < " alors n_colonne= " < < beta . Nb_colonne ( ) < < " et nb_ligne= " < < beta . Nb_ligne ( )
< < " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... " ;
Sortie ( 1 ) ;
} ;
if ( ( gamma . Nb_colonne ( ) ! = 2 ) | | ( gamma . Nb_ligne ( ) ! = 2 ) )
{ cout < < " \n Erreur : la dimension devrait etre 2 pour la matrice de changement de base = gamma! "
< < " alors n_colonne= " < < gamma . Nb_colonne ( ) < < " et nb_ligne= " < < gamma . Nb_ligne ( )
< < " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... " ;
Sortie ( 1 ) ;
} ;
# endif
if ( O_B ! = NULL )
{ for ( int i = 1 ; i < 3 ; i + + )
{ CoordonneeB Ap_B ( 2 ) ; // inter
MathUtil2 : : ChBase ( O_B - > CoordoB ( i ) , beta , Ap_B ) ;
O_B - > CoordoB ( i ) = Ap_B ;
}
} ;
if ( O_H ! = NULL )
{ for ( int i = 1 ; i < 3 ; i + + )
{ CoordonneeH Ap_H ( 2 ) ; // inter
MathUtil2 : : ChBase ( O_H - > CoordoH ( i ) , gamma , Ap_H ) ;
O_H - > CoordoH ( i ) = Ap_H ;
}
} ;
// les autres grandeurs sont issues du calcul
// normalement elles sont calculées en même temps que les contraintes
// mais on les change de repère néanmoins, au cas on on ferait une sortie
// d'info sans calcul (c'est pénalisant pour le cas avec calcul, mais cela
// évite peut-être des pb potentiels ??)
// Op_H est toujours calculé
{ for ( int i = 1 ; i < 3 ; i + + )
{ CoordonneeH Ap_H ( 2 ) ; // inter
MathUtil2 : : ChBase ( Op_H_t . CoordoH ( i ) , gamma , Ap_H ) ;
Op_H_t . CoordoH ( i ) = Ap_H ;
}
} ;
// cas des grandeurs locales si elles sont sauvegardées
if ( eps_loc_HH ! = NULL )
{ eps_loc_HH - > ChBase ( gamma ) ; } ;
if ( sig_loc_HH ! = NULL )
{ sig_loc_HH - > ChBase ( gamma ) ; } ;
} ;
// procedure permettant de completer éventuellement les données particulières
// de la loi stockées
// au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie
// completer est appelé apres sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
Loi_comp_abstraite : : SaveResul * Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee
: : Complete_SaveResul ( const BlocGen & bloc , const Tableau < Coordonnee > & tab_coor
, const Loi_comp_abstraite * loi )
{ // on regarde s'il s'agit d'un repère d'orthotropie
if ( bloc . Nom ( 1 ) = = " repere_anisotropie_ " )
{ // ensuite on vérifie le nom de l'identificateur
Loi_ortho2D_C_entrainee * loiOrtho = ( Loi_ortho2D_C_entrainee * ) loi ;
// dimensionnement des bases d'orthotropie
// . elles ont la dimension de l'espace: donc soit 2 soit 3
// . on utilise seulement les deux premiers vecteurs
int dim = ParaGlob : : Dimension ( ) ;
if ( loiOrtho - > Type_transport ( ) = = 0 )
{ O_H = new BaseH ( dim , 2 ) ; sig_loc_HH = NevezTenseurHH ( 2 ) ; }
else
{ O_B = new BaseB ( dim , 2 ) ; eps_loc_HH = NevezTenseurHH ( 2 ) ; } ;
// récupération du repère
if ( bloc . Nom ( 2 ) = = loiOrtho - > NomRepere ( ) )
{ // c'est le bon, récupération des 2 premiers vecteurs
if ( O_B ! = NULL )
{ for ( int i = 1 ; i < 3 ; i + + )
O_B - > CoordoB ( i ) . Change_val ( tab_coor ( i ) ) ;
} ;
if ( O_H ! = NULL )
{ for ( int i = 1 ; i < 3 ; i + + )
O_H - > CoordoH ( i ) . Change_val ( tab_coor ( i ) ) ;
} ;
} ;
} ;
//
return this ;
} ;
// initialise les informations de travail concernant le pas de temps en cours
void Loi_ortho2D_C_entrainee : : SaveResulLoi_ortho2D_C_entrainee : : Init_debut_calcul ( )
{ } ;
// ========== fin des fonctions pour la classe de sauvegarde des résultats =========
Loi_ortho2D_C_entrainee : : Loi_ortho2D_C_entrainee ( ) : // Constructeur par defaut
Loi_comp_abstraite ( ORTHOELA2D_C , CAT_MECANIQUE , 2 )
, E1 ( - ConstMath : : trespetit ) , E2 ( - ConstMath : : trespetit ) , E3 ( - ConstMath : : trespetit )
, nu12 ( - ConstMath : : trespetit ) , nu13 ( - ConstMath : : trespetit ) , nu23 ( - ConstMath : : trespetit )
, G12 ( - ConstMath : : trespetit )
, fct_para ( 7 ) , cas_calcul ( 0 ) , type_transport ( 0 )
, verification_convexite ( 1 ) , sortie_post ( 0 )
, nom_repere ( " " )
, inv_loi ( 2 , 2 ) , Op_B ( 2 , 2 ) , d_Op_B ( 2 , 2 ) , d_Op_H ( 2 , 2 ) , pO_B ( 2 , 2 ) , pO_H ( 2 , 2 )
, beta_inv ( 2 , 2 ) , beta ( 2 , 2 ) , gamma ( 2 , 2 ) , beta_transpose ( 2 , 2 ) , gamma_transpose ( 2 , 2 )
, alpha_H ( 2 , 2 )
, I_x_I_HHHH ( ) , I_xbarre_I_HHHH ( ) , I_x_eps_HHHH ( ) , Ixbarre_eps_HHHH ( )
{ for ( int i = 1 ; i < 8 ; i + + )
fct_para ( i ) = NULL ;
null_fct_para = 1 ; // pour l'instant pas de fonction
} ;
// Contructeur fonction de tous les paramètres constants de la loi
Loi_ortho2D_C_entrainee : : Loi_ortho2D_C_entrainee ( const double & EE1 , const double & EE2 , const double & EE3
, const double & nunu12 , const double & nunu13 , const double & nunu23
, const double & GG12
, const string & nom_rep ) :
Loi_comp_abstraite ( ORTHOELA2D_C , CAT_THERMO_MECANIQUE , 2 )
, E1 ( EE1 ) , E2 ( EE2 ) , E3 ( EE3 ) , nu12 ( nunu12 ) , nu13 ( nunu13 ) , nu23 ( nunu23 )
, G12 ( GG12 )
, fct_para ( 7 ) , cas_calcul ( 0 ) , type_transport ( 0 )
, verification_convexite ( 1 ) , sortie_post ( 0 )
, nom_repere ( nom_rep )
, inv_loi ( 2 , 2 ) , Op_B ( 2 , 2 ) , d_Op_B ( 2 , 2 ) , d_Op_H ( 2 , 2 ) , pO_B ( 2 , 2 ) , pO_H ( 2 , 2 )
, beta_inv ( 2 , 2 ) , beta ( 2 , 2 ) , gamma ( 2 , 2 ) , beta_transpose ( 2 , 2 ) , gamma_transpose ( 2 , 2 )
, alpha_H ( 2 , 2 )
, I_x_I_HHHH ( ) , I_xbarre_I_HHHH ( ) , I_x_eps_HHHH ( ) , Ixbarre_eps_HHHH ( )
{ for ( int i = 1 ; i < 8 ; i + + )
fct_para ( i ) = NULL ;
null_fct_para = 1 ; // pour l'instant pas de fonction
} ;
// Constructeur de copie
Loi_ortho2D_C_entrainee : : Loi_ortho2D_C_entrainee ( const Loi_ortho2D_C_entrainee & loi ) :
Loi_comp_abstraite ( loi )
, E1 ( loi . E1 ) , E2 ( loi . E2 ) , E3 ( loi . E3 ) , nu12 ( loi . nu12 ) , nu13 ( loi . nu13 ) , nu23 ( loi . nu23 )
, G12 ( loi . G12 )
, fct_para ( loi . fct_para ) , cas_calcul ( loi . cas_calcul )
, inv_loi ( loi . inv_loi ) , Op_B ( 2 , 2 ) , d_Op_B ( 2 , 2 ) , d_Op_H ( 2 , 2 ) , pO_B ( 2 , 2 ) , pO_H ( 2 , 2 )
, beta_inv ( 2 , 2 ) , beta ( 2 , 2 ) , gamma ( 2 , 2 ) , beta_transpose ( 2 , 2 ) , gamma_transpose ( 2 , 2 )
, alpha_H ( 2 , 2 )
, type_transport ( loi . type_transport )
, verification_convexite ( loi . verification_convexite ) , sortie_post ( loi . sortie_post )
, nom_repere ( loi . nom_repere )
, I_x_I_HHHH ( ) , I_xbarre_I_HHHH ( ) , I_x_eps_HHHH ( ) , Ixbarre_eps_HHHH ( )
{ // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
for ( int i = 1 ; i < 8 ; i + + )
{ if ( fct_para ( i ) ! = NULL )
{ null_fct_para = 0 ; // dans tous les cas on indique qu'il y a des fonctions
if ( fct_para ( i ) - > NomFonction ( ) = = " _ " )
{ // comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_fonction ( " _ " ) ;
fct_para ( i ) = Fonction_nD : : New_Fonction_nD ( * fct_para ( i ) ) ;
} ;
} ;
} ;
} ;
Loi_ortho2D_C_entrainee : : ~ Loi_ortho2D_C_entrainee ( )
// Destructeur
{ for ( int i = 1 ; i < 8 ; i + + )
{ if ( fct_para ( i ) ! = NULL )
if ( fct_para ( i ) - > NomFonction ( ) = = " _ " ) delete fct_para ( i ) ;
} ;
} ;
// Lecture des donnees de la classe sur fichier
void Loi_ortho2D_C_entrainee : : LectureDonneesParticulieres ( UtilLecture * entreePrinc , LesCourbes1D & lesCourbes1D
, LesFonctions_nD & lesFonctionsnD )
{
// on lit les coefficients dans l'ordre
string nom_class_methode ( " Loi_ortho2D_C_entrainee::LectureDonneesParticulieres " ) ;
double val_defaut = 0. ;
double min = 0. ; double max = - 1 ; // max < min => la condition n'est pas prise en compte
// pour faire une boucle de lecture on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// on boucle sur les 7 coefficients
for ( int i = 1 ; i < 8 ; i + + )
{ string mot_cle1 = tab_mot_cle ( i ) + " = " ;
string mot_cle2 = tab_mot_cle ( i ) + " _fonction_nD: " ;
if ( strstr ( entreePrinc - > tablcar , mot_cle2 . c_str ( ) ) = = 0 )
{ // lecture du paramètre
if ( i < 4 ) // dans le cas des Ei, il faut qu'ils soient tous non nulles
// sinon on ne peut pas calculer inv_loi
{ min = ConstMath : : unpeupetit ; max = ConstMath : : grand ; }
else { min = 0. ; max = - 1 ; } ; // max < min => la condition n'est pas prise en compte
if ( ! entreePrinc - > Lecture_un_parametre_double ( val_defaut , nom_class_methode
, min , max , mot_cle1 , * coef ( i ) ) )
{ entreePrinc - > MessageBuffer ( " **erreur en lecture** " + mot_cle1 ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
}
else // on lit une fonction
{ // on passe le mot clé générique
bool lec = entreePrinc - > Lecture_et_verif_mot_cle ( nom_class_methode , mot_cle1 ) ;
// on lit le nom de la fonction
string nom_fonct ;
lec = lec & & entreePrinc - > Lecture_mot_cle_et_string ( nom_class_methode , mot_cle2 , nom_fonct ) ;
if ( ! lec )
{ entreePrinc - > MessageBuffer ( " **erreur en lecture** " + mot_cle2 ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
null_fct_para = 0 ; // on indique qu'il y a des fonctions
// maintenant on définit la fonction
if ( lesFonctionsnD . Existe ( nom_fonct ) )
{ fct_para ( i ) = lesFonctionsnD . Trouve ( nom_fonct ) ;
}
else
{ // sinon il faut la lire maintenant
string non ( " _ " ) ;
fct_para ( i ) = Fonction_nD : : New_Fonction_nD ( non , Id_Nom_Fonction_nD ( nom_fonct ) ) ;
// lecture de la courbe
fct_para ( i ) - > LectDonnParticulieres_Fonction_nD ( non , entreePrinc ) ;
// maintenant on vérifie que la fonction est utilisable
if ( fct_para ( i ) - > NbComposante ( ) ! = 1 )
{ cout < < " \n erreur en lecture, la fonction " < < nom_fonct
< < " est une fonction vectorielle a " < < fct_para ( i ) - > NbComposante ( )
< < " composante alors qu'elle devrait etre scalaire ! "
< < " elle n'est donc pas utilisable !! " ;
string message ( " \n **erreur08** \n " + nom_class_methode + " (... " ) ;
entreePrinc - > MessageBuffer ( message ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
} ;
if ( i ! = 7 )
entreePrinc - > NouvelleDonnee ( ) ; // on se positionne sur un nouvel enreg
} ;
} ; // fin de la boucle for (int i=1;i< 7;i++)
// lecture du repère d'orthotropie entraîné, associé
string mot_cle ( " nom_repere_associe_ " ) ;
entreePrinc - > NouvelleDonnee ( ) ; // on se positionne sur un nouvel enreg
bool lec = entreePrinc - > Lecture_mot_cle_et_string ( nom_class_methode , mot_cle , nom_repere ) ;
if ( ! lec )
{ entreePrinc - > MessageBuffer ( " **erreur en lecture** " + mot_cle ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
// --- lecture éventuelle des paramètres de réglage ----
cas_calcul = 0 ; // par défaut
if ( strstr ( entreePrinc - > tablcar , " avec_parametres_de_reglage_ " ) ! = 0 )
{ string nom ;
entreePrinc - > NouvelleDonnee ( ) ; // on se positionne sur un nouvel enreg
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_"
// ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle ; // ref aux mots cle
while ( strstr ( entreePrinc - > tablcar , " fin_parametres_reglage_ " ) = = 0 )
{
// si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur
if ( motCle . SimotCle ( entreePrinc - > tablcar ) )
{ cout < < " \n erreur de lecture des parametre de reglage : on n'a pas trouve le mot cle "
< < " fin_parametres_reglage_ et par contre la ligne courante contient un mot cle global " ;
entreePrinc - > MessageBuffer ( " ** erreur5 des parametres de reglage de la loi de comportement de Loi_ortho2D_C_entrainee ** " ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
// lecture d'un mot clé
* ( entreePrinc - > entree ) > > nom ;
if ( ( entreePrinc - > entree ) - > rdstate ( ) = = 0 )
{ } // lecture normale
# ifdef ENLINUX
else if ( ( entreePrinc - > entree ) - > fail ( ) )
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc - > NouvelleDonnee ( ) ; // lecture d'un nouvelle enregistrement
* ( entreePrinc - > entree ) > > nom ;
}
# else
else if ( ( entreePrinc - > entree ) - > eof ( ) )
// la lecture est bonne mais on a atteind la fin de la ligne
{ if ( nom ! = " fin_parametres_reglage_ " )
{ entreePrinc - > NouvelleDonnee ( ) ; * ( entreePrinc - > entree ) > > nom ; } ;
}
# endif
else // cas d'une erreur de lecture
{ cout < < " \n erreur de lecture inconnue " ;
entreePrinc - > MessageBuffer ( " ** erreur4 des parametres de reglage de la loi de comportement de Loi_ortho2D_C_entrainee ** " ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
// type de transport
if ( nom = = " type_transport_ " )
{ // lecture du type
* ( entreePrinc - > entree ) > > type_transport ;
if ( ( type_transport ! = 0 ) & & ( type_transport ! = 1 ) )
{ cout < < " \n le type de transport lue pour la loi de Loi_ortho2D_C_entrainee: " < < type_transport
< < " n'est pas acceptable (uniquement 0 ou 1), on utilise le type par defaut (0) "
< < " qui correspond a un transport de type contravariant " ;
type_transport = 0 ;
} ;
}
// forcer un affichage particulier pour les méthodes
else if ( nom = = " permet_affichage_ " )
{ Lecture_permet_affichage ( entreePrinc , lesFonctionsnD ) ;
}
// on regarde si le calcul est éventuellement uniquement déviatorique
else if ( nom = = " seule_deviatorique " )
{ if ( cas_calcul = = 2 ) { cas_calcul = 0 ; } else { cas_calcul = 1 ; } ; }
// idem pour la partie sphérique
else if ( nom = = " seule_spherique " )
{ if ( cas_calcul = = 1 ) { cas_calcul = 0 ; } else { cas_calcul = 2 ; } ; }
// cas de la vérification de la convexité
else if ( nom = = " verification_convexite_ " )
{ * ( entreePrinc - > entree ) > > verification_convexite ;
}
// forcer un stockage pour des sorties
else if ( nom = = " sortie_post_ " )
{ * ( entreePrinc - > entree ) > > sortie_post ;
}
// sinon ce n'est pas un mot clé connu, on le signale
else if ( nom ! = " fin_parametres_reglage_ " )
{ cout < < " \n erreur en lecture d'un parametre, le mot cle est inconnu "
< < " on a lu : " < < nom < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > 3 )
cout < < " \n Loi_ortho2D_C_entrainee::LectureDonneesParticulieres(UtilLecture * entreePrinc) " < < endl ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
}
} ; //-- fin du while
} ; //-- fin de la lecture des paramètres de réglage
// appel au niveau de la classe mère
Loi_comp_abstraite : : Lecture_type_deformation_et_niveau_commentaire
( * entreePrinc , lesFonctionsnD ) ;
// dans le cas particulier où il n'y a pas de fonction nD on peut calculer inv_loi
if ( null_fct_para )
{ // on vérifie la convexité
if ( verification_convexite )
Verif_convexite ( ) ;
// on commence par remplir la matrice
inv_loi ( 1 , 1 ) = 1. / E1 ; inv_loi ( 2 , 2 ) = 1. / E2 ;
inv_loi ( 1 , 2 ) = inv_loi ( 2 , 1 ) = - nu12 / E1 ;
inv_loi = inv_loi . Inverse ( ) ; // on inverse la matrice
} ;
} ;
// affichage de la loi
void Loi_ortho2D_C_entrainee : : Affiche ( ) const
{ // pour faire une boucle on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < const double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// on boucle sur les 7 coefficients
cout < < " \n loi de comportement orthotrope elastique 2D CP " ;
for ( int i = 1 ; i < 8 ; i + + )
{ string mot_cle1 = tab_mot_cle ( i ) + " = " ;
string mot_cle2 = tab_mot_cle ( i ) + " _fonction_nD: " ;
cout < < mot_cle1 ;
if ( fct_para ( i ) = = NULL )
cout < < * coef ( i ) < < " " ;
else
{ cout < < mot_cle2 < < " " ;
if ( fct_para ( i ) - > NomFonction ( ) ! = " _ " )
cout < < fct_para ( i ) - > NomFonction ( ) ;
else
fct_para ( i ) - > Affiche ( ) ;
cout < < " \n " ;
} ;
} ;
// le nom du repère associé
cout < < " \n nom_repere_associe " < < nom_repere ;
// indicateur de cas de calcul
if ( cas_calcul ! = 0 )
{ if ( cas_calcul = = 1 )
{ cout < < " \n calcul uniquement deviatorique " ; }
else if ( cas_calcul = = 2 )
{ cout < < " calcul uniquement spherique " ; }
else
{ cout < < " cas de calcul mal defini !! " ; } ;
} ;
// affichage du type de transport
cout < < " type_transport: " < < type_transport ;
// niveau d'affichage
cout < < " niveau_affichage_local: " ;
Affiche_niveau_affichage ( ) ;
cout < < " verification_convexite: " < < verification_convexite ;
cout < < " sortie_post: " < < sortie_post ;
cout < < endl ;
// appel de la classe mère
Loi_comp_abstraite : : Affiche_don_classe_abstraite ( ) ;
} ;
// affichage et definition interactive des commandes particulières à chaques lois
void Loi_ortho2D_C_entrainee : : Info_commande_LoisDeComp ( UtilLecture & entreePrinc )
{ ofstream & sort = * ( entreePrinc . Commande_pointInfo ( ) ) ; // pour simplifier
cout < < " \n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? " ;
string rep = " _ " ;
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut ( true , " o " ) ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
E1 = 100000 ; E2 = 50000 ; E3 = 20000 ;
nu12 = 0.2 ; nu13 = 0.3 ; nu23 = 0.1 ;
G12 = 20000 ;
sort < < " \n # ....... loi de comportement orthotrope elastique 2D contrainte plane........ "
< < " \n # 7 parametres materiau: 3 modules, 3 coef de Poisson, 1 module de cisaillement "
< < " \n # et un nom de repere associe " ;
for ( int i = 1 ; i < 8 ; i + + )
{ string mot_cle1 = tab_mot_cle ( i ) + " = " ;
string mot_cle2 = tab_mot_cle ( i ) + " _fonction_nD: " ;
sort < < mot_cle1 < < setprecision ( 6 ) < < * coef ( i ) < < " " ;
} ;
sort < < " \n nom_repere_associe_ repere1 " ;
sort < < endl ;
// cas avec plus d'information
if ( ( rep ! = " o " ) & & ( rep ! = " O " ) & & ( rep ! = " 0 " ) )
{ // cas d'une loi thermo dépendante
sort < < " \n # .... infos complementaires .... "
< < " \n # 1) Pour chaque parametre materiau, individuellement, il est possible "
< < " \n # d'utiliser une fonction nD a la place d'une valeur numerique. "
< < " \n # La fonction nD peut alors dependre de toutes les grandeurs disponibles "
< < " \n # localement, en particulier la position, les donnees imposees par l'utilisateur "
< < " \n # par exe: une temperature, ou tout ddl obtenu directement ou par interpolation "
< < " \n # suivant sa disponibilite, sachant que l'on regarde d'abord si la grandeur est "
< < " \n # directement disponible au point d'integration, sinon on regarde si elle est "
< < " \n # disponible par interpolation. "
< < " \n # "
< < " \n # Supposons que l'on veuille que E2 soit une fonction nD on ecrira: "
< < " \n # soit a: "
< < " \n # E2= E2_fonction_nD: un_nom_de_fonction_existant "
< < " \n # soit b: "
< < " \n # E2= E2_fonction_nD: un_nom_de_type_de_fonction_existant "
< < " \n # suivit sur la ligne suivante de la definition specifique de la fonction "
< < " \n # "
< < " \n # exemple d'un cas a: "
< < " \n # E2= E2_fonction_nD: f1_temperature "
< < " \n # fi_temperature doit alors avoir ete definie dans les fonctions nD "
< < " \n # "
< < " \n # exemple d'un cas b: "
< < " \n # E2= E2_fonction_nD: FONCTION_EXPRESSION_LITTERALE_nD "
< < " \n # deb_list_var_ TEMP fin_list_var_ "
< < " \n # fct= (100726-101325)/50*TEMP + 101325 "
< < " \n # fin_parametres_fonction_expression_litterale_ "
< < " \n # "
< < " \n # Remarques: "
< < " \n # a) apres chaque definition d'une fonction nD on change de ligne "
< < " \n # b) pour les autres coefficients, on remplace E2 par E1, ou "
< < " \n # nu12 ou nu13 ou n23 ou G12 "
< < " \n # "
< < " \n # 2) Par defaut, la base initiale d'orthotropie est transportee dans l'etat courant "
< < " \n # via une methode de type transport contravariant (cf. doc) "
< < " \n # Il est possible d'indiquer un transport de type covariant. Pour ce faire "
< < " \n # on utilise le mot cle: type_transport_ suivi de 0 ou 1 "
< < " \n # 0 : pour un transport de type contravariant (valeur par defaut) "
< < " \n # 1 : pour un transport de type covariant "
< < " \n # "
< < " \n # 3) "
< < " \n # -------------- affichage des erreurs et des warning ---------- "
< < " \n # - l'affichage normale est fonction du parametre global d'affichage gerer "
< < " \n # par le niveau d'affichage cependant pour des raisons par exemple de mise au point, "
< < " \n # il est possible de permettre l'affichage a un niveau particulier "
< < " \n # (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. "
< < " \n # l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier. "
< < " \n # Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale "
< < " \n # soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global "
< < " \n # soit permet_affichage_ vaut n par exemple, dans ce cas l'affichage est fonction uniquement de n "
< < " \n # "
< < " \n # ex: permet_affichage_ 5 "
< < " \n # "
< < " \n # "
< < " \n # 4) Il est possible de calculer que la partie spherique du tenseur de contrainte "
< < " \n # ou que la partie deviatorique "
< < " \n # Pour ce faire on indique a la suite des autres parametres: "
< < " \n # soit le mot clef : seule_deviatorique "
< < " \n # soit le mot clef : seule_spherique "
< < " \n # "
< < " \n # 4) Par defaut, on verifie la convexite du potentiel (cf. theorie) "
< < " \n # mais le calcul ne s'arrete pas si le potentiel n'est pas convexe, "
< < " \n # il y a seulement un message d'erreur "
< < " \n # "
< < " \n # on peut supprimer cette verification a l'aide du mote cle "
< < " \n # verification_convexite_ "
< < " \n # suivi de 0 ou 1 (val par defaut) suivant que l'on ne veut pas de verification "
< < " \n # ou le contraire "
< < " \n # "
< < " \n # 5) --------------- acces en sortie a des grandeurs intermediaires de calcul ------- "
< < " \n # A chaque resolution, il est possible de stocker: "
< < " \n # - le tenseur des contraintes exprime dans le repere d'anisotropie "
< < " \n # - le tenseur des deformation exprime dans le repere d'anisotropie "
< < " \n # - les parametres d'orthotropie entrainee: interessant s'ils varient "
< < " \n # le mot cle est sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke "
< < " \n # s'il est different de 0, on peut acceder aux grandeurs "
< < " \n # seules les grandeurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment "
< < " \n # "
< < " \n # ex: sortie_post_ 1 "
< < " \n # "
< < " \n # "
;
} ;
// appel de la classe mère
Loi_comp_abstraite : : Info_commande_don_LoisDeComp ( entreePrinc ) ;
} ;
// test si la loi est complete
int Loi_ortho2D_C_entrainee : : TestComplet ( )
{ int ret = LoiAbstraiteGeneral : : TestComplet ( ) ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
for ( int i = 1 ; i < 8 ; i + + )
if ( ( * coef ( i ) = = - ConstMath : : trespetit ) & & ( fct_para ( i ) = = NULL ) )
{ string mot_cle1 = tab_mot_cle ( i ) + " = " ;
cout < < mot_cle1 < < " n'est pas defini \n " ;
ret = 0 ;
} ;
// test du cas de calcul
if ( ( cas_calcul < 0 ) | | ( cas_calcul > 2 ) )
{ cout < < " \n l'indicateur de calcul cas_calcul= " < < cas_calcul < < " n'est pas correcte "
< < " \n ceci pour la Loi_ortho2D_C_entrainee " ;
ret = 0 ;
} ;
// le nom du repère associé
if ( nom_repere . length ( ) = = 0 )
{ cout < < " \n le nom du repere assoce n'est pas defini "
< < " \n ceci pour la Loi_ortho2D_C_entrainee " ;
ret = 0 ;
} ;
// info globale disponible actuellement
if ( ! ret )
{ cout < < " \n loi ortho elastique incomplete : " ;
Affiche ( ) ;
} ;
// retour
return ret ;
} ;
// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_ortho2D_C_entrainee : : Grandeur_particuliere
( bool , List_io < TypeQuelconque > & liTQ , Loi_comp_abstraite : : SaveResul * saveDon , list < int > & decal ) const
{ // ici on est en 2D et les grandeurs sont par principe en locale, donc la variable absolue ne sert pas
// on passe en revue la liste
List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ;
list < int > : : iterator idecal = decal . begin ( ) ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + , idecal + + )
{ TypeQuelconque & tipParticu = ( * itq ) ; // pour simplifier
if ( tipParticu . EnuTypeQuelconque ( ) . Nom_vide ( ) ) // veut dire que c'est un enum pur
switch ( tipParticu . EnuTypeQuelconque ( ) . EnumTQ ( ) )
{
// -----cas de la déformation d'épaisseur à t
case DEF_EPAISSEUR :
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveDon ) ; Tab_Grandeur_scalaire_double & tyTQ = * ( ( Tab_Grandeur_scalaire_double * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
tyTQ ( 1 + ( * idecal ) ) = save_resul . eps33 ;
break ;
} ;
case REPERE_D_ANISOTROPIE :
// a) ----- cas du repère d'anisotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveDon ) ;
Tab_Grandeur_BaseH & tyTQ = * ( ( Tab_Grandeur_BaseH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
tyTQ ( 1 + ( * idecal ) ) = save_resul . Op_H ;
//////----- debug
//cout << "\n debug Loi_ortho2D_C_entrainee::Grandeur_particuliere(.. "
// << "\n save_resul.Op_H: "<< save_resul.Op_H << "\n ";
//Signature_pti_encours(cout);
//
//////----- fin debug
( * idecal ) + + ; break ;
}
case EPS_TRANSPORTEE_ANISO :
// ----- cas de la déformation transportée dans le repère d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveDon ) ;
Tab_Grandeur_TenseurHH & tyTQ = * ( ( Tab_Grandeur_TenseurHH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
if ( sortie_post ) { tyTQ ( 1 + ( * idecal ) ) = * ( save_resul . eps_loc_HH ) ; }
else { tyTQ ( 1 + ( * idecal ) ) . Inita ( 0. ) ; } ;
( * idecal ) + + ; break ;
}
case SIGMA_DANS_ANISO :
// ----- cas de la contrainte calculée dans le repère d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveDon ) ;
Tab_Grandeur_TenseurHH & tyTQ = * ( ( Tab_Grandeur_TenseurHH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
if ( sortie_post ) { tyTQ ( 1 + ( * idecal ) ) = * ( save_resul . sig_loc_HH ) ; }
else { tyTQ ( 1 + ( * idecal ) ) . Inita ( 0. ) ; } ;
( * idecal ) + + ; break ;
}
case PARA_ORTHO :
// ----- cas des paramètres d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveDon ) ;
Tab_Grandeur_Vecteur & tyTQ = * ( ( Tab_Grandeur_Vecteur * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
if ( sortie_post ) { tyTQ ( 1 + ( * idecal ) ) = * ( save_resul . para_loi ) ; }
else { tyTQ ( 1 + ( * idecal ) ) . Zero ( ) ; } ;
( * idecal ) + + ; break ;
}
default : ; // on ne fait rien
} ;
} ;
} ;
// récupération et création de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_ortho2D_C_entrainee : : ListeGrandeurs_particulieres ( bool absolue , List_io < TypeQuelconque > & liTQ ) const
{
// pour le stockage
Tableau < double > tab_double ( 1 ) ;
Tab_Grandeur_scalaire_double grand_courant ( tab_double ) ; // $$$ cas du repère local d'orthotropie
int dim_espace = ParaGlob : : Dimension ( ) ;
{ List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ; bool nexistePas = true ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + )
if ( ( * itq ) . EnuTypeQuelconque ( ) = = REPERE_D_ANISOTROPIE )
{ Tab_Grandeur_BaseH & tyTQ = * ( ( Tab_Grandeur_BaseH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
int taille = tyTQ . Taille ( ) + 1 ;
tyTQ . Change_taille ( taille ) ; nexistePas = false ;
} ;
if ( nexistePas )
{ Grandeur_BaseH v_rep ( dim_espace , 2 ) ;
Tab_Grandeur_BaseH grand5 ( v_rep , 1 ) ; // def d'une grandeur courante
TypeQuelconque typQ6 ( REPERE_D_ANISOTROPIE , EPS11 , grand5 ) ;
liTQ . push_back ( typQ6 ) ;
} ;
} ;
// -----cas de la déformation d'épaisseur à t uniquement
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{ List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ; bool nexistePas = true ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + )
if ( ( * itq ) . EnuTypeQuelconque ( ) = = DEF_EPAISSEUR )
{ Tab_Grandeur_scalaire_double & tyTQ = * ( ( Tab_Grandeur_scalaire_double * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
int taille = tyTQ . Taille ( ) + 1 ;
tyTQ . Change_taille ( taille ) ; nexistePas = false ;
} ;
if ( nexistePas )
{ TypeQuelconque typQ1 ( DEF_EPAISSEUR , EPS11 , grand_courant ) ;
liTQ . push_back ( typQ1 ) ;
} ;
} ;
// ---- la suite dépend de l'indicateur : sortie_post
if ( sortie_post )
{ // $$$ cas de la déformation transportée dans le repère d'orthotropie
{ List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ; bool nexistePas = true ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + )
if ( ( * itq ) . EnuTypeQuelconque ( ) = = EPS_TRANSPORTEE_ANISO )
{ Tab_Grandeur_TenseurHH & tyTQ = * ( ( Tab_Grandeur_TenseurHH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
int taille = tyTQ . Taille ( ) + 1 ;
tyTQ . Change_taille ( taille ) ; nexistePas = false ;
} ;
if ( nexistePas )
{ TenseurHH * tens = NevezTenseurHH ( 2 ) ; // un tenseur typique
Tab_Grandeur_TenseurHH eps_loc_HH ( * tens , 1 ) ;
// def d'un type quelconque représentatif
TypeQuelconque typQ ( EPS_TRANSPORTEE_ANISO , EPS11 , eps_loc_HH ) ;
liTQ . push_back ( typQ ) ;
delete tens ; // car on n'en a plus besoin
} ;
} ;
// $$$ cas de la contrainte calculée dans le repère d'orthotropie
{ List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ; bool nexistePas = true ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + )
if ( ( * itq ) . EnuTypeQuelconque ( ) = = SIGMA_DANS_ANISO )
{ Tab_Grandeur_TenseurHH & tyTQ = * ( ( Tab_Grandeur_TenseurHH * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
int taille = tyTQ . Taille ( ) + 1 ;
tyTQ . Change_taille ( taille ) ; nexistePas = false ;
} ;
if ( nexistePas )
{ TenseurHH * tens = NevezTenseurHH ( 2 ) ; // un tenseur typique
Tab_Grandeur_TenseurHH eps_loc_HH ( * tens , 1 ) ;
// def d'un type quelconque représentatif
TypeQuelconque typQ ( SIGMA_DANS_ANISO , SIG11 , eps_loc_HH ) ;
liTQ . push_back ( typQ ) ;
delete tens ; // car on n'en a plus besoin
} ;
} ;
// $$$ cas des paramètres de la loi de comportement
{ List_io < TypeQuelconque > : : iterator itq , itqfin = liTQ . end ( ) ; bool nexistePas = true ;
for ( itq = liTQ . begin ( ) ; itq ! = itqfin ; itq + + )
if ( ( * itq ) . EnuTypeQuelconque ( ) = = PARA_ORTHO )
{ Tab_Grandeur_Vecteur & tyTQ = * ( ( Tab_Grandeur_Vecteur * ) ( * itq ) . Grandeur_pointee ( ) ) ; // pour simplifier
int taille = tyTQ . Taille ( ) + 1 ;
tyTQ . Change_taille ( taille ) ; nexistePas = false ;
} ;
if ( nexistePas )
{ Vecteur tens ( 7 ) ; // les 7 paramètres
Tab_Grandeur_Vecteur gr_vec_para ( tens , 1 ) ;
// def d'un type quelconque représentatif
TypeQuelconque typQ ( PARA_ORTHO , EPS11 , gr_vec_para ) ;
liTQ . push_back ( typQ ) ;
} ;
} ;
} ; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs
// de résolution
} ;
//----- lecture écriture de restart -----
// 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)
2024-06-20 15:42:40 +02:00
void Loi_ortho2D_C_entrainee : : Lecture_base_info_loi ( istream & ent , const int cas , LesReferences & lesRef , LesCourbes1D & lesCourbes1D
2021-09-23 11:21:15 +02:00
, LesFonctions_nD & lesFonctionsnD )
{ string toto , nom ;
if ( cas = = 1 )
{ ent > > nom ;
if ( nom ! = " ORTHOELA2D_C " )
{ cout < < " \n *** erreur en lecture du type de la loi de comportement, on attendait "
< < " la chaine de caracteres: ORTHOELA2D_C et on a lu "
< < nom < < " !!! on ne peut pas continuer "
< < " \n Loi_ortho2D_C_entrainee::Lecture_base_info_loi(.. "
< < flush ;
Sortie ( 1 ) ;
} ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// cela va permettre de choisir entre une valeur fixe et une fonction nD
for ( int i = 1 ; i < 8 ; i + + )
{ ent > > toto > > nom ;
string mot_cle2 = tab_mot_cle ( i ) + " _fonction_nD: " ;
if ( nom = = mot_cle2 )
// cas d'une fonction nD
{ fct_para ( i ) = lesFonctionsnD . Lecture_pour_base_info ( ent , cas , fct_para ( i ) ) ;
}
else // cas d'une valeur fixe
{ ( * coef ( i ) ) = ChangeReel ( nom ) ; } ;
} ;
// lecture du repère associé
ent > > nom > > nom_repere ;
// indicateur pour les calculs partielles
ent > > nom > > cas_calcul ;
// le type de transport
ent > > nom > > type_transport ;
// le niveau d'affichage
Lecture_permet_affichage ( ent , cas , lesFonctionsnD ) ;
// sortie_post
ent > > nom > > sortie_post ;
} ;
// appel de la classe mère
Loi_comp_abstraite : : Lecture_don_base_info ( ent , cas , lesRef , lesCourbes1D , lesFonctionsnD ) ;
} ;
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
2024-06-20 15:42:40 +02:00
void Loi_ortho2D_C_entrainee : : Ecriture_base_info_loi ( ostream & sort , const int cas )
2021-09-23 11:21:15 +02:00
{ if ( cas = = 1 )
{ sort < < " ORTHOELA2D_C " ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau < string > tab_mot_cle ( 7 ) ;
tab_mot_cle ( 1 ) = " E1 " ; tab_mot_cle ( 2 ) = " E2 " ; tab_mot_cle ( 3 ) = " E3 " ;
tab_mot_cle ( 4 ) = " nu12 " ; tab_mot_cle ( 5 ) = " nu13 " ; tab_mot_cle ( 6 ) = " nu23 " ;
tab_mot_cle ( 7 ) = " G12 " ;
// puis un tableau pour les valeurs
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// on boucle sur les 7 coefficients
sort < < " \n loi de comportement orthotrope elastique 2D contrainte plane " ;
for ( int i = 1 ; i < 8 ; i + + )
{ string mot_cle1 = tab_mot_cle ( i ) + " = " ;
string mot_cle2 = tab_mot_cle ( i ) + " _fonction_nD: " ;
sort < < mot_cle1 ;
if ( fct_para ( i ) = = NULL )
sort < < * coef ( i ) < < " " ;
else
{ sort < < mot_cle2 < < " " ;
if ( fct_para ( i ) - > NomFonction ( ) ! = " _ " )
sort < < fct_para ( i ) - > NomFonction ( ) ;
else
fct_para ( i ) - > Affiche ( ) ;
sort < < " \n " ;
} ;
} ;
// le nom du repère associé
sort < < " \n nom_repere_associe_ " < < nom_repere ;
// indicateur de cas de calcul
if ( cas_calcul ! = 0 )
{ if ( cas_calcul = = 1 )
{ sort < < " \n seul_deviatorique " ; }
else if ( cas_calcul = = 2 )
{ sort < < " seul_spherique " ; }
else
{ sort < < " cas_de_calcul_mal_defini " ; } ;
} ;
// affichage du type de transport
sort < < " type_transport: " < < type_transport ;
// niveau d'affichage
Affiche_niveau_affichage ( sort , cas ) ;
sort < < " verification_convexite: " < < verification_convexite ;
sort < < " sortie_post: " < < sortie_post ;
sort < < endl ;
} ;
// appel de la classe mère
Loi_comp_abstraite : : Ecriture_don_base_info ( sort , cas ) ;
} ;
// calcul d'un module d'young équivalent à la loi pour un chargement nul
double Loi_ortho2D_C_entrainee : : Module_young_equivalent ( Enum_dure temps , const Deformation & def , SaveResul * )
{ /*if (!thermo_dependant)
{ return E ; }
else
{ temperature_tdt = def . DonneeInterpoleeScalaire ( TEMP , temps ) ;
return E_temperature - > Valeur ( temperature_tdt ) ;
} ;
*/
cout < < " \n *** attention, methode non implante: "
< < " \n Loi_ortho2D_C_entrainee::Module_young_equivalent(... " ;
Sortie ( 1 ) ;
} ;
// récupération d'un module de compressibilité équivalent à la loi pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
double Loi_ortho2D_C_entrainee : : Module_compressibilite_equivalent ( Enum_dure temps , const Deformation & def , SaveResul * )
{ /* if (!thermo_dependant)
{ return E / ( 3. * ( 1. - 2. * nu ) ) ; }
else
{ temperature_tdt = def . DonneeInterpoleeScalaire ( TEMP , temps ) ;
return E_temperature - > Valeur ( temperature_tdt ) / ( 3. * ( 1. - 2. * nu ) ) ;
} ;
*/
cout < < " \n *** attention, methode non implante: "
< < " \n Loi_ortho2D_C_entrainee::Module_compressibilite_equivalent(... " ;
Sortie ( 1 ) ;
} ;
// ========== codage des METHODES VIRTUELLES protegees:================
// virtual void Calcul_SigmaHH
// (TenseurHH & sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
// ,TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H,TenseurBB & epsBB
// ,TenseurBB & delta_epsBB,TenseurBB & gijBB,TenseurHH & gijHH,Tableau <TenseurBB *>& d_gijBB
// ,double& jacobien_0,double& jacobien,TenseurHH & sigHH
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Expli_t_tdt& ex) = 0; // calcul des contraintes a t+dt
void Loi_ortho2D_C_entrainee : : Calcul_SigmaHH ( TenseurHH & sigHH_t , TenseurBB & , DdlElement & tab_ddl
, TenseurBB & , TenseurHH & , BaseB & , BaseH & , TenseurBB & epsBB_
, TenseurBB & , TenseurBB & gijBB_
, TenseurHH & gijHH_ , Tableau < TenseurBB * > & d_gijBB_ , double & , double &
, TenseurHH & sigHH_ , EnergieMeca & energ , const EnergieMeca &
, double & module_compressibilite , double & module_cisaillement
, const Met_abstraite : : Expli_t_tdt & ex )
{
# ifdef MISE_AU_POINT
if ( epsBB_ . Dimension ( ) ! = 2 )
{ cout < < " \n Erreur : la dimension devrait etre 2 ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_SigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
2023-05-03 17:23:49 +02:00
bool affichage = ( Permet_affichage ( ) > 5 ) ;
2021-09-23 11:21:15 +02:00
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n --- loi de comportement orthotrope entrainee --- " ;
} ;
# endif
const Tenseur2BB & epsBB = * ( ( Tenseur2BB * ) & epsBB_ ) ; // passage en dim 2
const Tenseur2HH & gijHH = * ( ( Tenseur2HH * ) & gijHH_ ) ; // " " " "
const Tenseur2BB & gijBB = * ( ( Tenseur2BB * ) & gijBB_ ) ; // " " " "
Tenseur2HH & sigHH = * ( ( Tenseur2HH * ) & sigHH_ ) ; // " " " "
Tenseur2BH epsBH = epsBB * gijHH ; // deformation en mixte
int dim = ParaGlob : : Dimension ( ) ; // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveResul ) ;
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH & Op_H = save_resul . Op_H ;
Tableau < double > tab_norme ( 2 ) ;
if ( type_transport = = 0 )
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
# ifdef MISE_AU_POINT
if ( save_resul . O_H = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_SigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseH & O_H = ( * save_resul . O_H ) ; // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for ( int a = 1 ; a < 3 ; a + + )
{ CoordonneeH & inter = alpha_H . CoordoH ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
inter ( i ) = O_H ( a ) . ScalHH ( ( * ex . giH_0 ) ( i ) ) ;
} ;
// calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// mais exprimés dans le repère actuel \hat \vec g_j
CoordonneeH & Op_H_a = Op_H . CoordoH ( a ) ;
Op_H_a = alpha_H ( a ) ;
// calcul de la norme du vecteur Op_H_a
double norme = sqrt ( Op_H_a * gijBB * Op_H_a ) ;
tab_norme ( a ) = norme ;
// coordonnées finales
Op_H_a / = norme ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n Op_H( " < < a < < " ): " ;
Op_H_a . Affiche ( ) ;
cout < < " \n alpha_H( " < < a < < " ): " ;
alpha_H ( a ) . Affiche ( ) ;
cout < < " \n giB_tdt " ; ( * ex . giB_tdt ) ( a ) . Affiche ( ) ;
// affichage du repère tournée
CoordonneeB V ( dim ) ;
for ( int j = 1 ; j < = 2 ; j + + ) V + = ( * ex . giB_tdt ) ( j ) * Op_H_a ( j ) ;
cout < < " \n op_H( " < < a < < " ): en absolu " < < V ;
} ;
# endif
} ;
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
# ifdef MISE_AU_POINT
if ( save_resul . O_B = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_SigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseB & O_B = ( * save_resul . O_B ) ; // pour simplifier
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
CoordonneeB & Op_B_a = Op_B . CoordoB ( a ) ;
// calcul de la norme du vecteur Op_B_a
double norme = sqrt ( Op_B_a * gijHH * Op_B_a ) ;
// coordonnées finales
Op_B_a / = norme ;
} ;
// maintenant on calcule la base Op_H correspondante
for ( int i = 1 ; i < 3 ; i + + )
Op_H . CoordoH ( i ) = Op_B . CoordoB ( i ) * gijHH ;
} ;
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for ( int i = 1 ; i < 3 ; i + + )
for ( int j = 1 ; j < 3 ; j + + )
{ beta ( i , j ) = Op_H ( i ) ( j ) ; } ;
// puis on calcul les coordonnées de la base duale
beta_transpose = beta . Transpose ( ) ;
gamma = beta_transpose . Inverse ( ) ;
gamma_transpose = gamma . Transpose ( ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n beta: " ; beta . Affiche ( ) ;
cout < < " \n beta_transpose: " ; beta_transpose . Affiche ( ) ;
cout < < " \n gamma: " ; gamma . Affiche ( ) ;
cout < < " \n gamma_transpose: " ; gamma_transpose . Affiche ( ) ;
} ;
# endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'^i
# ifdef MISE_AU_POINT
if ( affichage )
{ TenseurBB * eps_p_BB = NevezTenseurBB ( epsBB ) ;
cout < < " \n eps_p_BB: " ; eps_p_BB - > Ecriture ( cout ) ;
delete eps_p_BB ;
} ;
# endif
// c-a-d les coordonnées dans le dual de O'_i
// il faut passer en 2 fois contravariant
Tenseur2BB eps_p_BB ( epsBB ) ;
//cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout);
// il faut passer en 2 fois contravariant
2023-05-03 17:23:49 +02:00
// on utilise l'opérateur d'affectation, car le résultat doit-être symétrique, or
// les multiplications intermédiaires vont générer un tenseur systématiquement non symétrique
Tenseur2HH eps_p_HH = gijHH * eps_p_BB * gijHH ;
2021-09-23 11:21:15 +02:00
eps_p_HH . ChBase ( gamma ) ; // res = (gamma * res) * gamma.Transpose();
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n eps_p_HH: " ; eps_p_HH . Ecriture ( cout ) ;
TenseurHH * toto = NevezTenseurHH ( eps_p_HH ) ;
toto - > ChBase ( beta_transpose ) ;
cout < < " \n retour dans la base g^i de eps^{ij} : " ; toto - > Ecriture ( cout ) ;
TenseurBB * titi = NevezTenseurBB ( gijBB * ( * toto ) * gijBB ) ;
cout < < " \n def eps_ij : " ; titi - > Ecriture ( cout ) ;
delete toto ; delete titi ;
} ;
# endif
double untiers = 1. / 3. ;
// dans le cas de fonctions nD récupération des valeurs
if ( ! null_fct_para )
// Tableau <Fonction_nD* > fct_para; // fonction nD éventuelle d'évolution des paramètres
{ // un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// opération de transmission de la métrique
const Met_abstraite : : Impli * ex_impli = NULL ;
const Met_abstraite : : Expli_t_tdt * ex_expli_tdt = & ex ;
const Met_abstraite : : Umat_cont * ex_expli = NULL ;
// on passe en revue les fonctions nD
for ( int i = 1 ; i < 8 ; i + + )
{ if ( fct_para ( i ) ! = NULL )
{ Fonction_nD * pt_fonct = fct_para ( i ) ; // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau < double > & tab_val = Loi_comp_abstraite : : Loi_comp_Valeur_FnD_Evoluee
( pt_fonct , 1 // une seule valeur attendue en retour
, ex_impli , ex_expli_tdt , ex_expli
, NULL
, NULL
, NULL
) ;
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io < Ddl_enum_etendu > & li_enu_scal = pt_fonct - > Li_enu_etendu_scalaire ( ) ;
List_io < TypeQuelconque > & li_quelc = pt_fonct - > Li_equi_Quel_evolue ( ) ;
bool absolue = true ; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau < double > val_ddl_enum ( Valeur_multi_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_enu_scal , ex_impli , ex_expli_tdt , ex_expli , NULL )
) ;
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_quelc , ex_impli , ex_expli_tdt , ex_expli , NULL ) ;
// calcul de la valeur et retour dans tab_ret
Tableau < double > & tab_val = pt_fonct - > Valeur_FnD_Evoluee ( & val_ddl_enum , & li_enu_scal , & li_quelc , NULL , NULL ) ;
# ifdef MISE_AU_POINT
if ( tab_val . Taille ( ) ! = 1 )
{ cout < < " \n Erreur : la fonction nD relative au parametre materiau " < < i
< < " doit calculer un scalaire or le tableau de retour est de taille "
< < tab_val . Taille ( ) < < " ce n'est pas normal ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_SigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
*/
// on récupère le premier élément du tableau uniquement
( * coef ( i ) ) = tab_val ( 1 ) ;
} ;
} ;
} ;
// puis fabrication de la matrice inv_loi
{ // on commence par remplir la matrice
inv_loi ( 1 , 1 ) = 1. / E1 ; inv_loi ( 2 , 2 ) = 1. / E2 ;
inv_loi ( 1 , 2 ) = inv_loi ( 2 , 1 ) = - nu12 / E1 ;
inv_loi = inv_loi . Inverse ( ) ; // on inverse la matrice
} ;
// on vérifie éventuellement la convexité
if ( verification_convexite )
Verif_convexite ( ) ;
// calcul des contraintes dans le repère O_p
Vecteur eps_ii ( 2 ) ; Vecteur sig_ii ( 2 ) ;
for ( int i = 1 ; i < 3 ; i + + )
eps_ii ( i ) = eps_p_HH ( i , i ) ;
sig_ii = inv_loi * eps_ii ;
// Tenseur2HH sig_HH;
for ( int i = 1 ; i < 3 ; i + + )
{ sigHH . Coor ( i , i ) = sig_ii ( i ) ;
} ;
sigHH . Coor ( 1 , 2 ) = 2. * G12 * eps_p_HH ( 1 , 2 ) ;
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if ( sortie_post )
{ if ( save_resul . eps_loc_HH = = NULL )
{ save_resul . eps_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . sig_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . para_loi = new Vecteur ( 7 ) ;
} ;
( * save_resul . eps_loc_HH ) = eps_p_HH ;
( * save_resul . sig_loc_HH ) = sigHH ;
// paramètres de la loi
( * save_resul . para_loi ) ( 1 ) = E1 ; ( * save_resul . para_loi ) ( 2 ) = E2 ;
( * save_resul . para_loi ) ( 3 ) = E3 ;
( * save_resul . para_loi ) ( 4 ) = nu12 ; ( * save_resul . para_loi ) ( 5 ) = nu13 ;
( * save_resul . para_loi ) ( 6 ) = nu23 ;
( * save_resul . para_loi ) ( 7 ) = G12 ;
} ;
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH . ChBase ( beta_transpose ) ;
// beta_inv = beta.Inverse();
// sig_BB.ChBase(beta_inv);
// passage dans la bonne variance
2023-05-03 17:23:49 +02:00
Tenseur2BH sigBH = gijBB * sigHH ;
2021-09-23 11:21:15 +02:00
switch ( cas_calcul )
{ case 0 : // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break ;
}
case 1 : // calcul de la partie déviatorique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH - = ( untiers * trace_sig ) * IdBH2 ;
sigHH - = ( untiers * trace_sig ) * gijHH ;
break ;
}
case 2 : // calcul de la partie sphérique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH = ( untiers * trace_sig ) * IdBH2 ;
sigHH = ( untiers * trace_sig ) * gijHH ;
break ;
}
default :
{ cout < < " \n erreur l'indicateur cas_calcul= " < < cas_calcul < < " n'a pas une valeur correcte !! "
< < " \n Loi_ortho2D_C_entrainee::Calcul_SigmaHH (.... " ;
Sortie ( 1 ) ;
}
} ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n epsBB= " < < epsBB < < " gijBB_tdt= " < < gijBB < < " gijHH_tdt= " < < gijHH < < " " ;
cout < < " \n sighh= " < < sigHH < < " " < < flush ;
} ;
# endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12 * E2 / E1 ;
save_resul . eps33 = - 1 / ( 1. - nu12 * nu21 ) * (
epsBH ( 1 , 1 ) * ( nu12 * nu23 + nu13 ) + epsBH ( 2 , 2 ) * ( nu23 + nu13 * nu21 )
) ;
// traitement des énergies
energ . Inita ( 0. ) ;
energ . ChangeEnergieElastique ( 0.5 * ( sigHH & & epsBB ) ) ;
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) ; // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0. ; // init
switch ( type_de_deformation )
{ case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
// cas d'une déformation d'Almansi
{ // epsBB33 = 1/2 * (1. - (h0/h)^2)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt ( 1. / ( 1. - 2. * save_resul . eps33 ) ) ;
} ;
break ;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp ( save_resul . eps33 ) ;
} ;
break ;
default :
cout < < " \n Erreur : type de deformation qui n'est pas actuellement pris en compte, type= "
< < Nom_type_deformation ( type_de_deformation ) ;
cout < < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n " ;
Sortie ( 1 ) ;
} ;
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai ) ;
// pour le module de compressibilité, choix entre les différents cas
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 2 ) )
{ if ( log_var_vol > ConstMath : : petit )
{ module_compressibilite = untiers * sigBH . Trace ( ) / ( log_var_vol ) ; }
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 2 directions d'orthotropie (cf. théorie)
{ double unsurKs1 = 1. / E1 - nu12 / E1 - nu13 / E1 ;
double unsurKs2 = - nu12 / E1 + 1. / E2 - nu23 / E2 ;
double unsurKs3 = - nu13 / E1 - nu23 / E2 + 1. / E3 ;
module_compressibilite = untiers * untiers * ( 1. / unsurKs1 + 1. / unsurKs2 + 1. / unsurKs3 ) ;
} ;
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{ module_compressibilite = 0. ; } ;
# ifdef MISE_AU_POINT
if ( Permet_affichage ( ) > 4 )
{ cout < < " \n var_vol= " < < ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai )
< < " log_var_vol= " < < log_var_vol
< < " sigBH.Trace()= " < < sigBH . Trace ( )
< < " module_compressibilite= " < < module_compressibilite
< < flush ;
if ( Permet_affichage ( ) > 5 ) cout < < " \n cas_calcul= " < < cas_calcul ;
} ;
# endif
// pour la partie cisaillement on garde la forme associée à la loi
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 1 ) )
{ module_cisaillement = 2. * ( G12 ) ; }
else
// en purement sphérique, le module est supposé nul
{ module_cisaillement = 0. ; } ;
LibereTenseur ( ) ;
} ;
// calcul des contraintes a t+dt et de ses variations
// void Calcul_DsigmaHH_tdt (TenseurHH & sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
// ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t
// ,BaseB& giB_tdt,Tableau <BaseB> & d_giB_tdt,BaseH& giH_tdt,Tableau <BaseH> & d_giH_tdt
// ,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>& d_epsBB
// ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt
// ,Tableau <TenseurBB *>& d_gijBB_tdt
// ,Tableau <TenseurHH *>& d_gijHH_tdt,double& jacobien_0,double& jacobien
// ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH,Tableau <TenseurHH *>& d_sigHH
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Impli& ex);
void Loi_ortho2D_C_entrainee : : Calcul_DsigmaHH_tdt ( TenseurHH & , TenseurBB & , DdlElement & tab_ddl
, BaseB & , TenseurBB & , TenseurHH &
, BaseB & , Tableau < BaseB > & , BaseH & , Tableau < BaseH > &
, TenseurBB & epsBB_tdt , Tableau < TenseurBB * > & d_epsBB
, TenseurBB & delta_epsBB , TenseurBB & gijBB_tdt , TenseurHH & gijHH_tdt
, Tableau < TenseurBB * > & d_gijBB_tdt
, Tableau < TenseurHH * > & d_gijHH_tdt , double & , double &
, Vecteur & , TenseurHH & sigHH_tdt , Tableau < TenseurHH * > & d_sigHH
, EnergieMeca & energ , const EnergieMeca &
, double & module_compressibilite , double & module_cisaillement
, const Met_abstraite : : Impli & ex )
{
# ifdef MISE_AU_POINT
if ( epsBB_tdt . Dimension ( ) ! = 2 )
{ cout < < " \n Erreur : la dimension devrait etre 2 ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt \n " ;
Sortie ( 1 ) ;
} ;
if ( tab_ddl . NbDdl ( ) ! = d_gijBB_tdt . Taille ( ) )
{ cout < < " \n Erreur : le nb de ddl est != de la taille de d_gijBB_tdt ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt \n " ;
Sortie ( 1 ) ;
} ;
# endif
2023-05-03 17:23:49 +02:00
bool affichage = ( Permet_affichage ( ) > 5 ) ;
2021-09-23 11:21:15 +02:00
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n --- loi de comportement orthotrope entrainee --- " ;
} ;
# endif
const Tenseur2BB & epsBB = * ( ( Tenseur2BB * ) & epsBB_tdt ) ; // passage en dim 2
const Tenseur2HH & gijHH = * ( ( Tenseur2HH * ) & gijHH_tdt ) ; // " " " "
Tenseur2HH & sigHH = * ( ( Tenseur2HH * ) & sigHH_tdt ) ; // " " " "
const Tenseur2BB & gijBB = * ( ( Tenseur2BB * ) & gijBB_tdt ) ; // " " " "
Tenseur2BH epsBH = epsBB * gijHH ; // deformation en mixte
2023-05-03 17:23:49 +02:00
Tenseur2HH epsHH = gijHH * epsBH ; // en deuxfois contra
2021-09-23 11:21:15 +02:00
int dim = ParaGlob : : Dimension ( ) ; // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveResul ) ;
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH & Op_H = save_resul . Op_H ;
Tableau < double > tab_norme ( 2 ) ;
if ( type_transport = = 0 )
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
# ifdef MISE_AU_POINT
if ( save_resul . O_H = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseH & O_H = ( * save_resul . O_H ) ; // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for ( int a = 1 ; a < 3 ; a + + )
{ CoordonneeH & inter = alpha_H . CoordoH ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
inter ( i ) = O_H ( a ) . ScalHH ( ( * ex . giH_0 ) ( i ) ) ;
} ;
// calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// mais exprimés dans le repère actuel \hat \vec g_j
CoordonneeH & Op_H_a = Op_H . CoordoH ( a ) ; // pour simplifier
Op_H_a = alpha_H ( a ) ;
// calcul de la norme du vecteur Op_H_a
double norme = sqrt ( Op_H_a * gijBB * Op_H_a ) ;
tab_norme ( a ) = norme ;
// coordonnées finales
Op_H_a / = norme ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n Op_H( " < < a < < " ): " ;
Op_H_a . Affiche ( ) ;
cout < < " \n alpha_H( " < < a < < " ): " ;
alpha_H ( a ) . Affiche ( ) ;
cout < < " \n giB_tdt " ; ( * ex . giB_tdt ) ( a ) . Affiche ( ) ;
// affichage du repère tournée
CoordonneeB V ( dim ) ;
for ( int j = 1 ; j < = 2 ; j + + ) V + = ( * ex . giB_tdt ) ( j ) * Op_H_a ( j ) ;
cout < < " \n op_H( " < < a < < " ): en absolu " < < V ;
} ;
# endif
} ;
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
# ifdef MISE_AU_POINT
if ( save_resul . O_B = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseB & O_B = ( * save_resul . O_B ) ; // pour simplifier
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
CoordonneeB & Op_B_a = Op_B . CoordoB ( a ) ;
// calcul de la norme du vecteur Op_B_a
double norme = sqrt ( Op_B_a * gijHH * Op_B_a ) ;
tab_norme ( a ) = norme ;
// coordonnées finales
Op_B_a / = norme ;
} ;
// maintenant on calcule la base Op_H correspondante
for ( int i = 1 ; i < 3 ; i + + )
Op_H . CoordoH ( i ) = Op_B . CoordoB ( i ) * gijHH ;
} ;
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for ( int i = 1 ; i < 3 ; i + + )
for ( int j = 1 ; j < 3 ; j + + )
{ beta ( i , j ) = Op_H ( i ) ( j ) ; } ;
// puis on calcul les coordonnées de la base duale
beta_transpose = beta . Transpose ( ) ;
gamma = beta_transpose . Inverse ( ) ;
gamma_transpose = gamma . Transpose ( ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n beta: " ; beta . Affiche ( ) ;
cout < < " \n beta_transpose: " ; beta_transpose . Affiche ( ) ;
cout < < " \n gamma: " ; gamma . Affiche ( ) ;
cout < < " \n gamma_transpose: " ; gamma_transpose . Affiche ( ) ;
} ;
# endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'_i
# ifdef MISE_AU_POINT
if ( affichage )
{ // Tenseur2BB eps_p_BB(epsBB);
cout < < " \n eps_p_BB en g^i: " ; epsBB . Ecriture ( cout ) ;
Tenseur2BB tiutiu ;
epsBB . BaseAbsolue ( tiutiu , * ( ex . giH_tdt ) ) ;
cout < < " \n eps en absolu : " ; tiutiu . Ecriture ( cout ) ;
} ;
# endif
// il faut passer en 2 fois contravariant
Tenseur2HH eps_p_HH ( epsHH ) ; // init
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n eps_p_HH en g_i: " ; eps_p_HH . Ecriture ( cout ) ;
} ;
# endif
eps_p_HH . ChBase ( gamma ) ; // res = (gamma * res) * gamma.Transpose();
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n eps_p_HH: " ; eps_p_HH . Ecriture ( cout ) ;
TenseurHH * toto = NevezTenseurHH ( eps_p_HH ) ;
toto - > ChBase ( beta_transpose ) ;
cout < < " \n retour dans la base g^i de eps^{ij} : " ; toto - > Ecriture ( cout ) ;
TenseurBB * titi = NevezTenseurBB ( gijBB * ( * toto ) * gijBB ) ;
cout < < " \n def eps_ij : " ; titi - > Ecriture ( cout ) ;
delete toto ; delete titi ;
} ;
# endif
double untiers = 1. / 3. ;
// dans le cas de fonctions nD récupération des valeurs
if ( ! null_fct_para )
// Tableau <Fonction_nD* > fct_para; // fonction nD éventuelle d'évolution des paramètres
{ // un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// opération de transmission de la métrique
const Met_abstraite : : Impli * ex_impli = & ex ;
const Met_abstraite : : Expli_t_tdt * ex_expli_tdt = NULL ;
const Met_abstraite : : Umat_cont * ex_expli = NULL ;
// on passe en revue les fonctions nD
for ( int i = 1 ; i < 8 ; i + + )
{ if ( fct_para ( i ) ! = NULL )
{ Fonction_nD * pt_fonct = fct_para ( i ) ; // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau < double > & tab_val = Loi_comp_abstraite : : Loi_comp_Valeur_FnD_Evoluee
( pt_fonct , 1 // une seule valeur attendue en retour
, ex_impli , ex_expli_tdt , ex_expli
, NULL
, NULL
, NULL
) ;
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io < Ddl_enum_etendu > & li_enu_scal = pt_fonct - > Li_enu_etendu_scalaire ( ) ;
List_io < TypeQuelconque > & li_quelc = pt_fonct - > Li_equi_Quel_evolue ( ) ;
bool absolue = true ; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau < double > val_ddl_enum ( Valeur_multi_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_enu_scal , ex_impli , ex_expli_tdt , ex_expli , NULL )
) ;
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_quelc , ex_impli , ex_expli_tdt , ex_expli , NULL ) ;
// calcul de la valeur et retour dans tab_ret
Tableau < double > & tab_val = pt_fonct - > Valeur_FnD_Evoluee ( & val_ddl_enum , & li_enu_scal , & li_quelc , NULL , NULL ) ;
# ifdef MISE_AU_POINT
if ( tab_val . Taille ( ) ! = 1 )
{ cout < < " \n Erreur : la fonction nD relative au parametre materiau " < < i
< < " doit calculer un scalaire or le tableau de retour est de taille "
< < tab_val . Taille ( ) < < " ce n'est pas normal ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
*/
// on récupère le premier élément du tableau uniquement
( * coef ( i ) ) = tab_val ( 1 ) ;
} ;
} ;
} ;
// puis fabrication de la matrice inv_loi
{ // on commence par remplir la matrice
inv_loi ( 1 , 1 ) = 1. / E1 ; inv_loi ( 2 , 2 ) = 1. / E2 ;
inv_loi ( 1 , 2 ) = inv_loi ( 2 , 1 ) = - nu12 / E1 ;
inv_loi = inv_loi . Inverse ( ) ; // on inverse la matrice
} ;
// on vérifie éventuellement la convexité
if ( verification_convexite )
Verif_convexite ( ) ;
// calcul des contraintes dans le repère O_p
Vecteur eps_ii ( 2 ) ; Vecteur sig_ii ( 2 ) ;
for ( int i = 1 ; i < 3 ; i + + )
eps_ii ( i ) = eps_p_HH ( i , i ) ;
sig_ii = inv_loi * eps_ii ;
for ( int i = 1 ; i < 3 ; i + + )
{ sigHH . Coor ( i , i ) = sig_ii ( i ) ;
} ;
sigHH . Coor ( 1 , 2 ) = 2. * G12 * eps_p_HH ( 1 , 2 ) ;
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if ( sortie_post )
{ if ( save_resul . eps_loc_HH = = NULL )
{ save_resul . eps_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . sig_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . para_loi = new Vecteur ( 7 ) ;
} ;
( * save_resul . eps_loc_HH ) = eps_p_HH ;
( * save_resul . sig_loc_HH ) = sigHH ;
// paramètres de la loi
( * save_resul . para_loi ) ( 1 ) = E1 ; ( * save_resul . para_loi ) ( 2 ) = E2 ;
( * save_resul . para_loi ) ( 3 ) = E3 ;
( * save_resul . para_loi ) ( 4 ) = nu12 ; ( * save_resul . para_loi ) ( 5 ) = nu13 ;
( * save_resul . para_loi ) ( 6 ) = nu23 ;
( * save_resul . para_loi ) ( 7 ) = G12 ;
} ;
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH . ChBase ( beta_transpose ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n sig_ijHH complet : " ; sigHH . Ecriture ( cout ) ;
Tenseur2HH tutu ;
sigHH . BaseAbsolue ( tutu , * ( ex . giB_tdt ) ) ;
cout < < " \n sig en absolu : " ; tutu . Ecriture ( cout ) ;
} ;
# endif
// passage dans la bonne variance
2023-05-03 17:23:49 +02:00
Tenseur2BH sigBH = gijBB * sigHH ;
2021-09-23 11:21:15 +02:00
switch ( cas_calcul )
{ case 0 : // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break ;
}
case 1 : // calcul de la partie déviatorique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH - = ( untiers * trace_sig ) * IdBH2 ;
sigHH - = ( untiers * trace_sig ) * gijHH ;
break ;
}
case 2 : // calcul de la partie sphérique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH = ( untiers * trace_sig ) * IdBH2 ;
sigHH = ( untiers * trace_sig ) * gijHH ;
break ;
}
default :
{ cout < < " \n erreur l'indicateur cas_calcul= " < < cas_calcul < < " n'a pas une valeur correcte !! "
< < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... " ;
Sortie ( 1 ) ;
}
} ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n epsBB= " < < epsBB < < " gijBB_tdt= " < < gijBB < < " gijHH_tdt= " < < gijHH < < " " ;
cout < < " \n sighh= " < < sigHH < < " " < < flush ;
} ;
# endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12 * E2 / E1 ;
save_resul . eps33 = - 1 / ( 1. - nu12 * nu21 ) * (
epsBH ( 1 , 1 ) * ( nu12 * nu23 + nu13 ) + epsBH ( 2 , 2 ) * ( nu23 + nu13 * nu21 )
) ;
// traitement des énergies
energ . Inita ( 0. ) ;
energ . ChangeEnergieElastique ( 0.5 * ( sigHH & & epsBB ) ) ;
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) ; // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0. ; // init
switch ( type_de_deformation )
{ case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
// cas d'une déformation d'Almansi
{ // epsBB33 = 1/2 * (1. - (h0/h)^2)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt ( 1. / ( 1. - 2. * save_resul . eps33 ) ) ;
} ;
break ;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp ( save_resul . eps33 ) ;
} ;
break ;
default :
cout < < " \n Erreur : type de deformation qui n'est pas actuellement pris en compte, type= "
< < Nom_type_deformation ( type_de_deformation ) ;
cout < < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n " ;
Sortie ( 1 ) ;
} ;
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai ) ;
// pour le module de compressibilité, choix entre les différents cas
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 2 ) )
{
if ( log_var_vol > ConstMath : : petit )
{ module_compressibilite = untiers * sigBH . Trace ( ) / ( log_var_vol ) ;
// module_compressibilite = untiers * sigBH.Trace() /
// (1.- 1./((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai));
}
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 3 directions d'orthotropie (cf. théorie)
{ double unsurKs1 = 1. / E1 - nu12 / E1 - nu13 / E1 ;
double unsurKs2 = - nu12 / E1 + 1. / E2 - nu23 / E2 ;
double unsurKs3 = - nu13 / E1 - nu23 / E2 + 1. / E3 ;
module_compressibilite = untiers * untiers * ( 1. / unsurKs1 + 1. / unsurKs2 + 1. / unsurKs3 ) ;
} ;
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{ module_compressibilite = 0. ; } ;
# ifdef MISE_AU_POINT
if ( Permet_affichage ( ) > 4 )
{ cout < < " \n eps33= " < < save_resul . eps33
< < " var_epai= " < < var_epai
< < " var_surf= " < < var_surf
< < " \n var_vol= " < < ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai )
< < " log_var_vol= " < < log_var_vol
< < " sigBH.Trace()= " < < sigBH . Trace ( )
< < " module_compressibilite= " < < module_compressibilite
< < flush ;
} ;
# endif
// pour la partie cisaillement on garde la forme associée à la loi
// on prend la moyenne des 3
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 1 ) )
{ module_cisaillement = 2. * ( G12 ) ; }
else
// en purement sphérique, le module est supposé nul
{ module_cisaillement = 0. ; } ;
// cas le la variation du tenseur des contraintes
int nbddl = d_gijBB_tdt . Taille ( ) ;
// des tenseurs de travail
Tenseur2BH d_sigBH ; Tenseur2HH d_sig_HH ;
Tenseur2HH d_epsHH ; Mat_pleine mat_d_epsHH ( 2 , 2 ) ;
Vecteur d_eps_ii ( 2 ) ; Vecteur d_sig_ii ( 2 ) ;
Mat_pleine d_beta ( 2 , 2 ) ; Mat_pleine d_beta_inv ( 2 , 2 ) ;
Mat_pleine d_beta_transpose ( 2 , 2 ) ;
Mat_pleine d_gamma ( 2 , 2 ) ;
Mat_pleine mat_d_eps_p_HH ( 2 , 2 ) ;
// on récupère la matrice des composantes de déformation dans O_p_a
Mat_pleine mat_epsHH ( 2 , 2 ) ; epsHH . Matrice_composante ( mat_epsHH ) ;
//cout << "\n mat_epsHH: ";mat_epsHH.Affiche();
for ( int i = 1 ; i < = nbddl ; i + + )
{ // on fait uniquement une égalité d'adresse et de ne pas utiliser
// le constructeur d'ou la profusion d'* et de ()
Tenseur2HH & dsigHH = * ( ( Tenseur2HH * ) ( d_sigHH ( i ) ) ) ; // passage en dim 2
const Tenseur2HH & dgijHH = * ( ( Tenseur2HH * ) ( d_gijHH_tdt ( i ) ) ) ; // pour simplifier l'ecriture
const Tenseur2BB & dgijBB = * ( ( Tenseur2BB * ) ( d_gijBB_tdt ( i ) ) ) ; // pour simplifier l'ecriture
const Tenseur2BB & depsBB = * ( ( Tenseur2BB * ) ( d_epsBB ( i ) ) ) ; // "
//Tableau <BaseB> * d_giB_tdt
BaseB & d_giB = ( * ex . d_giB_tdt ) ( i ) ;
BaseH & d_giH = ( * ex . d_giH_tdt ) ( i ) ;
// pour chacun des ddl on calcul les tenseurs derivees
Tenseur2BH depsBH = epsBB * dgijHH + depsBB * gijHH ;
//cout <<"\n depsBH: "; depsBH.Ecriture(cout);
/* // calcul des variations du repère O'_i
// en fait il s'agit des variations des beta_a^{.j}
if ( type_transport = = 0 )
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
BaseH & O_H = ( * save_resul . O_H ) ; // pour simplifier
for ( int a = 1 ; a < 3 ; a + + )
{ // calcul des variations du vecteur non normé
CoordonneeH d_pO_H_i ( 3 ) ;
d_pO_H_i . Zero ( ) ;
// on a: Op_H(a) non normé = alpha_a^{.k} * \hat \vec g_k
// d'où : d_Op_H(a) non normé = alpha_a^{.k} * d(\hat \vec g_k)
for ( int k = 1 ; k < 3 ; k + + )
{ const CoordonneeB & d_giB_k = d_giB ( k ) ;
// on change la variance car, celle-ci en fait dépend de la base
// et non de gi_B, mais ici on utilise la base sous forme d'un scalaire
// O_H(a)(k) et la variance est donnée par d_inter...
CoordonneeH d_inter ( 3 ) ;
d_inter . ConstructionAPartirDe_B ( d_giB_k ) ;
d_pO_H_i + = O_H ( a ) ( k ) * d_inter ;
} ;
// calcul de la variation du vecteur unitaire connaissant la variation du
// vecteur non unitaire et la norme
// d_Op_H.CoordoH(a) = Util::VarUnVect_coorH(pO_B.CoordoB(a),d_pO_H_i,tab_norme(a));
} ;
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
BaseB & O_B = ( * save_resul . O_B ) ; // pour simplifier
for ( int iloc = 1 ; iloc < 3 ; iloc + + )
{ // tout d'abord la base non normalisée
CoordonneeH & d_pO_H_i = d_Op_H . CoordoH ( iloc ) ;
d_pO_H_i . Zero ( ) ;
for ( int k = 1 ; k < 3 ; k + + )
{ CoordonneeH d_giH_k = d_giH ( k ) ;
d_pO_H_i + = O_B ( i ) ( k ) * d_giH_k ;
} ;
// calcul de la variation du vecteur unitaire connaissant la variation du
// vecteur non unitaire et la norme
CoordonneeH interH = Util : : VarUnVect_coorH ( pO_H . CoordoH ( iloc ) , d_pO_H_i , tab_norme ( iloc ) ) ;
} ;
// maintenant on calcule la base d_Op_B correspondante
for ( int i = 1 ; i < 3 ; i + + )
d_Op_B . CoordoB ( i ) = d_Op_H . CoordoH ( i ) * gijBB + Op_H . CoordoH ( i ) * dgijBB ;
} ;
*/
// on calcul la variation de matrice de passage de la base g_i vers la base O'_a
// O'_a = beta_a^{.i} * g_i
if ( type_transport = = 0 )
// transport de type contravariant
{ for ( int a = 1 ; a < 3 ; a + + )
{ const CoordonneeH & alpha_H_a = alpha_H . CoordoH ( a ) ;
// on calcul d'abord le produit alpha_a^l * alpha_a^m * d_g_ij(l,m)
double inter = 0. ;
for ( int l = 1 ; l < 3 ; l + + )
for ( int m = 1 ; m < 3 ; m + + )
inter + = alpha_H_a ( l ) * alpha_H_a ( m ) * dgijBB ( l , m ) ;
for ( int i = 1 ; i < 3 ; i + + )
{ double & d_beta_ai = d_beta ( a , i ) ; // pour simplifier
// ajout des termes or boucle
d_beta_ai * = - 0.5 * alpha_H_a ( i ) * inter / PUISSN ( tab_norme ( a ) , 3 ) ;
} ;
} ;
// on calcule ensuite la variation de gamma
d_beta_transpose = d_beta . Transpose ( ) ;
//cout << "\n gamma: ";gamma.Affiche();
// d_gamma = (gamma * d_beta_transpose);
d_gamma = - gamma * d_beta_transpose * gamma ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n d_beta: " ; d_beta . Affiche ( ) ;
cout < < " \n d_beta_transpose: " ; d_beta_transpose . Affiche ( ) ;
cout < < " \n d_gamma: " ; d_gamma . Affiche ( ) ;
d_gamma = - d_gamma ;
cout < < " \n d_gamma: " ; d_gamma . Affiche ( ) ;
} ;
# endif
}
else
{ cout < < " \n **** cas en attente "
< < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... " < < endl ;
Sortie ( 1 ) ;
} ;
// calcul des coordonnées de la variation de déformation dans le repère O'_i
// -- 1) en coordonnees contravariantes tout d'abord variations dans g_i
// epsHH = gijHH * epsBB * gijHH dans g_i
d_epsHH = dgijHH * epsBB * gijHH + gijHH * depsBB * gijHH
+ gijHH * epsBB * dgijHH ;
//cout <<"\n d_epsHH: "; d_epsHH.Ecriture(cout);
// -- maintenant on s'occupe du changement de base
// les beta et gamma sont des matrices et non des tenseurs ... on transforme localement
// en matrice
d_epsHH . Matrice_composante ( mat_d_epsHH ) ;
// -- calcul final de la variation de déformation dans le repère O'_i
// rappel du changement de base : res = (gamma * res) * gamma.Transpose();
//cout << "\n d_gamma: ";d_gamma.Affiche();
mat_d_eps_p_HH = ( d_gamma * mat_epsHH * gamma_transpose )
+ ( gamma * mat_d_epsHH * gamma_transpose )
+ gamma * mat_epsHH * d_gamma . Transpose ( ) ;
//cout << "\n mat_d_eps_p_HH: ";mat_d_eps_p_HH.Affiche();
// -- 2) calcul de la variation des contraintes dans le repère O_p
for ( int i = 1 ; i < 3 ; i + + )
d_eps_ii ( i ) = mat_d_eps_p_HH ( i , i ) ; // les def de la diagonale
d_sig_ii = inv_loi * d_eps_ii ; // les contraintes en ii
for ( int i = 1 ; i < 3 ; i + + )
{ dsigHH . Coor ( i , i ) = d_sig_ii ( i ) ; // affectation des contraintes en ii
} ;
// puis les contraintes en cisaillement
dsigHH . Coor ( 1 , 2 ) = 2. * G12 * mat_d_eps_p_HH ( 1 , 2 ) ;
//cout <<"\n dsigHH en O_p : "; dsigHH.Ecriture(cout);
// -- 3) calcul de la variation des contraintes dans le repère g_i
// c'est l'opération inverse et beta_transpose joue le rôle de gamma dans l'autre sens
sigHH . Var_tenseur_dans_nouvelle_base ( beta_transpose , dsigHH , d_beta_transpose ) ;
//cout <<"\n dsigHH en gi : "; dsigHH.Ecriture(cout);
double untiers = 1. / 3. ;
switch ( cas_calcul )
{ case 0 : // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break ;
}
case 1 : // calcul de la partie déviatorique seule
{ // passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * sigHH + gijBB * dsigHH ;
double d_trace_sig = d_sigBH . Trace ( ) ;
d_sigBH - = ( untiers * d_trace_sig ) * IdBH2 ;
// passage en deux fois contravariant
dsigHH = dgijHH * sigBH + gijHH * d_sigBH ;
break ;
}
case 2 : // calcul de la partie sphérique seule
{ // passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * sigHH + gijBB * dsigHH ;
double d_trace_sig = d_sigBH . Trace ( ) ;
d_sigBH = ( untiers * d_trace_sig ) * IdBH2 ;
// passage en deux fois contravariant
dsigHH = dgijHH * sigBH + gijHH * d_sigBH ;
break ;
}
default : break ; //l'erreur a déjà été traitée dans le calcul de la contrainte
} ;
////----------------- debug
// if ((i==2) || (i==5))
// {cout << "\n dsighh("<<i<<")="<<dsigHH<<" "
// << " dgijHH= " << dgijHH << " depsBB= " << depsBB ;
// };
//----------- fin debug
} ;
////----------------- debug
//cout << "\n\n\n"<<endl;Sortie(1);
//----------- fin debug
////debug
//cout << "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt ";
//cout << "\n sigHH: "; sigHH.Ecriture(cout);
//cout << "\n epsBB: "; epsBB.Ecriture(cout);
// << " epsBH.Trace()= " << Ieps
// << " sigBH.Trace()= " << sigBH.Trace() << " module_compressibilite= " << module_compressibilite;
////fin debug
LibereTenseur ( ) ;
} ;
// void Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB
// ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien
// ,TenseurHH& sigHH,TenseurHHHH& d_sigma_deps
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Umat_cont& ex) ; //= 0;
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// en_base_orthonormee:
// si true: le tenseur de contrainte en entrée est en orthonormee
// le tenseur de déformation et son incrémentsont également en orthonormees
// si = false: les bases transmises sont utilisées, sinon il s'agit de la base orthonormeee fixe
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void Loi_ortho2D_C_entrainee : : Calcul_dsigma_deps ( bool en_base_orthonormee , TenseurHH & , TenseurBB &
, TenseurBB & epsBB_tdt , TenseurBB & , double & , double &
, TenseurHH & sigHH_tdt , TenseurHHHH & d_sigma_deps_
, EnergieMeca & energ , const EnergieMeca &
, double & module_compressibilite , double & module_cisaillement
, const Met_abstraite : : Umat_cont & ex )
{
# ifdef MISE_AU_POINT
if ( epsBB_tdt . Dimension ( ) ! = 2 )
{ cout < < " \n Erreur : la dimension devrait etre 2 ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps \n " ;
Sortie ( 1 ) ;
} ;
# endif
2023-05-03 17:23:49 +02:00
bool affichage = ( Permet_affichage ( ) > 5 ) ;
2021-09-23 11:21:15 +02:00
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n --- loi de comportement orthotrope entrainee --- " ;
} ;
# endif
const Tenseur2HH & gijHH = * ( ( Tenseur2HH * ) ex . gijHH_tdt ) ; // " " " "
const Tenseur2BB & gijBB = * ( ( Tenseur2BB * ) ex . gijBB_tdt ) ; // " " " "
const Tenseur2BB & epsBB = * ( ( Tenseur2BB * ) & epsBB_tdt ) ; // passage en dim 2
Tenseur2HH & sigHH = * ( ( Tenseur2HH * ) & sigHH_tdt ) ; // " " " "
Tenseur2HHHH & d_sigma_deps = * ( ( Tenseur2HHHH * ) & d_sigma_deps_ ) ;
Tenseur2BH epsBH = epsBB * gijHH ; // deformation en mixte
Tenseur2HH epsHH ( gijHH * epsBH ) ; // en deuxfois contra
int dim = ParaGlob : : Dimension ( ) ; // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = * ( ( SaveResulLoi_ortho2D_C_entrainee * ) saveResul ) ;
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH & Op_H = save_resul . Op_H ;
Tableau < double > tab_norme ( 2 ) ;
if ( type_transport = = 0 )
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
# ifdef MISE_AU_POINT
if ( save_resul . O_H = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseH & O_H = ( * save_resul . O_H ) ; // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for ( int a = 1 ; a < 3 ; a + + )
{ CoordonneeH & inter = alpha_H . CoordoH ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
inter ( i ) = O_H ( a ) . ScalHH ( ( * ex . giH_0 ) ( i ) ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n O_H( " < < a < < " ): " ; O_H ( a ) . Affiche ( ) ;
cout < < " \n giH_0( " < < a < < " ): " ; ( * ex . giH_0 ) ( a ) . Affiche ( ) ;
//if ((*ex.giH_0)(a).Norme() < ConstMath::petit)
// cout << "\n debug lor_ortho pb ";
// cout << "\n alpha_H("<<a<<"): ";alpha_H(a).Affiche();
} ;
# endif
} ;
// calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
// récup du conteneur et affectation des coordonnées initiales
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// que O_H(a), mais exprimés dans le repère actuel \hat \vec g_j
CoordonneeH & Op_H_a = Op_H . CoordoH ( a ) ; // pour simplifier
Op_H_a = alpha_H ( a ) ;
// calcul de la norme du vecteur Op_H_a
double norme = sqrt ( Op_H_a * gijBB * Op_H_a ) ;
tab_norme ( a ) = norme ;
// coordonnées finales
Op_H_a / = norme ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n Op_H( " < < a < < " ): " ;
Op_H_a . Affiche ( ) ;
cout < < " \n giB_tdt( " < < a < < " ): " ; ( * ex . giB_tdt ) ( a ) . Affiche ( ) ;
cout < < " \n giH_tdt( " < < a < < " ): " ; ( * ex . giH_tdt ) ( a ) . Affiche ( ) ;
// affichage du repère tournée
CoordonneeB V ( dim ) ;
for ( int j = 1 ; j < = 2 ; j + + ) V + = ( * ex . giB_tdt ) ( j ) * Op_H_a ( j ) ;
cout < < " \n op_H( " < < a < < " ): en absolu " < < V ;
} ;
# endif
} ;
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
# ifdef MISE_AU_POINT
if ( save_resul . O_B = = NULL )
{ cout < < " \n *** erreur, le repere d'anisotropie n'est pas defini "
< < " on ne peut pas continuer " < < flush ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps \n " ;
Sortie ( 1 ) ;
} ;
# endif
BaseB & O_B = ( * save_resul . O_B ) ; // pour simplifier
for ( int a = 1 ; a < 3 ; a + + )
{ // tout d'abord la base non normalisée
CoordonneeB & Op_B_a = Op_B . CoordoB ( a ) ;
// calcul de la norme du vecteur Op_B_a
double norme = sqrt ( Op_B_a * gijHH * Op_B_a ) ;
// coordonnées finales
Op_B_a / = norme ;
} ;
// maintenant on calcule la base Op_H correspondante
for ( int i = 1 ; i < 3 ; i + + )
Op_H . CoordoH ( i ) = Op_B . CoordoB ( i ) * gijHH ;
} ;
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for ( int i = 1 ; i < 3 ; i + + )
for ( int j = 1 ; j < 3 ; j + + )
{ beta ( i , j ) = Op_H ( i ) ( j ) ; } ;
// puis on calcul les coordonnées de la base duale
beta_transpose = beta . Transpose ( ) ;
gamma = beta_transpose . Inverse ( ) ;
gamma_transpose = gamma . Transpose ( ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n beta: " ; beta . Affiche ( ) ;
cout < < " \n beta_transpose: " ; beta_transpose . Affiche ( ) ;
cout < < " \n gamma: " ; gamma . Affiche ( ) ;
cout < < " \n gamma_transpose: " ; gamma_transpose . Affiche ( ) ;
} ;
# endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'_i
# ifdef MISE_AU_POINT
if ( affichage )
{ // Tenseur2BB eps_p_BB(epsBB);
cout < < " \n eps_p_BB en g^i: " ; epsBB . Ecriture ( cout ) ;
Tenseur2BB tiutiu ;
epsBB . BaseAbsolue ( tiutiu , * ( ex . giH_tdt ) ) ;
cout < < " \n eps en absolu : " ; tiutiu . Ecriture ( cout ) ;
} ;
# endif
// il faut passer en 2 fois contravariant
Tenseur2HH eps_p_HH ( epsHH ) ; // init
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n eps_p_HH en g_i: " ; eps_p_HH . Ecriture ( cout ) ;
} ;
# endif
eps_p_HH . ChBase ( gamma ) ; // res = (gamma * res) * gamma.Transpose();
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n eps_p_HH: " ; eps_p_HH . Ecriture ( cout ) ;
TenseurHH * toto = NevezTenseurHH ( eps_p_HH ) ;
toto - > ChBase ( beta_transpose ) ;
cout < < " \n retour dans la base g^i de eps^{ij} : " ; toto - > Ecriture ( cout ) ;
TenseurBB * titi = NevezTenseurBB ( gijBB * ( * toto ) * gijBB ) ;
cout < < " \n def eps_ij : " ; titi - > Ecriture ( cout ) ;
delete toto ; delete titi ;
} ;
# endif
double untiers = 1. / 3. ;
// dans le cas de fonctions nD récupération des valeurs
if ( ! null_fct_para )
//rappel: Tableau <Fonction_nD* > fct_para; // fonction nD éventuelle d'évolution des paramètres
{ // un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef ( 7 ) ;
coef ( 1 ) = & E1 ; coef ( 2 ) = & E2 ; coef ( 3 ) = & E3 ;
coef ( 4 ) = & nu12 ; coef ( 5 ) = & nu13 ; coef ( 6 ) = & nu23 ;
coef ( 7 ) = & G12 ;
// opération de transmission de la métrique
const Met_abstraite : : Impli * ex_impli = NULL ;
const Met_abstraite : : Expli_t_tdt * ex_expli_tdt = NULL ;
const Met_abstraite : : Umat_cont * ex_expli = & ex ;
// on passe en revue les fonctions nD
for ( int i = 1 ; i < 8 ; i + + )
{ if ( fct_para ( i ) ! = NULL )
{ Fonction_nD * pt_fonct = fct_para ( i ) ; // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau < double > & tab_val = Loi_comp_abstraite : : Loi_comp_Valeur_FnD_Evoluee
( pt_fonct , 1 // une seule valeur attendue en retour
, ex_impli , ex_expli_tdt , ex_expli
, NULL
, NULL
, NULL
) ;
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io < Ddl_enum_etendu > & li_enu_scal = pt_fonct - > Li_enu_etendu_scalaire ( ) ;
List_io < TypeQuelconque > & li_quelc = pt_fonct - > Li_equi_Quel_evolue ( ) ;
bool absolue = true ; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau < double > val_ddl_enum ( Valeur_multi_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_enu_scal , ex_impli , ex_expli_tdt , ex_expli , NULL )
) ;
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
( absolue , TEMPS_tdt , li_quelc , ex_impli , ex_expli_tdt , ex_expli , NULL ) ;
// calcul de la valeur et retour dans tab_ret
Tableau < double > & tab_val = pt_fonct - > Valeur_FnD_Evoluee ( & val_ddl_enum , & li_enu_scal , & li_quelc , NULL , NULL ) ;
# ifdef MISE_AU_POINT
if ( tab_val . Taille ( ) ! = 1 )
{ cout < < " \n Erreur : la fonction nD relative au parametre materiau " < < i
< < " doit calculer un scalaire or le tableau de retour est de taille "
< < tab_val . Taille ( ) < < " ce n'est pas normal ! \n " ;
cout < < " Loi_ortho2D_C_entrainee::Calcul_SigmaHH \n " ;
Sortie ( 1 ) ;
} ;
# endif
*/
// on récupère le premier élément du tableau uniquement
( * coef ( i ) ) = tab_val ( 1 ) ;
} ;
} ;
} ;
// puis fabrication de la matrice inv_loi
{ // on commence par remplir la matrice
inv_loi ( 1 , 1 ) = 1. / E1 ; inv_loi ( 2 , 2 ) = 1. / E2 ;
inv_loi ( 1 , 2 ) = inv_loi ( 2 , 1 ) = - nu12 / E1 ;
inv_loi = inv_loi . Inverse ( ) ; // on inverse la matrice
} ;
// on vérifie éventuellement la convexité
if ( verification_convexite )
Verif_convexite ( ) ;
// calcul des contraintes dans le repère O_p
Vecteur eps_ii ( 2 ) ; Vecteur sig_ii ( 2 ) ;
for ( int i = 1 ; i < 3 ; i + + )
eps_ii ( i ) = eps_p_HH ( i , i ) ;
sig_ii = inv_loi * eps_ii ;
for ( int i = 1 ; i < 3 ; i + + )
{ sigHH . Coor ( i , i ) = sig_ii ( i ) ;
} ;
sigHH . Coor ( 1 , 2 ) = 2. * G12 * eps_p_HH ( 1 , 2 ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n sig_abHH : " ; sigHH . Ecriture ( cout ) ;
} ;
# endif
Tenseur2HH sig_ab_HH ( sigHH ) ;
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if ( sortie_post )
{ if ( save_resul . eps_loc_HH = = NULL )
{ save_resul . eps_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . sig_loc_HH = NevezTenseurHH ( 2 ) ;
save_resul . para_loi = new Vecteur ( 7 ) ;
} ;
( * save_resul . eps_loc_HH ) = eps_p_HH ;
( * save_resul . sig_loc_HH ) = sig_ab_HH ;
// paramètres de la loi
( * save_resul . para_loi ) ( 1 ) = E1 ; ( * save_resul . para_loi ) ( 2 ) = E2 ;
( * save_resul . para_loi ) ( 3 ) = E3 ;
( * save_resul . para_loi ) ( 4 ) = nu12 ; ( * save_resul . para_loi ) ( 5 ) = nu13 ;
( * save_resul . para_loi ) ( 6 ) = nu23 ;
( * save_resul . para_loi ) ( 7 ) = G12 ;
} ;
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH . ChBase ( beta_transpose ) ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n sig_ijHH complet : " ; sigHH . Ecriture ( cout ) ;
Tenseur2HH tutu ;
sigHH . BaseAbsolue ( tutu , * ( ex . giB_tdt ) ) ;
cout < < " \n sig en absolu : " ; tutu . Ecriture ( cout ) ;
} ;
# endif
// passage dans la variance mixte
2023-05-03 17:23:49 +02:00
Tenseur2BH sigBH = gijBB * sigHH ;
2021-09-23 11:21:15 +02:00
switch ( cas_calcul )
{ case 0 : // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break ;
}
case 1 : // calcul de la partie déviatorique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH - = ( untiers * trace_sig ) * IdBH2 ;
sigHH - = ( untiers * trace_sig ) * gijHH ;
break ;
}
case 2 : // calcul de la partie sphérique seule
{ double trace_sig = sigBH . Trace ( ) ;
sigBH = ( untiers * trace_sig ) * IdBH2 ;
sigHH = ( untiers * trace_sig ) * gijHH ;
break ;
}
default :
{ cout < < " \n erreur l'indicateur cas_calcul= " < < cas_calcul < < " n'a pas une valeur correcte !! "
< < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... " ;
Sortie ( 1 ) ;
}
} ;
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n epsBB= " < < epsBB < < " gijBB_tdt= " < < gijBB < < " gijHH_tdt= " < < gijHH < < " " ;
cout < < " \n sighh= " < < sigHH < < " " < < flush ;
} ;
# endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12 * E2 / E1 ;
save_resul . eps33 = - 1 / ( 1. - nu12 * nu21 ) * (
epsBH ( 1 , 1 ) * ( nu12 * nu23 + nu13 ) + epsBH ( 2 , 2 ) * ( nu23 + nu13 * nu21 )
) ;
// traitement des énergies
energ . Inita ( 0. ) ;
energ . ChangeEnergieElastique ( 0.5 * ( sigHH & & epsBB ) ) ;
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) ; // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0. ; // init
switch ( type_de_deformation )
{ case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
// cas d'une déformation d'Almansi
{ // epsBB33 = 1/2 * (1. - (h0/h)^2)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt ( 1. / ( 1. - 2. * save_resul . eps33 ) ) ;
} ;
break ;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp ( save_resul . eps33 ) ;
} ;
break ;
default :
cout < < " \n Erreur : type de deformation qui n'est pas actuellement pris en compte, type= "
< < Nom_type_deformation ( type_de_deformation ) ;
cout < < " \n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n " ;
Sortie ( 1 ) ;
} ;
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai ) ;
// pour le module de compressibilité, choix entre les différents cas
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 2 ) )
{ if ( log_var_vol > ConstMath : : petit )
{ module_compressibilite = untiers * sigBH . Trace ( ) / ( log_var_vol ) ; }
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 3 directions d'orthotropie (cf. théorie)
{ double unsurKs1 = 1. / E1 - nu12 / E1 - nu13 / E1 ;
double unsurKs2 = - nu12 / E1 + 1. / E2 - nu23 / E2 ;
double unsurKs3 = - nu13 / E1 - nu23 / E2 + 1. / E3 ;
module_compressibilite = untiers * untiers * ( 1. / unsurKs1 + 1. / unsurKs2 + 1. / unsurKs3 ) ;
} ;
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{ module_compressibilite = 0. ;
} ;
# ifdef MISE_AU_POINT
if ( Permet_affichage ( ) > 4 )
{ cout < < " \n var_vol= " < < ( ( * ( ex . jacobien_tdt ) ) / ( * ( ex . jacobien_0 ) ) * var_epai )
< < " log_var_vol= " < < log_var_vol
< < " sigBH.Trace()= " < < sigBH . Trace ( )
< < " module_compressibilite= " < < module_compressibilite
< < flush ;
if ( Permet_affichage ( ) > 5 ) cout < < " \n cas_calcul= " < < cas_calcul ;
} ;
# endif
// pour la partie cisaillement on garde la forme associée à la loi
// on prend la moyenne des 3
if ( ( cas_calcul = = 0 ) | | ( cas_calcul = = 1 ) )
{ module_cisaillement = 2. * ( G12 ) ; }
else
// en purement sphérique, le module est supposé nul
{ module_cisaillement = 0. ; } ;
// ----- calcul de l'opérateur tangent -----------
// calcul des variations de sigma / eps dans le repère transporté
Tenseur2HHBB var_sig_ab_cd_HHBB ;
for ( int i = 1 ; i < 3 ; i + + )
for ( int j = 1 ; j < 3 ; j + + )
var_sig_ab_cd_HHBB . Change ( i , i , j , j , inv_loi ( i , j ) ) ;
var_sig_ab_cd_HHBB . Change ( 1 , 2 , 1 , 2 , G12 ) ; // du coup = (1,2,2,1) = (2,1,1,2) = (2,1,2,1)
# ifdef MISE_AU_POINT
if ( affichage )
{ cout < < " \n var_sig_ab_cd_HHBB= " ;
var_sig_ab_cd_HHBB . Affiche_bidim ( cout ) ;
} ;
# endif
// cas de la variation des beta_a^{.i} par rapport aux eps_kl
// on va les stocker dans un tableau d_beta(a,i) de tenseur HH
Tableau2 < Tenseur2HH > d_beta_HH ( 2 , 2 ) ;
Tableau2 < Tenseur2HH > d_beta_transpose_HH ( 2 , 2 ) ;
if ( type_transport = = 0 )
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
BaseH & O_H = ( * save_resul . O_H ) ; // pour simplifier
for ( int a = 1 ; a < 3 ; a + + )
{ // calcul de la norme du vecteur O'_a
CoordonneeH alpha_H_a = alpha_H ( a ) ;
double n_O_a = tab_norme ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
{ d_beta_transpose_HH ( i , a )
= d_beta_HH ( a , i )
= - ( alpha_H_a ( i )
/ ( n_O_a * n_O_a * n_O_a ) ) * Tenseur2HH : : Prod_tensoriel ( alpha_H_a , alpha_H_a ) ;
} ;
} ;
} ; // fin du transport 0
//**** à faire le second transport
// vérif d_beta OK
/*{// vérif en différence finie de d_beta
for ( int a = 1 ; a < 3 ; a + + )
{ CoordonneeH alpha_H_a = alpha_H ( a ) ;
//Tenseur2HH toto(Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur2HH titi;
//for (int j=1;j<3;j++)
// for (int i=1;i<3;i++)
// titi.Coor(i,j) = alpha_H_a(i) * alpha_H_a(j);
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a) numerique = ";
//titi.Ecriture(cout);
// calcul de la norme du vecteur O'_a
double d_beta_num = 0. ;
double n_O_a = tab_norme ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
{ d_beta_num = d_beta_HH ( a , i ) & & epsBB ;
cout < < " \n delta_beta( " < < a < < " , " < < i < < " )= "
< < ( beta ( a , i ) - alpha_H_a ( i ) ) < < " num: " < < d_beta_num
< < " beta(a,i)= " < < beta ( a , i ) < < " alpha_H_a(i)= " < < alpha_H_a ( i ) ;
}
}
} ;
Sortie ( 1 ) ;
*/
// on calcule maintenant la variation de gamma
Tableau2 < Tenseur2HH > d_gamma_HH ( 2 , 2 ) ;
for ( int b = 1 ; b < 3 ; b + + )
for ( int j = 1 ; j < 3 ; j + + )
{ for ( int a = 1 ; a < 3 ; a + + )
for ( int i = 1 ; i < 3 ; i + + )
d_gamma_HH ( b , j ) - = ( gamma ( a , j ) * gamma ( b , i ) ) * d_beta_HH ( a , i ) ;
} ;
/*
// vérification numérique de d_gamma
// on a \hat{\vec g}_j = {\gamma}_{.j}^{b}~\hat{\vec O'}_b
{ Mat_pleine gamma_0 ( 2 , 2 ) ;
Mat_pleine O_p_0_ij ( 2 , 2 ) ; Mat_pleine O_p_tdt_ij ( 2 , 2 ) ;
for ( int a = 1 ; a < 3 ; a + + )
{
CoordonneeH alpha_H_a = alpha_H ( a ) ;
//Tenseur2HH toto(Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur2HH titi;
//for (int j=1;j<3;j++)
// for (int i=1;i<3;i++)
// titi.Coor(i,j) = alpha_H_a(i) * alpha_H_a(j);
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a) numerique = ";
//titi.Ecriture(cout);
// calcul de la norme du vecteur O'_a
double d_beta_num = 0. ;
double n_O_a = tab_norme ( a ) ;
for ( int i = 1 ; i < 3 ; i + + )
{ d_beta_num = d_beta_HH ( a , i ) & & epsBB ;
cout < < " \n delta_beta( " < < a < < " , " < < i < < " )= "
< < ( beta ( a , i ) - alpha_H_a ( i ) ) < < " num: " < < d_beta_num
< < " beta(a,i)= " < < beta ( a , i ) < < " alpha_H_a(i)= " < < alpha_H_a ( i ) ;
}
}
} ;
*/
//variation des déformations epsHH / eps_ij dans le repère initial gi
// Tenseur2HHHH var_eps_nm_kl_HHHH(Tenseur2HHHH::Prod_tensoriel_barre(gijHH,gijHH));
//--// Tenseur2HHHH var_eps_nm_kl_HHHH(Tenseur2HHHH::Prod_tensoriel_croise(gijHH,gijHH));
//cout << "\n (1) var_eps_nm_kl_HHHH= ";
//var_eps_nm_kl_HHHH.Affiche_bidim(cout);
//{// pour vérification on va calculer par composante
// Tenseur2HHHH deps_nmkl;
// for (int n=1;n<3;n++) for (int m=1;m<3;m++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
// { double inter= gijHH(n,k) * gijHH(l,m);
// deps_nmkl.Change(n,m,k,l,inter);
// };
// cout << "\n (1) deps_nmkl= calcul en composantes";
// deps_nmkl.Affiche_bidim(cout);
//}
// Tenseur2HHHH interHHHH1(Tenseur2HHHH::Prod_tensoriel_barre(gijHH,eps_p_HH));
// Tenseur2HHHH interHHHH2(Tenseur2HHHH::Prod_tensoriel_barre(eps_p_HH,gijHH));
//--// Tenseur2HHHH interHHHH1(Tenseur2HHHH::Prod_tensoriel_croise(gijHH,eps_HH));
//--// Tenseur2HHHH interHHHH2(Tenseur2HHHH::Prod_tensoriel_croise(eps_HH,gijHH));
//Tenseur2HHHH interHHHH2(interHHHH1+interHHHH2);
//cout << "\n interHHHH2= ";
//interHHHH2.Affiche_bidim(cout);
//cout << "\n interHHHH1= ";
//interHHHH1.Affiche_bidim(cout);
//cout << "\n interHHHH2= ";
//interHHHH2.Affiche_bidim(cout);
//{Tenseur2HHHH A(interHHHH2);
//A += interHHHH2;
//cout << "\n A= ";A.Affiche_bidim(cout);
//Tenseur2HHHH B(var_eps_nm_kl_HHHH);
//cout << "\n (1) B= ";B.Affiche_bidim(cout);
//B -= 2. * interHHHH2;
//cout << "\n B= ";B.Affiche_bidim(cout);
//
//}
//--// var_eps_nm_kl_HHHH -= 2. * (interHHHH1+interHHHH2);
//Tenseur2HHHH::Prod_tensoriel_barre(gijHH,eps_p_HH);
//(interHHHH1+interHHHH2);
//--//cout << "\n var_eps_nm_kl_HHHH: ";
//--//var_eps_nm_kl_HHHH.Affiche_bidim(cout);
/*
// vérif numérique de la variation
{ Tenseur2HH delta_eps = var_eps_nm_kl_HHHH & & epsBB ;
cout < < " \n delta_eps= " ; delta_eps . Ecriture ( cout ) ;
Tenseur2HH eps_p_HH ( gijHH * epsBB * gijHH ) ;
cout < < " \n eps_p_HH en g_i: " ; eps_p_HH . Ecriture ( cout ) ;
// vérif var de g^ij
Tenseur2HHHH d_gijHH ( Tenseur2HHHH : : Prod_tensoriel_croise ( gijHH , gijHH ) ) ;
d_gijHH * = - 2. ;
Tenseur2HH delta_gijHH ( gijHH - ( * ex . gijHH_0 ) ) ;
Tenseur2HH delta_gijHH_num = d_gijHH & & epsBB ;
cout < < " \n delta_gijHH= " ; delta_gijHH . Ecriture ( cout ) ;
cout < < " \n delta_gijHH_num (1) " ; delta_gijHH_num . Ecriture ( cout ) ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_gijHH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_gijHH_num . Coor ( n , m ) + = d_gijHH ( n , m , i , j ) * epsBB ( i , j ) ;
}
cout < < " \n delta_gijHH_num (2)) = " ; delta_gijHH_num . Ecriture ( cout ) ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_gijHH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_gijHH_num . Coor ( n , m ) + = - 2. * gijHH ( n , i ) * gijHH ( j , m ) * epsBB ( i , j ) ;
}
cout < < " \n delta_gijHH_num (2)) = " ; delta_gijHH_num . Ecriture ( cout ) ;
Tenseur2HHHH d_gijHH_num ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
d_gijHH_num . Change ( n , m , i , j , ( - 2. * gijHH ( n , i ) * gijHH ( j , m ) ) ) ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
{ cout < < " \n d_gijHH( " < < n < < " , " < < m < < " , " < < i < < " , " < < j < < " ) et "
< < " -2.* gijHH( " < < n < < " , " < < i < < " ) * gijHH( " < < j < < " , " < < m < < " )= et d_gijHH_num "
< < d_gijHH ( n , m , i , j ) < < " "
< < ( - 2. * gijHH ( n , i ) * gijHH ( j , m ) ) < < " "
< < d_gijHH_num ( n , m , i , j ) ;
}
}
*/
//{Tenseur2HH A(1,2,2,0.,0.,0.);
// Tenseur2HH B(4,5,6,0.,0.,0.);
// Tenseur2HHHH C(Tenseur2HHHH::Prod_tensoriel(A,B));
//cout << "\n C= ";C.Affiche_bidim(cout);
// Tenseur2HHHH C1(Tenseur2HHHH::Prod_tensoriel_barre(A,B));
//cout << "\n Prod_tensoriel_barre(A,B)= ";C1.Affiche_bidim(cout);
// Tenseur2HHHH C2(Tenseur2HHHH::Prod_tensoriel_croise(A,B));
//cout << "\n Prod_tensoriel_croise(A,B)= ";C2.Affiche_bidim(cout);
// Tenseur2HHHH C2(Tenseur2HHHH::Prod_tensoriel_croise_croise(A,B));
//cout << "\n Prod_tensoriel_croise_croise(A,B)= ";C2.Affiche_bidim(cout);
//}
//--// var_eps_nm_kl_HHHH -= 2. * (interHHHH1+interHHHH2);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH deps_nmkl_HHHH ;
{ for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + ) for ( int k = 1 ; k < 3 ; k + + ) for ( int l = 1 ; l < 3 ; l + + )
{ double inter = gijHH ( n , k ) * gijHH ( l , m )
- 2. * ( gijHH ( n , k ) * epsHH ( l , m ) + epsHH ( n , l ) * gijHH ( m , k ) ) ;
deps_nmkl_HHHH . Change ( n , m , k , l , inter ) ;
} ;
//// vérification du stockage
//cout << "\n deps_nmkl= calcul en composantes";
//for (int n=1;n<3;n++) for (int m=1;m<3;m++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
// { double inter= gijHH(n,k) * gijHH(l,m)
// -2.*(gijHH(n,k) * epsHH(l,m) + epsHH(n,l) * gijHH(m,k));
// cout << "\n deps_nmkl("<<n <<","<<m<<","<<k<<","<<l<<") = et formule directe "
// << inter <<" " << deps_nmkl_HHHH(n,m,k,l);
// };
} ;
// OK vérif variation deps_nmkl_HHHH
/*{
Tenseur2HH delta_epsHH_num ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_epsHH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_epsHH_num . Coor ( n , m ) + = deps_nmkl_HHHH ( n , m , i , j ) * epsBB ( i , j ) ;
}
cout < < " \n delta_epsHH_num = " ; delta_epsHH_num . Ecriture ( cout ) ;
cout < < " \n epsHH = " ; epsHH . Ecriture ( cout ) ;
}
Sortie ( 1 ) ;
*/
//variation des déformations epsHH / eps_ij dans le repère transporté / au eps_kl
// c'est à dire la variation de eps^ab / eps_kl
//--// Tenseur2HHHH var_eps_ab_kl_HHHH = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
//--// (gamma,var_eps_nm_kl_HHHH,d_gamma_HH,eps_p_HH);
//--//cout << "\n var_eps_ab_kl_HHHH= ";
//--//var_eps_ab_kl_HHHH.Affiche_bidim(cout);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH deps_abkl_HHHH ;
{ for ( int a = 1 ; a < 3 ; a + + ) for ( int b = 1 ; b < 3 ; b + + ) for ( int k = 1 ; k < 3 ; k + + ) for ( int l = 1 ; l < 3 ; l + + )
{ double inter = 0. ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
inter + = d_gamma_HH ( a , n ) ( k , l ) * epsHH ( n , m ) * gamma ( b , m )
+ gamma ( a , n ) * deps_nmkl_HHHH ( n , m , k , l ) * gamma ( b , m )
+ gamma ( a , n ) * epsHH ( n , m ) * d_gamma_HH ( b , m ) ( k , l ) ;
deps_abkl_HHHH . Change ( a , b , k , l , inter ) ;
} ;
//cout << "\n deps_abkl= calcul en composantes";
//deps_abkl.Affiche_bidim(cout);
} ;
// OK vérif numérique de la variation
/*{
Tenseur2HH delta_eps_ab_HH_num ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_eps_ab_HH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_eps_ab_HH_num . Coor ( n , m ) + = deps_abkl_HHHH ( n , m , i , j ) * epsBB ( i , j ) ;
}
cout < < " \n delta_eps_ab_HH_num = " ; delta_eps_ab_HH_num . Ecriture ( cout ) ;
cout < < " \n eps_p_HH = " ; eps_p_HH . Ecriture ( cout ) ;
Sortie ( 1 ) ;
}
*/
// variation des contraintes (composantes dans le repère transporté) / au eps_kl
//--// Tenseur2HHHH var_sig_ab_kl_HHHH = var_sig_ab_cd_HHBB && var_eps_ab_kl_HHHH;
TenseurQ2geneHHHH dsig_abkl_HHHH ;
{ // pour vérification on va calculer par composante
for ( int a = 1 ; a < 3 ; a + + ) for ( int b = 1 ; b < 3 ; b + + ) for ( int k = 1 ; k < 3 ; k + + ) for ( int l = 1 ; l < 3 ; l + + )
{ double inter = 0. ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
inter + = var_sig_ab_cd_HHBB ( a , b , n , m ) * deps_abkl_HHHH ( m , n , k , l ) ;
dsig_abkl_HHHH . Change ( a , b , k , l , inter ) ;
} ;
// cout << "\n dsig_abkl= calcul en composantes";
// dsig_abkl.Affiche_bidim(cout);
} ;
//cout << "\n var_sig_ab_kl_HHHH= ";
//var_sig_ab_kl_HHHH.Affiche_bidim(cout);
// OK vérif numérique de la variation
/*{
Tenseur2HH delta_sigma_ab_HH_num ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_sigma_ab_HH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_sigma_ab_HH_num . Coor ( n , m ) + = dsig_abkl_HHHH ( n , m , i , j ) * epsBB ( i , j ) ;
}
cout < < " \n delta_sigma_ab_HH_num = " ; delta_sigma_ab_HH_num . Ecriture ( cout ) ;
cout < < " \n sigma_ab_HH = " ; sig_sauveHH . Ecriture ( cout ) ;
Sortie ( 1 ) ;
}
*/
// variation des contraintes (composantes dans le repère g_i ) / au eps_kl
// on peut maintenant calculer la variation de sig_ij / eps_kl
//--// d_sigma_deps = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
//--// (beta_transpose,var_sig_ab_kl_HHHH,d_beta_transpose_HH,sigHH);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH dsig_ijkl_HHHH ;
{ for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + ) for ( int k = 1 ; k < 3 ; k + + ) for ( int l = 1 ; l < 3 ; l + + )
{ double inter = 0. ;
for ( int a = 1 ; a < 3 ; a + + ) for ( int b = 1 ; b < 3 ; b + + )
inter + = d_beta_HH ( a , i ) ( k , l ) * sig_ab_HH ( a , b ) * beta ( b , j )
+ beta ( a , i ) * dsig_abkl_HHHH ( a , b , k , l ) * beta ( b , j )
+ beta ( a , i ) * sig_ab_HH ( a , b ) * d_beta_HH ( b , j ) ( k , l ) ;
dsig_ijkl_HHHH . Change ( i , j , k , l , inter ) ;
} ;
//cout << "\n deps_abkl= calcul en composantes";
//deps_abkl.Affiche_bidim(cout);
} ;
// vérif numérique de la variation
/*{
Tenseur2HH delta_sigma_ij_HH_num ;
for ( int n = 1 ; n < 3 ; n + + ) for ( int m = 1 ; m < 3 ; m + + )
{ delta_sigma_ij_HH_num . Coor ( n , m ) = 0 ;
for ( int i = 1 ; i < 3 ; i + + ) for ( int j = 1 ; j < 3 ; j + + )
delta_sigma_ij_HH_num . Coor ( n , m ) + = dsig_ijkl_HHHH ( n , m , i , j ) * epsBB ( i , j ) ;
}
cout < < " \n delta_sigma_ij_HH_num = " ; delta_sigma_ij_HH_num . Ecriture ( cout ) ;
cout < < " \n sigma_ij_HH = " ; sigHH . Ecriture ( cout ) ;
Sortie ( 1 ) ;
}
*/
// on passe au tenseur de retour
d_sigma_deps . TransfertDunTenseurGeneral ( dsig_ijkl_HHHH . Symetrise1et2_3et4 ( ) ) ;
//cout << "\n d_sigma_deps= ";
//d_sigma_deps.Affiche_bidim(cout);
//
// d_sigma_deps = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
// (beta,var_sig_ab_kl_HHHH,d_beta_HH,sigHH);
//
//cout << "\n (2) d_sigma_deps= ";
//d_sigma_deps.Affiche_bidim(cout);
// Sortie(1);
/* // 1) la variation de d eps_ij / d eps_kl (dans le repère natuelle
// ici on utilise le fait que IdBB2(i,j) représente le kronecker et idem pour IdHH2(i,j)
// donc on met la variance qui va bien mais elle n'est pas utilisée
// var_eps_ab_BBHH(i,j,k,l) = delta_i^k * delta_j^l : puis avec les symétries
// car on peut changer i et j d'une part et k et l d'autre part
Tenseur2BBHH var_eps_ij_kl_BBHH ( Tenseur2BBHH : : Prod_tensoriel_barre ( IdBB2 , IdHH2 ) ) ;
// 2) la variation d eps_ab / d eps_ij
Tenseur2BBHH var_eps_ab_kl_BBHH = Tenseur2BBHH : : Var_tenseur_dans_nouvelle_base
( beta , var_eps_ij_kl_BBHH , d_beta_HH , eps_p_BB ) ;
// maintenant on calcul la variation de sigma_ab / d epsilon_kl
Tenseur2BBHH var_sig_ab_kl_BBHH = var_sig_ab_cd_BBHH & & var_eps_ab_kl_BBHH ;
// calcul de la variation de l'inverse de beta
// beta_inv = beta.Inverse();
Tableau2 < Tenseur2HH > d_beta_inv_HH ( 2 , 2 ) ;
for ( int b = 1 ; b < 3 ; b + + )
for ( int j = 1 ; j < 3 ; j + + )
{ Tenseur2HH & resHH = d_beta_inv_HH ( j , b ) ;
for ( int a = 1 ; a < 3 ; a + + )
for ( int i = 1 ; i < 3 ; i + + )
resHH - = ( beta_inv ( j , a ) * beta_inv ( i , b ) ) * d_beta_HH ( a , i ) ;
} ;
// on peut maintenant calculer la variation de sig_ij / eps_kl
Tenseur2BBHH var_sig_ij_kl_BBHH = Tenseur2BBHH : : Var_tenseur_dans_nouvelle_base
( beta_inv , var_sig_ab_kl_BBHH , d_beta_inv_HH , sig_BB ) ;
// calcul de la variation de \hat g^ij
Tenseur2HHHH gijkl_HHHH ( Tenseur2HHHH : : Prod_tensoriel_barre ( gijHH , gijHH ) ) ;
Tenseur2HHHH d_gij_kl_HHHH ( - 2. * Tenseur2HHHH : : Prod_tensoriel_barre ( gijHH , gijHH ) ) ;
Tenseur2HHBB interHHBB ( Tenseur2HHBB : : Prod_tensoriel_barre ( gijHH , sig_BB ) ) ;
// puis on calcul l'opérateur tangent dans la la bonne variance
d_sigma_deps = ( gijkl_HHHH & & var_sig_ij_kl_BBHH )
+ ( d_gij_kl_HHHH & & ( Tenseur2BBHH : : Prod_tensoriel_barre ( sig_BB , gijHH ) ) )
+ ( interHHBB & & d_gij_kl_HHHH ) ;
*/
LibereTenseur ( ) ;
LibereTenseurQ ( ) ;
} ;
//vérification de la convexité du potentiel
bool Loi_ortho2D_C_entrainee : : Verif_convexite ( )
{ // double E1,E2,E3,nu12,nu13,nu23,G12,G13,G23; // paramètres de la loi
//1. - \nu_{12} . \nu_{13} . \nu_{23}. \left ( \frac{E_3}{E_1} - \frac{E_2}{E_1}. \frac{E_3}{E_2} \right ) - \nu_{12}^2 . \frac{E_2}{E_1}-\nu_{13}^2 . \frac{E_3}{E_1}-\nu_{23}^2 . \frac{E_3}{E_2} > 0
bool convexe = true ; // vrai a priori
2023-05-03 17:23:49 +02:00
bool affichage = ( Permet_affichage ( ) > 0 ) ;
2021-09-23 11:21:15 +02:00
if ( 1. < = nu12 * nu12 * E2 / E1 )
{ if ( affichage )
cout < < " \n attention nu12*nu12*E2/E1 = " < < ( nu12 * nu12 * E2 / E1 ) < < " , etant superieur a 1. "
< < " le potentiel n'est pas strictement convexe! " ;
convexe = false ;
} ;
if ( 1. < = nu23 * nu23 * E3 / E2 )
{ if ( affichage )
cout < < " \n attention nu23*nu23*E3/E2 = " < < ( nu23 * nu23 * E3 / E2 ) < < " , etant superieur a 1. "
< < " le potentiel n'est pas strictement convexe! " ;
convexe = false ;
} ;
if ( 1. < = nu13 * nu13 * E3 / E1 )
{ if ( affichage )
cout < < " \n attention nu13*nu13*E3/E1 = " < < ( nu13 * nu13 * E3 / E1 ) < < " , etant superieur a 1. "
< < " le potentiel n'est pas strictement convexe! " ;
convexe = false ;
} ;
double x = 1. - nu12 * nu13 * nu23 * ( E3 / E1 - E2 / E1 * E3 / E2 )
- nu12 * nu12 * E2 / E1 - nu13 * nu13 * E3 / E1 - nu23 * nu23 * E3 / E2 ;
if ( x < = 0 )
{ if ( affichage )
cout < < " \n attention: 1. - nu12*nu13*nu23*(E3/E1-E2/E1*E3/E2) "
< < " - nu12*nu12 * E2/E1 - nu13*nu13 * E3/E1 - nu23*nu23 * E3/E2 = "
< < x < < " , etant inferieur ou egal a 0 "
< < " le potentiel n'est pas strictement convexe! " ;
convexe = false ;
} ;
// retour
return convexe ;
} ;