329 lines
12 KiB
C++
Executable file
329 lines
12 KiB
C++
Executable file
|
|
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
|
|
#include "DdlElement.h"
|
|
|
|
|
|
// CONSTRUCTEURS :
|
|
// par defaut
|
|
DdlElement::DdlElement () :
|
|
te(),nbddl(0),tab_enum_famille() {};
|
|
// definition du tableau pour n noeuds vide
|
|
DdlElement::DdlElement (int n) :
|
|
te(n),nbddl(0),tab_enum_famille()
|
|
{ };
|
|
// definition du tableau pour n noeuds et m ddl par noeud
|
|
// utile lorsque tous les noeuds ont le meme nombre de ddl
|
|
// par contre ici aucun ddl n'est encore défini
|
|
DdlElement::DdlElement (int n, int m) :
|
|
te(n),nbddl(n*m),tab_enum_famille()
|
|
{ for (int i=1; i<= n;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
tb.Change_taille (m);
|
|
for (int j=1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
};
|
|
// def du nombre des types particuliers de ddl, ici il s'agit de NU_DDL
|
|
Calcul_NbDdl_typer();
|
|
};
|
|
// definition du tableau pour n noeuds et un nombre de ddl par noeud
|
|
// stocke dans le tableau mddl qui doit avoir la dimension n
|
|
// par contre ici aucun ddl n'est encore défini
|
|
DdlElement::DdlElement (int n,const Tableau <int>& mddl) :
|
|
te(n),tab_enum_famille()
|
|
{ if (mddl.Taille() == n)
|
|
for (int i=1; i<= n;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int m = mddl(i);
|
|
tb.Change_taille (m);
|
|
for (int j=1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
}
|
|
else
|
|
{ cout << "\n erreur de dimension pour le tableau mddl, il doit avoir la ";
|
|
cout << " dimension : " << n << ", alors qu\'il a la dimension : "
|
|
<< mddl.Taille() << "\nDdlElement (int n, Tableau <int> mddl)" << endl;
|
|
Sortie (1);
|
|
}
|
|
// def du nombre total et des types particuliers de ddl
|
|
Calcul_NbDdl(); Calcul_NbDdl_typer();
|
|
};
|
|
|
|
// definition du tableau pour n noeuds et une meme liste de ddl pour chaque
|
|
// noeud identique au second argument
|
|
DdlElement::DdlElement (int n, DdlNoeudElement d) :
|
|
te(n,d),nbddl(n * d.tb.Taille()),tab_enum_famille()
|
|
{ // def du nombre total et des types particuliers de ddl
|
|
Calcul_NbDdl(); Calcul_NbDdl_typer();
|
|
};
|
|
|
|
DdlElement::DdlElement (const DdlElement& a) :
|
|
te(a.te),nbddl(a.nbddl),tab_enum_famille(a.tab_enum_famille)
|
|
{}; // de copie
|
|
// DESTRUCTEUR :
|
|
DdlElement::~DdlElement () {};
|
|
|
|
// acces en modification au ddl j du noeud i
|
|
void DdlElement::Change_Enum(int i,int j,const Enum_ddl enu)
|
|
{tab_enum_famille[PremierDdlFamille((te(i)).tb(j))]--;
|
|
(te(i)).tb(j) = enu;
|
|
tab_enum_famille[PremierDdlFamille(enu)]++;
|
|
};
|
|
|
|
// nombre de ddl du noeudElement i contenu
|
|
int DdlElement::NbDdl(int i) const
|
|
{ return (te(i)).tb.Taille();};
|
|
|
|
// change la dimension du tableau de ddl pour n noeuds et m ddl par noeud
|
|
//dans le cas ou tous les noeuds ont le meme nombre de ddl
|
|
// si la nouvelle taille est plus petite: suppression
|
|
// si la nouvelle dimension est plus grande on met les ddl suplémentaires à NU_DDL
|
|
void DdlElement::Change_taille(int n,int m)
|
|
{ int oldTaille = te.Taille();
|
|
te.Change_taille(n);
|
|
int deltataille = n-oldTaille;
|
|
if (deltataille > 0)
|
|
{ // cas où on augmente la taille
|
|
// 1) on traite différemment les anciens ddl et les nouveaux
|
|
for (int i=1;i<=oldTaille;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int otaille = tb.Taille();
|
|
if (m<=otaille)
|
|
{// on supprime sans pb
|
|
tb.Change_taille(m);
|
|
}
|
|
else // on augmente avec des ddl NU_DDL
|
|
{tb.Change_taille(m);
|
|
for (int j=otaille+1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
};
|
|
};
|
|
// 2) les nouveaux DdlNoeudElement sont mis à NU_DDL
|
|
for (int i1=oldTaille+1;i1<= n;i1++)
|
|
{ Tableau <Enum_ddl>& tb=te(i1).tb;
|
|
for (int j1=1;j1<=m;j1++)
|
|
tb(j1)=NU_DDL;
|
|
};
|
|
}
|
|
else // si on diminue
|
|
{ for (int i=1;i<=oldTaille;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int otaille = tb.Taille();
|
|
if (m<=otaille)
|
|
{// on supprime sans pb
|
|
tb.Change_taille(m);
|
|
}
|
|
else // on augmente avec des ddl NU_DDL
|
|
{tb.Change_taille(m);
|
|
for (int j=otaille+1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
};
|
|
};
|
|
};
|
|
nbddl = n*m;
|
|
Calcul_NbDdl_typer(); // mise à jour du nombre de ddl de chaque type
|
|
};
|
|
|
|
// change la dimension du tableau de ddl pour n noeuds et un nombre de ddl par noeud
|
|
// stocke dans le tableau mddl qui doit avoir la dimension n
|
|
// si la nouvelle taille est plus petite: suppression
|
|
// si la nouvelle dimension est plus grande on met les ddl suplémentaires à NU_DDL
|
|
void DdlElement::Change_taille(int n,Tableau <int> mddl)
|
|
{ int oldTaille = te.Taille();
|
|
te.Change_taille(n);
|
|
nbddl = 0;
|
|
if (mddl.Taille() == n)
|
|
{int deltataille = n-oldTaille;
|
|
if (deltataille > 0)
|
|
{ // cas où on augmente la taille
|
|
// 1) on traite différemment les anciens ddl et les nouveaux
|
|
for (int i=1;i<=oldTaille;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int otaille = tb.Taille();
|
|
int m = mddl(i);nbddl += m;
|
|
if (m<=otaille)
|
|
{// on supprime sans pb
|
|
tb.Change_taille(m);
|
|
}
|
|
else // on augmente avec des ddl NU_DDL
|
|
{tb.Change_taille(m);
|
|
for (int j=otaille+1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
};
|
|
};
|
|
// 2) les nouveaux DdlNoeudElement sont mis à NU_DDL
|
|
for (int i1=oldTaille+1;i1<= n;i1++)
|
|
{ Tableau <Enum_ddl>& tb=te(i1).tb;
|
|
int m = mddl(i1);nbddl += m;
|
|
for (int j1=1;j1<=m;j1++)
|
|
tb(j1)=NU_DDL;
|
|
};
|
|
}
|
|
else // si on diminue
|
|
{ for (int i=1;i<=oldTaille;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int otaille = tb.Taille();
|
|
int m = mddl(i); nbddl += m;
|
|
if (m<=otaille)
|
|
{// on supprime sans pb
|
|
tb.Change_taille(m);
|
|
}
|
|
else // on augmente avec des ddl NU_DDL
|
|
{tb.Change_taille(m);
|
|
for (int j=otaille+1;j<=m;j++)
|
|
tb(j)=NU_DDL;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{ cout << "\n erreur de dimension pour le tableau mddl, il doit avoir la ";
|
|
cout << " dimension : " << n << ", alors qu\'il a la dimension : "
|
|
<< mddl.Taille() << "\nChange_taille(int n,Tableau <int> mddl)" << endl;
|
|
Sortie (1);
|
|
}
|
|
Calcul_NbDdl_typer(); // mise à jour du nombre de ddl de chaque type
|
|
};
|
|
|
|
// met le tableau de ddl a zero
|
|
void DdlElement::TailleZero()
|
|
{ int maxi_elem = te.Taille();
|
|
for (int i=1; i<=maxi_elem;i++)
|
|
(te(i)).tb.Change_taille (0);
|
|
te.Change_taille(0);
|
|
nbddl = 0;
|
|
tab_enum_famille.erase(tab_enum_famille.begin(),tab_enum_famille.end());
|
|
};
|
|
// change un des ddlNoeudElements
|
|
void DdlElement::Change_un_ddlNoeudElement(int i,const DdlNoeudElement& add)
|
|
{ int nbdold = te(i).tb.Taille();
|
|
nbddl -= nbdold;
|
|
int nbdnew = add.tb.Taille();
|
|
nbddl += nbdnew;
|
|
// mise en place de add
|
|
te(i)=add;
|
|
// mise à jour des ddl par famille
|
|
Calcul_NbDdl_typer(); // mise à jour du nombre de ddl de chaque type
|
|
/*Tableau <Enum_ddl>& tb=te(i).tb;
|
|
for (int j=1;j<=nbdold;j++)
|
|
(tab_enum_famille[PremierDdlFamille(tb(j))])--;
|
|
for (int i=1;i<= nbdnew;i++)
|
|
(tab_enum_famille[PremierDdlFamille(add.tb(i))])++;*/
|
|
};
|
|
|
|
// surcharge de l'operateur d'affectation
|
|
DdlElement& DdlElement::operator = (const DdlElement & a)
|
|
{ int nb = a.NbNoeud();
|
|
this->te.Change_taille(nb);
|
|
for (int i=1;i<= nb;i++)
|
|
this->te(i) = a(i);
|
|
// mise à jour du nombre de ddl
|
|
nbddl = a.nbddl; tab_enum_famille = a.tab_enum_famille;
|
|
return *this;
|
|
};
|
|
// surcharge des operator de test
|
|
bool DdlElement::operator == (const DdlElement & a) const
|
|
{ int nb = a.NbNoeud();
|
|
for (int i=1;i<=nb;i++)
|
|
if (this->te(i) != a(i)) return false;
|
|
return true;
|
|
};
|
|
bool DdlElement::operator != (const DdlElement & a) const
|
|
{ if (*this == a) return false; else return true;
|
|
};
|
|
|
|
// surcharge de l'operator de lecture
|
|
istream & operator >> (istream & entree, DdlElement& a)
|
|
{ // vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "DdlElement")
|
|
{Sortie (1);
|
|
return entree;
|
|
}
|
|
// entrée du tableau
|
|
entree >> a.te;
|
|
// puis def du nombre total de ddl
|
|
a.Calcul_NbDdl();
|
|
a.Calcul_NbDdl_typer(); // mise à jour du nombre de ddl de chaque type
|
|
return entree;
|
|
};
|
|
// surcharge de l'operator d'ecriture
|
|
ostream & operator << (ostream & sort, const DdlElement& a)
|
|
{ // tout d'abord un indicateur donnant le type
|
|
sort << "DdlElement " ;
|
|
// puis le tableau
|
|
sort << a.te;
|
|
return sort;
|
|
};
|
|
|
|
// retour du nombre de ddl d'une famille donnée
|
|
int DdlElement::NbDdl_famille(Enum_ddl enu) const
|
|
{ // pour l'instant on sort la totalité des ddl ce qui est faux mais permet de fonctionner comme avant
|
|
// return nbddl;
|
|
map < Enum_ddl, Int_initer , std::less <Enum_ddl> >::const_iterator il = tab_enum_famille.find(enu);
|
|
if (il == tab_enum_famille.end()) return 0; else return (*il).second.vali;
|
|
};
|
|
|
|
//================================= methodes proteges ==================
|
|
|
|
// calcul du nb de ddl
|
|
void DdlElement::Calcul_NbDdl()
|
|
{ nbddl = 0;
|
|
int tetaille = te.Taille();
|
|
for (int i=1; i<= tetaille;i++)
|
|
nbddl += (te(i)).tb.Taille();
|
|
};
|
|
|
|
// calcul du nb de ddl de chaque type contenu
|
|
void DdlElement::Calcul_NbDdl_typer()
|
|
{ // méthode en utilisant "tab_enum_famille"
|
|
// qui est un tableau associatif
|
|
// on commence par initialiser le tableau
|
|
tab_enum_famille.erase(tab_enum_famille.begin(),tab_enum_famille.end());
|
|
// on passe en revue tous les ddl
|
|
int tetaille = te.Taille();
|
|
for (int i=1; i<= tetaille;i++)
|
|
{ Tableau <Enum_ddl>& tb=te(i).tb;
|
|
int nbd= tb.Taille();
|
|
for (int j=1;j<=nbd;j++)
|
|
(tab_enum_famille[PremierDdlFamille(tb(j))])++;
|
|
}
|
|
/* // pour vérif
|
|
map < Enum_ddl, Int_initer , std::less <Enum_ddl> >::iterator il,ilfin=tab_enum_famille.end();
|
|
for (il=tab_enum_famille.begin();il != ilfin;il++)
|
|
cout << "\n ddl= " << (*il).first << " nombre " << (*il).second.vali << endl;
|
|
|
|
cout << "toto ?";
|
|
int toto; cin >> toto; */
|
|
};
|
|
|
|
|