2194 lines
114 KiB
C++
2194 lines
114 KiB
C++
|
// FICHIER : LoiCritere.cp
|
||
|
// CLASSE : LoiCritere
|
||
|
|
||
|
|
||
|
// This file is part of the Herezh++ application.
|
||
|
//
|
||
|
// The finite element software Herezh++ is dedicated to the field
|
||
|
// of mechanics for large transformations of solid structures.
|
||
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
||
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
||
|
//
|
||
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
||
|
//
|
||
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
||
|
// AUTHOR : Gérard Rio
|
||
|
// E-MAIL : gerardrio56@free.fr
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
// See the GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
//
|
||
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
||
|
|
||
|
|
||
|
//#include "Debug.h"
|
||
|
#include "LesLoisDeComp.h"
|
||
|
|
||
|
# include <iostream>
|
||
|
using namespace std; //introduces namespace std
|
||
|
#include <math.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "Sortie.h"
|
||
|
#include "TypeConsTens.h"
|
||
|
#include "TypeQuelconqueParticulier.h"
|
||
|
#include "NevezTenseurQ.h"
|
||
|
|
||
|
#include "LoiCritere.h"
|
||
|
#include "LoiContraintesPlanesDouble.h"
|
||
|
#include "LoiContraintesPlanes.h"
|
||
|
#include "Util.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// fonction critère de plissement de membrane
|
||
|
// en entrée:
|
||
|
// implicit : si oui on est en implicite, sinon en explicite
|
||
|
// retour:
|
||
|
// ** ancienne mouture
|
||
|
// = -2 : erreur en calcul des valeurs propres de déformation, on ne tiens pas compte des plis
|
||
|
// = -1 : erreur en calcul des valeurs propres de contrainte, on ne tiens pas compte des plis
|
||
|
// : ou erreur en calcul des vecteurs propres de contrainte
|
||
|
// = 1 : tout est ok, il n'y a pas d'apparition de plis, rien n'est en compression
|
||
|
// = 2 : il y a des plis dans les deux sens, aucune raideur ni contrainte
|
||
|
// = 3 : on a des plis dans une direction
|
||
|
|
||
|
// ** nouvelle mouture
|
||
|
// = -1 : pas de calcul de valeur propre possible en contrainte
|
||
|
// = 1 : pas de plis (pas de calcul de nouvelle direction )
|
||
|
// = -2 : pas de calcul de valeur propre de déformation
|
||
|
// = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
// = 2 : plis dans les deux sens, calcul des directions de plis
|
||
|
// = -4 : pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
// = 3 : plis dans une seule directions, calcul ok
|
||
|
|
||
|
int LoiCritere::Critere_plis_membrane(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_inter
|
||
|
,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite
|
||
|
,double& module_cisaillement
|
||
|
,bool implicit,const Met_abstraite::Umat_cont& ex)
|
||
|
{// on sauvegarde les modules de compressibilité et de cisaillement
|
||
|
// car l'appel à la loi de contrainte plane annulle les valeurs stockées
|
||
|
// et dans le cas ou il y a un pb, le mieux est de garder les anciennes valeurs
|
||
|
// double module_compressibilite_save = module_compressibilite;
|
||
|
// double module_cisaillement_save = module_cisaillement;
|
||
|
|
||
|
// dim et vérification
|
||
|
int dim_tens = abs(sigHH.Dimension());
|
||
|
// normalement le critère ne s'applique que pour des tenseurs 2D
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (dim_tens != 2)
|
||
|
{ cout << "\n erreur le critere de plissement de membrane ne peut s'appliquer que pour des lois 2D"
|
||
|
<< " \n LoiCritere::Critere_plis_membrane_expli(..";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
int retour = 0; // init par défaut
|
||
|
|
||
|
// pilotage éventuelle du recalcul des directions de plis
|
||
|
int calcul_dir_plis = 1; // initialisation
|
||
|
// si rien n'a été auparavant calculé, on est obligé de faire un premier calcul
|
||
|
// de direction sinon on appelle éventuellement l'indicateur
|
||
|
|
||
|
// on récupère l'indicateur: qui est déterminé par une fonction nD
|
||
|
// si cas_cal_plis == 0 cela veut dire soit qu'il n'y a pas eu déjà un calcul
|
||
|
// soit que ce précédant calcul ne s'est pas bien passé, dans ces deux il faut
|
||
|
// imposer de faire le calcul
|
||
|
if ((recalcul_dir_plis != NULL) && (save_resul.cas_cal_plis != 0))
|
||
|
{// 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 ;
|
||
|
|
||
|
// 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
|
||
|
= recalcul_dir_plis->Li_enu_etendu_scalaire();
|
||
|
List_io <TypeQuelconque >& li_quelc = recalcul_dir_plis->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
|
||
|
= recalcul_dir_plis->Valeur_FnD_Evoluee
|
||
|
(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (tab_val.Taille() != 1)
|
||
|
{ cout << "\nErreur : la fonction nD relative au recalcul de la direction des plis "
|
||
|
<< " doit calculer un scalaire or le tableau de retour est de taille "
|
||
|
<< tab_val.Taille() << " ce n'est pas normal !\n";
|
||
|
cout << " LoiCritere::Critere_plis_membrane(... \n";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
// on récupère le premier élément du tableau uniquement
|
||
|
calcul_dir_plis = (int) tab_val(1);
|
||
|
};
|
||
|
|
||
|
// en fonction de l'indicateur calcul conditionnel des plis
|
||
|
// ou utilisation des grandeurs sauvegardées
|
||
|
Tableau <Coordonnee2H> V_Pr_H(2);
|
||
|
Coordonnee2 valPropreSig;
|
||
|
Coordonnee2 valPropreEps;
|
||
|
|
||
|
switch (calcul_dir_plis) // test en fonction d'un pilotage éventuel fct de la fonction nD
|
||
|
// recalcul_dir_plis->Valeur_FnD_Evoluee
|
||
|
// rappel de la gestion des différents cas via la valeur de: calcul_dir_plis
|
||
|
// si == 0 on utilise la valeur stockee actuelle, c-a-d ici à l'itération précédente
|
||
|
// si aucun calcul de direction n'a ete effectue, il y a un premier calcul qui est fait
|
||
|
// si == 1 on recalcule les directions des plis,
|
||
|
// si == 2 on recalcule les directions des plis uniquement pour la zone non complètement
|
||
|
// relâchée à l'incrément précédent, pour cette dernière on maintient le relâchement
|
||
|
// si == -1 on utilise la valeur stockee a t (celle de l'incrément precedent qui a convergé),
|
||
|
// si aucun calcul de direction n'a ete effectue, il y a un premier calcul qui est fait
|
||
|
// si == -2 idem -1 , sauf que s'il n'y a pas de direction existante, on ne recalcule pas une
|
||
|
// nouvelle direction, on continue avec un calcul sans plis
|
||
|
// --> cela signifie que la zone de plis est totalement figée / au précédent incrément
|
||
|
// si == -3 idem 0 , sauf que s'il n'y a pas de direction existante, on ne recalcule pas une
|
||
|
// nouvelle direction, on continue avec un calcul sans plis
|
||
|
// --> cela signifie que la zone de plis est totalement figée / à la précédente itération
|
||
|
|
||
|
{ case 2: // cas ou on doit recalculer la direction des plis uniquement pour la zone non relâché
|
||
|
{ if (save_resul.cas_cal_plis_t != 2)
|
||
|
{ int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// vérif normalement inutile car le retour doit toujours être non nul
|
||
|
if (!retour)
|
||
|
{cout << "\n **** erreur a priori: normalement on ne devrait jamais avoir de retour nul "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
else // sinon on maintien l'indicateur de relâchement
|
||
|
{save_resul.cas_cal_plis = save_resul.cas_cal_plis_t;
|
||
|
};
|
||
|
|
||
|
// retour dans le save_resul.cas_cal_plis
|
||
|
// = -1 : pas de calcul de valeur propre possible en contrainte
|
||
|
// = 1 : pas de plis (pas de calcul de nouvelle direction )
|
||
|
// = -2 : pas de calcul de valeur propre de déformation
|
||
|
// = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
// = 2 : plis dans les deux sens, calcul des directions de plis
|
||
|
// = -4 : pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
// = 3 : plis dans une seule directions, calcul ok
|
||
|
// si cela s'est bien passé, les résultats sont dans V_Pr_H
|
||
|
// sinon on utilisera pas de directions: calculées ou stockées
|
||
|
break; // fin du cas où on recalcule la direction des plis
|
||
|
}
|
||
|
case 1: // cas ou on doit recalculer la direction des plis
|
||
|
{ int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// vérif normalement inutile car le retour doit toujours être non nul
|
||
|
if (!retour)
|
||
|
{cout << "\n **** erreur a priori: normalement on ne devrait jamais avoir de retour nul "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// retour dans le save_resul.cas_cal_plis
|
||
|
// = -1 : pas de calcul de valeur propre possible en contrainte
|
||
|
// = 1 : pas de plis (pas de calcul de nouvelle direction )
|
||
|
// = -2 : pas de calcul de valeur propre de déformation
|
||
|
// = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
// = 2 : plis dans les deux sens, calcul des directions de plis
|
||
|
// = -4 : pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
// = 3 : plis dans une seule directions, calcul ok
|
||
|
// si cela s'est bien passé, les résultats sont dans V_Pr_H
|
||
|
// sinon on utilisera pas de directions: calculées ou stockées
|
||
|
break; // fin du cas où on recalcule la direction des plis
|
||
|
}
|
||
|
case 0: // cas où on se sert de ce qui a été sauvegardé à l'itération précédente
|
||
|
// si aucun calcul de direction n'a ete effectue, il y a un premier calcul qui est fait
|
||
|
{ // en fait seul les cas 3 et 2 sont exploitables et seront exploités
|
||
|
if ((save_resul.cas_cal_plis == 3)||(save_resul.cas_cal_plis == 2))
|
||
|
{ // V_Pr_H(be)(j) correspond à la coordonnée locale ^j du vecteur be
|
||
|
// donc V_Pr_H(be)(j) = V_Pr(be) * giH(j)
|
||
|
// les vecteurs V_Pr_H(be) sont supposés être dans le plan des g_alpha
|
||
|
for (int be=1;be<3;be++) // < 3 donc de 1 à 2
|
||
|
{for (int al=1;al<3;al++) // < 3 donc de 1 à 2
|
||
|
V_Pr_H(be)(al) = (*save_resul.V_P_sig)(be) * ex.giH_tdt->Coordo(al);
|
||
|
};
|
||
|
}
|
||
|
else // sinon cela veut dire que le calcul précédent n'est pas exploitable
|
||
|
// on refait un calcul
|
||
|
{int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// vérif normalement inutile car le retour doit toujours être non nul
|
||
|
if (!retour)
|
||
|
{cout << "\n **** erreur a priori: normalement on ne devrait jamais avoir de retour nul "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
break; // fin du cas où on utilise la direction des plis sauvegardée à l'itération prec
|
||
|
}
|
||
|
case -1: // cas où on se sert de ce qui a été sauvegardé à l'incrément précédent
|
||
|
// si aucun calcul de direction n'a ete effectue, il y a un premier calcul qui est fait
|
||
|
{ // en fait seul les cas 3 et 2 sont exploitables et seront exploités
|
||
|
if ((save_resul.cas_cal_plis_t == 3)||(save_resul.cas_cal_plis_t == 2))
|
||
|
{ // V_Pr_H(be)(j) correspond à la coordonnée locale ^j du vecteur be
|
||
|
// donc V_Pr_H(be)(j) = V_Pr(be) * giH(j)
|
||
|
// les vecteurs V_Pr_H(be) sont supposés être dans le plan des g_alpha
|
||
|
// on utilise aussi les vecteurs de la base à t, ce qui permet de convecter
|
||
|
// les vecteurs des directions de plis
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// on vérifie que les données à t existent
|
||
|
if (save_resul.V_P_sig_t == NULL)
|
||
|
{cout << "\n **** erreur la direction des plis a t n'est pas encore sauvegardee "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
for (int be=1;be<3;be++) // < 3 donc de 1 à 2
|
||
|
{for (int al=1;al<3;al++) // < 3 donc de 1 à 2
|
||
|
V_Pr_H(be)(al) = (*save_resul.V_P_sig_t)(be) * ex.giH_t->Coordo(al);
|
||
|
};
|
||
|
// on met à jour save_resul.cas_cal_plis en fonction
|
||
|
save_resul.cas_cal_plis = save_resul.cas_cal_plis_t;
|
||
|
}
|
||
|
else // sinon cela veut dire que le calcul précédent n'est pas exploitable
|
||
|
// on refait un calcul
|
||
|
{int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// vérif normalement inutile car le retour doit toujours être non nul
|
||
|
if (!retour)
|
||
|
{cout << "\n **** erreur a priori: normalement on ne devrait jamais avoir de retour nul "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
break; // fin du cas où on utilise la direction des plis sauvegardée à l'increment prec
|
||
|
}
|
||
|
case -2: // cas où la zone de plis de l'incrément précédent
|
||
|
// est totalement figée
|
||
|
{ // en fait seul les cas 3 et 2 sont exploitables et seront exploités
|
||
|
if ((save_resul.cas_cal_plis_t == 3)||(save_resul.cas_cal_plis_t == 2))
|
||
|
{ // V_Pr_H(be)(j) correspond à la coordonnée locale ^j du vecteur be
|
||
|
// donc V_Pr_H(be)(j) = V_Pr(be) * giH(j)
|
||
|
// les vecteurs V_Pr_H(be) sont supposés être dans le plan des g_alpha
|
||
|
// on utilise aussi les vecteurs de la base à t, ce qui permet de convecter
|
||
|
// les vecteurs des directions de plis
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// on vérifie que les données à t existent
|
||
|
if (save_resul.V_P_sig_t == NULL)
|
||
|
{cout << "\n **** erreur la direction des plis a t n'est pas encore sauvegardee "
|
||
|
<< " or on veut l'utiliser: ce n'est pas possible !! arret !! "
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
for (int be=1;be<3;be++) // < 3 donc de 1 à 2
|
||
|
{for (int al=1;al<3;al++) // < 3 donc de 1 à 2
|
||
|
V_Pr_H(be)(al) = (*save_resul.V_P_sig_t)(be) * ex.giH_t->Coordo(al);
|
||
|
};
|
||
|
// on met à jour save_resul.cas_cal_plis en fonction
|
||
|
save_resul.cas_cal_plis = save_resul.cas_cal_plis_t;
|
||
|
}
|
||
|
else // sinon on continue avec un cas sans plis
|
||
|
{ int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig,false);
|
||
|
// on met à jour save_resul.cas_cal_plis en fonction
|
||
|
save_resul.cas_cal_plis = retour;
|
||
|
};
|
||
|
break; // fin du cas où on utilise la direction des plis sauvegardée à l'increment prec
|
||
|
}
|
||
|
case -3: // cas où on se sert de ce qui a été sauvegardé à l'itération précédente
|
||
|
// idem 0 , sauf que s'il n'y a pas de direction existante, on ne recalcule pas une
|
||
|
// nouvelle direction, on continue avec un calcul sans plis
|
||
|
// --> cela signifie que la zone de plis est totalement figée / à la précédente itération
|
||
|
{ // en fait seul les cas 3 et 2 sont exploitables et seront exploités
|
||
|
if ((save_resul.cas_cal_plis == 3)||(save_resul.cas_cal_plis == 2))
|
||
|
{ // V_Pr_H(be)(j) correspond à la coordonnée locale ^j du vecteur be
|
||
|
// donc V_Pr_H(be)(j) = V_Pr(be) * giH(j)
|
||
|
// les vecteurs V_Pr_H(be) sont supposés être dans le plan des g_alpha
|
||
|
for (int be=1;be<3;be++) // < 3 donc de 1 à 2
|
||
|
{for (int al=1;al<3;al++) // < 3 donc de 1 à 2
|
||
|
V_Pr_H(be)(al) = (*save_resul.V_P_sig)(be) * ex.giH_tdt->Coordo(al);
|
||
|
};
|
||
|
}
|
||
|
else // sinon on continue avec un cas sans plis
|
||
|
{ int retour = Calcul_directions_plis(epsBB_tdt,sigHH,valPropreEps,V_Pr_H,ex,valPropreSig,false);
|
||
|
// on met à jour save_resul.cas_cal_plis en fonction
|
||
|
save_resul.cas_cal_plis = retour;
|
||
|
};
|
||
|
break; // fin du cas où on utilise la direction des plis sauvegardée à l'itération prec
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur non prevu : calcul_dir_plis= "<< save_resul.cas_cal_plis
|
||
|
<< "\n LoiCritere::Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test3: LoiCritere::Critere_plis_membrane(... " << flush;
|
||
|
|
||
|
// maintenant on fait un traitement en fonction de save_resul.cas_cal_plis
|
||
|
// = -1 : pas de calcul de valeur propre possible en contrainte
|
||
|
// = 1 : pas de plis (pas de calcul de nouvelle direction )
|
||
|
// = -2 : pas de calcul de valeur propre de déformation
|
||
|
// = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
// = 2 : plis dans les deux sens, calcul des directions de plis
|
||
|
// = -4 : pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
// = 3 : plis dans une seule directions, calcul ok
|
||
|
retour = save_resul.cas_cal_plis; // init
|
||
|
switch (save_resul.cas_cal_plis)
|
||
|
{ case -1: // pas de calcul de valeur propre possible en contrainte
|
||
|
{save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
break;
|
||
|
}
|
||
|
case 1: // pas de plis
|
||
|
{break;
|
||
|
}
|
||
|
case -2: // pas de calcul de valeur propre de déformation
|
||
|
{save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
break;
|
||
|
}
|
||
|
// on traite -3 et 2 en même temps, car la fin est commune
|
||
|
case -3: // plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
case 2: // plis dans les deux sens, calcul des directions de plis
|
||
|
{if (save_resul.cas_cal_plis == -3)
|
||
|
{save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
}
|
||
|
else // -> cas: save_resul.cas_cal_plis == 2
|
||
|
{if (calcul_dir_plis != 2)
|
||
|
{ // calcul normal relatif à la zone relâchée
|
||
|
// les coordonnées des vecteurs propres sont exprimées dans l'ancienne base
|
||
|
// on a donc
|
||
|
// Vi_B(i) = gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
|
||
|
Mat_pleine beta(2,2);
|
||
|
for (int i=1;i<3;i++) // < 3 donc de 1 à 2
|
||
|
for (int j=1;j<3;j++)
|
||
|
beta(i,j) = V_Pr_H(i)(j);
|
||
|
Mat_pleine gamma(beta.Inverse().Transpose()); // on calcule la matrice inverse
|
||
|
// la matrice gamma correspond à la matrice de changement de base des g^i au gpH
|
||
|
// gamma est l'inverse transposée
|
||
|
// gpH(i) = gamma(i,j) * gH(j), i indice de ligne, j indice de colonne
|
||
|
// c-a-d= gp^i = gamma^i_j * g^j
|
||
|
bool deux_plis = true;
|
||
|
// on calcul les def de plis : save_resul.eps_pli
|
||
|
Passage_3ou2_vers_1(gamma,sigHH_t,beta,DepsBB,epsBB_tdt
|
||
|
,delta_epsBB,deux_plis,save_resul.eps_pli);
|
||
|
}
|
||
|
else // sinon calcul_dir_plis == 2, cela veut dire que l'on n'a pas recalculé
|
||
|
// dans la zône relâchée donc on utilise les déformations déjà calculées à t
|
||
|
{ save_resul.eps_pli = save_resul.eps_pli_t;
|
||
|
// on retient les directions des plis précendentes
|
||
|
(*save_resul.V_P_sig) = (*save_resul.V_P_sig_t);
|
||
|
};
|
||
|
};
|
||
|
// traitement des épaisseurs et des largeurs
|
||
|
// LoiContraintesPlanes::SaveResul_LoiContraintesPlanes * save_result_plan_inter // pour simplifier
|
||
|
// = (LoiContraintesPlanes::SaveResul_LoiContraintesPlanes *)
|
||
|
// (*(save_resul.liste_des_SaveResul.begin()));
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_plan_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
switch (choix_calcul_epaisseur_si_relachement_complet)
|
||
|
{ case 1: // cas où on impose un retour à l'épaisseur et à la largeur initiales
|
||
|
save_result_plan_inter->hsurh0 = 1.;
|
||
|
save_result_plan_inter->bsurb0 = 1.;
|
||
|
break;
|
||
|
case 2: // cas où on impose l'épaisseur et la largeur du pas précédent
|
||
|
{if (save_result_plan_inter->h_tsurh0 != 0.)
|
||
|
{save_result_plan_inter->hsurh0 = save_result_plan_inter->h_tsurh0;}
|
||
|
else // sinon on remet à 1.
|
||
|
{save_result_plan_inter->hsurh0 = 1.;};
|
||
|
if (save_result_plan_inter->b_tsurb0 != 0.)
|
||
|
{save_result_plan_inter->bsurb0 = save_result_plan_inter->b_tsurb0;}
|
||
|
else // sinon on remet à 1.
|
||
|
{save_result_plan_inter->bsurb0 = 1.;};
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur *** la variable choix_calcul_epaisseur_si_relachement_complet= "
|
||
|
<< choix_calcul_epaisseur_si_relachement_complet
|
||
|
<< " est differente de 1= le seul choix actuellement implante " << endl;
|
||
|
Sortie(1);
|
||
|
break;
|
||
|
};
|
||
|
// on annule la contrainte et sa contribution éventuelle à la raideur
|
||
|
sigHH.Inita(0.);
|
||
|
//d_sigma_deps_inter.Inita(0.);
|
||
|
// on annule également les énergies
|
||
|
energ.Inita(0.);
|
||
|
break;
|
||
|
}
|
||
|
case -4: // pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
{save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
break;
|
||
|
}
|
||
|
case 3: // plis dans une seule directions
|
||
|
{// va être traité en dehors du switch car c'est le gros morceau
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default: // normalement n'arrive jamais car Calcul_directions_plis a toujours une solution diff de 0
|
||
|
{ cout << "\n *** cas d'erreur inconnue dans le calcul de la direction des plis "
|
||
|
<< " save_resul.cas_cal_plis= "<< save_resul.cas_cal_plis ;
|
||
|
Sortie(1);
|
||
|
break;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test4: LoiCritere::Critere_plis_membrane(... " << flush;
|
||
|
// le gros morceau: cas où on a une seule direction
|
||
|
if (save_resul.cas_cal_plis == 3)
|
||
|
{// choix entre la méthode historique et la nouvelle méthode
|
||
|
switch (choix_methode_cal_plis_memb)
|
||
|
{case 1:
|
||
|
{Premie_type_calcul_en_un_pli(epsBB_tdt,delta_epsBB
|
||
|
,sigHH_t,jacobien_0,jacobien,energ,energ_t
|
||
|
,DepsBB,module_compressibilite,module_cisaillement
|
||
|
,V_Pr_H,sigHH,d_sigma_deps_inter
|
||
|
,valPropreSig,ex);
|
||
|
break;
|
||
|
}
|
||
|
case 2:
|
||
|
{Deuxieme_type_calcul_en_un_pli(epsBB_tdt,delta_epsBB
|
||
|
,sigHH_t,jacobien_0,jacobien,energ,energ_t
|
||
|
,DepsBB,module_compressibilite,module_cisaillement
|
||
|
,V_Pr_H,sigHH,d_sigma_deps_inter
|
||
|
,valPropreSig,ex);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n cas non prevu: choix_methode_cal_plis_memb= "
|
||
|
<< choix_methode_cal_plis_memb ;
|
||
|
Sortie(1);
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
return retour;
|
||
|
};
|
||
|
|
||
|
// calcul d'une nouvelle direction de plis
|
||
|
// en entrée: force: = true par défaut
|
||
|
// si == false -> pas de calcul de direction demandée, et mise en place
|
||
|
// des indicateurs en cohérence avec le fait de ne pas faire de calcul
|
||
|
// en retour:
|
||
|
// = -1 : pas de calcul de valeur propre possible en contrainte
|
||
|
// = 1 : pas de plis (pas de calcul de nouvelle direction )
|
||
|
// = -2 : pas de calcul de valeur propre de déformation
|
||
|
// = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide
|
||
|
// = 2 : plis dans les deux sens, calcul des directions de plis
|
||
|
// = -4 : pas de calcul de vecteurs propres possible pour les contraintes
|
||
|
// = 3 : plis dans une seule directions, calcul ok
|
||
|
// = 0 : erreur inconnue ??
|
||
|
|
||
|
int LoiCritere::Calcul_directions_plis(const TenseurBB & epsBB_tdt,const TenseurHH& sigHH
|
||
|
,Coordonnee2& valPropreEps
|
||
|
,Tableau <Coordonnee2H>& V_Pr_H
|
||
|
,const Met_abstraite::Umat_cont& ex
|
||
|
,Coordonnee2& valPropreSig
|
||
|
, bool force
|
||
|
)
|
||
|
{// dim et vérification
|
||
|
int dim_tens = abs(sigHH.Dimension());
|
||
|
V_Pr_H.Change_taille(2);
|
||
|
// normalement le critère ne s'applique que pour des tenseurs 2D
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (dim_tens != 2)
|
||
|
{ cout << "\n erreur le critere de plissement de membrane ne peut s'appliquer que pour des lois 2D"
|
||
|
<< " \n LoiCritere::Calcul_directions_plis(..";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
int retour = 0; // init par défaut
|
||
|
|
||
|
if (!force)
|
||
|
// cas particulier ou on ne veut pas de calcul, mais par contre on veut mettre les indicateurs
|
||
|
// cohérence avec le fait de ne pas faire de calcul
|
||
|
{ retour = 1; //on signale
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
// comme il n'y a pas de plis, donc par de variation de largeur
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
save_result_1DCP2_inter->Zero_var_largeur(); // mise à 0 de b_surb0
|
||
|
}
|
||
|
else
|
||
|
{// on va calculer les valeurs propres relatives au tenseur des contraintes
|
||
|
|
||
|
TenseurHB* sigHB = (NevezTenseurHB(dim_tens,0.));
|
||
|
(*sigHB) = sigHH * (* ex.gijBB_tdt);
|
||
|
int casSig = 0; // init par défaut
|
||
|
// calcul des valeurs propres correspondantes à des vecteurs propres CoordonneeH
|
||
|
valPropreSig = sigHB->ValPropre(casSig);
|
||
|
// si le calcul n'est pas possible on ne fait rien mais on poste un message
|
||
|
if (casSig == -1)
|
||
|
// ==== cas d'une erreur de valeur propre sur la contrainte ====
|
||
|
{ if (Permet_affichage() > 4)
|
||
|
cout << "\n warning : le calcul des valeurs propres de contrainte n'a pas ete possible,"
|
||
|
<< " l'application du critere de plissement n'est pas possible, et donc non effectuee " << endl;
|
||
|
retour = -1;
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
}
|
||
|
else if (valPropreSig(dim_tens) >= save_resul.niveau_declenchement_critere) // 0.)
|
||
|
{ // on se trouve dans le cas où rien n'est en compression, donc cas normal sans plissement
|
||
|
retour = 1; //on signale
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
// comme il n'y a pas de plis, donc par de variation de largeur
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
save_result_1DCP2_inter->Zero_var_largeur(); // mise à 0 de b_surb0
|
||
|
}
|
||
|
else
|
||
|
{ // ==== on se trouve dans le cas où potentiellement on peut avoir des plis ====
|
||
|
// on regarde les valeurs propres en déformation
|
||
|
|
||
|
TenseurHB* epsHB = (NevezTenseurHB(dim_tens,0.));
|
||
|
(*epsHB) = (* ex.gijHH_tdt) * epsBB_tdt;
|
||
|
int casEps = 0; // init par défaut
|
||
|
// calcul des valeurs propres correspondantes à des vecteurs propres CoordonneeH
|
||
|
valPropreEps = epsHB->ValPropre(casEps);
|
||
|
if (casEps == -1)
|
||
|
{ if (Permet_affichage() > 4)
|
||
|
cout << "\n warning : le calcul des valeurs propres de deformation n'a pas ete possible,"
|
||
|
<< " l'application du critere de plissement n'est pas possible, et donc non effectuee " << endl;
|
||
|
retour = -2;
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
}
|
||
|
else if (valPropreEps(1) < 0.)
|
||
|
// ==== cas de plis dans les deux sens ====
|
||
|
{// si la plus grande des valeurs propres de déformation est négative,
|
||
|
// dans ce cas il y a des plis dans les deux sens il faut que l'on récupère
|
||
|
// les def des plis
|
||
|
//*** il faudra grouper ce if avec le cas d'un pli de manière à éviter les erreurs de duplication ***
|
||
|
// -- on doit définir un repère ortho dont le premier vecteur est celui selon lequel on fait du 1D
|
||
|
// calcul des vecteurs propres
|
||
|
int cas = 0; // init
|
||
|
|
||
|
Tableau <Coordonnee> V_inter;
|
||
|
sigHB->VecteursPropres(valPropreSig,cas, V_inter);
|
||
|
// si cas = -1, la construction des vecteurs propres est impossible, on arrête le traitement
|
||
|
if (cas == -1)
|
||
|
{save_resul.eps_pli.Zero(); // on ne peut pas donner une intensité au def de pli !
|
||
|
// les vecteurs propres sauvegardées sont nulles
|
||
|
Coordonnee3 zero3; // un vecteur nul
|
||
|
save_resul.V_P_sig->Change_taille(3,zero3); // en 3D qui est obligatoire ici
|
||
|
retour = -3;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
if (Dabs(V_inter(1) * V_inter(2)) > ConstMath::petit)
|
||
|
{cout << "\n== LoiCritere::Critere_plis_membrane: plis dans les deux sens ";
|
||
|
//cout << "\n sigma: vecteurs propres: \n "<< V_inter;
|
||
|
cout << "\n sigma: valeurs propres: "; valPropreSig.Affiche_1(cout);
|
||
|
// on va vérifier les vecteurs propres
|
||
|
Coordonnee2H VpH1; VpH1.Change_val(V_inter(1));
|
||
|
cout << "\n vecteur propre 1 VpH1= " << VpH1;
|
||
|
Coordonnee2H VpropreH1 = (*sigHB) * VpH1;
|
||
|
//cout << "\n sigHH * VH1 "<< VpropreH1;
|
||
|
// comme les valeurs peuvent être très petites on régularise
|
||
|
VpropreH1 /= (valPropreSig(1)+ConstMath::petit);
|
||
|
cout << "\n verif: (sigHB * VH1)/(lambda1+epsilon) = "<< VpropreH1;
|
||
|
CoordonneeB aB; aB.Change_val(V_inter(2));
|
||
|
Coordonnee2H VpH2 = aB * (* ex.gijHH_tdt);
|
||
|
cout << "\n vecteur propre 2 VpH2 "<< VpH2;
|
||
|
Coordonnee2H VpropreH2 = (*sigHB) * VpH2;
|
||
|
//cout << "\n sigHH * VH2 "<< VpropreH2;
|
||
|
VpropreH2 /= (valPropreSig(2)+ConstMath::petit);
|
||
|
cout << "\n verif: (sigHB * VH2)/(lambda2+epsilon) = "<< VpropreH2;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// Le premier vecteur propre s'exprime dans la base naturelle, par contre le second s'exprime
|
||
|
// dans la base duale donc : V1^H, et V2_B
|
||
|
// donc si on veut un changement de base de naturelle en naturelle il faut calculer V2^H
|
||
|
V_Pr_H(1).Change_val(V_inter(1)); // le premier vecteur ok
|
||
|
CoordonneeB aB; aB.Change_val(V_inter(2));
|
||
|
V_Pr_H(2)= aB * (* ex.gijHH_tdt);
|
||
|
// pour l'instant ces vecteurs propres ne sont pas normés car les vecteurs
|
||
|
// de base ne sont pas normés, on va donc les normer
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n normalisation des vecteurs propres:";
|
||
|
};
|
||
|
#endif
|
||
|
// on calcul les vecteurs propres en orthonormee
|
||
|
// on définit l'espace de stockage des vecteurs propres si nécessaire
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n vecteurs propres en orthonormee:";
|
||
|
};
|
||
|
#endif
|
||
|
if (save_resul.V_P_sig == NULL)
|
||
|
save_resul.V_P_sig = new Tableau <Coordonnee>;
|
||
|
Coordonnee3 zero3; // un vecteur nul
|
||
|
save_resul.V_P_sig->Change_taille(3,zero3); // on va calculer en 3D qui est obligatoire ici
|
||
|
|
||
|
for (int be=1;be<3;be++) // be < 3 donc de 1 à 2
|
||
|
for (int al=1;al<3;al++)
|
||
|
(*save_resul.V_P_sig)(be) += V_Pr_H(be)(al) * ex.giB_tdt->Coordo(al);
|
||
|
// on norme les vecteurs après le passage en absolue (modif prise en compte)
|
||
|
for (int al=1;al<3;al++) // al < 3 erreur
|
||
|
{
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n vecteur propre ("<<al<<") local avant normalisation " << V_Pr_H(al);
|
||
|
cout << "\n vecteur propre ("<<al<<") global avant normalisation " << (*save_resul.V_P_sig)(al);
|
||
|
double norme2 = sqrt(V_Pr_H(al) * ((* ex.gijBB_tdt) * V_Pr_H(al)));
|
||
|
cout << "\n norme locale pour verif (doit etre = norme globale): "<< norme2;
|
||
|
};
|
||
|
#endif
|
||
|
double norme2 = (*save_resul.V_P_sig)(al).Norme();
|
||
|
(*save_resul.V_P_sig)(al) /= (norme2+ConstMath::petit);
|
||
|
// on norme également les vecteurs V_Pr_H qui vont être utilisés par le programme appelant
|
||
|
V_Pr_H(al) /= (norme2+ConstMath::petit);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n vecteur propre local apres normalisation " << V_Pr_H(al);
|
||
|
cout << "\n norme VPH("<<al<<") en globale avant normalisation "<< norme2;
|
||
|
cout << "\n vecteur propre ("<<al<<") global apres normalisation " << (*save_resul.V_P_sig)(al);
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
(*save_resul.V_P_sig)(3) = Util::ProdVec_coor((*save_resul.V_P_sig)(1),(*save_resul.V_P_sig)(2));
|
||
|
(*save_resul.V_P_sig)(3).Normer();// on norme le troisième vecteur *** normalement ne devrait pas être nécessaire
|
||
|
retour = 2;
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{// cas où on passe d'un comportement 2D à 1D
|
||
|
Loi_comp_abstraite* loi = *(lois_internes.begin()); // pour simplifier
|
||
|
// -- donc maintenant la suite concerne le cas où seule une direction est en traction
|
||
|
// on va se mettre en 1D dans le repère principal de contrainte
|
||
|
|
||
|
// -- on doit définir un repère ortho dont le premier vecteur est celui selon lequel on fait du 1D
|
||
|
// calcul des vecteurs propres
|
||
|
int cas = 0; // init
|
||
|
Tableau <Coordonnee> V_inter;
|
||
|
sigHB->VecteursPropres(valPropreSig,cas, V_inter);
|
||
|
// si cas = -1, la construction des vecteurs propres est impossible, on arrête le traitement
|
||
|
if (cas == -1)
|
||
|
{ if (Permet_affichage() > 4)
|
||
|
cout << "\n warning : le calcul des valeurs propres de contrainte n'a pas ete possible,"
|
||
|
<< " l'application du critere de plissement n'est pas possible, et donc non effectuee " << endl;
|
||
|
retour = -4;
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
// les vecteurs propres sauvegardées sont nulles
|
||
|
Coordonnee3 zero3; // un vecteur nul
|
||
|
save_resul.V_P_sig->Change_taille(3,zero3); // en 3D qui est obligatoire ici
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n== LoiCritere::Critere_plis_membrane plis dans un seul sens ";
|
||
|
//cout << "\n sigma: vecteurs propres: \n "<< V_inter;
|
||
|
cout << "\n sigma: valeurs propres: "; valPropreSig.Affiche_1(cout);
|
||
|
// on va vérifier les vecteurs propres
|
||
|
Coordonnee2H VpH1; VpH1.Change_val(V_inter(1));
|
||
|
cout << "\n vecteur propre 1 VpH1= " << VpH1;
|
||
|
Coordonnee2H VpropreH1 = (*sigHB) * VpH1;
|
||
|
//cout << "\n sigHH * VH1 "<< VpropreH1;
|
||
|
// comme les valeurs peuvent être très petites on régularise
|
||
|
VpropreH1 /= (valPropreSig(1)+ConstMath::petit);
|
||
|
cout << "\n verif: (sigHB * VH1)/(lambda1+epsilon) = "<< VpropreH1;
|
||
|
CoordonneeB aB; aB.Change_val(V_inter(2));
|
||
|
Coordonnee2H VpH2 = aB * (* ex.gijHH_tdt);
|
||
|
cout << "\n vecteur propre 2 VpH2 "<< VpH2;
|
||
|
Coordonnee2H VpropreH2 = (*sigHB) * VpH2;
|
||
|
//cout << "\n sigHH * VH2 "<< VpropreH2;
|
||
|
VpropreH2 /= (valPropreSig(2)+ConstMath::petit);
|
||
|
cout << "\n verif: (sigHB * VH2)/(lambda2+epsilon) = "<< VpropreH2;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// Le premier vecteur propre s'exprime dans la base naturelle, par contre le second s'exprime
|
||
|
// dans la base duale donc : V1^H, et V2_B
|
||
|
// donc si on veut un changement de base de naturelle en naturelle il faut calculer V2^H
|
||
|
V_Pr_H(1).Change_val(V_inter(1)); // le premier vecteur ok
|
||
|
CoordonneeB aB; aB.Change_val(V_inter(2));
|
||
|
V_Pr_H(2)= aB * (* ex.gijHH_tdt);
|
||
|
// pour l'instant ces vecteurs propres ne sont pas normés car les vecteurs
|
||
|
// de base ne sont pas normés, on va donc les normer
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n normalisation des vecteurs propres:";
|
||
|
};
|
||
|
#endif
|
||
|
// on calcul les vecteurs propres en orthonormee
|
||
|
// on définit l'espace de stockage des vecteurs propres si nécessaire
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() >5)
|
||
|
{cout << "\n vecteurs propres en orthonormee:";
|
||
|
};
|
||
|
#endif
|
||
|
if (save_resul.V_P_sig == NULL) save_resul.V_P_sig = new Tableau <Coordonnee>;
|
||
|
Coordonnee3 zero3; // un vecteur nul
|
||
|
save_resul.V_P_sig->Change_taille(3,zero3); // on va calculer en 3D
|
||
|
|
||
|
for (int be=1;be<3;be++) // be < 3 donc de 1 à 2
|
||
|
for (int al=1;al<3;al++)
|
||
|
(*save_resul.V_P_sig)(be) += V_Pr_H(be)(al) * ex.giB_tdt->Coordo(al);
|
||
|
// on norme les vecteurs après le passage en absolue
|
||
|
for (int al=1;al<3;al++) // al < 3 erreur
|
||
|
{
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n vecteur propre local avant normalisation " << V_Pr_H(al);
|
||
|
cout << "\n vecteur propre ("<<al<<") global avant normalisation " << (*save_resul.V_P_sig)(al);
|
||
|
double norme2 = sqrt(V_Pr_H(al) * ((* ex.gijBB_tdt) * V_Pr_H(al)));
|
||
|
cout << "\n norme locale pour verif (doit etre = norme globale): "<< norme2;
|
||
|
};
|
||
|
#endif
|
||
|
double norme2 = (*save_resul.V_P_sig)(al).Norme();
|
||
|
(*save_resul.V_P_sig)(al) /= ((norme2)+ConstMath::petit);
|
||
|
// on norme également les vecteurs V_Pr_H qui vont être utilisés par le programme appelant
|
||
|
V_Pr_H(al) /= (norme2+ConstMath::petit);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n vecteur propre local apres normalisation " << V_Pr_H(al);
|
||
|
cout << "\n norme VPH("<<al<<") en globale avant normalisation "<< norme2;
|
||
|
cout << "\n vecteur propre ("<<al<<") global apres normalisation " << (*save_resul.V_P_sig)(al);
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
(*save_resul.V_P_sig)(3) = Util::ProdVec_coor((*save_resul.V_P_sig)(1),(*save_resul.V_P_sig)(2));
|
||
|
(*save_resul.V_P_sig)(3).Normer();// on norme le troisième vecteur *** normalement ne devrait pas être nécessaire
|
||
|
retour = 3;
|
||
|
};
|
||
|
};
|
||
|
// on supprime les tenseurs provisoires
|
||
|
delete epsHB;
|
||
|
};
|
||
|
// on supprime les tenseurs provisoires
|
||
|
delete sigHB;
|
||
|
};
|
||
|
|
||
|
// mise à jour de l'indicateur dans save_resul
|
||
|
save_resul.cas_cal_plis=retour;
|
||
|
// affichage conditionnelle
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 4)
|
||
|
{bool erreur = false;
|
||
|
switch (retour)
|
||
|
{ case -1 : cout << "\n pas de calcul de valeur propre possible en contrainte ";erreur=true;break;
|
||
|
case -2 : cout << "\n pas de calcul de valeur propre possible de deformation "; erreur=true;break;
|
||
|
case -3 : cout << "\n plis dans les deux sens, mais pas de calcul de direction propre valide "; erreur=true;break;
|
||
|
case -4 : cout << "\n pas de calcul de vecteurs propres possible pour les contraintes "; erreur=true;break;
|
||
|
case 0 : cout << "\n erreur inconnue dans le calcul directions plis ?? "; erreur=true;break;
|
||
|
default: break; // cas normal, aucun affichage
|
||
|
};
|
||
|
if (erreur)
|
||
|
if (ptintmeca_en_cours != NULL)
|
||
|
cout << " mail: "<< ptintmeca_en_cours->Nb_mail() << " ele: "<< ptintmeca_en_cours->Nb_ele()
|
||
|
<< " npti: "<< ptintmeca_en_cours->Nb_pti() ;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// retour
|
||
|
return retour;
|
||
|
};
|
||
|
|
||
|
|
||
|
// création du conteneur UMAT a partir des vecteurs propres
|
||
|
void LoiCritere::Creation_metrique_a_partir_vecteurs_propres_pour_Umat1D
|
||
|
(const Met_abstraite::Umat_cont& ex,const Mat_pleine& beta )
|
||
|
{
|
||
|
// on va se mettre en 1D dans le repère principal de contrainte
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
|
||
|
// la partie dépendant des vitesses: entre accolades pour pouvoir fermer
|
||
|
// ici il est nécessaire de recalculer les gradients dans la nouvelle base
|
||
|
// dans le cas où ils existent
|
||
|
{if (ex.gradVmoyBB_t != NULL)
|
||
|
{umat_cont_1D->gradVmoyBB_t= gradVmoyBB_t_1D_P = &gradVmoyBB_t_1D;
|
||
|
// on change de base
|
||
|
TenseurBB* t_interBB = NevezTenseurBB(*ex.gradVmoyBB_t);
|
||
|
t_interBB->ChBase(beta);
|
||
|
// puis on transfert en 1D
|
||
|
umat_cont_1D->gradVmoyBB_t->Affectation_trans_dimension(*t_interBB,true);
|
||
|
delete t_interBB;
|
||
|
};
|
||
|
if (ex.gradVmoyBB_tdt != NULL)
|
||
|
{umat_cont_1D->gradVmoyBB_tdt=gradVmoyBB_tdt_1D_P = &gradVmoyBB_tdt_1D;
|
||
|
// on change de base
|
||
|
TenseurBB* t_interBB = NevezTenseurBB(*ex.gradVmoyBB_tdt);
|
||
|
t_interBB->ChBase(beta);
|
||
|
// puis on transfert en 1D
|
||
|
umat_cont_1D->gradVmoyBB_tdt->Affectation_trans_dimension(*t_interBB,true);
|
||
|
delete t_interBB;
|
||
|
};
|
||
|
if (ex.gradVBB_tdt != NULL)
|
||
|
{umat_cont_1D->gradVBB_tdt=gradVBB_tdt_1D_P = &gradVBB_tdt_1D;
|
||
|
// on change de base
|
||
|
TenseurBB* t_interBB = NevezTenseurBB(*ex.gradVBB_tdt);
|
||
|
t_interBB->ChBase(beta);
|
||
|
// puis on transfert en 1D
|
||
|
umat_cont_1D->gradVBB_tdt->Affectation_trans_dimension(*t_interBB,true);
|
||
|
delete t_interBB;
|
||
|
};
|
||
|
}; // fin de la partie dédiée à la vitesse
|
||
|
|
||
|
// -- maintenant on construit les éléments de l'Umat pour le repère ortho avec 1 seul
|
||
|
// vecteur de base, et en orthonormé
|
||
|
// en fait on va construire un repère orthonormé à partir des vecteurs propres
|
||
|
// **** comme on considère que la base locale est orthonormé, normalement elle ne change pas
|
||
|
// pour l'instant on laisse sa construction, mais en fait une seule est suffisante
|
||
|
// ***** 2 oct 2018: je commente la ligne qui suit car en fait j'ai l'impression
|
||
|
// que la base change puisqu'elle vaut les directions propres et que ceux-ci dépendent
|
||
|
// du calcul .... là je ne comprends pas pourquoi j'ai mis le test ....
|
||
|
// if ((*(umat_cont_1D->gijBB_0))(1,1) == 0.) // pour savoir si la construction a été faite on non
|
||
|
{ // les vecteurs propres sont considérés normés: cf. voir leurs calculs
|
||
|
BaseB& giB_tdt = *(umat_cont_1D->giB_tdt); // pour simplifier
|
||
|
const Coordonnee& V_sig = (*save_resul.V_P_sig)(1); // pour simplifier
|
||
|
giB_tdt.CoordoB(1).Change_val(V_sig); // on utilise un vecteur 3D, ici dans la base orthonormee
|
||
|
// giB_tdt(1) = V_Pr_B(1); //.Change_val(V_sig);
|
||
|
// giB_tdt(1)(1) = 1.;
|
||
|
// idem pour les temps 0 et t
|
||
|
*(umat_cont_1D->giB_0)=giB_tdt;
|
||
|
*(umat_cont_1D->giB_t)=giB_tdt;
|
||
|
// idem pour le contravariant
|
||
|
BaseH& giH_tdt = *(umat_cont_1D->giH_tdt); // pour simplifier
|
||
|
// comme la base est orthonormée, H et B sont identiques
|
||
|
giH_tdt.CoordoH(1).Change_val(V_sig);
|
||
|
// giH_tdt(1).Change_val(V_Pr_B(1).Coor());
|
||
|
// giH_tdt(1)(1) = 1.;
|
||
|
*(umat_cont_1D->giH_0)=giH_tdt;
|
||
|
*(umat_cont_1D->giH_t)=giH_tdt;
|
||
|
// maintenant les métriques : ici identité
|
||
|
(*(umat_cont_1D->gijBB_0)).Coor(1,1)=(*(umat_cont_1D->gijHH_0)).Coor(1,1)=1.;
|
||
|
(*(umat_cont_1D->gijBB_t)).Coor(1,1)=(*(umat_cont_1D->gijHH_t)).Coor(1,1)=1.;
|
||
|
(*(umat_cont_1D->gijBB_tdt)).Coor(1,1)=(*(umat_cont_1D->gijHH_tdt)).Coor(1,1)=1.;
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n LoiCritere::Creation_metrique_a_partir_vecteurs_propres_pour_Umat1D( ";
|
||
|
cout << "\n base gipB(1) "<< giB_tdt(1)
|
||
|
<< "\n base gipH(1) "<< giH_tdt(1);
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// passage des grandeurs métriques de l'ordre 3 ou 2 à 1: cas implicite
|
||
|
void LoiCritere::Passage_metrique_ordre_3_2_vers_1(const Met_abstraite::Umat_cont& ex,const Mat_pleine& gamma)
|
||
|
{};
|
||
|
|
||
|
|
||
|
// chgt de repère et de dimension pour les variables de passage pour le calcul final de la loi en 1D
|
||
|
void LoiCritere::Passage_3ou2_vers_1(const Mat_pleine& gamma,const TenseurHH & sigHH_t
|
||
|
,const Mat_pleine& beta
|
||
|
,const TenseurBB& DepsBB
|
||
|
,const TenseurBB & epsBB_tdt,const TenseurBB & delta_epsBB
|
||
|
,const bool& deux_plis,Coordonnee2& eps_pli)
|
||
|
{ // on s'occupe du changement de base
|
||
|
int dim_tens = abs(sigHH_t.Dimension());
|
||
|
// on crée des nouveaux tenseurs au lieu d'utiliser les tenseurs initiaux, car on fait un changement de base
|
||
|
// qui a pour effet de modifier le tenseur. Donc si ensuite on veut utiliser les tenseurs initiaux, ce ne sera
|
||
|
// plus possible comme initialement
|
||
|
if (dim_tens == 2)
|
||
|
{ Tenseur2HH sigHH_2_inter(sigHH_t); sigHH_2_inter.ChBase(gamma);
|
||
|
sig_HH_t_1D.Affectation_trans_dimension(sigHH_2_inter,false);// passage des tenseurs résultats à l'ordre 1
|
||
|
Tenseur2BB DepsBB_2_inter(DepsBB); DepsBB_2_inter.ChBase(beta);
|
||
|
Deps_BB_1D.Affectation_trans_dimension(DepsBB_2_inter,false);
|
||
|
Tenseur2BB epsBB_tdt_2_inter(epsBB_tdt);epsBB_tdt_2_inter.ChBase(beta);
|
||
|
/*
|
||
|
|
||
|
Lorsqu'il y a un pli dans une seule direction, le premier vecteur indique la direction selon laquelle la membrane est en traction. Son intensité est égale à la déformation mécanique dans cette même direction. Le second vecteur est normal à la première direction, son intensité est égale à la déformation cinématique selon cette direction, c'est-à-dire calculée à l'aide des déplacements des noeuds du maillage. Cette déformation est différente de la déformation mécanique calculée par la loi 3D, c'est-à-dire issue de la contraction de la zone, due à la traction suivant la première direction. Cette déformation mécanique peut-être récupéré via la deformation "DEF\_LARGEUR" associée à la loi de comportement.
|
||
|
|
||
|
Lorsqu'il y a des plis dans deux directions, les deux vecteurs indiquent les directions principales d'apparition de plis. L'intensité des vecteurs est égale à la déformation cinématique dans la direction associée.
|
||
|
|
||
|
Lorsqu'il n'y a pas de plis, l'intensité des vecteurs est nulle.
|
||
|
|
||
|
*/
|
||
|
|
||
|
eps_pli(1) = epsBB_tdt_2_inter(2,2); // on sauvegarde les def de plis
|
||
|
if (deux_plis) // cas où il y aurait des plis dans les deux sens
|
||
|
eps_pli(2) = epsBB_tdt_2_inter(1,1);
|
||
|
else eps_pli(2) = 0.; // cas d'un seul plis
|
||
|
eps_BB_1D.Affectation_trans_dimension(epsBB_tdt_2_inter,false);
|
||
|
Tenseur2BB delta_epsBB_2_inter(delta_epsBB); delta_epsBB_2_inter.ChBase(beta);
|
||
|
delta_eps_BB_1D.Affectation_trans_dimension(delta_epsBB_2_inter,false);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{cout << "\n debug LoiCritere::Passage_3ou2_vers_1( ";
|
||
|
cout << "\n sigHH_t= en g_i "; sigHH_t.Ecriture(cout);
|
||
|
cout << "\n sigHH_t= en vecteurs propres "<< sigHH_2_inter;
|
||
|
cout << "\n epsBB_tdt en gi ";epsBB_tdt.Ecriture(cout);
|
||
|
cout << "\n epsBB_tdt en vecteurs propres "<< epsBB_tdt_2_inter;
|
||
|
cout << "\n epsBB 1D en local vecteurs propres " << eps_BB_1D;
|
||
|
// en orthonormee
|
||
|
Tenseur3BB epsBB_3_inter;
|
||
|
eps_BB_1D.BaseAbsolue(epsBB_3_inter,(giH_tdt_1D));
|
||
|
cout << "\n base giH_tdt_1D: "<<giH_tdt_1D;
|
||
|
cout << "\n epsBB 1D =en orthonormee (contient que l'action de la composante de traction) \n "
|
||
|
<<epsBB_3_inter;
|
||
|
cout << "\n delta_epsBB en vecteurs propres= "<< delta_epsBB_2_inter;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
else // cas 3D
|
||
|
{ Tenseur3HH sigHH_3_inter(sigHH_t); sigHH_3_inter.ChBase(gamma);
|
||
|
sig_HH_t_1D.Affectation_trans_dimension(sigHH_3_inter,false);// passage des tenseurs résultats à l'ordre 1
|
||
|
Tenseur3BB DepsBB_3_inter(DepsBB); DepsBB_3_inter.ChBase(beta);
|
||
|
Deps_BB_1D.Affectation_trans_dimension(DepsBB_3_inter,false);
|
||
|
Tenseur3BB epsBB_tdt_3_inter(epsBB_tdt);epsBB_tdt_3_inter.ChBase(beta);
|
||
|
eps_BB_1D.Affectation_trans_dimension(epsBB_tdt_3_inter,false);
|
||
|
Tenseur3BB delta_epsBB_3_inter(delta_epsBB); delta_epsBB_3_inter.ChBase(beta);
|
||
|
delta_eps_BB_1D.Affectation_trans_dimension(delta_epsBB_3_inter,false);
|
||
|
};
|
||
|
// cas des jacobiens: il nous faut définir des jacobiens cohérents en 1D au niveau de leur
|
||
|
// variation entre 0 et tdt
|
||
|
// on se sert de la déformation et d'un jacobien final mis à 1. arbitrairement
|
||
|
jacobien_tdt_1D = 1.; // initialisation arbitraire
|
||
|
// -- maintenant on tient compte du type de déformation, et de sa valeur 11
|
||
|
// sachant que le repère actuel est normé, donc le repère initial ne peut pas être normé
|
||
|
// le vecteur de base est le vecteur propre
|
||
|
// en 1D la longueur est le jacobien
|
||
|
switch (type_de_deformation)
|
||
|
{case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
|
||
|
// cas d'une déformation d'Almansi
|
||
|
{ // epsBB11 = 1/2 * (1. - (l0/l)^2), dans un repère normé, ce qui est le cas ici
|
||
|
// -> l0 = l * sqrt(1. - 2.* eps11)
|
||
|
jacobien_0_1D = sqrt(1.-eps_BB_1D(1,1));
|
||
|
};
|
||
|
break;
|
||
|
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
|
||
|
// cas d'une def logarithmique ou une approximation
|
||
|
// epsBB11 = log (l/l0) --> l0 = l / exp(epsBB11)
|
||
|
{ jacobien_0_1D = jacobien_tdt_1D / exp(eps_BB_1D(1,1));
|
||
|
};
|
||
|
break;
|
||
|
default :
|
||
|
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
|
||
|
<< Nom_type_deformation(type_de_deformation);
|
||
|
cout << "\n LoiCritere::Passage_3ou2_vers_1(.. \n";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
};
|
||
|
|
||
|
// passage inverse: chgt de repère et de dimension pour les variables de passage
|
||
|
// et stockage des infos de doublement plane pour le post-traitement pour le prochain appel
|
||
|
// en entrée: d_sigma_deps_1D : l'opérateur qui a été calculé
|
||
|
// en sortie: d_sigma_deps_inter
|
||
|
void LoiCritere::Passage_1_vers_3ou2(const Mat_pleine& gamma,TenseurHH & sigHH
|
||
|
,const TenseurHHHH& d_sigma_deps_1D
|
||
|
,const Mat_pleine& beta
|
||
|
,TenseurHHHH& d_sigma_deps_inter,const Met_abstraite::Umat_cont& ex
|
||
|
,const Tableau <Coordonnee2H>& V_Pr_H
|
||
|
,const Tableau <Coordonnee>& V_P_sig)
|
||
|
{ // on s'occupe du changement de base
|
||
|
int dim_tens = abs(sigHH.Dimension());
|
||
|
// if (dim_tens == 2)
|
||
|
// { // normalement les contraintes sont nulles dans les directions autres que 11
|
||
|
// sigHH.Affectation_trans_dimension(sig_HH_t_1D,true);
|
||
|
// sigHH.ChBase(beta); // on revient dans le repère naturel
|
||
|
// }
|
||
|
// else // cas 3D
|
||
|
// { Tenseur3HH sigHH_3_inter(sigHH_t); sigHH_3_inter.ChBase(gamma);
|
||
|
// sig_HH_t_1D.Affectation_trans_dimension(sigHH_3_inter,false);// passage des tenseurs résultats à l'ordre 1
|
||
|
// Tenseur3BB DepsBB_3_inter(DepsBB); DepsBB_3_inter.ChBase(gamma);
|
||
|
// Deps_BB_1D.Affectation_trans_dimension(DepsBB_3_inter,false);
|
||
|
// Tenseur3BB epsBB_tdt_3_inter(epsBB_tdt);epsBB_tdt_3_inter.ChBase(gamma);
|
||
|
// eps_BB_1D.Affectation_trans_dimension(epsBB_tdt_3_inter,false);
|
||
|
// Tenseur3BB delta_epsBB_3_inter(delta_epsBB); delta_epsBB_3_inter.ChBase(gamma);
|
||
|
// delta_eps_BB_1D.Affectation_trans_dimension(delta_epsBB_3_inter,false);
|
||
|
// };
|
||
|
|
||
|
// normalement les contraintes sont nulles dans les directions autres que 11
|
||
|
sigHH.Affectation_trans_dimension(sig_HH_1D,true);
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{Tenseur2HH sigHH_2_inter(sigHH);
|
||
|
cout << "\n LoiCritere::Passage_1_vers_3ou2(";
|
||
|
cout << "\n sigHH (en VP) affecté du resultat 1D = "; sigHH.Ecriture(cout);
|
||
|
// en base orthonormee
|
||
|
Tenseur3HH sigHH_3_inter;
|
||
|
sig_HH_1D.BaseAbsolue(sigHH_3_inter,(giB_tdt_1D));
|
||
|
cout << "\n sigHH 1D =en orthonormee "<<sigHH_3_inter;
|
||
|
// cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test2: LoiCritere::Passage_1_vers_3ou2(... " << flush;
|
||
|
// changement de base pour la contrainte
|
||
|
// ici il s'agit de revenir à la base initiale il faut donc utiliser
|
||
|
// l'inverse gamma c-a-d finalement beta transposée
|
||
|
sigHH.ChBase(beta.Transpose()); // on revient dans le repère naturel
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{Tenseur2HH sigHH_2_inter(sigHH);
|
||
|
// cout << "\n debug LoiCritere::Passage_1_vers_3ou2(";
|
||
|
cout << "\n sigHH en g_i après changement de base "; sigHH.Ecriture(cout);
|
||
|
// en base orthonormee
|
||
|
Tenseur3HH sigHH_3_inter;
|
||
|
sigHH.BaseAbsolue(sigHH_3_inter,(* ex.giB_tdt));
|
||
|
cout << "\n sigHH = en orthonormee "<<sigHH_3_inter;
|
||
|
// cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// concernant l'opérateur tangent: pour l'instant on a un opérateur en 33, mais une seule
|
||
|
// valeur est utilisée ! peut-être à changer par la suite, en tenseur 11
|
||
|
// Tenseur3HHHH& d_sig_deps_3HHHH = *((Tenseur3HHHH *) &d_sigma_deps);
|
||
|
// d_sig_deps_1HHHH.ChangeBase(<#TenseurHHHH &A#>, const BaseB &gi)
|
||
|
if (dim_tens == 2)
|
||
|
{ // un tenseur de travail qui contient l'opérateur tangent, mais transporté en 2D
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test3: LoiCritere::Passage_1_vers_3ou2(... " << flush;
|
||
|
Tenseur2HHHH tens_travail2HHHH;
|
||
|
bool plusZero=true;
|
||
|
tens_travail2HHHH.Affectation_trans_dimension(*d_sigma_deps_1D_P,plusZero);
|
||
|
// construction de la base qui permet de passer des vecteurs propres au gi
|
||
|
// donc on veut: V_al = beta_al^be g_be
|
||
|
// il se trouve que c'est égal à la matrice passée en paramètre : beta(al,be)
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test4: LoiCritere::Passage_1_vers_3ou2(... " << flush;
|
||
|
BaseB V_al_B(2,2,0.);
|
||
|
V_al_B.CoordoB(1)(1) = beta(1,1);V_al_B.CoordoB(1)(2) = beta(1,2);
|
||
|
V_al_B.CoordoB(2)(1) = beta(2,1);V_al_B.CoordoB(2)(2) = beta(2,2);
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{//cout << "\n debug LoiCritere::Passage_1_vers_3ou2(";
|
||
|
// vérif du calcul de la base
|
||
|
// cout << "\n BaseB des gi \n "<< (* ex.giB_tdt);
|
||
|
cout << "\n construction d'une BaseB V_al_B pour cgt base tenseurHHHH \n "<< V_al_B;
|
||
|
// calcul long
|
||
|
BaseB V_inter_B(2,2,0.);
|
||
|
for (int al = 1;al < 3; al++)
|
||
|
for (int be = 1; be < 3; be++)
|
||
|
V_inter_B.CoordoB(al)(be) = (* ex.giH_tdt).Coordo(be) * V_P_sig(al);
|
||
|
cout << "\n BaseB V_inter_B "<< V_inter_B;
|
||
|
|
||
|
// pour voir si la base est correcte on la teste sur le tenseur des contraintes
|
||
|
Tenseur2HH sigHH_2_inter;
|
||
|
// on exprime sigHH dans la base des V_P qui ici est considéré comme absolue pour la vérif
|
||
|
sig_HH_1D.BaseAbsolue(sigHH_2_inter,V_al_B);
|
||
|
cout << "\n verif via sig_HH_1D = dans la base des gi de nouveau \n "<<sigHH_2_inter;
|
||
|
// cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// on fait le changement de base
|
||
|
Tenseur2HHHH* d_sig_deps_2HHHH = ((Tenseur2HHHH *) &d_sigma_deps_inter);
|
||
|
// d_sig_deps_2HHHH->ChangeBase(tens_travail2HHHH,gi_al_B);
|
||
|
tens_travail2HHHH.ChangeBase(*d_sig_deps_2HHHH,V_al_B);
|
||
|
}
|
||
|
else // cas 3D
|
||
|
{ //if (d_sigma_deps_inter == NULL)
|
||
|
// d_sigma_deps_inter = NevezTenseurHHHH(3);
|
||
|
// la suite dépendra de l'application donc du critère, donc on met un message
|
||
|
// pour l'instant
|
||
|
cout << "\n pour l'instant la suite n'est pas codee !! se plaindre !! "
|
||
|
<< "\n LoiCritere::Passage_1_vers_3ou2(..." << endl;
|
||
|
Sortie(2);
|
||
|
};
|
||
|
// if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5))
|
||
|
// cout << "\n test7: LoiCritere::Passage_1_vers_3ou2(... " << flush;
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
// fonction interne utilisée par les classes dérivées de Loi_comp_abstraite
|
||
|
// pour répercuter les modifications de la température
|
||
|
// ici utiliser pour modifier la température des lois élémentaires
|
||
|
// l'Enum_dure: indique quel est la température courante : 0 t ou tdt
|
||
|
void LoiCritere::RepercuteChangeTemperature(Enum_dure temps)
|
||
|
{ list <Loi_comp_abstraite *>::const_iterator ili,ilifin=lois_internes.end();
|
||
|
for (ili=lois_internes.begin();ili!=ilifin;ili++)
|
||
|
{(*ili)->temperature_0 = this->temperature_0;
|
||
|
(*ili)->temperature_t = this->temperature_t;
|
||
|
(*ili)->temperature_tdt = this->temperature_tdt;
|
||
|
(*ili)->dilatation=dilatation;
|
||
|
|
||
|
// on répercute également les déformations thermiques, qui ne sont utilisées
|
||
|
// telles quelles que pour certaines lois: ex: loi hyper-élastique
|
||
|
if (dilatation)
|
||
|
{// a- dimensionnement des tenseurs intermédiaires
|
||
|
int dim_tens = epsBB_therm->Dimension();
|
||
|
// -- cas de la déformation
|
||
|
if ((*ili)->epsBB_therm == NULL) { (*ili)->epsBB_therm = NevezTenseurBB(dim_tens);}
|
||
|
else if ((*ili)->epsBB_therm->Dimension() != dim_tens)
|
||
|
{ delete (*ili)->epsBB_therm;(*ili)->epsBB_therm = NevezTenseurBB(dim_tens);};
|
||
|
// -- cas de la vitesse de déformation
|
||
|
if ((*ili)->DepsBB_therm == NULL) { (*ili)->DepsBB_therm = NevezTenseurBB(dim_tens);}
|
||
|
else if ((*ili)->DepsBB_therm->Dimension() != dim_tens)
|
||
|
{ delete (*ili)->DepsBB_therm;(*ili)->DepsBB_totale = NevezTenseurBB(dim_tens);};
|
||
|
// b- affectation des tenseurs
|
||
|
(*(*ili)->epsBB_therm)=(*epsBB_therm);
|
||
|
(*(*ili)->DepsBB_therm)=(*DepsBB_therm);
|
||
|
};
|
||
|
|
||
|
(*ili)->RepercuteChangeTemperature(temps);
|
||
|
|
||
|
switch (temps)
|
||
|
{ case TEMPS_0: {(*ili)->temperature = &(*ili)->temperature_0; break;}
|
||
|
case TEMPS_t: {(*ili)->temperature = &(*ili)->temperature_t; break;}
|
||
|
case TEMPS_tdt: {(*ili)->temperature = &(*ili)->temperature_tdt; break;}
|
||
|
default:
|
||
|
{ cout << "\n erreur, cas de temps non prevu !! "
|
||
|
<< "\n LoiCritere::RepercuteChangeTemperature(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// fonction surchargée dans les classes dérivée si besoin est
|
||
|
void LoiCritere::CalculGrandeurTravail
|
||
|
(const PtIntegMecaInterne& ptintmeca
|
||
|
,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP
|
||
|
,const Met_abstraite::Impli* ex_impli
|
||
|
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
|
||
|
,const Met_abstraite::Umat_cont* ex_umat
|
||
|
,const List_io<Ddl_etendu>* exclure_dd_etend
|
||
|
,const List_io<const TypeQuelconque *>* exclure_Q
|
||
|
)
|
||
|
{ if (avec_ponderation)
|
||
|
{ // on passe en revue les grandeurs servant au calcul des fonctions de proportion
|
||
|
list <Ponderation >::iterator il,ilfin=list_ponderation.end();
|
||
|
list <double>::iterator ipfonc = fonc_ponder.begin();
|
||
|
for (il=list_ponderation.begin();il != ilfin;il++,ipfonc++)
|
||
|
{ Ponderation& ponder = (*il); // pour simplifier
|
||
|
(*ipfonc)=1.; // init
|
||
|
int taille = ponder.Type_grandeur().Taille();
|
||
|
for (int i=1;i<= taille; i++)
|
||
|
{ // calcul des pondérations
|
||
|
if (ponder.Valeur_aux_noeuds()(i)) // pour l'instant que des ddl patentés !
|
||
|
// cas d'une proportion provenant d'une interpolation aux noeuds
|
||
|
{ double grand = def.DonneeInterpoleeScalaire(ponder.Type_grandeur()(i).Enum(),temps);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(grand);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
}
|
||
|
else
|
||
|
// sinon il s'agit d'une grandeur directement accessible au point d'intégration
|
||
|
// pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers
|
||
|
{
|
||
|
// deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu
|
||
|
if (ponder.Type_grandeur()(i).Nom_vide())
|
||
|
{switch (ponder.Type_grandeur()(i).Enum())
|
||
|
{ case PROP_CRISTA:
|
||
|
{ const double* taux_crita = dTP.TauxCrista();
|
||
|
if (taux_crita != NULL)
|
||
|
{ double fonc = ponder.C_proport()(i)->Valeur(*taux_crita);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration "
|
||
|
<< " il n'est pas possible de calculer la proportion pour la loi des melanges "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur, le type de proportion " << ponder.Type_grandeur()(i) << " n'est pas disponible "
|
||
|
<< " pour l'instant au point d'integration ! "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{// cas d'un vrai ddl étendue
|
||
|
switch (ponder.Type_grandeur()(i).Position()-NbEnum_ddl())
|
||
|
{case 87: // cas de "def_equivalente"
|
||
|
{const double def_equivalente = ptintmeca.Deformation_equi_const()(1); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_equivalente);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
//cout << "\n defEqui= " << def_equivalente << " fonct= " << fonc << " ";
|
||
|
break;
|
||
|
}
|
||
|
case 88: // cas de "def_duale_mises_maxi"
|
||
|
{const double def_duale_mises_maxi = ptintmeca.Deformation_equi_const()(3); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises_maxi);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 89: // cas de "vitesse_def_equivalente"
|
||
|
{const double delta_def_equivalente = ptintmeca.Deformation_equi_const()(4); // recup du delta def equi
|
||
|
// recup de l'incrément de temps
|
||
|
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
|
||
|
double unSurDeltat=0;
|
||
|
if (Abs(deltat) >= ConstMath::trespetit)
|
||
|
{unSurDeltat = 1./deltat;}
|
||
|
else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
|
||
|
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
|
||
|
if (unSurDeltat < 0)
|
||
|
{ cout << "\n le pas de temps est négatif !! "; };
|
||
|
unSurDeltat = ConstMath::tresgrand;
|
||
|
};
|
||
|
double vitesse_def_equi = delta_def_equivalente * unSurDeltat;
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(vitesse_def_equi);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
//cout << "\n vit= " << vitesse_def_equi << " f= " << fonc << endl;
|
||
|
break;
|
||
|
}
|
||
|
case 77: // cas de "def_duale_mises"
|
||
|
{const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 78: // cas de "Spherique_eps"
|
||
|
{const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants
|
||
|
double spherique_eps = epsInvar(1);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(spherique_eps);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 81: // cas de "Spherique_sig"
|
||
|
{const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants
|
||
|
double spherique_sig = sigInvar(1);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(spherique_sig);
|
||
|
(*ipfonc) *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur, le type de proportion " << ponder.Type_grandeur()(i)
|
||
|
<< " n'est pas disponible "
|
||
|
<< " pour l'instant au point d'integration ! "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// enregistrement dans les variables spécifiques au point calculé
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
save_resul.f_ponder = fonc_ponder;
|
||
|
// on initialise le niveau de déclanchement avec les grandeurs de la lois
|
||
|
// si la valeur est différente de 0, sinon ce sera 1.
|
||
|
// if (niveau_declenchement_critere != 0.)
|
||
|
// {save_resul.niveau_declenchement_critere = niveau_declenchement_critere;}
|
||
|
// else
|
||
|
// {save_resul.niveau_declenchement_critere = 1.;};
|
||
|
// init par défaut
|
||
|
save_resul.niveau_declenchement_critere = niveau_declenchement_critere;
|
||
|
|
||
|
if (avecNiveauSigmaI_mini_pour_plis)
|
||
|
{// on initialise le niveau de déclanchement avec les grandeurs de la lois
|
||
|
// si la valeur est différente de 0, sinon ce sera 1.
|
||
|
// car en multiplication, si on par de 0 cela donnera toujours 0
|
||
|
// if (niveau_declenchement_critere == 0.)
|
||
|
// {save_resul.niveau_declenchement_critere = 1.;};
|
||
|
// non on ne fait pas cela sinon c'est compliqué à comprendre
|
||
|
// donc si on est dans un niveau réglable, systématiquement on met 1.
|
||
|
// ce qui fait que l'on a directement la valeur de la fonction
|
||
|
save_resul.niveau_declenchement_critere = 1.;
|
||
|
|
||
|
if (niveauF_fct_nD != NULL)
|
||
|
{ // on appel la fonction générique
|
||
|
list <SaveResul*> list_save; // inter pour l'appel de la fonction
|
||
|
list_save.push_back(saveResul);
|
||
|
|
||
|
Tableau <double> & tab = Loi_comp_Valeur_FnD_Evoluee
|
||
|
(niveauF_fct_nD->C_proport(),1
|
||
|
,ex_impli,ex_expli_tdt,ex_umat
|
||
|
,exclure_dd_etend,exclure_Q
|
||
|
,&list_save
|
||
|
);
|
||
|
|
||
|
// // comme il s'agit d'une grandeur globale, on n'a pas besoin de la récupérer
|
||
|
// double fonc = niveauF_fct_nD->C_proport()->Valeur_pour_variables_globales()(1);
|
||
|
// save_resul.niveau_declenchement_critere *= fonc;
|
||
|
|
||
|
save_resul.niveau_declenchement_critere *= tab(1);
|
||
|
|
||
|
};
|
||
|
if (niveauF_temps != NULL) // cas d'une dépendance au temps
|
||
|
{ const VariablesTemps& var_temps = ParaGlob::Variables_de_temps();
|
||
|
double fonc = niveauF_temps->Valeur(var_temps.TempsCourant());
|
||
|
save_resul.niveau_declenchement_critere *= fonc;
|
||
|
};
|
||
|
// avec une dépendance via éventuellement un ddl étendu
|
||
|
if (niveauF_ddlEtendu != NULL)
|
||
|
{ Ponderation& ponder = *niveauF_ddlEtendu; // pour simplifier
|
||
|
double fonc_finale = 1.; // init
|
||
|
int taille = ponder.Type_grandeur().Taille();
|
||
|
for (int i=1;i<= taille; i++)
|
||
|
{ // calcul des pondérations
|
||
|
if (ponder.Valeur_aux_noeuds()(i)) // pour l'instant que des ddl patentés !
|
||
|
// cas d'une proportion provenant d'une interpolation aux noeuds
|
||
|
{ double grand = def.DonneeInterpoleeScalaire(ponder.Type_grandeur()(i).Enum(),temps);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(grand);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
}
|
||
|
else
|
||
|
// sinon il s'agit d'une grandeur directement accessible au point d'intégration
|
||
|
// pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers
|
||
|
{
|
||
|
// deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu
|
||
|
if (ponder.Type_grandeur()(i).Nom_vide())
|
||
|
{switch (ponder.Type_grandeur()(i).Enum())
|
||
|
{ case PROP_CRISTA:
|
||
|
{ const double* taux_crita = dTP.TauxCrista();
|
||
|
if (taux_crita != NULL)
|
||
|
{ double fonc = ponder.C_proport()(i)->Valeur(*taux_crita);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration "
|
||
|
<< " il n'est pas possible de calculer le niveau_declenchement_critere "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur, le type " << ponder.Type_grandeur()(i) << " n'est pas disponible "
|
||
|
<< " pour l'instant au point d'integration ! "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{// cas d'un vrai ddl étendue
|
||
|
switch (ponder.Type_grandeur()(i).Position()-NbEnum_ddl())
|
||
|
{case 87: // cas de "def_equivalente"
|
||
|
{const double def_equivalente = ptintmeca.Deformation_equi_const()(1); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_equivalente);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 88: // cas de "def_duale_mises_maxi"
|
||
|
{const double def_duale_mises_maxi = ptintmeca.Deformation_equi_const()(3); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises_maxi);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 89: // cas de "vitesse_def_equivalente"
|
||
|
{const double delta_def_equivalente = ptintmeca.Deformation_equi_const()(4); // recup du delta def equi
|
||
|
// recup de l'incrément de temps
|
||
|
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
|
||
|
double unSurDeltat=0;
|
||
|
if (Abs(deltat) >= ConstMath::trespetit)
|
||
|
{unSurDeltat = 1./deltat;}
|
||
|
else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
|
||
|
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
|
||
|
if (unSurDeltat < 0)
|
||
|
{ cout << "\n le pas de temps est négatif !! "; };
|
||
|
unSurDeltat = ConstMath::tresgrand;
|
||
|
};
|
||
|
double vitesse_def_equi = delta_def_equivalente * unSurDeltat;
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(vitesse_def_equi);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 77: // cas de "def_duale_mises"
|
||
|
{const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 78: // cas de "Spherique_eps"
|
||
|
{const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants
|
||
|
double spherique_eps = epsInvar(1);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(spherique_eps);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
case 81: // cas de "Spherique_sig"
|
||
|
{const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants
|
||
|
double spherique_sig = sigInvar(1);
|
||
|
double fonc = ponder.C_proport()(i)->Valeur(spherique_sig);
|
||
|
fonc_finale *= fonc; // on accumule multiplicativement
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n erreur, le type " << ponder.Type_grandeur()(i)
|
||
|
<< " n'est pas disponible "
|
||
|
<< " pour l'instant au point d'integration ! "
|
||
|
<< "\n LoiCritere::CalculGrandeurTravail(.... ";
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// on met à jour le niveau
|
||
|
save_resul.niveau_declenchement_critere *= fonc_finale;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// répercution sur les classes dérivées si besoin est
|
||
|
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
|
||
|
list <Loi_comp_abstraite *>::const_iterator ili,ilifin=lois_internes.end();
|
||
|
for (ili=lois_internes.begin();ili!=ilifin;ili++,isave++)
|
||
|
{// passage des informations spécifique à la loi liste_des_SaveResul
|
||
|
(*ili)->IndiqueSaveResult(*isave);
|
||
|
(*ili)->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
|
||
|
(*ili)->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
|
||
|
(*ili)->CalculGrandeurTravail(ptintmeca,def,temps,dTP
|
||
|
,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// fonction critère de plissement de biel
|
||
|
// en entrée:
|
||
|
// implicit : si oui on est en implicite, sinon en explicite
|
||
|
// retour:
|
||
|
// 0 : il y a eu un pb que l'on n'a pas peu résoudre, rien n'a été modifié
|
||
|
// 1 : le critère n'a rien modifié
|
||
|
// 2 : l'application du critère conduit à une contrainte et un opérateur tangent nul
|
||
|
int LoiCritere::Critere_plis_biel(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_inter
|
||
|
,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite
|
||
|
,double& module_cisaillement
|
||
|
,bool implicit,const Met_abstraite::Umat_cont& ex)
|
||
|
{// dim et vérification
|
||
|
int dim_tens = abs(sigHH.Dimension());
|
||
|
// normalement le critère ne s'applique que pour des tenseurs 1D
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (dim_tens != 1)
|
||
|
{ cout << "\n erreur le critere de plissement de biel ne peut s'appliquer que pour des lois 1D"
|
||
|
<< " \n LoiCritere::Critere_plis_biel(..";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
|
||
|
// on va utiliser la valeur de la contrainte, par contre on la ramène dans un repère normé
|
||
|
// pour son intensité ce qui revient à calculer la trace du tenseur
|
||
|
double sig_I = sigHH && (* ex.gijBB_tdt);
|
||
|
int retour = 0; // init par défaut
|
||
|
if (sig_I >= niveau_declenchement_critere) // pas de plis
|
||
|
{ // on se trouve dans le cas où rien n'est en compression, donc cas normal sans plissement
|
||
|
retour = 1; //on signale
|
||
|
save_resul.eps_pli.Zero(); // pas de pli répertorié
|
||
|
}
|
||
|
else
|
||
|
{ // on se trouve dans le cas où on a des plis
|
||
|
|
||
|
// l'idée est de ce positionner au niveau du seuil de déclenchement, pour cela on va utiliser
|
||
|
// un facteur multiplicatif de manière à pouvoir conserver un opérateur tangent cohérent avec le seuil
|
||
|
// (si on impose dans une boucle de Newton, la contrainte on va récupérer une def méca et un opérateur
|
||
|
// tangent par rapport à cette def méca. Du coup on ne pourra pas en déduire un opérateur tangent par
|
||
|
// rapport à la def cinématique ...)
|
||
|
// double rapport = niveau_declenchement_critere / (Dabs(sig_I)+ConstMath::pasmalpetit);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// on annule la contrainte et sa contribution éventuelle à la raideur
|
||
|
sigHH.Inita(0.);
|
||
|
d_sigma_deps_inter.Inita(0.); // dans le cas explicite, ne sert à rien mais c'est rapide
|
||
|
// comme marqueur de l'intensité des plis on utilise la def de compression
|
||
|
save_resul.eps_pli(1) = epsBB_tdt && (* ex.gijHH_tdt);
|
||
|
// d'autre part on définit le vecteur propre normé qui n'est autre que gi_1 normé
|
||
|
int dim = ParaGlob::Dimension();
|
||
|
if (save_resul.V_P_sig == NULL)
|
||
|
save_resul.V_P_sig = new Tableau <Coordonnee>;
|
||
|
Coordonnee zero(dim); // un vecteur nul
|
||
|
save_resul.V_P_sig->Change_taille(2); // on n'a besoin que d'un vecteur
|
||
|
// **** mais pour l'instant j'en mets 2 de manière à être cohérent avec les membranes
|
||
|
// sinon pb en sortie des grandeurs
|
||
|
Coordonnee inter = ex.giB_tdt->Coordo(1);
|
||
|
(*save_resul.V_P_sig)(1)= inter.Normer();
|
||
|
retour = 2;
|
||
|
};
|
||
|
|
||
|
return retour;
|
||
|
};
|
||
|
|
||
|
|
||
|
// récupération de la variation relative d'épaisseur calculée: h/h0
|
||
|
// cette variation n'est utile que pour des lois en contraintes planes
|
||
|
// - pour les lois 3D : retour d'un nombre très grand, indiquant que cette fonction est invalide
|
||
|
// - pour les lois 2D def planes: retour de 0
|
||
|
// les infos nécessaires à la récupération , sont stockées dans saveResul
|
||
|
// qui est le conteneur spécifique au point où a été calculé la loi
|
||
|
double LoiCritere::HsurH0(SaveResul * saveResul) const
|
||
|
{ SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
switch (type_critere)
|
||
|
{ case PLISSEMENT_MEMBRANE:
|
||
|
{ // traitement des épaisseurs
|
||
|
LoiContraintesPlanes::SaveResul_LoiContraintesPlanes * save_result_plan_inter // pour simplifier
|
||
|
= (LoiContraintesPlanes::SaveResul_LoiContraintesPlanes *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
return save_result_plan_inter->hsurh0;
|
||
|
break;
|
||
|
}
|
||
|
case PLISSEMENT_BIEL:
|
||
|
{ LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
return save_result_1DCP2_inter->hsurh0;
|
||
|
break;
|
||
|
}
|
||
|
default :
|
||
|
cout << "\nErreur : LoiCritere::HsurH0(.. non implante pour le critere " << Nom_Critere_Loi(type_critere)
|
||
|
<< " !\n";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
// premier type de calcul dans le cas d'un pli dans une seule direction
|
||
|
void LoiCritere::Premie_type_calcul_en_un_pli(const TenseurBB & epsBB_tdt,const TenseurBB & delta_epsBB
|
||
|
,const TenseurHH & sigHH_t
|
||
|
,const double& jacobien_0,const double& jacobien
|
||
|
,EnergieMeca & energ,const EnergieMeca & energ_t
|
||
|
,const TenseurBB& DepsBB
|
||
|
,double& module_compressibilite,double& module_cisaillement
|
||
|
,const Tableau <Coordonnee2H>& V_Pr_H
|
||
|
,TenseurHH& sigHH,TenseurHHHH& d_sigma_deps_inter
|
||
|
,const Coordonnee2& valPropreSig
|
||
|
,const Met_abstraite::Umat_cont& ex)
|
||
|
{
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
// les coordonnées des vecteurs propres sont exprimées dans l'ancienne base
|
||
|
// on a donc
|
||
|
// Vi_B(i) = gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
|
||
|
|
||
|
Mat_pleine beta(2,2);
|
||
|
for (int i=1;i<3;i++) // < 3 donc de 1 à 2
|
||
|
for (int j=1;j<3;j++)
|
||
|
beta(i,j) = V_Pr_H(i)(j);
|
||
|
Mat_pleine gamma(beta.Inverse().Transpose()); // on calcule la matrice inverse
|
||
|
// la matrice gamma correspond à la matrice de changement de base des g^i au gpH
|
||
|
// gamma est l'inverse transposée
|
||
|
// gpH(i) = gamma(i,j) * gH(j), i indice de ligne, j indice de colonne
|
||
|
// c-a-d= gp^i = gamma^i_j * g^j
|
||
|
|
||
|
// on va également définir une matrice de changement pour les tenseurs 3D
|
||
|
Tableau <Coordonnee3H> V_Pr3D_H(3);
|
||
|
// comme V_Pr est de dim 2, il faut transférer les coordonnées
|
||
|
V_Pr3D_H(1)(1) = V_Pr_H(1)(1);V_Pr3D_H(1)(2) = V_Pr_H(1)(2);
|
||
|
V_Pr3D_H(2)(1) = V_Pr_H(2)(1);V_Pr3D_H(2)(2) = V_Pr_H(2)(2);
|
||
|
// le troisième est en local 0,0,1
|
||
|
V_Pr3D_H(3)(3) = 1.;
|
||
|
Mat_pleine beta3D(3,3);// initialisée à 0
|
||
|
// d'abord les 2 vecteurs propres
|
||
|
for (int i=1;i<3;i++)
|
||
|
for (int j=1;j<4;j++)
|
||
|
beta3D(i,j) = V_Pr3D_H(i)(j);
|
||
|
// puis la normale
|
||
|
beta3D(3,3) = 1.;
|
||
|
Mat_pleine gamma3D(beta3D.Inverse().Transpose());
|
||
|
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// pour tester, on passe les contraintes dans le repère principal
|
||
|
if (Permet_affichage() > 5)
|
||
|
{Tenseur2HH sigHH_2_inter(sigHH);
|
||
|
cout << "\n utilisation du repere ortho des vecteurs propres: V_P ";
|
||
|
cout << "\n sigHH= en giB : "; sigHH.Ecriture(cout);
|
||
|
cout << "\n base giB(1) "<< (* ex.giB_tdt)(1)
|
||
|
<< "\n base giB(2) "<< (* ex.giB_tdt)(2);
|
||
|
// en base orthonormee
|
||
|
Tenseur3HH sigHH_3_inter;
|
||
|
sigHH.BaseAbsolue(sigHH_3_inter,(* ex.giB_tdt));
|
||
|
// TenseurHH* ptHH = NevezTenseurHH((*(*isig)));
|
||
|
// (*(*isig)).BaseAbsolue(*ptHH,giB);
|
||
|
cout << "\n sigHH= en absolue 3D : "<<sigHH_3_inter;
|
||
|
cout << "\n chgt de base: Vi_B(i) = gpB(i) = beta(i,j) * gB(j) --> beta= ";beta.Affiche();
|
||
|
cout << "\n sigHH_2_inter avant chgt= "<< sigHH_2_inter;
|
||
|
sigHH_2_inter.ChBase(gamma,false);
|
||
|
cout << "\n sigHH= en V_P : "<< sigHH_2_inter;
|
||
|
// on revient à la base de départ pour vérifier que l'opération inverse ne pose
|
||
|
// pas de pb
|
||
|
sigHH_2_inter.ChBase(beta.Transpose(),false);
|
||
|
cout << "\n verif: sigHH après retour au repère initial giB: ";
|
||
|
sigHH_2_inter.Ecriture(cout);
|
||
|
//cout << "\n gamma * beta = "; (gamma * beta).Affiche();
|
||
|
cout << "\n vecteurs propres en 3D ortho: "; //<< (*save_resul.V_P_sig);
|
||
|
cout << "\n VP1 "<< (*save_resul.V_P_sig)(1);
|
||
|
cout << "\n VP2 "<< (*save_resul.V_P_sig)(2);
|
||
|
cout << "\n VP3 "<< (*save_resul.V_P_sig)(3);
|
||
|
// vérif des vecteurs propres
|
||
|
Coordonnee3B VpB1; VpB1.Change_val((*save_resul.V_P_sig)(1));
|
||
|
Coordonnee3H VpropreH1 = sigHH_3_inter * VpB1;
|
||
|
//cout << "\n sigHH_3_inter * VP1 "<< VpropreH1;
|
||
|
VpropreH1 /= (valPropreSig(1)+ConstMath::petit);
|
||
|
cout << "\n (sigHH_3_ortho * VP1) / (lambda1+epsilon)= "<< VpropreH1;
|
||
|
Coordonnee3B VpB2; VpB2.Change_val((*save_resul.V_P_sig)(2));
|
||
|
Coordonnee3H VpropreH2 = sigHH_3_inter * VpB2;
|
||
|
//cout << "\n sigHH_3_inter * VP2 "<< VpropreH2;
|
||
|
VpropreH2 /= (valPropreSig(2)+ConstMath::petit);
|
||
|
cout << "\n (sigHH_3_ortho * VP2) / (lambda2+epsilon)= "<< VpropreH2;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
{ // --il faut créer un save_result pour l'appel des contraintes doublement planes
|
||
|
// on récupère le conteneur qui bien qu'associé à une loi CP, est également
|
||
|
// en réalité un conteneur CP2 car c'est comme cela qu'il a été créé via
|
||
|
// LoiCritere::LoiCritere::New_et_Initialise()
|
||
|
//*** là il va falloir revoir cette partie, car en fait ce n'est pas sûr qui faut utiliser un conteneur intermédiaire
|
||
|
//*** cela pose pas mal de pb, car il faut de nouveau mettre à jour les infos du conteneur initial, dans le cas des lois
|
||
|
//*** incrémentales, or pour l'instant ce n'est pas fait, ça c'est une erreur
|
||
|
/* *** l'idée initiale était que l'utilisation du 1D était transitoire en particulier d'une itération à l'autre.
|
||
|
donc supposons qu'à une itération on ait un plis dans une direction, on change toutes les grandeurs tensorielles en fonction
|
||
|
de cette direction (par exemple les tenseurs de ref) et donc à l'itération suivante on n'aura plus le même état de démarrage.
|
||
|
Mais ... en fait on remet les choses dans le repère initial à la fin du traitement:
|
||
|
save_resul.save_result_1DCP2->ChBase_des_grandeurs(gamma3D);
|
||
|
donc dans ce cas là, je ne comprends pas pourquoi on utilise pas directement le conteneur initial
|
||
|
Pour l'instant, je laisse en l'état (25 nov 2015) et après la réunion avec le CNES, je vais faire les tests en incrémental et modifier
|
||
|
car c'est possible qu'il y a quelque chose qui m'échappe.
|
||
|
Par contre à minima je remets les def de largeur, dans le conteneur initial
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
// on affecte les grandeurs à un conteneur de travail
|
||
|
if (save_resul.save_result_1DCP2 == NULL)
|
||
|
{ SaveResul * inter = save_result_1DCP2_inter->Nevez_SaveResul();
|
||
|
save_resul.save_result_1DCP2 = ((LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble*) inter);
|
||
|
}
|
||
|
else // sinon on peut affecter directement
|
||
|
*(save_resul.save_result_1DCP2) = *((Loi_comp_abstraite::SaveResul *) save_result_1DCP2_inter);
|
||
|
|
||
|
// . -- changement de repère pour venir dans le nouveau repère ortho
|
||
|
// on change toutes les infos tensorielles contenues pour qu'elles soient exprimées dans le nouveau repère
|
||
|
// ceci ne concerne pas les grandeurs scalaires et les grandeurs exprimées dans le repère global
|
||
|
|
||
|
// là il faut utiliser une matrice 3x3 car on a systématiquement des grandeurs 3D, car la loi interne est 3D
|
||
|
save_resul.save_result_1DCP2->ChBase_des_grandeurs(beta3D,gamma3D);
|
||
|
|
||
|
// il faut initialiser les métriques en 1D à null, pour qu'elles soient recalculer systématiquement car par exemple
|
||
|
// la métrique à 0 change d'une itération à l'autre et d'un incrément à l'autre
|
||
|
{Deformation::Stmet met_ref_00,met_ref_t,met_ref_tdt; // def de métrique vide, qui vont être construite pendant le calcul
|
||
|
save_resul.save_result_1DCP2->Affectation_metriques_locale(met_ref_00,met_ref_t,met_ref_tdt);
|
||
|
};
|
||
|
|
||
|
loi_1DCP2_de_3D->IndiquePtIntegMecaInterne(ptintmeca_en_cours); // on transmet le ptintmeca global
|
||
|
loi_1DCP2_de_3D->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
|
||
|
loi_1DCP2_de_3D->IndiqueSaveResult(save_resul.save_result_1DCP2); // on indique à la loi le conteneur qu'il faut utiliser
|
||
|
////-- debug --
|
||
|
{//#ifdef MISE_AU_POINT
|
||
|
//if ( save_resul.save_result_1DCP2->meti_ref_00.giB_ != NULL)
|
||
|
// cout << "\n debug Critere_plis_membrane ";
|
||
|
//#endif
|
||
|
////-- fin debug --
|
||
|
// -- appel du programme de contraintes doublement planes -> récup des résultats dans le nouveau repère
|
||
|
// 7 nov 2018: ?? normalement on est en base orthonormée ! bool base_orthonormee = false;
|
||
|
}
|
||
|
bool base_orthonormee = true;
|
||
|
// conditionnnement de la nouvelle métrique
|
||
|
Creation_metrique_a_partir_vecteurs_propres_pour_Umat1D(ex,beta);
|
||
|
// chgt de variable pour les autres variables de passage: contrainte, def, D, delta eps ...
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{
|
||
|
//cout << "\n debug LoiCritere::Critere_plis_membrane(";
|
||
|
// for (int a=1; a<4;a++)
|
||
|
// {cout << "\n giH_0("<<a<<"): "; (*(umat_cont_1D->giB_0))(a).Affiche();
|
||
|
// cout << "\n giH_0("<<a<<"): "; (*(umat_cont_1D->giB_0))(a).Affiche();
|
||
|
// };
|
||
|
cout << "\n epsBB initial en local 2D "; epsBB_tdt.Ecriture(cout);
|
||
|
// en orthonormee
|
||
|
Tenseur3BB epsBB_3_inter;
|
||
|
epsBB_tdt.BaseAbsolue(epsBB_3_inter,*(ex.giH_tdt));
|
||
|
cout << "\n epsBB d'entrée =en orthonormee "<<epsBB_3_inter;
|
||
|
cout << endl;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bool deux_plis = false;
|
||
|
Passage_3ou2_vers_1(gamma,sigHH_t,beta,DepsBB,epsBB_tdt
|
||
|
,delta_epsBB,deux_plis,save_resul.eps_pli);
|
||
|
|
||
|
// avant le calcul on initialise l'énergie
|
||
|
energ.Inita(0.); // car sinon on cumule l'énergie sans plis et avec plis !!
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
cout << "\n LoiCritere::Critere_plis_membrane ==> calcul en 1D CP2";
|
||
|
#endif
|
||
|
loi_1DCP2_de_3D->Calcul_dsigma_deps(base_orthonormee,sig_HH_t_1D,Deps_BB_1D
|
||
|
,eps_BB_1D,delta_eps_BB_1D,jacobien_0_1D,jacobien_tdt_1D
|
||
|
,sig_HH_1D,d_sigma_deps_1D,energ,energ_t,module_compressibilite, module_cisaillement
|
||
|
,*umat_cont_1D);
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 4)
|
||
|
{ if (Permet_affichage() > 5)
|
||
|
{cout << "\n\n ... LoiCritere::Critere_plis_membrane apres CP2: ";
|
||
|
cout << "\n sig_HH_1D "<< sig_HH_1D;
|
||
|
cout << "\n d_sigma_deps_1D "<< d_sigma_deps_1D;
|
||
|
};
|
||
|
if ((!isfinite(d_sigma_deps_1D(1,1,1,1))) || (isnan(d_sigma_deps_1D(1,1,1,1))) )
|
||
|
{cout << "\n *** attention d_sigma_deps_3D(1,1,1,1)= "<< d_sigma_deps_1D(1,1,1,1);
|
||
|
if (Ptintmeca_en_cours() != NULL) Ptintmeca_en_cours()->Signature();
|
||
|
cout << "\n LoiCritere::Critere_plis_membrane ==> calcul en 1D CP2";
|
||
|
cout << flush;
|
||
|
//// --- pour le débug
|
||
|
// loi_1DCP2_de_3D->Calcul_dsigma_deps(base_orthonormee,sig_HH_t_1D,Deps_BB_1D
|
||
|
// ,eps_BB_1D,delta_eps_BB_1D,jacobien_0_1D,jacobien_tdt_1D
|
||
|
// ,sig_HH_1D,d_sigma_deps_1D,energ,energ_t,module_compressibilite, module_cisaillement
|
||
|
// ,*umat_cont_1D);
|
||
|
//// ---fin debug
|
||
|
};
|
||
|
Tenseur1HH deltasigHH = (d_sigma_deps_1D && delta_eps_BB_1D);
|
||
|
cout << "\n deltasigHH "<< deltasigHH;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
if (Permet_affichage() > 4)
|
||
|
if (//(sig_HH_1D(1,1) <= -1.)||
|
||
|
(std::isinf(sig_HH_1D(1,1)))||( std::isnan(sig_HH_1D(1,1))))
|
||
|
{cout << "\n *** attention sig_HH_1D(1,1) negatif ou infinie (debug LoiCritere::Critere_plis_membrane(.. \n";
|
||
|
cout << sig_HH_1D(1,1)
|
||
|
<< endl;
|
||
|
cout << "\n ***** erreur detectee : on continue quand meme ... ";
|
||
|
// Sortie(2);
|
||
|
};
|
||
|
|
||
|
// -- passage des résultats: sig, dsig, module, énergies dans l'ancien repère
|
||
|
// passage inverse: chgt de repère et de dimension pour les variables de passage
|
||
|
// et stockage des infos de doublement plane pour le post-traitement pour le prochain appel
|
||
|
Passage_1_vers_3ou2(gamma,sigHH,d_sigma_deps_1D
|
||
|
,beta,d_sigma_deps_inter,ex,V_Pr_H
|
||
|
,*(save_resul.V_P_sig));
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{ cout << "\n apres Passage_1_vers_3ou2, suite LoiCritere::Critere_plis_membrane";
|
||
|
cout << "\n sigHH en giB: "; sigHH.Ecriture(cout);
|
||
|
cout << "\n d_sigma_deps_inter en giB: ";d_sigma_deps_inter.Ecriture(cout);
|
||
|
Tenseur2HH deltasigHH = (d_sigma_deps_inter && delta_epsBB);
|
||
|
cout << "\n deltasig2HH en giB: "<< deltasigHH;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
if (Permet_affichage() > 4)
|
||
|
for (int al = 1; al<3;al++)
|
||
|
for (int be=1;be<3;be++)
|
||
|
if (//(sigHH(al,be) < 0.)||
|
||
|
(std::isinf(sigHH(al,be))||( std::isnan(sigHH(al,be)))))
|
||
|
{cout << "\n *** attention (sigHH("<<al<<","<<be
|
||
|
<< ")="<< sigHH(al,be) << " nan debug LoiCritere::Critere_plis_membrane( \n";
|
||
|
cout << "\n ***** erreur detectee : on continue quand meme ... ";
|
||
|
};
|
||
|
// -- mise à jour du save_result de contraintes planes avec celui des doublements planes en tenant
|
||
|
// compte du chgt de repère
|
||
|
//*** ça ce sera à revoir: cf. la remarque plus haut ***
|
||
|
save_resul.save_result_1DCP2->ChBase_des_grandeurs(beta3D,gamma3D);
|
||
|
// on met à jour les def de largeur et d'épaisseur sur le conteneur initial
|
||
|
save_result_1DCP2_inter->Transfert_var_hetb(*save_resul.save_result_1DCP2);
|
||
|
|
||
|
};
|
||
|
|
||
|
// deuxième type de calcul dans le cas d'un pli dans une seule direction
|
||
|
void LoiCritere::Deuxieme_type_calcul_en_un_pli
|
||
|
(const TenseurBB & epsBB_tdt,const TenseurBB & delta_epsBB
|
||
|
,const TenseurHH & sigHH_t
|
||
|
,double& jacobien_0,double& jacobien
|
||
|
,EnergieMeca & energ,const EnergieMeca & energ_t
|
||
|
,const TenseurBB& DepsBB
|
||
|
,double& module_compressibilite,double& module_cisaillement
|
||
|
,const Tableau <Coordonnee2H>& V_Pr_H
|
||
|
,TenseurHH& sigHH,TenseurHHHH& d_sigma_deps_inter
|
||
|
,const Coordonnee2& valPropreSig
|
||
|
,const Met_abstraite::Umat_cont& ex
|
||
|
)
|
||
|
{
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
// le conteneur Met_abstraite::Umat_cont& ex correspond à une métrique 2D
|
||
|
// il nous faut l'équivalent en 3D, on se sert de la loi cp et de la méthode ad hoc
|
||
|
const Met_abstraite::Umat_cont* ex3D = loi_2DCP_de_3D->Passage_metrique_ordre2_vers_3(ex);
|
||
|
// en fait le repère 2D a été complété par la normale aux 2 premiers vecteurs
|
||
|
|
||
|
// -- en entrée on connait la direction des vecteurs propres de contrainte
|
||
|
// correspondant au calcul sans prise en compte de pli
|
||
|
// on va calculer les bases associées: ViB et ViH: ici 3 vecteurs en 3D
|
||
|
// a) ViH = les vecteurs en contravariant: c'est en fait = V_Pr_H pour
|
||
|
// les 2 premiers vecteurs
|
||
|
// mais on doit passer de 2D en 3D, manuellement
|
||
|
ViH.CoordoH(1)(1) = V_Pr_H(1)(1);ViH.CoordoH(1)(2) = V_Pr_H(1)(2);
|
||
|
ViH.CoordoH(1)(3) = 0.; // normalement pas de composante suivant la normale
|
||
|
ViH.CoordoH(2)(1) = V_Pr_H(2)(1);ViH.CoordoH(2)(2) = V_Pr_H(2)(2);
|
||
|
ViH.CoordoH(2)(3) = 0.; // normalement pas de composante suivant la normale
|
||
|
// pour le 3 ième vecteur on se sert des grandeurs sauvegardées
|
||
|
for (int i=1;i<4;i++) // < 4 donc de 1 à 3
|
||
|
ViH.CoordoH(3)(i) = (*save_resul.V_P_sig)(3) * ex3D->giH_tdt->Coordo(i);
|
||
|
// b) ViB -> là il faut les calculer
|
||
|
// on choisit d'utiliser les grandeurs stockées qui représentent les
|
||
|
// les vecteurs orthonormées
|
||
|
for (int j=1;j<4;j++)
|
||
|
for (int i=1;i<4;i++) // < 4 donc de 1 à 3
|
||
|
ViB.CoordoB(j)(i) = (*save_resul.V_P_sig)(j) * ex3D->giB_tdt->Coordo(i);
|
||
|
|
||
|
// on calcul les def de plis : save_resul.eps_pli
|
||
|
Mat_pleine beta(2,2);
|
||
|
for (int i=1;i<3;i++) // < 3 donc de 1 à 2
|
||
|
for (int j=1;j<3;j++)
|
||
|
beta(i,j) = V_Pr_H(i)(j);
|
||
|
Mat_pleine gamma(beta.Inverse().Transpose()); // on calcule la matrice inverse
|
||
|
Tenseur2BB epsBB_tdt_2_inter(epsBB_tdt);epsBB_tdt_2_inter.ChBase(beta);
|
||
|
save_resul.eps_pli(1) = epsBB_tdt_2_inter(2,2); // on sauvegarde les def de plis
|
||
|
save_resul.eps_pli(2) = 0.; // cas d'un seul plis
|
||
|
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
// pour tester et afficher: calcul des matrices de changement de base
|
||
|
if (Permet_affichage() > 5)
|
||
|
{// les coordonnées des vecteurs propres sont exprimées dans l'ancienne base
|
||
|
// on a donc
|
||
|
// Vi_B(i) = gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
|
||
|
|
||
|
// Mat_pleine beta(2,2);
|
||
|
// for (int i=1;i<3;i++) // < 3 donc de 1 à 2
|
||
|
// for (int j=1;j<3;j++)
|
||
|
// beta(i,j) = V_Pr_H(i)(j);
|
||
|
Mat_pleine gamma(beta.Inverse().Transpose()); // on calcule la matrice inverse
|
||
|
// la matrice gamma correspond à la matrice de changement de base des g^i au gpH
|
||
|
// gamma est l'inverse transposée
|
||
|
// gpH(i) = gamma(i,j) * gH(j), i indice de ligne, j indice de colonne
|
||
|
// c-a-d= gp^i = gamma^i_j * g^j
|
||
|
|
||
|
// on va également définir une matrice de changement pour les tenseurs 3D
|
||
|
Tableau <Coordonnee3H> V_Pr3D_H(3);
|
||
|
// comme V_Pr est de dim 2, il faut transférer les coordonnées
|
||
|
V_Pr3D_H(1)(1) = V_Pr_H(1)(1);V_Pr3D_H(1)(2) = V_Pr_H(1)(2);
|
||
|
V_Pr3D_H(2)(1) = V_Pr_H(2)(1);V_Pr3D_H(2)(2) = V_Pr_H(2)(2);
|
||
|
// le troisième est en local 0,0,1
|
||
|
V_Pr3D_H(3)(3) = 1.;
|
||
|
Mat_pleine beta3D(3,3);// initialisée à 0
|
||
|
// d'abord les 2 vecteurs propres
|
||
|
for (int i=1;i<3;i++)
|
||
|
for (int j=1;j<4;j++)
|
||
|
beta3D(i,j) = V_Pr3D_H(i)(j);
|
||
|
// puis la normale
|
||
|
beta3D(3,3) = 1.;
|
||
|
Mat_pleine gamma3D(beta3D.Inverse().Transpose());
|
||
|
Tenseur2HH sigHH_2_inter(sigHH);
|
||
|
cout << "\n utilisation du repere ortho des vecteurs propres: V_P ";
|
||
|
cout << "\n sigHH= en giB : "; sigHH.Ecriture(cout);
|
||
|
cout << "\n base giB(1) "<< (* ex3D->giB_tdt)(1)
|
||
|
<< "\n base giB(2) "<< (* ex3D->giB_tdt)(2);
|
||
|
// en base orthonormee
|
||
|
Tenseur3HH sigHH_3_inter;
|
||
|
sigHH.BaseAbsolue(sigHH_3_inter,(* ex3D->giB_tdt));
|
||
|
cout << "\n sigHH= en absolue 3D : "<<sigHH_3_inter;
|
||
|
cout << "\n chgt de base: Vi_B(i) = gpB(i) = beta(i,j) * gB(j) --> beta= ";beta.Affiche();
|
||
|
cout << "\n sigHH_2_inter avant chgt= "<< sigHH_2_inter;
|
||
|
sigHH_2_inter.ChBase(gamma,false);
|
||
|
cout << "\n sigHH= en V_P : "<< sigHH_2_inter;
|
||
|
// on revient à la base de départ pour vérifier que l'opération inverse ne pose
|
||
|
// pas de pb
|
||
|
sigHH_2_inter.ChBase(beta.Transpose(),false);
|
||
|
cout << "\n verif: sigHH après retour au repère initial giB: ";
|
||
|
sigHH_2_inter.Ecriture(cout);
|
||
|
//cout << "\n gamma * beta = "; (gamma * beta).Affiche();
|
||
|
cout << "\n vecteurs propres en 3D ortho: "; //<< (*save_resul.V_P_sig);
|
||
|
cout << "\n VP1 "<< (*save_resul.V_P_sig)(1);
|
||
|
cout << "\n VP2 "<< (*save_resul.V_P_sig)(2);
|
||
|
cout << "\n VP3 "<< (*save_resul.V_P_sig)(3);
|
||
|
// vérif des vecteurs propres
|
||
|
Coordonnee3B VpB1; VpB1.Change_val((*save_resul.V_P_sig)(1));
|
||
|
Coordonnee3H VpropreH1 = sigHH_3_inter * VpB1;
|
||
|
//cout << "\n sigHH_3_inter * VP1 "<< VpropreH1;
|
||
|
VpropreH1 /= (valPropreSig(1)+ConstMath::petit);
|
||
|
cout << "\n (sigHH_3_ortho * VP1) / (lambda1+epsilon)= "<< VpropreH1;
|
||
|
Coordonnee3B VpB2; VpB2.Change_val((*save_resul.V_P_sig)(2));
|
||
|
Coordonnee3H VpropreH2 = sigHH_3_inter * VpB2;
|
||
|
//cout << "\n sigHH_3_inter * VP2 "<< VpropreH2;
|
||
|
VpropreH2 /= (valPropreSig(2)+ConstMath::petit);
|
||
|
cout << "\n (sigHH_3_ortho * VP2) / (lambda2+epsilon)= "<< VpropreH2;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
|
||
|
loi_1DCP2_de_3D->IndiqueSaveResult(save_result_1DCP2_inter); // on indique à la loi le conteneur qu'il faut utiliser
|
||
|
loi_1DCP2_de_3D->IndiquePtIntegMecaInterne(ptintmeca_en_cours); // on transmet le ptintmeca global
|
||
|
loi_1DCP2_de_3D->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
|
||
|
bool base_orthonormee = false; // ici on va travailler avec les gi
|
||
|
// on utilise donc la métrique passée en paramètre
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{
|
||
|
//cout << "\n debug LoiCritere::Critere_plis_membrane(";
|
||
|
// for (int a=1; a<4;a++)
|
||
|
// {cout << "\n giH_0("<<a<<"): "; (*(umat_cont_1D->giB_0))(a).Affiche();
|
||
|
// cout << "\n giH_0("<<a<<"): "; (*(umat_cont_1D->giB_0))(a).Affiche();
|
||
|
// };
|
||
|
cout << "\n epsBB initial en local 2D "; epsBB_tdt.Ecriture(cout);
|
||
|
// en orthonormee
|
||
|
Tenseur3BB epsBB_3_inter;
|
||
|
epsBB_tdt.BaseAbsolue(epsBB_3_inter,*(ex.giH_tdt));
|
||
|
cout << "\n epsBB d'entrée =en orthonormee "<<epsBB_3_inter;
|
||
|
cout << endl;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// passage des informations liées à la déformation de 2 vers 3
|
||
|
Passage_deformation_contrainte_ordre2_vers_3(DepsBB,epsBB_tdt,delta_epsBB,sigHH_t);
|
||
|
// avant le calcul on initialise l'énergie
|
||
|
energ.Inita(0.); // car sinon on cumule l'énergie sans plis et avec plis !!
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{
|
||
|
cout << "\n LoiCritere::Critere_plis_membrane ==> calcul en 3D CP2";
|
||
|
}
|
||
|
#endif
|
||
|
loi_1DCP2_de_3D->Calcul_dsigma_deps
|
||
|
(base_orthonormee,&ViB,&ViH,sig_HH_t_3D,Deps_BB_3D
|
||
|
,eps_BB_3D,delta_eps_BB_3D,jacobien_0,jacobien
|
||
|
,sig_HH_3D,d_sig_deps_3D_HHHH
|
||
|
,energ,energ_t
|
||
|
,module_compressibilite,module_cisaillement
|
||
|
,*ex3D);
|
||
|
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{ cout << "\n\n ... LoiCritere::Deuxieme_type_calcul_en_un_pli apres CP2: ";
|
||
|
cout << "\n sigHH_3D en giB: "; sig_HH_3D.Ecriture(cout);
|
||
|
if (Permet_affichage() > 6)
|
||
|
{cout << "\n d_sig_deps_3D_HHHH en giB: ";d_sig_deps_3D_HHHH.Ecriture(cout);};
|
||
|
Tenseur3HH deltasigHH = (d_sig_deps_3D_HHHH && delta_eps_BB_3D);
|
||
|
cout << "\n deltasig3HH en giB: "<< deltasigHH;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
if (Permet_affichage() > 4)
|
||
|
{bool erreur = false;
|
||
|
for (int al = 1; al<4;al++)
|
||
|
for (int be=1;be<4;be++)
|
||
|
if (//(sigHH(al,be) < 0.)||
|
||
|
(std::isinf(sig_HH_3D(al,be))||( std::isnan(sig_HH_3D(al,be)))))
|
||
|
{cout << "\n *** attention (sigHH_3D("<<al<<","<<be
|
||
|
<< ")="<< sig_HH_3D(al,be) << " valeur nan LoiCritere::Critere_plis_membrane( \n"
|
||
|
<< "\n LoiCritere::Deuxieme_type_calcul_en_un_pli apres CP2:.. \n";
|
||
|
erreur = true;
|
||
|
};
|
||
|
if (erreur)
|
||
|
{cout << "\n sigHH= ";sig_HH_3D.Ecriture(cout);
|
||
|
cout << "\n **** erreur nan sur loi critere !! **** on continue quand meme ... ";
|
||
|
// Sortie(2);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// passage des informations liées à la nouvelle contrainte de 2 vers 3
|
||
|
// et à l'opérateur tangent : méthode 2
|
||
|
// non !! pas de mise à jour --> // mise à jour de save_resul.eps_pli
|
||
|
// *** a supprimer le passage de save_resul.eps_pli
|
||
|
// car c'est une erreur
|
||
|
|
||
|
|
||
|
bool deux_plis = false;
|
||
|
Passage_contrainte_et_operateur_tangent_ordre2_vers_3
|
||
|
(sigHH,d_sigma_deps_inter,deux_plis,save_resul.eps_pli);
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (Permet_affichage() > 5)
|
||
|
{ cout << "\n retour en dim 2 : ";
|
||
|
cout << "\n sigHH en giB: "; sigHH.Ecriture(cout);
|
||
|
cout << "\n d_sig_deps_HHHH en giB: ";d_sigma_deps_inter.Ecriture(cout);
|
||
|
Tenseur2HH deltasigHH = (d_sigma_deps_inter && delta_epsBB);
|
||
|
cout << "\n deltasig2HH en giB: "<< deltasigHH;
|
||
|
cout << endl;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
// fonction pre_critère de plissement de membrane
|
||
|
// dans le cas d'un critère pli (plutôt seconde méthode), l'incrément de déformation
|
||
|
// dépend de la situation précédente: avec pli ou pas
|
||
|
// du coup on utilise un delta_eps intermédiaire au lieu du delta cinématique
|
||
|
// ce deltat_eps doit être précalculé
|
||
|
// en entrée:
|
||
|
// implicit : si oui on est en implicite, sinon en explicite
|
||
|
// retour:
|
||
|
void LoiCritere::Pre_Critere_plis_membrane
|
||
|
(TenseurBB & epsBB_tdt_,TenseurBB & delta_epsBB
|
||
|
,const Met_abstraite::Expli_t_tdt* ex_expli
|
||
|
,const Met_abstraite::Impli* ex_impli
|
||
|
,const Met_abstraite::Umat_cont* ex_umat
|
||
|
)
|
||
|
{ // on commence par récupérer les métriques en fonctions du conteneur ex valide
|
||
|
const Tenseur2HH * gijHH_; // pour simplifier
|
||
|
const Tenseur2BB * gijBB_; // " " " "
|
||
|
const Tenseur2HH * gijHH_t_; // " " " "
|
||
|
const Tenseur2BB * gijBB_t_; // " " " "
|
||
|
if (ex_expli != NULL)
|
||
|
{ gijHH_ = ((Tenseur2HH*) ex_expli->gijHH_tdt); // pour simplifier
|
||
|
gijBB_ = ((Tenseur2BB*) ex_expli->gijBB_tdt); // " " " "
|
||
|
gijHH_t_ = ((Tenseur2HH*) ex_expli->gijHH_t); // " " " "
|
||
|
gijBB_t_ = ((Tenseur2BB*) ex_expli->gijBB_t); // " " " "
|
||
|
}
|
||
|
else if (ex_impli != NULL)
|
||
|
{ gijHH_ = ((Tenseur2HH*) ex_impli->gijHH_tdt); // pour simplifier
|
||
|
gijBB_ = ((Tenseur2BB*) ex_impli->gijBB_tdt); // " " " "
|
||
|
gijHH_t_ = ((Tenseur2HH*) ex_impli->gijHH_t); // " " " "
|
||
|
gijBB_t_ = ((Tenseur2BB*) ex_impli->gijBB_t); // " " " "
|
||
|
}
|
||
|
else if (ex_umat != NULL)
|
||
|
{ gijHH_ = ((Tenseur2HH*) ex_umat->gijHH_tdt); // pour simplifier
|
||
|
gijBB_ = ((Tenseur2BB*) ex_umat->gijBB_tdt); // " " " "
|
||
|
gijHH_t_ = ((Tenseur2HH*) ex_umat->gijHH_t); // " " " "
|
||
|
gijBB_t_ = ((Tenseur2BB*) ex_umat->gijBB_t); // " " " "
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n **** erreur: pas de conteneur de metrique disponible ..."
|
||
|
<< "\n LoiCritere::Pre_Critere_plis_membrane(...";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
const Tenseur2HH & gijHH = *gijHH_; // pour simplifier
|
||
|
const Tenseur2BB & gijBB = *gijBB_; // " " " "
|
||
|
const Tenseur2HH & gijHH_t = *gijHH_t_; // " " " "
|
||
|
const Tenseur2BB & gijBB_t = *gijBB_t_; // " " " "
|
||
|
|
||
|
// et la déformation
|
||
|
const Tenseur2BB & epsBB_tdt = *((Tenseur2BB*) &epsBB_tdt_); // " " " "
|
||
|
|
||
|
SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
int retour = 0; // init par défaut
|
||
|
LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
= (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
(*(save_resul.liste_des_SaveResul.begin()));
|
||
|
|
||
|
// l'objectif est de mettre à jour : delta_eps_BB_2D
|
||
|
delta_eps_BB_2D = delta_epsBB; // initialisation par défaut
|
||
|
|
||
|
// on regarde l'état précédent: sans plis, avec un pli, avec 2 plis ?
|
||
|
int cas_cal_plis_t = save_resul.cas_cal_plis_t;
|
||
|
// en fait seule les cas avec un deux plis, sans erreur, sont exploitables
|
||
|
// ou le cas sans pli, pour tous les autres cas, on considèrera qu'il n'y avait pas de plis
|
||
|
// car les infos sauvegardées (def méca) ne sont pas correctes
|
||
|
switch (save_resul.cas_cal_plis_t)
|
||
|
{ case -1: case 1: case -2: case -3: case -4:// pas de plis
|
||
|
{// a priori rien à faire, delta_eps_BB_2D a déjà été initialisée
|
||
|
break;
|
||
|
}
|
||
|
case 2: case 3: // plis dans une seule directions ou dans deux directions
|
||
|
{ // L'incrément de déformation, entre t et t+dt est obtenu par la différence entre les
|
||
|
// déformations t+dt et les déformations mécaniques à t, transportée de manière cohérente
|
||
|
// avec la dérivée de Jauman à t+dt: 1/2 deux fois covariant + deux fois contra
|
||
|
// a) on commence par récupérer les def méca à l'instant t
|
||
|
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_result_1DCP2_inter->eps_mecaBB_t));
|
||
|
// la déformation 33 est directement gérée par la loi 2D CP via les variations d'épaisseurs
|
||
|
// sachant que l'axe 3 est indépendant des deux autres axes donc on ne s'en occupe pas
|
||
|
eps_BB_2D_t.Affectation_3D_a_2D(eps_mecaBB_t);
|
||
|
// b) on fait le transport cohérent avec Jauman
|
||
|
eps_HH_2D_t = gijHH_t * eps_BB_2D_t * gijHH_t;
|
||
|
delta_epsBB = epsBB_tdt - 0.5 * (gijBB * eps_HH_2D_t * gijBB + eps_BB_2D_t);
|
||
|
break;
|
||
|
}
|
||
|
case 0:
|
||
|
// cas où aucun calcul n'a encore été effectué on n'a rien n'a faire
|
||
|
break;
|
||
|
default: // normalement n'arrive jamais car Calcul_directions_plis a toujours une solution diff de 0
|
||
|
{ cout << "\n *** cas d'erreur inconnue dans le calcul de la direction des plis "
|
||
|
<< " save_resul.cas_cal_plis= "<< save_resul.cas_cal_plis
|
||
|
<< "\n LoiCritere::Pre_Critere_plis_membrane(... ";
|
||
|
Sortie(1);
|
||
|
break;
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// passage des informations liées à la déformation de 2 vers 3
|
||
|
void LoiCritere::Passage_deformation_contrainte_ordre2_vers_3
|
||
|
(const TenseurBB& DepsBB,const TenseurBB & epsBB_tdt
|
||
|
,const TenseurBB & delta_epsBB,const TenseurHH& sig_HH_t)
|
||
|
|
||
|
{ // on complète avec des 0
|
||
|
bool plusZero = true;
|
||
|
Deps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &DepsBB),plusZero);
|
||
|
eps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &epsBB_tdt),plusZero);
|
||
|
delta_eps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &delta_epsBB),plusZero);
|
||
|
sig_HH_t_3D.Affectation_2D_a_3D(*((Tenseur2HH*) &sig_HH_t),plusZero);
|
||
|
};
|
||
|
|
||
|
// passage des informations liées à la nouvelle contrainte de 2 vers 3
|
||
|
// et à l'opérateur tangent : méthode 2
|
||
|
void LoiCritere::Passage_contrainte_et_operateur_tangent_ordre2_vers_3
|
||
|
(TenseurHH& sig_HH_tdt_,TenseurHHHH& d_sig_deps_HHHH_
|
||
|
,const bool& deux_plis,Coordonnee2& eps_pli)
|
||
|
{ // normalement les directions 1 et 2 sont identiques en 2D et 3D
|
||
|
// on recopie donc simplement les grandeurs
|
||
|
Tenseur2HH & sigHH = *((Tenseur2HH*) &sig_HH_tdt_); // " " " "
|
||
|
sigHH.Affectation_3D_a_2D(sig_HH_3D);
|
||
|
// idem pour l'opérateur tangent
|
||
|
Tenseur2HHHH & d_sig_deps_HHHH = *((Tenseur2HHHH*) &d_sig_deps_HHHH_); // pour simplifier
|
||
|
d_sig_deps_HHHH.TransfertDunTenseurGeneral(d_sig_deps_3D_HHHH);
|
||
|
|
||
|
/* Lorsqu'il y a un pli dans une seule direction, le premier vecteur indique la direction selon laquelle la membrane est en traction. Son intensité est égale à la déformation mécanique dans cette même direction. Le second vecteur est normal à la première direction, son intensité est égale à la déformation cinématique selon cette direction, c'est-à-dire calculée à l'aide des déplacements des noeuds du maillage. Cette déformation est différente de la déformation mécanique calculée par la loi 3D, c'est-à-dire issue de la contraction de la zone, due à la traction suivant la première direction. Cette déformation mécanique peut-être récupéré via la deformation "DEF\_LARGEUR" associée à la loi de comportement.
|
||
|
|
||
|
Lorsqu'il y a des plis dans deux directions, les deux vecteurs indiquent les directions principales d'apparition de plis. L'intensité des vecteurs est égale à la déformation cinématique dans la direction associée.
|
||
|
|
||
|
Lorsqu'il n'y a pas de plis, l'intensité des vecteurs est nulle.
|
||
|
|
||
|
*/
|
||
|
|
||
|
//--- modif 24 sept 2020:
|
||
|
// les def pour les plis ont déjà été calculées dans LoiCritere::Passage_3ou2_vers_1(..
|
||
|
// et il s'agit uniquement de def cinématique donc la suite n'est pas nécessaire et même incorrecte
|
||
|
|
||
|
// SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul);
|
||
|
// LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble * save_result_1DCP2_inter // pour simplifier
|
||
|
// = (LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble *)
|
||
|
// (*(save_resul.liste_des_SaveResul.begin()));
|
||
|
// Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_result_1DCP2_inter->eps_mecaBB));
|
||
|
//
|
||
|
// eps_pli(1) = eps_mecaBB(2,2); // on sauvegarde les def de plis
|
||
|
// if (deux_plis) // cas où il y aurait des plis dans les deux sens
|
||
|
// eps_pli(2) = eps_mecaBB(1,1);
|
||
|
// else eps_pli(2) = 0.; // cas d'un seul plis
|
||
|
// Tenseur3BB& eps_P_mecaBB = *((Tenseur3BB*) (save_result_1DCP2_inter->eps_P_mecaBB));
|
||
|
//
|
||
|
// eps_pli(1) = eps_P_mecaBB(2,2); // on sauvegarde les def de plis
|
||
|
// if (deux_plis) // cas où il y aurait des plis dans les deux sens
|
||
|
// eps_pli(2) = eps_P_mecaBB(1,1);
|
||
|
// else eps_pli(2) = 0.; // cas d'un seul plis
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|