ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/optimisation/src/mgopt_simp.cpp
Revision: 258
Committed: Thu Aug 12 19:10:34 2010 UTC (15 years ago) by francois
File size: 18479 byte(s)
Log Message:
Mise a jour toxfem + parametrisation compilation toxfem + bug 
comparaison

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