// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) .
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// For more information, please consult: .
#include "UmatAbaqus.h"
#include "NevezTenseur.h"
#include "NevezTenseurQ.h"
#include "ParaGlob.h"
#include "TenseurQ-3.h"
#include "TenseurQ-2.h"
#include "Tenseur3.h"
#include "Tenseur2.h"
#include "ConstMath.h"
// --- fichier pour le tube ------
#ifdef SYSTEM_MAC_OS_CARBON
#include
#include
#else
#include
#include
#endif
#include
#include /* Pour O_WRONLY, etc */
#include // pour les ordres read write close
//------------------------- variables statiques ---------------------------
const UmatAbaqus::ChangementIndex UmatAbaqus::cdex;
// init de la variable statique cdex: cas 3D
// fonctionne aussi avec le cas 3D axi, c'est uniquement le terme (1,2) (= (2,1)) qui est
// non nul
UmatAbaqus::ChangementIndex::ChangementIndex() :
idx_i(6),idx_j(6),odVect(3)
{ idx_i(1)=1;idx_i(2)=2;idx_i(3)=3;idx_i(4)=1;idx_i(5)=1;idx_i(6)=2;
idx_j(1)=1;idx_j(2)=2;idx_j(3)=3;idx_j(4)=2;idx_j(5)=3;idx_j(6)=3;
odVect(1,1)=1;odVect(2,1)=4;odVect(3,1)=5;
odVect(1,2)=4;odVect(2,2)=2;odVect(3,2)=6;
odVect(1,3)=5;odVect(2,3)=6;odVect(3,3)=3;
};
const UmatAbaqus::ChangementIndexCP UmatAbaqus::cdexCP;
// init de la variable statique cdexCP : cas 3D CP
UmatAbaqus::ChangementIndexCP::ChangementIndexCP() :
// 11 -> 1 22 -> 2 12 -> 3
idx_i(3),idx_j(3),odVect(2)
{ idx_i(1)=1;idx_i(2)=2;idx_i(3)=1;
idx_j(1)=1;idx_j(2)=2;idx_j(3)=2;
odVect(1,1)=1;odVect(1,2)=3;odVect(2,2)=2;
odVect(2,1)=3; // stockage symétrique
};
//---------------------- fin variables statiques ---------------------------
// par défaut
UmatAbaqus::UmatAbaqus(int dimension_espace, int nb_vecteur):
// si dimension = 2, on ne peut accepter que nb_vecteur = 2
// donc on prend MiN(dimension_espace,nb_vecteur)
STRESS(NULL),t_sigma(NevezTenseurHH(MiN(dimension_espace,nb_vecteur)))
,STATEV(NULL),v_statev()
,DDSDDE(NULL)
,d_sigma_deps(NevezTenseurHHHH(MiN(dimension_espace,nb_vecteur)*10+MiN(dimension_espace,nb_vecteur)))
,SSE(NULL),SPD(NULL),SCD(NULL)
,energie_elastique(0.),dissipation_plastique(0.),dissipation_visqueuse(0.)
,RPL(NULL),ener_therm_vol_par_utemps(0.)
,DDSDDT(NULL)
,d_sigma_d_tempera(NevezTenseurHH(MiN(dimension_espace,nb_vecteur)))
,DRPLDE(NULL)
,d_ener_therm_vol_deps(NevezTenseurHH(MiN(dimension_espace,nb_vecteur)))
,DRPLDT(NULL),d_ener_therm_dtemper(0.)
,PNEWDT(NULL),pnewdt(0.)
,STRAN(NULL)
,eps_meca(NevezTenseurBB(MiN(dimension_espace,nb_vecteur)))
,DSTRAN(NULL)
,delta_eps_meca(NevezTenseurBB(MiN(dimension_espace,nb_vecteur)))
,TIME(NULL),temps_t(0.),temps_tdt(0.)
,DTIME(NULL),delta_t(0.)
,TemP(NULL),temper_t(0.)
,DTEMP(NULL),delta_temper(0.)
,PREDEF(NULL),ddlNoeA_ptinteg()
,DPRED(NULL),delta_ddlNoeA_ptinteg()
,CMNAME(NULL),nom_materiau()
,NDI(NULL),dim_tens(0)
,NSHR(NULL),nb_tau_ij(0)
,NTENS(NULL),nb_ij_tenseur(0)
,NSTATV(NULL),nb_variables_etat(0)
,PROPS(NULL),proprietes_materiau()
,NPROPS(NULL),nb_proprietes_materiau(0)
,COORDS(NULL),coor_pt(dimension_espace)
,DROT(NULL),mat_corota(3,3) // je crois que l'on est obligé d'être toujours en 3x3
// pour abaqus
,CELENT(NULL),longueur_characteristique(-1)
,DFGRD0(NULL)
,giB_t(dimension_espace,MiN(dimension_espace,nb_vecteur))
,DFGRD1(NULL)
,giB_tdt(dimension_espace,MiN(dimension_espace,nb_vecteur))
,NOEL(NULL),nb_elem(0)
,NPT(NULL),nb_pt_integ(0)
,LAYER(NULL),nb_du_plis(0)
,KSPT(NULL),nb_pt_dans_le_plis(0)
,KSTEP(NULL),nb_step(0)
,KINC(NULL),nb_increment(0)
,passage(0),envoi("Umat_envoi_Hz"),reception("Umat_reception_Hz")
,N_t(dimension_espace),N_tdt(dimension_espace)
{
// on définit les grandeurs pointées au bon endroit dans la chaine de
// caractères
// on considère que les int sont codés sur 4 octets, les doubles sur 8
// On se met dans le cas en 3D (taille maxi) d'où l'ensemble des infos
// STRESS 6*8=48, STATEV rien on n'en tiend pas compte
// DDSDDE 36*8= 288, SSE+SPD+SCD 3*8=24
// RPL 8, DDSDDT 6*8=48, DRPLDE 6*8=48, DRPLDT 8, PNEWDT 8,
// STRAN 6*8=48, DSTRAN 6*8=48
// TIME 2*8=16, DTIME 8, TemP 8, DTEMP 8,
// PREDEF rien on n'en tiens pas compte
// DPRED rien on n'en tiens pas compte
// CMNAME 24 (par défaut sur 24 caractères: dans abaqus c'est sur 80)
// NDI+NSHR+NTENS+NSTATV 4*4=16,
// PROPS rien on n'en tiens pas compte
// NPROPS rien on n'en tiens pas compte
// COORDS 3*8=24, DROT 9*8=72,
// CELENT 8,
// DFGRD0 9*8=72, DFGRD1 9*8=72,
// NOEL+NPT+LAYER+KSPT+KSTEP+KINC 6*4=24
// total 952 octets
// --- en sortie uniquement
DDSDDT = &t_car_x_n.x[0]; // 6
DRPLDE = &t_car_x_n.x[6]; // 6
DDSDDE = &t_car_x_n.x[12]; // 36
// --- en entrée - sortie
RPL = &t_car_x_n.x[48]; // 1
STRESS = &t_car_x_n.x[49]; // 6
SSE = &t_car_x_n.x[55]; // 1
SPD = &t_car_x_n.x[56]; // 1
SCD = &t_car_x_n.x[57]; // 1
DRPLDT = &t_car_x_n.x[58]; // 1
PNEWDT = &t_car_x_n.x[59]; // 1
// --- en entrée seulement
STRAN = &t_car_x_n.x[60]; // 6
DSTRAN = &t_car_x_n.x[66]; // 6
TIME = &t_car_x_n.x[72]; // 2
DTIME = &t_car_x_n.x[74]; // 1
TemP = &t_car_x_n.x[75]; // 1
DTEMP = &t_car_x_n.x[76]; // 1
COORDS = &t_car_x_n.x[77]; // 3
DROT = &t_car_x_n.x[80]; // 9
CELENT = &t_car_x_n.x[89]; // 1
DFGRD0 = &t_car_x_n.x[90]; // 9
DFGRD1 = &t_car_x_n.x[99]; // 9
NDI = &t_car_x_n.n[216]; // 1
NSHR = &t_car_x_n.n[217]; // 1
NTENS = &t_car_x_n.n[218]; // 1
NSTATV = &t_car_x_n.n[219]; // 1
NOEL = &t_car_x_n.n[220]; // 1
NPT = &t_car_x_n.n[221]; // 1
LAYER = &t_car_x_n.n[222]; // 1
KSPT = &t_car_x_n.n[223]; // 1
KSTEP = &t_car_x_n.n[224]; // 1
KINC = &t_car_x_n.n[225]; // 1
CMNAME = &t_car_x_n.tampon[904];
// le nom
nom_materiau=CMNAME;
};
// constructeur de copie
UmatAbaqus::UmatAbaqus(const UmatAbaqus& a) :
STRESS(NULL),t_sigma(NULL)
,STATEV(NULL),v_statev(a.v_statev)
,DDSDDE(NULL),d_sigma_deps(NULL)
,SSE(NULL),SPD(NULL),SCD(NULL)
,energie_elastique(a.energie_elastique)
,dissipation_plastique(a.dissipation_plastique)
,dissipation_visqueuse(a.dissipation_visqueuse)
,RPL(NULL),ener_therm_vol_par_utemps(a.ener_therm_vol_par_utemps)
,DDSDDT(NULL),d_sigma_d_tempera(NULL)
,DRPLDE(NULL),d_ener_therm_vol_deps(NULL)
,DRPLDT(NULL),d_ener_therm_dtemper(a.d_ener_therm_dtemper)
,PNEWDT(NULL),pnewdt(a.pnewdt)
,STRAN(NULL),eps_meca(NULL)
,DSTRAN(NULL),delta_eps_meca(NULL)
,TIME(NULL),temps_t(a.temps_t),temps_tdt(a.temps_tdt)
,DTIME(NULL),delta_t(a.delta_t)
,TemP(NULL),temper_t(a.temper_t)
,DTEMP(NULL),delta_temper(a.delta_temper)
,PREDEF(NULL),ddlNoeA_ptinteg(a.ddlNoeA_ptinteg)
,DPRED(NULL),delta_ddlNoeA_ptinteg(a.delta_ddlNoeA_ptinteg)
,CMNAME(NULL),nom_materiau(a.nom_materiau)
,NDI(NULL),dim_tens(a.dim_tens)
,NSHR(NULL),nb_tau_ij(a.nb_tau_ij)
,NTENS(NULL),nb_ij_tenseur(a.nb_ij_tenseur)
,NSTATV(NULL),nb_variables_etat(a.nb_variables_etat)
,PROPS(NULL),proprietes_materiau(a.proprietes_materiau)
,NPROPS(NULL),nb_proprietes_materiau(a.nb_proprietes_materiau)
,COORDS(NULL),coor_pt(a.coor_pt)
,DROT(NULL),mat_corota(a.mat_corota)
,CELENT(NULL),longueur_characteristique(a.longueur_characteristique)
,DFGRD0(NULL),giB_t(a.giB_t)
,DFGRD1(NULL),giB_tdt(a.giB_tdt)
,NOEL(NULL),nb_elem(a.nb_elem)
,NPT(NULL),nb_pt_integ(a.nb_pt_integ)
,LAYER(NULL),nb_du_plis(a.nb_du_plis)
,KSPT(NULL),nb_pt_dans_le_plis(a.nb_pt_dans_le_plis)
,KSTEP(NULL),nb_step(a.nb_step)
,KINC(NULL),nb_increment(a.nb_increment)
,passage(a.passage),envoi(a.envoi),reception(a.reception)
,N_t(a.N_t),N_tdt(a.N_tdt)
{ // on définit les grandeurs pointées au bon endroit dans la chaine de
// caractères
// on considère que les int sont codés sur 4 octets, les doubles sur 8
// On se met dans le cas en 3D (taille maxi) d'où l'ensemble des infos
// STRESS 6*8=48, STATEV rien on n'en tiend pas compte
// DDSDDE 36*8= 288, SSE+SPD+SCD 3*8=24
// RPL 8, DDSDDT 6*8=48, DRPLDE 6*8=48, DRPLDT 8, PNEWDT 8,
// STRAN 6*8=48, DSTRAN 6*8=48
// TIME 2*8=16, DTIME 8, TemP 8, DTEMP 8,
// PREDEF rien on n'en tiens pas compte
// DPRED rien on n'en tiens pas compte
// CMNAME 20 (par défaut sur 20 caractères: dans abaqus c'est sur 80)
// NDI+NSHR+NTENS+NSTATV 4*4=16,
// PROPS rien on n'en tiens pas compte
// NPROPS rien on n'en tiens pas compte
// COORDS 3*8=24, DROT 9*8=72,
// CELENT 8,
// DFGRD0 9*8=72, DFGRD1 9*8=72,
// NOEL+NPT+LAYER+KSPT+KSTEP+KINC 6*4=24
// total 924 octets
int* pt1 = &(t_car_x_n.n[0]); const int *pt2= &(a.t_car_x_n.n[0]);
for (int i=0;i<232;i++,pt1++,pt2++) *pt1=*pt2;
// --- en sortie uniquement
DDSDDT = &t_car_x_n.x[0]; // 6
DRPLDE = &t_car_x_n.x[6]; // 6
DDSDDE = &t_car_x_n.x[12]; // 36
// --- en entrée - sortie
RPL = &t_car_x_n.x[48]; // 1
STRESS = &t_car_x_n.x[49]; // 6
SSE = &t_car_x_n.x[55]; // 1
SPD = &t_car_x_n.x[56]; // 1
SCD = &t_car_x_n.x[57]; // 1
DRPLDT = &t_car_x_n.x[58]; // 1
PNEWDT = &t_car_x_n.x[59]; // 1
// --- en entrée seulement
STRAN = &t_car_x_n.x[60]; // 6
DSTRAN = &t_car_x_n.x[66]; // 6
TIME = &t_car_x_n.x[72]; // 2
DTIME = &t_car_x_n.x[74]; // 1
TemP = &t_car_x_n.x[75]; // 1
DTEMP = &t_car_x_n.x[76]; // 1
COORDS = &t_car_x_n.x[77]; // 3
DROT = &t_car_x_n.x[80]; // 9
CELENT = &t_car_x_n.x[89]; // 1
DFGRD0 = &t_car_x_n.x[90]; // 9
DFGRD1 = &t_car_x_n.x[99]; // 9
NDI = &t_car_x_n.n[216]; // 1
NSHR = &t_car_x_n.n[217]; // 1
NTENS = &t_car_x_n.n[218]; // 1
NSTATV = &t_car_x_n.n[219]; // 1
NOEL = &t_car_x_n.n[220]; // 1
NPT = &t_car_x_n.n[221]; // 1
LAYER = &t_car_x_n.n[222]; // 1
KSPT = &t_car_x_n.n[223]; // 1
KSTEP = &t_car_x_n.n[224]; // 1
KINC = &t_car_x_n.n[225]; // 1
CMNAME = &t_car_x_n.tampon[904];
// le nom
nom_materiau=CMNAME;
// cas des grandeurs évoluées
if (a.t_sigma != NULL)
t_sigma = NevezTenseurHH(*(a.t_sigma));
if (a.d_sigma_deps != NULL )
d_sigma_deps = NevezTenseurHHHH(*(a.d_sigma_deps));
if (a.d_sigma_d_tempera != NULL)
d_sigma_d_tempera = NevezTenseurHH(*(a.d_sigma_d_tempera));
if (a.d_ener_therm_vol_deps != NULL)
d_ener_therm_vol_deps =NevezTenseurHH(*(a.d_ener_therm_vol_deps));
if (a.eps_meca != NULL)
eps_meca = NevezTenseurBB(*(a.eps_meca));
if (a.delta_eps_meca != NULL)
delta_eps_meca = NevezTenseurBB(*(a.delta_eps_meca));
};
// DESTRUCTEUR :
UmatAbaqus::~UmatAbaqus()
{ // cas des grandeurs évoluées
if (t_sigma != NULL)
delete t_sigma;
if (d_sigma_deps != NULL )
delete d_sigma_deps;
if (d_sigma_d_tempera != NULL)
delete d_sigma_d_tempera;
if (d_ener_therm_vol_deps != NULL)
delete d_ener_therm_vol_deps;
if (eps_meca != NULL)
delete eps_meca;
if (delta_eps_meca != NULL)
delete delta_eps_meca;
};
// Surcharge de l'operateur =
UmatAbaqus& UmatAbaqus::operator= (UmatAbaqus& a)
{ t_sigma = a.t_sigma;
v_statev = a.v_statev;
d_sigma_deps = a.d_sigma_deps;
energie_elastique = a.energie_elastique;
dissipation_plastique = a.dissipation_plastique;
dissipation_visqueuse = a.dissipation_visqueuse;
ener_therm_vol_par_utemps = a.ener_therm_vol_par_utemps;
d_sigma_d_tempera = a.d_sigma_d_tempera;
d_ener_therm_vol_deps = a.d_ener_therm_vol_deps;
d_ener_therm_dtemper = a.d_ener_therm_dtemper;
pnewdt = a.pnewdt;
eps_meca = a.eps_meca;
delta_eps_meca = a.delta_eps_meca;
temps_t = a.temps_t; temps_tdt = a.temps_tdt;
delta_t = a.delta_t;
temper_t = a.temper_t;
delta_temper = a.delta_temper;
ddlNoeA_ptinteg = a.ddlNoeA_ptinteg;
delta_ddlNoeA_ptinteg = a.delta_ddlNoeA_ptinteg;
nom_materiau = a.nom_materiau;
dim_tens = a.dim_tens;
nb_tau_ij = a.nb_tau_ij;
nb_ij_tenseur = a.nb_ij_tenseur;
nb_variables_etat = a.nb_variables_etat;
proprietes_materiau = a.proprietes_materiau;
nb_proprietes_materiau = a.nb_proprietes_materiau;
coor_pt = a.coor_pt;
mat_corota = a.mat_corota;
longueur_characteristique = a.longueur_characteristique;
giB_t = a.giB_t;
giB_tdt = a.giB_tdt;
nb_elem = a.nb_elem;
nb_pt_integ = a.nb_pt_integ;
nb_du_plis = a.nb_du_plis;
nb_pt_dans_le_plis = a.nb_pt_dans_le_plis;
nb_step = a.nb_step;
nb_increment = a.nb_increment;
N_t = a.N_t; N_tdt = a.N_tdt;
return *this;
};
// lecture des données Umat
void UmatAbaqus::LectureDonneesUmat(bool utilisation_umat_interne,const int niveau)
{ // Creation d'un processus de reception des données
// en fait l'objectif est de réceptionner que les variables d'entrées ou
// d'entrée sortie
if (niveau > 5)
cout << "\n hzpp: ouverture du tube en lecture, lecture sur le tube" << endl;
if (!utilisation_umat_interne)
{// dans le cas où l'état actuel de l'incrément est 0,1 ou 2, on initialise le champ de caractères
if (nb_increment<=2)
for (int i=0;i<24;i++) CMNAME[i]='\0';
char* tampon_envoi = &(t_car_x_n.tampon[384]);
int tub = open(reception.c_str(),O_RDONLY);
read (tub,tampon_envoi,544);
close (tub); // fermeture du tampon
// transformation de l'information
Copie_base_vers_evolue(niveau);
if (niveau > 5)
{ cout << "\n *********** grandeurs lues ************ ";
cout << "\n sigma_t "; for (int i=0;i<6;i++) cout << "("< 5)
cout << "\n HZpp: fermeture du tube en lecture" << endl;
// // transformation de l'information
// Copie_base_vers_evolue();
// à chaque lecture on incrémente un compteur
passage++; // pour des comptes éventuelles
};
// écriture des données Umat
void UmatAbaqus::EcritureDonneesUmat(bool utilisation_umat_interne,const int niveau)
{ // Creation d'un processus d'ecriture des variables
// en fait l'objectif est d'ecrire que les variables qui évoluent
if (niveau > 5)
cout << "\n hzpp: ouverture du tube en ecriture, ecriture sur le tube " << endl;
if (!utilisation_umat_interne)
{ // transformation de l'information
Copie_evolue_vers_base(niveau);
// ouverture du tube nomme en ecriture
int tub = open(envoi.c_str(),O_WRONLY);
write (tub,t_car_x_n.tampon,480);
close (tub); // fermeture du tampon
#ifdef SYSTEM_MAC_OS_CARBON
if (niveau > 5)
{// on ecrit les résultats à l'écran
if ((*NDI == 3) && (*NSHR == 3))
{ // cas classique 3D
Tenseur3HH& sigma = *((Tenseur3HH*) t_sigma);
cout << "\n ************* contraintes calculees: *********\n" << sigma;
Tenseur3HHHH& dd_sigma_deps = *((Tenseur3HHHH*) d_sigma_deps);
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
// Tenseur3HH& d_sigma_d_tempe = *((Tenseur3HH*) d_sigma_d_tempera);
// Tenseur3HH& d_ener_therm_vol_dep = *((Tenseur3HH*) d_ener_therm_vol_deps);
}
else if ((*NDI == 2) && (*NSHR == 1))
{ // cas contraintes planes
Tenseur2HH& sigma = *((Tenseur2HH*) t_sigma);
cout << "\n ************* contraintes calculees: *********\n" << sigma;
Tenseur2HHHH& dd_sigma_deps = *((Tenseur2HHHH*) d_sigma_deps);
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
// Tenseur3HH& d_sigma_d_tempe = *((Tenseur3HH*) d_sigma_d_tempera);
// Tenseur3HH& d_ener_therm_vol_dep = *((Tenseur3HH*) d_ener_therm_vol_deps);
cout <<"\n N_t= "< 7)
cout << "\n HZpp: fermeture du tube en ecriture" << endl;
};
// <<<<<< 2) <<<<<< contexte: utilisation par herezh d'une umat extérieure
// écriture des données pour l'umat
void UmatAbaqus::EcritureDonneesPourUmat(bool utilisation_umat_interne,const int niveau)
{ // Creation d'un processus d'ecriture des variables
// en fait l'objectif est d'ecrire que les variables nécessaires pour le calcul
if (niveau > 5)
cout << "\n hzpp-utilisation d'umat: ouverture du tube en ecriture, ecriture sur le tube "
<< endl;
if (!utilisation_umat_interne)
{//transformation de l'information
Copie_evolue_vers_base_PourUmat(niveau);
// ouverture du tube nomme en ecriture
char* tampon_envoi = &(t_car_x_n.tampon[384]);
int tub = open(reception.c_str(),O_WRONLY);
if (tub < 0)
{cout << "\n *** erreur en ouverture du pipe " << reception.c_str()
<< " peut-etre n'existe t'il pas ? en tout cas il ne veut pas s'ouvrir !! ";
Sortie(1);
};
write (tub,tampon_envoi,544);
if (niveau > 5)
{ cout << "\n *********** donnees envoyees ************ ";
cout << "\n sigma_t "; for (int i=0;i<6;i++) cout << "("< 5)
cout << "\n HZpp-utilisation d'umat: fermeture du tube en ecriture" << endl;
};
// Puis lecture des résultats de l'umat
void UmatAbaqus::LectureResultatUmat(bool utilisation_umat_interne,const int niveau)
{ // Creation d'un processus de reception des données
// en fait l'objectif est de réceptionner que les variables calculées
// ouverture du tube nomme en lecture
// lecture dans le t_car_x_n.tampon
if (niveau > 5)
cout << "\n hzpp-utilisation d'umat: ouverture du tube en lecture, lecture sur le tube"
<< endl;
if (!utilisation_umat_interne)
{ int tub = open(envoi.c_str(),O_RDONLY);
read (tub,t_car_x_n.tampon,480);
close (tub); // fermeture du tampon
// transformation de l'information
Copie_base_vers_evolue_PourUmat(niveau);
};
if (niveau > 5)
cout << "\n HZpp-utilisation d'umat: fermeture du tube en lecture" << endl;
};
// initialisation des données d'entrée tous à zéro
// sauf: nom_materiau: qui reste inchangé
// giB_t et BaseB: qui sont initialisée à une base absolue identité
// pnewdt: très grand, matrice de rotation identité
// sinon on a:
// *eps_meca, *delta_eps_meca : nulles, temps_t=0, temps_tdt et delta_t=0;
// temper_t et delta_temper: nulles,
// pas de variables aux noeuds, pas de proprietes_materiau
// coordonnées à 0,
// longueur caractéristique=0,
// et tous les indices=0:
// nb_elem nb_pt_integ nb_du_plis nb_pt_dans_le_plis nb_step nb_increment
void UmatAbaqus::Init_zero()
{t_sigma->Inita(0.);v_statev.Change_taille(0);
energie_elastique=0.;dissipation_plastique=0.;dissipation_visqueuse=0.;
pnewdt = ConstMath::tresgrand;
eps_meca->Inita(0);delta_eps_meca->Inita(0.);
temps_t=0.;temps_tdt=0.;delta_t=0.;
temper_t=0.;delta_temper=0.;
ddlNoeA_ptinteg.Change_taille(0);
delta_ddlNoeA_ptinteg.Change_taille(0);
//dim_tens=3;nb_tau_ij=3;nb_ij_tenseur=6;
dim_tens=Abs(eps_meca->Dimension());
// les valeurs de nb_tau_ij et nb_ij_tenseur
// dépendent du cas de travail, donc on ne les changes pas ici
// éventuellement en lecture il seront modifié
nb_variables_etat=0.;
proprietes_materiau.Change_taille(0);nb_proprietes_materiau=0;
coor_pt.Zero();
mat_corota.Initialise(0.);mat_corota(1,1)=1.;mat_corota(2,2)=1.;mat_corota(3,3)=1.;
longueur_characteristique=0.;
giB_tdt = giB_t=BaseB(giB_t.Dimension(),giB_t.NbVecteur());
if (giB_t.NbVecteur()==2)
N_tdt.Zero(); N_t=N_tdt;
// giB_tdt=BaseB(3);
nb_elem=1;
nb_pt_integ=1;
nb_du_plis=1;
nb_pt_dans_le_plis=1;
nb_step=1;
nb_increment=1;
};
// initialisation des données d'entrée à un démarrage correcte
// *t_sigma=0, v_statev de taille nulle, les énergies nulles, pnewdt très grand
// *eps_meca, *delta_eps_meca : nulles, temps_t=0, temps_tdt et delta_t=1;
// temper_t et delta_temper: nulles,
// pas de variables aux noeuds, pas de proprietes_materiau
// coordonnées à 0, matrice de rotation identité
// longueur caractéristique=1, giB_t et giB_tdt: base identité en absolue
// et tous les indices=1:
// nb_elem nb_pt_integ nb_du_plis nb_pt_dans_le_plis nb_step nb_increment
// par défaut la dimension des tenseurs est 3, mais pour les CP par exemple
// la dimension réelle utilisée est 2
// de même pour nb_reel_tau_ij qui indique le nombre de contrainte de cisaillement
// réellement utilisé: qui en CP = 1
void UmatAbaqus::Init_un(int dim_reel_tens ,int nb_reel_tau_ij)
{t_sigma->Inita(0.);v_statev.Change_taille(0);
energie_elastique=0.;dissipation_plastique=0.;dissipation_visqueuse=0.;
pnewdt = ConstMath::tresgrand;
eps_meca->Inita(0);delta_eps_meca->Inita(0.);
temps_t=0.;temps_tdt=1.;delta_t=1.;
temper_t=0.;delta_temper=0.;
ddlNoeA_ptinteg.Change_taille(0);
delta_ddlNoeA_ptinteg.Change_taille(0);
dim_tens=dim_reel_tens;
nb_tau_ij=nb_reel_tau_ij;
nb_ij_tenseur=dim_tens+nb_tau_ij; // correspond à NTENS,
// en CP on n'utilise normalement que 4, mais de toute manière
// on passe systématiquement des tenseurs 3D en paramètre
nb_variables_etat=0.;
proprietes_materiau.Change_taille(0);nb_proprietes_materiau=0;
coor_pt.Zero();
mat_corota.Initialise(0.);mat_corota(1,1)=1.;mat_corota(2,2)=1.;mat_corota(3,3)=1.;
longueur_characteristique=1.;
// giB_t=BaseB(3);giB_tdt=BaseB(3);
giB_tdt = giB_t=BaseB(giB_t.Dimension(),giB_t.NbVecteur());
if (giB_t.NbVecteur()==2)
N_tdt.Zero(); N_t=N_tdt;
// nb_elem=1;
// nb_pt_integ=1;
nb_du_plis=1;
nb_pt_dans_le_plis=1;
// nb_step=1;
// nb_increment=1;
};
// transfert de l'Umat vers le point d'intégration à t
void UmatAbaqus::Transfert_Umat_ptInteg_t(PtIntegMecaInterne& ptIntegMeca)
{ *(ptIntegMeca.EpsBB()) = *eps_meca;
*(ptIntegMeca.DeltaEpsBB()) = *delta_eps_meca;
*(ptIntegMeca.SigHH_t()) = *t_sigma;
};
// transfert de l'Umat vers le point d'intégration à tdt
void UmatAbaqus::Transfert_Umat_ptInteg_tdt(PtIntegMecaInterne& ptIntegMeca)
{ *(ptIntegMeca.SigHH()) = *t_sigma;
};
// affichage en fonction d'un niveau
// niveau > 0: données
void UmatAbaqus::Affiche(ofstream& sort,const int niveau)
{ sort << "\n *********** info umat ************ ";
sort << "\n sigma_t "; for (int i=0;i<6;i++) sort << "("<> toto;
if (toto != "StructureUmat_Abaqus")
{ cout << "\n erreur en lecture des parametres d'une structure Umat abaqus !! "
<< "\n UmatAbaqus::Lecture_base_info(... ";
Sortie(1);
};
ent >> toto >> envoi >> toto >> reception;
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void UmatAbaqus::Ecriture_base_info(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << "\n StructureUmat_Abaqus: "
<< " nom_tube_envoi " << envoi <<" nom_tube_reception= " << reception << " ";
};
};
// ---------------------------------------------------------------------------------------------
// méthodes protégées
// ---------------------------------------------------------------------------------------------
// 1)-- utilisation en tant qu'umat
// copie des grandeurs évoluées dans les grandeurs de base
// uniquement celles qui varient
void UmatAbaqus::Copie_evolue_vers_base(const int niveau)
{ if ((dim_tens == 3) && (nb_tau_ij == 3))
{ // cas classique 3D
Tenseur3HH& sigma = *((Tenseur3HH*) t_sigma);
Tenseur3HHHH& dd_sigma_deps = *((Tenseur3HHHH*) d_sigma_deps);
Tenseur3HH& d_sigma_d_tempe = *((Tenseur3HH*) d_sigma_d_tempera);
Tenseur3HH& d_ener_therm_vol_dep = *((Tenseur3HH*) d_ener_therm_vol_deps);
for (int ij=1;ij<=6;ij++)
{int i=cdex.idx_i(ij);int j=cdex.idx_j(ij);
STRESS[ij-1] = sigma(i,j);
DDSDDT[ij-1] = d_sigma_d_tempe(i,j);
DRPLDE[ij-1] = d_ener_therm_vol_dep(i,j);
for (int kl=1;kl<=6;kl++)
{int k=cdex.idx_i(kl);int l=cdex.idx_j(kl);
int r=(ij-1)*6+kl-1;
// DDSDDE[r] = dd_sigma_deps(i,j,k,l);
// en considérant que la matrice tangente est relative à gamma_ij = eps_ij + eps_ji
// et non la déformation !!, de plus en considérant que dd_sigma_deps (i,j,k,l)
// devrait être symétrique par rapport aux deux derniers indices
// enfin dans l'utilisation on fait directement sig(i,j) = dd(i,j,k,l) * gamma(k,l)
// et on ne considère pas le cas gamma(l,k), donc il ya seulement 6 gamma
if (k == l)
{DDSDDE[r] = dd_sigma_deps(i,j,k,l);}
else
// {DDSDDE[r] = 2. * dd_sigma_deps(i,j,k,l);};
{DDSDDE[r] = 0.5 * (dd_sigma_deps(i,j,k,l)+dd_sigma_deps(i,j,l,k));};
};
};
if (niveau > 5)
{ cout << "\n ************* contraintes calculees: *********\n" << sigma;
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
};
}
else if ((dim_tens == 2) && (nb_tau_ij == 1))
{ // cas des contraintes planes
Tenseur2HH& sigma = *((Tenseur2HH*) t_sigma);
Tenseur2HHHH& dd_sigma_deps = *((Tenseur2HHHH*) d_sigma_deps);
Tenseur2HH& d_sigma_d_tempe = *((Tenseur2HH*) d_sigma_d_tempera);
Tenseur2HH& d_ener_therm_vol_dep = *((Tenseur2HH*) d_ener_therm_vol_deps);
for (int ij=1;ij<=3;ij++)
{int i=cdexCP.idx_i(ij);int j=cdexCP.idx_j(ij);
STRESS[ij-1] = sigma(i,j);
DDSDDT[ij-1] = d_sigma_d_tempe(i,j);
DRPLDE[ij-1] = d_ener_therm_vol_dep(i,j);
for (int kl=1;kl<=3;kl++)
{int k=cdexCP.idx_i(kl);int l=cdexCP.idx_j(kl);
int r=(ij-1)*3+kl-1;
// DDSDDE[r] = dd_sigma_deps(i,j,k,l);
// en considérant que la matrice tangente est relative à gamma_ij = eps_ij + eps_ji
// et non la déformation !!, de plus en considérant que dd_sigma_deps (i,j,k,l)
// devrait être symétrique par rapport aux deux derniers indices
// enfin dans l'utilisation on fait directement sig(i,j) = dd(i,j,k,l) * gamma(k,l)
// et on ne considère pas le cas gamma(l,k), donc il ya seulement 3 gamma
if (k == l)
{DDSDDE[r] = dd_sigma_deps(i,j,k,l);}
else
{DDSDDE[r] = 0.5 * (dd_sigma_deps(i,j,k,l)+dd_sigma_deps(i,j,l,k));};
};
};
// on s'occupe de mettre à jour la normale
int i=3;
for (int j=1;j<=3;j++)
{int r=(i-1)*3+j-1;
DFGRD1[r] = N_tdt(j);
};
if (niveau > 5)
{ cout << "\n ************* contraintes calculees: *********\n" << sigma;
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
cout <<"\n N_t= "< 5)
{ cout << "\n ************* contraintes calculees: *********\n" << sigma;
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
};
}
else if ((*NDI == 2) && (*NSHR == 1))
{ // cas des contraintes planes
Tenseur2HH& sigma = *((Tenseur2HH*) t_sigma);
Tenseur2HHHH& dd_sigma_deps = *((Tenseur2HHHH*) d_sigma_deps);
Tenseur2HH& d_sigma_d_tempe = *((Tenseur2HH*) d_sigma_d_tempera);
Tenseur2HH& d_ener_therm_vol_dep = *((Tenseur2HH*) d_ener_therm_vol_deps);
for (int ij=1;ij<=3;ij++)
{int i=cdexCP.idx_i(ij);int j=cdexCP.idx_j(ij);
sigma.Coor(i,j) = STRESS[ij-1];
d_sigma_d_tempe.Coor(i,j) = DDSDDT[ij-1];
d_ener_therm_vol_dep.Coor(i,j) = DRPLDE[ij-1];
for (int kl=1;kl<=3;kl++)
{int k=cdexCP.idx_i(kl);int l=cdexCP.idx_j(kl);
int r=(ij-1)*3+kl-1;
dd_sigma_deps.Change(i,j,k,l,DDSDDE[r]);
};
};
// on met également à jour la normale finale
// ce qui permet de récupérer ensuite la déformation d'épaisseur
int i=3;
for (int j=1;j<=3;j++)
{int r=(i-1)*3+j-1;
N_tdt(j) = DFGRD1[r];
};
if (niveau > 5)
{ cout << "\n ************* contraintes calculees: *********\n" << sigma;
cout << "\n ************* matrice tangente ***************\n" << dd_sigma_deps;
cout <<"\n N_t= "< 5)
{ cout << "\n sigma_t ";
for (int i=0;i<(*NDI+*NSHR);i++) cout << " ("< 24)
{cout << "\n erreur: le nom du materiau a une longueur superieur a 24, pas possible actuellement"
<< "\n UmatAbaqus::Copie_evolue_vers_base_PourUmat()";
Sortie(1);
};
for (int i=0;i