ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/optimisation/src/mgopt_simp.cpp
Revision: 306
Committed: Wed Jan 11 21:14:52 2012 UTC (13 years, 4 months ago) by francois
File size: 20740 byte(s)
Log Message:
Adaption de la méthode SIMP à la gestion des matériaux

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