ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/aster/src/mgopt_simp.cpp
Revision: 1104
Committed: Fri Sep 16 19:46:33 2022 UTC (2 years, 11 months ago) by francois
File size: 26743 byte(s)
Log Message:
Generalisation du calcul du Jacobien en 2D et 3D

File Contents

# Content
1 #include "gestionversion.h"
2 #include "mgopt_simp.h"
3 #include "mg_file.h"
4 #include "mg_export.h"
5 #include <string.h>
6 #include <math.h>
7 #include "fct_taille_fem_solution.h"
8 #include "fct_generateur_3d.h"
9 #include "ot_cpu.h"
10 #include "mglanceuraster.h"
11
12 class SIMP_TETRA
13 {
14 public:
15 FEM_ELEMENT3* tet;
16 double densite;
17 double new_densite;
18 int design;
19 double new_denergie;
20 double energie;
21 double denergie;
22 double volume;
23 int maille_niveau;
24 int indice;
25 double distance_ref;
26 double distance_ref2;
27 double centre[3];
28 BOITE_3D get_boite_3D(void)
29 {
30 return tet->get_boite_3D();
31 };
32 std::vector<SIMP_TETRA*> voisin;
33 std::vector<SIMP_TETRA*> voisin2;
34 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 MGOPT_SIMP::MGOPT_SIMP(bool save):MGOPT(save)
54 {
55 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 params.ajouter("iter_vue",0.,OT_PARAMETRES::DOUBLE,"generation d'un fichier gmsh tous les iter_vue. 0 pas de generation");
76 params.ajouter("type_filtrage",0.,OT_PARAMETRES::DOUBLE,"0. filtrage par distance 1. filtrage par couches");
77 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 }
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 void MGOPT_SIMP::optimisation(int num_adapt,FEM_MAILLAGE* fem,char *nomparamaster,int iter)
92 {
93 MG_GEOMETRIE* geo=fem->get_mg_geometrie();
94 affiche((char*)" Initialisation");
95 std::vector<SIMP_TETRA*> lsttet;
96 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 {
101 affiche((char*)" Lecture de la carte de taille");
102 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 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 LISTE_FEM_ELEMENT3::iterator it;
116 int ntet=0;
117 for (FEM_ELEMENT3* tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
118 {
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 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 }
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 double jac[9],uv[3]={1./4.,1./4.,1./4.};
137 tet2->volume=1./6.*tet->get_jacobien(jac,uv,unite);
138 tet2->distance_ref=rminc;
139 tet2->distance_ref2=rmind;
140 double xyz[3]={tet2->centre[0]/unite,tet2->centre[1]/unite,tet2->centre[2]/unite};
141 double val[9];
142 if (tet2->distance_ref<1e-16)
143 {
144 carte->evaluer(xyz,val);
145 tet2->distance_ref=1./sqrt(val[0]);
146 }
147 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 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
155 {
156 tet2->design=1;
157 tet2->densite=f;
158 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 volume_tot=volume_design+volume_non_design;
169 double volumemoyen=volume_tot/fem->get_nb_fem_element3();
170 affiche((char*)" Recherche de voisins");
171 int nbsimptet=lsttet.size();
172 if (params.get_valeur("type_filtrage")==0.)
173 {
174 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 }
181 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 ajouter_voisin_couche(i,tet,lsttet,params.get_valeur("nb_couchesc"),params.get_valeur("nb_couchesd"));
188 }
189 }
190
191 int nbiteration=1;
192 int ok=0;
193 int niveaumax=(int)params.get_valeur("nbrniveau");
194 int itervue=(int)params.get_valeur("iter_vue");
195 double p=params.get_valeur("p");
196 std::vector<double> Ctotiter;
197 while (ok==0)
198 {
199 if (nbiteration>params.get_valeur("iter_max")) break;
200 char message[2000];
201 if (num_adapt==0) sprintf(message," Iteration \033[1;32m%d\033[1;33m",nbiteration);
202 else sprintf(message," Iteration \033[1;32m%d.%d\033[1;33m",num_adapt,nbiteration);
203 affiche(message);
204 std::vector<FEM_ELEMENT3*> *lstniveau=new std::vector<FEM_ELEMENT3*>[niveaumax+1];
205 double densmin = params.get_valeur("ro_void");
206 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 //int version_aster=params.get_valeur("version_aster");
215 exp.lire_params_aster(nomparamaster);
216 double version=exp.aster(geo,fem,nometude,MAGIC::CALCUL_ASTER::OPTIMISATIONTOPOLOGIQUE,(char*)"00000001",p,niveaumax,lstniveau);
217 delete [] lstniveau;
218 char messagever[255];
219 sprintf(messagever," Calcul aster \033[1;32m%.1lf\033[1;33m",version);
220 affiche(messagever);
221 MGLANCEURASTER aster;
222 int code=aster.execute(param,nometude,version);
223 if (code!=0)
224 {
225 char message[500];
226 sprintf(message," Code de sortie aster : %d",code);
227 affiche(message);
228 }
229 affiche((char*)" Analyse resultat");
230 recupere_energie(lsttet);
231 double Ctot=0;
232 for (int i=0;i<nbsimptet;i++)
233 {
234 SIMP_TETRA* tet=lsttet[i];
235 tet->denergie= -p*2.*tet->energie/tet->densite;
236 Ctot=Ctot+2.*tet->energie;
237 }
238 Ctotiter.insert(Ctotiter.end(),Ctot);
239 sprintf(message," Compliance \033[1;31m%le\033[1;33m",Ctot);
240 affiche(message);
241 if (nbiteration!=1)
242 {
243 int nb=Ctotiter.size();
244 double c1=Ctotiter[nb-2];
245 double c2=Ctotiter[nb-1];
246 double ecart=fabs((c2-c1)/c1)*100.;
247 if (ecart<params.get_valeur("critere_convergence")) ok=1;
248 sprintf(message," Ecart \033[1;31m%lf%%\033[1;33m",ecart);
249 affiche(message);
250 }
251 // lissage compliance
252 double kc=params.get_valeur("kc");
253 int type_lissage =(int)params.get_valeur("type_lissage");
254 int lissage_densite =(int)params.get_valeur("lissage_densite");
255 int type_lissage_densite =(int)params.get_valeur("type_lissage_densite");
256 int type_lissage_compliance=(int)params.get_valeur("type_lissage_compliance");
257 for (int i=0;i<nbsimptet;i++)
258 {
259 SIMP_TETRA* tet=lsttet[i];
260 if ((type_lissage==0) || (type_lissage==2))
261 tet->new_denergie=tet->denergie;
262 if ((type_lissage==1) || (type_lissage==3))
263 {
264 if (tet->design == 1)
265 {
266 double hi= pow(tet->distance_ref,kc);
267 double hisensi = hi*tet->densite*tet->denergie;
268 if (type_lissage_compliance==1)
269 {
270 hi=hi/tet->volume;
271 hisensi=hisensi/std::max(volumemoyen*0.00001,tet->volume);
272 }
273 int nbvoisin=tet->voisin.size();
274 for (int j = 0 ; j<nbvoisin ; j++)
275 {
276 SIMP_TETRA* tet2=tet->voisin[j];
277 if (tet2->design == 1)
278 {
279 double dist=tet->distance(tet2);
280 double hj =fabs(pow(tet->distance_ref - dist,kc));
281 if (type_lissage_compliance==0)
282 {
283 hisensi=hisensi+tet2->densite*hj*tet2->denergie;
284 hi=hi+hj;
285 }
286 if (type_lissage_compliance==1)
287 {
288 hisensi=hisensi+tet2->densite*hj*tet2->denergie/std::max(volumemoyen,tet2->volume);
289 hi=hi+hj/tet2->volume;
290 }
291 hisensi=hisensi+tet2->densite*hj*tet2->denergie;
292 hi=hi+hj;
293 }
294 }
295 tet->new_denergie = hisensi/hi/std::max(tet->densite,densmin);
296 }
297 else tet->new_denergie=tet->denergie;
298 }
299 }
300 // application formule pas encore connue
301 double l1= 1e-8 ;
302 double l2= 1e8;
303 double m=params.get_valeur("m");
304 double eta=params.get_valeur("eta");
305 double convergence_lagrange=params.get_valeur("convergence_lagrange");
306 double critere_densite = 0.0;
307 int oklagrange=0;
308 int compteurlagrange=0;
309 while (oklagrange==0)
310 {
311 compteurlagrange++;
312 double lmid = 0.5*(l2+l1);
313 critere_densite = 0.0;
314 for (int i=0;i<nbsimptet;i++)
315 {
316 SIMP_TETRA* tet=lsttet[i];
317 if (tet->design==1)
318 {
319 double x1 = tet->densite+m;
320 double beta=-tet->new_denergie/lmid/tet->volume;
321 double x2 = tet->densite*pow(beta,eta);
322 double x3 = std::min(x1,x2);
323 double x4 = 1.;
324 double x5 = std::min(x3,x4);
325 double x6 = tet->densite-m;
326 double x7 = std::max(x5,x6);
327 double x8 = densmin;
328 tet->new_densite = std::max(x7,x8);
329 critere_densite = critere_densite + tet->new_densite*tet->volume;
330 }
331 else
332 {
333 tet->new_densite=1.;
334 }
335 }
336 if (critere_densite - f*volume_design > 0.)
337 l1=lmid;
338 else
339 l2=lmid;
340 if (100.*fabs(critere_densite- f*volume_design )/(f*volume_design)<convergence_lagrange) oklagrange=1;
341 if (compteurlagrange>500) oklagrange=2;
342 }
343 if (oklagrange==1) sprintf(message," Convergence multiplicateur lagrange \033[1;31m%le%%\033[1;33m",100.*(critere_densite- f*volume_design )/(f*volume_design));
344 if (oklagrange==2) sprintf(message," Divergence multiplicateur lagrange \033[1;31m%le %le\033[1;33m",l1,l2);
345 affiche(message);
346 // lissage de densite.
347 double kd=params.get_valeur("kd");
348 for (int i=0;i<nbsimptet;i++)
349 {
350 SIMP_TETRA* tet=lsttet[i];
351 if ((type_lissage==2) || (type_lissage==3))
352 {
353 if (((lissage_densite==1)&&(ok==1)) || (lissage_densite==0))
354 {
355 if (tet->design == 1)
356 {
357 double widensite=0.;
358 double wi= 0.;
359 wi=poid_lissage(0.,tet->distance_ref2,kd,tet->volume,type_lissage_densite);
360 widensite = wi*tet->new_densite;
361 int nbvoisin=tet->voisin2.size();
362 for (int j = 0 ; j<nbvoisin ; j++)
363 {
364 SIMP_TETRA* tet2=tet->voisin2[j];
365 if (tet2->design == 1)
366 {
367 double dist=tet->distance(tet2);
368 double wj=poid_lissage(dist,tet->distance_ref2,kd,tet2->volume,type_lissage_densite);
369 wi = wi+wj;
370 widensite = widensite + tet2->new_densite*wj;
371 }
372 }
373 tet->densite = widensite/wi;
374 }
375 else tet->densite=tet->new_densite;
376 }
377 else tet->densite=tet->new_densite;
378 }
379 else tet->densite=tet->new_densite;
380 }
381 if (itervue!=0)
382 if (nbiteration%itervue==0)
383 {
384 affiche((char*)" Sauvegarde résultat iteration");
385 sprintf(message,"%s_densite_iter%d.soltmp",nometudesortie,nbiteration);
386 //int nbsolution=gestd->get_nb_fem_solution();
387 //for (int i=nbsolution;i>0;i--version 2 du for)
388 //gestd->supprimer_fem_solution_du_gestionnaire(i-1);
389 char message2[50];
390 static int step=0;
391 sprintf(message2,"Iteration%%%d",step);
392 step++;
393 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),message2,MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
394 gestd->ajouter_fem_solution(solution);
395 sprintf(message,"Densite");
396 solution->change_legende(0,message);
397 for (int i=0;i<nbsimptet;i++)
398 {
399 SIMP_TETRA* tet=lsttet[i];
400 solution->ecrire(tet->densite,i,0);
401 }
402 }
403 nbiteration++;
404 }
405 if (itervue!=0)
406 {
407 affiche((char*)" Sauvegarde GMSH résultats iterations");
408 MG_EXPORT exp;
409 char nomfichier[2000];
410 sprintf(nomfichier,"%s_iterations",nometudesortie);
411 exp.gmsh(fem,nomfichier);
412 }
413 double seuil=params.get_valeur("ro_min");
414 affiche((char*)" Ecriture des donnees finales");
415 char message[2000];
416 if (iter==0) sprintf(message,"%s.compliance",nometudesortie);
417 else sprintf(message,"%s_iter%d.compliance",nometudesortie,iter);
418 FILE *out=fopen(message,"wt");
419 time_t heurefin=time(NULL);
420 struct tm tfin = *localtime(&heurefin);
421 fprintf(out,"*****************************************************\n");
422 fprintf(out," Optimisateur de topologie\n");
423 fprintf(out," ERICCA - UQTR\n");
424 fprintf(out,"*****************************************************\n");
425 fprintf(out," Etude : %s\n",nometude);
426 fprintf(out," Date : %02u-%02u-%04u\n", tdebut.tm_mday, tdebut.tm_mon+1, 1900 + tdebut.tm_year);
427 fprintf(out," Heure debut : %02u:%02u:%02u\n", tdebut.tm_hour, tdebut.tm_min, tdebut.tm_sec);
428 fprintf(out," Heure fin : %02u:%02u:%02u\n", tfin.tm_hour, tfin.tm_min, tfin.tm_sec);
429 fprintf(out," Parametres : \n");
430 int nbparam=params.get_nb();
431 for (int i=0;i<nbparam;i++)
432 {
433 if (params.get_type(i)==OT_PARAMETRES::DOUBLE) fprintf(out," %s = %lf\n",params.get_nom(i).c_str(),params.get_valeur(i));
434 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());
435 }
436 fprintf(out,"*****************************************************\n");
437 fprintf(out," Compliance après chaque itération\n");
438 fprintf(out,"*****************************************************\n");
439 for (int i=0;i<Ctotiter.size();i++)
440 fprintf(out,"%le\n",Ctotiter[i]);
441 fprintf(out,"*****************************************************\n");
442 fprintf(out," Variation de la compliance après chaque itération\n");
443 fprintf(out,"*****************************************************\n");
444 for (int i=1;i<Ctotiter.size();i++)
445 fprintf(out,"%lf%%\n",(Ctotiter[i]-Ctotiter[i-1])*100./Ctotiter[i-1]);
446 double crit1=0.;
447 double crit2=0.;
448 double crit3=0.;
449 double critv1[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
450 double critv2[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
451 for (int i=0;i<nbsimptet;i++)
452 {
453 SIMP_TETRA* tet=lsttet[i];
454 if (tet->design==1)
455 {
456 crit1=crit1+tet->densite*tet->volume;
457 if (tet->densite>seuil)
458 {
459 crit2=crit2+tet->densite*tet->volume;
460 crit3=crit3+tet->volume;
461 }
462 for (int j=1;j<10;j++)
463 if (tet->densite>0.1*j)
464 {
465 critv1[j]=critv1[j]+tet->densite*tet->volume;
466 critv2[j]=critv2[j]+tet->volume;
467 }
468 }
469 }
470 fprintf(out,"*****************************************************\n");
471 fprintf(out," Résultat\n");
472 fprintf(out,"*****************************************************\n");
473 fprintf(out,"Volume du design : %le \n",volume_design);
474 fprintf(out,"Objectif du volume de design : %le \n",volume_design*f);
475 fprintf(out,"Volume de design obtenu : %le \n",crit1);
476 fprintf(out,"Volume de design obtenu avec le seuil: %le \n",crit2);
477 fprintf(out,"Volume reel de design obtenu avec le seuil: %le \n\n",crit3);
478 fprintf(out," : Volume : Volume reel : Objectif\n");
479 fprintf(out," : %le : %le : %le\n",volume_design,volume_design,volume_design);
480 for (int j=1;j<10;j++)
481 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);
482 fprintf(out,"*************************************************************\n");
483 fclose(out);
484 LISTE_FEM_NOEUD::iterator itnoeud;
485 int nbfemnoeud=fem->get_nb_fem_noeud();
486 /*double *nume=new double[nbfemnoeud];
487 double *deno=new double[nbfemnoeud];
488 int cpt=0;
489 for (FEM_NOEUD *nd=fem->get_premier_noeud(itnoeud);nd!=NULL;nd=fem->get_suivant_noeud(itnoeud))
490 {
491 nd->change_numero(cpt);
492 nume[cpt]=0.;
493 deno[cpt]=0.;
494 cpt++;
495 }*/
496 if (iter==0) sprintf(message,"%s_densite.sol",nometudesortie);
497 else sprintf(message,"%s_densite_iter%d.sol",nometudesortie,iter);
498 int nbsolution=gestd->get_nb_fem_solution();
499 for (int i=nbsolution;i>0;i--)
500 {
501 FEM_SOLUTION* sol=gestd->get_fem_solution(i-1);
502 if (sol->get_maillage()!=fem) continue;
503 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 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),"Optimisation",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
515 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 ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
523 else
524 ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
525 tet->tet->change_solution(tet->densite);
526 solution->ecrire(tet->densite,i,0);
527 /*for (int j=0;j<tet->tet->get_nb_fem_noeud();j++)
528 {
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 } */
533 }
534 /*sprintf(message,"%s_densite2.sol",nometudesortie);
535 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 solution2->ecrire(nume[cpt]/deno[cpt],cpt,0,);
542 cpt++;
543 }
544 delete [] deno;
545 delete [] nume;*/
546 int nb=lsttet.size();
547 for (int i=0;i<nb;i++) delete lsttet[i];
548 }
549
550 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
561 void MGOPT_SIMP::adapte_resultat(char *nomgestd,char *nomparam)
562 {
563 if (nomparam!=NULL) lire_params(nomparam);
564 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 double seuil=params.get_valeur("ro_min");
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 LISTE_FEM_ELEMENT3::iterator it;
577 for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
578 {
579 if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
580 if (tet->get_solution()>seuil)
581 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
582 else
583 ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
584
585 }
586 affiche((char*)"Enregistrement");
587 gestd->enregistrer(nomgestd);
588 affiche((char*)"Enregistrement sous GMSH");
589 char *p=strchr(nomgestd,'.');
590 strncpy(nometude,nomgestd,p-nomgestd);
591 nometude[p-nomgestd]=0;
592 MG_EXPORT exp;
593 char nomfichier[5000];
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 affiche((char*)"Fin");
599 }
600
601
602 void MGOPT_SIMP::recupere_energie(std::vector<class SIMP_TETRA*> lsttet)
603 {
604 char message[750];
605 sprintf(message,"%s.resu",nometude);
606 FILE* in=fopen(message,"rt");
607 int fin=0;
608 do
609 {
610 char* res=fgets(message,750,in);
611 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
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 sscanf(mot10,"%lf",&val);
632 CODE_ASTER_ECOULE=CODE_ASTER_ECOULE+val;
633 }
634
635
636 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 if (strcmp(mot6,"ELEMENT")==0)
643 if (strcmp(mot7,"DE")==0)
644 if (strcmp(mot8,"NOM")==0)
645 if (strcmp(mot9,"SYMBOLIQUE")==0)
646 if (strcmp(mot10,"ENERGIE")==0)
647 {
648 int fin2=0;
649 int passe=0;
650 int nbelement=0;
651 do
652 {
653 char message[750];
654 char* res=fgets(message,750,in);
655 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 char* res=fgets(message,750,in);
665 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 void MGOPT_SIMP::ajouter_voisin_distance(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst)
683 {
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 std::vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
705 if (tet->distance_ref<tet->distance_ref2)
706 lstvoisin=tet->voisin2;
707 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 int nbtetra=noeud->get_lien_element3()->get_nb();
714 for (int k=0;k<nbtetra;k++)
715 {
716 FEM_ELEMENT3* ftet=noeud->get_lien_element3()->get(k);
717 SIMP_TETRA* stet=lst[ftet->get_numero()];
718 if (stet->indice!=i)
719 {
720 stet->indice=i;
721 double dist=tet->distance(stet);
722 if (dist<tet->distance_ref)
723 tet->voisin.insert(tet->voisin.end(),stet);
724 if (dist<tet->distance_ref2)
725 tet->voisin2.insert(tet->voisin2.end(),stet);
726 }
727 }
728 }
729 if (compteur>=lstvoisin.size()) ok=1;
730 else
731 {
732 tetcour=lstvoisin[compteur];
733 compteur++;
734 }
735
736 }
737
738 }
739
740
741 void MGOPT_SIMP::ajouter_voisin_couche(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst,int nb_couches,int nb_couches2)
742 {
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 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 for (int ok=0;ok<std::max(nb_couches,nb_couches2);ok++)
768 {
769 for (int iliste=debut;iliste<fin;iliste++)
770 {
771 SIMP_TETRA* tetcour;
772 if (nb_couches>nb_couches2 ) tetcour=tet->voisin[iliste]; else tetcour=tet->voisin2[iliste];
773 for (int j=0;j<4;j++)
774 {
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 if (ok<nb_couches) tet->voisin.insert(tet->voisin.end(),stet);
786 if (ok<nb_couches2) tet->voisin2.insert(tet->voisin2.end(),stet);
787 }
788 }
789 }
790 }
791 debut=fin;
792 if (nb_couches>nb_couches2 ) fin=tet->voisin.size(); else fin=tet->voisin2.size();
793 }
794 }