ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 280
Committed: Thu Jun 30 19:51:22 2011 UTC (14 years, 2 months ago) by francois
File size: 44691 byte(s)
Log Message:
progression de couche dans le bouchage de trou lors de la construction des level-sets dans toIbrep

File Contents

# Content
1 #include "gestionversion.h"
2 #include "toibrep.h"
3 #include "mg_file.h"
4 #include "ot_mathematique.h"
5 #include "tpl_map_entite.h"
6 #include "tpl_relation_entite.h"
7 #include "tpl_octree.h"
8 #include "toibrep_point.h"
9 #include "vct.h"
10 #include <math.h>
11 #include <fstream>
12 #include <string>
13 #include "IBrep.h"
14 #include "ot_cpu.h"
15
16
17
18 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas,OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(compt)
19 {
20 }
21
22 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(NULL)
23 {
24 }
25 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(NULL)
26 {
27 }
28 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,class OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(compt)
29 {
30 }
31
32 TOIBREP::~TOIBREP()
33 {
34 }
35
36
37
38 void TOIBREP::active_affichage(void (*fonc)(char*))
39 {
40 affiche=fonc;
41 affichageactif=1;
42 }
43
44 int TOIBREP::compare_etat(int etat,int valeur)
45 {
46 int ope=etat&valeur;
47 if (ope==valeur)
48 return 1;
49 return 0;
50 }
51
52
53
54 int TOIBREP::estdansletetra(FEM_TETRA *tet,double x,double y, double z)
55 {
56 double *xyz1,*xyz2,*xyz3,*xyz4;
57 if (tet->get_nb_fem_noeud()==4)
58 {
59 xyz1=tet->get_fem_noeud(0)->get_coord();
60 xyz2=tet->get_fem_noeud(1)->get_coord();
61 xyz3=tet->get_fem_noeud(2)->get_coord();
62 xyz4=tet->get_fem_noeud(3)->get_coord();
63 }
64 if (tet->get_nb_fem_noeud()==10)
65 {
66 xyz1=tet->get_fem_noeud(0)->get_coord();
67 xyz2=tet->get_fem_noeud(2)->get_coord();
68 xyz3=tet->get_fem_noeud(4)->get_coord();
69 xyz4=tet->get_fem_noeud(9)->get_coord();
70 }
71 OT_VECTEUR_3D v1(xyz2[0]-xyz1[0],xyz2[1]-xyz1[1],xyz2[2]-xyz1[2]);
72 OT_VECTEUR_3D v2(xyz3[0]-xyz1[0],xyz3[1]-xyz1[1],xyz3[2]-xyz1[2]);
73 OT_VECTEUR_3D v3(xyz4[0]-xyz1[0],xyz4[1]-xyz1[1],xyz4[2]-xyz1[2]);
74 OT_VECTEUR_3D v4(x-xyz1[0],y-xyz1[1],z-xyz1[2]);
75 OT_MATRICE_3D mat(v1,v2,v3);
76 OT_MATRICE_3D mat1(v4,v2,v3);
77 OT_MATRICE_3D mat2(v1,v4,v3);
78 OT_MATRICE_3D mat3(v1,v2,v4);
79 double det=mat.get_determinant();
80 double xsi=mat1.get_determinant()/det;
81 double eta=mat2.get_determinant()/det;
82 double dseta=mat3.get_determinant()/det;
83 int reponse1=1;
84 int reponse2=1;
85 double eps=0.0001;
86 if (xsi<-eps) reponse1=0;
87 if (eta<-eps) reponse1=0;
88 if (dseta<-eps) reponse1=0;
89 if (xsi+eta+dseta>1.+eps) reponse1=0;
90 if (xsi<eps) reponse2=0;
91 if (eta<eps) reponse2=0;
92 if (dseta<eps) reponse2=0;
93 if (xsi+eta+dseta>1.-eps) reponse2=0;
94 return reponse1+2*reponse2;
95 }
96
97
98
99 double TOIBREP::calculdist(double *n,double x,double y,double z,FEM_NOEUD* noeud)
100 {
101 double* xyz=noeud->get_coord();
102 double dist=sqrt((xyz[0]-x)*(xyz[0]-x)+(xyz[1]-y)*(xyz[1]-y)+(xyz[2]-z)*(xyz[2]-z));
103 OT_VECTEUR_3D vec1(n[0],n[1],n[2]);
104 OT_VECTEUR_3D vec2(xyz[0]-x,xyz[1]-y,xyz[2]-z);
105 double ps=vec1*vec2;
106 if (ps<0.) dist=-dist;
107 return dist;
108 }
109
110 //void TOIBREP::importer(std::string nomfichier,class MagXchange* data,std::string nomfichierout)
111 IBrep TOIBREP::importer(std::string nomfichier,std::string nomfichieribrep,MG_GROUPE_TOPOLOGIQUE* mggt)
112 {
113 affiche((char*)"Traitement de base");
114 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> lst;
115 int nbface=geo->get_nb_mg_face();
116 if (mggt!=NULL)
117 {
118 int nb=mggt->get_nb();
119 for (int i=0;i<nb;i++)
120 {
121 lst.ajouter(mggt->get(i));
122 mggt->get(i)->get_topologie_sousjacente(&lst);
123 }
124 }
125 else
126 {
127 int nbvol=geo->get_nb_mg_volume();
128 for (int i=0;i<nbvol;i++)
129 {
130 lst.ajouter(geo->get_mg_volume(i));
131 geo->get_mg_volume(i)->get_topologie_sousjacente(&lst);
132 }
133 }
134 int nbvraiface=0;
135 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*>::ITERATEUR it;
136 for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
137 if (ele->get_dimension()==2) nbvraiface++;
138 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base selection");
139 int nb_noeud=mai->get_nb_fem_noeud();
140 int nb_tetra=mai->get_nb_fem_tetra();
141 std::string nomfichier2=nomfichier+"_dis.sol";
142 FEM_SOLUTION* solution=new FEM_SOLUTION(mai,nbvraiface,(char*)nomfichier2.c_str(),nb_noeud,"LS",ENTITE_NOEUD);
143 int i=0;
144 gest->ajouter_fem_solution(solution);
145 nomfichier2=nomfichier+"_ele.sol";
146 FEM_SOLUTION* solution_ele=new FEM_SOLUTION(mai,nbvraiface,(char*)nomfichier2.c_str(),nb_tetra,"A",ENTITE_TETRA);
147 gest->ajouter_fem_solution(solution_ele);
148 for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
149 {
150 if (ele->get_dimension()!=2) continue;
151 char mess[255];
152 sprintf(mess,"F %lu",ele->get_id());
153 solution->change_legende(i,mess);
154 solution_ele->change_legende(i,mess);
155 ++i;
156 }
157
158 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base creation solution");
159 double xmin=1e300,ymin=1e300,zmin=1e308;
160 double xmax=-1e300,ymax=-1e300,zmax=-1e308;
161 TPL_MAP_ENTITE<FEM_NOEUD*> lst_noeud;
162 LISTE_FEM_NOEUD::iterator it2;
163 i=0;
164 for (FEM_NOEUD* noeud=mai->get_premier_noeud(it2);noeud!=NULL;noeud=mai->get_suivant_noeud(it2))
165 {
166 double* xyz=noeud->get_coord();
167 if (xyz[0]<xmin) xmin=xyz[0];
168 if (xyz[1]<ymin) ymin=xyz[1];
169 if (xyz[2]<zmin) zmin=xyz[2];
170 if (xyz[0]>xmax) xmax=xyz[0];
171 if (xyz[1]>ymax) ymax=xyz[1];
172 if (xyz[2]>zmax) zmax=xyz[2];
173 for (int j=0;j<nbvraiface;j++)
174 solution->ecrire(i,j,1e300);
175 lst_noeud.ajouter(noeud);
176 i++;
177 }
178 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base recherche boite");
179 octree.initialiser(&lst_noeud,1,xmin,ymin,zmin,xmax,ymax,zmax);
180 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base ini octree");
181 LISTE_FEM_TETRA::iterator it3;
182 i=0;
183 for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
184 {
185 octree.inserer(tet);
186 for (int j=0;j<nbvraiface;j++)
187 solution_ele->ecrire(i,j,0);
188 i++;
189 }
190 if (compteur!=NULL) compteur->ajouter_etape("Traitement de base");
191 for (int i=0;i<nbface;i++)
192 {
193 if (affichageactif)
194 {
195 char mess[300];
196 sprintf(mess," Face %d",i);
197 affiche(mess);
198 }
199 MG_FACE* face=geo->get_mg_face(i);
200 if (!lst.existe(face)) continue;
201 vector<MG_FACE*> lstface;
202 lstface.push_back(face);
203 /// ici topologie virtuelle
204
205
206 /*TPL_LISTE_ENTITE<double> lst;
207 int type=face->get_surface()->get_type_geometrique(lst);
208 int idem=0;
209 for (int j=0;j<i;j++)
210 {
211 TPL_LISTE_ENTITE<double> lst2;
212 MG_FACE* face2=geo->get_mg_face(j);
213 int type2=face2->get_surface()->get_type_geometrique(lst2);
214 if (type==type2)
215 if (lst.get_nb()==lst2.get_nb())
216 {
217 int diff=0;
218 for (int i=0;i<lst.get_nb();i++)
219 if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
220 if (diff==0) idem=1;
221 }
222 }
223 if (!idem) lstface.push_back(geo->get_mg_face(i));
224 for (int j=i+1;j<nbface;j++)
225 {
226 TPL_LISTE_ENTITE<double> lst2;
227 MG_FACE* face2=geo->get_mg_face(j);
228 int type2=face2->get_surface()->get_type_geometrique(lst2);
229 if (type==type2)
230 if (lst.get_nb()==lst2.get_nb())
231 {
232 int diff=0;
233 for (int i=0;i<lst.get_nb();i++)
234 if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
235 if (diff==0) lstface.push_back(face2);
236 }
237 }*/
238 levelsetn(&lst,&lstface,solution,solution_ele,i);
239 }
240 affiche((char*)"Exportation IBREP");
241 IBrep brep=exporter_IBrep(nomfichieribrep,solution,solution_ele,mggt);
242 if (compteur!=NULL) compteur->ajouter_etape("Exportation IBREP");
243 return brep;
244 }
245
246 void TOIBREP::levelset0(FEM_SOLUTION *solution,int numsol)
247 {
248 /*solution->active_solution(numsol);
249 int nbface=geo->get_nb_mg_face();
250 vector<TOIBREP_POINT*> lst;
251 for (int iface=0;iface<nbface;iface++)
252 {
253 MG_FACE* face=geo->get_mg_face(iface);
254 int nbpoint=lst.size();
255 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
256 for (MG_ELEMENT_MAILLAGE* ele=face->get_lien_maillage()->get_premier(it);ele!=NULL;ele=face->get_lien_maillage()->get_suivant(it))
257 {
258 MG_TRIANGLE *tri=(Mvoid TOIBREP_POINT::get_coord2(double *uv)
259 {
260 uv[0]=u;
261 uv[1]=v;
262 }G_TRIANGLE*)ele;
263 TOIBREP_POINT *pt1=new TOIBREP_POINT(tri->get_noeud1()->get_x(),tri->get_noeud1()->get_y(),tri->get_noeud1()->get_z(),tri->get_noeud1()->get_lien_topologie());
264 TOIBREP_POINT *pt2=new TOIBREP_POINT(tri->get_noeud2()->get_x(),tri->get_noeud2()->get_y(),tri->get_noeud2()->get_z(),tri->get_noeud2()->get_lien_topologie());
265 TOIBREP_POINT *pt3=new TOIBREP_POINT(tri->get_noeud3()->get_x(),tri->get_noeud3()->get_y(),tri->get_noeud3()->get_z(),tri->get_noeud3()->get_lien_topologie());
266 lst.push_back(pt1);
267 lst.push_back(pt2);
268 lst.push_back(pt3);
269 }
270 calcullevelsetpremierepasse(solution,numsol,face,8,&lst,nbpoint,lst.size());
271 }
272 calcullevelsetdeuxiemepasse(solution,numsol,&lst);*/
273 }
274 void TOIBREP::echantillonne_sommet(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
275 {
276 TPL_MAP_ENTITE<MG_SOMMET*> lstsom;
277 int nbbou=face->get_nb_mg_boucle();
278 for (int i=0;i<nbbou;i++)
279 {
280 MG_BOUCLE* boucle=face->get_mg_boucle(i);
281 int nb_arete=boucle->get_nb_mg_coarete();
282 for (int j=0;j<nb_arete;j++)
283 {
284 MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
285 lstsom.ajouter(are->get_cosommet1()->get_sommet());
286 lstsom.ajouter(are->get_cosommet2()->get_sommet());
287 }
288 }
289 TPL_MAP_ENTITE<MG_SOMMET*>::ITERATEUR it;
290 for (MG_SOMMET* som=lstsom.get_premier(it);som!=NULL;som=lstsom.get_suivant(it))
291 {
292 double xyz[3];
293 som->get_point()->evaluer(xyz);
294 double uv[2];
295 face->inverser(uv,xyz);
296 int N=NPAS;
297 double rayon=1e-2;
298 for (int k=0;k<N+1;k++)
299 {
300 double uv2[2];
301 uv2[0]=uv[0]+rayon*cos(k*1.0/N*2.*M_PI);
302 uv2[1]=uv[1]+rayon*sin(k*1.0/N*2.*M_PI);
303 if ((face->valide_parametre_u(uv2[0])) && (face->valide_parametre_v(uv2[1])))
304 {
305 double distance=ot.calcule_distance_contour_face_uv(uv2,face);
306 if (distance>0.)
307 {
308 double xyz[3];
309 face->evaluer(uv2,xyz);
310 TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
311 lst.push_back(pt);
312 }
313 }
314 }
315
316 }
317 }
318 void TOIBREP::echantillonne_arete(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
319 {
320 echantillonne_sommet(lst,face);
321 int nbbou=face->get_nb_mg_boucle();
322 for (int i=0;i<nbbou;i++)
323 {
324 MG_BOUCLE* boucle=face->get_mg_boucle(i);
325 int nb_arete=boucle->get_nb_mg_coarete();
326 for (int j=0;j<nb_arete;j++)
327 {
328 MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
329 double tmin=are->get_tmin();
330 double tmax=are->get_tmax();
331 double N=NPAS;
332 for (int k=0;k<N+1;k++)
333 {
334 double t=tmin+k*1.0/N*(tmax-tmin);
335 double xyz[3];
336 are->evaluer(t,xyz);
337 TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
338 lst.push_back(pt);
339 // octree.inserer(pt);
340 }
341 /* double t=tmin+0.2/NPAS*(tmax-tmin);
342 double xyz[3];
343 are->evaluer(t,xyz);
344 TOIBREP_POINT *pt1=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
345 lst.push_back(pt1);
346 t=tmax-0.2/NPAS*(tmax-tmin);
347 are->evaluer(t,xyz);
348 TOIBREP_POINT *pt2=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
349 lst.push_back(pt2);*/
350
351
352
353 }
354 }
355 }
356
357 void TOIBREP::levelsetn(TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> *lsttopo,vector<MG_FACE*> *lstface,class FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele,int numsol)
358 {
359 if (affichageactif)
360 {
361 char mess[300];
362 sprintf(mess," Echantillonnage");
363 affiche(mess);
364 }
365
366 solution->active_solution(numsol);
367 solution_ele->active_solution(numsol);
368 int nbface=lstface->size();
369 if (nbface==0) return;
370 vector<TOIBREP_POINT*> lst;
371 BOITE_2D boite=ot.get_boite_2D((*lstface)[0]);
372 echantillonne_arete(lst,(*lstface)[0]);
373 for (int iface=1;iface<nbface;iface++)
374 {
375 MG_FACE* face=(*lstface)[iface];
376 BOITE_2D boiteface=ot.get_boite_2D(face);
377 boite=boite+boiteface;
378 echantillonne_arete(lst,(*lstface)[iface]);
379 }
380 MG_FACE* face=(*lstface)[0];
381 int trouve=0;
382 int orientation;
383 int j=0;
384 do
385 {
386 MG_COFACE* coface=face->get_mg_coface(j);
387 MG_VOLUME* vol=coface->get_coquille()->get_mg_volume();
388 if (lsttopo->existe(vol))
389 {
390 orientation=coface->get_orientation();
391 trouve=1;
392 }
393 j++;
394 }
395 while (trouve==0);
396 LISTE_FEM_TETRA::iterator ittetra;
397 for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
398 tet->change_etat(0);
399 LISTE_FEM_NOEUD::iterator itnoeud;
400 for (FEM_NOEUD* no=mai->get_premier_noeud(itnoeud);no!=NULL;no=mai->get_suivant_noeud(itnoeud))
401 no->change_etat(0);
402 double umin=boite.get_xmin();
403 double umax=boite.get_xmax();
404 double vmin=boite.get_ymin();
405 double vmax=boite.get_ymax();
406 if (face->get_surface()->est_periodique_u())
407 {
408 umin=0;
409 umax=face->get_surface()->get_periode_u();
410 }
411 if (face->get_surface()->est_periodique_v())
412 {
413 vmin=0;
414 vmax=face->get_surface()->get_periode_v();
415 }
416 for (int i=-5;i<NPAS+5;i++)
417 for (int j=-5;j<NPAS+5;j++)
418 {
419 double uv[2];
420 uv[0]=umin+i*1.0/NPAS*(umax-umin);
421 uv[1]=vmin+j*1.0/NPAS*(vmax-vmin);
422 double xyz[3];
423 if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
424 {
425 double distance=ot.calcule_distance_contour_face_uv(uv,face);
426 int inte=0;
427 if (distance>0.) inte=1.; else continue;
428 face->evaluer(uv,xyz);
429 TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],inte,face);
430 lst.push_back(pt);
431 // octree.inserer(pt);
432 }
433 }
434 // debut temp
435 /*
436 MG_GESTIONNAIRE gestemp;
437 MG_MAILLAGE *mai=new MG_MAILLAGE(NULL);
438 gestemp.ajouter_mg_maillage(mai);
439 for (int i=0;i<lst.size();i++)
440 {
441 double xyz[3];
442 lst[i]->get_coord3(xyz);
443 MG_NOEUD* no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],TRIANGULATION);
444 mai->ajouter_mg_noeud(no);
445 if (i!=0) {MG_SEGMENT* seg=new MG_SEGMENT(NULL,no,mai->get_mg_noeud(mai->get_nb_mg_noeud()-2),TRIANGULATION);mai->ajouter_mg_segment(seg);}
446 }
447
448 gestemp.enregistrer("debug.magic");
449 */
450 // fin temp
451 if (compteur!=NULL) compteur->ajouter_etape("Echantillonnage");
452 if (affichageactif)
453 {
454 char mess[300];
455 sprintf(mess," Preparation newton");
456 affiche(mess);
457 }
458 calcullevelsetpremierepasse(face,orientation,&lst,0,lst.size());
459 if (compteur!=NULL) compteur->ajouter_etape("Preparation newton");
460
461 if (affichageactif)
462 {
463 char mess[300];
464 sprintf(mess," Newton");
465 affiche(mess);
466 }
467 calcullevelsetdeuxiemepasse(&lst);
468 if (compteur!=NULL) compteur->ajouter_etape("Newton");
469 if (affichageactif)
470 {
471 char mess[300];
472 sprintf(mess," Remplissage des trous");
473 affiche(mess);
474 }
475 remplir_trou(&lst,face,orientation);
476 if (compteur!=NULL) compteur->ajouter_etape("Remplissage des trous");
477 //etendrelevelset(solution,numsol);
478 int i=0;
479 for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
480 {
481 if (noeud->get_etat()==1) solution->ecrire(i,numsol,noeud->get_solution());
482 else solution->ecrire(i,numsol,1e300);
483 ++i;
484 }
485 i=0;
486 for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
487 {
488 if (tet->get_etat()==1) solution_ele->ecrire(i,numsol,1.);
489 ++i;
490 }
491 int nbpt=lst.size();
492 for (int i=0;i<nbpt;i++) delete lst[i];
493 TOIBREP_POINT::remisecompteurid();
494
495
496
497 }
498
499 void TOIBREP::remplir_trou(std::vector<TOIBREP_POINT*> *lst,MG_FACE* face,int sens)
500 {
501 int castot=0;
502 int cas=0;
503 int couche_active;
504 int nb_couche=0;
505 do
506 {
507 nb_couche++;
508 LISTE_FEM_TETRA::iterator ittetra;
509 std::vector<FEM_TETRA*> couche;
510 couche_active=0;
511 for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
512 {
513 if (tet->get_etat()!=0) continue;
514 FEM_NOEUD *no1=tet->get_fem_noeud(0);
515 FEM_NOEUD *no2=tet->get_fem_noeud(1);
516 FEM_NOEUD *no3=tet->get_fem_noeud(2);
517 FEM_NOEUD *no4=tet->get_fem_noeud(3);
518 int nbactif=0;
519 int nbpositif=0;
520 if ((no1->get_etat()==1) || (no1->get_etat()==-1))
521 {
522 nbactif++;
523 if (no1->get_solution()>0.) nbpositif++;
524 }
525 if ((no2->get_etat()==1) || (no2->get_etat()==-1))
526 {
527 nbactif++;
528 if (no2->get_solution()>0.) nbpositif++;
529 }
530 if ((no3->get_etat()==1) || (no3->get_etat()==-1))
531 {
532 nbactif++;
533 if (no3->get_solution()>0.) nbpositif++;
534 }
535 if ((no4->get_etat()==1) || (no4->get_etat()==-1))
536 {
537 nbactif++;
538 if (no4->get_solution()>0.) nbpositif++;
539 }
540 if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
541 {
542 couche.push_back(tet);
543 }
544 }
545 for (int i=0;i<couche.size();i++)
546 {
547 FEM_TETRA* tet=couche[i];
548 FEM_NOEUD *no1=tet->get_fem_noeud(0);
549 FEM_NOEUD *no2=tet->get_fem_noeud(1);
550 FEM_NOEUD *no3=tet->get_fem_noeud(2);
551 FEM_NOEUD *no4=tet->get_fem_noeud(3);
552 TOIBREP_POINT* pt;
553 FEM_NOEUD* noeudref;
554 if (no1->get_etat()==0) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
555 if (no2->get_etat()==0) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
556 if (no3->get_etat()==0) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
557 if (no4->get_etat()==0) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
558 MG_FACE* face=(MG_FACE*)pt->get_mg_element_topologique();
559 double uv[2];
560 double xyz[3];
561 double dist=calcul_distance(noeudref,face,pt,xyz,uv);
562 double normal[3];
563 face->calcul_normale_unitaire(uv,normal);
564 normal[0]=normal[0]*sens*(-1.);
565 normal[1]=normal[1]*sens*(-1.);
566 normal[2]=normal[2]*sens*(-1.);
567 double dist2=calculdist(normal,xyz[0],xyz[1],xyz[2],noeudref);
568 if (dist2<0.) dist=dist*(-1);
569 noeudref->change_solution(dist);
570 noeudref->change_etat(2);
571 TOIBREP_POINT *nvpt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
572 lst->push_back(nvpt);
573 noeudref->change_numero(nvpt->get_id());
574
575 }
576 for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
577 {
578 FEM_NOEUD *no1=tet->get_fem_noeud(0);
579 FEM_NOEUD *no2=tet->get_fem_noeud(1);
580 FEM_NOEUD *no3=tet->get_fem_noeud(2);
581 FEM_NOEUD *no4=tet->get_fem_noeud(3);
582 if (no1->get_etat()!=0)
583 if (no2->get_etat()!=0)
584 if (no3->get_etat()!=0)
585 if (no4->get_etat()!=0)
586 if (tet->get_etat()==0)
587 {
588 castot++;
589 double lstptdecoup[5*3];
590 int nb=0;
591 decoupe_tetra(tet,lstptdecoup,&nb);
592 int reactive=0;
593 for (int i=0;i<nb;i++)
594 {
595 if (reactive) continue;
596 double uv[2];
597 face->inverser(uv,lstptdecoup+3*i);
598 if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
599 {
600 double distance=ot.calcule_distance_contour_face_uv(uv,face);
601 if (distance>1e-6)
602 {
603 cas++;
604 tet->change_etat(1);
605 no1->change_etat(1);
606 no2->change_etat(1);
607 no3->change_etat(1);
608 no4->change_etat(1);
609 reactive=1;
610 couche_active=1;
611 }
612 }
613 }
614 if (!reactive)
615 {
616 if (no1->get_etat()==2) no1->change_etat(-1);
617 if (no2->get_etat()==2) no2->change_etat(-1);
618 if (no3->get_etat()==2) no3->change_etat(-1);
619 if (no4->get_etat()==2) no4->change_etat(-1);
620 tet->change_etat(-1);
621 }
622 }
623 }
624 }
625 while (couche_active==1);
626 double res=cas*100.0/castot;
627 char mess[255];
628 sprintf(mess," %lf%% en %d couches",res,nb_couche);
629 affiche(mess);
630 }
631
632 void TOIBREP::decoupe_tetra(FEM_TETRA* tet,double* lst,int *nb)
633 {
634 FEM_NOEUD* no1=tet->get_fem_noeud(0);
635 FEM_NOEUD* no2=tet->get_fem_noeud(1);
636 FEM_NOEUD* no3=tet->get_fem_noeud(2);
637 FEM_NOEUD* no4=tet->get_fem_noeud(3);
638 if (no1->get_solution()*no2->get_solution()<-0.00000001)
639 {
640 double t=no1->get_solution()/(no1->get_solution()-no2->get_solution());
641 double x=no1->get_x()+t*(no2->get_x()-no1->get_x());
642 double y=no1->get_y()+t*(no2->get_y()-no1->get_y());
643 double z=no1->get_z()+t*(no2->get_z()-no1->get_z());
644 lst[3*(*nb)]=x;
645 lst[3*(*nb)+1]=y;
646 lst[3*(*nb)+2]=z;
647 (*nb)++;
648 }
649 if (no1->get_solution()*no3->get_solution()<-0.00000001)
650 {
651 double t=no1->get_solution()/(no1->get_solution()-no3->get_solution());
652 double x=no1->get_x()+t*(no3->get_x()-no1->get_x());
653 double y=no1->get_y()+t*(no3->get_y()-no1->get_y());
654 double z=no1->get_z()+t*(no3->get_z()-no1->get_z());
655 lst[3*(*nb)]=x;
656 lst[3*(*nb)+1]=y;
657 lst[3*(*nb)+2]=z;
658 (*nb)++;
659 }
660 if (no1->get_solution()*no4->get_solution()<-0.00000001)
661 {
662 double t=no1->get_solution()/(no1->get_solution()-no4->get_solution());
663 double x=no1->get_x()+t*(no4->get_x()-no1->get_x());
664 double y=no1->get_y()+t*(no4->get_y()-no1->get_y());
665 double z=no1->get_z()+t*(no4->get_z()-no1->get_z());
666 lst[3*(*nb)]=x;
667 lst[3*(*nb)+1]=y;
668 lst[3*(*nb)+2]=z;
669 (*nb)++;
670 }
671 if (no2->get_solution()*no3->get_solution()<-0.00000001)
672 {
673 double t=no2->get_solution()/(no2->get_solution()-no3->get_solution());
674 double x=no2->get_x()+t*(no3->get_x()-no2->get_x());
675 double y=no2->get_y()+t*(no3->get_y()-no2->get_y());
676 double z=no2->get_z()+t*(no3->get_z()-no2->get_z());
677 lst[3*(*nb)]=x;
678 lst[3*(*nb)+1]=y;
679 lst[3*(*nb)+2]=z;
680 (*nb)++;
681 }
682 if (no2->get_solution()*no4->get_solution()<-0.00000001)
683 {
684 double t=no2->get_solution()/(no2->get_solution()-no4->get_solution());
685 double x=no2->get_x()+t*(no4->get_x()-no2->get_x());
686 double y=no2->get_y()+t*(no4->get_y()-no2->get_y());
687 double z=no2->get_z()+t*(no4->get_z()-no2->get_z());
688 lst[3*(*nb)]=x;
689 lst[3*(*nb)+1]=y;
690 lst[3*(*nb)+2]=z;
691 (*nb)++;
692 }
693 if (no3->get_solution()*no4->get_solution()<-0.00000001)
694 {
695 double t=no3->get_solution()/(no3->get_solution()-no4->get_solution());
696 double x=no3->get_x()+t*(no4->get_x()-no3->get_x());
697 double y=no3->get_y()+t*(no4->get_y()-no3->get_y());
698 double z=no3->get_z()+t*(no4->get_z()-no3->get_z());
699 lst[3*(*nb)]=x;
700 lst[3*(*nb)+1]=y;
701 lst[3*(*nb)+2]=z;
702 (*nb)++;
703 }
704 }
705
706 void TOIBREP::calcullevelsetpremierepasse(MG_FACE* face,int sens,vector<TOIBREP_POINT*> *lst,int n1,int n2)
707 {
708 /*LISTE_FEM_TETRA::iterator it3;
709 for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
710 {
711 double *xyz1,*xyz2,*xyz3,*xyz4;
712 if (tet->get_nb_fem_noeud()==4)
713 {
714 xyz1=tet->get_fem_noeud(0)->get_coord();
715 xyz2=tet->get_fem_noeud(1)->get_coord();
716 xyz3=tet->get_fem_noeud(2)->get_coord();
717 xyz4=tet->get_fem_noeud(3)->get_coord();
718 }
719 if (tet->get_nb_fem_noeud()==10)
720 {
721 xyz1=tet->get_fem_noeud(0)->get_coord();
722 xyz2=tet->get_fem_noeud(2)->get_coord();
723 xyz3=tet->get_fem_noeud(4)->get_coord();
724 xyz4=tet->get_fem_noeud(9)->get_coord();
725 }
726 double xcentre=0.25*(xyz1[0]+xyz2[0]+xyz3[0]+xyz4[0]);
727 double ycentre=0.25*(xyz1[1]+xyz2[1]+xyz3[1]+xyz4[1]);
728 double zcentre=0.25*(xyz1[2]+xyz2[2]+xyz3[2]+xyz4[2]);
729 double rayon1=(xyz1[0]-xcentre)*(xyz1[0]-xcentre)+(xyz1[1]-ycentre)*(xyz1[1]-ycentre)+(xyz1[2]-zcentre)*(xyz1[2]-zcentre);
730 double rayon2=(xyz2[0]-xcentre)*(xyz2[0]-xcentre)+(xyz2[1]-ycentre)*(xyz2[1]-ycentre)+(xyz2[2]-zcentre)*(xyz2[2]-zcentre);
731 double rayon3=(xyz3[0]-xcentre)*(xyz3[0]-xcentre)+(xyz3[1]-ycentre)*(xyz3[1]-ycentre)+(xyz3[2]-zcentre)*(xyz3[2]-zcentre);
732 double rayon4=(xyz4[0]-xcentre)*(xyz4[0]-xcentre)+(xyz4[1]-ycentre)*(xyz4[1]-ycentre)+(xyz4[2]-zcentre)*(xyz4[2]-zcentre);
733 double rayon=std::max(rayonETRA_ACTIF1,std::max(rayon2,std::max(rayon3,rayon4)));
734 rayon=sqrt(rayon);
735 TPL_MAP_ENTITE<TOIBREP_POINT*> liste;
736 octree.rechercher(xcentre,ycentre,zcentre,rayon,liste);
737 TPL_MAP_ENTITE<TOIBREP_POINT*>::ITERATEUR it;
738 for (TOIBREP_POINT* pt=liste.get_premier(it);pt!=NULL;pt=liste.get_suivant(it))
739 {
740 double xyzpt[3];
741 pt->get_coord3(xyzpt);
742 int etat=estdansletetra(tet,xyzpt[0],xyzpt[1],xyzpt[2]);
743 if (compare_etat(etat,INTERIEUR))
744 {
745 for (int k=0;k<tet->get_nb_fem_noeud();k++)
746 {
747 double normal[3];
748 double uv[2];
749 face->inverser(uv,xyzpt);
750 face->calcul_normale_unitaire(uv,normal);
751 normal[0]=normal[0]*sens*(-1.);
752 normal[1]=normal[1]*sens*(-1.);
753 normal[2]=normal[2]*sens*(-1.);
754 double dist=calculdist(normal,xyzpt[0],xyzpt[1],xyzpt[2],tet->get_fem_noeud(k));
755 if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
756 {
757 tet->get_fem_noeud(k)->change_solution(dist);
758 tet->get_fem_noeud(k)->change_numero(pt->get_id());
759 pt->change_coord2(uv);
760 }
761 }
762 }
763 if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
764 {
765 tet->change_etat(1);
766 for (int k=0;k<tet->get_nb_fem_noeud();k++)
767 tet->get_fem_noeud(k)->change_etat(1);
768 }
769 if (tet->get_etat()==1) break;
770 }
771
772 }
773 octree.vide();
774 }*/
775 /*LISTE_FEM_TETRA::iterator it3;
776 for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
777 octree.inserer(tet);*/
778 for (int i=n1;i<n2;i++)
779 {
780 TOIBREP_POINT* pt=(*lst)[i];
781 double uv[2];
782 double xyz[3];
783 pt->get_coord3(xyz);
784 double normal[3];
785 face->inverser(uv,xyz);
786 face->calcul_normale_unitaire(uv,normal);
787 normal[0]=normal[0]*sens*(-1.);
788 normal[1]=normal[1]*sens*(-1.);
789 normal[2]=normal[2]*sens*(-1.);
790 TPL_MAP_ENTITE<FEM_TETRA*> liste;
791 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
792 TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR it;
793 for (FEM_TETRA* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
794 {
795 if (tet->get_etat()==1) continue;
796 int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
797 if (compare_etat(etat,INTERIEUR))
798 {
799 for (int k=0;k<tet->get_nb_fem_noeud();k++)
800 {
801 double dist=calculdist(normal,xyz[0],xyz[1],xyz[2],tet->get_fem_noeud(k));
802 if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
803 {
804 tet->get_fem_noeud(k)->change_solution(dist);
805 tet->get_fem_noeud(k)->change_numero(pt->get_id());
806 pt->change_coord2(uv);
807 }
808 }
809 }
810 if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
811 {
812 tet->change_etat(1);
813 for (int k=0;k<tet->get_nb_fem_noeud();k++)
814 {
815 tet->get_fem_noeud(k)->change_etat(1);
816 //octree.supprimer(tet);
817 }
818 }
819 }
820 }
821 //octree.vide();
822
823
824
825
826 }
827
828 void TOIBREP::calcullevelsetdeuxiemepasse(vector<TOIBREP_POINT*> *lst)
829 {
830 LISTE_FEM_NOEUD::iterator itno;
831 for (FEM_NOEUD* no=mai->get_premier_noeud(itno);no!=NULL;no=mai->get_suivant_noeud(itno))
832 if (no->get_solution()<1e250)
833 {
834 TOIBREP_POINT* pt=(*lst)[no->get_numero()];
835 int dim=pt->get_mg_element_topologique()->get_dimension();
836 if (dim==2)
837 {
838 MG_FACE* face=(MG_FACE*)pt->get_mg_element_topologique();
839 double xyz[3],uv[2];
840 double dist=calcul_distance(no,face,pt,xyz,uv);
841 int signe=1;
842 if (no->get_solution()<0) signe=-1;
843 no->change_solution(signe*dist);
844 }
845 if (dim==1)
846 {
847 MG_ARETE* arete=(MG_ARETE*)pt->get_mg_element_topologique();
848 double dist=calcul_distance(no,arete,pt);
849 no->change_solution(dist);
850 }
851 if (dim==0)
852 {
853 MG_SOMMET* sommet=(MG_SOMMET*)pt->get_mg_element_topologique();
854 MG_ARETE* arete=sommet->get_mg_cosommet(0)->get_arete();
855 double dist=calcul_distance(no,arete,pt);
856 no->change_solution(dist);
857 }
858
859 }
860
861
862
863
864 }
865
866 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_ARETE* are,TOIBREP_POINT* pt,double precision)
867 {
868 double tii,eps;
869 are->inverser(tii,noeud->get_coord());
870 int compteur=0;
871 OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
872 do
873 {
874 compteur++;
875 double ti=tii;
876 double xyz[3],dxyz[3],ddxyz[3];
877 are->deriver_seconde(ti,ddxyz,dxyz,xyz);
878 OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
879 OT_VECTEUR_3D Ct_deriver(dxyz[0],dxyz[1],dxyz[2]);
880 OT_VECTEUR_3D Ct_deriver_seconde(ddxyz[0],ddxyz[1],ddxyz[2]);
881 OT_VECTEUR_3D Distance = Ct-Pt;
882 tii=ti-Ct_deriver*Distance/(Ct_deriver_seconde*Distance+Ct_deriver.get_longueur2());
883 eps=fabs(tii-ti);
884 if (compteur>500) return 1e300;
885 if (tii<are->get_tmin())
886 {
887 tii=are->get_tmin();
888 eps=0.;
889 }
890 if (tii>are->get_tmax())
891 {
892 tii=are->get_tmax();
893 eps=0.;
894 }
895 }
896 while (eps>precision);
897 double xyz[3],dxyz[3];
898 are->evaluer(tii,xyz);
899 OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
900 double distance=(Ct-Pt).get_longueur();
901 MG_FACE* face1=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
902 MG_FACE* face2=are->get_mg_coarete(1)->get_boucle()->get_mg_face();
903 are->deriver(tii,dxyz);
904 OT_VECTEUR_3D x1(dxyz[0],dxyz[1],dxyz[2]);
905 OT_VECTEUR_3D x2(dxyz[0],dxyz[1],dxyz[2]);
906 x1=are->get_mg_coarete(0)->get_orientation()*x1;
907 x2=are->get_mg_coarete(1)->get_orientation()*x2;
908 x1.norme();
909 x2.norme();
910 double uv1[2],uv2[2];
911 double normal1[3],normal2[3];
912 face1->inverser(uv1,xyz);
913 face2->inverser(uv2,xyz);
914 face1->calcul_normale_unitaire(uv1,normal1);
915 face2->calcul_normale_unitaire(uv2,normal2);
916 OT_VECTEUR_3D z1(normal1[0],normal1[1],normal1[2]);
917 OT_VECTEUR_3D z2(normal2[0],normal2[1],normal2[2]);
918 z1=face1->get_mg_coface(0)->get_orientation()*z1;
919 z2=face2->get_mg_coface(0)->get_orientation()*z2;
920 OT_VECTEUR_3D y1=z1&x1;
921 OT_VECTEUR_3D y2=z2&x2;
922 double test=(z1&z2)*x1;
923 int signe=-1;
924 OT_VECTEUR_3D dirpt=Pt-Ct;
925 if (test>0)
926 {if ((z1*dirpt>0.) || (z2*dirpt>0.)) signe=1;}
927 else
928 {if ((z1*dirpt>0.) && (z2*dirpt>0.)) signe=1;}
929 return signe*distance;
930 }
931
932 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_FACE* face,TOIBREP_POINT* pt,double *xyz,double *uv,double precision)
933 {
934 double uvii[2],eps;
935 pt->get_coord2(uvii);
936 int compteur=0;
937 OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
938 double delta_u,delta_v;
939 do
940 {
941 compteur++;
942 double uvi[2];
943 uvi[0]=uvii[0];
944 uvi[1]=uvii[1];
945 double xyzduu[3],xyzdvv[3],xyzduv[3],xyzdu[3],xyzdv[3],xyz[3];
946 face->deriver_seconde(uvi,xyzduu,xyzduv,xyzdvv,xyz,xyzdu,xyzdv);
947 OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
948 OT_VECTEUR_3D Su(xyzdu[0],xyzdu[1],xyzdu[2]);
949 OT_VECTEUR_3D Sv(xyzdv[0],xyzdv[1],xyzdv[2]);
950 OT_VECTEUR_3D Suu(xyzduu[0],xyzduu[1],xyzduu[2]);
951 OT_VECTEUR_3D Suv(xyzduv[0],xyzduv[1],xyzduv[2]);
952 OT_VECTEUR_3D Svv(xyzdvv[0],xyzdvv[1],xyzdvv[2]);
953 OT_VECTEUR_3D Distance = S-Pt;
954 double a[4],b[2];
955 a[0]=Su.get_longueur2()+Distance*Suu;
956 a[1]=Su*Sv+Distance*Suv;
957 a[2]=Su*Sv+Distance*Suv;
958 a[3]=Sv.get_longueur2()+Distance*Svv;
959 b[0]=Distance*Su;b[0]=-b[0];
960 b[1]=Distance*Sv;b[1]=-b[1];
961 double deltau,deltav;
962 double denominateur_delta=(a[0]*a[3]-a[2]*a[1]);
963 if (a[0]<1E-12)
964 deltau=0;
965 else delta_u=(b[0]*a[3]-b[1]*a[1])/denominateur_delta;
966 if (a[3]<1E-12)
967 deltav=0;
968 else delta_v=(a[0]*b[1]-a[2]*b[0])/denominateur_delta;
969 /*if (fabs(denominateur_delta) < ( (fabs(a[0])+fabs(a[1])+fabs(a[2])+fabs(a[3]))*1e-12 ) )
970 return 1e300;*/
971 uvii[0]=uvi[0]+delta_u;
972 uvii[1]=uvi[1]+delta_v;
973 if (face->get_surface()->est_periodique_u()==1)
974 {
975 if(uvii[0]<0.) uvii[0]=face->get_surface()->get_periode_u()-uvii[0];
976 if(uvii[0]>face->get_surface()->get_periode_u()) uvii[0]=uvii[0]-face->get_surface()->get_periode_u();
977 }
978 if (face->get_surface()->est_periodique_v()==1)
979 {
980 if(uvii[1]<0.) uvii[0]=face->get_surface()->get_periode_v()-uvii[1];
981 if(uvii[1]>face->get_surface()->get_periode_v()) uvii[1]=uvii[1]-face->get_surface()->get_periode_v();
982 }
983 delta_u=uvii[0]-uvi[0];
984 delta_v=uvii[1]-uvi[1];
985 if (compteur>500) return 1e300;
986 }
987
988 while ((fabs(delta_u)>precision)||(fabs(delta_v)>precision));
989 face->evaluer(uvii,xyz);
990 OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
991 double distance=(S-Pt).get_longueur();
992 uv[0]=uvii[0];
993 uv[1]=uvii[1];
994 return distance;
995 }
996
997
998
999 void TOIBREP::etendrelevelset(FEM_SOLUTION* sol,int numsol)
1000 {
1001 sol->active_solution(numsol);
1002
1003
1004 LISTE_FM know;
1005 LISTE_FM trial;
1006 LISTE_FM far;
1007 LISTE_FM exterieur;
1008 LISTE_FM_TRI trialtri;
1009 LISTE_FM_TRI_ID trialtriid;
1010
1011
1012 LISTE_FEM_TETRA::iterator ittet;
1013 for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1014 {
1015 tet->change_solution(0.);
1016 int numsol=0;
1017 if (tet->get_fem_noeud(0)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(0)->change_numero(1);} else tet->get_fem_noeud(0)->change_numero(0);
1018 if (tet->get_fem_noeud(1)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(1)->change_numero(1);} else tet->get_fem_noeud(1)->change_numero(0);
1019 if (tet->get_fem_noeud(2)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(2)->change_numero(1);} else tet->get_fem_noeud(2)->change_numero(0);
1020 if (tet->get_fem_noeud(3)->get_solution()<1e200) {numsol++;tet->get_fem_noeud(3)->change_numero(1);} else tet->get_fem_noeud(3)->change_numero(0);
1021 if (numsol==4)
1022 ajouter_liste(know,tet);
1023
1024 else if (numsol==3)
1025 {
1026 if (tet->get_fem_noeud(0)->get_numero()==0) tet->change_numero(0);
1027 else if (tet->get_fem_noeud(1)->get_numero()==0) tet->change_numero(1);
1028 else if (tet->get_fem_noeud(2)->get_numero()==0) tet->change_numero(2);
1029 else tet->change_numero(3);
1030 ajouter_liste(trial,tet);
1031 }
1032 else
1033 ajouter_liste(far,tet);
1034
1035 }
1036 for (LISTE_FM::iterator i=trial.begin();i!=trial.end();i++)
1037 {
1038 FEM_TETRA* tet=*i;
1039 int signe;
1040 double sol=resoudgradT(tet,&signe);
1041 if (fabs(sol)>0.00000001)
1042 {
1043 if (fabs(sol)<fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()))
1044 {
1045 tet->get_fem_noeud(tet->get_numero())->change_solution(sol);
1046 ajouter_liste(trialtri,trialtriid,tet,fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()));
1047 }
1048 }
1049 else
1050 {
1051 ajouter_liste(exterieur,tet);
1052 tet->change_solution(1e300);
1053 }
1054 }
1055 int fin=0;
1056 LISTE_FM_TRI::iterator itfin=trialtri.end();
1057 itfin--;
1058 double longref=(*itfin).first;
1059 do
1060 {
1061 LISTE_FM_TRI::iterator it=trialtri.begin();
1062 FEM_TETRA* tet=(*it).second;
1063 double longcourant=(*it).first;
1064 supprimer_liste(trialtri,trialtriid,tet);
1065 ajouter_liste(know,tet);
1066 FEM_NOEUD* noeud=tet->get_fem_noeud(tet->get_numero());
1067 noeud->change_numero(1);
1068 if (noeud->get_solution()>20000)
1069 cout << "BUGGGGGGG" <<endl;
1070 int nbtetra=noeud->get_lien_tetra()->get_nb();
1071 for (int i=0;i<nbtetra;i++)
1072 {
1073 FEM_TETRA* tet2=noeud->get_lien_tetra()->get(i);
1074 if (tet2==tet) continue;
1075 LISTE_FM_TRI_ID::iterator it=trialtriid.find(tet2->get_id());
1076 if (it!=trialtriid.end())
1077 {
1078 int signe;
1079 double sol=resoudgradT(tet2,&signe);
1080 double solution=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1081 if (fabs(sol)>0.00000001)
1082 if (!((solution<1e200)&&(sol*solution<0)))
1083 if (fabs(sol)<fabs(solution))
1084 {
1085 supprimer_liste(trialtri,trialtriid,tet2);
1086 ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1087 tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1088 }
1089 }
1090 LISTE_FM::iterator it2=find(far.begin(),far.end(),tet2);
1091 if (it2!=far.end())
1092 {
1093 int numsol=0;
1094 if (tet2->get_fem_noeud(0)->get_numero()==1) numsol++;
1095 if (tet2->get_fem_noeud(1)->get_numero()==1) numsol++;
1096 if (tet2->get_fem_noeud(2)->get_numero()==1) numsol++;
1097 if (tet2->get_fem_noeud(3)->get_numero()==1) numsol++;
1098 //if (numsol==4)
1099 //cout << " BUG " <<endl;
1100 if (numsol==3)
1101 {
1102 if (tet2->get_fem_noeud(0)->get_numero()==0) tet2->change_numero(0);
1103 else if (tet2->get_fem_noeud(1)->get_numero()==0) tet2->change_numero(1);
1104 else if (tet2->get_fem_noeud(2)->get_numero()==0) tet2->change_numero(2);
1105 else tet2->change_numero(3);
1106 int signe;
1107 double sol=resoudgradT(tet2,&signe);
1108 double ancsol=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1109 if (fabs(sol)>0.00000001)
1110 {
1111 if (!((ancsol<1e200) && (ancsol*sol<0.) ))
1112 {
1113 tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1114 supprimer_liste(far,tet2);
1115 ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1116 }
1117 }
1118 else
1119 {
1120 tet2->change_solution(1e300);
1121 ajouter_liste(exterieur,tet2);
1122 }
1123 }
1124 }
1125 }
1126 if (trialtri.size()==0) fin=1;
1127 if (exterieur.size()>0)
1128 if (fin==0)
1129 if (longcourant>longref)
1130 {
1131 int nombre=exterieur.size();
1132 for (int i=0;i<nombre;i++)
1133 {
1134 FEM_TETRA* tet2=(*(exterieur.begin()));
1135 supprimer_liste(exterieur,tet2);
1136 ajouter_liste(know,tet2);
1137 for (int nd=0;nd<4;nd++)
1138 {
1139 FEM_NOEUD* noeud=tet2->get_fem_noeud(nd);
1140 int nbtetra=noeud->get_lien_tetra()->get_nb();
1141 for (int i=0;i<nbtetra;i++)
1142 {
1143 FEM_TETRA* tet3=noeud->get_lien_tetra()->get(i);
1144 if (tet2==tet3) continue;
1145 LISTE_FM::iterator it2=find(far.begin(),far.end(),tet3);
1146 if (it2!=far.end())
1147 {
1148 supprimer_liste(far,tet3);
1149 ajouter_liste(exterieur,tet3);
1150 tet3->change_solution(1e300);
1151 }
1152 }
1153 }
1154 }
1155 LISTE_FM_TRI::iterator itfin=trialtri.end();
1156 itfin--;
1157 longref=(*itfin).first;
1158 }
1159 }
1160 while (fin==0);
1161 LISTE_FEM_NOEUD::iterator itnoeud;
1162 for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1163 noeud->change_numero(0);
1164 for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1165 {
1166 if (tet->get_solution()>1e200) continue;
1167 tet->get_fem_noeud(0)->change_numero(1);
1168 tet->get_fem_noeud(1)->change_numero(1);
1169 tet->get_fem_noeud(2)->change_numero(1);
1170 tet->get_fem_noeud(3)->change_numero(1);
1171 }
1172 int i=0;
1173 for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1174 {
1175 if (noeud->get_numero()==1) sol->ecrire(i,numsol,noeud->get_solution()); else sol->ecrire(i,numsol,1e300);
1176 ++i;
1177 }
1178 }
1179 IBrep TOIBREP::exporter_IBrep(string chemin,FEM_SOLUTION* solution,FEM_SOLUTION *solution_ele,MG_GROUPE_TOPOLOGIQUE* mggt)
1180 {
1181 TPL_MAP_ENTITE<MG_VOLUME*> lst;
1182 if (mggt==NULL)
1183 {
1184 int nbvol=geo->get_nb_mg_volume();
1185 for (int i=0;i<nbvol;i++)
1186 lst.ajouter(geo->get_mg_volume(i));
1187 }
1188 else
1189 {
1190 int nbmggt=mggt->get_nb();
1191 for (int i=0;i<nbmggt;i++)
1192 if (mggt->get(i)->get_dimension()==3)
1193 lst.ajouter((MG_VOLUME*)mggt->get(i));
1194 }
1195 IBrep brep(100);
1196 int nbvolexp=lst.get_nb();
1197 for (int i=0;i<nbvolexp;i++)
1198 {
1199 MG_VOLUME* vol=lst.get(i);
1200 int nbcoq=vol->get_nb_mg_coquille();
1201 IVolumeN ivoltmp(vol->get_id());
1202 pair<IVolume*,bool> pair_ivol=brep.AddVolume(ivoltmp);
1203 IVolume* ivol=pair_ivol.first;
1204 for (int j=0;j<nbcoq;j++)
1205 {
1206 MG_COQUILLE* coq=vol->get_mg_coquille(j);
1207 int nbface=coq->get_nb_mg_coface();
1208 IShell ishell(nbface);
1209 for (int k=0;k<nbface;k++)
1210 {
1211 MG_COFACE* coface=coq->get_mg_coface(k);
1212 ishell[k]=coface->get_id();
1213 MG_FACE* face=coface->get_face();
1214 int sens=coface->get_orientation();
1215 ICoFaceN icoface(coface->get_id(),face->get_id(),sens);
1216 brep.AddCoFace(icoface);
1217 IFace* iface=brep.GetFace(face->get_id());
1218 if (iface==NULL)
1219 {
1220 IFaceN ifacenew(face->get_id());
1221 pair<IFace*,bool> pair_iface=brep.AddFace(ifacenew);
1222 iface=pair_iface.first;
1223 int nbbou=face->get_nb_mg_boucle();
1224 for (int l=0;l<nbbou;l++)
1225 {
1226 MG_BOUCLE* bou=face->get_mg_boucle(l);
1227 int nbare=bou->get_nb_mg_coarete();
1228 ILoop iloop(nbare);
1229 for (int m=0;m<nbare;m++)
1230 {
1231 MG_COARETE* coare=bou->get_mg_coarete(m);
1232 iloop[m]=coare->get_id();
1233 MG_ARETE* are=coare->get_arete();
1234 int sens=coare->get_orientation();
1235 ICoEdgeN icoedge(coare->get_id(),are->get_id(),sens,face->get_id());
1236 brep.AddCoEdge(icoedge);
1237 IEdge* iedge=brep.GetEdge(are->get_id());
1238 IVertex *ivertex1,*ivertex2;
1239 ICoVertex *icover1,*icover2;
1240 if (iedge==NULL)
1241 {
1242 MG_COSOMMET* cover1=are->get_cosommet1();
1243 MG_COSOMMET* cover2=are->get_cosommet2();
1244 MG_SOMMET* ver1=cover1->get_sommet();
1245 MG_SOMMET* ver2=cover2->get_sommet();
1246 ICoVertexN icovertmp1(cover1->get_id(),are->get_id(),ver1->get_id(),cover1->get_t());
1247 ICoVertexN icovertmp2(cover2->get_id(),are->get_id(),ver2->get_id(),cover2->get_t());
1248 pair<ICoVertex*,bool> pair_icover1=brep.AddCoVertex(icovertmp1);
1249 pair<ICoVertex*,bool> pair_icover2=brep.AddCoVertex(icovertmp2);
1250 icover1=pair_icover1.first;
1251 icover2=pair_icover2.first;
1252 IEdgeN iedgetmp(are->get_id(),cover1->get_id(),cover2->get_id());
1253 ivertex1=brep.GetVertex(ver1->get_id());
1254 ivertex2=brep.GetVertex(ver2->get_id());
1255 if (ivertex1==NULL)
1256 {
1257 MG_POINT* pt=ver1->get_point();
1258 double xyz[3];
1259 pt->evaluer(xyz);
1260 IVertexN ivertex(ver1->get_id(),xyz);
1261 pair<IVertex*,bool> pair_ivertex1=brep.AddVertex(ivertex);
1262 ivertex1=pair_ivertex1.first;
1263 }
1264 if (ivertex2==NULL)
1265 {
1266 MG_POINT* pt=ver2->get_point();
1267 double xyz[3];
1268 pt->evaluer(xyz);
1269 IVertexN ivertex(ver2->get_id(),xyz);
1270 pair<IVertex*,bool> pair_ivertex2=brep.AddVertex(ivertex);
1271 ivertex2=pair_ivertex2.first;
1272 }
1273 ivertex1->AddCoVertex(cover1->get_id());
1274 ivertex2->AddCoVertex(cover2->get_id());
1275 pair<IEdge*,bool> pair_iedge=brep.AddEdge(iedgetmp);
1276 iedge=pair_iedge.first;
1277 }
1278 iedge->AddCoEdge(coare->get_id(),brep);
1279 if (sens==1)
1280 {
1281 icover1=brep.GetCoVertex(iedge->FromCoVertex());
1282 ivertex1=brep.GetVertex(icover1->Vertex());
1283 ivertex1->AddFace(face->get_id());
1284 }
1285 else
1286 {
1287 icover2=brep.GetCoVertex(iedge->ToCoVertex());
1288 ivertex2=brep.GetVertex(icover2->Vertex());
1289 ivertex2->AddFace(face->get_id());
1290 }
1291 }
1292 iface->AddLoop(iloop);
1293 }
1294 }
1295 iface->AddCoFace(coface->get_id());
1296 }
1297 ivol->AddShell(ishell);
1298 }
1299 }
1300 int nbsol=solution->get_nb_champ();
1301 unsigned long *correspondface=new unsigned long[nbsol];
1302 for (int i=0;i<nbsol;i++)
1303 {
1304 std::string nom=solution->get_legende(i);
1305 char nom2[2];
1306 unsigned long id;
1307 sscanf(nom.c_str(),"%s %lu",nom2,&id);
1308 correspondface[i]=id;
1309 }
1310 LISTE_FEM_NOEUD::iterator itnoeud;
1311 int i=0;
1312 for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1313 {
1314 int nbsolnoeud=0;
1315 for (int j=0;j<nbsol;j++)
1316 {
1317 if (solution->lire(i,j)<1e200) nbsolnoeud++;
1318 }
1319 double *xyz=noeud->get_coord();
1320 INodeN inoeudtmp(noeud->get_id(),xyz[0],xyz[1],xyz[2],nbsolnoeud);
1321 pair<INode*,bool> pair_inoeud=brep.AddNode(inoeudtmp);
1322 INode* inoeud=pair_inoeud.first;
1323 int num=0;
1324 for (int j=0;j<nbsol;j++)
1325 {
1326 if (solution->lire(i,j)<1e200)
1327 {
1328 inoeud->Fields()[num]=correspondface[j];
1329 inoeud->Values()[num]=solution->lire(i,j);
1330 num++;
1331 }
1332 }
1333 i++;
1334 }
1335 LISTE_FEM_TETRA::iterator ittet;
1336 int num=0;
1337 i=0;
1338 for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1339 {
1340 int nbsolele=0;
1341 for (int j=0;j<nbsol;j++)
1342 {
1343 if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001) nbsolele++;
1344 }
1345 IElementN xfemele(IElement::TETRAHEDRON,nbsolele);
1346 num++;
1347 xfemele.num=num;
1348 xfemele.GetNode(0)=tet->get_fem_noeud(0)->get_id();
1349 xfemele.GetNode(1)=tet->get_fem_noeud(1)->get_id();
1350 xfemele.GetNode(2)=tet->get_fem_noeud(2)->get_id();
1351 xfemele.GetNode(3)=tet->get_fem_noeud(3)->get_id();
1352 int num=0;
1353 for (int j=0;j<nbsol;j++)
1354 {
1355 if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001)
1356 {
1357 xfemele.Fields()[num]=correspondface[j];
1358 num++;
1359 }
1360 }
1361 brep.AddElement(xfemele);
1362 i++;
1363 }
1364
1365 delete [] correspondface;
1366
1367
1368
1369 std::ofstream output(chemin.c_str());
1370 output << brep << std::endl;
1371 output.close();
1372
1373
1374
1375
1376 return brep;
1377 }
1378
1379
1380
1381 void TOIBREP::ajouter_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet,double val)
1382 {
1383 pair<double,FEM_TETRA*> p(val,tet);
1384 LISTE_FM_TRI::iterator it=lst.insert(p);
1385 lstid[tet->get_id()]=it;
1386 }
1387
1388 void TOIBREP::supprimer_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet)
1389 {
1390 LISTE_FM_TRI::iterator it2=lstid[tet->get_id()];
1391 LISTE_FM_TRI_ID::iterator it3=lstid.find(tet->get_id());
1392 lstid.erase(it3);
1393 lst.erase(it2);
1394 }
1395
1396 void TOIBREP::ajouter_liste(LISTE_FM& lst,FEM_TETRA* tet)
1397 {
1398 lst.push_back(tet);
1399 }
1400
1401 void TOIBREP::supprimer_liste(LISTE_FM& lst,FEM_TETRA* tet)
1402 {
1403 LISTE_FM::iterator it=find(lst.begin(),lst.end(),tet);
1404 if (it!=lst.end()) lst.erase(it);
1405 }
1406
1407
1408
1409 double TOIBREP::resoudgradT(FEM_TETRA* tet,int *signe)
1410 {
1411 double j[9];
1412 double N[12];
1413 double jN[12]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
1414 double T[4];
1415 double uv[2]={0.25,0.25};
1416
1417
1418 tet->get_inverse_jacob(j,uv);
1419 for (int i=0;i<3;i++)
1420 for (int k=0;k<4;k++)
1421 N[i*4+k]=tet->get_fonction_derive_interpolation(k+1,i+1,uv);
1422 int premier=0;
1423 double tmin=1e300;
1424 double tmax=-1e300;
1425 for (int i=0;i<4;i++)
1426 {
1427 if (i==tet->get_numero()) continue;
1428 T[i]=tet->get_fem_noeud(i)->get_solution();
1429 if (fabs(T[i])>0.000001)
1430 {
1431 if (premier==0)
1432 if (T[i]>0) (*signe)=1; else (*signe)=-1;
1433 else if (T[i]*(*signe)<0) (*signe)=0;
1434 }
1435 T[i]=fabs(T[i]);
1436 if (tet->get_numero()!=i)
1437 {
1438 if (T[i]<tmin) tmin=T[i];
1439 if (T[i]>tmax) tmax=T[i];
1440 }
1441 premier=1;
1442 }
1443 for (int i=0;i<3;i++)
1444 for (int k=0;k<4;k++)
1445 for (int l=0;l<3;l++)
1446 jN[i*4+k]=jN[i*4+k]+j[i*3+l]*N[l*4+k];
1447 double a=0.,b=0.,c=-1.;
1448 for (int i=0;i<3;i++)
1449 {
1450 double coef=0.;
1451 double coefinc=0.;
1452 for (int l=0;l<4;l++)
1453 {
1454 if (tet->get_numero()!=l) coef=coef+jN[i*4+l]*T[l];
1455 else coefinc=coefinc+jN[i*4+l];
1456 }
1457 c=c+coef*coef;
1458 a=a+coefinc*coefinc;
1459 b=b+2*coef*coefinc;
1460 }
1461 /*if (*signe==0)
1462 cout << "attention " <<endl;*/
1463 double det=b*b-4.*a*c;
1464 if (det<0.) det=0.; else det=sqrt(det);
1465 double sol1=(-b-det)/2./a;
1466 double sol2=(-b+det)/2./a;
1467 double sol=sol1;
1468 if (sol2>sol1) sol=sol2;
1469 if (sol<tmin*0.99)
1470 sol=0.;
1471 sol=sol*(*signe);
1472 return sol;
1473 }