MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
mgopt_mvt_normal.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_mvt_normal.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:57 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 #include "mgopt_mvt_normal.h"
23 #include "mg_gestionnaire.h"
24 #include "mg_geometrie_outils.h"
25 #include "opt_noeud.h"
26 #include "opt_triangle.h"
27 #include "mg_file.h"
28 #include "mgaster.h"
29 #include <string.h>
30 #include "mg_export.h"
31 #include "mg_import.h"
33 #include "ot_systeme.h"
35 #include <stdio.h>
36 
38 {
40 }
41 
42 MGOPT_MVT_NORMAL::MGOPT_MVT_NORMAL(FEM_MAILLAGE* fem, FEM_MAILLAGE* fem_visu):fem(fem),fem_visu(fem_visu)
43 {
44  // Correspondance entre OPT_NOEUD et FEM_NOEUD
45  int i=1;
46  LISTE_FEM_NOEUD::iterator it_fem_noeud;
47  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(it_fem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(it_fem_noeud))
48  {
49  OPT_NOEUD* opt_noeud=new OPT_NOEUD(fem_noeud);
50  listenoeud.ajouter(opt_noeud);
51  opt_noeud->change_num(i);
52  i++;
53  std::pair<OPT_NOEUD*,FEM_NOEUD*> asso(opt_noeud,fem_noeud);
54  std::pair<unsigned long,std::pair<OPT_NOEUD*,FEM_NOEUD*> > tmp(fem_noeud->get_id(),asso);
55  correspondance_noeud.insert(tmp);
56  }
57 
58  // Correspondance entre OPT_TRIANGLE et FEM_TRIANGLE3
59  i=1;
60  LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
61  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
62  {
64 
65  OPT_NOEUD* opt_noeud1=get_noeud(fem_tri3->get_fem_noeud(0));
66  OPT_NOEUD* opt_noeud2=get_noeud(fem_tri3->get_fem_noeud(1));
67  OPT_NOEUD* opt_noeud3=get_noeud(fem_tri3->get_fem_noeud(2));
68 
69  OPT_TRIANGLE* opt_tri=new OPT_TRIANGLE(fem_tri3,opt_noeud1,opt_noeud2,opt_noeud3);
70  listetriangle.ajouter(opt_tri);
71  opt_tri->change_num(i);
72  i++;
73  std::pair<OPT_TRIANGLE*,FEM_TRIANGLE3*> asso(opt_tri,fem_tri3);
74  std::pair<unsigned long,std::pair<OPT_TRIANGLE*,FEM_TRIANGLE3*> > tmp(fem_tri3->get_id(),asso);
75  correspondance_triangle.insert(tmp);
76  }
77 
80 
81  // Pour l'écriture d'un fichier de paramètres par défaut
83 }
84 
86 {
87  params=mdd.params;
88 }
89 
91 {
93  for (OPT_NOEUD* no=listenoeud.get_premier(it);no!=NULL;no=listenoeud.get_suivant(it))
94  delete no;
95 
97  for (OPT_TRIANGLE* tri=listetriangle.get_premier(ittri);tri!=NULL;tri=listetriangle.get_suivant(ittri))
98  delete tri;
99 }
100 
102 {
103  std::map<unsigned long, std::pair<OPT_NOEUD*,FEM_NOEUD*> >::iterator it=correspondance_noeud.find(fem_noeud->get_id());
104  return ((*it).second).first;
105 }
106 
108 {
109  std::map<unsigned long, std::pair<OPT_TRIANGLE*,FEM_TRIANGLE3*> >::iterator it=correspondance_triangle.find(fem_tri3->get_id());
110  return ((*it).second).first;
111 }
112 
113 void MGOPT_MVT_NORMAL::active_affichage(void (*fonc)(char*))
114 {
115  affiche=fonc;
116  affichageactif=1;
117 }
118 
120 {
121  // Paramètres de la méthode du mouvement normal
122  params.ajouter(" ##### Paramètres de la méthode du mouvement normal #####","",OT_PARAMETRES::STRING,"");
123  params.ajouter("s_objective",0.,OT_PARAMETRES::DOUBLE," Contrainte objectif de la méthode du mouvement normal en MPa (0: utilisation de la valeur moyenne actualisée à chaque itération)");
124  params.ajouter("c",0.1,OT_PARAMETRES::DOUBLE," Constante de convergence initiale");
125  params.ajouter("limite",0.1,OT_PARAMETRES::DOUBLE," Limite de convergence sur la contrainte objectif");
126  params.ajouter("iter_max",100.,OT_PARAMETRES::DOUBLE," Nombre maximal d'itérations de la méthode du mouvement normal");
127  params.ajouter("iter_vue",10.,OT_PARAMETRES::DOUBLE," Génération d'un fichier gmsh toutes les iter_vue (0: pas de génération)");
128  params.ajouter("actualisation_normales",0.,OT_PARAMETRES::DOUBLE," Actualisation des normales à chaque itération (0: non actualisées, 1: actualisées)");
129 
130  // Paramètres pour le contrôle avec écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe
131  params.ajouter(" ##### Paramètres pour le contrôle avec écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe #####","",OT_PARAMETRES::STRING,"");
132  params.ajouter("deplacement",0.,OT_PARAMETRES::DOUBLE," Contrôle avec écart de déplacement maximal entre 2 noeuds voisins dont l'un est fixe (0: sans contrôle, 1: avec contrôle)");
133  params.ajouter("ecart_max_depl",1.,OT_PARAMETRES::DOUBLE," Écart maximal de déplacement entre 2 noeuds voisins");
134  params.ajouter("facteur_repl",0.1,OT_PARAMETRES::DOUBLE," Facteur pour le replacement du noeud lors du dépassement de l'écart maximal de déplacement");
135 
136  // Paramètres pour le contrôle avec gradient maximal de déplacement
137  params.ajouter(" ##### Paramètres pour le contrôle avec gradient maximal de déplacement #####","",OT_PARAMETRES::STRING,"");
138  params.ajouter("gradient",0.,OT_PARAMETRES::DOUBLE," Contrôle avec gradient maximal de déplacement (0: sans gradient, 1: avec gradient)");
139  params.ajouter("norme_max_grad",0.2,OT_PARAMETRES::DOUBLE," Norme maximale du gradient de déplacement de chaque triangle par rapport à sa position initiale");
140  params.ajouter("pas",1.,OT_PARAMETRES::DOUBLE," Pas de l'algorithme du gradient");
141  params.ajouter("epsilon",0.001,OT_PARAMETRES::DOUBLE," Critère d'arrêt de l'algorithme du gradient");
142  params.ajouter("iter_max_grad",1000.,OT_PARAMETRES::DOUBLE," Nombre maximal d'itérations de l'algorithme du gradient");
143 
144  // Paramètres pour le contrôle avec lissage des noeuds par barycentrage
145  params.ajouter(" ##### Options de lissage #####","",OT_PARAMETRES::STRING,"");
146  params.ajouter("lissage_iter",0.,OT_PARAMETRES::DOUBLE," Lissage des noeuds à chaque X itérations de la méthode (0: sans lissage, X: avec lissage à chaque X itérations)");
147  params.ajouter("lissage_fin",0.,OT_PARAMETRES::DOUBLE," Lissage des noeuds à la fin de la méthode (0: sans lissage, 1: avec lissage)");
148 
149  // Paramètre pour le contrôle avec lissage contrôlé des noeuds par barycentrage
150  params.ajouter(" ##### Options de lissage contrôlé #####","",OT_PARAMETRES::STRING,"");
151  params.ajouter("ecart_max_pondere_norme_pos",0.02,OT_PARAMETRES::DOUBLE," Lissage des noeuds si l'écart pondéré entre la norme de la position moyenne et la norme de la position du noeud est supérieur à la valeur spécifiée (0.2: écart de 20 % sur la norme de la position moyenne pondérée))");
152  params.ajouter("lissage_controle_iter",0.,OT_PARAMETRES::DOUBLE," Lissage contrôlé des noeuds à chaque X itérations de la méthode (0: sans lissage, X: avec lissage contrôlé à chaque X itérations)");
153 
154  // Option de génération d'un fichier magic contenant uniquement les solutions de déplacement servant à la création d'un film
155  params.ajouter(" ##### Options de film #####","",OT_PARAMETRES::STRING,"");
156  params.ajouter("film",0.,OT_PARAMETRES::DOUBLE," Option de génération d'un fichier magic contenant uniquement les solutions de déplacement servant à la création d'un film");
157  //params.ajouter("coderesu","11100010","Code pour la sortie des résultats)");
158 }
159 
161 {
162  params.enregistrer(fichierparam);
163 }
164 
165 
166 void MGOPT_MVT_NORMAL::lire_params(char* fichier)
167 {
168  params.vide();
169  params.lire(fichier);
170 }
171 
173 {
175  for (OPT_NOEUD* opt_noeud=listenoeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=listenoeud.get_suivant(itopt_noeud))
176  {
177  // Création de la liste de noeuds à déplacer (vérification des conditions frontières)
178  double val;
179  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
180  int ndok=(fem_noeud->get_lien_topologie())->get_valeur_ccf((char*)"Nd",val); //(char*) pour régler warning
181  if (ndok!=1)
182  lstnoeud_deplacer_initiale->ajouter(opt_noeud);
183  }
184 }
185 
187 {
188  // Détermination des noeuds voisins
189  TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud_voisin;
190  int nb_fem_ele2=(opt_noeud->get_fem_noeud())->get_lien_element2()->get_nb();
191  for (int i=0;i<nb_fem_ele2;i++)
192  {
193  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
194  FEM_TRIANGLE3* fem_tri=(FEM_TRIANGLE3*)fem_noeud->get_lien_element2()->get(i);
195  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
196 
197  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
198  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
199  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
200 
201  if (opt_n1->get_id()==opt_noeud->get_id())
202  {
203  lst_noeud_voisin.ajouter(opt_n2);
204  lst_noeud_voisin.ajouter(opt_n3);
205  }
206  if (opt_n2->get_id()==opt_noeud->get_id())
207  {
208  lst_noeud_voisin.ajouter(opt_n1);
209  lst_noeud_voisin.ajouter(opt_n3);
210  }
211  if (opt_n3->get_id()==opt_noeud->get_id())
212  {
213  lst_noeud_voisin.ajouter(opt_n1);
214  lst_noeud_voisin.ajouter(opt_n2);
215  }
216  }
217  opt_noeud->change_liste_noeud_voisin(lst_noeud_voisin);
218 
219 }
220 
222 {
223  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
224  double* xyzn1=opt_tri->get_noeud1()->get_coord();
225  double* xyzn2=opt_tri->get_noeud2()->get_coord();
226  double* xyzn3=opt_tri->get_noeud3()->get_coord();
227 
228  OT_VECTEUR_3D vec1(xyzn1,xyzn3);
229  OT_VECTEUR_3D vec2(xyzn1,xyzn2);
230  OT_VECTEUR_3D n_tri=vec1&vec2; // Normale au triangle
231 
232  double aire=n_tri.get_longueur()*0.5;
233  return aire;
234 }
235 
237 {
238  // Calcul de la normale au noeud à partir de la normale des triangles voisins (somme pondérée par l'aire de chaque triangle)
239  OT_VECTEUR_3D w_n_tot(0.,0.,0.);
240  double norme_w_n_tot=0.;
241  OT_VECTEUR_3D w2_n_tot(0.,0.,0.);
242  double norme_w2_n_tot=0.;
243  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
244  int nbtri=fem_noeud->get_lien_element2()->get_nb();
245  for (int i=0;i<nbtri;i++)
246  {
247  FEM_TRIANGLE3* fem_tri=(FEM_TRIANGLE3*)(fem_noeud->get_lien_element2()->get(i));
248  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
249  double* xyzn1=opt_tri->get_noeud1()->get_coord();
250  double* xyzn2=opt_tri->get_noeud2()->get_coord();
251  double* xyzn3=opt_tri->get_noeud3()->get_coord();
252 
253  OT_VECTEUR_3D vec1(xyzn1,xyzn3);
254  OT_VECTEUR_3D vec2(xyzn1,xyzn2);
255  OT_VECTEUR_3D n_tri=vec1&vec2; // Normale au triangle
256 
257  double w=n_tri.get_longueur(); // 2 fois l'aire du triangle (pour éviter une division par 2)
258  n_tri.norme();
259  OT_VECTEUR_3D w_n=w*n_tri;
260  double norme_w_n=w_n.get_longueur();
261  w_n_tot=w_n_tot+w_n;
262  norme_w_n_tot=norme_w_n_tot+norme_w_n;
263  }
264  MG_NOEUD* mg_noeud=(MG_NOEUD*)fem_noeud->get_mg_element_maillage();
265  MG_TRIANGLE* mg_tri=mg_noeud->get_lien_triangle()->get(0);
266  MG_FACE* face=(MG_FACE*)(mg_tri->get_lien_topologie());
267  int orientation=face->get_mg_coface(0)->get_orientation();
268 
269  OT_VECTEUR_3D n=w_n_tot/norme_w_n_tot; // Normale à la surface au noeud
270  n.norme();
271  n=orientation*n; // Normale orientée
272  opt_noeud->change_normale(n);
273 }
274 
275 double MGOPT_MVT_NORMAL::get_sigma_vm_max(MG_GESTIONNAIRE* gest, FEM_NOEUD* fem_noeud, int numsolinf, int numsolmoy, int numsolsup)
276 {
277  // Contrainte de Von Mises maximale entre les 3 plans de calcul (inférieur, moyen, supérieur)
278  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
279  int num=opt_noeud->get_num();
280  double svm1=gest->get_fem_solution(numsolinf)->lire(num-1,0);
281  double svm2=gest->get_fem_solution(numsolmoy)->lire(num-1,0);
282  double svm3=gest->get_fem_solution(numsolsup)->lire(num-1,0);
283  double svm_max=0.;
284 
285  if ((svm1>=svm2) && (svm1>=svm3)) // Contrainte de Von Mises maximale entre les trois plans
286  svm_max=svm1;
287  if ((svm2>=svm1) && (svm2>=svm3))
288  svm_max=svm2;
289  if ((svm3>=svm1) && (svm3>=svm2))
290  svm_max=svm3;
291  return svm_max;
292 }
293 
294 double MGOPT_MVT_NORMAL::get_ecart_type_sigma_vm(MG_GESTIONNAIRE* gest, TPL_MAP_ENTITE< OPT_NOEUD* > lstnoeud, double moyenne, int numsolinf, int numsolmoy, int numsolsup)
295 {
297  int compteur_svm=0;
298  double somme_ecart_au_carre=0.;
299  double ecarttype=0.;
300  for (OPT_NOEUD* opt_noeud=lstnoeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud.get_suivant(itopt_noeud))
301  {
302  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
303  double svm=get_sigma_vm_max(gest,fem_noeud,numsolinf,numsolmoy,numsolsup);
304  somme_ecart_au_carre=somme_ecart_au_carre+((svm-moyenne)*(svm-moyenne));
305  compteur_svm++;
306  }
307  ecarttype=sqrt((1./compteur_svm)*somme_ecart_au_carre);
308  return ecarttype;
309 }
310 
312 {
313  // Solution de déplacement virtuel d'un opt_noeud
314  opt_noeud->change_sol_deplacement_virtuel(d);
315 
316  int nb_fem_ele2=(opt_noeud->get_fem_noeud())->get_lien_element2()->get_nb();
317  for (int i=0;i<nb_fem_ele2;i++)
318  {
319  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
320  FEM_TRIANGLE3* fem_tri=(FEM_TRIANGLE3*)fem_noeud->get_lien_element2()->get(i);
321  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
324  }
325 }
326 
328 {
329  // Déplacement réel d'un opt_noeud
330  //OT_VECTEUR_3D n=opt_noeud->get_normale_initiale();
331  OT_VECTEUR_3D n=opt_noeud->get_normale();
332  double *xyz=opt_noeud->get_coord();
333  double xyz_modif[3];
334 
335  xyz_modif[0]=xyz[0]+d*n[0];
336  xyz_modif[1]=xyz[1]+d*n[1];
337  xyz_modif[2]=xyz[2]+d*n[2];
338 
339  opt_noeud->change_x(xyz_modif[0]);
340  opt_noeud->change_y(xyz_modif[1]);
341  opt_noeud->change_z(xyz_modif[2]);
342 
344 
345  int nb_fem_ele2=(opt_noeud->get_fem_noeud())->get_lien_element2()->get_nb();
346  for (int i=0;i<nb_fem_ele2;i++)
347  {
348  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
349  FEM_TRIANGLE3* fem_tri=(FEM_TRIANGLE3*)fem_noeud->get_lien_element2()->get(i);
350  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
353  }
354 }
355 
356 
358 {
359  // Écriture de la solution de déplacement du fem_noeud
360  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
361  int num=opt_noeud->get_num();
362 
363  double dx=opt_noeud->get_x()-opt_noeud->get_x_initial();
364  double dy=opt_noeud->get_y()-opt_noeud->get_y_initial();
365  double dz=opt_noeud->get_z()-opt_noeud->get_z_initial();
366 
367  sol->ecrire(dx,num-1,0,0);
368  sol->ecrire(dy,num-1,0,1);
369  sol->ecrire(dz,num-1,0,2);
370 }
371 
372 
374 {
375  // Liste de opt_triangle ayant 2 noeuds fixes
376  (*lst_tri_2nd_fixe).vide();
377  LISTE_FEM_ELEMENT2::iterator itfem_ele2;
378  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(itfem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(itfem_ele2))
379  {
380  OPT_TRIANGLE* opt_tri=get_triangle((FEM_TRIANGLE3*)fem_ele2);
381 
382  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
383  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
384  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
385 
386  // Le triangle a 2 noeuds fixes
387  if ((!lstnoeud_deplacer.existe(opt_n1) && !lstnoeud_deplacer.existe(opt_n2) && lstnoeud_deplacer.existe(opt_n3)) || (!lstnoeud_deplacer.existe(opt_n1) && lstnoeud_deplacer.existe(opt_n2) && !lstnoeud_deplacer.existe(opt_n3)) || (lstnoeud_deplacer.existe(opt_n1) && !lstnoeud_deplacer.existe(opt_n2) && !lstnoeud_deplacer.existe(opt_n3)))
388  (*lst_tri_2nd_fixe).ajouter(opt_tri);
389  }
390 }
391 
393 {
394  (*lst_noeud).vide();
396  for (OPT_TRIANGLE* opt_tri=lst_tri.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri.get_suivant(itopt_tri))
397  {
398  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
399  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
400  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
401 
402  (*lst_noeud).ajouter(opt_n1);
403  (*lst_noeud).ajouter(opt_n2);
404  (*lst_noeud).ajouter(opt_n3);
405  }
406 }
407 
409 {
410  // Liste de opt_noeud mobiles des opt_triangle ayant 1 ou 2 noeuds fixes
411  (*lst_noeud_mobile_tri_2nd_fixe).vide();
413  for (OPT_TRIANGLE* opt_tri=lst_tri_2nd_fixe.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_2nd_fixe.get_suivant(itopt_tri))
414  {
415  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
416  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
417  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
418 
419  if (lstnoeud_deplacer.existe(opt_n1))
420  (*lst_noeud_mobile_tri_2nd_fixe).ajouter(opt_n1);
421  if (lstnoeud_deplacer.existe(opt_n2))
422  (*lst_noeud_mobile_tri_2nd_fixe).ajouter(opt_n2);
423  if (lstnoeud_deplacer.existe(opt_n3))
424  (*lst_noeud_mobile_tri_2nd_fixe).ajouter(opt_n3);
425  }
426 
427 }
428 
429 /*void MGOPT_MVT_NORMAL::get_liste_opt_tri_3nd_fixe(FEM_MAILLAGE* fem, TPL_MAP_ENTITE< OPT_NOEUD* > lstnoeud_deplacer, TPL_MAP_ENTITE< OPT_TRIANGLE* >* lst_opt_tri_3nd_fixe)
430 {
431  // Liste de fem_triangle3 ayant 3 noeuds fixes
432  (*lst_opt_tri_3nd_fixe).vide();
433  LISTE_FEM_ELEMENT2::iterator itfem_ele2;
434  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(itfem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(itfem_ele2))
435  {
436  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
437  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri3);
438  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
439  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
440  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
441 
442  // Le triangle a 3 noeuds fixes
443  if (!lstnoeud_deplacer.existe(opt_n1) && !lstnoeud_deplacer.existe(opt_n2) && !lstnoeud_deplacer.existe(opt_n3))
444  (*lst_opt_tri_3nd_fixe).ajouter(opt_tri);
445  }
446 }*/
447 
448 
449 
450 double MGOPT_MVT_NORMAL::evaluer_fonction_f(double seuil, TPL_MAP_ENTITE< OPT_TRIANGLE* > lst_tri, int affichage)
451 {
452  if (affichage==1)
453  std::cout << " Évaluation de la fonction f " << std::endl;
454  //cout << " Évaluation de la fonction f définie comme la somme de la différence au carré entre la norme du gradient de déplacement " << endl;
455  //cout << " de chaque triangle possédant 1 ou 2 noeuds fixes et dont la norme du gradient de déplacement dépasse la valeur seuil " << endl;
456  //cout << " et la valeur seuil. << endl;
457  double f=0.;
458 
459  double a1, a2, a3;
460  double b1, b2, b3;
461  double c1, c2, c3;
462 
463  double d1;
464  double d2;
465  double d3;
466 
469  for (OPT_TRIANGLE* opt_tri=lst_tri.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri.get_suivant(itopt_tri))
470  //for (OPT_TRIANGLE* opt_tri=listetriangle.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=listetriangle.get_suivant(itopt_tri))
471  {
472  double norme_grad_depl=opt_tri->get_norme_gradient_deplacement_virtuel();
473  if (norme_grad_depl>seuil)// || (norme_relle>seuil)) // À revoir!!!
474  {
475  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
476  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
477  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
478 
479  // Vérifier si un des 3 noeuds peut être déplacé par le mvt normal?
480  // (pour ne pas inclure un triangle dont le noeud mobile ne peut pas être déplacé par le mvt normal dû
481  // à un écart de contrainte insuffisant)
482 
483  //if ((opt_n1->get_mvt_normal()==1) || (opt_n2->get_mvt_normal()==1) || (opt_n3->get_mvt_normal()==1))
484  //{
485  OT_MATRICE_3D abc=opt_tri->get_matrice_abc();
486  a1=abc(0,0), a2=abc(0,1); a3=abc(0,2);
487  b1=abc(1,0), b2=abc(1,1), b3=abc(1,2);
488  c1=abc(2,0), c2=abc(2,1), c3=abc(2,2);
489 
490  d1=opt_n1->get_sol_deplacement_virtuel();
491  d2=opt_n2->get_sol_deplacement_virtuel();
492  d3=opt_n3->get_sol_deplacement_virtuel();
493 
494  // Calcul de f
495  double f_tri=pow(sqrt((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3))-seuil,0.2e1);
496  //double f_tri_test=pow(sqrt(pow(a1*d1+a2*d2+a3*d3,0.2e1)+pow(b1*d1+b2*d2+b3*d3,0.2e1)+pow(c1*d1+c2*d2+c3*d3,0.2e1))-s,0.2e1);
497  f=f+f_tri;
498  //cout << " Tri dépasse avant algo (id,num): " << opt_tri->get_id() << " " << opt_tri->get_num() << " Norme virtuelle: " << opt_tri->get_norme_gradient_deplacement_virtuel() << endl;
500  //}
501  }
502  }
503  if (f<0.0000000000001)
504  if (affichage==1)
505  std::cout << " Fonction f: " << f << " La norme max du gradient de déplacement n'est pas atteinte pour aucun triangle!!! " << std::endl;
506  if (f>0.0000000000001) // Si la norme d'au moins 1 triangle dépasse la valeur seuil
507  {
508  if (affichage==1)
509  {
510  std::cout << " Fonction f: " << f << std::endl;
511  std::cout << " Nb de triangles ayant 2 noeuds fixes et un noeud mobile qui dépassent le gradient max: " << nb_tri_grad_depasse << std::endl;
512  }
513  }
514  return f;
515 }
516 
517 void MGOPT_MVT_NORMAL::evaluer_gradient_f(int num_repl, double norme_max_grad, TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri)//, TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud__mobile_tri_12nd_fixe)
518 {
519  //cout << " Évaluation du gradient de la fonction f " << endl; //Enlever
521 
522  // Mise à 0 des termes du gradient de f (à revoir!!! Utiliser la liste des noeuds mobiles des tris ayant 2 noeuds fixes)
523  for (OPT_NOEUD* opt_noeud=listenoeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=listenoeud.get_suivant(itopt_noeud))
524  opt_noeud->change_terme_gradient_f(0.);
525 
526  double a1, a2, a3;
527  double b1, b2, b3;
528  double c1, c2, c3;
529 
530  double d1;
531  double d2;
532  double d3;
533 
535  for (OPT_TRIANGLE* opt_tri=lst_tri.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri.get_suivant(itopt_tri))
536  //for (OPT_TRIANGLE* opt_tri=listetriangle.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=listetriangle.get_suivant(itopt_tri))
537  {
538  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
539  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
540  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
541 
542  OT_MATRICE_3D abc=opt_tri->get_matrice_abc();
543 
544  d1=opt_n1->get_sol_deplacement_virtuel();
545  d2=opt_n2->get_sol_deplacement_virtuel();
546  d3=opt_n3->get_sol_deplacement_virtuel();
547 
548  //opt_tri->change_norme_gradient_deplacement_virtuel(); //Enlever
549  double norme_virtuelle=opt_tri->get_norme_gradient_deplacement_virtuel();
550  double norme_relle=opt_tri->get_norme_gradient_deplacement_reel(); //Enlever
551  if ((norme_virtuelle>norme_max_grad))// || (norme_relle>norme_max_grad)) // À revoir!!!
552  {
553  a1=abc(0,0), a2=abc(0,1); a3=abc(0,2);
554  b1=abc(1,0), b2=abc(1,1), b3=abc(1,2);
555  c1=abc(2,0), c2=abc(2,1), c3=abc(2,2);
556 
557  // Calcul du terme du gradient de f pour chaque noeud mobile devant être déplacé par le mvt_normal (non, pour chaque noeud mobile)
558  //if (opt_n1->get_mvt_normal()==1 && opt_n1->get_mobile()==1)
559  //if (opt_n1->get_mvt_normal()==1)
560  if (opt_n1->get_mobile()==1)
561  {
562  double df_tri=(sqrt((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3))-norme_max_grad)*pow((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3),-0.1e1/0.2e1)*(2*a1*a1*d1+2*a1*a2*d2+2*a1*a3*d3+2*b1*b1*d1+2*b1*b2*d2+2*b1*b3*d3+2*c1*c1*d1+2*c1*c2*d2+2*c1*c3*d3);
563  double df=opt_n1->get_terme_gradient_f()+fabs(df_tri);
564  opt_n1->change_terme_gradient_f(df);
565  opt_n1->change_num_replacement(num_repl);
566  }
567  //if (opt_n2->get_mvt_normal()==1 && opt_n2->get_mobile()==1)
568  //if (opt_n2->get_mvt_normal()==1)
569  if (opt_n2->get_mobile()==1)
570  {
571  double df_tri=(sqrt((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3))-norme_max_grad)*pow((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3),-0.1e1/0.2e1)*(2*a1*d1*a2+2*a2*a2*d2+2*a2*a3*d3+2*b1*d1*b2+2*b2*b2*d2+2*b2*b3*d3+2*c1*d1*c2+2*c2*c2*d2+2*c2*c3*d3);
572  double df=opt_n2->get_terme_gradient_f()+fabs(df_tri);
573  opt_n2->change_terme_gradient_f(df);
574  opt_n2->change_num_replacement(num_repl);
575  }
576  //if (opt_n3->get_mvt_normal()==1 && opt_n3->get_mobile()==1)
577  //if (opt_n3->get_mvt_normal()==1)
578  if (opt_n3->get_mobile()==1)
579  {
580  double df_tri=(sqrt((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3))-norme_max_grad)*pow((a1*a1*d1*d1+2*a1*d1*a2*d2+2*a1*d1*a3*d3+a2*a2*d2*d2+2*a2*d2*a3*d3+a3*a3*d3*d3+b1*b1*d1*d1+2*b1*d1*b2*d2+2*b1*d1*b3*d3+b2*b2*d2*d2+2*b2*d2*b3*d3+b3*b3*d3*d3+c1*c1*d1*d1+2*c1*d1*c2*d2+2*c1*d1*c3*d3+c2*c2*d2*d2+2*c2*d2*c3*d3+c3*c3*d3*d3),-0.1e1/0.2e1)*(2*a1*d1*a3+2*a2*d2*a3+2*a3*a3*d3+2*b1*d1*b3+2*b2*d2*b3+2*b3*b3*d3+2*c1*d1*c3+2*c2*d2*c3+2*c3*c3*d3);
581  double df=opt_n3->get_terme_gradient_f()+fabs(df_tri);
582  opt_n3->change_terme_gradient_f(df);
583  opt_n3->change_num_replacement(num_repl);
584  }
585  }
586  }
587 }
588 
590 {
591  double somme_termes_carre=0.;
593  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(itopt_noeud))
594  //for (OPT_NOEUD* opt_noeud=listenoeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=listenoeud.get_suivant(itopt_noeud))
595  {
596  //if (opt_noeud->get_a_replacer()==1)
597  if (opt_noeud->get_num_replacement()==num_repl)
598  {
599  double terme=opt_noeud->get_terme_gradient_f();
600  somme_termes_carre=somme_termes_carre+terme*terme;
601  }
602  }
603  double norme_grad_f=sqrt(somme_termes_carre);
604  return norme_grad_f;
605 }
606 
607 int MGOPT_MVT_NORMAL::algorithme_gradient(int num_repl, double norme_max_grad, double pas, double epsilon, int iter_max_grad, TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri, TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud, int affichage)
608 {
609  if (affichage==1)
610  std::cout << " Minimisation de la fonction f par l'algorithme du gradient " << std::endl;
611  evaluer_gradient_f(num_repl,norme_max_grad,lst_tri);//,lst_noeud_mobile_tri_2nd_fixe);
612  double norme_grad_f=get_norme_gradient_f(num_repl,lst_noeud);
613  double norme_grad_f_precedente= 1000000000000;
616 
617  int nb_iter_algo=0;
618  if (affichage==1)
619  {
620  std::cout.setf(std::ios::fixed,std::ios::floatfield);
621  std::cout.precision(6);
622  std::cout << " Norme initiale du gradient de la fonction f: " << norme_grad_f << std::endl; //Enlever
623  }
624 
625  // Mise à 0 du terme a_ete_replace (pas nécessaire car déjà fait lorsque le noeud est fixé)
626  //for (OPT_NOEUD* opt_noeud=listenoeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=listenoeud.get_suivant(itopt_noeud))
627  //opt_noeud->change_a_ete_replace(0);
628 
629  // Mise en mémoire du déplacement de chaque noeud pour pondérer le pas de l'algo
630  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(itopt_noeud))
631  opt_noeud->change_depl_avant_algo_grad(opt_noeud->get_sol_deplacement_virtuel());
632 
633  bool fin=false;
634  int code_erreur=0;
635  while ((norme_grad_f>epsilon) && (nb_iter_algo<iter_max_grad) && (fin==false))
636  {
637  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(itopt_noeud))
638  {
639  //if (opt_noeud->get_a_replacer()==1) // Noeud à replacer par l'algorithme du gradient
640  if ((opt_noeud->get_num_replacement()==num_repl))// && (opt_noeud->get_terme_gradient_f())>0.0000000001)
641  {
642  // Calcul de la norme du gradient de f avant déplacement du noeud
643  evaluer_gradient_f(num_repl,norme_max_grad,lst_tri);
644  double norme_grad_f_avant_depl=get_norme_gradient_f(num_repl,lst_noeud);
645 
646  double terme_gradient=opt_noeud->get_terme_gradient_f();
647  double d_precedent=opt_noeud->get_sol_deplacement_virtuel();
648 
649  //if (fabs(d_precedent)<0.0001) //Enlever
650  //d_precedent=0;
651 
652  double d_avant_algo=opt_noeud->get_depl_avant_algo_grad();
653 
654  // Terme du gradient de f positif
655  double sens=opt_noeud->get_sens_depl_virtuel();
656  //double d;
657  //if (fabs(d_precedent)>0.0000000001) // Pour ne pas modifier le déplacement s'il est nul (noeud replacé à sa position d'origine)
658  double d=d_precedent-pas*terme_gradient*d_avant_algo; // Ajouter *d_avant_algo pour tenir compte de l'ampleur et du signe du déplacement initial
659  //if (fabs(d)<0.0001)
660  //d=0;
661 
662  if (fabs(d)>fabs(d_precedent)) //Enlever
663  int stop=1;
664 
665  // Pour détecter un changement de signe du déplacement
666  if ((d*sens<0))//&& (fabs(d)>0.0001))
667  {
668  // Les changements de signe sont inévitables!!!
669  //cout << " CHANGEMENT DE SIGNE! LE NOEUD N'A PAS ÉTÉ REPLACÉ! VÉRIFIER LE PAS! " << endl;
670 
671 
672  //cout << " ERREUR!!! LE NOEUD N'A PAS ÉTÉ REPLACÉ (PAS ENTRE POSITION INITIALE ET POSITION ACTUELLE)!!! (id num)" << opt_noeud->get_id() << " " << opt_noeud->get_num() << endl;
673  //fin=true;
674 
675  // On replace le noeud à sa position initiale (déplacement nul)
676  //change_deplacement_virtuel_opt_noeud(opt_noeud,0);
677 
678  // Calcul de la norme du gradient de f après déplacement du noeud
679  //evaluer_gradient_f(num_repl,norme_max_grad,lst_tri);
680  //double norme_grad_f_apres_depl=get_norme_gradient_f(num_repl,lst_noeud);
681 
682  // On ne déplace pas le noeud s'il apporte une augmentation de la norme du gradient de f
683  // Ne devrait jamais être le cas si le pas de l'algorithme est adéquat
684  //if (norme_grad_f_apres_depl>norme_grad_f_avant_depl)
685  //{
686  //change_deplacement_virtuel_opt_noeud(opt_noeud,d_precedent);
687  //cout << " CHANGEMENT DE SIGNE! NOEUD REPLACÉ À SA POSITION INITIALE! VÉRIFIER LE PAS! " << endl;
688  //}
689  //fin=true; // À faire: essayer sans mettre fin à l'algo
690  //int stop=1;
691  }
692 
693  // Pour s'assurer de replacer le noeud entre sa position initiale et sa position obtenue par le mvt normal
694  if (d*sens>0)
695  {
697 
698  // Norme des triangles après déplacement noeud (enlever)
699  int nb_fem_ele2=(opt_noeud->get_fem_noeud())->get_lien_element2()->get_nb();
700  for (int i=0;i<nb_fem_ele2;i++)
701  {
702  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
703  FEM_TRIANGLE3* fem_tri=(FEM_TRIANGLE3*)fem_noeud->get_lien_element2()->get(i);
704  OPT_TRIANGLE* opt_tri=get_triangle(fem_tri);
705 
706  if (lst_tri.existe(opt_tri)) // Le triangle a 2 noeuds fixes
707  int test=1;
708  }
709 
710  // Calcul de la norme du gradient de f après déplacement du noeud
711  evaluer_gradient_f(num_repl,norme_max_grad,lst_tri);
712  double norme_grad_f_apres_depl=get_norme_gradient_f(num_repl,lst_noeud);
713 
714  // On ne déplace pas le noeud s'il apporte une augmentation de la norme du gradient de f
715  if (norme_grad_f_apres_depl>norme_grad_f_avant_depl)
716  change_deplacement_virtuel_opt_noeud(opt_noeud,d_precedent);
717  }
718 
719  /*evaluer_gradient_f(num_repl,seuil,lst_tri_voisin);
720  double norme_grad_f_positif=get_norme_gradient_f(num_repl,lst_noeud);
721  change_deplacement_virtuel_opt_noeud(opt_noeud,d0);
722 
723  // Terme du gradient de f négatif
724  double d_terme_grad_negatif=d0+pas*terme_gradient;
725  change_deplacement_virtuel_opt_noeud(opt_noeud,d_terme_grad_negatif);
726  evaluer_gradient_f(num_repl,seuil,lst_tri);
727  double norme_grad_f_negatif=get_norme_gradient_f(num_repl,lst_noeud);
728  change_deplacement_virtuel_opt_noeud(opt_noeud,d0);
729 
730  // On garde celui qui procure la norme du gradient de f la plus faible
731  if (norme_grad_f_positif<=norme_grad_f_negatif)
732  {
733  change_deplacement_virtuel_opt_noeud(opt_noeud,d_terme_grad_positif);
734  norme_grad_f=norme_grad_f_positif;
735  }
736  if (norme_grad_f_positif>norme_grad_f_negatif)
737  {
738  change_deplacement_virtuel_opt_noeud(opt_noeud,d_terme_grad_negatif);
739  norme_grad_f=norme_grad_f_negatif;
740  }*/
741  }
742  }
743 
744  // Recalcul du gradient de f et de sa norme avec ces nouvelles valeurs de déplacement
745  evaluer_gradient_f(num_repl,norme_max_grad,lst_tri);//,lst_noeud_mobile_tri_2nd_fixe);
746  norme_grad_f=get_norme_gradient_f(num_repl,lst_noeud);
747 
748  if (fabs(norme_grad_f-norme_grad_f_precedente)<0.0000001)
749  {
750  if (affichage==1)
751  std::cout << " LA NORME DU GRADIENT DE LA FONCTION F NE VARIE PLUS! " << std::endl;
752  fin=true;
753  }
754  if (norme_grad_f>norme_grad_f_precedente)
755  {
756  if (affichage==1)
757  std::cout << " ERREUR!!! LA NORME DU GRADIENT DE LA FONCTION F A AUGMENTÉE EN PASSANT DE: " << norme_grad_f_precedente << " à " << norme_grad_f << std::endl;
758  fin=true;
759  }
760  norme_grad_f_precedente=norme_grad_f;
761  nb_iter_algo++; //Enlever
762  if (nb_iter_algo==iter_max_grad)
763  {
764  if (affichage==1)
765  std::cout << " ERREUR!!! LE NOMBRE D'ITÉRATIONS MAXIMAL A ÉTÉ ATTEINT! " << std::endl;
766  fin=true;
767  }
768  }
769 
770  // ########## Affichage du nb de noeuds replacés par l'algo du gradient et le nb de triangles affectés ##########
771 
772  int nb_noeud_repl=0;
773  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(itopt_noeud))
774  if (opt_noeud->get_num_replacement()==num_repl)
775  nb_noeud_repl++;
776  if (affichage==1)
777  std::cout << " Nb de noeuds replacés par l'algorithme du gradient: " << nb_noeud_repl << std::endl;
778 
779  int nb_tri_repl=0;
780  for (OPT_TRIANGLE* opt_tri=lst_tri.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri.get_suivant(itopt_tri))
781  {
782  double repl_n1=opt_tri->get_noeud1()->get_num_replacement();
783  double repl_n2=opt_tri->get_noeud2()->get_num_replacement();
784  double repl_n3=opt_tri->get_noeud3()->get_num_replacement();
785  if ((repl_n1==num_repl) || (repl_n2==num_repl) || (repl_n3==(num_repl)))
786  nb_tri_repl++;
787  }
788  if (affichage==1)
789  std::cout << " Nb de triangles à 2 noeuds fixes affectés: " << nb_tri_repl << std::endl;
790  //cout << " Nb de triangles ayant 2 noeuds fixes: " << lst_tri.get_nb() << endl;
791 
792  if (fin==true)
793  {
794  //cout << " SORTIE FORCÉE DE L'ALGORITHME!!! La norme du gradient de f vaut " << norme_grad_f << endl;
795  //cout << " L'ALGORITHME DU GRADIENT A ÉCHOUÉ!!! VÉRIFIER LE PAS, LE CRITÈRE D'ARRÊT ET LA CONSTANTE DE CONVERGENCE! " << endl;
796  code_erreur=1;
797  }
798  if (affichage==1)
799  std::cout << " Norme finale du gradient de la fonction f: " << norme_grad_f << std::endl;
800 
801  // Affichage des termes du gradient de la fonction f après replacement (enlever)
802  //for (OPT_NOEUD* opt_noeud=lst_opt_noeud_tri_12nd_fixe.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_opt_noeud_tri_12nd_fixe.get_suivant(itopt_noeud))
803  //if (fabs(opt_noeud->get_terme_gradient_f())>0.000001)
804  //cout << " Noeud (id): " << opt_noeud->get_id() << " Terme gradient: " << opt_noeud->get_terme_gradient_f() << endl;
805  if (affichage==1)
806  std::cout << " Nb d'itérations effectuées: " << nb_iter_algo << std::endl;
807  return code_erreur;
808 }
809 
811 {
812  std::cout << " Lissage par barycentrage des noeuds " << std::endl;
813 
814  int nb_noeud=lst_noeud.get_nb();
817  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(it2);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(it2))
818  {
819  // Détermination des noeuds voisins
820  TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud_voisin;
821  lst_noeud_voisin=opt_noeud->get_liste_noeud_voisin();
822 
823  // Calcul de la position moyenne des noeuds voisins
824  OT_VECTEUR_3D pos_moy;
825  for (OPT_NOEUD* opt=lst_noeud_voisin.get_premier(it3);opt!=NULL;opt=lst_noeud_voisin.get_suivant(it3))
826  {
827  OT_VECTEUR_3D pos_opt(opt->get_x(),opt->get_y(),opt->get_z());
828  pos_moy=pos_moy+pos_opt;
829  }
830  // Sans prise en compte de la position du noeud
831  /*int nb_voisin=lst_noeud_voisin.get_nb();
832  pos_moy=pos_moy/nb_voisin;*/
833 
834  // Avec prise en compte de la position du noeud
835  OT_VECTEUR_3D pos_opt_noeud(opt_noeud->get_x(),opt_noeud->get_y(),opt_noeud->get_z());
836  pos_moy=pos_moy+pos_opt_noeud;
837  int nb_voisin=lst_noeud_voisin.get_nb();
838  pos_moy=pos_moy/(nb_voisin+1);
839 
840  // Calcul de la position moyenne à partir du déplacement actualisé (en cours de lissage) des noeuds
841  /*opt_noeud->change_x(pos_moy[0]);
842  opt_noeud->change_y(pos_moy[1]);
843  opt_noeud->change_z(pos_moy[2]);*/
844 
845  //double d_reel_initial=opt_noeud->get_norme_orientee_deplacement(); // Devraient être identiques???
846  //double d_virtuel_initial=opt_noeud->get_sol_deplacement_virtuel();
847 
848  // Calcul de la position moyenne à partir de la position initiale (avant lissage) des noeuds
849  opt_noeud->change_coord_lissee(pos_moy);
850  }
852  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(it4);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(it4))
853  {
854  OT_VECTEUR_3D pos_lissee(opt_noeud->get_coord_lissee()); // Position lissée du noeud
855  opt_noeud->change_x(pos_lissee[0]);
856  opt_noeud->change_y(pos_lissee[1]);
857  opt_noeud->change_z(pos_lissee[2]);
858  }
859 }
860 
861 void MGOPT_MVT_NORMAL::lissage_controle(TPL_MAP_ENTITE< OPT_NOEUD* > lst_noeud, double ecart_max_pondere_norme_pos)
862 {
863  std::cout << " Lissage contrôlé par barycentrage des noeuds (replacement des pires noeuds seulement) " << std::endl;
864 
865  int nb_noeud=lst_noeud.get_nb();
868  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(it2);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(it2))
869  {
870  // Détermination des noeuds voisins
871  TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud_voisin;
872  lst_noeud_voisin=opt_noeud->get_liste_noeud_voisin();
873 
874  // Calcul de la position moyenne des noeuds voisins
875  OT_VECTEUR_3D pos_moy;
876  for (OPT_NOEUD* opt=lst_noeud_voisin.get_premier(it3);opt!=NULL;opt=lst_noeud_voisin.get_suivant(it3))
877  {
878  OT_VECTEUR_3D pos_opt(opt->get_x(),opt->get_y(),opt->get_z());
879  pos_moy=pos_moy+pos_opt;
880  }
881 
882  // Avec prise en compte de la position du noeud
883  OT_VECTEUR_3D pos_opt_noeud(opt_noeud->get_x(),opt_noeud->get_y(),opt_noeud->get_z());
884  pos_moy=pos_moy+pos_opt_noeud;
885  int nb_voisin=lst_noeud_voisin.get_nb();
886  pos_moy=pos_moy/(nb_voisin+1);
887 
888  // Si l'écart pondéré entre la position du noeud et la position moyenne est supérieur à X% de la position moyenne
889  //OT_VECTEUR_3D pos_moy_max(pos_moy[0]/ecart_max_pondere_norme_pos,pos_moy[1]/ecart_max_pondere_norme_pos,pos_moy[2]/ecart_max_pondere_norme_pos);
890  double norme_pos_opt_noeud=pos_opt_noeud.get_longueur();
891  double norme_pos_moy=pos_moy.get_longueur();
892  //double norme_pos_moy_max=pos_moy_max.get_longueur();
893  if (fabs((norme_pos_moy-norme_pos_opt_noeud)/norme_pos_moy)>ecart_max_pondere_norme_pos)
894  {
895  opt_noeud->change_coord_lissee(pos_moy);
896 
897  // Le noeud est fixé pour les prochaines itérations s'il est voisin d'un noeud fixe
898  int voisin_fixe=0;
899  for (OPT_NOEUD* opt=lst_noeud_voisin.get_premier(it3);opt!=NULL;opt=lst_noeud_voisin.get_suivant(it3))
900  if (opt->get_mobile()==0)
901  voisin_fixe=1;
902  if (voisin_fixe==1)
903  opt_noeud->change_mobile(0);
904  }
905  else
906  opt_noeud->change_coord_lissee(pos_opt_noeud);
907  }
909  for (OPT_NOEUD* opt_noeud=lst_noeud.get_premier(it4);opt_noeud!=NULL;opt_noeud=lst_noeud.get_suivant(it4))
910  {
911  OT_VECTEUR_3D pos_lissee(opt_noeud->get_coord_lissee()); // Position lissée du noeud
912  opt_noeud->change_x(pos_lissee[0]);
913  opt_noeud->change_y(pos_lissee[1]);
914  opt_noeud->change_z(pos_lissee[2]);
915  }
916 }
917 
918 void MGOPT_MVT_NORMAL::optimisation(char* fichierin, char* fichierout, char* fichierparam, char* fichierparamaster)
919 {
920  // ########## Lecture du fichier de paramètres ##########
921 
922  if (fichierparam!=NULL) lire_params(fichierparam);
923 
924  // Code pour l'utilisation de la valeur moyenne actualisée comme contrainte objective
925  int contrainte_objective_moyenne=0;
926 
927  // Paramètres de la méthode du mouvement normal
928  double s_objective=(double)params.get_valeur("s_objective")*1e06; // Contrainte objective en MPa
929  if (s_objective<0.001)
930  contrainte_objective_moyenne=1; // Utilisation de la valeur moyenne de contrainte de Von Mises aux noeuds actualisée à chaque itération
931  double c=(double)params.get_valeur("c"); // Constante de convergence
932  double limite=(double)params.get_valeur("limite"); // Limite de convergence
933  int iter_max=(int)params.get_valeur("iter_max"); // Nb maximal d'itérations de la méthode du mouvement normal
934  int iter_vue=(int)params.get_valeur("iter_vue"); // Génération d'un fihcier gmsh toutes les iter_vue. 0 Pas de generation
935  int actualisation_normales=(int)params.get_valeur("actualisation_normales"); // Actualisation des normales à chaque itération (0: normales non actualisées, 1: normales actualisées)
936 
937  // Paramètres pour le contrôle avec écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe
938  int deplacement=(int)params.get_valeur("deplacement"); // Contrôle avec écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe (0: sans contrôle, 1: avec contrôle)
939  double ecart_max_depl=params.get_valeur("ecart_max_depl"); // Écart maximal de déplacement entre 2 noeuds voisins
940  double facteur_repl=params.get_valeur("facteur_repl"); // Facteur pour le replacement du noeud lors du dépassement de l'écart maximal de déplacement
941 
942  // Paramètres pour le contrôle avec gradient maximal de déplacement
943  int gradient=(int)params.get_valeur("gradient"); // Contrôle avec gradient maximal de déplacement (0: sans gradient, 1: avec gradient)
944  double norme_max_grad=params.get_valeur("norme_max_grad"); // Norme maximale du gradient de déplacement d'un noeud par rapport à sa position initiale
945  double pas=(double)params.get_valeur("pas"); // Pas de l'algorithme du gradient
946  double epsilon=(double)params.get_valeur("epsilon"); // Critère d'arrêt de l'algorithme du gradient
947  int iter_max_grad=(int)params.get_valeur("iter_max_grad"); // Nb maximal d'itérations de l'algorithme du gradient
948 
949  // Paramètres pour le contrôle avec lissage des noeuds
950  int lissage_iter=(int)params.get_valeur("lissage_iter"); // Lissage des noeuds à chaque X itérations de la méthode (0: sans lissage, X: avec lissage à chaque X itérations)
951  int lissage_fin=(int)params.get_valeur("lissage_fin"); // Lissage des noeuds à la fin de la méthode (0: sans lissage, 1: avec lissage)
952 
953  // Paramètre pour le contrôle avec lissage contrôlé des noeuds par barycentrage
954  double ecart_max_pondere_norme_pos=params.get_valeur("ecart_max_pondere_norme_pos"); // Lissage des noeuds si l'écart pondéré entre la norme de la position moyenne et la norme de la position du noeud est supérieur à la valeur spécifiée (0.2: écart de 20 % sur la norme de la position moyenne pondérée)
955  int lissage_controle_iter=(int)params.get_valeur("lissage_controle_iter"); // Lissage contrôlé des noeuds à chaque X itérations de la méthode (0: sans lissage, X: avec lissage contrôlé à chaque X itérations)
956 
957  //Option de génération d'un fichier magic contenant uniquement les solutions de déplacement servant à la création d'un film
958  int film=(int)params.get_valeur("film");
959 
960  char coderesu[10]="11110010"; // Déplacements et contraintes équivalentes de Von Mises sur les 3 plans de calcul (inf, moy et sup)
961  int numsolinf=1;
962  int numsolmoy=2;
963  int numsolsup=3;
964 
965  // ########## Affichage des paramètres à l'utilisateur ##########
966 
967  //affiche((char*)" Fichier d'entrée:");
968  //affiche((char*)fichier);
969  char mess[3000];
970  if (contrainte_objective_moyenne==1)
971  {
972  sprintf(mess," Paramètres mvt_normal: s_objective: moyenne");
973  affiche(mess);
974  }
975  else
976  {
977  sprintf(mess," Paramètres mvt_normal: s_objective: %.0f MPa",s_objective/1e06);
978  affiche(mess);
979  }
980  sprintf(mess," c: %.4lf",c);
981  affiche(mess);
982  sprintf(mess," limite: %.2lf",limite);
983  affiche(mess);
984  sprintf(mess," iter_max: %d",iter_max);
985  affiche(mess);
986  sprintf(mess," iter_vue: %d",iter_vue);
987  affiche(mess);
988  sprintf(mess," actualisation_normales: %d",actualisation_normales);
989  affiche(mess);
990 
991  sprintf(mess," Paramètres écart max dépl: deplacement: %d",deplacement);
992  affiche(mess);
993  if (deplacement==1)
994  {
995  sprintf(mess," ecart_max_depl: %.4lf",ecart_max_depl);
996  affiche(mess);
997  sprintf(mess," facteur_repl: %.4lf",facteur_repl);
998  affiche(mess);
999  }
1000 
1001  sprintf(mess," Paramètres gradient: gradient: %d",gradient);
1002  affiche(mess);
1003  if (gradient==1)
1004  {
1005  sprintf(mess," norme_max_grad: %.4lf",norme_max_grad);
1006  affiche(mess);
1007  sprintf(mess," pas: %.4lf",pas);
1008  affiche(mess);
1009  sprintf(mess," epsilon: %.6lf",epsilon);
1010  affiche(mess);
1011  sprintf(mess," iter_max_grad: %d",iter_max_grad);
1012  affiche(mess);
1013  }
1014 
1015  sprintf(mess," Paramètres lissage: lissage_iter: %d",lissage_iter);
1016  affiche(mess);
1017  sprintf(mess," lissage_fin: %d",lissage_fin);
1018  affiche(mess);
1019 
1020  sprintf(mess," lissage_controle_iter:%d",lissage_controle_iter);
1021  affiche(mess);
1022  if (lissage_controle_iter>0)
1023  {
1024  sprintf(mess," Paramètres lissage contrôlé: ecart_max_pondere_norme_pos: %.2lf",ecart_max_pondere_norme_pos);
1025  affiche(mess);
1026  }
1027 
1028  sprintf(mess," Paramètres film: film: %d",film);
1029  affiche(mess);
1030 
1031  char *p=strchr(fichierin,'.'); //Enlever
1032  strncpy(etude,fichierin,p-fichierin);
1033  etude[p-fichierin]=0;
1034 
1035  char *p2=strchr(fichierout,'.'); //Enlever
1036  strncpy(etudesortie,fichierout,p2-fichierout);
1037  etudesortie[p2-fichierout]=0;
1038 
1039  // ########## Option de génération d'un fichier magic servant à la création d'un film ##########
1040 
1041  char etudefilm[200];
1042  char fichierfilm[200];
1043  MG_GESTIONNAIRE *gest_film;
1044  if (film==1)
1045  {
1046  strcpy(etudefilm,etudesortie);
1047  //strcat(etudefilm,"_film");
1048  //strcpy(fichierfilm,etudefilm);
1049  //strcat(fichierfilm,".magic");
1050  gest_film=fem_visu->get_mg_maillage()->get_gestionnaire();
1051  }
1052 
1053  // ########## Initialisation de la méthode ##########
1054 
1055  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_deplacer_initiale; // Liste non altérée contenant tous les noeuds à déplacer initialement
1056  get_liste_noeud_deplacer_initiale(listenoeud,&lstnoeud_deplacer_initiale);
1057 
1058  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_deplacer;
1060  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1061  {
1062  lstnoeud_deplacer.ajouter(opt_noeud);
1063  opt_noeud->change_mobile_au_depart(1);
1064  opt_noeud->change_mobile(1);
1065 
1066  // Mise en mémoire de la position initiale des opt_noeud
1067  opt_noeud->change_x_initial(opt_noeud->get_x());
1068  opt_noeud->change_y_initial(opt_noeud->get_y());
1069  opt_noeud->change_z_initial(opt_noeud->get_z());
1070 
1071  // Calcul des normales à la triangulation initiale
1072  calcul_normale_opt_noeud(opt_noeud);
1073  opt_noeud->change_normale_initiale();
1074 
1075  // Initialisation du déplacement virtuel des noeuds
1076  opt_noeud->change_sol_deplacement_virtuel(0.);
1077 
1078  // Initialisation du déplacement réel des noeuds
1079  opt_noeud->change_norme_orientee_deplacement();
1080 
1081  // Détermination des noeuds voisins du noeud
1082  change_liste_noeud_voisin(opt_noeud);
1083  }
1084 
1085  // ########## Affichage (enlever?) ##########
1086 
1087  int nb_noeud=lstnoeud_deplacer_initiale.get_nb(); //Enlever
1088  sprintf(mess," Il y a initialement %d noeuds pouvant être déplacés",nb_noeud);
1089  affiche(mess);
1090 
1091  int nb_tri_mobile_initial=0; // Triangle ayant au moins 1 noeud mobile au départ (enlever)
1092  LISTE_FEM_ELEMENT2::iterator itfem_ele2;
1093  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(itfem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(itfem_ele2))
1094  {
1095  OPT_TRIANGLE* opt_tri=get_triangle((FEM_TRIANGLE3*)fem_ele2);
1096 
1097  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
1098  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
1099  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
1100 
1101  if ((opt_n1->get_mobile_au_depart()==1) || (opt_n2->get_mobile_au_depart()==1) || (opt_n3->get_mobile_au_depart()==1))
1102  nb_tri_mobile_initial++;
1103  }
1104 
1105  sprintf(mess," Il y a initialement %d triangles ayant au moins 1 noeud mobile",nb_tri_mobile_initial);
1106  affiche(mess);
1107 
1108  // ########## Définition des solutions de visualisation ##########
1109 
1110  // Valeurs maximales de la contrainte de Von Mises entre les 3 plans de calcul pour les géométries initiales et finales
1111  FEM_SOLUTION *sol_S_VM_MAX_I=new FEM_SOLUTION(fem_visu,1,(char*)"contrainte_vm_max_i.sol",1,"S_VM_MAX",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
1112  sol_S_VM_MAX_I->change_legende(0,"I");
1113  FEM_SOLUTION *sol_S_VM_MAX_F=new FEM_SOLUTION(fem_visu,1,(char*)"contrainte_vm_max_f.sol",1,"S_VM_MAX",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
1114  sol_S_VM_MAX_F->change_legende(0,"F");
1115 
1116  // Contraintes de Von Mises maximales initiales et finales sous forme de normales à la triangulation initiale
1117  FEM_SOLUTION* sol_S_VM_MAX_I_VEC=new FEM_SOLUTION(fem_visu,1,(char*)"contrainte_vm_max_i_vec.sol",1,"S_VM_MAXVEC",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::VECTEUR);
1118  sol_S_VM_MAX_I_VEC->change_legende(0,"I");
1119  FEM_SOLUTION* sol_S_VM_MAX_F_VEC=new FEM_SOLUTION(fem_visu,1,(char*)"contrainte_vm_max_f_vec.sol",1,"S_VM_MAXVEC",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::VECTEUR); // À revoir
1120  sol_S_VM_MAX_F_VEC->change_legende(0,"F");
1121 
1122  // Noeuds bloqués par le gradient de déplacement
1123  FEM_SOLUTION *sol_arret_gradient=new FEM_SOLUTION(fem_visu,1,(char*)"arret_gradient.sol",1,"Arret_GRAD",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::SCALAIRE);
1124  sol_arret_gradient->change_legende(0,"BIN"); // Solution binaire
1125 
1126  // Norme du gradient de déplacement des noeuds de chaque triangle de la zone de design ayant 3 noeuds fixes
1127  FEM_SOLUTION *sol_valeur_gradient=new FEM_SOLUTION(fem_visu,1,(char*)"valeur_gradient.sol",1,"Valeur_GRAD",MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT2,MAGIC::TYPE_SOLUTION::SCALAIRE);
1128  sol_valeur_gradient->change_legende(0,"BIN");
1129 
1130  // Forme initiale de la pièce
1131  FEM_SOLUTION* sol_forme_initiale=new FEM_SOLUTION(fem_visu,1,(char*)"optimisation0.sol",1,"Iteration0",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::VECTEUR);
1132  sol_forme_initiale->change_legende(0,"U");
1133 
1134  // ########## MAJ solution "sol_forme_initiale" ##########
1135 
1136  LISTE_FEM_NOEUD::iterator itfem_noeud;
1137  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1138  ecriture_fem_solution_deplacement(sol_forme_initiale,fem_noeud);
1139 
1140  affiche((char*)" Génération du fichier .msh de l'itération 0");
1141  char iter[100];
1142  sprintf(iter,"0");
1143  char etudeiter[100];
1144  strcpy(etudeiter,etudesortie);
1145  strcat(etudeiter,"_iter");
1146  strcat(etudeiter,iter);
1147  MG_EXPORT exp;
1148  //exp.gmsh(fem_visu,etudeiter);
1149  /*if (film==1)
1150  exp.gmsh(fem_visu,etudefilm);*/
1151 
1152  // ########## Calcul de l'état de contrainte initial ##########
1153 
1155  MGASTER mgaster;
1156  affiche((char*)" Calcul de l'état de contrainte initial");
1157  mgaster.active_affichage(affiche);
1158  int codesortie=mgaster.calcule(fichierparamaster,fem,etude,MAGIC::CALCUL_ASTER::ELASTIQUE,coderesu,false); // Exportation vers Code_aster et calcul
1159  std::cout << " Code de sortie: " << codesortie << std::endl;
1160 
1161  // ########## MAJ des contraintes min, moy et max sur la zone de design et des critères d'évaluation de la forme ##########
1162 
1163  double svm_min=1.e308;
1164  double svm_moy=0.;
1165  double svm_max=0.;
1166  double somme_svm=0.;
1167  int compteur_svm=0;
1168  double ecarttype=0.;
1169 
1170  // ##### Calcul de svm_moy #####
1171  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1172  {
1173  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
1174  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1175  if (svm<svm_min) svm_min=svm;
1176  if (svm>svm_max) svm_max=svm;
1177  somme_svm=somme_svm+svm;
1178  compteur_svm++;
1179  }
1180  svm_moy=somme_svm/compteur_svm;
1181  ecarttype=get_ecart_type_sigma_vm(gest_visu,lstnoeud_deplacer_initiale,svm_moy,numsolinf,numsolmoy,numsolsup);
1182  if (contrainte_objective_moyenne==1)
1183  s_objective=svm_moy;
1184 
1185  // ##### MAJ solutions de visualisation des contraintes initiales #####
1186  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1187  {
1188  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
1189  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1190  int num=opt_noeud->get_num();
1191  sol_S_VM_MAX_I->ecrire(svm/1e06,num-1,0);
1192 
1193  // Affichage des contraintes de Von Mises initiales sous forme de normales à la triangulation initiale
1194  OT_VECTEUR_3D normale_initiale=opt_noeud->get_normale_initiale();
1195  sol_S_VM_MAX_I_VEC->ecrire(svm/1e06*normale_initiale(0),num-1,0,0);
1196  sol_S_VM_MAX_I_VEC->ecrire(svm/1e06*normale_initiale(1),num-1,0,1);
1197  sol_S_VM_MAX_I_VEC->ecrire(svm/1e06*normale_initiale(2),num-1,0,2);
1198  }
1199 
1200  // ########## Critères d'évaluation de la forme initiale ##########
1201  double dx_max=0.;
1202  double dy_max=0.;
1203  double dz_max=0.;
1204  double a_tot=0.;
1205  double k_s=0.;
1206  double a_d=0.;
1207  double svm_s=0.;
1208  double nb_nic=0.;
1209  double nb_nnc=0.;
1210  double nb_noeud_design=0.;
1211  double pnic=0.;
1212  double pnnc=0.;
1213 
1214  // ##### Déplacement relatif maximal d'un noeud sous l'effet des efforts externes #####
1215  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1216  {
1217  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
1218  int num=opt_noeud->get_num();
1219  double dx=gest_visu->get_fem_solution(0)->lire(num-1,0);
1220  if (fabs(dx)>fabs(dx_max))
1221  dx_max=dx;
1222  double dy=gest_visu->get_fem_solution(0)->lire(num-1,1);
1223  if (fabs(dy)>fabs(dy_max))
1224  dy_max=dy;
1225  double dz=gest_visu->get_fem_solution(0)->lire(num-1,2);
1226  if (fabs(dz)>fabs(dz_max))
1227  dz_max=dz;
1228  }
1229 
1230  // ##### Aire totale de la surface #####
1231  LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
1232  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
1233  {
1234  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
1235  double aire_tri=get_aire_fem_tri3(fem_tri3);
1236  a_tot=a_tot+aire_tri;
1237  }
1238 
1239  // ##### Aire de la zone de design #####
1240  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
1241  {
1242  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
1243 
1244  OPT_NOEUD* opt_n1=get_noeud(fem_tri3->get_fem_noeud(0));
1245  OPT_NOEUD* opt_n2=get_noeud(fem_tri3->get_fem_noeud(1));
1246  OPT_NOEUD* opt_n3=get_noeud(fem_tri3->get_fem_noeud(2));
1247 
1248  if ((lstnoeud_deplacer_initiale.existe(opt_n1)) || (lstnoeud_deplacer_initiale.existe(opt_n2)) || (lstnoeud_deplacer_initiale.existe(opt_n3)))
1249  {
1250  double aire_tri=get_aire_fem_tri3(fem_tri3);
1251  a_d=a_d+aire_tri;
1252  }
1253  }
1254 
1255  // ##### Pourcentage de noeuds dont la contrainte est située dans l'intervalle de convergence (% NIC) et pourcentage de noeuds non contraints (% NNC) #####
1256  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1257  {
1258  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
1259  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1260  if (svm<svm_min) svm_min=svm;
1261  if (svm>svm_max) svm_max=svm;
1262  somme_svm=somme_svm+svm;
1263  compteur_svm++;
1264 
1265  double coef=fabs(svm-s_objective)/s_objective;
1266  if (coef<=limite)
1267  nb_nic++;
1268  if (svm<0.1*svm_moy)
1269  nb_nnc++;
1270  nb_noeud_design++;
1271  }
1272  pnic=nb_nic/nb_noeud_design*100;
1273  pnnc=nb_nnc/nb_noeud_design*100;
1274 
1275  // ########## Affichage des contraintes de Von Mises min, moy et max initiales et des critères d'évaluation de la forme ##########
1276 
1277  sprintf(mess," Les contraintes min, moy et max initiales valent: %.2lf MPa %.2lf MPa %.2lf MPa",svm_min/1e06,svm_moy/1e06,svm_max/1e06);
1278  affiche(mess);
1279  sprintf(mess," L'écart type est de: %.2lf MPa",ecarttype/1e06);
1280  affiche(mess);
1281  sprintf(mess," Les déplacements max selon X, Y et Z valent: %.2e m %.2e m %.2e m",dx_max,dy_max,dz_max);
1282  affiche(mess);
1283  sprintf(mess," L'aire totale vaut: %.4lf m²",a_tot/1e06);
1284  affiche(mess);
1285  sprintf(mess," L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
1286  affiche(mess);
1287  sprintf(mess," La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
1288  affiche(mess);
1289  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
1290  affiche(mess);
1291  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
1292  affiche(mess);
1293 
1294  sprintf(mess," %d noeuds peuvent être déplacés par la méthode du mouvement normal",lstnoeud_deplacer.get_nb());
1295  affiche(mess);
1296 
1297  // ########## Ajout des solutions au gestionnaire ##########
1298 
1299  // Après le calcul par Code_Aster pour que les trois premières solutions soient celles contenant les contraintes de Von Mises sur les plans inférieur, moyen et supérieur
1300  gest_visu->ajouter_fem_solution(sol_S_VM_MAX_I);
1301  gest_visu->ajouter_fem_solution(sol_S_VM_MAX_F);
1302  gest_visu->ajouter_fem_solution(sol_S_VM_MAX_I_VEC);
1303  gest_visu->ajouter_fem_solution(sol_S_VM_MAX_F_VEC);
1304  gest_visu->ajouter_fem_solution(sol_arret_gradient);
1305  gest_visu->ajouter_fem_solution(sol_valeur_gradient);
1306  gest_visu->ajouter_fem_solution(sol_forme_initiale);
1307 
1308  if (film==1)
1309  gest_film->ajouter_fem_solution(sol_forme_initiale);
1310 
1311  //MG_GESTIONNAIRE* gest_visu=fem_visu->get_mg_maillage()->get_gestionnaire();
1312  //MGASTER mgaster;
1313 
1314  int affichage=0;
1315  int convergence=1;
1316  int iter_methode=1;
1317  int iter_finale=0;
1318  int fin=0;
1319  int nb_noeud_bloque_par_gradient=0;
1320  int nb_tri_3nd_fixe=0;
1321  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_3nd_fixe; // Tous les tris ayant 3 noeuds fixes
1322 
1323  double d_moy_initial=0.; //Enlever?
1324  double d_moy_precedent=0.; //Enlever?
1325 
1326  while (fin==0 && iter_methode<=iter_max)
1327  {
1328  if (((iter_vue!=0) && (iter_methode%iter_vue==0)) || (iter_methode==iter_max))
1329  affichage=1;
1330  else
1331  affichage=0;
1332 
1333  affiche((char*)"");
1334  sprintf(mess," Itération %d",iter_methode);
1335  affiche(mess);
1336  // ########## Génération d'une solution pour visualiser le déplacement des noeuds à toutes les iter_vue ##########
1337 
1338  char nomsolution[100];
1339  sprintf(nomsolution,"optimisation%d.sol",iter_methode);
1340  char nomlegende[100];
1341  sprintf(nomlegende,"Iteration%d",iter_methode);
1342  FEM_SOLUTION* sol_visu_depl;
1343  if ((iter_vue!=0) && (iter_methode%iter_vue==0))// || (iter_methode==iter_max))
1344  {
1345  sol_visu_depl=new FEM_SOLUTION(fem_visu,1,nomsolution,1,nomlegende,MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD,MAGIC::TYPE_SOLUTION::VECTEUR);
1346  sol_visu_depl->change_legende(0,"U");
1347  gest_visu->ajouter_fem_solution(sol_visu_depl);
1348 
1349  if (film==1)
1350  gest_film->ajouter_fem_solution(sol_visu_depl);
1351  }
1352 
1353  //###########################################################################################################################
1354  // Modélisation du calcul du replacement des noeuds sous forme d'un problème de minimisation d'une fonction f définie comme
1355  // la somme de la différence au carré entre la norme du gradient de déplacement de chaque triangle et la valeur seuil imposée
1356  //###########################################################################################################################
1357 
1358  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_2nd_fixe; // Liste de triangles ayant 2 noeud fixes
1359  TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud_tri_2nd_fixe; // Liste contenant tous les opt_noeud de ces triangles
1360  TPL_MAP_ENTITE<OPT_NOEUD*> lst_noeud_mobile_tri_2nd_fixe; // Noeuds mobiles des triangles ayant 2 noeuds fixes
1362 
1363  get_liste_tri_2nd_fixe(fem,lstnoeud_deplacer,&lst_tri_2nd_fixe);
1364  get_liste_noeud_a_partir_liste_tri(lst_tri_2nd_fixe,&lst_noeud_tri_2nd_fixe);
1365  get_liste_noeud_mobile_tri_2nd_fixe(lst_tri_2nd_fixe,lstnoeud_deplacer,&lst_noeud_mobile_tri_2nd_fixe);
1366 
1367  if (actualisation_normales==1)
1368  {
1369  // Actualisation des normales à la triangulation
1370  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1371  calcul_normale_opt_noeud(opt_noeud);
1372  }
1373 
1374  if (gradient==1)
1375  {
1376  // Calcul du jacobien inverse de chaque opt_triangle avant le déplacement des noeuds
1377  for (OPT_TRIANGLE* opt_tri=listetriangle.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=listetriangle.get_suivant(itopt_tri)) // À revoir (utiliser l'autre liste)
1378  {
1379  opt_tri->change_jacobien_inverse();
1380  opt_tri->change_matrice_abc();
1381  opt_tri->change_nb_noeuds_fixes_iter(0);
1382  //opt_tri->change_noeuds_fixes_3(0);
1383  }
1384  }
1385 
1386  // ########## Déplacement virtuel des noeuds ##########
1387 
1388  if (affichage==1)
1389  std::cout << " Déplacement virtuel des noeuds " << std::endl;
1390  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer.get_suivant(itopt_noeud))
1391  {
1392  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
1393  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1394  double d=c*(svm-s_objective)/s_objective; // Grandeur du déplacement
1395 
1396  // Cas Matlab (enlever)
1397  //if (opt_noeud->get_num()==1)
1398  //d=10;
1399  /*if (opt_noeud->get_num()==2)
1400  d=5;
1401  if (opt_noeud->get_num()==3)
1402  d=5;
1403  //if (opt_noeud->get_num()==4)
1404  //d=10;
1405  if (opt_noeud->get_num()==5)
1406  d=5;*/
1407  //if (opt_noeud->get_num()==6)
1408  //d=10;
1409 
1410  //double d_precedent=opt_noeud->get_sol_deplacement_virtuel(); // Erreur avec lissage car d_reel > d_virtuel
1411  double d_precedent=opt_noeud->get_norme_orientee_deplacement();
1412  change_deplacement_virtuel_opt_noeud(opt_noeud,d_precedent+d);
1413  if (opt_noeud->get_sol_deplacement_virtuel()<0)
1414  opt_noeud->change_sens_depl_virtuel(-1.);
1415  else
1416  opt_noeud->change_sens_depl_virtuel(1.);
1417  }
1418 
1419  // ########## Affichage du nombre de noeuds déplacés par le mouvement normal ##########
1420 
1421  int nb_noeud_deplace=0;
1422  nb_noeud_deplace=lstnoeud_deplacer.get_nb();
1423  if (affichage==1)
1424  std::cout << " " << nb_noeud_deplace << " noeuds déplacés par la méthode du mouvement normal" << std::endl;
1425  if (affichage==1)
1426  std::cout << " Nb de triangles ayant 2 noeuds fixes: " << lst_tri_2nd_fixe.get_nb() << std::endl;
1427 
1428  // ########## Contrôle de l'écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe ##########
1429 
1430  if (deplacement==1)
1431  {
1432  if (affichage==1)
1433  std::cout << " Contrôle de l'écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe " << std::endl;
1437 
1438  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_deplacer_temp;
1439  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer.get_suivant(itopt_noeud))
1440  lstnoeud_deplacer_temp.ajouter(opt_noeud);
1441 
1442  while (lstnoeud_deplacer_temp.get_nb()!=0) // Pas de for car on supprime des noeuds de la liste en la parcourant
1443  {
1444  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_voisin;
1445  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_voisin_fixe;
1446  OPT_NOEUD* opt_noeud=lstnoeud_deplacer_temp.get_premier(itopt_noeud);
1447  lstnoeud_voisin=opt_noeud->get_liste_noeud_voisin();
1448 
1449  double depl_initial_noeud=opt_noeud->get_sol_deplacement_virtuel();
1450  int signe_depl=1;
1451  if (depl_initial_noeud<0.)
1452  signe_depl=-1;
1453 
1454  for (OPT_NOEUD* opt_voisin=lstnoeud_voisin.get_premier(it2);opt_voisin!=NULL;opt_voisin=lstnoeud_voisin.get_suivant(it2))
1455  if (opt_voisin->get_mobile()==0)
1456  lstnoeud_voisin_fixe.ajouter(opt_voisin);
1457 
1458  for (OPT_NOEUD* opt_voisin_fixe=lstnoeud_voisin_fixe.get_premier(it3);opt_voisin_fixe!=NULL;opt_voisin_fixe=lstnoeud_voisin_fixe.get_suivant(it3))
1459  {
1460  double depl_voisin_fixe=opt_voisin_fixe->get_sol_deplacement_virtuel();
1461  double ecart_depl_initial=fabs(depl_initial_noeud-depl_voisin_fixe);
1462  if (ecart_depl_initial>ecart_max_depl)
1463  {
1464  int signe_repl=1;
1465  if (depl_initial_noeud<depl_voisin_fixe)
1466  signe_repl=-1;
1467 
1468  double ecart_depl=ecart_depl_initial;
1469  double ecart_depl_precedent=ecart_depl_initial;
1470  double d_precedent=opt_noeud->get_sol_deplacement_virtuel();
1471  int compteur=0;
1472  while ((ecart_depl>ecart_max_depl) && (compteur<100))
1473  {
1474  //if (compteur==99)
1475  //cout << " ATTENTION! 100 ITÉRATIONS DE REPLACEMENT EFFECTUÉES! " << endl;
1476  // Replacement du noeud de "facteur_repl*ecart_depl_initiale" en sens inverse à sa normale
1477  // S'assurer de replacer le noeud dans la bonne direction
1478  double d=opt_noeud->get_sol_deplacement_virtuel()-facteur_repl*ecart_depl_initial*signe_repl;
1479  if (d*depl_initial_noeud>0) // Pour éviter un changement de signe du replacement
1480  {
1482  double depl_noeud=opt_noeud->get_sol_deplacement_virtuel();
1483  ecart_depl=fabs(depl_noeud-depl_voisin_fixe);
1484 
1485  // On ne déplace pas le noeud s'il apporte une augmentation de l'écart de déplacement avec ses noeuds voisins
1486  if (ecart_depl>ecart_depl_precedent)
1487  change_deplacement_virtuel_opt_noeud(opt_noeud,d_precedent);
1488  ecart_depl_precedent=ecart_depl;
1489  }
1490  d_precedent=d;
1491  compteur++;
1492  }
1493  opt_noeud->change_mobile(0);
1494  lstnoeud_deplacer.supprimer(opt_noeud);
1495  }
1496  }
1497  lstnoeud_deplacer_temp.supprimer(opt_noeud);
1498  }
1499  }
1500  int num_repl=1;
1501  if (gradient==1)
1502  {
1503  // ########## Évaluation d'une fonction f à minimiser par l'algorithme du gradient ##########
1504 
1505  // À faire: mettre les commentaires dans la fonction f
1506  double f=evaluer_fonction_f(norme_max_grad,lst_tri_2nd_fixe,affichage);
1507  std::cout.setf(std::ios::fixed,std::ios::floatfield);
1508  std::cout.precision(6);
1509  //if (f<0.0000000000001)
1510  //cout << " Fonction f: " << f << " La norme max du gradient de déplacement n'est pas atteinte pour aucun triangle!!! " << endl;
1511 
1512  if (f>0.0000000000001) // Si la norme d'au moins 1 triangle dépasse la valeur seuil
1513  {
1514  //cout << " Fonction f: " << f << endl;
1515  //cout << " Nb de triangles ayant 2 noeuds fixes et un noeud mobile qui dépassent le gradient max: " << nb_tri_grad_depasse << endl;
1516  if (affichage==1)
1517  std::cout << " Évaluation du gradient de la fonction f " << std::endl; //Enlever
1518  evaluer_gradient_f(num_repl,norme_max_grad,lst_tri_2nd_fixe);
1519  double norme_grad_f=get_norme_gradient_f(num_repl,lst_noeud_mobile_tri_2nd_fixe);
1520  if (affichage==1)
1521  std::cout << " Norme du gradient de f: " << norme_grad_f << std::endl;
1522 
1523  if (norme_grad_f>epsilon)
1524  fin=algorithme_gradient(num_repl,norme_max_grad,pas,epsilon,iter_max_grad,lst_tri_2nd_fixe,lst_noeud_mobile_tri_2nd_fixe,affichage);
1525  fin=false; // À revoir!!!
1526 
1527  /*//###
1528  // ########## Affichage du nb de noeuds replacés par l'algo du gradient et le nb de triangles affectés ##########
1529 
1530  int nb_noeud_repl=0;
1531  for (OPT_NOEUD* opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_suivant(itopt_noeud))
1532  if (opt_noeud->get_num_replacement()==num_repl)
1533  nb_noeud_repl++;
1534  cout << " Nb de noeuds replacés par l'algorithme du gradient: " << nb_noeud_repl << endl;
1535 
1536  int nb_tri_repl=0;
1537  for (OPT_TRIANGLE* opt_tri=lst_tri_2nd_fixe.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_2nd_fixe.get_suivant(itopt_tri))
1538  {
1539  double repl_n1=opt_tri->get_noeud1()->get_num_replacement();
1540  double repl_n2=opt_tri->get_noeud2()->get_num_replacement();
1541  double repl_n3=opt_tri->get_noeud3()->get_num_replacement();
1542  if ((repl_n1==num_repl) || (repl_n2==num_repl) || (repl_n3==(num_repl)))
1543  nb_tri_repl++;
1544  }
1545  cout << " Nb de triangles à 2 noeuds fixes affectés: " << nb_tri_repl << endl;
1546  //cout << " Nb de triangles ayant 2 noeuds fixes: " << lst_tri_2nd_fixe.get_nb() << endl;
1547  //###*/
1548  }
1549  }
1550 
1551  // ########## Déplacement réel des noeuds ##########
1552 
1553  if (affichage==1)
1554  std::cout << " Déplacement réel des noeuds " << std::endl;
1555  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1556  {
1557  double d_virtuel=opt_noeud->get_sol_deplacement_virtuel();
1558  double d_actuel=opt_noeud->get_norme_orientee_deplacement();
1559  double d=d_virtuel-d_actuel;
1560 
1561  if (fabs(d)>0.0000000000001)
1562  deplace_opt_noeud(opt_noeud,d);
1563  }
1564 
1565  if (gradient==1)
1566  {
1567 
1568  //###
1569  // ########## Affichage du déplacement moyens des noeuds ########## (Arrêt méthode si d_moy < 0.01*d_moy_initial) À revoir
1570  // À vérifier!!!
1571 
1572  //Calcul du déplacement absolu moyen initial
1573  if (iter_methode==1)
1574  {
1575  int nb_noeud_deplace_initial=0;
1576  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1577  {
1578  d_moy_initial=d_moy_initial+fabs(opt_noeud->get_norme_orientee_deplacement());
1579  nb_noeud_deplace_initial++;
1580  d_moy_initial=d_moy_initial/nb_noeud_deplace_initial;
1581  }
1582  }
1583 
1584  double d_moy=0.;
1585  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer.get_suivant(itopt_noeud))
1586  d_moy=d_moy+fabs(opt_noeud->get_norme_orientee_deplacement());
1587 
1588  if (nb_noeud_deplace>0)
1589  d_moy=d_moy/nb_noeud_deplace;
1590  else
1591  d_moy=0;
1592 
1593  // Arrêt de la méthode dû à une variation du déplacement moyen trop faible (variation de moins de 0.01 %)
1594  //if (fabs(d_moy)<fabs(0.01*d_moy_initial))
1595  /*if ((fabs(d_moy-d_moy_precedent)/d_moy_initial)<0.0001)
1596  fin=4;*/
1597  if (affichage==1)
1598  std::cout << " Déplacement absolu moyen des noeuds pour cette itération: " << fabs(d_moy-d_moy_precedent) << std::endl;
1599  d_moy_precedent=d_moy;
1600  //###
1601 
1602  //###
1603  // ########## Affichage de la norme du gradient après déplacement réel ##########
1604 
1605  // Vérification de la norme du gradient de déplacement des triangles appartenant à ce noeud et possédant au moins un noeud fixe (enlever)
1606  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_depasse_grad_virtuel_apres;
1607  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_depasse_grad_reel_apres;
1608  //for (OPT_TRIANGLE* opt_tri=listetriangle.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=listetriangle.get_suivant(itopt_tri))
1609  for (OPT_TRIANGLE* opt_tri=lst_tri_2nd_fixe.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_2nd_fixe.get_suivant(itopt_tri))
1610  //for (OPT_TRIANGLE* opt_tri=lst_tri_voisin.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_voisin.get_suivant(itopt_tri))
1611  {
1612  OPT_NOEUD* n1=opt_tri->get_noeud1();
1613  OPT_NOEUD* n2=opt_tri->get_noeud2();
1614  OPT_NOEUD* n3=opt_tri->get_noeud3();
1615 
1616  if ((n1->get_num_replacement()==num_repl) || (n2->get_num_replacement()==num_repl) || (n3->get_num_replacement()==num_repl))
1617  {
1618  if (opt_tri->get_norme_gradient_deplacement_virtuel()>norme_max_grad)
1619  lst_tri_depasse_grad_virtuel_apres.ajouter(opt_tri);
1620 
1621  if (opt_tri->get_norme_gradient_deplacement_reel()>norme_max_grad)
1622  lst_tri_depasse_grad_reel_apres.ajouter(opt_tri);
1623  }
1624  }
1625 
1626  //###
1627  // ########## On vérifie si un noeud mobile n'a que des noeuds voisins fixes ##########
1628 
1629  // Si c'est le cas, on calcul le déplacement moyen de ses voisins et on déplace le noeud de d_moy-d_actuel
1630  if (affichage==1)
1631  std::cout << " Vérification si tous les noeuds voisins d'un noeud sont fixes " << std::endl;
1632 
1633  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_deplacer_temp;
1634  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer.get_suivant(itopt_noeud))
1635  lstnoeud_deplacer_temp.ajouter(opt_noeud);
1636 
1637  while (lstnoeud_deplacer_temp.get_nb()!=0) // Pas de for car on supprime des noeuds de la liste en la parcourant
1638  {
1639  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_voisin;
1640  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_voisin_fixe;
1641  OPT_NOEUD* opt_noeud=lstnoeud_deplacer_temp.get_premier(itopt_noeud);
1642  lstnoeud_voisin=opt_noeud->get_liste_noeud_voisin();
1643 
1644  for (OPT_NOEUD* opt=lstnoeud_voisin.get_premier(itopt_noeud);opt!=NULL;opt=lstnoeud_voisin.get_suivant(itopt_noeud))
1645  if (opt->get_mobile()==0)
1646  lstnoeud_voisin_fixe.ajouter(opt);
1647 
1648  double nb_noeud_voisin=lstnoeud_voisin.get_nb();
1649  double nb_noeud_voisin_fixe=lstnoeud_voisin_fixe.get_nb();
1650  if (nb_noeud_voisin_fixe==nb_noeud_voisin) // Tous les noeuds voisins sont fixes
1651  {
1652  if (affichage==1)
1653  {
1654  std::cout << " Noeud dont tous ses noeuds voisins sont fixes: " << opt_noeud->get_id() << std::endl;
1655  std::cout << " Nb de noeuds voisins: " << nb_noeud_voisin_fixe << std::endl;
1656  }
1657 
1658  // Calcul du déplacement moyen des noeuds voisins
1659  double somme_d=0.;
1660  double d_moy=0.;
1661  for (OPT_NOEUD* opt=lstnoeud_voisin_fixe.get_premier(itopt_noeud);opt!=NULL;opt=lstnoeud_voisin_fixe.get_suivant(itopt_noeud))
1662  {
1663  double d_noeud=opt->get_norme_orientee_deplacement();
1664  somme_d=somme_d+d_noeud;
1665  if (affichage==1)
1666  std::cout << " Noeud: " << opt->get_id() << " " << opt->get_num() << " " << d_noeud << std::endl; //Enlever
1667  }
1668  d_moy=somme_d/nb_noeud_voisin_fixe;
1669 
1670  double d_actuel=opt_noeud->get_norme_orientee_deplacement();
1671  deplace_opt_noeud(opt_noeud,d_moy-d_actuel);
1672  change_deplacement_virtuel_opt_noeud(opt_noeud,d_moy);
1673 
1674  //opt_noeud->change_mvt_normal(0);
1675  opt_noeud->change_mobile(0);
1676  lstnoeud_deplacer.supprimer(opt_noeud);
1677 
1678  if (affichage==1)
1679  {
1680  std::cout << " Déplacement initial: " << d_actuel << std::endl; //Enlever
1681  std::cout << " Déplacement final: " << d_moy << std::endl;
1682  }
1683  }
1684  lstnoeud_deplacer_temp.supprimer(opt_noeud);
1685  }
1686  //###
1687 
1688  //###
1689  // ########## MAJ de la propriété "change_mobile" des noeuds replacés par l'algorithme du gradient pour détecter les triangles qui ont 3 noeuds fixes ##########
1690 
1691  //for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1692  for (OPT_NOEUD* opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_suivant(itopt_noeud))
1693  if (opt_noeud->get_num_replacement()==num_repl)
1694  opt_noeud->change_mobile(0);
1695  //###
1696 
1697  //###
1698  // ########## Affichage de la norme du gradient des triangles qui viennent d'avoir 3 noeuds fixes ##########
1699 
1700  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_3nd_fixe_precedent; // Ceux qui avaient 3 noeuds fixes à l'itération précédente
1701  for (OPT_TRIANGLE* opt_tri=lst_tri_3nd_fixe.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_3nd_fixe.get_suivant(itopt_tri))
1702  lst_tri_3nd_fixe_precedent.ajouter(opt_tri);
1703 
1704  TPL_MAP_ENTITE<OPT_TRIANGLE*> lst_tri_3nd_fixe_iter; // Ceux qui viennent d'avoir 3 noeuds fixes
1705  //int nb_tri_3nd_fixe_iter=0;
1706  for (OPT_TRIANGLE* opt_tri=listetriangle.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=listetriangle.get_suivant(itopt_tri))
1707  {
1708  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
1709  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
1710  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
1711 
1712  int nb_noeuds_fixes=0;
1713  if (opt_n1->get_mobile()==0)
1714  nb_noeuds_fixes++;
1715  if (opt_n2->get_mobile()==0)
1716  nb_noeuds_fixes++;
1717  if (opt_n3->get_mobile()==0)
1718  nb_noeuds_fixes++;
1719  if (nb_noeuds_fixes==3)
1720  {
1721  lst_tri_3nd_fixe.ajouter(opt_tri);
1722  if (!lst_tri_3nd_fixe_precedent.existe(opt_tri))
1723  {
1724  lst_tri_3nd_fixe_iter.ajouter(opt_tri);
1725  //nb_tri_3nd_fixe_iter++;
1726  }
1727  }
1728  }
1729 
1730  // Vérification si le triangle a 2 noeuds qui viennent d'être fixés à cette itération
1731  /*for (OPT_TRIANGLE* opt_tri=lst_tri_3nd_fixe_iter.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_3nd_fixe_iter.get_suivant(itopt_tri))
1732  {
1733  if (opt_tri->get_norme_gradient_deplacement_reel()>norme_max_grad)
1734  {
1735  OPT_NOEUD* opt_n1=opt_tri->get_noeud1();
1736  OPT_NOEUD* opt_n2=opt_tri->get_noeud2();
1737  OPT_NOEUD* opt_n3=opt_tri->get_noeud3();
1738  if (((opt_n1->get_num_replacement()==num_repl) && (opt_n2->get_num_replacement()==num_repl)) || ((opt_n1->get_num_replacement()==num_repl) && (opt_n3->get_num_replacement()==num_repl)) || ((opt_n2->get_num_replacement()==num_repl) && (opt_n3->get_num_replacement()==num_repl)))
1739  {
1740  if (((iter_vue!=0) && (iter_methode%iter_vue==0)) || (iter_methode==iter_max))
1741  cout << "2nd N_réel_3nd_fixes: " << opt_tri->get_norme_gradient_deplacement_reel() << " Tri(id,num): " << opt_tri->get_id() << " " << opt_tri->get_num() << " Nd: " << opt_tri->get_noeud1()->get_id() << " " << opt_tri->get_noeud2()->get_id() << " " << opt_tri->get_noeud3()->get_id() << " Vec_réel: " << opt_tri->get_vecteur_deplacement_reel().get_x() << " " << opt_tri->get_vecteur_deplacement_reel().get_y() << " " << opt_tri->get_vecteur_deplacement_reel().get_z() << endl;
1742  }
1743  else
1744  if (((iter_vue!=0) && (iter_methode%iter_vue==0)) || (iter_methode==iter_max))
1745  cout << " N_réel_3nd_fixes: " << opt_tri->get_norme_gradient_deplacement_reel() << " Tri(id,num): " << opt_tri->get_id() << " " << opt_tri->get_num() << " Nd: " << opt_tri->get_noeud1()->get_id() << " " << opt_tri->get_noeud2()->get_id() << " " << opt_tri->get_noeud3()->get_id() << " Vec_réel: " << opt_tri->get_vecteur_deplacement_reel().get_x() << " " << opt_tri->get_vecteur_deplacement_reel().get_y() << " " << opt_tri->get_vecteur_deplacement_reel().get_z() << endl;
1746  }
1747  }*/
1748  //###
1749 
1750  //###
1751  // ########## MAJ des propriétés des noeuds replacés par l'algorithme du gradient ##########
1752 
1753  for (OPT_NOEUD* opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lst_noeud_mobile_tri_2nd_fixe.get_suivant(itopt_noeud))
1754  {
1755  if (opt_noeud->get_num_replacement()==num_repl)
1756  {
1757  //opt_noeud->change_mvt_normal(0);
1758  //opt_noeud->change_mobile(0);
1759  lstnoeud_deplacer.supprimer(opt_noeud);
1760  opt_noeud->change_arret_gradient(1); // Noeud fixé par le gradient
1761 
1762  //if (((iter_vue!=0) && (iter_methode%iter_vue==0)) || (iter_methode==iter_max))
1763  //cout << " Noeud(id,num) " << opt_noeud->get_id() << " " << opt_noeud->get_num() << " Fixé " << endl;
1764  }
1765  opt_noeud->change_num_replacement(0);
1766  }
1767  //###
1768 
1769  //###
1770  //########## Affichage des triangles qui ont 3 noeuds fixes ##########
1771 
1772  // Pour déterminer les triangles qui ont 3 noeuds fixes et qui avaient au moins 1 noeud mobile au départ
1773  int nb_tri_3nd_fixe_iter=0;
1774  for (OPT_TRIANGLE* opt_tri=lst_tri_3nd_fixe_iter.get_premier(itopt_tri);opt_tri!=NULL;opt_tri=lst_tri_3nd_fixe_iter.get_suivant(itopt_tri))
1775  {
1776  OPT_NOEUD* opt_noeud1=opt_tri->get_noeud1();
1777  OPT_NOEUD* opt_noeud2=opt_tri->get_noeud2();
1778  OPT_NOEUD* opt_noeud3=opt_tri->get_noeud3();
1779  if ((opt_noeud1->get_mobile_au_depart()==1) || (opt_noeud2->get_mobile_au_depart()==1) || (opt_noeud3->get_mobile_au_depart()==1))
1780  {
1781  // Noeud bloqué par gradient ou fixe au départ
1782  //if (((opt_noeud1->get_gradient()==1) || (opt_noeud1->get_mobile_au_depart()==0)) && ((opt_noeud2->get_gradient()==1) || (opt_noeud2->get_mobile_au_depart()==0)) && ((opt_noeud3->get_gradient()==1) || (opt_noeud3->get_mobile_au_depart()==0)))
1783  //{
1784  opt_tri->change_noeuds_fixes_3(1);
1785  sol_valeur_gradient->ecrire(opt_tri->get_norme_gradient_deplacement_reel(),opt_tri->get_num()-1,0,0);
1786  nb_tri_3nd_fixe_iter++;
1787  //}
1788  }
1789  }
1790 
1791  nb_tri_3nd_fixe=nb_tri_3nd_fixe+nb_tri_3nd_fixe_iter;
1792  if (affichage==1)
1793  {
1794  sprintf(mess," Au total, %d triangles ont maintenant 3 noeuds fixes",nb_tri_3nd_fixe);
1795  affiche(mess);
1796  }
1797 
1798  // Si tous les triangles ont 3 noeuds fixes (ne devrait pas être requis à revoir!!!)
1799  if (nb_tri_3nd_fixe==nb_tri_mobile_initial)
1800  {
1801  if (affichage==1)
1802  {
1803  sprintf(mess," Tous les triangles ont maintenant 3 noeuds fixes");
1804  affiche(mess);
1805  }
1806  fin=1;
1807  }
1808 
1809  // ########## MAJ solution "sol_arret_gradient" ##########
1810  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1811  {
1812  if (opt_noeud->get_arret_gradient()==1)
1813  sol_arret_gradient->ecrire(1.,opt_noeud->get_num()-1,0);
1814  if (opt_noeud->get_arret_gradient()==0)
1815  sol_arret_gradient->ecrire(0.,opt_noeud->get_num()-1,0);
1816  }
1817  //###
1818  // ########## Affichage du nb de noeud fixés par le gradient ##########
1819 
1820  int nb_noeud_fixe_par_gradient=0;
1821  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1822  if (opt_noeud->get_arret_gradient()==1)
1823  nb_noeud_fixe_par_gradient++;
1824 
1825  int nb_noeud_deplacer=lstnoeud_deplacer.get_nb(); //Enlever
1826  if (affichage==1)
1827  {
1828  sprintf(mess," Au total, %d noeuds ont été fixés par le gradient",nb_noeud_fixe_par_gradient);
1829  affiche(mess);
1830  sprintf(mess," %d noeuds ne sont pas fixes",nb_noeud_deplacer);
1831  affiche(mess);
1832  }
1833  } // fin if (gradient==1)
1834 
1835  // ########## Option de lissage des noeuds par barycentrage à chaque X itérations de la méthode ##########
1836 
1837  if ((lissage_iter!=0) && (iter_methode%lissage_iter==0))
1838  lissage(lstnoeud_deplacer_initiale);
1839 
1840  // ########## Option de lissage contrôlé des noeuds par barycentrage à chaque X itérations de la méthode ##########
1841 
1842  if ((lissage_controle_iter!=0) && (iter_methode%lissage_controle_iter==0))
1843  {
1844  lissage_controle(lstnoeud_deplacer_initiale,ecart_max_pondere_norme_pos);
1845 
1846  // Suppression des noeuds repalés de la liste de noeuds à déplacer
1847  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer.get_suivant(itopt_noeud))
1848  {
1849  if (opt_noeud->get_mobile()==0)
1850  lstnoeud_deplacer.supprimer(opt_noeud);
1851  }
1852  }
1853 
1854  // ########## MAJ solution "sol_visu_depl" après déplacement ##########
1855 
1856  if ((iter_vue!=0) && (iter_methode%iter_vue==0))// || (iter_methode==iter_max))
1857  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1858  ecriture_fem_solution_deplacement(sol_visu_depl,fem_noeud);
1859 
1860  // ########## Calcul de l'état de contrainte après déplacement ##########
1861 
1862  if (affichage==1)
1863  affiche((char*)" Calcul de l'état de contrainte final après déplacement");
1864  int codesortie=mgaster.calcule(fichierparamaster,fem,etude,MAGIC::CALCUL_ASTER::ELASTIQUE,coderesu,false); // Exportation vers Code_aster et calcul
1865  if (affichage==1)
1866  std::cout << " Code de sortie: " << codesortie << std::endl;
1867 
1868  // ########## MAJ des contraintes sur la zone de design après déplacement ##########
1869 
1870  double svm_min=1.e308;
1871  double svm_moy=0.;
1872  double svm_max=0.;
1873  double somme_svm=0.;
1874  int compteur_svm=0;
1875  double ecarttype=0;
1876 
1877  // ##### Calcul de svm_moy #####
1878  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1879  {
1880  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
1881  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1882  if (svm<svm_min) svm_min=svm;
1883  if (svm>svm_max) svm_max=svm;
1884  somme_svm=somme_svm+svm;
1885  compteur_svm++;
1886  }
1887  svm_moy=somme_svm/compteur_svm;
1888  ecarttype=get_ecart_type_sigma_vm(gest_visu,lstnoeud_deplacer_initiale,svm_moy,numsolinf,numsolmoy,numsolsup);
1889  if (contrainte_objective_moyenne==1)
1890  s_objective=svm_moy;
1891 
1892  // ##### MAJ solutions de visualisation des contraintes finales après déplacement #####
1893  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1894  {
1895  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
1896  double svm=get_sigma_vm_max(gest_visu,fem_noeud,0,1,2);
1897  int num=opt_noeud->get_num();
1898  sol_S_VM_MAX_F->ecrire(svm/1e06,num-1,0);
1899 
1900  // Affichage des contraintes de Von Mises maximales finales sous forme de normales à la triangulation
1901  OT_VECTEUR_3D normale_initiale=opt_noeud->get_normale_initiale();
1902  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(0),num-1,0,0);
1903  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(1),num-1,0,1);
1904  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(2),num-1,0,2);
1905  }
1906 
1907  // ########## Critères d'évaluation de la forme initiale ##########
1908  double dx_max=0.;
1909  double dy_max=0.;
1910  double dz_max=0.;
1911  double a_tot=0.;
1912  double k_s=0.;
1913  double a_d=0.;
1914  double svm_s=0.;
1915  double nb_nic=0;
1916  double nb_nnc=0.;
1917  double nb_noeud_design=0.;
1918  double pnnc=0.;
1919  double pnic=0.;
1920 
1921  // ##### Déplacement relatif maximal d'un noeud sous l'effet des efforts externes #####
1922  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
1923  {
1924  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
1925  int num=opt_noeud->get_num();
1926  double dx=gest_visu->get_fem_solution(0)->lire(num-1,0);
1927  if (fabs(dx)>fabs(dx_max))
1928  dx_max=dx;
1929  double dy=gest_visu->get_fem_solution(0)->lire(num-1,1);
1930  if (fabs(dy)>fabs(dy_max))
1931  dy_max=dy;
1932  double dz=gest_visu->get_fem_solution(0)->lire(num-1,2);
1933  if (fabs(dz)>fabs(dz_max))
1934  dz_max=dz;
1935  }
1936 
1937  // ##### Aire totale de la surface #####
1938  LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
1939  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
1940  {
1941  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
1942  double aire_tri=get_aire_fem_tri3(fem_tri3);
1943  a_tot=a_tot+aire_tri;
1944  }
1945 
1946  // ##### Aire de la zone de design #####
1947  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
1948  {
1949  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
1950 
1951  OPT_NOEUD* opt_n1=get_noeud(fem_tri3->get_fem_noeud(0));
1952  OPT_NOEUD* opt_n2=get_noeud(fem_tri3->get_fem_noeud(1));
1953  OPT_NOEUD* opt_n3=get_noeud(fem_tri3->get_fem_noeud(2));
1954 
1955  if ((lstnoeud_deplacer_initiale.existe(opt_n1)) || (lstnoeud_deplacer_initiale.existe(opt_n2)) || (lstnoeud_deplacer_initiale.existe(opt_n3)))
1956  {
1957  double aire_tri=get_aire_fem_tri3(fem_tri3);
1958  a_d=a_d+aire_tri;
1959  }
1960  }
1961 
1962  // ##### Pourcentage de noeuds dont la contrainte est située dans l'intervalle de convergence (% NIC) et pourcentage de noeuds non contraints (% NNC) #####
1963  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
1964  {
1965  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
1966  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1967  if (svm<svm_min) svm_min=svm;
1968  if (svm>svm_max) svm_max=svm;
1969  somme_svm=somme_svm+svm;
1970  compteur_svm++;
1971 
1972  double coef=fabs(svm-s_objective)/s_objective;
1973  if (coef<=limite)
1974  nb_nic++;
1975  else
1976  convergence=0;
1977  if (svm<0.1*svm_moy)
1978  nb_nnc++;
1979  nb_noeud_design++;
1980  }
1981  pnic=nb_nic/nb_noeud_design*100;
1982  pnnc=nb_nnc/nb_noeud_design*100;
1983 
1984  // ########## Vérification et affichage du type de convergence ##########
1985 
1986  if (convergence==1)
1987  {
1988  sprintf(mess," La méthode a convergée (convergence par la contrainte)");
1989  affiche(mess);
1990  fin=1;
1991  }
1992  if (lstnoeud_deplacer.get_nb()==0)
1993  {
1994  sprintf(mess," La méthode a convergée (listenoeud_deplacer est vide)");
1995  affiche(mess);
1996  fin=2;
1997  }
1998 
1999  /*if (fin==4) // À revoir
2000  {
2001  sprintf(mess," Arrêt de la méthode dû à une variation trop faible (< 0.01 %) du déplacement absolu moyen par rapport à l'itération précédente");
2002  affiche(mess);
2003  }*/
2004 
2005  // ########## Affichage des contraintes de Von Mises min, moy et max après déplacement ##########
2006 
2007  if ((affichage==1) || (fin!=0)) // Pour afficher les contraintes à la dernière itération si la méthode converge
2008  {
2009  sprintf(mess," Les contraintes min, moy et max valent: %.2lf MPa %.2lf MPa %.2lf MPa",svm_min/1e06,svm_moy/1e06,svm_max/1e06);
2010  affiche(mess);
2011  sprintf(mess," L'écart type est de: %.2lf MPa",ecarttype/1e06);
2012  affiche(mess);
2013  sprintf(mess," Les déplacements max selon X, Y et Z valent: %.2e m %.2e m %.2e m",dx_max,dy_max,dz_max);
2014  affiche(mess);
2015  sprintf(mess," L'aire totale vaut: %.4lf m²",a_tot/1e06);
2016  affiche(mess);
2017  sprintf(mess," L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
2018  affiche(mess);
2019  sprintf(mess," La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
2020  affiche(mess);
2021  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
2022  affiche(mess);
2023  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
2024  affiche(mess);
2025  }
2026 
2027  // ########## Enregistrement GMSH pour l'itération (pour avoir un aperçu avant la fin du calcul) ##########
2028 
2029  if (iter_vue!=0)
2030  if (iter_methode%iter_vue==0)
2031  {
2032  affiche((char*)" Génération du fichier .msh de l'itération");
2033  char iter[100];
2034  sprintf(iter,"%d",iter_methode);
2035  char etudeiter[100];
2036  strcpy(etudeiter,etudesortie);
2037  strcat(etudeiter,"_iter");
2038  strcat(etudeiter,iter);
2039  //exp.gmsh(fem_visu,etudeiter);
2040  /*if (film==1)
2041  exp.gmsh(fem_visu,etudefilm);*/
2042  }
2043 
2044  iter_finale=iter_methode; // Sauvegarde du numéro de la dernière itération
2045  iter_methode++;
2046  convergence=1; // À revoir!!!
2047  }
2048 
2049  // ########## Option de lissage des noeuds par barycentrage à la fin de la méthode ##########
2050 
2051  if (lissage_fin==1)
2052  {
2053  lissage(lstnoeud_deplacer_initiale);
2054 
2055  // ########## Calcul de l'état de contrainte après lissage ##########
2056 
2057  affiche((char*)" Calcul de l'état de contrainte après lissage final");
2058  int codesortie=mgaster.calcule(fichierparamaster,fem,etude,MAGIC::CALCUL_ASTER::ELASTIQUE,coderesu,false); // Exportation vers Code_aster et calcul
2059  std::cout << " Code de sortie: " << codesortie << std::endl;
2060 
2061  // ########## MAJ des contraintes sur la zone de design après lissage ##########
2062 
2063  double svm_min=1.e308;
2064  double svm_moy=0.;
2065  double svm_max=0.;
2066  double somme_svm=0.;
2067  int compteur_svm=0;
2068 
2069  // ##### Calcul de svm_moy #####
2070  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
2071  {
2072  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
2073  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
2074  if (svm<svm_min) svm_min=svm;
2075  if (svm>svm_max) svm_max=svm;
2076  somme_svm=somme_svm+svm;
2077  compteur_svm++;
2078  }
2079  svm_moy=somme_svm/compteur_svm;
2080  ecarttype=get_ecart_type_sigma_vm(gest_visu,lstnoeud_deplacer_initiale,svm_moy,numsolinf,numsolmoy,numsolsup);
2081  if (contrainte_objective_moyenne==1)
2082  s_objective=svm_moy;
2083 
2084  // ##### MAJ solutions de visualisation des contraintes finales après lissage #####
2085  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
2086  {
2087  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
2088  double svm=get_sigma_vm_max(gest_visu,fem_noeud,0,1,2);
2089  int num=opt_noeud->get_num();
2090  sol_S_VM_MAX_F->ecrire(svm/1e06,num-1,0);
2091 
2092  // Affichage des contraintes de Von Mises maximales finales sous forme de normales à la triangulation
2093  OT_VECTEUR_3D normale_initiale=opt_noeud->get_normale_initiale();
2094  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(0),num-1,0,0);
2095  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(1),num-1,0,1);
2096  sol_S_VM_MAX_F_VEC->ecrire(svm/1e06*normale_initiale(2),num-1,0,2);
2097  }
2098 
2099  // ########## Critères d'évaluation de la forme initiale ##########
2100  double dx_max=0.;
2101  double dy_max=0.;
2102  double dz_max=0.;
2103  double a_tot=0.;
2104  double k_s=0.;
2105  double a_d=0.;
2106  double svm_s=0.;
2107  double nb_nic=0.;
2108  double nb_nnc=0.;
2109  double nb_noeud_design=0.;
2110  double pnnc=0.;
2111  double pnic=0.;
2112 
2113  // ##### Déplacement relatif maximal d'un noeud sous l'effet des efforts externes #####
2114  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
2115  {
2116  OPT_NOEUD* opt_noeud=get_noeud(fem_noeud);
2117  int num=opt_noeud->get_num();
2118  double dx=gest_visu->get_fem_solution(0)->lire(num-1,0);
2119  if (fabs(dx)>fabs(dx_max))
2120  dx_max=dx;
2121  double dy=gest_visu->get_fem_solution(0)->lire(num-1,1);
2122  if (fabs(dy)>fabs(dy_max))
2123  dy_max=dy;
2124  double dz=gest_visu->get_fem_solution(0)->lire(num-1,2);
2125  if (fabs(dz)>fabs(dz_max))
2126  dz_max=dz;
2127  }
2128 
2129  // ##### Aire totale de la surface #####
2130  LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
2131  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
2132  {
2133  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
2134  double aire_tri=get_aire_fem_tri3(fem_tri3);
2135  a_tot=a_tot+aire_tri;
2136  }
2137 
2138  // ##### Aire de la zone de design #####
2139  for (FEM_ELEMENT2* fem_ele2=fem->get_premier_element2(it_fem_ele2);fem_ele2!=NULL;fem_ele2=fem->get_suivant_element2(it_fem_ele2))
2140  {
2141  FEM_TRIANGLE3* fem_tri3=(FEM_TRIANGLE3*)fem_ele2;
2142 
2143  OPT_NOEUD* opt_n1=get_noeud(fem_tri3->get_fem_noeud(0));
2144  OPT_NOEUD* opt_n2=get_noeud(fem_tri3->get_fem_noeud(1));
2145  OPT_NOEUD* opt_n3=get_noeud(fem_tri3->get_fem_noeud(2));
2146 
2147  if ((lstnoeud_deplacer_initiale.existe(opt_n1)) || (lstnoeud_deplacer_initiale.existe(opt_n2)) || (lstnoeud_deplacer_initiale.existe(opt_n3)))
2148  {
2149  double aire_tri=get_aire_fem_tri3(fem_tri3);
2150  a_d=a_d+aire_tri;
2151  }
2152  }
2153 
2154  // ##### Pourcentage de noeuds dont la contrainte est située dans l'intervalle de convergence (% NIC) et pourcentage de noeuds non contraints (% NNC) #####
2155  for (OPT_NOEUD* opt_noeud=lstnoeud_deplacer_initiale.get_premier(itopt_noeud);opt_noeud!=NULL;opt_noeud=lstnoeud_deplacer_initiale.get_suivant(itopt_noeud))
2156  {
2157  FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
2158  double svm=get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
2159  if (svm<svm_min) svm_min=svm;
2160  if (svm>svm_max) svm_max=svm;
2161  somme_svm=somme_svm+svm;
2162  compteur_svm++;
2163 
2164  double coef=fabs(svm-s_objective)/s_objective;
2165  if (coef<=limite)
2166  nb_nic++;
2167  if (svm<0.1*svm_moy)
2168  nb_nnc++;
2169  nb_noeud_design++;
2170  }
2171  pnic=nb_nic/nb_noeud_design*100;
2172  pnnc=nb_nnc/nb_noeud_design*100;
2173 
2174  // ########## Affichage des contraintes de Von Mises min, moy et max après lissage ##########
2175 
2176  sprintf(mess," Les contraintes min, moy et max après lissage final valent: %.2lf MPa %.2lf MPa %.2lf MPa",svm_min/1e06,svm_moy/1e06,svm_max/1e06);
2177  affiche(mess);
2178  sprintf(mess," L'écart type est de: %.2lf MPa",ecarttype/1e06);
2179  affiche(mess);
2180  sprintf(mess," Les déplacements max selon X, Y et Z valent: %.2e m %.2e m %.2e m",dx_max,dy_max,dz_max);
2181  affiche(mess);
2182  sprintf(mess," L'aire totale vaut: %.4lf m²",a_tot/1e06);
2183  affiche(mess);
2184  sprintf(mess," L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
2185  affiche(mess);
2186  sprintf(mess," La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
2187  affiche(mess);
2188  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
2189  affiche(mess);
2190  sprintf(mess," %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
2191  affiche(mess);
2192  }
2193 
2194  // ########## Génération d'une solution pour visualiser le déplacement final des noeuds ##########
2195 
2196  char nomsolution[100];
2197  sprintf(nomsolution,"optimisation%d.sol",iter_finale);
2198  char nomlegende[100];
2199  sprintf(nomlegende,"Iteration%d",iter_finale);
2201  sol_visu_depl->change_legende(0,"U");
2202  gest_visu->ajouter_fem_solution(sol_visu_depl);
2203  if (film==1)
2204  gest_film->ajouter_fem_solution(sol_visu_depl);
2205 
2206  // ########## MAJ solution de déplacement ##########
2207  for (FEM_NOEUD* fem_noeud=fem->get_premier_noeud(itfem_noeud);fem_noeud!=NULL;fem_noeud=fem->get_suivant_noeud(itfem_noeud))
2208  ecriture_fem_solution_deplacement(sol_visu_depl,fem_noeud);
2209 
2210  // Pour ne pas afficher les solutions de contraintes des 3 plans de calcul
2211  /*gest_visu->supprimer_fem_solution(0);
2212  gest_visu->supprimer_fem_solution(0);
2213  gest_visu->supprimer_fem_solution(0);*/
2214 
2215  sprintf(mess," Génération du fichier .msh final");
2216  affiche(mess);
2217  exp.gmsh(fem_visu,etudesortie);
2218  if (film==1)
2219  {
2220  exp.gmsh(fem_visu,etudefilm);
2221  gest_film->enregistrer(fichierfilm);
2222  }
2223 }
2224 
2225 
2226 /*void MGOPT_MVT_NORMAL::deplacement_normal(double dpl_max, double angle_min, int nbpas)
2227 {
2228  TPL_MAP_ENTITE<OPT_NOEUD*>::ITERATEUR it;
2229  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_deplacer;
2230  MG_SOLUTION* sol=new MG_SOLUTION(mai,1,(char*)&"deplacement.sol",mai->get_nb_mg_noeud(),"Deplacement",MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD);
2231  MG_GESTIONNAIRE *gest=mai->get_gestionnaire();
2232  gest->ajouter_mg_solution(sol);
2233 
2234  // Création de la liste de noeuds à déplacer
2235  for (OPT_NOEUD* noeud=listenoeud.get_premier(it);noeud!=NULL;noeud=listenoeud.get_suivant(it))
2236  {
2237  // Vérification des ccf
2238  double val;
2239  int ndok=((FEM_NOEUD*)noeud)->get_lien_topologie()->get_valeur_ccf((char*)&"Nd",val);
2240  if (ndok!=1) lstnoeud_deplacer.ajouter(noeud);
2241  }
2242 
2243  // Initialisation de la solution (enlever)
2244  //for (OPT_NOEUD* noeud=listenoeud.get_premier(it);noeud!=NULL;noeud=listenoeud.get_suivant(it))
2245  //{
2246  //noeud->change_solution(0.);
2247  //}
2248 
2249  // Calcul de la normale initiale
2250  for (OPT_NOEUD* noeud=lstnoeud_deplacer.get_premier(it);noeud!=NULL;noeud=lstnoeud_deplacer.get_suivant(it))
2251  {
2252  calcul_normale_opt_noeud(noeud);
2253  noeud->change_normale_initiale();
2254  }
2255 
2256  // Boucle sur le nombre de pas
2257  for (int i=0;i<nbpas;i++)
2258  {
2259  // Angle initial entre chaque triangle voisin
2260  TPL_MAP_ENTITE<OPT_TRIANGLE*>::ITERATEUR itopt;
2261  TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_supprimer;
2262  for (OPT_TRIANGLE* tri=listetriangle.get_premier(itopt);tri!=NULL;tri=listetriangle.get_suivant(itopt))
2263  {
2264  if (tri->get_voisin1()!=NULL)
2265  {
2266  // Le triangle est à déplacer si son voisin est fixe
2267  int ex1=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud1());
2268  int ex2=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud2());
2269  int ex3=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud3());
2270  if ((ex1==0) && (ex2==0) && (ex3==0))
2271  {
2272  double angle1=calcul_angle(tri,tri->get_voisin1());
2273  tri->change_angle1_initial(angle1);
2274  }
2275  }
2276  if (tri->get_voisin2()!=NULL)
2277  {
2278  // Le triangle est à déplacer si son voisin est fixe
2279  int ex1=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud1());
2280  int ex2=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud2());
2281  int ex3=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud3());
2282  if ((ex1==0) && (ex2==0) && (ex3==0))
2283  {
2284  double angle2=calcul_angle(tri,tri->get_voisin2());
2285  tri->change_angle2_initial(angle2);
2286  }
2287  }
2288  if (tri->get_voisin3()!=NULL)
2289  {
2290  // Le triangle est à déplacer si son voisin est fixe
2291  int ex1=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud1());
2292  int ex2=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud2());
2293  int ex3=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud3());
2294  if ((ex1==0) && (ex2==0) && (ex3==0))
2295  {
2296  double angle3=calcul_angle(tri,tri->get_voisin3());
2297  tri->change_angle3_initial(angle3);
2298  }
2299  }
2300  }
2301 
2302  // Déplacement des noeuds
2303  for (OPT_NOEUD* noeud=lstnoeud_deplacer.get_premier(it);noeud!=NULL;noeud=lstnoeud_deplacer.get_suivant(it))
2304  {
2305  double *xyz=noeud->get_coord();
2306  double xyz_modif[3];
2307  OT_VECTEUR_3D n_initiale=noeud->get_normale_initiale();
2308 
2309  xyz_modif[0]=xyz[0]+n_initiale[0]*dpl_max/nbpas;
2310  xyz_modif[1]=xyz[1]+n_initiale[1]*dpl_max/nbpas;
2311  xyz_modif[2]=xyz[2]+n_initiale[2]*dpl_max/nbpas;
2312 
2313  ((FEM_NOEUD*)noeud)->change_x(xyz_modif[0]);
2314  ((FEM_NOEUD*)noeud)->change_y(xyz_modif[1]);
2315  ((FEM_NOEUD*)noeud)->change_z(xyz_modif[2]);
2316  ((FEM_NOEUD*)noeud)->change_solution(((FEM_NOEUD*)noeud)->get_solution()+dpl_max/nbpas);
2317  }
2318 
2319  // On vérifie si l'angle entre deux triangles voisins à déplacer est inférieur à angle_min
2320  //TPL_MAP_ENTITE<OPT_TRIANGLE*>::ITERATEUR itopt;
2321  //TPL_MAP_ENTITE<OPT_NOEUD*> lstnoeud_supprimer;
2322  for (OPT_TRIANGLE* tri=listetriangle.get_premier(itopt);tri!=NULL;tri=listetriangle.get_suivant(itopt))
2323  {
2324  if (tri->get_voisin1()!=NULL)
2325  {
2326  // Le triangle est à déplacer si son voisin est fixe
2327  int ex1=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud1());
2328  int ex2=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud2());
2329  int ex3=lstnoeud_deplacer.existe(tri->get_voisin1()->get_noeud3());
2330  if ((ex1==0) && (ex2==0) && (ex3==0))
2331  {
2332  double angle1=calcul_angle(tri,tri->get_voisin1());
2333  tri->change_angle1(angle1);
2334  if ((angle1<angle_min) || (2*M_PI-angle1<angle_min))
2335  {
2336  lstnoeud_supprimer.ajouter(tri->get_noeud1());
2337  lstnoeud_supprimer.ajouter(tri->get_noeud2());
2338  lstnoeud_supprimer.ajouter(tri->get_noeud3());
2339 
2340  // Replacements des noeuds à la valeur limite d'angle
2341  double delta_angle1=tri->get_angle1_initial()-angle1;
2342  double delta_dpl=dpl_max/nbpas;
2343  }
2344  }
2345  }
2346  if (tri->get_voisin2()!=NULL)
2347  {
2348  int ex1=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud1());
2349  int ex2=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud2());
2350  int ex3=lstnoeud_deplacer.existe(tri->get_voisin2()->get_noeud3());
2351  if ((ex1==0) && (ex2==0) && (ex3==0))
2352  {
2353  double angle2=calcul_angle(tri,tri->get_voisin2());
2354  tri->change_angle2(angle2);
2355  if ((angle2<angle_min) || (2*M_PI-angle2<angle_min))
2356  {
2357  lstnoeud_supprimer.ajouter(tri->get_noeud1());
2358  lstnoeud_supprimer.ajouter(tri->get_noeud2());
2359  lstnoeud_supprimer.ajouter(tri->get_noeud3());
2360  }
2361  }
2362  }
2363  if (tri->get_voisin3()!=NULL)
2364  {
2365  int ex1=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud1());
2366  int ex2=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud2());
2367  int ex3=lstnoeud_deplacer.existe(tri->get_voisin3()->get_noeud3());
2368  if ((ex1==0) && (ex2==0) && (ex3==0))
2369  {
2370  double angle3=calcul_angle(tri,tri->get_voisin3());
2371  tri->change_angle3(angle3);
2372  if ((angle3<angle_min) || (2*M_PI-angle3<angle_min))
2373  {
2374  lstnoeud_supprimer.ajouter(tri->get_noeud1());
2375  lstnoeud_supprimer.ajouter(tri->get_noeud2());
2376  lstnoeud_supprimer.ajouter(tri->get_noeud3());
2377  }
2378  }
2379  }
2380  }
2381 
2382  // Suppression des noeuds pour la prochaine itération
2383  for (OPT_NOEUD* noeud=lstnoeud_supprimer.get_premier(it);noeud!=NULL;noeud=lstnoeud_supprimer.get_suivant(it))
2384  {
2385  lstnoeud_deplacer.supprimer(noeud);
2386  }
2387  }
2388 
2389  // Écriture de la solution
2390  int i=0;
2391  for (OPT_NOEUD* noeud=listenoeud.get_premier(it);noeud!=NULL;noeud=listenoeud.get_suivant(it))
2392  {
2393  sol->ecrire(i,0,((FEM_NOEUD*)noeud)->get_solution());
2394  i++;
2395  }
2396 }*/
2397 
2398 /*void MGOPT_MVT_NORMAL::visualisation(int facteur)
2399 {
2400  MG_MAILLAGE::DIMENSIONMAILLAGESANSTOPO=1;
2401 
2402  // Affichage de la normale
2403  TPL_MAP_ENTITE<OPT_NOEUD*>::ITERATEUR it;
2404  for (OPT_NOEUD* noeud=listenoeud.get_premier(it);noeud!=NULL;noeud=listenoeud.get_suivant(it))
2405  {
2406  calcul_normale_opt_noeud(noeud);
2407  OT_VECTEUR_3D n=noeud->get_normale();
2408  double coord[3];
2409  coord[0]=((FEM_NOEUD*)noeud)->get_x()+n[0]*facteur;
2410  coord[1]=((FEM_NOEUD*)noeud)->get_y()+n[1]*facteur;
2411  coord[2]=((FEM_NOEUD*)noeud)->get_z()+n[2]*facteur;
2412  MG_NOEUD* noeud1=new MG_NOEUD(NULL,((FEM_NOEUD*)noeud)->get_x(),((FEM_NOEUD*)noeud)->get_y(),((FEM_NOEUD*)noeud)->get_z(),TRIANGULATION);
2413  MG_NOEUD* noeud2=new MG_NOEUD(NULL,coord[0],coord[1],coord[2],TRIANGULATION);
2414  MG_SEGMENT* segment=new MG_SEGMENT(NULL,noeud1,noeud2,TRIANGULATION);
2415  mai->ajouter_mg_noeud(noeud1);
2416  mai->ajouter_mg_noeud(noeud2);
2417  mai->ajouter_mg_segment(segment);
2418  }
2419 }*/
MGOPT_MVT_NORMAL::params
OT_PARAMETRES params
Definition: mgopt_mvt_normal.h:112
TPL_MAP_ENTITE::supprimer
virtual void supprimer(X x)
Definition: tpl_map_entite.h:69
OPT_NOEUD::get_z_initial
virtual double get_z_initial(void)
Definition: opt_noeud.cpp:288
OPT_NOEUD::get_y
virtual double get_y(void)
Definition: opt_noeud.cpp:268
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_MVT_NORMAL::fem_tri3
std::ostream fem_tri3()
MGOPT_MVT_NORMAL::fem
class FEM_MAILLAGE * fem
Definition: mgopt_mvt_normal.h:105
TPL_MAP_ENTITE::get_premier
virtual X get_premier(ITERATEUR &it)
Definition: tpl_map_entite.h:112
MGOPT_MVT_NORMAL::calcul_normale_opt_noeud
virtual void calcul_normale_opt_noeud(class OPT_NOEUD *noeud)
Definition: mgopt_mvt_normal.cpp:236
MGASTER::calcule
virtual int calcule(char *nomfichierparam, class FEM_MAILLAGE *fem, char *nometude, int typeetude, char *code=NULL, bool avecenreg=true)
Definition: mgaster.cpp:62
opt_noeud.h
FEM_SOLUTION
Definition: fem_solution.h:40
MAGIC::ENTITE_SOLUTION::ENTITE_ELEMENT2
@ ENTITE_ELEMENT2
Definition: mg_definition.h:86
OPT_NOEUD::get_id
virtual unsigned long get_id(void)
Definition: opt_noeud.cpp:258
OPT_NOEUD::get_x_initial
virtual double get_x_initial(void)
Definition: opt_noeud.cpp:278
tpl_fonctions_generiques.h
MGOPT_MVT_NORMAL::get_sigma_vm_max
virtual double get_sigma_vm_max(MG_GESTIONNAIRE *gest, FEM_NOEUD *fem_noeud, int num_sol_inf, int num_sol_moy, int num_sol_sup)
Definition: mgopt_mvt_normal.cpp:275
MGOPT_MVT_NORMAL::MGOPT_MVT_NORMAL
MGOPT_MVT_NORMAL()
Definition: mgopt_mvt_normal.cpp:37
OPT_NOEUD::get_x
virtual double get_x(void)
Definition: opt_noeud.cpp:263
MGOPT_MVT_NORMAL::evaluer_fonction_f
virtual double evaluer_fonction_f(double norme_max_grad, TPL_MAP_ENTITE< OPT_TRIANGLE * > lst_tri, int affichage)
Definition: mgopt_mvt_normal.cpp:450
fct_generateur_calibrage.h
OPT_NOEUD::get_y_initial
virtual double get_y_initial(void)
Definition: opt_noeud.cpp:283
MGOPT_MVT_NORMAL::lire_params
virtual void lire_params(char *fichier)
Definition: mgopt_mvt_normal.cpp:166
MGOPT_MVT_NORMAL::listenoeud
TPL_MAP_ENTITE< class OPT_NOEUD * > listenoeud
Definition: mgopt_mvt_normal.h:59
MGOPT_MVT_NORMAL::get_liste_noeud_mobile_tri_2nd_fixe
virtual void get_liste_noeud_mobile_tri_2nd_fixe(TPL_MAP_ENTITE< OPT_TRIANGLE * > lst_tri_2nd_fixe, TPL_MAP_ENTITE< OPT_NOEUD * > lstnoeud_deplacer, TPL_MAP_ENTITE< OPT_NOEUD * > *lst_noeud_mobile_tri_2nd_fixe)
Definition: mgopt_mvt_normal.cpp:408
TPL_MAP_ENTITE
Definition: tpl_map_entite.h:35
OT_PARAMETRES::get_valeur
double get_valeur(std::string chaine, int num=0)
Definition: ot_parametres.cpp:191
mg_gestionnaire.h
OPT_NOEUD::get_fem_noeud
virtual FEM_NOEUD * get_fem_noeud(void)
Definition: opt_noeud.cpp:63
MGOPT_MVT_NORMAL::get_liste_noeud_a_partir_liste_tri
virtual void get_liste_noeud_a_partir_liste_tri(TPL_MAP_ENTITE< OPT_TRIANGLE * > lst_tri, TPL_MAP_ENTITE< OPT_NOEUD * > *lst_noeud)
Definition: mgopt_mvt_normal.cpp:392
mgopt_mvt_normal.h
MG_NOEUD::get_lien_triangle
TPL_LISTE_ENTITE< class MG_TRIANGLE * > * get_lien_triangle(void)
Definition: mg_noeud.cpp:153
OPT_TRIANGLE::get_noeud2
virtual class OPT_NOEUD * get_noeud2(void)
Definition: opt_triangle.cpp:260
MAGIC::TYPE_SOLUTION::VECTEUR
@ VECTEUR
Definition: mg_definition.h:93
MG_IDENTIFICATEUR::get_id
unsigned long get_id()
Definition: mg_identificateur.cpp:53
MGOPT_MVT_NORMAL::init_parametre
virtual void init_parametre(void)
Definition: mgopt_mvt_normal.cpp:119
OPT_NOEUD::change_num
virtual void change_num(int val)
Definition: opt_noeud.cpp:73
MGOPT_MVT_NORMAL::affiche
void(* affiche)(char *mess)
Definition: mgopt_mvt_normal.h:110
FEM_TRIANGLE3
Definition: fem_triangle3.h:34
OPT_NOEUD::get_coord
virtual double * get_coord(void)
Definition: opt_noeud.cpp:293
FEM_SOLUTION::ecrire
void ecrire(double val, int i, int j, int coord=0, int num_no=0)
Definition: fem_solution.cpp:411
robustPredicates::epsilon
static REAL epsilon
Definition: robustpredicates.cc:371
OPT_NOEUD::change_num_replacement
virtual void change_num_replacement(int num)
Definition: opt_noeud.cpp:162
OT_PARAMETRES::STRING
@ STRING
Definition: ot_parametres.h:38
MGOPT_MVT_NORMAL::ecrire_fichier_params
virtual void ecrire_fichier_params(char *fichierparam)
Definition: mgopt_mvt_normal.cpp:160
OT_PARAMETRES::ajouter
void ajouter(std::string chaine, double valeur, int typep, std::string aide="")
Definition: ot_parametres.cpp:61
FEM_ELEMENT_MAILLAGE::get_lien_topologie
virtual class MG_ELEMENT_TOPOLOGIQUE * get_lien_topologie(void)
Definition: fem_element_maillage.cpp:89
OPT_NOEUD::change_liste_noeud_voisin
virtual void change_liste_noeud_voisin(TPL_MAP_ENTITE< class OPT_NOEUD * > lst)
Definition: opt_noeud.cpp:233
mg_file.h
OPT_TRIANGLE::change_num
virtual void change_num(int val)
Definition: opt_triangle.cpp:275
OPT_NOEUD
Definition: opt_noeud.h:31
FEM_MAILLAGE::get_premier_noeud
FEM_NOEUD * get_premier_noeud(LISTE_FEM_NOEUD::iterator &it)
Definition: fem_maillage.cpp:174
OPT_NOEUD::change_x
virtual void change_x(double xx)
Definition: opt_noeud.cpp:344
FEM_MAILLAGE::get_mg_geometrie
MG_GEOMETRIE * get_mg_geometrie(void)
Definition: fem_maillage.cpp:88
OPT_NOEUD::get_sol_deplacement_virtuel
virtual double get_sol_deplacement_virtuel(void)
Definition: opt_noeud.cpp:177
OPT_NOEUD::get_normale
virtual OT_VECTEUR_3D get_normale(void)
Definition: opt_noeud.cpp:320
TPL_MAP_ENTITE::existe
virtual int existe(X x)
Definition: tpl_map_entite.h:61
MG_COFACE::get_orientation
virtual int get_orientation(void)
Definition: mg_coface.cpp:69
MGOPT_MVT_NORMAL::correspondance_noeud
std::map< unsigned long, std::pair< class OPT_NOEUD *, class FEM_NOEUD * > > correspondance_noeud
Definition: mgopt_mvt_normal.h:61
MG_TRIANGLE
Definition: mg_triangle.h:38
MG_GESTIONNAIRE
Definition: mg_gestionnaire.h:57
MG_GESTIONNAIRE::ajouter_fem_solution
int ajouter_fem_solution(FEM_SOLUTION *mgsol)
Definition: mg_gestionnaire.cpp:902
OPT_TRIANGLE::change_norme_gradient_deplacement_virtuel
virtual void change_norme_gradient_deplacement_virtuel(void)
Definition: opt_triangle.cpp:181
MGOPT_MVT_NORMAL
Definition: mgopt_mvt_normal.h:38
FEM_ELEMENT2
Definition: fem_element2.h:34
FEM_MAILLAGE::get_mg_maillage
MG_MAILLAGE * get_mg_maillage(void)
Definition: fem_maillage.cpp:93
MGOPT_MVT_NORMAL::listetriangle
TPL_MAP_ENTITE< class OPT_TRIANGLE * > listetriangle
Definition: mgopt_mvt_normal.h:100
MG_GESTIONNAIRE::get_fem_solution
FEM_SOLUTION * get_fem_solution(unsigned int num)
Definition: mg_gestionnaire.cpp:930
MGOPT_MVT_NORMAL::get_ecart_type_sigma_vm
virtual double get_ecart_type_sigma_vm(MG_GESTIONNAIRE *gest, TPL_MAP_ENTITE< OPT_NOEUD * > lstnoeud, double moyenne, int numsolinf, int numsolmoy, int numsolsup)
Definition: mgopt_mvt_normal.cpp:294
FEM_MAILLAGE::get_premier_element2
FEM_ELEMENT2 * get_premier_element2(LISTE_FEM_ELEMENT2::iterator &it)
Definition: fem_maillage.cpp:561
OPT_NOEUD::change_terme_gradient_f
virtual void change_terme_gradient_f(double valeur)
Definition: opt_noeud.cpp:172
MGOPT_MVT_NORMAL::change_liste_noeud_voisin
virtual void change_liste_noeud_voisin(OPT_NOEUD *opt_noeud)
Definition: mgopt_mvt_normal.cpp:186
opt_triangle.h
MGASTER
Definition: mgaster.h:29
MGOPT_MVT_NORMAL::change_deplacement_virtuel_opt_noeud
virtual void change_deplacement_virtuel_opt_noeud(OPT_NOEUD *opt_noeud, double d)
Definition: mgopt_mvt_normal.cpp:311
OPT_TRIANGLE::change_vecteur_sol_deplacement_virtuel
virtual void change_vecteur_sol_deplacement_virtuel(void)
Definition: opt_triangle.cpp:151
OPT_TRIANGLE::change_norme_gradient_deplacement_reel
virtual void change_norme_gradient_deplacement_reel(void)
Definition: opt_triangle.cpp:170
MGOPT_MVT_NORMAL::active_affichage
virtual void active_affichage(void(*fonc)(char *))
Definition: mgopt_mvt_normal.cpp:113
MGOPT_MVT_NORMAL::lissage
virtual void lissage(TPL_MAP_ENTITE< OPT_NOEUD * > lst_noeud)
Definition: mgopt_mvt_normal.cpp:810
mgaster.h
OPT_TRIANGLE
Definition: opt_triangle.h:35
FEM_NOEUD::get_lien_element2
TPL_LISTE_ENTITE< class FEM_ELEMENT2 * > * get_lien_element2(void)
Definition: fem_noeud.cpp:406
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
mg_export.h
MGOPT_MVT_NORMAL::get_noeud
class OPT_NOEUD * get_noeud(class FEM_NOEUD *fem_noeud)
Definition: mgopt_mvt_normal.cpp:101
FEM_MAILLAGE
Definition: fem_maillage.h:66
OT_PARAMETRES::DOUBLE
@ DOUBLE
Definition: ot_parametres.h:38
MG_FACE::get_mg_coface
virtual MG_COFACE * get_mg_coface(int num)
Definition: mg_face.cpp:104
TPL_MAP_ENTITE::get_nb
virtual int get_nb(void)
Definition: tpl_map_entite.h:83
MG_EXPORT::gmsh
void gmsh(class MG_MAILLAGE *mai, std::string fichier)
Definition: mg_export.cpp:803
MG_NOEUD
Definition: mg_noeud.h:41
MGOPT_MVT_NORMAL::~MGOPT_MVT_NORMAL
~MGOPT_MVT_NORMAL()
Definition: mgopt_mvt_normal.cpp:90
OT_MATRICE_3D
Definition: ot_mathematique.h:160
OPT_NOEUD::change_mobile
virtual void change_mobile(int mob)
Definition: opt_noeud.cpp:132
FEM_ELEMENT_MAILLAGE::get_mg_element_maillage
virtual class MG_ELEMENT_MAILLAGE * get_mg_element_maillage(void)
Definition: fem_element_maillage.cpp:81
OPT_NOEUD::get_normale_initiale
virtual OT_VECTEUR_3D get_normale_initiale(void)
Definition: opt_noeud.cpp:334
MGOPT_MVT_NORMAL::orientation
int orientation
Definition: mgopt_mvt_normal.h:108
MGOPT_MVT_NORMAL::get_liste_noeud_deplacer_initiale
virtual void get_liste_noeud_deplacer_initiale(TPL_MAP_ENTITE< OPT_NOEUD * > listenoeud, TPL_MAP_ENTITE< OPT_NOEUD * > *lstnoeud_deplacer_initiale)
Definition: mgopt_mvt_normal.cpp:172
TPL_MAP_ENTITE::ITERATEUR
std::map< unsigned long, X, std::less< unsigned long > >::iterator ITERATEUR
Definition: tpl_map_entite.h:38
TPL_LISTE_ENTITE::get_nb
virtual int get_nb(void)
Definition: tpl_liste_entite.h:67
MGOPT_MVT_NORMAL::deplace_opt_noeud
virtual void deplace_opt_noeud(OPT_NOEUD *opt_noeud, double d)
Definition: mgopt_mvt_normal.cpp:327
OT_VECTEUR_3D::norme
virtual void norme(void)
Definition: ot_mathematique.cpp:494
FEM_MAILLAGE::get_suivant_element2
FEM_ELEMENT2 * get_suivant_element2(LISTE_FEM_ELEMENT2::iterator &it)
Definition: fem_maillage.cpp:569
FEM_SOLUTION::lire
double lire(int i, int j, int coord=0, int num_no=0)
Definition: fem_solution.cpp:398
MG_GEOMETRIE::get_mg_face
MG_FACE * get_mg_face(unsigned int num)
Definition: mg_geometrie.cpp:1251
TPL_LISTE_ENTITE::get
virtual X get(int num)
Definition: tpl_liste_entite.h:72
OPT_NOEUD::get_num_replacement
virtual int get_num_replacement(void)
Definition: opt_noeud.cpp:157
mg_import.h
MGOPT_MVT_NORMAL::geo
class MG_GEOMETRIE * geo
Definition: mgopt_mvt_normal.h:107
FEM_NOEUD
Definition: fem_noeud.h:35
OPT_NOEUD::get_norme_orientee_deplacement
virtual double get_norme_orientee_deplacement(void)
Definition: opt_noeud.cpp:298
MGOPT_MVT_NORMAL::algorithme_gradient
virtual int algorithme_gradient(int num_repl, double norme_max_grad, double pas, double epsilon, int iter_max_grad, TPL_MAP_ENTITE< OPT_TRIANGLE * > lst_tri, TPL_MAP_ENTITE< OPT_NOEUD * > lst_noeud, int affichage)
Definition: mgopt_mvt_normal.cpp:607
OPT_NOEUD::get_mobile
virtual int get_mobile(void)
Definition: opt_noeud.cpp:127
OT_PARAMETRES::enregistrer
void enregistrer(char *nom)
Definition: ot_parametres.cpp:132
OPT_NOEUD::change_norme_orientee_deplacement
virtual void change_norme_orientee_deplacement(void)
Definition: opt_noeud.cpp:303
MGOPT_MVT_NORMAL::lissage_controle
virtual void lissage_controle(TPL_MAP_ENTITE< OPT_NOEUD * > lst_noeud, double ecart_max_pondere_norme_pos)
Definition: mgopt_mvt_normal.cpp:861
OT_VECTEUR_3D
Definition: ot_mathematique.h:94
TPL_MAP_ENTITE::ajouter
virtual void ajouter(X x)
Definition: tpl_map_entite.h:55
MGOPT_MVT_NORMAL::nb_tri_grad_depasse
int nb_tri_grad_depasse
Definition: mgopt_mvt_normal.h:116
OPT_TRIANGLE::change_vecteur_deplacement_reel
virtual void change_vecteur_deplacement_reel(void)
Definition: opt_triangle.cpp:132
OPT_NOEUD::get_terme_gradient_f
virtual double get_terme_gradient_f(void)
Definition: opt_noeud.cpp:167
MGOPT_MVT_NORMAL::ecriture_fem_solution_deplacement
virtual void ecriture_fem_solution_deplacement(FEM_SOLUTION *sol, FEM_NOEUD *fem_noeud)
Definition: mgopt_mvt_normal.cpp:357
MAGIC::CALCUL_ASTER::ELASTIQUE
@ ELASTIQUE
Definition: mg_definition.h:134
OPT_TRIANGLE::get_noeud1
virtual class OPT_NOEUD * get_noeud1(void)
Definition: opt_triangle.cpp:255
MGOPT_MVT_NORMAL::correspondance_triangle
std::map< unsigned long, std::pair< class OPT_TRIANGLE *, class FEM_TRIANGLE3 * > > correspondance_triangle
Definition: mgopt_mvt_normal.h:102
OPT_NOEUD::change_z
virtual void change_z(double zz)
Definition: opt_noeud.cpp:354
OPT_NOEUD::change_y
virtual void change_y(double yy)
Definition: opt_noeud.cpp:349
MGOPT_MVT_NORMAL::get_aire_fem_tri3
virtual double get_aire_fem_tri3(FEM_TRIANGLE3 *fem_tri)
Definition: mgopt_mvt_normal.cpp:221
sqrt
double2 sqrt(double2 &val)
Definition: ot_doubleprecision.cpp:345
OT_PARAMETRES::vide
void vide(void)
Definition: ot_parametres.cpp:317
ot_systeme.h
MG_MAILLAGE::get_gestionnaire
MG_GESTIONNAIRE * get_gestionnaire(void)
Definition: mg_maillage.cpp:2658
OPT_NOEUD::get_liste_noeud_voisin
virtual TPL_MAP_ENTITE< class OPT_NOEUD * > get_liste_noeud_voisin(void)
Definition: opt_noeud.cpp:228
MGOPT_MVT_NORMAL::optimisation
virtual void optimisation(char *fichierin, char *fichierout, char *fichierparam, char *fichierparamaster)
Definition: mgopt_mvt_normal.cpp:918
MG_ELEMENT_MAILLAGE::get_lien_topologie
MG_ELEMENT_TOPOLOGIQUE * get_lien_topologie(void)
Definition: mg_element_maillage.cpp:51
mg_geometrie_outils.h
MGASTER::active_affichage
virtual void active_affichage(void(*fonc)(char *))
Definition: mgaster.cpp:56
OPT_NOEUD::get_num
virtual int get_num(void)
Definition: opt_noeud.cpp:68
OT_PARAMETRES::lire
int lire(char *nom)
Definition: ot_parametres.cpp:144
OPT_NOEUD::get_mobile_au_depart
virtual int get_mobile_au_depart(void)
Definition: opt_noeud.cpp:117
OPT_NOEUD::get_z
virtual double get_z(void)
Definition: opt_noeud.cpp:273
OT_VECTEUR_3D::get_longueur
virtual double get_longueur(void) const
Definition: ot_mathematique.cpp:483
FEM_MAILLAGE::get_suivant_noeud
FEM_NOEUD * get_suivant_noeud(LISTE_FEM_NOEUD::iterator &it)
Definition: fem_maillage.cpp:182
OPT_NOEUD::change_sol_deplacement_virtuel
virtual void change_sol_deplacement_virtuel(double deplacement)
Definition: opt_noeud.cpp:182
OPT_NOEUD::change_normale
virtual void change_normale(OT_VECTEUR_3D vec)
Definition: opt_noeud.cpp:315
MGOPT_MVT_NORMAL::fem_visu
class FEM_MAILLAGE * fem_visu
Definition: mgopt_mvt_normal.h:106
OPT_TRIANGLE::get_noeud3
virtual class OPT_NOEUD * get_noeud3(void)
Definition: opt_triangle.cpp:265
MG_FACE
Definition: mg_face.h:34
MGOPT_MVT_NORMAL::etude
char etude[500]
Definition: mgopt_mvt_normal.h:113
MAGIC::TYPE_SOLUTION::SCALAIRE
@ SCALAIRE
Definition: mg_definition.h:93
MGOPT_MVT_NORMAL::get_triangle
class OPT_TRIANGLE * get_triangle(class FEM_TRIANGLE3 *fem_tri3)
Definition: mgopt_mvt_normal.cpp:107
TPL_MAP_ENTITE::get_suivant
virtual X get_suivant(ITERATEUR &it)
Definition: tpl_map_entite.h:120
FEM_SOLUTION::change_legende
void change_legende(int num, std::string val)
Definition: fem_solution.cpp:457
MGOPT_MVT_NORMAL::evaluer_gradient_f
virtual void evaluer_gradient_f(int num_repl, double norme_max_grad, TPL_MAP_ENTITE< OPT_TRIANGLE * > lst_tri)
Definition: mgopt_mvt_normal.cpp:517
MGOPT_MVT_NORMAL::etudesortie
char etudesortie[500]
Definition: mgopt_mvt_normal.h:114
MGOPT_MVT_NORMAL::get_norme_gradient_f
virtual double get_norme_gradient_f(int num_repl, TPL_MAP_ENTITE< OPT_NOEUD * > lst_noeud)
Definition: mgopt_mvt_normal.cpp:589
MGOPT_MVT_NORMAL::affichageactif
int affichageactif
Definition: mgopt_mvt_normal.h:111
MGOPT_MVT_NORMAL::get_liste_tri_2nd_fixe
virtual void get_liste_tri_2nd_fixe(FEM_MAILLAGE *fem, TPL_MAP_ENTITE< OPT_NOEUD * > lstnoeud_deplacer, TPL_MAP_ENTITE< class OPT_TRIANGLE * > *lst_tri_2nd_fixe)
Definition: mgopt_mvt_normal.cpp:373
MAGIC::ENTITE_SOLUTION::ENTITE_NOEUD
@ ENTITE_NOEUD
Definition: mg_definition.h:86