version 7.029: (par rapport à la 7.028)

- modification du calcul des normales sur les facettes et sur les frontières, à l'initialisaion et lors des mises à jour
 - optimisation sur la l'ajout de grandeurs quelconque aux noeuds:
   . les anciennes versions étaient fonctionnelles  mais introduisait un stockage important. Avec  la nouvelle version,  on  économise 500M0 sur 2 Go !!
This commit is contained in:
Gérard Rio 2024-04-24 10:34:35 +02:00
parent 3a47230a73
commit 568dba18c7
6 changed files with 218 additions and 137 deletions

View file

@ -284,8 +284,8 @@ int ElFrontiere::CalculNormale_noeud(Enum_dure temps,const Noeud& noe,Coordonnee
else
{cout << "\n *** erreur le noeud demande num= "<<noe.Num_noeud()
<< " du maillage "<< noe.Num_Mail()
<< " ne fait pas parti de l'element de frontiere FrontSegLine "
<< "contenant les noeuds: \n";
<< " ne fait pas parti de l'element de frontiere "<< Nom_type_geom(enutygeom)
<< " contenant les noeuds: \n";
for (int i=1;i< borne_nb_noeud;i++)
{Noeud& noeloc = *tabNoeud(i);
cout << " num "<< noe.Num_noeud() << " mail " << noeloc.Num_Mail() << ", ";

View file

@ -1268,122 +1268,142 @@ void Maillage::InitNormaleAuxNoeuds()
int borne_max_nbNoeud = nbNoeud+1;
Coordonnee coor_inter; // coordonnée de travail
Coordonnee premiere_normale;// idem
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))
{ Grandeur_coordonnee grandCoordonnee(ParaGlob::Dimension()); // un type courant
TypeQuelconque typQ4(NN_SURF_t0,EPS11,grandCoordonnee);
noe.AjoutUnTypeQuelconque(typQ4);
};
// on fait la même chose à t ce qui évitera de tester à la mise à jour
if (!noe.Existe_ici(NN_SURF_t))
{ Grandeur_coordonnee grandCoordonnee(ParaGlob::Dimension()); // un type courant
TypeQuelconque typQ4(NN_SURF_t,EPS11,grandCoordonnee);
noe.AjoutUnTypeQuelconque(typQ4);
};
// et on le récupère après création éventuelle
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();
{
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 "<<tab_noeud(ine)->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 "<<tab_noeud(ine)->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 "<<tab_noeud(ine)->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 "<<tab_noeud(ine)->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 <Front>::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++;
};
};

View file

@ -625,7 +625,7 @@ class Noeud
// opération aussi longue que l'ajout !!
void SupprimeTabTypeQuelconque(const Tableau <TypeQuelconque > & 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

View file

@ -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 <Tableau <int > >::iterator ifin = list_tab_typeQuelconque.end();
list <Tableau <int > >::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)

View file

@ -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

View file

@ -168,6 +168,10 @@ class Tableau
// Surcharge de l'operateur ==
int operator== (const Tableau<T>& tab) const ;
// egalité d'une même tranche
// les tableaux doivent avoir la même taille
int Egalite_tranche(int deb,const Tableau<T> & tab,int fin)const;
// Surcharge de l'operateur d'affectation =
Tableau<T>& operator= (const Tableau<T>& tab);
@ -769,6 +773,44 @@ inline int Tableau<T>::operator ==(const Tableau<T> & tab) const
}
// egalité d'une même tranche
// les tableaux doivent avoir la même taille
template <class T>
inline int Tableau<T>::Egalite_tranche(int deb,const Tableau<T> & 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 <class T>