2021-09-27 12:42:13 +02:00
|
|
|
// FICHIER : SfeMembT.cc
|
|
|
|
// CLASSE : SfeMembT
|
|
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-27 12:42:13 +02:00
|
|
|
// 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 <iostream>
|
|
|
|
using namespace std; //introduces namespace std
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "Sortie.h"
|
|
|
|
#include "MathUtil.h"
|
|
|
|
|
|
|
|
#include "SfeMembT.h"
|
|
|
|
#include "TypeConsTens.h"
|
|
|
|
#include "FrontPointF.h"
|
|
|
|
#include "Loi_Umat.h"
|
|
|
|
#include "ExceptionsElemMeca.h"
|
|
|
|
|
|
|
|
// cas d'un chargement volumique,
|
|
|
|
// force indique la force volumique appliquée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// ici on considère l'épaisseur de l'élément pour constituer le volume
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_volumique_E
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,bool atdt,const ParaAlgoControle & pa,bool sur_volume_finale_)
|
|
|
|
{ SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// on se sert d'un calcul surfacique, en partant du principe que la force de volume est identique dans toute l'épaisseur
|
|
|
|
// seule la géométrie peut changer, dans l'épaisseur, on n'en tiend pas compte
|
|
|
|
|
|
|
|
// 1-- on calcul sur la surface -----
|
|
|
|
// initialisation du vecteur résidu de surface, que l'on va utiliser comme variable intermédiaire de stockage
|
|
|
|
// définition du vecteur de retour
|
|
|
|
// initialisation du résidu
|
|
|
|
residu->Zero();
|
|
|
|
Vecteur& SM = *residu;
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
// on pourrait utiliser la métrique des éléments de frontière avec l'instance déformation dédiée pour
|
|
|
|
// mais on utilise celle de l'élément
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if ( unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{if ( unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
Deformation & defS = *defSurf(1); // pour simplifier l'écriture
|
|
|
|
bool premier_calcul=true; // contrairement à la déformation, pas de sauvegarde
|
|
|
|
// donc il faut calculer tous les éléments de la métrique
|
|
|
|
// on boucle sur les pt d'integ de l'élément centrale
|
|
|
|
for (int ni=1; ni <= nombre->nbis;ni++)
|
|
|
|
{ const Tableau <Vecteur>& taphi = CoSfe->eleCentre->TaPhi(); // pour simplifier
|
|
|
|
const Vecteur& poids = CoSfe->eleCentre->TaWi(); // pour simplifier
|
|
|
|
defS.ChangeNumInteg(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
|
|
|
|
double jacobien;
|
|
|
|
if (atdt)
|
|
|
|
{ const Met_abstraite::Expli_t_tdt& ex = defS.Cal_explicit_tdt(premier_calcul);
|
|
|
|
if (sur_volume_finale_) {jacobien = (*ex.jacobien_tdt);}
|
|
|
|
else {jacobien = (*ex.jacobien_0);};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ const Met_abstraite::Expli& ex = defS.Cal_explicit_t(premier_calcul);
|
|
|
|
if (sur_volume_finale_) {jacobien = (*ex.jacobien_t);}
|
|
|
|
else {jacobien = (*ex.jacobien_0);};
|
|
|
|
};
|
|
|
|
// récup de l'épaisseur
|
|
|
|
double epais_courant = 0.;
|
|
|
|
if (donnee_specif.epais != NULL)
|
|
|
|
// multiplié par l'épaisseur pour avoir le volume dans le cas d'élément 2D
|
|
|
|
{ if (atdt) { epais_courant = donnee_specif.epais->epaisseur_tdt;}
|
|
|
|
else { epais_courant = donnee_specif.epais->epaisseur_t;};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ if (atdt) { epais_courant = defSurf(1)->DonneeInterpoleeScalaire(EPAIS,TEMPS_tdt);}
|
|
|
|
else { epais_courant = defSurf(1)->DonneeInterpoleeScalaire(EPAIS,TEMPS_t);};
|
|
|
|
};
|
|
|
|
// calcul de la contribution: il faut tenir compte que l'on peut avoir un ddl d'épaisseur
|
|
|
|
// or ici on ne considère que la contribution relativement au ddl de déplacement primaire
|
|
|
|
// par contre pour chaque DdlNoeudElement on commence par les ddl de déplacement des noeuds
|
|
|
|
int dimf = force.Dimension();
|
|
|
|
int decal_x =0; // décalage
|
|
|
|
for (int ne =1; ne<= nombre->nbnce; ne++)
|
|
|
|
{for (int i=1;i<= dimf;i++)
|
|
|
|
SM(i+decal_x) += taphi(ni)(ne)* force(i) * (poids(ni) * jacobien * epais_courant);
|
|
|
|
decal_x += CoSfe->tab_ddl.NbDdl(ne);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// liberation des tenseurs intermediaires
|
|
|
|
LibereTenseur();
|
|
|
|
// retour du second membre
|
|
|
|
return SM;
|
|
|
|
};
|
|
|
|
|
|
|
|
// calcul des seconds membres suivant les chargements
|
|
|
|
// cas d'un chargement volumique,
|
|
|
|
// force indique la force volumique appliquée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// ici on l'épaisseur de l'élément pour constituer le volume -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_volumique_I
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,const ParaAlgoControle & pa,bool sur_volume_finale_)
|
|
|
|
{ residu->Zero(); // initialisation du résidu
|
|
|
|
raideur->Zero(); // initialisation de la raideur
|
|
|
|
Vecteur& SM = *residu;
|
|
|
|
Mat_pleine & KM = *raideur;
|
|
|
|
// on se sert d'un calcul surfacique, en partant du principe que la force de volume est identique dans toute l'épaisseur
|
|
|
|
// seule la géométrie peut changer, dans l'épaisseur, on n'en tiend pas compte
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if ( unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
CoSfe->met_surf_cent.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
// controle
|
|
|
|
bool avec_raid = pa.Var_charge_externe();
|
|
|
|
// // 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, par contre on ne tient pas compte de la variation
|
|
|
|
// // des épaisseurs même si c'est un ddl (car on suppose qu'a priori cela n'a pas d'importance (?) )
|
|
|
|
// ParaAlgoControle pa_nevez(pa);
|
|
|
|
// if (!pa_nevez.Var_jacobien()) pa_nevez.Modif_Var_jacobien(true);
|
|
|
|
// la déformation surfacique est définit par défaut
|
|
|
|
Deformation & defS = *defSurf(1); // pour simplifier l'écriture
|
|
|
|
bool premier_calcul=true; // contrairement à la déformation, pas de sauvegarde
|
|
|
|
// donc il faut calculer tous les éléments de la métrique
|
|
|
|
// on boucle sur les pt d'integ de l'élément centrale
|
|
|
|
for (int ni=1; ni <= nombre->nbis;ni++)
|
|
|
|
{ const Tableau <Vecteur>& taphi = CoSfe->eleCentre->TaPhi(); // pour simplifier
|
|
|
|
const Vecteur& poids = CoSfe->eleCentre->TaWi(); // pour simplifier
|
|
|
|
defS.ChangeNumInteg(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
|
|
|
|
const Met_abstraite::Impli& ex = defS.Cal_implicit(premier_calcul);
|
|
|
|
// récup de l'épaisseur
|
|
|
|
double epais_courant = 0.;
|
|
|
|
if (donnee_specif.epais != NULL)
|
|
|
|
{ epais_courant = donnee_specif.epais->epaisseur_tdt;}
|
|
|
|
else
|
|
|
|
{ epais_courant = defSurf(1)->DonneeInterpoleeScalaire(EPAIS,TEMPS_tdt);};
|
|
|
|
// on regarde si éventuellement on voudrait calculer sur le volume initial
|
|
|
|
double jacobien=0.;
|
|
|
|
if (sur_volume_finale_) {jacobien = (*ex.jacobien_tdt);}
|
|
|
|
else {jacobien = (*ex.jacobien_0);};
|
|
|
|
// on boucle sur les degrés de liberté: a priori ne dépend que des ddl de déplacement des noeuds (choix pour l'instant)
|
|
|
|
int decal_x =0; // décalage
|
|
|
|
int dimf = force.Dimension(); int nbddl = (*ex.d_jacobien_tdt).Taille();
|
|
|
|
// NB: il s'agit ici de la métrique de la surface donc qui ne contient que les ddl de déplacement des noeuds, pas l'épaisseur par ex
|
|
|
|
for (int ne =1; ne<= nombre->nbnce; ne++)
|
|
|
|
{for (int i=1;i<= dimf;i++)
|
|
|
|
{ SM(i+decal_x) += taphi(ni)(ne)* force(i) * (poids(ni) * jacobien * epais_courant);
|
|
|
|
// dans le cas avec_raideur on calcul la contribution à la raideur,
|
|
|
|
if (avec_raid&& sur_volume_finale_)
|
|
|
|
for (int j =1; j<= nbddl; j++)
|
|
|
|
{KM(i+decal_x,j) += taphi(ni)(ne)* force(i) * (poids(ni) * (*ex.d_jacobien_tdt)(j)) * epais_courant;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
decal_x += CoSfe->tab_ddl.NbDdl(ne);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// liberation des tenseurs intermediaires
|
|
|
|
LibereTenseur();
|
|
|
|
Element::ResRaid el;
|
|
|
|
el.res = residu;
|
|
|
|
el.raid = raideur;
|
|
|
|
return el;
|
|
|
|
};
|
|
|
|
|
|
|
|
// calcul des seconds membres suivant les chargements
|
|
|
|
// cas d'un chargement surfacique, sur les frontières des éléments
|
|
|
|
// force indique la force surfacique appliquée
|
|
|
|
// numface indique le numéro de la face chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_surfacique_E
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
// on pourrait utiliser la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// mais on utilise celle de l'élément
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if ( unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if ( unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
// 1 pour dire que c'est la première surface externe
|
|
|
|
return ElemMeca::SM_charge_surf_E (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce //tab_noeud.Taille()
|
|
|
|
,CoSfe->eleS->TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement surfacique, sur les frontières des éléments
|
|
|
|
// force indique la force surfacique appliquée
|
|
|
|
// numface indique le numéro de la face chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_surfacique_I
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int ,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
// normalement numface = 1
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
((*raid_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if ( unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
CoSfe->met_surf_cent.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SMR_charge_surf_I (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce
|
|
|
|
,CoSfe->eleS->TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement de type pression, sur les frontières des éléments
|
|
|
|
// pression indique la pression appliquée
|
|
|
|
// numface indique le numéro de la face chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
|
|
|
|
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_pression_E(double pression,Fonction_nD* pt_fonct,int ,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique, si elle n'existe pas il faut la creer d'ou le true
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
// on pourrait utiliser la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// mais on utilise celle de l'élément
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if ( unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if ( unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
// 1 pour dire que c'est la première surface externe
|
|
|
|
return ElemMeca::SM_charge_pres_E (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce //tab_noeud.Taille()
|
|
|
|
,CoSfe->eleS->TaWi(),pression,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement de type pression, sur les frontières des éléments (type surface)
|
|
|
|
// pression indique la pression appliquée
|
|
|
|
// numface indique le numéro de la face chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
|
|
|
|
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_pression_I
|
|
|
|
(double pression,Fonction_nD* pt_fonct,int ,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
((*raid_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique, si elle n'existe pas il faut la creer d'ou le true
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if ( unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
CoSfe->met_surf_cent.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SMR_charge_pres_I (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),(tabb(1)->TabNoeud()).Taille()
|
|
|
|
,CoSfe->eleS->TaWi(),pression,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement de type pression unidirectionnelle, sur les frontières des éléments
|
|
|
|
// presUniDir indique le vecteur appliquée
|
|
|
|
// numface indique le numéro de la face chargée: ici 1
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booleenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_presUniDir_E
|
|
|
|
(const Coordonnee& presUniDir,Fonction_nD* pt_fonct,int ,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
// on pourrait utiliser la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// mais on utilise celle de l'élément
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if ( unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if ( unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SM_charge_surf_Suiv_E (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce
|
|
|
|
,CoSfe->eleS->TaWi(),presUniDir,pt_fonct,pa,atdt);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_presUniDir_I
|
|
|
|
(const Coordonnee& presUniDir,Fonction_nD* pt_fonct,int numface,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
((*raid_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique, si elle n'existe pas il faut la creer d'ou le true
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if ( unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
CoSfe->met_surf_cent.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SMR_charge_surf_Suiv_I (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce
|
|
|
|
,CoSfe->eleS->TaWi(),presUniDir,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement lineique, sur les arêtes frontières des éléments
|
|
|
|
// force indique la force lineique appliquée
|
|
|
|
// numArete indique le numéro de l'arête chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_lineique_E
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extA)(numArete))->Zero();
|
|
|
|
// on récupère ou on crée la frontière arrête
|
|
|
|
ElFrontiere* elf = Frontiere_lineique(numArete,true);
|
|
|
|
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// récupération de la métrique associée à l'élément qui est commune a tous les triangles
|
|
|
|
// du même type
|
|
|
|
Met_abstraite * meta= elf->Metrique();
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if( unefois->CalSMlin_t == 0)
|
|
|
|
{ unefois->CalSMlin_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(8);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = igradVBB_t;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if( unefois->CalSMlin_tdt == 0)
|
|
|
|
{ unefois->CalSMlin_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(8);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = igradVBB_tdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defArete(numArete) == NULL)
|
|
|
|
defArete(numArete) = new Deformation(*meta,elf->TabNoeud(),
|
|
|
|
(CoSfe->segS).TaDphi(),(CoSfe->segS).TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SM_charge_line_E (elf->DdlElem(),numArete
|
|
|
|
,(CoSfe->segS).TaPhi(),(elf->TabNoeud()).Taille()
|
|
|
|
,(CoSfe->segS).TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement lineique, sur les aretes frontières des éléments
|
|
|
|
// force indique la force lineique appliquée
|
|
|
|
// numarete indique le numéro de l'arete chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_lineique_I
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
((*res_extA)(numArete))->Zero();
|
|
|
|
((*raid_extA)(numArete))->Zero();
|
|
|
|
// on récupère ou on crée la frontière arrête
|
|
|
|
ElFrontiere* elf = Frontiere_lineique(numArete,true);
|
|
|
|
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// récupération de la métrique associée à l'élément qui est commune a tous les triangles
|
|
|
|
// du même type
|
|
|
|
Met_abstraite * meta= elf->Metrique();
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if( !(unefois->CalSMRlin ))
|
|
|
|
{ unefois->CalSMRlin += 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(15);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = igradVBB_tdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defArete(numArete) == NULL)
|
|
|
|
defArete(numArete) = new Deformation(*meta,elf->TabNoeud(),
|
|
|
|
(CoSfe->segS).TaDphi(),(CoSfe->segS).TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SMR_charge_line_I (elf->DdlElem(),numArete
|
|
|
|
,(CoSfe->segS).TaPhi(),(elf->TabNoeud()).Taille()
|
|
|
|
,(CoSfe->segS).TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// cas d'un chargement lineique suiveuse, sur les aretes frontières des éléments 2D (uniquement)
|
|
|
|
// force indique la force lineique appliquée
|
|
|
|
// numarete indique le numéro de l'arete chargée
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// -> explicite à t ou tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_lineique_Suiv_E
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extA)(numArete))->Zero();
|
|
|
|
// on récupère ou on crée la frontière arrête
|
|
|
|
ElFrontiere* elf = Frontiere_lineique(numArete,true);
|
|
|
|
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// récupération de la métrique associée à l'élément qui est commune a tous les triangles
|
|
|
|
// du même type
|
|
|
|
Met_abstraite * meta= elf->Metrique();
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if( unefois->CalSMlin_t == 0)
|
|
|
|
{ unefois->CalSMlin_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(8);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = igradVBB_t;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if( unefois->CalSMlin_tdt == 0)
|
|
|
|
{ unefois->CalSMlin_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(8);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = igradVBB_tdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defArete(numArete) == NULL)
|
|
|
|
defArete(numArete) = new Deformation(*meta,elf->TabNoeud(),
|
|
|
|
(CoSfe->segS).TaDphi(),(CoSfe->segS).TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SM_charge_line_Suiv_E (elf->DdlElem(),numArete
|
|
|
|
,(CoSfe->segS).TaPhi(),(elf->TabNoeud()).Taille()
|
|
|
|
,(CoSfe->segS).TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement lineique suiveuse, sur les aretes frontières des éléments 2D (uniquement)
|
|
|
|
// force indique la force lineique appliquée
|
|
|
|
// numarete indique le numéro de l'arete chargée
|
|
|
|
// retourne le second membre résultant -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_lineique_Suiv_I
|
|
|
|
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
((*res_extA)(numArete))->Zero();
|
|
|
|
((*raid_extA)(numArete))->Zero();
|
|
|
|
// on récupère ou on crée la frontière arrête
|
|
|
|
ElFrontiere* elf = Frontiere_lineique(numArete,true);
|
|
|
|
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// récupération de la métrique associée à l'élément qui est commune a tous les triangles
|
|
|
|
// du même type
|
|
|
|
Met_abstraite * meta= elf->Metrique();
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if( !(unefois->CalSMRlin ))
|
|
|
|
{ unefois->CalSMRlin += 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(15);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = igradVBB_tdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defArete(numArete) == NULL)
|
|
|
|
defArete(numArete) = new Deformation(*meta,elf->TabNoeud(),
|
|
|
|
(CoSfe->segS).TaDphi(),(CoSfe->segS).TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SMR_charge_line_Suiv_I (elf->DdlElem(),numArete
|
|
|
|
,(CoSfe->segS).TaPhi(),(elf->TabNoeud()).Taille()
|
|
|
|
,(CoSfe->segS).TaWi(),force,pt_fonct,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement de type pression hydrostatique, sur les frontières des éléments
|
|
|
|
// la charge dépend de la hauteur à la surface libre du liquide déterminée par un point
|
|
|
|
// et une direction normale à la surface libre:
|
|
|
|
// nSurf : le numéro de la surface externe
|
|
|
|
// poidvol: indique le poids volumique du liquide
|
|
|
|
// M_liquide : un point de la surface libre
|
|
|
|
// dir_normal_liquide : direction normale à la surface libre
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// calcul à l'instant tdt ou t en fonction de la variable atdt
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
|
|
|
|
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
|
|
|
|
// -> explicite à t ou à tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_hydrostatique_E(const Coordonnee& dir_normal_liquide,const double& poidvol
|
|
|
|
,int ,const Coordonnee& M_liquide,bool atdt,const ParaAlgoControle & pa
|
|
|
|
,bool sans_limitation)
|
|
|
|
{ // initialisation du vecteur résidu
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
// on pourrait utiliser la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
// mais on utilise celle de l'élément
|
|
|
|
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if (!atdt)
|
|
|
|
{if ( unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if ( unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
CoSfe->met_SfeMembT.PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(1) == NULL)
|
|
|
|
defSurf(1) = new Deformation
|
|
|
|
(CoSfe->met_surf_cent,tabb(1)->TabNoeud(),CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// appel du programme général d'elemmeca et retour du vecteur second membre
|
|
|
|
// 1 pour dire que c'est la première surface externe
|
|
|
|
return ElemMeca::SM_charge_hydro_E (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce
|
|
|
|
,CoSfe->eleS->TaWi(),dir_normal_liquide,poidvol,M_liquide,sans_limitation,pa,atdt);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement de type pression hydrostatique, sur les frontières des éléments
|
|
|
|
// la charge dépend de la hauteur à la surface libre du liquide déterminée par un point
|
|
|
|
// et une direction normale à la surface libre:
|
|
|
|
// nSurf : le numéro de la surface externe
|
|
|
|
// poidvol: indique le poids volumique du liquide
|
|
|
|
// M_liquide : un point de la surface libre
|
|
|
|
// dir_normal_liquide : direction normale à la surface libre
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// calcul à l'instant tdt ou t en fonction de la variable atdt
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
|
|
|
|
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
|
|
|
|
// -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_hydrostatique_I (const Coordonnee& dir_normal_liquide,const double& poidvol
|
|
|
|
,int ,const Coordonnee& M_liquide,const ParaAlgoControle & pa
|
|
|
|
,bool sans_limitation)
|
|
|
|
{ // initialisation du vecteur résidu et de la raideur
|
|
|
|
// normalement numface = 1
|
|
|
|
((*res_extS)(1))->Zero();
|
|
|
|
((*raid_extS)(1))->Zero();
|
|
|
|
// on récupère ou on crée la frontière surfacique
|
|
|
|
Frontiere_surfacique(1,true);
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
if ( unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
CoSfe->met_surf_cent.PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// la déformation surfacique defSurf(1), est définit par défaut, sauf si elle a été supprimée
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
return ElemMeca::SMR_charge_hydro_I (tabb(1)->DdlElem(),1
|
|
|
|
,CoSfe->eleS->TaPhi(),nombre->nbnce
|
|
|
|
,CoSfe->eleS->TaWi(),dir_normal_liquide,poidvol,M_liquide,sans_limitation,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas d'un chargement surfacique hydro-dynamique,
|
|
|
|
// 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
|
|
|
|
// coef_mul: est un coefficient multiplicateur global (de tout)
|
|
|
|
// retourne le second membre résultant
|
|
|
|
// // -> explicite à t ou à tdt en fonction de la variable booléenne atdt
|
|
|
|
Vecteur SfeMembT::SM_charge_hydrodynamique_E( Courbe1D* frot_fluid,const double& poidvol
|
|
|
|
, Courbe1D* coef_aero_n,int numface,const double& coef_mul
|
|
|
|
, Courbe1D* coef_aero_t,bool atdt,const ParaAlgoControle & pa)
|
|
|
|
{ SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
Met_abstraite * meta = tabb(numface)->Metrique();
|
|
|
|
ElemGeomC0* elemGeom = CoSfe->eleS;
|
|
|
|
|
|
|
|
// initialisation du vecteur résidu et de la raideur pour la surface
|
|
|
|
((*res_extS)(numface))->Zero(); ((*raid_extS)(numface))->Zero();
|
|
|
|
Frontiere_surfacique(numface,true);// on récupère ou on crée la frontière surfacique
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
// définition des constantes de la métrique si nécessaire
|
|
|
|
if (!atdt)
|
|
|
|
{if (unefois->CalSMsurf_t == 0)
|
|
|
|
{ unefois->CalSMsurf_t = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(10);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igijBB_0;tab(4) = igijBB_t;
|
|
|
|
tab(5) = igijHH_t; tab(6) = id_giB_t; tab(7) = id_gijBB_t ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = igradVBB_t; tab(10) = iVt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};}
|
|
|
|
else
|
|
|
|
{if (unefois->CalSMsurf_tdt == 0)
|
|
|
|
{ unefois->CalSMsurf_tdt = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(11);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_tdt; tab(3) = igijBB_0;tab(4) = igijBB_tdt;
|
|
|
|
tab(5) = igijHH_tdt; tab(6) = id_giB_tdt; tab(7) = id_gijBB_tdt ;
|
|
|
|
tab(8) = id_gijBB_t ;tab(9) = id_gijBB_tdt ;
|
|
|
|
tab(10) = igradVBB_tdt;tab(11) = iVtdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(numface) == NULL)
|
|
|
|
defSurf(numface) = new Deformation(*meta,tabb(numface)->TabNoeud()
|
|
|
|
,CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// appel du programme général d'ElemMeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SM_charge_hydrodyn_E (poidvol,elemGeom->TaPhi(),(tabb(numface)->TabNoeud()).Taille()
|
|
|
|
,frot_fluid,elemGeom->TaWi()
|
|
|
|
,coef_aero_n,numface,coef_mul,coef_aero_t,pa,atdt);
|
|
|
|
};
|
|
|
|
|
|
|
|
// -> 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
|
|
|
|
Element::ResRaid SfeMembT::SMR_charge_hydrodynamique_I( Courbe1D* frot_fluid,const double& poidvol
|
|
|
|
, Courbe1D* coef_aero_n,int numface,const double& coef_mul
|
|
|
|
, Courbe1D* coef_aero_t,const ParaAlgoControle & pa)
|
|
|
|
{ SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// on utilise la métrique des éléments de frontière
|
|
|
|
// avec l'instance déformation dédiée pour
|
|
|
|
Met_abstraite * meta = tabb(numface)->Metrique();
|
|
|
|
ElemGeomC0* elemGeom = CoSfe->eleS;
|
|
|
|
// initialisation du vecteur résidu et de la raideur pour la surface
|
|
|
|
((*res_extS)(numface))->Zero(); ((*raid_extS)(numface))->Zero();
|
|
|
|
Frontiere_surfacique(numface,true);// on récupère ou on crée la frontière surfacique
|
|
|
|
|
|
|
|
// dimensionnement de la metrique
|
|
|
|
// définition des constantes de la métrique si nécessaire
|
|
|
|
if (unefois->CalSMRsurf == 0)
|
|
|
|
{ unefois->CalSMRsurf = 1;
|
|
|
|
Tableau<Enum_variable_metrique> tab(20);
|
|
|
|
tab(1) = igiB_0; tab(2) = igiB_t; tab(3) = igiB_tdt; tab(4) = igijBB_0;
|
|
|
|
tab(5) = igijBB_t;tab(6) = igijBB_tdt; tab(7) = igijHH_tdt; tab(8) = id_giB_tdt;
|
|
|
|
tab(9) = id_gijBB_tdt ;tab(10) = igiH_tdt;tab(11) = id_giH_tdt;
|
|
|
|
tab(12) = id_gijHH_tdt;tab(13) = id_jacobien_tdt;tab(14) = id2_gijBB_tdt;
|
|
|
|
tab(15) = id_gijBB_t ;tab(16) = id_gijBB_tdt ;tab(17) = idMtdt ;
|
|
|
|
tab(18) = igradVBB_tdt; tab(19) = iVtdt; tab(20) = idVtdt;
|
|
|
|
meta->PlusInitVariables(tab) ;
|
|
|
|
};
|
|
|
|
// on définit la déformation a doc si elle n'existe pas déjà
|
|
|
|
if (defSurf(numface) == NULL)
|
|
|
|
defSurf(numface) = new Deformation(*meta,tabb(numface)->TabNoeud()
|
|
|
|
,CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
|
|
|
|
// appel du programme général d'ElemMeca et retour du vecteur second membre
|
|
|
|
return ElemMeca::SM_charge_hydrodyn_I (poidvol,elemGeom->TaPhi(),(tabb(numface)->TabNoeud()).Taille()
|
|
|
|
,frot_fluid,elemGeom->TaWi(),tabb(numface)->DdlElem()
|
|
|
|
,coef_aero_n,numface,coef_mul
|
|
|
|
,coef_aero_t,pa);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ramène le nombre de points d'intégration correspondant à un type énuméré
|
|
|
|
int SfeMembT::NbPtInteg(Enum_ddl ddl) const
|
|
|
|
{ Enum_ddl enu = PremierDdlFamille(ddl);
|
|
|
|
switch (enu)
|
|
|
|
{ case X1 : case SIG11 : case EPS11 : case DEPS11 :
|
|
|
|
return (nombre->nbie * nombre->nbis); break;
|
|
|
|
case ERREUR :
|
|
|
|
return (nombre->nbieEr * nombre->nbisEr); break;
|
|
|
|
default :
|
|
|
|
{cout << "\n cas non prévu ou non encore implanté: ddl= " << Nom_ddl(ddl)
|
|
|
|
<< "\n SfeMembT::NbPtInteg(Enum_ddl ddl) " ;
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return (nombre->nbie * nombre->nbis); // pour taire le compilo
|
|
|
|
};
|
|
|
|
|
|
|
|
// Calcul des frontieres de l'element
|
|
|
|
// creation des elements frontieres et retour du tableau de ces elements
|
|
|
|
// la création n'a lieu qu'au premier appel
|
|
|
|
// ou lorsque l'on force le paramètre force a true
|
|
|
|
// dans ce dernier cas seul les frontière effacées sont recréée
|
|
|
|
Tableau <ElFrontiere*> const & SfeMembT::Frontiere(bool force)
|
|
|
|
{ // en 3D on veut des faces et des lignes
|
|
|
|
int cas = 0; // init
|
|
|
|
if ((ParaGlob::Dimension()==3)&& (!ParaGlob::AxiSymetrie()))
|
|
|
|
{cas = 4;}
|
|
|
|
else if (ParaGlob::Dimension()==2)
|
|
|
|
{cas = 2;};
|
|
|
|
// = 0 -> on veut toutes les frontières
|
|
|
|
// = 1 -> on veut uniquement les surfaces
|
|
|
|
// = 2 -> on veut uniquement les lignes
|
|
|
|
// = 3 -> on veut uniquement les points
|
|
|
|
// = 4 -> on veut les surfaces + les lignes
|
|
|
|
// = 5 -> on veut les surfaces + les points
|
|
|
|
// = 6 -> on veut les lignes + les points
|
|
|
|
return Frontiere_elemeca(cas,force);
|
|
|
|
// {// le calcul et la création ne sont effectués qu'au premier appel
|
|
|
|
// // ou lorsque l'on veut forcer une recréation
|
|
|
|
// if (((ind_front_lin == 0) && (ind_front_surf == 0) && (ind_front_point == 0))
|
|
|
|
// || force )
|
|
|
|
//// if ((ind_front_lin == 0) || force || (ind_front_lin == 2))
|
|
|
|
// {SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// ElemGeomC0 & el = *(CoSfe->eleCentre);
|
|
|
|
// DdlElement & tdd = CoSfe->tab_ddl;
|
|
|
|
// int tail_fa = el.NbFe(); // nombre de faces, normalement = 1
|
|
|
|
// // dimensionnement des tableaux intermediaires
|
|
|
|
// Tableau <Noeud *> tab(nombre->nbneA); // les noeuds des segments frontieres
|
|
|
|
// DdlElement ddelem(nombre->nbneA); // les ddlelements des noeuds frontieres
|
|
|
|
//
|
|
|
|
// // ici la dimension ne peut-être qu'égale à 3
|
|
|
|
// int tail_ar = el.NbSe(); // le nombre d'arêtes (de l'élément central)
|
|
|
|
// int tail = tail_fa + tail_ar; // les cotés et la face centrale: normalement NbFe()=1
|
|
|
|
//
|
|
|
|
// if ((ind_front_point > 0) && (ind_front_lin == 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières points existent seule
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds de l'élément central
|
|
|
|
// int taille_f = tail_fa + tail_ar + tail_p;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++)
|
|
|
|
// { tabb(i+tail) = tabb(i);
|
|
|
|
// tabb(i) = NULL;
|
|
|
|
// }
|
|
|
|
// posi_tab_front_point=tail;
|
|
|
|
// posi_tab_front_lin=tail_fa;
|
|
|
|
// }
|
|
|
|
// else if ((ind_front_point > 0) && (ind_front_lin == 0) && (ind_front_surf > 0))
|
|
|
|
// // cas où les frontières points existent et surface et pas de ligne
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds de l'élément central
|
|
|
|
// int taille_f = tail + tail_p + 1;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++) // transfert pour les noeuds
|
|
|
|
// { tabb(i+tail) = tabb(i+1);tabb(i+1) = NULL;}
|
|
|
|
// posi_tab_front_point=tail;
|
|
|
|
// // pour la surface, c'est la première, elle y reste
|
|
|
|
// }
|
|
|
|
// else if ((ind_front_point > 0) && (ind_front_lin > 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières points existent et ligne et pas de surface
|
|
|
|
// { int tail_af = nombre->nbnce+el.NonS().Taille(); // nombre d'arête + noeud
|
|
|
|
// int taille_f = tail + tail_af;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_af;i++) // transfert pour les noeuds
|
|
|
|
// { tabb(i+tail) = tabb(i);tabb(i) = NULL;}
|
|
|
|
// posi_tab_front_point +=tail;
|
|
|
|
// posi_tab_front_lin +=tail;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// { // cas où il n'y a pas de frontières points
|
|
|
|
// if (ind_front_surf == 0) // dimensionnement éventuelle
|
|
|
|
// tabb.Change_taille(tail); // le tableau total de frontières
|
|
|
|
// };
|
|
|
|
//
|
|
|
|
// // création de la surface
|
|
|
|
// if (tabb(1) == NULL)
|
|
|
|
// { int nbnoe = nombre->nbnce; // nb noeud de la face centrale
|
|
|
|
// Tableau <Noeud *> tab(nbnoe); // les noeuds des faces frontieres
|
|
|
|
// DdlElement ddelem(nbnoe); // les ddlelements des noeuds frontieres
|
|
|
|
// for (int i=1;i<= nbnoe;i++)
|
|
|
|
// { tab(i) = tab_noeud(el.Nonf()(1)(i));
|
|
|
|
// ddelem.Change_un_ddlNoeudElement(i,tdd(el.Nonf()(1)(i)));
|
|
|
|
// // ddelem(i) = tdd(el.Nonf()(1)(i));
|
|
|
|
// }
|
|
|
|
// tabb(1) = new_frontiere_surf(tab,ddelem);
|
|
|
|
// // mise à jour de l'indicateur de création de face
|
|
|
|
// ind_front_surf = 1;
|
|
|
|
// };
|
|
|
|
// // positionnement du début des lignes
|
|
|
|
// posi_tab_front_lin = 1; // dans tous les cas, comme on vient de créer la surface, la ligne vient après
|
|
|
|
// // création éventuelle des lignes
|
|
|
|
// for (int nlign=1;nlign<=tail_ar;nlign++)
|
|
|
|
// if (tabb(posi_tab_front_lin+nlign) == NULL)
|
|
|
|
// { int nbnoe = el.NonS()(nlign).Taille(); // nb noeud de l'arête
|
|
|
|
// Tableau <Noeud *> tab(nbnoe); // les noeuds de l'arête frontiere
|
|
|
|
// DdlElement ddelem(nombre->nbneA); // les ddlelements des noeuds frontieres
|
|
|
|
// for (int i=1;i<= nbnoe;i++)
|
|
|
|
// { tab(i) = tab_noeud(el.NonS()(nlign)(i));
|
|
|
|
// ddelem.Change_un_ddlNoeudElement(i,tdd(el.NonS()(nlign)(i)));
|
|
|
|
// };
|
|
|
|
// tabb(posi_tab_front_lin+nlign) = new_frontiere_lin(tab,ddelem);
|
|
|
|
// }
|
|
|
|
// // mise à jour de l'indicateur
|
|
|
|
// ind_front_lin = 1;
|
|
|
|
// }
|
|
|
|
// // retour du tableau
|
|
|
|
// return (Tableau <ElFrontiere*>&) tabb;
|
|
|
|
};
|
|
|
|
|
|
|
|
//// ramène la frontière point
|
|
|
|
//// éventuellement création des frontieres points de l'element et stockage dans l'element
|
|
|
|
//// si c'est la première fois sinon il y a seulement retour de l'elements
|
|
|
|
//// a moins que le paramètre force est mis a true
|
|
|
|
//// dans ce dernier cas la frontière effacéee est recréée
|
|
|
|
//// num indique le numéro du point à créer (numérotation EF)
|
|
|
|
//ElFrontiere* const SfeMembT::Frontiere_points(int num,bool force)
|
|
|
|
// { // le calcul et la création ne sont effectués qu'au premier appel
|
|
|
|
// // ou lorsque l'on veut forcer une recréation
|
|
|
|
// #ifdef MISE_AU_POINT
|
|
|
|
// if ((num > nombre->nbnce)||(num <=0))
|
|
|
|
// { cout << "\n *** erreur, le noeud demande pour frontiere: " << num << " esten dehors de la numeration de l'element ! "
|
|
|
|
// << "\n Frontiere_points(int num,bool force)";
|
|
|
|
// Sortie(1);
|
|
|
|
// }
|
|
|
|
// #endif
|
|
|
|
//
|
|
|
|
// if ((ind_front_point == 0) || force || (ind_front_point == 2))
|
|
|
|
// {Tableau <Noeud *> tab(1); // les noeuds des points frontieres
|
|
|
|
// DdlElement ddelem(1); // les ddlelements des points frontieres
|
|
|
|
// // on regarde si les frontières points existent sinon on les crée
|
|
|
|
// if (ind_front_point == 1)
|
|
|
|
// return (ElFrontiere*)tabb(posi_tab_front_point+num);
|
|
|
|
// else if ( ind_front_point == 2)
|
|
|
|
// // cas où certaines frontières existent
|
|
|
|
// if (tabb(posi_tab_front_point+num) != NULL)
|
|
|
|
// return (ElFrontiere*)tabb(posi_tab_front_point+num);
|
|
|
|
// // dans tous les autres cas on construit la frontière point
|
|
|
|
// // on commence par dimensionner le tableau de frontière, comme les frontières points sont
|
|
|
|
// // les dernières, il suffit de les ajouter, d'où on redimentionne le tableau mais on ne créra
|
|
|
|
// // que la frontière adoc
|
|
|
|
// // def de la taille
|
|
|
|
// int taille_actuelle = tabb.Taille();
|
|
|
|
// if ((ind_front_point == 0) && ((ind_front_lin > 0) || (ind_front_surf > 0)))
|
|
|
|
// // cas où les frontières lignes ou surfaces existent, mais pas les points
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds de l'élément central
|
|
|
|
// int taille_f = taille_actuelle + tail_p;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++)
|
|
|
|
// { tabb(i+taille_actuelle) = tabb(i);tabb(i) = NULL;};
|
|
|
|
// posi_tab_front_point +=taille_actuelle;
|
|
|
|
// if (ind_front_lin > 0) posi_tab_front_lin += taille_actuelle;
|
|
|
|
// }
|
|
|
|
// else if (ind_front_point == 0)
|
|
|
|
// // cas où aucune frontière n'existe
|
|
|
|
// {tabb.Change_taille(nombre->nbnce);};
|
|
|
|
// // dans les autres cas, les frontières points exitent donc pas à dimensionner
|
|
|
|
// // on définit tous les points par simplicité
|
|
|
|
// for (int i=1;i<=nombre->nbnce;i++)
|
|
|
|
// {tab(1) = tab_noeud(i);ddelem.Change_un_ddlNoeudElement(1,unefois->doCoMemb->tab_ddl(i));
|
|
|
|
// if (tabb(i+posi_tab_front_point) == NULL)
|
|
|
|
// tabb(i+posi_tab_front_point) = new FrontPointF (tab,ddelem);
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
// return (ElFrontiere*)tabb(num+posi_tab_front_point);
|
|
|
|
// };
|
|
|
|
|
|
|
|
//// ramène la frontière linéique
|
|
|
|
//// éventuellement création des frontieres linéique de l'element et stockage dans l'element
|
|
|
|
//// si c'est la première fois et en 3D sinon il y a seulement retour de l'elements
|
|
|
|
//// a moins que le paramètre force est mis a true
|
|
|
|
//// dans ce dernier cas la frontière effacéee est recréée
|
|
|
|
//// num indique le numéro de l'arête à créer (numérotation EF)
|
|
|
|
//ElFrontiere* const SfeMembT::Frontiere_lineique(int num,bool force)
|
|
|
|
//{ // le calcul et la création ne sont effectués qu'au premier appel
|
|
|
|
// // ou lorsque l'on veut forcer une recréation
|
|
|
|
// // on regarde si les frontières linéiques existent sinon on les crée
|
|
|
|
// if (!force)
|
|
|
|
// {if (ind_front_lin == 1)
|
|
|
|
// {return (ElFrontiere*)tabb(posi_tab_front_lin+num);}
|
|
|
|
// else if ( ind_front_lin == 2)
|
|
|
|
// // cas où certaines frontières existent
|
|
|
|
// {if (tabb(posi_tab_front_lin+num) != NULL)
|
|
|
|
// return (ElFrontiere*)tabb(posi_tab_front_lin+num);
|
|
|
|
// };
|
|
|
|
// }
|
|
|
|
// else // cas où on veut forcer une nouvelle création
|
|
|
|
// { if (ind_front_lin != 0)
|
|
|
|
// if (tabb(posi_tab_front_lin+num) != NULL)
|
|
|
|
// {delete tabb(posi_tab_front_lin+num); //on commence par supprimer
|
|
|
|
// tabb(posi_tab_front_lin+num)=NULL;
|
|
|
|
// // on supprime également éventuellement la déformation associée pour un calcul d'arête
|
|
|
|
// if (defArete.Taille() != 0)
|
|
|
|
// {delete defArete(num);defArete(num)=NULL;};
|
|
|
|
// if (ind_front_lin == 1)
|
|
|
|
// ind_front_lin = 2; // on indique
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
// // arrivée ici cela veut dire que la frontière ligne n'existe pas
|
|
|
|
// // on l'a reconstruit
|
|
|
|
//
|
|
|
|
// // le calcul et la création ne sont effectués qu'au premier appel
|
|
|
|
// // ou lorsque l'on veut forcer une recréation
|
|
|
|
// if ((ind_front_lin == 0) || force || (ind_front_lin == 2))
|
|
|
|
// {SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// ElemGeomC0 & el = *(CoSfe->eleCentre);
|
|
|
|
// DdlElement & tdd = CoSfe->tab_ddl;
|
|
|
|
// int tail_fa = el.NbFe(); // nombre de faces, normalement = 1
|
|
|
|
// // dimensionnement des tableaux intermediaires
|
|
|
|
// Tableau <Noeud *> tab(nombre->nbneA); // les noeuds des segments frontieres
|
|
|
|
// DdlElement ddelem(nombre->nbneA); // les ddlelements des noeuds frontieres
|
|
|
|
//
|
|
|
|
// // ici la dimension ne peut-être qu'égale à 3
|
|
|
|
// int tail_ar = el.NbSe(); // le nombre d'arêtes (de l'élément central)
|
|
|
|
// int tail = tail_fa + tail_ar; // les cotés et la face centrale: normalement NbFe()=1
|
|
|
|
//
|
|
|
|
// // dimensionnement du tableau de frontières ligne si nécessaire
|
|
|
|
// if (ind_front_lin == 0)
|
|
|
|
// {if ((ind_front_point > 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières points existent seule
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds de l'élément central
|
|
|
|
// int taille_f = tail_fa + tail_ar + tail_p;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++)
|
|
|
|
// { tabb(i+tail) = tabb(i);
|
|
|
|
// tabb(i) = NULL;
|
|
|
|
// }
|
|
|
|
// posi_tab_front_point=tail;
|
|
|
|
// posi_tab_front_lin=tail_fa;
|
|
|
|
// }
|
|
|
|
// else if ((ind_front_point > 0) && (ind_front_surf > 0))
|
|
|
|
// // cas où les frontières points existent et surface et pas de ligne
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds de l'élément central
|
|
|
|
// int taille_f = tail + tail_p + 1;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++) // transfert pour les noeuds
|
|
|
|
// { tabb(i+tail) = tabb(i+1);tabb(i+1) = NULL;}
|
|
|
|
// posi_tab_front_point=tail;
|
|
|
|
// // pour la surface, c'est la première, elle y reste
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// { // cas où il n'y a pas de frontières points
|
|
|
|
// if (ind_front_surf == 0) // cas où il n'y a pas la surface
|
|
|
|
// {tabb.Change_taille(tail_ar,NULL); // on n'a pas de ligne, pas de point et pas de surface
|
|
|
|
// posi_tab_front_lin = 0;} // on peut tout mettre à NULL
|
|
|
|
// else {tabb.Change_taille(tail_ar+tail_fa); // cas où les surfaces existent
|
|
|
|
// for (int i=1;i<=tail_ar;i++)
|
|
|
|
// tabb(i+tail_fa)=NULL;
|
|
|
|
// posi_tab_front_lin = 1;};
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
//
|
|
|
|
// // création de la ligne éventuellement
|
|
|
|
// if ((tabb(posi_tab_front_lin+num) == NULL) || force)
|
|
|
|
// { int nbnoe = el.NonS()(num).Taille(); // nb noeud de l'arête
|
|
|
|
// Tableau <Noeud *> tab(nbnoe); // les noeuds de l'arête frontiere
|
|
|
|
// DdlElement ddelem(nombre->nbneA); // les ddlelements des noeuds frontieres
|
|
|
|
// for (int i=1;i<= nbnoe;i++)
|
|
|
|
// { tab(i) = tab_noeud(el.NonS()(num)(i));
|
|
|
|
// ddelem.Change_un_ddlNoeudElement(i,tdd(el.NonS()(num)(i)));
|
|
|
|
// };
|
|
|
|
// tabb(posi_tab_front_lin+num) = new_frontiere_lin(tab,ddelem);
|
|
|
|
// ind_front_lin = 1; // a priori
|
|
|
|
// for (int nlign=1;nlign<=3;nlign++)
|
|
|
|
// if (tabb(posi_tab_front_lin+nlign) == NULL)
|
|
|
|
// { ind_front_lin = 2; break;};
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
// // maintenant normalement la frontière est créé on la ramène
|
|
|
|
// return (ElFrontiere*)tabb(posi_tab_front_lin+num);
|
|
|
|
//};
|
|
|
|
|
|
|
|
//// ramène la frontière surfacique
|
|
|
|
//// éventuellement création de la frontiere surfacique de l'element et stockage dans l'element
|
|
|
|
//// si c'est la première fois sinon il y a seulement retour de l'elements
|
|
|
|
//// a moins que le paramètre force est mis a true
|
|
|
|
//// dans ce dernier cas la frontière effacéee est recréée
|
|
|
|
//// num indique le numéro de la surface à créer (numérotation EF) ici normalement uniquement 1 possible
|
|
|
|
//ElFrontiere* const SfeMembT::Frontiere_surfacique(int ,bool force)
|
|
|
|
// { // le calcul et la création ne sont effectués qu'au premier appel
|
|
|
|
// // ou lorsque l'on veut forcer une recréation
|
|
|
|
// if ((ind_front_surf == 0) || force || (ind_front_surf == 2))
|
|
|
|
// { SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// ElemGeomC0 & el = *(CoSfe->eleCentre);
|
|
|
|
// DdlElement & tdd = CoSfe->tab_ddlXi_C;
|
|
|
|
//// int taille = tabb.Taille(); // la taille initiales des frontières
|
|
|
|
// int tail_fa = 1; // nombre de faces
|
|
|
|
//// int tail_a = el.NonS().Taille(); // nombre d'arête
|
|
|
|
// posi_tab_front_lin = 1; // init indice de début d'arrête dans tabb
|
|
|
|
// // dimensionnement du tableau de frontières ligne si nécessaire
|
|
|
|
// // def de la taille
|
|
|
|
// if ((ind_front_point > 0) && (ind_front_lin == 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières points existent seule
|
|
|
|
// { int tail_p = nombre->nbnce; // le nombre de noeuds
|
|
|
|
// int taille_f = tail_fa + tail_p;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_p;i++)
|
|
|
|
// { tabb(i+tail_fa) = tabb(i);tabb(i) = NULL;};
|
|
|
|
// posi_tab_front_point=tail_fa;
|
|
|
|
// }
|
|
|
|
// else if ((ind_front_point > 0) && (ind_front_lin > 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières points existent et ligne et pas de surface
|
|
|
|
// { int tail_af = nombre->nbnce+el.NonS().Taille(); // nombre d'arête + noeud
|
|
|
|
// int taille_f = tail_fa + tail_af;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_af;i++) // transfert pour les noeuds
|
|
|
|
// { tabb(i+tail_fa) = tabb(i);tabb(i) = NULL;}
|
|
|
|
// posi_tab_front_point +=tail_fa;
|
|
|
|
// posi_tab_front_lin +=tail_fa;
|
|
|
|
// }
|
|
|
|
// else if ((ind_front_point == 0) && (ind_front_lin > 0) && (ind_front_surf == 0))
|
|
|
|
// // cas où les frontières ligne existent seule
|
|
|
|
// { int tail_a = el.NonS().Taille(); // nombre d'arête
|
|
|
|
// int taille_f = tail_fa + tail_a;
|
|
|
|
// tabb.Change_taille(taille_f);
|
|
|
|
// for (int i=1;i<= tail_a;i++) // transfert pour les noeuds
|
|
|
|
// { tabb(i+tail_fa) = tabb(i);tabb(i) = NULL;}
|
|
|
|
// posi_tab_front_point +=tail_fa;
|
|
|
|
// posi_tab_front_lin +=tail_fa;
|
|
|
|
// }
|
|
|
|
// else if (ind_front_surf == 0) // cas autre, où la frontière surface n'existe pas
|
|
|
|
// // et qu'il n'y a pas de ligne ni de point
|
|
|
|
// tabb.Change_taille(tail_fa); // le tableau total de frontières
|
|
|
|
// // création éventuelle de la face
|
|
|
|
// if (tabb(1) == NULL)
|
|
|
|
// { int nbnoe = nombre->nbnce; // nb noeud de la surface centrale
|
|
|
|
// Tableau <Noeud *> tab(nbnoe); // les noeuds de la surface centrale
|
|
|
|
// DdlElement ddelem(nbnoe); // les ddlelements des noeuds frontieres
|
|
|
|
// for (int i=1;i<= nbnoe;i++)
|
|
|
|
// { tab(i) = tab_noeud(el.Nonf()(1)(i));
|
|
|
|
// ddelem.Change_un_ddlNoeudElement(i,tdd(el.Nonf()(1)(i)));
|
|
|
|
// // ddelem(i) = tdd(el.Nonf()(1)(i));
|
|
|
|
// }
|
|
|
|
// tabb(1) = new_frontiere_surf(tab,ddelem);
|
|
|
|
// }
|
|
|
|
// // mise à jour de l'indicateur
|
|
|
|
// ind_front_surf = 1;
|
|
|
|
// }
|
|
|
|
// return (ElFrontiere*)tabb(1);
|
|
|
|
// };
|
|
|
|
|
|
|
|
// liberation de la place pointee
|
|
|
|
void SfeMembT::Libere ()
|
|
|
|
{Element::Libere (); // liberation de residu et raideur
|
|
|
|
LibereTenseur() ; // liberation des tenseur intermediaires
|
|
|
|
};
|
|
|
|
// acquisition ou modification d'une loi de comportement
|
|
|
|
void SfeMembT::DefLoi (LoiAbstraiteGeneral * NouvelleLoi)
|
|
|
|
{ // verification du type de loi
|
|
|
|
if (donnee_specif.epais != NULL) // cas d'un élément 2D
|
|
|
|
{if ((NouvelleLoi->Dimension_loi() != 2) && (NouvelleLoi->Dimension_loi() != 4))
|
|
|
|
{ cout << "\n Erreur, la loi de comportement a utiliser avec des SfeMembTs 2D ";
|
|
|
|
cout << " doit etre de type 2D, \n ici elle est de type = "
|
|
|
|
<< (NouvelleLoi->Dimension_loi()) << "D !!! " << endl;
|
|
|
|
Sortie(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // cas 3D ou quelconque
|
|
|
|
{if ((NouvelleLoi->Dimension_loi() != 3) && (NouvelleLoi->Dimension_loi() != 4))
|
|
|
|
{ cout << "\n Erreur, la loi de comportement a utiliser avec des SfeMembTs 3D ";
|
|
|
|
cout << " doit etre de type 3D, \n ici elle est de type = "
|
|
|
|
<< (NouvelleLoi->Dimension_loi()) << "D !!! " << endl;
|
|
|
|
Sortie(1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// cas d'une loi mécanique
|
|
|
|
if (GroupeMecanique(NouvelleLoi->Id_categorie()))
|
|
|
|
{loiComp = (Loi_comp_abstraite *) NouvelleLoi;
|
|
|
|
// initialisation du stockage particulier, ici en fonction du nb de pt d'integ
|
|
|
|
int imaxi = tabSaveDon.Taille();
|
|
|
|
for (int i=1;i<= imaxi;i++) tabSaveDon(i) = loiComp->New_et_Initialise();
|
|
|
|
// idem pour le type de déformation mécanique associé
|
|
|
|
int iDefmax = tabSaveDefDon.Taille();
|
|
|
|
for (int i=1;i<= iDefmax;i++) tabSaveDefDon(i) = def->New_et_Initialise();
|
|
|
|
// définition du type de déformation associé à la loi
|
|
|
|
loiComp->Def_type_deformation(*def);
|
|
|
|
// on active les données particulières nécessaires au fonctionnement de la loi de comp
|
|
|
|
loiComp->Activation_donnees(tab_noeud,dilatation,lesPtMecaInt);
|
|
|
|
};
|
|
|
|
// cas d'une loi thermo physique
|
|
|
|
if (GroupeThermique(NouvelleLoi->Id_categorie()))
|
|
|
|
{loiTP = (CompThermoPhysiqueAbstraite *) NouvelleLoi;
|
|
|
|
// initialisation du stockage particulier thermo physique,
|
|
|
|
int imax = tabSaveTP.Taille();
|
|
|
|
for (int i=1;i<= imax;i++) tabSaveTP(i) = loiTP->New_et_Initialise();
|
|
|
|
// on active les données particulières nécessaires au fonctionnement de la loi de comp
|
|
|
|
loiTP->Activation_donnees(tab_noeud);
|
|
|
|
};
|
|
|
|
// cas d'une loi de frottement
|
|
|
|
if (GroupeFrottement(NouvelleLoi->Id_categorie()))
|
|
|
|
loiFrot = (CompFrotAbstraite *) NouvelleLoi;
|
|
|
|
};
|
|
|
|
|
|
|
|
// définition de conditions limites pouvant affecter l'élément
|
|
|
|
// on peut ainsi soit mettre une nouvelle condition, soit changer une ancienne condition
|
|
|
|
// en cours de calcul, la condition peut changer
|
|
|
|
// cas de plusieurs arêtes, la dimension des tableaux = le nombre d'arêtes
|
|
|
|
// si arTypeCL(i) == RIEN_TYPE_CL, la condition est supprimée, et vpla(i) n'est pas utilisé
|
|
|
|
void SfeMembT::DefCondLim(const Tableau <EnuTypeCL> & arTypeCL,const Tableau <Coordonnee3>& vpla )
|
|
|
|
{ // on commence par créer les tableaux locaux si besoin est
|
|
|
|
if (areteTypeCL == (&(unefois->doCoMemb->tabType_rienCL)))
|
|
|
|
{ // si ça ne pointe pas sur la valeur par défaut, alors c'est qu'il y a
|
|
|
|
// des CL particulières, on les crée donc à l'identique
|
|
|
|
areteTypeCL = new Tableau <EnuTypeCL> (3,RIEN_TYPE_CL);
|
|
|
|
vplan = new Tableau <Coordonnee3> (3);
|
|
|
|
};
|
|
|
|
// affectation
|
|
|
|
(*areteTypeCL) = arTypeCL;
|
|
|
|
int taille = areteTypeCL->Taille();
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
if ((taille != 3) && (taille != 0))
|
|
|
|
{ cout << "\n *** erreur dans la definition des conditions limites dans un element sfe, "
|
|
|
|
<< " le tableau doit etre de taille nulle ou =3 et ici la taille = " << taille;
|
|
|
|
Affiche(1);
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
if (taille == 3)
|
|
|
|
{(*vplan) = vpla; // on affecte aussi les vecteurs de directions de tangente imposée
|
|
|
|
#ifdef MISE_AU_POINT // on vérifie la taille
|
|
|
|
if (vplan->Taille() != 3)
|
|
|
|
{ cout << "\n erreur dans la definition des conditions limites dans un element sfe, "
|
|
|
|
<< "la taille du tableau vplan doit etre =3 et ici la taille = " << vplan->Taille();
|
|
|
|
Affiche(1);
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
for (int i=1; i<= 3; i++)
|
|
|
|
{ if ((*areteTypeCL)(i)!=TANGENTE_CL)
|
|
|
|
{ cout << "\n erreur dans la definition des conditions limites dans un element sfe, "
|
|
|
|
<< "elle ne peuvent etre que de type de tangente imposée alors qu'ici "
|
|
|
|
<< " elle sont de type " << NomTypeCL((*areteTypeCL)(i));
|
|
|
|
Affiche(1);
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
// on renseigne maintenant la déformation
|
|
|
|
((DeformationSfe1*) def)->RenseigneCondLim(*areteTypeCL,*vplan );
|
|
|
|
};
|
|
|
|
|
|
|
|
// définition de conditions limites pouvant affecter l'élément
|
|
|
|
// on peut ainsi soit mettre une nouvelle condition, soit changer une ancienne condition
|
|
|
|
// en cours de calcul, la condition peut changer
|
|
|
|
// cas d'une seule arête, nb_ar = le numéro de l'arete
|
|
|
|
// si arTypeCL == RIEN_TYPE_CL, la condition est supprimée, et vpla n'est pas utilisé
|
|
|
|
void SfeMembT::DefCondLim(const EnuTypeCL & arTypeCL,const Coordonnee3& vpla,const int& nb_ar)
|
|
|
|
{ // on commence par créer les tableaux locaux si besoin est
|
|
|
|
if (areteTypeCL == (&(unefois->doCoMemb->tabType_rienCL)))
|
|
|
|
{ // si ça ne pointe pas sur la valeur par défaut, alors c'est qu'il y a
|
|
|
|
// des CL particulières, on les crée donc à l'identique
|
|
|
|
areteTypeCL = new Tableau <EnuTypeCL> (3,RIEN_TYPE_CL);
|
|
|
|
vplan = new Tableau <Coordonnee3> (3);
|
|
|
|
};
|
|
|
|
// affectation
|
|
|
|
if (arTypeCL == RIEN_TYPE_CL)
|
|
|
|
// cas où l'on veut par exemple annuler une condition existante
|
|
|
|
{(*areteTypeCL)(nb_ar)=RIEN_TYPE_CL;
|
|
|
|
// on laisse le vecteur condition telle qu'il est, de toute façon on ne s'en sert pas
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// cas où l'on met une nouvelle condition
|
|
|
|
{(*areteTypeCL)(nb_ar)=arTypeCL;
|
|
|
|
(*vplan)(nb_ar)=vpla;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef MISE_AU_POINT // on vérifie la taille
|
|
|
|
{ if (arTypeCL!=TANGENTE_CL)
|
|
|
|
{ cout << "\n erreur dans la definition des conditions limites dans un element sfe, "
|
|
|
|
<< "elle ne peuvent etre que de type de tangente imposée alors qu'ici "
|
|
|
|
<< " elle sont de type " << NomTypeCL(arTypeCL);
|
|
|
|
Affiche(1);
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
// on renseigne maintenant la déformation
|
|
|
|
((DeformationSfe1*) def)->RenseigneCondLim(*areteTypeCL,*vplan );
|
|
|
|
};
|
|
|
|
|
|
|
|
// test si l'element est complet
|
|
|
|
int SfeMembT::TestComplet()
|
|
|
|
{ int res = ElemMeca::TestComplet(); // test dans la fonction mere
|
|
|
|
if (donnee_specif.epais != NULL) // test valide uniquement pour des éléments 2D
|
|
|
|
if (( donnee_specif.epais->epaisseur0 == epaisseur_defaut)
|
|
|
|
|| ( donnee_specif.epais->epaisseur_t == epaisseur_defaut)
|
|
|
|
|| ( donnee_specif.epais->epaisseur_tdt == epaisseur_defaut))
|
|
|
|
{ cout << "\n l\'epaisseur de l\'element Sfe n\'est pas defini \n";
|
|
|
|
res = 0; };
|
|
|
|
if ( tab_noeud(1) == NULL)
|
|
|
|
{ cout << "\n les noeuds de l\'element Sfe ne sont pas defini \n";
|
|
|
|
res = 0; }
|
|
|
|
else
|
|
|
|
{ int testi =1;
|
|
|
|
int posi = Id_nom_ddl("X1") -1;
|
|
|
|
int dim = ParaGlob::Dimension();
|
|
|
|
int jmax = tab_noeud.Taille();
|
|
|
|
for (int i =1; i<= dim; i++)
|
|
|
|
for (int j=1;j<=jmax;j++)
|
|
|
|
if(!(tab_noeud(j)->Existe_ici(Enum_ddl(posi+i))))
|
|
|
|
testi = 0;
|
|
|
|
// dans le cas où les épaisseurs sont stockées aux noeuds
|
|
|
|
if (donnee_specif.epais == NULL)
|
|
|
|
for (int j=1;j<=jmax;j++)
|
|
|
|
if(!(tab_noeud(j)->Existe_ici(EPAIS)))
|
|
|
|
testi = 0;
|
|
|
|
|
|
|
|
if(testi == 0)
|
|
|
|
{ cout << "\n les ddls Xi des noeuds de la facette ne sont pas defini \n";
|
|
|
|
cout << " \n utilisez SfeMembT::ConstTabDdl() pour completer " ;
|
|
|
|
res = 0;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
return res;
|
|
|
|
};
|
|
|
|
|
|
|
|
// procedure permettant de completer l'element apres
|
|
|
|
// sa creation avec les donnees du bloc transmis
|
|
|
|
// ici il s'agit de l'epaisseur et de la masse volumique
|
|
|
|
Element* SfeMembT::Complete(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD)
|
|
|
|
{ // complétion avec bloc
|
|
|
|
if (bloc.Nom(1) == "epaisseurs")
|
|
|
|
{if (donnee_specif.epais != NULL)
|
|
|
|
{ donnee_specif.epais->epaisseur0 = donnee_specif.epais->epaisseur_t
|
|
|
|
=donnee_specif.epais->epaisseur_tdt = bloc.Val(1);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ cout << "\n erreur: l'element SFE utilise une epaisseur definie aux noeuds "
|
|
|
|
<< " et non a l'element !!!!! ";
|
|
|
|
Element::Affiche(1);
|
|
|
|
Sortie(1);
|
|
|
|
return this; // pour taire le compilo
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// cas de la définition d'une stabilisation transversale pour membrane ou biel
|
|
|
|
else if (bloc.Nom(1) == "stabilisation_transvers_membrane_biel_")
|
|
|
|
{// l'objectif ici est d'allouer la raideur et résidu local spécifique à l'élément
|
|
|
|
int nbddl = (*residu).Taille();
|
|
|
|
if (unefois->doCoMemb->sfematD == NULL)
|
|
|
|
unefois->doCoMemb->sfematD = new Mat_pleine(nbddl,nbddl);
|
|
|
|
if (unefois->doCoMemb->sferesD == NULL)
|
|
|
|
unefois->doCoMemb->sferesD = new Vecteur(nbddl);
|
|
|
|
|
|
|
|
// on renseigne les pointeurs d'ElemeMeca
|
|
|
|
ElemMeca::matD = unefois->doCoMemb->sfematD;
|
|
|
|
ElemMeca::resD = unefois->doCoMemb->sferesD;
|
|
|
|
|
|
|
|
// on définie le tableau: noeud_a_prendre_en_compte
|
|
|
|
if (unefois->doCoMemb->noeud_a_prendre_en_compte == NULL)
|
|
|
|
{unefois->doCoMemb->noeud_a_prendre_en_compte = new Tableau <int> (nombre->nbnte);}
|
|
|
|
else
|
|
|
|
{unefois->doCoMemb->noeud_a_prendre_en_compte->Change_taille(nombre->nbnte);};
|
|
|
|
// on prend en compte les noeuds centraux autres que sommet
|
|
|
|
for (int i=1;i<=3;i++ )
|
|
|
|
(*unefois->doCoMemb->noeud_a_prendre_en_compte)(i)=0;
|
|
|
|
for (int i=1;i<=nombre->nbnce;i++ )
|
|
|
|
(*unefois->doCoMemb->noeud_a_prendre_en_compte)(i)=1;
|
|
|
|
// on ne prend pas en compte les noeuds externes
|
|
|
|
for (int i=nombre->nbnce+1;i<=nombre->nbnte;i++ )
|
|
|
|
(*unefois->doCoMemb->noeud_a_prendre_en_compte)(i)=0;
|
|
|
|
|
|
|
|
// ensuite les autres informations sont gérées par ElemMeca
|
|
|
|
return ElemMeca::Complete_ElemMeca(bloc,lesFonctionsnD);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ return ElemMeca::Complete_ElemMeca(bloc,lesFonctionsnD);};
|
|
|
|
};
|
|
|
|
|
|
|
|
// ajout du tableau de ddl des noeuds
|
|
|
|
void SfeMembT::ConstTabDdl()
|
|
|
|
{ int dim = ParaGlob::Dimension();
|
|
|
|
Tableau <Ddl> ta(dim);
|
|
|
|
int posi = Id_nom_ddl("X1") -1;
|
|
|
|
for (int i =1; i<= dim; i++)
|
|
|
|
{Ddl inter((Enum_ddl(i+posi)),0.,LIBRE);
|
|
|
|
ta(i) = inter;
|
|
|
|
};
|
|
|
|
// attribution des ddls aux noeuds
|
|
|
|
for (int ne=1; ne<= nombre->nbnte; ne++)
|
|
|
|
{tab_noeud(ne)->PlusTabDdl(ta);
|
|
|
|
// dans le cas où les épaisseurs sont stockées aux noeuds
|
|
|
|
// on ajoute si besoin est l'épaisseur pour les noeuds du centre
|
|
|
|
if ((donnee_specif.epais == NULL) && (ne <= nombre->nbnce))
|
|
|
|
{if (!(tab_noeud(ne)->Existe_ici(EPAIS)))
|
|
|
|
{Ddl inter(EPAIS,0.,LIBRE);
|
|
|
|
tab_noeud(ne)->PlusDdl(inter);}
|
|
|
|
else
|
|
|
|
{tab_noeud(ne)->Met_en_service(EPAIS);};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// =====>>>> methodes privées appelees par les classes dérivees <<<<=====
|
|
|
|
|
|
|
|
// fonction d'initialisation servant dans les classes derivant
|
|
|
|
// au niveau du constructeur
|
|
|
|
// nbis : nb de pt d'integ de surface,nbie : nb de pt d'integ d'epaisseur
|
|
|
|
// nbiSur : point d'intégration pour les forces de surfaces extérieures
|
|
|
|
SfeMembT::DonnComSfe* SfeMembT::Init
|
|
|
|
(ElemGeomC0* eleCentre,ElemGeomC0* eleEr,ElemGeomC0* eleS,ElemGeomC0* eleMas
|
|
|
|
,int type_calcul_jacobien,Donnee_specif donnee_spec,bool sans_init_noeud)
|
|
|
|
{ // bien que la grandeur donnee_specif est défini dans la classe generique
|
|
|
|
// le fait de le passer en paramètre permet de tout initialiser dans Init
|
|
|
|
// et ceci soit avec les valeurs par défaut soit avec les bonnes valeurs
|
|
|
|
donnee_specif =donnee_spec;
|
|
|
|
// le fait de mettre les pointeurs a null permet
|
|
|
|
// de savoir que l'element n'est pas complet
|
|
|
|
// dans le cas d'un constructeur avec tableau de noeud, il ne faut pas mettre
|
|
|
|
// les pointeurs à nuls d'où le test
|
|
|
|
if (!sans_init_noeud)
|
|
|
|
for (int i =1;i<= nombre->nbnte;i++) tab_noeud(i) = NULL;
|
|
|
|
// definition des donnees communes aux SfeMembTxxx
|
|
|
|
// a la premiere definition d'une instance
|
|
|
|
bool epaisAuNoeud = (donnee_spec.epais == NULL);
|
|
|
|
if (unefois->doCoMemb == NULL)
|
|
|
|
unefois->doCoMemb = SfeMembT::Def_DonneeCommune(epaisAuNoeud,eleCentre,eleEr,eleS,eleMas);
|
|
|
|
SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
met = &(CoSfe->met_SfeMembT); // met est defini dans elemeca
|
|
|
|
// def de la manière dont le jacobien est calculé (ex: plat ou courbe)
|
|
|
|
CoSfe->met_SfeMembT.ChangeTypeCalculJacobien(type_calcul_jacobien);
|
|
|
|
// ajout de l'interpolation dans l'epaisseur aux tableaux globaux
|
|
|
|
// def pointe sur la deformation specifique a l'element
|
|
|
|
def = new DeformationSfe1(*met,tab_noeud,CoSfe->eleCentre->TaDphi(),CoSfe->eleCentre->TaPhi()
|
|
|
|
,(CoSfe->segment).TaDphi(),(CoSfe->segment).TaPhi());
|
|
|
|
// on met les conditions limites par défaut
|
|
|
|
((DeformationSfe1*) def)->RenseigneCondLim(CoSfe->tabType_rienCL,CoSfe->vplan_rien );
|
|
|
|
// on met à jour les pointeurs sur les infos par défaut
|
|
|
|
areteTypeCL = (&(unefois->doCoMemb->tabType_rienCL));
|
|
|
|
vplan = (&(unefois->doCoMemb->vplan_rien));
|
|
|
|
|
|
|
|
// idem pour la remonte aux contraintes et le calcul d'erreur
|
|
|
|
defEr = new Deformation(*met,tab_noeud,CoSfe->eleEr->TaDphi(),CoSfe->eleEr->TaPhi());
|
|
|
|
// idem pour les calculs relatifs à la matrice de masse
|
|
|
|
defMas = new Deformation(*met,tab_noeud,CoSfe->eleMas->TaDphi(),CoSfe->eleMas->TaPhi());
|
|
|
|
// idem pour la déformation pour la surface, relative au force répartie
|
|
|
|
// pour le calcul de second membre
|
|
|
|
defSurf.Change_taille(1); // une seule surface pour le second membre
|
|
|
|
defSurf(1) = new Deformation(CoSfe->met_surf_cent,t_N_centre,
|
|
|
|
CoSfe->eleS->TaDphi(),CoSfe->eleS->TaPhi());
|
|
|
|
// pour le calcul de second membre
|
|
|
|
int nb_arrete = CoSfe->eleCentre->NbSe(); // le nombre d'arêtes
|
|
|
|
defArete.Change_taille(nb_arrete); // arrêtes utilisées pour le second membre
|
|
|
|
// la déformation sera construite si nécessaire au moment du calcul de second membre
|
|
|
|
for (int ia=1;ia<=nb_arrete;ia++)
|
|
|
|
defArete(ia) = NULL;
|
|
|
|
|
|
|
|
//dimensionnement des deformations et contraintes
|
|
|
|
int nbi = nombre->nbis * nombre->nbie;
|
|
|
|
|
|
|
|
//dimensionnement des deformations et contraintes etc..
|
|
|
|
int dimtens = 2;
|
|
|
|
if (epaisAuNoeud) dimtens = 3;
|
|
|
|
lesPtMecaInt.Change_taille_PtIntegMeca(nbi,dimtens);
|
|
|
|
// attribution des numéros de référencement dans le conteneur
|
|
|
|
for (int ni = 1; ni<= nbi; ni++)
|
|
|
|
{lesPtMecaInt(ni).Change_Nb_mail(this->num_maillage);
|
|
|
|
lesPtMecaInt(ni).Change_Nb_ele(this->num_elt);
|
|
|
|
lesPtMecaInt(ni).Change_Nb_pti(ni);
|
|
|
|
};
|
|
|
|
|
|
|
|
// stockage des donnees particulieres de la loi de comportement mécanique au point d'integ
|
|
|
|
tabSaveDon.Change_taille(nbi);
|
|
|
|
// stockage des donnees particulieres de la loi de comportement thermo physique au point d'integ
|
|
|
|
tabSaveTP.Change_taille(nbi);
|
|
|
|
// stockage des donnees particulieres de la déformation mécanique au point d'integ
|
|
|
|
tabSaveDefDon.Change_taille(nbi);
|
|
|
|
tab_energ.Change_taille(nbi);
|
|
|
|
tab_energ_t.Change_taille(nbi);
|
|
|
|
// initialisation des pointeurs définis dans la classe Element concernant les résidus et
|
|
|
|
// raideur
|
|
|
|
// --- cas de la puissance interne ---
|
|
|
|
residu = &(CoSfe->residu_interne); // residu local
|
|
|
|
raideur = &(CoSfe->raideur_interne); // raideur locale
|
|
|
|
// --- cas de la dynamique -----
|
|
|
|
mat_masse = &(CoSfe->matrice_masse);
|
|
|
|
// --- cas des efforts externes concernant les points ------
|
|
|
|
res_extN = &(CoSfe->residus_externeN); // pour les résidus et second membres
|
|
|
|
raid_extN= &(CoSfe->raideurs_externeN);// pour les raideurs
|
|
|
|
// --- cas des efforts externes concernant les aretes ------
|
|
|
|
res_extA = &(CoSfe->residus_externeA); // pour les résidus et second membres
|
|
|
|
raid_extA= &(CoSfe->raideurs_externeA);// pour les raideurs
|
|
|
|
// --- cas des efforts externes concernant les faces ------
|
|
|
|
res_extS= &(CoSfe->residus_externeS); // pour les résidus et second membres
|
|
|
|
raid_extS= &(CoSfe->raideurs_externeS); // pour les raideurs
|
|
|
|
|
|
|
|
|
|
|
|
return CoSfe;
|
|
|
|
};
|
|
|
|
|
|
|
|
// fonction permettant le calcul de CoSfe
|
|
|
|
// epaisAuNoeud indique si oui ou non l'épaisseur est définit aux noeuds
|
|
|
|
SfeMembT::DonnComSfe* SfeMembT::Def_DonneeCommune (bool epaisAuNoeud,ElemGeomC0* eleCentre
|
|
|
|
,ElemGeomC0* eleEr,ElemGeomC0* eleS,ElemGeomC0* eleMas)
|
|
|
|
{ SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
// interpollation
|
|
|
|
Enum_type_pt_integ type_pti=PTI_GAUSS;
|
|
|
|
// dans le cas d'un nombre impair > 2, on utilise des points de Gauss lobatto
|
|
|
|
if(nombre->nbie > 2)
|
|
|
|
{ if (nombre->nbie % 2 == 1)
|
|
|
|
type_pti=PTI_GAUSS_LOBATTO;
|
|
|
|
};
|
|
|
|
GeomSeg seg(nombre->nbie,2,type_pti); // interpolation dans l'épaisseur
|
|
|
|
// degre de liberte
|
|
|
|
int dim = 3;
|
|
|
|
int nb_epais=0;
|
|
|
|
if (epaisAuNoeud) nb_epais = 1;
|
|
|
|
|
|
|
|
// --- def du tableau de ddl pour l'élément, il est ici possible que les noeuds n'aient
|
|
|
|
// pas tous le même nombre de ddl actif (pour le centre xi+epai, pour les autres uniquement xi)
|
|
|
|
Tableau <int> mddl(nombre->nbnte); //contient le nb de ddl actif par noeud
|
|
|
|
for (int ne = 1;ne<= nombre->nbnce;ne++) mddl(ne)=dim+nb_epais;
|
|
|
|
for (int ne=nombre->nbnce+1;ne<=nombre->nbnte;ne++) mddl(ne)=dim;
|
|
|
|
DdlElement tab_ddl(nombre->nbnte,mddl);
|
|
|
|
// on le remplit
|
|
|
|
int posi = Id_nom_ddl("X1") -1;
|
|
|
|
for (int i =1; i<= dim; i++)
|
|
|
|
for (int j=1; j<= nombre->nbnte; j++)
|
|
|
|
// tab_ddl (j,i) = Enum_ddl(i+posi);
|
|
|
|
tab_ddl.Change_Enum(j,i,Enum_ddl(i+posi));
|
|
|
|
// pour l'épaisseur éventuellement
|
|
|
|
if (epaisAuNoeud)
|
|
|
|
for (int j=1; j<= nombre->nbnce; j++)
|
|
|
|
tab_ddl.Change_Enum(j,dim+nb_epais,EPAIS);
|
|
|
|
// on définit le tableau de correspondance entre la numérotation des ddl dans la métrique et
|
|
|
|
// celui dans tab_ddl. Pour la métrique, on a d'abord tous les ddl de xi, puis à la fin
|
|
|
|
// les ddl d'épaisseurs éventuel. Dans tab_ddl, on a pour chaque noeud central ddlxi puis epais
|
|
|
|
// et pour les ddl externes que les xi
|
|
|
|
int nbddl = tab_ddl.NbDdl(); int nbddl_xi = tab_ddl.NbDdl_famille(X1);
|
|
|
|
Tableau <int> nMetVTab_ddl(nbddl);
|
|
|
|
|
|
|
|
if (!epaisAuNoeud)
|
|
|
|
// cas sans ddl d'épaisseur
|
|
|
|
{for (int i=1;i<=nbddl;i++) nMetVTab_ddl(i)=i;}
|
|
|
|
else
|
|
|
|
// cas avec des ddl d'épaisseur
|
|
|
|
{int iddl=1;
|
|
|
|
// d'abord les xi du centre
|
|
|
|
for (int ne = 1;ne <= nombre->nbnce; ne++)
|
|
|
|
for (int i=1;i<=dim;i++,iddl++)
|
|
|
|
nMetVTab_ddl(iddl) = i + (ne-1) * (dim+1);
|
|
|
|
// puis les xi des noeuds externes
|
|
|
|
int decalxi = nombre->nbnce*(dim+1); // le total de ddl xi du centre pour tab_ddl
|
|
|
|
int nddcentreXi = nombre->nbnce*dim; // le total de ddl xi du centre pour metsfe
|
|
|
|
int restexi = nbddl_xi - nddcentreXi;
|
|
|
|
for (int ddi = 1;ddi<=restexi;ddi++,iddl++)
|
|
|
|
nMetVTab_ddl(iddl) = ddi + decalxi;
|
|
|
|
// puis les épaisseurs
|
|
|
|
for (int iep=1;iep<= nombre->nbnce;iep++,iddl++)
|
|
|
|
nMetVTab_ddl(iddl) = iep * (dim+1);
|
|
|
|
};
|
|
|
|
|
|
|
|
// cas des ddl éléments secondaires pour le calcul d'erreur
|
|
|
|
// def du nombre de composantes du tenseur de contrainte en absolu
|
|
|
|
int nbcomposante = ParaGlob::NbCompTens ();
|
|
|
|
DdlElement tab_ddlErr(nombre->nbnce,nbcomposante);
|
|
|
|
posi = Id_nom_ddl("SIG11") -1;
|
|
|
|
// uniquement deux cas a considéré 3 ou 6 composantes
|
|
|
|
for (int j=1; j<= nombre->nbnce; j++)
|
|
|
|
{// on definit le nombre de composante de sigma en absolu
|
|
|
|
if (nbcomposante == 3)
|
|
|
|
// dans l'énumération les composantes ne sont pas a suivre
|
|
|
|
{//tab_ddlErr (j,1) = Enum_ddl(1+posi); // cas de SIG11
|
|
|
|
//tab_ddlErr (j,2) = Enum_ddl(2+posi); // cas de SIG22
|
|
|
|
//tab_ddlErr (j,3) = Enum_ddl(4+posi); // cas de SIG12
|
|
|
|
tab_ddlErr.Change_Enum(j,1,Enum_ddl(1+posi)); // cas de SIG11
|
|
|
|
tab_ddlErr.Change_Enum(j,2,Enum_ddl(2+posi)); // cas de SIG22
|
|
|
|
tab_ddlErr.Change_Enum(j,3,Enum_ddl(4+posi)); // cas de SIG12
|
|
|
|
}
|
|
|
|
else if (nbcomposante == 6)
|
|
|
|
// les composantes sont a suivre dans l'enumération
|
|
|
|
for (int i= 1;i<= nbcomposante; i++)
|
|
|
|
// tab_ddlErr (j,i) = Enum_ddl(i+posi);
|
|
|
|
tab_ddlErr.Change_Enum(j,i,Enum_ddl(i+posi));
|
|
|
|
};
|
|
|
|
// egalement pour tab_Err1Sig11, def d'un tableau de un ddl : enum SIG11
|
|
|
|
// par noeud
|
|
|
|
DdlElement tab_Err1Sig11(nombre->nbnce,DdlNoeudElement(SIG11));
|
|
|
|
// toujours pour le calcul d'erreur definition des fonctions d'interpolation
|
|
|
|
// pour le calcul du hession de la fonctionnelle
|
|
|
|
GeomSeg segEr(nombre->nbieEr);
|
|
|
|
// pour les calculs relatifs à la matrice masse
|
|
|
|
GeomSeg segMas(nombre->nbieMas);
|
|
|
|
// pour le calcul des seconds membres
|
|
|
|
GeomSeg segS(nombre->nbiA,nombre->nbneA);
|
|
|
|
|
|
|
|
// --- def metrique
|
|
|
|
// on definit les variables a priori toujours utiles
|
|
|
|
Tableau<Enum_variable_metrique> tab(27);
|
|
|
|
tab(1) = iM0; tab(2) = iMt; tab(3) = iMtdt ;
|
|
|
|
tab(4) = igiB_0; tab(5) = igiB_t; tab(6) = igiB_tdt;
|
|
|
|
tab(7) = igiH_0; tab(8) = igiH_t; tab(9) = igiH_tdt ;
|
|
|
|
tab(10)= igijBB_0; tab(11)= igijBB_t; tab(12)= igijBB_tdt;
|
|
|
|
tab(13)= igijHH_0; tab(14)= igijHH_t; tab(15)= igijHH_tdt ;
|
|
|
|
tab(16)= id_gijBB_tdt; tab(17)= id_giH_tdt; tab(18)= id_gijHH_tdt;
|
|
|
|
tab(19)= idMtdt ; tab(20)= id_jacobien_tdt;tab(21)= id2_gijBB_tdt;
|
|
|
|
tab(22)= igradVBB_tdt; tab(23) = iVtdt; tab(24)= idVtdt;
|
|
|
|
tab(25)= id_giB_t; tab(26)= id_giH_t; tab(27)= id_giB_tdt;
|
|
|
|
// tableau de ddl et la def de variables
|
|
|
|
|
|
|
|
// def du nombre de vecteur de la métrique pour l'élément SFE, donc choix entre tenseur 2x2 ou 3x3
|
|
|
|
int nbvec = 2; // choix par défaut
|
|
|
|
if (epaisAuNoeud) nbvec = 3;
|
|
|
|
Met_Sfe1 metri(tab_ddl,nbvec,tab,id_interpol,nombre->nbnce) ;
|
|
|
|
|
|
|
|
// --- def de la métrique de surface qui est utile en particulier pour calculer les forces externes ---
|
|
|
|
// !! on n'utilise que la facette centrale et les ddl xi uniquement !!
|
|
|
|
// en effet: on part du principe que cette métrique et la def associée ne seront relatives qu'aux ddl de déplacement
|
|
|
|
// en particulier on ne tiend pas compte d'un ddl d'épaisseur éventuel: par exemple on estime que la
|
|
|
|
// variation des efforts dus à une pression, ne dépend pas des ddl d'épaisseur (s'ils existent)
|
|
|
|
// == on reconstruit un DdlElement relatif aux xi uniquement
|
|
|
|
// --- def du tableau de ddl pour l'élément, il est ici possible que les noeuds n'aient
|
|
|
|
// pas tous le même nombre de ddl actif (pour le centre xi+epai, pour les autres uniquement xi)
|
|
|
|
Tableau <int> mddl_C(nombre->nbnce); //contient le nb de ddl xi par noeud
|
|
|
|
for (int ne = 1;ne<= nombre->nbnce;ne++)
|
|
|
|
mddl_C(ne)=dim;
|
|
|
|
DdlElement tab_ddlXi_C(nombre->nbnce,mddl_C);
|
|
|
|
// on le remplit
|
|
|
|
posi = Id_nom_ddl("X1") -1;
|
|
|
|
for (int i =1; i<= dim; i++)
|
|
|
|
for (int j=1; j<= nombre->nbnce; j++)
|
|
|
|
tab_ddlXi_C.Change_Enum(j,i,Enum_ddl(i+posi));
|
|
|
|
// == maintenant on s'occupe de définir la métrique
|
|
|
|
int nbvec_surf = 2; // nombre de vecteur de la surface médiane
|
|
|
|
Met_abstraite met_centrale(dim,nbvec_surf,tab_ddlXi_C,tab,nombre->nbnce);
|
|
|
|
|
|
|
|
// ---- cas du calcul d'erreur sur sigma ou epsilon
|
|
|
|
// les tenseurs sont exprimees en absolu donc nombre de composante fonction
|
|
|
|
// de la dimension absolue
|
|
|
|
Tableau <Vecteur *> resEr(nbcomposante);
|
|
|
|
for (int i=1; i<= nbcomposante; i++)
|
|
|
|
resEr(i)=new Vecteur (nombre->nbnce);
|
|
|
|
Mat_pleine raidEr(nombre->nbnce,nombre->nbnce); // la raideur pour l'erreur
|
|
|
|
// dimensionnement des différents résidus et raideurs pour le calcul mécanique
|
|
|
|
Vecteur residu_int(nbddl); Mat_pleine raideur_int(nbddl,nbddl);
|
|
|
|
// cas de la dynamique
|
|
|
|
Mat_pleine matmasse(1,nbddl); // a priori on dimensionne en diagonale
|
|
|
|
// cas des noeuds
|
|
|
|
//*** pour l'instant , le dimensionnement pour les noeuds et pour les arêtes n'est pas correcte dans le cas
|
|
|
|
// où il y a un ddl d'épaisseur au noeuds (voir face interne comme exemple correcte)
|
|
|
|
Tableau <Vecteur* > residus_extN(nombre->nbnce);
|
|
|
|
residus_extN(1) = new Vecteur(dim);
|
|
|
|
Tableau <Mat_pleine* > raideurs_extN(nombre->nbnce);
|
|
|
|
raideurs_extN(1) = new Mat_pleine(dim,dim);
|
|
|
|
for (int i = 2;i<= nombre->nbnce;i++)
|
|
|
|
{ residus_extN(i) = residus_extN(1);
|
|
|
|
raideurs_extN(i) = raideurs_extN(1);
|
|
|
|
}
|
|
|
|
// cas des arêtes
|
|
|
|
int nbddlA = nombre->nbneA * dim; int nbA = 3; // 3 arêtes internes
|
|
|
|
Tableau <Vecteur* > residus_extA(nbA); residus_extA(1) = new Vecteur(nbddlA);
|
|
|
|
residus_extA(2) = residus_extA(1); residus_extA(3) = residus_extA(1);
|
|
|
|
Tableau <Mat_pleine* > raideurs_extA(nbA);
|
|
|
|
raideurs_extA(1) = new Mat_pleine(nbddlA,nbddlA);
|
|
|
|
raideurs_extA(2) = raideurs_extA(1); raideurs_extA(3) = raideurs_extA(1);
|
|
|
|
|
|
|
|
// cas de la face interne
|
|
|
|
int nbddlS = nombre->nbnce * dim; // ddl pour la face
|
|
|
|
Vecteur * res_extS_inter=NULL; Mat_pleine * raid_extS_inter=NULL; // grandeurs intermédiaires
|
|
|
|
if (epaisAuNoeud)
|
|
|
|
{// on définit les tableaux inter, de dimensionnement classique pour pouvoir
|
|
|
|
// utiliser les méthodes classiques d'ElemMeca
|
|
|
|
res_extS_inter = new Vecteur(nbddlS);
|
|
|
|
raid_extS_inter = new Mat_pleine(nbddlS,nbddlS);
|
|
|
|
// puis on prend en compte le ddl d'épaisseur
|
|
|
|
nbddlS += nombre->nbnce; // on ajoute l'épaisseur
|
|
|
|
};
|
|
|
|
Tableau <Vecteur* > residus_extS(1); residus_extS(1) = new Vecteur(nbddlS);
|
|
|
|
Tableau <Mat_pleine* > raideurs_extS(1);
|
|
|
|
raideurs_extS(1) = new Mat_pleine(nbddlS,nbddlS);
|
|
|
|
// définition des conditions limites par défaut
|
|
|
|
Tableau <EnuTypeCL> tabType_rienCL(3);
|
|
|
|
tabType_rienCL(1)=RIEN_TYPE_CL;tabType_rienCL(2)=RIEN_TYPE_CL;
|
|
|
|
tabType_rienCL(3)=RIEN_TYPE_CL;
|
|
|
|
Tableau <Coordonnee3> vplan_rien(3); // initialisé à 0. par défaut
|
|
|
|
// definition de la classe static contenant toute les variables communes aux SfeMembT
|
|
|
|
SfeMembT::DonnComSfe* dodo;
|
|
|
|
dodo = new DonnComSfe
|
|
|
|
(eleCentre,seg,tab_ddl,tab_ddlErr,tab_Err1Sig11,tab_ddlXi_C,metri,resEr,raidEr,eleEr,segEr,eleS,segS
|
|
|
|
,residu_int,raideur_int,residus_extN,raideurs_extN,residus_extA,raideurs_extA,residus_extS,raideurs_extS
|
|
|
|
,matmasse,eleMas,segMas,nombre->nbis * nombre->nbie,tabType_rienCL,vplan_rien,nMetVTab_ddl,met_centrale);
|
|
|
|
|
|
|
|
return dodo;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// destructions de certaines grandeurs pointées, créées au niveau de l'initialisation
|
|
|
|
void SfeMembT::Destruction()
|
|
|
|
{ // tout d'abord l'idée est de détruire certaines grandeurs pointées que pour le dernier élément
|
|
|
|
if ((unefois->nbelem_in_Prog == 0)&& (unefois->doCoMemb != NULL))
|
|
|
|
// cas de la destruction du dernier élément
|
|
|
|
{ SfeMembT::DonnComSfe* CoSfe = unefois->doCoMemb; // pour simplifier l'écriture
|
|
|
|
int resErrTaille = CoSfe->resErr.Taille();
|
|
|
|
for (int i=1;i<= resErrTaille;i++)
|
|
|
|
delete CoSfe->resErr(i);
|
|
|
|
delete CoSfe->residus_externeN(1);
|
|
|
|
delete CoSfe->raideurs_externeN(1);
|
|
|
|
delete CoSfe->residus_externeA(1);
|
|
|
|
delete CoSfe->raideurs_externeA(1);
|
|
|
|
delete CoSfe->residus_externeS(1);
|
|
|
|
delete CoSfe->raideurs_externeS(1);
|
|
|
|
// suppression des éléments géométriques de référence
|
|
|
|
delete CoSfe->eleCentre; delete CoSfe->eleEr; delete CoSfe->eleS; delete CoSfe->eleMas;
|
|
|
|
};
|
|
|
|
// enfin il faut certaine fois supprimer les conditions limites tant que unefois existe
|
|
|
|
// comme unefois pointe sur un membre statique de la classe dérivée, si on attend d'arriver dans
|
|
|
|
// le destructeur de SfeMembT il n'existe plus à ce moment là donc erreur
|
|
|
|
if (areteTypeCL != (&(unefois->doCoMemb->tabType_rienCL)))
|
|
|
|
// si ça ne pointe pas sur la valeur par défaut, alors c'est qu'il y a
|
|
|
|
// des CL particulières, on les supprime
|
|
|
|
{ delete areteTypeCL; delete vplan;};
|
|
|
|
|
|
|
|
};
|