// FICHIER : PoutTimo.cp
// CLASSE : PoutTimo
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) .
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// For more information, please consult: .
//#include "Debug.h"
#include
#include
#include "Sortie.h"
#include "PoutTimo.h"
#include "FrontPointF.h"
#include "FrontSegLine.h"
//----------------------------------------------------------------
// def des donnees commune a tous les elements
// la taille n'est pas defini ici car elle depend de la lecture
//----------------------------------------------------------------
PoutTimo::DonneeCommune * PoutTimo::doCo = NULL;
int PoutTimo::CalculResidu_t_PoutTimo_met_abstraite = 0;
int PoutTimo::Calcul_implicit_PoutTimo_met_abstraite = 0;
int PoutTimo::Calcul_VarDualSort = 0;
PoutTimo::ConstrucElementpoutTimo PoutTimo::construcElementpoutTimo;
// fonction privee
// dans cette fonction il ne doit y avoir que les données communes !!
void PoutTimo::Def_DonneeCommune()
{ // interpollation
GeomSeg segment(1,2) ; // element geometrique correspondant: 1 pt integ, 2 noeuds
// degre de liberte
int dim = ParaGlob::Dimension();
DdlElement tab_ddl(2,dim);
int posi = Id_nom_ddl("X1") -1;
for (int i =1; i<= ParaGlob::Dimension(); i++)
{tab_ddl (1,i) = Enum_ddl(i+posi);
tab_ddl (2,i) = Enum_ddl(i+posi); }
// def metrique
// on definit les variables a priori toujours utiles
Tableau tab(15);
tab(1) = iM0; tab(2) = iMt; tab(3) = iMtdt ;
tab(4)=igiB_0;tab(5)=igiB_t;tab(6)=igiB_tdt;
tab(7)=igiH_0;tab(8)=igiH_t;tab(9)=igiH_tdt ;
tab(10)=igijBB_0;tab(11)=igijBB_t;tab(12)=igijBB_tdt;
tab(13)=igijHH_0;tab(14)=igijHH_t;tab(15)=igijHH_tdt ;
// dim du pb , nb de vecteur de la base , tableau de ddl et la def de variables
Met_biellette metri(ParaGlob::Dimension(),tab_ddl,tab,2) ;
// definition de la classe static contenant toute les variables communes aux biellettes
doCo = new DonneeCommune(segment,tab_ddl,metri);
};
PoutTimo::PoutTimo () :
// Constructeur par defaut
ElemMeca()
{ id_interpol=BIE1; // donnees de la classe mere
id_geom=POUT; //
// stockage des donnees particulieres de la loi de comportement au point d'integ
tabSaveDon.Change_taille(1);
section=-1.;
tab_noeud.Change_taille(2);
// le fait de mettre les pointeurs a null permet
// de savoir que l'element n'est pas complet
tab_noeud(1) = NULL;tab_noeud(2) = NULL;
// definition des donnees communes aux biellettes
// a la premiere definition d'une biellette
if (doCo == NULL) Def_DonneeCommune();
met = &(doCo->met_biellette); // met est defini dans elemeca
// def pointe sur la deformation specifique a l'element
def = new Deformation(*met,*this,(doCo->segment).taDphi(),(doCo->segment).taPhi());
//dimensionnement des deformations et contraintes
epsBB = NevezTenseurBB (1);
sigHH = NevezTenseurHH (1);
int nbddl = doCo->tab_ddl.NbDdl();
d_epsBB.Change_taille(nbddl);
for (int i=1; i<= nbddl; i++)
d_epsBB(i) = NevezTenseurBB (1);
};
PoutTimo::PoutTimo (double sect,int num_id):
// Constructeur utile si la section de l'element et
// le numero de l'element sont connus
ElemMeca(num_id,BIE1,POUT)
{ // stockage des donnees particulieres de la loi de comportement au point d'integ
tabSaveDon.Change_taille(1);
section=sect;
tab_noeud.Change_taille(2);
// le fait de mettre les pointeurs a null permet
// de savoir que l'element n'est pas complet
tab_noeud(1) = NULL;tab_noeud(2) = NULL;
// definition des donnees communes aux biellettes
// a la premiere definition d'une biellette
if (doCo == NULL) Def_DonneeCommune();
met = &(doCo->met_biellette);// met est defini dans elemeca
// def pointe sur la deformation specifique a l'element
def = new Deformation(*met,*this,(doCo->segment).taDphi(),(doCo->segment).taPhi());
//dimensionnement des deformations et contraintes
epsBB = NevezTenseurBB (1);
sigHH = NevezTenseurHH (1);
int nbddl = doCo->tab_ddl.NbDdl();
d_epsBB.Change_taille(nbddl);
for (int i=1; i<= nbddl; i++)
d_epsBB(i) = NevezTenseurBB (1);
};
// Constructeur fonction d'un numero d'identification
PoutTimo::PoutTimo (int num_id) :
ElemMeca(num_id,BIE1,POUT)
{ // stockage des donnees particulieres de la loi de comportement au point d'integ
tabSaveDon.Change_taille(1);
section=-1.; // c-a-d non valide
tab_noeud.Change_taille(2);
// le fait de mettre les pointeurs a null permet
// de savoir que l'element n'est pas complet
tab_noeud(1) = NULL;tab_noeud(2) = NULL;
// definition des donnees communes aux biellettes
// a la premiere definition d'une biellette
if (doCo == NULL) Def_DonneeCommune();
met = &(doCo->met_biellette);// met est defini dans elemeca
// def pointe sur la deformation specifique a l'element
def = new Deformation(*met,*this,(doCo->segment).taDphi(),(doCo->segment).taPhi());
//dimensionnement des deformations et contraintes
epsBB = NevezTenseurBB (1);
sigHH = NevezTenseurHH (1);
int nbddl = doCo->tab_ddl.NbDdl();
d_epsBB.Change_taille(nbddl);
for (int i=1; i<= nbddl; i++)
d_epsBB(i) = NevezTenseurBB (1);
};
PoutTimo::PoutTimo (double sect,int num_id,const Tableau& tab):
// Constructeur utile si la section de l'element, le numero de l'element et
// le tableau des noeuds sont connus
ElemMeca(num_id,tab,BIE1,POUT)
{ // stockage des donnees particulieres de la loi de comportement au point d'integ
tabSaveDon.Change_taille(1);
section=sect;
if (tab_noeud.Taille() != 2)
{ cout << "\n erreur de dimensionnement du tableau de noeud \n";
cout << " PoutTimo::PoutTimo (double sect,int num_id,const Tableau& tab)\n";
Sortie (1); }
// definition des donnees communes aux biellettes
// a la premiere definition d'une biellette
if (doCo == NULL) Def_DonneeCommune();
met = &(doCo->met_biellette);// met est defini dans elemeca
// def pointe sur la deformation specifique a l'element
def = new Deformation(*met,*this,(doCo->segment).taDphi(),(doCo->segment).taPhi());
//dimensionnement des deformations et contraintes
epsBB = NevezTenseurBB (1);
sigHH = NevezTenseurHH (1);
int nbddl = doCo->tab_ddl.NbDdl();
d_epsBB.Change_taille(nbddl);
for (int i=1; i<= nbddl; i++)
d_epsBB(i) = NevezTenseurBB (1);
// construction du tableau de ddl des noeuds de biellette
ConstTabDdl();
};
PoutTimo::PoutTimo (PoutTimo& poutTimo) :
ElemMeca (poutTimo)
// Constructeur de copie
{ // stockage des donnees particulieres de la loi de comportement au point d'integ
tabSaveDon.Change_taille(1);
section=poutTimo.section;
*(epsBB) = *(poutTimo.epsBB);
*(sigHH) = *(poutTimo.sigHH);
d_epsBB=poutTimo.d_epsBB;
for (int i=1; i<= d_epsBB.Taille(); i++)
{ d_epsBB(i) = NevezTenseurBB(1);
*d_epsBB(i) = *(poutTimo.d_epsBB(i)); }
*(residu) = *(poutTimo.residu);
*(raideur) = *(poutTimo.raideur);
*met = *(poutTimo.met);
*def = *(poutTimo.def);
};
PoutTimo::~PoutTimo ()
// Destructeur
{ delete epsBB;
delete sigHH;
for (int i=1; i<= d_epsBB.Taille(); i++)
delete d_epsBB(i);
LibereTenseur();
delete def; // la deformation
};
// Lecture des donnees de la classe sur fichier
void
PoutTimo::LectureDonneesParticulieres
(UtilLecture * entreePrinc,Tableau * tabMaillageNoeud)
{ int nb;
tab_noeud.Change_taille(2);
for (int i=1; i<= 2; i++)
{ *(entreePrinc->entree) >> nb;
tab_noeud(i) = (*tabMaillageNoeud)(nb);
}
// construction du tableau de ddl des noeuds de biellette
ConstTabDdl();
};
// Calcul du residu local
Vecteur* PoutTimo::CalculResidu_t ()
{ // dimensionnement de la metrique
if( CalculResidu_t_PoutTimo_met_abstraite == 0)
{ Tableau tab(7);
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
doCo->met_biellette.PlusInitVariables(tab) ;
CalculResidu_t_PoutTimo_met_abstraite = 1;
};
// dimensionnement du residu
int nbddl = doCo->tab_ddl.NbDdl();
if ( residu == NULL)
residu = new Vecteur(nbddl); // cas du premier passage
else
for (int i =1; i<= nbddl; i++) // cas des autres passages
(*residu)(i) = 0.; // on initialise a zero
Vecteur poids =(doCo->segment).taWi(); // poids d'interpolation = 2
poids(1) *= section;
Tableau tabSigHH(1); tabSigHH(1) = sigHH;
Tableau tabEpsBB(1); tabEpsBB(1) = epsBB;
ElemMeca::Cal_explicit ( doCo->tab_ddl,tabEpsBB,d_epsBB,tabSigHH,1,poids);
return residu;
};
// Calcul du residu local et de la raideur locale,
// pour le schema implicite
Element::ResRaid PoutTimo::Calcul_implicit ()
{ if( Calcul_implicit_PoutTimo_met_abstraite == 0)
{ Tableau tab(13);
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;
doCo->met_biellette.PlusInitVariables(tab) ;
Calcul_implicit_PoutTimo_met_abstraite = 1;
};
// dimensionnement du residu
int nbddl = doCo->tab_ddl.NbDdl();
if ( residu == NULL)
residu = new Vecteur(nbddl); // cas du premier passage
else
for (int i =1; i<= nbddl; i++) // cas des autres passages
(*residu)(i) = 0.; // on initialise a zero
// dimensionnement de la raideur
if ( raideur == NULL)
raideur = new Mat_pleine(nbddl,nbddl); // cas du premier passage
else
for (int i =1; i<= nbddl; i++) // cas des autres passages
for (int j=1; j<= nbddl; j++) //
(*raideur)(i,j) = 0.; // on initialise a zero
Vecteur poids =(doCo->segment).taWi(); // poids d'interpolation = 2
poids(1) *= section;
Tableau tabSigHH(1); tabSigHH(1) = sigHH;
Tableau tabEpsBB(1); tabEpsBB(1) = epsBB;
ElemMeca::Cal_implicit (doCo->tab_ddl,tabEpsBB, d_epsBB,tabSigHH,1,poids);
Element::ResRaid el;
el.res = residu;
el.raid = raideur;
return el;
};
// Calcul de la matrice géométrique et initiale
ElemMeca::MatGeomInit PoutTimo::MatricesGeometrique_Et_Initiale ()
{ if( Calcul_implicit_PoutTimo_met_abstraite == 0)
{ Tableau tab(14);
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
doCo->met_biellette.PlusInitVariables(tab) ;
Calcul_implicit_PoutTimo_met_abstraite = 1;
};
// Par simplicité
Mat_pleine & matGeom = doCo->matGeom;
Mat_pleine & matInit = doCo->matInit;
// mise à zéro de la matrice géométrique
matGeom.Initialise();
Vecteur poids =(doCo->segment).taWi(); // poids d'interpolation = 2
poids(1) *= section;
Tableau tabSigHH(1); tabSigHH(1) = sigHH;
Tableau tabEpsBB(1); tabEpsBB(1) = epsBB;
ElemMeca::Cal_matGeom_Init
(matGeom,matInit,doCo->tab_ddl,tabEpsBB, d_epsBB,
doCo->d2_epsBB,tabSigHH,1,poids);
return MatGeomInit(&matGeom,&matInit);
} ;
// retourne les tableaux de ddl gere par l'element
// ce tableau et specifique a l'element
DdlElement & PoutTimo::TableauDdl()
{ return doCo->tab_ddl; };
// liberation de la place pointee
void PoutTimo::Libere ()
{Element::Libere (); // liberation de residu et raideur
LibereTenseur() ; // liberation des tenseur intermediaires
for (int i=1; i<= d_epsBB.Taille(); i++) // a priori est locale
delete d_epsBB(i);
};
// acquisition ou modification d'une loi de comportement
void PoutTimo::DefLoi (LoiAbstraiteGeneral * NouvelleLoi)
{ loiComp = (Loi_comp_abstraite *) NouvelleLoi;
// verification du type de loi
if (loiComp->Dimension() != 1)
{ cout << "\n Erreur, la loi de comportement a utiliser avec des biellettes";
cout << " doit etre de type 1D, \n ici est de type = "
<< (NouvelleLoi->Dimension()) << " !!! " << endl;
Sortie(1);
}
// initialisation du stockage particulier, ici 1 pt d'integ
tabSaveDon(1) = loiComp->Initialise();
};
// test si l'element est complet
int PoutTimo::TestComplet()
{ int res = ElemMeca::TestComplet(); // test dans la fonction mere
if ( section == -1)
{ cout << "\n la section de la biellette n'est pas defini \n";
res = 0; }
if ( tab_noeud(1) == NULL)
{ cout << "\n les noeuds de la biellette ne sont pas defini \n";
res = 0; }
else
{ int testi =1;
int posi = Id_nom_ddl("X1") -1;
for (int i =1; i<= ParaGlob::Dimension(); i++)
for (int j=1;j<=2;j++)
if(!(tab_noeud(j)->Existe_ici(Enum_ddl(posi+i))))
testi = 0;
if(testi == 0)
{ cout << "\n les ddls X1,X2 etc des noeuds de la biellette ne sont pas defini \n";
cout << " \n utilisez PoutTimo::ConstTabDdl() pour completer " ;
res = 0; }
}
return res;
};
// ajout du tableau de ddl des noeuds de biellette
void PoutTimo::ConstTabDdl()
{
Tableau ta(ParaGlob::Dimension());
int posi = Id_nom_ddl("X1") -1;
for (int i =1; i<= ParaGlob::Dimension(); i++)
{Ddl inter((Enum_ddl(i+posi)),0.,false);
ta(i) = inter;
}
// attribution des ddls aux noeuds
tab_noeud(1)->PlusTabDdl(ta);
tab_noeud(2)->PlusTabDdl(ta);
};
// procesure permettant de completer l'element apres
// sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
Element* PoutTimo::Complete(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD)
{ if (bloc.Nom(1) == "sections")
{ section = bloc.Val(1);
return this;
}
else
return ElemMeca::Complete_ElemMeca(bloc,lesFonctionsnD);
//return NULL;
};
// affichage dans la sortie transmise, des variables duales "nom"
// dans le cas ou nom est vide, affichage de "toute" les variables
void PoutTimo::AfficheVarDual(ofstream& sort, Tableau& nom)
{// affichage de l'entête de l'element
sort << "\n******************************************************************";
sort << "\n Element poutTimo (2 noeuds 1 point d'integration) ";
sort << "\n******************************************************************";
// appel de la procedure de elem meca
Tableau tabSigHH(1); tabSigHH(1) = sigHH;
Tableau tabEpsBB(1); tabEpsBB(1) = epsBB;
if ((Calcul_VarDualSort == 0) && (Calcul_implicit_PoutTimo_met_abstraite != 0))
{ VarDualSort(sort,nom,tabSigHH,tabEpsBB,1,1);
Calcul_VarDualSort = 1;
}
else if ((Calcul_VarDualSort == 1) && (Calcul_implicit_PoutTimo_met_abstraite != 0))
VarDualSort(sort,nom,tabSigHH,tabEpsBB,1,11);
else if ((Calcul_VarDualSort == 0) && (CalculResidu_t_PoutTimo_met_abstraite != 0))
{ VarDualSort(sort,nom,tabSigHH,tabEpsBB,1,2);
Calcul_VarDualSort = 1;
}
else if ((Calcul_VarDualSort == 1) && (CalculResidu_t_PoutTimo_met_abstraite != 0))
VarDualSort(sort,nom,tabSigHH,tabEpsBB,1,12);
// sinon on ne fait rien
};
// Calcul des frontieres de l'element
// creation des elements frontieres et retour du tableau de ces elements
Tableau & PoutTimo::Frontiere()
{ int cas = 6; // on veut des lignes et des points
return Frontiere_elemeca(cas,force);
// { // dimensionnement des tableaux intermediaires
// Tableau tab(1); // les noeuds des points frontieres
// DdlElement ddelem(1); // les ddlelements des points frontieres
// int tail;
// if (ParaGlob::Dimension() <= 2)
// tail = 2; // deux points
// else if (ParaGlob::Dimension() == 3)
// tail = 3; // deux points et le segment lui-meme
// #ifdef MISE_AU_POINT
// else
// { cout << "\n erreur de dimension dans PoutTimo, dim = " << ParaGlob::Dimension();
// cout << "\n alors que l'on doit avoir 1 ou 2 ou 3 !! " << endl;
// Sortie (1);
// }
// #endif
// tabb.Change_taille(tail);
// // premier point
// tab(1) = tab_noeud(1);
// ddelem(1) = doCo->tab_ddl(1);
// tabb(1) = new FrontPointF (tab,ddelem);
// // second point
// tab(1) = tab_noeud(2);
// ddelem(1) = doCo->tab_ddl(2);
// tabb(2) = new FrontPointF (tab,ddelem);
// // 3 ieme cote eventuelle
// if (tail == 3)
// tabb(3) = new FrontSegLine(tab_noeud,doCo->tab_ddl);
//
// return tabb;
};