MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
mgopt_simp.cpp
Aller à la documentation de ce fichier.
1 //####//------------------------------------------------------------
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 #include "gestionversion.h"
23 #include "mgopt_simp.h"
24 #include "mg_file.h"
25 #include "mg_export.h"
26 #include <string.h>
27 #include <math.h>
29 #include "fct_generateur_3d.h"
30 #include "ot_cpu.h"
31 #include "mglanceuraster.h"
32 
34 {
35 public:
37 double densite;
38 double new_densite;
39 int design;
40 double new_denergie;
41 double energie;
42 double denergie;
43 double volume;
45 int indice;
46 double distance_ref;
48 double centre[3];
50  {
51  return tet->get_boite_3D();
52  };
53 std::vector<SIMP_TETRA*> voisin;
54 std::vector<SIMP_TETRA*> voisin2;
55 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 MGOPT_SIMP::MGOPT_SIMP(bool save):MGOPT(save)
75 {
76 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 params.ajouter("iter_vue",0.,OT_PARAMETRES::DOUBLE,"generation d'un fichier gmsh tous les iter_vue. 0 pas de generation");
97 params.ajouter("type_filtrage",0.,OT_PARAMETRES::DOUBLE,"0. filtrage par distance 1. filtrage par couches");
98 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 }
101 
103 {
104 }
105 
106 
108 {
109 }
110 
111 
112 void MGOPT_SIMP::optimisation(int num_adapt,FEM_MAILLAGE* fem,char *nomparamaster,int iter)
113 {
114 MG_GEOMETRIE* geo=fem->get_mg_geometrie();
115 affiche((char*)" Initialisation");
116 std::vector<SIMP_TETRA*> lsttet;
117 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  {
122  affiche((char*)" Lecture de la carte de taille");
123  int typecarte=(int)params.get_valeur("typecarte");
124  std::string fichiercarte=params.get_nom("fichiercarte");
125  if ((typecarte==0) || (typecarte==1))
126  {
128  carte->lire((char *)fichiercarte.c_str());
129  }
130  if ((typecarte==2) || (typecarte==3)) carte=new FCT_TAILLE_FEM_SOLUTION((char *)fichiercarte.c_str());
131  }
132 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 LISTE_FEM_ELEMENT3::iterator it;
137 int ntet=0;
138 for (FEM_ELEMENT3* tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
139  {
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  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  }
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  tet2->volume=1./6.*tet->get_jacobien(jac,uv,unite);
159  tet2->distance_ref=rminc;
160  tet2->distance_ref2=rmind;
161  double xyz[3]={tet2->centre[0]/unite,tet2->centre[1]/unite,tet2->centre[2]/unite};
162  double val[9];
163  if (tet2->distance_ref<1e-16)
164  {
165  carte->evaluer(xyz,val);
166  tet2->distance_ref=1./sqrt(val[0]);
167  }
168  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  if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
176  {
177  tet2->design=1;
178  tet2->densite=f;
179  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 volume_tot=volume_design+volume_non_design;
190 double volumemoyen=volume_tot/fem->get_nb_fem_element3();
191 affiche((char*)" Recherche de voisins");
192 int nbsimptet=lsttet.size();
193 if (params.get_valeur("type_filtrage")==0.)
194  {
195  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  }
202 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  ajouter_voisin_couche(i,tet,lsttet,params.get_valeur("nb_couchesc"),params.get_valeur("nb_couchesd"));
209  }
210  }
211 
212 int nbiteration=1;
213 int ok=0;
214 int niveaumax=(int)params.get_valeur("nbrniveau");
215 int itervue=(int)params.get_valeur("iter_vue");
216 double p=params.get_valeur("p");
217 std::vector<double> Ctotiter;
218 while (ok==0)
219  {
220  if (nbiteration>params.get_valeur("iter_max")) break;
221  char message[2000];
222  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  affiche(message);
225  std::vector<FEM_ELEMENT3*> *lstniveau=new std::vector<FEM_ELEMENT3*>[niveaumax+1];
226  double densmin = params.get_valeur("ro_void");
227  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  //int version_aster=params.get_valeur("version_aster");
236  exp.lire_params_aster(nomparamaster);
237  double version=exp.aster(geo,fem,nometude,MAGIC::CALCUL_ASTER::OPTIMISATIONTOPOLOGIQUE,(char*)"00000001",p,niveaumax,lstniveau);
238  delete [] lstniveau;
239  char messagever[255];
240  sprintf(messagever," Calcul aster \033[1;32m%.1lf\033[1;33m",version);
241  affiche(messagever);
242  MGLANCEURASTER aster;
243  int code=aster.execute(param,nometude,version);
244  if (code!=0)
245  {
246  char message[500];
247  sprintf(message," Code de sortie aster : %d",code);
248  affiche(message);
249  }
250  affiche((char*)" Analyse resultat");
251  recupere_energie(lsttet);
252  double Ctot=0;
253  for (int i=0;i<nbsimptet;i++)
254  {
255  SIMP_TETRA* tet=lsttet[i];
256  tet->denergie= -p*2.*tet->energie/tet->densite;
257  Ctot=Ctot+2.*tet->energie;
258  }
259  Ctotiter.insert(Ctotiter.end(),Ctot);
260  sprintf(message," Compliance \033[1;31m%le\033[1;33m",Ctot);
261  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  sprintf(message," Ecart \033[1;31m%lf%%\033[1;33m",ecart);
270  affiche(message);
271  }
272  // lissage compliance
273  double kc=params.get_valeur("kc");
274  int type_lissage =(int)params.get_valeur("type_lissage");
275  int lissage_densite =(int)params.get_valeur("lissage_densite");
276  int type_lissage_densite =(int)params.get_valeur("type_lissage_densite");
277  int type_lissage_compliance=(int)params.get_valeur("type_lissage_compliance");
278  for (int i=0;i<nbsimptet;i++)
279  {
280  SIMP_TETRA* tet=lsttet[i];
281  if ((type_lissage==0) || (type_lissage==2))
282  tet->new_denergie=tet->denergie;
283  if ((type_lissage==1) || (type_lissage==3))
284  {
285  if (tet->design == 1)
286  {
287  double hi= pow(tet->distance_ref,kc);
288  double hisensi = hi*tet->densite*tet->denergie;
289  if (type_lissage_compliance==1)
290  {
291  hi=hi/tet->volume;
292  hisensi=hisensi/std::max(volumemoyen*0.00001,tet->volume);
293  }
294  int nbvoisin=tet->voisin.size();
295  for (int j = 0 ; j<nbvoisin ; j++)
296  {
297  SIMP_TETRA* tet2=tet->voisin[j];
298  if (tet2->design == 1)
299  {
300  double dist=tet->distance(tet2);
301  double hj =fabs(pow(tet->distance_ref - dist,kc));
302  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  hisensi=hisensi+tet2->densite*hj*tet2->denergie/std::max(volumemoyen,tet2->volume);
310  hi=hi+hj/tet2->volume;
311  }
312  hisensi=hisensi+tet2->densite*hj*tet2->denergie;
313  hi=hi+hj;
314  }
315  }
316  tet->new_denergie = hisensi/hi/std::max(tet->densite,densmin);
317  }
318  else tet->new_denergie=tet->denergie;
319  }
320  }
321  // application formule pas encore connue
322  double l1= 1e-8 ;
323  double l2= 1e8;
324  double m=params.get_valeur("m");
325  double eta=params.get_valeur("eta");
326  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  {
332  compteurlagrange++;
333  double lmid = 0.5*(l2+l1);
334  critere_densite = 0.0;
335  for (int i=0;i<nbsimptet;i++)
336  {
337  SIMP_TETRA* tet=lsttet[i];
338  if (tet->design==1)
339  {
340  double x1 = tet->densite+m;
341  double beta=-tet->new_denergie/lmid/tet->volume;
342  double x2 = tet->densite*pow(beta,eta);
343  double x3 = std::min(x1,x2);
344  double x4 = 1.;
345  double x5 = std::min(x3,x4);
346  double x6 = tet->densite-m;
347  double x7 = std::max(x5,x6);
348  double x8 = densmin;
349  tet->new_densite = std::max(x7,x8);
350  critere_densite = critere_densite + tet->new_densite*tet->volume;
351  }
352  else
353  {
354  tet->new_densite=1.;
355  }
356  }
357  if (critere_densite - f*volume_design > 0.)
358  l1=lmid;
359  else
360  l2=lmid;
361  if (100.*fabs(critere_densite- f*volume_design )/(f*volume_design)<convergence_lagrange) oklagrange=1;
362  if (compteurlagrange>500) oklagrange=2;
363  }
364  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  affiche(message);
367  // lissage de densite.
368  double kd=params.get_valeur("kd");
369  for (int i=0;i<nbsimptet;i++)
370  {
371  SIMP_TETRA* tet=lsttet[i];
372  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  }
402  if (itervue!=0)
403  if (nbiteration%itervue==0)
404  {
405  affiche((char*)" Sauvegarde résultat iteration");
406  sprintf(message,"%s_densite_iter%d.soltmp",nometudesortie,nbiteration);
407  //int nbsolution=gestd->get_nb_fem_solution();
408  //for (int i=nbsolution;i>0;i--version 2 du for)
409  //gestd->supprimer_fem_solution_du_gestionnaire(i-1);
410  char message2[50];
411  static int step=0;
412  sprintf(message2,"Iteration%%%d",step);
413  step++;
414  FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),message2,MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
415  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  solution->ecrire(tet->densite,i,0);
422  }
423  }
424  nbiteration++;
425  }
426 if (itervue!=0)
427  {
428  affiche((char*)" Sauvegarde GMSH résultats iterations");
429  MG_EXPORT exp;
430  char nomfichier[2000];
431  sprintf(nomfichier,"%s_iterations",nometudesortie);
432  exp.gmsh(fem,nomfichier);
433  }
434 double seuil=params.get_valeur("ro_min");
435 affiche((char*)" Ecriture des donnees finales");
436 char message[2000];
437 if (iter==0) sprintf(message,"%s.compliance",nometudesortie);
438 else sprintf(message,"%s_iter%d.compliance",nometudesortie,iter);
439 FILE *out=fopen(message,"wt");
440 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 fprintf(out," Date : %02u-%02u-%04u\n", tdebut.tm_mday, tdebut.tm_mon+1, 1900 + tdebut.tm_year);
448 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  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  }
457 fprintf(out,"*****************************************************\n");
458 fprintf(out," Compliance après chaque itération\n");
459 fprintf(out,"*****************************************************\n");
460 for (int i=0;i<Ctotiter.size();i++)
461  fprintf(out,"%le\n",Ctotiter[i]);
462 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 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 fprintf(out,"*****************************************************\n");
492 fprintf(out," Résultat\n");
493 fprintf(out,"*****************************************************\n");
494 fprintf(out,"Volume du design : %le \n",volume_design);
495 fprintf(out,"Objectif du volume de design : %le \n",volume_design*f);
496 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  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 fprintf(out,"*************************************************************\n");
504 fclose(out);
505 LISTE_FEM_NOEUD::iterator itnoeud;
506 int nbfemnoeud=fem->get_nb_fem_noeud();
507 /*double *nume=new double[nbfemnoeud];
508 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  }*/
517 if (iter==0) sprintf(message,"%s_densite.sol",nometudesortie);
518 else sprintf(message,"%s_densite_iter%d.sol",nometudesortie,iter);
519 int nbsolution=gestd->get_nb_fem_solution();
520 for (int i=nbsolution;i>0;i--)
521  {
523  if (sol->get_maillage()!=fem) continue;
524  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)
532  }
533 
534 
535 FEM_SOLUTION* solution=new FEM_SOLUTION(fem,1,message,fem->get_nb_fem_element3(),"Optimisation",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3);
536 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  ((MG_TETRA*)tet->tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
544  else
546  tet->tet->change_solution(tet->densite);
547  solution->ecrire(tet->densite,i,0);
548  /*for (int j=0;j<tet->tet->get_nb_fem_noeud();j++)
549  {
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  } */
554  }
555 /*sprintf(message,"%s_densite2.sol",nometudesortie);
556 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  solution2->ecrire(nume[cpt]/deno[cpt],cpt,0,);
563  cpt++;
564  }
565 delete [] deno;
566 delete [] nume;*/
567 int nb=lsttet.size();
568 for (int i=0;i<nb;i++) delete lsttet[i];
569 }
570 
571 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 
582 void MGOPT_SIMP::adapte_resultat(char *nomgestd,char *nomparam)
583 {
584 if (nomparam!=NULL) lire_params(nomparam);
585 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 double seuil=params.get_valeur("ro_min");
593 gestd=new MG_FILE(nomgestd);
595 FEM_SOLUTION* solution=gestd->get_fem_solution(0);
596 solution->active_solution(0);
597 LISTE_FEM_ELEMENT3::iterator it;
598 for (FEM_ELEMENT3 *tet=fem->get_premier_element3(it);tet!=NULL;tet=fem->get_suivant_element3(it))
599  {
600  if (((MG_TETRA*)tet->get_mg_element_maillage())->get_origine()!=MAGIC::ORIGINE::IMPOSE)
601  if (tet->get_solution()>seuil)
602  ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::OPTIMISE);
603  else
604  ((MG_TETRA*)tet->get_mg_element_maillage())->change_origine(MAGIC::ORIGINE::MAILLEUR_AUTO);
605 
606  }
607 affiche((char*)"Enregistrement");
608 gestd->enregistrer(nomgestd);
609 affiche((char*)"Enregistrement sous GMSH");
610 char *p=strchr(nomgestd,'.');
611 strncpy(nometude,nomgestd,p-nomgestd);
612 nometude[p-nomgestd]=0;
613 MG_EXPORT exp;
614 char nomfichier[5000];
615 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 affiche((char*)"Fin");
620 }
621 
622 
623 void MGOPT_SIMP::recupere_energie(std::vector<class SIMP_TETRA*> lsttet)
624 {
625 char message[750];
626 sprintf(message,"%s.resu",nometude);
627 FILE* in=fopen(message,"rt");
628 int fin=0;
629 do
630  {
631  char* res=fgets(message,750,in);
632  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 
645 
646  if (numlu>2)
647  if (strcmp(mot2,"TOTAL_JOB")==0)
648  {
649  double val;
650  sscanf(mot8,"%lf",&val);
652  sscanf(mot10,"%lf",&val);
654  }
655 
656 
657  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  if (strcmp(mot6,"ELEMENT")==0)
664  if (strcmp(mot7,"DE")==0)
665  if (strcmp(mot8,"NOM")==0)
666  if (strcmp(mot9,"SYMBOLIQUE")==0)
667  if (strcmp(mot10,"ENERGIE")==0)
668  {
669  int fin2=0;
670  int passe=0;
671  int nbelement=0;
672  do
673  {
674  char message[750];
675  char* res=fgets(message,750,in);
676  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  char* res=fgets(message,750,in);
686  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 void MGOPT_SIMP::ajouter_voisin_distance(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst)
704 {
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 std::vector<SIMP_TETRA*>& lstvoisin=tet->voisin;
726 if (tet->distance_ref<tet->distance_ref2)
727  lstvoisin=tet->voisin2;
728 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  int nbtetra=noeud->get_lien_element3()->get_nb();
735  for (int k=0;k<nbtetra;k++)
736  {
737  FEM_ELEMENT3* ftet=noeud->get_lien_element3()->get(k);
738  SIMP_TETRA* stet=lst[ftet->get_numero()];
739  if (stet->indice!=i)
740  {
741  stet->indice=i;
742  double dist=tet->distance(stet);
743  if (dist<tet->distance_ref)
744  tet->voisin.insert(tet->voisin.end(),stet);
745  if (dist<tet->distance_ref2)
746  tet->voisin2.insert(tet->voisin2.end(),stet);
747  }
748  }
749  }
750  if (compteur>=lstvoisin.size()) ok=1;
751  else
752  {
753  tetcour=lstvoisin[compteur];
754  compteur++;
755  }
756 
757  }
758 
759 }
760 
761 
762 void MGOPT_SIMP::ajouter_voisin_couche(int i,SIMP_TETRA* tet,std::vector<SIMP_TETRA*> &lst,int nb_couches,int nb_couches2)
763 {
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 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 for (int ok=0;ok<std::max(nb_couches,nb_couches2);ok++)
789  {
790  for (int iliste=debut;iliste<fin;iliste++)
791  {
792  SIMP_TETRA* tetcour;
793  if (nb_couches>nb_couches2 ) tetcour=tet->voisin[iliste]; else tetcour=tet->voisin2[iliste];
794  for (int j=0;j<4;j++)
795  {
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  if (ok<nb_couches) tet->voisin.insert(tet->voisin.end(),stet);
807  if (ok<nb_couches2) tet->voisin2.insert(tet->voisin2.end(),stet);
808  }
809  }
810  }
811  }
812  debut=fin;
813  if (nb_couches>nb_couches2 ) fin=tet->voisin.size(); else fin=tet->voisin2.size();
814  }
815 }
CODE_ASTER_CPU
double CODE_ASTER_CPU
Definition: ot_cpu.cpp:26
MG_EXPORT
Definition: mg_export.h:33
MG_GESTIONNAIRE::enregistrer
virtual void enregistrer(std::ostream &o, double version=MAGIC_VERSION_FICHIER_DOUBLE)
Definition: mg_gestionnaire.cpp:1070
MGOPT::lire_params
virtual void lire_params(char *fichier)
Definition: mgopt.cpp:90
fct_generateur_3d.h
FEM_SOLUTION
Definition: fem_solution.h:40
MG_GESTIONNAIRE::supprimer_fem_solution_du_gestionnaire
int supprimer_fem_solution_du_gestionnaire(unsigned int num)
Definition: mg_gestionnaire.cpp:1001
FEM_ELEMENT_MAILLAGE::change_numero
virtual void change_numero(int num)
Definition: fem_element_maillage.cpp:95
FEM_MAILLAGE::get_suivant_element3
FEM_ELEMENT3 * get_suivant_element3(LISTE_FEM_ELEMENT3::iterator &it)
Definition: fem_maillage.cpp:680
gestionversion.h
MGOPT::nometudesortie
char nometudesortie[500]
Definition: mgopt.h:56
SIMP_TETRA::get_boite_3D
BOITE_3D get_boite_3D(void)
Definition: mgopt_simp.cpp:49
FCT_TAILLE_FEM_SOLUTION
Definition: fct_taille_fem_solution.h:37
OT_PARAMETRES::get_valeur
double get_valeur(std::string chaine, int num=0)
Definition: ot_parametres.cpp:191
SIMP_TETRA
Definition: mgopt_simp.cpp:33
FEM_ELEMENT3::get_fem_noeud
virtual class FEM_NOEUD * get_fem_noeud(int num)=0
MG_IDENTIFICATEUR::get_id
unsigned long get_id()
Definition: mg_identificateur.cpp:53
FEM_ELEMENT_MAILLAGE::change_solution
virtual void change_solution(double val, int num=0)
Definition: fem_element_maillage.cpp:107
FEM_SOLUTION::ecrire
void ecrire(double val, int i, int j, int coord=0, int num_no=0)
Definition: fem_solution.cpp:411
FCT_GENERATEUR_3D< 4 >
SIMP_TETRA::volume
double volume
Definition: mgopt_simp.cpp:43
OT_PARAMETRES::STRING
@ STRING
Definition: ot_parametres.h:38
OT_PARAMETRES::ajouter
void ajouter(std::string chaine, double valeur, int typep, std::string aide="")
Definition: ot_parametres.cpp:61
MGOPT_SIMP::MGOPT_SIMP
MGOPT_SIMP(bool save)
Definition: mgopt_simp.cpp:74
ot_cpu.h
mg_file.h
FEM_ELEMENT3
Definition: fem_element3.h:34
FEM_SOLUTION::get_nom_fichier
std::string get_nom_fichier(void)
Definition: fem_solution.cpp:839
FEM_MAILLAGE::get_mg_geometrie
MG_GEOMETRIE * get_mg_geometrie(void)
Definition: fem_maillage.cpp:88
FCT_TAILLE::lire
virtual void lire(char *nom)=0
FEM_SOLUTION::get_maillage
FEM_MAILLAGE * get_maillage(void)
Definition: fem_solution.cpp:472
MG_GESTIONNAIRE::ajouter_fem_solution
int ajouter_fem_solution(FEM_SOLUTION *mgsol)
Definition: mg_gestionnaire.cpp:902
MGOPT_SIMP
Definition: mgopt_simp.h:30
MG_TETRA
Definition: mg_tetra.h:37
FEM_ELEMENT_MAILLAGE::get_numero
virtual int get_numero(void)
Definition: fem_element_maillage.cpp:101
MGOPT::param
OT_PARAMETRES param
Definition: mgopt.h:54
mglanceuraster.h
SIMP_TETRA::new_denergie
double new_denergie
Definition: mgopt_simp.cpp:40
FEM_MAILLAGE::get_mg_maillage
MG_MAILLAGE * get_mg_maillage(void)
Definition: fem_maillage.cpp:93
FEM_MAILLAGE::get_nb_fem_noeud
unsigned int get_nb_fem_noeud(void)
Definition: fem_maillage.cpp:190
MG_GESTIONNAIRE::get_fem_solution
FEM_SOLUTION * get_fem_solution(unsigned int num)
Definition: mg_gestionnaire.cpp:930
SIMP_TETRA::indice
int indice
Definition: mgopt_simp.cpp:45
MGOPT::tdebut
struct tm tdebut
Definition: mgopt.h:49
SIMP_TETRA::distance
double distance(SIMP_TETRA *tet2)
Definition: mgopt_simp.cpp:56
MGLANCEURASTER
Definition: mglanceuraster.h:28
MAGIC::ORIGINE::OPTIMISE
@ OPTIMISE
Definition: mg_definition.h:79
f
double f(double x, long nb, double *xfonc, double *fonc, double eng, double eni, double lambda, double nor, double *fonc2)
Definition: fct_generateur_calibrage.cpp:96
SIMP_TETRA::densite
double densite
Definition: mgopt_simp.cpp:37
FEM_SOLUTION::active_solution
void active_solution(int num)
Definition: fem_solution.cpp:490
mgopt_simp.h
mg_export.h
MGOPT::params
OT_PARAMETRES params
Definition: mgopt.h:53
MGOPT_SIMP::~MGOPT_SIMP
~MGOPT_SIMP()
Definition: mgopt_simp.cpp:107
OT_PARAMETRES::get_nom
std::string get_nom(std::string chaine)
Definition: ot_parametres.cpp:266
FEM_MAILLAGE
Definition: fem_maillage.h:66
MGOPT
Definition: mgopt.h:30
OT_PARAMETRES::DOUBLE
@ DOUBLE
Definition: ot_parametres.h:38
MGOPT::affiche
void affiche(char *mess)
Definition: mgopt.cpp:80
MG_EXPORT::gmsh
void gmsh(class MG_MAILLAGE *mai, std::string fichier)
Definition: mg_export.cpp:803
FEM_NOEUD::get_lien_element3
TPL_LISTE_ENTITE< class FEM_ELEMENT3 * > * get_lien_element3(void)
Definition: fem_noeud.cpp:417
MAGIC::ORIGINE::IMPOSE
@ IMPOSE
Definition: mg_definition.h:79
FEM_ELEMENT_MAILLAGE::get_mg_element_maillage
virtual class MG_ELEMENT_MAILLAGE * get_mg_element_maillage(void)
Definition: fem_element_maillage.cpp:81
MAGIC::CALCUL_ASTER::OPTIMISATIONTOPOLOGIQUE
@ OPTIMISATIONTOPOLOGIQUE
Definition: mg_definition.h:136
MG_GESTIONNAIRE::get_fem_maillage
FEM_MAILLAGE * get_fem_maillage(unsigned int num)
Definition: mg_gestionnaire.cpp:670
OT_PARAMETRES::get_type
int get_type(std::string chaine)
Definition: ot_parametres.cpp:281
FEM_ELEMENT3::get_nb_fem_noeud
virtual int get_nb_fem_noeud(void)=0
FEM_MAILLAGE::get_nb_fem_element3
unsigned int get_nb_fem_element3(void)
Definition: fem_maillage.cpp:605
TPL_LISTE_ENTITE::get_nb
virtual int get_nb(void)
Definition: tpl_liste_entite.h:67
SIMP_TETRA::distance_ref2
double distance_ref2
Definition: mgopt_simp.cpp:47
MG_EXPORT::aster
double aster(class MG_GEOMETRIE *geo, class FEM_MAILLAGE *mai, std::string fichier, int typeetude, char *coderesu, double penal=0., int niveaumax=0, std::vector< class FEM_ELEMENT3 * > *lst=NULL)
MG_FILE
Definition: mg_file.h:31
TPL_LISTE_ENTITE::get
virtual X get(int num)
Definition: tpl_liste_entite.h:72
MGOPT_SIMP::poid_lissage
double poid_lissage(double dist, double distref, double k, double volume, int type)
Definition: mgopt_simp.cpp:571
FEM_NOEUD
Definition: fem_noeud.h:35
OT_PARAMETRES::get_nb
int get_nb(void)
Definition: ot_parametres.cpp:311
BOITE_3D
Definition: ot_boite_3d.h:27
MG_GESTIONNAIRE::supprimer_fem_solution
int supprimer_fem_solution(unsigned int num)
Definition: mg_gestionnaire.cpp:984
MGOPT_SIMP::adapte_resultat
virtual void adapte_resultat(char *nomgestd, char *nomparam=NULL)
Definition: mgopt_simp.cpp:582
sqrt
double2 sqrt(double2 &val)
Definition: ot_doubleprecision.cpp:345
MGOPT::gestd
class MG_FILE * gestd
Definition: mgopt.h:57
SIMP_TETRA::voisin2
std::vector< SIMP_TETRA * > voisin2
Definition: mgopt_simp.cpp:54
MG_MAILLAGE::get_mg_geometrie
MG_GEOMETRIE * get_mg_geometrie(void)
Definition: mg_maillage.cpp:410
fct_taille_fem_solution.h
SIMP_TETRA::voisin
std::vector< SIMP_TETRA * > voisin
Definition: mgopt_simp.cpp:52
MG_EXPORT::lire_params_aster
void lire_params_aster(char *fichier)
Definition: mg_export.cpp:100
MGOPT_SIMP::ajouter_voisin_couche
void ajouter_voisin_couche(int i, SIMP_TETRA *tet, std::vector< SIMP_TETRA * > &lst, int nb_couches, int nb_couches2)
Definition: mgopt_simp.cpp:762
SIMP_TETRA::design
int design
Definition: mgopt_simp.cpp:39
MG_GEOMETRIE::get_valeur_unite
double get_valeur_unite(void)
Definition: mg_geometrie.cpp:2652
MGOPT_SIMP::optimisation
void optimisation(int num_adapt, class FEM_MAILLAGE *fem, char *nomparamaster, int iter=0)
Definition: mgopt_simp.cpp:112
MGOPT_SIMP::recupere_energie
void recupere_energie(std::vector< class SIMP_TETRA * > lsttet)
Definition: mgopt_simp.cpp:623
SIMP_TETRA::get_id
unsigned long get_id(void)
Definition: mgopt_simp.cpp:55
MG_GEOMETRIE
Definition: mg_geometrie.h:84
res
#define res(i, j)
SIMP_TETRA::denergie
double denergie
Definition: mgopt_simp.cpp:42
CODE_ASTER_ECOULE
double CODE_ASTER_ECOULE
Definition: ot_cpu.cpp:27
SIMP_TETRA::centre
double centre[3]
Definition: mgopt_simp.cpp:48
FEM_ELEMENT3::get_boite_3D
virtual BOITE_3D & get_boite_3D(void)=0
SIMP_TETRA::new_densite
double new_densite
Definition: mgopt_simp.cpp:38
MG_GESTIONNAIRE::get_nb_fem_solution
unsigned int get_nb_fem_solution(void)
Definition: mg_gestionnaire.cpp:960
MGLANCEURASTER::execute
virtual int execute(OT_PARAMETRES &param, char *nometude, double version)
Definition: mglanceuraster.cpp:41
MGOPT::nometude
char nometude[500]
Definition: mgopt.h:55
SIMP_TETRA::distance_ref
double distance_ref
Definition: mgopt_simp.cpp:46
MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT3
@ ENTITE_ELEMENT3
Definition: mg_definition.h:86
MAGIC::ORIGINE::MAILLEUR_AUTO
@ MAILLEUR_AUTO
Definition: mg_definition.h:79
MGOPT_SIMP::ajouter_voisin_distance
void ajouter_voisin_distance(int i, SIMP_TETRA *tet, std::vector< SIMP_TETRA * > &lst)
Definition: mgopt_simp.cpp:703
MGOPT::carte
class FCT_TAILLE * carte
Definition: mgopt.h:59
FEM_SOLUTION::change_legende
void change_legende(int num, std::string val)
Definition: fem_solution.cpp:457
SIMP_TETRA::energie
double energie
Definition: mgopt_simp.cpp:41
FCT_TAILLE::evaluer
virtual void evaluer(double *param, double *resultat)=0
SIMP_TETRA::tet
FEM_ELEMENT3 * tet
Definition: mgopt_simp.cpp:36
FEM_MAILLAGE::get_premier_element3
FEM_ELEMENT3 * get_premier_element3(LISTE_FEM_ELEMENT3::iterator &it)
Definition: fem_maillage.cpp:672
SIMP_TETRA::maille_niveau
int maille_niveau
Definition: mgopt_simp.cpp:44
m
#define m(i, j)