ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_simp.cpp
Revision: 1158
Committed: Thu Jun 13 22:18:49 2024 UTC (11 months ago) by francois
File size: 27818 byte(s)
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

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