From 568dba18c760d2bf0fbc4aa15e14ef8703c166f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Rio?= Date: Wed, 24 Apr 2024 10:34:35 +0200 Subject: [PATCH] =?UTF-8?q?version=207.029:=20(par=20rapport=20=C3=A0=20la?= =?UTF-8?q?=207.028)=20=20-=20modification=20du=20calcul=20des=20normales?= =?UTF-8?q?=20sur=20les=20facettes=20et=20sur=20les=20fronti=C3=A8res,=20?= =?UTF-8?q?=C3=A0=20l'initialisaion=20et=20lors=20des=20mises=20=C3=A0=20j?= =?UTF-8?q?our=20=20-=20optimisation=20sur=20la=20l'ajout=20de=20grandeurs?= =?UTF-8?q?=20quelconque=20aux=20noeuds:=20=20=20=20.=20les=20anciennes=20?= =?UTF-8?q?versions=20=C3=A9taient=20fonctionnelles=20=20mais=20introduisa?= =?UTF-8?q?it=20un=20stockage=20important.=20Avec=20=20la=20nouvelle=20ver?= =?UTF-8?q?sion,=20=20on=20=20=C3=A9conomise=20500M0=20sur=202=20Go=20!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Elements/Geometrie/Frontiere/ElFrontiere.cc | 4 +- Maillage/Maillage.cc | 290 +++++++++++--------- Maillage/Noeud.h | 6 +- Maillage/Noeud2.cc | 11 +- Parametres/EnteteParaGlob.h | 2 +- Tableaux/Tableau_T.h | 42 +++ 6 files changed, 218 insertions(+), 137 deletions(-) diff --git a/Elements/Geometrie/Frontiere/ElFrontiere.cc b/Elements/Geometrie/Frontiere/ElFrontiere.cc index 7288ebb..06a679f 100644 --- a/Elements/Geometrie/Frontiere/ElFrontiere.cc +++ b/Elements/Geometrie/Frontiere/ElFrontiere.cc @@ -284,8 +284,8 @@ int ElFrontiere::CalculNormale_noeud(Enum_dure temps,const Noeud& noe,Coordonnee else {cout << "\n *** erreur le noeud demande num= "<Indice(); + { + Grandeur_coordonnee grandCoordonnee_0(ParaGlob::Dimension()); // un type courant + TypeQuelconque typQ4_0(NN_SURF_t0,EPS11,grandCoordonnee_0); + Grandeur_coordonnee grandCoordonnee_t(ParaGlob::Dimension()); // un type courant + TypeQuelconque typQ4_t(NN_SURF_t,EPS11,grandCoordonnee_t); - List_io < Element*>& li_elem = indice(ine);// la liste des éléments qui contiennent le noeud - List_io < Element*>::iterator il,ilfin = li_elem.end(); - // on balaie les éléments - int nb_normale=0; // le nombre de normales trouvées - for (il = li_elem.begin(); il != ilfin; il++) - {Element& elem = *(*il); - Enum_type_geom enutygeom = Type_geom_generique(elem.Id_geometrie()); -// if ((enutygeom == LIGNE) || (enutygeom == SURFACE)) - if (enutygeom == SURFACE) // pour l'intant on ne traite que les surfaces - {int cas = elem.CalculNormale_noeud(TEMPS_0,*tab_noeud(ine),coor_inter); - if (cas == 0) - {cout << "\n *** erreur, le calcul de la normale n'est pas possible " - << " pour le noeud "<Num_noeud() - << " du maillage " << tab_noeud(ine)->Num_Mail() - << " par rapport a l'element "<< elem.Num_elt() - << " du maillage " << elem.Num_maillage() - << "\n Maillage::MiseAjourNormaleAuxNoeuds() "; - Sortie(1); - } - else if (cas == 2) - {// le calcul n'est pas licite, mais ce n'est pas une erreur - // simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien - } - else // sinon c'est ok - {// on peut avoir des directions très proches mais de sens inverse ... ce qui va - // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire - // s'il est négatif on utilise l'inverse de la normale - // donc en définitif on gardera globalement la direction précédente - if ((normale * coor_inter) > 0.) - {normale += coor_inter;} - else - {normale -= coor_inter;}; - nb_normale++; - }; - }; - }; - if (nb_normale != 0) - {normale /= nb_normale; - // enfin on normalise la normale -////------ debug -//if (normale.Norme() == 0.) -// { -// for (il = li_elem.begin(); il != ilfin; il++) -// {Element& elem = *(*il); -// Enum_type_geom enutygeom = Type_geom_generique(elem.Id_geometrie()); -// // if ((enutygeom == LIGNE) || (enutygeom == SURFACE)) -// if (enutygeom == SURFACE) // pour l'intant on ne traite que les surfaces -// {elem.CalculNormale_noeud(TEMPS_0,*tab_noeud(ine),coor_inter); -// if (coor_inter.Dimension() == 0) -// {cout << "\n *** erreur, le calcul de la normale n'est pas possible " -// << " pour le noeud "<Num_noeud() -// << " du maillage " << tab_noeud(ine)->Num_Mail() -// << " par rapport a l'element "<< elem.Num_elt() -// << " du maillage " << elem.Num_maillage() -// << "\n Maillage::MiseAjourNormaleAuxNoeuds() "; -// Sortie(1); -// } -// else // sinon c'est ok -// {normale += coor_inter; -// nb_normale++; -// }; -// }; -// }; -// -// } -// -//// end debug - normale.Normer(); - // ce qui fini la mise à jour de la normale au noeud + // on commence par ajouter les conteneurs + // on fait un conteneur particulier pour tous les noeuds, donc 2 boucles + // car cela permet d'optimiser l'utilisation de la méthode AjoutUnTypeQuelconque de Noeud + + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {// on regarde si le conteneur de la normale existe au noeud et création éventuelle + Noeud & noe = *tab_noeud(ine); // pour simplifier + if (!noe.Existe_ici(NN_SURF_t0)) + noe.AjoutUnTypeQuelconque(typQ4_0); + }; + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {// on regarde si le conteneur de la normale existe au noeud et création éventuelle + Noeud & noe = *tab_noeud(ine); // pour simplifier + if (!noe.Existe_ici(NN_SURF_t)) + noe.AjoutUnTypeQuelconque(typQ4_t); + }; + + // maintenant on s'occupe du contenu + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {Noeud & noe = *tab_noeud(ine); // pour simplifier + + // on récupère le conteneur de la normale + TypeQuelconque& tiq = noe.ModifGrandeur_quelconque(NN_SURF_t0); + Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tiq.Grandeur_pointee())); + Coordonnee& normale = *gr.ConteneurCoordonnee(); + normale.Zero(); // init + // calcul éventuel du tableau Indice + this->Indice(); + + List_io < Element*>& li_elem = indice(ine);// la liste des éléments qui contiennent le noeud + List_io < Element*>::iterator il,ilfin = li_elem.end(); + // on balaie les éléments + int nb_normale=0; // le nombre de normales trouvées + for (il = li_elem.begin(); il != ilfin; il++) + {Element& elem = *(*il); + Enum_type_geom enutygeom = Type_geom_generique(elem.Id_geometrie()); + // if ((enutygeom == LIGNE) || (enutygeom == SURFACE)) + if (enutygeom == SURFACE) // pour l'intant on ne traite que les surfaces + {int cas = elem.CalculNormale_noeud(TEMPS_0,*tab_noeud(ine),coor_inter); + if (cas == 0) + {cout << "\n *** erreur, le calcul de la normale n'est pas possible " + << " pour le noeud "<Num_noeud() + << " du maillage " << tab_noeud(ine)->Num_Mail() + << " par rapport a l'element "<< elem.Num_elt() + << " du maillage " << elem.Num_maillage() + << "\n Maillage::MiseAjourNormaleAuxNoeuds() "; + Sortie(1); + } + else if (cas == 2) + {// le calcul n'est pas licite, mais ce n'est pas une erreur + // simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien + } + else // sinon c'est ok + {// on peut avoir des directions très proches mais de sens inverse ... ce qui va + // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire + // s'il est négatif on utilise l'inverse de la normale + // donc en définitif on gardera globalement la direction précédente + if ((normale * coor_inter) > 0.) + {normale += coor_inter;} + else + {normale -= coor_inter;}; + nb_normale++; + }; + }; }; - }; + if (nb_normale != 0) + {normale /= nb_normale; + // enfin on normalise la normale + ////------ debug + //if (normale.Norme() == 0.) + // { + // for (il = li_elem.begin(); il != ilfin; il++) + // {Element& elem = *(*il); + // Enum_type_geom enutygeom = Type_geom_generique(elem.Id_geometrie()); + // // if ((enutygeom == LIGNE) || (enutygeom == SURFACE)) + // if (enutygeom == SURFACE) // pour l'intant on ne traite que les surfaces + // {elem.CalculNormale_noeud(TEMPS_0,*tab_noeud(ine),coor_inter); + // if (coor_inter.Dimension() == 0) + // {cout << "\n *** erreur, le calcul de la normale n'est pas possible " + // << " pour le noeud "<Num_noeud() + // << " du maillage " << tab_noeud(ine)->Num_Mail() + // << " par rapport a l'element "<< elem.Num_elt() + // << " du maillage " << elem.Num_maillage() + // << "\n Maillage::MiseAjourNormaleAuxNoeuds() "; + // Sortie(1); + // } + // else // sinon c'est ok + // {normale += coor_inter; + // nb_normale++; + // }; + // }; + // }; + // + // } + // + //// end debug + normale.Normer(); + // ce qui fini la mise à jour de la normale au noeud + }; + }; + } // on fait de même pour les éléments frontières minimals // calcul éventuel du tableau indice_NFr this->Indice_NFr(); int dima = ParaGlob::Dimension(); - for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {Grandeur_coordonnee grandCoordonnee_0(ParaGlob::Dimension()); // un type courant + TypeQuelconque typQ4_0(N_FRONT_t0,EPS11,grandCoordonnee_0); + Grandeur_coordonnee grandCoordonnee_t(ParaGlob::Dimension()); // un type courant + TypeQuelconque typQ4_t(N_FRONT_t,EPS11,grandCoordonnee_t); + + // à t=0 + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) {Noeud & noe = *tab_noeud(ine); // pour simplifier - // on regarde si le conteneur de la normale à un noeud frontière existe au noeud - // et création éventuelle + // on regarde si le conteneur de la normale à un noeud frontière existe au noeud et création éventuelle if (!noe.Existe_ici(N_FRONT_t0)) - { Grandeur_coordonnee grandCoordonnee(ParaGlob::Dimension()); // un type courant - TypeQuelconque typQ4(N_FRONT_t0,EPS11,grandCoordonnee); - noe.AjoutUnTypeQuelconque(typQ4); - }; - // on fait la même chose à t ce qui évitera de tester à la mise à jour + noe.AjoutUnTypeQuelconque(typQ4_0); + }; + // on fait la même chose à t ce qui évitera de tester à la mise à jour + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {Noeud & noe = *tab_noeud(ine); // pour simplifier + // on regarde si le conteneur de la normale à un noeud frontière existe au noeud et création éventuelle if (!noe.Existe_ici(N_FRONT_t)) - { Grandeur_coordonnee grandCoordonnee(ParaGlob::Dimension()); // un type courant - TypeQuelconque typQ4(N_FRONT_t,EPS11,grandCoordonnee); - noe.AjoutUnTypeQuelconque(typQ4); - }; + noe.AjoutUnTypeQuelconque(typQ4_t); + }; + // on s'occupe du contenu + for (int ine =1; ine < borne_max_nbNoeud;ine++ ) + {Noeud & noe = *tab_noeud(ine); // pour simplifier - // on récupère le conteneur au noeud après création éventuelle + // on récupère le conteneur au noeud TypeQuelconque& tiq = noe.ModifGrandeur_quelconque(N_FRONT_t0); Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) (tiq.Grandeur_pointee())); Coordonnee& normale = *gr.ConteneurCoordonnee(); @@ -1426,24 +1446,25 @@ void Maillage::InitNormaleAuxNoeuds() else // sinon c'est ok {// on peut avoir des directions très proches mais de sens inverse ... ce qui va // conduire à une somme nulle, - // double intens_normale = normale.Norme(); // l'intensité actuelle - // Coordonnee inter_co = normale + coor_inter; + double intens_normale = normale.Norme(); // l'intensité actuelle + Coordonnee inter_co = normale + coor_inter; // if ((intens_normale > ConstMath::unpeupetit) && (inter_co.Norme() < ConstMath::petit)) // // normalement ne devrait pas arriver // { // // } - normale += coor_inter; // ici cela me semble plus juste: on ne doit pas avoir de pb d'inversion de normale - - - - // //pour éviter cela, on regarde le produit scalaire - // // s'il est négatif on utilise l'inverse de la normale - // // donc en définitif on gardera globalement la direction précédente - // if ((normale * coor_inter) > 0.) - // {normale += coor_inter;} - // else - // {normale -= coor_inter;}; + + //pour éviter cela, on pourrait regarder le produit scalaire + // s'il est négatif on utilise l'inverse de la normale + // donc en définitif on gardera globalement la direction précédente + if ((intens_normale > ConstMath::unpeupetit) && (inter_co.Norme() < ConstMath::petit)) + {normale -= coor_inter;} // cas où la somme s'annulle + else // sinon cas normale + // if ((normale * coor_inter) > 0.) + {normale += coor_inter;} + +// {normale += coor_inter; }// ici cela me semble plus juste: on ne doit pas avoir de pb d'inversion de normale + nb_normale++; }; }; @@ -1461,6 +1482,7 @@ void Maillage::InitNormaleAuxNoeuds() }; }; }; + } #ifdef MISE_AU_POINT // on vérifie que tous les noeuds des frontières possèdent une normales {LaLIST ::iterator il,ilfin = listFrontiere.end(); @@ -1568,7 +1590,15 @@ void Maillage::MiseAjourNormaleAuxNoeuds() // simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien } else // sinon c'est ok - {normale += coor_inter; + {// on peut avoir des directions très proches mais de sens inverse ... ce qui va + // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire + // s'il est négatif on utilise l'inverse de la normale + // donc en définitif on gardera globalement la direction précédente + if ((normale * coor_inter) > 0.) + {normale += coor_inter;} + else + {normale -= coor_inter;}; +// {normale += coor_inter; nb_normale++; }; }; @@ -1626,10 +1656,10 @@ void Maillage::MiseAjourNormaleAuxNoeuds() // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire // s'il est négatif on utilise l'inverse de la normale // donc en définitif on gardera globalement la direction précédente - // if ((normale * coor_inter) > 0.) + if ((normale * coor_inter) > 0.) {normale += coor_inter;} - // else - // {normale -= coor_inter;}; + else + {normale -= coor_inter;}; nb_normale++; }; }; @@ -1715,7 +1745,15 @@ void Maillage::MiseAjourNormaleAuxNoeuds_de_tdt_vers_T() // simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien } else // sinon c'est ok - {normale += coor_inter; + {// on peut avoir des directions très proches mais de sens inverse ... ce qui va + // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire + // s'il est négatif on utilise l'inverse de la normale + // donc en définitif on gardera globalement la direction précédente + if ((normale * coor_inter) > 0.) + {normale += coor_inter;} + else + {normale -= coor_inter;}; +// {normale += coor_inter; nb_normale++; }; }; @@ -1776,10 +1814,10 @@ void Maillage::MiseAjourNormaleAuxNoeuds_de_tdt_vers_T() // conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire // s'il est négatif on utilise l'inverse de la normale // donc en définitif on gardera globalement la direction précédente - // if ((normale * coor_inter) > 0.) + if ((normale * coor_inter) > 0.) {normale += coor_inter;} - // else - // {normale -= coor_inter;}; + else + {normale -= coor_inter;}; nb_normale++; }; }; diff --git a/Maillage/Noeud.h b/Maillage/Noeud.h index 4253fbb..1d6a91f 100644 --- a/Maillage/Noeud.h +++ b/Maillage/Noeud.h @@ -625,7 +625,7 @@ class Noeud // opération aussi longue que l'ajout !! void SupprimeTabTypeQuelconque(const Tableau & tab_t_quel); // ramène un booléen indiquant si la grandeur quelconque existe ou pas - inline bool Existe_ici(TypeQuelconque_enum_etendu en) const + inline bool Existe_ici(const TypeQuelconque_enum_etendu& en) const { if (Existe(en) == 0) return false; else return true;}; // récupération d'une grandeur quelconque pour modification // après l'appel de cette méthode, la grandeur quelconque est réputée updaté @@ -810,7 +810,7 @@ class Noeud void Ecriture_grandeurs_quelconque(ostream & sort) const; // récupe de l'indice d'une grandeur quelconque // si la grandeur n'existe pas -> ramène 0 - int Indice_grandeur_quelconque(TypeQuelconque_enum_etendu a); + int Indice_grandeur_quelconque(const TypeQuelconque_enum_etendu& a); // mise a jour de l'adressage via l'identificateur d'énumération // c'est-à-dire la gestion via list_tab_typeQuelconque et pos_Quelconque // ne doit être appelé que si l'on a introduit un nouveau type quelconque !! @@ -818,7 +818,7 @@ class Noeud void MiseAjourTypeQuelconque(); // retourne le numero du type quelconque recherche identifie par en, // s'il existe sinon 0 - int Existe(TypeQuelconque_enum_etendu en) + int Existe(const TypeQuelconque_enum_etendu& en) const { return ( (pos_Quelconque == list_tab_typeQuelconque.end()) ? 0 : (*pos_Quelconque)(en.Position()));}; // --- cas des Ddl_etendu ---- // lecture des Ddl_etendu sur flot diff --git a/Maillage/Noeud2.cc b/Maillage/Noeud2.cc index 811139b..828a39a 100644 --- a/Maillage/Noeud2.cc +++ b/Maillage/Noeud2.cc @@ -605,7 +605,7 @@ void Noeud::Ecriture_grandeurs_quelconque(ostream & sort) const // récupe de l'indice d'une grandeur quelconque // si la grandeur n'existe pas -> ramène 0 -int Noeud::Indice_grandeur_quelconque(TypeQuelconque_enum_etendu a) +int Noeud::Indice_grandeur_quelconque(const TypeQuelconque_enum_etendu& a) { int tailtab = tab_type_quel.Taille(); for (int i=posi_type_quel;i<=tailtab;i++) { if ( tab_type_quel(i).EnuTypeQuelconque() == a) @@ -621,7 +621,7 @@ int Noeud::Indice_grandeur_quelconque(TypeQuelconque_enum_etendu a) }; // mise a jour de l'adressage via l'identificateur d'énumération -// c'est-à-dire la gestion via list_tab_typeQuelconque et popos_Quelconque +// c'est-à-dire la gestion via list_tab_typeQuelconque et pos_Quelconque // ne doit être appelé que si l'on a introduit un nouveau type quelconque !! // ou changé l'ordre etc.. void Noeud::MiseAjourTypeQuelconque() @@ -639,7 +639,7 @@ void Noeud::MiseAjourTypeQuelconque() // cela signifie qu'il n'y a jamais eu de type quelconque pour tous les noeuds // et qu'il n'y a rien à faire, retour directe {return;} - else // sinon c'est le cas d'une destruction de types quelconques + else // sinon c'est le cas d'une destruction de types quelconques // on met à jour les indicateurs ad hoc { // l'avant dernier élément du tableau contient le nombre de noeud qui utilise ce type int taille_pos_quelconque = (*pos_Quelconque).Taille(); @@ -707,8 +707,9 @@ void Noeud::MiseAjourTypeQuelconque() list >::iterator ifin = list_tab_typeQuelconque.end(); list >::iterator iter; bool trouver = false; - for (iter = ideb;ideb!= ifin;ideb++) - if ((*iter) == tab_indi_TypeQ) + for (iter = ideb;iter!= ifin;iter++) +// if ((*iter) == tab_indi_TypeQ) + if (tab_indi_TypeQ.Egalite_tranche(1,(*iter),nbmaxTypeQ)) { trouver = true; break;} // si pas trouver on ajoute sinon on utilise la position déjà existante if (!trouver) diff --git a/Parametres/EnteteParaGlob.h b/Parametres/EnteteParaGlob.h index 2adb26e..3e7b965 100644 --- a/Parametres/EnteteParaGlob.h +++ b/Parametres/EnteteParaGlob.h @@ -41,7 +41,7 @@ EnumLangue ParaGlob::langueHZ = FRANCAIS; // langue utilisée pour les entrées sorties int ParaGlob::nbComposantesTenseur = 1; // nombre de composantes par defaut a 1 int ParaGlob::nivImpression = 2; // niveau d'impression - string ParaGlob::nbVersion = "7.028" ; // numéro de version du logiciel + string ParaGlob::nbVersion = "7.029" ; // numéro de version du logiciel string ParaGlob::NbVersionsurfichier = ""; // numéro de version lue en entrée fichier int ParaGlob::nb_diggit_double_calcul= 17; // nombre de chiffre significatifs utilisé pour // l'affichage des double précision pour l'archivage diff --git a/Tableaux/Tableau_T.h b/Tableaux/Tableau_T.h index 4968990..2d44549 100644 --- a/Tableaux/Tableau_T.h +++ b/Tableaux/Tableau_T.h @@ -168,6 +168,10 @@ class Tableau // Surcharge de l'operateur == int operator== (const Tableau& tab) const ; + + // egalité d'une même tranche + // les tableaux doivent avoir la même taille + int Egalite_tranche(int deb,const Tableau & tab,int fin)const; // Surcharge de l'operateur d'affectation = Tableau& operator= (const Tableau& tab); @@ -769,6 +773,44 @@ inline int Tableau::operator ==(const Tableau & tab) const } +// egalité d'une même tranche +// les tableaux doivent avoir la même taille +template +inline int Tableau::Egalite_tranche(int deb,const Tableau & tab,int fin)const +// Renvoie 1 si les tranches sont égales +// Renvoie 0 sinon +{ + #ifdef MISE_AU_POINT + if (( deb < 1 )||(deb > taille)) + { cout << "\nErreur l'indice de debut de tranche: "<< deb << " est inf 1 ou sup taille: "<< taille; + cout << "\n TABLEAU_T::Egalite_tranche(.. \n"; + Sortie(1); + } + if ( fin > taille ) + { cout << "\nErreur l'indice de fin de tranche: "<< fin << " est sup taille: "<< taille; + cout << "\n TABLEAU_T::Egalite_tranche(.. \n"; + Sortie(1); + } + #endif + + if ( tab.taille!=taille ) + return 0; + else + { + T* ptr1=t; + T* ptr2=tab.t; + for (int i=deb-1;i< fin;i++) + { + if ( (*ptr2++)!=(*ptr1++) ) + return 0; + }; + return 1; + }; + +} + + + // opération de lecture sur un flot d'entrée // les données sont le type puis la dimension puis les datas template