3020 lines
172 KiB
C++
3020 lines
172 KiB
C++
|
|
||
|
// 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 "ElemMeca.h"
|
||
|
#include <iomanip>
|
||
|
#include "ConstMath.h"
|
||
|
#include "Util.h"
|
||
|
#include "CharUtil.h"
|
||
|
#include "Coordonnee2.h"
|
||
|
#include "Coordonnee3.h"
|
||
|
#include "TypeConsTens.h"
|
||
|
#include "TypeQuelconqueParticulier.h"
|
||
|
|
||
|
|
||
|
// retourne la liste de tous les types de ddl interne actuellement utilisés
|
||
|
// par l'élément (actif ou non), sont exclu de cette liste les ddl des noeuds
|
||
|
// reliés à l'élément (ddl implique grandeur uniquement scalaire !)
|
||
|
// par contre sont inclus les ddl venant de l'élément, qui sont représenté directement aux noeuds
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
List_io <Ddl_enum_etendu> ElemMeca::Les_type_de_ddl_internes(bool absolue) const
|
||
|
{ List_io <Ddl_enum_etendu> ret;
|
||
|
switch (this->Dim_sig_eps())
|
||
|
{ case 1 :
|
||
|
{ret.push_back(SIG11); ret.push_back(EPS11);ret.push_back(DEPS11);
|
||
|
ret.push_back(string("Green-Lagrange11"));ret.push_back(string("Almansi11"));ret.push_back(string("logarithmique11"));
|
||
|
ret.push_back(string("Cauchy_local11"));
|
||
|
ret.push_back(string("Almansi_local11"));
|
||
|
ret.push_back(string("Def_principaleI"));ret.push_back(string("Sigma_principaleI"));
|
||
|
ret.push_back(string("Vit_principaleI"));ret.push_back(string("Delta_def11"));
|
||
|
if (dilatation)
|
||
|
{ret.push_back(string("Almansi_totale11"));ret.push_back(string("Green_Lagrange_totale11"));
|
||
|
ret.push_back(string("logarithmique_totale11"));};
|
||
|
break;
|
||
|
}
|
||
|
case 2 :
|
||
|
{ret.push_back(SIG11); ret.push_back(SIG22);
|
||
|
ret.push_back(SIG12); ret.push_back(EPS11);
|
||
|
ret.push_back(EPS22); ret.push_back(EPS12);
|
||
|
ret.push_back(DEPS11);ret.push_back(DEPS22);ret.push_back(DEPS12);
|
||
|
ret.push_back(string("Green-Lagrange11")); ret.push_back(string("Green-Lagrange22"));
|
||
|
ret.push_back(string("Green-Lagrange12")); ret.push_back(string("Almansi11"));
|
||
|
ret.push_back(string("Almansi22")); ret.push_back(string("Almansi12"));
|
||
|
ret.push_back(string("logarithmique11")); ret.push_back(string("logarithmique22"));
|
||
|
ret.push_back(string("logarithmique12"));
|
||
|
ret.push_back(string("Cauchy_local11")); ret.push_back(string("Cauchy_local22"));
|
||
|
ret.push_back(string("Cauchy_local12"));
|
||
|
ret.push_back(string("Almansi_local11"));
|
||
|
ret.push_back(string("Almansi_local22")); ret.push_back(string("Almansi_local12"));
|
||
|
ret.push_back(string("Def_principaleI"));ret.push_back(string("Def_principaleII"));
|
||
|
ret.push_back(string("Sigma_principaleI"));ret.push_back(string("Sigma_principaleII"));
|
||
|
ret.push_back(string("Vit_principaleI"));ret.push_back(string("Vit_principaleII"));
|
||
|
ret.push_back(string("Delta_def11"));ret.push_back(string("Delta_def22"));ret.push_back(string("Delta_def12"));
|
||
|
if (dilatation)
|
||
|
{ret.push_back(string("Almansi_totale11"));ret.push_back(string("Almansi_totale12"));ret.push_back(string("Almansi_totale22"));
|
||
|
ret.push_back(string("Green_Lagrange_totale11"));ret.push_back(string("Green_Lagrange_totale12"));
|
||
|
ret.push_back(string("Green_Lagrange_totale22"));
|
||
|
ret.push_back(string("logarithmique_totale11"));ret.push_back(string("logarithmique_totale12"));
|
||
|
ret.push_back(string("logarithmique_totale22"));
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case 3 :
|
||
|
{ret.push_back(SIG11); ret.push_back(SIG22);
|
||
|
ret.push_back(SIG33); ret.push_back(SIG12);
|
||
|
ret.push_back(SIG23); ret.push_back(SIG13);
|
||
|
ret.push_back(EPS11); ret.push_back(EPS22);
|
||
|
ret.push_back(EPS33); ret.push_back(EPS12);
|
||
|
ret.push_back(EPS23); ret.push_back(EPS13);
|
||
|
ret.push_back(DEPS11); ret.push_back(DEPS22);
|
||
|
ret.push_back(DEPS33); ret.push_back(DEPS12);
|
||
|
ret.push_back(DEPS23); ret.push_back(DEPS13);
|
||
|
ret.push_back(string("Green-Lagrange11")); ret.push_back(string("Green-Lagrange22"));
|
||
|
ret.push_back(string("Green-Lagrange33")); ret.push_back(string("Green-Lagrange12"));
|
||
|
ret.push_back(string("Green-Lagrange23")); ret.push_back(string("Green-Lagrange13"));
|
||
|
ret.push_back(string("Almansi11")); ret.push_back(string("Almansi22"));
|
||
|
ret.push_back(string("Almansi33")); ret.push_back(string("Almansi12"));
|
||
|
ret.push_back(string("Almansi23")); ret.push_back(string("Almansi13"));
|
||
|
ret.push_back(string("logarithmique11")); ret.push_back(string("logarithmique22"));
|
||
|
ret.push_back(string("logarithmique33")); ret.push_back(string("logarithmique12"));
|
||
|
ret.push_back(string("logarithmique23")); ret.push_back(string("logarithmique13"));
|
||
|
ret.push_back(string("Cauchy_local11")); ret.push_back(string("Cauchy_local22"));
|
||
|
ret.push_back(string("Cauchy_local33")); ret.push_back(string("Cauchy_local12"));
|
||
|
ret.push_back(string("Cauchy_local23")); ret.push_back(string("Cauchy_local13"));
|
||
|
ret.push_back(string("Almansi_local11")); ret.push_back(string("Almansi_local22"));
|
||
|
ret.push_back(string("Almansi_local33")); ret.push_back(string("Almansi_local12"));
|
||
|
ret.push_back(string("Almansi_local23")); ret.push_back(string("Almansi_local13"));
|
||
|
ret.push_back(string("Def_principaleI"));ret.push_back(string("Def_principaleII"));
|
||
|
ret.push_back(string("Def_principaleIII"));
|
||
|
ret.push_back(string("Sigma_principaleI"));ret.push_back(string("Sigma_principaleII"));
|
||
|
ret.push_back(string("Sigma_principaleIII"));
|
||
|
ret.push_back(string("Vit_principaleI"));ret.push_back(string("Vit_principaleII"));ret.push_back(string("Vit_principaleIII"));
|
||
|
ret.push_back(string("Delta_def11"));ret.push_back(string("Delta_def22"));ret.push_back(string("Delta_def33"));
|
||
|
ret.push_back(string("Delta_def12"));ret.push_back(string("Delta_def13"));ret.push_back(string("Delta_def23"));
|
||
|
if (dilatation)
|
||
|
{ret.push_back(string("Almansi_totale11"));ret.push_back(string("Almansi_totale22"));
|
||
|
ret.push_back(string("Almansi_totale33"));ret.push_back(string("Almansi_totale12"));
|
||
|
ret.push_back(string("Almansi_totale23"));ret.push_back(string("Almansi_totale13"));
|
||
|
ret.push_back(string("Green_Lagrange_totale11"));ret.push_back(string("Green_Lagrange_totale22"));
|
||
|
ret.push_back(string("Green_Lagrange_totale33"));ret.push_back(string("Green_Lagrange_totale12"));
|
||
|
ret.push_back(string("Green_Lagrange_totale23"));ret.push_back(string("Green_Lagrange_totale13"));
|
||
|
ret.push_back(string("logarithmique_totale11"));ret.push_back(string("logarithmique_totale22"));
|
||
|
ret.push_back(string("logarithmique_totale33"));ret.push_back(string("logarithmique_totale12"));
|
||
|
ret.push_back(string("logarithmique_totale23"));ret.push_back(string("logarithmique_totale13"));
|
||
|
};
|
||
|
ret.push_back(string("Spherique_eps"));ret.push_back(string("Q_eps"));ret.push_back(string("Cos3phi_eps"));
|
||
|
ret.push_back(string("Spherique_sig"));ret.push_back(string("Q_sig"));ret.push_back(string("Cos3phi_sig"));
|
||
|
break;
|
||
|
}
|
||
|
};
|
||
|
// cas de mises et tresca
|
||
|
ret.push_back(string("contrainte_mises"));
|
||
|
ret.push_back(string("contrainte_tresca"));
|
||
|
// déformation duale de mises = sqrt(2/3 * eps_barre:eps_barre)
|
||
|
ret.push_back(string("def_duale_mises"));
|
||
|
// déformation cumulée: int_0^t sqrt(2./3. * ( ((*delta_epsBH) && (*delta_epsBH)) - Sqr(delta_epsBH->Trace()) /3. ))
|
||
|
ret.push_back(string("def_equivalente"));
|
||
|
// déformation duale de mises maxi
|
||
|
ret.push_back(string("def_duale_mises_maxi"));
|
||
|
// vitesse de déformation équivalente
|
||
|
ret.push_back(string("vitesse_def_equivalente"));
|
||
|
// cas de l'existence de l'erreur
|
||
|
if (sigErreur != NULL) ret.push_back(ERREUR);
|
||
|
// cas de la plasticité classique
|
||
|
string nom_comport(loiComp->Nom_comport());
|
||
|
if ((strstr(nom_comport.c_str(),"PRANDTL_REUSS")!=NULL))
|
||
|
ret.push_back(string("def_plastique_cumulee"));
|
||
|
// cas des énergies locales
|
||
|
ret.push_back(string("energie_elastique"));
|
||
|
ret.push_back(string("dissipation_plastique"));
|
||
|
ret.push_back(string("dissipation_visqueuse"));
|
||
|
// cas des coordonnées du points
|
||
|
switch (ParaGlob::Dimension())
|
||
|
{case 3: ret.push_back(X3);
|
||
|
case 2: ret.push_back(X2);
|
||
|
case 1: ret.push_back(X1);
|
||
|
};
|
||
|
// cas des pressions éventuellement exercées sur les faces de l'élément
|
||
|
// modif 15 juin 2019: on sort systématiquement même s'il n'y a pas de pression enregistrée
|
||
|
// car la pression peut ne pas être active au début puis ensuite elle devient active
|
||
|
// et ret sert pour autoriser la sortie par la suite dans les résultats
|
||
|
// de plus au moment de la sortie, lesChargeExtSurEle sera testé et si c'est non nul ce sera ok
|
||
|
// si c'est nul, ce sera by passé
|
||
|
// if (lesChargeExtSurEle != NULL)
|
||
|
// if (lesChargeExtSurEle->LesPressionsExternes() != NULL)
|
||
|
ret.push_back(string("pression_ext"));
|
||
|
// dans le cas d'un élément 2D, dans un espace 3D, on peut récupérer la normale
|
||
|
if ((Type_geom_generique(this->Id_geometrie()) == SURFACE )
|
||
|
&& (ParaGlob::Dimension() == 3))
|
||
|
{ret.push_back(string("N_surf_1"));ret.push_back(string("N_surf_2"));ret.push_back(string("N_surf_3"));
|
||
|
ret.push_back(string("N_surf_1_t0"));ret.push_back(string("N_surf_2_t0"));ret.push_back(string("N_surf_3_t0"));
|
||
|
};
|
||
|
|
||
|
// retour
|
||
|
return ret;
|
||
|
};
|
||
|
|
||
|
// retourne la liste abondée de tous les données particulières interne actuellement utilisés
|
||
|
// par l'élément (actif ou non), sont exclu de cette liste les données particulières des noeuds
|
||
|
// reliés à l'élément
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
List_io <TypeQuelconque> ElemMeca::Les_types_particuliers_internes(bool absolue) const
|
||
|
{ List_io <TypeQuelconque> ret;
|
||
|
// on s'intéresse au information stockée au niveau des points d'intégration
|
||
|
// 1° récupéreration les grandeurs
|
||
|
// a) cas des grandeurs liées à la déformation
|
||
|
def->ListeGrandeurs_particulieres(absolue,ret);
|
||
|
// b) cas des grandeurs liées à la loi de comportement mécanique
|
||
|
loiComp->ListeGrandeurs_particulieres(absolue,ret);
|
||
|
// c) cas des grandeurs liées à la loi de comportement thermo-physique
|
||
|
if (loiTP != NULL) loiTP->ListeGrandeurs_particulieres(absolue,ret);
|
||
|
// d) cas des infos stockés aux points d'intégration, donc par l'élément
|
||
|
Grandeur_scalaire_double grand_courant; // def d'une grandeur courante
|
||
|
Tableau <double> tab_1(1);
|
||
|
Tab_Grandeur_scalaire_double tab_grand_courant(tab_1);
|
||
|
// def d'un type quelconque représentatif à chaque grandeur
|
||
|
// a priori ces grandeurs sont défini aux points d'intégration
|
||
|
// $$$ cas de MODULE_COMPRESSIBILITE_TOTAL: intègre toutes les sous_lois par exemple
|
||
|
TypeQuelconque typQ1(MODULE_COMPRESSIBILITE_TOTAL,SIG11,grand_courant);
|
||
|
ret.push_back(typQ1);
|
||
|
// $$$ cas de MODULE_CISAILLEMENT_TOTAL: intègre toutes les sous_lois par exemple
|
||
|
TypeQuelconque typQ2(MODULE_CISAILLEMENT_TOTAL,SIG11,grand_courant);
|
||
|
ret.push_back(typQ2);
|
||
|
// e) cas des infos stockés à l'élément
|
||
|
// $$$ cas du volume total :
|
||
|
TypeQuelconque typQ3(VOLUME_ELEMENT,SIG11,grand_courant);
|
||
|
ret.push_back(typQ3);
|
||
|
// $$$ cas du volume élémentaire associé au pti
|
||
|
TypeQuelconque typQ34(VOLUME_PTI,SIG11,grand_courant);
|
||
|
ret.push_back(typQ34);
|
||
|
// $$$ cas éventuel d'intégrale de volume: INTEG_SUR_VOLUME
|
||
|
if (integ_vol_typeQuel != NULL)
|
||
|
{int nb_integration = integ_vol_typeQuel->Taille();
|
||
|
// on va créer un conteneur particulier pour chaque intégrale
|
||
|
Tableau <TypeQuelconque> & tab_integ = *integ_vol_typeQuel; //_t; // pour simplifier
|
||
|
for (int i=1; i<= nb_integration;i++)
|
||
|
{ TypeQuelconque& tbinteg = tab_integ(i); // pour simplifier
|
||
|
EnuTypeQuelParticulier type_interne =
|
||
|
tbinteg.Const_Grandeur_pointee()->Type_enumGrandeurParticuliere();
|
||
|
const TypeQuelconque_enum_etendu& enuTQetendu = tbinteg.EnuTypeQuelconque();
|
||
|
|
||
|
{switch (type_interne)
|
||
|
{case PARTICULIER_DDL_ETENDU:
|
||
|
{ Grandeur_Ddl_etendu& gin
|
||
|
= *((Grandeur_Ddl_etendu*) tbinteg.Grandeur_pointee()); // pour simplifier
|
||
|
// // on va créer (éventuellement s'il n'existe pas déjà) un nouveau :
|
||
|
// // -- on crée le nom de référence
|
||
|
// string nom(enuTQetendu.NomPlein()+"_"+(*(gin.Nom_ref()))+"_"
|
||
|
// +ChangeEntierSTring((*index_Integ_vol_typeQuel)(i)));
|
||
|
// TypeQuelconque_enum_etendu tqnevez =
|
||
|
// TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
// (INTEG_SUR_VOLUME,nom,tbinteg.EnuTypeGrandeur());
|
||
|
// // on enregistre pour la gestion future
|
||
|
// (*enu_integ_vol_TQ)(i)=tqnevez;
|
||
|
// on crée un exemplaire de conteneur pointé
|
||
|
Grandeur_Ddl_etendu inter(gin);
|
||
|
// création du type conteneur
|
||
|
TypeQuelconque typQ91((*enu_integ_vol_TQ)(i),tbinteg.Enum(),inter);
|
||
|
ret.push_back(typQ91);
|
||
|
break;
|
||
|
};
|
||
|
case PARTICULIER_VECTEUR_NOMMER:
|
||
|
{ Grandeur_Vecteur_Nommer& gin
|
||
|
= *((Grandeur_Vecteur_Nommer*) tbinteg.Grandeur_pointee()); // pour simplifier
|
||
|
// // on va créer (éventuellement s'il n'existe pas déjà) un nouveau :
|
||
|
// // -- on crée le nom de référence
|
||
|
// string nom(enuTQetendu.NomPlein()+"_"+(*(gin.Nom_ref()))+"_"
|
||
|
// +ChangeEntierSTring((*index_Integ_vol_typeQuel)(i)));
|
||
|
// TypeQuelconque_enum_etendu tqnevez =
|
||
|
// TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
// (INTEG_SUR_VOLUME,nom,tbinteg.EnuTypeGrandeur());
|
||
|
// // on enregistre pour la gestion future
|
||
|
// (*enu_integ_vol_TQ)(i)=tqnevez;
|
||
|
//// //----- debug
|
||
|
//// cout << "\n ElemMeca::Les_types_particuliers_internes( "
|
||
|
//// << "\n (*enu_integ_vol_TQ)("<<i<<")=" <<(*enu_integ_vol_TQ)(i);
|
||
|
//// //----- fin debug
|
||
|
// on crée un exemplaire de conteneur pointé
|
||
|
Grandeur_Vecteur_Nommer inter(gin);
|
||
|
// création du type conteneur
|
||
|
TypeQuelconque typQ91((*enu_integ_vol_TQ)(i),tbinteg.Enum(),inter);
|
||
|
ret.push_back(typQ91);
|
||
|
break;
|
||
|
}
|
||
|
default: // pas d'intégrale ad hoc dispo ici pour la demande
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// $$$ cas éventuel d'intégrale de volume et en temps: INTEG_SUR_VOLUME_ET_TEMPS
|
||
|
if (integ_vol_t_typeQuel != NULL)
|
||
|
{int nb_integration = integ_vol_t_typeQuel->Taille();
|
||
|
// on va créer un conteneur particulier pour chaque intégrale
|
||
|
Tableau <TypeQuelconque> & tab_integ = *integ_vol_t_typeQuel; //_t; // pour simplifier
|
||
|
for (int i=1; i<= nb_integration;i++)
|
||
|
{TypeQuelconque& tbinteg = tab_integ(i); // pour simplifier
|
||
|
EnuTypeQuelParticulier type_interne =
|
||
|
tbinteg.Const_Grandeur_pointee()->Type_enumGrandeurParticuliere();
|
||
|
const TypeQuelconque_enum_etendu& enuTQetendu = tbinteg.EnuTypeQuelconque();
|
||
|
|
||
|
{switch (type_interne)
|
||
|
{case PARTICULIER_DDL_ETENDU:
|
||
|
{ Grandeur_Ddl_etendu& gin
|
||
|
= *((Grandeur_Ddl_etendu*) tbinteg.Grandeur_pointee()); // pour simplifier
|
||
|
// // on va créer (éventuellement s'il n'existe pas déjà) un nouveau :
|
||
|
// // -- on crée le nom de référence
|
||
|
// string nom(enuTQetendu.NomPlein()+"_"+(*(gin.Nom_ref()))+"_"
|
||
|
// +ChangeEntierSTring((*index_Integ_vol_typeQuel)(i)));
|
||
|
// TypeQuelconque_enum_etendu tqnevez =
|
||
|
// TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
// (INTEG_SUR_VOLUME,nom,tbinteg.EnuTypeGrandeur());
|
||
|
// // on enregistre pour la gestion future
|
||
|
// (*enu_integ_vol_t_TQ)(i)=tqnevez;
|
||
|
// on crée un exemplaire de conteneur pointé
|
||
|
Grandeur_Ddl_etendu inter(gin);
|
||
|
// création du type conteneur
|
||
|
TypeQuelconque typQ91((*enu_integ_vol_t_TQ)(i),tbinteg.Enum(),inter);
|
||
|
ret.push_back(typQ91);
|
||
|
break;
|
||
|
};
|
||
|
case PARTICULIER_VECTEUR_NOMMER:
|
||
|
{ Grandeur_Vecteur_Nommer& gin
|
||
|
= *((Grandeur_Vecteur_Nommer*) tbinteg.Grandeur_pointee()); // pour simplifier
|
||
|
// // on va créer (éventuellement s'il n'existe pas déjà) un nouveau :
|
||
|
// // -- on crée le nom de référence
|
||
|
// string nom(enuTQetendu.NomPlein()+"_"+(*(gin.Nom_ref()))+"_"
|
||
|
// +ChangeEntierSTring((*index_Integ_vol_typeQuel)(i)));
|
||
|
// TypeQuelconque_enum_etendu tqnevez =
|
||
|
// TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
// (INTEG_SUR_VOLUME,nom,tbinteg.EnuTypeGrandeur());
|
||
|
// // on enregistre pour la gestion future
|
||
|
// (*enu_integ_vol_t_TQ)(i)=tqnevez;
|
||
|
// on crée un exemplaire de conteneur pointé
|
||
|
Grandeur_Vecteur_Nommer inter(gin);
|
||
|
// création du type conteneur
|
||
|
TypeQuelconque typQ91((*enu_integ_vol_t_TQ)(i),tbinteg.Enum(),inter);
|
||
|
ret.push_back(typQ91);
|
||
|
break;
|
||
|
}
|
||
|
default: // pas d'intégrale ad hoc dispo ici pour la demande
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// $$$ cas de l'énergie d'hourglasse :
|
||
|
TypeQuelconque typQ31(ENERGIE_HOURGLASS,SIG11,grand_courant);
|
||
|
ret.push_back(typQ31);
|
||
|
// $$$ cas de la puissance bulk :
|
||
|
TypeQuelconque typQ32(PUISSANCE_BULK,SIG11,grand_courant);
|
||
|
ret.push_back(typQ32);
|
||
|
// $$$ cas de l'énergie bulk :
|
||
|
TypeQuelconque typQ33(ENERGIE_BULK,SIG11,grand_courant);
|
||
|
ret.push_back(typQ33);
|
||
|
// $$$ cas de l'énergie de stabilisation membrane ou biel :
|
||
|
TypeQuelconque typQ330(ENERGIE_STABMEMB_BIEL,SIG11,grand_courant);
|
||
|
ret.push_back(typQ330);
|
||
|
// $$$ cas de la force de stabilisation membrane ou biel :
|
||
|
TypeQuelconque typQ331(FORCE_STABMEMB_BIEL,SIG11,grand_courant);
|
||
|
ret.push_back(typQ331);
|
||
|
// $$$ cas du temps cpu relativement à la loi de comp :
|
||
|
TypeQuelconque typQ35(TEMPS_CPU_LOI_COMP,SIG11,grand_courant);
|
||
|
ret.push_back(typQ35);
|
||
|
// $$$ cas du temps cpu relativement à la métrique :
|
||
|
TypeQuelconque typQ36(TEMPS_CPU_METRIQUE,SIG11,grand_courant);
|
||
|
ret.push_back(typQ36);
|
||
|
|
||
|
// $$$ cas des numéros
|
||
|
Grandeur_scalaire_entier entier_courant;
|
||
|
TypeQuelconque typQ37(NUM_ELEMENT,SIG11,entier_courant);
|
||
|
ret.push_back(typQ37);
|
||
|
TypeQuelconque typQ38(NUM_MAIL_ELEM,SIG11,entier_courant);
|
||
|
ret.push_back(typQ38);
|
||
|
TypeQuelconque typQ39(NUM_PTI,SIG11,entier_courant);
|
||
|
ret.push_back(typQ39);
|
||
|
|
||
|
// f) cas des infos calculable à la demande sur l'élément
|
||
|
// $$$ cas des volumes entre les plans et l'élément dans le cas ou l'élément des de surface
|
||
|
// et que le calcul est 3D :
|
||
|
if ((ParaGlob::Dimension()==3)&&(Type_geom_generique(id_geom)==SURFACE))
|
||
|
{Grandeur_coordonnee grandCoordonnee(3); // un type courant
|
||
|
TypeQuelconque typQ4(VOL_ELEM_AVEC_PLAN_REF,SIG11,grandCoordonnee);
|
||
|
ret.push_back(typQ4);
|
||
|
};
|
||
|
|
||
|
// liberation des tenseurs intermediaires
|
||
|
LibereTenseur();
|
||
|
return ret;
|
||
|
};
|
||
|
|
||
|
// retourne la liste des grandeurs évoluées interne actuellement utilisés
|
||
|
// par l'élément, c'est-à-dire directement sous forme de vecteur, tenseurs ....
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
List_io <TypeQuelconque> ElemMeca::Les_type_evolues_internes(bool absolue) const
|
||
|
{ List_io <TypeQuelconque> liTQ;
|
||
|
|
||
|
|
||
|
// // def de la dimension des tenseurs
|
||
|
// // il y a deux pb a gérer: 1) le fait que la dimension absolue peut-être différente de la dimension des tenseurs
|
||
|
// // 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
|
||
|
// int dim = lesPtIntegMecaInterne->DimTens();int dim_sortie_tenseur = dim;
|
||
|
// // dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
|
||
|
// int dim_espace = ParaGlob::Dimension();
|
||
|
// if (absolue)
|
||
|
// dim_sortie_tenseur = dim_espace;
|
||
|
// // pour ne faire qu'un seul test ensuite
|
||
|
// bool prevoir_change_dim_tenseur = false;
|
||
|
// if ((absolue) && (dim != dim_sortie_tenseur))
|
||
|
// prevoir_change_dim_tenseur = true;
|
||
|
|
||
|
|
||
|
// def des grandeurs courantes de type tenseur BB
|
||
|
int dim_espace = ParaGlob::Dimension();
|
||
|
int dim_tenseur_sortie = this->Dim_sig_eps(); // la dimension a priori
|
||
|
if (absolue)
|
||
|
dim_tenseur_sortie = dim_espace; // si on sort en absolue, on utilise la dim globale
|
||
|
|
||
|
{TenseurBB* tens = NevezTenseurBB(dim_tenseur_sortie); // un tenseur typique
|
||
|
// maintenant on définit une grandeur typique de type tenseurBB
|
||
|
Grandeur_TenseurBB gtBB(*tens);
|
||
|
// def d'un type quelconque représentatif pour chaque grandeur
|
||
|
{TypeQuelconque typQ(DEFORMATION_COURANTE,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VITESSE_DEFORMATION_COURANTE,DEPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(ALMANSI,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(GREEN_LAGRANGE,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(LOGARITHMIQUE,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(DELTA_DEF,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
if (dilatation)
|
||
|
{{TypeQuelconque typQ(ALMANSI_TOTAL,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(GREEN_LAGRANGE_TOTAL,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(LOGARITHMIQUE_TOTALE,EPS11,gtBB);liTQ.push_back(typQ);};
|
||
|
};
|
||
|
delete tens; // car on n'en a plus besoin
|
||
|
};
|
||
|
// def des grandeurs courantes de type tenseur HH
|
||
|
{TenseurHH* tens = NevezTenseurHH(dim_tenseur_sortie); // un tenseur typique
|
||
|
// maintenant on définit une grandeur typique de type tenseurHH
|
||
|
Grandeur_TenseurHH gtHH(*tens);
|
||
|
// def d'un type quelconque représentatif pour chaque grandeur
|
||
|
TypeQuelconque typQ(CONTRAINTE_COURANTE,SIG11,gtHH);liTQ.push_back(typQ);
|
||
|
delete tens; // car on n'en a plus besoin
|
||
|
};
|
||
|
// def des grandeurs courantes de type coordonnee
|
||
|
{Coordonnee coor(dim_tenseur_sortie); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// def d'un type quelconque représentatif pour chaque grandeur
|
||
|
{TypeQuelconque typQ(DEF_PRINCIPALES,EPS11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(SIGMA_PRINCIPALES,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VIT_PRINCIPALES,DEPS11,gt);liTQ.push_back(typQ);};
|
||
|
// pour la position il s'agit de la position du point d'intégration
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
}
|
||
|
|
||
|
{Coordonnee coor(dim_espace); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// *** 21 avril 2020: on change la position d'expression: du noeuds au pti
|
||
|
// donc on passe de X1 à SIG11 , mais il s'agit d'un pti spécifique de surface ou de ligne ...
|
||
|
// le chargement de type pression, sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_PRESSION,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force volumique sous forme d'un vecteur charge, exprimée aux pti volume
|
||
|
{TypeQuelconque typQ(VECT_FORCE_VOLUM,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force de direction fixe sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_DIR_FIXE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force suiveuse sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_SURF_SUIV,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force hydrodynamique sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_Fn,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_Ft,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_T,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force linéique sous forme d'un vecteur charge, exprimée aux pti ligne
|
||
|
{TypeQuelconque typQ(VECT_LINE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force linéique suiveuse sous forme d'un vecteur charge, exprimée aux pti ligne
|
||
|
{TypeQuelconque typQ(VECT_LINE_SUIV,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// *** fin modif avril 2020
|
||
|
// // les réaction sous forme d'un vecteur charge, exprimée aux noeuds
|
||
|
// {TypeQuelconque typQ(VECT_REAC,X1,gt);liTQ.push_back(typQ);};
|
||
|
};
|
||
|
// def des grandeurs courantes de type scalaires
|
||
|
{// on définit une grandeur typique de type Grandeur_scalaire_double
|
||
|
Grandeur_scalaire_double scd(0.);
|
||
|
// def d'un type quelconque représentatif pour chaque grandeur
|
||
|
{TypeQuelconque typQ(CONTRAINTE_MISES,SIG11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(CONTRAINTE_TRESCA,SIG11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(DEF_DUALE_MISES,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(DEF_DUALE_MISES_MAXI,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(DEF_EQUIVALENTE,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
// cas de l'existence de l'erreur
|
||
|
// if (sigErreur != NULL)
|
||
|
{TypeQuelconque typQ(ERREUR_Q,ERREUR,scd);liTQ.push_back(typQ);}
|
||
|
// if (sigErreur_relative != NULL)
|
||
|
{TypeQuelconque typQ(ERREUR_SIG_RELATIVE,ERREUR,scd);liTQ.push_back(typQ);}
|
||
|
|
||
|
// cas de la plasticité classique
|
||
|
string nom_comport(loiComp->Nom_comport());
|
||
|
if ((strstr(nom_comport.c_str(),"PRANDTL_REUSS")!=NULL))
|
||
|
{TypeQuelconque typQ(DEF_PLASTIQUE_CUMULEE,EPS11,scd);liTQ.push_back(typQ);}
|
||
|
// les infos sur la décomposition spherique,polaire des contraintes et déformations
|
||
|
// seulement en 3D
|
||
|
if (ParaGlob::Dimension() == 3)
|
||
|
{{TypeQuelconque typQ(SPHERIQUE_EPS,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(Q_EPS,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(COS3PHI_EPS,EPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(SPHERIQUE_SIG,SIG11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(Q_SIG,SIG11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(COS3PHI_SIG,SIG11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(SPHERIQUE_DEPS,DEPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(Q_DEPS,DEPS11,scd);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(COS3PHI_DEPS,DEPS11,scd);liTQ.push_back(typQ);};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// $$$ cas du repère local ad hoc orthonormé d'expression des tenseurs
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(REPERE_LOCAL_ORTHO,EPS11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
|
||
|
// $$$ cas du repère local dual exprimé dans le repère global
|
||
|
// par défaut, on réserve dim_espace vecteurs, éventuellement certains peuvent être nuls
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(REPERE_LOCAL_H,EPS11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
// $$$ cas du repère local naturel exprimé dans le repère global
|
||
|
// par défaut, on réserve dim_espace vecteurs, éventuellement certains peuvent être nuls
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(REPERE_LOCAL_B,EPS11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
|
||
|
// $$$ cas du repère principal orthonormé du tenseur des contraintes
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(DIRECTIONS_PRINC_SIGMA,SIG11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
|
||
|
// $$$ cas du repère principal orthonormé du tenseur des déformations
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(DIRECTIONS_PRINC_DEF,EPS11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
|
||
|
// $$$ cas du repère principal orthonormé du tenseur des vitesses de déformation
|
||
|
{Coordonnee v_rep(dim_espace);
|
||
|
Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
TypeQuelconque typQ6(DIRECTIONS_PRINC_D,DEPS11,grand5);
|
||
|
liTQ.push_back(typQ6);
|
||
|
};
|
||
|
// dans le cas d'un élément 2D, dans un espace 3D, on peut récupérer la normale
|
||
|
if ((Type_geom_generique(this->Id_geometrie()) == SURFACE )
|
||
|
&& (ParaGlob::Dimension() == 3))
|
||
|
{Grandeur_coordonnee grandCoordonnee(3); // un type courant
|
||
|
TypeQuelconque typQ4(NN_SURF,EPS11,grandCoordonnee);
|
||
|
liTQ.push_back(typQ4);
|
||
|
};
|
||
|
|
||
|
// retour
|
||
|
return liTQ;
|
||
|
};
|
||
|
|
||
|
// retourne la liste de toutes les grandeurs quelconques relatives aux faces de
|
||
|
// l'élément (actif ou non),
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
List_io <TypeQuelconque> ElemMeca::Les_type_quelconque_de_face(bool absolue) const
|
||
|
{ List_io <TypeQuelconque> liTQ;
|
||
|
|
||
|
|
||
|
// // def de la dimension des tenseurs
|
||
|
// // il y a deux pb a gérer: 1) le fait que la dimension absolue peut-être différente de la dimension des tenseurs
|
||
|
// // 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
|
||
|
// int dim = lesPtIntegMecaInterne->DimTens();int dim_sortie_tenseur = dim;
|
||
|
// // dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
|
||
|
// int dim_espace = ParaGlob::Dimension();
|
||
|
// if (absolue)
|
||
|
// dim_sortie_tenseur = dim_espace;
|
||
|
// // pour ne faire qu'un seul test ensuite
|
||
|
// bool prevoir_change_dim_tenseur = false;
|
||
|
// if ((absolue) && (dim != dim_sortie_tenseur))
|
||
|
// prevoir_change_dim_tenseur = true;
|
||
|
|
||
|
|
||
|
// def des grandeurs courantes de type tenseur BB
|
||
|
int dim_espace = ParaGlob::Dimension();
|
||
|
int dim_tenseur_sortie = this->Dim_sig_eps(); // la dimension a priori
|
||
|
if (absolue)
|
||
|
dim_tenseur_sortie = dim_espace; // si on sort en absolue, on utilise la dim globale
|
||
|
|
||
|
// def des grandeurs courantes de type coordonnee
|
||
|
{Coordonnee coor(dim_tenseur_sortie); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// pour la position il s'agit de la position du point d'intégration
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE_t,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE_t0,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
}
|
||
|
|
||
|
{Coordonnee coor(dim_espace); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// le chargement de type pression, sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_PRESSION,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force de direction fixe sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_DIR_FIXE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force suiveuse sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_SURF_SUIV,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force hydrodynamique sous forme d'un vecteur charge, exprimée aux pti surface
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_Fn,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_Ft,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(VECT_HYDRODYNA_T,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// // les réaction sous forme d'un vecteur charge, exprimée aux noeuds
|
||
|
// {TypeQuelconque typQ(VECT_REAC,X1,gt);liTQ.push_back(typQ);};
|
||
|
};
|
||
|
// def des grandeurs courantes de type scalaires
|
||
|
{// def d'un type quelconque représentatif pour chaque grandeur
|
||
|
|
||
|
// // $$$ cas du repère local ad hoc orthonormé d'expression des tenseurs
|
||
|
// {Coordonnee v_rep(dim_espace);
|
||
|
// Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
// TypeQuelconque typQ6(REPERE_LOCAL_ORTHO,EPS11,grand5);
|
||
|
// liTQ.push_back(typQ6);
|
||
|
// };
|
||
|
//
|
||
|
// // $$$ cas du repère local dual exprimé dans le repère global
|
||
|
// // par défaut, on réserve dim_espace vecteurs, éventuellement certains peuvent être nuls
|
||
|
// {Coordonnee v_rep(dim_espace);
|
||
|
// Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
// TypeQuelconque typQ6(REPERE_LOCAL_H,EPS11,grand5);
|
||
|
// liTQ.push_back(typQ6);
|
||
|
// };
|
||
|
// // $$$ cas du repère local naturel exprimé dans le repère global
|
||
|
// // par défaut, on réserve dim_espace vecteurs, éventuellement certains peuvent être nuls
|
||
|
// {Coordonnee v_rep(dim_espace);
|
||
|
// Tab_Grandeur_Coordonnee grand5(v_rep,dim_espace); // def d'une grandeur courante coordonnée
|
||
|
// TypeQuelconque typQ6(REPERE_LOCAL_B,EPS11,grand5);
|
||
|
// liTQ.push_back(typQ6);
|
||
|
// };
|
||
|
|
||
|
{Grandeur_coordonnee grandCoordonnee(3); // un type courant
|
||
|
TypeQuelconque typQ4(NN_SURF,EPS11,grandCoordonnee);
|
||
|
liTQ.push_back(typQ4);
|
||
|
};
|
||
|
{Grandeur_coordonnee grandCoordonnee(3); // un type courant
|
||
|
TypeQuelconque typQ4(NN_SURF_t,EPS11,grandCoordonnee);
|
||
|
liTQ.push_back(typQ4);
|
||
|
};
|
||
|
{Grandeur_coordonnee grandCoordonnee(3); // un type courant
|
||
|
TypeQuelconque typQ4(NN_SURF_t0,EPS11,grandCoordonnee);
|
||
|
liTQ.push_back(typQ4);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// $$$ cas des numéros
|
||
|
Grandeur_scalaire_entier entier_courant;
|
||
|
TypeQuelconque typQ37(NUM_ELEMENT,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ37);
|
||
|
TypeQuelconque typQ38(NUM_MAIL_ELEM,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ38);
|
||
|
TypeQuelconque typQ39(NUM_FACE,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ39);
|
||
|
TypeQuelconque typQ40(NUM_PTI,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ40);
|
||
|
|
||
|
Grandeur_scalaire_double double_courant;
|
||
|
TypeQuelconque typQ41(PRESSION_SCALAIRE,SIG11,double_courant);
|
||
|
liTQ.push_back(typQ41);
|
||
|
|
||
|
// retour
|
||
|
return liTQ;
|
||
|
};
|
||
|
|
||
|
// retourne la liste de toutes les grandeurs quelconques relatives aux arêtes de
|
||
|
// l'élément (actif ou non),
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
List_io <TypeQuelconque> ElemMeca::Les_type_quelconque_de_arete(bool absolue) const
|
||
|
{ List_io <TypeQuelconque> liTQ;
|
||
|
|
||
|
|
||
|
// // def de la dimension des tenseurs
|
||
|
// // il y a deux pb a gérer: 1) le fait que la dimension absolue peut-être différente de la dimension des tenseurs
|
||
|
// // 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
|
||
|
// int dim = lesPtIntegMecaInterne->DimTens();int dim_sortie_tenseur = dim;
|
||
|
// // dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
|
||
|
// int dim_espace = ParaGlob::Dimension();
|
||
|
// if (absolue)
|
||
|
// dim_sortie_tenseur = dim_espace;
|
||
|
// // pour ne faire qu'un seul test ensuite
|
||
|
// bool prevoir_change_dim_tenseur = false;
|
||
|
// if ((absolue) && (dim != dim_sortie_tenseur))
|
||
|
// prevoir_change_dim_tenseur = true;
|
||
|
|
||
|
|
||
|
// def des grandeurs courantes de type tenseur BB
|
||
|
int dim_espace = ParaGlob::Dimension();
|
||
|
int dim_tenseur_sortie = this->Dim_sig_eps(); // la dimension a priori
|
||
|
if (absolue)
|
||
|
dim_tenseur_sortie = dim_espace; // si on sort en absolue, on utilise la dim globale
|
||
|
|
||
|
// def des grandeurs courantes de type coordonnee
|
||
|
{Coordonnee coor(dim_tenseur_sortie); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// pour la position il s'agit de la position du point d'intégration
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE_t,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
{TypeQuelconque typQ(POSITION_GEOMETRIQUE_t0,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
}
|
||
|
|
||
|
{Coordonnee coor(dim_espace); // un type coordonnee typique
|
||
|
// maintenant on définit une grandeur typique de type Grandeur_coordonnee
|
||
|
Grandeur_coordonnee gt(coor);
|
||
|
// le chargement de type force linéique sous forme d'un vecteur charge, exprimée aux pti ligne
|
||
|
{TypeQuelconque typQ(VECT_LINE,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
// le chargement de type force linéique suiveuse sous forme d'un vecteur charge, exprimée aux pti ligne
|
||
|
{TypeQuelconque typQ(VECT_LINE_SUIV,SIG11,gt);liTQ.push_back(typQ);};
|
||
|
};
|
||
|
|
||
|
|
||
|
// $$$ cas des numéros
|
||
|
Grandeur_scalaire_entier entier_courant;
|
||
|
TypeQuelconque typQ37(NUM_ELEMENT,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ37);
|
||
|
TypeQuelconque typQ38(NUM_MAIL_ELEM,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ38);
|
||
|
TypeQuelconque typQ39(NUM_ARETE,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ39);
|
||
|
TypeQuelconque typQ40(NUM_PTI,SIG11,entier_courant);
|
||
|
liTQ.push_back(typQ40);
|
||
|
|
||
|
// retour
|
||
|
return liTQ;
|
||
|
};
|
||
|
|
||
|
|
||
|
// récupération de grandeurs particulières au numéro d'ordre = iteg
|
||
|
// celles-ci peuvent être quelconques
|
||
|
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
void ElemMeca::Grandeur_particuliere(bool absolue,List_io<TypeQuelconque>& liTQ,int iteg)
|
||
|
{ // on s'intéresse au information stockée au niveau des points d'intégration
|
||
|
// pour tenir compte du fait qu'il peut y avoir plusieurs fois la même information, ces dernières sont systématiquement
|
||
|
// stockées dans des tableaux, et on associe à ce tableau un indice qui indique aux méthodes appelées, à quel endroit
|
||
|
// elles doivent écrire les infos. les indices sont stockés dans une liste de même dim que liTQ
|
||
|
list <int> decal(liTQ.size(),0.); // on initi tous les membres à 0
|
||
|
|
||
|
// 0° on initialise les grandeurs à 0 pour éviter d'avoir des valeurs aléatoires
|
||
|
// -- on commence par initialiser les conteneurs car certaines données peuvent ne pas exister
|
||
|
List_io<TypeQuelconque>::iterator iquefin=liTQ.end();
|
||
|
List_io<TypeQuelconque>::iterator ique,ique_deb=liTQ.begin();
|
||
|
for (ique=ique_deb;ique!=iquefin;ique++) (*ique).Grandeur_pointee()->InitParDefaut();
|
||
|
|
||
|
// 1° on change le numéro de point d'intégration courant
|
||
|
def->ChangeNumInteg(iteg);
|
||
|
// 2° on commence par récupérer les grandeurs
|
||
|
// a) cas des grandeurs liées à la déformation
|
||
|
// met à jour les données spécifiques du point considéré
|
||
|
def->Mise_a_jour_data_specif(tabSaveDefDon(iteg));
|
||
|
def->Grandeur_particuliere(absolue,liTQ);
|
||
|
// b) cas des grandeurs liées à la loi de comportement méca
|
||
|
// on commence par indiquer quel saveresult de pti a utiliser
|
||
|
loiComp->IndiquePtIntegMecaInterne(&((*lesPtIntegMecaInterne)(iteg)));
|
||
|
// puis on récupère les grandeurs
|
||
|
loiComp->Grandeur_particuliere(absolue,liTQ,tabSaveDon(iteg),decal);
|
||
|
// pour le débug ----
|
||
|
//cout << "\n debug ElemMeca::Grandeur_particuliere " << liTQ << endl; // débug
|
||
|
// fin pour le débug ----
|
||
|
// c) cas des grandeurs liées à la loi de comportement thermo-physique
|
||
|
if (loiTP != NULL) loiTP->Grandeur_particuliere(absolue,liTQ,tabSaveTP(iteg),decal);
|
||
|
|
||
|
// 3° on change éventuellement de repère (local en global) si nécessaire
|
||
|
// a) définition des grandeurs qui sont indépendante de la boucle qui suit
|
||
|
// dimension des vecteurs de base de la métrique
|
||
|
int dim = met->Dim_vec_base();
|
||
|
// calcul des matrices de passages
|
||
|
Mat_pleine* gamma0=NULL; Mat_pleine* gammat=NULL; Mat_pleine* gammatdt=NULL;
|
||
|
Mat_pleine* beta0=NULL; Mat_pleine* betat=NULL; Mat_pleine* betatdt=NULL;
|
||
|
|
||
|
// const Met_abstraite::Info0_t_tdt& ex = def->Remont0_t_tdt(gamma0,gammat,gammatdt);
|
||
|
// Mat_pleine beta0(gamma0.Inverse().Transpose());
|
||
|
// Mat_pleine betat(gammat.Inverse().Transpose());
|
||
|
// Mat_pleine betatdt(gammatdt.Inverse().Transpose());
|
||
|
List_io<TypeQuelconque>::iterator il,ilfin = liTQ.end();
|
||
|
for (il=liTQ.begin();il!=ilfin;il++)
|
||
|
{ TypeQuelconque& tipParticu = (*il); // pour simplifier
|
||
|
// n'intervient que si la grandeur est active:
|
||
|
if ((*il).Activite())
|
||
|
{ // on regarde si c'est une grandeur locale ou pas
|
||
|
if (tipParticu.TypeExpressionGrandeur()==0)
|
||
|
// cas d'une grandeur exprimée dans le repère locale, changement de repère
|
||
|
{ // calcul des matrices de passages, au premier passage
|
||
|
if (gamma0 == NULL)
|
||
|
{ Mat_pleine Aa0(dim,dim),Aat(dim,dim),Aatdt(dim,dim);
|
||
|
const Met_abstraite::Info0_t_tdt& ex = def->Remont0_t_tdt(absolue,Aa0,Aat,Aatdt);
|
||
|
// a) ----- dans le sens: gi -> Ia
|
||
|
// on a: g^i = A^i_{.a} * I^a ou Ip^a suivant que absolue est true ou false
|
||
|
// si false, cela veut dire que Ip^a est un repère ad hoc
|
||
|
// sinon cela veut dire que c'est le repère absolu donc I_a = I^a
|
||
|
// et g_j = B_j^{.a} * I_a d'où [B_j^{.a}] = [A^i_{.a}]^{-1T}
|
||
|
//
|
||
|
// b) ----- dans le sens: Ia -> gi
|
||
|
// pour les formules de passage de repère il nous faut :
|
||
|
// Ip_a = beta_a^{.j} g_j et Ip^b = gamma^b_{.j} g^j
|
||
|
// on a alors : [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// et [gamma^b_{.j}] = [beta_a^{.j}]^{-1T} = [Aa^j_{.a}]^{-1}
|
||
|
//
|
||
|
// au final: [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// [gamma^b_{.j}] = [Aa^j_{.a}]^{-1}
|
||
|
// [B_j^{.a}] = [gamma^b_{.j}]^T
|
||
|
|
||
|
gamma0 = new Mat_pleine(Aa0.Inverse());
|
||
|
gammat = new Mat_pleine(Aat.Inverse());
|
||
|
gammatdt = new Mat_pleine(Aatdt.Inverse());
|
||
|
// on détermine également les matrices beta
|
||
|
beta0 = new Mat_pleine(Aa0.Transpose());
|
||
|
betat = new Mat_pleine(Aat.Transpose());
|
||
|
betatdt = new Mat_pleine(Aatdt.Transpose());
|
||
|
//---------- debug
|
||
|
/*
|
||
|
{
|
||
|
cout << "\n debug en 3D ElemMeca::Grandeur_particuliere( ";
|
||
|
cout << "\n -- affichage de la sauvegarde du pti "<<iteg<<" de la loi de comp ---";
|
||
|
tabSaveDon(iteg)->Affiche();
|
||
|
cout << "\n Aatdt: "; Aatdt.Affiche();
|
||
|
cout << "\n betatdt: "; betatdt->Affiche();
|
||
|
cout << "\n gammatdt: "; gammatdt->Affiche();
|
||
|
|
||
|
Tableau <Vecteur > gB_itdt(3),gH_itdt(3);
|
||
|
|
||
|
for (int a=1; a<3;a++)
|
||
|
{ cout << "\n giB_tdt("<<a<<"): "; (*ex.giB_tdt)(a).Affiche();
|
||
|
cout << "\n giH_tdt("<<a<<"): "; (*ex.giH_tdt)(a).Affiche();
|
||
|
gH_itdt(a) = (*ex.giH_tdt)(a).Vect(); // il manque le 3ième
|
||
|
gB_itdt(a) = (*ex.giB_tdt)(a).Vect(); // il manque le 3ième
|
||
|
};
|
||
|
// calcul des g^i à l'aide des A^i_{.a}
|
||
|
for (int a=1; a<4;a++)
|
||
|
{ cout << "\n giH_tdt("<<a<<"): via A^i_{.a} " << Aatdt.Ligne (a);
|
||
|
if (a == 3 )
|
||
|
{gH_itdt(a) = gB_itdt(a) = Aatdt.Ligne(a);}
|
||
|
};
|
||
|
// vérif des relations entre beta et gamma
|
||
|
Mat_pleine AA(*betatdt);
|
||
|
cout << "\n beta * gamma "; ((*gammatdt)* AA).Affiche();
|
||
|
Mat_pleine BB(betatdt->Transpose());
|
||
|
cout << "\n beta^T * gamma "; ((*gammatdt)* BB).Affiche();
|
||
|
|
||
|
// calcul des Ip_a à l'aide de betatdt
|
||
|
for (int a=1; a<4;a++)
|
||
|
{ Vecteur V(3);
|
||
|
for (int j=1;j<4;j++)
|
||
|
V += (*betatdt)(a,j) * gB_itdt(j);
|
||
|
// V += BB(a,j) * gB_itdt(j);
|
||
|
cout << "\n Ip("<<a<<"): via betatdt " << V;
|
||
|
};
|
||
|
// idem calcul des Ip_a à l'aide de gamma
|
||
|
for (int a=1; a<4;a++)
|
||
|
{ Vecteur V(3);
|
||
|
for (int j=1;j<4;j++)
|
||
|
V += (*gammatdt)(a,j) * gH_itdt(j);
|
||
|
cout << "\n Ip("<<a<<"): via gammatdt " << V;
|
||
|
};
|
||
|
|
||
|
};
|
||
|
*/
|
||
|
//----------- fin debug
|
||
|
};
|
||
|
tipParticu.Change_repere(*beta0,*betat,*betatdt,*gamma0,*gammat,*gammatdt);
|
||
|
};
|
||
|
// on utilise la boucle également pour mettre à jour les grandeurs particulières liés à l'élément
|
||
|
|
||
|
// 1) -----cas du module de compressibilité ou de cisaillement totale
|
||
|
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
|
||
|
{case MODULE_COMPRESSIBILITE_TOTAL:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=(*lesPtIntegMecaInterne)(iteg).ModuleCompressibilite();break;}
|
||
|
case MODULE_CISAILLEMENT_TOTAL:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=(*lesPtIntegMecaInterne)(iteg).ModuleCisaillement();break;}
|
||
|
// e) cas des infos stockés à l'élément
|
||
|
case VOLUME_ELEMENT:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=volume;break;}
|
||
|
case VOLUME_PTI:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())
|
||
|
=(*lesPtIntegMecaInterne)(iteg).Volume_pti_const();break;
|
||
|
}
|
||
|
|
||
|
|
||
|
// $$$ cas éventuel d'intégrales de volume: INTEG_SUR_VOLUME
|
||
|
case INTEG_SUR_VOLUME:
|
||
|
// on utilise la valeur actuelle plutôt que la valeur à t, sinon on est en retard d'un incrément
|
||
|
// et par exemple en relaxation dynamique sur un incrément, on ne voit rien car, tant que l'incrément
|
||
|
// n'est pas fini, la valeur à t n'est pas abondée
|
||
|
{if (integ_vol_typeQuel != NULL) // cas où localement il y a une intégrale de définie
|
||
|
{int nb_integration = integ_vol_typeQuel->Taille();//_t->Taille();
|
||
|
Tableau <TypeQuelconque> & tab_integ = *integ_vol_typeQuel; //_t; // pour simplifier
|
||
|
const TypeQuelconque_enum_etendu& type_externe = tipParticu.EnuTypeQuelconque();
|
||
|
// maintenant il faut trouver la locale qui correspond: le plus simple
|
||
|
// mais pas le plus rapide !! est d'itérer
|
||
|
for (int i=1; i<= nb_integration;i++)
|
||
|
{EnuTypeQuelParticulier enuTQP = tipParticu.Grandeur_pointee()->Type_enumGrandeurParticuliere();
|
||
|
|
||
|
// //----- debug
|
||
|
// cout << "\n ElemMeca::Grandeur_particuliere( ";
|
||
|
// cout << "\n type_externe " << type_externe
|
||
|
// << "\n (*enu_integ_vol_TQ)("<<i<<")=" <<(*enu_integ_vol_TQ)(i);
|
||
|
// //----- fin debug
|
||
|
|
||
|
|
||
|
if (type_externe == (*enu_integ_vol_TQ)(i))
|
||
|
{switch (enuTQP)
|
||
|
{case PARTICULIER_DDL_ETENDU:
|
||
|
{ Grandeur_Ddl_etendu& gex
|
||
|
= *((Grandeur_Ddl_etendu*) tipParticu.Grandeur_pointee()); // pour simplifier
|
||
|
Grandeur_Ddl_etendu& gin
|
||
|
= *((Grandeur_Ddl_etendu*) tab_integ(i).Grandeur_pointee()); // pour simplifier
|
||
|
if ((*(gex.Nom_ref())) == (*(gin.Nom_ref())))
|
||
|
// là on a récupérer la même grandeur
|
||
|
{Ddl_etendu& ddl = *(gex.ConteneurDdl_etendu());// récup du ddl
|
||
|
ddl.Valeur() = gin.ConteneurDdl_etendu()->Valeur();
|
||
|
}
|
||
|
break;
|
||
|
};
|
||
|
case PARTICULIER_VECTEUR_NOMMER:
|
||
|
{ Grandeur_Vecteur_Nommer& gex
|
||
|
= *((Grandeur_Vecteur_Nommer*) tipParticu.Grandeur_pointee()); // pour simplifier
|
||
|
Grandeur_Vecteur_Nommer& gin
|
||
|
= *((Grandeur_Vecteur_Nommer*) tab_integ(i).Grandeur_pointee()); // pour simplifier
|
||
|
if ((*(gex.Nom_ref())) == (*(gin.Nom_ref())))
|
||
|
// là on a récupérer la même grandeur
|
||
|
{Vecteur& V = gex.ConteneurVecteur();
|
||
|
V = gin.ConteneurVecteur();
|
||
|
// //----- debug
|
||
|
// cout << "\n ElemMeca::Grandeur_particuliere( ";
|
||
|
// V.Affiche();
|
||
|
// //----- fin debug
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default: // pas d'intégrale ad hoc dispo ici pour la demande
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case INTEG_SUR_VOLUME_ET_TEMPS:
|
||
|
{if (integ_vol_t_typeQuel != NULL)//_t != NULL) // cas où localement il y a une intégrale de définie
|
||
|
{int nb_integration = integ_vol_t_typeQuel->Taille(); //_t->Taille();
|
||
|
Tableau <TypeQuelconque> & tab_integ = *integ_vol_t_typeQuel; //_t; // pour simplifier
|
||
|
const TypeQuelconque_enum_etendu& type_externe = tipParticu.EnuTypeQuelconque();
|
||
|
// maintenant il faut trouver la locale qui correspond: le plus simple
|
||
|
// mais pas le plus rapide !! est d'itérer
|
||
|
for (int i=1; i<= nb_integration;i++)
|
||
|
{EnuTypeQuelParticulier enuTQP = tipParticu.Grandeur_pointee()->Type_enumGrandeurParticuliere();
|
||
|
if (type_externe == (*enu_integ_vol_TQ)(i))
|
||
|
{switch (enuTQP)
|
||
|
{case PARTICULIER_DDL_ETENDU:
|
||
|
{ Grandeur_Ddl_etendu& gex
|
||
|
= *((Grandeur_Ddl_etendu*) tipParticu.Grandeur_pointee()); // pour simplifier
|
||
|
Grandeur_Ddl_etendu& gin
|
||
|
= *((Grandeur_Ddl_etendu*) tab_integ(i).Grandeur_pointee()); // pour simplifier
|
||
|
if ((*(gex.Nom_ref())) == (*(gin.Nom_ref())))
|
||
|
// là on a récupérer la même grandeur
|
||
|
{Ddl_etendu& ddl = *(gex.ConteneurDdl_etendu());// récup du ddl
|
||
|
ddl.Valeur() = gin.ConteneurDdl_etendu()->Valeur();
|
||
|
}
|
||
|
break;
|
||
|
};
|
||
|
case PARTICULIER_VECTEUR_NOMMER:
|
||
|
{ Grandeur_Vecteur_Nommer& gex
|
||
|
= *((Grandeur_Vecteur_Nommer*) tipParticu.Grandeur_pointee()); // pour simplifier
|
||
|
Grandeur_Vecteur_Nommer& gin
|
||
|
= *((Grandeur_Vecteur_Nommer*) tab_integ(i).Grandeur_pointee()); // pour simplifier
|
||
|
if ((*(gex.Nom_ref())) == (*(gin.Nom_ref())))
|
||
|
// là on a récupérer la même grandeur
|
||
|
{Vecteur& V = gex.ConteneurVecteur();
|
||
|
V = gin.ConteneurVecteur();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default: // pas d'intégrale ad hoc dispo ici pour la demande
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ENERGIE_HOURGLASS:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=ElemMeca::Energie_Hourglass();break;}
|
||
|
case PUISSANCE_BULK:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=ElemMeca::Puissance_Bulk();break;}
|
||
|
case ENERGIE_BULK:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=ElemMeca::Energie_Bulk();break;}
|
||
|
case ENERGIE_STABMEMB_BIEL:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=ElemMeca::Energie_StabMembBiel(iteg);break;}
|
||
|
case FORCE_STABMEMB_BIEL:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=ElemMeca::Force_StabMembBiel(iteg);break;}
|
||
|
// d) cas des infos calculable à la demande sur l'élément
|
||
|
case VOL_ELEM_AVEC_PLAN_REF:
|
||
|
{ *((Grandeur_coordonnee*) tipParticu.Grandeur_pointee())=VolumePlan();break;}
|
||
|
// cas des temps d'exécution
|
||
|
case TEMPS_CPU_LOI_COMP:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=
|
||
|
(*lesPtIntegMecaInterne)(iteg).Tps_cpu_loi_comp_const().Temps_CPU_User();break;}
|
||
|
case TEMPS_CPU_METRIQUE:
|
||
|
{ *((Grandeur_scalaire_double*) tipParticu.Grandeur_pointee())=
|
||
|
(*lesPtIntegMecaInterne)(iteg).TpsMetrique_const().Temps_CPU_User();break;}
|
||
|
case NUM_ELEMENT:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_elt; break;}
|
||
|
case NUM_MAIL_ELEM:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_maillage; break;}
|
||
|
case NUM_PTI:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= iteg; break;}
|
||
|
|
||
|
default: ;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
};
|
||
|
// suppression des bases de passages
|
||
|
if (gamma0 != NULL)
|
||
|
{delete gamma0; delete gammat; delete gammatdt; delete beta0; delete betat; delete betatdt;};
|
||
|
// liberation des tenseurs intermediaires
|
||
|
LibereTenseur();
|
||
|
def->Retour_pti_precedant(); // on revient au pti initial
|
||
|
};
|
||
|
|
||
|
// récupération de grandeurs particulières pour une face au numéro d'ordre = iteg
|
||
|
// celles-ci peuvent être quelconques
|
||
|
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
void ElemMeca::Grandeur_particuliere_face (bool absolue,List_io<TypeQuelconque>& liTQ,int face, int iteg)
|
||
|
{ // on s'intéresse au information stockée au niveau des points d'intégration
|
||
|
// pour tenir compte du fait qu'il peut y avoir plusieurs fois la même information, ces dernières sont systématiquement
|
||
|
// stockées dans des tableaux, et on associe à ce tableau un indice qui indique aux méthodes appelées, à quel endroit
|
||
|
// elles doivent écrire les infos. les indices sont stockés dans une liste de même dim que liTQ
|
||
|
list <int> decal(liTQ.size(),0.); // on initi tous les membres à 0
|
||
|
|
||
|
// 0° on initialise les grandeurs à 0 pour éviter d'avoir des valeurs aléatoires
|
||
|
// -- on commence par initialiser les conteneurs car certaines données peuvent ne pas exister
|
||
|
List_io<TypeQuelconque>::iterator iquefin=liTQ.end();
|
||
|
List_io<TypeQuelconque>::iterator ique,ique_deb=liTQ.begin();
|
||
|
for (ique=ique_deb;ique!=iquefin;ique++) (*ique).Grandeur_pointee()->InitParDefaut();
|
||
|
|
||
|
// 1° on change le numéro de point d'intégration courant si c'est possible
|
||
|
// on récupère l'élément frontière associée
|
||
|
int num_face = face; // init par défaut
|
||
|
// if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
// {num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
// if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
// {num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
// const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
|
||
|
Deformation* definter=NULL; // variable de travail transitoire
|
||
|
if (!(ParaGlob::AxiSymetrie()))
|
||
|
{ definter = defSurf(num_face); } // le cas normal est non axisymétrique
|
||
|
else { definter = defArete(num_face);}; // en axisymétrie, c'est une def d'arête
|
||
|
Deformation * defS = definter; // pour simplifier l'écriture
|
||
|
|
||
|
if (defS != NULL) // cas où la face existe
|
||
|
{ defS->ChangeNumInteg(iteg);
|
||
|
|
||
|
// calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en explicit mais pour un calcul autre que mécanique
|
||
|
Met_abstraite::Expli_t_tdt ex = (defS->Cal_explicit_tdt(true));
|
||
|
|
||
|
// 3° on change éventuellement de repère (local en global) si nécessaire
|
||
|
// a) définition des grandeurs qui sont indépendante de la boucle qui suit
|
||
|
// dimension des vecteurs de base de la métrique
|
||
|
int dim = met->Dim_vec_base();
|
||
|
// calcul des matrices de passages
|
||
|
Mat_pleine* gamma0=NULL; Mat_pleine* gammat=NULL; Mat_pleine* gammatdt=NULL;
|
||
|
Mat_pleine* beta0=NULL; Mat_pleine* betat=NULL; Mat_pleine* betatdt=NULL;
|
||
|
|
||
|
// const Met_abstraite::Info0_t_tdt& ex = def->Remont0_t_tdt(gamma0,gammat,gammatdt);
|
||
|
// Mat_pleine beta0(gamma0.Inverse().Transpose());
|
||
|
// Mat_pleine betat(gammat.Inverse().Transpose());
|
||
|
// Mat_pleine betatdt(gammatdt.Inverse().Transpose());
|
||
|
List_io<TypeQuelconque>::iterator il,ilfin = liTQ.end();
|
||
|
for (il=liTQ.begin();il!=ilfin;il++)
|
||
|
{ TypeQuelconque& tipParticu = (*il); // pour simplifier
|
||
|
// n'intervient que si la grandeur est active:
|
||
|
if ((*il).Activite())
|
||
|
{ // on regarde si c'est une grandeur locale ou pas
|
||
|
if (tipParticu.TypeExpressionGrandeur()==0)
|
||
|
// cas d'une grandeur exprimée dans le repère locale, changement de repère
|
||
|
{ // calcul des matrices de passages, au premier passage
|
||
|
if (gamma0 == NULL)
|
||
|
{ Mat_pleine Aa0(dim,dim),Aat(dim,dim),Aatdt(dim,dim);
|
||
|
const Met_abstraite::Info0_t_tdt& ex = defS->Remont0_t_tdt(absolue,Aa0,Aat,Aatdt);
|
||
|
// a) ----- dans le sens: gi -> Ia
|
||
|
// on a: g^i = A^i_{.a} * I^a ou Ip^a suivant que absolue est true ou false
|
||
|
// si false, cela veut dire que Ip^a est un repère ad hoc
|
||
|
// sinon cela veut dire que c'est le repère absolu donc I_a = I^a
|
||
|
// et g_j = B_j^{.a} * I_a d'où [B_j^{.a}] = [A^i_{.a}]^{-1T}
|
||
|
//
|
||
|
// b) ----- dans le sens: Ia -> gi
|
||
|
// pour les formules de passage de repère il nous faut :
|
||
|
// Ip_a = beta_a^{.j} g_j et Ip^b = gamma^b_{.j} g^j
|
||
|
// on a alors : [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// et [gamma^b_{.j}] = [beta_a^{.j}]^{-1T} = [Aa^j_{.a}]^{-1}
|
||
|
//
|
||
|
// au final: [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// [gamma^b_{.j}] = [Aa^j_{.a}]^{-1}
|
||
|
// [B_j^{.a}] = [gamma^b_{.j}]^T
|
||
|
|
||
|
gamma0 = new Mat_pleine(Aa0.Inverse());
|
||
|
gammat = new Mat_pleine(Aat.Inverse());
|
||
|
gammatdt = new Mat_pleine(Aatdt.Inverse());
|
||
|
// on détermine également les matrices beta
|
||
|
beta0 = new Mat_pleine(Aa0.Transpose());
|
||
|
betat = new Mat_pleine(Aat.Transpose());
|
||
|
betatdt = new Mat_pleine(Aatdt.Transpose());
|
||
|
};
|
||
|
tipParticu.Change_repere(*beta0,*betat,*betatdt,*gamma0,*gammat,*gammatdt);
|
||
|
};
|
||
|
// on la boucle également pour mettre à jour les grandeurs quelconque liés à la face de l'élément
|
||
|
|
||
|
// 1) -----cas du module de compressibilité ou de cisaillement totale
|
||
|
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
|
||
|
{
|
||
|
case POSITION_GEOMETRIQUE :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defS->Position_tdt();
|
||
|
break;
|
||
|
}
|
||
|
case POSITION_GEOMETRIQUE_t :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defS->Position_t();
|
||
|
break;
|
||
|
}
|
||
|
case POSITION_GEOMETRIQUE_t0 :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defS->Position_0();
|
||
|
break;
|
||
|
}
|
||
|
case VECT_PRESSION:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{if (lesChargeExtSurEle->LesPressionsExternes() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Pression_appliquee> >& lesPressionsExternes = *lesChargeExtSurEle->LesPressionsExternes();
|
||
|
// on se positionne sur la face
|
||
|
if (lesPressionsExternes(num_face).Taille() != 0)
|
||
|
{ Tableau <Pression_appliquee>& tab_press_appliquee = (lesPressionsExternes(num_face)); // pour simplifier
|
||
|
if (tab_press_appliquee.Taille())
|
||
|
{(*gr.ConteneurCoordonnee())=tab_press_appliquee(iteg).P;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case VECT_DIR_FIXE:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{ if (lesChargeExtSurEle->LesEffortsDirFixe() != NULL) // cas où il existe des valeurs sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesEffortsDirFixe();
|
||
|
// on se positionne sur la face
|
||
|
if (lesForcesExternes(num_face).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(num_face)); // pour simplifier
|
||
|
if (tab_force_appliquee.Taille())
|
||
|
{(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case VECT_SURF_SUIV:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{ if (lesChargeExtSurEle->LesPressDir() != NULL) // cas où il existe des valeurs sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesPressDir();
|
||
|
// on se positionne sur la num_face
|
||
|
if (lesForcesExternes(num_face).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(num_face)); // pour simplifier
|
||
|
if (tab_force_appliquee.Taille())
|
||
|
{(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case VECT_HYDRODYNA_Fn:case VECT_HYDRODYNA_Ft:case VECT_HYDRODYNA_T:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{ if (lesChargeExtSurEle->LesHydroDyna() != NULL) // cas où il existe des valeurs sauvegardées
|
||
|
{ Tableau <Tableau <Force_hydroDyna> >& lesForcesExternes = *lesChargeExtSurEle->LesHydroDyna();
|
||
|
// on se positionne sur la face
|
||
|
if (lesForcesExternes(num_face).Taille() != 0)
|
||
|
{ Tableau <Force_hydroDyna>& tab_force_appliquee = (lesForcesExternes(num_face)); // pour simplifier
|
||
|
|
||
|
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
|
||
|
{case VECT_HYDRODYNA_Fn:
|
||
|
(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg).F_n;
|
||
|
break;
|
||
|
case VECT_HYDRODYNA_Ft:
|
||
|
(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg).F_t;
|
||
|
break;
|
||
|
case VECT_HYDRODYNA_T:
|
||
|
(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg).T;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case NN_SURF:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
// la normale vaut le produit vectoriel des 2 premiers vecteurs
|
||
|
(*gr.ConteneurCoordonnee()) = Util::ProdVec_coorBN( (*ex.giB_tdt)(1), (*ex.giB_tdt)(2));
|
||
|
gr.ConteneurCoordonnee()->Normer(); // que l'on norme
|
||
|
break;
|
||
|
};
|
||
|
case NN_SURF_t:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
// la normale vaut le produit vectoriel des 2 premiers vecteurs
|
||
|
(*gr.ConteneurCoordonnee()) = Util::ProdVec_coorBN( (*ex.giB_t)(1), (*ex.giB_t)(2));
|
||
|
gr.ConteneurCoordonnee()->Normer(); // que l'on norme
|
||
|
break;
|
||
|
};
|
||
|
case NN_SURF_t0:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
// la normale vaut le produit vectoriel des 2 premiers vecteurs
|
||
|
(*gr.ConteneurCoordonnee()) = Util::ProdVec_coorBN( (*ex.giB_0)(1), (*ex.giB_0)(2));
|
||
|
gr.ConteneurCoordonnee()->Normer(); // que l'on norme
|
||
|
break;
|
||
|
};
|
||
|
case NUM_ELEMENT:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_elt; break;}
|
||
|
case NUM_MAIL_ELEM:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_maillage; break;}
|
||
|
case NUM_FACE:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_face; break;}
|
||
|
case NUM_PTI:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= iteg; break;
|
||
|
}
|
||
|
case PRESSION_SCALAIRE:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{if (lesChargeExtSurEle->LesPressionsExternes() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Pression_appliquee> >& lesPressionsExternes = *lesChargeExtSurEle->LesPressionsExternes();
|
||
|
// on se positionne sur la face
|
||
|
if (lesPressionsExternes(num_face).Taille() != 0)
|
||
|
{ Tableau <Pression_appliquee>& tab_press_appliquee = (lesPressionsExternes(num_face)); // pour simplifier
|
||
|
if (tab_press_appliquee.Taille())
|
||
|
{(*gr.ConteneurDouble())=tab_press_appliquee(iteg).press;
|
||
|
//// --- debug
|
||
|
//cout << "\n debug ElemMeca::Grandeur_particuliere_face ( ";
|
||
|
//cout << "\n pression = "<<
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
default: ;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
};
|
||
|
// suppression des bases de passages
|
||
|
if (gamma0 != NULL)
|
||
|
{delete gamma0; delete gammat; delete gammatdt; delete beta0; delete betat; delete betatdt;};
|
||
|
// liberation des tenseurs intermediaires
|
||
|
LibereTenseur();
|
||
|
defS->Retour_pti_precedant(); // on revient au pti initial
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// récupération de grandeurs particulières pour une arête au numéro d'ordre = iteg
|
||
|
// celles-ci peuvent être quelconques
|
||
|
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
|
||
|
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
|
||
|
void ElemMeca::Grandeur_particuliere_arete (bool absolue,List_io<TypeQuelconque>& liTQ,int arete, int iteg)
|
||
|
{ // on s'intéresse au information stockée au niveau des points d'intégration
|
||
|
// pour tenir compte du fait qu'il peut y avoir plusieurs fois la même information, ces dernières sont systématiquement
|
||
|
// stockées dans des tableaux, et on associe à ce tableau un indice qui indique aux méthodes appelées, à quel endroit
|
||
|
// elles doivent écrire les infos. les indices sont stockés dans une liste de même dim que liTQ
|
||
|
list <int> decal(liTQ.size(),0.); // on initi tous les membres à 0
|
||
|
|
||
|
// 0° on initialise les grandeurs à 0 pour éviter d'avoir des valeurs aléatoires
|
||
|
// -- on commence par initialiser les conteneurs car certaines données peuvent ne pas exister
|
||
|
List_io<TypeQuelconque>::iterator iquefin=liTQ.end();
|
||
|
List_io<TypeQuelconque>::iterator ique,ique_deb=liTQ.begin();
|
||
|
for (ique=ique_deb;ique!=iquefin;ique++) (*ique).Grandeur_pointee()->InitParDefaut();
|
||
|
|
||
|
// 1° on change le numéro de point d'intégration courant si c'est possible
|
||
|
Deformation * defA = defArete(arete); // pour simplifier l'écriture
|
||
|
if (defA != NULL)
|
||
|
{defA->ChangeNumInteg(iteg);
|
||
|
|
||
|
// calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en explicit mais pour un calcul autre que mécanique
|
||
|
Met_abstraite::Expli_t_tdt ex = (defA->Cal_explicit_tdt(true));
|
||
|
|
||
|
// 3° on change éventuellement de repère (local en global) si nécessaire
|
||
|
// a) définition des grandeurs qui sont indépendante de la boucle qui suit
|
||
|
// dimension des vecteurs de base de la métrique
|
||
|
int dim = met->Dim_vec_base();
|
||
|
// calcul des matrices de passages
|
||
|
Mat_pleine* gamma0=NULL; Mat_pleine* gammat=NULL; Mat_pleine* gammatdt=NULL;
|
||
|
Mat_pleine* beta0=NULL; Mat_pleine* betat=NULL; Mat_pleine* betatdt=NULL;
|
||
|
|
||
|
// const Met_abstraite::Info0_t_tdt& ex = def->Remont0_t_tdt(gamma0,gammat,gammatdt);
|
||
|
// Mat_pleine beta0(gamma0.Inverse().Transpose());
|
||
|
// Mat_pleine betat(gammat.Inverse().Transpose());
|
||
|
// Mat_pleine betatdt(gammatdt.Inverse().Transpose());
|
||
|
List_io<TypeQuelconque>::iterator il,ilfin = liTQ.end();
|
||
|
for (il=liTQ.begin();il!=ilfin;il++)
|
||
|
{ TypeQuelconque& tipParticu = (*il); // pour simplifier
|
||
|
// n'intervient que si la grandeur est active:
|
||
|
if ((*il).Activite())
|
||
|
{ // on regarde si c'est une grandeur locale ou pas
|
||
|
if (tipParticu.TypeExpressionGrandeur()==0)
|
||
|
// cas d'une grandeur exprimée dans le repère locale, changement de repère
|
||
|
{ // calcul des matrices de passages, au premier passage
|
||
|
if (gamma0 == NULL)
|
||
|
{ Mat_pleine Aa0(dim,dim),Aat(dim,dim),Aatdt(dim,dim);
|
||
|
const Met_abstraite::Info0_t_tdt& ex = defA->Remont0_t_tdt(absolue,Aa0,Aat,Aatdt);
|
||
|
// a) ----- dans le sens: gi -> Ia
|
||
|
// on a: g^i = A^i_{.a} * I^a ou Ip^a suivant que absolue est true ou false
|
||
|
// si false, cela veut dire que Ip^a est un repère ad hoc
|
||
|
// sinon cela veut dire que c'est le repère absolu donc I_a = I^a
|
||
|
// et g_j = B_j^{.a} * I_a d'où [B_j^{.a}] = [A^i_{.a}]^{-1T}
|
||
|
//
|
||
|
// b) ----- dans le sens: Ia -> gi
|
||
|
// pour les formules de passage de repère il nous faut :
|
||
|
// Ip_a = beta_a^{.j} g_j et Ip^b = gamma^b_{.j} g^j
|
||
|
// on a alors : [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// et [gamma^b_{.j}] = [beta_a^{.j}]^{-1T} = [Aa^j_{.a}]^{-1}
|
||
|
//
|
||
|
// au final: [beta_a^{.j}] = [Aa^j_{.a}]^T
|
||
|
// [gamma^b_{.j}] = [Aa^j_{.a}]^{-1}
|
||
|
// [B_j^{.a}] = [gamma^b_{.j}]^T
|
||
|
|
||
|
gamma0 = new Mat_pleine(Aa0.Inverse());
|
||
|
gammat = new Mat_pleine(Aat.Inverse());
|
||
|
gammatdt = new Mat_pleine(Aatdt.Inverse());
|
||
|
// on détermine également les matrices beta
|
||
|
beta0 = new Mat_pleine(Aa0.Transpose());
|
||
|
betat = new Mat_pleine(Aat.Transpose());
|
||
|
betatdt = new Mat_pleine(Aatdt.Transpose());
|
||
|
};
|
||
|
tipParticu.Change_repere(*beta0,*betat,*betatdt,*gamma0,*gammat,*gammatdt);
|
||
|
};
|
||
|
// on la boucle également pour mettre à jour les grandeurs quelconque liés à la arete de l'élément
|
||
|
|
||
|
// 1) -----cas du module de compressibilité ou de cisaillement totale
|
||
|
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
|
||
|
{
|
||
|
case POSITION_GEOMETRIQUE :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defA->Position_tdt();
|
||
|
break;
|
||
|
}
|
||
|
case POSITION_GEOMETRIQUE_t :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defA->Position_t();
|
||
|
break;
|
||
|
}
|
||
|
case POSITION_GEOMETRIQUE_t0 :
|
||
|
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
(*gr.ConteneurCoordonnee())= defA->Position_0();
|
||
|
break;
|
||
|
}
|
||
|
case VECT_LINE:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{ if (lesChargeExtSurEle->LesLineique() != NULL) // cas où il existe des valeurs sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesLineique();
|
||
|
// on se positionne sur la arete
|
||
|
if (lesForcesExternes(arete).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(arete)); // pour simplifier
|
||
|
if (tab_force_appliquee.Taille())
|
||
|
{(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case VECT_LINE_SUIV:
|
||
|
{// on récupère les infos
|
||
|
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tipParticu.Grandeur_pointee()));
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
{ if (lesChargeExtSurEle->LesLineiqueSuiveuse() != NULL) // cas où il existe des valeurs sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesLineiqueSuiveuse();
|
||
|
// on se positionne sur la arete
|
||
|
if (lesForcesExternes(arete).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(arete)); // pour simplifier
|
||
|
if (tab_force_appliquee.Taille())
|
||
|
{(*gr.ConteneurCoordonnee())=tab_force_appliquee(iteg);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
case NUM_ELEMENT:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_elt; break;}
|
||
|
case NUM_MAIL_ELEM:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= num_maillage; break;}
|
||
|
case NUM_ARETE:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= arete; break;}
|
||
|
case NUM_PTI:
|
||
|
{ *((Grandeur_scalaire_entier*) tipParticu.Grandeur_pointee())= iteg; break;
|
||
|
}
|
||
|
|
||
|
|
||
|
default: ;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
};
|
||
|
// suppression des bases de passages
|
||
|
if (gamma0 != NULL)
|
||
|
{delete gamma0; delete gammat; delete gammatdt; delete beta0; delete betat; delete betatdt;};
|
||
|
// liberation des tenseurs intermediaires
|
||
|
LibereTenseur();
|
||
|
defA->Retour_pti_precedant(); // on revient au pti initial
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
// --- transfert des grandeurs des points d'intégration aux noeuds
|
||
|
// transfert de ddl des points d'intégrations (de tous) aux noeuds d'un éléments (on ajoute aux noeuds, on ne remplace pas)
|
||
|
// les ddl doivent déjà exister aux noeuds sinon erreur
|
||
|
// il doit s'agir du même type de répartition de pt d'integ pour toutes les grandeurs
|
||
|
// tab_val(i)(j) : valeur associée au i ième pt d'integ et au j ième ddl_enum_etendu
|
||
|
void ElemMeca::TransfertAjoutAuNoeuds(const List_io < Ddl_enum_etendu >& lietendu
|
||
|
,const Tableau <Tableau <double> > & tab_val,int cas)
|
||
|
{List_io < Ddl_enum_etendu >::const_iterator ili,ilifin = lietendu.end();
|
||
|
// on récupère l'élément géométrique associé au ddl pur du premier ddl étendu,
|
||
|
ili = lietendu.begin();
|
||
|
Enum_ddl enu = (*ili).Enum();
|
||
|
|
||
|
int indice = 1;
|
||
|
for (ili = lietendu.begin();ili!=ilifin;ili++,indice++)
|
||
|
{ // cas normal courant
|
||
|
// récupération des tableaux d'indiçage pour le calcul aux noeuds
|
||
|
const ElemGeomC0& elemgeom = ElementGeometrie(enu);
|
||
|
// on récupère le nombre de noeud de l'élément géométrique (qui peut-être différent de celui de l'élément
|
||
|
// par ex: element sfe, donc on utilise les noeuds de l'élément géom. On considère que ce sont les premiers
|
||
|
// du tableau des noeuds
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
// calcul des valeurs aux noeuds
|
||
|
// val_au_noeud(i) = somme_(de j=indir(i)(1) à indir(i)(taille(indice(i)) )) {tab(i)(j) * val_pt_integ(j) }
|
||
|
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ Ddl_etendu& de = tab_noeud(ine)->ModifDdl_etendu(*ili);
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
de.Valeur() += contExtra.tab(ine)(indir(j)) * tab_val(indir(j))(indice);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// transfert de type quelconque des points d'intégrations (de tous) aux noeuds d'un éléments (on ajoute aux noeuds,
|
||
|
// on ne remplace pas). Les types quelconques doivent déjà exister.
|
||
|
// un tableau tab_liQ correspondent aux grandeurs quelconque pour tous les pt integ. tab_liQ(i) est associé au pt d'integ i
|
||
|
// Toutes les listes sont identiques au niveau des descripteurs (types...) ce sont uniquement les valeurs numériques
|
||
|
// c-a-dire les valeurs associées à TypeQuelconque::Grandeur qui sont différentes (elles sont associées à chaque pt d'integ)
|
||
|
// liQ_travail: est une liste de travail qui sera utilisée dans le transfert
|
||
|
void ElemMeca::TransfertAjoutAuNoeuds(const Tableau <List_io < TypeQuelconque > >& tab_liQ
|
||
|
,List_io < TypeQuelconque > & liQ_travail,int cas)
|
||
|
{int nb_pt_integ = lesPtIntegMecaInterne->NbPti();
|
||
|
// ---- modif transitoire pour la sortie des coques !!!!
|
||
|
// on s'occupe uniquement de la première couche d'élément
|
||
|
if ((this->PoutrePlaqueCoque() == COQUE)||(this->PoutrePlaqueCoque() == PLAQUE))
|
||
|
nb_pt_integ = this->NbPtIntegSurface(SIG11); // SIG11 arbitraire car c'est les pt d'integ classique
|
||
|
|
||
|
|
||
|
//------- fin modif transitoire --------
|
||
|
if (tab_liQ.Taille() == 0)
|
||
|
return; // cas où on n'a rien à faire
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (nb_pt_integ != tab_liQ.Taille())
|
||
|
{ cout << "\n erreur de dimension, la taille de tab_liQ= " << tab_liQ.Taille() << " n'est pas egale "
|
||
|
<< " au nombre de pt_d'integ de l'element : " << nb_pt_integ ;
|
||
|
cout << "\n ElemMeca::TransfertAjoutAuNoeuds(... " << endl;
|
||
|
Sortie(1);
|
||
|
}
|
||
|
#endif
|
||
|
//---- pour le debug
|
||
|
//cout << " \n debug ElemMeca::TransfertAjoutAuNoeuds " << tab_liQ << endl;
|
||
|
//--- fin pour le debug
|
||
|
// sinon on a au moins un élément, on récupère la 1ère liste qui nous servira pour les descripteurs
|
||
|
List_io <TypeQuelconque > & liQ_ref = tab_liQ(1); // pour simplifier
|
||
|
List_io < TypeQuelconque >::const_iterator ili_ref,ilifin_ref=liQ_ref.end();
|
||
|
// la liste de travail
|
||
|
List_io < TypeQuelconque >::iterator ili_travail = liQ_travail.begin();
|
||
|
// on définit un tableau d'itérator de dimension = le nb de pt d'integ
|
||
|
static Tableau < List_io < TypeQuelconque >::const_iterator > tab_iterator;
|
||
|
// on le redimentionne si besoin est
|
||
|
tab_iterator.Change_taille(nb_pt_integ);
|
||
|
// on définit ses éléments
|
||
|
for (int ia=1;ia<=nb_pt_integ;ia++)
|
||
|
tab_iterator(ia) = tab_liQ(ia).begin();
|
||
|
// on boucle sur les éléments de la liste de référence
|
||
|
for (ili_ref = liQ_ref.begin();ili_ref != ilifin_ref;ili_ref++,ili_travail++)
|
||
|
{ // on récupère l'élément géométrique associé au ddl pur dont les valeurs sont calculées aux mêmes
|
||
|
// endroits que la grandeur quelconque
|
||
|
Enum_ddl enu = (*ili_ref). Enum();
|
||
|
const ElemGeomC0& elemgeom = ElementGeometrie(enu);
|
||
|
// on récupère le nombre de noeud de l'élément géométrique (qui peut-être différent de celui de l'élément
|
||
|
// par ex: element sfe, donc on utilise les noeuds de l'élément géom. On considère que ce sont les premiers
|
||
|
// du tableau des noeuds
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
// récupération des tableaux d'indiçage pour le calcul aux noeuds
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
// on boucle sur les noeuds, ceci est due à la technique utilisée pour accumuler dans les conteneurs du noeud
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{TypeQuelconque& tq = tab_noeud(ine)->ModifGrandeur_quelconque((*ili_ref).EnuTypeQuelconque());
|
||
|
TypeQuelconque::Grandeur & grandeur_au_noeud = *(tq.Grandeur_pointee());
|
||
|
// on récupère une grandeur du même type que les grandeurs à manipuler, ceci pour accumuler
|
||
|
TypeQuelconque::Grandeur & stockage_inter = *((*ili_travail).Grandeur_pointee());
|
||
|
// calcul des valeurs aux noeuds
|
||
|
// val_au_noeud(i) = somme_(de j=indir(i)(1) à indir(i)(taille(indice(i)) )) {tab(i)(j) * val_pt_integ(j) }
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ stockage_inter *= 0.; // met à 0 la grandeur inter
|
||
|
// tab_iterator(j) pointe sur la grandeur quelconque du point d'intégration voulu
|
||
|
stockage_inter = *((*(tab_iterator(indir(j)))).Const_Grandeur_pointee()); // récup de la grandeur pointée
|
||
|
//---- debug
|
||
|
//cout << "\n debug ElemMeca::TransfertAjoutAuNoeuds: stockage_inter 1= " << stockage_inter;
|
||
|
//-- fin debug
|
||
|
stockage_inter *= contExtra.tab(ine)(indir(j)); // * par le coeff
|
||
|
grandeur_au_noeud += stockage_inter; // stockage dans le noeud
|
||
|
//---- debug
|
||
|
//cout << " stockage_inter 2= "<< stockage_inter << " grandeur_au_noeud= " << grandeur_au_noeud;
|
||
|
//if (Dabs(grandeur_au_noeud.GrandeurNumOrdre(2)) > 1.)
|
||
|
// {cout << "\n ***** grandeur_au_noeud.GrandeurNumOrdre(2) = " << grandeur_au_noeud.GrandeurNumOrdre(2)
|
||
|
// << "\n contExtra.tab= "<< contExtra.tab << " contExtra.indir= "<< contExtra.indir;
|
||
|
//
|
||
|
// };
|
||
|
//
|
||
|
//-- fin debug
|
||
|
};
|
||
|
};
|
||
|
// on incrémente les itérators de points d'intégration
|
||
|
for (int ib=1;ib<=nb_pt_integ;ib++)
|
||
|
(tab_iterator(ib))++;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
// accumulation aux noeuds de grandeurs venant des éléments vers leurs noeuds (exemple la pression appliquée)
|
||
|
// autres que celles aux pti classiques, mais directements disponibles
|
||
|
// le contenu du conteneur stockées dans liQ est utilisé en variable intermédiaire
|
||
|
void ElemMeca::Accumul_aux_noeuds(const List_io < Ddl_enum_etendu >& lietendu
|
||
|
,List_io < TypeQuelconque > & liQ,int cas)
|
||
|
{// ... cas des ddl étendu ...
|
||
|
{List_io < Ddl_enum_etendu >::const_iterator ili,ilifin = lietendu.end();
|
||
|
ili = lietendu.begin();
|
||
|
for (ili = lietendu.begin();ili!=ilifin;ili++)
|
||
|
{// on traite en fonctions des cas particuliers
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " *ili = " << *ili << endl;
|
||
|
// fin debug
|
||
|
|
||
|
switch ((*ili).Position()-NbEnum_ddl())
|
||
|
{ case 94 : // cas des pressions externes
|
||
|
{if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesPressionsExternes() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Pression_appliquee> >& lesPressionsExternes = *lesChargeExtSurEle->LesPressionsExternes();
|
||
|
int nb_face = lesPressionsExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesPressionsExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Pression_appliquee>& tab_press_appliquee = (lesPressionsExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_press_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ Ddl_etendu& de = tab_noe(ine)->ModifDdl_etendu(*ili);
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ de.Valeur() += contExtra.tab(ine)(indir(j)) * tab_press_appliquee(indir(j)).press;
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
default :
|
||
|
break;
|
||
|
// sinon on ne fait rien, cela signifie que ce n'est pas un ddl géré par l'élément
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// ... cas des grandeurs quelconque ...
|
||
|
// on traite d'abord le cas où on n'a rien à faire
|
||
|
if (liQ.size() == 0)
|
||
|
return;
|
||
|
//---- pour le debug
|
||
|
//cout << " \n debug ElemMeca::TransfertAjoutAuNoeuds " << tab_liQ << endl;
|
||
|
//--- fin pour le debug
|
||
|
{List_io < TypeQuelconque >::const_iterator ili,ilifin=liQ.end();
|
||
|
|
||
|
// on boucle sur les grandeurs de la liste
|
||
|
for (ili = liQ.begin();ili != ilifin;ili++)
|
||
|
{ // on récupère l'énuméré
|
||
|
TypeQuelconque_enum_etendu enutq = (*ili).EnuTypeQuelconque();
|
||
|
switch (enutq.EnumTQ())
|
||
|
{ case VECT_PRESSION:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesPressionsExternes() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Pression_appliquee> >& lesPressionsExternes = *lesChargeExtSurEle->LesPressionsExternes();
|
||
|
int nb_face = lesPressionsExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesPressionsExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Pression_appliquee>& tab_press_appliquee = (lesPressionsExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_press_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += contExtra.tab(ine)(indir(j)) * tab_press_appliquee(indir(j)).P;
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_FORCE_VOLUM:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->Force_volume() != NULL) // cas où il existe des F volume sauvegardées
|
||
|
{ Tableau <Coordonnee>& force_volume = *lesChargeExtSurEle->Force_volume();
|
||
|
int t_tail = force_volume.Taille();
|
||
|
if (t_tail != 0) // cas où on a des forces volumique
|
||
|
{ // on récupère l'élément géométrique associée
|
||
|
const ElemGeomC0& elemgeom = ElementGeometrie(X1);
|
||
|
// on récupère le nombre de noeud de l'élément géométrique (qui peut-être différent de celui de l'élément
|
||
|
// par ex: element sfe, donc on utilise les noeuds de l'élément géom. On considère que ce sont les premiers
|
||
|
// du tableau des noeuds
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
// récupération des tableaux d'indiçage pour le calcul aux noeuds
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
// on boucle sur les noeuds,
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{TypeQuelconque& tq = tab_noeud(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) tq.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += (contExtra.tab(ine)(indir(j))) * force_volume(indir(j));
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_DIR_FIXE:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesEffortsDirFixe() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesEffortsDirFixe();
|
||
|
int nb_face = lesForcesExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesForcesExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_force_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j));
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_SURF_SUIV:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesPressDir() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesPressDir();
|
||
|
int nb_face = lesForcesExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesForcesExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_force_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j));
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_HYDRODYNA_Fn:case VECT_HYDRODYNA_Ft:case VECT_HYDRODYNA_T:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Force_hydroDyna> >& lesForcesExternes = *lesChargeExtSurEle->LesHydroDyna();
|
||
|
int nb_face = lesForcesExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesForcesExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Force_hydroDyna>& tab_force_appliquee = (lesForcesExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_force_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
switch (enutq.EnumTQ())
|
||
|
{case VECT_HYDRODYNA_Fn:
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j)).F_n;
|
||
|
break;
|
||
|
case VECT_HYDRODYNA_Ft:
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j)).F_t;
|
||
|
break;
|
||
|
case VECT_HYDRODYNA_T:
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j)).T;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_LINE:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesLineique() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesLineique();
|
||
|
int nb_face = lesForcesExternes.Taille();
|
||
|
for (int n_face=1;n_face<=nb_face;n_face++) // on boucle sur les faces
|
||
|
if (lesForcesExternes(n_face).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(n_face)); // pour simplifier
|
||
|
int t_tail = tab_force_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une face chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_face = n_face; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les faces
|
||
|
{num_face += posi_tab_front_lin;}; // sont en faites les frontières lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_face)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_face)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j));
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
case VECT_LINE_SUIV:
|
||
|
{ // on récupère les infos pour extrapoler les valeurs
|
||
|
if (lesChargeExtSurEle != NULL)
|
||
|
if (lesChargeExtSurEle->LesLineiqueSuiveuse() != NULL) // cas où il existe des pressions sauvegardées
|
||
|
{ Tableau <Tableau <Coordonnee> >& lesForcesExternes = *lesChargeExtSurEle->LesLineiqueSuiveuse();
|
||
|
int nb_ligne = lesForcesExternes.Taille();
|
||
|
for (int n_ligne=1;n_ligne<=nb_ligne;n_ligne++) // on boucle sur les lignes
|
||
|
if (lesForcesExternes(n_ligne).Taille() != 0)
|
||
|
{ Tableau <Coordonnee>& tab_force_appliquee = (lesForcesExternes(n_ligne)); // pour simplifier
|
||
|
int t_tail = tab_force_appliquee.Taille();
|
||
|
if (t_tail != 0) // cas où on a une ligne chargée
|
||
|
{ // on récupère l'élément frontière associée (on considère qu'il y en a forcément 1)
|
||
|
int num_ligne = n_ligne; // init par défaut
|
||
|
if(ParaGlob::AxiSymetrie()) // dans le cas d'éléments axysymétriques, les lignes
|
||
|
{num_ligne += posi_tab_front_point;} // sont en faites les frontières points
|
||
|
else {num_ligne += posi_tab_front_lin;}; // sinon c'est des lignes
|
||
|
const ElemGeomC0 & elemgeom = tabb(num_ligne)->ElementGeometrique();
|
||
|
int nbn = elemgeom.Nbne();
|
||
|
const ElemGeomC0::ConteneurExtrapolation & contExtra = elemgeom.ExtrapolationNoeud(cas);
|
||
|
Tableau <Noeud *>& tab_noe = tabb(num_ligne)->TabNoeud(); // récup du tableau de noeuds de la frontière
|
||
|
for (int ine=1;ine<=nbn;ine++)
|
||
|
{ TypeQuelconque& de = tab_noe(ine)->ModifGrandeur_quelconque(enutq);
|
||
|
// récup des coordonnées
|
||
|
Grandeur_coordonnee* gr_coor = ((Grandeur_coordonnee*) de.Const_Grandeur_pointee());
|
||
|
Coordonnee& coor = *(gr_coor->ConteneurCoordonnee());
|
||
|
Tableau <int>& indir = contExtra.indir(ine); // pour simplifier
|
||
|
int nbindir = indir.Taille();
|
||
|
for (int j=1; j<= nbindir; j++)
|
||
|
{ coor += contExtra.tab(ine)(indir(j)) * tab_force_appliquee(indir(j));
|
||
|
//debug
|
||
|
//cout << "\n debug ElemMeca::Accumul_aux_noeuds"
|
||
|
// << " de.Valeur() = " << de.Valeur() << endl;
|
||
|
// fin debug
|
||
|
} };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
// case VECT_REAC:
|
||
|
// // là on ne fait rien car la grandeur est directement à construire via les noeuds
|
||
|
// // et ceci est fait dans la routine:
|
||
|
// // lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles()
|
||
|
// break;
|
||
|
|
||
|
default:
|
||
|
// VECT_PRESSION pour l'instant il n'y a aucune grandeur a priori qui est disponible directement
|
||
|
// donc message d'erreur
|
||
|
cout << "\n cas de grandeur actuellement non traité "
|
||
|
<< "\n pas de grandeur " << (*ili).EnuTypeQuelconque().NomPlein()
|
||
|
<< " dans l'element "
|
||
|
<< "\n ou cas non implante pour l'instant"
|
||
|
<< "\n ElemMeca::Accumul_aux_noeuds(....";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// procedure permettant de completer l'element, en ce qui concerne les variables gérés
|
||
|
// par ElemMeca, apres sa creation avec les donnees du bloc transmis
|
||
|
// peut etre appeler plusieurs fois
|
||
|
Element* ElemMeca::Complete_ElemMeca(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD)
|
||
|
{ // cas de la masse volumique
|
||
|
if (bloc.Nom(1) == "masse_volumique")
|
||
|
{ masse_volumique = bloc.Val(1);
|
||
|
return this;
|
||
|
}
|
||
|
// cas de données thermique
|
||
|
else if (bloc.Nom(1) == "dilatation_thermique")
|
||
|
{ if (bloc.Val(1) == 1) {dilatation=1;} else {dilatation = 0;};
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
// cas de la définition d'une intégrale sur le volume
|
||
|
// on prévoit une intégrale via les pti, on utilise donc le ddl EPS11 pour la position
|
||
|
// (*index_Integ_vol_typeQuel)(ii) contient alors le numéro de l'intégrale qui a été
|
||
|
// demandé par l'utilisateur = le numéro d'apparition dans le .info
|
||
|
// idem pour (*index_Integ_vol_t_typeQuel)(ii)
|
||
|
if (bloc.Nom(1) == "integrale_sur_volume_")
|
||
|
{ if (bloc.Nom(2) == "un_ddl_etendu_")
|
||
|
{ // il s'agit d'une intégrale d'un ddl étendu de nom: bloc.Nom(3)
|
||
|
Ddl_etendu ddl(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
|
||
|
Grandeur_Ddl_etendu grand_courant(ddl,bloc.Nom(4));// le conteneur ad hoc
|
||
|
TypeQuelconque typQ(INTEG_SUR_VOLUME,EPS11,grand_courant);
|
||
|
|
||
|
// on garde en mémoire le TypeQuelconque_enum_etendu associé
|
||
|
// -- on crée le nom de référence
|
||
|
// string nom(NomTypeQuelconque(INTEG_SUR_VOLUME)+"_"+bloc.Nom(4)+"_"
|
||
|
// +ChangeEntierSTring(bloc.Val(1)));
|
||
|
// modif le 29 janvier 2018 version >= 6.827, on ne met plus le chiffre du rang
|
||
|
// de l'intégrale à la fin, car le rang peu changer après un restart par exemple
|
||
|
// du coup c'est une complexité qui n'apporte pas d'info sup, car la rang est stocké dans l'index
|
||
|
string nom(NomTypeQuelconque(INTEG_SUR_VOLUME)+"_"+bloc.Nom(4)+"_");
|
||
|
|
||
|
// on regarde si l'identificateur existe déjà, sinon on le crée
|
||
|
if (!TypeQuelconque_enum_etendu::VerifExistence(nom))
|
||
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
(INTEG_SUR_VOLUME,nom,typQ.EnuTypeGrandeur());
|
||
|
// puis récupération
|
||
|
TypeQuelconque_enum_etendu tqnevez =
|
||
|
TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(nom);
|
||
|
|
||
|
if (integ_vol_typeQuel == NULL)
|
||
|
{// ici rien n'existe, donc on crée sans se poser des questions
|
||
|
int taille = 1;
|
||
|
integ_vol_typeQuel = new Tableau <TypeQuelconque>(1);
|
||
|
integ_vol_typeQuel_t = new Tableau <TypeQuelconque>(1);
|
||
|
(*integ_vol_typeQuel)(1) = typQ;(*integ_vol_typeQuel_t)(1) = typQ;
|
||
|
index_Integ_vol_typeQuel = new Tableau <int>(1);
|
||
|
(*index_Integ_vol_typeQuel)(1) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_TQ = new Tableau <TypeQuelconque_enum_etendu>(1);
|
||
|
(*enu_integ_vol_TQ)(1)=tqnevez;
|
||
|
}
|
||
|
else
|
||
|
{// sinon, deux cas suivant que la grandeur a déjà été enregistrée
|
||
|
// suite à un restart par exemple , ou au contraire en n'existe pas encore
|
||
|
// on utilise l'identificateur pour repérer l'intégrale
|
||
|
int indic = enu_integ_vol_TQ->Contient(tqnevez);
|
||
|
if (!indic)
|
||
|
{// cas où l'intégrale n'existe pas déjà
|
||
|
int taille = integ_vol_typeQuel->Taille()+1;
|
||
|
integ_vol_typeQuel->Change_taille(taille);
|
||
|
integ_vol_typeQuel_t->Change_taille(taille);
|
||
|
(*integ_vol_typeQuel)(taille) = typQ;
|
||
|
(*integ_vol_typeQuel_t)(taille) = typQ;
|
||
|
index_Integ_vol_typeQuel->Change_taille(taille);
|
||
|
(*index_Integ_vol_typeQuel)(taille) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_TQ->Change_taille(taille);
|
||
|
(*enu_integ_vol_TQ)(taille)=tqnevez;
|
||
|
}
|
||
|
else // sinon les conteneurs existent déjà
|
||
|
// il faut juste mettre à jour l'index
|
||
|
{ (*index_Integ_vol_typeQuel)(indic) = (int) bloc.Val(1);
|
||
|
} ;
|
||
|
};
|
||
|
}
|
||
|
else if (bloc.Nom(2) == "une_fonction_nD_")
|
||
|
{ // il s'agit d'une intégrale d'une fonction nD de nom: bloc.Nom(3)
|
||
|
// on récupère le pointeur de fonction correspondant:
|
||
|
Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
|
||
|
int nb_composante = fct->NbComposante();
|
||
|
Grandeur_Vecteur_Nommer grand_courant(bloc.Nom(3),nb_composante,fct);
|
||
|
TypeQuelconque typQ(INTEG_SUR_VOLUME,EPS11,grand_courant);
|
||
|
// on garde en mémoire le TypeQuelconque_enum_etendu associé
|
||
|
// -- on crée le nom de référence
|
||
|
// string nom(NomTypeQuelconque(INTEG_SUR_VOLUME)+"_"+bloc.Nom(4)+"_"
|
||
|
// +ChangeEntierSTring(bloc.Val(1)));
|
||
|
// modif le 29 janvier 2018 version >= 6.827, on ne met plus le chiffre du rang
|
||
|
// de l'intégrale à la fin, car le rang peu changer après un restart par exemple
|
||
|
// du coup c'est une complexité qui n'apporte pas d'info sup, car la rang est stocké dans l'index
|
||
|
string nom(NomTypeQuelconque(INTEG_SUR_VOLUME)+"_"+bloc.Nom(4)+"_");
|
||
|
// on regarde si l'identificateur existe déjà, sinon on le crée
|
||
|
if (!TypeQuelconque_enum_etendu::VerifExistence(nom))
|
||
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
(INTEG_SUR_VOLUME,nom,typQ.EnuTypeGrandeur());
|
||
|
// puis récupération
|
||
|
TypeQuelconque_enum_etendu tqnevez =
|
||
|
TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(nom);
|
||
|
|
||
|
if (integ_vol_typeQuel == NULL)
|
||
|
{ // ici rien n'existe, donc on crée sans se poser des questions
|
||
|
int taille = 1;
|
||
|
integ_vol_typeQuel = new Tableau <TypeQuelconque>(1);
|
||
|
integ_vol_typeQuel_t = new Tableau <TypeQuelconque>(1);
|
||
|
(*integ_vol_typeQuel)(1) = typQ;(*integ_vol_typeQuel_t)(1) = typQ;
|
||
|
index_Integ_vol_typeQuel = new Tableau <int>(1);
|
||
|
(*index_Integ_vol_typeQuel)(1) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_TQ = new Tableau <TypeQuelconque_enum_etendu>(1);
|
||
|
(*enu_integ_vol_TQ)(1)=tqnevez;
|
||
|
}
|
||
|
else
|
||
|
{// sinon, deux cas suivant que la grandeur a déjà été enregistrée
|
||
|
// suite à un restart par exemple , ou au contraire en n'existe pas encore
|
||
|
// on utilise l'identificateur pour repérer l'intégrale
|
||
|
int indic = enu_integ_vol_TQ->Contient(tqnevez);
|
||
|
if (!indic)
|
||
|
{// cas où l'intégrale n'existe pas déjà
|
||
|
int taille = integ_vol_typeQuel->Taille()+1;
|
||
|
integ_vol_typeQuel->Change_taille(taille);
|
||
|
integ_vol_typeQuel_t->Change_taille(taille);
|
||
|
(*integ_vol_typeQuel)(taille) = typQ;
|
||
|
(*integ_vol_typeQuel_t)(taille) = typQ;
|
||
|
index_Integ_vol_typeQuel->Change_taille(taille);
|
||
|
(*index_Integ_vol_typeQuel)(taille) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_TQ->Change_taille(taille);
|
||
|
(*enu_integ_vol_TQ)(taille)=tqnevez;
|
||
|
}
|
||
|
else // sinon les conteneurs existent déjà
|
||
|
// il faut juste mettre à jour l'index
|
||
|
{ (*index_Integ_vol_typeQuel)(indic) = (int) bloc.Val(1);
|
||
|
} ;
|
||
|
};
|
||
|
|
||
|
};
|
||
|
return this;
|
||
|
}
|
||
|
// cas de la définition d'une intégrale sur le volume et le temps
|
||
|
else if (bloc.Nom(1) == "integrale_sur_vol_et_temps_")
|
||
|
{ if (bloc.Nom(2) == "un_ddl_etendu_")
|
||
|
{ // il s'agit d'une intégrale d'un ddl étendu de nom: bloc.Nom(3)
|
||
|
Ddl_etendu ddl(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
|
||
|
Grandeur_Ddl_etendu grand_courant(ddl,bloc.Nom(4));// le conteneur ad hoc
|
||
|
TypeQuelconque typQ(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant);
|
||
|
|
||
|
// on garde en mémoire le TypeQuelconque_enum_etendu associé
|
||
|
// -- on crée le nom de référence
|
||
|
// string nom(NomTypeQuelconque(INTEG_SUR_VOLUME_ET_TEMPS)+"_"+bloc.Nom(4)+"_"
|
||
|
// +ChangeEntierSTring(bloc.Val(1)));
|
||
|
// modif le 29 janvier 2018 version >= 6.827, on ne met plus le chiffre du rang
|
||
|
// de l'intégrale à la fin, car le rang peu changer après un restart par exemple
|
||
|
// du coup c'est une complexité qui n'apporte pas d'info sup, car la rang est stocké dans l'index
|
||
|
string nom(NomTypeQuelconque(INTEG_SUR_VOLUME_ET_TEMPS)+"_"+bloc.Nom(4)+"_");
|
||
|
|
||
|
// on regarde si l'identificateur existe déjà, sinon on le crée
|
||
|
if (!TypeQuelconque_enum_etendu::VerifExistence(nom))
|
||
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
(INTEG_SUR_VOLUME_ET_TEMPS,nom,typQ.EnuTypeGrandeur());
|
||
|
// puis récupération
|
||
|
TypeQuelconque_enum_etendu tqnevez =
|
||
|
TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(nom);
|
||
|
|
||
|
if (integ_vol_t_typeQuel == NULL)
|
||
|
{// ici rien n'existe, donc on crée sans se poser des questions
|
||
|
int taille = 1;
|
||
|
integ_vol_t_typeQuel = new Tableau <TypeQuelconque>(1);
|
||
|
integ_vol_t_typeQuel_t = new Tableau <TypeQuelconque>(1);
|
||
|
(*integ_vol_t_typeQuel)(1) = typQ;(*integ_vol_t_typeQuel_t)(1) = typQ;
|
||
|
index_Integ_vol_t_typeQuel = new Tableau <int>(1);
|
||
|
(*index_Integ_vol_t_typeQuel)(1) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_t_TQ = new Tableau <TypeQuelconque_enum_etendu>(1);
|
||
|
(*enu_integ_vol_t_TQ)(1)=tqnevez;
|
||
|
}
|
||
|
else
|
||
|
{// sinon, deux cas suivant que la grandeur a déjà été enregistrée
|
||
|
// suite à un restart par exemple , ou au contraire en n'existe pas encore
|
||
|
// on utilise l'identificateur pour repérer l'intégrale
|
||
|
int indic = enu_integ_vol_t_TQ->Contient(tqnevez);
|
||
|
if (!indic)
|
||
|
{int taille = integ_vol_t_typeQuel->Taille()+1;
|
||
|
integ_vol_t_typeQuel->Change_taille(taille);
|
||
|
integ_vol_t_typeQuel_t->Change_taille(taille);
|
||
|
(*integ_vol_t_typeQuel)(taille) = typQ;
|
||
|
(*integ_vol_t_typeQuel_t)(taille) = typQ;
|
||
|
index_Integ_vol_t_typeQuel->Change_taille(taille);
|
||
|
(*index_Integ_vol_t_typeQuel)(taille) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_t_TQ->Change_taille(taille);
|
||
|
(*enu_integ_vol_t_TQ)(taille)=tqnevez;
|
||
|
}
|
||
|
else // sinon les conteneurs existent déjà
|
||
|
// il faut juste mettre à jour l'index
|
||
|
{ (*index_Integ_vol_t_typeQuel)(indic) = (int) bloc.Val(1);
|
||
|
} ;
|
||
|
};
|
||
|
}
|
||
|
else if (bloc.Nom(2) == "une_fonction_nD_")
|
||
|
{ // il s'agit d'une intégrale d'une fonction nD de nom: bloc.Nom(3)
|
||
|
// on récupère le pointeur de fonction correspondant:
|
||
|
Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
|
||
|
int nb_composante = fct->NbComposante();
|
||
|
Grandeur_Vecteur_Nommer grand_courant(bloc.Nom(3),nb_composante,fct);
|
||
|
TypeQuelconque typQ(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant);
|
||
|
|
||
|
// on garde en mémoire le TypeQuelconque_enum_etendu associé
|
||
|
// -- on crée le nom de référence
|
||
|
// string nom(NomTypeQuelconque(INTEG_SUR_VOLUME_ET_TEMPS)+"_"+bloc.Nom(4)+"_"
|
||
|
// +ChangeEntierSTring(bloc.Val(1)));
|
||
|
// modif le 29 janvier 2018 version >= 6.827, on ne met plus le chiffre du rang
|
||
|
// de l'intégrale à la fin, car le rang peu changer après un restart par exemple
|
||
|
// du coup c'est une complexité qui n'apporte pas d'info sup, car la rang est stocké dans l'index
|
||
|
string nom(NomTypeQuelconque(INTEG_SUR_VOLUME_ET_TEMPS)+"_"+bloc.Nom(4)+"_");
|
||
|
if (!TypeQuelconque_enum_etendu::VerifExistence(nom))
|
||
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
||
|
(INTEG_SUR_VOLUME_ET_TEMPS,nom,typQ.EnuTypeGrandeur());
|
||
|
// puis récupération
|
||
|
TypeQuelconque_enum_etendu tqnevez =
|
||
|
TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(nom);
|
||
|
|
||
|
if (integ_vol_t_typeQuel == NULL)
|
||
|
{// ici rien n'existe, donc on crée sans se poser des questions
|
||
|
int taille = 1;
|
||
|
integ_vol_t_typeQuel = new Tableau <TypeQuelconque>(1);
|
||
|
integ_vol_t_typeQuel_t = new Tableau <TypeQuelconque>(1);
|
||
|
(*integ_vol_t_typeQuel)(1) = typQ;(*integ_vol_t_typeQuel_t)(1) = typQ;
|
||
|
index_Integ_vol_t_typeQuel = new Tableau <int>(1);
|
||
|
(*index_Integ_vol_t_typeQuel)(1) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_t_TQ = new Tableau <TypeQuelconque_enum_etendu>(1);
|
||
|
(*enu_integ_vol_t_TQ)(1)=tqnevez;
|
||
|
}
|
||
|
else
|
||
|
{// sinon, deux cas suivant que la grandeur a déjà été enregistrée
|
||
|
// suite à un restart par exemple , ou au contraire en n'existe pas encore
|
||
|
// on utilise l'identificateur pour repérer l'intégrale
|
||
|
int indic = enu_integ_vol_t_TQ->Contient(tqnevez);
|
||
|
if (!indic)
|
||
|
{int taille = integ_vol_t_typeQuel->Taille()+1;
|
||
|
integ_vol_t_typeQuel->Change_taille(taille);
|
||
|
integ_vol_t_typeQuel_t->Change_taille(taille);
|
||
|
(*integ_vol_t_typeQuel)(taille) = typQ;
|
||
|
(*integ_vol_t_typeQuel_t)(taille) = typQ;
|
||
|
index_Integ_vol_t_typeQuel->Change_taille(taille);
|
||
|
(*index_Integ_vol_t_typeQuel)(taille) = (int) bloc.Val(1);
|
||
|
enu_integ_vol_t_TQ->Change_taille(taille);
|
||
|
(*enu_integ_vol_t_TQ)(taille)=tqnevez;
|
||
|
}
|
||
|
else // sinon les conteneurs existent déjà
|
||
|
// il faut juste mettre à jour l'index
|
||
|
{ (*index_Integ_vol_t_typeQuel)(indic) = (int) bloc.Val(1);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
return this;
|
||
|
}
|
||
|
// cas de la définition d'une stabilisation transversale pour membrane ou biel
|
||
|
else if (bloc.Nom(1) == "stabilisation_transvers_membrane_biel_")
|
||
|
{// on vérifie qu'il s'agit d'une géométrie membrane ou biel
|
||
|
Enum_type_geom enu_type_geom = Type_geom_generique(this->Id_geometrie());
|
||
|
if ((enu_type_geom != LIGNE) && (enu_type_geom != SURFACE))
|
||
|
{cout << "\n **** erreur, la stabilisation n'est pas prevue pour ce type d'element: ";
|
||
|
this->Affiche(1);
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// maintenant on va allouer le conteneur d'infos
|
||
|
|
||
|
// pour savoir comment dimensionner le stockage
|
||
|
// il faut prendre en compte le type de stabilisation
|
||
|
Enum_StabMembraneBiel enu_stab = Id_Enum_StabMembraneBiel(bloc.Nom(2));
|
||
|
int taille_stockage = 0; // init
|
||
|
if (!Contient_Normale_au_noeud(enu_stab))
|
||
|
// cas d'un stockage aux pti
|
||
|
{ // détermination de la taille en fonction du type d'élément
|
||
|
// ** non car finalement on ne prend que les pti de surface
|
||
|
// Enum_type_geom enu_type_geom = Type_geom_generique(this->Id_geometrie());
|
||
|
// switch (enu_type_geom)
|
||
|
// { case SURFACE:
|
||
|
// taille_stockage = NbPtIntegSurface(X1) * NbPtIntegEpaiss(X1);
|
||
|
// break;
|
||
|
// default:
|
||
|
// cout << "\n *** actuellement seule les elements de surface peuvent etre stabilise ** revoir la mise en donnees ...";
|
||
|
// Sortie(1);
|
||
|
// };
|
||
|
taille_stockage = this->ElementGeometrique().Nbi();
|
||
|
}
|
||
|
else // sinon c'est un stockage aux noeuds
|
||
|
{ taille_stockage = tab_noeud.Taille();};
|
||
|
|
||
|
pt_StabMembBiel = new StabMembBiel(taille_stockage);
|
||
|
// définition du type de stabilisation
|
||
|
if (Type_Enum_StabMembraneBiel_existe(bloc.Nom(2)))
|
||
|
{pt_StabMembBiel->Type_stabMembrane()= Id_Enum_StabMembraneBiel(bloc.Nom(2));}
|
||
|
else
|
||
|
{cout << "\n *** erreur en mise en place de la stabilisation de membrane et/ou biel: "
|
||
|
<< " le type de stabilisation "<<bloc.Nom(2)<<" n'existe pas ! ";
|
||
|
cout << "\n ElemMeca::Complete_ElemMeca(..."<<endl; this->Affiche(1);
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
// choix entre valeur numérique ou une fonction nD
|
||
|
if (bloc.Nom(3) == "une_valeur_numerique_")
|
||
|
{// dans ce cas la valeur numémrique est en string
|
||
|
pt_StabMembBiel->Valgamma() = ChangeReel(bloc.Nom(4));
|
||
|
}
|
||
|
else if (bloc.Nom(3) == "une_fonction_nD_")
|
||
|
{// il s'agit d'une fonction nD: récupération de la fonction
|
||
|
pt_StabMembBiel->Change_pt_fct_gamma(lesFonctionsnD->Trouve(bloc.Nom(4)));
|
||
|
// pour l'instant seules les variables globales sont autorisées:
|
||
|
if (pt_StabMembBiel->Pt_fct_gamma()->Nom_variables().Taille() == 0)
|
||
|
// cas où il n'y a que des variables globales
|
||
|
{// on vérifie qu'en retour on a un scalaire
|
||
|
Tableau <double> & tava = pt_StabMembBiel->Pt_fct_gamma()->Valeur_pour_variables_globales(); // pour simplifier
|
||
|
if (pt_StabMembBiel->Pt_fct_gamma()->NbComposante() != 1)
|
||
|
{cout << "\n *** erreur en mise en place de la stabilisation de membrane et/ou biel : "
|
||
|
<< " la fonction nD avec grandeur(s) globale(s) ne renvoie pas un scalaire ! ";
|
||
|
cout << "\n element: "; this->Affiche(1);
|
||
|
cout << "\n fonction nD : "; pt_StabMembBiel->Pt_fct_gamma()->Affiche();
|
||
|
Sortie(1);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n *** erreur en mise en place de la stabilisation: "
|
||
|
<< " la fonction nD ne doit utiliser que des variables globales ! ";
|
||
|
cout << "\n element: "; this->Affiche(1);
|
||
|
cout << "\n fonction nD : "; pt_StabMembBiel->Pt_fct_gamma()->Affiche();
|
||
|
Sortie(1);
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n **** erreur, en mise en place de la stabilisation: "
|
||
|
<< " le mot cle: "<< bloc.Nom(3) << "n'est pas exploitable ";
|
||
|
if (ParaGlob::NiveauImpression() > 2)
|
||
|
cout << "\n ElemMeca::Complete_ElemMeca(..";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// on regarde s'il y a des infos sur les limites
|
||
|
int nb_info = (bloc.DimNom()-4)/2; // nombre de couples
|
||
|
// on passe en revue les noms s'ils existent, > 4
|
||
|
// on va de 2 en 2
|
||
|
for (int i=1;i<= nb_info;i++)
|
||
|
{if (bloc.Nom(3+i*2) == "beta_")
|
||
|
{pt_StabMembBiel->Change_beta(ChangeReel(bloc.Nom(4+i*2)));}
|
||
|
else if (bloc.Nom(3+i*2) == "f_mini_")
|
||
|
{pt_StabMembBiel->Change_f_mini(ChangeReel(bloc.Nom(4+i*2)));}
|
||
|
else if (bloc.Nom(3+i*2) == "d_maxi_")
|
||
|
{pt_StabMembBiel->Change_d_maxi(ChangeReel(bloc.Nom(4+i*2)));}
|
||
|
};
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
// cas de la définition d'un repère d'anisotropie
|
||
|
else if (bloc.Nom(1) == "repere_anisotropie_")
|
||
|
{// pour l'instant le repère d'anisotropie est éventuellement
|
||
|
// utilisable par la loi de comportement
|
||
|
// 1) tout d'abord on doit définir le repère au niveau de chaque point d'intégration
|
||
|
// définition d'un repère d'anisotropie à un point d'intégration
|
||
|
// ici on ne fait que définir les conteneurs, la définition exacte des repères
|
||
|
// ne se fera que pendant l'initialisation de l'algo et/ou pendant le calcul
|
||
|
int nb_pti = lesPtIntegMecaInterne->NbPti();
|
||
|
int dim = ParaGlob::Dimension();
|
||
|
Coordonnee u(dim);
|
||
|
Tableau <Coordonnee> tab_coor(dim,u);
|
||
|
|
||
|
for (int ni=1;ni<= nb_pti;ni++)
|
||
|
{// passage des infos
|
||
|
if (tabSaveDon(ni) != NULL)
|
||
|
tabSaveDon(ni)->Complete_SaveResul(bloc,tab_coor,loiComp);
|
||
|
};
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
// sinon rien
|
||
|
else
|
||
|
{ return NULL;};
|
||
|
};
|
||
|
|
||
|
// calcul de la contrainte modifiée en fonction du bulk viscosity
|
||
|
// ramène l'énergie par unité de volume, dépensée par le bulk
|
||
|
DeuxDoubles ElemMeca::ModifContrainteBulk(Enum_dure temps,const TenseurHH& gijHH,TenseurHH & sigHH
|
||
|
,const TenseurBB & DepsBB,TenseurHH & sigbulkHH )
|
||
|
{ DeuxDoubles ener_bulk_volumique; // pour le retour
|
||
|
// on calcul la trace du tenseur de vitesse de déformation
|
||
|
TenseurBH* DepsBH = NevezTenseurBH(DepsBB.Dimension());
|
||
|
(*DepsBH) = DepsBB * gijHH;
|
||
|
double IDeps = DepsBH->Trace();
|
||
|
// on intervient que si la trace est négative dans le cas où bulk_viscosity != 2
|
||
|
// ou dans tous les cas si == 2
|
||
|
if ((bulk_viscosity == 2) || (IDeps < 0.))
|
||
|
{ // calcul d'une longueur caractéristique de l'élément
|
||
|
// cout << "\n c_carreBulk" << c_carreBulk << " c_traceBulk" << c_traceBulk << endl;
|
||
|
double lon=this->LongueurGeometrique(1); // cas 1 pour l'instant
|
||
|
// on calcul la célérité
|
||
|
double cc = sqrt(ElemMeca::Calcul_maxi_E_qui(temps)/masse_volumique);
|
||
|
// calcul de la pression
|
||
|
//-- double q = masse_volumique * lon * ( c_carreBulk * lon * IDeps*IDeps + c_traceBulk * cc * IDeps );
|
||
|
//-- modification car il y a une erreur / à la théorique concernant le signe de c_carreBulk
|
||
|
double q = masse_volumique * lon * ( c_carreBulk * lon * IDeps*IDeps - c_traceBulk * cc * IDeps );
|
||
|
// calcul de la modification du tenseur sigHH
|
||
|
//-- sigHH += q * gijHH;
|
||
|
sigbulkHH = (-q) * gijHH;
|
||
|
//--- debug
|
||
|
//cout << "\n sigbulkHH= " << sigbulkHH(1,1) << " sigHH= " << sigHH(1,1)
|
||
|
// << " lon="<<lon<<" cc="<< cc<<" q="<<q << " IDeps= " << IDeps << endl;
|
||
|
//--- fin debug
|
||
|
sigHH += sigbulkHH;
|
||
|
// -- on calcul également l'énergie par unité de volume non réversible visqueuse dépensée
|
||
|
// on considère que la contrainte du bulk demeure constante sur l'incrément de temps
|
||
|
// recup de l'incrément de temps
|
||
|
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
|
||
|
ener_bulk_volumique.un = -q*IDeps*deltat;
|
||
|
ener_bulk_volumique.deux = -q*IDeps;
|
||
|
}
|
||
|
else
|
||
|
{ sigbulkHH.Inita(0.);}; // dans le cas où le bulk n'est pas activé on le met à 0
|
||
|
delete DepsBH;
|
||
|
LibereTenseur();
|
||
|
return ener_bulk_volumique;
|
||
|
};
|
||
|
|
||
|
// récupération de la base locales au noeud noe, pour le temps: temps
|
||
|
const BaseB & ElemMeca::Gib_elemeca(Enum_dure temps, const Noeud * noe)
|
||
|
{ int nb_noeud = tab_noeud.Taille(); // nombre de noeud de l'élément local
|
||
|
// on fait une rotation sur les noeuds de l'élément
|
||
|
int num=1;
|
||
|
for (num=1;num<= nb_noeud;num++)
|
||
|
{ if (noe == tab_noeud(num)) break; }
|
||
|
// récupération des coordonnées locales du noeud
|
||
|
ElemGeomC0& elem_geom = ElementGeometrique(); // recup de l'élément géométrique correspondant
|
||
|
// récup de la référence des coordonnées locales du noeud num
|
||
|
const Coordonnee & coo = elem_geom.PtelemRef()(num);
|
||
|
// calcul de la dérivée des fonctions au point
|
||
|
const Mat_pleine& ddphi = elem_geom.Dphi(coo);
|
||
|
const Vecteur& pphi = elem_geom.Phi(coo);
|
||
|
// en fonction du temps on calcul la base naturelle
|
||
|
switch (temps)
|
||
|
{ case TEMPS_0: return (met->BaseNat_0(tab_noeud,ddphi,pphi)); break;
|
||
|
case TEMPS_t: return (met->BaseNat_t(tab_noeud,ddphi,pphi)); break;
|
||
|
case TEMPS_tdt: return (met->BaseNat_tdt(tab_noeud,ddphi,pphi)); break;
|
||
|
};
|
||
|
// pour faire taire le compilateur
|
||
|
cout << "\n erreur, on ne devrait jamais passer ici"
|
||
|
<< "\n ElemMeca::Gib_elemeca(...";
|
||
|
Sortie(1);
|
||
|
BaseB *toto = new BaseB(0);
|
||
|
return (*toto);
|
||
|
};
|
||
|
|
||
|
// calcul du mini du module d'young équivalent pour tous les points d'intégrations
|
||
|
double ElemMeca::Calcul_mini_E_qui(Enum_dure temps)
|
||
|
{ double mini = 0.; // init
|
||
|
int ni;
|
||
|
for (def->PremierPtInteg(), ni = 1;def->DernierPtInteg();def->NevezPtInteg(),ni++)
|
||
|
{ def->ChangeNumInteg(ni);def->Mise_a_jour_data_specif(tabSaveDefDon(ni));
|
||
|
// si l'on a une thermo-dépendance il faut s'assurer que la température est mise à jour
|
||
|
loiComp->Mise_a_jour_temperature(temps,*def);
|
||
|
// indique également à la loi quelle valeur de saveResult il faut se référer
|
||
|
double E_equi = loiComp->Module_young_equivalent(temps,*def,tabSaveDon(ni));
|
||
|
if (E_equi < mini) mini = E_equi;
|
||
|
}
|
||
|
return mini;
|
||
|
};
|
||
|
|
||
|
// calcul du maxi du module d'young équivalent pour tous les points d'intégrations
|
||
|
double ElemMeca::Calcul_maxi_E_qui(Enum_dure temps)
|
||
|
{ double maxi = 0.; // init
|
||
|
int ni;
|
||
|
for (def->PremierPtInteg(), ni = 1;def->DernierPtInteg();def->NevezPtInteg(),ni++)
|
||
|
{ def->ChangeNumInteg(ni);def->Mise_a_jour_data_specif(tabSaveDefDon(ni));
|
||
|
// si l'on a une thermo-dépendance il faut s'assurer que la température est mise à jour
|
||
|
loiComp->Mise_a_jour_temperature(temps,*def);
|
||
|
|
||
|
double E_equi = loiComp->Module_young_equivalent(temps,*def,tabSaveDon(ni));
|
||
|
if (E_equi > maxi) maxi = E_equi;
|
||
|
}
|
||
|
return maxi;
|
||
|
};
|
||
|
|
||
|
|
||
|
// cas d'un chargement aero-hydrodynamique, sur les frontières de l'élément
|
||
|
// Il y a trois forces: une suivant la direction de la vitesse: de type traînée aerodynamique
|
||
|
// Fn = poids_volu * fn(V) * S * (normale*u) * u, u étant le vecteur directeur de V (donc unitaire)
|
||
|
// une suivant la direction normale à la vitesse de type portance
|
||
|
// Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire, normal à V, et dans le plan n et V
|
||
|
// une suivant la vitesse tangente de type frottement visqueux
|
||
|
// T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
// retourne le second membre résultant
|
||
|
// calcul à l'instant tdt ou t en fonction de la variable atdt
|
||
|
// coef_mul: est un coefficient multiplicateur global (de tout)
|
||
|
Vecteur& ElemMeca::SM_charge_hydrodyn_E (const double& poidvol,const Tableau <Vecteur>& taphi,int nbne
|
||
|
,Courbe1D* frot_fluid,const Vecteur& poids
|
||
|
,Courbe1D* coef_aero_n,int numfront,const double& coef_mul
|
||
|
,Courbe1D* coef_aero_t,const ParaAlgoControle & ,bool atdt)
|
||
|
{
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// *** dans l'ensemble du sp on utilise des vecteurs et on gére directement la variance
|
||
|
// *** sinon c'est intractable et long
|
||
|
// remarque: l'initialisation du résidu n'est pas fait ici, mais dans les routines appelants
|
||
|
Vecteur* SM_r;
|
||
|
int dime = ParaGlob::Dimension();
|
||
|
bool premier_calcul=true; // contrairement à la déformation, pas de sauvegarde
|
||
|
// donc il faut calculer tous les éléments de la métrique
|
||
|
switch (dime)
|
||
|
{case 3: // cas de la dimension 3
|
||
|
{ // définition du vecteur de retour
|
||
|
Vecteur& SM = *((*res_extS)(numfront));SM_r=&SM;
|
||
|
// dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit) return SM;
|
||
|
int ni; // compteur globale de point d'integration
|
||
|
Deformation & defS = *defSurf(numfront); // pour simplifier l'écriture
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
{if(ParaGlob::AxiSymetrie())
|
||
|
{lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbSe());}
|
||
|
else
|
||
|
{lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbFe());}
|
||
|
};
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != defS.Phi1_Taille())
|
||
|
tab_hydrodyna.Change_taille(defS.Phi1_Taille());
|
||
|
|
||
|
for (defS.PremierPtInteg(), ni = 1;defS.DernierPtInteg();defS.NevezPtInteg(),ni++)
|
||
|
{ // -- calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en explicit mais pour un calcul autre que mécanique
|
||
|
Met_abstraite::Expli ex;
|
||
|
if (atdt) {ex = (defS.Cal_explicit_tdt(premier_calcul)).Tdt_dans_t(); }
|
||
|
else {ex = defS.Cal_explicit_t(premier_calcul); };
|
||
|
// détermination de la normale à la surface qui vaut le produit vectoriel des 2 premiers vecteurs
|
||
|
// conversion explicite en coordonnées sans variance
|
||
|
Coordonnee normale = Util::ProdVec_coorBN( (*ex.giB_t)(1), (*ex.giB_t)(2));
|
||
|
// cout << "\n normale avant normalisation";
|
||
|
// normale.Affiche();
|
||
|
normale.Normer(); // on norme la normale
|
||
|
// cout << "\n normale après normalisation";
|
||
|
// normale.Affiche(); Sortie(1);
|
||
|
|
||
|
// récupération de la vitesse
|
||
|
const Coordonnee* Vp;
|
||
|
if (atdt) {Vp = &(defS.VitesseM_tdt());}
|
||
|
else {Vp = &(defS.VitesseM_t());};
|
||
|
const Coordonnee& V = *Vp; double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return SM;
|
||
|
Coordonnee Vt=V-(V*normale)*normale;// calcul de la vitesse tangente
|
||
|
double nVt = Vt.Norme(); // norme de la vitesse tangente
|
||
|
if (nVt < ConstMath::trespetit) { nVt=0.;Vt.Zero();} else {Vt /= nVt;}; // on norme la vitesse tangente
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
double cos_directeur = u * normale; // permet de calculer surface normale à la vitesse
|
||
|
Coordonnee w(3);
|
||
|
if (coef_aero_t != NULL)
|
||
|
{w = Util::ProdVec_coor(u,Util::ProdVec_coor( u, normale));
|
||
|
// si w est non nulle on le norme
|
||
|
double norme_w = w.Norme();
|
||
|
if (norme_w > ConstMath::trespetit) {w /= norme_w;};
|
||
|
};
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(ni); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1; int dimf = 3; // ne fonctionne qu'en dim 3
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
double coef_frot_fluid=0.;
|
||
|
if (frot_fluid != NULL) { coef_frot_fluid += frot_fluid->Valeur(nVt) * poids(ni) * (*ex.jacobien_t);
|
||
|
Fsauve.T += frot_fluid->Valeur(nVt) * Vt;};
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ coef_n += poidvol * coef_aero_n->Valeur(nV) * poids(ni) * (*ex.jacobien_t) * cos_directeur;
|
||
|
Fsauve.F_n += (poidvol * coef_aero_n->Valeur(nV) * cos_directeur) * u ;};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
double coef_t=0.;
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ coef_t += poidvol * coef_aero_t->Valeur(nV) * poids(ni) * (*ex.jacobien_t) * cos_directeur;
|
||
|
Fsauve.F_t += (poidvol * coef_aero_t->Valeur(nV) * cos_directeur) * w ;};
|
||
|
for (int ne =1; ne<= nbne; ne++)
|
||
|
for (int i=1;i<= dimf;i++,ix++)
|
||
|
{ SM(ix) += taphi(ni)(ne) * coef_mul * (coef_frot_fluid * Vt(i) + coef_n * u(i) + coef_t * w(i));};
|
||
|
} // fin boucle sur les points d'intégrations
|
||
|
break;
|
||
|
}; // fin du cas de la dimension 3
|
||
|
case 2: // cas de la dimension 2
|
||
|
{ // définition du vecteur de retour
|
||
|
Vecteur& SM = *((*res_extA)(numfront));SM_r=&SM;
|
||
|
// dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit) return SM;
|
||
|
int ni; // compteur globale de point d'integration
|
||
|
Deformation & defA = *defArete(numfront); // pour simplifier l'écriture
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbSe());
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != defA.Phi1_Taille())
|
||
|
tab_hydrodyna.Change_taille(defA.Phi1_Taille());
|
||
|
|
||
|
for (defA.PremierPtInteg(), ni = 1;defA.DernierPtInteg();defA.NevezPtInteg(),ni++)
|
||
|
{ // -- calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en explicit mais pour un calcul autre que mécanique
|
||
|
Met_abstraite::Expli ex;
|
||
|
if (atdt) {ex = (defA.Cal_explicit_tdt(premier_calcul)).Tdt_dans_t(); }
|
||
|
else {ex = defA.Cal_explicit_t(premier_calcul); };
|
||
|
// détermination de la normale à la surface qui vaut le vecteur perpendiculaire au g1
|
||
|
// dans le sens directe
|
||
|
Coordonnee normale; normale(1) = - (*ex.giB_t)(1)(2); normale(2) = (*ex.giB_t)(1)(1);
|
||
|
normale.Normer(); // on norme la normale
|
||
|
// récupération de la vitesse
|
||
|
const Coordonnee* Vp;
|
||
|
if (atdt) {Vp = &(defA.VitesseM_tdt());}
|
||
|
else {Vp = &(defA.VitesseM_t());};
|
||
|
const Coordonnee& V = *Vp; double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return SM;
|
||
|
Coordonnee Vt=V-(V*normale)*normale;// calcul de la vitesse tangente
|
||
|
double nVt = Vt.Norme(); // norme de la vitesse tangente
|
||
|
if (nVt < ConstMath::trespetit) { nVt=0.;Vt.Zero();} else {Vt /= nVt;}; // on norme la vitesse tangente
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
double cos_directeur = u * normale; // permet de calculer surface normale à la vitesse
|
||
|
Coordonnee w(dime); // comme on est en 2D w ce calcul directement avec les composantes de u
|
||
|
if (coef_aero_t != NULL) {w(1) = -u(2); w(2)=u(1);};
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(ni); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1;
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
double coef_frot_fluid=0.;
|
||
|
if (frot_fluid != NULL) { coef_frot_fluid += frot_fluid->Valeur(nVt) * poids(ni) * (*ex.jacobien_t);
|
||
|
Fsauve.T+=frot_fluid->Valeur(nVt) * Vt;};
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ coef_n += poidvol * coef_aero_n->Valeur(nV) * poids(ni) * (*ex.jacobien_t) * cos_directeur;
|
||
|
Fsauve.F_n += (poidvol * coef_aero_n->Valeur(nV) * cos_directeur) * u ;};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
double coef_t=0.;
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ coef_t += poidvol * coef_aero_t->Valeur(nV) * poids(ni) * (*ex.jacobien_t) * cos_directeur;
|
||
|
Fsauve.F_t += (poidvol * coef_aero_t->Valeur(nV) * cos_directeur) * w ;};
|
||
|
for (int ne =1; ne<= nbne; ne++)
|
||
|
for (int i=1;i<= dime;i++,ix++)
|
||
|
{ SM(ix) += taphi(ni)(ne) * coef_mul * (coef_frot_fluid * Vt(i) + coef_n * u(i) + coef_t * w(i));};
|
||
|
} // fin boucle sur les points d'intégrations
|
||
|
} // fin boucle sur les points d'intégrations
|
||
|
break;
|
||
|
case 1: // cas de la dimension 1
|
||
|
{ // définition du vecteur de retour
|
||
|
Vecteur& SM = *((*res_extN)(numfront));SM_r=&SM;
|
||
|
// dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit) return SM;
|
||
|
// il n'y a pas plusieurs point d'intégration
|
||
|
// en 1D il ne peut y avoir que deux extrémités, la première à une normale = -1 , la seconde 1
|
||
|
Coordonnee normale(1); if (numfront == 1) {normale(1)=-1.;} else {normale(1)=1.;};
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
lesChargeExtSurEle->LesHydroDyna_Change_taille(2); // car deux extrémités au plus
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != 1)
|
||
|
tab_hydrodyna.Change_taille(1); // un seul point d'intégration en un point !
|
||
|
|
||
|
// récupération de la vitesse
|
||
|
const Coordonnee* Vp;
|
||
|
Noeud* noe = (tabb(posi_tab_front_point+numfront)->TabNoeud())(1); // on récupére tout d'abord le noeud fontière
|
||
|
if (atdt) {Vp = &(def->VitesseM_tdt(noe));} // on utilise la déformation générale, qui convient pour un noeud
|
||
|
else {Vp = &(def->VitesseM_t(noe));};
|
||
|
const Coordonnee& V = *Vp; double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return SM;
|
||
|
// dans le cas 1D il n'y a qu'un effort de trainée (car pas de vitesse tangente)
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
// inutile double cos_directeur = u * normale; // permet de calculer surface normale à la vitesse
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(1); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1; int dimf = dime;
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL) // le poids(1) contiend la section, et il n'y a pas de jacobien, cos directeur = 1
|
||
|
{ coef_n += poidvol * coef_aero_n->Valeur(nV) * poids(1) ;
|
||
|
Fsauve.F_n += (poidvol * coef_aero_n->Valeur(nV) ) * u ;};
|
||
|
for (int ne =1; ne<= nbne; ne++) // il n'y qu'un point d'intégration le noeud lui-même
|
||
|
for (int i=1;i<= dimf;i++,ix++)
|
||
|
{ SM(ix) += taphi(1)(ne) * coef_mul * ( coef_n * u(i) );};
|
||
|
break;
|
||
|
}; // fin du cas de la dimension 1 */
|
||
|
|
||
|
}; //-- fin du switch sur la dimension
|
||
|
// retour du second membre
|
||
|
return *SM_r;
|
||
|
};
|
||
|
|
||
|
// idem SM_charge_hydrodyn_E mais -> implicite,
|
||
|
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
|
||
|
// retourne le second membre et la matrice de raideur correspondant
|
||
|
// coef_mul: est un coefficient multiplicateur global (de tout)
|
||
|
Element::ResRaid ElemMeca::SM_charge_hydrodyn_I (const double& poidvol,const Tableau <Vecteur>& taphi,int nbne
|
||
|
,Courbe1D* frot_fluid,const Vecteur& poids,DdlElement & ddls
|
||
|
,Courbe1D* coef_aero_n,int numfront,const double& coef_mul
|
||
|
,Courbe1D* coef_aero_t,const ParaAlgoControle & pa)
|
||
|
{
|
||
|
|
||
|
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
//****************** attention voir w non normé pour les dimensions 2 et 1 ****************
|
||
|
|
||
|
|
||
|
// *** dans l'ensemble du sp on utilise des vecteurs et on gére directement la variance
|
||
|
// *** sinon c'est intractable et long
|
||
|
// remarque: l'initialisation du résidu n'est pas fait ici, mais dans les routines appelants
|
||
|
Element::ResRaid el;
|
||
|
int nbddl = ddls.NbDdl();
|
||
|
bool avec_raid = pa.Var_charge_externe(); // controle
|
||
|
// // dans le cas où la variation sur la raideur est demandé on s'assure que la variation
|
||
|
// // du jacobien est bien effective sinon on l'impose
|
||
|
// ParaAlgoControle pa_nevez(pa);
|
||
|
// if (!pa_nevez.Var_jacobien()) pa_nevez.Modif_Var_jacobien(true);
|
||
|
int dime = ParaGlob::Dimension();
|
||
|
bool premier_calcul=true; // contrairement à la déformation, pas de sauvegarde
|
||
|
// donc il faut calculer tous les éléments de la métrique
|
||
|
switch (dime)
|
||
|
{case 3: // cas de la dimension 3
|
||
|
{ // dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit)
|
||
|
{ el.res = (*res_extS)(numfront); el.raid = (*raid_extS)(numfront);
|
||
|
return el;
|
||
|
};
|
||
|
Vecteur& SM = (*((*res_extS)(numfront))); // pour simplifier
|
||
|
Mat_pleine & KM = (*((*raid_extS)(numfront))); // " " "
|
||
|
el.res = (*res_extS)(numfront); el.raid = (*raid_extS)(numfront); // pour le retour
|
||
|
int ni; // compteur globale de point d'integration
|
||
|
Deformation & defS = *defSurf(numfront); // pour simplifier l'écriture
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
{if(ParaGlob::AxiSymetrie())
|
||
|
{lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbSe());}
|
||
|
else
|
||
|
{lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbFe());}
|
||
|
};
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != defS.Phi1_Taille())
|
||
|
tab_hydrodyna.Change_taille(defS.Phi1_Taille());
|
||
|
|
||
|
for (defS.PremierPtInteg(), ni = 1;defS.DernierPtInteg();defS.NevezPtInteg(),ni++)
|
||
|
{ // -- calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en implicit mais pour un calcul autre que mécanique
|
||
|
const Met_abstraite::Impli& ex = defS.Cal_implicit(premier_calcul);
|
||
|
// détermination de la normale à la surface qui vaut le produit vectoriel des 2 premiers vecteurs
|
||
|
Coordonnee normale = Util::ProdVec_coorBN( (*ex.giB_tdt)(1), (*ex.giB_tdt)(2));
|
||
|
normale.Normer(); // on norme la normale
|
||
|
// récupération de la vitesse
|
||
|
const Coordonnee V = defS.VitesseM_tdt(); double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return el;
|
||
|
Coordonnee Vt=V-(V*normale)*normale;// calcul de la vitesse tangente
|
||
|
double nVt = Vt.Norme(); // norme de la vitesse tangente
|
||
|
if (nVt < ConstMath::trespetit) { nVt=0.;Vt.Zero();} else {Vt /= nVt;}; // on norme la vitesse tangente
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
double cos_directeur = u * normale; // permet de calculer surface normale à la vitesse
|
||
|
Coordonnee w(3);double norme_w=0.;
|
||
|
Coordonnee vecNul(3); // un vecteur nul pour l'initialisation
|
||
|
if (coef_aero_t != NULL)
|
||
|
{w = Util::ProdVec_coor(u,Util::ProdVec_coor( u, normale));
|
||
|
// si w est non nulle on le norme
|
||
|
norme_w = w.Norme();
|
||
|
if (norme_w > ConstMath::trespetit) {w /= norme_w;};
|
||
|
};
|
||
|
// calcul éventuel des variations
|
||
|
static Tableau <Coordonnee> D_Vt,D_u,D_w,D_w_non_normer;
|
||
|
static Tableau <double> D_coef_frot_fluid,D_coef_n,D_coef_t;
|
||
|
if (avec_raid)
|
||
|
{ // calcul de la variation de la normale
|
||
|
// 1) variation du produit vectoriel
|
||
|
Tableau <Coordonnee > D_pasnormale =
|
||
|
Util::VarProdVect_coor((*ex.giB_tdt)(1).Coor(),(*ex.giB_tdt)(2).Coor(),(*ex.d_giB_tdt));
|
||
|
// 2) de la normale
|
||
|
Tableau <Coordonnee> D_normale = Util::VarUnVect_coor(normale,D_pasnormale,normale.Norme());
|
||
|
// récupération de la variation de vitesse
|
||
|
bool ddl_vitesse;
|
||
|
const Tableau <Coordonnee> D_V = defS.Der_VitesseM_tdt(ddl_vitesse);
|
||
|
D_Vt.Change_taille(nbddl); // calcul de la variation de la vitesse tangente
|
||
|
for (int ii=1;ii<=nbddl;ii++)
|
||
|
{D_Vt(ii)=D_V(ii) - (D_V(ii) * normale + V * D_normale(ii)) * normale
|
||
|
- (V*normale) * D_normale(ii);};
|
||
|
// variation de u
|
||
|
D_u.Change_taille(nbddl); D_u = Util::VarUnVect_coor( V, D_V,nV);
|
||
|
// variation de la norme de V
|
||
|
Tableau <double> D_nV = Util::VarNorme(D_V,V,nV);
|
||
|
// variation de w s'il a une norme différente de 0
|
||
|
D_w.Change_taille(nbddl,vecNul); // !! init obligatoire car peut ne pas rentrer dans les if qui suivent
|
||
|
if (norme_w > ConstMath::trespetit)
|
||
|
{if (coef_aero_t != NULL)
|
||
|
{ D_w_non_normer.Change_taille(nbddl);
|
||
|
// tout d'abord la variation du produit vectoriel
|
||
|
Coordonnee k = Util::ProdVec_coor( u, normale);
|
||
|
Tableau <Coordonnee> D_k = Util::VarProdVect_coor(u,normale,D_u,D_normale);
|
||
|
D_w_non_normer=Util::VarProdVect_coor(u,k,D_u,D_k);
|
||
|
D_w = Util::VarUnVect_coor(w,D_w_non_normer,norme_w);
|
||
|
}
|
||
|
};
|
||
|
// variation des coefficients
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
D_coef_frot_fluid.Change_taille(nbddl);
|
||
|
if (frot_fluid != NULL)
|
||
|
{ Courbe1D::ValDer valder = frot_fluid->Valeur_Et_derivee(nVt);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_frot_fluid(i) = valder.derivee * D_nV(i) * poids(ni) * (*ex.jacobien_tdt)
|
||
|
+ valder.valeur * poids(ni) * (*ex.d_jacobien_tdt)(i);
|
||
|
};
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
D_coef_n.Change_taille(nbddl);
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ Courbe1D::ValDer valder = coef_aero_n->Valeur_Et_derivee(nV);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_n(i) = poidvol * poids(ni) * (
|
||
|
valder.derivee * D_nV(i) * (*ex.jacobien_tdt) * cos_directeur
|
||
|
+ valder.valeur * (*ex.d_jacobien_tdt)(i) * cos_directeur
|
||
|
+ valder.valeur * (*ex.jacobien_tdt) * (D_u(i) * normale + u * D_normale(i))
|
||
|
);
|
||
|
};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
D_coef_t.Change_taille(nbddl);
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ Courbe1D::ValDer valder = coef_aero_t->Valeur_Et_derivee(nV);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_t(i) = poidvol * poids(ni) * (
|
||
|
valder.derivee * D_nV(i) * (*ex.jacobien_tdt) * cos_directeur
|
||
|
+ valder.valeur * (*ex.d_jacobien_tdt)(i) * cos_directeur
|
||
|
+ valder.valeur * (*ex.jacobien_tdt) * (D_u(i) * normale + u * D_normale(i))
|
||
|
);
|
||
|
};
|
||
|
}; //-- fin du if (avec_raid)
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(ni); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1; int dimf = 3; // ne fonctionne qu'en dim 3
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
double coef_frot_fluid=0.;
|
||
|
if (frot_fluid != NULL) { coef_frot_fluid += frot_fluid->Valeur(nVt) * poids(ni) * (*ex.jacobien_tdt);
|
||
|
Fsauve.T += frot_fluid->Valeur(nVt) * Vt;};
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ coef_n += poidvol * coef_aero_n->Valeur(nV) * poids(ni) * (*ex.jacobien_tdt) * cos_directeur;
|
||
|
Fsauve.F_n += (poidvol * coef_aero_n->Valeur(nV) * cos_directeur) * u ;};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
double coef_t=0.;
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ coef_t += poidvol * coef_aero_t->Valeur(nV) * poids(ni) * (*ex.jacobien_tdt) * cos_directeur;
|
||
|
Fsauve.F_t += (poidvol * coef_aero_t->Valeur(nV) * cos_directeur) * w ;};
|
||
|
for (int ne =1; ne<= nbne; ne++)
|
||
|
for (int i=1;i<= dimf;i++,ix++)
|
||
|
{ SM(ix) += taphi(ni)(ne) * coef_mul * (coef_frot_fluid * Vt(i) + coef_n * u(i) + coef_t * w(i));
|
||
|
if (avec_raid)
|
||
|
{for (int j =1; j<= nbddl; j++)
|
||
|
{ //cout << "\n taphi(ni)(ne)= " << taphi(ni)(ne) << endl;
|
||
|
//cout << "\n D_coef_frot_fluid(j) " << D_coef_frot_fluid(j) << endl;
|
||
|
//cout << "\n Vt(i) " << Vt(i) << endl;
|
||
|
//cout << "\n D_Vt(j)(i) " << D_Vt(j)(i) << endl;
|
||
|
//cout << "\n D_coef_n(j) " << D_coef_n(j) << endl;
|
||
|
//cout << "\n u(i) " << u(i) << endl;
|
||
|
//cout << "\n D_u(j)(i) " << D_u(j)(i) << endl;
|
||
|
//cout << "\n D_coef_t(j) " << D_coef_t(j) << endl;
|
||
|
//cout << "\n w(i) " << w(i) << endl;
|
||
|
//cout << "\n D_w(j)(i) " << D_w(j)(i) << endl;
|
||
|
|
||
|
KM(ix,j) -= taphi(ni)(ne) * coef_mul *(
|
||
|
D_coef_frot_fluid(j) * Vt(i) + coef_frot_fluid * D_Vt(j)(i)
|
||
|
+ D_coef_n(j) * u(i) + coef_n * D_u(j)(i)
|
||
|
+ D_coef_t(j) * w(i) + coef_t * D_w(j)(i)
|
||
|
);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
} // fin boucle sur les points d'intégrations
|
||
|
break;
|
||
|
}; // fin du cas de la dimension 3
|
||
|
case 2: // cas de la dimension 2
|
||
|
{ // dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit)
|
||
|
{ el.res = (*res_extS)(numfront); el.raid = (*raid_extS)(numfront);
|
||
|
return el;
|
||
|
};
|
||
|
Vecteur& SM = (*((*res_extA)(numfront))); // pour simplifier
|
||
|
Mat_pleine & KM = (*((*raid_extA)(numfront))); // " " "
|
||
|
el.res = (*res_extA)(numfront); el.raid = (*raid_extA)(numfront); // pour le retour
|
||
|
int ni; // compteur globale de point d'integration
|
||
|
Deformation & defA = *defArete(numfront); // pour simplifier l'écriture
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
lesChargeExtSurEle->LesHydroDyna_Change_taille(ElementGeometrique().NbSe());
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != defA.Phi1_Taille())
|
||
|
tab_hydrodyna.Change_taille(defA.Phi1_Taille());
|
||
|
|
||
|
for (defA.PremierPtInteg(), ni = 1;defA.DernierPtInteg();defA.NevezPtInteg(),ni++)
|
||
|
{ // -- calcul des éléments de la métrique, entre autre le jacobien, on utilise le même calcul
|
||
|
// que pour un calcul primaire en explicit mais pour un calcul autre que mécanique
|
||
|
const Met_abstraite::Impli& ex = defA.Cal_implicit(premier_calcul);
|
||
|
// détermination de la normale à la surface qui vaut le vecteur perpendiculaire au g1
|
||
|
// dans le sens directe
|
||
|
Coordonnee normale; normale(1) = -(*ex.giB_tdt)(1)(2); normale(2) = (*ex.giB_tdt)(1)(1);
|
||
|
normale.Normer(); // on norme la normale
|
||
|
// récupération de la vitesse
|
||
|
const Coordonnee V = defA.VitesseM_tdt(); double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return el;
|
||
|
Coordonnee Vt=V-(V*normale)*normale;// calcul de la vitesse tangente
|
||
|
double nVt = Vt.Norme(); // norme de la vitesse tangente
|
||
|
if (nVt < ConstMath::trespetit) { nVt=0.;Vt.Zero();} else {Vt /= nVt;}; // on norme la vitesse tangente
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
double cos_directeur = u * normale; // permet de calculer surface normale à la vitesse
|
||
|
Coordonnee w(dime); // comme on est en 2D, w ce calcul directement avec les composantes de u
|
||
|
if (coef_aero_t != NULL) {w(1) = -u(2); w(2)=u(1);};
|
||
|
// calcul éventuel des variations
|
||
|
static Tableau <Coordonnee> D_Vt,D_u,D_w;
|
||
|
static Tableau <double> D_coef_frot_fluid,D_coef_n,D_coef_t;
|
||
|
if (avec_raid)
|
||
|
{ // calcul de la variation de la normale
|
||
|
// 1) variation du produit vectoriel
|
||
|
Tableau <Coordonnee > D_pasnormale(nbddl);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
{D_pasnormale(i)(1) = -(*ex.d_giB_tdt)(i)(1)(2); D_pasnormale(i)(2) = (*ex.d_giB_tdt)(i)(1)(1);};
|
||
|
// 2) de la normale
|
||
|
Tableau <Coordonnee> D_normale = Util::VarUnVect_coor(normale,D_pasnormale,normale.Norme());
|
||
|
// récupération de la variation de vitesse
|
||
|
bool ddl_vitesse;
|
||
|
const Tableau <Coordonnee> D_V = defA.Der_VitesseM_tdt(ddl_vitesse);
|
||
|
D_Vt.Change_taille(nbddl); // calcul de la variation de la vitesse tangente
|
||
|
for (int ii=1;ii<=nbddl;ii++)
|
||
|
{D_Vt(ii)=D_V(ii) - (D_V(ii) * normale + V * D_normale(ii)) * normale
|
||
|
- (V*normale) * D_normale(ii);};
|
||
|
// variation de u
|
||
|
D_u.Change_taille(nbddl); D_u = Util::VarUnVect_coor( V, D_V,nV);
|
||
|
// variation de la norme de V
|
||
|
Tableau <double> D_nV = Util::VarNorme(D_V,V,nV);
|
||
|
// variation de w
|
||
|
D_w.Change_taille(nbddl);
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ for (int i=1;i<=nbddl;i++) {D_w(i)(1)=-D_u(i)(2);D_w(i)(2)=D_u(i)(1);};
|
||
|
}
|
||
|
// variation des coefficients
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
D_coef_frot_fluid.Change_taille(nbddl);
|
||
|
if (frot_fluid != NULL)
|
||
|
{ Courbe1D::ValDer valder = frot_fluid->Valeur_Et_derivee(nVt);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_frot_fluid(i) = valder.derivee * D_nV(i) * poids(ni) * (*ex.jacobien_tdt)
|
||
|
+ valder.valeur * poids(ni) * (*ex.d_jacobien_tdt)(i);
|
||
|
};
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
D_coef_n.Change_taille(nbddl);
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ Courbe1D::ValDer valder = coef_aero_n->Valeur_Et_derivee(nV);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_n(i) = poidvol * poids(ni) * (
|
||
|
valder.derivee * D_nV(i) * (*ex.jacobien_tdt) * cos_directeur
|
||
|
+ valder.valeur * (*ex.d_jacobien_tdt)(i) * cos_directeur
|
||
|
+ valder.valeur * (*ex.jacobien_tdt) * (D_u(i) * normale + u * D_normale(i))
|
||
|
);
|
||
|
};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
D_coef_t.Change_taille(nbddl);
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ Courbe1D::ValDer valder = coef_aero_t->Valeur_Et_derivee(nV);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_t(i) = poidvol * poids(ni) * (
|
||
|
valder.derivee * D_nV(i) * (*ex.jacobien_tdt) * cos_directeur
|
||
|
+ valder.valeur * (*ex.d_jacobien_tdt)(i) * cos_directeur
|
||
|
+ valder.valeur * (*ex.jacobien_tdt) * (D_u(i) * normale + u * D_normale(i))
|
||
|
);
|
||
|
};
|
||
|
}; //-- fin du if (avec_raid)
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(ni); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1;
|
||
|
// cas de T: T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
|
||
|
double coef_frot_fluid=0.;
|
||
|
if (frot_fluid != NULL) { coef_frot_fluid += frot_fluid->Valeur(nVt) * poids(ni) * (*ex.jacobien_tdt);
|
||
|
Fsauve.T+=frot_fluid->Valeur(nVt) * Vt;};
|
||
|
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ coef_n += poidvol * coef_aero_n->Valeur(nV) * poids(ni) * (*ex.jacobien_tdt) * cos_directeur;
|
||
|
Fsauve.F_n += (poidvol * coef_aero_n->Valeur(nV) * cos_directeur) * u ;};
|
||
|
// cas de Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire suivant la normal à V
|
||
|
double coef_t=0.;
|
||
|
if (coef_aero_t != NULL)
|
||
|
{ coef_t += poidvol * coef_aero_t->Valeur(nV) * poids(ni) * (*ex.jacobien_tdt) * cos_directeur;
|
||
|
Fsauve.F_t += (poidvol * coef_aero_t->Valeur(nV) * cos_directeur) * w ;};
|
||
|
for (int ne =1; ne<= nbne; ne++)
|
||
|
for (int i=1;i<= dime;i++,ix++)
|
||
|
{ SM(ix) += taphi(ni)(ne) * coef_mul * (coef_frot_fluid * Vt(i) + coef_n * u(i) + coef_t * w(i));
|
||
|
if (avec_raid)
|
||
|
{for (int j =1; j<= nbddl; j++)
|
||
|
{KM(ix,j) -= taphi(ni)(ne) * coef_mul * (
|
||
|
D_coef_frot_fluid(j) * Vt(i) + coef_frot_fluid * D_Vt(j)(i)
|
||
|
+ D_coef_n(j) * u(i) + coef_n * D_u(j)(i)
|
||
|
+ D_coef_t(j) * w(i) + coef_t * D_w(j)(i)
|
||
|
);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
} // fin boucle sur les points d'intégrations
|
||
|
break;
|
||
|
};
|
||
|
case 1: // cas de la dimension 1
|
||
|
{ // dans le cas ou le poid volumique est nul, on retourne sans calcul
|
||
|
if (Dabs(poidvol) < ConstMath::trespetit)
|
||
|
{ Element::ResRaid el;
|
||
|
el.res = (*res_extN)(numfront);
|
||
|
el.raid = (*raid_extN)(numfront);
|
||
|
return el;
|
||
|
};
|
||
|
Vecteur& SM = (*((*res_extN)(numfront))); // pour simplifier
|
||
|
Mat_pleine & KM = (*((*raid_extN)(numfront))); // " " "
|
||
|
el.res = (*res_extN)(numfront); el.raid = (*raid_extN)(numfront); // pour le retour
|
||
|
// il n'y a pas plusieurs point d'intégration
|
||
|
// en 1D il ne peut y avoir que deux extrémités, la première à une normale = -1 , la seconde 1
|
||
|
Coordonnee normale(1); if (numfront == 1) {normale(1)=-1.;} else {normale(1)=1.;};
|
||
|
|
||
|
// éventuellement dimensionnement de la sauvegarde
|
||
|
if (lesChargeExtSurEle == NULL)
|
||
|
lesChargeExtSurEle = new LesChargeExtSurElement;
|
||
|
if (lesChargeExtSurEle->LesHydroDyna() == NULL)
|
||
|
lesChargeExtSurEle->LesHydroDyna_Change_taille(2); // car deux extrémités au plus
|
||
|
Tableau <Force_hydroDyna>& tab_hydrodyna= (*lesChargeExtSurEle->LesHydroDyna())(numfront); // pour simplifier
|
||
|
if (tab_hydrodyna.Taille() != 1)
|
||
|
tab_hydrodyna.Change_taille(1); // un seul point d'intégration en un point !
|
||
|
|
||
|
// récupération de la vitesse
|
||
|
Noeud* noe = (tabb(posi_tab_front_point+numfront)->TabNoeud())(1); // on récupére tout d'abord le noeud fontière
|
||
|
const Coordonnee& V = def->VitesseM_tdt(noe); double nV = V.Norme();
|
||
|
// dans le cas où la vitesse est trop faible, le résidu est nul
|
||
|
if (nV < ConstMath::trespetit) return el;
|
||
|
// dans le cas 1D il n'y a qu'un effort de trainée (car pas de vitesse tangente)
|
||
|
Coordonnee u= V / nV; // on norme la vitesse, car ensuite on n'a besoin que de la direction unitaire de la vitesse
|
||
|
// u en fait = 1 ou -1 d'où variation = 0
|
||
|
// calcul éventuel des variations
|
||
|
static Tableau <double> D_coef_n;
|
||
|
if (avec_raid)
|
||
|
{ // calcul de la variation de la normale
|
||
|
// récupération de la variation de vitesse
|
||
|
bool ddl_vitesse;
|
||
|
const Tableau <Coordonnee> D_V = def->Der_VitesseM_tdt(ddl_vitesse,noe);
|
||
|
// variation de la norme de V
|
||
|
Tableau <double> D_nV = Util::VarNorme(D_V,V,nV);
|
||
|
// variation des coefficients
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
D_coef_n.Change_taille(nbddl);
|
||
|
if (coef_aero_n != NULL)
|
||
|
{ Courbe1D::ValDer valder = coef_aero_n->Valeur_Et_derivee(nV);
|
||
|
for (int i=1;i<=nbddl;i++)
|
||
|
D_coef_n(i) = poidvol * poids(1) * valder.derivee * D_nV(i);
|
||
|
};
|
||
|
}; //-- fin du if (avec_raid)
|
||
|
Force_hydroDyna& Fsauve = tab_hydrodyna(1); // pour simplifier la sauvegarde
|
||
|
// calcul du résidu
|
||
|
int ix=1; int dimf = dime;
|
||
|
// cas de Fn = poids_volu * fn(V) * S * (normale*u) * u, u unitaire suivant V
|
||
|
double coef_n=0.;
|
||
|
if (coef_aero_n != NULL) // le poids(1) contiend la section, et il n'y a pas de jacobien, cos directeur = 1
|
||
|
{ coef_n += poidvol * coef_mul * coef_aero_n->Valeur(nV) * poids(1) ;
|
||
|
Fsauve.F_n = (poidvol * coef_aero_n->Valeur(nV) ) * u ;};
|
||
|
for (int ne =1; ne<= nbne; ne++) // il n'y qu'un point d'intégration le noeud lui-même
|
||
|
for (int i=1;i<= dimf;i++,ix++)
|
||
|
{ SM(ix) += taphi(1)(ne) * ( coef_n * u(i) );
|
||
|
if (avec_raid)
|
||
|
{for (int j =1; j<= nbddl; j++)
|
||
|
{KM(ix,j) -= taphi(1)(ne) * coef_mul * (D_coef_n(j) * u(i));};
|
||
|
};
|
||
|
};
|
||
|
break;
|
||
|
}; // fin du cas de la dimension 1 */
|
||
|
|
||
|
}; //-- fin du switch sur la dimension
|
||
|
// retour
|
||
|
return el;
|
||
|
};
|
||
|
|