ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 276
Committed: Wed Jun 15 18:25:46 2011 UTC (13 years, 11 months ago) by francois
File size: 43778 byte(s)
Log Message:
Correction de bug + Version toIbrep  version du premier exmple complet + construction de la vectorisation a la lecture du fichier

File Contents

# User Rev Content
1 bechet 105 #include "gestionversion.h"
2 francois 259 #include "toibrep.h"
3 francois 104 #include "mg_file.h"
4     #include "ot_mathematique.h"
5     #include "tpl_map_entite.h"
6 francois 222 #include "tpl_relation_entite.h"
7 francois 104 #include "tpl_octree.h"
8 francois 259 #include "toibrep_point.h"
9 francois 106 #include "vct.h"
10 francois 104 #include <math.h>
11 francois 259 #include <fstream>
12 francois 262 #include <string>
13 francois 259 #include "IBrep.h"
14 francois 276 #include "ot_cpu.h"
15 francois 104
16    
17 francois 222
18 francois 276 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 francois 104 {
20     }
21    
22 francois 276 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 francois 104
32 francois 259 TOIBREP::~TOIBREP()
33 francois 104 {
34     }
35    
36    
37    
38 francois 276 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 francois 259 int TOIBREP::estdansletetra(FEM_TETRA *tet,double x,double y, double z)
55 francois 104 {
56 francois 222 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 francois 104 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 francois 276 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 francois 104 }
96    
97 francois 276
98    
99 francois 259 double TOIBREP::calculdist(double *n,double x,double y,double z,FEM_NOEUD* noeud)
100 francois 104 {
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 francois 259 //void TOIBREP::importer(std::string nomfichier,class MagXchange* data,std::string nomfichierout)
111 francois 276 IBrep TOIBREP::importer(std::string nomfichier,std::string nomfichieribrep,MG_GROUPE_TOPOLOGIQUE* mggt)
112 francois 104 {
113 francois 276 affiche((char*)"Traitement de base");
114 francois 222 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> lst;
115 francois 106 int nbface=geo->get_nb_mg_face();
116 francois 222 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 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base selection");
139 francois 222 int nb_noeud=mai->get_nb_fem_noeud();
140 francois 276 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 francois 222 int i=0;
144 francois 276 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 francois 222 for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
149 francois 106 {
150 francois 222 if (ele->get_dimension()!=2) continue;
151 francois 106 char mess[255];
152 francois 262 sprintf(mess,"F %lu",ele->get_id());
153 francois 276 solution->change_legende(i,mess);
154     solution_ele->change_legende(i,mess);
155 francois 222 ++i;
156 francois 106 }
157 francois 276
158     //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base creation solution");
159 francois 104 double xmin=1e300,ymin=1e300,zmin=1e308;
160     double xmax=-1e300,ymax=-1e300,zmax=-1e308;
161 francois 222 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 francois 104 {
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 francois 276 for (int j=0;j<nbvraiface;j++)
174 francois 106 solution->ecrire(i,j,1e300);
175 francois 104 lst_noeud.ajouter(noeud);
176 francois 222 i++;
177 francois 104 }
178 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base recherche boite");
179 francois 104 octree.initialiser(&lst_noeud,1,xmin,ymin,zmin,xmax,ymax,zmax);
180 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base ini octree");
181 francois 222 LISTE_FEM_TETRA::iterator it3;
182 francois 276 i=0;
183 francois 222 for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
184 francois 276 {
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 francois 106 for (int i=0;i<nbface;i++)
192     {
193 francois 276 if (affichageactif)
194     {
195     char mess[300];
196     sprintf(mess," Face %d",i);
197     affiche(mess);
198     }
199 francois 222 MG_FACE* face=geo->get_mg_face(i);
200     if (!lst.existe(face)) continue;
201 francois 106 vector<MG_FACE*> lstface;
202 francois 222 lstface.push_back(face);
203 francois 276 /// ici topologie virtuelle
204    
205    
206 francois 222 /*TPL_LISTE_ENTITE<double> lst;
207 francois 106 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 francois 222 }*/
238 francois 276 levelsetn(&lst,&lstface,solution,solution_ele,i);
239 francois 106 }
240 francois 276 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 francois 106 }
245    
246 francois 259 void TOIBREP::levelset0(FEM_SOLUTION *solution,int numsol)
247 francois 106 {
248 francois 276 /*solution->active_solution(numsol);
249 francois 104 int nbface=geo->get_nb_mg_face();
250 francois 259 vector<TOIBREP_POINT*> lst;
251 francois 104 for (int iface=0;iface<nbface;iface++)
252     {
253 francois 106 MG_FACE* face=geo->get_mg_face(iface);
254     int nbpoint=lst.size();
255 francois 104 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 francois 276 MG_TRIANGLE *tri=(Mvoid TOIBREP_POINT::get_coord2(double *uv)
259     {
260     uv[0]=u;
261     uv[1]=v;
262     }G_TRIANGLE*)ele;
263 francois 259 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 francois 106 lst.push_back(pt1);
267     lst.push_back(pt2);
268     lst.push_back(pt3);
269 francois 104 }
270 francois 222 calcullevelsetpremierepasse(solution,numsol,face,8,&lst,nbpoint,lst.size());
271 francois 106 }
272 francois 276 calcullevelsetdeuxiemepasse(solution,numsol,&lst);*/
273 francois 106 }
274 francois 276 void TOIBREP::echantillonne_sommet(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
275 francois 106 {
276 francois 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 francois 104 {
390 francois 276 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()) 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()) 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     LISTE_FEM_TETRA::iterator ittetra;
504     std::vector<FEM_TETRA*> couche;
505     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
506     {
507     FEM_NOEUD *no1=tet->get_fem_noeud(0);
508     FEM_NOEUD *no2=tet->get_fem_noeud(1);
509     FEM_NOEUD *no3=tet->get_fem_noeud(2);
510     FEM_NOEUD *no4=tet->get_fem_noeud(3);
511     int nbactif=0;
512     int nbpositif=0;
513     if (no1->get_etat())
514     {
515     nbactif++;
516     if (no1->get_solution()>0.) nbpositif++;
517     }
518     if (no2->get_etat())
519     {
520     nbactif++;
521     if (no2->get_solution()>0.) nbpositif++;
522     }
523     if (no3->get_etat())
524     {
525     nbactif++;
526     if (no3->get_solution()>0.) nbpositif++;
527     }
528     if (no4->get_etat())
529     {
530     nbactif++;
531     if (no4->get_solution()>0.) nbpositif++;
532     }
533     if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
534     {
535     couche.push_back(tet);
536     }
537     }
538     for (int i=0;i<couche.size();i++)
539     {
540     FEM_TETRA* tet=couche[i];
541     FEM_NOEUD *no1=tet->get_fem_noeud(0);
542     FEM_NOEUD *no2=tet->get_fem_noeud(1);
543     FEM_NOEUD *no3=tet->get_fem_noeud(2);
544     FEM_NOEUD *no4=tet->get_fem_noeud(3);
545     TOIBREP_POINT* pt;
546     FEM_NOEUD* noeudref;
547     if (!no1->get_etat()) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
548     if (!no2->get_etat()) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
549     if (!no3->get_etat()) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
550     if (!no4->get_etat()) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
551     MG_FACE* face=(MG_FACE*)pt->get_mg_element_topologique();
552     double dist=calcul_distance(noeudref,face,pt);
553     double uv[2];
554     double xyz[3];
555     pt->get_coord3(xyz);
556     double normal[3];
557     face->inverser(uv,xyz);
558     face->calcul_normale_unitaire(uv,normal);
559     normal[0]=normal[0]*sens*(-1.);
560     normal[1]=normal[1]*sens*(-1.);
561     normal[2]=normal[2]*sens*(-1.);
562     double dist2=calculdist(normal,xyz[0],xyz[1],xyz[2],noeudref);
563     if (dist2<0.) dist=dist*(-1);
564     noeudref->change_solution(dist);
565     noeudref->change_etat(1);
566     noeudref->change_numero(pt->get_id()); //provisoire
567    
568     }
569     for (FEM_TETRA* tet=mai->get_premier_tetra(ittetra);tet!=NULL;tet=mai->get_suivant_tetra(ittetra))
570     {
571     FEM_NOEUD *no1=tet->get_fem_noeud(0);
572     FEM_NOEUD *no2=tet->get_fem_noeud(1);
573     FEM_NOEUD *no3=tet->get_fem_noeud(2);
574     FEM_NOEUD *no4=tet->get_fem_noeud(3);
575     if (no1->get_etat())
576     if (no2->get_etat())
577     if (no3->get_etat())
578     if (no4->get_etat())
579     if (!tet->get_etat())
580     {
581     castot++;
582     double lst[5*3];
583     int nb=0;
584     decoupe_tetra(tet,lst,&nb);
585     for (int i=0;i<nb;i++)
586     {
587     double uv[2];
588     face->inverser(uv,lst+3*i);
589     if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
590     {
591     double distance=ot.calcule_distance_contour_face_uv(uv,face);
592     if (distance>1e-6)
593     {
594     cas++;
595     tet->change_etat(1);
596     break;
597     }
598     }
599     }
600     }
601     }
602     double res=cas*100.0/castot;
603     char mess[255];
604     sprintf(mess," %lf%%",res);
605     affiche(mess);
606     }
607    
608     void TOIBREP::decoupe_tetra(FEM_TETRA* tet,double* lst,int *nb)
609     {
610     FEM_NOEUD* no1=tet->get_fem_noeud(0);
611     FEM_NOEUD* no2=tet->get_fem_noeud(1);
612     FEM_NOEUD* no3=tet->get_fem_noeud(2);
613     FEM_NOEUD* no4=tet->get_fem_noeud(3);
614     if (no1->get_solution()*no2->get_solution()<-0.00000001)
615     {
616     double t=no1->get_solution()/(no1->get_solution()-no2->get_solution());
617     double x=no1->get_x()+t*(no2->get_x()-no1->get_x());
618     double y=no1->get_y()+t*(no2->get_y()-no1->get_y());
619     double z=no1->get_z()+t*(no2->get_z()-no1->get_z());
620     lst[3*(*nb)]=x;
621     lst[3*(*nb)+1]=y;
622     lst[3*(*nb)+2]=z;
623     (*nb)++;
624     }
625     if (no1->get_solution()*no3->get_solution()<-0.00000001)
626     {
627     double t=no1->get_solution()/(no1->get_solution()-no3->get_solution());
628     double x=no1->get_x()+t*(no3->get_x()-no1->get_x());
629     double y=no1->get_y()+t*(no3->get_y()-no1->get_y());
630     double z=no1->get_z()+t*(no3->get_z()-no1->get_z());
631     lst[3*(*nb)]=x;
632     lst[3*(*nb)+1]=y;
633     lst[3*(*nb)+2]=z;
634     (*nb)++;
635     }
636     if (no1->get_solution()*no4->get_solution()<-0.00000001)
637     {
638     double t=no1->get_solution()/(no1->get_solution()-no4->get_solution());
639     double x=no1->get_x()+t*(no4->get_x()-no1->get_x());
640     double y=no1->get_y()+t*(no4->get_y()-no1->get_y());
641     double z=no1->get_z()+t*(no4->get_z()-no1->get_z());
642     lst[3*(*nb)]=x;
643     lst[3*(*nb)+1]=y;
644     lst[3*(*nb)+2]=z;
645     (*nb)++;
646     }
647     if (no2->get_solution()*no3->get_solution()<-0.00000001)
648     {
649     double t=no2->get_solution()/(no2->get_solution()-no3->get_solution());
650     double x=no2->get_x()+t*(no3->get_x()-no2->get_x());
651     double y=no2->get_y()+t*(no3->get_y()-no2->get_y());
652     double z=no2->get_z()+t*(no3->get_z()-no2->get_z());
653     lst[3*(*nb)]=x;
654     lst[3*(*nb)+1]=y;
655     lst[3*(*nb)+2]=z;
656     (*nb)++;
657     }
658     if (no2->get_solution()*no4->get_solution()<-0.00000001)
659     {
660     double t=no2->get_solution()/(no2->get_solution()-no4->get_solution());
661     double x=no2->get_x()+t*(no4->get_x()-no2->get_x());
662     double y=no2->get_y()+t*(no4->get_y()-no2->get_y());
663     double z=no2->get_z()+t*(no4->get_z()-no2->get_z());
664     lst[3*(*nb)]=x;
665     lst[3*(*nb)+1]=y;
666     lst[3*(*nb)+2]=z;
667     (*nb)++;
668     }
669     if (no3->get_solution()*no4->get_solution()<-0.00000001)
670     {
671     double t=no3->get_solution()/(no3->get_solution()-no4->get_solution());
672     double x=no3->get_x()+t*(no4->get_x()-no3->get_x());
673     double y=no3->get_y()+t*(no4->get_y()-no3->get_y());
674     double z=no3->get_z()+t*(no4->get_z()-no3->get_z());
675     lst[3*(*nb)]=x;
676     lst[3*(*nb)+1]=y;
677     lst[3*(*nb)+2]=z;
678     (*nb)++;
679     }
680     }
681    
682     void TOIBREP::calcullevelsetpremierepasse(MG_FACE* face,int sens,vector<TOIBREP_POINT*> *lst,int n1,int n2)
683     {
684     /*LISTE_FEM_TETRA::iterator it3;
685     for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
686     {
687     double *xyz1,*xyz2,*xyz3,*xyz4;
688     if (tet->get_nb_fem_noeud()==4)
689     {
690     xyz1=tet->get_fem_noeud(0)->get_coord();
691     xyz2=tet->get_fem_noeud(1)->get_coord();
692     xyz3=tet->get_fem_noeud(2)->get_coord();
693     xyz4=tet->get_fem_noeud(3)->get_coord();
694     }
695     if (tet->get_nb_fem_noeud()==10)
696     {
697     xyz1=tet->get_fem_noeud(0)->get_coord();
698     xyz2=tet->get_fem_noeud(2)->get_coord();
699     xyz3=tet->get_fem_noeud(4)->get_coord();
700     xyz4=tet->get_fem_noeud(9)->get_coord();
701     }
702     double xcentre=0.25*(xyz1[0]+xyz2[0]+xyz3[0]+xyz4[0]);
703     double ycentre=0.25*(xyz1[1]+xyz2[1]+xyz3[1]+xyz4[1]);
704     double zcentre=0.25*(xyz1[2]+xyz2[2]+xyz3[2]+xyz4[2]);
705     double rayon1=(xyz1[0]-xcentre)*(xyz1[0]-xcentre)+(xyz1[1]-ycentre)*(xyz1[1]-ycentre)+(xyz1[2]-zcentre)*(xyz1[2]-zcentre);
706     double rayon2=(xyz2[0]-xcentre)*(xyz2[0]-xcentre)+(xyz2[1]-ycentre)*(xyz2[1]-ycentre)+(xyz2[2]-zcentre)*(xyz2[2]-zcentre);
707     double rayon3=(xyz3[0]-xcentre)*(xyz3[0]-xcentre)+(xyz3[1]-ycentre)*(xyz3[1]-ycentre)+(xyz3[2]-zcentre)*(xyz3[2]-zcentre);
708     double rayon4=(xyz4[0]-xcentre)*(xyz4[0]-xcentre)+(xyz4[1]-ycentre)*(xyz4[1]-ycentre)+(xyz4[2]-zcentre)*(xyz4[2]-zcentre);
709     double rayon=std::max(rayonETRA_ACTIF1,std::max(rayon2,std::max(rayon3,rayon4)));
710     rayon=sqrt(rayon);
711     TPL_MAP_ENTITE<TOIBREP_POINT*> liste;
712     octree.rechercher(xcentre,ycentre,zcentre,rayon,liste);
713     TPL_MAP_ENTITE<TOIBREP_POINT*>::ITERATEUR it;
714     for (TOIBREP_POINT* pt=liste.get_premier(it);pt!=NULL;pt=liste.get_suivant(it))
715     {
716     double xyzpt[3];
717     pt->get_coord3(xyzpt);
718     int etat=estdansletetra(tet,xyzpt[0],xyzpt[1],xyzpt[2]);
719     if (compare_etat(etat,INTERIEUR))
720     {
721     for (int k=0;k<tet->get_nb_fem_noeud();k++)
722     {
723     double normal[3];
724     double uv[2];
725     face->inverser(uv,xyzpt);
726     face->calcul_normale_unitaire(uv,normal);
727     normal[0]=normal[0]*sens*(-1.);
728     normal[1]=normal[1]*sens*(-1.);
729     normal[2]=normal[2]*sens*(-1.);
730     double dist=calculdist(normal,xyzpt[0],xyzpt[1],xyzpt[2],tet->get_fem_noeud(k));
731     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
732     {
733     tet->get_fem_noeud(k)->change_solution(dist);
734     tet->get_fem_noeud(k)->change_numero(pt->get_id());
735     pt->change_coord2(uv);
736     }
737     }
738     }
739     if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
740     {
741     tet->change_etat(1);
742     for (int k=0;k<tet->get_nb_fem_noeud();k++)
743     tet->get_fem_noeud(k)->change_etat(1);
744     }
745     if (tet->get_etat()==1) break;
746     }
747    
748     }
749     octree.vide();
750     }*/
751     /*LISTE_FEM_TETRA::iterator it3;
752     for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
753     octree.inserer(tet);*/
754     for (int i=n1;i<n2;i++)
755     {
756 francois 259 TOIBREP_POINT* pt=(*lst)[i];
757 francois 104 double uv[2];
758 francois 106 double xyz[3];
759     pt->get_coord3(xyz);
760 francois 222 double normal[3];
761 francois 104 face->inverser(uv,xyz);
762     face->calcul_normale_unitaire(uv,normal);
763 francois 222 normal[0]=normal[0]*sens*(-1.);
764     normal[1]=normal[1]*sens*(-1.);
765     normal[2]=normal[2]*sens*(-1.);
766     TPL_MAP_ENTITE<FEM_TETRA*> liste;
767 francois 259 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
768 francois 222 TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR it;
769     for (FEM_TETRA* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
770 francois 104 {
771 francois 276 if (tet->get_etat()==1) continue;
772     int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
773     if (compare_etat(etat,INTERIEUR))
774 francois 104 {
775 francois 222 for (int k=0;k<tet->get_nb_fem_noeud();k++)
776 francois 106 {
777 francois 222 double dist=calculdist(normal,xyz[0],xyz[1],xyz[2],tet->get_fem_noeud(k));
778     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
779     {
780     tet->get_fem_noeud(k)->change_solution(dist);
781     tet->get_fem_noeud(k)->change_numero(pt->get_id());
782     pt->change_coord2(uv);
783     }
784 francois 106 }
785 francois 104 }
786 francois 276 if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
787     {
788     tet->change_etat(1);
789     for (int k=0;k<tet->get_nb_fem_noeud();k++)
790     {
791     tet->get_fem_noeud(k)->change_etat(1);
792     //octree.supprimer(tet);
793     }
794     }
795 francois 104 }
796     }
797 francois 276 //octree.vide();
798    
799    
800    
801    
802 francois 106 }
803    
804 francois 276 void TOIBREP::calcullevelsetdeuxiemepasse(vector<TOIBREP_POINT*> *lst)
805 francois 106 {
806 francois 276 LISTE_FEM_NOEUD::iterator itno;
807     for (FEM_NOEUD* no=mai->get_premier_noeud(itno);no!=NULL;no=mai->get_suivant_noeud(itno))
808     if (no->get_solution()<1e250)
809 francois 106 {
810 francois 276 TOIBREP_POINT* pt=(*lst)[no->get_numero()];
811 francois 106 int dim=pt->get_mg_element_topologique()->get_dimension();
812     if (dim==2)
813     {
814     MG_FACE* face=(MG_FACE*)pt->get_mg_element_topologique();
815 francois 276 double dist=calcul_distance(no,face,pt);
816 francois 106 int signe=1;
817 francois 276 if (no->get_solution()<0) signe=-1;
818     no->change_solution(signe*dist);
819 francois 106 }
820     if (dim==1)
821     {
822     MG_ARETE* arete=(MG_ARETE*)pt->get_mg_element_topologique();
823 francois 276 double dist=calcul_distance(no,arete,pt);
824     no->change_solution(dist);
825 francois 106 }
826     if (dim==0)
827     {
828     MG_SOMMET* sommet=(MG_SOMMET*)pt->get_mg_element_topologique();
829     MG_ARETE* arete=sommet->get_mg_cosommet(0)->get_arete();
830 francois 276 double dist=calcul_distance(no,arete,pt);
831     no->change_solution(dist);
832 francois 106 }
833    
834     }
835 francois 104
836 francois 276
837    
838    
839 francois 106 }
840    
841 francois 259 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_ARETE* are,TOIBREP_POINT* pt,double precision)
842 francois 106 {
843     double tii,eps;
844     are->inverser(tii,noeud->get_coord());
845     int compteur=0;
846     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
847     do
848     {
849     compteur++;
850     double ti=tii;
851     double xyz[3],dxyz[3],ddxyz[3];
852     are->deriver_seconde(ti,ddxyz,dxyz,xyz);
853     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
854     OT_VECTEUR_3D Ct_deriver(dxyz[0],dxyz[1],dxyz[2]);
855     OT_VECTEUR_3D Ct_deriver_seconde(ddxyz[0],ddxyz[1],ddxyz[2]);
856     OT_VECTEUR_3D Distance = Ct-Pt;
857     tii=ti-Ct_deriver*Distance/(Ct_deriver_seconde*Distance+Ct_deriver.get_longueur2());
858     eps=fabs(tii-ti);
859     if (compteur>500) return 1e300;
860     if (tii<are->get_tmin())
861     {
862     tii=are->get_tmin();
863     eps=0.;
864     }
865     if (tii>are->get_tmax())
866     {
867     tii=are->get_tmax();
868     eps=0.;
869     }
870     }
871     while (eps>precision);
872     double xyz[3],dxyz[3];
873     are->evaluer(tii,xyz);
874     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
875     double distance=(Ct-Pt).get_longueur();
876     MG_FACE* face1=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
877     MG_FACE* face2=are->get_mg_coarete(1)->get_boucle()->get_mg_face();
878     are->deriver(tii,dxyz);
879     OT_VECTEUR_3D x1(dxyz[0],dxyz[1],dxyz[2]);
880     OT_VECTEUR_3D x2(dxyz[0],dxyz[1],dxyz[2]);
881     x1=are->get_mg_coarete(0)->get_orientation()*x1;
882     x2=are->get_mg_coarete(1)->get_orientation()*x2;
883     x1.norme();
884     x2.norme();
885     double uv1[2],uv2[2];
886     double normal1[3],normal2[3];
887     face1->inverser(uv1,xyz);
888     face2->inverser(uv2,xyz);
889     face1->calcul_normale_unitaire(uv1,normal1);
890     face2->calcul_normale_unitaire(uv2,normal2);
891     OT_VECTEUR_3D z1(normal1[0],normal1[1],normal1[2]);
892     OT_VECTEUR_3D z2(normal2[0],normal2[1],normal2[2]);
893     z1=face1->get_mg_coface(0)->get_orientation()*z1;
894     z2=face2->get_mg_coface(0)->get_orientation()*z2;
895     OT_VECTEUR_3D y1=z1&x1;
896     OT_VECTEUR_3D y2=z2&x2;
897     double test=(z1&z2)*x1;
898     int signe=-1;
899     OT_VECTEUR_3D dirpt=Pt-Ct;
900     if (test>0)
901     {if ((z1*dirpt>0.) || (z2*dirpt>0.)) signe=1;}
902     else
903     {if ((z1*dirpt>0.) && (z2*dirpt>0.)) signe=1;}
904     return signe*distance;
905     }
906    
907 francois 259 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_FACE* face,TOIBREP_POINT* pt,double precision)
908 francois 106 {
909     double uvii[2],eps;
910     pt->get_coord2(uvii);
911     int compteur=0;
912     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
913     double delta_u,delta_v;
914     do
915     {
916     compteur++;
917     double uvi[2];
918     uvi[0]=uvii[0];
919     uvi[1]=uvii[1];
920     double xyzduu[3],xyzdvv[3],xyzduv[3],xyzdu[3],xyzdv[3],xyz[3];
921     face->deriver_seconde(uvi,xyzduu,xyzduv,xyzdvv,xyz,xyzdu,xyzdv);
922     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
923     OT_VECTEUR_3D Su(xyzdu[0],xyzdu[1],xyzdu[2]);
924     OT_VECTEUR_3D Sv(xyzdv[0],xyzdv[1],xyzdv[2]);
925     OT_VECTEUR_3D Suu(xyzduu[0],xyzduu[1],xyzduu[2]);
926     OT_VECTEUR_3D Suv(xyzduv[0],xyzduv[1],xyzduv[2]);
927     OT_VECTEUR_3D Svv(xyzdvv[0],xyzdvv[1],xyzdvv[2]);
928     OT_VECTEUR_3D Distance = S-Pt;
929     double a[4],b[2];
930     a[0]=Su.get_longueur2()+Distance*Suu;
931     a[1]=Su*Sv+Distance*Suv;
932     a[2]=Su*Sv+Distance*Suv;
933     a[3]=Sv.get_longueur2()+Distance*Svv;
934     b[0]=Distance*Su;b[0]=-b[0];
935     b[1]=Distance*Sv;b[1]=-b[1];
936     double deltau,deltav;
937     double denominateur_delta=(a[0]*a[3]-a[2]*a[1]);
938     if (a[0]<1E-12)
939     deltau=0;
940     else delta_u=(b[0]*a[3]-b[1]*a[1])/denominateur_delta;
941     if (a[3]<1E-12)
942     deltav=0;
943     else delta_v=(a[0]*b[1]-a[2]*b[0])/denominateur_delta;
944     /*if (fabs(denominateur_delta) < ( (fabs(a[0])+fabs(a[1])+fabs(a[2])+fabs(a[3]))*1e-12 ) )
945     return 1e300;*/
946     uvii[0]=uvi[0]+delta_u;
947     uvii[1]=uvi[1]+delta_v;
948     if (face->get_surface()->est_periodique_u()==1)
949     {
950     if(uvii[0]<0.) uvii[0]=face->get_surface()->get_periode_u()-uvii[0];
951     if(uvii[0]>face->get_surface()->get_periode_u()) uvii[0]=uvii[0]-face->get_surface()->get_periode_u();
952     }
953     if (face->get_surface()->est_periodique_v()==1)
954     {
955     if(uvii[1]<0.) uvii[0]=face->get_surface()->get_periode_v()-uvii[1];
956     if(uvii[1]>face->get_surface()->get_periode_v()) uvii[1]=uvii[1]-face->get_surface()->get_periode_v();
957     }
958     delta_u=uvii[0]-uvi[0];
959     delta_v=uvii[1]-uvi[1];
960     if (compteur>500) return 1e300;
961     }
962    
963     while ((fabs(delta_u)>precision)||(fabs(delta_v)>precision));
964     double xyz[3];
965     face->evaluer(uvii,xyz);
966     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
967     double distance=(S-Pt).get_longueur();
968     return distance;
969     }
970    
971    
972 francois 276
973 francois 259 void TOIBREP::etendrelevelset(FEM_SOLUTION* sol,int numsol)
974 francois 222 {
975     sol->active_solution(numsol);
976    
977    
978     LISTE_FM know;
979     LISTE_FM trial;
980     LISTE_FM far;
981     LISTE_FM exterieur;
982     LISTE_FM_TRI trialtri;
983     LISTE_FM_TRI_ID trialtriid;
984    
985    
986     LISTE_FEM_TETRA::iterator ittet;
987     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
988     {
989     tet->change_solution(0.);
990     int numsol=0;
991     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);
992     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);
993     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);
994     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);
995     if (numsol==4)
996     ajouter_liste(know,tet);
997    
998     else if (numsol==3)
999     {
1000     if (tet->get_fem_noeud(0)->get_numero()==0) tet->change_numero(0);
1001     else if (tet->get_fem_noeud(1)->get_numero()==0) tet->change_numero(1);
1002     else if (tet->get_fem_noeud(2)->get_numero()==0) tet->change_numero(2);
1003     else tet->change_numero(3);
1004     ajouter_liste(trial,tet);
1005     }
1006     else
1007     ajouter_liste(far,tet);
1008    
1009     }
1010     for (LISTE_FM::iterator i=trial.begin();i!=trial.end();i++)
1011     {
1012     FEM_TETRA* tet=*i;
1013     int signe;
1014     double sol=resoudgradT(tet,&signe);
1015     if (fabs(sol)>0.00000001)
1016     {
1017     if (fabs(sol)<fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()))
1018     {
1019     tet->get_fem_noeud(tet->get_numero())->change_solution(sol);
1020     ajouter_liste(trialtri,trialtriid,tet,fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()));
1021     }
1022     }
1023     else
1024     {
1025     ajouter_liste(exterieur,tet);
1026     tet->change_solution(1e300);
1027     }
1028     }
1029     int fin=0;
1030     LISTE_FM_TRI::iterator itfin=trialtri.end();
1031     itfin--;
1032     double longref=(*itfin).first;
1033     do
1034     {
1035     LISTE_FM_TRI::iterator it=trialtri.begin();
1036     FEM_TETRA* tet=(*it).second;
1037     double longcourant=(*it).first;
1038     supprimer_liste(trialtri,trialtriid,tet);
1039     ajouter_liste(know,tet);
1040     FEM_NOEUD* noeud=tet->get_fem_noeud(tet->get_numero());
1041     noeud->change_numero(1);
1042     if (noeud->get_solution()>20000)
1043     cout << "BUGGGGGGG" <<endl;
1044     int nbtetra=noeud->get_lien_tetra()->get_nb();
1045     for (int i=0;i<nbtetra;i++)
1046     {
1047     FEM_TETRA* tet2=noeud->get_lien_tetra()->get(i);
1048     if (tet2==tet) continue;
1049     LISTE_FM_TRI_ID::iterator it=trialtriid.find(tet2->get_id());
1050     if (it!=trialtriid.end())
1051     {
1052     int signe;
1053     double sol=resoudgradT(tet2,&signe);
1054     double solution=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1055     if (fabs(sol)>0.00000001)
1056     if (!((solution<1e200)&&(sol*solution<0)))
1057     if (fabs(sol)<fabs(solution))
1058     {
1059     supprimer_liste(trialtri,trialtriid,tet2);
1060     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1061     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1062     }
1063     }
1064     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet2);
1065     if (it2!=far.end())
1066     {
1067     int numsol=0;
1068     if (tet2->get_fem_noeud(0)->get_numero()==1) numsol++;
1069     if (tet2->get_fem_noeud(1)->get_numero()==1) numsol++;
1070     if (tet2->get_fem_noeud(2)->get_numero()==1) numsol++;
1071     if (tet2->get_fem_noeud(3)->get_numero()==1) numsol++;
1072     //if (numsol==4)
1073     //cout << " BUG " <<endl;
1074     if (numsol==3)
1075     {
1076     if (tet2->get_fem_noeud(0)->get_numero()==0) tet2->change_numero(0);
1077     else if (tet2->get_fem_noeud(1)->get_numero()==0) tet2->change_numero(1);
1078     else if (tet2->get_fem_noeud(2)->get_numero()==0) tet2->change_numero(2);
1079     else tet2->change_numero(3);
1080     int signe;
1081     double sol=resoudgradT(tet2,&signe);
1082     double ancsol=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1083     if (fabs(sol)>0.00000001)
1084     {
1085     if (!((ancsol<1e200) && (ancsol*sol<0.) ))
1086     {
1087     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1088     supprimer_liste(far,tet2);
1089     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1090     }
1091     }
1092     else
1093     {
1094     tet2->change_solution(1e300);
1095     ajouter_liste(exterieur,tet2);
1096     }
1097     }
1098     }
1099     }
1100     if (trialtri.size()==0) fin=1;
1101     if (exterieur.size()>0)
1102     if (fin==0)
1103     if (longcourant>longref)
1104     {
1105     int nombre=exterieur.size();
1106     for (int i=0;i<nombre;i++)
1107     {
1108     FEM_TETRA* tet2=(*(exterieur.begin()));
1109     supprimer_liste(exterieur,tet2);
1110     ajouter_liste(know,tet2);
1111     for (int nd=0;nd<4;nd++)
1112     {
1113     FEM_NOEUD* noeud=tet2->get_fem_noeud(nd);
1114     int nbtetra=noeud->get_lien_tetra()->get_nb();
1115     for (int i=0;i<nbtetra;i++)
1116     {
1117     FEM_TETRA* tet3=noeud->get_lien_tetra()->get(i);
1118     if (tet2==tet3) continue;
1119     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet3);
1120     if (it2!=far.end())
1121     {
1122     supprimer_liste(far,tet3);
1123     ajouter_liste(exterieur,tet3);
1124     tet3->change_solution(1e300);
1125     }
1126     }
1127     }
1128     }
1129     LISTE_FM_TRI::iterator itfin=trialtri.end();
1130     itfin--;
1131     longref=(*itfin).first;
1132     }
1133     }
1134     while (fin==0);
1135     LISTE_FEM_NOEUD::iterator itnoeud;
1136     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1137     noeud->change_numero(0);
1138     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1139     {
1140     if (tet->get_solution()>1e200) continue;
1141     tet->get_fem_noeud(0)->change_numero(1);
1142     tet->get_fem_noeud(1)->change_numero(1);
1143     tet->get_fem_noeud(2)->change_numero(1);
1144     tet->get_fem_noeud(3)->change_numero(1);
1145     }
1146     int i=0;
1147     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1148     {
1149     if (noeud->get_numero()==1) sol->ecrire(i,numsol,noeud->get_solution()); else sol->ecrire(i,numsol,1e300);
1150     ++i;
1151     }
1152     }
1153 francois 276 IBrep TOIBREP::exporter_IBrep(string chemin,FEM_SOLUTION* solution,FEM_SOLUTION *solution_ele,MG_GROUPE_TOPOLOGIQUE* mggt)
1154 francois 259 {
1155     TPL_MAP_ENTITE<MG_VOLUME*> lst;
1156     if (mggt==NULL)
1157     {
1158     int nbvol=geo->get_nb_mg_volume();
1159     for (int i=0;i<nbvol;i++)
1160     lst.ajouter(geo->get_mg_volume(i));
1161     }
1162     else
1163     {
1164     int nbmggt=mggt->get_nb();
1165     for (int i=0;i<nbmggt;i++)
1166     if (mggt->get(i)->get_dimension()==3)
1167     lst.ajouter((MG_VOLUME*)mggt->get(i));
1168     }
1169     IBrep brep(100);
1170     int nbvolexp=lst.get_nb();
1171     for (int i=0;i<nbvolexp;i++)
1172     {
1173     MG_VOLUME* vol=lst.get(i);
1174     int nbcoq=vol->get_nb_mg_coquille();
1175     IVolumeN ivoltmp(vol->get_id());
1176 francois 263 pair<IVolume*,bool> pair_ivol=brep.AddVolume(ivoltmp);
1177     IVolume* ivol=pair_ivol.first;
1178 francois 259 for (int j=0;j<nbcoq;j++)
1179     {
1180     MG_COQUILLE* coq=vol->get_mg_coquille(j);
1181     int nbface=coq->get_nb_mg_coface();
1182     IShell ishell(nbface);
1183     for (int k=0;k<nbface;k++)
1184     {
1185     MG_COFACE* coface=coq->get_mg_coface(k);
1186     ishell[k]=coface->get_id();
1187     MG_FACE* face=coface->get_face();
1188     int sens=coface->get_orientation();
1189     ICoFaceN icoface(coface->get_id(),face->get_id(),sens);
1190     brep.AddCoFace(icoface);
1191     IFace* iface=brep.GetFace(face->get_id());
1192     if (iface==NULL)
1193     {
1194     IFaceN ifacenew(face->get_id());
1195 francois 263 pair<IFace*,bool> pair_iface=brep.AddFace(ifacenew);
1196     iface=pair_iface.first;
1197 francois 259 int nbbou=face->get_nb_mg_boucle();
1198     for (int l=0;l<nbbou;l++)
1199     {
1200     MG_BOUCLE* bou=face->get_mg_boucle(l);
1201     int nbare=bou->get_nb_mg_coarete();
1202     ILoop iloop(nbare);
1203     for (int m=0;m<nbare;m++)
1204     {
1205     MG_COARETE* coare=bou->get_mg_coarete(m);
1206     iloop[m]=coare->get_id();
1207     MG_ARETE* are=coare->get_arete();
1208     int sens=coare->get_orientation();
1209     ICoEdgeN icoedge(coare->get_id(),are->get_id(),sens,face->get_id());
1210     brep.AddCoEdge(icoedge);
1211     IEdge* iedge=brep.GetEdge(are->get_id());
1212     IVertex *ivertex1,*ivertex2;
1213     ICoVertex *icover1,*icover2;
1214     if (iedge==NULL)
1215     {
1216     MG_COSOMMET* cover1=are->get_cosommet1();
1217     MG_COSOMMET* cover2=are->get_cosommet2();
1218     MG_SOMMET* ver1=cover1->get_sommet();
1219     MG_SOMMET* ver2=cover2->get_sommet();
1220     ICoVertexN icovertmp1(cover1->get_id(),are->get_id(),ver1->get_id(),cover1->get_t());
1221     ICoVertexN icovertmp2(cover2->get_id(),are->get_id(),ver2->get_id(),cover2->get_t());
1222 francois 263 pair<ICoVertex*,bool> pair_icover1=brep.AddCoVertex(icovertmp1);
1223     pair<ICoVertex*,bool> pair_icover2=brep.AddCoVertex(icovertmp2);
1224     icover1=pair_icover1.first;
1225     icover2=pair_icover2.first;
1226 francois 259 IEdgeN iedgetmp(are->get_id(),cover1->get_id(),cover2->get_id());
1227     ivertex1=brep.GetVertex(ver1->get_id());
1228     ivertex2=brep.GetVertex(ver2->get_id());
1229     if (ivertex1==NULL)
1230     {
1231     MG_POINT* pt=ver1->get_point();
1232     double xyz[3];
1233     pt->evaluer(xyz);
1234     IVertexN ivertex(ver1->get_id(),xyz);
1235 francois 263 pair<IVertex*,bool> pair_ivertex1=brep.AddVertex(ivertex);
1236     ivertex1=pair_ivertex1.first;
1237 francois 259 }
1238     if (ivertex2==NULL)
1239     {
1240     MG_POINT* pt=ver2->get_point();
1241     double xyz[3];
1242     pt->evaluer(xyz);
1243     IVertexN ivertex(ver2->get_id(),xyz);
1244 francois 263 pair<IVertex*,bool> pair_ivertex2=brep.AddVertex(ivertex);
1245     ivertex2=pair_ivertex2.first;
1246 francois 259 }
1247     ivertex1->AddCoVertex(cover1->get_id());
1248     ivertex2->AddCoVertex(cover2->get_id());
1249 francois 263 pair<IEdge*,bool> pair_iedge=brep.AddEdge(iedgetmp);
1250     iedge=pair_iedge.first;
1251 francois 259 }
1252     iedge->AddCoEdge(coare->get_id(),brep);
1253     if (sens==1)
1254     {
1255     icover1=brep.GetCoVertex(iedge->FromCoVertex());
1256     ivertex1=brep.GetVertex(icover1->Vertex());
1257     ivertex1->AddFace(face->get_id());
1258     }
1259     else
1260     {
1261     icover2=brep.GetCoVertex(iedge->ToCoVertex());
1262     ivertex2=brep.GetVertex(icover2->Vertex());
1263     ivertex2->AddFace(face->get_id());
1264     }
1265     }
1266     iface->AddLoop(iloop);
1267     }
1268     }
1269     iface->AddCoFace(coface->get_id());
1270     }
1271     ivol->AddShell(ishell);
1272     }
1273     }
1274     int nbsol=solution->get_nb_champ();
1275 francois 262 unsigned long *correspondface=new unsigned long[nbsol];
1276     for (int i=0;i<nbsol;i++)
1277     {
1278     std::string nom=solution->get_legende(i);
1279     char nom2[2];
1280     unsigned long id;
1281 francois 272 sscanf(nom.c_str(),"%s %lu",nom2,&id);
1282 francois 262 correspondface[i]=id;
1283     }
1284 francois 259 LISTE_FEM_NOEUD::iterator itnoeud;
1285     int i=0;
1286     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1287     {
1288     int nbsolnoeud=0;
1289     for (int j=0;j<nbsol;j++)
1290     {
1291     if (solution->lire(i,j)<1e200) nbsolnoeud++;
1292     }
1293     double *xyz=noeud->get_coord();
1294     INodeN inoeudtmp(noeud->get_id(),xyz[0],xyz[1],xyz[2],nbsolnoeud);
1295 francois 263 pair<INode*,bool> pair_inoeud=brep.AddNode(inoeudtmp);
1296     INode* inoeud=pair_inoeud.first;
1297 francois 259 int num=0;
1298     for (int j=0;j<nbsol;j++)
1299     {
1300     if (solution->lire(i,j)<1e200)
1301     {
1302 francois 262 inoeud->Fields()[num]=correspondface[j];
1303 francois 259 inoeud->Values()[num]=solution->lire(i,j);
1304     num++;
1305     }
1306     }
1307     i++;
1308     }
1309     LISTE_FEM_TETRA::iterator ittet;
1310     int num=0;
1311 francois 276 i=0;
1312 francois 259 for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
1313     {
1314 francois 276 int nbsolele=0;
1315     for (int j=0;j<nbsol;j++)
1316     {
1317     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001) nbsolele++;
1318     }
1319     IElementN xfemele(IElement::TETRAHEDRON,nbsolele);
1320 francois 259 num++;
1321     xfemele.num=num;
1322     xfemele.GetNode(0)=tet->get_fem_noeud(0)->get_id();
1323     xfemele.GetNode(1)=tet->get_fem_noeud(1)->get_id();
1324     xfemele.GetNode(2)=tet->get_fem_noeud(2)->get_id();
1325     xfemele.GetNode(3)=tet->get_fem_noeud(3)->get_id();
1326 francois 276 int num=0;
1327     for (int j=0;j<nbsol;j++)
1328     {
1329     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001)
1330     {
1331     xfemele.Fields()[num]=correspondface[j];
1332     num++;
1333     }
1334     }
1335 francois 259 brep.AddElement(xfemele);
1336 francois 276 i++;
1337 francois 259 }
1338 francois 222
1339 francois 276 delete [] correspondface;
1340 francois 259
1341    
1342    
1343     std::ofstream output(chemin.c_str());
1344     output << brep << std::endl;
1345     output.close();
1346    
1347 francois 262
1348    
1349    
1350 francois 276 return brep;
1351 francois 259 }
1352    
1353    
1354    
1355     void TOIBREP::ajouter_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet,double val)
1356 francois 222 {
1357     pair<double,FEM_TETRA*> p(val,tet);
1358     LISTE_FM_TRI::iterator it=lst.insert(p);
1359     lstid[tet->get_id()]=it;
1360     }
1361    
1362 francois 259 void TOIBREP::supprimer_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet)
1363 francois 222 {
1364     LISTE_FM_TRI::iterator it2=lstid[tet->get_id()];
1365     LISTE_FM_TRI_ID::iterator it3=lstid.find(tet->get_id());
1366     lstid.erase(it3);
1367     lst.erase(it2);
1368     }
1369    
1370 francois 259 void TOIBREP::ajouter_liste(LISTE_FM& lst,FEM_TETRA* tet)
1371 francois 222 {
1372     lst.push_back(tet);
1373     }
1374    
1375 francois 259 void TOIBREP::supprimer_liste(LISTE_FM& lst,FEM_TETRA* tet)
1376 francois 222 {
1377     LISTE_FM::iterator it=find(lst.begin(),lst.end(),tet);
1378     if (it!=lst.end()) lst.erase(it);
1379     }
1380    
1381    
1382    
1383 francois 259 double TOIBREP::resoudgradT(FEM_TETRA* tet,int *signe)
1384 francois 222 {
1385     double j[9];
1386     double N[12];
1387     double jN[12]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
1388     double T[4];
1389     double uv[2]={0.25,0.25};
1390    
1391    
1392     tet->get_inverse_jacob(j,uv);
1393     for (int i=0;i<3;i++)
1394     for (int k=0;k<4;k++)
1395     N[i*4+k]=tet->get_fonction_derive_interpolation(k+1,i+1,uv);
1396     int premier=0;
1397     double tmin=1e300;
1398     double tmax=-1e300;
1399     for (int i=0;i<4;i++)
1400     {
1401     if (i==tet->get_numero()) continue;
1402     T[i]=tet->get_fem_noeud(i)->get_solution();
1403     if (fabs(T[i])>0.000001)
1404     {
1405     if (premier==0)
1406     if (T[i]>0) (*signe)=1; else (*signe)=-1;
1407     else if (T[i]*(*signe)<0) (*signe)=0;
1408     }
1409     T[i]=fabs(T[i]);
1410     if (tet->get_numero()!=i)
1411     {
1412     if (T[i]<tmin) tmin=T[i];
1413     if (T[i]>tmax) tmax=T[i];
1414     }
1415     premier=1;
1416     }
1417     for (int i=0;i<3;i++)
1418     for (int k=0;k<4;k++)
1419     for (int l=0;l<3;l++)
1420     jN[i*4+k]=jN[i*4+k]+j[i*3+l]*N[l*4+k];
1421     double a=0.,b=0.,c=-1.;
1422     for (int i=0;i<3;i++)
1423     {
1424     double coef=0.;
1425     double coefinc=0.;
1426     for (int l=0;l<4;l++)
1427     {
1428     if (tet->get_numero()!=l) coef=coef+jN[i*4+l]*T[l];
1429     else coefinc=coefinc+jN[i*4+l];
1430     }
1431     c=c+coef*coef;
1432     a=a+coefinc*coefinc;
1433     b=b+2*coef*coefinc;
1434     }
1435     /*if (*signe==0)
1436     cout << "attention " <<endl;*/
1437     double det=b*b-4.*a*c;
1438     if (det<0.) det=0.; else det=sqrt(det);
1439     double sol1=(-b-det)/2./a;
1440     double sol2=(-b+det)/2./a;
1441     double sol=sol1;
1442     if (sol2>sol1) sol=sol2;
1443     if (sol<tmin*0.99)
1444     sol=0.;
1445     sol=sol*(*signe);
1446     return sol;
1447     }