// 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 "PiPoCo.h" #include #include "ConstMath.h" #include "Loi_Umat.h" #include "ExceptionsElemMeca.h" #include "ExceptionsLoiComp.h" // =========================== variables communes =============================== // a priori les pointeurs de fonction pointent sur rien au debut TenseurHH* PiPoCo::sig_bulk_pourPiPoCo_HH = NULL; // variable de travail pour le bulk // =========================== fin variables communes =========================== // =========================== methodes publiques =============================== // calcul si un point est a l'interieur de l'element ou non // il faut que M est la dimension globale // les trois fonctions sont pour l'etude a t=0, t et tdt // retour : =0 le point est externe, =1 le point est interne , // = 2 le point est sur la frontière à la précision près // coor_locales : s'il est différent de NULL, est affecté des coordonnées locales calculées, // uniquement précises si le point est interne int PiPoCo::Interne_0(const Coordonnee& M,Coordonnee* ) { cout << "\n fonction non implante, bool PiPoCo::Interne_0(Coordonnee& M)"; Sortie(1); return Interne(TEMPS_0,M); }; int PiPoCo::Interne_t(const Coordonnee& M,Coordonnee* ) { cout << "\n fonction non implante, bool PiPoCo::Interne_t(Coordonnee& M)"; Sortie(1); return Interne(TEMPS_t,M); }; int PiPoCo::Interne_tdt(const Coordonnee& M,Coordonnee* ) { cout << "\n fonction non implante, bool PiPoCo::Interne_tdt(Coordonnee& M)"; Sortie(1); return Interne(TEMPS_tdt,M); }; // METHODES VIRTUELLES: // --------- calculs utils dans le cadre de la recherche du flambement linéaire // dans un premier temps uniquement virtuelles, ensuite se sera virtuelle pure pour éviter // les oubli de définition ----> AMODIFIER !!!!!!!! // Calcul de la matrice géométrique et initiale ElemMeca::MatGeomInit PiPoCo::MatricesGeometrique_Et_Initiale (const ParaAlgoControle & ) { cout << "\n attention le calcul de la matrice g\'eom\'etrique et de la matrice " << " initiale ne sont pas implant\'ees \n" ; this->Affiche(1); cout << "\nvoid PiPoCo::MatricesGeometrique_Et_Initiale (Mat_pleine &,Mat_pleine &)" << endl; Sortie(1); return MatGeomInit(NULL,NULL); // pour supprimer le warning }; // =========================== methodes protegees =============================== // Calcul du residu local et de la raideur locale, // pour le schema implicite void PiPoCo::Cal_implicitPiPoCo (DdlElement & tab_ddl, Tableau & d_epsBB,Tableau < Tableau2 > d2_epsBB_, Tableau & d_sigHH,int nbintS,Vecteur& poidsS,int nbintH ,Vecteur& poidsH,const ParaAlgoControle & pa,bool cald_Dvirtuelle) { int nbddl = tab_ddl.NbDdl(); double jacobien; // def du jacobien Vecteur d_jacobien_tdt; energie_totale.Inita(0.); // init de l'énergie totale sur l'élément TenseurHH* sigHH_t_1 = (*lesPtIntegMecaInterne)(1).SigHH_t(); // simplification d'écriture if (ElemMeca::Bulk_visco_actif()) { if (sig_bulk_pourPiPoCo_HH == NULL) {sig_bulk_pourPiPoCo_HH = NevezTenseurHH(*sigHH_t_1);} else if (sig_bulk_pourPiPoCo_HH->Dimension() != sigHH_t_1->Dimension()) {delete sig_bulk_pourPiPoCo_HH; sig_bulk_pourPiPoCo_HH = NevezTenseurHH(*sigHH_t_1);}; }; int indice = 1; for (int nisur =1; nisur<= nbintS; nisur++) // boucle sur les pt d'integ de surface for (int niepais =1; niepais<= nbintH; niepais++, indice++) // pt d'integ d'epaisseur { ((DeformationPP*) def)->ChangeNumIntegSH(nisur,niepais); ((DeformationPP*) def)->Mise_a_jour_data_specif(tabSaveDefDon(indice)); PtIntegMecaInterne & ptIntegMeca = (*lesPtIntegMecaInterne)(indice); TenseurHH & sigHH = *(ptIntegMeca.SigHH()); TenseurBB & DepsBB_tdt = *(ptIntegMeca.DepsBB()); EnergieMeca& energ = tab_energ(indice); EnergieMeca& energ_t = tab_energ_t(indice); double poids = poidsS(nisur) * poidsH(niepais) ; CompThermoPhysiqueAbstraite::SaveResul* sTP=NULL; // les données spécifique thermo physiques if (loiTP != NULL) {sTP = tabSaveTP(indice);}; // au pt d'integ si elles existes if ((loiComp->Id_comport()==LOI_VIA_UMAT) // cas de l'utilisation d'une loi umat || (loiComp->Id_comport()==LOI_VIA_UMAT_CP)) ((Loi_Umat*) loiComp)->Mise_a_jour_nbe_nbptinteg(this->Num_elt(),indice); // -- on gère les exceptions éventuelles en mettant le bloc sous surveillance const Met_abstraite::Impli* ex_pointe = NULL; // c'est pour construire ex try // ce qui permet de donner les numéros d'éléments et de pti { ex_pointe = &loiComp->Cal_implicit(tabSaveDon(indice), *def,tab_ddl,ptIntegMeca ,d_epsBB,jacobien,d_jacobien_tdt,d_sigHH ,pa,sTP,loiTP,dilatation,energ,energ_t ,premier_calcul_meca_impli_expli); } catch (ErrNonConvergence_loiDeComportement excep) // cas d'une d'une erreur survenue à cause d'une non convergence pour la résolution // d'une loi de comportement incrémentale { cout << "\n erreur de loi de comportement element= " << this->Num_elt() << " point d'integration de surface= "< & d_epsBB,int nbintS, Vecteur& poidsS,int nbintH,Vecteur& poidsH,const ParaAlgoControle & ,bool atdt) { double jacobien; // def du jacobien int nbddl = tab_ddl.NbDdl(); int indice = 1; energie_totale.Inita(0.); // init de l'énergie totale sur l'élément TenseurHH* sigHH_t_1 = (*lesPtIntegMecaInterne)(1).SigHH_t(); // simplification d'écriture if (ElemMeca::Bulk_visco_actif()) { if (sig_bulk_pourPiPoCo_HH == NULL) {sig_bulk_pourPiPoCo_HH = NevezTenseurHH(*sigHH_t_1);} else if (sig_bulk_pourPiPoCo_HH->Dimension() != sigHH_t_1->Dimension()) {delete sig_bulk_pourPiPoCo_HH; sig_bulk_pourPiPoCo_HH = NevezTenseurHH(*sigHH_t_1);}; }; for (int nisur =1; nisur<= nbintS; nisur++) // boucle sur les pt d'integ de surface for (int niepais =1; niepais<= nbintH; niepais++, indice++) // pt d'integ d'epaisseur { ((DeformationPP*) def)->ChangeNumIntegSH(nisur,niepais); ((DeformationPP*) def)->Mise_a_jour_data_specif(tabSaveDefDon(indice)); PtIntegMecaInterne & ptIntegMeca = (*lesPtIntegMecaInterne)(indice); TenseurHH & sigHH = *(ptIntegMeca.SigHH()); TenseurBB & DepsBB_ = *(ptIntegMeca.DepsBB()); EnergieMeca& energ = tab_energ(indice); EnergieMeca& energ_t = tab_energ_t(indice); double poids = poidsS(nisur) * poidsH(niepais) ; CompThermoPhysiqueAbstraite::SaveResul* sTP=NULL; // les données spécifique thermo physiques if (loiTP != NULL) {sTP = tabSaveTP(indice);}; // au pt d'integ si elles existes if ((loiComp->Id_comport()==LOI_VIA_UMAT) // cas de l'utilisation d'une loi umat || (loiComp->Id_comport()==LOI_VIA_UMAT_CP)) ((Loi_Umat*) loiComp)->Mise_a_jour_nbe_nbptinteg(this->Num_elt(),indice); // -- on gère les exceptions éventuelles en mettant le bloc sous surveillance try // ce qui permet de donner les numéros d'éléments et de pti {if (atdt) { const Met_abstraite::Expli_t_tdt& ex = loiComp->Cal_explicit_tdt (tabSaveDon(indice), *def,tab_ddl,ptIntegMeca,d_epsBB,jacobien ,sTP,loiTP,dilatation,energ,energ_t,premier_calcul_meca_impli_expli); // examen du cas où on désire utiliser la méthode d'atténuation des hautes fréquences avec le bulk viscosity if (Bulk_visco_actif()) ModifContrainteBulk(TEMPS_tdt,*ex.gijHH_tdt,sigHH,DepsBB_ ,(*sig_bulk_pourPiPoCo_HH)); } else { const Met_abstraite::Expli& ex = loiComp->Cal_explicit_t (tabSaveDon(indice), *def,tab_ddl,ptIntegMeca,d_epsBB,jacobien ,sTP,loiTP,dilatation,energ,energ_t,premier_calcul_meca_impli_expli); // examen du cas où on désire utiliser la méthode d'atténuation des hautes fréquences avec le bulk viscosity if (Bulk_visco_actif()) ModifContrainteBulk(TEMPS_t,*ex.gijHH_t,sigHH,DepsBB_ ,(*sig_bulk_pourPiPoCo_HH)); }; } catch (ErrNonConvergence_loiDeComportement excep) // cas d'une d'une erreur survenue à cause d'une non convergence pour la résolution // d'une loi de comportement incrémentale { cout << "\n erreur de loi de comportement element= " << this->Num_elt() << " point d'integration de surface= "< nbint et poids void PiPoCo::Cal_matGeom_InitPiPoCo (Mat_pleine & matGeom, Mat_pleine & matInit, DdlElement & tab_ddl,Tableau & d_epsBB, Tableau < Tableau2 > d2_epsBB_, Tableau & d_sigHH,int nbintS ,Vecteur& poidsS,int nbintH,Vecteur& poidsH,const ParaAlgoControle & pa,bool cald_Dvirtuelle) { // le début du programme est semblable au calcul implicit // seule la constitution des matrices finales est différente int nbddl = tab_ddl.NbDdl(); double jacobien; // def du jacobien Vecteur d_jacobien_tdt; int indice = 1; for (int nisur =1; nisur<= nbintS; nisur++) // boucle sur les pt d'integ de surface for (int niepais =1; niepais<= nbintH; niepais++, indice++) // pt d'integ d'epaisseur { ((DeformationPP*) def)->ChangeNumIntegSH(nisur,niepais); ((DeformationPP*) def)->Mise_a_jour_data_specif(tabSaveDefDon(indice)); PtIntegMecaInterne & ptIntegMeca = (*lesPtIntegMecaInterne)(indice); TenseurHH & sigHH = *(ptIntegMeca.SigHH()); TenseurBB & DepsBB_tdt = *(ptIntegMeca.DepsBB()); EnergieMeca& energ = tab_energ(indice); EnergieMeca& energ_t = tab_energ_t(indice); double poids = poidsS(nisur) * poidsH(niepais) ; CompThermoPhysiqueAbstraite::SaveResul* sTP=NULL; // les données spécifique thermo physiques if (loiTP != NULL) {sTP = tabSaveTP(indice);}; // au pt d'integ si elles existes if ((loiComp->Id_comport()==LOI_VIA_UMAT) // cas de l'utilisation d'une loi umat || (loiComp->Id_comport()==LOI_VIA_UMAT_CP)) ((Loi_Umat*) loiComp)->Mise_a_jour_nbe_nbptinteg(this->Num_elt(),indice); // -- on gère les exceptions éventuelles en mettant le bloc sous surveillance try // ce qui permet de donner les numéros d'éléments et de pti {loiComp->Cal_flamb_lin(tabSaveDon(indice), *def,tab_ddl,ptIntegMeca,d_epsBB ,jacobien,d_jacobien_tdt, d_sigHH,pa,sTP,loiTP,dilatation ,energ,energ_t,premier_calcul_meca_impli_expli); } catch (ErrNonConvergence_loiDeComportement excep) // cas d'une d'une erreur survenue à cause d'une non convergence pour la résolution // d'une loi de comportement incrémentale { cout << "\n erreur de loi de comportement element= " << this->Num_elt() << " point d'integration de surface= "<