3038 lines
167 KiB
C++
3038 lines
167 KiB
C++
|
|
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
#include "LesCondLim.h"
|
|
#include "CharUtil.h"
|
|
#include "SfeMembT.h"
|
|
#include "TypeQuelconqueParticulier.h"
|
|
|
|
|
|
// --- conteneur pour les réactions -----
|
|
// surcharge de l'operator de lecture typée
|
|
istream & operator >> (istream & ent , LesCondLim::ReactStoc & a)
|
|
{ // lecture du type et vérification
|
|
string nom_type;
|
|
ent >> nom_type;
|
|
if (nom_type != "ReactStoc")
|
|
Sortie(1);
|
|
// lecture des infos
|
|
ent >> a.numMail >> a.numNoeud >> a.ddl >> a.casAss;
|
|
return ent;
|
|
};
|
|
// surcharge de l'operator d'ecriture typée
|
|
ostream & operator << (ostream & sort , const LesCondLim::ReactStoc & a)
|
|
{ // écriture du type
|
|
sort << "ReactStoc ";
|
|
// les données
|
|
sort << a.numMail << " " << a.numNoeud << " " << a.ddl <<" "<< a.casAss;
|
|
return sort;
|
|
};
|
|
|
|
// surcharge de l'operator de lecture typée
|
|
istream & operator >> (istream & ent , LesCondLim::TorseurReac & a)
|
|
{ // lecture du type et vérification
|
|
string nom_type;
|
|
ent >> nom_type;
|
|
if (nom_type != "TorseurReac")
|
|
Sortie(1);
|
|
// lecture des infos
|
|
ent >> a.existe_torseur_reac >> a.resultante >> a.moment ;
|
|
return ent;
|
|
};
|
|
// surcharge de l'operator d'ecriture typée
|
|
ostream & operator << (ostream & sort , const LesCondLim::TorseurReac & a)
|
|
{ // écriture du type
|
|
sort << " TorseurReac ";
|
|
// les données
|
|
sort << a.existe_torseur_reac << " " << a.resultante << " " << a.moment <<" ";
|
|
return sort;
|
|
};
|
|
|
|
// --- fin conteneur pour les réactions -----
|
|
|
|
// CONSTRUCTEURS :
|
|
LesCondLim::LesCondLim () : // par defaut
|
|
tabBloq(),tabInit(),condlim()
|
|
,reaction(),reaction_CLin(),reactionApresCHrepere()
|
|
,tab_torseurReac(),ttRG(),ttorBloq()
|
|
,tab_iocondiline(),tab_CLinApplique(),ttRGCLL(),ttorCLL()
|
|
,ttRG_noms_ref(),ttRGCLL_noms_ref()
|
|
// ,map_reaction()
|
|
,nb_maillage(0)
|
|
,tempsCL(),tempsCLL()
|
|
{ };
|
|
|
|
// DESTRUCTEUR :
|
|
LesCondLim::~LesCondLim ()
|
|
{ };
|
|
|
|
// METHODES PUBLIQUES :
|
|
// lecture des conditions limites : ddl bloque
|
|
void LesCondLim::Lecture1(UtilLecture & entreePrinc,LesReferences& lesRef)
|
|
{ MotCle motCle; // ref aux mots cle
|
|
// on se positionne sur un mot cle
|
|
while ( !motCle.SimotCle(entreePrinc.tablcar))
|
|
entreePrinc.NouvelleDonnee();
|
|
bool sortie_info = false;
|
|
if ( (strstr(entreePrinc.tablcar,"blocages")!=NULL) ) // à rajouter tous les cas de lectures éventuelles
|
|
{if (ParaGlob::NiveauImpression() >= 4)
|
|
cout << " debut de la lecture des conditions limites ddl bloque " << endl;
|
|
sortie_info = true;
|
|
};
|
|
|
|
// def d'une instance de classe de lecture de Ddl
|
|
LectBloc <DdlLim> lecDdl;
|
|
|
|
// lecture eventuelle des blocages en condition limite
|
|
lecDdl.Lecture(entreePrinc,lesRef,"blocages",
|
|
"lecture des blocages de ddl en condition limite",tabBloq);
|
|
// dimensionnement du tableau des torseurs résultants
|
|
LesCondLim::DimensionneTorseurs();
|
|
|
|
|
|
if ((ParaGlob::NiveauImpression() >= 4)&& sortie_info)
|
|
cout << " fin de la lecture des conditions limites ddl bloque " << endl;
|
|
};
|
|
|
|
// lecture des conditions limites linéaire
|
|
void LesCondLim::Lecture2(UtilLecture & entreePrinc,LesReferences& lesRef)
|
|
{ MotCle motCle; // ref aux mots cle
|
|
// on se positionne sur un mot cle
|
|
while ( !motCle.SimotCle(entreePrinc.tablcar))
|
|
entreePrinc.NouvelleDonnee();
|
|
bool sortie_info = false;
|
|
if ( (strstr(entreePrinc.tablcar,"condition_limite_lineaire_")!=NULL) ) // à rajouter tous les cas de lectures éventuelles
|
|
{if (ParaGlob::NiveauImpression() >= 4)
|
|
cout << " debut de la lecture des conditions limites lineaires " << endl;
|
|
sortie_info = true;
|
|
};
|
|
|
|
// def d'une instance de classe de lecture de Ddl
|
|
LectBloc <I_O_Condilineaire> lecI_O_Condli;
|
|
|
|
// lecture eventuelle des conditions linéaire en condition limite
|
|
lecI_O_Condli.Lecture(entreePrinc,lesRef,"condition_limite_lineaire_",
|
|
"lecture des conditions limites lineaires ",tab_iocondiline);
|
|
// mise à jour de la dimension du tableau associé: tab_CLinApplique
|
|
tab_CLinApplique.Change_taille(tab_iocondiline.Taille());
|
|
|
|
// dimensionnement du tableau des torseurs résultants
|
|
LesCondLim::DimensionneTorseurs();
|
|
|
|
if ((ParaGlob::NiveauImpression() >= 4)&& sortie_info)
|
|
cout << " fin de la lecture des conditions limites lineaire " << endl;
|
|
};
|
|
|
|
// lecture des conditions limites : initialisation
|
|
void LesCondLim::Lecture3(UtilLecture & entreePrinc,LesReferences& lesRef)
|
|
{ MotCle motCle; // ref aux mots cle
|
|
// on se positionne sur un mot cle
|
|
while ( !motCle.SimotCle(entreePrinc.tablcar))
|
|
entreePrinc.NouvelleDonnee();
|
|
|
|
bool sortie_info = false;
|
|
if ( (strstr(entreePrinc.tablcar,"initialisation")!=NULL) ) // à rajouter tous les cas de lectures éventuelles
|
|
{if (ParaGlob::NiveauImpression() >= 4)
|
|
cout << " debut de la lecture des conditions d'initialisation " << endl;
|
|
sortie_info = true;
|
|
};
|
|
// def d'une instance de classe de lecture de Ddl
|
|
LectBloc <DdlLim> lecDdl;
|
|
|
|
// lecture eventuelle des conditions limites d'initialisation
|
|
lecDdl.Lecture(entreePrinc,lesRef,"initialisation",
|
|
"lecture des conditions limites d\'initialisation",tabInit);
|
|
if ((ParaGlob::NiveauImpression() >= 4) && sortie_info)
|
|
cout << " fin de la lecture des conditions d'initialisation " << endl;
|
|
|
|
//debug
|
|
//Affiche();
|
|
//fin debug
|
|
|
|
};
|
|
|
|
// affichage des informations concernant les conditions limites
|
|
void LesCondLim::Affiche() const // affichage de tous les infos
|
|
{ Affiche1();
|
|
Affiche2();
|
|
Affiche3();
|
|
};
|
|
|
|
void LesCondLim::Affiche1() const
|
|
{ if (tabBloq.Taille() != 0)
|
|
{cout << "\n ******** conditions limites : ddl bloque ******** \n";
|
|
cout << tabBloq.Taille() << " reference de conditions limites lue \n";
|
|
int tabBloqTaille = tabBloq.Taille();
|
|
for (int i=1; i<=tabBloqTaille; i++)
|
|
tabBloq(i).Affiche();
|
|
cout << "\n\n";
|
|
}
|
|
};
|
|
void LesCondLim::Affiche2() const
|
|
{
|
|
if (tabInit.Taille() != 0)
|
|
{cout << "\n ******** conditions limites : lineaire ******** \n";
|
|
cout << tab_iocondiline.Taille() << " reference de conditions limites lue \n";
|
|
int tabInitTaille = tabInit.Taille();
|
|
for (int i=1; i<=tabInitTaille; i++)
|
|
tabInit(i).Affiche();
|
|
cout << "\n\n";
|
|
}
|
|
};
|
|
void LesCondLim::Affiche3() const
|
|
{
|
|
if (tabInit.Taille() != 0)
|
|
{cout << "\n ******** conditions limites : initialisation ******** \n";
|
|
cout << tabInit.Taille() << " reference de conditions limites lue \n";
|
|
int tabInitTaille = tabInit.Taille();
|
|
for (int i=1; i<=tabInitTaille; i++)
|
|
tabInit(i).Affiche();
|
|
cout << "\n\n";
|
|
}
|
|
};
|
|
|
|
// introduction des données et variables pour leurs emplois futures, avec init par défaut
|
|
void LesCondLim::IntroductionDonnees(LesMaillages * lesMail,LesReferences* lesRef
|
|
,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD)
|
|
{
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
// 1) on parcours le tableau de ddl d'initialisation
|
|
int tabInitTaille = tabInit.Taille();
|
|
for (int i=1;i<= tabInitTaille;i++)
|
|
{ DdlLim& tabInit_i = tabInit(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const Reference & refinitial = lesRef->Trouve(tabInit_i.NomRef(),tabInit_i.NomMaillage());
|
|
if ((refinitial.Indic() == 4) &&
|
|
(tabInit_i.TypeDeCL()==TANGENTE_CL))
|
|
{// cas des références d'arêtes, avec des conditions initiales de tangente imposée
|
|
// ici on vérifie que les données d'entrées sont cohérentes, c'est tout
|
|
const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// on renseigne les éléments ad hoc
|
|
int refTaille = ref.Taille();
|
|
for (int ne =1; ne<= refTaille;ne++)
|
|
{int tabInitiTaille = tabInit_i.Taille();
|
|
// dans le cas d'une référence de champ on vérifie le nombre de ddlLim
|
|
if ((tabInit_i.Champ()) && (tabInitiTaille != ref.Taille()))
|
|
{cout << "\n erreur: la condition limite de champ n'a pas le meme nombre de ddl bloque"
|
|
<< " que le nombre d'element de la reference associee !! "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
// dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
if (tabInit_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl1 = tabInit_i.ElemLim(nd); // récup des 3 ddl
|
|
Ddl ddl2 = tabInit_i.ElemLim(nd+1); // récup des 3 ddl
|
|
Ddl ddl3 = tabInit_i.ElemLim(nd+2); // récup des 3 ddl
|
|
|
|
// on vérifie qu'il s'agit bien de 3 coordonnées
|
|
if (ddl1.Id_nom()!=X1)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le premier ddl doit etre X1 "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
if (ddl2.Id_nom()!=X2)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le deuxieme ddl doit etre X2 "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
if (ddl3.Id_nom()!=X3)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le troisieme ddl doit etre X3 "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
// on vérifie que le numéro de l'arête existe bien
|
|
int num_elem = ref.NumeroElem(ne);
|
|
int num_ar = ref.NumeroFA(ne);
|
|
// récup de l'élément
|
|
Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),num_elem);
|
|
if (!(el.AreteExiste(num_ar)))
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, l'arete nb : " << num_ar
|
|
<< " pour l'element " << num_elem << " n'existe pas !! "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
// on vérifie que c'est un élément sfe
|
|
if (!(ElementSfe(el.Id_interpolation())))
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, les elements doivent etre "
|
|
<< " de type SFE : et non l'element= "; el.Affiche(1);
|
|
cout << "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabInit_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
}// fin boucle sur tabInit_i
|
|
}// fin boucle sur les éléments de la référence
|
|
} // ---- fin du cas des conditions initiales d'encastrement ou de symétrie pour les SFE
|
|
|
|
else if (refinitial.Indic() != 1)
|
|
// cas d'element
|
|
{ cout << "\n introduction autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
cout << "void LesCondLim::IntroductionDonnees(... " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
else
|
|
// cas de noeuds
|
|
{// traitement proprement dit
|
|
const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
int refTaille = ref.Taille();
|
|
for (int nn =1; nn<= refTaille;nn++)
|
|
{int tabInitiTaille = tabInit_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
if (tabInit_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl = tabInit_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// ---modif 10 sep 2017
|
|
// cas ou le ddl n'existe pas
|
|
// on le met en service et comme on ne sait pas s'il va être actif ou pas, on le met libre
|
|
// c'est-à-dire qu'il n'est pas pour l'instant imposé à quelque chose
|
|
// on fait cela, et ce qu'il y avait avant, car sinon, le ddl au niveau des noeuds n'est pas
|
|
// mis à jour de t à tdt car seule les ddl qui ne sont pas HS, sont mis à jour
|
|
// or le fait que le ddl soit géré par une condition limite fait qu'il est succeptible d'être
|
|
// utilisé à t et tdt, donc il ne faut pas le mettre en HS
|
|
// par contre on le met en lisible c-a-d en donnée par défaut
|
|
|
|
ddl.ChangeVariable_a_Donnee();
|
|
if (!(noe.Existe_ici(ddl.Id_nom())))
|
|
// cas ou le ddl n'existe pas
|
|
// si cas d'un ddl de déplacement, et que le ddl X1 existe déjà, pas de pb, on ne fait rien
|
|
// { if (!((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))))
|
|
{ if (!((noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))))
|
|
{ // sinon cas d'un ddl inexistant diff de U ou qu'il n'y a pas de X1, alors création puis
|
|
// initialisation a zero et on indique qu'il est hors service (non !! voir la modif 10 sept 2017)
|
|
noe.PlusDdl(ddl);
|
|
noe.Change_val_0(ddl.Id_nom(),0.);
|
|
noe.Change_val_t(ddl.Id_nom(),0.);
|
|
// ---modif 10 sep 2017 // puis on indique que le ddl est bloque et hors service
|
|
// ---modif 10 sep 2017 noe.Met_hors_service(ddl.Id_nom());
|
|
noe.Met_en_service(ddl.Id_nom());
|
|
|
|
noe.Change_fixe(ddl.Id_nom(),true);
|
|
}
|
|
} // fin du if (!(noe.Existe_ici(ddl.Id_nom())))
|
|
} // fin de la boucle sur les ddl
|
|
} // fin de la boucle sur les noeuds de la référence
|
|
} // fin du traitement pour les noeuds
|
|
} // fin de la boucle sur le tableau générale d'initialisation
|
|
|
|
// 2) cas des ddl imposes on verifie leurs existences et on crée si besoin
|
|
// on parcours le tableau de ddl bloques
|
|
// mais on ne met pas les valeurs en places, ce sera fait lors de la mise à jour à tdt
|
|
int tabBloqTaille = tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const Reference & refinitial = lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage());
|
|
if ((refinitial.Indic() == 4) && (tabBloq_i.TypeDeCL()==TANGENTE_CL) )
|
|
{// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
// on s'occupe de vérifier la cohérence de l'entrée des données, c'est tout
|
|
const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// on renseigne les éléments ad hoc
|
|
int refTaille = ref.Taille();
|
|
for (int ne =1; ne<= refTaille;ne++)
|
|
{int tabBloqiTaille = tabBloq_i.Taille();
|
|
// dans le cas d'une référence de champ on vérifie le nombre de ddlLim
|
|
if ((tabBloq_i.Champ()) && (tabBloqiTaille != ref.Taille()))
|
|
{cout << "\n erreur: la condition limite de champ n'a pas le meme nombre de ddl bloque"
|
|
<< " que le nombre d'element de la reference associee !! "
|
|
<< "\n void LesCondLim::IntroductionDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
// dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl1 = tabBloq_i.ElemLim(nd); // récup des 3 ddl
|
|
Ddl ddl2 = tabBloq_i.ElemLim(nd+1); // récup des 3 ddl
|
|
Ddl ddl3 = tabBloq_i.ElemLim(nd+2); // récup des 3 ddl
|
|
|
|
// on vérifie qu'il s'agit bien de 3 coordonnées
|
|
if (ddl1.Id_nom()!=X1)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le premier ddl doit etre X1 "
|
|
<< "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
if (ddl2.Id_nom()!=X2)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le deuxieme ddl doit etre X2 "
|
|
<< "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
if (ddl3.Id_nom()!=X3)
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, le troisieme ddl doit etre X3 "
|
|
<< "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
// on vérifie que le numéro de l'arête existe bien
|
|
int num_elem = ref.NumeroElem(ne);
|
|
int num_ar = ref.NumeroFA(ne);
|
|
// récup de l'élément
|
|
Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),num_elem);
|
|
if (!(el.AreteExiste(num_ar)))
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, l'arete nb : " << num_ar
|
|
<< " pour l'element " << num_elem << " n'existe pas !! "
|
|
<< "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
// on vérifie que c'est un élément sfe
|
|
if (!(ElementSfe(el.Id_interpolation())))
|
|
{cout << "\n erreur: pour l'encastrement ou la symetrie, les elements doivent etre "
|
|
<< " de type SFE : et non l'element= "; el.Affiche(1);
|
|
cout << "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
}// fin boucle sur tabBloq_i
|
|
}// fin boucle sur les noeuds de la référence
|
|
} // ---- fin du cas des conditions d'encastrement ou de symétrie pour les SFE
|
|
|
|
else if (refinitial.Indic() != 1) // cas d'une autre référence que des noeuds
|
|
// cas d'element
|
|
{ cout << "\n blocage autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
cout << "\n void LesCondLim::InitialDonnees(... " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
}
|
|
else
|
|
// cas de noeuds
|
|
{const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
int refTaille = ref.Taille();
|
|
for (int nn =1; nn<= refTaille;nn++)
|
|
{int tabBloqiTaille = tabBloq_i.Taille();
|
|
// dans le cas d'une référence de champ on vérifie le nombre de ddlLim
|
|
if ((tabBloq_i.Champ()) && (tabBloqiTaille != ref.Taille()))
|
|
{cout << "\n erreur: la condition limite de champ n'a pas le meme nombre de ddl bloque"
|
|
<< " que le nombre de noeud de la reference associee !! "
|
|
<< "\n void LesCondLim::InitialDonnees(... ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd); // récup du ddl
|
|
// récup du noeud
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(noe,tabBloq_i,lesFonctionsnD);
|
|
|
|
// on regarde si le temps est actif ou pas
|
|
if ((tabBloq_i.Temps_actif(0.))) {tabBloq_i.ElemLim(nd).Met_en_service();}
|
|
else { tabBloq_i.ElemLim(nd).Met_hors_service();};
|
|
// dans le cas où le ddl n'existe pas on le crée pour qu'il puisse ensuite être utilisé
|
|
// on regarde du coté du noeuds
|
|
if (!noe.Existe_ici(ddl.Id_nom()))
|
|
// cas ou il faut creer un ddl sup
|
|
// si cas d'un ddl de déplacement, et que le ddl X1 existe déjà, pas de pb, on ne fait rien
|
|
// {if (!((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))))
|
|
{ if (!((noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))))
|
|
{// sinon cas d'un ddl inexistant diff de U ou qu'il n'y a pas de X1, alors création puis
|
|
// initialisation a zero et on indique qu'il est hors service
|
|
// ---modif 10 sep 2017
|
|
// cas ou le ddl n'existe pas
|
|
// on le met en service et comme on ne sait pas s'il va être actif ou pas, on le met libre
|
|
// c'est-à-dire qu'il n'est pas pour l'instant imposé à quelque chose
|
|
// on fait cela, et ce qu'il y avait avant, car sinon, le ddl au niveau des noeuds n'est pas
|
|
// mis à jour de t à tdt car seule les ddl qui ne sont pas HS, sont mis à jour
|
|
// or le fait que le ddl soit géré par une condition limite fait qu'il est succeptible d'être
|
|
// utilisé à t et tdt, donc il ne faut pas le mettre en HS
|
|
// par contre on le met en lisible c-a-d en donnée par défaut
|
|
|
|
ddl.ChangeVariable_a_Donnee();
|
|
noe.PlusDdl(ddl);
|
|
noe.Change_val_0(ddl.Id_nom(),0.);
|
|
noe.Change_val_t(ddl.Id_nom(),0.);
|
|
// ---modif 10 sep 2017 // puis on indique que le ddl est bloque et hors service
|
|
// ---modif 10 sep 2017 noe.Met_hors_service(ddl.Id_nom());
|
|
noe.Met_en_service(ddl.Id_nom());
|
|
|
|
noe.Change_fixe(ddl.Id_nom(),true);
|
|
};
|
|
};
|
|
// pour le reste on ne fait rien, se sera géré par les mises à jour
|
|
// en fonction de l'évolution du temps
|
|
} // fin boucle sur tabBloq_i
|
|
} // fin boucle sur les noeuds de la référence
|
|
} // fin du cas des noeuds
|
|
} // fin bouble sur tabBloq
|
|
// définition du nombre de maillage en cours dans le calcul
|
|
nb_maillage=lesMail->NbMaillage();
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
};
|
|
|
|
|
|
// initialisation des ddl avec le tableau de ddl d'init
|
|
// verif de l'existence de tous les ddl (initialisation et imposes)
|
|
// ajout si necessaire
|
|
// choix =false : indique qu'il faut initialiser que les ddl t
|
|
// choix = true : indique qu'il faut initialiser les ddl a t et t+dt
|
|
// vérification de l'existence des courbes de charge adoc si nécessaire
|
|
// idem pour les fonctions nD de charge adoc si nécessaire
|
|
// cas : indique le cas d'association de ddl en cours, ces ddl sont gérés globalement, c-a-d lorsque
|
|
// le statut d'un ddl est modifié (de bloqué à non bloqué par exemple) tous les ddl associés ont
|
|
// leur statut modifié de manière équivalente
|
|
// =0 pas d'association
|
|
// =1 association X V GAMMA
|
|
void LesCondLim::Initial(LesMaillages * lesMail,LesReferences* lesRef
|
|
,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
,bool choixtdt,int cas)
|
|
{
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
// 1) on parcours le tableau de ddl d'initialisation
|
|
int tabInitTaille = tabInit.Taille();
|
|
for (int i=1;i<= tabInitTaille;i++)
|
|
{ DdlLim& tabInit_i = tabInit(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const Reference & refinitial = lesRef->Trouve(tabInit_i.NomRef(),tabInit_i.NomMaillage());
|
|
if ((refinitial.Indic() == 4) &&
|
|
(tabInit_i.TypeDeCL()==TANGENTE_CL) )
|
|
{// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// on renseigne les éléments ad hoc
|
|
int refTaille = ref.Taille();
|
|
for (int ne =1; ne<= refTaille;ne++)
|
|
{int tabInitiTaille = tabInit_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
if (tabInit_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl1 = tabInit_i.ElemLim(nd); // récup des 3 ddl
|
|
Ddl ddl2 = tabInit_i.ElemLim(nd+1); // récup des 3 ddl
|
|
Ddl ddl3 = tabInit_i.ElemLim(nd+2); // récup des 3 ddl
|
|
// récup de l'élément
|
|
Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
SfeMembT & elsfe = (SfeMembT&) el;
|
|
// on renseigne l'élément
|
|
Coordonnee3 vpla(ddl1.Valeur(),ddl2.Valeur(),ddl3.Valeur());
|
|
elsfe.DefCondLim(tabInit_i.TypeDeCL(),vpla, ref.NumeroFA(ne) );
|
|
|
|
}// fin boucle sur tabInit_i
|
|
}// fin boucle sur les éléments de la référence
|
|
} // ---- fin du cas des conditions initiales d'encastrement ou de symétrie pour les SFE
|
|
|
|
else if (refinitial.Indic() != 1)
|
|
// cas d'element
|
|
{ cout << "\n initialisation autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
cout << "void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
else
|
|
// cas de noeuds
|
|
{// on définit des tableaux intermédiaires qui servent pour la vérification qu'il n'y ait pas de doublon
|
|
// la procédure est un peu couteuse en place mémoire mais elle n'est appelée qu'une seule fois ou en tout
|
|
// cas peut de fois,
|
|
const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
// traitement proprement dit
|
|
int refTaille = ref.Taille();
|
|
for (int nn =1; nn<= refTaille;nn++)
|
|
{int tabInitiTaille = tabInit(i).Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
if (tabInit_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl = tabInit_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// on vérifie que le ddl est compatible avec la dimension sinon message d'erreur
|
|
if (!CompatDim(ddl.Id_nom()))
|
|
{cout << "\n *** erreur, le ddl d'initialisation : " << ddl.Nom()
|
|
<< " pour la reference " << ref.Nom()
|
|
<< " n'est pas compatible avec la dimension ( " << ParaGlob::Dimension()
|
|
<< ") de l'espace de travail " ;
|
|
if (ParaGlob::NiveauImpression()>6)
|
|
cout << "\n void LesCondLim::Initial(LesMaillages * lesMail) " ;
|
|
cout << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
};
|
|
|
|
if (noe.Existe_ici(ddl.Id_nom()))
|
|
// cas ou le ddl existe deja
|
|
{ noe.Change_val_t(ddl.Id_nom(),ddl.Valeur());
|
|
if (choixtdt)
|
|
noe.Change_val_tdt(ddl.Id_nom(),ddl.Valeur());
|
|
// mise a jour des ddl aux temps 0 pour tous les ddl sauf ceux de position
|
|
// car ces derniers sont les seuls dont la position initiale est déterminées à la lecture
|
|
// du maillage
|
|
if (!(Meme_famille(ddl.Id_nom(),X1)))
|
|
noe.Change_val_0(ddl.Id_nom(),ddl.Valeur());
|
|
// on regarde s'il fait partie de la combinaison
|
|
// si oui on met en place les ddl correspondant à HSLIBRE
|
|
Enum_ddl en = ddl.Id_nom();
|
|
Init_appart_groupe(ddl.UneVariable(),en,false,noe,cas,choixtdt);
|
|
}
|
|
else
|
|
// cas ou le ddl n'existe pas
|
|
{ // tout d'abord on regarde si c'est un déplacement
|
|
// if ((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL)))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
{if(!CompatDim(ddl.Nom())) // vérif de dimension
|
|
{ cout << "\n erreur, ce ddl de fait pas partie des ddl attribues"
|
|
<< " par les elements donc inutiles !! ddl = " << ddl.Nom() ;
|
|
cout << " \n cas des ddl bloquees ";
|
|
cout << "\nvoid LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
};
|
|
// cas ok on impose le déplacement sur le Xi correspondant
|
|
Enum_ddl en = ddl.Id_nom();
|
|
//on cherche l'equivalent Ui en Xi
|
|
en = UxyzXi(en);
|
|
noe.Ajout_val_t(en,ddl.Valeur());
|
|
// mise a jour des ddl aux autres temps
|
|
// noe.Ajout_val_0(en,ddl.Valeur());
|
|
if (choixtdt)
|
|
noe.Ajout_val_tdt(en,ddl.Valeur());
|
|
// puis on regarde si le ddl initial fait partie de la combinaison
|
|
// si oui on met en place les ddl correspondant à HSLIBRE
|
|
Init_appart_groupe(ddl.UneVariable(),en,false,noe,cas,choixtdt);
|
|
}
|
|
else
|
|
{ // cas ou il faut creer un ddl sup
|
|
//noe.PlusDdl(ddl);
|
|
cout << "\n erreur, ce ddl ne fait pas partie des ddl attribues"
|
|
<< " par les elements donc inutiles !! ddl = " << ddl.Nom() ;
|
|
cout << "\n cas des ddl d'initialisation ";
|
|
cout << "\n void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
// 2) cas des ddl imposes on verifie leurs existences
|
|
// on vérifie également l'existence des courbes de charge adoc si nécessaire
|
|
// idem pour les fonctions nD de charge adoc si nécessaire
|
|
// on vérifie qu'il n'y a pas de surcharge de ddl bloqué: par exemple
|
|
// vitesse et position ou accélération pour un même ddl
|
|
// on parcours le tableau de ddl bloques
|
|
// mais on ne met pas les valeurs en places, ce sera fait lors de la mise à jour à tdt
|
|
int tabBloqTaille = tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const Reference & refinitial = lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage());
|
|
if ((refinitial.Indic() == 4) &&
|
|
(tabBloq_i.TypeDeCL()==TANGENTE_CL) )
|
|
{// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
// ici on s'occupe de renseigner les éléments
|
|
const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// on renseigne les éléments ad hoc
|
|
int refTaille = ref.Taille();
|
|
for (int ne =1; ne<= refTaille;ne++)
|
|
{int tabBloqiTaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl1 = tabBloq_i.ElemLim(nd); // récup des 3 ddl
|
|
Ddl ddl2 = tabBloq_i.ElemLim(nd+1); // récup des 3 ddl
|
|
Ddl ddl3 = tabBloq_i.ElemLim(nd+2); // récup des 3 ddl
|
|
// récup de l'élément
|
|
Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
SfeMembT & elsfe = (SfeMembT&) el;
|
|
// on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(tabBloq_i,lesFonctionsnD);
|
|
// on continue que si le temps est actif ou pas
|
|
if ((tabBloq_i.Temps_actif(0.)))
|
|
{ // on renseigne l'élément
|
|
Coordonnee3 vpla(ddl1.Valeur(),ddl2.Valeur(),ddl3.Valeur());
|
|
elsfe.DefCondLim(tabBloq_i.TypeDeCL(),vpla, ref.NumeroFA(ne) );
|
|
};
|
|
};// fin boucle sur tabBloq_i
|
|
};// fin boucle sur les noeuds de la référence
|
|
} // ---- fin du cas des conditions d'encastrement ou de symétrie pour les SFE
|
|
|
|
else if (refinitial.Indic() != 1)
|
|
// cas autre d'element par exemple
|
|
{ cout << "\n blocage autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
cout << "void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
}
|
|
else
|
|
// cas de noeuds
|
|
{const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
int refTaille = ref.Taille();
|
|
for (int nn =1; nn<= refTaille;nn++)
|
|
{int tabBloqiTaille = tabBloq_i.Taille();
|
|
/* // dans le cas d'une référence de champ on vérifie ne nombre de ddlLim
|
|
if ((tabBloq_i.Champ()) && (tabBloqiTaille != ref.Taille()))
|
|
{cout << "\n erreur: la condition limite de champ n'a pas le meme nombre de ddl bloque"
|
|
<< " que le nombre de noeud de la reference associee !! ";
|
|
cout << " condition limite : "; tabBloq_i.Affiche();
|
|
Sortie(1);
|
|
}*/
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// affectation de la valeur d'initialisation
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd); // récup du ddl
|
|
// on vérifie que le ddl est compatible avec la dimension sinon message d'erreur
|
|
if (!CompatDim(ddl.Id_nom()))
|
|
{cout << "\n *** erreur, le ddl de blocage : " << ddl.Nom()
|
|
<< " pour la reference " << ref.Nom()
|
|
<< " n'est pas compatible avec la dimension ( " << ParaGlob::Dimension()
|
|
<< ") de l'espace de travail " ;
|
|
if (ParaGlob::NiveauImpression()>6)
|
|
cout << "\n void LesCondLim::Initial(LesMaillages * lesMail) " ;
|
|
cout << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
};
|
|
// récup du noeud
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(noe,tabBloq_i,lesFonctionsnD);
|
|
|
|
// on regarde si le temps est actif ou pas
|
|
if ((tabBloq_i.Temps_actif(0.)))
|
|
{ // on n'intervient que si le temps initial est actif
|
|
tabBloq_i.ElemLim(nd).Met_en_service();
|
|
// récup du noeud
|
|
string nom_courbe = tabBloq_i.Nom_courbe(nd);
|
|
Courbe1D * pt_courbe = NULL;
|
|
if (nom_courbe != "")
|
|
// cas de l'existence d'une courbe de charge
|
|
// appel pour récupérer la courbe (juste pour la vérif
|
|
// car on ne s'en sert pas aprés !)
|
|
{ pt_courbe = lesCourbes1D->Trouve(nom_courbe);
|
|
};
|
|
// idem pour les fonctions nD
|
|
string nom_fctnD = tabBloq_i.NomF_charge(nd);
|
|
Fonction_nD * pt_fctnD = NULL;
|
|
if (nom_fctnD != "")
|
|
// cas de l'existence d'une fonction de charge
|
|
// appel pour récupérer la fct (juste pour la vérif
|
|
// car on ne s'en sert pas aprés !)
|
|
{ pt_fctnD = lesFonctionsnD->Trouve(nom_fctnD);
|
|
};
|
|
// maintenant on regarde du coté des noeuds
|
|
if (!noe.Existe_ici(ddl.Id_nom()))
|
|
// cas ou il faut creer un ddl sup
|
|
// on regarde le cas eventuel des coordonnees entrainees
|
|
// si on est en entraine et que le ddl a imposer est un Ui
|
|
// alors on ne verifie que les dimensions et on indique le blocage
|
|
// {if ((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL)))
|
|
{if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
{ // cas d'un ddl de déplacement, et que le ddl X1 existe déjà
|
|
if(!CompatDim(ddl.Nom()))
|
|
{ cout << "\n erreur, ce ddl de fait pas partie des ddl attribues"
|
|
<< " par les elements pour la dimension en cours donc inutiles !! ddl = " << ddl.Nom() ;
|
|
cout << " \n cas des ddl bloquees ";
|
|
cout << "\nvoid LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie (1);
|
|
}
|
|
else // cas ou c'est Xi le ddl bloque, on indique le blocage
|
|
{ Enum_ddl en = ddl.Id_nom();
|
|
//on cherche l'equivalent Ui en Xi
|
|
en = UxyzXi(en);
|
|
noe.Change_fixe(en,true);
|
|
// on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
}
|
|
}
|
|
else
|
|
// cas d'un ddl inexistant diff de U, création puis initialisation a zero
|
|
{ noe.PlusDdl(ddl);
|
|
noe.Change_val_0(ddl.Id_nom(),0.);
|
|
noe.Change_val_t(ddl.Id_nom(),0.);
|
|
if (choixtdt)
|
|
noe.Change_val_tdt(ddl.Id_nom(),0.);
|
|
// puis on indique que le ddl est bloque
|
|
noe.Change_fixe(ddl.Id_nom(),true);
|
|
// on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
Enum_ddl en = ddl.Id_nom();
|
|
Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
}
|
|
}
|
|
else // cas ou le ddl existe
|
|
// on indique que le ddl est bloque, mais on ne change pas sa valeur
|
|
// ce sera fait au moment de la mise à jour à tdt
|
|
{ // comme le ddl existe déjà, deux solutions: soit il provient de l'initialisation 1)
|
|
// dans ce cas il est libre, on peut le bloquer sans pb,
|
|
// soit il a déjà été bloquer, dans ce cas on le surbloque se qui déclanchera un message d'avertissement
|
|
noe.Change_fixe(ddl.Id_nom(),true);
|
|
// on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
Enum_ddl en = ddl.Id_nom();
|
|
Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
};
|
|
}
|
|
else
|
|
{// si le ddl bloqué n'est pas actif pour le temps 0.
|
|
tabBloq_i.ElemLim(nd).Met_hors_service();
|
|
// dans le cas où le ddl n'existe pas on le crée pour qu'il puisse ensuite être utilisé
|
|
// récup du noeud
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// on regarde du coté du noeuds
|
|
if (!noe.Existe_ici(ddl.Id_nom()))
|
|
// cas ou il faut creer un ddl sup
|
|
// on regarde le cas eventuel des coordonnees entrainees
|
|
// si cas d'un ddl de déplacement, et que le ddl X1 existe déjà, pas de pb, on ne fait rien
|
|
// {if (!((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))))
|
|
{if (!((noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))))
|
|
{ // sinon cas d'un ddl inexistant diff de U ou qu'il n'y a pas de X1, alors création puis
|
|
// initialisation a zero et on indique qu'il est hors service (non cf modif qui suit)
|
|
// ---modif 10 sep 2017
|
|
// cas ou le ddl n'existe pas
|
|
// on le met en service et comme on ne sait pas s'il va être actif ou pas, on le met libre
|
|
// c'est-à-dire qu'il n'est pas pour l'instant imposé à quelque chose
|
|
// on fait cela, et ce qu'il y avait avant, car sinon, le ddl au niveau des noeuds n'est pas
|
|
// mis à jour de t à tdt car seule les ddl qui ne sont pas HS, sont mis à jour
|
|
// or le fait que le ddl soit géré par une condition limite fait qu'il est succeptible d'être
|
|
// utilisé à t et tdt, donc il ne faut pas le mettre en HS
|
|
// par contre on le met en lisible c-a-d en donnée par défaut
|
|
Ddl ddl_inter(ddl); // pour pas que cela influe sur les autres noeuds
|
|
|
|
ddl_inter.ChangeVariable_a_Donnee();
|
|
noe.PlusDdl(ddl_inter);
|
|
noe.Change_val_0(ddl_inter.Id_nom(),0.);
|
|
noe.Change_val_t(ddl_inter.Id_nom(),0.);
|
|
if (choixtdt) noe.Change_val_tdt(ddl_inter.Id_nom(),0.);
|
|
// ---modif 10 sep 2017 // puis on indique que le ddl est bloque et hors service
|
|
// ---modif 10 sep 2017 noe.Met_hors_service(ddl.Id_nom());
|
|
noe.Met_en_service(ddl.Id_nom());
|
|
|
|
noe.Change_fixe(ddl.Id_nom(),true);
|
|
};
|
|
};
|
|
// pour le reste on ne fait rien, se sera géré par les mises à jour
|
|
// en fonction de l'évolution du temps
|
|
}; // fin du cas ddl bloqué et pas actif pour le temps 0.
|
|
};
|
|
};
|
|
};
|
|
};
|
|
// on initialise la situation de blocage et condition linéaires
|
|
Validation_blocage (lesRef,0.);
|
|
// vérif qu'il n'y a pas de surcharge de blocage
|
|
Verif_surcharge_blocage(lesMail,lesRef,0.,cas);
|
|
// pour le tps cpu, il y a une petite part de CLL, mais on la néglige
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
};
|
|
|
|
|
|
//// mise à jour de l'initialisation, par exemple après un restart
|
|
//// même paramètres que Initial, par contre ici il n'y a aucune création
|
|
//void LesCondLim::Re_initial(LesMaillages * lesMail,LesReferences* lesRef,LesCourbes1D* lesCourbes1D
|
|
// ,bool choixtdt,int cas)
|
|
// { // 1) on parcours le tableau de ddl d'initialisation
|
|
// int tabInitTaille = tabInit.Taille();
|
|
// for (int i=1;i<= tabInitTaille;i++)
|
|
// { DdlLim& tabInit_i = tabInit(i);
|
|
// // recup de la reference correspondant au mot cle
|
|
// const Reference & refinitial = lesRef->Trouve(tabInit_i.NomRef(),tabInit_i.NomMaillage());
|
|
// if ((refinitial.Indic() == 4) &&
|
|
// (tabInit_i.TypeDeCL()==TANGENTE_CL) )
|
|
// {// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
// const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// // on renseigne les éléments ad hoc
|
|
// int refTaille = ref.Taille();
|
|
// for (int ne =1; ne<= refTaille;ne++)
|
|
// {int tabInitiTaille = tabInit_i.Taille();
|
|
// // dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// // sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
// int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
// if (tabInit_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
// for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// // affectation de la valeur d'initialisation
|
|
// { Ddl ddl1 = tabInit_i.ElemLim(nd); // récup des 3 ddl
|
|
// Ddl ddl2 = tabInit_i.ElemLim(nd+1); // récup des 3 ddl
|
|
// Ddl ddl3 = tabInit_i.ElemLim(nd+2); // récup des 3 ddl
|
|
// // récup de l'élément
|
|
// Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
// SfeMembT & elsfe = (SfeMembT&) el;
|
|
// // on renseigne l'élément
|
|
// Coordonnee3 vpla(ddl1.Valeur(),ddl2.Valeur(),ddl3.Valeur());
|
|
// elsfe.DefCondLim(tabInit_i.TypeDeCL(),vpla, ref.NumeroFA(ne) );
|
|
//
|
|
// }// fin boucle sur tabInit_i
|
|
// }// fin boucle sur les éléments de la référence
|
|
// } // ---- fin du cas des conditions initiales d'encastrement ou de symétrie pour les SFE
|
|
//
|
|
// else if (refinitial.Indic() != 1)
|
|
// // cas d'element
|
|
// { cout << "\n initialisation autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
// cout << "void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
// Sortie(1);
|
|
// }
|
|
// else
|
|
// // cas de noeuds
|
|
// {// on définit des tableaux intermédiaires qui servent pour la vérification qu'il n'y ait pas de doublon
|
|
// // la procédure est un peu couteuse en place mémoire mais elle n'est appelée qu'une seule fois ou en tout
|
|
// // cas peut de fois,
|
|
// const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
// // traitement proprement dit
|
|
// int refTaille = ref.Taille();
|
|
// for (int nn =1; nn<= refTaille;nn++)
|
|
// {int tabInitiTaille = tabInit(i).Taille();
|
|
// // dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// // sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
// int idebut=1; int ifinfin = tabInitiTaille;// début normale
|
|
// if (tabInit_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
// for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// // affectation de la valeur d'initialisation
|
|
// { Ddl ddl = tabInit_i.ElemLim(nd);
|
|
// Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// if (noe.Existe_ici(ddl.Id_nom()))
|
|
// // cas ou le ddl existe deja
|
|
// { noe.Change_val_t(ddl.Id_nom(),ddl.Valeur());
|
|
// if (choixtdt)
|
|
// noe.Change_val_tdt(ddl.Id_nom(),ddl.Valeur());
|
|
// // mise a jour des ddl aux temps 0 pour tous les ddl sauf ceux de position
|
|
// // car ces derniers sont les seuls dont la position initiale est déterminées à la lecture
|
|
// // du maillage
|
|
// if (!(Meme_famille(ddl.Id_nom(),X1)))
|
|
// noe.Change_val_0(ddl.Id_nom(),ddl.Valeur());
|
|
// // on regarde s'il fait partie de la combinaison
|
|
// // si oui on met en place les ddl correspondant à HSLIBRE
|
|
// Enum_ddl en = ddl.Id_nom();
|
|
// Init_appart_groupe(ddl.UneVariable(),en,false,noe,cas,choixtdt);
|
|
// }
|
|
// else
|
|
// // cas ou le ddl n'existe pas
|
|
// { // tout d'abord on regarde si c'est un déplacement
|
|
// // if ((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL)))
|
|
// if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// { if(!CompatDim(ddl.Nom())) // vérif de dimension
|
|
// { cout << "\n erreur, ce ddl de fait pas partie des ddl attribues"
|
|
// << " par les elements donc inutiles !! ddl = " << ddl.Nom() ;
|
|
// cout << " \n cas des ddl bloquees ";
|
|
// cout << "\nvoid LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
// Sortie (1);
|
|
// }
|
|
// // cas ok on impose le déplacement sur le Xi correspondant
|
|
// Enum_ddl en = ddl.Id_nom();
|
|
// //on cherche l'equivalent Ui en Xi
|
|
// en = UxyzXi(en);
|
|
// noe.Ajout_val_t(en,ddl.Valeur());
|
|
// // mise a jour des ddl aux autres temps
|
|
// // noe.Ajout_val_0(en,ddl.Valeur());
|
|
// if (choixtdt)
|
|
// noe.Ajout_val_tdt(en,ddl.Valeur());
|
|
// // puis on regarde si le ddl initial fait partie de la combinaison
|
|
// // si oui on met en place les ddl correspondant à HSLIBRE
|
|
// Init_appart_groupe(ddl.UneVariable(),en,false,noe,cas,choixtdt);
|
|
// }
|
|
// else
|
|
// { // cas ou il faut creer un ddl sup
|
|
// //noe.PlusDdl(ddl);
|
|
// cout << "\n erreur, ce ddl ne fait pas partie des ddl attribues"
|
|
// << " par les elements donc inutiles !! ddl = " << ddl.Nom() ;
|
|
// cout << "\n cas des ddl d'initialisation ";
|
|
// cout << "\n void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
// Sortie (1);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// // 2) cas des ddl imposes on verifie leurs existences
|
|
// // on vérifie également l'existence des courbes de charge adoc si nécessaire
|
|
// // on vérifie qu'il n'y a pas de surcharge de ddl bloqué: par exemple
|
|
// // vitesse et position ou accélération pour un même ddl
|
|
// // on parcours le tableau de ddl bloques
|
|
// // mais on ne met pas les valeurs en places, ce sera fait lors de la mise à jour à tdt
|
|
// int tabBloqTaille = tabBloq.Taille();
|
|
// for (int i=1;i<= tabBloqTaille;i++)
|
|
// { DdlLim& tabBloq_i = tabBloq(i);
|
|
// // recup de la reference correspondant au mot cle
|
|
// const Reference & refinitial = lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage());
|
|
// if ((refinitial.Indic() == 4) &&
|
|
// (tabBloq_i.TypeDeCL()==TANGENTE_CL) )
|
|
// {// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
// // ici on s'occupe de renseigner les éléments
|
|
// const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
// // on renseigne les éléments ad hoc
|
|
// int refTaille = ref.Taille();
|
|
// for (int ne =1; ne<= refTaille;ne++)
|
|
// {int tabBloqiTaille = tabBloq_i.Taille();
|
|
// // dans le cas d'un champ, pour chaque ddl on a un élément associé, il ne faut donc pas itérer
|
|
// // sur les éléments, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
// int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
// if (tabBloq_i.Champ()) {idebut = ne; ifinfin = ne;};
|
|
// for (int nd=idebut;nd<= ifinfin ;nd+=3) // on va de 3 en 3
|
|
// // affectation de la valeur d'initialisation
|
|
// { Ddl ddl1 = tabBloq_i.ElemLim(nd); // récup des 3 ddl
|
|
// Ddl ddl2 = tabBloq_i.ElemLim(nd+1); // récup des 3 ddl
|
|
// Ddl ddl3 = tabBloq_i.ElemLim(nd+2); // récup des 3 ddl
|
|
// // récup de l'élément
|
|
// Element & el=lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
// SfeMembT & elsfe = (SfeMembT&) el;
|
|
// // on continue que si le temps est actif ou pas
|
|
// if ((tabBloq_i.Temps_actif(0.)))
|
|
// { // on renseigne l'élément
|
|
// Coordonnee3 vpla(ddl1.Valeur(),ddl2.Valeur(),ddl3.Valeur());
|
|
// elsfe.DefCondLim(tabBloq_i.TypeDeCL(),vpla, ref.NumeroFA(ne) );
|
|
// };
|
|
// }// fin boucle sur tabBloq_i
|
|
// }// fin boucle sur les noeuds de la référence
|
|
// } // ---- fin du cas des conditions d'encastrement ou de symétrie pour les SFE
|
|
//
|
|
// else if (refinitial.Indic() != 1)
|
|
// // cas autre d'element par exemple
|
|
// { cout << "\n blocage autre que des noeuds, pas d\'action implentee a ce sujet !!";
|
|
// cout << "void LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
// Sortie (1);
|
|
// }
|
|
// else
|
|
// // cas de noeuds
|
|
// {const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
// int refTaille = ref.Taille();
|
|
// for (int nn =1; nn<= refTaille;nn++)
|
|
// {int tabBloqiTaille = tabBloq_i.Taille();
|
|
// /* // dans le cas d'une référence de champ on vérifie ne nombre de ddlLim
|
|
// if ((tabBloq_i.Champ()) && (tabBloqiTaille != ref.Taille()))
|
|
// {cout << "\n erreur: la condition limite de champ n'a pas le meme nombre de ddl bloque"
|
|
// << " que le nombre de noeud de la reference associee !! ";
|
|
// cout << " condition limite : "; tabBloq_i.Affiche();
|
|
// Sortie(1);
|
|
// }*/
|
|
// // dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// // sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
// int idebut=1; int ifinfin = tabBloqiTaille;// début normale
|
|
// if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
// for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// // affectation de la valeur d'initialisation
|
|
// { Ddl ddl = tabBloq_i.ElemLim(nd); // récup du ddl
|
|
// // on regarde si le temps est actif ou pas
|
|
// if ((tabBloq_i.Temps_actif(0.)))
|
|
// { // on n'intervient que si le temps initial est actif
|
|
// tabBloq_i.ElemLim(nd).Met_en_service();
|
|
// // récup du noeud
|
|
// Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// string nom_courbe = tabBloq_i.Nom_courbe(nd);
|
|
// Courbe1D * pt_courbe = NULL;
|
|
// if (nom_courbe != "")
|
|
// // cas de l'existence d'une courbe de charge
|
|
// // appel pour récupérer la courbe (juste pour la vérif
|
|
// // car on ne s'en sert pas aprés !)
|
|
// { pt_courbe = lesCourbes1D->Trouve(nom_courbe);
|
|
// }
|
|
// // maintenant on regarde du coté des noeuds
|
|
// if (!noe.Existe_ici(ddl.Id_nom()))
|
|
// // cas ou il faut creer un ddl sup
|
|
// // on regarde le cas eventuel des coordonnees entrainees
|
|
// // si on est en entraine et que le ddl a imposer est un Ui
|
|
// // alors on ne verifie que les dimensions et on indique le blocage
|
|
// // {if ((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL)))
|
|
// {if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// { // cas d'un ddl de déplacement, et que le ddl X1 existe déjà
|
|
// if(!CompatDim(ddl.Nom()))
|
|
// { cout << "\n erreur, ce ddl de fait pas partie des ddl attribues"
|
|
// << " par les elements pour la dimension en cours donc inutiles !! ddl = " << ddl.Nom() ;
|
|
// cout << " \n cas des ddl bloquees ";
|
|
// cout << "\nvoid LesCondLim::Initial(LesMaillages * lesMail) " << endl;
|
|
// Sortie (1);
|
|
// }
|
|
// else // cas ou c'est Xi le ddl bloque, on indique le blocage
|
|
// { Enum_ddl en = ddl.Id_nom();
|
|
// //on cherche l'equivalent Ui en Xi
|
|
// en = UxyzXi(en);
|
|
// noe.Change_fixe(en,true);
|
|
// // on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
// Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
// }
|
|
// }
|
|
// else
|
|
// // cas d'un ddl inexistant diff de U, création puis initialisation a zero
|
|
// { noe.PlusDdl(ddl);
|
|
// noe.Change_val_0(ddl.Id_nom(),0.);
|
|
// noe.Change_val_t(ddl.Id_nom(),0.);
|
|
// if (choixtdt)
|
|
// noe.Change_val_tdt(ddl.Id_nom(),0.);
|
|
// // puis on indique que le ddl est bloque
|
|
// noe.Change_fixe(ddl.Id_nom(),true);
|
|
// // on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
// Enum_ddl en = ddl.Id_nom();
|
|
// Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
// }
|
|
// }
|
|
// else // cas ou le ddl existe
|
|
// // on indique que le ddl est bloque, mais on ne change pas sa valeur
|
|
// // ce sera fait au moment de la mise à jour à tdt
|
|
// { // comme le ddl existe déjà, deux solutions: soit il provient de l'initialisation 1)
|
|
// // dans ce cas il est libre, on peut le bloquer sans pb,
|
|
// // soit il a déjà été bloquer, dans ce cas on le surbloque se qui déclanchera un message d'avertissement
|
|
// noe.Change_fixe(ddl.Id_nom(),true);
|
|
// // on regarde s'il fait partie de la combinaison et on fixe les blocages
|
|
// Enum_ddl en = ddl.Id_nom();
|
|
// Init_appart_groupe(ddl.UneVariable(),en,true,noe,cas,choixtdt);
|
|
// }
|
|
// }
|
|
// else
|
|
// {// si le ddl bloqué n'est pas actif pour le temps 0.
|
|
// tabBloq_i.ElemLim(nd).Met_hors_service();
|
|
// // dans le cas où le ddl n'existe pas on le crée pour qu'il puisse ensuite être utilisé
|
|
// // récup du noeud
|
|
// Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// // on regarde du coté du noeuds
|
|
// if (!noe.Existe_ici(ddl.Id_nom()))
|
|
// // cas ou il faut creer un ddl sup
|
|
// // on regarde le cas eventuel des coordonnees entrainees
|
|
// // si cas d'un ddl de déplacement, et que le ddl X1 existe déjà, pas de pb, on ne fait rien
|
|
// // {if (!((noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))))
|
|
// {if (!((noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))))
|
|
// {// sinon cas d'un ddl inexistant diff de U ou qu'il n'y a pas de X1, alors création puis
|
|
// // initialisation a zero et on indique qu'il est hors service
|
|
// noe.PlusDdl(ddl);
|
|
// noe.Change_val_0(ddl.Id_nom(),0.);
|
|
// noe.Change_val_t(ddl.Id_nom(),0.);
|
|
// if (choixtdt) noe.Change_val_tdt(ddl.Id_nom(),0.);
|
|
// // puis on indique que le ddl est bloque et hors service
|
|
// noe.Met_hors_service(ddl.Id_nom());
|
|
// noe.Change_fixe(ddl.Id_nom(),true);
|
|
// }
|
|
// }
|
|
// // pour le reste on ne fait rien, se sera géré par les mises à jour
|
|
// // en fonction de l'évolution du temps
|
|
// } // fin du cas ddl bloqué et pas actif pour le temps 0.
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// // on initialise la situation de blocage et condition linéaires
|
|
// Validation_blocage (lesRef,0.);
|
|
// // vérif qu'il n'y a pas de surcharge de blocage
|
|
// Verif_surcharge_blocage(lesMail,lesRef,0.,cas);
|
|
// };
|
|
|
|
|
|
// incrementation des coordonnees a t+dt et des ddl en fonctions des ddl imposes
|
|
// et du chargement
|
|
// coef: est un facteur multiplicatif des ddl sans courbes de charge,
|
|
// est supposé intégrer déjà le multiplicateur général
|
|
// en fait du chargement impose
|
|
// mult_gene : multiplicateur général de tous les chargements
|
|
// deltat : le pas de temps en cours
|
|
// temps : le temps courant où sont calculées les conditions
|
|
// ch_statut : indique s'il y a changement ou non de statut des conditions limites (pour les ddl aux noeuds)
|
|
// c-a-d un ddl qui passe de bloqué à non bloqué ou inversement: il s'agit uniquement des ddl aux noeuds
|
|
// c-a-d ceux qui ont une influence sur la mise en place des cl sur la raideur et le résidu
|
|
// cas : indique le cas d'association de ddl en cours, ces ddl sont gérés globalement, c-a-d lorsque
|
|
// le statut d'un ddl est modifié (de bloqué à non bloqué par exemple) tous les ddl associés ont
|
|
// leur statut modifié de manière équivalente
|
|
// =0 pas d'association
|
|
// =1 association X V GAMMA
|
|
// lorsque en_ddl est égal à NU_DDL, cela signifie que l'on met les conditions limites sur tous les
|
|
// ddl de noeud actifs
|
|
// lorsque en_ddl est différent de NU_DDL, il donne le type des seules ddl pour lesquels on met les
|
|
// conditions de blocage: par exemple X1 -> blocage sur X1,X2,X3 selon la dimension
|
|
|
|
|
|
void LesCondLim::MiseAJour_tdt
|
|
(const double& mult_gene,LesMaillages * lesMail,const double& deltat,const LesReferences* lesRef
|
|
,const double& temps,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
,const double& coef,bool& ch_statut
|
|
,int cas,Enum_ddl en_ddl)
|
|
{
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
// préparation
|
|
bool tous_les_blocages = true;
|
|
if (en_ddl != NU_DDL) tous_les_blocages = false;
|
|
// la mise en place des blocages s'effectue en deux temps, ceci pour préparer la vérification
|
|
// de la non sur imposition de ddl: ceci pour les ddl aux noeuds
|
|
// 1- au premier passage : on met en libre les ddl qui sont relachés, on met tous les ddl actifs
|
|
// en libre
|
|
// 2- au second passage : les ddl au temps actifs sont fixés (et éventuellement surfixé si pb)
|
|
//
|
|
// pour les ddl d'encastrement ou de symétrie pour les sfe, tout ce fait au premier passage uniquement
|
|
// ---- premier passage ----
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(tabBloq_i,lesFonctionsnD);
|
|
// pour le ddlLim, si le temps est inférieur au temps actif
|
|
// ou si d'une part le temps n'est pas actif et qu'au pas précédent
|
|
// il n'était pas également actif on ne fait rien
|
|
if (!(tabBloq_i.Pas_a_prendre_en_compte(temps)))
|
|
{bool actif_pour_le_temps = tabBloq_i.Temps_actif(temps); // pour simplifier
|
|
// recup de la reference correspondant au mot cle
|
|
const Reference & refinitial = lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage());
|
|
if ((refinitial.Indic() == 4) &&
|
|
(tabBloq_i.TypeDeCL()==TANGENTE_CL) )
|
|
{// cas des références d'arêtes, avec des conditions de tangente imposée
|
|
bool devient_actif = (actif_pour_le_temps && (!tabBloq_i.Etat_validation()));
|
|
bool devient_inactif = ((!actif_pour_le_temps) && (tabBloq_i.Etat_validation()));
|
|
// on n'intervient que s'il y a un changement d'état
|
|
if (devient_actif || devient_inactif)
|
|
{//int tabBloqitaille = tabBloq_i.Taille();
|
|
const ReferenceAF & ref = ((ReferenceAF &) refinitial);
|
|
int reftaille = ref.Taille();
|
|
// on boucle sur les numéros de la référence
|
|
for (int ne =1; ne<= reftaille;ne++)
|
|
{// on regarde si le temps est actif ou pas
|
|
if (devient_actif)
|
|
// cas ou on veut le blocage mais qu'au temps précédent ce n'était pas valide
|
|
{ // récup de l'élément
|
|
SfeMembT & elsfe = (SfeMembT&) lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
// que ce soit dans le cas d'un champ ou normal, on n'a pas besoin d'itérer sur les ddl du ddlLim
|
|
// car d'un part pour le champ, on a autant de dim_espace ddl que d'élément dans la référence
|
|
// et d'autre part dans le cas normal on a uniquement un seul dim_espace ddl -> vecteur
|
|
// !!!!!! pour l'instant on considère que c'est en 3D
|
|
#ifdef MISE_AU_POINT
|
|
if ((ParaGlob::Dimension() < 3) || (tabBloq_i.Taille() != 3))
|
|
{ cout << "\n erreur, pour l'instant les conditions de type TANGENTE_CL ne sont operationnelles "
|
|
<< " que pour la dimension 3 !! ";
|
|
cout << "\n reference concernee: "; ref.Affiche();
|
|
cout << "\n condition limite concernee: ";tabBloq_i.Affiche();
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
int tabBloqitaille = tabBloq_i.Taille(); // normalement = 3 ici
|
|
Tableau <Ddl> t_ddl(tabBloqitaille); // les valeurs du vecteur qui permet le calcul de la tangence
|
|
for (int nd=1;nd<=tabBloqitaille;nd++)
|
|
{Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
// choix entre valeur simple et valeur qui varie
|
|
if(tabBloq_i.Nom_courbe(nd) != "")
|
|
{ // cas d'une courbe de charge, récup de la courbe
|
|
Courbe1D * pt_courbe = lesCourbes1D->Trouve(tabBloq_i.Nom_courbe(nd));
|
|
// on change la valeur du ddl
|
|
if (tabBloq_i.BlocageRelatif()) // cas d'une modif relativement au temps précédent
|
|
{ // pour l'instant ce n'est pas implanté
|
|
// en fait, il faudrait une valeur sauvegardée, or le plus simple serait d'utiliser la
|
|
// position actuelle de la tangente sur l'élément, donc il faudrait donner l'incrément à
|
|
// l'élément qui updaterait sa position (qui peut être différente pour chaque élément)
|
|
// $$$ à faire s'il y a une demande, pour l'instant on attend $$$$
|
|
cout << "\n *** blocage relatif pour l'evolution d'une tangente aux elements, pour l'instant"
|
|
<< " ce cas n'est pas implante, donc le demander !!! "
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ // mise à jour de la valeur du ddl en absolu, c-a-d relativement à t=0
|
|
ddl.Valeur() = (pt_courbe->Valeur(temps)) * tabBloq_i.Echelle_courbe(nd);
|
|
};
|
|
t_ddl(nd) = ddl;
|
|
}
|
|
else if (tabBloq_i.NomF_charge(nd) != "")
|
|
{ // cas d'une fonction nD de charge, récup
|
|
Fonction_nD * pt_fctnD = lesFonctionsnD->Trouve(tabBloq_i.NomF_charge(nd));
|
|
// on change la valeur du ddl
|
|
if (tabBloq_i.BlocageRelatif()) // cas d'une modif relativement au temps précédent
|
|
{ // pour l'instant ce n'est pas implanté
|
|
// en fait, il faudrait une valeur sauvegardée, or le plus simple serait d'utiliser la
|
|
// position actuelle de la tangente sur l'élément, donc il faudrait donner l'incrément à
|
|
// l'élément qui updaterait sa position (qui peut être différente pour chaque élément)
|
|
// $$$ à faire s'il y a une demande, pour l'instant on attend $$$$
|
|
cout << "\n *** blocage relatif pour l'evolution d'une tangente aux elements, pour l'instant"
|
|
<< " ce cas n'est pas implante, donc le demander !!! "
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{// pour l'instant on limite l'utilisation des fonctions aux seules grandeurs globales
|
|
if (pt_fctnD->NbVariable_locale() != 0)
|
|
{cout << "\n *** blocage via une fonction nD pour l'evolution d'une tangente aux elements, pour l'instant"
|
|
<< " seule une dependance a des variables globales est possible !!! "
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
Tableau <double> & tab_ret = pt_fctnD->Valeur_pour_variables_globales();
|
|
#ifdef MISE_AU_POINT
|
|
if (tab_ret.Taille() != 1)
|
|
{cout << "\n*** Erreur : la fonction nD retourne un vecteur et non un scalaire comme escompte "
|
|
<< "\n *** blocage via une fonction nD pour l'evolution d'une tangente aux elements"
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// mise à jour de la valeur du ddl en absolu, c-a-d relativement à t=0
|
|
ddl.Valeur() = tab_ret(1) * tabBloq_i.Echelle_courbe(nd);
|
|
};
|
|
t_ddl(nd) = ddl;
|
|
}
|
|
else // cas d'un ddl à valeur fixe
|
|
{ // cas d'un ddl à valeur fixe
|
|
t_ddl(nd) = ddl;
|
|
};
|
|
};
|
|
// on renseigne l'élément
|
|
Coordonnee3 vpla(t_ddl(1).Valeur(),t_ddl(2).Valeur(),t_ddl(3).Valeur());
|
|
elsfe.DefCondLim(tabBloq_i.TypeDeCL(),vpla, ref.NumeroFA(ne) );
|
|
}
|
|
else if (devient_inactif)
|
|
// on relache le blocage si nécessaire, pour cela on regarde donc s'il y a changement de statut
|
|
{ // récup de l'élément
|
|
SfeMembT & elsfe = (SfeMembT&) lesMail->Element_LesMaille(ref.Nbmaille(),ref.NumeroElem(ne));
|
|
// on renseigne l'élément
|
|
Coordonnee3 vpla; // initalisé à 0 par défaut, ne sert pas ici
|
|
elsfe.DefCondLim(RIEN_TYPE_CL,vpla, ref.NumeroFA(ne) );
|
|
};
|
|
// sinon on ne fait rien
|
|
}; //-- fin de la boucle sur ne
|
|
}//-- fin du test sur devient_actif ou devient_inactif
|
|
}//-- fin du cas ref d'encastrement ou de symétrie
|
|
else // cas d'une référence de noeud
|
|
{const ReferenceNE & ref = ((ReferenceNE &) refinitial);
|
|
int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// incrementation en fonction de la valeur de blocage et du coef
|
|
{Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
// concernant le temps, soit le ddlLim est actif ou il change de statut: actif à non actif
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// cas de deplacements imposes en entraine on change les Ui en Xi
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
bool a_considerer = tous_les_blocages;
|
|
if (! a_considerer) // cas ou on ne veut que certain blocage, a_bloque est faux
|
|
{if (Meme_famille(en_ddl,ddl.Id_nom())) a_considerer = true;}
|
|
Enum_ddl ddlenu= ddl.Id_nom(); // pour simplifier
|
|
if (a_considerer)
|
|
{ if ( noe.En_service(ddlenu) )
|
|
{ // on regarde si le temps est actif ou pas
|
|
if (!actif_pour_le_temps)
|
|
// cas du temps non actif, on relache le blocage si nécessaire
|
|
// on regarde donc s'il y a changement de statut
|
|
{if (tabBloq_i.Etat_validation() && (noe.Ddl_fixe(ddlenu)))
|
|
{ch_statut = true;
|
|
Retire_cl(nd,tabBloq_i,ddlenu,noe,cas);
|
|
}
|
|
} //-- fin du test ou le temps n'est pas actif
|
|
else
|
|
// cas du temps actif
|
|
// on regarde s'il y a changement de statut
|
|
{if (!(tabBloq_i.Etat_validation())&& (!(noe.Ddl_fixe(ddlenu))))
|
|
{ // on change le statut que si c'est une variable, les données n'influencent pas les raideurs et seconds membres
|
|
if (noe.UneVariable(ddlenu))
|
|
ch_statut = true;
|
|
// Mise_cl(nd,tabBloq_i,ddlenu,noe,cas);
|
|
};
|
|
// gestion des surcharges de blocage
|
|
// au premier passage on met tous les ddl en libre s'ils sont actifs
|
|
if (noe.Ddl_fixe(ddlenu))
|
|
Retire_cl(nd,tabBloq_i,ddlenu,noe,cas);
|
|
}//-- fin du test si le temps est actif
|
|
}//-- fin du test si le ddl du noeud est une variable et est en service
|
|
}//-- fin du test si le noeud est à considérer ou pas
|
|
}//-- fin de la boucle sur tabBloq_i: indice nd
|
|
}//-- fin de la boucle nn
|
|
}//-- fin du cas des noeuds
|
|
} // fin du if (!(tabBloq_i.Pas_a_prendre_en_compte(temps)))
|
|
}//-- fin de la boucle sur tabBloq
|
|
|
|
// ---- second passage ----
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
// on ne continue que si c'est une référence de noeud
|
|
if (ref.Indic() == 1)
|
|
{ int reftaille = ref.Taille();
|
|
// cas particulier des mouvements solides
|
|
if (tabBloq_i.Mouvement_Solide())
|
|
{MiseAjour_tdt_second_passage_mvtSolide(mult_gene,lesMail,deltat,cas
|
|
,lesCourbes1D,lesFonctionsnD,coef,tabBloq_i,ref,temps,en_ddl);
|
|
}
|
|
else
|
|
// cas différent des mouvements solides
|
|
{for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// incrementation en fonction de la valeur de blocage et du coef
|
|
{Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
// pour le ddlLim, si le temps est inférieur au temps actif
|
|
// ou si d'une part le temps n'est pas actif et qu'au pas précédent
|
|
// il n'était pas également actif on ne fait rien
|
|
if (tabBloq_i.Pas_a_prendre_en_compte(temps)) break;
|
|
// maintenant soit le ddlLim est actif ou il change de statut: actif à non actif
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
|
|
////--debug
|
|
//if (noe.Num_noeud()==197)
|
|
// {cout << "\n debug1: LesCondLim::MiseAJour_tdt(..";
|
|
// noe.Affiche();cout << endl;
|
|
// };
|
|
////--fin debug
|
|
|
|
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// cas de deplacements imposes en entraine on change les Ui en Xi
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
bool a_considerer = tous_les_blocages;
|
|
if (! a_considerer) // cas ou on ne veut que certain blocage, a_bloque est faux
|
|
{if (Meme_famille(en_ddl,ddl.Id_nom())) a_considerer = true;}
|
|
Enum_ddl ddlenu= ddl.Id_nom(); // pour simplifier
|
|
if (a_considerer)
|
|
{ // on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(noe,tabBloq_i,lesFonctionsnD);
|
|
bool actif_pour_le_temps = tabBloq_i.Temps_actif(temps); // pour simplifier
|
|
bool une_variable = noe.UneVariable(ddlenu); // pour simplifier
|
|
// cas des variables: si le ddl du noeud est en service on continue sinon on ne fait rien
|
|
// ou cas d'une donnée et le temps actif
|
|
if ( ( une_variable && noe.En_service(ddlenu))
|
|
||(!une_variable && actif_pour_le_temps) )
|
|
{ // on regarde si le temps est actif ou pas, seul le cas actif est ici considérer
|
|
if (actif_pour_le_temps)
|
|
// gestion des surcharges de blocage
|
|
// au second passage on fixe les ddl actifs
|
|
{Mise_cl(nd,tabBloq_i,ddlenu,noe,cas);
|
|
// on choisit entre ddl à valeur fixe ou avec une courbe de charge
|
|
// coef intègre le multiplicateur global: mult_gene
|
|
if ((tabBloq_i.Nom_courbe(nd) != "")&&(tabBloq_i.NomF_charge(nd) == ""))
|
|
{ // cas d'une courbe de charge, récup de la courbe
|
|
Courbe1D * pt_courbe = lesCourbes1D->Trouve(tabBloq_i.Nom_courbe(nd));
|
|
// on change la valeur du ddl du noeud, même si la valeur à bloquer est nulle
|
|
// car au paravant il pouvait être non nul
|
|
// ici changement et non ajout , prise en compte de la relativité du blocage
|
|
double val_final = 0.;
|
|
if (tabBloq_i.BlocageRelatif()) // cas d'une modif relativement au temps précédent
|
|
{ // mise à jour de la valeur de l'incrément du ddl (et non ce sa valeur) sur deltat
|
|
ddl.Valeur() = ((pt_courbe->Valeur(temps)) - (pt_courbe->Valeur(temps-deltat)))
|
|
* tabBloq_i.Echelle_courbe(nd);
|
|
val_final = mult_gene * ddl.Valeur() + noe.Valeur_t(ddlenu);
|
|
}
|
|
else
|
|
{ // mise à jour de la valeur du ddl en absolu, c-a-d relativement à t=0
|
|
ddl.Valeur() = (pt_courbe->Valeur(temps)) * tabBloq_i.Echelle_courbe(nd);
|
|
val_final = mult_gene * ddl.Valeur() + noe.Valeur_0(ddlenu);
|
|
};
|
|
noe.Change_val_tdt(ddlenu,val_final); // mise à jour
|
|
}
|
|
else if ((tabBloq_i.NomF_charge(nd) != "")&&(tabBloq_i.Nom_courbe(nd) == ""))
|
|
{ // cas d'une fonction nD de charge, récup
|
|
Fonction_nD * pt_fctnD = lesFonctionsnD->Trouve(tabBloq_i.NomF_charge(nd));
|
|
// on commence par récupérer les conteneurs des grandeurs à fournir
|
|
List_io <Ddl_enum_etendu>& li_enu_scal = pt_fctnD->Li_enu_etendu_scalaire();
|
|
List_io <TypeQuelconque >& li_quelc = pt_fctnD->Li_equi_Quel_evolue();
|
|
// on va utiliser la méhode Valeur_multi pour les grandeurs strictement scalaire
|
|
Tableau <double> val_ddl_enum(Valeur_multi_interpoler_ou_calculer
|
|
(noe, TEMPS_tdt,li_enu_scal));
|
|
// on utilise la méthode des grandeurs évoluées pour les Coordonnees et Tenseur
|
|
Valeurs_Tensorielles_interpoler_ou_calculer(noe, TEMPS_tdt,li_quelc);
|
|
// calcul de la valeur et retour dans tab_ret
|
|
Tableau <double> & tab_ret = pt_fctnD->Valeur_FnD_Evoluee
|
|
(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
|
|
#ifdef MISE_AU_POINT
|
|
if (tab_ret.Taille() != 1)
|
|
{cout << "\n*** Erreur : la fonction nD retourne un vecteur et non un scalaire comme escompte "
|
|
<< "\n *** blocage via une fonction nD pour l'evolution du ddl"
|
|
<< Nom_ddl(ddlenu)
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on change la valeur du ddl du noeud, même si la valeur à bloquer est nulle
|
|
// car au paravant il pouvait être non nul
|
|
// ici changement et non ajout , prise en compte de la relativité du blocage
|
|
double val_final = 0.;
|
|
if (tabBloq_i.BlocageRelatif()) // cas d'une modif relativement au temps précédent
|
|
{ // pour l'instant a priori ce n'est pas possible car le temps
|
|
// est une variable globale que l'on ne peut pas modifier pour les fonctions nD
|
|
// il faut donc utiliser conjointement une courbe1D pour le temps et la fonction nD pour le reste
|
|
cout << "\n *** blocage relatif avec uniquement une fonction nD: ce n'est pas possible"
|
|
<< " pour avoir un blocage relatif il faut utiliser conjointement une courbe de charge "
|
|
<< " pour le temps et une fonction nD pour le reste !!!!"
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ // mise à jour de la valeur du ddl en absolu, c-a-d relativement à t=0
|
|
ddl.Valeur() = tab_ret(1) * tabBloq_i.Echelle_courbe(nd);
|
|
val_final = mult_gene * ddl.Valeur() + noe.Valeur_0(ddlenu);
|
|
};
|
|
noe.Change_val_tdt(ddlenu,val_final); // mise à jour
|
|
}
|
|
else if ((tabBloq_i.NomF_charge(nd) != "")&&(tabBloq_i.Nom_courbe(nd) != ""))
|
|
{ // cas d'une fonction nD de charge, récup
|
|
Fonction_nD * pt_fctnD = lesFonctionsnD->Trouve(tabBloq_i.NomF_charge(nd));
|
|
// on commence par récupérer les conteneurs des grandeurs à fournir
|
|
List_io <Ddl_enum_etendu>& li_enu_scal = pt_fctnD->Li_enu_etendu_scalaire();
|
|
List_io <TypeQuelconque >& li_quelc = pt_fctnD->Li_equi_Quel_evolue();
|
|
// on va utiliser la méhode Valeur_multi pour les grandeurs strictement scalaire
|
|
Tableau <double> val_ddl_enum(Valeur_multi_interpoler_ou_calculer
|
|
(noe, TEMPS_tdt,li_enu_scal));
|
|
// on utilise la méthode des grandeurs évoluées pour les Coordonnees et Tenseur
|
|
Valeurs_Tensorielles_interpoler_ou_calculer(noe, TEMPS_tdt,li_quelc);
|
|
// calcul de la valeur et retour dans tab_ret
|
|
Tableau <double> & tab_ret = pt_fctnD->Valeur_FnD_Evoluee
|
|
(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
|
|
#ifdef MISE_AU_POINT
|
|
if (tab_ret.Taille() != 1)
|
|
{cout << "\n*** Erreur : la fonction nD retourne un vecteur et non un scalaire comme escompte "
|
|
<< "\n *** blocage via une fonction nD pour l'evolution du ddl"
|
|
<< Nom_ddl(ddlenu)
|
|
<< "\n LesCondLim::MiseAJour_tdt(.... ";
|
|
tempsCL.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// idem pour la courbe 1D
|
|
Courbe1D * pt_courbe = lesCourbes1D->Trouve(tabBloq_i.Nom_courbe(nd));
|
|
// on change la valeur du ddl du noeud, même si la valeur à bloquer est nulle
|
|
// car au paravant il pouvait être non nul
|
|
// ici changement et non ajout , prise en compte de la relativité du blocage
|
|
double val_final = 0.;
|
|
if (tabBloq_i.BlocageRelatif()) // cas d'une modif relativement au temps précédent
|
|
{ // mise à jour de la valeur de l'incrément du ddl (et non ce sa valeur) sur deltat
|
|
ddl.Valeur() = tab_ret(1) *
|
|
(((pt_courbe->Valeur(temps)) - (pt_courbe->Valeur(temps-deltat)))
|
|
* tabBloq_i.Echelle_courbe(nd)
|
|
);
|
|
|
|
val_final = mult_gene * ddl.Valeur() + noe.Valeur_t(ddlenu);
|
|
}
|
|
else
|
|
{ // mise à jour de la valeur du ddl en absolu, c-a-d relativement à t=0
|
|
ddl.Valeur() = tab_ret(1) *
|
|
(pt_courbe->Valeur(temps)) * tabBloq_i.Echelle_courbe(nd);
|
|
val_final = mult_gene * ddl.Valeur() + noe.Valeur_0(ddlenu);
|
|
};
|
|
noe.Change_val_tdt(ddlenu,val_final); // mise à jour
|
|
}
|
|
else
|
|
{ // cas d'un ddl à valeur fixe
|
|
// du au fait de l'initialisation d'un incrément à l'autre dans les algos globaux on change
|
|
double val_final=noe.Valeur_t(ddlenu); // récup de la valeur à t
|
|
val_final += coef * ddl.Valeur(); // mise en place du delta
|
|
noe.Change_val_tdt(ddlenu,val_final);
|
|
};
|
|
|
|
}; //-- fin du test si le temps est actif
|
|
}; //-- fin du test si le ddl du noeud est en service
|
|
}; //-- fin du test si le noeud est à considérer ou pas
|
|
}; //-- fin de la boucle sur tabBloq_i
|
|
}; //-- fin de la boucle sur nn
|
|
}; //-- fin du else du if (tabBloq_i.Mouvement_Solide())
|
|
}; //-- fin du du test : if (ref.Indic() == 1)
|
|
};//-- fin de la boucle sur tabBloq
|
|
// vérif qu'il n'y a pas de surcharge de blocage
|
|
Verif_surcharge_blocage(lesMail,lesRef,temps,cas);
|
|
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
|
|
};
|
|
|
|
// validation des conditions de blocages, pour l'incrément.
|
|
// concernant l'activité des ddlLim, elle est enregistrée en fonction du temps
|
|
// idem pour les conditions linéaires
|
|
void LesCondLim::Validation_blocage (LesReferences* lesRef,const double& temps)
|
|
{
|
|
// tout d'abord les conditions de blocage
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok que si c'est une ref de noeud
|
|
{ int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
for (int nd=1;nd<= tabBloqitaille;nd++)
|
|
// validation de l'activité du ddlLim
|
|
tabBloq_i.Validation(temps);
|
|
};
|
|
};
|
|
};
|
|
// maintenant les conditions linéaires
|
|
int tabTaille = tab_iocondiline.Taille();
|
|
////----- debug
|
|
//cout << "\n LesCondLim::Validation_blocage: avant validation \n temps = " << temps << "\n";
|
|
//cout << tab_iocondiline;
|
|
////--- fin debug
|
|
for (int icondli=1;icondli<= tabTaille; icondli++)
|
|
tab_iocondiline(icondli).Validation(temps);
|
|
////----- debug
|
|
//cout << "\n LesCondLim::Validation_blocage: après validation \n";
|
|
//cout << tab_iocondiline;
|
|
////--- fin debug
|
|
};
|
|
|
|
// test s'il y a changement de statut pour le temps indiqué par rapport à la situation actuelle ou pas
|
|
// n'effectue aucune autre opération
|
|
// si en_ddl est différent de NU_DDL on test le changement de statut uniquement pour le ddl en_ddl
|
|
bool LesCondLim::Changement_statut(const LesMaillages * lesMail,const LesReferences* lesRef
|
|
,LesFonctions_nD* lesFonctionsnD
|
|
,const double& temps,const Enum_ddl en_ddl)
|
|
// *************** a mettre en conformité avec miseà jour tdt ***************$
|
|
|
|
|
|
|
|
{ cout << "\n methode pas operationnelle, a mettre a jour !!!!"
|
|
<< "\n LesCondLim::Changement_statut(....";
|
|
Sortie(1);
|
|
|
|
// préparation
|
|
bool tous_les_blocages = true;
|
|
if (en_ddl != NU_DDL) tous_les_blocages = false;
|
|
bool ch_statut = false; // valeur de retour
|
|
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
// on parcours le tableau de ddl bloques
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
for (int nd=1;nd<= tabBloqitaille;nd++)
|
|
// incrementation en fonction de la valeur de blocage et du coef
|
|
{Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// on regarde si les temps dépendent d'une fct nD
|
|
// si oui on modifie les bornes du ddl
|
|
if (tabBloq_i.Temps_depend_nD())
|
|
LesCondLim::Mise_a_jour_t_minmax_ddlLim(noe,tabBloq_i,lesFonctionsnD);
|
|
Enum_ddl ddlenu= ddl.Id_nom(); // pour simplifier
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// cas de deplacements imposes en entraine on change les Ui en Xi
|
|
ddl.Change_nom(UxyzXi(ddlenu));
|
|
bool a_bloquer = tous_les_blocages;
|
|
if (! a_bloquer) // cas ou on ne veut que certain blocage, a_bloque est faux
|
|
{if (Meme_famille(en_ddl,ddlenu)) a_bloquer = true;}
|
|
if (a_bloquer)
|
|
{ if (!(tabBloq_i.Temps_actif(temps)))
|
|
// cas de la courbe non active pour le temps
|
|
{ // si le ddl du noeud est en service on continue sinon on ne fait rien
|
|
if ( noe.En_service(ddlenu) )
|
|
// on regarde s'il y a changement de statut et que c'est une variable
|
|
{if ((noe.Ddl_fixe(ddlenu)) && (noe.UneVariable(ddlenu)))
|
|
ch_statut = true;
|
|
} //-- fin du test si le ddl du noeud est en service
|
|
} //-- fin du test ou le temps n'est pas actif
|
|
else
|
|
// cas du temps actif
|
|
{ if (ddl.Valeur() != 0)
|
|
{// si le ddl du noeud est en service on continue sinon on ne fait rien
|
|
if ( noe.En_service(ddlenu) )
|
|
// on regarde s'il y a changement de statut et que c'est une variable
|
|
{if ( (!(noe.Ddl_fixe(ddlenu))) && (noe.UneVariable(ddlenu)))
|
|
ch_statut = true;
|
|
} //-- fin du test si le ddl du noeud est en service
|
|
} //-- fin du test si la valeur a bloquer est différente de 0
|
|
} //-- fin du test si le temps est actif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ch_statut;
|
|
};
|
|
|
|
|
|
// récupération des tableaux d'indices généraux des variables ddl bloqués
|
|
// cas : donne le type d'association de ddl que l'on veut
|
|
// =0 -> pas d'association
|
|
// =1 -> association de Xi avec Vi avec Gammai
|
|
// t_assemb: donne pour chaque type d'association, le numéro d'assemblage correspondant au different ddl
|
|
// de l'association
|
|
// cas=1 -> numéro d'assemblage de X1 puis V1 puis GAMMA1
|
|
// : en sortie une liste de Gene_asso, correspondant à tous les ddl bloqués et les
|
|
// les ddl associés
|
|
list <LesCondLim::Gene_asso> LesCondLim::Tableau_indice
|
|
(const LesMaillages * lesMail,const Tableau <Nb_assemb> & t_assemb
|
|
,const LesReferences* lesRef,const double& temps,int cas)
|
|
{ // def de la liste de retour
|
|
list <LesCondLim::Gene_asso> li_ret;
|
|
// préparation
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
// on parcours le tableau de ddl bloques
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok pour les noeuds uniquement
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// incrementation en fonction de la valeur de blocage
|
|
{Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
const Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
// cas de deplacements imposes en entraine on change les Ui en Xi
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// si le blocage est relatif à une donnée et non à une variable arrêt
|
|
if (!(noe.UneVariable(ddl.Id_nom()))) break;
|
|
// si le ddl concerne la direction 3 et que l'on est en axi, arrêt
|
|
// car le ddl 3 n'est pas utilisé en blocage en axi
|
|
Enum_ddl en_ddl = ddl.Id_nom(); // le type principal de l'élément Gene_asso
|
|
if (ParaGlob::AxiSymetrie() && FoncDim(en_ddl))
|
|
{Enum_ddl prem_ddl = PremierDdlFamille(en_ddl);
|
|
// pour l'instant on ne traite que X, U, V et Gamma
|
|
bool fin_traitement = false; // init
|
|
switch (prem_ddl)
|
|
{ case X1: if (en_ddl == X3)fin_traitement = true;
|
|
break;
|
|
case V1: if (en_ddl == V3)fin_traitement = true;
|
|
break;
|
|
case GAMMA1:if (en_ddl == GAMMA3)fin_traitement = true;
|
|
break;
|
|
default:
|
|
cout << "\n *** erreur pour l'instant en axi, seules les cas "
|
|
<< " Xi, Vi, GAMMAi sont pris en compte pour les CL selon dir 3 "
|
|
<< " \n LesCondLim::Tableau_indice(... "<< endl;
|
|
break;
|
|
};
|
|
if (fin_traitement) break;
|
|
};
|
|
|
|
// on regarde si le ddl fait partie de la liste à scruter, si l'on est
|
|
// dans le cas d'une combinaison, sinon c'est ok
|
|
bool choix = true; // vrai a priori, c'est à dire le cas = 0
|
|
// qui convient que dans le cas = 0, sinon:
|
|
if (cas!= 0)
|
|
{ if (Dans_combinaison(cas,en_ddl))
|
|
{choix = true;}
|
|
else
|
|
{choix = false;} // cas d'une combinaison , et d'un ddl qui ni appartiend pas
|
|
};
|
|
if (choix)
|
|
{ // on test que si le temps est actif
|
|
// ici les tmin et tmax du ddl ne sont pas modifiés, on considère que ce sont
|
|
// ceux qui ont été mise à jour à la précédente mise à jour
|
|
if ((tabBloq_i.Temps_actif(temps)))
|
|
{ switch (cas)
|
|
{ case 0 : // cas pas d'association
|
|
{ // def du tableau de position pour l'élément Gene_asso
|
|
Tableau <int> pointe(1); // dimension pour Xi,Vi,GAMMAi
|
|
// recup de la position du ddl
|
|
pointe(1) = noe.Pointeur_assemblage(en_ddl,t_assemb(1).n);
|
|
// ajout dans la liste
|
|
Gene_asso aa(en_ddl,pointe);
|
|
li_ret.push_back(aa);
|
|
break;
|
|
}
|
|
case 1 : // cas de l'association X V GAMMA
|
|
{ // def du tableau de position pour l'élément Gene_asso
|
|
Tableau <int> pointe(3); // dimension pour Xi,Vi,GAMMAi
|
|
// récup des ddl secondaire et du ddl principal bloqué
|
|
Tableau <Enum_ddl> t_enu = MemeCombinaison(cas,en_ddl);
|
|
pointe(1) = noe.Pointeur_assemblage(t_enu(1),t_assemb(1).n);
|
|
pointe(2) = noe.Pointeur_assemblage(t_enu(2),t_assemb(2).n);
|
|
pointe(3) = noe.Pointeur_assemblage(t_enu(3),t_assemb(3).n);
|
|
// ajout dans la liste
|
|
Gene_asso aa(en_ddl,pointe);
|
|
li_ret.push_back(aa);
|
|
////// --debug
|
|
//cout << "\n debug LesCondlim::Tableau_indice("
|
|
// << "\n li_ret.size= "<< li_ret.size() << endl;
|
|
////// -- fin debug
|
|
|
|
break;
|
|
}
|
|
}; //-- fin du switch (cas)
|
|
}; //-- fin du if ((tabBloq_i.Temps_actif(temps)))
|
|
}; //-- fin du if (choix)
|
|
}; //-- fin du for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin du for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin du if (ref.Indic() == 1)
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
//// --debug
|
|
//cout << "\n debug LesCondlim::Tableau_indice("
|
|
// << "\n li_ret.size= "<< li_ret.size() ;
|
|
//list <LesCondLim::Gene_asso>::iterator ie,iefin=li_ret.end();; // def d'un iterator adoc
|
|
//int ih=1; // indice
|
|
//for(ie=li_ret.begin(),ih=1;ie!=iefin;ie++,ih++)
|
|
// // comme les valeurs des X V Gamma vont être écrasé par le calcul global, on utilise
|
|
// // des conteneurs intermédiaires
|
|
// {//trois cas
|
|
// LesCondLim::Gene_asso & s = (*ie); // pour simplifier
|
|
// int ix=s.pointe(1); // début des Xi
|
|
// int iv=s.pointe(2); // début des Vi
|
|
// int ig=s.pointe(3); // début des gammai
|
|
// cout << "\n ix= " << ix << ", iv= "<< iv << ", ig= "<< ig;
|
|
// };
|
|
//cout << endl;
|
|
//// -- fin debug
|
|
|
|
// retour de la liste
|
|
return li_ret;
|
|
};
|
|
|
|
|
|
|
|
// mise en place des conditions limites sur les matrices et/ou second membres
|
|
// cas : indique un type d'association de ddl
|
|
// = 0 -> pas d'association, seules les ddl fournis par l'utilisateur sont considéré
|
|
// = 1 -> association de Xi Vi Gammai, qui sont pris en compte dès
|
|
// lors que l'un a été fixé par l'utilisateur
|
|
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
|
|
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
|
|
void LesCondLim::ImposeConLimtdt(LesMaillages * lesMail,LesReferences* lesRef,
|
|
Mat_abstraite & matglob,Vecteur& vecglob
|
|
,const Nb_assemb& nb_casAssemb,int cas,Vecteur* vec2)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on parcours le tableau de ddl bloques
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok pour les noeuds uniquement
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// mise en place de la condition limite
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// cas de deplacements imposes en coordonnees entrainees on change les Ui en Xi
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// on continue uniquement si le ddl du tableau de blocage est en service
|
|
// et si pour le noeud c'est une variable
|
|
if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
{ // récup des enu_ddl équivalent au groupe
|
|
tmc = MemeCombinaison(cas,ddl.Id_nom());
|
|
int tailletmc = tmc.Taille();
|
|
for (int itc=1;itc <= tailletmc;itc++)
|
|
{// on boucle sur tous les ddl a imposer
|
|
// calcul du pointeur correspondant au ddl cherche
|
|
int pt = noe.Pointeur_assemblage(tmc(itc),nb_casAss);
|
|
// cas ou le ddl fait partie du cas d'assemblage et qu'il est actif
|
|
if ((pt != -1) && (noe.En_service(tmc(itc))))
|
|
{// ce que l'on veut c'est une variation nulle des ddl imposee
|
|
// -> valeur imposee = 0
|
|
// cas de la matrice, et modif du second membre si la valeur imposee
|
|
// est differente de zero (ce qui n'est pas le cas ici !)
|
|
condlim(nb_casAss).Val_imposee_Mat(matglob,vecglob,pt,0.,vec2);
|
|
// cas du second membre et sauvegarde des reactions
|
|
condlim(nb_casAss).Val_imposee_Sm(vecglob,pt,0.,vec2);
|
|
};
|
|
}; //-- fin de for (int itc=1;itc <= tailletmc;itc++)
|
|
}; //-- fin de if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
}; //-- fin de for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin de for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin de if (ref.Indic() == 1)
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
// affichage éventuelle de la matrice de raideur et du second membre
|
|
if (ParaGlob::NiveauImpression() >= 10)
|
|
{ string entete = " affichage de la matrice apres conditions limites des ddl initialement bloques ";
|
|
matglob.Affichage_ecran(entete);
|
|
entete = " affichage du second membre apres conditions limites des ddl initialement bloques ";
|
|
vecglob.Affichage_ecran(entete);
|
|
};
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
};
|
|
|
|
// mise en place des conditions limites sur le second membres
|
|
// nb_casAssemb : le cas d'assemblage
|
|
// cas : indique un type d'association de ddl
|
|
// = 0 -> pas d'association, seules les ddl fournis par l'utilisateur sont considéré
|
|
// = 1 -> association de Xi Vi Gammai, qui sont pris en compte dès lors que l'un
|
|
// a été fixé par l'utilisateur
|
|
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
|
|
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
|
|
void LesCondLim::ImposeConLimtdt(LesMaillages * lesMail,LesReferences* lesRef
|
|
,Vecteur& vecglob,const Nb_assemb& nb_casAssemb
|
|
,int cas,Vecteur* vec2)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on parcours le tableau de ddl bloques
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok pour les noeuds uniquement
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// mise en place de la condition limite
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// cas de deplacements imposes en coordonnees entrainees on change les Ui en Xi
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// on continue uniquement si le ddl du tableau de blocage est en service
|
|
// et si pour le noeud c'est une variable
|
|
if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
{ // récup des enu_ddl équivalent au groupe
|
|
tmc = MemeCombinaison(cas,ddl.Id_nom());
|
|
int tailletmc = tmc.Taille();
|
|
for (int itc=1;itc <= tailletmc;itc++)
|
|
{// on boucle sur tous les ddl a imposer
|
|
// calcul du pointeur correspondant au ddl cherche
|
|
int pt = noe.Pointeur_assemblage(tmc(itc),nb_casAss);
|
|
// cas ou le ddl fait partie du cas d'assemblage et qu'il est actif
|
|
if ((pt != -1) && (noe.En_service(tmc(itc))))
|
|
{// ce que l'on veut c'est une variation nulle des ddl imposee
|
|
// -> valeur imposee = 0
|
|
// cas du second membre et sauvegarde des reactions
|
|
condlim(nb_casAss).Val_imposee_Sm(vecglob,pt,0.,vec2);
|
|
};
|
|
}; //-- fin de for (int itc=1;itc <= tailletmc;itc++)
|
|
}; //-- fin de if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
}; //-- fin de for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin de for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin de if (ref.Indic() == 1)
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
// affichage éventuelle du second membre
|
|
if (ParaGlob::NiveauImpression() >= 10)
|
|
{ string entete = " affichage du second membre apres conditions limites des ddl initialement bloques ";
|
|
vecglob.Affichage_ecran(entete);
|
|
};
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
};
|
|
|
|
// mise en place des conditions limites sur deux matrices
|
|
// utilisé par exemple pour le flambement
|
|
// la première matrice est initialisée avec des 1 sur la diagonale
|
|
// la seconde avec des 0 sur la diagonale
|
|
// cas : indique un type d'association de ddl
|
|
// = 0 -> pas d'association, seules les ddl fournis par l'utilisateur sont considéré
|
|
// = 1 -> association de Xi Vi Gammai, qui sont pris en compte dès lors que l'un
|
|
// a été fixé par l'utilisateur
|
|
void LesCondLim::ImpConLimtdt2Mat(LesMaillages * lesMail,LesReferences* lesRef,
|
|
Mat_abstraite & matglob,Mat_abstraite & matgeom
|
|
,const Nb_assemb& nb_casAssemb,int cas)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
|
|
tempsCL.Mise_en_route_du_comptage(); // temps cpu
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on parcours le tableau de ddl bloques
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok pour les noeuds uniquement
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// mise en place de la condition limite
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// cas de deplacements imposes en coordonnees entrainees on change les Ui en Xi
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// on continue uniquement si le ddl du tableau de blocage est en service
|
|
// et si pour le noeud c'est une variable
|
|
if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
{ // récup des enu_ddl équivalent au groupe
|
|
tmc = MemeCombinaison(cas,ddl.Id_nom());
|
|
int tailletmc = tmc.Taille();
|
|
for (int itc=1;itc <= tailletmc;itc++)
|
|
{// on boucle sur tous les ddl a imposer
|
|
// calcul du pointeur correspondant au ddl cherche
|
|
int pt = noe.Pointeur_assemblage(tmc(itc),nb_casAss);
|
|
// cas ou le ddl fait partie du cas d'assemblage et qu'il est actif
|
|
if ((pt != -1) && (noe.En_service(tmc(itc))))
|
|
{// ici on ne fait que modifier les matrices -> un 1 sur la diagonale
|
|
// et 0 sur le reste de la ligne et colonne correspondantes
|
|
condlim(nb_casAss).Val_imposSimple_Mat(matglob,pt,1.);
|
|
condlim(nb_casAss).Val_imposSimple_Mat(matgeom,pt,0.);
|
|
};
|
|
}; //-- fin de for (int itc=1;itc <= tailletmc;itc++)
|
|
}; //-- fin de if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
}; //-- fin de for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin de for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin de if (ref.Indic() == 1)
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
// affichage éventuelle des deux matrices de raideur
|
|
if (ParaGlob::NiveauImpression() >= 10)
|
|
{ string entete = " affichage de la premiere matrice de raideur apres conditions limites (matglob) ";
|
|
entete += " des ddl initialement bloques";
|
|
matglob.Affichage_ecran(entete);
|
|
entete = " affichage de la seconde matrice de raideur apres conditions limites (matgeom) ";
|
|
entete += " des ddl initialement bloques";
|
|
matgeom.Affichage_ecran(entete);
|
|
};
|
|
tempsCL.Arret_du_comptage(); // temps cpu
|
|
};
|
|
|
|
// récupération des reactions initiales, avant les rotations dues aux conditions linéaires
|
|
// il s'agit des réactions dues aux ddl bloqués et dues aux conditions linéaires
|
|
// et calcul des torseurs de réaction
|
|
void LesCondLim::ReacAvantCHrepere(Vecteur& residu,LesMaillages * lesMail,
|
|
LesReferences* lesRef,const Nb_assemb& nb_casAssemb,int cas)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, pour l'instant seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on cree une liste de stockage intermediaire
|
|
list <ReactStoc> lili;
|
|
list <int> indice_tabBloq; // tableau de travail, qui sert pour le calcul des torseurs de réaction
|
|
ReactStoc elem; // element courant de stockage des réactions
|
|
|
|
//----------- cas des ddl bloqués -----------------
|
|
// on parcours le tableau de ddl bloques
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (!((ref.Indic() == 4) && // le cas des conditions de tangence sur
|
|
(tabBloq_i.TypeDeCL()==TANGENTE_CL )) // les arrêtes n'est pas à prendre en compte
|
|
&& (ref.Indic() == 1)) // s'applique uniquement au cas des ref de noeuds
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// récupération de la condition limite
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// cas de deplacements imposes en coordonnees entrainees on change les Ui en Xi
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// on continue uniquement si le ddl du tableau de blocage est en service
|
|
// et si pour le noeud c'est une variable
|
|
if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
{ // récup des enu_ddl équivalent au groupe
|
|
tmc = MemeCombinaison(cas,ddl.Id_nom());
|
|
int tailletmc = tmc.Taille();
|
|
for (int itc=1;itc <= tailletmc;itc++)
|
|
{// on boucle sur tous les ddl a imposer
|
|
// calcul du pointeur correspondant au ddl cherche
|
|
int pt = noe.Pointeur_assemblage(tmc(itc),nb_casAss);
|
|
// cas ou le ddl fait partie du cas d'assemblage et qu'il est actif
|
|
if ((pt != -1) && (noe.En_service(tmc(itc))))
|
|
{ // maintenant on peut récupérer la réaction
|
|
elem.ddl = ddl;
|
|
elem.ddl.Valeur() = residu(pt);
|
|
elem.numMail = ref.Nbmaille();
|
|
elem.numNoeud = ref.Numero(nn);
|
|
elem.casAss = nb_casAss;
|
|
lili.push_back(elem); // sauvegarde de la réaction
|
|
indice_tabBloq.push_back(i); // sauvegarde de l'indice dans tabBloq
|
|
};
|
|
}; //-- fin de for (int itc=1;itc <= tailletmc;itc++)
|
|
}; //-- fin de if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
}; //-- fin de for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin de for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin de if (!((ref.Indic() == 4) && (tabBloq_i.TypeDeCL()==TANGENTE_CL) ) )
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
|
|
//----------- cas des conditions linéaires -----------------
|
|
// on cree une liste de stockage intermediaire
|
|
list <ReactStoc> lili_CLin;List_io <DeuxEntiers> indice_dans_tab_iocondiline;
|
|
|
|
// on a besoin d'enregistrer une seule fois chaque réaction, or le mode de fabrication des CLL
|
|
// fait que cela conduit à des redondances. Pour les repérer, on va utiliser un conteneur de drapeau
|
|
// de manière à limiter la taille de ce conteneur on utilise une map, c'est moins rapide en acces
|
|
// qu'un tableau, mais c'est mieux qu'une liste et c'est plus petit qu'un tableau, car a priori
|
|
// il y a moins beaucoup moins de ddl bloqué par les CLL que de ddl total du pb
|
|
map < int , bool, std::less <int> > reac_deja_stocke;
|
|
|
|
// on parcours le tableau des CLL
|
|
// on boucle sur le tableau de conditions limites linéaires enregistré
|
|
int tabTaille = tab_CLinApplique.Taille();
|
|
for (int i=1;i<= tabTaille; i++)
|
|
{int sous_taille = tab_CLinApplique(i).Taille();
|
|
for (int j=1; j<= sous_taille; j++)
|
|
{ Condilineaire& condi = tab_CLinApplique(i)(j);
|
|
// on met à jour les pointeurs d'assemblage pour bien localiser les infos dans SM et K
|
|
// ce sera refait dans l'assemblage...
|
|
condi.ConditionPourPointeursAssemblage(nb_casAssemb);
|
|
// on n'intervient que si la condition est exploitable c-a-d Iddl() > -1
|
|
if (condi.Iddl() > -1)
|
|
{ // chaque ddl qui appartient à une CLL et qui est associé
|
|
// à un coefficient non nulle conduit à une condition limite
|
|
const Vecteur& Vectval = condi.Val();
|
|
const Tableau<int>& pt = condi.Pt_t();
|
|
const Tableau<Enum_ddl>& t_enu = condi.Tab_Enum();
|
|
const Tableau < Noeud *>& t_noeud = condi.TabNoeud();
|
|
|
|
// on boucle sur les noeuds puis sur les ddl de la CLL
|
|
int taille = pt.Taille();
|
|
int nb_noeud = t_noeud.Taille();int itab=1;
|
|
int nbddlfamille = taille / nb_noeud;
|
|
for (int i_noe=1;i_noe <= nb_noeud;i_noe++)
|
|
for (int i_fa =1; i_fa<= nbddlfamille; i_fa++,itab++)
|
|
{ // on ne stocke que si la réaction n'a pas déjà été stockée
|
|
if ((reac_deja_stocke.find(pt(itab))==reac_deja_stocke.end())
|
|
&& (Vectval(itab) != 0.) ) // et que le coef est non nul
|
|
{ // on définit la réaction
|
|
elem.ddl.Change_nom(t_enu(itab));
|
|
elem.ddl.Valeur() = residu(pt(itab));
|
|
elem.numMail = t_noeud(i_noe)->Num_Mail();
|
|
elem.numNoeud = t_noeud(i_noe)->Num_noeud();
|
|
// elem.casAss = condi.CasAssemb().n;
|
|
elem.casAss = nb_casAssemb.n;
|
|
lili_CLin.push_back(elem); // on sauvegarde la réaction
|
|
// sauvegarde de l'indice dans tab_iocondiline car le premier indice "i"
|
|
// de tab_CLinApplique est celui correspondant à la condition tab_iocondiline(i)
|
|
// le second indice permet de retrouver la ref
|
|
indice_dans_tab_iocondiline.push_back(DeuxEntiers(i,i_noe));
|
|
// on renseigne la map
|
|
reac_deja_stocke[pt(itab)] = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
//----------- fin du cas des conditions linéaires -----------------
|
|
//--débug ---
|
|
//cout << "\n " << indice_dans_tab_iocondiline << endl;
|
|
//--débug---
|
|
|
|
|
|
// ----- on initialise le tableau des torseurs de réaction
|
|
int tabtorsTaille = tab_torseurReac.Taille();
|
|
for (int i=1;i<= tabtorsTaille;i++)
|
|
if (tab_torseurReac(i).existe_torseur_reac)
|
|
tab_torseurReac(i).Zero_init_torseur();
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
|
|
// --- enregistrement des réactions pour ddl bloqué et calcul des torseurs
|
|
{ // on encapsule
|
|
list <ReactStoc>::iterator i; // def d'un iterator adoc
|
|
reaction.Change_taille((int)lili.size());
|
|
// map_reaction.erase(map_reaction.begin(),map_reaction.end());
|
|
int j;
|
|
list <int>::iterator i_taBloq=indice_tabBloq.begin();
|
|
for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++,i_taBloq++)
|
|
{ reaction(j) = *i;
|
|
// map_reaction["mail"+ChangeEntierSTring((*i).numMail)+"noeud"+ChangeEntierSTring((*i).numNoeud)]
|
|
// .push_back(&(reaction(j)));
|
|
// transfert des informations aux noeuds
|
|
ReactStoc& reac = reaction(j); // pour simplifier
|
|
// récup du noeud j du maillage i
|
|
Noeud& noe = lesMail->Noeud_LesMaille(reac.numMail,reac.numNoeud);
|
|
Enum_ddl enu_reac = Vers_enum_reac(reac.ddl.Id_nom()); // le ddl de réaction
|
|
// dans le cas où la réaction n'existe pas on l'ajoute
|
|
// a priori on traite à chaque fois car c'est l'algorithme globale qui détermine si un ddl est actif ou pas
|
|
// ainsi, pour ne pas ajouter des réactions pour des ddl HS, c'est ici que l'on peut réellement voir l'activité
|
|
{ if (!noe.Existe_ici(enu_reac))
|
|
// { Ddl reac_ddl(enu_reac,0.0,HS_LISIBLE_FIXE);
|
|
{ Ddl reac_ddl(enu_reac,0.0,LISIBLE_FIXE);
|
|
noe.PlusDdl(reac_ddl);
|
|
}
|
|
else
|
|
// sinon il faut le bloquer car la réaction est imposée
|
|
{ noe.Change_fixe(enu_reac,true);};
|
|
// mise à jour et calcul éventuel du torseur de réaction: uniquement pour les ddl X1, X2, X3
|
|
if (ttRG(*i_taBloq) != 0) // si = 0 c'est que le ddl n'est pas un déplacement classique
|
|
CalculTorseurReaction(tab_torseurReac(ttRG(*i_taBloq)),noe,reac);
|
|
};
|
|
// mise à jour de la réaction
|
|
noe.Change_val_tdt(enu_reac,reac.ddl.Valeur()); // t=tdt
|
|
};
|
|
// on va maintenant exporter les composantes du tenseur vers des grandeurs globales
|
|
int taille_tors_bloqu = ttRG_noms_ref.Taille();
|
|
int taille_tors_bloquplus1 = taille_tors_bloqu +1;
|
|
// cas d'un blocage de ddl
|
|
{int il = 1;
|
|
for (int ia=1;ia<taille_tors_bloquplus1;ia++,il++)
|
|
{ TorseurReac& torseur= tab_torseurReac(ia); // tableau des torseurs de réaction
|
|
// 1) la résultante
|
|
int dimaPlus1 = dima+1;
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRG_noms_ref(il)+"_Re_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.resultante(ic);
|
|
};
|
|
// 2) le moment
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRG_noms_ref(il)+"_Mo_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.moment(ic);
|
|
};
|
|
};
|
|
};
|
|
}; // fin encapsulation
|
|
|
|
// --- enregistrement des réactions pour les CLL et calcul également des torseurs associés
|
|
// il s'agit des réactions définies précédemment (-- cas des conditions linéaires --)
|
|
{ // on encapsule
|
|
list <ReactStoc>::iterator i; // def d'un iterator adoc
|
|
List_io <DeuxEntiers>::iterator iti = indice_dans_tab_iocondiline.begin();
|
|
reaction_CLin.Change_taille((int)lili_CLin.size());
|
|
int j;
|
|
for (i=lili_CLin.begin(),j=1 ; i != lili_CLin.end(); i++,j++,iti++)
|
|
{ reaction_CLin(j) = *i;
|
|
// transfert des informations aux noeuds
|
|
ReactStoc& reac = reaction_CLin(j); // pour simplifier
|
|
// récup du noeud j du maillage i
|
|
Noeud& noe = lesMail->Noeud_LesMaille(reac.numMail,reac.numNoeud);
|
|
Enum_ddl enu_reac = Vers_enum_reac(reac.ddl.Id_nom()); // le ddl de réaction
|
|
// dans le cas où la réaction n'existe pas on l'ajoute
|
|
// a priori on traite à chaque fois car c'est l'algorithme globale qui détermine si un ddl est actif ou pas
|
|
// ainsi, pour ne pas ajouter des réactions pour des ddl HS, c'est ici que l'on peut réellement voir l'activité
|
|
{ if (!noe.Existe_ici(enu_reac))
|
|
// { Ddl reac_ddl(enu_reac,0.0,HS_LISIBLE_FIXE);
|
|
{ Ddl reac_ddl(enu_reac,0.0,LISIBLE_FIXE);
|
|
noe.PlusDdl(reac_ddl);
|
|
}
|
|
else
|
|
// sinon il faut le bloquer car la réaction est imposée
|
|
{ noe.Change_fixe(enu_reac,true);};
|
|
// mise à jour et calcul éventuel du torseur de réaction: uniquement pour les ddl X1, X2, X3
|
|
CalculTorseurReaction(tab_torseurReac(ttRGCLL((*iti).un)((*iti).deux)),noe,reac);
|
|
};
|
|
// mise à jour de la réaction
|
|
noe.Change_val_tdt(enu_reac,reac.ddl.Valeur()); // t=tdt
|
|
};
|
|
// exportation en grandeurs globales: cas d'un blocage venant d'une CLL
|
|
int taille_tors_bloqu = ttRG_noms_ref.Taille();
|
|
int taille_tors_bloquplus1 = taille_tors_bloqu +1;
|
|
int taille_torsP1 = tab_torseurReac.Taille() + 1;
|
|
{int il = 1; //ttRGCLL_noms_ref.begin();
|
|
for (int ia=taille_tors_bloquplus1;ia<taille_torsP1;ia++,il++)
|
|
{ TorseurReac& torseur= tab_torseurReac(ia); // tableau des torseurs de réaction
|
|
// 1) la résultante
|
|
int dimaPlus1 = dima+1;
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRGCLL_noms_ref(il)+"_Re_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.resultante(ic);
|
|
};
|
|
// 2) le moment
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRGCLL_noms_ref(il)+"_Mo_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.moment(ic);
|
|
};
|
|
};
|
|
};
|
|
}; // fin encapsulation
|
|
};
|
|
|
|
// calcul des reactions et stockage des valeurs
|
|
// ceci dans le cas ou il n'y a pas de conditions lineaires appliquee
|
|
// on se sert des valeurs sauvegardees lors de la mise en place des CL bloquees
|
|
// cas : indique un type d'association de ddl
|
|
// = 0 -> pas d'association, seules les ddl fournis par l'utilisateur sont considéré
|
|
// = 1 -> association de Xi Vi Gammai, qui sont pris en compte dès lors que l'un
|
|
// a été fixé par l'utilisateur
|
|
void LesCondLim::CalculReaction(LesMaillages * lesMail,LesReferences* lesRef
|
|
,const Nb_assemb& nb_casAssemb,int cas)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, pour l'instant seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on cree une liste de stockage intermediaire
|
|
list <ReactStoc> lili;
|
|
list <int> indice_tabBloq; // tableau de travail
|
|
ReactStoc elem; // l'element courant
|
|
// on parcours le tableau de ddl bloques
|
|
int tabBloqTaille =tabBloq.Taille();
|
|
for (int i=1;i<= tabBloqTaille;i++)
|
|
{ DdlLim& tabBloq_i = tabBloq(i);
|
|
// recup de la reference correspondant au mot cle
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef->Trouve(tabBloq_i.NomRef(),tabBloq_i.NomMaillage()));
|
|
if (ref.Indic() == 1) // ok pour les noeuds uniquement
|
|
{int reftaille = ref.Taille();
|
|
for (int nn =1; nn<= reftaille;nn++)
|
|
{int tabBloqitaille = tabBloq_i.Taille();
|
|
// dans le cas d'un champ, pour chaque ddl on a un noeud associé, il ne faut donc pas itérer
|
|
// sur les noeuds, pour cela on modifie les borne de la boucle pour ne faire qu'un seul bon passage
|
|
int idebut=1; int ifinfin = tabBloqitaille;// début normale
|
|
if (tabBloq_i.Champ()) {idebut = nn; ifinfin = nn;};
|
|
for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
// calcul de la reaction
|
|
{ Ddl ddl = tabBloq_i.ElemLim(nd);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
|
|
// cas de deplacements imposes en coordonnees entrainees on change les Ui en Xi
|
|
// if (noe.Existe_ici(X1) && (strchr(ddl.Nom(),'U') != NULL))
|
|
if (noe.Existe_ici(X1) && (PremierDdlFamille(ddl.Id_nom())==UX))
|
|
ddl.Change_nom(UxyzXi(ddl.Id_nom()));
|
|
// on continue uniquement si le ddl du tableau de blocage est en service
|
|
// et si pour le noeud c'est une variable
|
|
if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
{ // récup des enu_ddl équivalent au groupe
|
|
tmc = MemeCombinaison(cas,ddl.Id_nom());
|
|
int tailletmc = tmc.Taille();
|
|
for (int itc=1;itc <= tailletmc;itc++)
|
|
{// on boucle sur tous les ddl a imposer
|
|
// calcul du pointeur correspondant au ddl cherche
|
|
int pt = noe.Pointeur_assemblage(tmc(itc),nb_casAss);
|
|
// cas ou le ddl fait partie du cas d'assemblage et qu'il est actif
|
|
if ((pt != -1) && (noe.En_service(tmc(itc))))
|
|
{ elem.ddl = ddl;
|
|
elem.ddl.Valeur() = condlim(nb_casAss).ValReact(pt);
|
|
elem.numMail = ref.Nbmaille();
|
|
elem.numNoeud = ref.Numero(nn);
|
|
elem.casAss = nb_casAss;
|
|
lili.push_back(elem);
|
|
indice_tabBloq.push_back(i); // sauvegarde de l'indice dans tabBloq
|
|
};
|
|
}; //-- fin de for (int itc=1;itc <= tailletmc;itc++)
|
|
}; //-- fin de if ((ddl.Service()) && (noe.UneVariable(ddl.Id_nom())))
|
|
}; //-- fin de for (int nd=idebut;nd<= ifinfin ;nd++)
|
|
}; //-- fin de for (int nn =1; nn<= reftaille;nn++)
|
|
}; //-- fin de if (ref.Indic() == 1)
|
|
}; //-- fin de for (int i=1;i<= tabBloqTaille;i++)
|
|
// on initialise le tableau des torseurs de réaction
|
|
int tabtorsTaille = tab_torseurReac.Taille();
|
|
for (int i=1;i<= tabtorsTaille;i++)
|
|
if (tab_torseurReac(i).existe_torseur_reac)
|
|
tab_torseurReac(i).Zero_init_torseur();
|
|
|
|
// enregistrement
|
|
list <ReactStoc>::iterator i,ilfin = lili.end(); // def d'un iterator adoc
|
|
reaction.Change_taille((int)lili.size());
|
|
// map_reaction.erase(map_reaction.begin(),map_reaction.end());
|
|
int j;
|
|
list <int>::iterator i_taBloq=indice_tabBloq.begin();
|
|
for (i=lili.begin(),j=1 ; i != ilfin; i++,j++,i_taBloq++)
|
|
{reaction(j) = *i;
|
|
// map_reaction["mail"+ChangeEntierSTring((*i).numMail)+"noeud"+ChangeEntierSTring((*i).numNoeud)]
|
|
// .push_back(&(reaction(j)));
|
|
// transfert des informations aux noeuds
|
|
ReactStoc& reac = reaction(j); // pour simplifier
|
|
// récup du noeud j du maillage i
|
|
Noeud& noe = lesMail->Noeud_LesMaille(reac.numMail,reac.numNoeud);
|
|
Enum_ddl enu_reac = Vers_enum_reac(reac.ddl.Id_nom()); // le ddl de réaction
|
|
// dans le cas où la réaction n'existe pas on l'ajoute
|
|
// a priori on traite à chaque fois car c'est l'algorithme globale qui détermine si un ddl est actif ou pas
|
|
// ainsi, pour ne pas ajouter des réactions pour des ddl HS, c'est ici que l'on peut réellement voir l'activité
|
|
{ if (!noe.Existe_ici(enu_reac))
|
|
// { Ddl reac_ddl(enu_reac,0.0,HS_LISIBLE_FIXE);
|
|
{ Ddl reac_ddl(enu_reac,0.0,LISIBLE_FIXE);
|
|
noe.PlusDdl(reac_ddl);
|
|
}
|
|
else
|
|
// sinon il faut le bloquer car la réaction est imposée
|
|
{ noe.Change_fixe(enu_reac,true);};
|
|
// mise à jour et calcul éventuel du torseur de réaction: uniquement pour les ddl X1, X2, X3
|
|
CalculTorseurReaction(tab_torseurReac(ttRG(*i_taBloq)),noe,reac);
|
|
};
|
|
// mise à jour de la réaction
|
|
noe.Change_val_tdt(enu_reac,reac.ddl.Valeur()); // t=tdt
|
|
};
|
|
// on va maintenant exporter les composantes du tenseur vers des grandeurs globales
|
|
int taille_tors_bloqu = ttRG_noms_ref.Taille();
|
|
int taille_tors_bloquplus1 = taille_tors_bloqu +1;
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
// cas d'un blocage de ddl
|
|
{int il = 1;
|
|
for (int ia=1;ia<taille_tors_bloquplus1;ia++,il++)
|
|
{TorseurReac& torseur= tab_torseurReac(ia); // tableau des torseurs de réaction
|
|
// 1) la résultante
|
|
int dimaPlus1 = dima+1;
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRG_noms_ref(il)+"_Re_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.resultante(ic);
|
|
};
|
|
// 2) le moment
|
|
for (int ic= 1; ic < dimaPlus1; ic++)
|
|
{string nom_ref="tors_"+ttRG_noms_ref(il)+"_Mo_"+ChangeEntierSTring(ic);
|
|
// récup du pointeur de conteneur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_ref));
|
|
#ifdef MISE_AU_POINT
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans l'exportation de composantes de torseur !! "
|
|
<< " la variable globale "<< (nom_ref)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n LesCondLim::ReacAvantCHrepere(..."<<flush;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on l'affecte:
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
Grandeur_Ddl_etendu& tyTQ= *((Grandeur_Ddl_etendu*) (gr_quelc->Grandeur_pointee())); // pour simplifier
|
|
tyTQ.ConteneurDdl_etendu()->Valeur() = torseur.moment(ic);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// récupération des reactions= residu et stockage des valeurs
|
|
// NB: après changement de repère, il n'y a plus que des ddl bloqués
|
|
// cas : indique un type d'association de ddl
|
|
// = 0 -> pas d'association, seules les ddl fournis par l'utilisateur sont considéré
|
|
// = 1 -> association de Xi Vi Gammai, qui sont pris en compte dès lors que l'un
|
|
// a été fixé par l'utilisateur
|
|
void LesCondLim::ReacApresCHrepere(Vecteur& residu,LesMaillages * lesMail,
|
|
LesReferences* ,const Nb_assemb& nb_casAssemb,int )
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, pour l'instant seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
|
|
int nb_casAss = nb_casAssemb.n; // recup du numéro du cas d'assemblage
|
|
Tableau <Enum_ddl> tmc; // tableau de travail
|
|
// on cree une liste de stockage intermediaire
|
|
list <ReactStoc> lili;
|
|
list <int> indice_tabBloq; // tableau de travail
|
|
ReactStoc elem; // l'element courant
|
|
|
|
//----------- cas des ddl bloqués -----------------
|
|
// l'indice des ddl bloqués reste inchangé après chgt de repère on utilise donc les
|
|
// réactions avant rotation par simplicité
|
|
// a priori ce sont exactement les mêmes conditions qui existent avant et après chgt de repère
|
|
// sauf la valeur de la réaction
|
|
int nb_reac = reaction.Taille();
|
|
for (int i=1; i<= nb_reac; i++)
|
|
if (reaction(i).casAss == nb_casAss) // si ce n'est pas le bon cas d'assemblage on ne fait rien
|
|
{ elem = reaction(i);
|
|
Noeud & noe=lesMail->Noeud_LesMaille(elem.numMail,elem.numNoeud);
|
|
elem.ddl.Valeur() = residu(noe.Position_ddl(elem.ddl.Id_nom(),nb_casAss) );
|
|
lili.push_back(elem);
|
|
};
|
|
|
|
// ------- cas des CLL --------------
|
|
// contrairement aux cas des ddl boqués ici on ne peut pas utiliser reaction_CLin
|
|
// car il y a une seule réaction dans le nouveau repère alors qu'il y en avait autant que de ddl
|
|
// dans la CLL, dans le repère initial, donc on reparcours le tableau des CLL
|
|
// on parcours le tableau des CLL
|
|
// on boucle sur le tableau de conditions limites linéaires enregistré
|
|
// et pour chaque element on impose une condition lineaire
|
|
int tabTaille = tab_CLinApplique.Taille();
|
|
for (int i=1;i<= tabTaille; i++)
|
|
{int sous_taille = tab_CLinApplique(i).Taille();
|
|
for (int j=1; j<= sous_taille; j++)
|
|
{ Condilineaire& condi = tab_CLinApplique(i)(j);
|
|
// on n'intervient que si la condition est exploitable c-a-d Iddl() > -1
|
|
if (condi.Iddl() > -1)
|
|
{ if (condi.CasAssemb() == nb_casAssemb)
|
|
{ // la condition limite concerne uniquement un ddl pour chaque CLL
|
|
// il s'agit du premier ddl, pour le premier noeud
|
|
// on définit la réaction
|
|
elem.ddl.Change_nom(condi.Tab_Enum()(1));
|
|
elem.ddl.Valeur() = residu(condi.Pt_t()(1));
|
|
elem.numMail = condi.TabNoeud()(1)->Num_Mail();
|
|
elem.numNoeud = condi.TabNoeud()(1)->Num_noeud();
|
|
elem.casAss = condi.CasAssemb().n;
|
|
lili.push_back(elem); // on sauvegarde la réaction
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// enregistrement
|
|
list <ReactStoc>::iterator i; // def d'un iterator adoc
|
|
reactionApresCHrepere.Change_taille((int)lili.size());
|
|
int j;
|
|
for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++)
|
|
{reactionApresCHrepere(j) = *i;};
|
|
|
|
};
|
|
|
|
|
|
// affichage sur la sortie sort des reactions
|
|
void LesCondLim::Affiche_reaction(ofstream& sort,const LesMaillages * lesMail) const
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule le CPU 0 est concerné
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return ;
|
|
#endif
|
|
|
|
// l'entete
|
|
sort << "\n==========================================================================";
|
|
sort << "\n sortie des efforts generes par l\'exterieur sur les noeuds ";
|
|
sort << "\n==========================================================================\n";
|
|
sort << "\n\n 1) les reactions individuelles \n ";
|
|
|
|
// on balaie le tableau de reaction et on constitue une liste intermédiaire, pour éviter
|
|
// de sortir des doublons
|
|
int reactionTaille = reaction.Taille();
|
|
List_io <ReactStoc> li_inter;
|
|
|
|
// Tableau <ReactStoc> reaction; // les reactions pour les ddl bloqués
|
|
for (int i= 1; i<= reactionTaille;i++)
|
|
li_inter.push_back(reaction(i));
|
|
li_inter.sort(); // on organise la liste
|
|
li_inter.unique(); // on supprime les doublons
|
|
|
|
// *** on change de signe à la réaction car on veut l'extérieur sur les noeuds et non
|
|
// le contraire
|
|
List_io <ReactStoc>::iterator il,ilfin=li_inter.end();
|
|
for (il= li_inter.begin(); il != ilfin;il++)
|
|
{ sort << "\ncas assemb " << (*il).casAss
|
|
<< " maillage " << (*il).numMail <<", noeud " <<(*il).numNoeud
|
|
<< ", ddl = " << (*il).ddl.Nom() << ", valeur = " << (-(*il).ddl.Valeur()) ;
|
|
};
|
|
// on s'occupe maintenant des torseurs de réactions globales si éventuellement il en existe
|
|
sort << "\n\n\n==========================================================================";
|
|
sort << "\n 2) les torseurs globaux ";
|
|
sort << "\n==========================================================================\n";
|
|
// au niveau des références, il est possible d'avoir une référence qui sert pour plusieurs conditions limites
|
|
// aussi on va globaliser les torseurs de réaction en sortie
|
|
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
int ttail = tab_torseurReac.Taille();
|
|
for (int i=1;i<= ttail;i++)
|
|
{ TorseurReac& torseurReac = tab_torseurReac(i); // pour simplifier
|
|
if (torseurReac.existe_torseur_reac)
|
|
{// tout d'abord l'affichage de l'entête
|
|
if (torseurReac.bloque_ou_CLL)
|
|
// cas où le torseur provient d'une condition ddl bloquée
|
|
{DdlLim& tabBloq_i = tabBloq(*(ttorBloq(i).begin())); // pour simplifier (on ne prend que le
|
|
// premier des bloqués), tous les autres ont le même nom de maillage et de ref
|
|
sort << "\n";
|
|
if (tabBloq_i.NomMaillage() != NULL)
|
|
sort << " nom_maillage " << *(tabBloq_i.NomMaillage());
|
|
sort << " nom_ref " << tabBloq_i.NomRef()
|
|
<< "\n F= ";
|
|
}
|
|
else
|
|
// cas où le torseur provient d'une condition CLL
|
|
{I_O_Condilineaire& iocondiline_i = tab_iocondiline((*(ttorCLL(i).begin())).un); // pour simplifier
|
|
sort << "\n";
|
|
if (iocondiline_i.NomMaillage() != NULL)
|
|
// cas où on considère les noms de maillage
|
|
{ int num_ref = (*(ttorCLL(i).begin())).deux; // pour simplifier
|
|
if (num_ref == 1)
|
|
{// cas d'une référence principale de CLL
|
|
const string& nom_maillage = *(iocondiline_i.NomMaillage());
|
|
sort << " nom_maillage " << nom_maillage
|
|
<< " nom_ref " << iocondiline_i.NomRef() << "_CLL ";
|
|
}
|
|
else
|
|
{// cas d'une référence associé
|
|
// on fait (*(ttorCLL(i).begin())).deux - 1) car ttorCLL contient l'ensemble des refs, y compris
|
|
// la ref principale, et ReferenceAssociees() ne ramène que les ref associés, donc il faut retirer 1
|
|
// qui correspond à la référence principale
|
|
//debug
|
|
//cout << "\n (*(ttorCLL(i).begin())).deux= " << (*(ttorCLL(i).begin())).deux << endl ;
|
|
//fin debug
|
|
const string& nom_maillage = iocondiline_i.NomMaillageAssociees()((*(ttorCLL(i).begin())).deux - 1);
|
|
sort << " nom_maillage " << nom_maillage
|
|
<< " nom_ref " << iocondiline_i.ReferenceAssociees()((*(ttorCLL(i).begin())).deux - 1)
|
|
<< "_CLL ";
|
|
}
|
|
}
|
|
else
|
|
{// cas où on ne considère pas les noms de maillage
|
|
int num_ref = (*(ttorCLL(i).begin())).deux; // pour simplifier
|
|
if (num_ref == 1)
|
|
// cas d'une référence principale de CLL
|
|
{ sort << " nom_ref " << iocondiline_i.NomRef() << "_CLL "; }
|
|
else
|
|
// cas d'une référence associé
|
|
// on fait (*(ttorCLL(i).begin())).deux - 1) car ttorCLL contient l'ensemble des refs, y compris
|
|
// la ref principale, et ReferenceAssociees() ne ramène que les ref associés, donc il faut retirer 1
|
|
// qui correspond à la référence principale
|
|
{ sort << " nom_ref " << iocondiline_i.ReferenceAssociees()((*(ttorCLL(i).begin())).deux - 1)
|
|
<< "_CLL ";
|
|
};
|
|
};
|
|
sort << "\n F= ";
|
|
};
|
|
// et maintenant l'affichage des infos
|
|
torseurReac.resultante.Affiche(sort,ParaGlob::NbdigdoCA());
|
|
switch (dima)
|
|
{case 1: break; // pas de moment en dimension 1
|
|
case 2: sort << "\n M=" << setprecision(ParaGlob::NbdigdoCA())
|
|
<< torseurReac.moment(1); // la première composante est le moment
|
|
break;
|
|
case 3: sort << "\n M=";
|
|
torseurReac.moment.Affiche(sort,ParaGlob::NbdigdoCA());
|
|
break;
|
|
};
|
|
};
|
|
};
|
|
// sortie des réactions dues aux conditions linéaires
|
|
sort << "\n\n\n==========================================================================";
|
|
sort << "\n 3) les reactions dues aux conditions lineaires ";
|
|
sort << "\n==========================================================================\n";
|
|
|
|
// on balaie le tableau de reaction_CLin
|
|
// *** on change de signe à la réaction car on veut l'extérieur sur les noeuds et non le contraire
|
|
// non, j'ai l'impression qu'il ne faut pas ici changer de signe ??? à voir par la suite en fonction des résultats
|
|
// si finalement ??
|
|
int reaction_CLinTaille = reaction_CLin.Taille();
|
|
for (int i= 1; i<= reaction_CLinTaille;i++)
|
|
{ sort << "\ncas assemb " << reaction_CLin(i).casAss
|
|
<< " maillage " << reaction_CLin(i).numMail <<", noeud " <<reaction_CLin(i).numNoeud
|
|
<< ", ddl = " << reaction_CLin(i).ddl.Nom() << ", valeur = " << (-reaction_CLin(i).ddl.Valeur()) ;
|
|
// << ", ddl = " << reaction_CLin(i).ddl.Nom() << ", valeur = " << (reaction_CLin(i).ddl.Valeur()) ;
|
|
};
|
|
// l'entete
|
|
sort << "\n==========================================================================";
|
|
sort << "\n 4) sortie sous forme de force des efforts de l\'exterieur sur les noeuds ";
|
|
sort << "\n==========================================================================";
|
|
sort << "\n les reactions sont ordonnees et sous forme de vecteurs avec 3 composantes \n ";
|
|
|
|
// on balaie le tableau de reaction
|
|
// *** on change de signe à la réaction car on veut l'extérieur sur les noeuds et non
|
|
// le contraire nb_maillage
|
|
{Tableau <list <DeuxEntiers > > tab_indi(nb_maillage); // un tableau de travail
|
|
for (int i= 1; i<= reactionTaille;i++) // on remplit le tableau d'adressage indirecte
|
|
tab_indi(reaction(i).numMail).push_back(DeuxEntiers(i,reaction(i).numNoeud));
|
|
// on trie et on ordonne
|
|
for (int i=1;i<=nb_maillage;i++)
|
|
{ list <DeuxEntiers >& indica = (tab_indi(i)); // pour simplifier
|
|
indica.sort(); // ordonne en fonction du numéro de noeud
|
|
list <DeuxEntiers >::iterator ili,ilifin=indica.end();
|
|
// --- tout d'abord on sort une ref sur la liste des noeuds en réaction au cas ou
|
|
sort << "\n # pour information la ref des noeuds concernes\n ";
|
|
sort << "\n # nom_mail= "<<lesMail->NomMaillage(i)
|
|
<<"\n# N_list_noe_en_react ";
|
|
int compteur=0; int total_force=0;
|
|
for (ili=indica.begin();ili != ilifin;ili++)
|
|
// là on suit la progression des numéros de noeuds
|
|
{ ReactStoc& rea = reaction((*ili).un);
|
|
int num_noeud = (*ili).deux; // le noeud considéré
|
|
bool sortie_valide=false; // la sortie est validée ou non
|
|
while (num_noeud == (*ili).deux)
|
|
{switch (rea.ddl.Id_nom()) // on regarde les ddl
|
|
{ case X1 : sortie_valide=true;break;
|
|
case X2 : sortie_valide=true;break;
|
|
case X3 : sortie_valide=true;break;
|
|
default: break;
|
|
};
|
|
ili++;
|
|
};
|
|
// arrivée ici il y a une incrémentation de trop, on revient en arrière
|
|
ili--;
|
|
if (sortie_valide)
|
|
{ total_force++;
|
|
sort << num_noeud << " ";compteur++;
|
|
if (compteur > 20) {sort << "\n"; compteur=0;};
|
|
};
|
|
};
|
|
|
|
// --- maintenant on sort les forces
|
|
sort << "\n\n # --- les (" <<total_force<<") forces \n";
|
|
for (ili=indica.begin();ili != ilifin;ili++)
|
|
// là on suit la progression des numéros de noeuds
|
|
{
|
|
ReactStoc& rea = reaction((*ili).un);
|
|
int num_noeud = (*ili).deux; // le noeud considéré
|
|
Coordonnee3 force; // la force initialisée à 0.
|
|
bool sortie_valide=false; // la sortie est validée ou non
|
|
while (num_noeud == (*ili).deux)
|
|
{switch (rea.ddl.Id_nom()) // on regarde les ddl
|
|
{ case X1 : force(1)=rea.ddl.Valeur();sortie_valide=true;break;
|
|
case X2 : force(2)=rea.ddl.Valeur();sortie_valide=true;break;
|
|
case X3 : force(3)=rea.ddl.Valeur();sortie_valide=true;break;
|
|
default: break;
|
|
};
|
|
ili++;
|
|
if (ili != ilifin)
|
|
rea = reaction((*ili).un);
|
|
};
|
|
// arrivée ici il y a une incrémentation de trop, on revient en arrière
|
|
ili--;
|
|
if (sortie_valide)
|
|
{ sort << num_noeud << " " ;
|
|
force.Affiche(sort,ParaGlob::NbdigdoCA());
|
|
sort <<"\n";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// mise en place de condition externes lineaires
|
|
// expression de la raideur et du second membre dans un nouveau repere
|
|
// ramène si oui ou non, il y a eu un changement effectué
|
|
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
|
|
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
|
|
bool LesCondLim::CoLinCHrepere_ext(Mat_abstraite & matglob,Vecteur& vecglob
|
|
,const Tableau <Condilineaire>& tab,const Nb_assemb& nb_casAssemb,Vecteur* vec2)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return false ;
|
|
#endif
|
|
|
|
tempsCLL.Mise_en_route_du_comptage(); // temps cpu
|
|
|
|
// on boucle sur le tableau et pour chaque element on impose une condition lineaire
|
|
int tabTaille = tab.Taille();
|
|
bool modification = false; // init du retour
|
|
for (int i=1;i<= tabTaille; i++)
|
|
{Condilineaire& condi = tab(i);
|
|
// calcul des pointeurs d'assemblage
|
|
condi.ConditionPourPointeursAssemblage(nb_casAssemb);
|
|
// application de la condition
|
|
condlim(nb_casAssemb.n).CondlineaireCHRepere
|
|
( matglob,vecglob,tab(i).Pt_t(),tab(i).Val(),tab(i).Beta(),vec2);
|
|
modification=true;
|
|
};
|
|
// affichage éventuelle de la matrice de raideur et du second membre
|
|
if ((ParaGlob::NiveauImpression() >= 10) && (tabTaille != 0))
|
|
{ string entete = " affichage de la matrice apres changement de repere du aux conditions limites externes (ex contact)";
|
|
matglob.Affichage_ecran(entete);
|
|
entete = " affichage du second membre apres changement de repere du aux conditions limites externes (ex contact) ";
|
|
vecglob.Affichage_ecran(entete);
|
|
};
|
|
tempsCLL.Arret_du_comptage(); // temps cpu
|
|
// retour du fait qu'il y a eu ou non une modification faite
|
|
return modification;
|
|
};
|
|
|
|
// mise en place de condition externe lineaires en une opération
|
|
// retour de la raideur et du second membre sans changement de repere
|
|
// ramène si oui ou non, il y a eu un changement effectué
|
|
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
|
|
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
|
|
bool LesCondLim::CoLinUneOpe_ext(Mat_abstraite & matglob,Vecteur& vecglob
|
|
,const Tableau <Condilineaire>& tab
|
|
,const Nb_assemb& nb_casAssemb,Vecteur* vec2)
|
|
{
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
|
|
if (ParaGlob::Monde()->rank() != 0)
|
|
return false;
|
|
#endif
|
|
|
|
tempsCLL.Mise_en_route_du_comptage(); // temps cpu
|
|
|
|
// on boucle sur le tableau et pour chaque element on impose une condition lineaire
|
|
int tabTaille = tab.Taille();
|
|
bool modification = false; // init du retour
|
|
for (int i=1;i<= tabTaille; i++)
|
|
{Condilineaire& condi = tab(i);
|
|
// calcul des pointeurs d'assemblage
|
|
condi.ConditionPourPointeursAssemblage(nb_casAssemb);
|
|
// application d'une condition linéaire seule, avec en retour, la situation de la condition linéaire
|
|
// imposée, ramené dans le repère initial
|
|
condlim(nb_casAssemb.n).CondiLineaireImposeComplet
|
|
( matglob,vecglob,tab(i).Pt_t(),tab(i).Val(),tab(i).Beta(),vec2);
|
|
modification=true;
|
|
};
|
|
// affichage éventuelle de la matrice de raideur et du second membre
|
|
if ((ParaGlob::NiveauImpression() >= 10) && (tabTaille != 0))
|
|
{ string entete = " affichage de la matrice apres application CLL externes (ex contact) ";
|
|
matglob.Affichage_ecran(entete);
|
|
entete = " affichage du second membre apres apres application CLL externes (ex contact) ";
|
|
vecglob.Affichage_ecran(entete);
|
|
};
|
|
tempsCLL.Arret_du_comptage(); // temps cpu
|
|
// retour du fait qu'il y a eu ou non une modification faite
|
|
return modification;
|
|
};
|
|
|
|
|
|
//initialisation, mise a zero des sauvegarde
|
|
void LesCondLim::InitSauve(const Nb_assemb& nb_casAssemb)
|
|
{ condlim(nb_casAssemb.n).EffaceSauvegarde(); // blocages : second membre et matrice,
|
|
condlim(nb_casAssemb.n).EffaceCoLin(); // conditions lineaires
|
|
// puis les torseurs de réactions
|
|
int taille = tab_torseurReac.Taille();
|
|
for (int i=1; i<= taille; i++)
|
|
if (tab_torseurReac(i).existe_torseur_reac)
|
|
tab_torseurReac(i).Zero_init_torseur();
|
|
};
|
|
|
|
//----- lecture écriture dans base info -----
|
|
// le cas d'assemblage n'est pas sauvegardé, car ce n'est pas une variable
|
|
// qui appartient réellement à la classe
|
|
// cas donne le niveau de la récupération
|
|
// = 1 : on récupère tout
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
void LesCondLim::Lecture_base_info(ifstream& ent,const int cas,LesReferences& ,LesCourbes1D&
|
|
,LesFonctions_nD& lesFonctionsnD)
|
|
{ // les conditions linéaires qui varies par exemples dues au contact sont stockées
|
|
// autre part, dans LesContacts par exemple
|
|
string toto;
|
|
switch (cas)
|
|
{ case 1:
|
|
{ cout << "== lecture des conditions limites \n";
|
|
// lecture du type et vérification
|
|
string nomtype;
|
|
ent >> nomtype;
|
|
if (nomtype != "****LesCondLim")
|
|
Sortie(1);
|
|
// lecture des différents tableaux
|
|
ent >> toto >> tabBloq >> toto >> tabInit
|
|
>> toto >> tab_iocondiline >> toto >> reaction >> toto >> reaction_CLin;
|
|
// dimensionnement du tableau des torseurs résultants
|
|
LesCondLim::DimensionneTorseurs();
|
|
break;
|
|
}
|
|
case 2:
|
|
{// on lit les grandeurs relatives aux réactions
|
|
ent >> toto;
|
|
reaction.Entree(ent);
|
|
ent >> toto;
|
|
reaction_CLin.Entree(ent);
|
|
// lectue des temps cpu de l'algo:
|
|
ent >> toto >> tempsCL;
|
|
ent >> toto >> tempsCLL;
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n **** erreur !! cas non prevu: cas = " << cas
|
|
<< "\n LesCondLim::Lecture_base_info(...";
|
|
Sortie(1);
|
|
}
|
|
};
|
|
// on met à jour le tableau map_reaction
|
|
// map_reaction.erase(map_reaction.begin(),map_reaction.end());
|
|
// int tail_reaction=reaction.Taille();
|
|
// for (int j=1; j<=tail_reaction; j++)
|
|
// { map_reaction["mail"+ChangeEntierSTring(reaction(j).numMail)
|
|
// +"noeud"+ChangeEntierSTring(reaction(j).numNoeud)].push_back(&(reaction(j)));
|
|
// };
|
|
};
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void LesCondLim::Ecriture_base_info(ofstream& sort,const int cas)
|
|
{ // les conditions linéaires qui varies par exemples dues au contact sont stockées
|
|
// autre part, dans LesContacts par exemple
|
|
switch (cas)
|
|
{ case 1:
|
|
{// écriture du type
|
|
sort << "\n ****LesCondLim \n";
|
|
// écriture des différents tableaux
|
|
sort << " blocage " << tabBloq;
|
|
sort << " initialisation " << tabInit;
|
|
sort << " CLL_en_entree " << tab_iocondiline;
|
|
sort << " reactions " << reaction;
|
|
sort << " reac_CLineaire " << reaction_CLin << " ";
|
|
break;
|
|
}
|
|
case 2:
|
|
{// on sort les grandeurs relatives aux réactions
|
|
// en fait les réactions sont également sauvé aux noeuds mais peut-être que ce sera utile
|
|
// d'avoir ici le type réaction stocké ?? donc on laisse
|
|
sort << " reac_ddl_bloque ";
|
|
reaction.Sortir(sort);
|
|
sort << " reac_CLineaire ";
|
|
reaction_CLin.Sortir(sort); sort << " ";
|
|
// écriture des temps cpu de l'algo:
|
|
sort << "\n tps_cpu_CL " << tempsCL;
|
|
sort << "\n tps_cpu_CLL " << tempsCLL;
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n **** erreur !! cas non prevu: cas = " << cas
|
|
<< "\n LesCondLim::Ecriture_base_info(...";
|
|
Sortie(1);
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|