Herezh_dev/herezh_pp/Maillage/Noeud.cc

1865 lines
73 KiB
C++
Executable file

// FICHIER : Noeud.cp
// CLASSE : Noeud
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "Noeud.h"
#include "Util.h"
#include <iomanip>
#include "TypeQuelconqueParticulier.h"
// variable globale à la classe
short int Noeud::posi_type_quel = 1;
short int Noeud::posi_ddletendu = 1;
list <Tableau <int > > Noeud::list_tab_enum;
List_io <Tableau <int > > Noeud::list_tab_posi_actif;
List_io <Tableau <int > > Noeud::list_tab_typeQuelconque; // au début il n'y a rien dans la liste
List_io <Tableau <int > > Noeud::list_tab_ddletendu; // au début il n'y a rien dans la liste
// ------ méthode concernant laclass Posi_ddl_noeud ----------------
// surcharge de l'operateur de lecture
istream & operator >> ( istream & ent, Posi_ddl_noeud & a)
{ // lecture du type et vérification
string nomtype; ent >> nomtype;
if (nomtype != "Posi_ddl_noeud")
{ Sortie(1);
return ent;
}
// lecture des data
ent >> a.nb_maillage >> a.nb_noeud >> a.enu ;
return ent;
};
// surcharge de l'operateur d'ecriture
ostream & operator << ( ostream & sort,const Posi_ddl_noeud & a)
{ // écriture du type
sort << " Posi_ddl_noeud " ;
// les data
sort << a.nb_maillage << " "<< a.nb_noeud << " "<< a.enu << " ";
return sort;
};
// Affiche les donnees liees au noeud
void Posi_ddl_noeud::Affiche (ofstream& sort) const
{ // les data
sort << " Posi_ddl_noeud " ;
sort << nb_maillage << " "<< nb_noeud << " "<< enu << " ";
};
// ------ fin des méthodes concernant la sous_class Posi_ddl_noeud ----------------
//=========================================================================
// Fait appel au constructeur par defaut de Coordonnee et de Tableau<Ddl>
// Constructeur se servant eventuellement d'un numero d'identification
Noeud::Noeud (int num_id,int num_M):
tab_0(),tab_ddl(),tab_tdt(),coord1()
,tab_var_actives(),tab_actif(),pos_enum(list_tab_enum.end())
,posiAssemb(),baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,t_enum_s(),tab_type_quel(),update_type_quel(),nbTypeQ_update(0)
,tab_nb_Elem(),pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = NULL;
coord2 = NULL;
num_Mail = num_M;
posi_type_quel = 1;
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur utile quand seuls le numero d'identification et la
// dimension de l'espace sont connus
Noeud::Noeud (int num_id,int dimension,int num_M):
tab_0(),tab_ddl(),tab_tdt(),coord1(),tab_var_actives(),tab_actif()
,pos_enum(list_tab_enum.end())
,posiAssemb(),baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,t_enum_s(),tab_type_quel()
,update_type_quel(),nbTypeQ_update(0),tab_nb_Elem()
,pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = new Coordonnee(dimension);
coord2 = NULL;
num_Mail = num_M;
posi_type_quel = 1;
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur pour un noeud dont le numero et les coordonnees initiales
// sont connus
Noeud::Noeud (int num_id,const Coordonnee& c0,int num_M):
tab_0(),tab_ddl(),tab_tdt(),coord1(),tab_var_actives(),tab_actif()
,pos_enum(list_tab_enum.end())
,posiAssemb(),baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,t_enum_s(),tab_type_quel()
,update_type_quel(),nbTypeQ_update(0),tab_nb_Elem()
,pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = new Coordonnee(c0);
coord2 = NULL;
num_Mail = num_M;
posi_type_quel = 1;
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur fonction d'un numero d'identification, des coordonnees
// initiales et du tableau des degres de liberte
// les ddl t=0 sont initialises avec les valeurs du tableaux
// sauf coord0 qui est initialise avec c0
// par defaut les tableaux de ddl a 0 et t sont initialises mais pas
// a t+dt
Noeud::Noeud (int num_id,const Coordonnee& c0,const Tableau<Ddl>& tab,int num_M):
tab_ddl(tab),tab_0(tab_ddl.Taille()),tab_tdt(),coord1()
,tab_var_actives(),tab_actif()
,pos_enum(list_tab_enum.end())
,baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,posiAssemb(),t_enum_s(),tab_type_quel()
,update_type_quel(),nbTypeQ_update(0),tab_nb_Elem()
,pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = NULL;
coord2 = NULL;
num_Mail = num_M;
// init de tab_0
for (int i=1;i<=tab_0.Taille();i++)
tab_0(i) = tab_ddl(i).Valeur();
// cas ou l'on est en coordonnees entrainees
if ( Existe(X1) != 0)
{ Liaison_t(Existe(X1));
*coord0 = c0;
}
// cas ou les ddl sont separes des coordonnees
else
{ coord0 = new Coordonnee(c0);
};
posi_type_quel = 1;
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur fonction d'un numero d'identification, des coordonnees
// initiales, a un instant t, et du tableau des degres de liberte
// les ddl t=0 sont initialises avec les valeurs du tableaux
// par defaut les tableaux de ddl a 0 et t sont initialises mais pas
// a t+dt
// les ddl corespondant a Xi sont ajoute s'ils n'existaient pas
// et il y a automatiquement liaison entre ddl et coordonnées
Noeud::Noeud (int num_id,const Coordonnee& c0,const Coordonnee& c1,const Tableau<Ddl>& tab,int num_M):
tab_ddl(tab),tab_0(tab_ddl.Taille()),tab_tdt(),coord1(c1.Dimension())
,tab_var_actives(),tab_actif()
,pos_enum(list_tab_enum.end())
,posiAssemb(),baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,t_enum_s(),tab_type_quel()
,update_type_quel(),nbTypeQ_update(0),tab_nb_Elem()
,pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = NULL;
coord2 = NULL;
num_Mail = num_M;
// init de tab_0
#ifdef MISE_AU_POINT // vérification de la dimension de tab_ddl
if (tab.Taille() < c1.Dimension())
{ cout << "\nErreur : dans le constructeur de noeud : ";
cout << " Noeud (int num_id,Coordonnee& c0,Coordonnee& c1,"
<< "const Tableau<Ddl>& tab,int num_M)\n";
Sortie(1);
};
#endif
for (int i=1;i<=tab_0.Taille();i++)
tab_0(i) = tab_ddl(i).Valeur();
// cas ou l'on est en coordonnees entrainees
int posi_X1=0; // init
if ( Existe(X1) == 0)
{ // le ddl X1 n'existe pas on le rajoute
int an = tab_ddl.Taille();
tab_ddl.Change_taille(an+Dimension());
tab_0.Change_taille(an+Dimension());
for (int jj=1;jj<=Dimension();jj++)
tab_ddl(an+jj).Change_nom(Enum_ddl(jj));
posi_X1 = an+1; // c'est la position du ddl X1
}
else // sinon il existe on récupère sa position
posi_X1 = Existe(X1) ;
// on effectue la liaison ddl/ deplacement
Liaison_t(posi_X1); // (Existe(X1));
*coord0 = c0;
for (int j=1;j<= Dimension();j++)
*(coord1(j)) = c1(j);
posi_type_quel = 1;
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur pour un noeud dont le numero, les coordonnees initiales, aux
// instant t et t+dt ainsi que le tableau des degres de liberte sont connus
// comme les coordonnées à t+dt sont données cela signifie qu'ils sont des
// degrés de liberté
// les ddl corespondant a Xi sont ajoute s'ils n'existaient pas
// et il y a automatiquement liaison entre ddl et coordonnées
Noeud::Noeud (int num_id,const Coordonnee& c0,const Coordonnee& c1,const Coordonnee& c2,
const Tableau<Ddl>& tab,int num_M):
tab_ddl(tab),tab_0(tab.Taille()),tab_tdt(tab.Taille()),coord1(c1.Dimension())
,tab_var_actives(),tab_actif()
,pos_enum(list_tab_enum.end())
,posiAssemb(),baseB(NULL),baseB_t(NULL),baseB_0(NULL)
,t_enum_s(),tab_type_quel()
,update_type_quel(),nbTypeQ_update(0),tab_nb_Elem()
,pos_Quelconque(list_tab_typeQuelconque.end())
,pos_ddletendu(list_tab_ddletendu.end())
,nbddletendu_update(0),tab_ddletendu(0),update_ddletendu(0)
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=num_id;
coord0 = NULL;
coord2 = NULL;
num_Mail = num_M;
// init de tab_0
#ifdef MISE_AU_POINT // vérification de la dimension de tab_ddl
if (tab.Taille() < c1.Dimension())
{ cout << "\nErreur : dans le constructeur de noeud : ";
cout << " Noeud (int num_id,Coordonnee& c0,Coordonnee& c1,Coordonnee& c2,"
<< "const Tableau<Ddl>& tab,int num_M)\n";
Sortie(1);
};
#endif
int tab0Taille = tab_0.Taille();
for (int i=1;i<=tab0Taille;i++)
tab_0(i) = tab_ddl(i).Valeur();
// on est en coordonnees entrainees, on vérifie que les ddl XI
// sont présent sinon on rajoute
int posi_X1=0; // init
if ( Existe(X1) == 0)
{ // le ddl X1 n'existe pas on rajoute les XI
int an = tab_ddl.Taille();
tab_ddl.Change_taille(an+Dimension());
tab_0.Change_taille(an+Dimension());
tab_tdt.Change_taille(an+Dimension());
for (int jj=1;jj<=Dimension();jj++)
tab_ddl(an+jj).Change_nom(Enum_ddl(jj));
posi_X1 = an+1; // c'est la position du ddl X1
}
else // sinon il existe on récupère sa position
posi_X1 = Existe(X1) ;
// on effectue la liaison ddl/ deplacement, donc la mémoire
// des coordonnées est positionnée dans le tableau de ddl
Liaison_tdt(posi_X1); // (Existe(X1));
// Liaison_tdt(Existe(X1));
*coord0 = c0; // recopie des valeurs
*coord2 = c2; // """"
for (int j=1;j<= Dimension();j++)
*(coord1(j)) = c1(j);
posi_type_quel = 1;
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
MiseAjourEnum(); // mise en place de l'adressage directe
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
// Constructeur de copie
Noeud::Noeud (const Noeud& nd):
tab_0(nd.tab_0),tab_ddl(nd.tab_ddl),tab_tdt(nd.tab_tdt),coord1()
,tab_var_actives(nd.tab_var_actives),tab_actif(nd.tab_actif)
,pos_enum(nd.pos_enum)
,posiAssemb(nd.posiAssemb),baseB(NULL),baseB_t(NULL) // on définit ensuite la base
,baseB_0(NULL)
,t_enum_s(nd.t_enum_s)
,tab_type_quel(nd.tab_type_quel),update_type_quel(nd.update_type_quel)
,nbTypeQ_update(0),tab_nb_Elem(nd.tab_nb_Elem)
,pos_Quelconque(list_tab_typeQuelconque.end()) // idem ddl étendues
,pos_ddletendu(list_tab_ddletendu.end()) // c'est dans la méthode MiseAjourDdl_etendu, que le pointeur sera mis à jour
,nbddletendu_update(nd.nbddletendu_update)
,tab_ddletendu(nd.tab_ddletendu),update_ddletendu(nd.update_ddletendu)
// pour les liaisons cinématiques: pas de recopie, il s'agit d'un stockage uniquement:
// l'utilisation et la manipulation est à la charge des classes appelantes
,tab_enu_liaison(NULL),tab_ddl_lier(NULL)
{ num_noeud=nd.num_noeud;
coord2 = NULL; // initialisation
num_Mail = nd.num_Mail;
if ( Existe(X1) != 0)
{ coord0 = NULL;
// traitement des liaisons et avec du cas de coord1
if ( tab_tdt.Taille() != 0)
// cas avec les coordonnees a t+dt
//on effectue la liaison ddl/ deplacement
Liaison_tdt(Existe(X1));
else // sinon uniquement à t
Liaison_t(Existe(X1));
}
else
{if (nd.coord0 != NULL)
{coord0 = new Coordonnee(*(nd.coord0));
}
else
{coord0 = NULL;
};
};
// cas d'une base locale éventuelle
if (nd.baseB != NULL)
{baseB = new BaseB(*nd.baseB);};
if (nd.baseB_t != NULL)
{baseB_t = new BaseB(*nd.baseB_t);};
if (nd.baseB_0 != NULL)
{baseB_0 = new BaseB(*nd.baseB_0);};
posi_type_quel = nd.posi_type_quel;
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
// pour les grandeurs quelconques, a priori on les met "non a jour"
// la mise à jour nécessite l'appel explicite à l'ordre de mise à jour
if (update_type_quel.Taille() != 0)
{ int t_typTaille = update_type_quel.Taille();
for (int titq=1;titq<= t_typTaille;titq++) update_type_quel(titq)=0;
};
MiseAjourDdl_etendu(); // cas des ddl étendue
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
};
Noeud::~Noeud()
// Destructeur de Noeud utilisant les destructeurs
// de Coordonnee et de Tableau<Ddl>
{ delete coord0; // le choix de la destruction ou pas de la zone
//mémoire est fait dans coord0
if (coord2 != NULL) delete coord2;
// on n'efface pas le tableau coord2 car s'il existe (c-a-d différent de null) il représente aussi
// des degrés de liberté, donc il se situe au même endroit que les éléments de tab_tdt
// qui lui sera de toute façon détruit par le destructeur automatique
// pour les enum étendus, on utilise la méthode MiseAjourDdl_etendu(), pour que tout soit cohérent
// on commence par supprimer les tableaux ad hoc et ensuite on met à jour
tab_ddletendu.Libere();update_ddletendu.Libere();nbddletendu_update=0;
MiseAjourDdl_etendu();
// idem pour les grandeurs quelconques
tab_type_quel.Libere(); update_type_quel.Libere(); nbTypeQ_update=0;
MiseAjourTypeQuelconque(); // cas des grandeurs quelconques
// dans le cas ou il existe des liaisons cinématiques on supprime les conteneurs
Suppression_tous_liaisons_noeuds();
// cas où il existe une base locale
if (baseB_0 != NULL) delete baseB_0;
if (baseB_t != NULL) delete baseB_t;
if (baseB != NULL) delete baseB;
};
// surcharge de l'operator de lecture, avec typage
istream & operator >> (istream & ent, Noeud & noe)
{ // lecture du type et vérification
string nomType,nom;
ent >> nomType;
if (nomType != "Noeud")
{ Sortie(1);
return ent;
};
// puis le numéro de noeud et le numéro de maillage
ent >> noe.num_noeud >> noe.num_Mail ;
// les liaisons éventuelles
bool test;
ent >> nom >> test; // tab_enu_liaison
if (test)
{ int nb;int toto;
ent >> nb;
if (noe.tab_enu_liaison != NULL)
{noe.tab_enu_liaison->Change_taille(nb);}
else
{noe.tab_enu_liaison = new Tableau <Enum_liaison_noeud>(nb);};
for (int i=1;i<= nb;i++)
{ ent >> nom >> toto >> nom;
(*noe.tab_enu_liaison)(i) = Id_nom_liaison_noeud(nom);
};
}
else
{if (noe.tab_enu_liaison != NULL)
{ delete noe.tab_enu_liaison; noe.tab_enu_liaison = NULL;}
};
ent >> nom >> test; // tab_ddl_lier
if (test)
{ int nb;int toto;
ent >> nb;
if (noe.tab_ddl_lier != NULL)
{noe.tab_ddl_lier->Change_taille(nb);}
else
{noe.tab_ddl_lier = new Tableau <Tableau <Posi_ddl_noeud> >(nb);};
for (int i=1;i<= nb;i++)
ent >> nom >> toto >> (*noe.tab_ddl_lier)(i);
}
else
{if (noe.tab_ddl_lier != NULL)
{ delete noe.tab_ddl_lier; noe.tab_ddl_lier = NULL;}
};
// le tableau des degrés de liberté
ent >> noe.tab_ddl;
// coordonnee initiale on les récupère par défaut
// ensuite on fera la mise à jour
ent >> *(noe.coord0);
ent >> nom >> noe.tab_0; // valeurs a l'instant 0 des ddl
ent >> nom >> noe.tab_tdt; // valeurs a l'instant t+dt des ddl
// les coordonnees a un instant t et tdt sont reconstruit avec
// la mise à jour si nécessaire
noe.MiseAjour();
// vérif si les coordonnees a un instant t+dt existent
// si oui liaison
ent >> nom;
if (nom == "coord2Existe")
noe.Liaison_tdt(noe.Existe(X1));
// ent >> nom >> noe.tab_var_actives; // les numéros des ddl actifs
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
noe.MiseAjourActif();
noe.MiseAjourEnum(); // mise en place de l'adressage directe
// %% cas des types quelconques éventuelles %%
noe.Lecture_grandeurs_quelconque(ent);
// idem pour les ddl_etendu
noe.Lecture_Ddl_etendu(ent);
// cas d'une base locale éventuelle
{int existe_base;
ent >> existe_base;
if (existe_base == 1)
{if (noe.baseB_0 == NULL) {noe.baseB_0=new BaseB();};
ent >> nom >> (*noe.baseB_0);
};
ent >> existe_base;
if (existe_base == 1)
{if (noe.baseB_t == NULL) {noe.baseB_t=new BaseB();};
ent >> nom >> (*noe.baseB_t);
};
ent >> existe_base;
if (existe_base == 1)
{if (noe.baseB == NULL) {noe.baseB=new BaseB();};
ent >> nom >> (*noe.baseB);
};
};
return ent;
};
// surcharge de l'operator d'ecriture avec typage
ostream & operator << (ostream & sort , const Noeud & noe)
{ // le type, le numéro de noeud et le numéro de maillage
sort << "Noeud " << noe.num_noeud << " " << noe.num_Mail ;
// les liaisons éventuelles
if (noe.tab_enu_liaison != NULL)
{ sort << "\n tab_enu_liaison " << 1 << " "; // on signale la présence du tableau
int nb = (noe.tab_enu_liaison)->Taille();
sort << nb << " ";
for (int i=1;i<= nb;i++)
sort << " ass: "<< i << Nom_liaison_noeud((*noe.tab_enu_liaison)(i)) << " ";
}
else
sort << "\n tab_enu_liaison " << 0 << " "; // on signale l'absence du tableau ;
if (noe.tab_ddl_lier != NULL)
{ sort << "\n tab_ddl_lier " << 1 << " "; // on signale la présence du tableau
int nb = (noe.tab_ddl_lier)->Taille();
sort << nb << " ";
for (int i=1;i<= nb;i++)
sort << "\n ass: "<< i << " "<< (*noe.tab_ddl_lier)(i);
}
else
sort << "\n tab_ddl_lier " << 0 << " "; // on signale l'absence du tableau ;
// le tableau des degrés de liberté
sort << noe.tab_ddl;
// coordonnee initiale on les sauvegarde par défaut
// ensuite on fera la mise à jour
sort << *(noe.coord0);
sort << " ddl_a_0 " << noe.tab_0; // valeurs a l'instant 0 des ddl
sort << " ddl_a_tdt " << noe.tab_tdt; // valeurs a l'instant t+dt des ddl
// les coordonnees a un instant t ne sont pas sauvegardées elles seront
// reconstruites si besoin avec la mise à jour
// coordonnee a un instant t+dt on signale son existence
if (noe.coord2 != NULL)
sort << "coord2Existe \n";
else
sort << "pascoord2 \n";
// sort << "ddl_actif " << noe.tab_var_actives; // les numéros des ddl actifs
// %% cas des types quelconques éventuelles %%
noe.Ecriture_grandeurs_quelconque(sort);
// idem pour les ddl_etendu
noe.Ecriture_Ddl_etendu(sort);
// cas d'une base locale éventuelle
if (noe.baseB_0 != NULL)
{sort << "\n 1 base_locale_0: " << (*noe.baseB_0);}
else {sort << "\n 0 base_locale_0: "; };
if (noe.baseB_t != NULL)
{sort << "\n 1 base_locale_t: " << (*noe.baseB_t);}
else {sort << "\n 0 base_locale_t: "; };
if (noe.baseB != NULL)
{sort << "\n 1 base_locale: " << (*noe.baseB);}
else {sort << "\n 0 base_locale: "; };
return sort;
};
// lecture du noeud en mémoire
void Noeud::Lecture(UtilLecture *entreePrinc)
{ int numero;
Coordonnee co(Dimension()); // def d'un tableau de coordonnées
*(entreePrinc->entree) >> numero ;
// lecture brut des coordonnées sans la dimension
co.Lecture(*entreePrinc);
Change_coord0(co); // transmission a noeud
if (numero != num_noeud)
{ cout << " ***ATTENTION dans la lecture du noeud ";
cout << " le numero d identification du noeud attribue par "
<< " le constructeur (" << num_noeud << ") est different de celui lu !!! "
<< " (" << numero << ") "
<< " Noeud::Lecture((UtilLecture *entreePrinc) " << endl ;
};
};
// affichage et definition interactive des commandes
// coor: des coordonnees fixée pour un affichage different pour chaque noeud
void Noeud::Info_commande_Noeud(UtilLecture * entreePrinc,Coordonnee& co,int numero)
{ ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
int dima = ParaGlob::Dimension();
sort << "\n" << setw (6) << numero <<" ";
double sero = 0.;
#ifndef ENLINUX_STREAM
sort.setf(ios_base::scientific);
#else
sort.setf(ios::scientific);
#endif
// sort.setf(ios_base::scientific);
for (int j=1;j<=3;j++)
if (j<=dima)
sort << setw (18) << setprecision(ParaGlob::NbdigdoCA()) <<co(j) << " ";
else
sort << setw (18) << setprecision(ParaGlob::NbdigdoCA()) << sero << " ";
Change_coord0(co); // transmission a noeud
};
// Affiche les donnees liees au noeud
// le niveau différent de 0 permet d'accèder à plus d'info
void Noeud::Affiche (int niveau) const
{ cout << "\n --noeud -- \nNumero : " << num_noeud << ", du maillage: "<< num_Mail << '\n';
// les liaisons éventuelles
if (niveau > 0)
{// les liaisons éventuelles
if (tab_enu_liaison != NULL)
{ cout << "\n tab_enu_liaison " << 1 << " "; // on signale la présence du tableau
int nb = (tab_enu_liaison)->Taille();
cout << nb << " ";
for (int i=1;i<= nb;i++)
cout << " ass: "<< i << Nom_liaison_noeud((*tab_enu_liaison)(i)) << " ";
}
else
cout << "\n tab_enu_liaison " << 0 << " "; // on signale l'absence du tableau ;
if (tab_ddl_lier != NULL)
{ cout << "\n tab_ddl_lier " << 1 << " "; // on signale la présence du tableau
int nb = (tab_ddl_lier)->Taille();
cout << nb << " ";
for (int i=1;i<= nb;i++)
cout << "\n ass: "<< i << " "<< (*tab_ddl_lier)(i);
}
else
cout << "\n tab_ddl_lier " << 0 << " "; // on signale l'absence du tableau ;
};
cout << "Coordonnee(s) initiale(s) du noeud : \n";
coord0->Affiche();
if (coord1.Taille() != 0)
{ cout << "Coordonnee(s) a l'instant t : \n";
Coord1().Affiche();
}
if (coord2 != NULL)
{ cout << "Coordonnee(s) a l'instant t+dt : \n";
coord2->Affiche();
}
cout << "Degre(s) de liberte lie(s) au noeud : \n";
cout << "Taille du tableau : " << tab_ddl.Taille() << " , a 0, a t ( et t+dt ?)\n";
for (int i=1;i<=tab_ddl.Taille();i++)
{ if (tab_0.Taille() != 0) cout << tab_0(i) << " ";
tab_ddl(i).Affiche();
if (tab_tdt.Taille() != 0) cout << tab_tdt(i) << " ";
};
// affichage éventuelle des grandeurs enum étendue stockées au noeud
int tail_tab_ddletendu = tab_ddletendu.Taille();
if (tail_tab_ddletendu != 0)
{cout << "\nddl_etendu: ";
for (int itq=1;itq<=tail_tab_ddletendu;itq++)
{Ddl_etendu& ddlenum = tab_ddletendu(itq);
if (ddlenum.DdlEnumEtendu().Nom_vide())
{ cout << Nom_ddl(ddlenum.DdlEnumEtendu().Enum()) ;}
else
{ cout << ddlenum.DdlEnumEtendu().Nom() ;};
cout << " " << ddlenum.ConstValeur()<< " ";
};
};
// affichage éventuelle des grandeurs quelconques stockées au noeud
int tail_tab_type_quel = tab_type_quel.Taille();
if (tail_tab_type_quel != 0)
{cout << "\nddl_quelconque: ";
for (int itq=1;itq<=tail_tab_type_quel;itq++)
{cout << tab_type_quel(itq).EnuTypeQuelconque().NomPlein() << " "
<< *(tab_type_quel(itq).Grandeur_pointee()) << " \n";
};
};
// cas d'une base locale éventuelle
if (baseB_0 != NULL)
{cout << "\n base_locale_0: " << (*baseB_0);}
if (baseB_t != NULL)
{cout << "\n base_locale_t: " << (*baseB_t);}
if (baseB != NULL)
{cout << "\n base_locale: " << (*baseB);}
// dans le cas ou la variable niveau est plus grande que 0 on affiche plus d'information
if (niveau > 0)
{ cout << "\n le tableau d'adressage directe " << (* pos_enum) << endl;
};
cout << "-- fin noeud --\n";
};
// Affiche les donnees liees au noeud
void Noeud::Affiche (ofstream& sort) const
{ // l'entete
sort << " Numero : [ " << num_noeud
<< " ]****/////, du maillage: < "<< num_Mail
<< " > ";
// les liaisons éventuelles
if (tab_enu_liaison != NULL)
{ int nb = (tab_enu_liaison)->Taille();
sort << nb << " liaison(s) (ass,type): ";
for (int i=1;i<= nb;i++)
sort << i << " " << Nom_liaison_noeud((*tab_enu_liaison)(i)) << " ";
};
if (tab_ddl_lier != NULL)
{ cout << "\n tab_ddl_lier " << 1 << " "; // on signale la présence du tableau
int nb = (tab_ddl_lier)->Taille();
sort << nb << " , ddl_lie(s) (ass,maill,noe,enu): ";
for (int i=1;i<= nb;i++)
sort << i << " "<< (*tab_ddl_lier)(i);
};
sort << " =======================\n";
// les coordonnees
sort << "Coord t=0 : "; coord0->Affiche(sort,16); sort << ", " ;
if (coord1.Taille() != 0)
{ sort << "\nCoord a t : "; Coord1().Affiche(sort,16); sort << ", " ;};
if (coord2 != NULL)
{sort << "\nCoord a t+dt: " ; coord2->Affiche(sort,16); sort << ", " ;};
// les ddl et variations
sort << '\n' << tab_ddl.Taille() << " Ddl a ";
if (tab_0.Taille() != 0) sort << " <<0>> ";
sort << " <<t>> ( et variation) ";
if (tab_tdt.Taille() != 0) sort << " <<tdt>> (et variation) : \n";
for (int i=1;i<=tab_ddl.Taille();i++)
{ sort << tab_ddl(i).Nom() << " = "; // le nom
if (tab_0.Taille() != 0) sort << setw (16) << tab_0(i) << ", "; // val a t=0
sort << setw (16) << tab_ddl(i).Valeur() << " "; // val a t
if (tab_0.Taille() != 0)
sort << "( " << setw (16) << (tab_ddl(i).Valeur() - tab_0(i)) << "), "; // delta 0 t
if (tab_tdt.Taille() != 0) sort << setw (16) << tab_tdt(i) << " "; // val a tdt
if ((tab_0.Taille() != 0)&&(tab_tdt.Taille() != 0))
sort << "(" << setw (16) << (tab_tdt(i) - tab_0(i)) << " );"; // deltat 0 tdt
// decalage pour la ligne suivante
sort << "\n";
};
// affichage éventuelle des grandeurs quelconques stockées au noeud
int tail_tab_type_quel = tab_type_quel.Taille();
for (int itq=1;itq<=tail_tab_type_quel;itq++)
{sort << (tab_type_quel(itq).EnuTypeQuelconque()).NomPlein() << " "
<< *(tab_type_quel(itq).Grandeur_pointee()) << " \n";
};
// cas d'une base locale éventuelle
if (baseB_0 != NULL)
{sort << "\n base_locale_0: " << (*baseB_0);}
if (baseB_t != NULL)
{sort << "\n base_locale_t: " << (*baseB_t);}
if (baseB != NULL)
{sort << "\n base_locale: " << (*baseB);}
sort << "\n";
};
// insert des coordonnees coord1 si elles n'existent pas encore
// permet de définir des coordonnées à t, dans ce cas des ddl XI sont inclus
// et sont mis inactif par défaut
void Noeud::Insert_coord1(const Coordonnee& nouveau_coord1)
{ // si les coordonnées n'existe pas encore il faut les créer
if ( Existe(X1) == 0)
{ // le ddl X1 n'existe pas on le rajoute
int an = tab_ddl.Taille();
tab_ddl.Change_taille(an+Dimension());
tab_0.Change_taille(an+Dimension());
int dim = Dimension();
for (int jj=1;jj<=dim;jj++)
tab_ddl(an+jj).Change_nom(Enum_ddl(jj));
// on effectue la liaison ddl/ deplacement
Liaison_t(Existe(X1));
// on met les XI hors service
for (int i = 1; i<=dim; i++)
tab_ddl(an+i).Met_hors_service();
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
MiseAjourEnum(); // mise en place de l'adressage directe
};
// copie des ddl
for (int i=1;i<=coord1.Taille();i++)
*(coord1(i)) = nouveau_coord1(i);
};
// idem mais sans paramètre indique que l'on initialise aux coordonnées à t=0
// s'ils n'existent pas, sinon on ne fait rien
void Noeud::Insert_coord1()
{ // si les coordonnées n'existe pas encore il faut les créer
if ( Existe(X1) == 0)
{ // le ddl X1 n'existe pas on le rajoute
int an = tab_ddl.Taille();
tab_ddl.Change_taille(an+Dimension());
tab_0.Change_taille(an+Dimension());
int dim = Dimension();
for (int jj=1;jj<=dim;jj++)
tab_ddl(an+jj).Change_nom(Enum_ddl(jj));
// on effectue la liaison ddl/ deplacement
// donc le ddl X1 se situe maintenant à la place an+1 dans le tableau
// des ddl
Liaison_t(an+1); //(Existe(X1));
// on met les XI hors service
for (int i = 1; i<=dim; i++)
tab_ddl(an+i).Met_hors_service();
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
MiseAjourEnum(); // mise en place de l'adressage directe
// copie des ddl
for (int i=1;i<=coord1.Taille();i++)
*(coord1(i)) = (*coord0)(i);
};
};
// Modifie les valeurs des coordonnees coord1
void Noeud::Change_coord1(const Coordonnee& nouveau_coord1)
{ // si les coordonnées n'existe pas encore il faudrait les créer avant de les utiliser
#ifdef MISE_AU_POINT // vérif
if ((nouveau_coord1.Dimension() != Dimension()) ||
(coord1.Taille() == 0) || ((coord1(1)) == NULL))
{ cout << "\nErreur : dans l'affectation de coordonnées à t, elles ne sont pas définies !\n";
cout << " Noeud::Change_coord1(Coordonnee& nouveau_coord1)\n";
Sortie(1);
}
#endif
for (int i=1;i<=coord1.Taille();i++)
*(coord1(i)) = nouveau_coord1(i);
};
// Retourne les coordonnees coord1 du noeud
// uniquement pour la lecture
//Coordonnee Noeud::Coord1 ()
// { int nbcoo = coord1.Taille();
// Coordonnee coo(nbcoo);
// for (int i=1;i<=nbcoo;i++)
// coo(i) = *(coord1(i));
// return coo;
// };
// Retourne le nombre de degres de liberte du noeud
// qui sont actuellement actifs
//int Noeud::Nombre_var_ddl_actives ()
// { int total = 0;
// int imax = tab_ddl.Taille();
// for (int i=1;i<=imax;i++)
// if (tab_ddl(i).Service()) total ++;
// return total;
// };
// retourne la liste de tous les types de ddl actuellement utilisé
// par le noeud (actif ou non)
List_io <Enum_ddl> Noeud::Les_type_de_ddl(bool)
{ int tail = tab_ddl.Taille();
List_io <Enum_ddl> tab_enum;
for (int i= 1;i<= tail;i++)
tab_enum.push_back(tab_ddl(i).Id_nom());
return tab_enum;
};
// retourne la liste de tous les Ddl_enum_etendu disponible
List_io <Ddl_enum_etendu> Noeud::Les_type_de_ddl_etendu(bool)
{ int tail = tab_ddletendu.Taille();
List_io <Ddl_enum_etendu> tab_enum_etendu;
for (int i= 1;i<= tail;i++)
tab_enum_etendu.push_back(tab_ddletendu(i).Const_DdlEnumEtendu());
return tab_enum_etendu;
};
// retourne la liste de tous les TypeQuelconque disponibles
List_io <TypeQuelconque> Noeud::Les_TypeQuelconque(bool )
{ int tail = tab_type_quel.Taille();
List_io <TypeQuelconque> tab_TypeQuelconque;
for (int i= 1;i<= tail;i++)
tab_TypeQuelconque.push_back(tab_type_quel(i));
return tab_TypeQuelconque;
};
// récupération d'une liste d'info
// le tableau de retour à la taille de li_enu_scal et contient
// les valeurs correspondantes aux Ddl_enum_etendu stockées au noeud
// en fait ici on cumule les ddl pur "et" les ddl_étendue,
// li_quelc : est modifié par les valeurs contenues au noeud
Tableau <double> Noeud::Valeur_multi_et_Tensorielle
(const List_io <Ddl_enum_etendu>& li_enu_scal,List_io <TypeQuelconque >& li_quelc) const
{int nb_ddl_enum_etendu = li_enu_scal.size(); // la taille du tableau de retour
Tableau <double> tab_ret(nb_ddl_enum_etendu); // le tableau de retour
// on balaie les ddl_enum_etendu pour les alimenter
{List_io <Ddl_enum_etendu>::const_iterator il,il_fin = li_enu_scal.end();
int i_tab=1; // init
for (il= li_enu_scal.begin(); il != il_fin; il++,i_tab++)
{ // on regarde s'il s'agit d'un ddl pur
const Ddl_enum_etendu& ddl = (*il); // pour simplifier
if (ddl.Nom_vide())
// cas d'un ddl pur
{ if (Existe_ici(ddl.Enum()))
{tab_ret(i_tab)= Valeur_tdt(ddl.Enum());}
else
{cout << "\n *** erreur d'acces, le ddl "<< Nom_ddl(ddl.Enum())
<< " n'est pas disponible au temps tdt "
<< "\n Noeud::Valeur_multi_et_Tensorielle(...";
Noeud::Affiche(0);
Sortie(1);
};
}
else // cas d'un ddl étendu
{ if (Existe_ici_ddlEtendu(ddl))
{tab_ret(i_tab)= DdlEtendue(ddl).ConstValeur();}
else
{cout << "\n *** erreur d'acces, le ddl etendue "<< ddl.Nom_plein()
<< " n'est pas disponible au temps tdt "
<< "\n Noeud::Valeur_multi_et_Tensorielle(...";
Noeud::Affiche(0);
Sortie(1);
};
};
};
};
//on balaie les types quelconques
{List_io <TypeQuelconque>::iterator il,il_fin = li_quelc.end();
int i_tab=1; // init
for (il= li_quelc.begin(); il != il_fin; il++,i_tab++)
{ TypeQuelconque& etq = (*il); // pour simplifier
// on regarde s'il existe
TypeQuelconque_enum_etendu en = etq.EnuTypeQuelconque(); // pour simplifier
if (Existe_ici(en))
{ etq = Grandeur_quelconque(en);}
else
{// on test s'il s'agit d'un type correspondant à une grandeur
// stockée naturellement au noeud
bool trouver = false; // init
if(en.Nom_vide()) // on ne prend en compte que les types initiaux
{switch (en.EnumTQ())
{ case NUM_NOEUD:
{ Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) (etq.Grandeur_pointee()));
*(gr.ConteneurEntier()) = this->Num_noeud();
trouver = true;
break;
}
case NUM_MAIL_NOEUD:
{ Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) (etq.Grandeur_pointee()));
*(gr.ConteneurEntier()) = this->Num_Mail();
trouver = true;
break;
}
case POSITION_GEOMETRIQUE:
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (etq.Grandeur_pointee()));
(*gr.ConteneurCoordonnee())= this->Coord2();
trouver = true;
break;
}
case POSITION_GEOMETRIQUE_t:
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (etq.Grandeur_pointee()));
(*gr.ConteneurCoordonnee())= this->Coord1();
trouver = true;
break;
}
case POSITION_GEOMETRIQUE_t0:
{Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (etq.Grandeur_pointee()));
(*gr.ConteneurCoordonnee())= this->Coord0();
trouver = true;
break;
}
//*** fin
default:
trouver = false;
break;
};
};
if (!trouver)
{cout << "\n *** erreur d'acces, le ddl "<< en.NomPlein()
<< " n'est pas disponible "
<< "\n Noeud::Valeur_multi_et_Tensorielle(...";
Noeud::Affiche(0);
Sortie(1);
};
};
};
};
// retour
return tab_ret;
};
// ramene le nombre de variables ddl actives pour un type de ddl donné,
// c'est-à-dire 1 ou la dimension, suivant que le type dépend
// ou pas de la dimension
int Noeud::Nombre_var_ddl_actives (Enum_ddl en) const
{ int retour = 0;
if ((Existe(en) != 0) && (En_service(en)) && (UneVariable(en)))
{ switch (TypeGrandeur(en))
{ case SCALAIRE :
retour=1;
break;
case VECTEUR : case COORDONNEE : // là il y a un mélange pas sain !
// dans le cas où le calcul est axisymétrique
// on ne prend pas en compte le 3 ième ddl
if (ParaGlob::AxiSymetrie())
{retour = 2; }// on est forcément en 3D
else
{retour=ParaGlob::Dimension();};
break;
case TENSEUR :
retour = ParaGlob::NbCompTens();
break;
case RIEN_TYPEGRANDEUR :
retour = 0;
break;
default :
cout << "\nErreur : valeur incorrecte du type Enum_ddl !\n";
cout << "Nombre_var_ddl_actives (Enum_ddl en) \n";
Sortie(1);
};
};
return retour;
};
// surcharge de l'affectation entre deux noeuds
Noeud& Noeud::operator= (const Noeud& nd)
{ // recopie des tableaux
tab_0 = nd.tab_0;
tab_ddl = nd.tab_ddl;
tab_tdt = nd.tab_tdt;
num_Mail = nd.num_Mail;
// // liaison éventuelle
// enu_liaison = nd.enu_liaison;
// noeud_lier = nd.noeud_lier;
// puis les variables
num_noeud=nd.num_noeud;
posiAssemb = nd.posiAssemb;
// cas d'une base locale éventuelle
if (nd.baseB != NULL)
{if (baseB != NULL)
{ (*baseB) = (*(nd.baseB));}
else
{baseB = new BaseB(*nd.baseB);};
}
else // cas où nulle
{ if (baseB != NULL) delete baseB;}
if (nd.baseB_t != NULL)
{if (baseB_t != NULL)
{ (*baseB_t) = (*(nd.baseB_t));}
else
{baseB_t = new BaseB(*nd.baseB_t);};
}
else // cas où nulle
{ if (baseB_t != NULL) delete baseB_t;}
if (nd.baseB_0 != NULL)
{if (baseB_0 != NULL)
{ (*baseB_0) = (*(nd.baseB_0));}
else
{baseB_0 = new BaseB(*nd.baseB_0);};
}
else // cas où nulle
{ if (baseB_0 != NULL) delete baseB_0;}
coord2 = NULL; // initialisation
if ( Existe(X1) != 0)
{ // on met à null coord0 pour éviter de prendre ses valeurs
coord0 = NULL;
if ( tab_tdt.Taille() != 0)
// cas avec les coordonnees a t+dt
//on effectue la liaison ddl/ deplacement
Liaison_tdt(Existe(X1));
else
Liaison_t(Existe(X1));
}
else // cas où il n'y a pas de liaison
{coord0 = new Coordonnee(*(nd.coord0));
// la taille de coord1 est initialisé à 0 par défaut
};
tab_var_actives = nd.tab_var_actives;tab_actif = nd.tab_actif;
pos_enum = nd.pos_enum; // mise en place de l'adressage directe
t_enum_s = nd.t_enum_s; // mise en place
// dans le cas où il y a des ddl_etendu
// on recopie les différents tableaux et on met à jour
tab_ddletendu=nd.tab_ddletendu;
update_ddletendu=nd.update_ddletendu;
nbddletendu_update=nd.nbddletendu_update;
// on ne recopie pas le pointeur pos_ddletendu, car se sera dans la méthode MiseAjourDdl_etendu
// qu'il sera mis à jour
MiseAjourDdl_etendu();
// dans le cas où il y a des grandeurs quelconques (mêmes remarques que dans le cas des enum étendus)
tab_type_quel = nd.tab_type_quel;
update_type_quel = nd.update_type_quel;
nbTypeQ_update = nd.nbTypeQ_update;
MiseAjourTypeQuelconque();
return (*this);
};
// initialisation d'un ou de plusieurs nouveaux cas d'assemblage
void Noeud::InitNouveauCasAssemb(int nb_cas)
{ // récup de la taille actuelle
int taille_actuelle = posiAssemb.Taille();
// nouvelle taille
int nouvelle_taille = taille_actuelle + nb_cas;
// changement de taille, normalement les anciennes valeurs sont gardée
// en début de tableau
posiAssemb.Change_taille(nouvelle_taille);
t_enum_s.Change_taille(nouvelle_taille);
// on initialise les nouveaux éléments -> pour l'instant pointe sur rien
// car c'est la fin de la liste
for (int i= taille_actuelle+1;i<= nouvelle_taille;i++)
t_enum_s(i)=list_tab_posi_actif.end();
};
// enregistrement de l'ordre des variables ddl actives, ceci pour un cas d'assemblage
// donné, cette fonction permet ensuite d'utiliser la fonction
// Position_ddl qui donne la position d'un ddl pour un cas d'assemblage
// donné
void Noeud::Enreg_ordre_variable_ddl_actives(int nb_assemb)
{ // l'objectif est de déterminer ou de construire s'il n'existe pas, un tableau
// indexé par les types énumérés des ddl actifs
// le programme est construit sur le même modèle que MiseAjourEnum()
// mais ici on ne s'intéresse qu'au ddl actif
List_io <Tableau <int > >::iterator& pos_enum_s = t_enum_s(nb_assemb); // pour simplifier
// tout d'abord on regarde si le dernier tableau construit dans la liste
// list_tab_posi_actif, convient, car ce sera le cas pour le cas courant
// le dernier tableau est positionné en début de liste.
List_io <Tableau <int > >::iterator ideb;
ideb = list_tab_posi_actif.begin();
List_io <Tableau <int > >::iterator iancien = pos_enum_s;
int taille = tab_var_actives.Taille();
// le dernier élément stocké contiend le nombre d'élément non nul, on récupère sa position
int ttail = (*ideb).Taille();
bool okk = true;
// le test n'est effectué que si la liste n'est pas vide
if (list_tab_posi_actif.size() != 0)
{ // d'abort la taille, on compte le nombre d'élément non nul dans
int ttaile = (*ideb)(ttail);
if (taille != ttaile)
okk = false;
else
// maintenant le contenu
for (int i = 1; i<= taille;i++)
if( (*ideb)(tab_ddl(tab_var_actives(i)).Id_nom()) != i)
{ okk = false; break;}
}
else
okk = false;
// si le tableau convient on met à jour le pointeur et c'est fini
// sinon on passe en revu toute la liste
if (okk)
pos_enum_s = ideb;
else // ---- cas où on passe en revue la liste -----
// ici la procédure est plus longue, mais normalement elle ne sera
// utilisé que peut souvent
{
// on reconstruit un tableau d'adressage indirect des ddl
// la taille du tableau d'adressage est celui du nombre maxi
// de type de ddl différent (donc certain ne serviron pas)
// les données du tableau sont initialisées à 0, ainsi si l'on
// cherche à utiliser un ddl indice 0, l'erreur sera détecté au
// niveau de Tableau_T
// l'avant dernier élément du tableau sert à stocker le nombre de noeud
// qui utilise le tableau
// le dernier élément indique le nombre d'élément non nul
Tableau <int> tab_indi_enum(NbEnum_ddl()+2,0);
for (int i=1;i<=taille;i++)
tab_indi_enum(tab_ddl(tab_var_actives(i)).Id_nom())=i;
// on enregistre la taille
tab_indi_enum(NbEnum_ddl()+2) = taille;
// maintenant on va regarder si ce tableau existe dans la liste
List_io <Tableau <int > >::iterator ifin = list_tab_posi_actif.end();
List_io <Tableau <int > >::iterator iter;
bool trouver = false;
for (iter = ideb;ideb!= ifin;ideb++)
if ((*iter) == tab_indi_enum)
{ trouver = true; break;}
// si pas trouver on ajoute sinon on utilise la position déjà existante
if (!trouver)
// cas où on n'a pas trouvé de tableau
{ list_tab_posi_actif.push_front(tab_indi_enum); // allocation
// on attribue le nouveau pointage
pos_enum_s = list_tab_posi_actif.begin(); // sauvegarde de la position
}
else // cas où on a trouvé un tableau dans la liste
pos_enum_s = iter;
};
// on regarde si pos_enum_s était déjà attribué
if (iancien != list_tab_posi_actif.end())
// cas où ce n'est pas la première initialisation
{if ((*iancien)(NbEnum_ddl()+1) == 1)
// cas où c'est le dernier noeud qui pointe sur ce tableau
// on supprime le tableau
list_tab_posi_actif.erase(iancien);
else
// sinon on décrémente le compteur
((*iancien)(NbEnum_ddl()+1))--;
// maintenant on s'occupe du nouveau pointage
((*pos_enum_s)(NbEnum_ddl()+1))++;
}
else
// c'est la première initialisation
// on incrémente le compteur du tableau
((*pos_enum_s)(NbEnum_ddl()+1))++;
};
// test si le noeud est complet
// = 1 tout est ok, =0 element incomplet
int Noeud::TestComplet() const
{ bool ret=true;
if ((num_noeud == -3) || (num_Mail == -3))
{ if (num_noeud == -3) cout << "\n le numero du noeud n'est pas defini";
if (num_Mail == -3) cout << "\n le numero de maillage n'est pas defini";
if (ParaGlob::NiveauImpression() >= 6) this->Affiche();
ret = false;
}
if (tab_ddl.Taille() == 0)
{ cout << "\n ***** warning : il n'y a pas de ddl rattache au noeud " << num_noeud
<< ", du maillage " << num_Mail;
// ret = false;
// maintenant normalement ce n'est plus un pb
}
else
{ int nbdd = tab_ddl.Taille();
for (int i=1;i<= nbdd ;i++)
if (tab_ddl(i).TestComplet() == 0)
{ cout << "\n probleme avec le ddl " << i << "du noeud " << num_noeud
<< ", du maillage " << num_Mail;
ret = false;
};
// if (posiAssemb.Taille() == 0) return 0;
};
return ret;
};
// ajout de ddl
// 1) s'il n'y a pas de ddl il y a initialisation
// 2) si les ddl existent deja, on égalise au ddl passé en paramètre
// 3) lorsque le ddl appartient à une famille, tous les ddl de la famille sont
// ajoutées, les ddl supplémentaires ont une valeurs par défaut nulle
void Noeud::PlusDdl(Ddl& a)
{ // on regarde si le tableau des ddl existant est vide
int taille = tab_ddl.Taille();
if (taille == 0)
{ tab_ddl.Change_taille(1);
tab_ddl(1) = a;
// on peut maintenant mettre en place l'adressage directe
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
MiseAjourEnum(); // mise en place de l'adressage directe
// mise a jour des tableaux et des liaisons ddl/deplacement
MiseAjour();
}
else
{ // on regarde si le Ddl existe
for (int i=1;i<= taille; i++)
// on test uniquement sur l'identificateur du ddl, ces caractéristiques
// pouvant être différents suite à un précédent calcul
if ((tab_ddl(i)).Id_nom() == a.Id_nom())
{ tab_ddl(i) = a;
MiseAjourActif();
return;
};
// dans le cas où la dimension est supérieur à 1 et que le ddl appartient
// à une famille dépendant de la dimension, on ajoute tous les ddl de la famille
Enum_ddl enu = a.Id_nom();
if ((ParaGlob::Dimension()>1)&&FoncDim(enu))
{// on récupère tous les ddl de la famille
Tableau<Enum_ddl> t_enu =TableauTypeDdl(enu);
// fabrication d'un tableau de ddl associé
int ttaille = t_enu.Taille();
Tableau <Ddl > t_ddl(ttaille,a);// tous les nouveaux ddl on le même statut que a
for (int il=1;il<=ttaille;il++)
{t_ddl(il).Change_nom(t_enu(il));
if (t_ddl(il).Id_nom() != enu)
t_ddl(il).Valeur() = 0.; // mise à 0 pour les valeurs des ddl supplémentaires
}
// appel de la méthode gérant un tableau de ddl
PlusTabDdl(t_ddl);
return;
};
// dans le cas ou la dimension est supérieur à 1 et que les ddl est un XI
// erreur
// if ( (PremierDdlFamille(a.Id_nom())==X1) && (ParaGlob::Dimension() != 1))
// { cout <<"\n Erreur, la dimension etant superieur a 1 il n'est pas "
// << " possible d'ajouter qu'un seul ddl de position \n";
// cout << "void Noeud::PlusDdl(Ddl& a)" << endl;
// Sortie (1);
// }
// on regarde s'il y a une incompatibilite Xi Ui
if ((Existe_ici(X1) && (PremierDdlFamille(a.Id_nom())==UX)) ||
(Existe_ici(UX) && (PremierDdlFamille(a.Id_nom())==X1)) ||
(Existe_ici(UY) && (PremierDdlFamille(a.Id_nom())==X1)) ||
(Existe_ici(UZ) && (PremierDdlFamille(a.Id_nom())==X1)) )
{ cout <<"\n Erreur, on ne peut pas avoir de coordonnees entrainees"
<< " avec des ddl Ui \n";
cout << "void Noeud::PlusDdl(Ddl& a)" << endl;
Sortie (1);
};
// sauvegarde éventuelle des coordonnées
if (coord0 != NULL) // il existe déjà des coordonnées 0
// si les coordonnees existent deja on les sauvegarde dans une
//instance réelle et non éventuellement pointé
// sera ensuite modifié avec MiseAjour() éventuellement
{ Coordonnee truc(*coord0);
delete coord0;
coord0 = new Coordonnee(truc);
};
int coord1Taille = coord1.Taille();
Vecteur* toto = NULL;
if (coord1Taille != 0)
// signifie qu'il y a une liaison entre les ddl à t et coord1
if (coord1(1) != NULL)
// tableau existant et affecte, on cré un tableau
//intermédiaire, qui est supprimé à la fin de la routine
toto = new Vecteur(coord1Taille);
// réécriture dans toto, place qui sera utilisée dans mise à jour
// puis après MiseAjour() suppression de toto
for (int ii=1;ii<=coord1Taille;ii++)
{ (*toto)(ii) = *(coord1(ii));
coord1(ii) = &(*toto)(ii);
};
if (coord2 != NULL) // il existe déjà des coordonnées finales
// si les coordonnees existent deja on les sauvegarde dans
// une instance réelle et non éventuellement pointé
{ Coordonnee truc(*coord2);
delete coord2;
coord2 = new Coordonnee(truc);
};
// maintenant on peut changer le tableau de ddl
// on augmente la taille du tableau
tab_ddl.Change_taille(taille+1);
tab_ddl(taille+1) = a;
// on peut maintenant mettre en place l'adressage directe
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
MiseAjourEnum(); // mise en place de l'adressage directe
// mise a jour des tableaux et des liaisons ddl/deplacement
MiseAjour();
if (toto != NULL) delete toto;
};
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
// MiseAjourEnum(); // mise en place de l'adressage directe
};
// ajout d'un tableau de ddl
// 1) s'il n'y a pas de ddl il y a initialisation
// 2) si les ddl existent deja, on égalise avec les ddl passés en par
// 3) lorsque un nouveau ddl appartient à une famille, et que tous les ddl de la famille
// ne sont pas présents dans les ddl passés en paramètre, tous les ddl manquant de la famille sont
// ajoutées, avec une valeurs par défaut nulle
void Noeud::PlusTabDdl(Tableau<Ddl>& ta)
{ // on commence par ordonner le tableau ta
OrdonnerTableauDdl(ta);
// maintenant tous les ddl de ta sont dans le bonne ordre et à suivre
// on regarde si le tableau est vide
int taille = tab_ddl.Taille();
if (taille == 0)
{ tab_ddl = ta;
// on peut maintenant mettre en place l'adressage directe
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
MiseAjourEnum(); // mise en place de l'adressage directe
// mise a jour des tableaux et des liaisons ddl/deplacement
MiseAjour();
}
else
{// on regarde combien de Ddl existe deja
// et on crée une liste des ddl à ajouter
// les ddl qui existent déjà sont éventuellement updaté
list<Ddl> liDdl;
bool change_donn_var=false;
ListeDdlAajouter(liDdl,ta,change_donn_var);
// on augmente la taille du tableau en consequence
// mais auparavant dans le cas où les coordonnées sont connues
// que sous la forme de valeurs pointées il faut les sauvegarder
if (liDdl.size() == 0)
{ // dans le cas où on a aucun ddl a ajouter
// on regarde cependant si il y a eu un changement de type
if (change_donn_var) MiseAjourActif();
return;
}
else
{ // sauvegarde éventuelle des coordonnées
if (coord0 != NULL) // il existe déjà des coordonnées 0
// si les coordonnees existent deja on les sauvegarde
// dans une instance réelle et non éventuellement pointé
{ Coordonnee truc(*coord0);
delete coord0;
coord0 = new Coordonnee(truc);
};
int coord1Taille = coord1.Taille();
Vecteur* toto = NULL;
if (coord1Taille != 0)
if (coord1(1) != NULL)
{// tableau existant et affecte, on crée un tableau intermédiaire,
// qui est supprimé à la fin de la routine
toto = new Vecteur(coord1Taille);
// réécriture dans toto, place qui sera utilisée dans mise à jour
// puis après MiseAjour() suppression de toto
for (int ii=1;ii<=coord1Taille;ii++)
{ (*toto)(ii) = *(coord1(ii));
coord1(ii) = &(*toto)(ii);
};
};
if (coord2 != NULL) // il existe déjà des coordonnées finales
// si les coordonnees existent deja on les sauvegarde dans
// une instance réelle et non éventuellement pointé
{ Coordonnee truc(*coord2);
delete coord2;
coord2 = new Coordonnee(truc);
};
// maintenant on peut changer le tableau de ddl
int nbddl_a_ajouter=liDdl.size();
tab_ddl.Change_taille(taille+nbddl_a_ajouter);
// on rempli le tableau
list <Ddl >::iterator il=liDdl.begin();
for (int j1=1;j1<= nbddl_a_ajouter;j1++,il++)
{ tab_ddl(taille+j1)=(*il);};
// on peut maintenant mettre en place l'adressage directe
// ce qui permettra d'utiliser Existe(..) dans MiseAjour par exemple
MiseAjourEnum(); // mise en place de l'adressage directe
// on regarde s'il y a une incompatibilite Xi Ui
int tab_ddlTaille = tab_ddl.Taille();
if (Existe_ici(X1))
for (int i=1;i<= tab_ddlTaille;i++)
if (Meme_famille(tab_ddl(i).Id_nom(),UX))
{ cout <<"\n Erreur, on ne peut pas avoir de coordonnees entrainees"
<< " avec des ddl Ui \n";
cout << "void Noeud::PlusTabDdl(Tableau<Ddl>& ta)" << endl;
Sortie (1);
};
// mise a jour des tableaux et des liaisons ddl/deplacement
MiseAjour();
if (toto != NULL) delete toto;
};
};
// mise a jour des ddl actifs et de l'adressage via l'énumération des ddl
MiseAjourActif();
// MiseAjourEnum(); // mise en place de l'adressage directe
};
// ajout du tableau de ddl d'un autre noeud
void Noeud::PlusTabDdl(const Noeud & noe)
{ // on récupère le tableau de ddl géné par noe
Tableau<Ddl> ta = noe.tab_ddl;
if (ta.Taille() != 0)
Noeud::PlusTabDdl(ta);
};
// modification du statut d'un ddl
// si en est inconnu, aucune action
void Noeud::Met_hors_service(Enum_ddl en)
{ tab_ddl(Existe(en)).Met_hors_service();
MiseAjourActif();
};
void Noeud::Met_en_service(Enum_ddl en)
{ tab_ddl(Existe(en)).Met_en_service();
MiseAjourActif();
};
// modification du statut d'un tableau de ddl
// si un des elements du tableau est inconnu, aucune action
void Noeud::Met_hors_service(const Tableau<Enum_ddl>& taben)
{ int tabenTaille = taben.Taille();
for (int i = 1; i<=tabenTaille; i++)
tab_ddl(Existe(taben(i))).Met_hors_service();
MiseAjourActif();
};
void Noeud::Met_en_service(const Tableau<Enum_ddl>& taben)
{ int tabenTaille = taben.Taille();
for (int i = 1; i<=tabenTaille; i++)
tab_ddl(Existe(taben(i))).Met_en_service();
MiseAjourActif();
};
// modification du statut de tous les ddl actuellements présent
// y compris les données
// si un des elements du tableau est inconnu, aucune action
void Noeud::Met_hors_service()
{ int tab_ddlTaille = tab_ddl.Taille();
for (int i = 1; i<=tab_ddlTaille; i++)
tab_ddl(i).Met_hors_service();
MiseAjourActif();
};
void Noeud::Met_en_service()
// y compris les données
{ int tab_ddlTaille = tab_ddl.Taille();
for (int i = 1; i<=tab_ddlTaille; i++)
tab_ddl(i).Met_en_service();
MiseAjourActif();
};
// modification du statut de tous les ddl actuellements présent
// sauf les données qui ne sont pas modifiées
// si un des elements du tableau est inconnu, aucune action
void Noeud::Met_hors_service_ddl()
{ int tab_ddlTaille = tab_ddl.Taille();
for (int i = 1; i<=tab_ddlTaille; i++)
tab_ddl(i).Met_hors_service_ddl();
MiseAjourActif();
};
void Noeud::Met_en_service_ddl()
// y compris les données
{ int tab_ddlTaille = tab_ddl.Taille();
for (int i = 1; i<=tab_ddlTaille; i++)
tab_ddl(i).Met_en_service_ddl();
MiseAjourActif();
};
// changement du statut de variable à donnée pour un tableau d'enum de ddl
void Noeud::ChangeVariable_a_Donnee(const Tableau<Enum_ddl>& taben)
{ int tabenTaille = taben.Taille();
for (int i = 1; i<=tabenTaille; i++)
tab_ddl(Existe(taben(i))).ChangeVariable_a_Donnee();
MiseAjourActif();
};
// changement du statut de donnée à variable pour un tableau d'enum de ddl
void Noeud::ChangeDonnee_a_Variable(const Tableau<Enum_ddl>& taben)
{ int tabenTaille = taben.Taille();
for (int i = 1; i<=tabenTaille; i++)
tab_ddl(Existe(taben(i))).ChangeVariable_a_Donnee();
MiseAjourActif();
};
// changement de toutes les conditions données (service, variable, fixage ..)
// selon le tableau de ddl passé en paramètre
// par contre la valeur n'est pas utilisé donc la valeur actuelle reste inchangé
void Noeud::ChangeToutesLesConditions(const Tableau<Ddl>& ta)
{ int taTaille = ta.Taille();
for (int i = 1; i<=taTaille; i++)
{ tab_ddl(Existe(ta(i).Id_nom())).CopieToutesLesConditions(ta(i).Retour_Fixe());};
MiseAjourActif();
};
// changement de statu des ddl d'une combinaison, (cf. Enum_ddl)
// les ddl de la combinaison, prennent le même statut que celui
// actuellement stocké, correspondant à enuta
// cas est la combinaison,
void Noeud::ChangeStatut(int cas,Enum_ddl enuta)
{ // on récupère tous les membres de la combinaison
Tableau <Enum_ddl> tenu= Combinaison(cas);
int tenuTaille = tenu.Taille();
Enum_boolddl enubold=tab_ddl(Existe(enuta)).Retour_Fixe();
for (int i = 1; i<=tenuTaille; i++)
{ tab_ddl(Existe(tenu(i))).CopieToutesLesConditions(enubold);};
MiseAjourActif();
};
// changement de statu des ddl d'une combinaison, (cf. Enum_ddl)
// les ddl de la combinaison, prennent le même statut que celui de enubold
// cas est la combinaison,
void Noeud::ChangeStatut(int cas,Enum_boolddl enubold)
{ // on récupère tous les membres de la combinaison
Tableau <Enum_ddl> tenu= Combinaison(cas);
int tenuTaille = tenu.Taille();
for (int i = 1; i<=tenuTaille; i++)
{ tab_ddl(Existe(tenu(i))).CopieToutesLesConditions(enubold);};
MiseAjourActif();
};
/*// retourne le numero du ddl recherche identifie par en,
// s'il existe sinon 0
int Noeud::Existe(const Enum_ddl en)
{ int tab_ddl_Taille = tab_ddl.Taille();
// on commence par tester a partir de la derniere position sauvegardee
for (short int i=(short)(posiddl);i<= tab_ddl_Taille;i++)
if (en == tab_ddl(i).Id_nom())
{ posiddl=i; return i; }
// on continue la recherche a partir du debut
for (short int i=1;i< posiddl;i++)
if (en == tab_ddl(i).Id_nom())
{ posiddl=i; return i; }
// sinon retour 0
return 0;
}; */
// indique que l'on va utiliser les ddl en 0, t et tdt
// les grandeurs en tdt sont cree s'ils n'existent pas
// et initialisees par defaut
void Noeud::Travail_tdt()
{ if (tab_tdt.Taille() == 0)
tab_tdt.Change_taille(tab_ddl.Taille());
// les grandeurs à tdt peuvent changer des coordonnées vers
// autre chose, pour cela on commence par les supprimer, ensuite
// dans la procédure MiseAjour() elles sont recréées si besoin est
// a partir du tableau de tab_tdt
if (coord2 != NULL) delete coord2;
coord2 = NULL;
MiseAjour();
};
// indique que l'on va utiliser les ddl en 0, t
// si les grandeurs en tdt existaient, elles sont supprimées
void Noeud::Travail_t()
{ if (tab_tdt.Taille() != 0)
{ tab_tdt.Libere();
if (coord2 != NULL) delete coord2;
coord2 = NULL;
}
MiseAjour();
};
// mise a zero de tous les variables ddl actives
// sauf dans le cas de coordonnees entrainees. dans ce dernier
// cas les coordonnees correspondants a Xi pour t et t+dt
// sont mis a la valeur de celles de t=0
// a moins que le paramètre booléen est mis à false,
// dans ce cas les coordonnées à t sont inchangées
void Noeud::ZeroVariablesDdl(bool cas)
{ int nbactif = tab_var_actives.Taille();
for (int j=1; j<= nbactif; j++)
{int i = tab_var_actives(j);
if (((tab_ddl(i)).Nom())[0] != 'X')
{ tab_ddl(i).Valeur() = 0.;
tab_0(i) = 0.;
}
else // cas de coordonnees entrainees
if (cas)
tab_ddl(i).Valeur() = tab_0(i);
};
if (tab_tdt.Taille() != 0)
// cas de l'utilisation du tableau a tdt
for (int j1=1; j1<= nbactif; j1++)
{int ii = tab_var_actives(j1);
if (((tab_ddl(ii)).Nom())[0] != 'X')
tab_tdt(ii) = 0.;
else
tab_tdt(ii) = tab_0(ii);
};
};
// actualisation des ddl actifs (variable et donnee) de t+dt vers t
void Noeud::TdtversT()
{ int nbactif = tab_actif.Taille();
for (int j=1; j<= nbactif; j++)
{int i = tab_actif(j);
tab_ddl(i).Valeur() = tab_tdt(i);
};
// cas d'une base locale
if (baseB != NULL)
{(*baseB_t) = (*baseB);}
};
// actualisation des ddl actifs (variables et donnees) de t vers t+dt
void Noeud::TversTdt()
{ int nbactif = tab_actif.Taille();
for (int j=1; j<= nbactif; j++)
{int i = tab_actif(j);
tab_tdt(i)= tab_ddl(i).Valeur();
};
// cas d'une base locale
if (baseB != NULL)
{(*baseB) = (*baseB_t);}
};
// retourne dans le vecteur d'entrée les réels représentant les contraintes
// si les degrés de liberté contrainte existent
// sinon retourne false, en ne modifiant pas l'entrée
bool Noeud::Contrainte(Vecteur& Sig)
{ int position = Existe(SIG11);
int l_sigma; // dimension des contraintes
// test pour l'existence des ddl de sigma
if ( position != 0)
{ l_sigma = 1 ; // c'est au moins un tenseur d'ordre 1
if (Existe(SIG22) != 0)
{ l_sigma = 3 ; // c'est au moins un tenseur d'ordre 2
// donc trois coordonnées
if (Existe(SIG33) != 0)
l_sigma = 6 ; // c'est un tenseur d'ordre 3
// donc 6 coordonnées
};
if (Sig.Taille() != l_sigma) Sig.Change_taille(l_sigma);
int fin = position + l_sigma-1; int j = 1;
for (int i=position;i<= fin; i++,j++)
Sig(j) = tab_ddl(i).Valeur();
return true;
}
else
return false; // pas de contrainte
};
// retourne dans le tenseur d'entrée les réels représentant les contraintes
// si les degrés de liberté contrainte existent
// sinon retourne l'entrée sans modification
// le tenseur est choisit mixte pour représenter tous les cas
// !!! important : le tenseur Sig doit avoir la bonne dimension
// en entrée, car il n'est pas redimensionné dans la méthode
TenseurHB& Noeud::Contrainte(TenseurHB& Sig)
{ int position = Existe(SIG11);
if (position == 0) return Sig; // cas où il n'y a pas de contrainte
// ----- sinon on remplit les composantes du tenseur ------
int l_sigma = Sig.Dimension(); // dimension des contraintes
#ifdef MISE_AU_POINT // vérif des dimensions pour le debug
// comme position n'est pas nulle la dimension dans les ddl est au moins 1
int dimm = 1;
if (Existe(SIG22) != 0)
{ dimm = 2 ; // c'est au moins un tenseur d'ordre 2
if (Existe(SIG33) != 0)
dimm = 3 ; // c'est un tenseur d'ordre 3
};
if (l_sigma != dimm)
{ cout << "\nErreur : dimensions du tenseur d'entrée incorrecte Sig = " << dimm << " !\n";
cout << " Noeud::Contrainte(TenseurHB& Sig)\n";
Sortie(1);
};
#endif
switch (l_sigma)
{ case 1 : // cas à une dimension
Sig.Coor(1,1) = tab_ddl(position).Valeur();
break;
case 2 : // cas à 2 dimension
Sig.Coor(1,1) = tab_ddl(position).Valeur();
Sig.Coor(2,2) = tab_ddl(position+1).Valeur();
Sig.Coor(1,2) = tab_ddl(position+2).Valeur();
Sig.Coor(2,1) = tab_ddl(position+2).Valeur();
break;
case 3 : // cas à 3 dimension
Sig.Coor(1,1) = tab_ddl(position).Valeur();
Sig.Coor(2,2) = tab_ddl(position+1).Valeur();
Sig.Coor(3,3) = tab_ddl(position+2).Valeur();
Sig.Coor(1,2) = tab_ddl(position+3).Valeur();Sig.Coor(2,1) = Sig(1,2);
Sig.Coor(2,3) = tab_ddl(position+4).Valeur();Sig.Coor(3,2) = Sig(2,3);
Sig.Coor(1,3) = tab_ddl(position+5).Valeur();Sig.Coor(3,1) = Sig(1,3);
break;
default :
{ cout <<"\n Erreur, la dimension du tenseur Sig n'est pas correcte ";
cout << "Noeud::Contrainte(TenseurHB& Sig)" << endl;
Sortie (1);
}
};
return Sig;
};
// lecture sur le flot d'entée de déplacement
// et mise à jour des positions à t et t+dt correspondantes
void Noeud::LectureDeplacements(UtilLecture *entreePrinc)
{ // récup de la dimension
// définition du déplacement
Coordonnee dep = *coord0;
// lecture brut des coordonnées du déplacement sans la dimension
dep.Lecture(*entreePrinc);
// on ajoute aux coordonnées initiales pour avoir celles à t
dep += (*coord0);
// on insert les coordonnées à t qui sont créées si elles n'existent pas
// elles ont le statut inactif par défaut
Insert_coord1(dep);
};
//----- lecture écriture dans base info -----
// 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)
// ( ici on ne redimentionne pas,
// cela signifie que le nombre de ddl augmente mais ne diminue pas !!)
void Noeud::Lecture_base_info(ifstream& ent,int cas)
{ // traitement en fonction du cas
switch (cas)
{ case 1 : // ------- on récupère tout -------------------------
{ ent >> (*this) ;
break;
}
case 2 : // ----------- récup uniquement de se qui varie --------------------
{ // ici se sont les degrés de liberté
string toto;int nb;
ent >> toto >> nb;
#ifdef MISE_AU_POINT // vérification du numéro
if (nb != num_noeud )
{ cout << "\nErreur : numero de noeud lu : " << nb
<< " au lieu de " << num_noeud << " \n";;
cout << " Noeud::Lecture_base_info";
Sortie(1);
};
#endif
/* // ici on ne redimentionne pas,
/// // cela signifie que le nombre de ddl augmente mais ne diminue pas !
/// Tableau<Ddl > * pt_tableau = tab_ddl.New_en_lecture_si_taille_superieur_a_lire(ent);
/// // on regarde si le tableau a été redimensionné
/// if (pt_tableau != NULL)
/// // cas d'une redimension on ajoute les ddl
/// PlusTabDdl(*pt_tableau); */
// le code précédent pose des pb lorsque les ddl à lire sont différents de ceux existants
// donc systématiquement, on en crée des nouveaux et on met à jour
Tableau<Ddl > tableau;
tableau.Entree(ent);
// on ajoute les ddl
PlusTabDdl(tableau);
// on recopie les valeurs à t
int taille_tabddl=tab_ddl.Taille();
// en fait ce n'est pas la peine, ça a été fait dans PlusTabDdl !!
// cas de valeur à tdt
if (tab_tdt.Taille() != 0)
{for (int i=1;i<=taille_tabddl;i++)
tab_tdt(i) = tab_ddl(i).Valeur();
};
// cas d'une base locale éventuelle
{int existe_base;
ent >> existe_base >> toto;
if (existe_base == 1)
{if (baseB == NULL) {baseB=new BaseB();};
ent >> toto >> (*baseB);
// dans le cas où la grandeur à t n'existe pas
// on l'a crée et on lui donne la valeur de tdt
// sinon on fait une affectation, pour redémarrer avec quelque chose de correcte à t
if (baseB_t == NULL)
{baseB_t=new BaseB(*baseB);}
else // sinon on affecte
{(*baseB_t) = (*baseB);};
// cas à 0
if (baseB_0 == NULL)
{baseB_0=new BaseB(*baseB);};
// sinon on ne fait rien car la base est sensée avoir été correctement
// définit au départ
};
};
break;
}
default :
{ cout << "\nErreur : valeur incorrecte du type d'écriture !\n";
cout << "Noeud::Ecriture_base_info(ofstream& sort,int cas)"
<< " cas= " << cas << endl;
Sortie(1);
}
}
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Noeud::Ecriture_base_info(ofstream& sort,int cas)
{ // traitement en fonction du cas
switch (cas)
{ case 1 : // ------- on sauvegarde tout -------------------------
{ sort << (*this) << "\n";
break;
}
case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
{ // ici se sont les degrés de liberté
sort << "Noeud " << num_noeud << " ";
sort << tab_ddl ;
if (baseB != NULL)
{sort << " 1 baseLoc: " << (*baseB);}
else {sort << " 0 baseLoc: "; };
sort << "\n";
break;
}
default :
{ cout << "\nErreur : valeur incorrecte du type d'écriture !\n";
cout << "Noeud::Ecriture_base_info(ofstream& sort,int cas)"
<< " cas= " << cas << endl;
Sortie(1);
}
};
// pour l'instant on ne sauvegarde pas les ddl_étendu et les type_quelconque car on considère
// que ce sont des résultats et non pas des données indispensables.
// idem pour enu_liaison et noeud_lier, qui sont liées aux conditions limites
// A priori, c'est infos sont reconstruites
// à chaque démarrage
};