ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 259
Committed: Fri Aug 13 14:12:04 2010 UTC (14 years, 9 months ago) by francois
File size: 27883 byte(s)
Log Message:
Changement de nom du projet toxfem pour toIbrep

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     #include "IBrep.h"
13 francois 104
14    
15 francois 222
16 francois 259 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas):geo(ge),gest(g),mai(femm),NPAS(nbpas)
17 francois 104 {
18     }
19    
20    
21 francois 259 TOIBREP::~TOIBREP()
22 francois 104 {
23     }
24    
25    
26    
27 francois 259 int TOIBREP::estdansletetra(FEM_TETRA *tet,double x,double y, double z)
28 francois 104 {
29 francois 222 double *xyz1,*xyz2,*xyz3,*xyz4;
30     if (tet->get_nb_fem_noeud()==4)
31     {
32     xyz1=tet->get_fem_noeud(0)->get_coord();
33     xyz2=tet->get_fem_noeud(1)->get_coord();
34     xyz3=tet->get_fem_noeud(2)->get_coord();
35     xyz4=tet->get_fem_noeud(3)->get_coord();
36     }
37     if (tet->get_nb_fem_noeud()==10)
38     {
39     xyz1=tet->get_fem_noeud(0)->get_coord();
40     xyz2=tet->get_fem_noeud(2)->get_coord();
41     xyz3=tet->get_fem_noeud(4)->get_coord();
42     xyz4=tet->get_fem_noeud(9)->get_coord();
43     }
44 francois 104 OT_VECTEUR_3D v1(xyz2[0]-xyz1[0],xyz2[1]-xyz1[1],xyz2[2]-xyz1[2]);
45     OT_VECTEUR_3D v2(xyz3[0]-xyz1[0],xyz3[1]-xyz1[1],xyz3[2]-xyz1[2]);
46     OT_VECTEUR_3D v3(xyz4[0]-xyz1[0],xyz4[1]-xyz1[1],xyz4[2]-xyz1[2]);
47     OT_VECTEUR_3D v4(x-xyz1[0],y-xyz1[1],z-xyz1[2]);
48     OT_MATRICE_3D mat(v1,v2,v3);
49     OT_MATRICE_3D mat1(v4,v2,v3);
50     OT_MATRICE_3D mat2(v1,v4,v3);
51     OT_MATRICE_3D mat3(v1,v2,v4);
52     double det=mat.get_determinant();
53     double xsi=mat1.get_determinant()/det;
54     double eta=mat2.get_determinant()/det;
55     double dseta=mat3.get_determinant()/det;
56     int reponse=1;
57     if (xsi<-0.000001) reponse=0;
58     if (eta<-0.000001) reponse=0;
59     if (dseta<-0.000001) reponse=0;
60     if (xsi+eta+dseta>1.000001) reponse=0;
61     return reponse;
62    
63     }
64    
65 francois 259 double TOIBREP::calculdist(double *n,double x,double y,double z,FEM_NOEUD* noeud)
66 francois 104 {
67     double* xyz=noeud->get_coord();
68     double dist=sqrt((xyz[0]-x)*(xyz[0]-x)+(xyz[1]-y)*(xyz[1]-y)+(xyz[2]-z)*(xyz[2]-z));
69     OT_VECTEUR_3D vec1(n[0],n[1],n[2]);
70     OT_VECTEUR_3D vec2(xyz[0]-x,xyz[1]-y,xyz[2]-z);
71     double ps=vec1*vec2;
72     if (ps<0.) dist=-dist;
73     return dist;
74     }
75    
76 francois 259 //void TOIBREP::importer(std::string nomfichier,class MagXchange* data,std::string nomfichierout)
77     void TOIBREP::importer(std::string nomfichier,std::string nomfichieribrep,MG_GROUPE_TOPOLOGIQUE* mggt)
78 francois 104 {
79 francois 222 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> lst;
80 francois 106 int nbface=geo->get_nb_mg_face();
81 francois 222 if (mggt!=NULL)
82     {
83     int nb=mggt->get_nb();
84     for (int i=0;i<nb;i++)
85     {
86     lst.ajouter(mggt->get(i));
87     mggt->get(i)->get_topologie_sousjacente(&lst);
88     }
89     }
90     else
91     {
92     int nbvol=geo->get_nb_mg_volume();
93     for (int i=0;i<nbvol;i++)
94     {
95     lst.ajouter(geo->get_mg_volume(i));
96     geo->get_mg_volume(i)->get_topologie_sousjacente(&lst);
97     }
98     }
99     int nbvraiface=0;
100     TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*>::ITERATEUR it;
101     for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
102     if (ele->get_dimension()==2) nbvraiface++;
103     int nb_noeud=mai->get_nb_fem_noeud();
104 francois 104 std::string nomfichier2=nomfichier+".sol";
105 francois 222 FEM_SOLUTION* solution=new FEM_SOLUTION(mai,nbvraiface+1,(char*)nomfichier2.c_str(),nb_noeud,"LS_",ENTITE_NOEUD);
106 francois 106 solution->change_legende(0,"Peau");
107 francois 222 int i=0;
108     for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
109 francois 106 {
110 francois 222 if (ele->get_dimension()!=2) continue;
111     if (mggt!=NULL)
112     if (lst.existe(ele)==0) continue;
113 francois 106 char mess[255];
114 francois 222 sprintf(mess,"Face %lu",ele->get_id());
115     ++i;
116     solution->change_legende(i,mess);
117 francois 106 }
118 francois 222 gest->ajouter_fem_solution(solution);
119 francois 104 double xmin=1e300,ymin=1e300,zmin=1e308;
120     double xmax=-1e300,ymax=-1e300,zmax=-1e308;
121 francois 222 TPL_MAP_ENTITE<FEM_NOEUD*> lst_noeud;
122     LISTE_FEM_NOEUD::iterator it2;
123     i=0;
124     for (FEM_NOEUD* noeud=mai->get_premier_noeud(it2);noeud!=NULL;noeud=mai->get_suivant_noeud(it2))
125 francois 104 {
126     double* xyz=noeud->get_coord();
127     if (xyz[0]<xmin) xmin=xyz[0];
128     if (xyz[1]<ymin) ymin=xyz[1];
129     if (xyz[2]<zmin) zmin=xyz[2];
130     if (xyz[0]>xmax) xmax=xyz[0];
131     if (xyz[1]>ymax) ymax=xyz[1];
132     if (xyz[2]>zmax) zmax=xyz[2];
133 francois 222 for (int j=0;j<nbvraiface+1;j++)
134 francois 106 solution->ecrire(i,j,1e300);
135 francois 104 lst_noeud.ajouter(noeud);
136 francois 222 i++;
137 francois 104 }
138     octree.initialiser(&lst_noeud,1,xmin,ymin,zmin,xmax,ymax,zmax);
139 francois 222 LISTE_FEM_TETRA::iterator it3;
140     for (FEM_TETRA* tet=mai->get_premier_tetra(it3);tet!=NULL;tet=mai->get_suivant_tetra(it3))
141 francois 104 octree.inserer(tet);
142 francois 222 //levelset0(solution,0);
143 francois 106 for (int i=0;i<nbface;i++)
144     {
145 francois 222 MG_FACE* face=geo->get_mg_face(i);
146     if (!lst.existe(face)) continue;
147 francois 106 vector<MG_FACE*> lstface;
148 francois 222 lstface.push_back(face);
149     /*TPL_LISTE_ENTITE<double> lst;
150 francois 106 int type=face->get_surface()->get_type_geometrique(lst);
151     int idem=0;
152     for (int j=0;j<i;j++)
153     {
154     TPL_LISTE_ENTITE<double> lst2;
155     MG_FACE* face2=geo->get_mg_face(j);
156     int type2=face2->get_surface()->get_type_geometrique(lst2);
157     if (type==type2)
158     if (lst.get_nb()==lst2.get_nb())
159     {
160     int diff=0;
161     for (int i=0;i<lst.get_nb();i++)
162     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
163     if (diff==0) idem=1;
164     }
165     }
166     if (!idem) lstface.push_back(geo->get_mg_face(i));
167     for (int j=i+1;j<nbface;j++)
168     {
169     TPL_LISTE_ENTITE<double> lst2;
170     MG_FACE* face2=geo->get_mg_face(j);
171     int type2=face2->get_surface()->get_type_geometrique(lst2);
172     if (type==type2)
173     if (lst.get_nb()==lst2.get_nb())
174     {
175     int diff=0;
176     for (int i=0;i<lst.get_nb();i++)
177     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
178     if (diff==0) lstface.push_back(face2);
179     }
180 francois 222 }*/
181     levelsetn(&lst,&lstface,solution,i+1);
182 francois 106 }
183 francois 259 exporter_IBrep(nomfichieribrep,solution,mggt);
184 francois 106 }
185    
186 francois 259 void TOIBREP::levelset0(FEM_SOLUTION *solution,int numsol)
187 francois 106 {
188     solution->active_solution(numsol);
189 francois 104 int nbface=geo->get_nb_mg_face();
190 francois 259 vector<TOIBREP_POINT*> lst;
191 francois 104 for (int iface=0;iface<nbface;iface++)
192     {
193 francois 106 MG_FACE* face=geo->get_mg_face(iface);
194     int nbpoint=lst.size();
195 francois 104 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
196     for (MG_ELEMENT_MAILLAGE* ele=face->get_lien_maillage()->get_premier(it);ele!=NULL;ele=face->get_lien_maillage()->get_suivant(it))
197     {
198     MG_TRIANGLE *tri=(MG_TRIANGLE*)ele;
199 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());
200     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());
201     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());
202 francois 106 lst.push_back(pt1);
203     lst.push_back(pt2);
204     lst.push_back(pt3);
205 francois 104 }
206 francois 222 calcullevelsetpremierepasse(solution,numsol,face,8,&lst,nbpoint,lst.size());
207 francois 106 }
208     calcullevelsetdeuxiemepasse(solution,numsol,&lst);
209     }
210 francois 259 void TOIBREP::calcullevelsetpremierepasse(FEM_SOLUTION *solution,int numsol,MG_FACE* face,int sens,vector<TOIBREP_POINT*> *lst,int n1,int n2)
211 francois 106 {
212     for (int i=n1;i<n2;i++)
213 francois 104 {
214 francois 259 TOIBREP_POINT* pt=(*lst)[i];
215 francois 104 double uv[2];
216 francois 106 double xyz[3];
217     pt->get_coord3(xyz);
218 francois 222 double normal[3];
219 francois 104 face->inverser(uv,xyz);
220     face->calcul_normale_unitaire(uv,normal);
221 francois 222 normal[0]=normal[0]*sens*(-1.);
222     normal[1]=normal[1]*sens*(-1.);
223     normal[2]=normal[2]*sens*(-1.);
224     TPL_MAP_ENTITE<FEM_TETRA*> liste;
225 francois 259 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
226 francois 222 TPL_MAP_ENTITE<FEM_TETRA*>::ITERATEUR it;
227     for (FEM_TETRA* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
228 francois 104 {
229 francois 249 //if (estdansletetra(tet,xyz[0],xyz[1],xyz[2]))
230 francois 104 {
231 francois 222 for (int k=0;k<tet->get_nb_fem_noeud();k++)
232 francois 106 {
233 francois 222 double dist=calculdist(normal,xyz[0],xyz[1],xyz[2],tet->get_fem_noeud(k));
234     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
235     {
236     tet->get_fem_noeud(k)->change_solution(dist);
237     tet->get_fem_noeud(k)->change_numero(pt->get_id());
238     pt->change_coord2(uv);
239     }
240 francois 106 }
241 francois 104 }
242     }
243     }
244 francois 106 }
245    
246 francois 259 void TOIBREP::calcullevelsetdeuxiemepasse(FEM_SOLUTION *solution,int numsol,vector<TOIBREP_POINT*> *lst)
247 francois 106 {
248 francois 222 LISTE_FEM_TETRA::iterator ittet;
249     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
250 francois 106 {
251 francois 222 for (int i=0;i<tet->get_nb_fem_noeud();i++)
252     if (tet->get_fem_noeud(i)->get_solution()<1e250)
253 francois 106 {
254 francois 259 TOIBREP_POINT* pt=(*lst)[tet->get_fem_noeud(i)->get_numero()];
255 francois 106 int dim=pt->get_mg_element_topologique()->get_dimension();
256     if (dim==2)
257     {
258     MG_FACE* face=(MG_FACE*)pt->get_mg_element_topologique();
259 francois 222 double dist=calcul_distance(tet->get_fem_noeud(i),face,pt);
260 francois 106 int signe=1;
261 francois 222 if (tet->get_fem_noeud(i)->get_solution()<0) signe=-1;
262     tet->get_fem_noeud(i)->change_solution(signe*dist);
263 francois 106 }
264     if (dim==1)
265     {
266     MG_ARETE* arete=(MG_ARETE*)pt->get_mg_element_topologique();
267 francois 222 double dist=calcul_distance(tet->get_fem_noeud(i),arete,pt);
268     tet->get_fem_noeud(i)->change_solution(dist);
269 francois 106 }
270     if (dim==0)
271     {
272     MG_SOMMET* sommet=(MG_SOMMET*)pt->get_mg_element_topologique();
273     MG_ARETE* arete=sommet->get_mg_cosommet(0)->get_arete();
274 francois 222 double dist=calcul_distance(tet->get_fem_noeud(i),arete,pt);
275     tet->get_fem_noeud(i)->change_solution(dist);
276 francois 106 }
277    
278     }
279 francois 104 }
280 francois 222 int i=0;
281     LISTE_FEM_NOEUD::iterator itnoeud;
282     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
283 francois 104 {
284 francois 106 solution->ecrire(i,numsol,noeud->get_solution());
285 francois 222 ++i;
286 francois 104 }
287 francois 106 int nbpt=(*lst).size();
288     for (int i=0;i<nbpt;i++) delete (*lst)[i];
289 francois 259 TOIBREP_POINT::remisecompteurid();
290 francois 104
291 francois 106 }
292    
293 francois 259 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_ARETE* are,TOIBREP_POINT* pt,double precision)
294 francois 106 {
295     double tii,eps;
296     are->inverser(tii,noeud->get_coord());
297     int compteur=0;
298     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
299     do
300     {
301     compteur++;
302     double ti=tii;
303     double xyz[3],dxyz[3],ddxyz[3];
304     are->deriver_seconde(ti,ddxyz,dxyz,xyz);
305     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
306     OT_VECTEUR_3D Ct_deriver(dxyz[0],dxyz[1],dxyz[2]);
307     OT_VECTEUR_3D Ct_deriver_seconde(ddxyz[0],ddxyz[1],ddxyz[2]);
308     OT_VECTEUR_3D Distance = Ct-Pt;
309     tii=ti-Ct_deriver*Distance/(Ct_deriver_seconde*Distance+Ct_deriver.get_longueur2());
310     eps=fabs(tii-ti);
311     if (compteur>500) return 1e300;
312     if (tii<are->get_tmin())
313     {
314     tii=are->get_tmin();
315     eps=0.;
316     }
317     if (tii>are->get_tmax())
318     {
319     tii=are->get_tmax();
320     eps=0.;
321     }
322     }
323     while (eps>precision);
324     double xyz[3],dxyz[3];
325     are->evaluer(tii,xyz);
326     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
327     double distance=(Ct-Pt).get_longueur();
328     MG_FACE* face1=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
329     MG_FACE* face2=are->get_mg_coarete(1)->get_boucle()->get_mg_face();
330     are->deriver(tii,dxyz);
331     OT_VECTEUR_3D x1(dxyz[0],dxyz[1],dxyz[2]);
332     OT_VECTEUR_3D x2(dxyz[0],dxyz[1],dxyz[2]);
333     x1=are->get_mg_coarete(0)->get_orientation()*x1;
334     x2=are->get_mg_coarete(1)->get_orientation()*x2;
335     x1.norme();
336     x2.norme();
337     double uv1[2],uv2[2];
338     double normal1[3],normal2[3];
339     face1->inverser(uv1,xyz);
340     face2->inverser(uv2,xyz);
341     face1->calcul_normale_unitaire(uv1,normal1);
342     face2->calcul_normale_unitaire(uv2,normal2);
343     OT_VECTEUR_3D z1(normal1[0],normal1[1],normal1[2]);
344     OT_VECTEUR_3D z2(normal2[0],normal2[1],normal2[2]);
345     z1=face1->get_mg_coface(0)->get_orientation()*z1;
346     z2=face2->get_mg_coface(0)->get_orientation()*z2;
347     OT_VECTEUR_3D y1=z1&x1;
348     OT_VECTEUR_3D y2=z2&x2;
349     double test=(z1&z2)*x1;
350     int signe=-1;
351     OT_VECTEUR_3D dirpt=Pt-Ct;
352     if (test>0)
353     {if ((z1*dirpt>0.) || (z2*dirpt>0.)) signe=1;}
354     else
355     {if ((z1*dirpt>0.) && (z2*dirpt>0.)) signe=1;}
356     return signe*distance;
357     }
358    
359 francois 259 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_FACE* face,TOIBREP_POINT* pt,double precision)
360 francois 106 {
361     double uvii[2],eps;
362     pt->get_coord2(uvii);
363     int compteur=0;
364     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
365     double delta_u,delta_v;
366     do
367     {
368     compteur++;
369     double uvi[2];
370     uvi[0]=uvii[0];
371     uvi[1]=uvii[1];
372     double xyzduu[3],xyzdvv[3],xyzduv[3],xyzdu[3],xyzdv[3],xyz[3];
373     face->deriver_seconde(uvi,xyzduu,xyzduv,xyzdvv,xyz,xyzdu,xyzdv);
374     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
375     OT_VECTEUR_3D Su(xyzdu[0],xyzdu[1],xyzdu[2]);
376     OT_VECTEUR_3D Sv(xyzdv[0],xyzdv[1],xyzdv[2]);
377     OT_VECTEUR_3D Suu(xyzduu[0],xyzduu[1],xyzduu[2]);
378     OT_VECTEUR_3D Suv(xyzduv[0],xyzduv[1],xyzduv[2]);
379     OT_VECTEUR_3D Svv(xyzdvv[0],xyzdvv[1],xyzdvv[2]);
380     OT_VECTEUR_3D Distance = S-Pt;
381     double a[4],b[2];
382     a[0]=Su.get_longueur2()+Distance*Suu;
383     a[1]=Su*Sv+Distance*Suv;
384     a[2]=Su*Sv+Distance*Suv;
385     a[3]=Sv.get_longueur2()+Distance*Svv;
386     b[0]=Distance*Su;b[0]=-b[0];
387     b[1]=Distance*Sv;b[1]=-b[1];
388     double deltau,deltav;
389     double denominateur_delta=(a[0]*a[3]-a[2]*a[1]);
390     if (a[0]<1E-12)
391     deltau=0;
392     else delta_u=(b[0]*a[3]-b[1]*a[1])/denominateur_delta;
393     if (a[3]<1E-12)
394     deltav=0;
395     else delta_v=(a[0]*b[1]-a[2]*b[0])/denominateur_delta;
396     /*if (fabs(denominateur_delta) < ( (fabs(a[0])+fabs(a[1])+fabs(a[2])+fabs(a[3]))*1e-12 ) )
397     return 1e300;*/
398     uvii[0]=uvi[0]+delta_u;
399     uvii[1]=uvi[1]+delta_v;
400     if (face->get_surface()->est_periodique_u()==1)
401     {
402     if(uvii[0]<0.) uvii[0]=face->get_surface()->get_periode_u()-uvii[0];
403     if(uvii[0]>face->get_surface()->get_periode_u()) uvii[0]=uvii[0]-face->get_surface()->get_periode_u();
404     }
405     if (face->get_surface()->est_periodique_v()==1)
406     {
407     if(uvii[1]<0.) uvii[0]=face->get_surface()->get_periode_v()-uvii[1];
408     if(uvii[1]>face->get_surface()->get_periode_v()) uvii[1]=uvii[1]-face->get_surface()->get_periode_v();
409     }
410     delta_u=uvii[0]-uvi[0];
411     delta_v=uvii[1]-uvi[1];
412     if (compteur>500) return 1e300;
413     }
414    
415     while ((fabs(delta_u)>precision)||(fabs(delta_v)>precision));
416     double xyz[3];
417     face->evaluer(uvii,xyz);
418     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
419     double distance=(S-Pt).get_longueur();
420     return distance;
421     }
422    
423 francois 259 void TOIBREP::levelsetn(TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> *lsttopo,vector<MG_FACE*> *lstface,class FEM_SOLUTION* solution,int numsol)
424 francois 106 {
425     solution->active_solution(numsol);
426     int nbface=lstface->size();
427     if (nbface==0) return;
428 francois 259 vector<TOIBREP_POINT*> lst;
429 francois 222 BOITE_2D boite=ot.get_boite_2D((*lstface)[0]);
430     for (int iface=1;iface<nbface;iface++)
431 francois 104 {
432 francois 222 MG_FACE* face=(*lstface)[iface];
433     BOITE_2D boiteface=ot.get_boite_2D(face);
434     boite=boite+boiteface;
435     }
436     MG_FACE* face=(*lstface)[0];
437     int trouve=0;
438     int orientation;
439     int j=0;
440     do
441     {
442     MG_COFACE* coface=face->get_mg_coface(j);
443     MG_VOLUME* vol=coface->get_coquille()->get_mg_volume();
444     if (lsttopo->existe(vol))
445 francois 104 {
446 francois 222 orientation=coface->get_orientation();
447     trouve=1;
448 francois 106 }
449 francois 222 j++;
450 francois 104 }
451 francois 222 while (trouve==0);
452     double umin=boite.get_xmin();
453     double umax=boite.get_xmax();
454     double vmin=boite.get_ymin();
455     double vmax=boite.get_ymax();
456 francois 106 if (face->get_surface()->est_periodique_u())
457 francois 104 {
458 francois 106 umin=0;
459     umax=face->get_surface()->get_periode_u();
460 francois 104 }
461 francois 106 if (face->get_surface()->est_periodique_v())
462     {
463     vmin=0;
464     vmax=face->get_surface()->get_periode_v();
465     }
466     for (int i=-5;i<NPAS+5;i++)
467     for (int j=-5;j<NPAS+5;j++)
468     {
469 francois 222 double uv[2];
470 francois 106 uv[0]=umin+i*1.0/NPAS*(umax-umin);
471     uv[1]=vmin+j*1.0/NPAS*(vmax-vmin);
472     double xyz[3];
473     if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_u(uv[1])))
474     {
475     face->evaluer(uv,xyz);
476 francois 259 TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],face);
477 francois 106 lst.push_back(pt);
478     }
479     }
480 francois 222 calcullevelsetpremierepasse(solution,numsol,face,orientation,&lst,0,lst.size());
481     calcullevelsetdeuxiemepasse(solution,numsol,&lst);
482 francois 249 //etendrelevelset(solution,numsol);
483 francois 104 }
484 francois 106
485 francois 259 void TOIBREP::etendrelevelset(FEM_SOLUTION* sol,int numsol)
486 francois 222 {
487     sol->active_solution(numsol);
488    
489    
490     LISTE_FM know;
491     LISTE_FM trial;
492     LISTE_FM far;
493     LISTE_FM exterieur;
494     LISTE_FM_TRI trialtri;
495     LISTE_FM_TRI_ID trialtriid;
496    
497    
498     LISTE_FEM_TETRA::iterator ittet;
499     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
500     {
501     tet->change_solution(0.);
502     int numsol=0;
503     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);
504     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);
505     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);
506     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);
507     if (numsol==4)
508     ajouter_liste(know,tet);
509    
510     else if (numsol==3)
511     {
512     if (tet->get_fem_noeud(0)->get_numero()==0) tet->change_numero(0);
513     else if (tet->get_fem_noeud(1)->get_numero()==0) tet->change_numero(1);
514     else if (tet->get_fem_noeud(2)->get_numero()==0) tet->change_numero(2);
515     else tet->change_numero(3);
516     ajouter_liste(trial,tet);
517     }
518     else
519     ajouter_liste(far,tet);
520    
521     }
522     for (LISTE_FM::iterator i=trial.begin();i!=trial.end();i++)
523     {
524     FEM_TETRA* tet=*i;
525     int signe;
526     double sol=resoudgradT(tet,&signe);
527     if (fabs(sol)>0.00000001)
528     {
529     if (fabs(sol)<fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()))
530     {
531     tet->get_fem_noeud(tet->get_numero())->change_solution(sol);
532     ajouter_liste(trialtri,trialtriid,tet,fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()));
533     }
534     }
535     else
536     {
537     ajouter_liste(exterieur,tet);
538     tet->change_solution(1e300);
539     }
540     }
541     int fin=0;
542     LISTE_FM_TRI::iterator itfin=trialtri.end();
543     itfin--;
544     double longref=(*itfin).first;
545     do
546     {
547     LISTE_FM_TRI::iterator it=trialtri.begin();
548     FEM_TETRA* tet=(*it).second;
549     double longcourant=(*it).first;
550     supprimer_liste(trialtri,trialtriid,tet);
551     ajouter_liste(know,tet);
552     FEM_NOEUD* noeud=tet->get_fem_noeud(tet->get_numero());
553     noeud->change_numero(1);
554     if (noeud->get_solution()>20000)
555     cout << "BUGGGGGGG" <<endl;
556     int nbtetra=noeud->get_lien_tetra()->get_nb();
557     for (int i=0;i<nbtetra;i++)
558     {
559     FEM_TETRA* tet2=noeud->get_lien_tetra()->get(i);
560     if (tet2==tet) continue;
561     LISTE_FM_TRI_ID::iterator it=trialtriid.find(tet2->get_id());
562     if (it!=trialtriid.end())
563     {
564     int signe;
565     double sol=resoudgradT(tet2,&signe);
566     double solution=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
567     if (fabs(sol)>0.00000001)
568     if (!((solution<1e200)&&(sol*solution<0)))
569     if (fabs(sol)<fabs(solution))
570     {
571     supprimer_liste(trialtri,trialtriid,tet2);
572     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
573     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
574     }
575     }
576     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet2);
577     if (it2!=far.end())
578     {
579     int numsol=0;
580     if (tet2->get_fem_noeud(0)->get_numero()==1) numsol++;
581     if (tet2->get_fem_noeud(1)->get_numero()==1) numsol++;
582     if (tet2->get_fem_noeud(2)->get_numero()==1) numsol++;
583     if (tet2->get_fem_noeud(3)->get_numero()==1) numsol++;
584     //if (numsol==4)
585     //cout << " BUG " <<endl;
586     if (numsol==3)
587     {
588     if (tet2->get_fem_noeud(0)->get_numero()==0) tet2->change_numero(0);
589     else if (tet2->get_fem_noeud(1)->get_numero()==0) tet2->change_numero(1);
590     else if (tet2->get_fem_noeud(2)->get_numero()==0) tet2->change_numero(2);
591     else tet2->change_numero(3);
592     int signe;
593     double sol=resoudgradT(tet2,&signe);
594     double ancsol=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
595     if (fabs(sol)>0.00000001)
596     {
597     if (!((ancsol<1e200) && (ancsol*sol<0.) ))
598     {
599     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
600     supprimer_liste(far,tet2);
601     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
602     }
603     }
604     else
605     {
606     tet2->change_solution(1e300);
607     ajouter_liste(exterieur,tet2);
608     }
609     }
610     }
611     }
612     if (trialtri.size()==0) fin=1;
613     if (exterieur.size()>0)
614     if (fin==0)
615     if (longcourant>longref)
616     {
617     int nombre=exterieur.size();
618     for (int i=0;i<nombre;i++)
619     {
620     FEM_TETRA* tet2=(*(exterieur.begin()));
621     supprimer_liste(exterieur,tet2);
622     ajouter_liste(know,tet2);
623     for (int nd=0;nd<4;nd++)
624     {
625     FEM_NOEUD* noeud=tet2->get_fem_noeud(nd);
626     int nbtetra=noeud->get_lien_tetra()->get_nb();
627     for (int i=0;i<nbtetra;i++)
628     {
629     FEM_TETRA* tet3=noeud->get_lien_tetra()->get(i);
630     if (tet2==tet3) continue;
631     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet3);
632     if (it2!=far.end())
633     {
634     supprimer_liste(far,tet3);
635     ajouter_liste(exterieur,tet3);
636     tet3->change_solution(1e300);
637     }
638     }
639     }
640     }
641     LISTE_FM_TRI::iterator itfin=trialtri.end();
642     itfin--;
643     longref=(*itfin).first;
644     }
645     }
646     while (fin==0);
647     LISTE_FEM_NOEUD::iterator itnoeud;
648     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
649     noeud->change_numero(0);
650     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
651     {
652     if (tet->get_solution()>1e200) continue;
653     tet->get_fem_noeud(0)->change_numero(1);
654     tet->get_fem_noeud(1)->change_numero(1);
655     tet->get_fem_noeud(2)->change_numero(1);
656     tet->get_fem_noeud(3)->change_numero(1);
657     }
658     int i=0;
659     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
660     {
661     if (noeud->get_numero()==1) sol->ecrire(i,numsol,noeud->get_solution()); else sol->ecrire(i,numsol,1e300);
662     ++i;
663     }
664     }
665 francois 259 void TOIBREP::exporter_IBrep(string chemin,FEM_SOLUTION* solution,MG_GROUPE_TOPOLOGIQUE* mggt)
666     {
667     TPL_MAP_ENTITE<MG_VOLUME*> lst;
668     if (mggt==NULL)
669     {
670     int nbvol=geo->get_nb_mg_volume();
671     for (int i=0;i<nbvol;i++)
672     lst.ajouter(geo->get_mg_volume(i));
673     }
674     else
675     {
676     int nbmggt=mggt->get_nb();
677     for (int i=0;i<nbmggt;i++)
678     if (mggt->get(i)->get_dimension()==3)
679     lst.ajouter((MG_VOLUME*)mggt->get(i));
680     }
681     IBrep brep(100);
682     int nbvolexp=lst.get_nb();
683     for (int i=0;i<nbvolexp;i++)
684     {
685     MG_VOLUME* vol=lst.get(i);
686     int nbcoq=vol->get_nb_mg_coquille();
687     IVolumeN ivoltmp(vol->get_id());
688     IVolume* ivol=brep.AddVolume(ivoltmp);
689     for (int j=0;j<nbcoq;j++)
690     {
691     MG_COQUILLE* coq=vol->get_mg_coquille(j);
692     int nbface=coq->get_nb_mg_coface();
693     IShell ishell(nbface);
694     for (int k=0;k<nbface;k++)
695     {
696     MG_COFACE* coface=coq->get_mg_coface(k);
697     ishell[k]=coface->get_id();
698     MG_FACE* face=coface->get_face();
699     int sens=coface->get_orientation();
700     ICoFaceN icoface(coface->get_id(),face->get_id(),sens);
701     brep.AddCoFace(icoface);
702     IFace* iface=brep.GetFace(face->get_id());
703     if (iface==NULL)
704     {
705     IFaceN ifacenew(face->get_id());
706     iface=brep.AddFace(ifacenew);
707     int nbbou=face->get_nb_mg_boucle();
708     for (int l=0;l<nbbou;l++)
709     {
710     MG_BOUCLE* bou=face->get_mg_boucle(l);
711     int nbare=bou->get_nb_mg_coarete();
712     ILoop iloop(nbare);
713     for (int m=0;m<nbare;m++)
714     {
715     MG_COARETE* coare=bou->get_mg_coarete(m);
716     iloop[m]=coare->get_id();
717     MG_ARETE* are=coare->get_arete();
718     int sens=coare->get_orientation();
719     ICoEdgeN icoedge(coare->get_id(),are->get_id(),sens,face->get_id());
720     brep.AddCoEdge(icoedge);
721     IEdge* iedge=brep.GetEdge(are->get_id());
722     IVertex *ivertex1,*ivertex2;
723     ICoVertex *icover1,*icover2;
724     if (iedge==NULL)
725     {
726     MG_COSOMMET* cover1=are->get_cosommet1();
727     MG_COSOMMET* cover2=are->get_cosommet2();
728     MG_SOMMET* ver1=cover1->get_sommet();
729     MG_SOMMET* ver2=cover2->get_sommet();
730     ICoVertexN icovertmp1(cover1->get_id(),are->get_id(),ver1->get_id(),cover1->get_t());
731     ICoVertexN icovertmp2(cover2->get_id(),are->get_id(),ver2->get_id(),cover2->get_t());
732     icover1=brep.AddCoVertex(icovertmp1);
733     icover2=brep.AddCoVertex(icovertmp2);
734     IEdgeN iedgetmp(are->get_id(),cover1->get_id(),cover2->get_id());
735     ivertex1=brep.GetVertex(ver1->get_id());
736     ivertex2=brep.GetVertex(ver2->get_id());
737     if (ivertex1==NULL)
738     {
739     MG_POINT* pt=ver1->get_point();
740     double xyz[3];
741     pt->evaluer(xyz);
742     IVertexN ivertex(ver1->get_id(),xyz);
743     ivertex1=brep.AddVertex(ivertex);
744     }
745     if (ivertex2==NULL)
746     {
747     MG_POINT* pt=ver2->get_point();
748     double xyz[3];
749     pt->evaluer(xyz);
750     IVertexN ivertex(ver2->get_id(),xyz);
751     ivertex2=brep.AddVertex(ivertex);
752     }
753     ivertex1->AddCoVertex(cover1->get_id());
754     ivertex2->AddCoVertex(cover2->get_id());
755     iedge=brep.AddEdge(iedgetmp);
756     }
757     iedge->AddCoEdge(coare->get_id(),brep);
758     if (sens==1)
759     {
760     icover1=brep.GetCoVertex(iedge->FromCoVertex());
761     ivertex1=brep.GetVertex(icover1->Vertex());
762     ivertex1->AddFace(face->get_id());
763     }
764     else
765     {
766     icover2=brep.GetCoVertex(iedge->ToCoVertex());
767     ivertex2=brep.GetVertex(icover2->Vertex());
768     ivertex2->AddFace(face->get_id());
769     }
770     }
771     iface->AddLoop(iloop);
772     }
773     }
774     iface->AddCoFace(coface->get_id());
775     }
776     ivol->AddShell(ishell);
777     }
778     }
779     int nbsol=solution->get_nb_champ();
780     LISTE_FEM_NOEUD::iterator itnoeud;
781     int i=0;
782     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
783     {
784     int nbsolnoeud=0;
785     for (int j=0;j<nbsol;j++)
786     {
787     if (solution->lire(i,j)<1e200) nbsolnoeud++;
788     }
789     double *xyz=noeud->get_coord();
790     INodeN inoeudtmp(noeud->get_id(),xyz[0],xyz[1],xyz[2],nbsolnoeud);
791     INode* inoeud=brep.AddNode(inoeudtmp);
792     int num=0;
793     for (int j=0;j<nbsol;j++)
794     {
795     if (solution->lire(i,j)<1e200)
796     {
797     inoeud->Fields()[num]=j;
798     inoeud->Values()[num]=solution->lire(i,j);
799     num++;
800     }
801     }
802     i++;
803     }
804     LISTE_FEM_TETRA::iterator ittet;
805     int num=0;
806     for (FEM_TETRA* tet=mai->get_premier_tetra(ittet);tet!=NULL;tet=mai->get_suivant_tetra(ittet))
807     {
808     IElementN xfemele(IElement::TETRAHEDRON);
809     num++;
810     xfemele.num=num;
811     xfemele.GetNode(0)=tet->get_fem_noeud(0)->get_id();
812     xfemele.GetNode(1)=tet->get_fem_noeud(1)->get_id();
813     xfemele.GetNode(2)=tet->get_fem_noeud(2)->get_id();
814     xfemele.GetNode(3)=tet->get_fem_noeud(3)->get_id();
815     brep.AddElement(xfemele);
816     }
817 francois 222
818 francois 259
819    
820    
821     std::ofstream output(chemin.c_str());
822     output << brep << std::endl;
823     output.close();
824    
825     }
826    
827    
828    
829     void TOIBREP::ajouter_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet,double val)
830 francois 222 {
831     pair<double,FEM_TETRA*> p(val,tet);
832     LISTE_FM_TRI::iterator it=lst.insert(p);
833     lstid[tet->get_id()]=it;
834     }
835    
836 francois 259 void TOIBREP::supprimer_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_TETRA* tet)
837 francois 222 {
838     LISTE_FM_TRI::iterator it2=lstid[tet->get_id()];
839     LISTE_FM_TRI_ID::iterator it3=lstid.find(tet->get_id());
840     lstid.erase(it3);
841     lst.erase(it2);
842     }
843    
844 francois 259 void TOIBREP::ajouter_liste(LISTE_FM& lst,FEM_TETRA* tet)
845 francois 222 {
846     lst.push_back(tet);
847     }
848    
849 francois 259 void TOIBREP::supprimer_liste(LISTE_FM& lst,FEM_TETRA* tet)
850 francois 222 {
851     LISTE_FM::iterator it=find(lst.begin(),lst.end(),tet);
852     if (it!=lst.end()) lst.erase(it);
853     }
854    
855    
856    
857 francois 259 double TOIBREP::resoudgradT(FEM_TETRA* tet,int *signe)
858 francois 222 {
859     double j[9];
860     double N[12];
861     double jN[12]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
862     double T[4];
863     double uv[2]={0.25,0.25};
864    
865    
866     tet->get_inverse_jacob(j,uv);
867     for (int i=0;i<3;i++)
868     for (int k=0;k<4;k++)
869     N[i*4+k]=tet->get_fonction_derive_interpolation(k+1,i+1,uv);
870     int premier=0;
871     double tmin=1e300;
872     double tmax=-1e300;
873     for (int i=0;i<4;i++)
874     {
875     if (i==tet->get_numero()) continue;
876     T[i]=tet->get_fem_noeud(i)->get_solution();
877     if (fabs(T[i])>0.000001)
878     {
879     if (premier==0)
880     if (T[i]>0) (*signe)=1; else (*signe)=-1;
881     else if (T[i]*(*signe)<0) (*signe)=0;
882     }
883     T[i]=fabs(T[i]);
884     if (tet->get_numero()!=i)
885     {
886     if (T[i]<tmin) tmin=T[i];
887     if (T[i]>tmax) tmax=T[i];
888     }
889     premier=1;
890     }
891     for (int i=0;i<3;i++)
892     for (int k=0;k<4;k++)
893     for (int l=0;l<3;l++)
894     jN[i*4+k]=jN[i*4+k]+j[i*3+l]*N[l*4+k];
895     double a=0.,b=0.,c=-1.;
896     for (int i=0;i<3;i++)
897     {
898     double coef=0.;
899     double coefinc=0.;
900     for (int l=0;l<4;l++)
901     {
902     if (tet->get_numero()!=l) coef=coef+jN[i*4+l]*T[l];
903     else coefinc=coefinc+jN[i*4+l];
904     }
905     c=c+coef*coef;
906     a=a+coefinc*coefinc;
907     b=b+2*coef*coefinc;
908     }
909     /*if (*signe==0)
910     cout << "attention " <<endl;*/
911     double det=b*b-4.*a*c;
912     if (det<0.) det=0.; else det=sqrt(det);
913     double sol1=(-b-det)/2./a;
914     double sol2=(-b+det)/2./a;
915     double sol=sol1;
916     if (sol2>sol1) sol=sol2;
917     if (sol<tmin*0.99)
918     sol=0.;
919     sol=sol*(*signe);
920     return sol;
921     }