46 LISTE_FEM_NOEUD::iterator it_fem_noeud;
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);
60 LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
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);
104 return ((*it).second).first;
110 return ((*it).second).first;
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)");
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)");
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)");
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)");
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");
179 FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
182 lstnoeud_deplacer_initiale->
ajouter(opt_noeud);
191 for (
int i=0;i<nb_fem_ele2;i++)
203 lst_noeud_voisin.
ajouter(opt_n2);
204 lst_noeud_voisin.
ajouter(opt_n3);
208 lst_noeud_voisin.
ajouter(opt_n1);
209 lst_noeud_voisin.
ajouter(opt_n3);
213 lst_noeud_voisin.
ajouter(opt_n1);
214 lst_noeud_voisin.
ajouter(opt_n2);
240 double norme_w_n_tot=0.;
242 double norme_w2_n_tot=0.;
245 for (
int i=0;i<nbtri;i++)
262 norme_w_n_tot=norme_w_n_tot+norme_w_n;
285 if ((svm1>=svm2) && (svm1>=svm3))
287 if ((svm2>=svm1) && (svm2>=svm3))
289 if ((svm3>=svm1) && (svm3>=svm2))
298 double somme_ecart_au_carre=0.;
302 FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
304 somme_ecart_au_carre=somme_ecart_au_carre+((svm-moyenne)*(svm-moyenne));
307 ecarttype=
sqrt((1./compteur_svm)*somme_ecart_au_carre);
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++)
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];
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++)
367 sol->
ecrire(dx,num-1,0,0);
368 sol->
ecrire(dy,num-1,0,1);
369 sol->
ecrire(dz,num-1,0,2);
376 (*lst_tri_2nd_fixe).vide();
377 LISTE_FEM_ELEMENT2::iterator itfem_ele2;
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);
402 (*lst_noeud).ajouter(opt_n1);
403 (*lst_noeud).ajouter(opt_n2);
404 (*lst_noeud).ajouter(opt_n3);
411 (*lst_noeud_mobile_tri_2nd_fixe).vide();
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);
453 std::cout <<
" Évaluation de la fonction f " << std::endl;
472 double norme_grad_depl=opt_tri->get_norme_gradient_deplacement_virtuel();
473 if (norme_grad_depl>seuil)
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);
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);
503 if (
f<0.0000000000001)
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)
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;
524 opt_noeud->change_terme_gradient_f(0.);
549 double norme_virtuelle=opt_tri->get_norme_gradient_deplacement_virtuel();
550 double norme_relle=opt_tri->get_norme_gradient_deplacement_reel();
551 if ((norme_virtuelle>norme_max_grad))
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);
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);
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);
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);
591 double somme_termes_carre=0.;
597 if (opt_noeud->get_num_replacement()==num_repl)
599 double terme=opt_noeud->get_terme_gradient_f();
600 somme_termes_carre=somme_termes_carre+terme*terme;
603 double norme_grad_f=
sqrt(somme_termes_carre);
610 std::cout <<
" Minimisation de la fonction f par l'algorithme du gradient " << std::endl;
613 double norme_grad_f_precedente= 1000000000000;
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;
631 opt_noeud->change_depl_avant_algo_grad(opt_noeud->get_sol_deplacement_virtuel());
635 while ((norme_grad_f>
epsilon) && (nb_iter_algo<iter_max_grad) && (fin==
false))
640 if ((opt_noeud->get_num_replacement()==num_repl))
646 double terme_gradient=opt_noeud->get_terme_gradient_f();
647 double d_precedent=opt_noeud->get_sol_deplacement_virtuel();
652 double d_avant_algo=opt_noeud->get_depl_avant_algo_grad();
655 double sens=opt_noeud->get_sens_depl_virtuel();
658 double d=d_precedent-pas*terme_gradient*d_avant_algo;
662 if (fabs(d)>fabs(d_precedent))
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++)
702 FEM_NOEUD* fem_noeud=opt_noeud->get_fem_noeud();
706 if (lst_tri.
existe(opt_tri))
715 if (norme_grad_f_apres_depl>norme_grad_f_avant_depl)
748 if (fabs(norme_grad_f-norme_grad_f_precedente)<0.0000001)
751 std::cout <<
" LA NORME DU GRADIENT DE LA FONCTION F NE VARIE PLUS! " << std::endl;
754 if (norme_grad_f>norme_grad_f_precedente)
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;
760 norme_grad_f_precedente=norme_grad_f;
762 if (nb_iter_algo==iter_max_grad)
765 std::cout <<
" ERREUR!!! LE NOMBRE D'ITÉRATIONS MAXIMAL A ÉTÉ ATTEINT! " << std::endl;
774 if (opt_noeud->get_num_replacement()==num_repl)
777 std::cout <<
" Nb de noeuds replacés par l'algorithme du gradient: " << nb_noeud_repl << std::endl;
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)))
789 std::cout <<
" Nb de triangles à 2 noeuds fixes affectés: " << nb_tri_repl << std::endl;
799 std::cout <<
" Norme finale du gradient de la fonction f: " << norme_grad_f << std::endl;
806 std::cout <<
" Nb d'itérations effectuées: " << nb_iter_algo << std::endl;
812 std::cout <<
" Lissage par barycentrage des noeuds " << std::endl;
814 int nb_noeud=lst_noeud.
get_nb();
821 lst_noeud_voisin=opt_noeud->get_liste_noeud_voisin();
827 OT_VECTEUR_3D pos_opt(opt->get_x(),opt->get_y(),opt->get_z());
828 pos_moy=pos_moy+pos_opt;
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);
849 opt_noeud->change_coord_lissee(pos_moy);
855 opt_noeud->change_x(pos_lissee[0]);
856 opt_noeud->change_y(pos_lissee[1]);
857 opt_noeud->change_z(pos_lissee[2]);
863 std::cout <<
" Lissage contrôlé par barycentrage des noeuds (replacement des pires noeuds seulement) " << std::endl;
865 int nb_noeud=lst_noeud.
get_nb();
872 lst_noeud_voisin=opt_noeud->get_liste_noeud_voisin();
878 OT_VECTEUR_3D pos_opt(opt->get_x(),opt->get_y(),opt->get_z());
879 pos_moy=pos_moy+pos_opt;
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);
890 double norme_pos_opt_noeud=pos_opt_noeud.
get_longueur();
893 if (fabs((norme_pos_moy-norme_pos_opt_noeud)/norme_pos_moy)>ecart_max_pondere_norme_pos)
895 opt_noeud->change_coord_lissee(pos_moy);
900 if (opt->get_mobile()==0)
903 opt_noeud->change_mobile(0);
906 opt_noeud->change_coord_lissee(pos_opt_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]);
925 int contrainte_objective_moyenne=0;
929 if (s_objective<0.001)
930 contrainte_objective_moyenne=1;
935 int actualisation_normales=(int)
params.
get_valeur(
"actualisation_normales");
954 double ecart_max_pondere_norme_pos=
params.
get_valeur(
"ecart_max_pondere_norme_pos");
960 char coderesu[10]=
"11110010";
970 if (contrainte_objective_moyenne==1)
972 sprintf(mess,
" Paramètres mvt_normal: s_objective: moyenne");
977 sprintf(mess,
" Paramètres mvt_normal: s_objective: %.0f MPa",s_objective/1e06);
980 sprintf(mess,
" c: %.4lf",c);
982 sprintf(mess,
" limite: %.2lf",limite);
984 sprintf(mess,
" iter_max: %d",iter_max);
986 sprintf(mess,
" iter_vue: %d",iter_vue);
988 sprintf(mess,
" actualisation_normales: %d",actualisation_normales);
991 sprintf(mess,
" Paramètres écart max dépl: deplacement: %d",deplacement);
995 sprintf(mess,
" ecart_max_depl: %.4lf",ecart_max_depl);
997 sprintf(mess,
" facteur_repl: %.4lf",facteur_repl);
1001 sprintf(mess,
" Paramètres gradient: gradient: %d",gradient);
1005 sprintf(mess,
" norme_max_grad: %.4lf",norme_max_grad);
1007 sprintf(mess,
" pas: %.4lf",pas);
1009 sprintf(mess,
" epsilon: %.6lf",
epsilon);
1011 sprintf(mess,
" iter_max_grad: %d",iter_max_grad);
1015 sprintf(mess,
" Paramètres lissage: lissage_iter: %d",lissage_iter);
1017 sprintf(mess,
" lissage_fin: %d",lissage_fin);
1020 sprintf(mess,
" lissage_controle_iter:%d",lissage_controle_iter);
1022 if (lissage_controle_iter>0)
1024 sprintf(mess,
" Paramètres lissage contrôlé: ecart_max_pondere_norme_pos: %.2lf",ecart_max_pondere_norme_pos);
1028 sprintf(mess,
" Paramètres film: film: %d",film);
1031 char *p=strchr(fichierin,
'.');
1032 strncpy(
etude,fichierin,p-fichierin);
1033 etude[p-fichierin]=0;
1035 char *p2=strchr(fichierout,
'.');
1041 char etudefilm[200];
1042 char fichierfilm[200];
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))
1062 lstnoeud_deplacer.
ajouter(opt_noeud);
1063 opt_noeud->change_mobile_au_depart(1);
1064 opt_noeud->change_mobile(1);
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());
1073 opt_noeud->change_normale_initiale();
1076 opt_noeud->change_sol_deplacement_virtuel(0.);
1079 opt_noeud->change_norme_orientee_deplacement();
1087 int nb_noeud=lstnoeud_deplacer_initiale.
get_nb();
1088 sprintf(mess,
" Il y a initialement %d noeuds pouvant être déplacés",nb_noeud);
1091 int nb_tri_mobile_initial=0;
1092 LISTE_FEM_ELEMENT2::iterator itfem_ele2;
1102 nb_tri_mobile_initial++;
1105 sprintf(mess,
" Il y a initialement %d triangles ayant au moins 1 noeud mobile",nb_tri_mobile_initial);
1136 LISTE_FEM_NOEUD::iterator itfem_noeud;
1140 affiche((
char*)
" Génération du fichier .msh de l'itération 0");
1143 char etudeiter[100];
1145 strcat(etudeiter,
"_iter");
1146 strcat(etudeiter,iter);
1156 affiche((
char*)
" Calcul de l'état de contrainte initial");
1159 std::cout <<
" Code de sortie: " << codesortie << std::endl;
1163 double svm_min=1.e308;
1166 double somme_svm=0.;
1168 double ecarttype=0.;
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))
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;
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;
1189 double svm=
get_sigma_vm_max(gest_visu,fem_noeud,numsolinf,numsolmoy,numsolsup);
1191 sol_S_VM_MAX_I->
ecrire(svm/1e06,num-1,0);
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);
1210 double nb_noeud_design=0.;
1220 if (fabs(dx)>fabs(dx_max))
1223 if (fabs(dy)>fabs(dy_max))
1226 if (fabs(dz)>fabs(dz_max))
1231 LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
1236 a_tot=a_tot+aire_tri;
1248 if ((lstnoeud_deplacer_initiale.
existe(opt_n1)) || (lstnoeud_deplacer_initiale.
existe(opt_n2)) || (lstnoeud_deplacer_initiale.
existe(opt_n3)))
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))
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;
1265 double coef=fabs(svm-s_objective)/s_objective;
1268 if (svm<0.1*svm_moy)
1272 pnic=nb_nic/nb_noeud_design*100;
1273 pnnc=nb_nnc/nb_noeud_design*100;
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);
1279 sprintf(mess,
" L'écart type est de: %.2lf MPa",ecarttype/1e06);
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);
1283 sprintf(mess,
" L'aire totale vaut: %.4lf m²",a_tot/1e06);
1285 sprintf(mess,
" L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
1287 sprintf(mess,
" La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
1289 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
1291 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
1294 sprintf(mess,
" %d noeuds peuvent être déplacés par la méthode du mouvement normal",lstnoeud_deplacer.
get_nb());
1319 int nb_noeud_bloque_par_gradient=0;
1320 int nb_tri_3nd_fixe=0;
1323 double d_moy_initial=0.;
1324 double d_moy_precedent=0.;
1326 while (fin==0 && iter_methode<=iter_max)
1328 if (((iter_vue!=0) && (iter_methode%iter_vue==0)) || (iter_methode==iter_max))
1334 sprintf(mess,
" Itération %d",iter_methode);
1338 char nomsolution[100];
1339 sprintf(nomsolution,
"optimisation%d.sol",iter_methode);
1340 char nomlegende[100];
1341 sprintf(nomlegende,
"Iteration%d",iter_methode);
1343 if ((iter_vue!=0) && (iter_methode%iter_vue==0))
1367 if (actualisation_normales==1)
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))
1379 opt_tri->change_jacobien_inverse();
1380 opt_tri->change_matrice_abc();
1381 opt_tri->change_nb_noeuds_fixes_iter(0);
1389 std::cout <<
" Déplacement virtuel des noeuds " << std::endl;
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;
1411 double d_precedent=opt_noeud->get_norme_orientee_deplacement();
1413 if (opt_noeud->get_sol_deplacement_virtuel()<0)
1414 opt_noeud->change_sens_depl_virtuel(-1.);
1416 opt_noeud->change_sens_depl_virtuel(1.);
1421 int nb_noeud_deplace=0;
1422 nb_noeud_deplace=lstnoeud_deplacer.
get_nb();
1424 std::cout <<
" " << nb_noeud_deplace <<
" noeuds déplacés par la méthode du mouvement normal" << std::endl;
1426 std::cout <<
" Nb de triangles ayant 2 noeuds fixes: " << lst_tri_2nd_fixe.
get_nb() << std::endl;
1433 std::cout <<
" Contrôle de l'écart maximal de déplacement entre 2 noeuds voisins dont l'un est fixe " << std::endl;
1440 lstnoeud_deplacer_temp.
ajouter(opt_noeud);
1442 while (lstnoeud_deplacer_temp.
get_nb()!=0)
1451 if (depl_initial_noeud<0.)
1455 if (opt_voisin->get_mobile()==0)
1456 lstnoeud_voisin_fixe.
ajouter(opt_voisin);
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)
1465 if (depl_initial_noeud<depl_voisin_fixe)
1468 double ecart_depl=ecart_depl_initial;
1469 double ecart_depl_precedent=ecart_depl_initial;
1472 while ((ecart_depl>ecart_max_depl) && (compteur<100))
1479 if (d*depl_initial_noeud>0)
1483 ecart_depl=fabs(depl_noeud-depl_voisin_fixe);
1486 if (ecart_depl>ecart_depl_precedent)
1488 ecart_depl_precedent=ecart_depl;
1497 lstnoeud_deplacer_temp.
supprimer(opt_noeud);
1507 std::cout.setf(std::ios::fixed,std::ios::floatfield);
1508 std::cout.precision(6);
1512 if (
f>0.0000000000001)
1517 std::cout <<
" Évaluation du gradient de la fonction f " << std::endl;
1521 std::cout <<
" Norme du gradient de f: " << norme_grad_f << std::endl;
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);
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))
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;
1561 if (fabs(d)>0.0000000000001)
1573 if (iter_methode==1)
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))
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;
1586 d_moy=d_moy+fabs(opt_noeud->get_norme_orientee_deplacement());
1588 if (nb_noeud_deplace>0)
1589 d_moy=d_moy/nb_noeud_deplace;
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;
1618 if (opt_tri->get_norme_gradient_deplacement_virtuel()>norme_max_grad)
1619 lst_tri_depasse_grad_virtuel_apres.
ajouter(opt_tri);
1621 if (opt_tri->get_norme_gradient_deplacement_reel()>norme_max_grad)
1622 lst_tri_depasse_grad_reel_apres.
ajouter(opt_tri);
1631 std::cout <<
" Vérification si tous les noeuds voisins d'un noeud sont fixes " << std::endl;
1635 lstnoeud_deplacer_temp.
ajouter(opt_noeud);
1637 while (lstnoeud_deplacer_temp.
get_nb()!=0)
1645 if (opt->get_mobile()==0)
1646 lstnoeud_voisin_fixe.
ajouter(opt);
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)
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;
1663 double d_noeud=opt->get_norme_orientee_deplacement();
1664 somme_d=somme_d+d_noeud;
1666 std::cout <<
" Noeud: " << opt->get_id() <<
" " << opt->get_num() <<
" " << d_noeud << std::endl;
1668 d_moy=somme_d/nb_noeud_voisin_fixe;
1680 std::cout <<
" Déplacement initial: " << d_actuel << std::endl;
1681 std::cout <<
" Déplacement final: " << d_moy << std::endl;
1684 lstnoeud_deplacer_temp.
supprimer(opt_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);
1702 lst_tri_3nd_fixe_precedent.
ajouter(opt_tri);
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();
1712 int nb_noeuds_fixes=0;
1719 if (nb_noeuds_fixes==3)
1721 lst_tri_3nd_fixe.
ajouter(opt_tri);
1722 if (!lst_tri_3nd_fixe_precedent.
existe(opt_tri))
1724 lst_tri_3nd_fixe_iter.
ajouter(opt_tri);
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))
1755 if (opt_noeud->get_num_replacement()==num_repl)
1760 opt_noeud->change_arret_gradient(1);
1765 opt_noeud->change_num_replacement(0);
1773 int nb_tri_3nd_fixe_iter=0;
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();
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++;
1791 nb_tri_3nd_fixe=nb_tri_3nd_fixe+nb_tri_3nd_fixe_iter;
1794 sprintf(mess,
" Au total, %d triangles ont maintenant 3 noeuds fixes",nb_tri_3nd_fixe);
1799 if (nb_tri_3nd_fixe==nb_tri_mobile_initial)
1803 sprintf(mess,
" Tous les triangles ont maintenant 3 noeuds fixes");
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))
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);
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++;
1825 int nb_noeud_deplacer=lstnoeud_deplacer.
get_nb();
1828 sprintf(mess,
" Au total, %d noeuds ont été fixés par le gradient",nb_noeud_fixe_par_gradient);
1830 sprintf(mess,
" %d noeuds ne sont pas fixes",nb_noeud_deplacer);
1837 if ((lissage_iter!=0) && (iter_methode%lissage_iter==0))
1838 lissage(lstnoeud_deplacer_initiale);
1842 if ((lissage_controle_iter!=0) && (iter_methode%lissage_controle_iter==0))
1849 if (opt_noeud->get_mobile()==0)
1856 if ((iter_vue!=0) && (iter_methode%iter_vue==0))
1863 affiche((
char*)
" Calcul de l'état de contrainte final après déplacement");
1866 std::cout <<
" Code de sortie: " << codesortie << std::endl;
1870 double svm_min=1.e308;
1873 double somme_svm=0.;
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))
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;
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;
1898 sol_S_VM_MAX_F->
ecrire(svm/1e06,num-1,0);
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);
1917 double nb_noeud_design=0.;
1927 if (fabs(dx)>fabs(dx_max))
1930 if (fabs(dy)>fabs(dy_max))
1933 if (fabs(dz)>fabs(dz_max))
1938 LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
1943 a_tot=a_tot+aire_tri;
1955 if ((lstnoeud_deplacer_initiale.
existe(opt_n1)) || (lstnoeud_deplacer_initiale.
existe(opt_n2)) || (lstnoeud_deplacer_initiale.
existe(opt_n3)))
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))
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;
1972 double coef=fabs(svm-s_objective)/s_objective;
1977 if (svm<0.1*svm_moy)
1981 pnic=nb_nic/nb_noeud_design*100;
1982 pnnc=nb_nnc/nb_noeud_design*100;
1988 sprintf(mess,
" La méthode a convergée (convergence par la contrainte)");
1992 if (lstnoeud_deplacer.
get_nb()==0)
1994 sprintf(mess,
" La méthode a convergée (listenoeud_deplacer est vide)");
2007 if ((affichage==1) || (fin!=0))
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);
2011 sprintf(mess,
" L'écart type est de: %.2lf MPa",ecarttype/1e06);
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);
2015 sprintf(mess,
" L'aire totale vaut: %.4lf m²",a_tot/1e06);
2017 sprintf(mess,
" L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
2019 sprintf(mess,
" La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
2021 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
2023 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
2030 if (iter_methode%iter_vue==0)
2032 affiche((
char*)
" Génération du fichier .msh de l'itération");
2034 sprintf(iter,
"%d",iter_methode);
2035 char etudeiter[100];
2037 strcat(etudeiter,
"_iter");
2038 strcat(etudeiter,iter);
2044 iter_finale=iter_methode;
2053 lissage(lstnoeud_deplacer_initiale);
2057 affiche((
char*)
" Calcul de l'état de contrainte après lissage final");
2059 std::cout <<
" Code de sortie: " << codesortie << std::endl;
2063 double svm_min=1.e308;
2066 double somme_svm=0.;
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))
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;
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;
2090 sol_S_VM_MAX_F->
ecrire(svm/1e06,num-1,0);
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);
2109 double nb_noeud_design=0.;
2119 if (fabs(dx)>fabs(dx_max))
2122 if (fabs(dy)>fabs(dy_max))
2125 if (fabs(dz)>fabs(dz_max))
2130 LISTE_FEM_ELEMENT2::iterator it_fem_ele2;
2135 a_tot=a_tot+aire_tri;
2147 if ((lstnoeud_deplacer_initiale.
existe(opt_n1)) || (lstnoeud_deplacer_initiale.
existe(opt_n2)) || (lstnoeud_deplacer_initiale.
existe(opt_n3)))
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))
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;
2164 double coef=fabs(svm-s_objective)/s_objective;
2167 if (svm<0.1*svm_moy)
2171 pnic=nb_nic/nb_noeud_design*100;
2172 pnnc=nb_nnc/nb_noeud_design*100;
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);
2178 sprintf(mess,
" L'écart type est de: %.2lf MPa",ecarttype/1e06);
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);
2182 sprintf(mess,
" L'aire totale vaut: %.4lf m²",a_tot/1e06);
2184 sprintf(mess,
" L'aire de la zone de design vaut: %.4lf m²",a_d/1e06);
2186 sprintf(mess,
" La contrainte moyenne spécifique vaut: %.4lf MPa*m²",svm_moy*a_d*1e-12);
2188 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte comprise dans l'intervalle de convergence",pnic);
2190 sprintf(mess,
" %.2lf %% des noeuds situés dans la zone de design ont une contrainte inférieure à 10 %% de la valeur moyenne",pnnc);
2196 char nomsolution[100];
2197 sprintf(nomsolution,
"optimisation%d.sol",iter_finale);
2198 char nomlegende[100];
2199 sprintf(nomlegende,
"Iteration%d",iter_finale);
2215 sprintf(mess,
" Génération du fichier .msh final");