ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 272
Committed: Mon Dec 13 21:04:45 2010 UTC (14 years, 5 months ago) by francois
File size: 28814 byte(s)
Log Message:
suppression des warnings

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