Herezh_dev/herezh_pp/Maillage/Maillage2.cc

1784 lines
84 KiB
C++
Executable file

// FICHIER : Maillage.cp
// CLASSE : Maillage
// 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 "Maillage.h"
# include <iostream>
using namespace std; //introduces namespace std
#include <stdlib.h>
#include "Sortie.h"
#include <stdio.h>
#include <vector>
#include "List_io.h"
#include "CharUtil.h"
#ifndef SYSTEM_MAC_OS_X_unix
#include "Frontier.h"
#endif
#include "ConstMath.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "Util.h"
#include "MvtSolide.h"
// --------- utilitaires de manipulation de maillage
// test pour savoir si le maillage contiend des éléments à interpolation linéaire
bool Maillage::Contient_lineaire()
{ // on balaie les éléments
int taille_elem = tab_element.Taille();
for (int i=1; i<=taille_elem;i++)
{ Enum_interpol eninter = tab_element(i)->Id_interpolation();
// LINEAIRE indique que l'on a une interpolation linéaire
if (eninter == LINEAIRE) return true;
}
// sinon pas d'élément incomplet quadratique
return false;
};
bool Maillage::Contient_quadratique_incomplet()
{ // on balaie les éléments
int taille_elem = tab_element.Taille();
for (int i=1; i<=taille_elem;i++)
{ Enum_interpol eninter = tab_element(i)->Id_interpolation();
// QUADRATIQUE indique que l'on a une interpolation quadratique incomplète
// alors que QUADRACOMPL indique que c'est quadratique complet
if (eninter == QUADRATIQUE) return true;
}
// sinon pas d'élément incomplet quadratique
return false;
};
// transformation des éléments linéaires du maillage en quadratiques.
// les éléments linéaires sont supprimés,
// Important: dans la procédure de renumérotation, la routine modifie la numérotation initiale des noeuds !!
// il y a également création de référence adaptée au nouveau maillage en cohérence avec l'ancien maillage
void Maillage::Transfo_lin_quadraIncomp(LesReferences &lesRef)
{list <Element *> nv_remplace;
list <Maillage::PosiEtNoeud> li_nv_noeud;
list <DeuxEntiers> li_bornes;
// 1) on balaie les éléments
int nbnt=tab_noeud.Taille(); // le nombre de noeud total (évolue pendant la transformation)
// nbnt permet à Construct_from_imcomplet de donner des numéros de noeud licite, en particulier
// permet d'éviter que deux noeuds aient le même numéro
int taille_elem = tab_element.Taille();
for (int i=1; i<=taille_elem;i++)
{ Enum_interpol eninter = tab_element(i)->Id_interpolation();
// LINEAIRE indique que l'on a une interpolation linéaire
if (eninter == LINEAIRE)
{// 2) on a trouvé un linéaire
// on crée un quadratique incomplet de même type
Element * elem = tab_element(i); // pour simplifier
Element::Signature signa = elem->Signature_element();
// on change l'interpolation
signa.id_interpol=QUADRATIQUE;
// on crée le nouvel élément quadratique avec le même numéro que le linéaire (car il le remplacera
// par la suite)
Element* elem2= Element::Choix_element(elem->Num_maillage(),elem->Num_elt(),signa);
if (elem2 == NULL)
{ cout << "\n erreur de creation d'un element quadratique incomplet a partir d'un lineaire"
<< "\n signature du lineaire: interpolation " << Nom_interpol(signa.id_interpol)
<< " geometrie: " << Nom_geom(signa.id_geom) << " problem: " << NomElemTypeProblem(signa.id_problem)
<< " infos_annexes: " << signa.infos_annexes
<< "\n Maillage::Transfo_lin_quadraIncomp(...";
Sortie(1);
}
// 3) on demande à l'élément de définir ses noeuds, d'une part à partir des noeuds
// déjà existants de l'élément linéaire, et d'autre part à partir de nouveaux noeuds
// construit à partir de l'interpolation initiale linéaire.
// on fournit également le premier numéro -1 du nouveau noeud
list <DeuxEntiers> li_bo; // les bornes pour la renumérotation
list <Noeud *> l_nv_noe = elem2->Construct_from_lineaire(*elem,li_bo,nbnt);
nbnt += l_nv_noe.size();
// 4) on ajoute les nouveaux noeuds
list <Noeud *>::iterator lni,lnifin=l_nv_noe.end();
for (lni=l_nv_noe.begin();lni!=lnifin;lni++)
{li_nv_noeud.push_back(Maillage::PosiEtNoeud(*lni,elem2));
}
list <DeuxEntiers>::iterator pni,pnifin=li_bo.end();
for (pni=li_bo.begin();pni!=pnifin;pni++)
{li_bornes.push_back(*pni);
}
// 5) on enregistre l'élément linéaire et on le remplace par le quadratique dans
// la liste d'élément
nv_remplace.push_back(elem);
tab_element(i) = elem2;
}
}
// 6) on supprime les doublons dans la liste des noeuds en réaffectant les bons pointeurs dans les éléments
// li_nv_noeud.sort(); // ordonne la liste
// suppression des doublons et réaffectation des pointeurs de noeuds supprimés dans les éléments
if (li_nv_noeud.size() != 1)
{list <Maillage::PosiEtNoeud>::iterator lili,lilifin = li_nv_noeud.end();
list <Maillage::PosiEtNoeud>::iterator lila = li_nv_noeud.begin();lili=lila; lili++;
list <DeuxEntiers>::iterator pili,pilifin = li_bornes.end();
list <DeuxEntiers>::iterator pila = li_bornes.begin();pili=pila; pili++;
do
{ if (*lila == *lili)
{ //cas de deux noeuds identiques, on réaffecte le pointeur de noeud dans l'élément
(*lila).el->Reaffectation_pointeur_noeud((*lila).noe,(*lili).noe);
// on supprime le noeud doublon
delete (*lila).noe;
// on supprime les éléments de la liste
li_nv_noeud.erase(lila); li_bornes.erase(pila);
}
lila = lili; lili++;
pila = pili; pili++;
} while (lili!= lilifin);
}
// 7) insertion des nouveaux noeuds dans le tableau définitif et renumérotation
// a) on commence par définir une liste de noeud, équivalente au tableau tab_noeud
List_io <Noeud *> li_no;
int nbn = tab_noeud.Taille();
// petite vérif: il faut que le maillage contienne au moins un noeud
#ifdef MISE_AU_POINT
if (nbn == 0)
{ cout << "\n erreur le maillage contiend 0 noeud en propre, ce qui est insufisent pour la routine"
<< "\n list <Element *> Maillage::Transfo_quadraIncomp_quadraComp()";
Sortie(1);
}
#endif
// b) on définit un tableau de listes de pointeurs de noeud
Tableau <List_io<Noeud*> > tab_ln(nbn);
// c) on remplit chaque liste des noeuds qu'il faudrait ajouter pour avoir une bonne numérotation
list <Maillage::PosiEtNoeud>::iterator lili,lilifin = li_nv_noeud.end();
list <DeuxEntiers>::iterator pilifin = li_bornes.end();
list <DeuxEntiers>::iterator pili = li_bornes.begin();
for (lili=li_nv_noeud.begin();lili != lilifin; lili++,pili++)
{ // récup de la position moyenne d'insertion et remplissage de la liste correspondante
// cout << "\n un= " << (*pili).un << "deux= " << (*pili).deux ;
int bi=( (*pili).un + (*pili).deux ) / 2; // division entière
// cout << " bi= " << bi << endl;
tab_ln(bi).push_back((*lili).noe);
}
// d) on définit un nouveau tableau de noeud qui comprend les anciens et les nouveaux noeuds, ordonnées
int nbn_nv = nbn+li_nv_noeud.size();
Tableau<Noeud *> tab_noe_nv(nbn_nv);
// définition également d'un tableau d'indiçage inverse
Tableau <int> indic(nbn);
int ino=0;
for (int ivo=1;ivo<= nbn;ivo++)
{ // tout d'abord le noeud ancien
ino++; tab_noe_nv(ino)=tab_noeud(ivo);
indic(ivo)=ino;
// puis éventuellement les noeuds à intercaler
List_io<Noeud*>& li_ln = tab_ln(ivo); // pour simplifier
if (li_ln.size() != 0)
{ List_io<Noeud*>::iterator iln,iln_end=li_ln.end();
for (iln=li_ln.begin(); iln != iln_end; iln++)
{ ino++; tab_noe_nv(ino)=*iln;};
}
}
tab_noeud = tab_noe_nv; // remplacement du tableau du maillage
// e) on renumérote les différents noeuds
for (int j=1;j<= nbn_nv;j++) tab_noeud(j)->Change_num_noeud(j);
// 7) modification des références sur les noeuds
// a) on passe en revue les références et on sélectionne les références relatives aux noeuds
// de l'ancien maillage
const Reference* ref1 = lesRef.Init_et_Premiere();
do { if((ref1->Nbmaille() == idmail) && (ref1->Indic() == 1))
// on a trouvé une référence de noeud à considérer
{ ReferenceNE * refNE = ( ReferenceNE *) ref1; // pour simplifier
int nb_num=refNE->Taille();
for (int it= 1;it<=nb_num;it++)
refNE->Change_num_dans_ref(it,indic(refNE->Numero(it)));
}
ref1 = lesRef.Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
cout << "\n *** attention les references generes ici ne sont pas bonnes !! , seul le maillage est "
<< " actuellement correcte ";
// 8) suppression des éléments linéaires qui n'ont plus lieu d'être
list <Element *>::iterator lele,lelefin=nv_remplace.end();
for (lele=nv_remplace.begin();lele!=lelefin;lele++)
delete (*lele);
// 9) rien à faire sur les références d'élément, ou de face d'élément ou d'arrête d'élément
// car d'une part les nouveaux éléments ont le même numéro que les anciens, et d'autre part
// le fait de passer en élément complet ne modifie pas les arrêtes ou faces
};
// transformation des éléments quadratiques incomplet du maillage en quadratiques complets.
// les éléments incomplets sont supprimée,
// Important: dans la procédure de renumérotation, la routine modifie la numérotation initiale des noeuds !!
// il y a également création de référence adaptée au nouveau maillage en cohérence avec l'ancien maillage
void Maillage::Transfo_quadraIncomp_quadraComp(LesReferences &lesRef)
{list <Element *> nv_remplace;
list <Maillage::PosiEtNoeud> li_nv_noeud;
list <DeuxEntiers> li_bornes;
// 1) on balaie les éléments
int nbnt=tab_noeud.Taille(); // le nombre de noeud total (évolue pendant la transformation)
// nbnt permet à Construct_from_imcomplet de donner des numéros de noeud licite, en particulier
// permet d'éviter que deux noeuds aient le même numéro
int taille_elem = tab_element.Taille();
for (int i=1; i<=taille_elem;i++)
{ Enum_interpol eninter = tab_element(i)->Id_interpolation();
// QUADRATIQUE indique que l'on a une interpolation quadratique incomplète
// alors que QUADRACOMPL indique que c'est quadratique complet
if (eninter == QUADRATIQUE)
{// 2) on a trouvé un quadratique incomplet
// on crée un quadratique complet de même type
Element * elem = tab_element(i); // pour simplifier
Element::Signature signa = elem->Signature_element();
// on change l'interpolation
signa.id_interpol=QUADRACOMPL;
// on crée le nouvel élément complet avec le même numéro que l'incomplet (car il le remplacera
// par la suite)
Element* elem2= Element::Choix_element(elem->Num_maillage(),elem->Num_elt(),signa);
if (elem2 == NULL)
{ cout << "\n erreur de creation d'un element quadratique complet a partir d'un incomplet"
<< "\n signature du quadratique incomplet: interpolation " << Nom_interpol(signa.id_interpol)
<< " geometrie: " << Nom_geom(signa.id_geom) << " problem: " << NomElemTypeProblem(signa.id_problem)
<< " infos_annexes: " << signa.infos_annexes
<< "\n Maillage::Transfo_quadraIncomp_quadraComp(...";
Sortie(1);
}
// 3) on demande à l'élément de définir ses noeuds, d'une part à partir des noeuds
// déjà existants de l'élément incomplet, et d'autre part à partir de nouveaux noeuds
// construit à partir de l'interpolation initiale incomplète.
// on fournit également le premier numéro -1 du nouveau noeud
list <DeuxEntiers> li_bo; // les bornes pour la renumérotation
list <Noeud *> l_nv_noe = elem2->Construct_from_imcomplet(*elem,li_bo,nbnt);
nbnt += l_nv_noe.size();
// 4) on ajoute les nouveaux noeuds
list <Noeud *>::iterator lni,lnifin=l_nv_noe.end();
for (lni=l_nv_noe.begin();lni!=lnifin;lni++)
{li_nv_noeud.push_back(Maillage::PosiEtNoeud(*lni,elem2));
}
list <DeuxEntiers>::iterator pni,pnifin=li_bo.end();
for (pni=li_bo.begin();pni!=pnifin;pni++)
{li_bornes.push_back(*pni);
}
// 5) on enregistre l'élément incomplet et on le remplace par le complet dans
// la liste d'élément
nv_remplace.push_back(elem);
tab_element(i) = elem2;
}
}
// 6) on supprime les doublons dans la liste des noeuds en réaffectant les bons pointeurs dans les éléments
// non car cela ne sert à rien et il faudrait également traiter li_bornes li_nv_noeud.sort(); // ordonne la liste
// suppression des doublons et réaffectation des pointeurs de noeuds supprimés dans les éléments
if (li_nv_noeud.size() != 1)
{list <Maillage::PosiEtNoeud>::iterator lili,lilifin = li_nv_noeud.end();
list <Maillage::PosiEtNoeud>::iterator lila = li_nv_noeud.begin();lili=lila; lili++;
list <DeuxEntiers>::iterator pili,pilifin = li_bornes.end();
list <DeuxEntiers>::iterator pila = li_bornes.begin();pili=pila; pili++;
do
{ if (*lila == *lili)
{ //cas de deux noeuds identiques, on réaffecte le pointeur de noeud dans l'élément
(*lila).el->Reaffectation_pointeur_noeud((*lila).noe,(*lili).noe);
// on supprime le noeud doublon
delete (*lila).noe;
// on supprime les éléments de la liste
li_nv_noeud.erase(lila); li_bornes.erase(pila);
}
lila = lili; lili++;
pila = pili; pili++;
} while (lili!= li_nv_noeud.end());
};
////------ debug
//{
//cout << "\n debug: Maillage::Transfo_quadraIncomp_quadraComp ";
//list <DeuxEntiers>::iterator pili = li_bornes.begin();
//int i=1;
//for (pili;pili != li_bornes.end();pili++,i++)
// cout << "\n borne "<< i <<": " << *pili;
//cout << endl;
//};
////----- fin debug
// 7) insertion des nouveaux noeuds dans le tableau définitif et renumérotation
// a) on commence par définir une liste de noeud, équivalente au tableau tab_noeud
List_io <Noeud *> li_no;
int nbn = tab_noeud.Taille();
// petite vérif: il faut que le maillage contienne au moins un noeud
#ifdef MISE_AU_POINT
if (nbn == 0)
{ cout << "\n erreur le maillage contiend 0 noeud en propre, ce qui est insufisent pour la routine"
<< "\n list <Element *> Maillage::Transfo_quadraIncomp_quadraComp()";
Sortie(1);
}
#endif
// b) on définit un tableau de listes de pointeurs de noeud
Tableau <List_io<Noeud*> > tab_ln(nbn);
// c) on remplit chaque liste des noeuds qu'il faudrait ajouter pour avoir une bonne numérotation
list <Maillage::PosiEtNoeud>::iterator lili,lilifin = li_nv_noeud.end();
list <DeuxEntiers>::iterator pilifin = li_bornes.end();
list <DeuxEntiers>::iterator pili = li_bornes.begin();
for (lili=li_nv_noeud.begin();lili != lilifin; lili++,pili++)
{ // récup de la position moyenne d'insertion et remplissage de la liste correspondante
int bi=( (*pili).un + (*pili).deux ) / 2; // division entière
////------ debug
//{
//cout << "\n debug: Maillage::Transfo_quadraIncomp_quadraComp ";
// cout << "\n bornes : " << *pili << endl;
//};
////----- fin debug
tab_ln(bi).push_back((*lili).noe);
};
// d) on définit un nouveau tableau de noeud qui comprend les anciens et les nouveaux noeuds, ordonnées
int nbn_nv = nbn+li_nv_noeud.size();
Tableau<Noeud *> tab_noe_nv(nbn_nv);
// définition également d'un tableau d'indiçage inverse
Tableau <int> indic(nbn);
int ino=0;
for (int ivo=1;ivo<= nbn;ivo++)
{ // tout d'abord le noeud ancien
ino++; tab_noe_nv(ino)=tab_noeud(ivo);
indic(ivo)=ino;
// puis éventuellement les noeuds à intercaler
List_io<Noeud*>& li_ln = tab_ln(ivo); // pour simplifier
if (li_ln.size() != 0)
{ List_io<Noeud*>::iterator iln,iln_end=li_ln.end();
for (iln=li_ln.begin(); iln != iln_end; iln++)
{ ino++; tab_noe_nv(ino)=*iln;};
}
}
tab_noeud = tab_noe_nv; // remplacement du tableau du maillage
// e) on renumérote les différents noeuds
for (int j=1;j<= nbn_nv;j++) tab_noeud(j)->Change_num_noeud(j);
// 7) modification des références sur les noeuds
// a) on passe en revue les références et on sélectionne les références relatives aux noeuds
// de l'ancien maillage
const Reference* ref1 = lesRef.Init_et_Premiere();
do { if((ref1->Nbmaille() == idmail) && (ref1->Indic() == 1))
// on a trouvé une référence de noeud à considérer
{ ReferenceNE * refNE = ( ReferenceNE *) ref1; // pour simplifier
int nb_num=refNE->Taille();
for (int it= 1;it<=nb_num;it++)
refNE->Change_num_dans_ref(it,indic(refNE->Numero(it)));
}
ref1 = lesRef.Reference_suivante(); // la référence suivante
} while (ref1 != NULL);
// 8) suppression des élément incomplet qui n'ont plus lieu d'être
list <Element *>::iterator lele,lelefin=nv_remplace.end();
for (lele=nv_remplace.begin();lele!=lelefin;lele++)
delete (*lele);
// 9) rien à faire sur les références d'élément, ou de face d'élément ou d'arrête d'élément
// car d'une part les nouveaux éléments ont le même numéro que les anciens, et d'autre part
// le fait de passer en élément complet ne modifie pas les arrêtes ou faces
};
// Affiche les donnees du maillage dans un fichier
// dont le nom est construit à partir du nom du maillage
// au format ".her" et ".lis"
void Maillage::Affiche_dans_her_lis(LesReferences &lesRef,Enum_dure temps)
{
//------------- écriture du .her -------------
// ouverture du fichier pour les noeuds
char nomm[132];
char*fileName = nomm;
strcpy(fileName, nomDuMaillage.c_str());
ofstream * sur_sort = new ofstream (strcat(fileName,".her"));
ofstream & sort = * sur_sort;
if(!(sort.is_open()))
// le fichier ne peut être ouvert, message d'erreur
{ cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n"
<< " Maillage::Affiche_dans_her_lis(.... " << endl;
Sortie(1);
};
// écriture de l'entete
sort << "\n ###########################################################################"
<< "\n # ecriture automatique d'un maillage au format .her, par Herezh++ #"
<< "\n ###########################################################################"
<< "\n # version: " << ParaGlob::NbVersion() << "\n \n \n ";
// écriture du nom du maillage
sort << "\n nom_maillage " << nomDuMaillage << " # nom du maillage"
<< "\n"
<< "\n noeuds ------------ # definition des noeuds";
int dimen = ParaGlob::Dimension();
// l'entete des noeuds
int nbn = tab_noeud.Taille();
sort << "\n "<< nbn << " NOEUDS # definition du nombre de noeuds"
<< "\n \n"
<< "\n#---------------------------------------------------------------"
<< "\n#|NO DU| X | Y | Z |"
<< "\n#|NOEUD| | | |"
<< "\n#---------------------------------------------------------------"
<< "\n";
// écriture des noeuds
double sero = 0.;
for (int ine=1;ine<=nbn; ine++)
{ sort << "\n" << setw (6) << ine <<" ";
Coordonnee co;
switch (temps)
{
case TEMPS_0 : co=tab_noeud(ine)->Coord0(); break;
// si les noeuds n'ont pas bougés on sort les coordonnées à 0
case TEMPS_t :
{ if (tab_noeud(ine)->ExisteCoord1())
{ co=tab_noeud(ine)->Coord1(); }
else co=tab_noeud(ine)->Coord0();
break;
}
case TEMPS_tdt :
{ if (tab_noeud(ine)->ExisteCoord2())
{ co=tab_noeud(ine)->Coord2(); }
else co=tab_noeud(ine)->Coord0();
break;
}
default :
cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
cout << "Maillage::Affiche_dans_her_lis(.. \n";
Sortie(1);
};
#ifndef ENLINUX_STREAM
sort.setf(ios_base::scientific);
#else
sort.setf(ios::scientific);
#endif
for (int j=1;j<=3;j++)
if (j<=dimen)
sort << setw (18) << setprecision(ParaGlob::NbdigdoCA()) <<co(j) << " ";
else
sort << setw (18) << setprecision(ParaGlob::NbdigdoCA()) << sero << " ";
}
sort << "\n \n";
// entête des éléments
int nbe=tab_element.Taille();
sort << "\n elements ---------- \n"
<< "\n " << nbe << " ELEMENTS # definition du nombre d'elements"
<< "\n #----------------------------------------------------------------------"
<< "\n #| NO | | |"
<< "\n #|ELTS | type element | Noeuds |"
<< "\n #----------------------------------------------------------------------"
<< "\n";
// écriture des éléments
for (int ie=1;ie<=nbe;ie++)
{ sort << "\n" << setw (6) << ie <<" ";
Element::Signature sign = tab_element(ie)->Signature_element();
sort << Nom_geom(sign.id_geom) << " " << Nom_interpol(sign.id_interpol)
<< " " << sign.infos_annexes << " ";
Tableau<Noeud *>& tab_n = tab_element(ie)->Tab_noeud();
int taille_tab_n = tab_n.Taille();
for (int ite=1;ite<=taille_tab_n;ite++)
sort << tab_n(ite)->Num_noeud() << " ";
}
// quelques lignes blanches à la fin du fichier
sort << "\n \n \n";
// fermeture du fichier
delete sur_sort;
//------------- écriture du .lis -------------
// Affiche les donnees des références pour le maillage imail dans un fichier
// dont le nom est construit à partir du nom du maillage au format ".lis"
lesRef.Affiche_dans_lis(nomDuMaillage,idmail);
};
//modification du maillage pour le restreindre aux seuls éléments de la référence passée en paramètre
// toutes les infos relatives à des éléments supprimés, sont également supprimés
void Maillage::Restreint_sous_maillage(LesReferences* lesRef, string nom_ref)
{ // on définit un tableau d'indicateur donnant les éléments non référencés
Tableau <bool> tab_el_non_referencer(tab_element.Taille(),true); // par défaut on ne conserve pas
// on définit un tableau d'indicateur donnant les noeuds non référencés
Tableau <bool> tab_noe_non_referencer(tab_noeud.Taille(),true);
// récup de la référence des éléments
const ReferenceNE & ref =((ReferenceNE &) lesRef->Trouve(nom_ref,idmail));
if (ref.Indic() != 2)
{cout << "\n *** erreur: la reference "<<nom_ref<<" n'est pas une ref d'element "
<< " on ne peut pas continuer ";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Maillage::Restreint_sous_maillage(... ";
Sortie(1);
};
// récup du tableau d'éléments de la référence
const Tableau<int>& tab_E_ref = ref.Tab_num();
// on marque les éléments à conserver ainsi que les noeuds
// qui appartiennent à des éléments à conserver
int nb_el = tab_E_ref.Taille();
for (int i=1;i<=nb_el;i++)
{tab_el_non_referencer(tab_E_ref(i)) = false;
Element * el = tab_element(tab_E_ref(i));
const Tableau<Noeud *>& tab_noeu = el->Tab_noeud_const();
int nb_noe = tab_noeu.Taille();
for (int noe = 1;noe <= nb_noe; noe++)
tab_noe_non_referencer(tab_noeu(noe)->Num_noeud())=false;
};
// suppression des éléments non référencés
int NBE=tab_element.Taille();
for (int i=1;i<=NBE;i++)
if (tab_el_non_referencer(i))
delete tab_element(i);
// suppression des noeuds non référencés
int NBN = tab_noeud.Taille();
int nb_noeud_final = 0; // init
for (int i=1;i<= NBN;i++)
if (tab_noe_non_referencer(i))
{delete tab_noeud(i);}
else {nb_noeud_final++;}; // sinon on compte
// on redimentionne et réafecte le tableau de noeuds
Tableau<Noeud *> tab_old_noe = tab_noeud; // sauvegarde de l'ancien tableau
// nv_tab est tel que : nv_tab_noe(i) est le nouveau numéro qui avait auparavant le numéro "i"
Tableau <int > nv_tab_noe(NBN);
tab_noeud.Change_taille(nb_noeud_final);
int indice_noeu=1; // pour parcourir le tableau final de noeud
for (int i=1;i<=NBN;i++)
if (!tab_noe_non_referencer(i))
{tab_noeud(indice_noeu) = tab_old_noe(i);
nv_tab_noe(i)=indice_noeu;
tab_noeud(indice_noeu)->Change_num_noeud(indice_noeu);
indice_noeu++;
};
// on redimentionne et réafecte le tableau d'élément
Tableau<Element *> tab_old_El = tab_element; // sauvegarde de l'ancien tableau
// nv_tab est tel que : nv_tab_ele(i) est le nouveau numéro qui avait auparavant le numéro "i"
Tableau <int > nv_tab_ele(NBE);
tab_element.Change_taille(nb_el);
int indice_ele=1; // pour parcourir le tableau final d'élément
for (int i=1;i<=NBE;i++)
if (!tab_el_non_referencer(i))
{tab_element(indice_ele) = tab_old_El(i);
nv_tab_ele(i)=indice_ele;
tab_element(indice_ele)->Change_num_elt(indice_ele);
indice_ele++;
};
// on s'occupe maintenant des références
lesRef->Mise_a_jour_ref_element(nv_tab_ele,idmail,tab_el_non_referencer);
lesRef->Mise_a_jour_ref_noeud(nv_tab_noe,idmail,tab_noe_non_referencer);
// toilettage final
listFrontiere.clear();tab_noeud_front.Change_taille(0);indice.Change_taille(0);
mitoyen_de_chaque_element.Change_taille(0);
};
// relocalisation des points milieux des arrêtes des éléments quadratiques
void Maillage::RelocPtMilieuMailleQuadra()
{ // on passe en revue les différents éléments pour voir s'il ont une arrête quadratique
int nbe = tab_element.Taille();
for (int ne=1;ne<=nbe;ne++)
{ // récup de l'élément géométrique
const ElemGeomC0& elgeom = tab_element(ne)->ElementGeometrique_const();
// récup du nombre de segment
int nbse= elgeom.NbSe();
// on boucle sur les segments pour voir s'il y a un quadratique
for (int iseg=1;iseg<=nbse;iseg++)
{ ElemGeomC0 const & elseg = elgeom.ElemSeg(iseg);
if (elseg.TypeInterpolation() == QUADRACOMPL)
{ // récup de la connection des noeuds des arêtes par rapport a ceux de l'element
Tableau<Tableau<int> > const & nonStout = elgeom.NonS();
Tableau <int> const & nonS = nonStout(iseg);
Tableau<Noeud *>& t_noeud = tab_element(ne)->Tab_noeud();
Noeud & N1=*t_noeud(nonS(1));Noeud & N2=*t_noeud(nonS(2));Noeud & N3=*t_noeud(nonS(3));
// ------------- étape de modification du noeud milieu -----------------------
Coordonnee M01= N1.Coord0();Coordonnee M02= N2.Coord0();Coordonnee M03= N3.Coord0();
Coordonnee M1M3=(M03-M01);Coordonnee M1M2=(M02-M01);Coordonnee M2M3=(M03-M02);
double d12=M1M2.Norme();double d13=M1M3.Norme();double d23=M2M3.Norme();
if ((d12 < ConstMath::unpeupetit) || (d13 < ConstMath::unpeupetit) || (d23 < ConstMath::unpeupetit))
{ cout << "\n erreur deux des trois points du segment quadratique sont confondu a l'instant 0"
<< "\n il n'est pas possible d'effectuer la relocalisation du noeud milieu pour ce segment"
<< "\n Maillage::RelocPtMilieuMailleQuadra()";
N1.Affiche(); N2.Affiche(); N3.Affiche();
break;
}
Coordonnee U=M1M3/d13;
// le vecteur normal à U
int dim = ParaGlob::Dimension(); Coordonnee V(dim);
double sinusangle;
switch (dim)
{ case 1: // ici il suffit de prendre le point milieu
{ sinusangle=0.; break;}
case 2 : {V(1) = -U(2); V(2)=U(1);sinusangle = Util::Determinant(U,M1M2);break;}
case 3 : {Coordonnee W = Util::ProdVec_coor(U,M1M2); sinusangle = Util::Determinant(U,M1M2);
if (sinusangle > ConstMath::unpeupetit)
{ W.Normer(); V = Util::ProdVec_coor(W,U);}
break;
}
};
// on vérifie que les 3 points ne sont pas naturellement alignés
if (sinusangle > ConstMath::unpeupetit)
// cas où l'on peut considérer une base locale
{
double N1H = M1M2*U; double HN2 = M1M2*V;
double p1 = d13/2.; double p2 = d13*d13*HN2/(4.*N1H*(d13-N1H));
Coordonnee P = M01 + p1 * U + p2 * V;;
N2.Change_coord0(P); break;
}
else
// cas où les 3 points sont originalement alignés
{ Coordonnee milieu = (M01+M03)/2.;
N2.Change_coord0(milieu); break;
}
// +++++++ si les coordonnées à t existent, même traitement
if (N1.ExisteCoord1())
{ M01= N1.Coord1();M02= N2.Coord1();M03= N3.Coord1();
M1M3=(M03-M01); M1M2=(M02-M01); M2M3=(M03-M02);
d12=M1M2.Norme(); d13=M1M3.Norme(); d23=M2M3.Norme();
if ((d12 < ConstMath::unpeupetit) || (d13 < ConstMath::unpeupetit) || (d23 < ConstMath::unpeupetit))
{ cout << "\n erreur deux des trois points du segment quadratique sont confondu a l'instant t"
<< "\n il n'est pas possible d'effectuer la relocalisation du noeud milieu pour ce segment"
<< "\n Maillage::RelocPtMilieuMailleQuadra()";
N1.Affiche(); N2.Affiche(); N3.Affiche();
break;
}
U=M1M3/d13;
// le vecteur normal à U
switch (dim)
{ case 1: // ici il suffit de prendre le point milieu
{ sinusangle=0.; break;}
case 2 : {V(1) = -U(2); V(2)=U(1);sinusangle = Util::Determinant(U,M1M2);break;}
case 3 : {Coordonnee W = Util::ProdVec_coor(U,M1M2); sinusangle = Util::Determinant(U,M1M2);
if (sinusangle > ConstMath::unpeupetit)
{ W.Normer(); V = Util::ProdVec_coor(W,U);}
break;
}
};
// on vérifie que les 3 points ne sont pas naturellement alignés
if (sinusangle > ConstMath::unpeupetit)
// cas où l'on peut considérer une base locale
{
double N1H = M1M2*U; double HN2 = M1M2*V;
double p1 = d13/2.; double p2 = d13*d13*HN2/(4.*N1H*(d13-N1H));
Coordonnee P = M01 + p1 * U + p2 * V;;
N2.Change_coord1(P); break;
}
else
// cas où les 3 points sont originalement alignés
{ Coordonnee milieu = (M01+M03)/2.;
N2.Change_coord1(milieu); break;
}
}
// +++++ si les coordonnées à t existent, même traitement
if (N1.ExisteCoord2())
{ M01= N1.Coord2();M02= N2.Coord2();M03= N3.Coord2();
M1M3=(M03-M01); M1M2=(M02-M01); M2M3=(M03-M02);
d12=M1M2.Norme(); d13=M1M3.Norme(); d23=M2M3.Norme();
if ((d12 < ConstMath::unpeupetit) || (d13 < ConstMath::unpeupetit) || (d23 < ConstMath::unpeupetit))
{ cout << "\n erreur deux des trois points du segment quadratique sont confondu a l'instant tdt"
<< "\n il n'est pas possible d'effectuer la relocalisation du noeud milieu pour ce segment"
<< "\n Maillage::RelocPtMilieuMailleQuadra()";
N1.Affiche(); N2.Affiche(); N3.Affiche();
break;
}
U=M1M3/d13;
// le vecteur normal à U
switch (dim)
{ case 1: // ici il suffit de prendre le point milieu
{ sinusangle=0.; break;}
case 2 : {V(1) = -U(2); V(2)=U(1);sinusangle = Util::Determinant(U,M1M2);break;}
case 3 : {Coordonnee W = Util::ProdVec_coor(U,M1M2); sinusangle = Util::Determinant(U,M1M2);
if (sinusangle > ConstMath::unpeupetit)
{ W.Normer(); V = Util::ProdVec_coor(W,U);}
break;
}
};
// on vérifie que les 3 points ne sont pas naturellement alignés
if (sinusangle > ConstMath::unpeupetit)
// cas où l'on peut considérer une base locale
{
double N1H = M1M2*U; double HN2 = M1M2*V;
double p1 = d13/2.; double p2 = d13*d13*HN2/(4.*N1H*(d13-N1H));
Coordonnee P = M01 + p1 * U + p2 * V;;
N2.Change_coord2(P); break;
}
else
// cas où les 3 points sont originalement alignés
{ Coordonnee milieu = (M01+M03)/2.;
N2.Change_coord2(milieu); break;
}
}
// ------------- fin de l'étape de modification du noeud milieu - --------------
}
}
}
};
// sortie du schemaXML: en fonction de enu
void Maillage::SchemaXML_Maillages(ofstream& sort,const Enum_IO_XML enu)
{ switch (enu)
{case XML_TYPE_GLOBAUX:
{// on définit des types pour un maillage
Noeud::SchemaXML_Noeud(sort,enu);
// def du type maillage
sort << "\n <xs:complexType name=\"Maillage\" >"
<< "\n <xs:annotation>"
<< "\n <xs:documentation> un nom de maillage, des noeuds, des references de noeuds,"
<< "\n des elements, des references d'elements "
<< "\n </xs:documentation>"
<< "\n </xs:annotation>"
<< "\n <xs:sequence>"
<< "\n <xs:element name=\"nom_du_maillage\" type=\"xs:string\" />"
<< "\n <xs:element name=\"Noeud\" type=\"Noeud\" "
<< "\n minOccurs=\"1\" maxOccurs=\"unbounded\" />";
/* << "\n <xs:complexType>"
<< "\n <xs:element name=\"****les_maillages:_nombre=\" type=\"xs:positiveInteger\" "
<< "\n use=\"required\" minOccurs=\"1\" maxOccurs=\"unbounded\" />"
<< "\n <xs:element name=\"defMaillages\" type=\"Maillage\" use=\"required\" />" */
sort << "\n </xs:sequence>"
<< "\n </xs:complexType>";
break;
}
case XML_IO_POINT_INFO:
{// cas de la définition d'un maillage
/* sort << "\n <xs:element name=\"Maillages\" minOccurs=\"1\" maxOccurs=\"unbounded\" >"
<< "\n <xs:complexType>"
<< "\n <xs:annotation>"
<< "\n <xs:documentation> un nom de maillage, des noeuds, des references de noeuds,"
<< "\n des elements, des references d'elements "
<< "\n </xs:documentation>"
<< "\n </xs:annotation>"
<< "\n <xs:sequence>"
<< "\n <xs:element name=\"nom_du_maillage\" type=\"xs:string\" />"
<< "\n <xs:element name=\"les_noeuds\" type=\"Noeud\" "
<< "\n minOccurs=\"1\" maxOccurs=\"unbounded\" />"*/
/* << "\n <xs:complexType>"
<< "\n <xs:element name=\"****les_maillages:_nombre=\" type=\"xs:positiveInteger\" "
<< "\n use=\"required\" minOccurs=\"1\" maxOccurs=\"unbounded\" />"
<< "\n <xs:element name=\"defMaillages\" type=\"Maillage\" use=\"required\" />" */
/* sort << "\n </xs:sequence>"
<< "\n </xs:complexType>"
<< "\n </xs:element>";*/
// def de Maillage
// SchemaXML_Maillage(sort,niveau);
break;
}
};
};
//---------------------- class de travail ---------------------------
// classe de travail qui sert pour pouvoir classer les noeuds par leur position géométrique initiale
// deux élément sont identiques si leur position initiale sont identique
// a >= b si : soit a.x >= b.x, ou a.x==b.x et a.y >= b.y, ou a.x==b.x et a.y == b.y et a.z >= b.z
Maillage::PosiEtNoeud& Maillage::PosiEtNoeud::operator= (const Maillage::PosiEtNoeud& po) // affectation
{ noe=po.noe; return *this;};
bool Maillage::PosiEtNoeud::operator == (const Maillage::PosiEtNoeud& po) const // test d'égalité
{ if ((noe->Coord0()-po.noe->Coord0()).Norme() <= ConstMath::unpeupetit) return true; else return false; };
bool Maillage::PosiEtNoeud::operator != (const Maillage::PosiEtNoeud& po) const // test d'inégalité
{ if (noe->Coord0() != po.noe->Coord0()) return true; else return false; };
bool Maillage::PosiEtNoeud::operator < (const Maillage::PosiEtNoeud& po) const // relation d'ordre
{ Coordonnee co1=noe->Coord0(); Coordonnee co2=po.noe->Coord0();
switch (co1.Dimension())
{ case 1: return (co1(1) < co2(1));break;
case 2: {if (co1(1) < co2(1)) return true;
else if (co1(1) == co2(1))
{ return (co1(2) < co2(2));}
else return false;
break;}
case 3: {if (co1(1) < co2(1)) return true;
else if (co1(1) == co2(1))
{ if (co1(2) < co2(2)) return true;
else if (co1(2) == co2(2))
{ return (co1(3) < co2(3));}
else false;
}
return false;
break;
}
default:
{ cout << "\n erreur le cas différent de 1 2 3 n'est pas admissible ici= " << co1.Dimension()
<< "\n bool Maillage::PosiEtNoeud::operator < (co... ";
Sortie(1);
}
};
Sortie(1); // ne doit jamais passer ici !!
return false;
};
bool Maillage::PosiEtNoeud::operator <= (const Maillage::PosiEtNoeud& po) const // relation d'ordre
{ Coordonnee co1=noe->Coord0(); Coordonnee co2=po.noe->Coord0();
switch (co1.Dimension())
{ case 1: return (co1(1) <= co2(1));break;
case 2: {if (co1(1) < co2(1)) return true;
else if (co1(1) == co2(1))
{ return (co1(2) <= co2(2));}
else return false;
break;}
case 3: {if (co1(1) < co2(1)) return true;
else if (co1(1) == co2(1))
{ if (co1(2) < co2(2)) return true;
else if (co1(2) == co2(2))
{ return (co1(3) <= co2(3));}
else false;
}
return false;
break;
}
default:
{ cout << "\n erreur le cas différent de 1 2 3 n'est pas admissible ici= " << co1.Dimension()
<< "\n bool Maillage::PosiEtNoeud::operator <= (co... ";
Sortie(1);
}
};
Sortie(1); // ne doit jamais passer ici !!
return false;
};
bool Maillage::PosiEtNoeud::operator > (const Maillage::PosiEtNoeud& po) const // relation d'ordre
{ return !(*this <= po);};
bool Maillage::PosiEtNoeud::operator >= (const Maillage::PosiEtNoeud& po) const // relation d'ordre
{ return !(*this < po);};
// transfert de grandeurs des points d'intégration aux noeuds
// 1- en entrée les type évolués et quelconques que l'on veut transférer
// 2- en entrée: cas qui indique la méthode de transfert à utiliser
// =1 : les valeurs aux noeuds sont obtenue par moyennage
// des valeurs des pts d'integ les plus près
// des éléments qui entourent le noeud
// on décompose le processus en 3 étapes pour éviter d'initialiser plusieurs
// fois lorque l'on refait à chaque fois
// le même transfert
// A) première étape def des conteneurs et c'est tout, la méthode peut donc être utilisée
// pour autre chose. tabQ: permet d'avoir plusieurs listes de TypeQuelconque
// en entrée: tabQ doit-être de dimension 2, donc pointe sur 2 listes, si un des pointeur
// est nulle on n'en tient pas compte
void Maillage::AjoutConteneurAuNoeud(const List_io < Ddl_enum_etendu >& lienu
,const Tableau <List_io < TypeQuelconque > * >& tabQ)
{ // on crée des tableaux pour optimiser le nombre d'appel aux fonctions d'ajout de grandeur aux noeuds
// 1) cas des Ddl_enum_etendu
Tableau <Ddl_enum_etendu > tab_ddlEnuEtendu(lienu.size());
{List_io < Ddl_enum_etendu >::const_iterator ilienu,ilienufin = lienu.end();
int indice = 1;
for (ilienu = lienu.begin();ilienu != ilienufin; ilienu++,indice++)
tab_ddlEnuEtendu(indice) = (*ilienu);
};
// 2) cas des grandeurs quelconques
Tableau < TypeQuelconque > tabglobQ;
int ttai = 0;
if (tabQ(1) != NULL) ttai += tabQ(1)->size();
if (tabQ(2) != NULL) ttai += tabQ(2)->size();
tabglobQ.Change_taille(ttai);
int indice = 1;
if (tabQ(1) != NULL)
{List_io < TypeQuelconque >::const_iterator itabQ,itabQfin = tabQ(1)->end();
for (itabQ = tabQ(1)->begin();itabQ != itabQfin; itabQ++,indice++)
{tabglobQ(indice).ChangeGrandeur(*itabQ); // on commence par changer la grandeur
tabglobQ(indice) = (*itabQ); // et on affecte
};
};
if (tabQ(2) != NULL)
{List_io < TypeQuelconque >::const_iterator itabQ,itabQfin = tabQ(2)->end();
for (itabQ = tabQ(2)->begin();itabQ != itabQfin; itabQ++,indice++)
{tabglobQ(indice).ChangeGrandeur(*itabQ); // on commence par changer la grandeur
tabglobQ(indice) = (*itabQ); // et on affecte
};
};
int nbN=tab_noeud.Taille();
// on met à jour les noeuds
for(int i=1;i<=nbN;i++)
{ // Pour les grandeurs ddl étendu on les ajoutes aux noeuds si ce n'est pas déjà fait
tab_noeud(i)->AjoutTabDdl_etendu(tab_ddlEnuEtendu);
// on ajoute également les différents types quelconques aux noeuds
tab_noeud(i)->AjoutTabTypeQuelconque(tabglobQ);
// on met à jour le tableau d'indice de noeud, qui donne le nombre de fois où chaque noeud à été updaté
tab_noeud(i)->Mise_non_update_Ddl_etendu();
tab_noeud(i)->Mise_non_update_grandeurs_quelconques();
};
};
// B) initialisation des updates sur les noeuds
void Maillage::InitUpdateAuNoeud(const List_io < Ddl_enum_etendu >& lienetendu
,const Tableau <List_io < TypeQuelconque > * >& tabQ, int )
{int nbN=tab_noeud.Taille();
List_io <Ddl_enum_etendu>::const_iterator iliet,ilietfin = lienetendu.end();
List_io <TypeQuelconque>::const_iterator iliGQ,iliGQfin;
// on met à jour tous les noeuds
for(int inoeud=1;inoeud<=nbN;inoeud++)
{for (iliet = lienetendu.begin();iliet != ilietfin; iliet++)
{Ddl_etendu& dd = tab_noeud(inoeud)->ModifDdl_etendu(*iliet);
// on initialise la grandeur pointée:
dd.Valeur()=0.;
// mise à 0 du nombre d'appel
tab_noeud(inoeud)->Mise_non_update_Ddl_etendu(*iliet);
};
for (int iQu=1;iQu<=tabQ.Taille();iQu++)
{if (tabQ(iQu) != NULL)
{iliGQfin = tabQ(iQu)->end();
for (iliGQ = tabQ(iQu)->begin();iliGQ != iliGQfin; iliGQ++)
{TypeQuelconque& tq = tab_noeud(inoeud)->ModifGrandeur_quelconque((*iliGQ).EnuTypeQuelconque());
TypeQuelconque::Grandeur & grandeur = *(tq.Grandeur_pointee());
// on initialise la grandeur pointée:
grandeur *= 0.;
// mise à 0 du nombre d'appel
tab_noeud(inoeud)->Mise_non_update_grandeurs_quelconques((*iliGQ).EnuTypeQuelconque());
};
}
};
};
};
// D) dernière étape: (par exemple calcul des moyennes en chaque noeuds)
void Maillage::FinTransfertPtIntegAuNoeud
(const List_io < Ddl_enum_etendu >& lienetendu,const Tableau <List_io < TypeQuelconque > * >& tabQ,int cas)
{switch(cas)
{ case 1: // cas du transfert par moyennage
{ int nbN=tab_noeud.Taille();
List_io <Ddl_enum_etendu>::const_iterator iliet,ilietfin = lienetendu.end();
List_io <TypeQuelconque>::const_iterator iliGQ,iliGQfin;
// on passe en revue les grandeurs aux noeuds, et on les moyennes
for(int inoeud=1;inoeud<=nbN;inoeud++)
{ // .. pour les ddl étendus ..
for (iliet = lienetendu.begin();iliet != ilietfin; iliet++)
{Ddl_etendu& dd = tab_noeud(inoeud)->ModifDdl_etendu(*iliet);
// on modifie la grandeur pointée: -1 car ici on vient d'appeler
// ModifDdl_etendu qui comptabilise un appel de +
// dd.Valeur()/=(tab_noeud(inoeud)->DdlEtendue_update(*iliet)-1);
int nbappel = MaX((tab_noeud(inoeud)->DdlEtendue_update(*iliet)-1),1);
dd.Valeur()/=nbappel;
};
// .. pour les grandeurs quelconques ..
for (int iQu=1;iQu<=tabQ.Taille();iQu++)
{if (tabQ(iQu) != NULL)
{iliGQfin = tabQ(iQu)->end();
for (iliGQ = tabQ(iQu)->begin();iliGQ != iliGQfin; iliGQ++)
{TypeQuelconque_enum_etendu enuQ = (*iliGQ).EnuTypeQuelconque();
TypeQuelconque& tq = tab_noeud(inoeud)->ModifGrandeur_quelconque(enuQ);
TypeQuelconque::Grandeur & grandeur = *(tq.Grandeur_pointee());
// on modifie les grandeurs pointées: -1 car ici on vient d'appeler
// ModifGrandeur_quelconque qui comptabilise un appel de +
grandeur /= MaX((tab_noeud(inoeud)->Grandeur_quelconque_update(enuQ)-1),1);
//--- debug
//if (iliGQ == tabQ(iQu)->begin())
// cout << " noeud " << inoeud << " grandeur " << grandeur << endl;
//--- fin debug
};
}
};
};
break;
}
default :
cout << "\n *** cas non implante, cas = " << cas
<< "\n FinTransfertPtIntegAuNoeud(... ";
Sortie(1);
};
};
// fonctions utilitaires du même genre
// ajout sur le maillage d'un conteneur particulier quelconque
void Maillage::AjoutConteneurAuNoeud(TypeQuelconque& tQ)
{ int nbN=tab_noeud.Taille();
// on met à jour les noeuds
for(int i=1;i<=nbN;i++)
{ // on ajoute le type quelconque au noeud
tab_noeud(i)->AjoutUnTypeQuelconque(tQ);
// on met à jour le tableau d'indice de noeud, qui donne le nombre de fois où chaque noeud à été updaté
tab_noeud(i)->Mise_non_update_grandeurs_quelconques();
};
};
// ajout sur le maillage d'un ou plusieur ddl_enum_etendu comme conteneur
void Maillage::AjoutConteneurAuNoeud(const List_io < Ddl_enum_etendu >& lienu)
{ // on crée des tableaux pour optimiser le nombre d'appel aux fonctions d'ajout de grandeur aux noeuds
// 1) cas des Ddl_enum_etendu
Tableau <Ddl_enum_etendu > tab_ddlEnuEtendu(lienu.size());
{List_io < Ddl_enum_etendu >::const_iterator ilienu,ilienufin = lienu.end();
int indice = 1;
for (ilienu = lienu.begin();ilienu != ilienufin; ilienu++,indice++)
tab_ddlEnuEtendu(indice) = (*ilienu);
};
int nbN=tab_noeud.Taille();
int nb_ienu = lienu.size();
// on met à jour les noeuds
for(int i=1;i<=nbN;i++)
{ // Pour les grandeurs ddl étendu on les ajoutes aux noeuds si ce n'est pas déjà fait
tab_noeud(i)->AjoutTabDdl_etendu(tab_ddlEnuEtendu);
// on met à jour le tableau d'indice de noeud, qui donne le nombre de fois où chaque noeud à été updaté
for (int idee=1; idee <= nb_ienu; idee++)
tab_noeud(i)->Mise_non_update_Ddl_etendu(tab_ddlEnuEtendu(idee));
};
};
// initialisation des updates de ddl_étendu uniquement sur les noeuds: on met à 0 les ddl_etendu correspondant,
// les compteurs, comptant le nombre de fois où les noeuds sont modifiés, sont mis à 0
void Maillage::InitUpdateAuNoeud(const List_io < Ddl_enum_etendu >& lienetendu)
{int nbN=tab_noeud.Taille();
List_io <Ddl_enum_etendu>::const_iterator iliet,ilietfin = lienetendu.end();
// on met à jour tous les noeuds
for(int inoeud=1;inoeud<=nbN;inoeud++)
{for (iliet = lienetendu.begin();iliet != ilietfin; iliet++)
{Ddl_etendu& dd = tab_noeud(inoeud)->ModifDdl_etendu(*iliet);
// on initialise la grandeur pointée:
dd.Valeur()=0.;
};
// on met à 0 le tableau d'indice de noeud, qui donne le nombre de fois où chaque noeud à été updaté
tab_noeud(inoeud)->Mise_non_update_Ddl_etendu();
};
};
// initialisation des updates d'un seul ddl_étendu uniquement sur les noeuds: on met à 0 le ddl_etendu correspondant,
// le compteur, comptant le nombre de fois où le noeud est modifié, est mis à 0
void Maillage::InitUpdateAuNoeud(const Ddl_enum_etendu & enetendu)
{int nbN=tab_noeud.Taille();
// on met à jour tous les noeuds
for(int inoeud=1;inoeud<=nbN;inoeud++)
{ // on initialise la grandeur pointée:
(tab_noeud(inoeud)->ModifDdl_etendu(enetendu)).Valeur()=0.;
// on met à 0 le tableau d'indice de noeud, qui donne le nombre de fois où chaque noeud à été updaté
tab_noeud(inoeud)->Mise_non_update_Ddl_etendu();
};
};
// moyenne des valeurs aux noeuds (en fonction du nombre ou le noeud a été modifié)
void Maillage::MoyenneCompteurAuNoeud(const Ddl_enum_etendu & enu)
{ int nbN=tab_noeud.Taille();
// on passe en revue les grandeurs aux noeuds, et on les moyennes
for(int inoeud=1;inoeud<=nbN;inoeud++)
{ Ddl_etendu& dd = tab_noeud(inoeud)->ModifDdl_etendu(enu);
// on modifie la grandeur pointée: -1 car ici on vient d'appeler
// ModifDdl_etendu qui comptabilise un appel de +
int nbappel = (tab_noeud(inoeud)->DdlEtendue_update(enu)-1);
dd.Valeur()/=nbappel;
};
};
// initialisation des coordonnées à t et tdt aux mêmes valeurs qu'à 0
// utile quand on veut utiliser les métriques pour un pb non couplés
void Maillage::Init_Xi_t_et_tdt_de_0()
{ int nbN=tab_noeud.Taille();
// on passe en revue les grandeurs aux noeuds, et on les moyennes
for(int inoeud=1;inoeud<=nbN;inoeud++)
{ Noeud & noe = *tab_noeud(inoeud);
const Coordonnee& co1 = noe.Coord0();
noe.Change_coord1(co1);
noe.Change_coord2(co1);
};
};
// lecture des mouvements solides si nécessaire
void Maillage::Lecture_des_mouvements_solides(UtilLecture * entreePrinc)
{ // on définit un mouvement solide (vide par défaut)
MvtSolide mvtsolide;
if (strstr(entreePrinc->tablcar,"def_mouvement_solide_initiaux_")!=NULL) // cas de mouvements initiaux initiaux
{ if (ParaGlob::NiveauImpression() >= 6) cout << " lecture des mouvements solides initiaux " << endl ;
entreePrinc->NouvelleDonnee(); // on passe le mot clé
};
// lecture éventuelle des mouvements solides
mvtsolide.Lecture_mouvements_solides(entreePrinc);
// traitement au cas où il y a eu lecture de mouvements non nul
if (mvtsolide.ExisteMvtSolide())
{ if (ParaGlob::NiveauImpression() >= 6)
cout << " traitement des mouvements solides initiaux sur le maillage " << endl ;
// on passe le mot clé de fin de mouvement solides pour les lectures suivantes
entreePrinc->NouvelleDonnee();
// --- dans le cas où il y a des centres de rotation qui sont des positions de noeud, on renseigne
// a) récupération des centres de rotation noeud, éventuellement
const list <String_et_entier>& lis_centre_noeud = mvtsolide.Liste_ident_centreNoeud();
if (lis_centre_noeud.size() != 0)
{ list <String_et_entier>::const_iterator ict,ictfin=lis_centre_noeud.end();
list <Coordonnee> list_coor; // liste des coordonnées des noeuds centre de rotation
for (ict = lis_centre_noeud.begin();ict!=ictfin;ict++)
{ // a priori ne concerne que le maillage en question
if (((*ict).nom == "")|| ((*ict).nom == nomDuMaillage))
// cas normal
{ int num_noeud = (*ict).n;
if ((num_noeud < 0) || (num_noeud > tab_noeud.Taille()))
{ cout << "\n *** erreur sur le numero de noeud de centre de rotation = "<< num_noeud
<< " on ne peut pas appliquer la rotation " << endl;
if (ParaGlob::NiveauImpression() >= 6) cout << " lecture des mouvements solides initiaux " << endl ;
};
list_coor.push_back(tab_noeud(num_noeud)->Coord0()); // on récupère les coordonnées initiales
}
else // cas où il s'agit d'un autre maillage, pour l'instant non pris en compte
{ cout << "\n *** erreur sur le numero de noeud concerne un autre maillage = "<< (*ict).nom
<< " cette option n'est pas prise en compte " << endl;
if (ParaGlob::NiveauImpression() >= 6) cout << " lecture des mouvements solides initiaux " << endl ;
};
};
// b) maintenant on passe l'info au mouvement solide
mvtsolide.RenseigneCentreNoeud(list_coor);
};
int nbnoeud = tab_noeud.Taille();
Coordonnee point_inter;
for (int ne=1;ne<=nbnoeud;ne++)
{ point_inter = tab_noeud(ne)->Coord0(); // récupération des coordonnées initiales
mvtsolide.AppliqueMvtSolide(point_inter); // on applique le mouvement solide
tab_noeud(ne)->Change_coord0(point_inter); // on met à jour les nouvelles coordonnées
};
};
};
// ajout d'une liste de noeud à un maillage
// si le numéro de maillage associé au noeud est nul, il est remplacé par celui du maillage
// si le numéro de maillage est déjà existant et est différent ce celui de this, il y a
// création d'un nouveau noeud identique, avec le numéro this
// ajout éventuel d'une liste de référence de noeuds, si celle-ci est non-nulle
// il y a création de nouvelles ref correspondantes au numéro de maillage de this
// et ces références sont rajoutées à lesRef
void Maillage::Ajout_de_Noeuds(const list <Noeud *> & lisN, list <const Reference*>* lref,LesReferences* lesRef )
{ // on change de taille du tableau de noeud et on ajoute les noeuds passés en paramètre
int nbN = tab_noeud.Taille();
int nb_lisN = lisN.size();
tab_noeud.Change_taille(nbN+nb_lisN);
list<Noeud*>::const_iterator il,ilfin=lisN.end();
// on définit un tableau indiquant les nouveaux numéros indicés par les anciens
// t_new_num(i) : = le numéro du nouveau noeud correspondant au noeud initial i
int taille_maxi = 0;
for(il=lisN.begin();il!=ilfin;il++) // un premier passage pour avoir la dimension maxi du tableau
if ((*il)->Num_noeud() > taille_maxi)
taille_maxi = (*il)->Num_noeud();
Tableau<int> t_new_num(taille_maxi,0); // les données du tableau sont initialisées à 0
int i=1;
for(il=lisN.begin();il!=ilfin;il++,i++)
{ int ancien_num = (*il)->Num_noeud();
if (((*il)->Num_Mail() != 0) && ((*il)->Num_Mail() != idmail))
{ // on crée un nouveau noeud identique
Noeud* new_noe = new Noeud(*(*il));
// on change les numéros de noeud et de maillage
new_noe->Change_num_noeud(i+nbN);
new_noe->Change_num_Mail(idmail);
// affectation
tab_noeud(i+nbN) = new_noe;
}
else // sinon cela signifie que le noeud n'appartient pas pour l'instant à un maillage
{ // on change les numéros de noeud et de maillage
(*il)->Change_num_noeud(i+nbN);
(*il)->Change_num_Mail(idmail);
// affectation
tab_noeud(i+nbN) = (*il);
};
// on enregistre le nouveau num que si l'ancien est non nul
if (ancien_num != 0)
t_new_num(ancien_num) = i+nbN;
};
// cas de la présence d'une liste de référence éventuellement à ajouter
if (lref != NULL)
{
#ifdef MISE_AU_POINT
if (lesRef == NULL)
{ cout << "\n erreur le conteneur de reference n'est pas defini "
<< "\n Maillage::Ajout_de_Noeuds(... ";
Sortie(1);
};
#endif
// on va passer en revue la liste des références à ajouter
list<const Reference*>::const_iterator im,imfin = lref->end();
for (im=lref->begin();im!=imfin;im++)
{ if ((*im)->Indic() == 1)
{const ReferenceNE & refN = *((ReferenceNE *) (*im));
// on va contruire une nouvelle référence ad hoc:
string nouveau_nom = (refN.Nom());
// on regarde s'il y a déjà une ref avec le même nom dans le maillage
// si oui on change le nom de la ref à ajouter
string ajout="";int num=0;
while (lesRef->Existe((refN.Nom()+ajout),idmail))
{num++;ajout = "_"+ChangeEntierSTring(num);};
if (ajout != "")
{ nouveau_nom += ajout;
if (ParaGlob::NiveauImpression() > 0)
cout << "\n >>> attention la reference "<<refN.Nom()<<" a ajouter au maillage "
<< nomDuMaillage << " a un nouveau nom "<< (refN.Nom()+ajout);
};
Tableau<int> tt = refN.Tab_num(); // on récupère une copie du tableau de ref
// on le met à jour / aux nouveaux numéros
int tai = tt.Taille();int kn=0; // kn c'est le pointeur dans la nouvelle ref
for (int k=1;k<= tai; k++)
{if (t_new_num(k) != 0)
{ kn++;
tt(kn) = t_new_num(k); // cas où effectivement on a rajouté un noeud qui était déjà référencé
// dans l'ancienne référence
}
else
{if (ParaGlob::NiveauImpression() > 0)
cout << "\n le noeud "<<k<<" de la ref "<<refN.Nom()
<<" n'existe plus dans le nouveau maillage "<<nomDuMaillage;
};
};
// on redimentionne le tableau au maxi d'élément
tt.Change_taille(kn);
// on crée la nouvelle référence si le tableau n'est pas nul
if (tt.Taille() != 0)
{ ReferenceNE* newref = new ReferenceNE(tt,idmail,1,nouveau_nom);
// ajout de la référence
lesRef->Ajout_reference(newref);
};
};
};
};
};
// ajout d'une liste d'éléments et de noeud à un maillage
// si le numéro de maillage associé à l'élément ou noeud est nul, il est remplacé par celui du maillage
// si le numéro de maillage est déjà existant et est différent ce celui de this, il y a
// création d'un nouvel item identique, avec le numéro this
// ajout éventuel d'une liste de références associées , si celle-ci est non-nulle
// il y a création de nouvelles ref correspondantes au numéro de maillage de this
// et ces références sont rajoutées à lesRef
// les noeuds qui sont associés aux éléments de lisE, doivent faire partie : soit de lisN, soit du maillage this
void Maillage::Ajout_elements_et_noeuds
(const list <Noeud *> & lisN, const list <Element *> & lisE,list <const Reference*>* lref,LesReferences* lesRef )
{ // -- on commence par ajouter les noeuds en gardant une trace du type d'ajout
// on change de taille du tableau de noeud et on ajoute les noeuds passés en paramètre
int nbN = tab_noeud.Taille();
int nb_lisN = lisN.size();
tab_noeud.Change_taille(nbN+nb_lisN);
list<Noeud*>::const_iterator il,ilfin=lisN.end();
// on définit un tableau indiquant les nouveaux numéros indicés par les anciens
// t_new_num(i) : = le numéro du nouveau noeud correspondant au noeud initial i
int taille_maxi = 0;
for(il=lisN.begin();il!=ilfin;il++) // un premier passage pour avoir la dimension maxi du tableau
if ((*il)->Num_noeud() > taille_maxi)
taille_maxi = (*il)->Num_noeud();
Tableau<int> t_new_num(taille_maxi,0); // les données du tableau sont initialisées à 0
list<Noeud*> li_nevez_noeud; // la liste des nouvelles positions de noeuds
int i=1;
for(il=lisN.begin();il!=ilfin;il++,i++)
{ int ancien_num = (*il)->Num_noeud();
if (((*il)->Num_Mail() != 0) && ((*il)->Num_Mail() != idmail))
{ // on crée un nouveau noeud identique
Noeud* new_noe = new Noeud(*(*il));
// on change les numéros de noeud et de maillage
new_noe->Change_num_noeud(i+nbN);
new_noe->Change_num_Mail(idmail);
// affectation
tab_noeud(i+nbN) = new_noe;
li_nevez_noeud.push_back(new_noe);
}
else // sinon cela signifie que le noeud n'appartient pas pour l'instant à un maillage
{ // on change les numéros de noeud et de maillage
(*il)->Change_num_noeud(i+nbN);
(*il)->Change_num_Mail(idmail);
// affectation
tab_noeud(i+nbN) = (*il);
li_nevez_noeud.push_back((*il));
};
// on enregistre le nouveau num que si l'ancien est non nul
// sinon
if (ancien_num != 0)
t_new_num(ancien_num) = i+nbN;
};
// -- puis on s'occupe des éléments
// on change de taille du tableau d'éléments et on ajoute les éléments passés en paramètre
int nbE = tab_element.Taille();
int nb_lisE = lisE.size();
tab_element.Change_taille(nbE+nb_lisE);
list<Element*>::const_iterator ie,iefin=lisE.end();
// on définit un tableau indiquant les nouveaux numéros indicés par les anciens
// t_new_num_elem(i) : = le numéro du nouvel élément correspondant à l'élément initial i
taille_maxi = 0;
for(ie=lisE.begin();ie!=iefin;ie++) // un premier passage pour avoir la dimension maxi du tableau
if ((*ie)->Num_elt_const() > taille_maxi)
taille_maxi = (*ie)->Num_elt_const();
Tableau<int> t_new_num_elem(taille_maxi,0); // les données du tableau sont initialisées à 0
i=1;
for(ie=lisE.begin();ie!=iefin;ie++,i++)
{ int num_elt = i+nbE; // numéro interne de l'élément
int ancien_num = (*ie)->Num_elt_const();
Element* new_elem = NULL; // sera affecté dans le if qui suit
if (((*ie)->Num_maillage() != 0) && ((*ie)->Num_maillage() != idmail))
{ Element::Signature signa = (*ie)->Signature_element(); // récupération de la signature de l'élément
// on crée un nouveau element identique
new_elem = Element::Choix_element(idmail,num_elt,signa);
if (new_elem == NULL)
{ // l'operation a echouee
cout << "\n Erreur dans la creation d'un nouvel element ****** ";
cout << "\n element : " << Nom_interpol(signa.id_interpol)
<< " " << Nom_geom(signa.id_geom)
<< "\n Maillage::Ajout_elements_et_noeuds(... " << endl;
Sortie (1);
};
// on affecte les données internes
(*new_elem) = (*(*ie));
// il faut de nouveau définir les numéros de maillage et d'élément
new_elem->Change_num_elt(num_elt);
new_elem->Change_num_maillage(idmail);
}
else // sinon cela signifie que l'éléments n'appartient pas pour l'instant à un maillage
{ // on change les numéros d'élément et de maillage, et peut directement l'affecté
(*ie)->Change_num_elt(num_elt);
(*ie)->Change_num_maillage(idmail);
new_elem = (*ie);
};
// maintenant on va s'occuper de la connexion
Tableau<Noeud *>& t_n_elem = new_elem->Tab_noeud();
int nbnoe = t_n_elem.Taille();
for (int inoe = 1; inoe <= nbnoe; inoe++)
{// on regarde si le noeud fait partie de la liste des noeuds en entrée
// ou alors, qu'il utilise les noeuds existants
bool fait_partie = false;
list<Noeud*>::iterator it=li_nevez_noeud.begin();
for(il=lisN.begin();il!=ilfin;il++,it++)
if ((*il) == t_n_elem(inoe))
{ fait_partie = true; break;};
// deux cas
if (fait_partie)
// on réaffecte
{t_n_elem(inoe)=(*it);}
else // sinon cela signifie que l'on utilise les noeuds existants
// on vérifie qu'il s'agit bien de noeud existant
{ bool verif = false;
for (int j=1;j<= nbN;j++) // on boucle jusqu'à nbN = le nombre initial de noeud
if (tab_noeud(j) == t_n_elem(inoe))
{verif = true; break;};
if (!verif)
{ cout << "\n erreur, la connexion de l'element a ajouter n'est pas recevable "
<< " le noeud "<<t_n_elem(inoe)->Num_noeud()<< " de l'element "
<< new_elem->Num_elt() << " n'existe pas dans le maillage initial "
<< "\n Maillage::Ajout_elements_et_noeuds(... " << endl;
Sortie (1);
};
}
};
// arrivée ici c'est que tout est ok, on ajoute l'élément
tab_element(nbE+i)=new_elem;
// on enregistre le nouveau num que si l'ancien est non nul
if (ancien_num != 0)
t_new_num_elem(ancien_num) = nbE+i;
};
// cas de la présence d'une liste de référence éventuellement à ajouter
if (lref != NULL)
{
#ifdef MISE_AU_POINT
if (lesRef == NULL)
{ cout << "\n erreur le conteneur de reference n'est pas defini "
<< "\n Maillage::Ajout_de_Noeuds(... ";
Sortie(1);
};
#endif
// on va passer en revue la liste des références à ajouter
list<const Reference*>::const_iterator im,imfin = lref->end();
for (im=lref->begin();im!=imfin;im++)
{int indic = (*im)->Indic(); // pour simplifier
switch (indic)
{case 1: // cas d'une ref de noeuds
{const ReferenceNE & refN = *((ReferenceNE *) (*im));
// on va contruire une nouvelle référence ad hoc:
string nouveau_nom = (refN.Nom());
// on regarde s'il y a déjà une ref avec le même nom dans le maillage
// si oui on change le nom de la ref à ajouter
string ajout="";int num=0;
while (lesRef->Existe((refN.Nom()+ajout),idmail))
{num++;ajout = "_"+ChangeEntierSTring(num);};
if (ajout != "")
{ nouveau_nom += ajout;
if (ParaGlob::NiveauImpression() > 0)
cout << "\n >>> attention la reference "<<refN.Nom()<<" a ajouter au maillage "
<< nomDuMaillage << " a un nouveau nom "<< (refN.Nom()+ajout);
};
Tableau<int> tt = refN.Tab_num(); // on récupère une copie du tableau de ref
Tableau<int> tt_new = tt; // le nouveau tableau
// on le met à jour / aux nouveaux numéros
int tai = tt.Taille();int kn=0; // kn c'est le pointeur dans la nouvelle ref
for (int k=1;k<= tai; k++)
{if (t_new_num(tt(k)) != 0)
{ kn++;
tt_new(kn) = t_new_num(tt(k)); // cas où effectivement on a rajouté un noeud qui était déjà référencé
// dans l'ancienne référence
}
else
{if (ParaGlob::NiveauImpression() > 0)
cout << "\n le noeud "<<tt(k)<<" de la ref "<<refN.Nom()
<<" n'existe plus dans le nouveau maillage "<<nomDuMaillage;
};
};
// on redimentionne le tableau au maxi d'élément
tt_new.Change_taille(kn);
// on crée la nouvelle référence si le tableau n'est pas nul
if (tt_new.Taille() != 0)
{ReferenceNE* newref = new ReferenceNE(tt_new,idmail,indic,nouveau_nom);
// ajout de la référence
lesRef->Ajout_reference(newref);
};
break;
}
case 2: // cas d'une ref d'éléments
{const ReferenceNE & refE = *((ReferenceNE *) (*im));
// on va contruire une nouvelle référence ad hoc:
string nouveau_nom = (refE.Nom());
// on regarde s'il y a déjà une ref avec le même nom dans le maillage
// si oui on change le nom de la ref à ajouter
string ajout="";int num=0;
while (lesRef->Existe((refE.Nom()+ajout),idmail))
{num++;ajout = "_"+ChangeEntierSTring(num);};
if (ajout != "")
{ nouveau_nom += ajout;
if (ParaGlob::NiveauImpression() > 0)
cout << "\n >>> attention la reference "<<refE.Nom()<<" a ajouter au maillage "
<< nomDuMaillage << " a un nouveau nom "<< (refE.Nom()+ajout);
};
Tableau<int> tt = refE.Tab_num(); // on récupère une copie du tableau de ref
// on le met à jour / aux nouveaux numéros
int tai = tt.Taille();int kn=0; // kn c'est le pointeur dans la nouvelle ref
Tableau<int> tt_new = tt; // le nouveau tableau
for (int k=1;k<= tai; k++)
{if (t_new_num_elem(tt(k)) != 0)
{ kn++;
tt_new(kn) = t_new_num_elem(tt(k)); // cas où effectivement on a rajouté un élément qui était déjà référencé
// dans l'ancienne référence
}
else
{if (ParaGlob::NiveauImpression() > 0)
cout << "\n l'element "<<tt(k)<<" de la ref "<<refE.Nom()
<<" n'existe plus dans le nouveau maillage "<<nomDuMaillage;
};
};
// on redimentionne le tableau au maxi d'élément
tt_new.Change_taille(kn);
// on crée la nouvelle référence si le tableau n'est pas nul
if (tt_new.Taille() != 0)
{ReferenceNE* newref = new ReferenceNE(tt_new,idmail,indic,nouveau_nom);
// ajout de la référence
lesRef->Ajout_reference(newref);
};
break;
}
case 3: case 4: case 5: case 6:// cas des autres refs: exemple surfaces
{const ReferenceAF & refAF = *((ReferenceAF *) (*im));
// on va contruire une nouvelle référence ad hoc:
string nouveau_nom = (refAF.Nom());
// on regarde s'il y a déjà une ref avec le même nom dans le maillage
// si oui on change le nom de la ref à ajouter
string ajout="";int num=0;
while (lesRef->Existe((refAF.Nom()+ajout),idmail))
{num++;ajout = "_"+ChangeEntierSTring(num);};
if (ajout != "")
{ nouveau_nom += ajout;
if (ParaGlob::NiveauImpression() > 0)
cout << "\n >>> attention la reference "<<refAF.Nom()<<" a ajouter au maillage "
<< nomDuMaillage << " a un nouveau nom "<< (refAF.Nom()+ajout);
};
Tableau<int> te = refAF.Tab_Elem(); // on récupère une copie du tableau des éléments
Tableau<int> te_new = te; // le nouveau tableau
// apriori seules les numéros d'élément sont succeptible d'avoir changé, les numéros
// locaux: surface, arête, noeuds relatifs à l'éléments, et pti restent inchangé
// par contre ils peuvent être supprimés si le num d'élément est supprimé
Tableau<int> tl = refAF.Tab_FA(); // on récupère une copie du tableau des num locaux
// on met à jour le tableau de d'éléments / aux nouveaux numéros
int tai = te.Taille();int kn=0; // kn c'est le pointeur dans la nouvelle ref
for (int k=1;k<= tai; k++)
{if (t_new_num_elem(te(k)) != 0)
{ kn++;
te_new(kn) = t_new_num_elem(te(k)); // cas où effectivement on a rajouté un élément qui était déjà référencé
// dans l'ancienne référence
tl(kn) = tl(k); // normalement k est > kn, donc cela revient à décaler
// en ne gardant que les termes viables
}
else
{if (ParaGlob::NiveauImpression() > 0)
cout << "\n l'element "<<te(k)<<" de la ref "<<refAF.Nom()
<<" n'existe plus dans le nouveau maillage "<<nomDuMaillage;
};
};
// on redimentionne le tableau au maxi d'élément
te_new.Change_taille(kn);tl.Change_taille(kn);
// on crée la nouvelle référence si le tableau n'est pas nul
if (te_new.Taille() != 0)
{ReferenceAF* newref = new ReferenceAF(te_new,tl,idmail,indic,nouveau_nom);
// ajout de la référence
lesRef->Ajout_reference(newref);
};
break;
}
};
};
};
// -------------- ajout de références globales si elles n'existent pas ---------------------
// ---- mise à jour de la référence de tous les éléments si elle n'existe pas déjà
int nbElement = tab_element.Taille();
string etout("E_tout");
if (lesRef->Existe(etout,idmail))
lesRef->SupprimeReference("E_tout",idmail); // on supprime la référence E_tout
// on construit le tableau des numéros des éléments
Tableau <int> tabE(nbElement); for (int i=1;i<=nbElement;i++) tabE(i)=i;
ReferenceNE* retout = new ReferenceNE(tabE,idmail,2,etout);// construction de la référence
lesRef->Ajout_reference(retout); // ajout de la ref, qui est maintenant géré par lesRef
// ---- dans tous les cas on ajoute ou modifie la référence de tous les noeuds
string ntout("N_tout");
int nbNoeud = tab_noeud.Taille();
if (lesRef->Existe(ntout,idmail))
lesRef->SupprimeReference("N_tout",idmail); // on supprime la référence N_tout
// on construit le tableau des numéros de noeuds
Tableau <int> tabN(nbNoeud); for (int i=1;i<=nbNoeud;i++) tabN(i)=i;
ReferenceNE* rtout = new ReferenceNE(tabN,idmail,1,ntout);// construction de la référence
lesRef->Ajout_reference(rtout); // ajout de la ref, qui est maintenant géré par lesRef
//debug
//cout << "\n nbElement " << nbElement << ", nbNoeud "<< nbNoeud << endl;
// fin debug
};
// force la mise à une valeur d'un ddl (ou de la liste de ddl fonction de la dimention) particulier, quelques soit son activité
// si fonction_de_la_dimension = true : c'est toute les ddl fct de la dimension qui sont mis à la valeur
void Maillage::Force_Ddl_aux_noeuds_a_une_valeur(Enum_ddl enu, const double& val,Enum_dure temps, bool fonction_de_la_dimension)
{
int nbnoeud = tab_noeud.Taille();
int dima = ParaGlob::Dimension();
switch (temps)
{case TEMPS_0:
{ if (!(fonction_de_la_dimension) || !FoncDim(enu))
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
noe.Change_val_0(enu,val);
};
}
else
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
{ switch (dima)
{ case 3: noe.Change_val_0(Enum_ddl(enu+2),val);
case 2: noe.Change_val_0(Enum_ddl(enu+1),val);
case 1: noe.Change_val_0(Enum_ddl(enu),val);
};
};
};
};
break;
}
case TEMPS_t:
{ if (!(fonction_de_la_dimension) || !FoncDim(enu))
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
noe.Change_val_t(enu,val);
};
}
else
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
{ switch (dima)
{ case 3: noe.Change_val_t(Enum_ddl(enu+2),val);
case 2: noe.Change_val_t(Enum_ddl(enu+1),val);
case 1: noe.Change_val_t(Enum_ddl(enu),val);
};
};
};
};
break;
}
case TEMPS_tdt:
{ if (!(fonction_de_la_dimension) || !FoncDim(enu))
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
noe.Change_val_tdt(enu,val);
};
}
else
{for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici(enu)) // on intervient que si le ddl existe
{ switch (dima)
{ case 3: noe.Change_val_tdt(Enum_ddl(enu+2),val);
case 2: noe.Change_val_tdt(Enum_ddl(enu+1),val);
case 1: noe.Change_val_tdt(Enum_ddl(enu),val);
};
};
};
};
break;
}
};
};
// mise à zéro de dd_enum_etendu aux noeuds : force la mise à une valeur à 0
void Maillage::Force_Ddl_etendu_aux_noeuds_a_zero(const Tableau<Ddl_enum_etendu>& tab_enu)
{
int nbnoeud = tab_noeud.Taille();
int nb_enu = tab_enu.Taille();
for (int i=1;i<=nb_enu;i++)
{const Ddl_enum_etendu& enu = tab_enu(i);
for (int i=1;i<= nbnoeud;i++)
{ Noeud& noe = *tab_noeud(i); // pour simplifier
if (noe.Existe_ici_ddlEtendu(enu)) // on intervient que si le ddl existe
noe.ModifDdl_etendu(enu).Valeur() = 0.;
};
};
};
// on s'occupe de mettre à jour les types de pb et les ddl types associés
void Maillage::Mise_a_jour_type_pb_type_associe_ddl()
{ //types_de_problemes.clear();
//ddl_representatifs_des_physiques.clear();
// types_de_problemes.Libere();ddl_representatifs_des_physiques.Libere();
// int nbElement = tab_element.Taille();
//string titi;
//cout << "\n nbElement "<<nbElement << " une valeur ? ";
//cin >> titi;
// // on définit un tableau intermédiaire
// int nombre_de_EnumElemTypeProblem = Nombre_de_EnumElemTypeProblem();
//cout << "\n nombre_de_EnumElemTypeProblem "<<nombre_de_EnumElemTypeProblem << " une valeur ? ";
//cin >> titi;
// Tableau < int> types_de_problemes_actif(nombre_de_EnumElemTypeProblem,0);
// types_de_problemes_actif(1)=1;
//cout << "\n taill "<<types_de_problemes_actif.Taille() << " une valeur ? ";
//cin >> titi;
//cout << "\n types_de_problemes_actif(1) "<<types_de_problemes_actif(1) << " une valeur ? ";
//cin >> titi;
//
// for (int i;i<=nbElement;i++)
// {Element& ele = *tab_element(i);
//cout << "\n i"<<i <<"ele "<<ele.Num_elt() << " une valeur ? ";
//cin >> titi;
//ele.Affiche();
//cout << "\n i"<<i <<"ele "<<ele.Num_elt() << " une valeur ? ";
//cin >> titi;
// EnumElemTypeProblem enu = ele.Id_TypeProblem();
//cout << "\n i"<<i <<"ele "<<ele.Num_elt() << " une valeur ? ";
//cin >> titi;
//int truc =enu;
//cout << "\n enu= "<<enu<<" truc "<< truc<< " une valeur ? ";
//cin >> titi;
//cout << "\n types_de_problemes_actif(1) "<<types_de_problemes_actif(1) << " une valeur ? ";
//cin >> titi;
//types_de_problemes_actif(1) = 1;
//cout << "\n types_de_problemes_actif(1) "<<types_de_problemes_actif(1) << " une valeur ? ";
//cin >> titi;
//types_de_problemes_actif(int(enu)) = 1;
//cout << "\n types_de_problemes_actif(1) "<<types_de_problemes_actif(1) << " une valeur ? ";
//cin >> titi;
// // types_de_problemes_actif(truc) = 1; // on rend actif l'élément du tableau
// };
//cout << "\n une valeur ? ";
//cin >> titi;
// // maintenant on regarde le nombre de pb actif
// int nb_pb = 0; // init
// for (int i=1;i<=nombre_de_EnumElemTypeProblem;i++)
// if (types_de_problemes_actif(i)) nb_pb++;
//cout << "\n une valeur ? ";
//cin >> titi;
// // on redimentionne et on rempli
// types_de_problemes.Change_taille(nb_pb);
//cout << "\n une valeur ? ";
//cin >> titi;
// nb_pb = 0; // init
// for (int i=1;i<=nombre_de_EnumElemTypeProblem;i++)
// if (types_de_problemes_actif(i))
// {nb_pb++;types_de_problemes(nb_pb)=EnumElemTypeProblem(i);};
//cout << "\n une valeur ? ";
//cin >> titi;
//
//
////cout << "\n enu"<<enu << " une valeur ? ";
////cin >> titi;
//// bool trouve = false;
//// list <EnumElemTypeProblem>::iterator il,ilfin=types_de_problemes.end();
////if (!types_de_problemes.empty())
////cout << "\n ilfin il begin " << (*types_de_problemes.begin())<< " une valeur ? ";
////cin >> titi;
//// for (il=types_de_problemes.begin();il != ilfin; il++)
//// {cout << "\n "<<NomElemTypeProblem(*il) << " une valeur ? ";
//// cin >> titi;
////
//// if ((*il)==enu) {trouve = true; break;};
//// };
//// if (find(types_de_problemes.begin(),types_de_problemes.end(),enu) == types_de_problemes.end())
//// if (!trouve)
////EnumElemTypeProblem tutu = MECA_SOLIDE_DEFORMABLE;
// // { types_de_problemes.push_back(tutu);};
////
//// int taill = types_de_problemes.Taille();
//// for (int j=1;j<=taill;j++)
//// if (types_de_problemes(j) == enu)
//// { types_de_problemes.Change_taille(taill+1);
//// types_de_problemes(taill+1)=enu;
//// break;
//// };
//// };
//// inter.sort(); inter.unique();
//// types_de_problemes = inter;
// // on parcours les types de pb pour attribuer les types de ddl
//// list <EnumElemTypeProblem>::iterator il,ilfin=types_de_problemes.end();
//// for (il=types_de_problemes.begin();il != ilfin;il++)
////
//// { switch (types_de_problemes(j))
//// {case MECA_SOLIDE_DEFORMABLE :
//// ddl_representatifs_des_physiques.push_back(X1);break;
//// case THERMIQUE :
//// ddl_representatifs_des_physiques.push_back(TEMP);break;
//// default :
//// cout << "\n***Erreur : pour l'instant le type de probleme: "<<NomElemTypeProblem(*il)
//// << "n'est pas pris en compte !\n";
//// cout << "\n Maillage::LectureMaillage(... \n";
//// Sortie(1);
//// };
//// };
//// types_de_problemes.sort(); types_de_problemes.unique();
//// ddl_representatifs_des_physiques.sort(); ddl_representatifs_des_physiques.unique();
//
// ddl_representatifs_des_physiques.Change_taille(nb_pb);
// for (int j=1;j<=nb_pb;j++)
// { switch (types_de_problemes(j))
// {case MECA_SOLIDE_DEFORMABLE :
// ddl_representatifs_des_physiques(j)=X1;break;
// case THERMIQUE :
// ddl_representatifs_des_physiques(j)=TEMP;break;
// default :
// cout << "\n***Erreur : pour l'instant le type de probleme: "
// <<NomElemTypeProblem(types_de_problemes(j))
// << "n'est pas pris en compte !\n";
// cout << "\n Maillage::LectureMaillage(... \n";
// Sortie(1);
// };
// };
};