ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_simp.cpp
Revision: 951
Committed: Fri Aug 10 15:17:17 2018 UTC (6 years, 9 months ago) by couturad
File size: 26704 byte(s)
Log Message:
-> Ajout de Project Chrono (voir CMakeLists.txt).
-> Ajout d'un générateur de microstructure basé sur la dynamique des corps rigides (MSTRUCT_GENERATEUR_DCR).
-> Ajout d'un opérateur de décallage de la topologie (MG_CG_OP_TRANSF_DECALLAGE).
-> Retrait de «using namespace std»  (conflit avec namespace chrono) et modification des fichiers affectés.
-> Modification de mailleur2d.cpp afin d'enregistrer un fichier MAGiC (void.magic) lorsque le nombre d'itération dépasse la valeur maximale.

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