ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_simp.cpp
Revision: 681
Committed: Wed Jun 10 15:52:55 2015 UTC (9 years, 11 months ago) by francois
File size: 26296 byte(s)
Log Message:
Affichage du numero des iterations de la SIMP_adaptative lors du déroulement de celle-ci
bug de relecture du fichier de parametre

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 468 #include "fct_taille_fem_solution.h"
8 nana 565 #include "ot_cpu.h"
9 francois 239
10    
11     class SIMP_TETRA
12     {
13     public:
14 francois 309 FEM_ELEMENT3* tet;
15 francois 239 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 francois 468 std::vector<SIMP_TETRA*> voisin;
32     std::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 francois 494 MGOPT_SIMP::MGOPT_SIMP(bool save):MGOPT(save)
53 francois 239 {
54 francois 396 params.ajouter("f",0.3,OT_PARAMETRES::DOUBLE,"Fraction volumique de la methode SIMP");
55     params.ajouter("rminc",0.,OT_PARAMETRES::DOUBLE,"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.,OT_PARAMETRES::DOUBLE,"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,OT_PARAMETRES::DOUBLE,"Coefficient de multiplication de rminc");
58     params.ajouter("coefvoisind",1.0,OT_PARAMETRES::DOUBLE,"Coefficient de multiplication de rmind");
59     params.ajouter("nbrniveau",150.,OT_PARAMETRES::DOUBLE,"Nombre de matériaux utilisés");
60     params.ajouter("p",3.,OT_PARAMETRES::DOUBLE,"Coefficient de penalite du module d'Young");
61     params.ajouter("ro_void",0.001,OT_PARAMETRES::DOUBLE,"Densite minimale consideree comme nulle");
62     params.ajouter("m",0.2,OT_PARAMETRES::DOUBLE,"Limite d'evolution de densité entre deux itérations");
63     params.ajouter("eta",0.5,OT_PARAMETRES::DOUBLE,"Coefficent d'affectation du beta");
64     params.ajouter("type_lissage",1.,OT_PARAMETRES::DOUBLE,"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.,OT_PARAMETRES::DOUBLE,"0. Complet 1. Derniere iteration");
66     params.ajouter("type_lissage_densite",1.,OT_PARAMETRES::DOUBLE,"0. Distance 1. Distance pondéré 2. Gaussien 3. Gaussien pondéré");
67     params.ajouter("type_lissage_compliance",1.,OT_PARAMETRES::DOUBLE,"0. Sigmund 1997 1. Sigmund 2007");
68     params.ajouter("kc",1.0,OT_PARAMETRES::DOUBLE,"Ponderation de la distance dans le lissage de la compliance");
69     params.ajouter("kd",1.0,OT_PARAMETRES::DOUBLE,"Ponderation de la distance dans le lissage de la densité");
70     params.ajouter("convergence_lagrange",0.1,OT_PARAMETRES::DOUBLE,"Critere de convergence de la recherche du multiplicateur de Lagrange en \%");
71     params.ajouter("iter_max",50.,OT_PARAMETRES::DOUBLE,"Nombre d'iteration maximale dans le processus SIMP");
72     params.ajouter("critere_convergence",0.5,OT_PARAMETRES::DOUBLE,"Critere de convergence de la méthode SIMP en \%");
73     params.ajouter("ro_min",0.8,OT_PARAMETRES::DOUBLE,"Seuil de conservation des éléments");
74 francois 433 params.ajouter("iter_vue",0.,OT_PARAMETRES::DOUBLE,"generation d'un fichier gmsh tous les iter_vue. 0 pas de generation");
75 nana 565 params.ajouter("type_filtrage",0.,OT_PARAMETRES::DOUBLE,"0. filtrage par distance 1. filtrage par couches");
76 francois 578 params.ajouter("nb_couchesc",1.,OT_PARAMETRES::DOUBLE,"nombre de couches filtrage de la compliance");
77     params.ajouter("nb_couchesd",1.,OT_PARAMETRES::DOUBLE,"nombre de couches filtrage de la densite");
78 francois 239 }
79    
80     MGOPT_SIMP::MGOPT_SIMP(MGOPT_SIMP &mdd):MGOPT(mdd)
81     {
82     }
83    
84    
85     MGOPT_SIMP::~MGOPT_SIMP()
86     {
87     }
88    
89    
90 francois 681 void MGOPT_SIMP::optimisation(int num_adapt,FEM_MAILLAGE* fem,int iter)
91 francois 239 {
92 francois 319 MG_VOLUME* vol=fem->get_mg_geometrie()->get_mg_volume(0);
93 francois 272 affiche((char*)" Initialisation");
94 francois 468 std::vector<SIMP_TETRA*> lsttet;
95 francois 247 double f=params.get_valeur("f");
96     double rminc=params.get_valeur("rminc");
97     double rmind=params.get_valeur("rmind");
98     if (((rminc<1e-16)||(rmind<1e-16)) && (carte==NULL))
99 francois 246 {
100 francois 272 affiche((char*)" Lecture de la carte de taille");
101 francois 468 int typecarte=(int)params.get_valeur("typecarte");
102     std::string fichiercarte=params.get_nom("fichiercarte");
103     if ((typecarte==0) &&(typecarte==1))
104     {
105     carte=new FCT_GENERATEUR_3D<4>;
106     carte->lire((char *)fichiercarte.c_str());
107     }
108     if ((typecarte==2) &&(typecarte==3)) carte=new FCT_TAILLE_FEM_SOLUTION((char *)fichiercarte.c_str());
109     }
110 francois 239 double volume_tot;
111     double volume_design=0;
112     double volume_non_design=0;
113     double unite=fem->get_mg_maillage()->get_mg_geometrie()->get_valeur_unite();
114 francois 309 LISTE_FEM_ELEMENT3::iterator it;
115 francois 239 int ntet=0;
116 francois 309 for (FEM_ELEMENT3* tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
117 francois 239 {
118     SIMP_TETRA* tet2=new SIMP_TETRA;
119     tet2->tet=tet;
120     tet2->tet->change_numero(ntet);
121     ntet++;
122     tet2->centre[0]=0.;
123     tet2->centre[1]=0.;
124     tet2->centre[2]=0.;
125     int nbnoeud=tet->get_nb_fem_noeud();
126     for (int i=0;i<nbnoeud;i++)
127     {
128 francois 242 tet2->centre[0]=tet2->centre[0]+tet->get_fem_noeud(i)->get_x()*unite;
129     tet2->centre[1]=tet2->centre[1]+tet->get_fem_noeud(i)->get_y()*unite;
130     tet2->centre[2]=tet2->centre[2]+tet->get_fem_noeud(i)->get_z()*unite;
131 francois 239 }
132     tet2->centre[0]=tet2->centre[0]/nbnoeud;
133     tet2->centre[1]=tet2->centre[1]/nbnoeud;
134     tet2->centre[2]=tet2->centre[2]/nbnoeud;
135     int lig,col;
136     double jac[9],uv[3]={1./4.,1./4.,1./4.};
137 francois 242 tet2->volume=1./6.*tet->get_jacobien(jac,uv,lig,col,unite);
138 francois 247 tet2->distance_ref=rminc;
139     tet2->distance_ref2=rmind;
140 cuillier 395 double xyz[3]={tet2->centre[0]/unite,tet2->centre[1]/unite,tet2->centre[2]/unite};
141 francois 246 double val[9];
142     if (tet2->distance_ref<1e-16)
143 francois 242 {
144 francois 246 carte->evaluer(xyz,val);
145     tet2->distance_ref=1./sqrt(val[0]);
146 francois 242 }
147 francois 247 if (tet2->distance_ref2<1e-16)
148     {
149     carte->evaluer(xyz,val);
150     tet2->distance_ref2=1./sqrt(val[0]);
151     }
152     tet2->distance_ref=params.get_valeur("coefvoisinc")*tet2->distance_ref*unite;
153     tet2->distance_ref2=params.get_valeur("coefvoisind")*tet2->distance_ref2*unite;
154 francois 239 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
155     {
156     tet2->design=1;
157 francois 247 tet2->densite=f;
158 francois 239 volume_design=volume_design+tet2->volume;
159     }
160     else
161     {
162     tet2->design=0;
163     tet2->densite=1.;
164     volume_non_design=volume_non_design+tet2->volume;
165     }
166     lsttet.insert(lsttet.end(),tet2);
167     }
168 francois 268 volume_tot=volume_design+volume_non_design;
169 francois 309 double volumemoyen=volume_tot/fem->get_nb_fem_element3();
170 francois 272 affiche((char*)" Recherche de voisins");
171 francois 239 int nbsimptet=lsttet.size();
172 nana 565 if (params.get_valeur("type_filtrage")==0.)
173 francois 239 {
174 nana 565 for (int i=0;i<nbsimptet;i++)
175     {
176     SIMP_TETRA* tet=lsttet[i];
177     if (tet->design==0) continue;
178     ajouter_voisin_distance(i,tet,lsttet);
179     }
180 francois 239 }
181 nana 565 if (params.get_valeur("type_filtrage")==1.)
182     {
183     for (int i=0;i<nbsimptet;i++)
184     {
185     SIMP_TETRA* tet=lsttet[i];
186     if (tet->design==0) continue;
187 francois 578 ajouter_voisin_couche(i,tet,lsttet,params.get_valeur("nb_couchesc"),params.get_valeur("nb_couchesd"));
188 nana 565 }
189     }
190    
191 francois 239 int nbiteration=1;
192     int ok=0;
193     int niveaumax=(int)params.get_valeur("nbrniveau");
194 francois 339 int itervue=(int)params.get_valeur("iter_vue");
195 francois 247 double p=params.get_valeur("p");
196 francois 468 std::vector<double> Ctotiter;
197 francois 239 while (ok==0)
198     {
199 francois 247 if (nbiteration>params.get_valeur("iter_max")) break;
200 francois 239 char message[255];
201 francois 681 if (num_adapt==0) sprintf(message," Iteration %d",nbiteration);
202     else sprintf(message," Iteration %d.%d",num_adapt,nbiteration);
203 francois 239 affiche(message);
204 francois 468 std::vector<FEM_ELEMENT3*> *lstniveau=new std::vector<FEM_ELEMENT3*>[niveaumax+1];
205 francois 247 double densmin = params.get_valeur("ro_void");
206 francois 239 for (int i=0;i<nbsimptet;i++)
207     {
208     SIMP_TETRA* tet=lsttet[i];
209     tet->maille_niveau=(int)((tet->densite-densmin)*niveaumax/(1.-densmin))+1;
210     if (tet->maille_niveau>niveaumax) tet->maille_niveau=niveaumax;
211     lstniveau[tet->maille_niveau].insert(lstniveau[tet->maille_niveau].end(),tet->tet);
212     }
213     MG_EXPORT exp;
214 francois 512 //int version_aster=params.get_valeur("version_aster");
215 francois 581 double version=exp.aster(vol,fem,nometude,MAGIC::CALCUL_ASTER::OPTIMISATIONTOPOLOGIQUE,(char*)"00000001",p,niveaumax,lstniveau);
216 francois 239 delete [] lstniveau;
217 francois 581 char messagever[255];
218     sprintf(messagever," Calcul aster %.1lf",version);
219     affiche(messagever);
220 francois 239 char nomfichiertmp[255];
221     sprintf(nomfichiertmp,"%s/as_run %s.export 1>aster.log 2>&1",getenv("PATHASTER"),nometude);
222 francois 242 int code=system(nomfichiertmp);
223     if (code!=0)
224     {
225     sprintf(nomfichiertmp," Code de sortie aster : %d",code);
226     affiche(nomfichiertmp);
227     }
228 francois 272 affiche((char*)" Analyse resultat");
229 francois 239 recupere_energie(lsttet);
230     double Ctot=0;
231     for (int i=0;i<nbsimptet;i++)
232     {
233     SIMP_TETRA* tet=lsttet[i];
234 francois 247 tet->denergie= -p*2.*tet->energie/tet->densite;
235 francois 239 Ctot=Ctot+2.*tet->energie;
236     }
237     Ctotiter.insert(Ctotiter.end(),Ctot);
238     sprintf(message," Compliance %le",Ctot);
239     affiche(message);
240     if (nbiteration!=1)
241     {
242     int nb=Ctotiter.size();
243     double c1=Ctotiter[nb-2];
244     double c2=Ctotiter[nb-1];
245     double ecart=fabs((c2-c1)/c1)*100.;
246     if (ecart<params.get_valeur("critere_convergence")) ok=1;
247     sprintf(message," Ecart %lf%%",ecart);
248     affiche(message);
249     }
250 francois 247 // lissage compliance
251     double kc=params.get_valeur("kc");
252 francois 243 int type_lissage =(int)params.get_valeur("type_lissage");
253 francois 247 int lissage_densite =(int)params.get_valeur("lissage_densite");
254     int type_lissage_densite =(int)params.get_valeur("type_lissage_densite");
255 francois 267 int type_lissage_compliance=(int)params.get_valeur("type_lissage_compliance");
256 francois 242 for (int i=0;i<nbsimptet;i++)
257     {
258     SIMP_TETRA* tet=lsttet[i];
259 francois 247 if ((type_lissage==0) || (type_lissage==2))
260 francois 243 tet->new_denergie=tet->denergie;
261 francois 247 if ((type_lissage==1) || (type_lissage==3))
262 francois 242 {
263 francois 243 if (tet->design == 1)
264 francois 242 {
265 francois 247 double hi= pow(tet->distance_ref,kc);
266     double hisensi = hi*tet->densite*tet->denergie;
267 francois 267 if (type_lissage_compliance==1)
268     {
269     hi=hi/tet->volume;
270 francois 268 hisensi=hisensi/max(volumemoyen*0.00001,tet->volume);
271 francois 267 }
272     int nbvoisin=tet->voisin.size();
273 francois 243 for (int j = 0 ; j<nbvoisin ; j++)
274     {
275     SIMP_TETRA* tet2=tet->voisin[j];
276     if (tet2->design == 1)
277     {
278 francois 247 double dist=tet->distance(tet2);
279     double hj =fabs(pow(tet->distance_ref - dist,kc));
280 francois 267 if (type_lissage_compliance==0)
281     {
282     hisensi=hisensi+tet2->densite*hj*tet2->denergie;
283     hi=hi+hj;
284     }
285     if (type_lissage_compliance==1)
286     {
287 francois 268 hisensi=hisensi+tet2->densite*hj*tet2->denergie/max(volumemoyen,tet2->volume);
288 francois 267 hi=hi+hj/tet2->volume;
289     }
290     hisensi=hisensi+tet2->densite*hj*tet2->denergie;
291 francois 247 hi=hi+hj;
292 francois 243 }
293 francois 242 }
294 francois 268 tet->new_denergie = hisensi/hi/max(tet->densite,densmin);
295 francois 243 }
296     else tet->new_denergie=tet->denergie;
297 francois 242 }
298     }
299 francois 239 // application formule pas encore connue
300     double l1= 1e-8 ;
301     double l2= 1e8;
302     double m=params.get_valeur("m");
303 francois 241 double eta=params.get_valeur("eta");
304 francois 242 double convergence_lagrange=params.get_valeur("convergence_lagrange");
305     double critere_densite = 0.0;
306     int oklagrange=0;
307     int compteurlagrange=0;
308     while (oklagrange==0)
309 francois 239 {
310 francois 242 compteurlagrange++;
311     double lmid = 0.5*(l2+l1);
312     critere_densite = 0.0;
313     for (int i=0;i<nbsimptet;i++)
314 francois 239 {
315     SIMP_TETRA* tet=lsttet[i];
316     if (tet->design==1)
317     {
318     double x1 = tet->densite+m;
319 francois 242 double beta=-tet->new_denergie/lmid/tet->volume;
320 francois 241 double x2 = tet->densite*pow(beta,eta);
321     double x3 = min(x1,x2);
322     double x4 = 1.;
323     double x5 = min(x3,x4);
324     double x6 = tet->densite-m;
325     double x7 = max(x5,x6);
326     double x8 = densmin;
327 francois 239 tet->new_densite = max(x7,x8);
328 francois 242 critere_densite = critere_densite + tet->new_densite*tet->volume;
329     }
330 francois 239 else
331     {
332     tet->new_densite=1.;
333     }
334 francois 242 }
335 francois 247 if (critere_densite - f*volume_design > 0.)
336 francois 239 l1=lmid;
337     else
338     l2=lmid;
339 francois 247 if (100.*fabs(critere_densite- f*volume_design )/(f*volume_design)<convergence_lagrange) oklagrange=1;
340 francois 243 if (compteurlagrange>500) oklagrange=2;
341 francois 242 }
342 francois 247 if (oklagrange==1) sprintf(message," Convergence multiplicateur lagrange %le%%",100.*(critere_densite- f*volume_design )/(f*volume_design));
343 francois 242 if (oklagrange==2) sprintf(message," Divergence multiplicateur lagrange %le %le",l1,l2);
344     affiche(message);
345 francois 247 // lissage de densite.
346     double kd=params.get_valeur("kd");
347 francois 239 for (int i=0;i<nbsimptet;i++)
348 francois 242 {
349 francois 239 SIMP_TETRA* tet=lsttet[i];
350 francois 247 if ((type_lissage==2) || (type_lissage==3))
351     {
352     if (((lissage_densite==1)&&(ok==1)) || (lissage_densite==0))
353     {
354     if (tet->design == 1)
355     {
356     double widensite=0.;
357     double wi= 0.;
358     wi=poid_lissage(0.,tet->distance_ref2,kd,tet->volume,type_lissage_densite);
359     widensite = wi*tet->new_densite;
360     int nbvoisin=tet->voisin2.size();
361     for (int j = 0 ; j<nbvoisin ; j++)
362     {
363     SIMP_TETRA* tet2=tet->voisin2[j];
364     if (tet2->design == 1)
365     {
366     double dist=tet->distance(tet2);
367     double wj=poid_lissage(dist,tet->distance_ref2,kd,tet2->volume,type_lissage_densite);
368     wi = wi+wj;
369     widensite = widensite + tet2->new_densite*wj;
370     }
371     }
372     tet->densite = widensite/wi;
373     }
374     else tet->densite=tet->new_densite;
375     }
376     else tet->densite=tet->new_densite;
377     }
378     else tet->densite=tet->new_densite;
379 francois 242 }
380 francois 339 if (itervue!=0)
381     if (nbiteration%itervue==0)
382     {
383     affiche((char*)" Sauvegarde résultat iteration");
384 cuillier 341 sprintf(message,"%s_densite_iter%d.soltmp",nometudesortie,nbiteration);
385 francois 339 //int nbsolution=gestd->get_nb_fem_solution();
386 nana 565 //for (int i=nbsolution;i>0;i--version 2 du for)
387 francois 339 //gestd->supprimer_fem_solution_du_gestionnaire(i-1);
388 francois 342 char message2[50];
389     sprintf(message2,"Iteration %d",nbiteration);
390 francois 375 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),message2,MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
391 francois 339 gestd->ajouter_fem_solution(solution);
392     sprintf(message,"Densite");
393     solution->change_legende(0,message);
394     for (int i=0;i<nbsimptet;i++)
395     {
396     SIMP_TETRA* tet=lsttet[i];
397 francois 375 solution->ecrire(tet->densite,i,0);
398 francois 339 }
399     }
400 francois 239 nbiteration++;
401     }
402 francois 339 if (itervue!=0)
403 nana 565 {
404 francois 339 affiche((char*)" Sauvegarde GMSH résultats iterations");
405     MG_EXPORT exp;
406     char nomfichier[500];
407     sprintf(nomfichier,"%s_iterations",nometudesortie);
408     exp.gmsh(fem,nomfichier);
409     }
410 francois 247 double seuil=params.get_valeur("ro_min");
411 francois 272 affiche((char*)" Ecriture des donnees finales");
412 francois 239 char message[255];
413 francois 512 if (iter==0) sprintf(message,"%s.compliance",nometudesortie);
414     else sprintf(message,"%s_iter%d.compliance",nometudesortie,iter);
415 francois 239 FILE *out=fopen(message,"wt");
416 francois 271 time_t heurefin=time(NULL);
417     struct tm tfin = *localtime(&heurefin);
418     fprintf(out,"*****************************************************\n");
419     fprintf(out," Optimisateur de topologie\n");
420     fprintf(out," ERICCA - UQTR\n");
421     fprintf(out,"*****************************************************\n");
422     fprintf(out," Etude : %s\n",nometude);
423 francois 274 fprintf(out," Date : %02u-%02u-%04u\n", tdebut.tm_mday, tdebut.tm_mon+1, 1900 + tdebut.tm_year);
424 francois 271 fprintf(out," Heure debut : %02u:%02u:%02u\n", tdebut.tm_hour, tdebut.tm_min, tdebut.tm_sec);
425     fprintf(out," Heure fin : %02u:%02u:%02u\n", tfin.tm_hour, tfin.tm_min, tfin.tm_sec);
426     fprintf(out," Parametres : \n");
427     int nbparam=params.get_nb();
428     for (int i=0;i<nbparam;i++)
429     {
430 francois 397 if (params.get_type(i)==OT_PARAMETRES::DOUBLE) fprintf(out," %s = %lf\n",params.get_nom(i).c_str(),params.get_valeur(i));
431     if (params.get_type(i)==OT_PARAMETRES::STRING) fprintf(out," %s = %s\n",params.get_nom(i).c_str(),params.get_nom(params.get_nom(i).c_str()).c_str());
432 francois 271 }
433     fprintf(out,"*****************************************************\n");
434     fprintf(out," Compliance après chaque itération\n");
435     fprintf(out,"*****************************************************\n");
436 francois 239 for (int i=0;i<Ctotiter.size();i++)
437     fprintf(out,"%le\n",Ctotiter[i]);
438 francois 355 fprintf(out,"*****************************************************\n");
439     fprintf(out," Variation de la compliance après chaque itération\n");
440     fprintf(out,"*****************************************************\n");
441     for (int i=1;i<Ctotiter.size();i++)
442     fprintf(out,"%lf%%\n",(Ctotiter[i]-Ctotiter[i-1])*100./Ctotiter[i-1]);
443 francois 245 double crit1=0.;
444     double crit2=0.;
445     double crit3=0.;
446     double critv1[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
447     double critv2[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
448     for (int i=0;i<nbsimptet;i++)
449     {
450     SIMP_TETRA* tet=lsttet[i];
451     if (tet->design==1)
452     {
453     crit1=crit1+tet->densite*tet->volume;
454     if (tet->densite>seuil)
455     {
456     crit2=crit2+tet->densite*tet->volume;
457     crit3=crit3+tet->volume;
458     }
459     for (int j=1;j<10;j++)
460     if (tet->densite>0.1*j)
461     {
462     critv1[j]=critv1[j]+tet->densite*tet->volume;
463     critv2[j]=critv2[j]+tet->volume;
464     }
465     }
466     }
467 francois 271 fprintf(out,"*****************************************************\n");
468     fprintf(out," Résultat\n");
469     fprintf(out,"*****************************************************\n");
470 francois 245 fprintf(out,"Volume du design : %le \n",volume_design);
471 francois 247 fprintf(out,"Objectif du volume de design : %le \n",volume_design*f);
472 francois 245 fprintf(out,"Volume de design obtenu : %le \n",crit1);
473     fprintf(out,"Volume de design obtenu avec le seuil: %le \n",crit2);
474     fprintf(out,"Volume reel de design obtenu avec le seuil: %le \n\n",crit3);
475     fprintf(out," : Volume : Volume reel : Objectif\n");
476     fprintf(out," : %le : %le : %le\n",volume_design,volume_design,volume_design);
477     for (int j=1;j<10;j++)
478 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);
479 francois 245 fprintf(out,"*************************************************************\n");
480     fclose(out);
481 francois 239 LISTE_FEM_NOEUD::iterator itnoeud;
482     int nbfemnoeud=fem->get_nb_fem_noeud();
483 francois 242 /*double *nume=new double[nbfemnoeud];
484 francois 239 double *deno=new double[nbfemnoeud];
485     int cpt=0;
486     for (FEM_NOEUD *nd=fem->get_premier_noeud(itnoeud);nd!=NULL;nd=fem->get_suivant_noeud(itnoeud))
487     {
488     nd->change_numero(cpt);
489     nume[cpt]=0.;
490     deno[cpt]=0.;
491     cpt++;
492 francois 242 }*/
493 francois 512 if (iter==0) sprintf(message,"%s_densite.sol",nometudesortie);
494     else sprintf(message,"%s_densite_iter%d.sol",nometudesortie,iter);
495 francois 241 int nbsolution=gestd->get_nb_fem_solution();
496 francois 242 for (int i=nbsolution;i>0;i--)
497 cuillier 341 {
498 francois 342 FEM_SOLUTION* sol=gestd->get_fem_solution(i-1);
499 cuillier 341 std::string nom=sol->get_nom_fichier();
500     char message[500],extension[500];
501     sprintf(message,"%s",nom.c_str());
502     char *p=strrchr(message,'.');
503     strncpy(extension,p,strlen(message)+message-p);
504     if (strcmp(extension,".soltmp")==0)
505     gestd->supprimer_fem_solution(i-1);
506     else gestd->supprimer_fem_solution_du_gestionnaire(i-1);
507     }
508    
509    
510 francois 375 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),"Optimisation",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
511 francois 239 gestd->ajouter_fem_solution(solution);
512     solution->change_legende(0,"Densite");
513     for (int i=0;i<nbsimptet;i++)
514     {
515     SIMP_TETRA* tet=lsttet[i];
516     if (tet->design==1)
517     if (tet->densite>seuil)
518     ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(OPTIMISE);
519     else
520     ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(MAILLEUR_AUTO);
521 francois 384 tet->tet->change_solution(tet->densite);
522 francois 375 solution->ecrire(tet->densite,i,0);
523 francois 242 /*for (int j=0;j<tet->tet->get_nb_fem_noeud();j++)
524 francois 239 {
525     FEM_NOEUD* noeud=tet->tet->get_fem_noeud(j);
526     nume[noeud->get_numero()]=nume[noeud->get_numero()]+tet->volume*tet->densite;
527     deno[noeud->get_numero()]=deno[noeud->get_numero()]+tet->volume;
528 francois 242 } */
529 francois 239 }
530 francois 243 /*sprintf(message,"%s_densite2.sol",nometudesortie);
531 francois 239 FEM_SOLUTION* solution2=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_noeud(),"Optimisation",ENTITE_NOEUD);
532     gestd->ajouter_fem_solution(solution2);
533     solution2->change_legende(0,"Densite");
534     cpt=0;
535     for (FEM_NOEUD *nd=fem->get_premier_noeud(itnoeud);nd!=NULL;nd=fem->get_suivant_noeud(itnoeud))
536     {
537 francois 375 solution2->ecrire(nume[cpt]/deno[cpt],cpt,0,);
538 francois 239 cpt++;
539     }
540     delete [] deno;
541 francois 242 delete [] nume;*/
542 francois 239 int nb=lsttet.size();
543     for (int i=0;i<nb;i++) delete lsttet[i];
544     }
545    
546 francois 247 double MGOPT_SIMP::poid_lissage(double dist,double distref,double k,double volume,int type)
547     {
548     double wi;
549     if (type==0) wi=pow(distref-dist,k);
550     if (type==1) wi=pow(distref-dist,k)*volume;
551     if (type==2) wi=exp(-dist*dist/2./distref/distref/9.)/2./M_PI/(distref/3.);
552     if (type==3) wi=volume*exp(-dist*dist/2./distref/distref/9.)/2./M_PI/(distref/3.);
553     return fabs(wi);
554    
555     }
556 francois 239
557 francois 240 void MGOPT_SIMP::adapte_resultat(char *nomgestd,char *nomparam)
558     {
559     if (nomparam!=NULL) lire_params(nomparam);
560 francois 272 affiche((char*)"");
561     affiche((char*)"*************************");
562     affiche((char*)"Optimisation de topologie");
563     affiche((char*)"*************************");
564     affiche((char*)"");
565     affiche((char*)"");
566     affiche((char*)"Changement du seuil dans les resultats");
567 francois 240 double seuil=params.get_valeur("seuil");
568     gestd=new MG_FILE(nomgestd);
569     FEM_MAILLAGE* fem=gestd->get_fem_maillage(0);
570     FEM_SOLUTION* solution=gestd->get_fem_solution(0);
571     solution->active_solution(0);
572 francois 309 LISTE_FEM_ELEMENT3::iterator it;
573     for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
574 francois 240 {
575     if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=IMPOSE)
576     if (tet->get_solution()>seuil)
577     ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(OPTIMISE);
578     else
579     ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAILLEUR_AUTO);
580    
581     }
582 francois 272 affiche((char*)"Enregistrement");
583 francois 240 gestd->enregistrer(nomgestd);
584 francois 272 affiche((char*)"Enregistrement sous GMSH");
585 francois 245 char *p=strchr(nomgestd,'.');
586     strncpy(nometude,nomgestd,p-nomgestd);
587     nometude[p-nomgestd]=0;
588     MG_EXPORT exp;
589     char nomfichier[500];
590     sprintf(nomfichier,"%s_mg",nometude);
591     exp.gmsh(fem->get_mg_maillage(),nomfichier);
592     sprintf(nomfichier,"%s_fem",nometude);
593     exp.gmsh(fem,nomfichier);
594 francois 272 affiche((char*)"Fin");
595 francois 240 }
596 francois 239
597    
598 francois 468 void MGOPT_SIMP::recupere_energie(std::vector<class SIMP_TETRA*> lsttet)
599 francois 239 {
600     char message[750];
601     sprintf(message,"%s.resu",nometude);
602     FILE* in=fopen(message,"rt");
603     int fin=0;
604     do
605     {
606 francois 276 char* res=fgets(message,750,in);
607 francois 239 if (feof(in)) fin=1;
608     char mot1[100];
609     char mot2[100];
610     char mot3[100];
611     char mot4[100];
612     char mot5[100];
613     char mot6[100];
614     char mot7[100];
615     char mot8[100];
616     char mot9[100];
617     char mot10[100];
618     int numlu=sscanf(message,"%s %s %s %s %s %s %s %s %s %s",mot1,mot2,mot3,mot4,mot5,mot6,mot7,mot8,mot9,mot10);
619 francois 674
620    
621     if (numlu>2)
622     if (strcmp(mot2,"TOTAL_JOB")==0)
623     {
624     double val;
625     sscanf(mot8,"%lf",&val);
626     CODE_ASTER_CPU=CODE_ASTER_CPU+val;
627     }
628    
629    
630 francois 239 if (numlu>9)
631     if (strcmp(mot1,"CHAMP")==0)
632     if (strcmp(mot2,"PAR")==0)
633     if (strcmp(mot3,"ELEMENT")==0)
634     if (strcmp(mot4,"CONSTANT")==0)
635     if (strcmp(mot5,"SUR")==0)
636 francois 322 if (strcmp(mot6,"ELEMENT")==0)
637 francois 239 if (strcmp(mot7,"DE")==0)
638     if (strcmp(mot8,"NOM")==0)
639     if (strcmp(mot9,"SYMBOLIQUE")==0)
640 francois 322 if (strcmp(mot10,"ENERGIE")==0)
641 francois 239 {
642     int fin2=0;
643     int passe=0;
644     int nbelement=0;
645     do
646     {
647     char message[750];
648 francois 276 char* res=fgets(message,750,in);
649 francois 239 char mot1[500];
650     char mot2[500];
651     int numlu=sscanf(message,"%s %s",mot1,mot2);
652     int decalage;
653     if ((numlu==2) && (strcmp(mot2,"TOTALE")==0))
654     {
655     char *p=strchr(mot1,'M')+1;
656     int num=atoi(p);
657     if (passe==0) {passe=1;decalage=num;}
658 francois 276 char* res=fgets(message,750,in);
659 francois 239 double val;
660     sscanf(message,"%lf",&val);
661     lsttet[num-decalage]->energie=val;
662     nbelement++;
663     }
664     if (nbelement == lsttet.size()) {fin2=1;fin=0;}
665     }
666    
667     while (fin2==0);
668     }
669     }
670     while (fin==0);
671     fclose(in);
672     }
673    
674    
675    
676 nana 565 void MGOPT_SIMP::ajouter_voisin_distance(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst)
677 francois 239 {
678     tet->indice=i;
679     int nbnoeud=tet->tet->get_nb_fem_noeud();
680     int correspondance[4];
681     if (nbnoeud==4)
682     {
683     correspondance[0]=0;
684     correspondance[1]=1;
685     correspondance[2]=2;
686     correspondance[3]=3;
687     }
688     if (nbnoeud==10)
689     {
690     correspondance[0]=0;
691     correspondance[1]=2;
692     correspondance[2]=4;
693     correspondance[3]=9;
694     }
695     SIMP_TETRA* tetcour=tet;
696     int ok=0;
697     int compteur=0;
698 francois 468 std::vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
699 francois 247 if (tet->distance_ref<tet->distance_ref2)
700     lstvoisin=tet->voisin2;
701 francois 239 while (ok==0)
702     {
703     for (int j=0;j<4;j++)
704     {
705     int num=correspondance[j];
706     FEM_NOEUD *noeud=tetcour->tet->get_fem_noeud(num);
707 francois 309 int nbtetra=noeud->get_lien_element3()->get_nb();
708 francois 239 for (int k=0;k<nbtetra;k++)
709     {
710 francois 309 FEM_ELEMENT3* ftet=noeud->get_lien_element3()->get(k);
711 francois 239 SIMP_TETRA* stet=lst[ftet->get_numero()];
712     if (stet->indice!=i)
713     {
714     stet->indice=i;
715 francois 247 double dist=tet->distance(stet);
716     if (dist<tet->distance_ref)
717 francois 239 tet->voisin.insert(tet->voisin.end(),stet);
718 francois 247 if (dist<tet->distance_ref2)
719     tet->voisin2.insert(tet->voisin2.end(),stet);
720 francois 239 }
721     }
722     }
723 francois 247 if (compteur>=lstvoisin.size()) ok=1;
724 francois 239 else
725     {
726 francois 247 tetcour=lstvoisin[compteur];
727 francois 239 compteur++;
728     }
729 francois 247
730 francois 239 }
731    
732 francois 274 }
733 nana 565
734    
735 francois 578 void MGOPT_SIMP::ajouter_voisin_couche(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst,int nb_couches,int nb_couches2)
736 nana 565 {
737     tet->indice=i;
738     int nbnoeud=tet->tet->get_nb_fem_noeud();
739     int correspondance[4];
740     if (nbnoeud==4)
741     {
742     correspondance[0]=0;
743     correspondance[1]=1;
744     correspondance[2]=2;
745     correspondance[3]=3;
746     }
747     if (nbnoeud==10)
748     {
749     correspondance[0]=0;
750     correspondance[1]=2;
751     correspondance[2]=4;
752     correspondance[3]=9;
753     }
754     std::vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
755     if (tet->distance_ref<tet->distance_ref2)
756     lstvoisin=tet->voisin2;
757 francois 578 tet->voisin.insert(tet->voisin.end(),tet);
758     tet->voisin2.insert(tet->voisin2.end(),tet);
759     tet->indice=i;
760     int debut=0,fin=1;
761     for (int ok=0;ok<max(nb_couches,nb_couches2);ok++)
762 nana 565 {
763 francois 578 for (int iliste=debut;iliste<fin;iliste++)
764     {
765 francois 579 SIMP_TETRA* tetcour;
766     if (nb_couches>nb_couches2 ) tetcour=tet->voisin[iliste]; else tetcour=tet->voisin2[iliste];
767 francois 578 for (int j=0;j<4;j++)
768 nana 565 {
769     int num=correspondance[j];
770     FEM_NOEUD *noeud=tetcour->tet->get_fem_noeud(num);
771     int nbtetra=noeud->get_lien_element3()->get_nb();
772     for (int k=0;k<nbtetra;k++)
773     {
774     FEM_ELEMENT3* ftet=noeud->get_lien_element3()->get(k);
775     SIMP_TETRA* stet=lst[ftet->get_numero()];
776     if (stet->indice!=i)
777     {
778     stet->indice=i;
779 francois 578 if (ok<nb_couches) tet->voisin.insert(tet->voisin.end(),stet);
780     if (ok<nb_couches2) tet->voisin2.insert(tet->voisin2.end(),stet);
781 nana 565 }
782     }
783     }
784 francois 578 }
785     debut=fin;
786     if (nb_couches>nb_couches2 ) fin=tet->voisin.size(); else fin=tet->voisin2.size();
787 nana 565 }
788     }