// 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) . // // 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 . // // For more information, please consult: . #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 & 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 & mddl) : te(n),tab_enum_famille() { if (mddl.Taille() == n) for (int i=1; i<= n;i++) { Tableau & 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 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 & 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 & 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 & 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 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 & 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 & 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 & 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 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 & 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 >::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 & 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 >::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; */ };