ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 249
Committed: Fri Jun 18 14:03:27 2010 UTC (14 years, 10 months ago) by francois
Original Path: magic/lib/toxfem/toxfem/src/toxfem.cpp
File size: 24193 byte(s)
Log Message:
Mise a jour toxfem au 18 juin 2010

File Contents

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