ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mailleur/src/mailleur_analyse.cpp
Revision: 1189
Committed: Tue Feb 4 17:26:49 2025 UTC (3 months ago) by francois
File size: 27033 byte(s)
Log Message:
Version 5.0 de MAGIC. Integration de ALGLIB pour faire de l'optimisation. ALGLIB se download automatiquement en executant un script dans le repertoire config update_magic.bash


File Contents

# Content
1 //####//------------------------------------------------------------
2 //####//------------------------------------------------------------
3 //####// MAGiC
4 //####// Jean Christophe Cuilliere et Vincent FRANCOIS
5 //####// Departement de Genie Mecanique - UQTR
6 //####//------------------------------------------------------------
7 //####// MAGIC est un projet de recherche de l equipe ERICCA
8 //####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres
9 //####// http://www.uqtr.ca/ericca
10 //####// http://www.uqtr.ca/
11 //####//------------------------------------------------------------
12 //####//------------------------------------------------------------
13 //####//
14 //####// mailleur_analyse.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:55 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 #include "gestionversion.h"
23 #include "mailleur_analyse.h"
24 #include "mg_gestionnaire.h"
25 #include "m3d_triangle.h"
26 #include "tpl_fonctions_generiques.h"
27 #include "fct_taille.h"
28 #include "fem_maillage_quadratique_outils.h"
29
30
31
32
33
34 MAILLEUR_ANALYSE::MAILLEUR_ANALYSE(MG_MAILLAGE* m,OT_CPU* comp):MAILLEUR(comp),mai(m),borne1(0.1),borne2(0.2),borne3(0.5),eps_angle_retourne(0.03),fem(NULL)
35 {
36
37 }
38
39
40 MAILLEUR_ANALYSE::MAILLEUR_ANALYSE(FEM_MAILLAGE* m,OT_CPU* comp):MAILLEUR(comp),fem(m),mai(NULL),borne1(0.1),borne2(0.2),borne3(0.5),eps_angle_retourne(0.03)
41 {
42
43 }
44
45
46
47
48
49 MAILLEUR_ANALYSE::MAILLEUR_ANALYSE(MAILLEUR_ANALYSE &mdd):MAILLEUR(mdd),mai(mdd.mai),borne1(mdd.borne1),borne2(mdd.borne2),borne3(mdd.borne3)
50 {
51
52 }
53
54
55
56 MAILLEUR_ANALYSE::~MAILLEUR_ANALYSE()
57 {
58
59 }
60
61 void MAILLEUR_ANALYSE::change_borne(double val1,double val2,double val3)
62 {
63 borne1=val1;
64 borne2=val2;
65 borne3=val3;
66 }
67
68 void MAILLEUR_ANALYSE::get_borne(double &val1,double &val2,double &val3)
69 {
70 val1=borne1;
71 val2=borne2;
72 val3=borne3;
73 }
74
75 void MAILLEUR_ANALYSE::change_eps_angle_retourne(double val)
76 {
77 eps_angle_retourne=val;
78 }
79
80 double MAILLEUR_ANALYSE::get_eps_angle_retourne(void)
81 {
82 return eps_angle_retourne;
83 }
84
85
86 void MAILLEUR_ANALYSE::analyse(char *nom)
87 {
88 if (mai!=NULL) analyse_mg(nom);
89 if (fem!=NULL) analyse_fem(nom);
90 }
91
92 void MAILLEUR_ANALYSE::analyse_fem(char *nom)
93 {
94 char mess[500];
95 sprintf(mess,"ANALYSEUR DE FEM MAILLAGE 3D");
96 affiche(mess);
97 sprintf(mess,"---------------------------");
98 affiche(mess);
99 affiche((char*)"");
100 sprintf(mess,"Constitution du maillage");
101 affiche(mess);
102 affiche((char*)"");
103 int nbnoeud=fem->get_nb_fem_noeud();
104 int nbele1=fem->get_nb_fem_element1();
105 int nbele2=fem->get_nb_fem_element2();
106 int nbele3=fem->get_nb_fem_element3();
107 int degre=fem->get_degre();
108 sprintf(mess," Maillage numero : %lu degre : %d",fem->get_id(),degre);affiche(mess);
109 sprintf(mess," %d noeuds",nbnoeud); affiche(mess);
110 sprintf(mess," %d elements 1D",nbele1); affiche(mess);
111
112 LISTE_FEM_ELEMENT1::iterator it1;
113 int nbseg2=0,nbseg3=0;
114 for (FEM_ELEMENT1 *ele=fem->get_premier_element1(it1);ele!=NULL;ele=fem->get_suivant_element1(it1))
115 {
116 if (ele->get_nb_fem_noeud()==2) nbseg2++;
117 if (ele->get_nb_fem_noeud()==3) nbseg3++;
118 }
119 if (degre==1) {sprintf(mess," %d segment2",nbseg2); affiche(mess); }
120 if (degre==2) {sprintf(mess," %d segment3",nbseg3); affiche(mess); }
121 sprintf(mess," %d elements 2D",nbele2); affiche(mess);
122 LISTE_FEM_ELEMENT2::iterator it2;
123 int nbtri3=0,nbtri6=0,nbquad4=0,nbquad8=0;
124 for (FEM_ELEMENT2 *ele=fem->get_premier_element2(it2);ele!=NULL;ele=fem->get_suivant_element2(it2))
125 {
126 if (ele->get_nb_fem_noeud()==3) nbtri3++;
127 if (ele->get_nb_fem_noeud()==6) nbtri6++;
128 if (ele->get_nb_fem_noeud()==4) nbquad4++;
129 if (ele->get_nb_fem_noeud()==8) nbquad8++;
130 }
131 if (degre==1) {sprintf(mess," %d triangle3",nbtri3); affiche(mess); }
132 if (degre==2) {sprintf(mess," %d triangle6",nbtri6); affiche(mess); }
133 if (degre==1) {sprintf(mess," %d quadrangle4",nbquad4); affiche(mess); }
134 if (degre==2) {sprintf(mess," %d quadrangle8",nbquad8); affiche(mess); }
135 sprintf(mess," %d elements 3D",nbele3); affiche(mess);
136 LISTE_FEM_ELEMENT3::iterator it3;
137 int nbtet4=0,nbtet10=0,nbhex8=0,nbhex20=0,nbpenta5=0,nbpenta15=0;
138 for (FEM_ELEMENT3 *ele=fem->get_premier_element3(it3);ele!=NULL;ele=fem->get_suivant_element3(it3))
139 {
140 if (ele->get_nb_fem_noeud()==4) nbtet4++;
141 if (ele->get_nb_fem_noeud()==10) nbtet10++;
142 if (ele->get_nb_fem_noeud()==8) nbhex8++;
143 if (ele->get_nb_fem_noeud()==20) nbhex20++;
144 if (ele->get_nb_fem_noeud()==5) nbpenta5++;
145 if (ele->get_nb_fem_noeud()==15) nbpenta15++;
146 }
147 if (degre==1) {sprintf(mess," %d tetra4",nbtet4); affiche(mess); }
148 if (degre==2) {sprintf(mess," %d tetra10",nbtet10); affiche(mess); }
149 if (degre==1) {sprintf(mess," %d hex8",nbhex8); affiche(mess); }
150 if (degre==2) {sprintf(mess," %d hex20",nbhex20); affiche(mess); }
151 if (degre==1) {sprintf(mess," %d penta5",nbpenta5); affiche(mess); }
152 if (degre==2) {sprintf(mess," %d penta15",nbpenta15); affiche(mess); }
153 affiche((char*)"");
154 sprintf(mess,"Qualité du maillage");
155 affiche(mess);
156 if (degre==1)
157 {
158 mai=fem->get_mg_maillage();
159 analyse_mg(nom);
160 }
161 if (degre==2)
162 {
163 FEM_SOLUTION *sol=NULL;
164 if (nom!=NULL)
165 {
166 std::string nomsol=nom;nomsol=nomsol+".sol";
167 if (fem->get_nb_fem_element3()==0) sol=new FEM_SOLUTION(fem,4,(char*)nomsol.c_str(),fem->get_nb_fem_element2(),"Qualité",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT2,MAGIC::TYPE_SOLUTION::SCALAIRE);
168 if (fem->get_nb_fem_element3()!=0) sol=new FEM_SOLUTION(fem,4,(char*)nomsol.c_str(),fem->get_nb_fem_element3(),"Qualité",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3,MAGIC::TYPE_SOLUTION::SCALAIRE);
169 fem->get_mg_maillage()->get_gestionnaire()->ajouter_fem_solution(sol);
170 sol->change_legende(0,"jmin");
171 sol->change_legende(1,"jmax");
172 sol->change_legende(2,"distorsion");
173 sol->change_legende(3,"Qlin");
174 }
175 if (nbtri6>0)
176 {
177 sprintf(mess," Qualité des triangle6");
178 affiche(mess);
179 FEM_MAILLAGE_QUADRATIQUE_OUTILS ot;
180 double jminmin=1e300,jmaxmax=1e-300,dismoy=0,dismin=1e300,dismax=-1e300;
181 int nb=0;
182 int i=0;
183 for (FEM_ELEMENT2 *ele=fem->get_premier_element2(it2);ele!=NULL;ele=fem->get_suivant_element2(it2))
184 {
185 if (ele->get_nb_fem_noeud()==6)
186 {
187 double jmin=ot.get_jmin(ele);
188 double jmax=ot.get_jmax(ele);
189 double dis=ot.get_distorsion2(ele);
190 nb++;
191 dismoy=dismoy+dis;
192 if (jmin<jminmin) jminmin=jmin;
193 if (jmax>jmaxmax) jmaxmax=jmax;
194 if (dis<dismin) dismin=dis;
195 if (dis>dismax) dismax=dis;
196 if (sol!=NULL)
197 if (sol->get_entite_solution()==MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT2)
198 {
199 sol->ecrire(jmin,i,0);
200 sol->ecrire(jmax,i,1);
201 sol->ecrire(dis,i,2);
202 }
203 }
204 i++;
205 }
206 sprintf(mess," Jacobien min %le",jminmin);
207 affiche(mess);
208 sprintf(mess," Jacobien max %le",jmaxmax);
209 affiche(mess);
210 sprintf(mess," Distortion min %lf",dismin);
211 affiche(mess);
212 sprintf(mess," Distortion moy %lf",dismoy/nb);
213 affiche(mess);
214 sprintf(mess," Distortion max %lf",dismax);
215 affiche(mess);
216
217 }
218 if (nbtet10>0)
219 {
220 sprintf(mess," Qualité des tetra10");
221 affiche(mess);
222 FEM_MAILLAGE_QUADRATIQUE_OUTILS ot;
223 double jminmin=1e300,jmaxmax=1e-300,dismoy=0,dismin=1e300,dismax=-1e300;
224 int nb=0;
225 int i=0;
226 for (FEM_ELEMENT3 *ele=fem->get_premier_element3(it3);ele!=NULL;ele=fem->get_suivant_element3(it3))
227 {
228 if (ele->get_nb_fem_noeud()==10)
229 {
230 double jmin=ot.get_jmin(ele);
231 double jmax=ot.get_jmax(ele);
232 double dis=ot.get_distorsion2(ele);
233 nb++;
234 dismoy=dismoy+dis;
235 if (jmin<jminmin) jminmin=jmin;
236 if (jmax>jmaxmax) jmaxmax=jmax;
237 if (dis<dismin) dismin=dis;
238 if (dis>dismax) dismax=dis;
239 if (sol!=NULL)
240 if (sol->get_entite_solution()==MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3)
241 {
242 sol->ecrire(jmin,i,0);
243 sol->ecrire(jmax,i,1);
244 sol->ecrire(dis,i,2);
245 MG_TETRA* tet=(MG_TETRA*)ele->get_mg_element_maillage();
246 double qual=OPERATEUR::qualite_tetra(tet->get_noeud1()->get_coord(),tet->get_noeud2()->get_coord(),tet->get_noeud3()->get_coord(),tet->get_noeud4()->get_coord());
247 sol->ecrire(qual,i,3);
248 if (jmin<0.)
249 {
250 sprintf(mess," Erreur maille numero %d identificateur %lu\n Jmin=%lf Jmax=%lf Distorsion=%lf Qualite lineaire=%lf\n",i,ele->get_id(),jmin,jmax,dis,qual);
251 affiche(mess);
252 }
253 }
254 }
255 i++;
256 }
257 sprintf(mess," Jacobien min %le",jminmin);
258 affiche(mess);
259 sprintf(mess," Jacobien max %le",jmaxmax);
260 affiche(mess);
261 sprintf(mess," Distortion min %lf",dismin);
262 affiche(mess);
263 sprintf(mess," Distortion moy %lf",dismoy/nb);
264 affiche(mess);
265 sprintf(mess," Distortion max %lf",dismax);
266 affiche(mess);
267
268 }
269 if (nom!=NULL)
270 {
271 std::string nomf=nom;
272 nomf=nomf+".magic";
273 fem->get_mg_maillage()->get_gestionnaire()->enregistrer((char*)nomf.c_str());
274 }
275
276 }
277 }
278
279
280 void MAILLEUR_ANALYSE::analyse_mg(char *nom)
281 {
282 char mess[500];
283 sprintf(mess,"ANALYSEUR DE MG MAILLAGE 3D");
284 affiche(mess);
285 sprintf(mess,"---------------------------");
286 affiche(mess);
287 affiche((char*)"");
288 sprintf(mess,"Constitution du maillage");
289 affiche(mess);
290 affiche((char*)"");
291 int nbnofront,nbsegfront,nbtrifront,nbquadfront;
292 denombre_maillage(nbnofront,nbsegfront,nbtrifront,nbquadfront);
293 sprintf(mess," Maillage numero : %lu",mai->get_id());affiche(mess);
294 sprintf(mess," %d noeuds",mai->get_nb_mg_noeud()); affiche(mess);
295 sprintf(mess," %d segments",mai->get_nb_mg_segment()); affiche(mess);
296 sprintf(mess," %d triangles",mai->get_nb_mg_triangle()); affiche(mess);
297 sprintf(mess," %d quadrangles",mai->get_nb_mg_quadrangle()); affiche(mess);
298 sprintf(mess," %d tetras",mai->get_nb_mg_tetra()); affiche(mess);
299 sprintf(mess," %d hexas",mai->get_nb_mg_hexa()); affiche(mess); affiche((char*)"");
300 sprintf(mess," %d noeuds frontiere",nbnofront); affiche(mess);
301 sprintf(mess," %d segments frontiere",nbsegfront); affiche(mess);
302 sprintf(mess," %d triangles frontiere",nbtrifront); affiche(mess);
303 sprintf(mess," %d quadrangles frontiere",nbquadfront); affiche(mess);affiche((char*)"");
304
305
306 MG_SOLUTION *sol=NULL;
307 if (nom!=NULL)
308 {
309 std::string nomsol=nom;nomsol=nomsol+".sol";
310 if (mai->get_nb_mg_tetra()==0) sol=new MG_SOLUTION(mai,1,(char*)nomsol.c_str(),mai->get_nb_mg_triangle(),"Qualité",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT2,MAGIC::TYPE_SOLUTION::SCALAIRE);
311 if (mai->get_nb_mg_tetra()!=0) sol=new MG_SOLUTION(mai,1,(char*)nomsol.c_str(),mai->get_nb_mg_tetra(),"Qualité",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3,MAGIC::TYPE_SOLUTION::SCALAIRE);
312 mai->get_gestionnaire()->ajouter_mg_solution(sol);
313 }
314
315
316 if (nbtrifront!=0)
317 {
318 affiche((char*)"");
319 sprintf(mess,"Analyse maillage triangulaire 2D");
320 affiche(mess);
321 affiche((char*)"");
322 double qualmin,qualmax,qualmoy;
323 int tab[7];
324 analyse_qualite_maillage_2D(sol,qualmin,qualmax,qualmoy,tab);
325 sprintf(mess," Nombre de triangles avec des noeuds fusionnés : %d",tab[6]); affiche(mess);
326 sprintf(mess," Nombre de triangles avec 1 voisin manquant : %d",tab[5]); affiche(mess);
327 sprintf(mess," critere d'angle limite pour l'inversion : %lf",eps_angle_retourne); affiche(mess);
328 sprintf(mess," qualite moyenne des triangles de frontiere : %lf",qualmoy); affiche(mess);
329 sprintf(mess," qualite min des triangles de frontiere : %lf",qualmin); affiche(mess);
330 sprintf(mess," qualite max des triangles de frontiere : %lf",qualmax); affiche(mess);
331 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne3,tab[4],tab[4]*100./nbtrifront); affiche(mess);
332 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne2,tab[3],tab[3]*100./nbtrifront); affiche(mess);
333 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",borne1,tab[2],tab[2]*100./nbtrifront); affiche(mess);
334 sprintf(mess," nombre de triangles de frontiere >%lf : %d (%.2lf%%)",0.,tab[1],tab[1]*100./nbtrifront); affiche(mess);
335 sprintf(mess," nombre de triangles de frontiere retournes : %d (%.2lf%%)",tab[0],tab[0]*100./nbtrifront); affiche(mess); affiche((char*)"");
336 }
337 if (mai->get_nb_mg_tetra()!=0)
338 {
339 affiche((char*)"");
340 sprintf(mess,"Analyse maillage tetraedrique 3D");
341 affiche(mess);
342 affiche((char*)"");
343 double qualmin,qualmax,qualmoy;
344 int tab[5];
345 analyse_qualite_maillage_3D(sol,qualmin,qualmax,qualmoy,tab);
346 sprintf(mess," qualite moyenne des tetra : %lf",qualmoy); affiche(mess);
347 if (qualmin>1e-6)
348 {sprintf(mess," qualite min des tetra : %lf",qualmin); affiche(mess); }
349 else
350 {sprintf(mess," qualite min des tetra : %le",qualmin); affiche(mess); }
351 sprintf(mess," qualite max des tetra : %lf",qualmax); affiche(mess);
352 sprintf(mess," nombre de tetra >%lf : %d (%.2lf%%)",borne3,tab[4],tab[4]*100./mai->get_nb_mg_tetra()); affiche(mess);
353 sprintf(mess," nombre de tetra >%lf : %d (%.2lf%%)",borne2,tab[3],tab[3]*100./mai->get_nb_mg_tetra()); affiche(mess);
354 sprintf(mess," nombre de tetra >%lf : %d (%.2lf%%)",borne1,tab[2],tab[2]*100./mai->get_nb_mg_tetra()); affiche(mess);
355 sprintf(mess," nombre de tetra >%lf : %d (%.2lf%%)",0.,tab[1],tab[1]*100./mai->get_nb_mg_tetra()); affiche(mess);
356 sprintf(mess," nombre de tetra retournes : %d (%.2lf%%)",tab[0],tab[0]*100./mai->get_nb_mg_tetra()); affiche(mess);
357 affiche((char*)"");
358 sprintf(mess,"Validite maillage tétraedrique 3D");
359 affiche(mess);
360 affiche((char*)"");
361 int nbsegcorrect,nbsegincorrect;
362 analyse_validite_maillage_3D(nbsegcorrect,nbsegincorrect);
363
364 sprintf(mess," segment correct %d(%.2lf%%) segment incorrect %d(%.2lf%%) ",nbsegcorrect,nbsegcorrect*100./(nbsegcorrect+nbsegincorrect),nbsegincorrect,nbsegincorrect*100./(nbsegcorrect+nbsegincorrect)); affiche(mess);
365
366 }
367
368 if (nom!=NULL)
369 {
370 std::string nomf=nom;
371 nomf=nomf+".magic";
372 mai->get_gestionnaire()->enregistrer((char*)nomf.c_str());
373 }
374
375 }
376
377 void MAILLEUR_ANALYSE::denombre_maillage(int &nbnofront,int &nbsegfront,int &nbtrifront,int &nbquadfront)
378 {
379 LISTE_MG_NOEUD::iterator itn;
380 for (MG_NOEUD* no=mai->get_premier_noeud(itn);no!=NULL;no=mai->get_suivant_noeud(itn))
381 no->change_nouveau_numero(0);
382
383 LISTE_MG_SEGMENT::iterator its;
384 for (MG_SEGMENT* seg=mai->get_premier_segment(its);seg!=NULL;seg=mai->get_suivant_segment(its))
385 seg->change_nouveau_numero(0);
386
387
388 LISTE_MG_TRIANGLE::iterator ittr;
389 for (MG_TRIANGLE* tri=mai->get_premier_triangle(ittr);tri!=NULL;tri=mai->get_suivant_triangle(ittr))
390 tri->change_nouveau_numero(0);
391
392 LISTE_MG_QUADRANGLE::iterator itq;
393 for (MG_QUADRANGLE* quad=mai->get_premier_quadrangle(itq);quad!=NULL;quad=mai->get_suivant_quadrangle(itq))
394 quad->change_nouveau_numero(0);
395
396 LISTE_MG_TETRA::iterator itt;
397 for (MG_TETRA* tet=mai->get_premier_tetra(itt);tet!=NULL;tet=mai->get_suivant_tetra(itt))
398 {
399 tet->get_triangle1()->change_nouveau_numero(tet->get_triangle1()->get_nouveau_numero()+1);
400 tet->get_triangle2()->change_nouveau_numero(tet->get_triangle2()->get_nouveau_numero()+1);
401 tet->get_triangle3()->change_nouveau_numero(tet->get_triangle3()->get_nouveau_numero()+1);
402 tet->get_triangle4()->change_nouveau_numero(tet->get_triangle4()->get_nouveau_numero()+1);
403 }
404
405 LISTE_MG_HEXA::iterator ith;
406 for (MG_HEXA* hex=mai->get_premier_hexa(ith);hex!=NULL;hex=mai->get_suivant_hexa(ith))
407 {
408 hex->get_quadrangle1()->change_nouveau_numero(hex->get_quadrangle1()->get_nouveau_numero()+1);
409 hex->get_quadrangle2()->change_nouveau_numero(hex->get_quadrangle2()->get_nouveau_numero()+1);
410 hex->get_quadrangle3()->change_nouveau_numero(hex->get_quadrangle3()->get_nouveau_numero()+1);
411 hex->get_quadrangle4()->change_nouveau_numero(hex->get_quadrangle4()->get_nouveau_numero()+1);
412 hex->get_quadrangle5()->change_nouveau_numero(hex->get_quadrangle5()->get_nouveau_numero()+1);
413 hex->get_quadrangle6()->change_nouveau_numero(hex->get_quadrangle6()->get_nouveau_numero()+1);
414 }
415 nbtrifront=0;
416 for (MG_TRIANGLE* tri=mai->get_premier_triangle(ittr);tri!=NULL;tri=mai->get_suivant_triangle(ittr))
417 {
418 if (mai->get_nb_mg_tetra()==0)
419 tri->change_nouveau_numero(1);
420 if (tri->get_nouveau_numero()==1)
421 {
422 nbtrifront++;
423 tri->get_segment1()->change_nouveau_numero(tri->get_segment1()->get_nouveau_numero()+1);
424 tri->get_segment2()->change_nouveau_numero(tri->get_segment2()->get_nouveau_numero()+1);
425 tri->get_segment3()->change_nouveau_numero(tri->get_segment3()->get_nouveau_numero()+1);
426 tri->get_noeud1()->change_nouveau_numero(1);
427 tri->get_noeud2()->change_nouveau_numero(1);
428 tri->get_noeud3()->change_nouveau_numero(1);
429
430 }
431 }
432 nbquadfront=0;
433 for (MG_QUADRANGLE* quad=mai->get_premier_quadrangle(itq);quad!=NULL;quad=mai->get_suivant_quadrangle(itq))
434 {
435 if (mai->get_nb_mg_hexa()==0)
436 quad->change_nouveau_numero(1);
437 if (quad->get_nouveau_numero()==1)
438 {
439 nbquadfront++;
440 quad->get_segment1()->change_nouveau_numero(quad->get_segment1()->get_nouveau_numero()+1);
441 quad->get_segment2()->change_nouveau_numero(quad->get_segment2()->get_nouveau_numero()+1);
442 quad->get_segment3()->change_nouveau_numero(quad->get_segment3()->get_nouveau_numero()+1);
443 quad->get_segment4()->change_nouveau_numero(quad->get_segment4()->get_nouveau_numero()+1);
444 quad->get_noeud1()->change_nouveau_numero(1);
445 quad->get_noeud2()->change_nouveau_numero(1);
446 quad->get_noeud3()->change_nouveau_numero(1);
447 quad->get_noeud4()->change_nouveau_numero(1);
448 }
449 }
450 nbsegfront=0;
451 for (MG_SEGMENT* seg=mai->get_premier_segment(its);seg!=NULL;seg=mai->get_suivant_segment(its))
452 if (seg->get_nouveau_numero()==2) nbsegfront++;
453 nbnofront=0;
454 for (MG_NOEUD* no=mai->get_premier_noeud(itn);no!=NULL;no=mai->get_suivant_noeud(itn))
455 if (no->get_nouveau_numero()==1) nbnofront++;
456 }
457
458 void MAILLEUR_ANALYSE::analyse_qualite_maillage_2D(MG_SOLUTION *sol,double &qualmin,double &qualmax,double &qualmoy,int *tab)
459 {
460 int nbnofront,nbsegfront,nbtrifront,nbquadfront;
461 denombre_maillage(nbnofront,nbsegfront,nbtrifront,nbquadfront);
462 qualmin=1e300,qualmax=-1e300,qualmoy=0.;
463 tab[0]=0;tab[1]=0;tab[2]=0;tab[3]=0;tab[4]=0;tab[5]=0;tab[6]=0;
464 int itri=0;
465 LISTE_MG_TRIANGLE::iterator ittr;
466 for (MG_TRIANGLE* tri=mai->get_premier_triangle(ittr);tri!=NULL;tri=mai->get_suivant_triangle(ittr))
467 if (tri->get_nouveau_numero()==1)
468 {
469 double qual=OPERATEUR::qualite_triangle(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord(),tri->get_noeud3()->get_coord());
470 MG_NOEUD * no1=tri->get_noeud1();
471 MG_NOEUD * no2=tri->get_noeud2();
472 MG_NOEUD * no3=tri->get_noeud3();
473 if (no1==no2)
474 if (no1==no3)
475 tab[6]++;
476 int nb1=no1->get_lien_triangle()->get_nb();
477 int nb2=no2->get_lien_triangle()->get_nb();
478 int nb3=no3->get_lien_triangle()->get_nb();
479 OT_VECTEUR_3D vec1(tri->get_noeud1()->get_coord(),tri->get_noeud2()->get_coord());
480 OT_VECTEUR_3D vec2(tri->get_noeud1()->get_coord(),tri->get_noeud3()->get_coord());
481 OT_VECTEUR_3D normal=vec1&vec2;
482 normal.norme();
483 int nbretourne=0;
484 int nbvoisin=0;
485 for (int i=0;i<nb1;i++)
486 for (int j=0;j<nb2;j++)
487 {
488 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
489 MG_TRIANGLE* tri2=no2->get_lien_triangle()->get(j);
490 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
491 {
492 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
493 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
494 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
495 normaltmp.norme();
496 double psca=normal*normaltmp;
497 if (psca<-cos(eps_angle_retourne)) nbretourne++;
498 nbvoisin++;
499 }
500 }
501 for (int i=0;i<nb1;i++)
502 for (int j=0;j<nb3;j++)
503 {
504 MG_TRIANGLE* tri1=no1->get_lien_triangle()->get(i);
505 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
506 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
507 {
508 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
509 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
510 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
511 normaltmp.norme();
512 double psca=normal*normaltmp;
513 if (psca<-cos(eps_angle_retourne)) nbretourne++;
514 nbvoisin++;
515 }
516 }
517 for (int i=0;i<nb2;i++)
518 for (int j=0;j<nb3;j++)
519 {
520 MG_TRIANGLE* tri1=no2->get_lien_triangle()->get(i);
521 MG_TRIANGLE* tri2=no3->get_lien_triangle()->get(j);
522 if ( (tri1==tri2) && (tri1!=tri) && (tri1->get_nouveau_numero()==1))
523 {
524 OT_VECTEUR_3D vec1tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud2()->get_coord());
525 OT_VECTEUR_3D vec2tmp(tri1->get_noeud1()->get_coord(),tri1->get_noeud3()->get_coord());
526 OT_VECTEUR_3D normaltmp=vec1tmp&vec2tmp;
527 normaltmp.norme();
528 double psca=normal*normaltmp;
529 if (psca<-cos(eps_angle_retourne)) nbretourne++;
530 nbvoisin++;
531 }
532 }
533 if (nbvoisin!=3)
534 tab[5]++;
535 if (nbretourne>1) qual=-qual;
536 qualmoy=qualmoy+qual;
537 if (qual<qualmin) qualmin=qual;
538 if (qual>qualmax) qualmax=qual;
539 if (qual<0.) tab[0]++;
540 else if (qual<borne1) tab[1]++;
541 else if (qual<borne2) tab[2]++;
542 else if (qual<borne3) tab[3]++;
543 else tab[4]++;
544 if (sol!=NULL)
545 if (mai->get_nb_mg_tetra()==0) sol->ecrire(qual,itri,0);
546 itri++;
547 }
548 qualmoy=qualmoy/nbtrifront;
549 }
550
551 void MAILLEUR_ANALYSE::analyse_qualite_maillage_3D(MG_SOLUTION *sol,double &qualmin,double &qualmax,double &qualmoy,int *tab)
552 {
553 qualmin=1e300,qualmax=-1e300,qualmoy=0.;
554 tab[0]=0;tab[1]=0;tab[2]=0;tab[3]=0;tab[4]=0;
555 qualmin=1e300,qualmax=-1e300,qualmoy=0.;
556 int itet=0;
557 LISTE_MG_TETRA::iterator itt;
558 for (MG_TETRA* tet=mai->get_premier_tetra(itt);tet!=NULL;tet=mai->get_suivant_tetra(itt))
559 {
560 double qual=OPERATEUR::qualite_tetra(tet->get_noeud1()->get_coord(),tet->get_noeud2()->get_coord(),tet->get_noeud3()->get_coord(),tet->get_noeud4()->get_coord());
561 OT_VECTEUR_3D vec1(tet->get_noeud1()->get_coord(),tet->get_noeud2()->get_coord());
562 OT_VECTEUR_3D vec2(tet->get_noeud1()->get_coord(),tet->get_noeud3()->get_coord());
563 OT_VECTEUR_3D vec3(tet->get_noeud1()->get_coord(),tet->get_noeud4()->get_coord());
564 OT_VECTEUR_3D pvec=vec1&vec2;
565 double psca=pvec*vec3;
566 if (psca<0.) qual=-qual;
567 qualmoy=qualmoy+qual;
568 if (qual<qualmin) qualmin=qual;
569 if (qual>qualmax) qualmax=qual;
570 if (qual<0.) tab[0]++;
571 else if (qual<borne1) tab[1]++;
572 else if (qual<borne2) tab[2]++;
573 else if (qual<borne3) tab[3]++;
574 else tab[4]++;
575 if (sol!=NULL)
576 sol->ecrire(qual,itet,0);
577 itet++;
578 }
579 qualmoy=qualmoy/mai->get_nb_mg_tetra();
580 }
581
582 void MAILLEUR_ANALYSE::analyse_validite_maillage_3D(int &nbsegcorrect,int &nbsegincorrect)
583 {
584
585 nbsegcorrect=0;
586 nbsegincorrect=0;
587 LISTE_MG_SEGMENT::iterator its;
588 for (MG_SEGMENT* seg=mai->get_premier_segment(its);seg!=NULL;seg=mai->get_suivant_segment(its))
589 if (seg->get_nouveau_numero()!=2)
590 {
591 MG_NOEUD* no1=seg->get_noeud1();
592 MG_NOEUD* no2=seg->get_noeud2();
593 int nb1=no1->get_lien_tetra()->get_nb();
594 int nb2=no2->get_lien_tetra()->get_nb();
595 double angletot=0;
596 for (int i=0;i<nb1;i++)
597 for (int j=0;j<nb2;j++)
598 {
599 MG_TETRA* tet1=no1->get_lien_tetra()->get(i);
600 MG_TETRA* tet2=no2->get_lien_tetra()->get(j);
601 if (tet1==tet2)
602 {
603 MG_NOEUD *nn1,*nn2,*nn3,*nn4;
604 if (tet1->get_noeud1()==no1) nn1=tet1->get_noeud1();
605 if (tet1->get_noeud2()==no1) nn1=tet1->get_noeud2();
606 if (tet1->get_noeud3()==no1) nn1=tet1->get_noeud3();
607 if (tet1->get_noeud4()==no1) nn1=tet1->get_noeud4();
608 if (tet1->get_noeud1()==no2) nn2=tet1->get_noeud1();
609 if (tet1->get_noeud2()==no2) nn2=tet1->get_noeud2();
610 if (tet1->get_noeud3()==no2) nn2=tet1->get_noeud3();
611 if (tet1->get_noeud4()==no2) nn2=tet1->get_noeud4();
612 if (tet1->get_noeud1()!=nn1)
613 if (tet1->get_noeud1()!=nn2) nn3=tet1->get_noeud1();
614 if (tet1->get_noeud2()!=nn1)
615 if (tet1->get_noeud2()!=nn2) nn3=tet1->get_noeud2();
616 if (tet1->get_noeud3()!=nn1)
617 if (tet1->get_noeud3()!=nn2) nn3=tet1->get_noeud3();
618 if (tet1->get_noeud4()!=nn1)
619 if (tet1->get_noeud4()!=nn2) nn3=tet1->get_noeud4();
620 if (tet1->get_noeud1()!=nn1)
621 if (tet1->get_noeud1()!=nn2)
622 if (tet1->get_noeud1()!=nn3) nn4=tet1->get_noeud1();
623 if (tet1->get_noeud2()!=nn1)
624 if (tet1->get_noeud2()!=nn2)
625 if (tet1->get_noeud2()!=nn3) nn4=tet1->get_noeud2();
626 if (tet1->get_noeud3()!=nn1)
627 if (tet1->get_noeud3()!=nn2)
628 if (tet1->get_noeud3()!=nn3) nn4=tet1->get_noeud3();
629 if (tet1->get_noeud4()!=nn1)
630 if (tet1->get_noeud4()!=nn2)
631 if (tet1->get_noeud4()!=nn3) nn4=tet1->get_noeud4();
632 double angle=get_angle_par_noeud<MG_NOEUD*>(nn1,nn2,nn3,nn1,nn2,nn4);
633 if (angle>M_PI) angle=2.*M_PI-angle;
634 angletot=angletot+angle;
635
636 }
637 }
638 if ((angletot<2*M_PI-0.001) || (angletot>2*M_PI+0.001))
639 {
640 char mess[255];
641 sprintf(mess," segment %lu angle matiere autour de %.2lf",seg->get_id(),angletot); affiche(mess);
642 nbsegincorrect++;
643 }
644 else nbsegcorrect++;
645 }
646 }
647
648
649 void MAILLEUR_ANALYSE::compare_maillage_carte_isotrope(FCT_TAILLE* carte,char *nom,double *tab)
650 {
651 MG_GESTIONNAIRE *gest=mai->get_gestionnaire();
652 LISTE_MG_TETRA::iterator ittet;
653 double vol=0;
654 for (MG_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
655 vol=vol+carte->calcul_volume_tetra_metrique(tet);
656 tab[0]=vol;
657 tab[1]=mai->get_nb_mg_tetra();
658 tab[2]=(tab[1]-tab[0])/tab[0]*100;
659 MG_SOLUTION *sol=new MG_SOLUTION(mai,4,nom,1,"Comparaison_taille",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
660 gest->ajouter_mg_solution(sol);
661 sol->change_legende(0,(char*)"taille_reelle");
662 sol->change_legende(1,(char*)"taille_carte");
663 sol->change_legende(2,(char*)"erreur");
664 sol->change_legende(3,(char*)"erreur absolue");
665 LISTE_MG_NOEUD::iterator it;
666 int i=0;
667 for (MG_NOEUD* no=mai->get_premier_noeud(it);no!=NULL;no=mai->get_suivant_noeud(it))
668 {
669 double *xyz=no->get_coord();
670 double tenseur[9];
671 carte->evaluer(xyz,tenseur);
672 double cartetaille=1./sqrt(tenseur[0]);
673 int nbseg=no->get_lien_segment()->get_nb();
674 double taille=0.;
675 int nbreelseg=0;
676 for (int j=0;j<nbseg;j++)
677 if (mai->get_mg_segmentid(no->get_lien_segment()->get(j)->get_id())!=NULL) {taille=taille+no->get_lien_segment()->get(j)->get_longueur();nbreelseg++;}
678 taille=taille/nbreelseg;
679 double erreur=(taille-cartetaille)*100./cartetaille;
680 sol->ecrire(taille,i,0);
681 sol->ecrire(cartetaille,i,1);
682 sol->ecrire(erreur,i,2);
683 sol->ecrire(fabs(erreur),i,3);
684 i++;
685 }
686 }