1187 lines
51 KiB
C++
1187 lines
51 KiB
C++
// FICHIER : Noeud2.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"
|
|
|
|
// ajout d'un type quelconque au noeud (il s'agit ici de définir le conteneur)
|
|
// dans le cas où les types existent déjà, on ne fait rien
|
|
// cas d'un tableau
|
|
void Noeud::AjoutTabTypeQuelconque(const Tableau <TypeQuelconque > & tab_t_quel)
|
|
{// on passe en revue le tableau transmis
|
|
int tailt = tab_t_quel.Taille();
|
|
int tailtab = tab_type_quel.Taille();
|
|
// pour ne faire qu'une passe on crée un tableau d'existence
|
|
Tableau <int> tab_ex(tailt);
|
|
int a_ajouter=0; // le nombre de grandeur à ajouter
|
|
for (int i=1;i<=tailt;i++)
|
|
{ bool trouver = false;
|
|
for (int j=1;j<=tailtab;j++)
|
|
if (tab_type_quel(j).EnuTypeQuelconque()==tab_t_quel(i).EnuTypeQuelconque())
|
|
{trouver = true;break;};
|
|
if (!trouver)
|
|
{a_ajouter++; tab_ex(i)=1;};
|
|
};
|
|
// dans le cas où il n'y a rien n'a ajouter on retourne
|
|
if (a_ajouter == 0) return;
|
|
// maintenant on ajoute vraiment
|
|
tab_type_quel.Change_taille(tailtab+a_ajouter);
|
|
update_type_quel.Change_taille(tailtab+a_ajouter); // =0 par défaut
|
|
int compteur=1;
|
|
for (int ii=1;ii<=tailt;ii++)
|
|
{if (tab_ex(ii)==1) {tab_type_quel(tailtab+compteur).ChangeGrandeur(tab_t_quel(ii));compteur++;} };
|
|
// on peut maintenant mettre en place l'adressage directe
|
|
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
|
|
MiseAjourTypeQuelconque(); // mise en place de l'adressage directe
|
|
};
|
|
|
|
// cas d'une seule grandeur quelconque
|
|
void Noeud::AjoutUnTypeQuelconque(const TypeQuelconque & t_quel)
|
|
{int tailtab = tab_type_quel.Taille();
|
|
// on n'ajoute que si la grandeur n'existe pas déjà
|
|
bool existe=false;
|
|
for (int j=1;j<=tailtab;j++)
|
|
if (tab_type_quel(j).EnuTypeQuelconque()==t_quel.EnuTypeQuelconque())
|
|
{existe = true;break;};
|
|
if (!existe)
|
|
{ tab_type_quel.Change_taille(tailtab+1);
|
|
update_type_quel.Change_taille(tailtab+1,0); // =0 par défaut
|
|
tab_type_quel(tailtab+1).ChangeGrandeur(t_quel);
|
|
// on peut maintenant mettre en place l'adressage directe
|
|
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
|
|
MiseAjourTypeQuelconque(); // mise en place de l'adressage directe
|
|
};
|
|
};
|
|
|
|
// supprime une grandeur quelconque (si elle est présente)
|
|
void Noeud::SupprimeUnTypeQuelconque(const TypeQuelconque & t_quel)
|
|
{ // récup du type
|
|
TypeQuelconque_enum_etendu en = t_quel.EnuTypeQuelconque();
|
|
int nb=Existe(en);
|
|
if ( nb != 0)
|
|
{// dans le cas où la grandeur existe on la supprime
|
|
int tai=tab_type_quel.Taille();
|
|
if ( update_type_quel(nb) != 0) nbTypeQ_update--;
|
|
for (int i= nb;i<tai;i++)
|
|
{ tab_type_quel(i).ChangeGrandeur(tab_type_quel(i+1));
|
|
update_type_quel(i)=update_type_quel(i+1);
|
|
};
|
|
tab_type_quel.Change_taille(tai-1);
|
|
update_type_quel.Change_taille(tai-1,0); // =0 par défaut
|
|
// on met à jour le tableau de gestion d'indiçage indirecte
|
|
MiseAjourTypeQuelconque();
|
|
};
|
|
};
|
|
// supprime un tableau de grandeurs quelconques (si elles sont présentes)
|
|
void Noeud::SupprimeTabTypeQuelconque(const Tableau <TypeQuelconque > & tab_t_quel)
|
|
{// on passe en revue le tableau transmis
|
|
int tailt = tab_t_quel.Taille();
|
|
int tailtab = tab_type_quel.Taille();
|
|
// pour ne faire qu'une passe on crée un tableau d'existence
|
|
Tableau <int> tab_in(tailtab);
|
|
bool on_supprime=false;
|
|
for (int i=1;i<=tailt;i++)
|
|
{ // on passe en revue le tableau fourni
|
|
int num = Existe(tab_t_quel(i).EnuTypeQuelconque());
|
|
if (num != 0)
|
|
{tab_in(num)=1;
|
|
if ( update_type_quel(num) != 0) nbTypeQ_update--;
|
|
on_supprime=true;};
|
|
};
|
|
// retour s'il n'y a rien à supprimer
|
|
if (!on_supprime) return;
|
|
// maintenant on supprime vraiment
|
|
int i=1; // pointeur des grandeurs restantes
|
|
for (int j=1;i<=tailtab;i++,j++)
|
|
{ // on passe en revue
|
|
if (tab_in(j)!=1)
|
|
{ // grandeur à garder
|
|
tab_type_quel(i).ChangeGrandeur(tab_type_quel(j));
|
|
update_type_quel(i)=update_type_quel(j);
|
|
i++;
|
|
};
|
|
};
|
|
// la valeur de i-1 = la taille à conserver
|
|
tab_type_quel.Change_taille(i-1);
|
|
// on met à jour le tableau de gestion d'indiçage indirecte
|
|
MiseAjourTypeQuelconque();
|
|
};
|
|
|
|
// récupération d'une grandeur quelconque pour modification
|
|
// après l'appel de cette méthode, la grandeur quelconque est réputée updaté
|
|
TypeQuelconque& Noeud::ModifGrandeur_quelconque(TypeQuelconque_enum_etendu enu)
|
|
{ // récup de l'indice de la grandeur
|
|
int indice = (*pos_Quelconque)(enu.Position());
|
|
// si le type n'était pas updaté on met à jour les 2 indicateurs
|
|
if (update_type_quel(indice) == 0) {update_type_quel(indice)=1; nbTypeQ_update++;}
|
|
else {update_type_quel(indice)++; };
|
|
return (tab_type_quel(indice));
|
|
};
|
|
|
|
// signale que toutes les grandeurs quelconques sont non-updatées
|
|
void Noeud::Mise_non_update_grandeurs_quelconques()
|
|
{ int tailupdate = update_type_quel.Taille();
|
|
for (int i=1;i<=tailupdate;i++) update_type_quel(i)=0;
|
|
nbTypeQ_update=0; // reset du nombre total
|
|
};
|
|
|
|
// signale qu'une grandeur quelconque est non-updatées
|
|
// en particulier la grandeur en question ne sera pas sauvegarder dans base_info
|
|
void Noeud::Mise_non_update_grandeurs_quelconques(TypeQuelconque_enum_etendu enu)
|
|
{ // récup de l'indice
|
|
int nb=Existe(enu);
|
|
update_type_quel(nb)=0;
|
|
nbTypeQ_update--; // met à jour du nombre total
|
|
};
|
|
|
|
// ajout d'un ddl étendu (il s'agit ici de définir le conteneur)
|
|
// dans le cas où les types existent déjà, on ne fait rien
|
|
// cas d'un tableau
|
|
void Noeud::AjoutTabDdl_etendu(const Tableau <Ddl_enum_etendu > & t_ddletendu)
|
|
{// on passe en revue le tableau transmis
|
|
int tailt = t_ddletendu.Taille();
|
|
int tailtab = tab_ddletendu.Taille();
|
|
// pour ne faire qu'une passe on crée un tableau d'existence
|
|
Tableau <int> tab_ex(tailt,0);
|
|
int a_ajouter=0; // le nombre de grandeur à ajouter
|
|
int ttaill = tab_ddletendu.Taille();
|
|
for (int i=1;i<=tailt;i++)
|
|
{ bool trouver = false;
|
|
// on passe en revue le tableau actuel
|
|
for (int j=1;j<=tailtab;j++)
|
|
if (tab_ddletendu(j).DdlEnumEtendu()==t_ddletendu(i))
|
|
{trouver = true;break;};
|
|
if (!trouver)
|
|
{a_ajouter++; tab_ex(i)=1;};
|
|
};
|
|
// dans le cas où il n'y a rien n'a ajouter on retourne
|
|
if (a_ajouter == 0) return;
|
|
// maintenant on ajoute vraiment
|
|
tab_ddletendu.Change_taille(tailtab+a_ajouter);
|
|
update_ddletendu.Change_taille(tailtab+a_ajouter,0); // =0 par défaut
|
|
int compteur=1;
|
|
for (int ii=1;ii<=tailt;ii++)
|
|
{if (tab_ex(ii)==1)
|
|
{tab_ddletendu(tailtab+compteur)=t_ddletendu(ii); compteur++;};
|
|
};
|
|
// on peut maintenant mettre en place l'adressage directe
|
|
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
|
|
MiseAjourDdl_etendu(); // mise en place de l'adressage directe
|
|
};
|
|
|
|
// cas d'un seul ddl étendu
|
|
void Noeud::AjoutUnDdl_etendu(const Ddl_enum_etendu & ddlenumetendu)
|
|
{int tailtab = tab_ddletendu.Taille();
|
|
// on n'ajoute que si la grandeur n'existe pas déjà
|
|
bool existe=false;
|
|
for (int j=1;j<=tailtab;j++)
|
|
if (tab_ddletendu(j).DdlEnumEtendu()==ddlenumetendu)
|
|
{existe = true;break;};
|
|
if (!existe)
|
|
{ tab_ddletendu.Change_taille(tailtab+1);
|
|
update_ddletendu.Change_taille(tailtab+1,0); // =0 par défaut
|
|
tab_ddletendu(tailtab+1)=Ddl_etendu(ddlenumetendu);
|
|
// on peut maintenant mettre en place l'adressage directe
|
|
// ce qui permettra d'utiliser Existe(..) dans MiseAjour
|
|
MiseAjourDdl_etendu(); // mise en place de l'adressage directe
|
|
};
|
|
};
|
|
|
|
// supprime un ddl étendu (si il est présent)
|
|
void Noeud::SupprimeUnDdl_etendu(const Ddl_enum_etendu & ddletendu)
|
|
{ // récup du type
|
|
int nb=Existe_ddlEtendu(ddletendu);
|
|
if ( nb != 0)
|
|
{// dans le cas où la grandeur existe on la supprime
|
|
int tai=tab_ddletendu.Taille();
|
|
if ( update_ddletendu(nb) != 0) nbddletendu_update--;
|
|
for (int i= nb;i<tai;i++)
|
|
{ tab_ddletendu(i)=tab_ddletendu(i+1);
|
|
update_ddletendu(i)=update_ddletendu(i+1);
|
|
};
|
|
tab_ddletendu.Change_taille(tai-1);
|
|
update_ddletendu.Change_taille(tai-1);
|
|
// on met à jour le tableau de gestion d'indiçage indirecte
|
|
MiseAjourDdl_etendu();
|
|
};
|
|
};
|
|
// supprime un tableau de grandeurs quelconques (si elles sont présentes)
|
|
void Noeud::SupprimeTabDdl_etendu(const Tableau <Ddl_enum_etendu > & t_ddletendu)
|
|
{// on passe en revue le tableau transmis
|
|
int tailt = t_ddletendu.Taille();
|
|
int tailtab = tab_ddletendu.Taille();
|
|
// pour ne faire qu'une passe on crée un tableau d'existence
|
|
Tableau <int> tab_in(tailtab);
|
|
bool on_supprime=false;
|
|
for (int i=1;i<=tailt;i++)
|
|
{ // on passe en revue le tableau fourni
|
|
int num = Existe_ddlEtendu(t_ddletendu(i));
|
|
if (num != 0)
|
|
{tab_in(num)=1;
|
|
if ( update_type_quel(num) == 1) nbTypeQ_update--;
|
|
on_supprime=true;};
|
|
};
|
|
// retour s'il n'y a rien à supprimer
|
|
if (!on_supprime) return;
|
|
// maintenant on supprime vraiment
|
|
int i=1; // pointeur des grandeurs restantes
|
|
for (int j=1;i<=tailtab;i++,j++)
|
|
{ // on passe en revue
|
|
if (tab_in(j)!=1)
|
|
{ // grandeur à garder
|
|
tab_ddletendu(i)=tab_ddletendu(j);
|
|
update_ddletendu(i)=update_ddletendu(j);
|
|
i++;
|
|
};
|
|
};
|
|
// la taille à conserver
|
|
update_ddletendu.Change_taille(i-1);
|
|
tab_ddletendu.Change_taille(i-1);
|
|
// on met à jour le tableau de gestion d'indiçage indirecte
|
|
MiseAjourDdl_etendu();
|
|
};
|
|
|
|
// récupération d'un ddl étendu pour modification
|
|
// après l'appel de cette méthode, le ddl étendu est réputée updaté
|
|
Ddl_etendu& Noeud::ModifDdl_etendu(const Ddl_enum_etendu& ddletendu)
|
|
{ // récup de l'indice de la grandeur
|
|
int indice = Existe_ddlEtendu(ddletendu);
|
|
// si le type n'était pas updaté on met à jour les 2 indicateurs
|
|
if (update_ddletendu(indice) == 0) {update_ddletendu(indice)=1; nbddletendu_update++;}
|
|
else {update_ddletendu(indice)++;};
|
|
return (tab_ddletendu(indice));
|
|
};
|
|
|
|
// signale que toutes les ddl étendus sont non-updatées
|
|
void Noeud::Mise_non_update_Ddl_etendu()
|
|
{ int tailupdate = update_ddletendu.Taille();
|
|
for (int i=1;i<=tailupdate;i++) update_ddletendu(i)=0;
|
|
nbddletendu_update=0; // reset du nombre total
|
|
};
|
|
|
|
// signale qu'un Ddl_etendu est non-updatées
|
|
// en particulier le Ddl_etendu en question ne sera pas sauvegarder dans base_info
|
|
void Noeud::Mise_non_update_Ddl_etendu(Ddl_enum_etendu ddlenumetendu)
|
|
{ // récup de l'indice de la grandeur
|
|
int indice = Existe_ddlEtendu(ddlenumetendu);
|
|
update_ddletendu(indice)=0;
|
|
nbddletendu_update--; // met à jour du nombre total
|
|
};
|
|
|
|
// ------------------------ procedures protegees ------------------------
|
|
|
|
|
|
// liaison des ddl et des deplacement a t et 0
|
|
// nb = le numero correspondant aux début des coordonnees dans les tableaux
|
|
// de ddl
|
|
void Noeud::Liaison_t(int nb)
|
|
{ // cas ou l'on est en coordonnees entrainees
|
|
// 1) cas des coord0
|
|
// positionnement a l'adresse des coordonnees
|
|
double * pt = &(tab_0(nb));
|
|
if (coord0 != NULL)
|
|
// si les coordonnees existent deja on les sauvegarde
|
|
// et on remplace les valeurs des ddl par les coor
|
|
{ Coordonnee truc(*coord0);
|
|
delete coord0;
|
|
// on passe un pointeur donc il n'y a pas de creation de memoire
|
|
// dans le new
|
|
coord0 = new Coordonnee(ParaGlob::Dimension(),pt);
|
|
*coord0 = truc;
|
|
}
|
|
else
|
|
// sinon on cree coord0 a la meme place que les ddl a t = 0
|
|
{coord0 = new Coordonnee(ParaGlob::Dimension(),pt);
|
|
}
|
|
// 2) cas des coord1
|
|
int dim = ParaGlob::Dimension();
|
|
if (coord1.Taille() == 0)
|
|
{ // il faut construire le tableau
|
|
coord1.Change_taille(dim);
|
|
for (int ii=1;ii<=dim;ii++)
|
|
coord1(ii) = &(tab_ddl(nb+ii-1).Valeur());
|
|
}
|
|
else if (coord1(1) == NULL)
|
|
// tableau existant mais non affecte
|
|
for (int ii=1;ii<=dim;ii++)
|
|
coord1(ii) = &(tab_ddl(nb+ii-1).Valeur());
|
|
else
|
|
// tableau existant et affecte, donc ici pas de pb a priori car lorsque les coordonnées à t
|
|
// sont affectées elles le sont obligatoirement sur le tableau de ddl
|
|
//les valeurs du tableau
|
|
// de coordonnées vont etre misent a la place des valeurs de ddl
|
|
for (int ii=1;ii<=dim;ii++)
|
|
{ double sa = *(coord1(ii));
|
|
// on ne supprime pas la valeur pointée car il n'y a jamais eu de new avec
|
|
// l'allocation de coord1
|
|
// on réaffecte
|
|
coord1(ii) = &(tab_ddl(nb+ii-1).Valeur());
|
|
// récup de la valeur
|
|
*(coord1(ii)) = sa;
|
|
}
|
|
};
|
|
|
|
// liaison des ddl et des deplacement a tdt seulement
|
|
// nb = le nb du début des deplacement dans les ddl
|
|
void Noeud::LiaiSeuletdt(int nb)
|
|
{
|
|
// positionnement a l'adresse des coordonnees
|
|
double * pt = &(tab_tdt(nb));
|
|
if (coord2 != NULL)
|
|
// si les coordonnees existent deja on les sauvegarde
|
|
// et on remplace les valeurs des ddl par les coor
|
|
{ Coordonnee truc(*coord2);
|
|
delete coord2;
|
|
coord2 = new Coordonnee(ParaGlob::Dimension(),pt);
|
|
*coord2 = truc;
|
|
}
|
|
else
|
|
// sinon on cree coord2 a la meme place que les ddl a tdt
|
|
{coord2 = new Coordonnee(ParaGlob::Dimension(),pt);
|
|
}
|
|
|
|
};
|
|
|
|
// liaison des ddl et des deplacement a t,tdt et 0
|
|
// nb = le nb du début des deplacement dans les ddl
|
|
void Noeud::Liaison_tdt(int nb)
|
|
{ // cas ou l'on est en coordonnees entrainees
|
|
// 1) cas des coord0 et des coord1
|
|
Liaison_t(nb);
|
|
// 2) cas des coord2
|
|
LiaiSeuletdt(nb);
|
|
};
|
|
|
|
// mise a jour des tableaux et des liaisons
|
|
void Noeud::MiseAjour()
|
|
{ // tout d'abord on regarde si tab_0 est correctement dimensionne
|
|
int t1 = tab_0.Taille();
|
|
int t2 = tab_ddl.Taille();
|
|
if (t1 != t2)
|
|
// cas ou le tableau de ddl a ete agrandi
|
|
// on change la taille des tableaux.
|
|
// on sauvegarde les coordonnées à 0 si elles sont liées
|
|
if (Existe(X1))
|
|
{ Coordonnee truc(*coord0);
|
|
delete coord0;
|
|
coord0 = new Coordonnee(truc);
|
|
};
|
|
// maintenant on peut changer les tableaux
|
|
{ tab_0.Change_taille(t2);
|
|
for (int i=t1+1;i<=t2;i++)
|
|
tab_0(i) = tab_ddl(i).Valeur();
|
|
if ( tab_tdt.Taille() != 0)
|
|
// cas ou le tableau tdt est en service
|
|
tab_tdt.Change_taille(t2);
|
|
}
|
|
// on regarde ensuite s'il y a des liaisons entre ddl et deplacements
|
|
int nb = Existe(X1);
|
|
if (nb != 0) // cas ou il y a une liaison ddl coordonnées
|
|
{double * pt0 = &((*coord0)(1));
|
|
if (pt0 != &(tab_0(nb)))
|
|
// cas d'une mauvaise liaison, on remet à jour
|
|
if (tab_tdt.Taille() == 0) // choix t ou t et tdt
|
|
Liaison_t(nb);
|
|
else
|
|
Liaison_tdt(nb);
|
|
else if (tab_tdt.Taille() != 0)
|
|
// cas d'une bonne liaison pour t=0, reste le cas à tdt
|
|
{ if (coord2 != NULL)
|
|
// cas ou les coord2 sont deja affectees
|
|
{ double * pt2 = &((*coord2)(1));
|
|
if (pt2 != &(tab_tdt(nb)))
|
|
LiaiSeuletdt(nb); // cas pas affectees au bonne endroit
|
|
}
|
|
else // cas où il n'y avait pas encore de liaison
|
|
LiaiSeuletdt(nb); // on affecte les coordonnees
|
|
}
|
|
}
|
|
};
|
|
|
|
// mise a jour de l'adressage via l'identificateur d'énumération
|
|
// c'est-à-dire la gestion via list_tab_enum et pos_enum
|
|
// ne doit être appelé que si l'on a introduit un nouveau ddl !!
|
|
// ou changé l'ordre etc..
|
|
void Noeud::MiseAjourEnum()
|
|
{ // tout d'abord on regarde si le dernier tableau construit dans la liste
|
|
// convient, car ce sera le cas pour le cas courant
|
|
// le dernier tableau est positionné en début de liste.
|
|
list <Tableau <int > >::iterator ideb = list_tab_enum.begin();
|
|
list <Tableau <int > >::iterator iancien = pos_enum;
|
|
int taille = tab_ddl.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_enum.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(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 = 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(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 <Tableau <int > >::iterator ifin = list_tab_enum.end();
|
|
list <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_enum.push_front(tab_indi_enum); // allocation
|
|
// on attribue le nouveau pointage
|
|
pos_enum = list_tab_enum.begin(); // sauvegarde de la position
|
|
}
|
|
else // cas où on a trouvé un tableau dans la liste
|
|
pos_enum = iter;
|
|
}
|
|
// --- gestions des tableaux ----
|
|
// l'avant dernier élément stocké contiend le nombre de noeud qui utilise le tableau
|
|
// (permet de supprimer les tableaux qui ne servent plus)
|
|
// on regarde si pos_enum était déjà attribué
|
|
if (iancien != list_tab_enum.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_enum.erase(iancien);
|
|
else
|
|
// sinon on décrémente le compteur
|
|
((*iancien)(NbEnum_ddl()+1))--;
|
|
// maintenant on s'occupe du nouveau pointage
|
|
((*pos_enum)(NbEnum_ddl()+1))++;
|
|
}
|
|
else
|
|
// c'est la première initialisation
|
|
// on incrémente le compteur du tableau
|
|
((*pos_enum)(NbEnum_ddl()+1))++;
|
|
};
|
|
|
|
// mise a jour du tableau des ddl de variable actives
|
|
// et du tableau de ddl actives (variables et données)
|
|
void Noeud::MiseAjourActif()
|
|
{ // ------- cas des variables uniquement --------
|
|
// tout d'abord on regarde le nombre de ddl actif
|
|
int nbddlactif = 0;
|
|
int tab_ddlTaille = tab_ddl.Taille();
|
|
for (int i = 1; i<=tab_ddlTaille; i++)
|
|
if ((tab_ddl(i).Service())&&(tab_ddl(i).UneVariable())) nbddlactif++;
|
|
// dimensionnement du tableau de pointeur
|
|
if (tab_var_actives.Taille() != nbddlactif)
|
|
{
|
|
////----- debug
|
|
//if (num_noeud == 120)
|
|
// {cout << "\n debug Noeud::MiseAjourActif()";
|
|
// for (int j = 1; j <= tab_var_actives.Taille(); j++)
|
|
// cout << "\n tab_var_actives(" << j <<")= "
|
|
// << tab_var_actives(j) << " ";
|
|
// cout << endl;
|
|
// };
|
|
////----- fin debug
|
|
|
|
tab_var_actives.Change_taille(nbddlactif);
|
|
}
|
|
// remplissage du tableau
|
|
int indice = 1;
|
|
for (short int i = 1; i<=tab_ddlTaille; i++)
|
|
if ((tab_ddl(i).Service())&&(tab_ddl(i).UneVariable()))
|
|
{tab_var_actives(indice) = i; indice++; }
|
|
// -------- cas des données et des variables ----------
|
|
nbddlactif = 0;
|
|
for (int i = 1; i<=tab_ddlTaille; i++)
|
|
if (tab_ddl(i).Service()) nbddlactif++;
|
|
// dimensionnement du tableau de pointeur
|
|
if (tab_actif.Taille() != nbddlactif) tab_actif.Change_taille(nbddlactif);
|
|
// remplissage du tableau
|
|
indice = 1;
|
|
for (short int i = 1; i<=tab_ddlTaille; i++)
|
|
if (tab_ddl(i).Service())
|
|
{tab_actif(indice) = i; indice++; }
|
|
|
|
};
|
|
|
|
// lecture des grandeurs quelconques sur flot
|
|
void Noeud::Lecture_grandeurs_quelconque(istream & ent)
|
|
{ // la lecture est longue, ne sert que pour la visualisation en faite
|
|
string nom;
|
|
ent >> nom >> nbTypeQ_update;
|
|
if (nbTypeQ_update != 0) // lecture que s'il y a des types updatées enregistrées
|
|
{ // tout d'abord on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
|
|
TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
|
|
// lecture de l'entête et récup d'enu
|
|
EnuTypeQuelParticulier enu = pour_lire.Lecture_un(ent);
|
|
// on regarde si ce type quelconque existe déjà
|
|
int indice = Indice_grandeur_quelconque(pour_lire.EnuTypeQuelconque());
|
|
if (indice == 0)
|
|
{ // cas d'une grandeur qui n'existe pas déjà, on la crée
|
|
int tailtab = tab_type_quel.Taille();tailtab++;
|
|
tab_type_quel.Change_taille(tailtab);
|
|
update_type_quel.Change_taille(tailtab); // =0 par défaut
|
|
// création d'une grandeur associée et lecture des information sur le flot
|
|
TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
|
|
// création d'un type quelconque
|
|
TypeQuelconque tq(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
|
|
delete grandeur; // car il ne sert plus à rien
|
|
// affectation
|
|
tab_type_quel(tailtab)=tq;update_type_quel(tailtab)=1; //normalement update
|
|
}
|
|
else
|
|
{ // cas d'une grandeur qui existe déjà
|
|
ent >> tab_type_quel(indice);update_type_quel(indice)=1; //normalement update
|
|
};
|
|
};
|
|
};
|
|
|
|
// écriture des grandeurs quelconques sur flot
|
|
void Noeud::Ecriture_grandeurs_quelconque(ostream & sort) const
|
|
{ // on ne sauvegarde que les grandeurs updatées et qui sont prévu pour une sauvegarde
|
|
sort << " G_quel " << nbTypeQ_update << " "; // en tête et nombre de grandeurs updatées
|
|
int tailupdate = update_type_quel.Taille();
|
|
for (int i=1;i<=tailupdate;i++)
|
|
{ if (update_type_quel(i) != 0) sort << tab_type_quel(i) << " ";};
|
|
};
|
|
|
|
// récupe de l'indice d'une grandeur quelconque
|
|
// si la grandeur n'existe pas -> ramène 0
|
|
int Noeud::Indice_grandeur_quelconque(TypeQuelconque_enum_etendu a)
|
|
{ int tailtab = tab_type_quel.Taille();
|
|
for (int i=posi_type_quel;i<=tailtab;i++)
|
|
{ if ( tab_type_quel(i).EnuTypeQuelconque() == a)
|
|
{ posi_type_quel=i; return i;}
|
|
};
|
|
// cas on la grandeur a chercher est peut-être au début du tableau
|
|
for (int j=1;j< posi_type_quel;j++)
|
|
{ if ( tab_type_quel(j).EnuTypeQuelconque() == a)
|
|
{ posi_type_quel=j; return j;}
|
|
};
|
|
// cas où l'on n'a pas trouvé la grandeur
|
|
return 0;
|
|
};
|
|
|
|
// mise a jour de l'adressage via l'identificateur d'énumération
|
|
// c'est-à-dire la gestion via list_tab_typeQuelconque et popos_Quelconque
|
|
// ne doit être appelé que si l'on a introduit un nouveau type quelconque !!
|
|
// ou changé l'ordre etc..
|
|
void Noeud::MiseAjourTypeQuelconque()
|
|
{ // la méthode sert à mettre à jour les différents indicateurs d'adressage rapides
|
|
// 1-- s'il n'y a pas de type quelconque, on regarde si le pointeur de tableau a changé
|
|
// utilisé par exemple par le destructeur, ou les constructeurs
|
|
|
|
// on récupère le nombre maxi de type de grandeurs quelconques existantes actuellement
|
|
// (ce nombre n'est pas forcément fixe pendant le calcul, on peut avoir de nouvelle grandeur qui
|
|
// sont définit pendant le calcul : typiquement associée à de nouvelles grandeurs globales créées par
|
|
// l'utilisateur: ex: le calcul d'une intégrale)
|
|
int nbmaxTypeQ = TypeQuelconque_enum_etendu::NBmax_TypeQuelconque_enum_etendue();
|
|
if (tab_type_quel.Taille() == 0) // -> pas de type quelconque stocké
|
|
{ if (pos_Quelconque == list_tab_typeQuelconque.end())
|
|
// cela signifie qu'il n'y a jamais eu de type quelconque pour tous les noeuds
|
|
// et qu'il n'y a rien à faire, retour directe
|
|
{return;}
|
|
else // sinon c'est le cas d'une destruction de types quelconques
|
|
// on met à jour les indicateurs ad hoc
|
|
{ // l'avant dernier élément du tableau contient le nombre de noeud qui utilise ce type
|
|
int taille_pos_quelconque = (*pos_Quelconque).Taille();
|
|
// on n'utilise pas nbmaxTypeQ car il peut varier pendant le calcul if ((*pos_Quelconque)(nbmaxTypeQ+1) == 1)
|
|
if ((*pos_Quelconque)(taille_pos_quelconque-1) == 1)
|
|
// cas où c'est le dernier noeud qui pointe sur ce tableau on supprime le tableau
|
|
list_tab_typeQuelconque.erase(pos_Quelconque);
|
|
else
|
|
// sinon on décrémente le compteur
|
|
((*pos_Quelconque)(taille_pos_quelconque-1))--;
|
|
// puis on met à jour le pointeur
|
|
pos_Quelconque = list_tab_typeQuelconque.end(); // -> veut dire pas de tableau associé
|
|
// et retour
|
|
return;
|
|
};
|
|
};
|
|
|
|
// 2-- la suite concerne le cas où des types quelconque existent
|
|
// tout d'abord on regarde si le dernier tableau construit dans la liste
|
|
// convient, car ce sera le cas pour le cas courant
|
|
// le dernier tableau est positionné en début de liste.
|
|
list <Tableau <int > >::iterator ideb = list_tab_typeQuelconque.begin();
|
|
list <Tableau <int > >::iterator iancien = pos_Quelconque;
|
|
int taille = tab_type_quel.Taille(); // nombre d'éléments quelconques actuellement stocké
|
|
// le dernier élément stocké contiend le nombre d'élément non nul, on récupère sa position
|
|
bool okk = true;
|
|
// le test n'est effectué que si la liste n'est pas vide
|
|
if (list_tab_typeQuelconque.size() != 0)
|
|
{ // d'abort la taille, on compte le nombre d'élément non nul
|
|
int ttail = (*ideb).Taille();// les deux dernières valeurs = le nombre de noeuds associés, le nombre de quelconque à considérer
|
|
int ttaile = (*ideb)(ttail); // == le nombre de quelconque qui sont considérer
|
|
if (taille != ttaile) // -> là c'est sûr que cela ne convient pas car déjà le nombre est différent
|
|
okk = false;
|
|
else // sinon on test les contenues
|
|
// maintenant le contenu
|
|
for (int i = 1; i<= taille;i++)
|
|
if( (*ideb)(tab_type_quel(i).EnuTypeQuelconque().Position()) != i)
|
|
{ okk = false; break;}
|
|
}
|
|
else // si n'existe pas encore, il faut le créer
|
|
{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_Quelconque = ideb;} // cas ou on n'a pas à faire de création
|
|
else // ---- cas où on passe en revue la liste : cas d'une création -----
|
|
// ici la procédure est plus longue, mais normalement elle ne sera
|
|
// utilisé que peut souvent
|
|
{
|
|
// on reconstruit un tableau d'adressage indirect des types quelconques
|
|
// la taille du tableau d'adressage est celui du nombre maxi
|
|
// de type quelconques différent (donc certain ne serviront pas)
|
|
// les données du tableau sont initialisées à 0, ainsi si l'on
|
|
// cherche à utiliser un type quelconque 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_TypeQ(nbmaxTypeQ+2,0);
|
|
for (int i=1;i<=taille;i++)
|
|
tab_indi_TypeQ(tab_type_quel(i).EnuTypeQuelconque().Position())=i;
|
|
// on enregistre la taille
|
|
tab_indi_TypeQ(nbmaxTypeQ+2) = taille;
|
|
// maintenant on va regarder si ce tableau existe dans la liste
|
|
list <Tableau <int > >::iterator ifin = list_tab_typeQuelconque.end();
|
|
list <Tableau <int > >::iterator iter;
|
|
bool trouver = false;
|
|
for (iter = ideb;ideb!= ifin;ideb++)
|
|
if ((*iter) == tab_indi_TypeQ)
|
|
{ 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_typeQuelconque.push_front(tab_indi_TypeQ); // allocation
|
|
// on attribue le nouveau pointage
|
|
pos_Quelconque = list_tab_typeQuelconque.begin(); // sauvegarde de la position
|
|
}
|
|
else // cas où on a trouvé un tableau dans la liste
|
|
pos_Quelconque = iter;
|
|
};
|
|
// --- gestions des tableaux ----
|
|
// l'idée est ici la suivante: si le pointeur de tableau: pos_Quelconque a changé par rapport à iancien
|
|
// et que iancien était associé à un seul noeud, alors il faut le supprimer car il n'est plus associé à aucun noeud
|
|
// évidemment ceci n'est a considérer que si iancien pointait sur quelque chose de valide
|
|
|
|
int taille_pos_quelconque = (*pos_Quelconque).Taille(); // récup de la taille actuelle
|
|
// on regarde si pos_Quelconque était déjà attribué
|
|
// l'avant dernier élément stocké contiend le nombre de noeud qui utilise le tableau
|
|
// (permet de supprimer les tableaux qui ne servent plus)
|
|
if (iancien != pos_Quelconque)
|
|
{ // cas où on a changé de pointeur de tableau
|
|
if (iancien != list_tab_typeQuelconque.end())
|
|
// cas où ce n'est pas la première initialisation
|
|
{int taille_pos_ancien = (*iancien).Taille();
|
|
if ((*iancien)(taille_pos_ancien-1) == 1)
|
|
// cas où c'est le dernier noeud qui pointe sur ce tableau on supprime le tableau
|
|
list_tab_typeQuelconque.erase(iancien);
|
|
else
|
|
// sinon on décrémente le compteur
|
|
((*iancien)(taille_pos_ancien-1))--;
|
|
// maintenant on s'occupe du nouveau pointage
|
|
((*pos_Quelconque)(taille_pos_quelconque-1))++;
|
|
}
|
|
else
|
|
// c'est la première initialisation
|
|
// on incrémente le compteur du tableau: -> on ajoute 1 noeud
|
|
((*pos_Quelconque)(taille_pos_quelconque-1))++;
|
|
};
|
|
// si iancien == pos_Quelconque, il n'y a pas eu de nouveau noeud ajouté, donc rien à faire
|
|
};
|
|
|
|
// --- cas des Ddl_enum_etendu ----
|
|
|
|
// lecture des Ddl_enum_etendu sur flot
|
|
void Noeud::Lecture_Ddl_etendu(istream & ent)
|
|
{ string nom;
|
|
ent >> nom >> nbddletendu_update;
|
|
tab_ddletendu.Change_taille(nbddletendu_update);
|
|
ent >> nom >> update_ddletendu;
|
|
int tailupdate = update_ddletendu.Taille();
|
|
for (int i=1;i<=tailupdate;i++)
|
|
{ if (update_ddletendu(i) != 0) ent >> tab_ddletendu(i) ;};
|
|
};
|
|
|
|
// écriture des Ddl_enum_etendu sur flot
|
|
void Noeud::Ecriture_Ddl_etendu(ostream & sort) const
|
|
{ // on ne sauvegarde que les grandeurs updatées et qui sont prévu pour une sauvegarde
|
|
sort << "\n G_ddletendu " << nbddletendu_update << " "; // en tête et nombre de grandeurs updatées
|
|
// écriture du tableau d'update
|
|
sort << "\n update_ddletendu: "<< update_ddletendu << " ";
|
|
// sortie conditionnelle de tab_ddletendu
|
|
int tailupdate = update_ddletendu.Taille();
|
|
for (int i=1;i<=tailupdate;i++)
|
|
{ if (update_ddletendu(i) != 0) sort << tab_ddletendu(i) << " ";};
|
|
};
|
|
|
|
// récupe de l'indice d'un Ddl_enum_etendu
|
|
// si la grandeur n'existe pas -> ramène 0
|
|
int Noeud::Indice_Ddl_etendu(const Ddl_enum_etendu& a)
|
|
{ int tailtab = tab_ddletendu.Taille();
|
|
for (int i=posi_ddletendu;i<=tailtab;i++)
|
|
{ if ( tab_ddletendu(i).Const_DdlEnumEtendu() == a)
|
|
{ posi_ddletendu=i; return i;}
|
|
};
|
|
// cas ou la grandeur a chercher est peut-être au début du tableau
|
|
for (int j=1;j< posi_ddletendu;j++)
|
|
{ if ( tab_ddletendu(j).Const_DdlEnumEtendu() == a)
|
|
{ posi_ddletendu=j; return j;}
|
|
};
|
|
// cas où l'on n'a pas trouvé la grandeur
|
|
return 0;
|
|
};
|
|
|
|
// mise a jour de l'adressage via l'identificateur d'énumération
|
|
// c'est-à-dire la gestion via list_tab_ddletendu et pos_ddletendu
|
|
// ne doit être appelé que si l'on a introduit un nouveau Ddl_enum_etendu !!
|
|
// ou changé l'ordre etc..
|
|
void Noeud::MiseAjourDdl_etendu()
|
|
{ // la méthode sert à mettre à jour les différents indicateurs d'adressage rapides
|
|
// 1-- s'il n'y a pas de ddl étendue, on regarde si le pointeur de tableau a changé
|
|
// utilisé par exemple par le destructeur, ou les constructeurs
|
|
int nbmaxddleten = Ddl_enum_etendu::NBmax_ddl_enum_etendue();
|
|
if (tab_ddletendu.Taille() == 0)
|
|
{ if (pos_ddletendu == list_tab_ddletendu.end())
|
|
// cela signifie qu'il n'y a jamais eu de ddl étendue et qu'il n'y a rien à faire, retour directe
|
|
{return;}
|
|
else // sinon c'est le cas d'une destruction des ddl étendue
|
|
// on met à jour les indicateurs ad hoc
|
|
{ if ((*pos_ddletendu)(nbmaxddleten+1) == 1)
|
|
// cas où c'est le dernier noeud qui pointe sur ce tableau on supprime le tableau
|
|
list_tab_ddletendu.erase(pos_ddletendu);
|
|
else
|
|
// sinon on décrémente le compteur
|
|
((*pos_ddletendu)(nbmaxddleten+1))--;
|
|
// puis on met à jour le pointeur
|
|
pos_ddletendu = list_tab_ddletendu.end(); // -> veut dire pas de tableau associé
|
|
// et retour
|
|
return;
|
|
};
|
|
};
|
|
|
|
// 2-- la suite concerne le cas où il y a des ddl étendue
|
|
// tout d'abord on regarde si le dernier tableau construit dans la liste
|
|
// convient, car ce sera le cas courant
|
|
// le dernier tableau est positionné en début de liste.
|
|
list <Tableau <int > >::iterator ideb = list_tab_ddletendu.begin();
|
|
list <Tableau <int > >::iterator iancien = pos_ddletendu;
|
|
int taille = tab_ddletendu.Taille();
|
|
// le dernier élément stocké contiend le nombre d'élément non nul, on récupère sa position
|
|
bool okk = true; // init
|
|
// le test n'est effectué que si la liste n'est pas vide
|
|
if (list_tab_ddletendu.size() != 0)
|
|
{ // d'abort la taille, on compte le nombre d'élément non nul
|
|
int ttail = (*ideb).Taille(); // les deux dernières valeurs = le nombre de noeuds associés, le nombre de ddl enum étendu à considérer
|
|
int ttaile = (*ideb)(ttail);
|
|
if (taille != ttaile)
|
|
okk = false;
|
|
else
|
|
// maintenant le contenu
|
|
for (int i = 1; i<= taille;i++)
|
|
if( (*ideb)(tab_ddletendu(i).Const_DdlEnumEtendu().Position()) != 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_ddletendu = ideb;
|
|
else // ---- cas où on passe en revue la liste -----
|
|
// ici la procédure est plus longue, mais normalement elle ne sera
|
|
// utilisé que peu souvent
|
|
{
|
|
// on reconstruit un tableau d'adressage indirect des ddl étendu
|
|
// la taille du tableau d'adressage est celui du nombre maxi
|
|
// de ddl étendu différents (donc certain ne serviron pas)
|
|
// les données du tableau sont initialisées à 0, ainsi si l'on
|
|
// cherche à utiliser un ddl étendu 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_ddletendu(nbmaxddleten+2,0);
|
|
for (int i=1;i<=taille;i++)
|
|
tab_indi_ddletendu(tab_ddletendu(i).Const_DdlEnumEtendu().Position())=i;
|
|
// on enregistre la taille
|
|
tab_indi_ddletendu(nbmaxddleten+2) = taille;
|
|
// maintenant on va regarder si ce tableau existe dans la liste
|
|
list <Tableau <int > >::iterator ifin = list_tab_ddletendu.end();
|
|
list <Tableau <int > >::iterator iter;
|
|
bool trouver = false;
|
|
for (iter = ideb;ideb!= ifin;ideb++)
|
|
if ((*iter) == tab_indi_ddletendu)
|
|
{ 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_ddletendu.push_front(tab_indi_ddletendu); // allocation
|
|
// on attribue le nouveau pointage
|
|
pos_ddletendu = list_tab_ddletendu.begin(); // sauvegarde de la position
|
|
}
|
|
else // cas où on a trouvé un tableau dans la liste
|
|
pos_ddletendu = iter;
|
|
};
|
|
// --- gestions des tableaux ----
|
|
// l'idée est ici la suivante: si le pointeur de tableau: pos_ddletendu a changé par rapport à iancien
|
|
// et que iancien était associé à un seul noeud, alors il faut le supprimer car il n'est plus associé à aucun noeud
|
|
// évidemment ceci n'est a considérer que si iancien pointait sur quelque chose de valide
|
|
|
|
// on regarde si pos_ddletendu était déjà attribué
|
|
// l'avant dernier élément stocké contiend le nombre de noeud qui utilise le tableau
|
|
// (permet de supprimer les tableaux qui ne servent plus)
|
|
if (iancien != pos_ddletendu)
|
|
{ // cas où on a changé de pointeur de tableau
|
|
if (iancien != list_tab_ddletendu.end())
|
|
// cas où ce n'est pas la première initialisation
|
|
{if ((*iancien)(nbmaxddleten+1) == 1)
|
|
// cas où c'est le dernier noeud qui pointe sur ce tableau
|
|
// on supprime le tableau
|
|
list_tab_ddletendu.erase(iancien);
|
|
else
|
|
// sinon on décrémente le compteur
|
|
((*iancien)(nbmaxddleten+1))--;
|
|
// maintenant on s'occupe du nouveau pointage
|
|
((*pos_ddletendu)(nbmaxddleten+1))++;
|
|
}
|
|
else
|
|
// c'est la première initialisation
|
|
// on incrémente le compteur du tableau
|
|
((*pos_ddletendu)(nbmaxddleten+1))++;
|
|
};
|
|
// si iancien == pos_ddletendu, il n'y a pas eu de nouveau noeud ajouté, donc rien à faire
|
|
};
|
|
|
|
// ordonne et on met a suivre les ddl d'une même famille suivant un ordre croissant
|
|
// ceci pour des ddl que l'on vient d'ajouter, QUE L'ON CONSIDÈRE ÊTRE À LA FIN DE TAB_DDL !
|
|
// en paramètre le ou les ddl
|
|
/*void Noeud::OrdonneDdlMemeFamille(const Ddl& a)
|
|
{ // on ne traite que si la dimension est supérieur à 1 ou que le ddl fait partie d'une famille
|
|
if ((ParaGlob::Dimension()>1)&&FoncDim(a.Id_nom()))
|
|
{Enum_ddl enu=a.Id_nom(); int dim = ParaGlob::Dimension();// pour simplifier
|
|
// On parcourt le tableau pour trouver les autres ddl de la même famille
|
|
// et on en profite pour ordonner les ddl
|
|
Tableau<int> ptin(dim); int irecup=0;
|
|
int taille=tab_ddl.Taille();
|
|
for (int i=0; i<= taille-1;i++)
|
|
if (Meme_famille(tab_ddl(i).Id_nom(),enu))
|
|
{if (tab_ddl(i).Id_nom() > enu)
|
|
Permutation_2ddl(i,taille);
|
|
irecup++; ptin(irecup)=i;
|
|
};
|
|
// -- maintenant les ddl de la même famille sont dans un ordre croissant, il reste
|
|
// -- à les mettre à suivre
|
|
// on continu que si effectivement il y a des autre ddl de la même famille
|
|
if (irecup == 0) return; // retour car aucun ddl de la meme famille
|
|
// on traite en fonction de irecup
|
|
if (irecup == 1)
|
|
{// cas sympathique ou l'on a simplement à permutter deux positions du tableau
|
|
Enum_ddl enu1=tab_ddl(ptin(irecup)).Id_nom();
|
|
if (ptin(irecup)==taille-1)
|
|
{return;}// cas déjà à suivre
|
|
else // sinon on permutte le suivant de enu1 et enu
|
|
{Permutation_2ddl(ptin(irecup)+1,taille);}
|
|
}
|
|
else // cas
|
|
|
|
};
|
|
|
|
void Noeud::OrdonneDdlMemeFamille(const Tableau<Ddl>& ta)
|
|
{
|
|
|
|
};
|
|
|
|
// permutation de deux ddl (sert pour OrdonneDdlMemeFamille)
|
|
void Noeud::Permutation_2ddl(const int& ipo1,cont int& ipo2)
|
|
{ // tout d'abord le ddl
|
|
Ddl intir=tab_ddl(ipo1);
|
|
tab_ddl(ipo1)=tab_ddl(ipo2); tab_ddl(ipo2)=intir;
|
|
// maintenant les valeurs à 0
|
|
double xnia0=tab_0(ipo1);
|
|
tab_0(ipo1)=tab_0(ipo2); tab_0(ipo2)=xnia0;
|
|
// éventuellement les valeurs à tdt
|
|
if (tab_tdt.Taille()!=0)
|
|
{ double xniatdt=tab_tdt(ipo1);
|
|
tab_tdt(ipo1)=tab_tdt(ipo2); tab_tdt(ipo2)=xniatdt;
|
|
};
|
|
}; */
|
|
|
|
// ordonner un tableau de ddl suivant un ordre croissant et avec des ddl à suivre
|
|
void Noeud::OrdonnerTableauDdl(Tableau<Ddl>& ta)
|
|
{ int tataille = ta.Taille();
|
|
for (int i1=1;i1<=tataille;i1++)
|
|
{for (int j1=i1+1;j1<=tataille;j1++)
|
|
if (ta(i1).Id_nom() > ta(j1).Id_nom())
|
|
{// il ne sont pas dans le bonne ordre on permutte
|
|
Ddl intir = ta(i1);
|
|
ta(i1)=ta(j1);
|
|
ta(j1)=intir;
|
|
}
|
|
}
|
|
};
|
|
|
|
// liste des ddl (en famille) à ajouter
|
|
// (la liste est initialisée au début)
|
|
// recopie des ddl existant déjà
|
|
// change_donn_var indique si les ddl existant on été modifiée
|
|
void Noeud::ListeDdlAajouter(list<Ddl>& liDdl,Tableau<Ddl>& ta,bool& change_donn_var)
|
|
{ // dans la liste existante tous les ddl des familles existantes, sont présents
|
|
// et ordonné dans chaque famille mais par forcément globalement,
|
|
// par contre dans ta on peut avoir que certains représentants de famille
|
|
// mais ta est également ordonnée
|
|
// on regarde combien de Ddl existe deja
|
|
list <Ddl >::iterator il;
|
|
liDdl.clear(); // init au début
|
|
list <Enum_ddl> li_travail; // une liste de travaille
|
|
int j=1;
|
|
int taille=tab_ddl.Taille();
|
|
int tataille=ta.Taille();
|
|
if (j>tataille) return; // cas d'un tableau vide
|
|
do
|
|
{ bool rel = false;Enum_ddl enu=ta(j).Id_nom();
|
|
// on cherche si le ddl existe déjà
|
|
for (int i=1;i<= taille; i++)
|
|
{if (tab_ddl(i).Id_nom() == enu)
|
|
{ rel = true;
|
|
tab_ddl(i) = ta(j);
|
|
change_donn_var=true;
|
|
j++; // on passe au suivant
|
|
break;
|
|
};
|
|
};
|
|
|
|
// cas où il n'y a pas de ddl existant
|
|
if (!rel)
|
|
{// dans le cas d'une famille:
|
|
// on regarde si tous les ddl de la famille font partie de la liste
|
|
if (FoncDim(enu) && (ParaGlob::Dimension()!=1))
|
|
{// on récupère tous les ddl de la famille
|
|
Tableau<Enum_ddl> t_enu =TableauTypeDdl(enu);
|
|
int ttlle = t_enu.Taille();
|
|
// on regarde tout d'abord si les premiers ddl sont présents
|
|
// sachant que enu est le plus petit de la famille ! (car ta est ordonné)
|
|
int iy=0;
|
|
for (iy=1;iy<=ttlle;iy++)
|
|
{if (t_enu(iy)!=enu)
|
|
{ // on regarde également s'il est déjà dans la liste, si oui, on passe
|
|
if (find(li_travail.begin(),li_travail.end(),t_enu(iy)) == li_travail.end())
|
|
{li_travail.push_back(t_enu(iy));
|
|
// on ajoute le ddl pour l'instant hors service et a priori libre
|
|
Ddl addl(t_enu(iy),0.0,HS_LISIBLE_LIBRE);
|
|
liDdl.push_back(addl);
|
|
};
|
|
}
|
|
else
|
|
{ // on regarde également s'il est déjà dans la liste, si oui, on passe
|
|
if (find(li_travail.begin(),li_travail.end(),t_enu(iy)) == li_travail.end())
|
|
{li_travail.push_back(t_enu(iy));
|
|
// il n'existe pas , on ajoute le bon ddl
|
|
liDdl.push_back(ta(j));
|
|
}
|
|
else // il exite, on met la bonne valeur
|
|
{ list <Ddl >::iterator ith,ithfin=liDdl.end();
|
|
for (ith = liDdl.begin();ith!=ithfin;ith++)
|
|
{ if ((*ith).Id_nom() == t_enu(iy))
|
|
{(*ith)=ta(j);break;}
|
|
};
|
|
};
|
|
break;
|
|
};
|
|
};
|
|
|
|
iy++; // on passe à l'enu suivant des ddl de la famille
|
|
// maintenant on balaie les enu restants si nécessaire
|
|
j++; //on incrémente car on regarde l'élément suivant du tableau
|
|
for (;iy<=ttlle;iy++)
|
|
{ if(j <= tataille) // donc j est valide
|
|
{ if ((t_enu(iy)!=ta(j).Id_nom()))
|
|
{ // on regarde également s'il est déjà dans la liste, si oui, on passe
|
|
if (find(li_travail.begin(),li_travail.end(),t_enu(iy)) == li_travail.end())
|
|
{li_travail.push_back(t_enu(iy));
|
|
// on ajoute le ddl pour l'instant hors service et a priori libre
|
|
Ddl addl(t_enu(iy),0.0,HS_LISIBLE_LIBRE);
|
|
liDdl.push_back(addl);
|
|
};
|
|
}
|
|
else
|
|
{ // on regarde également s'il est déjà dans la liste, si oui, on passe
|
|
if (find(li_travail.begin(),li_travail.end(),t_enu(iy)) == li_travail.end())
|
|
{li_travail.push_back(t_enu(iy));
|
|
// il n'existe pas , on ajoute le bon ddl
|
|
liDdl.push_back(ta(j));
|
|
}
|
|
else // il exite, on met la bonne valeur
|
|
{ list <Ddl >::iterator ith,ithfin=liDdl.end();
|
|
for (ith = liDdl.begin();ith!=ithfin;ith++)
|
|
{ if ((*ith).Id_nom() == t_enu(iy))
|
|
{(*ith)=ta(j);break;}
|
|
};
|
|
};
|
|
break;
|
|
};
|
|
}
|
|
else // cas ou le j n'est plus valide on rajoute les ddl manquants
|
|
{ // on regarde également s'il est déjà dans la liste, si oui, on passe
|
|
if (find(li_travail.begin(),li_travail.end(),t_enu(iy)) == li_travail.end())
|
|
{li_travail.push_back(t_enu(iy));
|
|
// on ajoute le ddl pour l'instant hors service et a priori libre
|
|
Ddl addl(t_enu(iy),0.0,HS_LISIBLE_LIBRE);
|
|
liDdl.push_back(addl);
|
|
};
|
|
};
|
|
};
|
|
}
|
|
else // cas d'un ddl qui n'appartient pas à une famille
|
|
// on l'ajoute tout simplement
|
|
{ liDdl.push_back(ta(j));
|
|
j++;
|
|
};
|
|
}//-- fin du cas on on ajoute des ddl à la liste
|
|
} while (j<=tataille) ;
|
|
|
|
};
|
|
|
|
// modification du type de laison entre noeud éventuel avec init des tableaux de liaison
|
|
// pour le cas d'assemblage nb_assemb
|
|
void Noeud::Change_Enu_liason(int nb_assemb, Enum_liaison_noeud enu_liai
|
|
,const Tableau <Posi_ddl_noeud>& tab_N_lier)
|
|
{
|
|
// on fait tout d'abord une petite vérification
|
|
if (enu_liai && ((tab_N_lier.Taille() == 0)))
|
|
{ cout << "\n inchoerence !! on veut une liaison entre noeud mais le tableau de liaison est vide ! "
|
|
<< "\n nb_assemb= "<< nb_assemb << " Enum_liaison_noeud= "<< Nom_liaison_noeud(enu_liai)
|
|
<< " taille de tab_N_lier= " << tab_N_lier.Taille()
|
|
<< "\n Noeud::Change_Enu_liason(... "<<endl;
|
|
Sortie(1);
|
|
};
|
|
if (!enu_liai && ((tab_N_lier.Taille() != 0)))
|
|
{ cout << "\n inchoerence !! on ne veut pas de liaison entre noeud mais le tableau de liaison n'est pas vide ! "
|
|
<< "\n nb_assemb= "<< nb_assemb << " Enum_liaison_noeud= "<< Nom_liaison_noeud(enu_liai)
|
|
<< " taille de tab_N_lier= " << tab_N_lier.Taille()
|
|
<< "\n Noeud::Change_Enu_liason(... "<<endl;
|
|
Sortie(1);
|
|
};
|
|
|
|
// puis on met à jour les dimensions des tableaux en fonction du numéro d'assemblage
|
|
if (tab_enu_liaison == NULL) // cas où rien n'existe
|
|
{tab_enu_liaison = new Tableau <Enum_liaison_noeud>;
|
|
tab_ddl_lier = new Tableau < Tableau <Posi_ddl_noeud> > ;
|
|
};
|
|
// cas où il faut augmenter les tailles
|
|
if (nb_assemb > tab_enu_liaison->Taille())
|
|
{tab_enu_liaison->Change_taille(nb_assemb);
|
|
tab_ddl_lier->Change_taille(nb_assemb);
|
|
};
|
|
// maintenant on renseigne les valeurs
|
|
(*tab_enu_liaison)(nb_assemb) = enu_liai;
|
|
(*tab_ddl_lier)(nb_assemb) = tab_N_lier;
|
|
};
|
|
|
|
// suppression de tous les liaisons noeuds
|
|
void Noeud::Suppression_tous_liaisons_noeuds()
|
|
{ if (tab_enu_liaison != NULL)
|
|
delete tab_enu_liaison;
|
|
if (tab_ddl_lier != NULL)
|
|
delete tab_ddl_lier;
|
|
};
|
|
|
|
// sortie du schemaXML: en fonction de enu
|
|
void Noeud::SchemaXML_Noeud(ofstream& sort,const Enum_IO_XML enu)
|
|
{ switch (enu)
|
|
{case XML_TYPE_GLOBAUX:
|
|
{// on définit des types pour un maillage
|
|
sort << "\n <!-- *************************** un noeud de maillage *************************** -->"
|
|
<< "\n<xs:complexType name=\"Noeud\" >"
|
|
<< "\n <xs:annotation>"
|
|
<< "\n <xs:documentation> un numero et 3 coordonnees </xs:documentation>"
|
|
<< "\n </xs:annotation>"
|
|
<< "\n <xs:sequence>"
|
|
<< "\n <xs:element name=\"numero\" type=\"xs:integer\" />"
|
|
<< "\n <xs:element name=\"coordonnees\" >"
|
|
<< "\n <xs:simpleType>"
|
|
<< "\n <xs:restriction base=\"liste_de_reels\">"
|
|
<< "\n <xs:minLength value=\"3\" />"
|
|
<< "\n <xs:maxLength value=\"3\" />"
|
|
<< "\n </xs:restriction>"
|
|
<< "\n </xs:simpleType>"
|
|
<< "\n </xs:element>"
|
|
<< "\n </xs:sequence>"
|
|
<< "\n</xs:complexType>";
|
|
break;
|
|
}
|
|
case XML_IO_POINT_INFO:
|
|
{ // définition d'une liste de noeuds
|
|
// sort << "\n <xs:element name=\"les_noeuds\" type=\"noeud_maillage\" "
|
|
// << "\n minOccurs=\"1\" maxOccurs=\"unbounded\" />";
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|