ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/optimisation/src/mgopt_simp.cpp
Revision: 247
Committed: Wed May 5 21:02:39 2010 UTC (15 years ago) by francois
Original Path: magic/lib/optimisation/optimisation/src/mgopt_simp.cpp
File size: 18462 byte(s)
Log Message:
ajout du lissage densite (distance + gaussien) + changement de notation pour etre conforme avec l'article

File Contents

# User Rev Content
1 francois 239 #include "gestionversion.h"
2     #include "mgopt_simp.h"
3     #include "mg_file.h"
4     #include "mg_export.h"
5     #include <string.h>
6    
7    
8    
9    
10    
11     class SIMP_TETRA
12     {
13     public:
14     FEM_TETRA* tet;
15     double densite;
16 francois 242 double new_densite;
17 francois 239 int design;
18 francois 242 double new_denergie;
19 francois 239 double energie;
20     double denergie;
21     double volume;
22     int maille_niveau;
23     int indice;
24     double distance_ref;
25 francois 247 double distance_ref2;
26 francois 239 double centre[3];
27     BOITE_3D get_boite_3D(void)
28     {
29     return tet->get_boite_3D();
30     };
31     vector<SIMP_TETRA*> voisin;
32 francois 247 vector<SIMP_TETRA*> voisin2;
33 francois 239 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 francois 247 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 francois 243 params.ajouter("nbrniveau",150.,"Nombre de matériaux utilisés");
60 francois 247 params.ajouter("p",3.,"Coefficient de penalite du module d'Young");
61     params.ajouter("ro_void",0.001,"Densite minimale consideree comme nulle");
62 francois 243 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 francois 247 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 francois 243 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 francois 247 params.ajouter("ro_min",0.8,"Seuil de conservation des éléments");
73 francois 239 }
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 francois 247 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 francois 246 {
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 francois 239 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 francois 242 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 francois 239 }
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 francois 242 tet2->volume=1./6.*tet->get_jacobien(jac,uv,lig,col,unite);
127 francois 247 tet2->distance_ref=rminc;
128     tet2->distance_ref2=rmind;
129 francois 246 double xyz[3]={tet2->centre[0],tet2->centre[1],tet2->centre[2]};
130     double val[9];
131     if (tet2->distance_ref<1e-16)
132 francois 242 {
133 francois 246 carte->evaluer(xyz,val);
134     tet2->distance_ref=1./sqrt(val[0]);
135 francois 242 }
136 francois 247 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 francois 239 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
144     {
145     tet2->design=1;
146 francois 247 tet2->densite=f;
147 francois 239 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 francois 247 double p=params.get_valeur("p");
169 francois 239 vector<double> Ctotiter;
170     while (ok==0)
171     {
172 francois 247 if (nbiteration>params.get_valeur("iter_max")) break;
173 francois 239 char message[255];
174     sprintf(message," Iteration %d",nbiteration);
175     affiche(message);
176     vector<FEM_TETRA*> *lstniveau=new vector<FEM_TETRA*>[niveaumax+1];
177 francois 247 double densmin = params.get_valeur("ro_void");
178 francois 239 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 francois 247 exp.aster(fem,nometude,2,"00000001",p,niveaumax,lstniveau);
187 francois 239 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 francois 242 int code=system(nomfichiertmp);
192     if (code!=0)
193     {
194     sprintf(nomfichiertmp," Code de sortie aster : %d",code);
195     affiche(nomfichiertmp);
196     }
197 francois 239 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 francois 247 tet->denergie= -p*2.*tet->energie/tet->densite;
204 francois 239 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 francois 247 // lissage compliance
220     double kc=params.get_valeur("kc");
221 francois 243 int type_lissage =(int)params.get_valeur("type_lissage");
222 francois 247 int lissage_densite =(int)params.get_valeur("lissage_densite");
223     int type_lissage_densite =(int)params.get_valeur("type_lissage_densite");
224 francois 242 for (int i=0;i<nbsimptet;i++)
225     {
226     SIMP_TETRA* tet=lsttet[i];
227 francois 247 if ((type_lissage==0) || (type_lissage==2))
228 francois 243 tet->new_denergie=tet->denergie;
229 francois 247 if ((type_lissage==1) || (type_lissage==3))
230 francois 242 {
231 francois 243 if (tet->design == 1)
232 francois 242 {
233 francois 247 double hi= pow(tet->distance_ref,kc);
234     double hisensi = hi*tet->densite*tet->denergie;
235     int nbvoisin=tet->voisin.size();
236 francois 243 for (int j = 0 ; j<nbvoisin ; j++)
237     {
238     SIMP_TETRA* tet2=tet->voisin[j];
239     if (tet2->design == 1)
240     {
241 francois 247 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 francois 243 }
246 francois 242 }
247 francois 247 tet->new_denergie = hisensi/hi/tet->densite;
248 francois 243 }
249     else tet->new_denergie=tet->denergie;
250 francois 242 }
251     }
252 francois 239 // application formule pas encore connue
253     double l1= 1e-8 ;
254     double l2= 1e8;
255     double m=params.get_valeur("m");
256 francois 241 double eta=params.get_valeur("eta");
257 francois 242 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 francois 239 {
263 francois 242 compteurlagrange++;
264     double lmid = 0.5*(l2+l1);
265     critere_densite = 0.0;
266     for (int i=0;i<nbsimptet;i++)
267 francois 239 {
268     SIMP_TETRA* tet=lsttet[i];
269     if (tet->design==1)
270     {
271     double x1 = tet->densite+m;
272 francois 242 double beta=-tet->new_denergie/lmid/tet->volume;
273 francois 241 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 francois 239 tet->new_densite = max(x7,x8);
281 francois 242 critere_densite = critere_densite + tet->new_densite*tet->volume;
282     }
283 francois 239 else
284     {
285     tet->new_densite=1.;
286     }
287 francois 242 }
288 francois 247 if (critere_densite - f*volume_design > 0.)
289 francois 239 l1=lmid;
290     else
291     l2=lmid;
292 francois 247 if (100.*fabs(critere_densite- f*volume_design )/(f*volume_design)<convergence_lagrange) oklagrange=1;
293 francois 243 if (compteurlagrange>500) oklagrange=2;
294 francois 242 }
295 francois 247 if (oklagrange==1) sprintf(message," Convergence multiplicateur lagrange %le%%",100.*(critere_densite- f*volume_design )/(f*volume_design));
296 francois 242 if (oklagrange==2) sprintf(message," Divergence multiplicateur lagrange %le %le",l1,l2);
297     affiche(message);
298 francois 247 // lissage de densite.
299     double kd=params.get_valeur("kd");
300 francois 239 for (int i=0;i<nbsimptet;i++)
301 francois 242 {
302 francois 239 SIMP_TETRA* tet=lsttet[i];
303 francois 247 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 francois 242 }
333 francois 239 nbiteration++;
334     }
335 francois 247 double seuil=params.get_valeur("ro_min");
336 francois 245 affiche(" Ecriture des donnees finales");
337 francois 239 char message[255];
338 francois 244 sprintf(message,"%s.compliance",nometudesortie);
339 francois 239 FILE *out=fopen(message,"wt");
340     for (int i=0;i<Ctotiter.size();i++)
341     fprintf(out,"%le\n",Ctotiter[i]);
342 francois 245 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 francois 247 fprintf(out,"Objectif du volume de design : %le \n",volume_design*f);
369 francois 245 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 francois 247 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 francois 245 fprintf(out,"*************************************************************\n");
377     fclose(out);
378 francois 239 LISTE_FEM_NOEUD::iterator itnoeud;
379     int nbfemnoeud=fem->get_nb_fem_noeud();
380 francois 242 /*double *nume=new double[nbfemnoeud];
381 francois 239 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 francois 242 }*/
390 francois 243 sprintf(message,"%s_densite1.sol",nometudesortie);
391 francois 241 int nbsolution=gestd->get_nb_fem_solution();
392 francois 242 for (int i=nbsolution;i>0;i--)
393 francois 243 gestd->supprimer_fem_solution_du_gestionnaire(i-1);
394 francois 239 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 francois 242 /*for (int j=0;j<tet->tet->get_nb_fem_noeud();j++)
407 francois 239 {
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 francois 242 } */
412 francois 239 }
413 francois 243 /*sprintf(message,"%s_densite2.sol",nometudesortie);
414 francois 239 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 francois 242 delete [] nume;*/
425 francois 239 int nb=lsttet.size();
426     for (int i=0;i<nb;i++) delete lsttet[i];
427     }
428    
429 francois 247 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 francois 239
440 francois 240 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 francois 245 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 francois 240 affiche("Fin");
478     }
479 francois 239
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 francois 247 vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
571     if (tet->distance_ref<tet->distance_ref2)
572     lstvoisin=tet->voisin2;
573 francois 239 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 francois 247 double dist=tet->distance(stet);
588     if (dist<tet->distance_ref)
589 francois 239 tet->voisin.insert(tet->voisin.end(),stet);
590 francois 247 if (dist<tet->distance_ref2)
591     tet->voisin2.insert(tet->voisin2.end(),stet);
592 francois 239 }
593     }
594     }
595 francois 247 if (compteur>=lstvoisin.size()) ok=1;
596 francois 239 else
597     {
598 francois 247 tetcour=lstvoisin[compteur];
599 francois 239 compteur++;
600     }
601 francois 247
602 francois 239 }
603    
604     }