// 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; };