ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/optimisation/src/mgopt_simp.cpp
Revision: 268
Committed: Fri Oct 29 21:42:16 2010 UTC (14 years, 10 months ago) by francois
File size: 19193 byte(s)
Log Message:
ajout de securite pour les eventuels divisions par 0 dans le changement precedent

File Contents

# Content
1 #include "gestionversion.h"
2 #include "mgopt_simp.h"
3 #include "mg_file.h"
4 #include "mg_export.h"
5 #include <string.h>
6 #include <math.h>
7
8
9
10
11 class SIMP_TETRA
12 {
13 public:
14 FEM_TETRA* tet;
15 double densite;
16 double new_densite;
17 int design;
18 double new_denergie;
19 double energie;
20 double denergie;
21 double volume;
22 int maille_niveau;
23 int indice;
24 double distance_ref;
25 double distance_ref2;
26 double centre[3];
27 BOITE_3D get_boite_3D(void)
28 {
29 return tet->get_boite_3D();
30 };
31 vector<SIMP_TETRA*> voisin;
32 vector<SIMP_TETRA*> voisin2;
33 unsigned long get_id(void) {return tet->get_id();};
34 double distance(SIMP_TETRA* tet2)
35 {
36 double dx=centre[0]-tet2->centre[0];
37 double dy=centre[1]-tet2->centre[1];
38 double dz=centre[2]-tet2->centre[2];
39 return sqrt(dx*dx+dy*dy+dz*dz);
40 };
41 };
42
43
44
45
46
47
48
49
50
51
52 MGOPT_SIMP::MGOPT_SIMP():MGOPT()
53 {
54 params.ajouter("f",0.3,"Fraction volumique de la methode SIMP");
55 params.ajouter("rminc",0.,"0. Valeur de la carte de taille (si pas de maillage le parametre fichiercarte permet d'utiliser une carte de taille) sinon valeur de rmin pour le lissage de la compliance");
56 params.ajouter("rmind",0.,"0. Valeur de la carte de taille (si pas de maillage le parametre fichiercarte permet d'utiliser une carte de taille) sinon valeur de rmin pour le lissage de la densite");
57 params.ajouter("coefvoisinc",1.0,"Coefficient de multiplication de rminc");
58 params.ajouter("coefvoisind",1.0,"Coefficient de multiplication de rmind");
59 params.ajouter("nbrniveau",150.,"Nombre de matériaux utilisés");
60 params.ajouter("p",3.,"Coefficient de penalite du module d'Young");
61 params.ajouter("ro_void",0.001,"Densite minimale consideree comme nulle");
62 params.ajouter("m",0.2,"Limite d'evolution de densité entre deux itérations");
63 params.ajouter("eta",0.5,"Coefficent d'affectation du beta");
64 params.ajouter("type_lissage",1.,"0. Pas de lissage 1. Lissage de la compliance 2. Lissage de la densité 3. Lissage de la compliance et de la densite");
65 params.ajouter("lissage_densite",1.,"0. Complet 1. Derniere iteration");
66 params.ajouter("type_lissage_densite",1.,"0. Distance 1. Distance pondéré 2. Gaussien 3. Gaussien pondéré");
67 params.ajouter("type_lissage_compliance",1.,"0. Sigmund 1997 1. Sigmund 2007");
68 params.ajouter("kc",1.0,"Ponderation de la distance dans le lissage de la compliance");
69 params.ajouter("kd",1.0,"Ponderation de la distance dans le lissage de la densité");
70 params.ajouter("convergence_lagrange",0.1,"Critere de convergence de la recherche du multiplicateur de Lagrange en \%");
71 params.ajouter("iter_max",50.,"Nombre d'iteration maximale dans le processus SIMP");
72 params.ajouter("critere_convergence",0.5,"Critere de convergence de la méthode SIMP en \%");
73 params.ajouter("ro_min",0.8,"Seuil de conservation des éléments");
74 }
75
76 MGOPT_SIMP::MGOPT_SIMP(MGOPT_SIMP &mdd):MGOPT(mdd)
77 {
78 }
79
80
81 MGOPT_SIMP::~MGOPT_SIMP()
82 {
83 }
84
85
86 void MGOPT_SIMP::optimisation(FEM_MAILLAGE* fem)
87 {
88 affiche(" Initialisation");
89 vector<SIMP_TETRA*> lsttet;
90 double f=params.get_valeur("f");
91 double rminc=params.get_valeur("rminc");
92 double rmind=params.get_valeur("rmind");
93 if (((rminc<1e-16)||(rmind<1e-16)) && (carte==NULL))
94 {
95 affiche(" Lecture de la carte de taille");
96 carte=new FCT_GENERATEUR_3D<4>;
97 std::string fichiercarte=params.get_nom("fichiercarte");
98 carte->lire((char *)fichiercarte.c_str());
99 }
100 double volume_tot;
101 double volume_design=0;
102 double volume_non_design=0;
103 double unite=fem->get_mg_maillage()->get_mg_geometrie()->get_valeur_unite();
104 LISTE_FEM_TETRA::iterator it;
105 int ntet=0;
106 for (FEM_TETRA* tet=fem->get_premier_tetra(it);tet!=NULL;tet=fem->get_suivant_tetra(it))
107 {
108 SIMP_TETRA* tet2=new SIMP_TETRA;
109 tet2->tet=tet;
110 tet2->tet->change_numero(ntet);
111 ntet++;
112 tet2->centre[0]=0.;
113 tet2->centre[1]=0.;
114 tet2->centre[2]=0.;
115 int nbnoeud=tet->get_nb_fem_noeud();
116 for (int i=0;i<nbnoeud;i++)
117 {
118 tet2->centre[0]=tet2->centre[0]+tet->get_fem_noeud(i)->get_x()*unite;
119 tet2->centre[1]=tet2->centre[1]+tet->get_fem_noeud(i)->get_y()*unite;
120 tet2->centre[2]=tet2->centre[2]+tet->get_fem_noeud(i)->get_z()*unite;
121 }
122 tet2->centre[0]=tet2->centre[0]/nbnoeud;
123 tet2->centre[1]=tet2->centre[1]/nbnoeud;
124 tet2->centre[2]=tet2->centre[2]/nbnoeud;
125 int lig,col;
126 double jac[9],uv[3]={1./4.,1./4.,1./4.};
127 tet2->volume=1./6.*tet->get_jacobien(jac,uv,lig,col,unite);
128 tet2->distance_ref=rminc;
129 tet2->distance_ref2=rmind;
130 double xyz[3]={tet2->centre[0],tet2->centre[1],tet2->centre[2]};
131 double val[9];
132 if (tet2->distance_ref<1e-16)
133 {
134 carte->evaluer(xyz,val);
135 tet2->distance_ref=1./sqrt(val[0]);
136 }
137 if (tet2->distance_ref2<1e-16)
138 {
139 carte->evaluer(xyz,val);
140 tet2->distance_ref2=1./sqrt(val[0]);
141 }
142 tet2->distance_ref=params.get_valeur("coefvoisinc")*tet2->distance_ref*unite;
143 tet2->distance_ref2=params.get_valeur("coefvoisind")*tet2->distance_ref2*unite;
144 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
145 {
146 tet2->design=1;
147 tet2->densite=f;
148 volume_design=volume_design+tet2->volume;
149 }
150 else
151 {
152 tet2->design=0;
153 tet2->densite=1.;
154 volume_non_design=volume_non_design+tet2->volume;
155 }
156 lsttet.insert(lsttet.end(),tet2);
157 }
158 volume_tot=volume_design+volume_non_design;
159 double volumemoyen=volume_tot/fem->get_nb_fem_tetra();
160 affiche(" Recherche de voisins");
161 int nbsimptet=lsttet.size();
162 for (int i=0;i<nbsimptet;i++)
163 {
164 SIMP_TETRA* tet=lsttet[i];
165 if (tet->design==0) continue;
166 ajouter_voisin(i,tet,lsttet);
167 }
168 int nbiteration=1;
169 int ok=0;
170 int niveaumax=(int)params.get_valeur("nbrniveau");
171 double p=params.get_valeur("p");
172 vector<double> Ctotiter;
173 while (ok==0)
174 {
175 if (nbiteration>params.get_valeur("iter_max")) break;
176 char message[255];
177 sprintf(message," Iteration %d",nbiteration);
178 affiche(message);
179 vector<FEM_TETRA*> *lstniveau=new vector<FEM_TETRA*>[niveaumax+1];
180 double densmin = params.get_valeur("ro_void");
181 for (int i=0;i<nbsimptet;i++)
182 {
183 SIMP_TETRA* tet=lsttet[i];
184 tet->maille_niveau=(int)((tet->densite-densmin)*niveaumax/(1.-densmin))+1;
185 if (tet->maille_niveau>niveaumax) tet->maille_niveau=niveaumax;
186 lstniveau[tet->maille_niveau].insert(lstniveau[tet->maille_niveau].end(),tet->tet);
187 }
188 MG_EXPORT exp;
189 exp.aster(fem,nometude,2,"00000001",p,niveaumax,lstniveau);
190 delete [] lstniveau;
191 affiche(" Calcul aster");
192 char nomfichiertmp[255];
193 sprintf(nomfichiertmp,"%s/as_run %s.export 1>aster.log 2>&1",getenv("PATHASTER"),nometude);
194 int code=system(nomfichiertmp);
195 if (code!=0)
196 {
197 sprintf(nomfichiertmp," Code de sortie aster : %d",code);
198 affiche(nomfichiertmp);
199 }
200 affiche(" Analyse resultat");
201 recupere_energie(lsttet);
202 double Ctot=0;
203 for (int i=0;i<nbsimptet;i++)
204 {
205 SIMP_TETRA* tet=lsttet[i];
206 tet->denergie= -p*2.*tet->energie/tet->densite;
207 Ctot=Ctot+2.*tet->energie;
208 }
209 Ctotiter.insert(Ctotiter.end(),Ctot);
210 sprintf(message," Compliance %le",Ctot);
211 affiche(message);
212 if (nbiteration!=1)
213 {
214 int nb=Ctotiter.size();
215 double c1=Ctotiter[nb-2];
216 double c2=Ctotiter[nb-1];
217 double ecart=fabs((c2-c1)/c1)*100.;
218 if (ecart<params.get_valeur("critere_convergence")) ok=1;
219 sprintf(message," Ecart %lf%%",ecart);
220 affiche(message);
221 }
222 // lissage compliance
223 double kc=params.get_valeur("kc");
224 int type_lissage =(int)params.get_valeur("type_lissage");
225 int lissage_densite =(int)params.get_valeur("lissage_densite");
226 int type_lissage_densite =(int)params.get_valeur("type_lissage_densite");
227 int type_lissage_compliance=(int)params.get_valeur("type_lissage_compliance");
228 for (int i=0;i<nbsimptet;i++)
229 {
230 SIMP_TETRA* tet=lsttet[i];
231 if ((type_lissage==0) || (type_lissage==2))
232 tet->new_denergie=tet->denergie;
233 if ((type_lissage==1) || (type_lissage==3))
234 {
235 if (tet->design == 1)
236 {
237 double hi= pow(tet->distance_ref,kc);
238 double hisensi = hi*tet->densite*tet->denergie;
239 if (type_lissage_compliance==1)
240 {
241 hi=hi/tet->volume;
242 hisensi=hisensi/max(volumemoyen*0.00001,tet->volume);
243 }
244 int nbvoisin=tet->voisin.size();
245 for (int j = 0 ; j<nbvoisin ; j++)
246 {
247 SIMP_TETRA* tet2=tet->voisin[j];
248 if (tet2->design == 1)
249 {
250 double dist=tet->distance(tet2);
251 double hj =fabs(pow(tet->distance_ref - dist,kc));
252 if (type_lissage_compliance==0)
253 {
254 hisensi=hisensi+tet2->densite*hj*tet2->denergie;
255 hi=hi+hj;
256 }
257 if (type_lissage_compliance==1)
258 {
259 hisensi=hisensi+tet2->densite*hj*tet2->denergie/max(volumemoyen,tet2->volume);
260 hi=hi+hj/tet2->volume;
261 }
262 hisensi=hisensi+tet2->densite*hj*tet2->denergie;
263 hi=hi+hj;
264 }
265 }
266 tet->new_denergie = hisensi/hi/max(tet->densite,densmin);
267 }
268 else tet->new_denergie=tet->denergie;
269 }
270 }
271 // application formule pas encore connue
272 double l1= 1e-8 ;
273 double l2= 1e8;
274 double m=params.get_valeur("m");
275 double eta=params.get_valeur("eta");
276 double convergence_lagrange=params.get_valeur("convergence_lagrange");
277 double critere_densite = 0.0;
278 int oklagrange=0;
279 int compteurlagrange=0;
280 while (oklagrange==0)
281 {
282 compteurlagrange++;
283 double lmid = 0.5*(l2+l1);
284 critere_densite = 0.0;
285 for (int i=0;i<nbsimptet;i++)
286 {
287 SIMP_TETRA* tet=lsttet[i];
288 if (tet->design==1)
289 {
290 double x1 = tet->densite+m;
291 double beta=-tet->new_denergie/lmid/tet->volume;
292 double x2 = tet->densite*pow(beta,eta);
293 double x3 = min(x1,x2);
294 double x4 = 1.;
295 double x5 = min(x3,x4);
296 double x6 = tet->densite-m;
297 double x7 = max(x5,x6);
298 double x8 = densmin;
299 tet->new_densite = max(x7,x8);
300 critere_densite = critere_densite + tet->new_densite*tet->volume;
301 }
302 else
303 {
304 tet->new_densite=1.;
305 }
306 }
307 if (critere_densite - f*volume_design > 0.)
308 l1=lmid;
309 else
310 l2=lmid;
311 if (100.*fabs(critere_densite- f*volume_design )/(f*volume_design)<convergence_lagrange) oklagrange=1;
312 if (compteurlagrange>500) oklagrange=2;
313 }
314 if (oklagrange==1) sprintf(message," Convergence multiplicateur lagrange %le%%",100.*(critere_densite- f*volume_design )/(f*volume_design));
315 if (oklagrange==2) sprintf(message," Divergence multiplicateur lagrange %le %le",l1,l2);
316 affiche(message);
317 // lissage de densite.
318 double kd=params.get_valeur("kd");
319 for (int i=0;i<nbsimptet;i++)
320 {
321 SIMP_TETRA* tet=lsttet[i];
322 if ((type_lissage==2) || (type_lissage==3))
323 {
324 if (((lissage_densite==1)&&(ok==1)) || (lissage_densite==0))
325 {
326 if (tet->design == 1)
327 {
328 double widensite=0.;
329 double wi= 0.;
330 wi=poid_lissage(0.,tet->distance_ref2,kd,tet->volume,type_lissage_densite);
331 widensite = wi*tet->new_densite;
332 int nbvoisin=tet->voisin2.size();
333 for (int j = 0 ; j<nbvoisin ; j++)
334 {
335 SIMP_TETRA* tet2=tet->voisin2[j];
336 if (tet2->design == 1)
337 {
338 double dist=tet->distance(tet2);
339 double wj=poid_lissage(dist,tet->distance_ref2,kd,tet2->volume,type_lissage_densite);
340 wi = wi+wj;
341 widensite = widensite + tet2->new_densite*wj;
342 }
343 }
344 tet->densite = widensite/wi;
345 }
346 else tet->densite=tet->new_densite;
347 }
348 else tet->densite=tet->new_densite;
349 }
350 else tet->densite=tet->new_densite;
351 }
352 nbiteration++;
353 }
354 double seuil=params.get_valeur("ro_min");
355 affiche(" Ecriture des donnees finales");
356 char message[255];
357 sprintf(message,"%s.compliance",nometudesortie);
358 FILE *out=fopen(message,"wt");
359 for (int i=0;i<Ctotiter.size();i++)
360 fprintf(out,"%le\n",Ctotiter[i]);
361 double crit1=0.;
362 double crit2=0.;
363 double crit3=0.;
364 double critv1[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
365 double critv2[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
366 for (int i=0;i<nbsimptet;i++)
367 {
368 SIMP_TETRA* tet=lsttet[i];
369 if (tet->design==1)
370 {
371 crit1=crit1+tet->densite*tet->volume;
372 if (tet->densite>seuil)
373 {
374 crit2=crit2+tet->densite*tet->volume;
375 crit3=crit3+tet->volume;
376 }
377 for (int j=1;j<10;j++)
378 if (tet->densite>0.1*j)
379 {
380 critv1[j]=critv1[j]+tet->densite*tet->volume;
381 critv2[j]=critv2[j]+tet->volume;
382 }
383 }
384 }
385 fprintf(out,"\n\n\n**************************************************************\n");
386 fprintf(out,"Volume du design : %le \n",volume_design);
387 fprintf(out,"Objectif du volume de design : %le \n",volume_design*f);
388 fprintf(out,"Volume de design obtenu : %le \n",crit1);
389 fprintf(out,"Volume de design obtenu avec le seuil: %le \n",crit2);
390 fprintf(out,"Volume reel de design obtenu avec le seuil: %le \n\n",crit3);
391 fprintf(out," : Volume : Volume reel : Objectif\n");
392 fprintf(out," : %le : %le : %le\n",volume_design,volume_design,volume_design);
393 for (int j=1;j<10;j++)
394 fprintf(out,"Volume de design obtenu avec le seuil de %.1f : %le : %le : %le \n",j*0.1,critv1[j],critv2[j],volume_design*f);
395 fprintf(out,"*************************************************************\n");
396 fclose(out);
397 LISTE_FEM_NOEUD::iterator itnoeud;
398 int nbfemnoeud=fem->get_nb_fem_noeud();
399 /*double *nume=new double[nbfemnoeud];
400 double *deno=new double[nbfemnoeud];
401 int cpt=0;
402 for (FEM_NOEUD *nd=fem->get_premier_noeud(itnoeud);nd!=NULL;nd=fem->get_suivant_noeud(itnoeud))
403 {
404 nd->change_numero(cpt);
405 nume[cpt]=0.;
406 deno[cpt]=0.;
407 cpt++;
408 }*/
409 sprintf(message,"%s_densite1.sol",nometudesortie);
410 int nbsolution=gestd->get_nb_fem_solution();
411 for (int i=nbsolution;i>0;i--)
412 gestd->supprimer_fem_solution_du_gestionnaire(i-1);
413 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_tetra(),"Optimisation",ENTITE_TETRA);
414 gestd->ajouter_fem_solution(solution);
415 solution->change_legende(0,"Densite");
416 for (int i=0;i<nbsimptet;i++)
417 {
418 SIMP_TETRA* tet=lsttet[i];
419 if (tet->design==1)
420 if (tet->densite>seuil)
421 ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(OPTIMISE);
422 else
423 ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(MAILLEUR_AUTO);
424 solution->ecrire(i,0,tet->densite);
425 /*for (int j=0;j<tet->tet->get_nb_fem_noeud();j++)
426 {
427 FEM_NOEUD* noeud=tet->tet->get_fem_noeud(j);
428 nume[noeud->get_numero()]=nume[noeud->get_numero()]+tet->volume*tet->densite;
429 deno[noeud->get_numero()]=deno[noeud->get_numero()]+tet->volume;
430 } */
431 }
432 /*sprintf(message,"%s_densite2.sol",nometudesortie);
433 FEM_SOLUTION* solution2=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_noeud(),"Optimisation",ENTITE_NOEUD);
434 gestd->ajouter_fem_solution(solution2);
435 solution2->change_legende(0,"Densite");
436 cpt=0;
437 for (FEM_NOEUD *nd=fem->get_premier_noeud(itnoeud);nd!=NULL;nd=fem->get_suivant_noeud(itnoeud))
438 {
439 solution2->ecrire(cpt,0,nume[cpt]/deno[cpt]);
440 cpt++;
441 }
442 delete [] deno;
443 delete [] nume;*/
444 int nb=lsttet.size();
445 for (int i=0;i<nb;i++) delete lsttet[i];
446 }
447
448 double MGOPT_SIMP::poid_lissage(double dist,double distref,double k,double volume,int type)
449 {
450 double wi;
451 if (type==0) wi=pow(distref-dist,k);
452 if (type==1) wi=pow(distref-dist,k)*volume;
453 if (type==2) wi=exp(-dist*dist/2./distref/distref/9.)/2./M_PI/(distref/3.);
454 if (type==3) wi=volume*exp(-dist*dist/2./distref/distref/9.)/2./M_PI/(distref/3.);
455 return fabs(wi);
456
457 }
458
459 void MGOPT_SIMP::adapte_resultat(char *nomgestd,char *nomparam)
460 {
461 if (nomparam!=NULL) lire_params(nomparam);
462 affiche("");
463 affiche("*************************");
464 affiche("Optimisation de topologie");
465 affiche("*************************");
466 affiche("");
467 affiche("");
468 affiche("Changement du seuil dans les resultats");
469 double seuil=params.get_valeur("seuil");
470 gestd=new MG_FILE(nomgestd);
471 FEM_MAILLAGE* fem=gestd->get_fem_maillage(0);
472 FEM_SOLUTION* solution=gestd->get_fem_solution(0);
473 solution->active_solution(0);
474 LISTE_FEM_TETRA::iterator it;
475 for (FEM_TETRA *tet=fem->get_premier_tetra(it);tet!=NULL;tet=fem->get_suivant_tetra(it))
476 {
477 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
478 if (tet->get_solution()>seuil)
479 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(OPTIMISE);
480 else
481 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAILLEUR_AUTO);
482
483 }
484 affiche("Enregistrement");
485 gestd->enregistrer(nomgestd);
486 affiche("Enregistrement sous GMSH");
487 char *p=strchr(nomgestd,'.');
488 strncpy(nometude,nomgestd,p-nomgestd);
489 nometude[p-nomgestd]=0;
490 MG_EXPORT exp;
491 char nomfichier[500];
492 sprintf(nomfichier,"%s_mg",nometude);
493 exp.gmsh(fem->get_mg_maillage(),nomfichier);
494 sprintf(nomfichier,"%s_fem",nometude);
495 exp.gmsh(fem,nomfichier);
496 affiche("Fin");
497 }
498
499
500 void MGOPT_SIMP::recupere_energie(vector<class SIMP_TETRA*> lsttet)
501 {
502 char message[750];
503 sprintf(message,"%s.resu",nometude);
504 FILE* in=fopen(message,"rt");
505 int fin=0;
506 do
507 {
508 fgets(message,750,in);
509 if (feof(in)) fin=1;
510 char mot1[100];
511 char mot2[100];
512 char mot3[100];
513 char mot4[100];
514 char mot5[100];
515 char mot6[100];
516 char mot7[100];
517 char mot8[100];
518 char mot9[100];
519 char mot10[100];
520 int numlu=sscanf(message,"%s %s %s %s %s %s %s %s %s %s",mot1,mot2,mot3,mot4,mot5,mot6,mot7,mot8,mot9,mot10);
521 if (numlu>9)
522 if (strcmp(mot1,"CHAMP")==0)
523 if (strcmp(mot2,"PAR")==0)
524 if (strcmp(mot3,"ELEMENT")==0)
525 if (strcmp(mot4,"CONSTANT")==0)
526 if (strcmp(mot5,"SUR")==0)
527 if (strcmp(mot6,"L'ELEMENT")==0)
528 if (strcmp(mot7,"DE")==0)
529 if (strcmp(mot8,"NOM")==0)
530 if (strcmp(mot9,"SYMBOLIQUE")==0)
531 if (strcmp(mot10,"EPOT_ELEM_DEPL")==0)
532 {
533 int fin2=0;
534 int passe=0;
535 int nbelement=0;
536 do
537 {
538 char message[750];
539 fgets(message,750,in);
540 char mot1[500];
541 char mot2[500];
542 int numlu=sscanf(message,"%s %s",mot1,mot2);
543 int decalage;
544 if ((numlu==2) && (strcmp(mot2,"TOTALE")==0))
545 {
546 char *p=strchr(mot1,'M')+1;
547 int num=atoi(p);
548 if (passe==0) {passe=1;decalage=num;}
549 fgets(message,750,in);
550 double val;
551 sscanf(message,"%lf",&val);
552 lsttet[num-decalage]->energie=val;
553 nbelement++;
554 }
555 if (nbelement == lsttet.size()) {fin2=1;fin=0;}
556 }
557
558 while (fin2==0);
559 }
560 }
561 while (fin==0);
562 fclose(in);
563 }
564
565
566
567 void MGOPT_SIMP::ajouter_voisin(int i,SIMP_TETRA* tet,vector<SIMP_TETRA*> &lst)
568 {
569 tet->indice=i;
570 int nbnoeud=tet->tet->get_nb_fem_noeud();
571 int correspondance[4];
572 if (nbnoeud==4)
573 {
574 correspondance[0]=0;
575 correspondance[1]=1;
576 correspondance[2]=2;
577 correspondance[3]=3;
578 }
579 if (nbnoeud==10)
580 {
581 correspondance[0]=0;
582 correspondance[1]=2;
583 correspondance[2]=4;
584 correspondance[3]=9;
585 }
586 SIMP_TETRA* tetcour=tet;
587 int ok=0;
588 int compteur=0;
589 vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
590 if (tet->distance_ref<tet->distance_ref2)
591 lstvoisin=tet->voisin2;
592 while (ok==0)
593 {
594 for (int j=0;j<4;j++)
595 {
596 int num=correspondance[j];
597 FEM_NOEUD *noeud=tetcour->tet->get_fem_noeud(num);
598 int nbtetra=noeud->get_lien_tetra()->get_nb();
599 for (int k=0;k<nbtetra;k++)
600 {
601 FEM_TETRA* ftet=noeud->get_lien_tetra()->get(k);
602 SIMP_TETRA* stet=lst[ftet->get_numero()];
603 if (stet->indice!=i)
604 {
605 stet->indice=i;
606 double dist=tet->distance(stet);
607 if (dist<tet->distance_ref)
608 tet->voisin.insert(tet->voisin.end(),stet);
609 if (dist<tet->distance_ref2)
610 tet->voisin2.insert(tet->voisin2.end(),stet);
611 }
612 }
613 }
614 if (compteur>=lstvoisin.size()) ok=1;
615 else
616 {
617 tetcour=lstvoisin[compteur];
618 compteur++;
619 }
620
621 }
622
623 }