2021-09-18 09:47:14 +02:00
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-18 09:47:14 +02:00
|
|
|
// 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));}
|
2023-05-03 17:23:49 +02:00
|
|
|
else { return false;};
|
2021-09-18 09:47:14 +02:00
|
|
|
}
|
|
|
|
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));}
|
2023-05-03 17:23:49 +02:00
|
|
|
else {return false;};
|
2021-09-18 09:47:14 +02:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
|
|
|
|
};
|
|
|
|
|