ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 254
Committed: Tue Jul 13 20:30:01 2010 UTC (14 years, 10 months ago) by francois
Original Path: magic/lib/toxfem/src/toxfem.cpp
File size: 24152 byte(s)
Log Message:
mise a jour de la precedente. LE tout fonctionne avec ccmake maintenant. Les repertoires cas_test ne sont pas encore a jour. Ni le wiki.

File Contents

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