ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/optimisation/src/mgopt_simp.cpp
Revision: 322
Committed: Thu Mar 1 21:34:08 2012 UTC (13 years, 6 months ago) by francois
File size: 20640 byte(s)
Log Message:
gestion des differentes versions de code aster

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