1870 lines
74 KiB
C++
1870 lines
74 KiB
C++
// 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-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 "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 >> nom >> noe.tab_ddl;
|
|
// coordonnee initiale on les récupère par défaut
|
|
// ensuite on fera la mise à jour
|
|
ent >> nom >> *(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 << "\n ddl_primaires "<< noe.tab_ddl;
|
|
// coordonnee initiale on les sauvegarde par défaut
|
|
// ensuite on fera la mise à jour
|
|
sort << "\n coordo_0 "<< *(noe.coord0);
|
|
sort << "\n ddl_a_0 " << noe.tab_0; // valeurs a l'instant 0 des ddl
|
|
sort << "\n 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 << "\ncoord2Existe \n";
|
|
else
|
|
sort << "\npascoord2 \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) << " ";
|
|
};
|
|
|
|
// les numéros de ddl actif
|
|
if (niveau > 3)
|
|
{cout << "\n les num des ddl actifs: " << tab_var_actives;
|
|
};
|
|
|
|
// 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
|
|
|
|
};
|
|
|