ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/toIbrep/src/toibrep.cpp
Revision: 346
Committed: Fri Jun 29 15:32:53 2012 UTC (12 years, 10 months ago) by francois
File size: 70449 byte(s)
Log Message:
un oubli dans les derniers commits.

File Contents

# User Rev Content
1 bechet 105 #include "gestionversion.h"
2 francois 259 #include "toibrep.h"
3 francois 104 #include "mg_file.h"
4     #include "ot_mathematique.h"
5     #include "tpl_map_entite.h"
6 francois 222 #include "tpl_relation_entite.h"
7 francois 104 #include "tpl_octree.h"
8 francois 259 #include "toibrep_point.h"
9 francois 106 #include "vct.h"
10 francois 104 #include <math.h>
11 francois 259 #include <fstream>
12 francois 262 #include <string>
13 francois 259 #include "IBrep.h"
14 francois 276 #include "ot_cpu.h"
15 francois 346 #include "fem_tetra4.h"
16     #include "xfem_tetra4.h"
17 francois 104
18    
19 francois 222
20 francois 276 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas,OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(compt)
21 francois 104 {
22     }
23    
24 francois 276 TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,int nbpas):geo(ge),gest(g),mai(femm),NPAS(nbpas),affichageactif(0),compteur(NULL)
25     {
26     }
27     TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(NULL)
28     {
29     }
30     TOIBREP::TOIBREP(class MG_GESTIONNAIRE *g,class MG_GEOMETRIE *ge,class FEM_MAILLAGE* femm,class OT_CPU* compt):geo(ge),gest(g),mai(femm),NPAS(50),affichageactif(0),compteur(compt)
31     {
32     }
33 francois 104
34 francois 259 TOIBREP::~TOIBREP()
35 francois 104 {
36     }
37    
38    
39    
40 francois 276 void TOIBREP::active_affichage(void (*fonc)(char*))
41     {
42     affiche=fonc;
43     affichageactif=1;
44     }
45    
46     int TOIBREP::compare_etat(int etat,int valeur)
47     {
48 francois 281 if ((etat==1) && (valeur==INTERIEUR)) return 1;
49     if ((etat==3) && (valeur==INTERIEUR)) return 1;
50     if ((etat==3) && (valeur==STRICTINTERIEUR)) return 1;
51     if ((etat==1) && (valeur==SUR_FACE)) return 1;
52 francois 276 return 0;
53     }
54    
55    
56    
57 francois 309 int TOIBREP::estdansletetra(FEM_ELEMENT3 *tet,double x,double y, double z)
58 francois 104 {
59 francois 222 double *xyz1,*xyz2,*xyz3,*xyz4;
60     if (tet->get_nb_fem_noeud()==4)
61     {
62     xyz1=tet->get_fem_noeud(0)->get_coord();
63     xyz2=tet->get_fem_noeud(1)->get_coord();
64     xyz3=tet->get_fem_noeud(2)->get_coord();
65     xyz4=tet->get_fem_noeud(3)->get_coord();
66     }
67     if (tet->get_nb_fem_noeud()==10)
68     {
69     xyz1=tet->get_fem_noeud(0)->get_coord();
70     xyz2=tet->get_fem_noeud(2)->get_coord();
71     xyz3=tet->get_fem_noeud(4)->get_coord();
72     xyz4=tet->get_fem_noeud(9)->get_coord();
73     }
74 francois 104 OT_VECTEUR_3D v1(xyz2[0]-xyz1[0],xyz2[1]-xyz1[1],xyz2[2]-xyz1[2]);
75     OT_VECTEUR_3D v2(xyz3[0]-xyz1[0],xyz3[1]-xyz1[1],xyz3[2]-xyz1[2]);
76     OT_VECTEUR_3D v3(xyz4[0]-xyz1[0],xyz4[1]-xyz1[1],xyz4[2]-xyz1[2]);
77     OT_VECTEUR_3D v4(x-xyz1[0],y-xyz1[1],z-xyz1[2]);
78     OT_MATRICE_3D mat(v1,v2,v3);
79     OT_MATRICE_3D mat1(v4,v2,v3);
80     OT_MATRICE_3D mat2(v1,v4,v3);
81     OT_MATRICE_3D mat3(v1,v2,v4);
82     double det=mat.get_determinant();
83     double xsi=mat1.get_determinant()/det;
84     double eta=mat2.get_determinant()/det;
85     double dseta=mat3.get_determinant()/det;
86 francois 276 int reponse1=1;
87     int reponse2=1;
88 francois 281 double eps=0.0000001;
89 francois 276 if (xsi<-eps) reponse1=0;
90     if (eta<-eps) reponse1=0;
91     if (dseta<-eps) reponse1=0;
92     if (xsi+eta+dseta>1.+eps) reponse1=0;
93     if (xsi<eps) reponse2=0;
94     if (eta<eps) reponse2=0;
95     if (dseta<eps) reponse2=0;
96     if (xsi+eta+dseta>1.-eps) reponse2=0;
97     return reponse1+2*reponse2;
98 francois 104 }
99    
100 francois 276
101    
102 francois 259 double TOIBREP::calculdist(double *n,double x,double y,double z,FEM_NOEUD* noeud)
103 francois 104 {
104     double* xyz=noeud->get_coord();
105     double dist=sqrt((xyz[0]-x)*(xyz[0]-x)+(xyz[1]-y)*(xyz[1]-y)+(xyz[2]-z)*(xyz[2]-z));
106     OT_VECTEUR_3D vec1(n[0],n[1],n[2]);
107     OT_VECTEUR_3D vec2(xyz[0]-x,xyz[1]-y,xyz[2]-z);
108     double ps=vec1*vec2;
109     if (ps<0.) dist=-dist;
110     return dist;
111     }
112    
113 francois 281 void TOIBREP::recherche_arete_tangeante(TPL_MAP_ENTITE<MG_ARETE*> &lst,TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> &lsttopo)
114     {
115    
116    
117     LISTE_MG_ARETE::iterator it;
118     for (MG_ARETE* are=geo->get_premier_arete(it);are!=NULL;are=geo->get_suivant_arete(it))
119     {
120     if (lsttopo.existe(are))
121     if (ot.arete_virtuelle(are)) lst.ajouter(are);
122     }
123    
124     }
125    
126    
127 francois 259 //void TOIBREP::importer(std::string nomfichier,class MagXchange* data,std::string nomfichierout)
128 francois 276 IBrep TOIBREP::importer(std::string nomfichier,std::string nomfichieribrep,MG_GROUPE_TOPOLOGIQUE* mggt)
129 francois 104 {
130 francois 222 TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> lst;
131     if (mggt!=NULL)
132     {
133     int nb=mggt->get_nb();
134     for (int i=0;i<nb;i++)
135     {
136     lst.ajouter(mggt->get(i));
137     mggt->get(i)->get_topologie_sousjacente(&lst);
138     }
139     }
140     else
141     {
142     int nbvol=geo->get_nb_mg_volume();
143     for (int i=0;i<nbvol;i++)
144     {
145     lst.ajouter(geo->get_mg_volume(i));
146     geo->get_mg_volume(i)->get_topologie_sousjacente(&lst);
147     }
148     }
149 francois 281 affiche((char*)"Recherche aretes tangeantes");
150     TPL_MAP_ENTITE<MG_ARETE*> lstaretetan;
151     recherche_arete_tangeante(lstaretetan,lst);
152     char mess[300];
153     sprintf(mess," Nombre d'aretes tangeantes %d",lstaretetan.get_nb());
154     affiche(mess);
155     if (compteur!=NULL) compteur->ajouter_etape("Aretes tangeantes");
156     affiche((char*)"Traitement de base");
157     int nbface=geo->get_nb_mg_face();
158 francois 222 int nbvraiface=0;
159     TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*>::ITERATEUR it;
160     for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
161     if (ele->get_dimension()==2) nbvraiface++;
162 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base selection");
163 francois 222 int nb_noeud=mai->get_nb_fem_noeud();
164 francois 309 int nb_element3=mai->get_nb_fem_element3();
165 francois 276 std::string nomfichier2=nomfichier+"_dis.sol";
166 francois 281 FEM_SOLUTION* solution=new FEM_SOLUTION(mai,nbvraiface+lstaretetan.get_nb(),(char*)nomfichier2.c_str(),nb_noeud,"LS",ENTITE_NOEUD);
167 francois 222 int i=0;
168 francois 276 gest->ajouter_fem_solution(solution);
169     nomfichier2=nomfichier+"_ele.sol";
170 francois 309 FEM_SOLUTION* solution_ele=new FEM_SOLUTION(mai,nbvraiface+lstaretetan.get_nb(),(char*)nomfichier2.c_str(),nb_element3,"A",ENTITE_ELEMENT3);
171 francois 276 gest->ajouter_fem_solution(solution_ele);
172 francois 222 for (MG_ELEMENT_TOPOLOGIQUE* ele=lst.get_premier(it);ele!=NULL;ele=lst.get_suivant(it))
173 francois 106 {
174 francois 222 if (ele->get_dimension()!=2) continue;
175 francois 106 char mess[255];
176 francois 262 sprintf(mess,"F %lu",ele->get_id());
177 francois 276 solution->change_legende(i,mess);
178     solution_ele->change_legende(i,mess);
179 francois 222 ++i;
180 francois 106 }
181 francois 281 TPL_MAP_ENTITE<MG_ARETE*>::ITERATEUR itare;
182     for (MG_ARETE* are=lstaretetan.get_premier(itare);are!=NULL;are=lstaretetan.get_suivant(itare))
183     {
184     char mess[255];
185     sprintf(mess,"A %lu",are->get_id());
186     solution->change_legende(i,mess);
187     solution_ele->change_legende(i,mess);
188     ++i;
189     }
190 francois 276
191 francois 281
192 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base creation solution");
193 francois 104 double xmin=1e300,ymin=1e300,zmin=1e308;
194     double xmax=-1e300,ymax=-1e300,zmax=-1e308;
195 francois 222 TPL_MAP_ENTITE<FEM_NOEUD*> lst_noeud;
196     LISTE_FEM_NOEUD::iterator it2;
197     i=0;
198     for (FEM_NOEUD* noeud=mai->get_premier_noeud(it2);noeud!=NULL;noeud=mai->get_suivant_noeud(it2))
199 francois 104 {
200     double* xyz=noeud->get_coord();
201     if (xyz[0]<xmin) xmin=xyz[0];
202     if (xyz[1]<ymin) ymin=xyz[1];
203     if (xyz[2]<zmin) zmin=xyz[2];
204     if (xyz[0]>xmax) xmax=xyz[0];
205     if (xyz[1]>ymax) ymax=xyz[1];
206     if (xyz[2]>zmax) zmax=xyz[2];
207 francois 281 for (int j=0;j<nbvraiface+lstaretetan.get_nb();j++)
208 francois 106 solution->ecrire(i,j,1e300);
209 francois 104 lst_noeud.ajouter(noeud);
210 francois 222 i++;
211 francois 104 }
212 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base recherche boite");
213 francois 104 octree.initialiser(&lst_noeud,1,xmin,ymin,zmin,xmax,ymax,zmax);
214 francois 276 //if (compteur!=NULL) compteur->ajouter_etape("Traitement de base ini octree");
215 francois 309 LISTE_FEM_ELEMENT3::iterator it3;
216 francois 276 i=0;
217 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
218 francois 276 {
219     octree.inserer(tet);
220 francois 281 for (int j=0;j<nbvraiface+lstaretetan.get_nb();j++)
221 francois 276 solution_ele->ecrire(i,j,0);
222     i++;
223     }
224     if (compteur!=NULL) compteur->ajouter_etape("Traitement de base");
225 francois 106 for (int i=0;i<nbface;i++)
226 francois 346 //for (int i=0;i<1;i++)
227 francois 106 {
228 francois 281 MG_FACE* face=geo->get_mg_face(i);
229 francois 346 //MG_FACE* face=geo->get_mg_faceid(757);
230 francois 276 if (affichageactif)
231     {
232     char mess[300];
233 francois 281 sprintf(mess," Face %d numero %lu",i,face->get_id());
234 francois 276 affiche(mess);
235     }
236 francois 222 if (!lst.existe(face)) continue;
237 francois 106 vector<MG_FACE*> lstface;
238 francois 222 lstface.push_back(face);
239 francois 276 /// ici topologie virtuelle
240    
241    
242 francois 222 /*TPL_LISTE_ENTITE<double> lst;
243 francois 106 int type=face->get_surface()->get_type_geometrique(lst);
244     int idem=0;
245     for (int j=0;j<i;j++)
246     {
247     TPL_LISTE_ENTITE<double> lst2;
248     MG_FACE* face2=geo->get_mg_face(j);
249     int type2=face2->get_surface()->get_type_geometrique(lst2);
250     if (type==type2)
251     if (lst.get_nb()==lst2.get_nb())
252     {
253     int diff=0;
254     for (int i=0;i<lst.get_nb();i++)
255     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
256     if (diff==0) idem=1;
257     }
258     }
259     if (!idem) lstface.push_back(geo->get_mg_face(i));
260     for (int j=i+1;j<nbface;j++)
261     {
262     TPL_LISTE_ENTITE<double> lst2;
263     MG_FACE* face2=geo->get_mg_face(j);
264     int type2=face2->get_surface()->get_type_geometrique(lst2);
265     if (type==type2)
266     if (lst.get_nb()==lst2.get_nb())
267     {
268     int diff=0;
269     for (int i=0;i<lst.get_nb();i++)
270     if (fabs(lst.get(i)-lst2.get(i))>0.000001) diff=1;
271     if (diff==0) lstface.push_back(face2);
272     }
273 francois 222 }*/
274 francois 276 levelsetn(&lst,&lstface,solution,solution_ele,i);
275 francois 106 }
276 francois 281
277     TPL_MAP_ENTITE<MG_ARETE*>::ITERATEUR itare2;
278     i=0;
279     for (MG_ARETE* are=lstaretetan.get_premier(itare2);are!=NULL;are=lstaretetan.get_suivant(itare2))
280     {
281     if (affichageactif)
282     {
283     char mess[300];
284     sprintf(mess," Arete tangeante %d numero %lu",i,are->get_id());
285     affiche(mess);
286     }
287     traite_arete_tangeante(are,nbface+i,solution,solution_ele);
288     i++;
289     }
290    
291    
292 francois 276 affiche((char*)"Exportation IBREP");
293     IBrep brep=exporter_IBrep(nomfichieribrep,solution,solution_ele,mggt);
294     if (compteur!=NULL) compteur->ajouter_etape("Exportation IBREP");
295 francois 346 affiche((char*)"Decoupage maillage");
296     for (int i=0;i<lstaretetan.get_nb();i++)
297     decoupe_maillage(nbface+i,solution,solution_ele,0);
298     for (int i=0;i<nbface;i++)
299     decoupe_maillage(i,solution,solution_ele,1);
300     if (compteur!=NULL) compteur->ajouter_etape("Decoupage maillage");
301     affiche((char*)"Tag maillage");
302     cree_tag_maillage();
303     if (compteur!=NULL) compteur->ajouter_etape("Tag maillage");
304 francois 276 return brep;
305 francois 106 }
306    
307 francois 346
308    
309    
310     void TOIBREP::cree_tag_maillage(void)
311     {
312     /*vector<FEM_ELEMENT3*> couche;
313     LISTE_FEM_ELEMENT3::iterator ittetra;
314     for (FEM_ELEMENT3 *tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
315     {
316     if (tet->est_decoupe_arete_tangeante())
317     {
318     for (int i=tet->get_nb_xfem()-1;i>-1;i--)
319     tet->supprimer_xfem(mai,tet->get_xfem(i));
320     }
321     if (tet->get_nb_xfem()>0)
322     {
323     tet->change_etat(2);
324     couche.push_back(tet);
325     }
326     else tet->change_etat(3);
327     }
328     for (int i=0;i<couche.size();i++)
329     {
330     FEM_ELEMENT3* tet=couche[i];
331     for (int j=0;j<tet->get_nb_fem_noeud();j++)
332     {
333     int propage=0;
334     if (tet->get_etat()==2)
335     {
336     for (int k=0;k<tet->get_nb_xfem();k++)
337     {
338     XFEM_TETRA4* xtet=(XFEM_TETRA4*)tet->get_xfem(k);
339     if (xtet->est_noeud_fem(tet->get_fem_noeud(j))==1) propage=1;
340     }
341     }
342     if (tet->get_etat()!=2) propage=1;
343     if (propage==1)
344     {
345     for (int k=0;k<tet->get_fem_noeud(j)->get_lien_element3()->get_nb();k++)
346     {
347     if (tet->get_fem_noeud(j)->get_lien_element3()->get(k)->get_etat()==3)
348     {
349     tet->get_fem_noeud(j)->get_lien_element3()->get(k)->change_etat(1);
350     couche.push_back(tet->get_fem_noeud(j)->get_lien_element3()->get(k));
351     }
352     }
353     }
354    
355     }
356     }
357     double volume=0.;
358     for (FEM_ELEMENT3 *tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
359     {
360     if (tet->get_etat()==1) volume=volume+get_volume(tet);
361     if (tet->get_etat()==2)
362     {
363     for (int i=0;i<tet->get_nb_xfem();i++)
364     {
365     XFEM_TETRA4* xtet=(XFEM_TETRA4*)tet->get_xfem(i);
366     volume=volume+get_volume(xtet);
367     }
368     }
369    
370     }
371     char chaine[500];
372     sprintf(chaine," Volume=%le",volume);
373     affiche(chaine);*/
374     }
375    
376    
377     double TOIBREP::get_volume(FEM_ELEMENT3* tet)
378     {
379     FEM_NOEUD *no1=tet->get_fem_noeud(0);
380     FEM_NOEUD *no2=tet->get_fem_noeud(1);
381     FEM_NOEUD *no3=tet->get_fem_noeud(2);
382     FEM_NOEUD *no4=tet->get_fem_noeud(3);
383     OT_VECTEUR_3D vec12(no1->get_coord(),no2->get_coord());
384     OT_VECTEUR_3D vec13(no1->get_coord(),no3->get_coord());
385     OT_VECTEUR_3D vec14(no1->get_coord(),no4->get_coord());
386     double vol= (vec12&vec13)*vec14*1./6.;
387     return vol;
388     }
389    
390    
391     void TOIBREP::decoupe_maillage(int num,FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele,int avecsuppression)
392     {
393    
394     solution->active_solution(num);
395     solution_ele->active_solution(num);
396     LISTE_FEM_ELEMENT3::iterator ittetra;
397     for (FEM_ELEMENT3 *tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
398     {
399     if ((tet->get_solution()>0.5) || (tet->get_nb_xfem()!=0))
400     {
401     tet->change_etat(1);
402     int nb=tet->get_nb_xfem();
403     if (nb==0)
404     {
405     int nb2=decoupe_tetra(tet,tet,mai);
406     if (nb2!=0)
407     if (avecsuppression==1) tet->decoupe_frontiere(); else tet->decoupe_arete_tangeante();
408     }
409     else
410     for (int i=nb-1;i>-1;i--)
411     {
412     calcul_valeur_sous_element(tet,tet->get_xfem(i));
413     int nb2=decoupe_tetra(tet,tet->get_xfem(i),mai);
414     if (nb2!=0) tet->supprimer_xfem(mai,tet->get_xfem(i));
415     if (nb2!=0)
416     if (avecsuppression==1) tet->decoupe_frontiere(); else tet->decoupe_arete_tangeante();
417     }
418     if (avecsuppression==1)
419     {
420     nb=tet->get_nb_xfem();
421     for (int i=nb-1;i>-1;i--)
422     {
423     if (signe_tetra(tet->get_xfem(i))==-1)
424     {
425     FEM_NOEUD* no[4];
426     no[0]=tet->get_xfem(i)->get_fem_noeud(0);
427     no[1]=tet->get_xfem(i)->get_fem_noeud(1);
428     no[2]=tet->get_xfem(i)->get_fem_noeud(2);
429     no[3]=tet->get_xfem(i)->get_fem_noeud(3);
430     tet->supprimer_xfem(mai,tet->get_xfem(i));
431     for (int j=0;j<4;j++)
432     if (no[j]->get_numero_opt()==-1)
433     if (no[j]->get_numero()==0)
434     mai->supprimer_fem_noeud(no[j]->get_id());
435     }
436     }
437     }
438     }
439     }
440    
441     }
442    
443     void TOIBREP::calcul_valeur_sous_element(FEM_ELEMENT3* ele,FEM_ELEMENT3 *xele)
444     {
445     double x1=ele->get_fem_noeud(0)->get_x();
446     double y1=ele->get_fem_noeud(0)->get_y();
447     double z1=ele->get_fem_noeud(0)->get_z();
448     double x2=ele->get_fem_noeud(1)->get_x();
449     double y2=ele->get_fem_noeud(1)->get_y();
450     double z2=ele->get_fem_noeud(1)->get_z();
451     double x3=ele->get_fem_noeud(2)->get_x();
452     double y3=ele->get_fem_noeud(2)->get_y();
453     double z3=ele->get_fem_noeud(2)->get_z();
454     double x4=ele->get_fem_noeud(3)->get_x();
455     double y4=ele->get_fem_noeud(3)->get_y();
456     double z4=ele->get_fem_noeud(3)->get_z();
457     double sol1=ele->get_fem_noeud(0)->get_solution();
458     double sol2=ele->get_fem_noeud(1)->get_solution();
459     double sol3=ele->get_fem_noeud(2)->get_solution();
460     double sol4=ele->get_fem_noeud(3)->get_solution();
461     int nb=xele->get_nb_fem_noeud();
462     for (int i=0;i<nb;i++)
463     if (xele->get_fem_noeud(i)->get_numero_opt()==1)
464     {
465     double x=xele->get_fem_noeud(i)->get_x();
466     double y=xele->get_fem_noeud(i)->get_y();
467     double z=xele->get_fem_noeud(i)->get_z();
468     double u = -(x3 * y1 * z4 - x3 * y1 * z - y1 * z4 * x - z3 * y1 * x4 + z3 * y1 * x + y1 * z * x4 - y3 * x1 * z4 - z1 * y * x4 + z1 * y3 * x4 - z3 * x1 * y - z1 * y3 * x + y3 * x1 * z - z * x1 * y4 + z * x3 * y4 + z4 * y3 * x + z4 * x1 * y - z4 * x3 * y - z3 * y4 * x + z1 * y4 * x - z1 * x3 * y4 - y3 * z * x4 + z3 * x1 * y4 + z3 * y * x4 + z1 * x3 * y) / (-z1 * y2 * x3 - z1 * x2 * y4 - z1 * y3 * x4 + z1 * x2 * y3 + z1 * x3 * y4 + z3 * y1 * x4 + y2 * z3 * x1 + x2 * y1 * z4 - y1 * z2 * x4 + y1 * z2 * x3 + z1 * y2 * x4 + y3 * z2 * x4 + x1 * z2 * y4 - x1 * z2 * y3 - x3 * y1 * z4 - x3 * z2 * y4 - z3 * x1 * y4 + y2 * x3 * z4 - x2 * y3 * z4 + x2 * z3 * y4 - x2 * z3 * y1 - y2 * z3 * x4 - y2 * x1 * z4 + y3 * x1 * z4);
469     double v = (z1 * y4 * x + z1 * y2 * x4 - z1 * y2 * x + z1 * x2 * y - z1 * x2 * y4 - z1 * y * x4 + z4 * x1 * y - z * x1 * y4 + y2 * x1 * z - y1 * z4 * x + y1 * z * x4 + z * x2 * y4 - z * y2 * x4 + z4 * y2 * x - y4 * z2 * x + y * z2 * x4 - z4 * x2 * y + y1 * z2 * x - x2 * y1 * z - x1 * z2 * y + x2 * y1 * z4 - y1 * z2 * x4 + x1 * z2 * y4 - y2 * x1 * z4) / (-z1 * y2 * x3 - z1 * x2 * y4 - z1 * y3 * x4 + z1 * x2 * y3 + z1 * x3 * y4 + z3 * y1 * x4 + y2 * z3 * x1 + x2 * y1 * z4 - y1 * z2 * x4 + y1 * z2 * x3 + z1 * y2 * x4 + y3 * z2 * x4 + x1 * z2 * y4 - x1 * z2 * y3 - x3 * y1 * z4 - x3 * z2 * y4 - z3 * x1 * y4 + y2 * x3 * z4 - x2 * y3 * z4 + x2 * z3 * y4 - x2 * z3 * y1 - y2 * z3 * x4 - y2 * x1 * z4 + y3 * x1 * z4);
470     double w = -(-y2 * x3 * z - y2 * z3 * x1 + y2 * z3 * x + y2 * x1 * z - z3 * y1 * x + y1 * z2 * x - y1 * z2 * x3 - y3 * x1 * z - y3 * z2 * x + x2 * y3 * z + x2 * z3 * y1 - x2 * z3 * y - x2 * y1 * z - x1 * z2 * y + x1 * z2 * y3 + z1 * x2 * y + x3 * z2 * y + z3 * x1 * y + z1 * y2 * x3 + z1 * y3 * x - z1 * y2 * x - z1 * x2 * y3 + x3 * y1 * z - z1 * x3 * y) / (-z1 * y2 * x3 - z1 * x2 * y4 - z1 * y3 * x4 + z1 * x2 * y3 + z1 * x3 * y4 + z3 * y1 * x4 + y2 * z3 * x1 + x2 * y1 * z4 - y1 * z2 * x4 + y1 * z2 * x3 + z1 * y2 * x4 + y3 * z2 * x4 + x1 * z2 * y4 - x1 * z2 * y3 - x3 * y1 * z4 - x3 * z2 * y4 - z3 * x1 * y4 + y2 * x3 * z4 - x2 * y3 * z4 + x2 * z3 * y4 - x2 * z3 * y1 - y2 * z3 * x4 - y2 * x1 * z4 + y3 * x1 * z4);
471     double sol=(1.-u-v-w)*sol1+u*sol2+v*sol3+w*sol4;
472     xele->get_fem_noeud(i)->change_solution(sol);
473     }
474     }
475    
476    
477    
478    
479    
480     int TOIBREP::signe_tetra(FEM_ELEMENT3* tet)
481     {
482     int signep=0;
483     int signen=0;
484     int signem=0;
485     double val1=tet->get_fem_noeud(0)->get_solution();
486     double val2=tet->get_fem_noeud(1)->get_solution();
487     double val3=tet->get_fem_noeud(2)->get_solution();
488     double val4=tet->get_fem_noeud(3)->get_solution();
489     if (val1<1e200)
490     {
491     if (val1>0.00000001) signep++;
492     else if (val1<-0.00000001) signem++;
493     else signen++;
494     }
495     if (val2<1e200)
496     {
497     if (val2>0.00000001) signep++;
498     else if (val2<-0.00000001) signem++;
499     else signen++;
500     }
501     if (val3<1e200)
502     {
503     if (val3>0.00000001) signep++;
504     else if (val3<-0.00000001) signem++;
505     else signen++;
506     }
507     if (val4<1e200)
508     {
509     if (val4>0.00000001) signep++;
510     else if (val4<-0.00000001) signem++;
511     else signen++;
512     }v
513     if ((signep==0) && (signem>0)) return -1;
514     if ((signem==0) && (signep>0)) return 1;
515     return 0;
516     }
517    
518    
519    
520 francois 281 void TOIBREP::traite_arete_tangeante(MG_ARETE* are,int numsol,FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele)
521 francois 106 {
522 francois 281 //NPAS=150;
523     solution->active_solution(numsol);
524     solution_ele->active_solution(numsol);
525 francois 259 vector<TOIBREP_POINT*> lst;
526 francois 309 LISTE_FEM_ELEMENT3::iterator ittetra;
527     for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
528 francois 281 tet->change_etat(0);
529     LISTE_FEM_NOEUD::iterator itnoeud;
530     for (FEM_NOEUD* no=mai->get_premier_noeud(itnoeud);no!=NULL;no=mai->get_suivant_noeud(itnoeud))
531     no->change_etat(0);
532     double tmin=are->get_tmin();
533     double tmax=are->get_tmax();
534     double eps=1e-3*(tmax-tmin);
535     for (int i=0;i<NPAS+1;i++)
536     {
537     double t=tmin+i*1.0/NPAS*(tmax-tmin);
538     double xyz[3],xyzplus[3],xyzmoins[3];
539     are->evaluer(t,xyz);
540     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,NULL);
541     lst.push_back(pt);
542     if (t+eps<tmax)
543     {
544     are->evaluer(t+eps,xyzplus);
545     pt->ajoute_point_eps(xyzplus);
546     }
547     if (t-eps>tmin)
548     {
549     are->evaluer(t-eps,xyzmoins);
550     pt->ajoute_point_eps(xyzmoins);
551     }
552    
553     }
554     for (int i=0;i<lst.size();i++)
555     {
556     TOIBREP_POINT* pt=lst[i];
557     double xyz[3];
558     pt->get_coord3(xyz);
559 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*> liste;
560 francois 281 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
561 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*>::ITERATEUR it;
562     for (FEM_ELEMENT3* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
563 francois 281 {
564     if (tet->get_etat()==1) continue;
565     int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
566     if ((compare_etat(etat,SUR_FACE)) && (pt->get_interieur()))
567 francois 104 {
568 francois 281 int nbeps=pt->get_nb_point_eps();
569     for (int k=0;k<nbeps;k++)
570     {
571     double xyztmp[3];
572     pt->get_point_eps(k,xyztmp);
573     int etattmp=estdansletetra(tet,xyztmp[0],xyztmp[1],xyztmp[2]);
574     if (compare_etat(etattmp,SUR_FACE)) {etat=STRICTINTERIEUR;break;}
575     if (compare_etat(etattmp,INTERIEUR)) {etat=STRICTINTERIEUR;break;}
576     if (compare_etat(etattmp,STRICTINTERIEUR)) {etat=STRICTINTERIEUR;break;}
577     }
578 francois 104 }
579 francois 281 if (compare_etat(etat,STRICTINTERIEUR))
580     {
581     for (int k=0;k<tet->get_nb_fem_noeud();k++)
582     {
583     double dist=calcul_distance_level_ortho(tet->get_fem_noeud(k),are,pt);
584     tet->get_fem_noeud(k)->change_solution(dist);
585     tet->get_fem_noeud(k)->change_numero(pt->get_id());
586     tet->change_etat(1); //temp
587     tet->get_fem_noeud(k)->change_etat(1); //temp
588     }
589     }
590     }
591     }
592     remplir_trou_tangeant(&lst,are,solution_ele);
593    
594    
595    
596     int i=0;
597     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
598     {
599     if (noeud->get_etat()==1) solution->ecrire(i,numsol,noeud->get_solution());
600     else solution->ecrire(i,numsol,1e300);
601     ++i;
602 francois 106 }
603 francois 281 i=0;
604 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
605 francois 281 {
606     if (tet->get_etat()==1) solution_ele->ecrire(i,numsol,1.);
607     ++i;
608     }
609     int nbpt=lst.size();
610     for (int i=0;i<nbpt;i++) delete lst[i];
611     TOIBREP_POINT::remisecompteurid();
612 francois 106 }
613 francois 281
614    
615     void TOIBREP::echantillonne_sommets(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
616 francois 106 {
617 francois 276 TPL_MAP_ENTITE<MG_SOMMET*> lstsom;
618     int nbbou=face->get_nb_mg_boucle();
619     for (int i=0;i<nbbou;i++)
620     {
621     MG_BOUCLE* boucle=face->get_mg_boucle(i);
622     int nb_arete=boucle->get_nb_mg_coarete();
623     for (int j=0;j<nb_arete;j++)
624     {
625     MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
626     lstsom.ajouter(are->get_cosommet1()->get_sommet());
627     lstsom.ajouter(are->get_cosommet2()->get_sommet());
628     }
629     }
630     TPL_MAP_ENTITE<MG_SOMMET*>::ITERATEUR it;
631     for (MG_SOMMET* som=lstsom.get_premier(it);som!=NULL;som=lstsom.get_suivant(it))
632     {
633     double xyz[3];
634     som->get_point()->evaluer(xyz);
635     double uv[2];
636     face->inverser(uv,xyz);
637     int N=NPAS;
638     double rayon=1e-2;
639     for (int k=0;k<N+1;k++)
640     {
641     double uv2[2];
642     uv2[0]=uv[0]+rayon*cos(k*1.0/N*2.*M_PI);
643     uv2[1]=uv[1]+rayon*sin(k*1.0/N*2.*M_PI);
644     if ((face->valide_parametre_u(uv2[0])) && (face->valide_parametre_v(uv2[1])))
645     {
646     double distance=ot.calcule_distance_contour_face_uv(uv2,face);
647     if (distance>0.)
648     {
649     double xyz[3];
650     face->evaluer(uv2,xyz);
651     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
652     lst.push_back(pt);
653     }
654     }
655     }
656    
657     }
658     }
659 francois 281 void TOIBREP::echantillonne_aretes(std::vector<TOIBREP_POINT*> &lst,MG_FACE* face)
660 francois 276 {
661 francois 281 echantillonne_sommets(lst,face);
662 francois 276 int nbbou=face->get_nb_mg_boucle();
663     for (int i=0;i<nbbou;i++)
664     {
665     MG_BOUCLE* boucle=face->get_mg_boucle(i);
666     int nb_arete=boucle->get_nb_mg_coarete();
667     for (int j=0;j<nb_arete;j++)
668     {
669     MG_ARETE* are=boucle->get_mg_coarete(j)->get_arete();
670     double tmin=are->get_tmin();
671     double tmax=are->get_tmax();
672     double N=NPAS;
673     for (int k=0;k<N+1;k++)
674     {
675     double t=tmin+k*1.0/N*(tmax-tmin);
676     double xyz[3];
677     are->evaluer(t,xyz);
678     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
679     lst.push_back(pt);
680     // octree.inserer(pt);
681     }
682     /* double t=tmin+0.2/NPAS*(tmax-tmin);
683     double xyz[3];
684     are->evaluer(t,xyz);
685     TOIBREP_POINT *pt1=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
686     lst.push_back(pt1);
687     t=tmax-0.2/NPAS*(tmax-tmin);
688     are->evaluer(t,xyz);
689     TOIBREP_POINT *pt2=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,1,face);
690     lst.push_back(pt2);*/
691    
692    
693    
694     }
695     }
696     }
697    
698     void TOIBREP::levelsetn(TPL_MAP_ENTITE<MG_ELEMENT_TOPOLOGIQUE*> *lsttopo,vector<MG_FACE*> *lstface,class FEM_SOLUTION* solution,FEM_SOLUTION* solution_ele,int numsol)
699     {
700     if (affichageactif)
701     {
702     char mess[300];
703     sprintf(mess," Echantillonnage");
704     affiche(mess);
705     }
706    
707     solution->active_solution(numsol);
708     solution_ele->active_solution(numsol);
709     int nbface=lstface->size();
710     if (nbface==0) return;
711     vector<TOIBREP_POINT*> lst;
712     BOITE_2D boite=ot.get_boite_2D((*lstface)[0]);
713 francois 281 echantillonne_aretes(lst,(*lstface)[0]);
714 francois 276 for (int iface=1;iface<nbface;iface++)
715     {
716     MG_FACE* face=(*lstface)[iface];
717     BOITE_2D boiteface=ot.get_boite_2D(face);
718     boite=boite+boiteface;
719 francois 281 echantillonne_aretes(lst,(*lstface)[iface]);
720 francois 276 }
721     MG_FACE* face=(*lstface)[0];
722     int trouve=0;
723     int orientation;
724     int j=0;
725     do
726     {
727     MG_COFACE* coface=face->get_mg_coface(j);
728     MG_VOLUME* vol=coface->get_coquille()->get_mg_volume();
729     if (lsttopo->existe(vol))
730 francois 104 {
731 francois 276 orientation=coface->get_orientation();
732     trouve=1;
733     }
734     j++;
735     }
736     while (trouve==0);
737 francois 309 LISTE_FEM_ELEMENT3::iterator ittetra;
738     for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
739 francois 276 tet->change_etat(0);
740     LISTE_FEM_NOEUD::iterator itnoeud;
741     for (FEM_NOEUD* no=mai->get_premier_noeud(itnoeud);no!=NULL;no=mai->get_suivant_noeud(itnoeud))
742     no->change_etat(0);
743     double umin=boite.get_xmin();
744     double umax=boite.get_xmax();
745     double vmin=boite.get_ymin();
746     double vmax=boite.get_ymax();
747     if (face->get_surface()->est_periodique_u())
748     {
749     umin=0;
750     umax=face->get_surface()->get_periode_u();
751     }
752     if (face->get_surface()->est_periodique_v())
753     {
754     vmin=0;
755     vmax=face->get_surface()->get_periode_v();
756     }
757 francois 281 double epsu=1e-3*(umax-umin);
758     double epsv=1e-3*(vmax-vmin);
759     for (int i=0;i<NPAS;i++)
760     for (int j=0;j<NPAS;j++)
761 francois 276 {
762     double uv[2];
763 francois 281 uv[0]=umin+(i*1.0+0.5)/NPAS*(umax-umin);
764     uv[1]=vmin+(j*1.0+0.5)/NPAS*(vmax-vmin);
765 francois 276 double xyz[3];
766     if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
767     {
768     double distance=ot.calcule_distance_contour_face_uv(uv,face);
769     int inte=0;
770     if (distance>0.) inte=1.; else continue;
771     face->evaluer(uv,xyz);
772     TOIBREP_POINT *pt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],inte,face);
773     lst.push_back(pt);
774 francois 281 if (uv[0]+epsu<umax)
775     {
776     double uvtmp[2]={uv[0]+epsu,uv[1]};
777     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
778     if (distance>1e-8)
779     {
780     face->evaluer(uvtmp,xyz);
781     pt->ajoute_point_eps(xyz);
782     }
783     }
784     if (uv[0]-epsu>umin)
785     {
786     double uvtmp[2]={uv[0]-epsu,uv[1]};
787     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
788     if (distance>1e-8)
789     {
790     face->evaluer(uvtmp,xyz);
791     pt->ajoute_point_eps(xyz);
792     }
793     }
794     if (uv[1]+epsv<vmax)
795     {
796     double uvtmp[2]={uv[0],uv[1]+epsv};
797     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
798     if (distance>1e-8)
799     {
800     face->evaluer(uvtmp,xyz);
801     pt->ajoute_point_eps(xyz);
802     }
803     }
804     if (uv[1]-epsv>vmin)
805     {
806     double uvtmp[2]={uv[0],uv[1]-epsv};
807     double distance=ot.calcule_distance_contour_face_uv(uvtmp,face);
808     if (distance>1e-8)
809     {
810     face->evaluer(uvtmp,xyz);
811     pt->ajoute_point_eps(xyz);
812     }
813     }
814 francois 276 // octree.inserer(pt);
815     }
816     }
817 francois 346 /* debut temp
818     {
819 francois 276 MG_GESTIONNAIRE gestemp;
820     MG_MAILLAGE *mai=new MG_MAILLAGE(NULL);
821     gestemp.ajouter_mg_maillage(mai);
822     for (int i=0;i<lst.size();i++)
823     {
824     double xyz[3];
825     lst[i]->get_coord3(xyz);
826     MG_NOEUD* no=new MG_NOEUD(NULL,xyz[0],xyz[1],xyz[2],TRIANGULATION);
827     mai->ajouter_mg_noeud(no);
828     if (i!=0) {MG_SEGMENT* seg=new MG_SEGMENT(NULL,no,mai->get_mg_noeud(mai->get_nb_mg_noeud()-2),TRIANGULATION);mai->ajouter_mg_segment(seg);}
829     }
830    
831     gestemp.enregistrer("debug.magic");
832 francois 346 }*/
833 francois 276 // fin temp
834     if (compteur!=NULL) compteur->ajouter_etape("Echantillonnage");
835     if (affichageactif)
836     {
837     char mess[300];
838     sprintf(mess," Preparation newton");
839     affiche(mess);
840     }
841     calcullevelsetpremierepasse(face,orientation,&lst,0,lst.size());
842     if (compteur!=NULL) compteur->ajouter_etape("Preparation newton");
843    
844     if (affichageactif)
845     {
846     char mess[300];
847     sprintf(mess," Newton");
848     affiche(mess);
849     }
850     calcullevelsetdeuxiemepasse(&lst);
851     if (compteur!=NULL) compteur->ajouter_etape("Newton");
852     if (affichageactif)
853     {
854     char mess[300];
855     sprintf(mess," Remplissage des trous");
856     affiche(mess);
857     }
858     remplir_trou(&lst,face,orientation);
859     if (compteur!=NULL) compteur->ajouter_etape("Remplissage des trous");
860     //etendrelevelset(solution,numsol);
861     int i=0;
862     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
863     {
864 francois 280 if (noeud->get_etat()==1) solution->ecrire(i,numsol,noeud->get_solution());
865 francois 276 else solution->ecrire(i,numsol,1e300);
866     ++i;
867     }
868     i=0;
869 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
870 francois 276 {
871 francois 280 if (tet->get_etat()==1) solution_ele->ecrire(i,numsol,1.);
872 francois 276 ++i;
873     }
874     int nbpt=lst.size();
875     for (int i=0;i<nbpt;i++) delete lst[i];
876     TOIBREP_POINT::remisecompteurid();
877    
878    
879    
880     }
881 francois 281 void TOIBREP::remplir_trou_tangeant(std::vector<TOIBREP_POINT*> *lst,MG_ARETE* are,FEM_SOLUTION *solution_ele)
882     {
883     MG_FACE* face1=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
884     MG_FACE* face2=are->get_mg_coarete(1)->get_boucle()->get_mg_face();
885 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*> lst_element3_concerne;
886 francois 281 int num1,num2;
887     int nbchamp=solution_ele->get_nb_champ();
888     for (int i=0;i<nbchamp;i++)
889     {
890     std::string nom=solution_ele->get_legende(i);
891     char nom2[2];
892     unsigned long id;
893     sscanf(nom.c_str(),"%s %lu",nom2,&id);
894     if (id==face1->get_id()) num1=i;
895     if (id==face2->get_id()) num2=i;
896     }
897 francois 309 LISTE_FEM_ELEMENT3::iterator ittet;
898 francois 281 int i=0;
899 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittet);tet!=NULL;tet=mai->get_suivant_element3(ittet))
900 francois 281 {
901     if (solution_ele->lire(i,num1)>0.000001)
902 francois 309 lst_element3_concerne.ajouter(tet);
903 francois 281 if (solution_ele->lire(i,num2)>0.000001)
904 francois 309 lst_element3_concerne.ajouter(tet);
905 francois 281 i++;
906     }
907 francois 276
908 francois 281
909     int couche_active;
910     int nb_couche=0;
911     do
912     {
913     nb_couche++;
914 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*>::ITERATEUR ittetra;
915     std::vector<FEM_ELEMENT3*> couche;
916 francois 281 couche_active=0;
917 francois 309 for (FEM_ELEMENT3* tet=lst_element3_concerne.get_premier(ittetra);tet!=NULL;tet=lst_element3_concerne.get_suivant(ittetra))
918 francois 281 {
919     if (tet->get_etat()!=0) continue;
920     FEM_NOEUD *no1=tet->get_fem_noeud(0);
921     FEM_NOEUD *no2=tet->get_fem_noeud(1);
922     FEM_NOEUD *no3=tet->get_fem_noeud(2);
923     FEM_NOEUD *no4=tet->get_fem_noeud(3);
924     int nbactif=0;
925     int nbpositif=0;
926     if ((no1->get_etat()==1) || (no1->get_etat()==-1))
927     {
928     nbactif++;
929     if (no1->get_solution()>0.) nbpositif++;
930     }
931     if ((no2->get_etat()==1) || (no2->get_etat()==-1))
932     {
933     nbactif++;
934     if (no2->get_solution()>0.) nbpositif++;
935     }
936     if ((no3->get_etat()==1) || (no3->get_etat()==-1))
937     {
938     nbactif++;
939     if (no3->get_solution()>0.) nbpositif++;
940     }
941     if ((no4->get_etat()==1) || (no4->get_etat()==-1))
942     {
943     nbactif++;
944     if (no4->get_solution()>0.) nbpositif++;
945     }
946     if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
947     {
948     couche.push_back(tet);
949     }
950     }
951     for (int i=0;i<couche.size();i++)
952     {
953 francois 309 FEM_ELEMENT3* tet=couche[i];
954 francois 281 FEM_NOEUD *no1=tet->get_fem_noeud(0);
955     FEM_NOEUD *no2=tet->get_fem_noeud(1);
956     FEM_NOEUD *no3=tet->get_fem_noeud(2);
957     FEM_NOEUD *no4=tet->get_fem_noeud(3);
958     TOIBREP_POINT* pt;
959     FEM_NOEUD* noeudref;
960     if (no1->get_etat()==0) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
961     if (no2->get_etat()==0) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
962     if (no3->get_etat()==0) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
963     if (no4->get_etat()==0) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
964     MG_FACE* face=pt->get_mg_face();
965     double t,xyz[3];
966     double dist=calcul_distance_level_ortho(noeudref,are,pt,t,xyz);
967     noeudref->change_solution(dist);
968     noeudref->change_etat(2);
969     TOIBREP_POINT *nvpt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],t,0.,1,NULL);
970     lst->push_back(nvpt);
971     noeudref->change_numero(nvpt->get_id());
972     }
973 francois 309 for (FEM_ELEMENT3* tet=lst_element3_concerne.get_premier(ittetra);tet!=NULL;tet=lst_element3_concerne.get_suivant(ittetra))
974 francois 281 {
975     FEM_NOEUD *no1=tet->get_fem_noeud(0);
976     FEM_NOEUD *no2=tet->get_fem_noeud(1);
977     FEM_NOEUD *no3=tet->get_fem_noeud(2);
978     FEM_NOEUD *no4=tet->get_fem_noeud(3);
979     if (no1->get_etat()!=0)
980     if (no2->get_etat()!=0)
981     if (no3->get_etat()!=0)
982     if (no4->get_etat()!=0)
983     if (tet->get_etat()==0)
984     {
985     int reactive=0;
986     for (int i=0;i<tet->get_nb_fem_noeud();i++)
987     {
988     if (reactive) continue;
989     FEM_NOEUD* no=tet->get_fem_noeud(i);
990     TOIBREP_POINT *pt=(*lst)[no->get_numero()];
991     double t;
992     pt->get_coord1(t);
993     double eps=1e-4*(are->get_tmax()-are->get_tmin());
994     if ((t>=are->get_tmin()-eps) && (t<are->get_tmax()+eps))
995     {
996     tet->change_etat(1);
997     no1->change_etat(1);
998     no2->change_etat(1);
999     no3->change_etat(1);
1000     no4->change_etat(1);
1001     reactive=1;
1002     couche_active=1;
1003    
1004     }
1005    
1006     }
1007     if (!reactive)
1008     {
1009     if (no1->get_etat()==2) no1->change_etat(-1);
1010     if (no2->get_etat()==2) no2->change_etat(-1);
1011     if (no3->get_etat()==2) no3->change_etat(-1);
1012     if (no4->get_etat()==2) no4->change_etat(-1);
1013     tet->change_etat(-1);
1014     }
1015     }
1016     }
1017     }
1018     while (couche_active==1);
1019 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*>::ITERATEUR ittetra;
1020     for (FEM_ELEMENT3* tet=lst_element3_concerne.get_premier(ittetra);tet!=NULL;tet=lst_element3_concerne.get_suivant(ittetra))
1021 francois 281 {
1022     if (tet->get_etat()!=1) continue;
1023     FEM_NOEUD *no1=tet->get_fem_noeud(0);
1024     FEM_NOEUD *no2=tet->get_fem_noeud(1);
1025     FEM_NOEUD *no3=tet->get_fem_noeud(2);
1026     FEM_NOEUD *no4=tet->get_fem_noeud(3);
1027     int nbpositif=0;
1028     int nbnegatif=0;
1029     double epsdist=1e-6*tet->get_boite_3D().get_rayon();
1030     if (no1->get_solution()>epsdist) nbpositif++;
1031     if (no1->get_solution()<-epsdist) nbnegatif++;
1032     if (no2->get_solution()>epsdist) nbpositif++;
1033     if (no2->get_solution()<-epsdist) nbnegatif++;
1034     if (no3->get_solution()>epsdist) nbpositif++;
1035     if (no3->get_solution()<-epsdist) nbnegatif++;
1036     if (no4->get_solution()>epsdist) nbpositif++;
1037     if (no4->get_solution()<-epsdist) nbnegatif++;
1038     if (!(((nbnegatif>0) && (nbpositif>0)) ||(nbnegatif+nbpositif==1)))
1039     tet->change_etat(0);
1040     }
1041     }
1042    
1043    
1044 francois 276 void TOIBREP::remplir_trou(std::vector<TOIBREP_POINT*> *lst,MG_FACE* face,int sens)
1045     {
1046     int castot=0;
1047     int cas=0;
1048 francois 280 int couche_active;
1049     int nb_couche=0;
1050 francois 309 LISTE_FEM_ELEMENT3::iterator ittetra;
1051 francois 280 do
1052     {
1053     nb_couche++;
1054 francois 281
1055 francois 309 std::vector<FEM_ELEMENT3*> couche;
1056 francois 280 couche_active=0;
1057 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
1058 francois 276 {
1059 francois 280 if (tet->get_etat()!=0) continue;
1060 francois 276 FEM_NOEUD *no1=tet->get_fem_noeud(0);
1061     FEM_NOEUD *no2=tet->get_fem_noeud(1);
1062     FEM_NOEUD *no3=tet->get_fem_noeud(2);
1063     FEM_NOEUD *no4=tet->get_fem_noeud(3);
1064     int nbactif=0;
1065     int nbpositif=0;
1066 francois 280 if ((no1->get_etat()==1) || (no1->get_etat()==-1))
1067 francois 276 {
1068     nbactif++;
1069     if (no1->get_solution()>0.) nbpositif++;
1070     }
1071 francois 280 if ((no2->get_etat()==1) || (no2->get_etat()==-1))
1072 francois 276 {
1073     nbactif++;
1074     if (no2->get_solution()>0.) nbpositif++;
1075     }
1076 francois 280 if ((no3->get_etat()==1) || (no3->get_etat()==-1))
1077 francois 276 {
1078     nbactif++;
1079     if (no3->get_solution()>0.) nbpositif++;
1080     }
1081 francois 280 if ((no4->get_etat()==1) || (no4->get_etat()==-1))
1082 francois 276 {
1083     nbactif++;
1084     if (no4->get_solution()>0.) nbpositif++;
1085     }
1086     if ((nbactif==3) && (nbpositif<3) && (nbpositif>0))
1087     {
1088     couche.push_back(tet);
1089     }
1090     }
1091     for (int i=0;i<couche.size();i++)
1092     {
1093 francois 309 FEM_ELEMENT3* tet=couche[i];
1094 francois 276 FEM_NOEUD *no1=tet->get_fem_noeud(0);
1095     FEM_NOEUD *no2=tet->get_fem_noeud(1);
1096     FEM_NOEUD *no3=tet->get_fem_noeud(2);
1097     FEM_NOEUD *no4=tet->get_fem_noeud(3);
1098     TOIBREP_POINT* pt;
1099     FEM_NOEUD* noeudref;
1100 francois 280 if (no1->get_etat()==0) {noeudref=no1;pt=(*lst)[no2->get_numero()];}
1101     if (no2->get_etat()==0) {noeudref=no2;pt=(*lst)[no1->get_numero()];}
1102     if (no3->get_etat()==0) {noeudref=no3;pt=(*lst)[no1->get_numero()];}
1103     if (no4->get_etat()==0) {noeudref=no4;pt=(*lst)[no1->get_numero()];}
1104 francois 281 MG_FACE* face=pt->get_mg_face();
1105 francois 280 double uv[2];
1106 francois 276 double xyz[3];
1107 francois 280 double dist=calcul_distance(noeudref,face,pt,xyz,uv);
1108     double normal[3];
1109 francois 276 face->calcul_normale_unitaire(uv,normal);
1110     normal[0]=normal[0]*sens*(-1.);
1111     normal[1]=normal[1]*sens*(-1.);
1112     normal[2]=normal[2]*sens*(-1.);
1113     double dist2=calculdist(normal,xyz[0],xyz[1],xyz[2],noeudref);
1114     if (dist2<0.) dist=dist*(-1);
1115     noeudref->change_solution(dist);
1116 francois 280 noeudref->change_etat(2);
1117     TOIBREP_POINT *nvpt=new TOIBREP_POINT(xyz[0],xyz[1],xyz[2],uv[0],uv[1],1,face);
1118     lst->push_back(nvpt);
1119     noeudref->change_numero(nvpt->get_id());
1120 francois 276
1121     }
1122 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
1123 francois 276 {
1124     FEM_NOEUD *no1=tet->get_fem_noeud(0);
1125     FEM_NOEUD *no2=tet->get_fem_noeud(1);
1126     FEM_NOEUD *no3=tet->get_fem_noeud(2);
1127     FEM_NOEUD *no4=tet->get_fem_noeud(3);
1128 francois 280 if (no1->get_etat()!=0)
1129     if (no2->get_etat()!=0)
1130     if (no3->get_etat()!=0)
1131     if (no4->get_etat()!=0)
1132     if (tet->get_etat()==0)
1133 francois 276 {
1134     castot++;
1135 francois 280 double lstptdecoup[5*3];
1136 francois 276 int nb=0;
1137 francois 346 decoupe_tetra_noeud(tet,lstptdecoup,&nb);
1138 francois 280 int reactive=0;
1139 francois 276 for (int i=0;i<nb;i++)
1140     {
1141 francois 280 if (reactive) continue;
1142 francois 276 double uv[2];
1143 francois 280 face->inverser(uv,lstptdecoup+3*i);
1144 francois 276 if ((face->valide_parametre_u(uv[0])) && (face->valide_parametre_v(uv[1])))
1145     {
1146     double distance=ot.calcule_distance_contour_face_uv(uv,face);
1147     if (distance>1e-6)
1148     {
1149     cas++;
1150     tet->change_etat(1);
1151 francois 280 no1->change_etat(1);
1152     no2->change_etat(1);
1153     no3->change_etat(1);
1154     no4->change_etat(1);
1155     reactive=1;
1156     couche_active=1;
1157 francois 276 }
1158     }
1159     }
1160 francois 280 if (!reactive)
1161     {
1162     if (no1->get_etat()==2) no1->change_etat(-1);
1163     if (no2->get_etat()==2) no2->change_etat(-1);
1164     if (no3->get_etat()==2) no3->change_etat(-1);
1165     if (no4->get_etat()==2) no4->change_etat(-1);
1166     tet->change_etat(-1);
1167     }
1168 francois 276 }
1169     }
1170 francois 280 }
1171     while (couche_active==1);
1172 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittetra);tet!=NULL;tet=mai->get_suivant_element3(ittetra))
1173 francois 281 {
1174     FEM_NOEUD *no1=tet->get_fem_noeud(0);
1175     FEM_NOEUD *no2=tet->get_fem_noeud(1);
1176     FEM_NOEUD *no3=tet->get_fem_noeud(2);
1177     FEM_NOEUD *no4=tet->get_fem_noeud(3);
1178 francois 346 /* if (no1->get_etat()==1)
1179     if (no2->get_etat()==1)
1180     if (no3->get_etat()==1)
1181     if (no4->get_etat()==1)
1182     if (tet->get_etat()!=1)
1183     tet->change_etat(1);*/
1184    
1185     if (tet->get_etat()!=1) continue;
1186 francois 281 int nbpositif=0;
1187     int nbnegatif=0;
1188     double epsdist=1e-6*tet->get_boite_3D().get_rayon();
1189     if (no1->get_solution()>epsdist) nbpositif++;
1190     if (no1->get_solution()<-epsdist) nbnegatif++;
1191     if (no2->get_solution()>epsdist) nbpositif++;
1192     if (no2->get_solution()<-epsdist) nbnegatif++;
1193     if (no3->get_solution()>epsdist) nbpositif++;
1194     if (no3->get_solution()<-epsdist) nbnegatif++;
1195     if (no4->get_solution()>epsdist) nbpositif++;
1196     if (no4->get_solution()<-epsdist) nbnegatif++;
1197     if (!(((nbnegatif>0) && (nbpositif>0)) ||(nbnegatif+nbpositif==1)))
1198     tet->change_etat(0);
1199     }
1200     double res=cas*100.0/castot;
1201 francois 276 char mess[255];
1202 francois 280 sprintf(mess," %lf%% en %d couches",res,nb_couche);
1203 francois 276 affiche(mess);
1204     }
1205    
1206 francois 346 int TOIBREP::decoupe_tetra(FEM_ELEMENT3* tet,FEM_ELEMENT3* xtet,FEM_MAILLAGE* mai)
1207 francois 276 {
1208 francois 346 FEM_NOEUD* no1=xtet->get_fem_noeud(0);
1209     FEM_NOEUD* no2=xtet->get_fem_noeud(1);
1210     FEM_NOEUD* no3=xtet->get_fem_noeud(2);
1211     FEM_NOEUD* no4=xtet->get_fem_noeud(3);
1212     if (no1->get_solution()*no2->get_solution()<-0.00000001)
1213     {
1214     double t=no1->get_solution()/(no1->get_solution()-no2->get_solution());
1215     double x=no1->get_x()+t*(no2->get_x()-no1->get_x());
1216     double y=no1->get_y()+t*(no2->get_y()-no1->get_y());
1217     double z=no1->get_z()+t*(no2->get_z()-no1->get_z());
1218     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1219     no->change_solution(0.0);
1220     no->change_numero(0);
1221     no->change_numero_opt(1);
1222     mai->ajouter_fem_noeud(no);
1223     FEM_NOEUD *lstno[4];
1224     lstno[0]=no1;
1225     lstno[1]=no;
1226     lstno[2]=no3;
1227     lstno[3]=no4;
1228     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1229     lstno[0]=no;
1230     lstno[1]=no2;
1231     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1232     int nb=decoupe_tetra(tet,tet1,mai);
1233     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1234     nb=decoupe_tetra(tet,tet2,mai);
1235     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1236     return 2;
1237     }
1238     if (no1->get_solution()*no3->get_solution()<-0.00000001)
1239     {
1240     double t=no1->get_solution()/(no1->get_solution()-no3->get_solution());
1241     double x=no1->get_x()+t*(no3->get_x()-no1->get_x());
1242     double y=no1->get_y()+t*(no3->get_y()-no1->get_y());
1243     double z=no1->get_z()+t*(no3->get_z()-no1->get_z());
1244     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1245     no->change_solution(0.0);
1246     no->change_numero(0);
1247     no->change_numero_opt(1);
1248     mai->ajouter_fem_noeud(no);
1249     FEM_NOEUD *lstno[4];
1250     lstno[0]=no1;
1251     lstno[1]=no2;
1252     lstno[2]=no;
1253     lstno[3]=no4;
1254     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1255     lstno[0]=no;
1256     lstno[2]=no3;
1257     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1258     int nb=decoupe_tetra(tet,tet1,mai);
1259     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1260     nb=decoupe_tetra(tet,tet2,mai);
1261     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1262     return 2;
1263     }
1264     if (no1->get_solution()*no4->get_solution()<-0.00000001)
1265     {
1266     double t=no1->get_solution()/(no1->get_solution()-no4->get_solution());
1267     double x=no1->get_x()+t*(no4->get_x()-no1->get_x());
1268     double y=no1->get_y()+t*(no4->get_y()-no1->get_y());
1269     double z=no1->get_z()+t*(no4->get_z()-no1->get_z());
1270     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1271     no->change_solution(0.0);
1272     no->change_numero(0);
1273     no->change_numero_opt(1);
1274     mai->ajouter_fem_noeud(no);
1275     FEM_NOEUD *lstno[4];
1276     lstno[0]=no1;
1277     lstno[1]=no2;
1278     lstno[2]=no3;
1279     lstno[3]=no;
1280     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1281     lstno[0]=no;
1282     lstno[3]=no4;
1283     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1284     int nb=decoupe_tetra(tet,tet1,mai);
1285     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1286     nb=decoupe_tetra(tet,tet2,mai);
1287     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1288     return 2;
1289     }
1290     if (no2->get_solution()*no3->get_solution()<-0.00000001)
1291     {
1292     double t=no2->get_solution()/(no2->get_solution()-no3->get_solution());
1293     double x=no2->get_x()+t*(no3->get_x()-no2->get_x());
1294     double y=no2->get_y()+t*(no3->get_y()-no2->get_y());
1295     double z=no2->get_z()+t*(no3->get_z()-no2->get_z());
1296     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1297     no->change_solution(0.0);
1298     no->change_numero(0);
1299     no->change_numero_opt(1);
1300     mai->ajouter_fem_noeud(no);
1301     FEM_NOEUD *lstno[4];
1302     lstno[0]=no1;
1303     lstno[1]=no2;
1304     lstno[2]=no;
1305     lstno[3]=no4;
1306     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1307     lstno[1]=no;
1308     lstno[2]=no3;
1309     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1310     int nb=decoupe_tetra(tet,tet1,mai);
1311     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1312     nb=decoupe_tetra(tet,tet2,mai);
1313     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1314     return 2;
1315     }
1316     if (no2->get_solution()*no4->get_solution()<-0.00000001)
1317     {
1318     double t=no2->get_solution()/(no2->get_solution()-no4->get_solution());
1319     double x=no2->get_x()+t*(no4->get_x()-no2->get_x());
1320     double y=no2->get_y()+t*(no4->get_y()-no2->get_y());
1321     double z=no2->get_z()+t*(no4->get_z()-no2->get_z());
1322     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1323     no->change_solution(0.0);
1324     no->change_numero_opt(1);
1325     no->change_numero(0);
1326     mai->ajouter_fem_noeud(no);
1327     FEM_NOEUD *lstno[4];
1328     lstno[0]=no1;
1329     lstno[1]=no2;
1330     lstno[2]=no3;
1331     lstno[3]=no;
1332     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1333     lstno[1]=no;
1334     lstno[3]=no4;
1335     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1336     int nb=decoupe_tetra(tet,tet1,mai);
1337     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1338     nb=decoupe_tetra(tet,tet2,mai);
1339     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1340     return 2;
1341     }
1342     if (no3->get_solution()*no4->get_solution()<-0.00000001)
1343     {
1344     double t=no3->get_solution()/(no3->get_solution()-no4->get_solution());
1345     double x=no3->get_x()+t*(no4->get_x()-no3->get_x());
1346     double y=no3->get_y()+t*(no4->get_y()-no3->get_y());
1347     double z=no3->get_z()+t*(no4->get_z()-no3->get_z());
1348     FEM_NOEUD* no=new FEM_NOEUD(tet->get_mg_element_maillage(),x,y,z);
1349     no->change_solution(0.0);
1350     no->change_numero_opt(1);
1351     no->change_numero(0);
1352     mai->ajouter_fem_noeud(no);
1353     FEM_NOEUD *lstno[4];
1354     lstno[0]=no1;
1355     lstno[1]=no2;
1356     lstno[2]=no3;
1357     lstno[3]=no;
1358     XFEM_TETRA4* tet1=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1359     lstno[2]=no;
1360     lstno[3]=no4;
1361     XFEM_TETRA4* tet2=new XFEM_TETRA4(mai,(FEM_TETRA4*)tet,lstno);
1362     int nb=decoupe_tetra(tet,tet1,mai);
1363     if (nb!=0) tet->supprimer_xfem(mai,tet1);
1364     nb=decoupe_tetra(tet,tet2,mai);
1365     if (nb!=0) tet->supprimer_xfem(mai,tet2);
1366     return 2;
1367     }
1368     return 0;
1369     }
1370    
1371    
1372    
1373    
1374     void TOIBREP::decoupe_tetra_noeud(FEM_ELEMENT3* tet,double* lst,int *nb)
1375     {
1376 francois 276 FEM_NOEUD* no1=tet->get_fem_noeud(0);
1377     FEM_NOEUD* no2=tet->get_fem_noeud(1);
1378     FEM_NOEUD* no3=tet->get_fem_noeud(2);
1379     FEM_NOEUD* no4=tet->get_fem_noeud(3);
1380     if (no1->get_solution()*no2->get_solution()<-0.00000001)
1381     {
1382     double t=no1->get_solution()/(no1->get_solution()-no2->get_solution());
1383     double x=no1->get_x()+t*(no2->get_x()-no1->get_x());
1384     double y=no1->get_y()+t*(no2->get_y()-no1->get_y());
1385     double z=no1->get_z()+t*(no2->get_z()-no1->get_z());
1386     lst[3*(*nb)]=x;
1387     lst[3*(*nb)+1]=y;
1388     lst[3*(*nb)+2]=z;
1389     (*nb)++;
1390     }
1391     if (no1->get_solution()*no3->get_solution()<-0.00000001)
1392     {
1393     double t=no1->get_solution()/(no1->get_solution()-no3->get_solution());
1394     double x=no1->get_x()+t*(no3->get_x()-no1->get_x());
1395     double y=no1->get_y()+t*(no3->get_y()-no1->get_y());
1396     double z=no1->get_z()+t*(no3->get_z()-no1->get_z());
1397     lst[3*(*nb)]=x;
1398     lst[3*(*nb)+1]=y;
1399     lst[3*(*nb)+2]=z;
1400     (*nb)++;
1401     }
1402     if (no1->get_solution()*no4->get_solution()<-0.00000001)
1403     {
1404     double t=no1->get_solution()/(no1->get_solution()-no4->get_solution());
1405     double x=no1->get_x()+t*(no4->get_x()-no1->get_x());
1406     double y=no1->get_y()+t*(no4->get_y()-no1->get_y());
1407     double z=no1->get_z()+t*(no4->get_z()-no1->get_z());
1408     lst[3*(*nb)]=x;
1409     lst[3*(*nb)+1]=y;
1410     lst[3*(*nb)+2]=z;
1411     (*nb)++;
1412     }
1413     if (no2->get_solution()*no3->get_solution()<-0.00000001)
1414     {
1415     double t=no2->get_solution()/(no2->get_solution()-no3->get_solution());
1416     double x=no2->get_x()+t*(no3->get_x()-no2->get_x());
1417     double y=no2->get_y()+t*(no3->get_y()-no2->get_y());
1418     double z=no2->get_z()+t*(no3->get_z()-no2->get_z());
1419     lst[3*(*nb)]=x;
1420     lst[3*(*nb)+1]=y;
1421     lst[3*(*nb)+2]=z;
1422     (*nb)++;
1423     }
1424     if (no2->get_solution()*no4->get_solution()<-0.00000001)
1425     {
1426     double t=no2->get_solution()/(no2->get_solution()-no4->get_solution());
1427     double x=no2->get_x()+t*(no4->get_x()-no2->get_x());
1428     double y=no2->get_y()+t*(no4->get_y()-no2->get_y());
1429     double z=no2->get_z()+t*(no4->get_z()-no2->get_z());
1430     lst[3*(*nb)]=x;
1431     lst[3*(*nb)+1]=y;
1432     lst[3*(*nb)+2]=z;
1433     (*nb)++;
1434     }
1435     if (no3->get_solution()*no4->get_solution()<-0.00000001)
1436     {
1437     double t=no3->get_solution()/(no3->get_solution()-no4->get_solution());
1438     double x=no3->get_x()+t*(no4->get_x()-no3->get_x());
1439     double y=no3->get_y()+t*(no4->get_y()-no3->get_y());
1440     double z=no3->get_z()+t*(no4->get_z()-no3->get_z());
1441     lst[3*(*nb)]=x;
1442     lst[3*(*nb)+1]=y;
1443     lst[3*(*nb)+2]=z;
1444     (*nb)++;
1445     }
1446     }
1447    
1448     void TOIBREP::calcullevelsetpremierepasse(MG_FACE* face,int sens,vector<TOIBREP_POINT*> *lst,int n1,int n2)
1449     {
1450 francois 309 /*LISTE_FEM_ELEMENT3::iterator it3;
1451     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
1452 francois 276 {
1453     double *xyz1,*xyz2,*xyz3,*xyz4;
1454     if (tet->get_nb_fem_noeud()==4)
1455     {
1456     xyz1=tet->get_fem_noeud(0)->get_coord();
1457     xyz2=tet->get_fem_noeud(1)->get_coord();
1458     xyz3=tet->get_fem_noeud(2)->get_coord();
1459     xyz4=tet->get_fem_noeud(3)->get_coord();
1460     }
1461     if (tet->get_nb_fem_noeud()==10)
1462     {
1463     xyz1=tet->get_fem_noeud(0)->get_coord();
1464     xyz2=tet->get_fem_noeud(2)->get_coord();
1465     xyz3=tet->get_fem_noeud(4)->get_coord();
1466     xyz4=tet->get_fem_noeud(9)->get_coord();
1467     }
1468     double xcentre=0.25*(xyz1[0]+xyz2[0]+xyz3[0]+xyz4[0]);
1469     double ycentre=0.25*(xyz1[1]+xyz2[1]+xyz3[1]+xyz4[1]);
1470     double zcentre=0.25*(xyz1[2]+xyz2[2]+xyz3[2]+xyz4[2]);
1471     double rayon1=(xyz1[0]-xcentre)*(xyz1[0]-xcentre)+(xyz1[1]-ycentre)*(xyz1[1]-ycentre)+(xyz1[2]-zcentre)*(xyz1[2]-zcentre);
1472     double rayon2=(xyz2[0]-xcentre)*(xyz2[0]-xcentre)+(xyz2[1]-ycentre)*(xyz2[1]-ycentre)+(xyz2[2]-zcentre)*(xyz2[2]-zcentre);
1473     double rayon3=(xyz3[0]-xcentre)*(xyz3[0]-xcentre)+(xyz3[1]-ycentre)*(xyz3[1]-ycentre)+(xyz3[2]-zcentre)*(xyz3[2]-zcentre);
1474     double rayon4=(xyz4[0]-xcentre)*(xyz4[0]-xcentre)+(xyz4[1]-ycentre)*(xyz4[1]-ycentre)+(xyz4[2]-zcentre)*(xyz4[2]-zcentre);
1475     double rayon=std::max(rayonETRA_ACTIF1,std::max(rayon2,std::max(rayon3,rayon4)));
1476     rayon=sqrt(rayon);
1477     TPL_MAP_ENTITE<TOIBREP_POINT*> liste;
1478     octree.rechercher(xcentre,ycentre,zcentre,rayon,liste);
1479     TPL_MAP_ENTITE<TOIBREP_POINT*>::ITERATEUR it;
1480     for (TOIBREP_POINT* pt=liste.get_premier(it);pt!=NULL;pt=liste.get_suivant(it))
1481     {
1482     double xyzpt[3];
1483     pt->get_coord3(xyzpt);
1484     int etat=estdansletetra(tet,xyzpt[0],xyzpt[1],xyzpt[2]);
1485     if (compare_etat(etat,INTERIEUR))
1486     {
1487     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1488     {
1489     double normal[3];
1490     double uv[2];
1491     face->inverser(uv,xyzpt);
1492     face->calcul_normale_unitaire(uv,normal);
1493     normal[0]=normal[0]*sens*(-1.);
1494     normal[1]=normal[1]*sens*(-1.);
1495     normal[2]=normal[2]*sens*(-1.);
1496     double dist=calculdist(normal,xyzpt[0],xyzpt[1],xyzpt[2],tet->get_fem_noeud(k));
1497     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
1498     {
1499     tet->get_fem_noeud(k)->change_solution(dist);
1500     tet->get_fem_noeud(k)->change_numero(pt->get_id());
1501     pt->change_coord2(uv);
1502     }
1503     }
1504     }
1505     if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
1506     {
1507     tet->change_etat(1);
1508     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1509     tet->get_fem_noeud(k)->change_etat(1);
1510     }
1511     if (tet->get_etat()==1) break;
1512     }
1513    
1514     }
1515     octree.vide();
1516 francois 281 it}*/
1517 francois 309 /*LISTE_FEM_ELEMENT3::iterator it3;
1518     for (FEM_ELEMENT3* tet=mai->get_premier_element3(it3);tet!=NULL;tet=mai->get_suivant_element3(it3))
1519 francois 276 octree.inserer(tet);*/
1520     for (int i=n1;i<n2;i++)
1521     {
1522 francois 259 TOIBREP_POINT* pt=(*lst)[i];
1523 francois 104 double uv[2];
1524 francois 106 double xyz[3];
1525     pt->get_coord3(xyz);
1526 francois 222 double normal[3];
1527 francois 104 face->inverser(uv,xyz);
1528     face->calcul_normale_unitaire(uv,normal);
1529 francois 222 normal[0]=normal[0]*sens*(-1.);
1530     normal[1]=normal[1]*sens*(-1.);
1531     normal[2]=normal[2]*sens*(-1.);
1532 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*> liste;
1533 francois 259 octree.rechercher(xyz[0],xyz[1],xyz[2],0.,liste);
1534 francois 309 TPL_MAP_ENTITE<FEM_ELEMENT3*>::ITERATEUR it;
1535     for (FEM_ELEMENT3* tet=liste.get_premier(it);tet!=NULL;tet=liste.get_suivant(it))
1536 francois 104 {
1537 francois 276 if (tet->get_etat()==1) continue;
1538     int etat=estdansletetra(tet,xyz[0],xyz[1],xyz[2]);
1539 francois 281 if ((compare_etat(etat,SUR_FACE)) && (pt->get_interieur()))
1540     {
1541     int nbeps=pt->get_nb_point_eps();
1542     for (int k=0;k<nbeps;k++)
1543     {
1544     double xyztmp[3];
1545     pt->get_point_eps(k,xyztmp);
1546     int etattmp=estdansletetra(tet,xyztmp[0],xyztmp[1],xyztmp[2]);
1547     if (compare_etat(etattmp,SUR_FACE)) {etat=STRICTINTERIEUR;break;}
1548     if (compare_etat(etattmp,INTERIEUR)) {etat=STRICTINTERIEUR;break;}
1549     if (compare_etat(etattmp,STRICTINTERIEUR)) {etat=STRICTINTERIEUR;break;}
1550     }
1551     }
1552 francois 276 if (compare_etat(etat,INTERIEUR))
1553 francois 104 {
1554 francois 222 for (int k=0;k<tet->get_nb_fem_noeud();k++)
1555 francois 106 {
1556 francois 222 double dist=calculdist(normal,xyz[0],xyz[1],xyz[2],tet->get_fem_noeud(k));
1557     if (fabs(dist)<fabs(tet->get_fem_noeud(k)->get_solution()))
1558     {
1559     tet->get_fem_noeud(k)->change_solution(dist);
1560     tet->get_fem_noeud(k)->change_numero(pt->get_id());
1561     pt->change_coord2(uv);
1562     }
1563 francois 106 }
1564 francois 104 }
1565 francois 276 if ((compare_etat(etat,STRICTINTERIEUR)) && (pt->get_interieur()))
1566     {
1567     tet->change_etat(1);
1568     for (int k=0;k<tet->get_nb_fem_noeud();k++)
1569     {
1570     tet->get_fem_noeud(k)->change_etat(1);
1571     //octree.supprimer(tet);
1572     }
1573     }
1574 francois 104 }
1575     }
1576 francois 276 //octree.vide();
1577    
1578    
1579    
1580    
1581 francois 106 }
1582    
1583 francois 276 void TOIBREP::calcullevelsetdeuxiemepasse(vector<TOIBREP_POINT*> *lst)
1584 francois 106 {
1585 francois 276 LISTE_FEM_NOEUD::iterator itno;
1586     for (FEM_NOEUD* no=mai->get_premier_noeud(itno);no!=NULL;no=mai->get_suivant_noeud(itno))
1587     if (no->get_solution()<1e250)
1588 francois 106 {
1589 francois 276 TOIBREP_POINT* pt=(*lst)[no->get_numero()];
1590 francois 281 MG_FACE* face=pt->get_mg_face();
1591     double xyz[3],uv[2];
1592     double dist=calcul_distance(no,face,pt,xyz,uv);
1593     int signe=1;
1594     if (no->get_solution()<0) signe=-1;
1595     no->change_solution(signe*dist);
1596 francois 106 }
1597 francois 104
1598 francois 276
1599    
1600    
1601 francois 106 }
1602    
1603 francois 281
1604    
1605     double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_ARETE* are,TOIBREP_POINT* pt,double &tii,double *xyz,double precision)
1606 francois 106 {
1607 francois 281 double eps;
1608 francois 106 are->inverser(tii,noeud->get_coord());
1609     int compteur=0;
1610     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
1611     do
1612     {
1613     compteur++;
1614     double ti=tii;
1615     double xyz[3],dxyz[3],ddxyz[3];
1616     are->deriver_seconde(ti,ddxyz,dxyz,xyz);
1617     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
1618     OT_VECTEUR_3D Ct_deriver(dxyz[0],dxyz[1],dxyz[2]);
1619     OT_VECTEUR_3D Ct_deriver_seconde(ddxyz[0],ddxyz[1],ddxyz[2]);
1620     OT_VECTEUR_3D Distance = Ct-Pt;
1621     tii=ti-Ct_deriver*Distance/(Ct_deriver_seconde*Distance+Ct_deriver.get_longueur2());
1622     eps=fabs(tii-ti);
1623     if (compteur>500) return 1e300;
1624     if (tii<are->get_tmin())
1625     {
1626     tii=are->get_tmin();
1627     eps=0.;
1628     }
1629     if (tii>are->get_tmax())
1630     {
1631     tii=are->get_tmax();
1632     eps=0.;
1633     }
1634     }
1635     while (eps>precision);
1636     are->evaluer(tii,xyz);
1637     OT_VECTEUR_3D Ct(xyz[0],xyz[1],xyz[2]);
1638     double distance=(Ct-Pt).get_longueur();
1639 francois 281 return distance;
1640 francois 106 }
1641    
1642 francois 281
1643     double TOIBREP::calcul_distance_level_ortho(FEM_NOEUD* no,MG_ARETE* are,TOIBREP_POINT* pt,double precision)
1644     {
1645     double t;
1646     double xyz[3];
1647     return calcul_distance_level_ortho(no,are,pt,t,xyz,precision);
1648     }
1649    
1650     double TOIBREP::calcul_distance_level_ortho(FEM_NOEUD* no,MG_ARETE* are,TOIBREP_POINT* pt,double &t,double *xyz,double precision)
1651     {
1652     calcul_distance(no,are,pt,t,xyz,precision);
1653     double dir[3];
1654     are->deriver(t,dir);
1655     double uv[2];
1656     MG_FACE* face=are->get_mg_coarete(0)->get_boucle()->get_mg_face();
1657     face->inverser(uv,xyz);
1658     double nor[3];
1659     face->calcul_normale_unitaire(uv,nor);
1660     OT_VECTEUR_3D dirv(dir);
1661     OT_VECTEUR_3D norv(nor);
1662     OT_VECTEUR_3D sensv=norv&dirv;
1663     double d=-(sensv.get_x()*xyz[0]+sensv.get_y()*xyz[1],sensv.get_z()*xyz[2]);
1664     double dist=fabs(sensv.get_x()*no->get_x()+sensv.get_y()*no->get_y()+sensv.get_z()*no->get_z()+d);
1665     OT_VECTEUR_3D distv(no->get_x()-xyz[0],no->get_y()-xyz[1],no->get_z()-xyz[2]);
1666     if (sensv*distv<0.) dist=-dist;
1667     return dist;
1668     }
1669    
1670    
1671 francois 280 double TOIBREP::calcul_distance(FEM_NOEUD* noeud,MG_FACE* face,TOIBREP_POINT* pt,double *xyz,double *uv,double precision)
1672 francois 106 {
1673     double uvii[2],eps;
1674     pt->get_coord2(uvii);
1675     int compteur=0;
1676     OT_VECTEUR_3D Pt(noeud->get_x(),noeud->get_y(),noeud->get_z());
1677     double delta_u,delta_v;
1678     do
1679     {
1680     compteur++;
1681     double uvi[2];
1682     uvi[0]=uvii[0];
1683     uvi[1]=uvii[1];
1684     double xyzduu[3],xyzdvv[3],xyzduv[3],xyzdu[3],xyzdv[3],xyz[3];
1685     face->deriver_seconde(uvi,xyzduu,xyzduv,xyzdvv,xyz,xyzdu,xyzdv);
1686     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
1687     OT_VECTEUR_3D Su(xyzdu[0],xyzdu[1],xyzdu[2]);
1688     OT_VECTEUR_3D Sv(xyzdv[0],xyzdv[1],xyzdv[2]);
1689     OT_VECTEUR_3D Suu(xyzduu[0],xyzduu[1],xyzduu[2]);
1690     OT_VECTEUR_3D Suv(xyzduv[0],xyzduv[1],xyzduv[2]);
1691     OT_VECTEUR_3D Svv(xyzdvv[0],xyzdvv[1],xyzdvv[2]);
1692     OT_VECTEUR_3D Distance = S-Pt;
1693     double a[4],b[2];
1694     a[0]=Su.get_longueur2()+Distance*Suu;
1695     a[1]=Su*Sv+Distance*Suv;
1696     a[2]=Su*Sv+Distance*Suv;
1697     a[3]=Sv.get_longueur2()+Distance*Svv;
1698     b[0]=Distance*Su;b[0]=-b[0];
1699     b[1]=Distance*Sv;b[1]=-b[1];
1700     double deltau,deltav;
1701     double denominateur_delta=(a[0]*a[3]-a[2]*a[1]);
1702     if (a[0]<1E-12)
1703     deltau=0;
1704     else delta_u=(b[0]*a[3]-b[1]*a[1])/denominateur_delta;
1705     if (a[3]<1E-12)
1706     deltav=0;
1707     else delta_v=(a[0]*b[1]-a[2]*b[0])/denominateur_delta;
1708     /*if (fabs(denominateur_delta) < ( (fabs(a[0])+fabs(a[1])+fabs(a[2])+fabs(a[3]))*1e-12 ) )
1709     return 1e300;*/
1710     uvii[0]=uvi[0]+delta_u;
1711     uvii[1]=uvi[1]+delta_v;
1712     if (face->get_surface()->est_periodique_u()==1)
1713     {
1714     if(uvii[0]<0.) uvii[0]=face->get_surface()->get_periode_u()-uvii[0];
1715     if(uvii[0]>face->get_surface()->get_periode_u()) uvii[0]=uvii[0]-face->get_surface()->get_periode_u();
1716     }
1717     if (face->get_surface()->est_periodique_v()==1)
1718     {
1719     if(uvii[1]<0.) uvii[0]=face->get_surface()->get_periode_v()-uvii[1];
1720     if(uvii[1]>face->get_surface()->get_periode_v()) uvii[1]=uvii[1]-face->get_surface()->get_periode_v();
1721     }
1722     delta_u=uvii[0]-uvi[0];
1723     delta_v=uvii[1]-uvi[1];
1724     if (compteur>500) return 1e300;
1725     }
1726    
1727     while ((fabs(delta_u)>precision)||(fabs(delta_v)>precision));
1728     face->evaluer(uvii,xyz);
1729     OT_VECTEUR_3D S(xyz[0],xyz[1],xyz[2]);
1730     double distance=(S-Pt).get_longueur();
1731 francois 280 uv[0]=uvii[0];
1732     uv[1]=uvii[1];
1733 francois 106 return distance;
1734     }
1735    
1736    
1737 francois 276
1738 francois 259 void TOIBREP::etendrelevelset(FEM_SOLUTION* sol,int numsol)
1739 francois 222 {
1740     sol->active_solution(numsol);
1741    
1742    
1743     LISTE_FM know;
1744     LISTE_FM trial;
1745     LISTE_FM far;
1746     LISTE_FM exterieur;
1747     LISTE_FM_TRI trialtri;
1748     LISTE_FM_TRI_ID trialtriid;
1749    
1750    
1751 francois 309 LISTE_FEM_ELEMENT3::iterator ittet;
1752     for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittet);tet!=NULL;tet=mai->get_suivant_element3(ittet))
1753 francois 222 {
1754     tet->change_solution(0.);
1755     int numsol=0;
1756     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);
1757     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);
1758     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);
1759     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);
1760     if (numsol==4)
1761     ajouter_liste(know,tet);
1762    
1763     else if (numsol==3)
1764     {
1765     if (tet->get_fem_noeud(0)->get_numero()==0) tet->change_numero(0);
1766     else if (tet->get_fem_noeud(1)->get_numero()==0) tet->change_numero(1);
1767     else if (tet->get_fem_noeud(2)->get_numero()==0) tet->change_numero(2);
1768     else tet->change_numero(3);
1769     ajouter_liste(trial,tet);
1770     }
1771     else
1772     ajouter_liste(far,tet);
1773    
1774     }
1775     for (LISTE_FM::iterator i=trial.begin();i!=trial.end();i++)
1776     {
1777 francois 309 FEM_ELEMENT3* tet=*i;
1778 francois 222 int signe;
1779     double sol=resoudgradT(tet,&signe);
1780     if (fabs(sol)>0.00000001)
1781     {
1782     if (fabs(sol)<fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()))
1783     {
1784     tet->get_fem_noeud(tet->get_numero())->change_solution(sol);
1785     ajouter_liste(trialtri,trialtriid,tet,fabs(tet->get_fem_noeud(tet->get_numero())->get_solution()));
1786     }
1787     }
1788     else
1789     {
1790     ajouter_liste(exterieur,tet);
1791     tet->change_solution(1e300);
1792     }
1793     }
1794     int fin=0;
1795     LISTE_FM_TRI::iterator itfin=trialtri.end();
1796     itfin--;
1797     double longref=(*itfin).first;
1798     do
1799     {
1800     LISTE_FM_TRI::iterator it=trialtri.begin();
1801 francois 309 FEM_ELEMENT3* tet=(*it).second;
1802 francois 222 double longcourant=(*it).first;
1803     supprimer_liste(trialtri,trialtriid,tet);
1804     ajouter_liste(know,tet);
1805     FEM_NOEUD* noeud=tet->get_fem_noeud(tet->get_numero());
1806     noeud->change_numero(1);
1807     if (noeud->get_solution()>20000)
1808     cout << "BUGGGGGGG" <<endl;
1809 francois 309 int nbtetra=noeud->get_lien_element3()->get_nb();
1810 francois 222 for (int i=0;i<nbtetra;i++)
1811     {
1812 francois 309 FEM_ELEMENT3* tet2=noeud->get_lien_element3()->get(i);
1813 francois 222 if (tet2==tet) continue;
1814     LISTE_FM_TRI_ID::iterator it=trialtriid.find(tet2->get_id());
1815     if (it!=trialtriid.end())
1816     {
1817     int signe;
1818     double sol=resoudgradT(tet2,&signe);
1819     double solution=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1820     if (fabs(sol)>0.00000001)
1821     if (!((solution<1e200)&&(sol*solution<0)))
1822     if (fabs(sol)<fabs(solution))
1823     {
1824     supprimer_liste(trialtri,trialtriid,tet2);
1825     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1826     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1827     }
1828     }
1829     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet2);
1830     if (it2!=far.end())
1831     {
1832     int numsol=0;
1833     if (tet2->get_fem_noeud(0)->get_numero()==1) numsol++;
1834     if (tet2->get_fem_noeud(1)->get_numero()==1) numsol++;
1835     if (tet2->get_fem_noeud(2)->get_numero()==1) numsol++;
1836     if (tet2->get_fem_noeud(3)->get_numero()==1) numsol++;
1837     //if (numsol==4)
1838     //cout << " BUG " <<endl;
1839     if (numsol==3)
1840     {
1841     if (tet2->get_fem_noeud(0)->get_numero()==0) tet2->change_numero(0);
1842     else if (tet2->get_fem_noeud(1)->get_numero()==0) tet2->change_numero(1);
1843     else if (tet2->get_fem_noeud(2)->get_numero()==0) tet2->change_numero(2);
1844     else tet2->change_numero(3);
1845     int signe;
1846     double sol=resoudgradT(tet2,&signe);
1847     double ancsol=tet2->get_fem_noeud(tet2->get_numero())->get_solution();
1848     if (fabs(sol)>0.00000001)
1849     {
1850     if (!((ancsol<1e200) && (ancsol*sol<0.) ))
1851     {
1852     tet2->get_fem_noeud(tet2->get_numero())->change_solution(sol);
1853     supprimer_liste(far,tet2);
1854     ajouter_liste(trialtri,trialtriid,tet2,fabs(sol));
1855     }
1856     }
1857     else
1858     {
1859     tet2->change_solution(1e300);
1860     ajouter_liste(exterieur,tet2);
1861     }
1862     }
1863     }
1864     }
1865     if (trialtri.size()==0) fin=1;
1866     if (exterieur.size()>0)
1867     if (fin==0)
1868     if (longcourant>longref)
1869     {
1870     int nombre=exterieur.size();
1871     for (int i=0;i<nombre;i++)
1872     {
1873 francois 309 FEM_ELEMENT3* tet2=(*(exterieur.begin()));
1874 francois 222 supprimer_liste(exterieur,tet2);
1875     ajouter_liste(know,tet2);
1876     for (int nd=0;nd<4;nd++)
1877     {
1878     FEM_NOEUD* noeud=tet2->get_fem_noeud(nd);
1879 francois 309 int nbtetra=noeud->get_lien_element3()->get_nb();
1880 francois 222 for (int i=0;i<nbtetra;i++)
1881     {
1882 francois 309 FEM_ELEMENT3* tet3=noeud->get_lien_element3()->get(i);
1883 francois 222 if (tet2==tet3) continue;
1884     LISTE_FM::iterator it2=find(far.begin(),far.end(),tet3);
1885     if (it2!=far.end())
1886     {
1887     supprimer_liste(far,tet3);
1888     ajouter_liste(exterieur,tet3);
1889     tet3->change_solution(1e300);
1890     }
1891     }
1892     }
1893     }
1894     LISTE_FM_TRI::iterator itfin=trialtri.end();
1895     itfin--;
1896     longref=(*itfin).first;
1897     }
1898     }
1899     while (fin==0);
1900     LISTE_FEM_NOEUD::iterator itnoeud;
1901     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1902     noeud->change_numero(0);
1903 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittet);tet!=NULL;tet=mai->get_suivant_element3(ittet))
1904 francois 222 {
1905     if (tet->get_solution()>1e200) continue;
1906     tet->get_fem_noeud(0)->change_numero(1);
1907     tet->get_fem_noeud(1)->change_numero(1);
1908     tet->get_fem_noeud(2)->change_numero(1);
1909     tet->get_fem_noeud(3)->change_numero(1);
1910     }
1911     int i=0;
1912     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
1913     {
1914     if (noeud->get_numero()==1) sol->ecrire(i,numsol,noeud->get_solution()); else sol->ecrire(i,numsol,1e300);
1915     ++i;
1916     }
1917     }
1918 francois 276 IBrep TOIBREP::exporter_IBrep(string chemin,FEM_SOLUTION* solution,FEM_SOLUTION *solution_ele,MG_GROUPE_TOPOLOGIQUE* mggt)
1919 francois 259 {
1920     TPL_MAP_ENTITE<MG_VOLUME*> lst;
1921     if (mggt==NULL)
1922     {
1923     int nbvol=geo->get_nb_mg_volume();
1924     for (int i=0;i<nbvol;i++)
1925     lst.ajouter(geo->get_mg_volume(i));
1926     }
1927     else
1928     {
1929     int nbmggt=mggt->get_nb();
1930     for (int i=0;i<nbmggt;i++)
1931     if (mggt->get(i)->get_dimension()==3)
1932     lst.ajouter((MG_VOLUME*)mggt->get(i));
1933     }
1934     IBrep brep(100);
1935     int nbvolexp=lst.get_nb();
1936     for (int i=0;i<nbvolexp;i++)
1937     {
1938     MG_VOLUME* vol=lst.get(i);
1939     int nbcoq=vol->get_nb_mg_coquille();
1940     IVolumeN ivoltmp(vol->get_id());
1941 francois 263 pair<IVolume*,bool> pair_ivol=brep.AddVolume(ivoltmp);
1942 francois 282 if (vol->get_idoriginal()!="") brep.SetName(pair_ivol.first,vol->get_idoriginal());
1943 francois 263 IVolume* ivol=pair_ivol.first;
1944 francois 259 for (int j=0;j<nbcoq;j++)
1945     {
1946     MG_COQUILLE* coq=vol->get_mg_coquille(j);
1947     int nbface=coq->get_nb_mg_coface();
1948     IShell ishell(nbface);
1949     for (int k=0;k<nbface;k++)
1950     {
1951     MG_COFACE* coface=coq->get_mg_coface(k);
1952     ishell[k]=coface->get_id();
1953     MG_FACE* face=coface->get_face();
1954     int sens=coface->get_orientation();
1955     ICoFaceN icoface(coface->get_id(),face->get_id(),sens);
1956     brep.AddCoFace(icoface);
1957     IFace* iface=brep.GetFace(face->get_id());
1958     if (iface==NULL)
1959     {
1960     IFaceN ifacenew(face->get_id());
1961 francois 263 pair<IFace*,bool> pair_iface=brep.AddFace(ifacenew);
1962 francois 282 if (face->get_idoriginal()!="") brep.SetName(pair_iface.first,face->get_idoriginal());
1963 francois 263 iface=pair_iface.first;
1964 francois 259 int nbbou=face->get_nb_mg_boucle();
1965     for (int l=0;l<nbbou;l++)
1966     {
1967     MG_BOUCLE* bou=face->get_mg_boucle(l);
1968     int nbare=bou->get_nb_mg_coarete();
1969     ILoop iloop(nbare);
1970     for (int m=0;m<nbare;m++)
1971     {
1972     MG_COARETE* coare=bou->get_mg_coarete(m);
1973     iloop[m]=coare->get_id();
1974     MG_ARETE* are=coare->get_arete();
1975     int sens=coare->get_orientation();
1976     ICoEdgeN icoedge(coare->get_id(),are->get_id(),sens,face->get_id());
1977     brep.AddCoEdge(icoedge);
1978     IEdge* iedge=brep.GetEdge(are->get_id());
1979     IVertex *ivertex1,*ivertex2;
1980     ICoVertex *icover1,*icover2;
1981     if (iedge==NULL)
1982     {
1983     MG_COSOMMET* cover1=are->get_cosommet1();
1984     MG_COSOMMET* cover2=are->get_cosommet2();
1985     MG_SOMMET* ver1=cover1->get_sommet();
1986     MG_SOMMET* ver2=cover2->get_sommet();
1987     ICoVertexN icovertmp1(cover1->get_id(),are->get_id(),ver1->get_id(),cover1->get_t());
1988     ICoVertexN icovertmp2(cover2->get_id(),are->get_id(),ver2->get_id(),cover2->get_t());
1989 francois 263 pair<ICoVertex*,bool> pair_icover1=brep.AddCoVertex(icovertmp1);
1990     pair<ICoVertex*,bool> pair_icover2=brep.AddCoVertex(icovertmp2);
1991     icover1=pair_icover1.first;
1992     icover2=pair_icover2.first;
1993 francois 259 IEdgeN iedgetmp(are->get_id(),cover1->get_id(),cover2->get_id());
1994     ivertex1=brep.GetVertex(ver1->get_id());
1995     ivertex2=brep.GetVertex(ver2->get_id());
1996     if (ivertex1==NULL)
1997     {
1998     MG_POINT* pt=ver1->get_point();
1999     double xyz[3];
2000     pt->evaluer(xyz);
2001     IVertexN ivertex(ver1->get_id(),xyz);
2002 francois 263 pair<IVertex*,bool> pair_ivertex1=brep.AddVertex(ivertex);
2003 francois 282 if (ver1->get_idoriginal()!="") brep.SetName(pair_ivertex1.first,ver1->get_idoriginal());
2004 francois 263 ivertex1=pair_ivertex1.first;
2005 francois 259 }
2006     if (ivertex2==NULL)
2007     {
2008     MG_POINT* pt=ver2->get_point();
2009     double xyz[3];
2010     pt->evaluer(xyz);
2011     IVertexN ivertex(ver2->get_id(),xyz);
2012 francois 263 pair<IVertex*,bool> pair_ivertex2=brep.AddVertex(ivertex);
2013 francois 282 if (ver2->get_idoriginal()!="") brep.SetName(pair_ivertex2.first,ver2->get_idoriginal());
2014 francois 263 ivertex2=pair_ivertex2.first;
2015 francois 259 }
2016     ivertex1->AddCoVertex(cover1->get_id());
2017     ivertex2->AddCoVertex(cover2->get_id());
2018 francois 263 pair<IEdge*,bool> pair_iedge=brep.AddEdge(iedgetmp);
2019 francois 282 if (are->get_idoriginal()!="") brep.SetName(pair_iedge.first,are->get_idoriginal());
2020 francois 263 iedge=pair_iedge.first;
2021 francois 259 }
2022     iedge->AddCoEdge(coare->get_id(),brep);
2023     if (sens==1)
2024     {
2025     icover1=brep.GetCoVertex(iedge->FromCoVertex());
2026     ivertex1=brep.GetVertex(icover1->Vertex());
2027     ivertex1->AddFace(face->get_id());
2028     }
2029     else
2030     {
2031     icover2=brep.GetCoVertex(iedge->ToCoVertex());
2032     ivertex2=brep.GetVertex(icover2->Vertex());
2033     ivertex2->AddFace(face->get_id());
2034     }
2035     }
2036     iface->AddLoop(iloop);
2037     }
2038     }
2039     iface->AddCoFace(coface->get_id());
2040     }
2041     ivol->AddShell(ishell);
2042     }
2043     }
2044     int nbsol=solution->get_nb_champ();
2045 francois 281 //unsigned long *correspondface=new unsigned long[nbsol];
2046 francois 262 for (int i=0;i<nbsol;i++)
2047     {
2048     std::string nom=solution->get_legende(i);
2049     char nom2[2];
2050     unsigned long id;
2051 francois 272 sscanf(nom.c_str(),"%s %lu",nom2,&id);
2052 francois 282 std::pair<IField *,bool> fld=brep.AddField(id);
2053     if (nom2[0]!='F')
2054     {
2055     IField *f=fld.first;
2056     f->info.tag=1;
2057     }
2058 francois 262 }
2059 francois 259 LISTE_FEM_NOEUD::iterator itnoeud;
2060     int i=0;
2061     for (FEM_NOEUD* noeud=mai->get_premier_noeud(itnoeud);noeud!=NULL;noeud=mai->get_suivant_noeud(itnoeud))
2062     {
2063     int nbsolnoeud=0;
2064     for (int j=0;j<nbsol;j++)
2065     {
2066     if (solution->lire(i,j)<1e200) nbsolnoeud++;
2067     }
2068     double *xyz=noeud->get_coord();
2069     INodeN inoeudtmp(noeud->get_id(),xyz[0],xyz[1],xyz[2],nbsolnoeud);
2070 francois 263 pair<INode*,bool> pair_inoeud=brep.AddNode(inoeudtmp);
2071     INode* inoeud=pair_inoeud.first;
2072 francois 259 int num=0;
2073 francois 281 IBrep::iterator_fields itf=brep.begin_fields();
2074 francois 259 for (int j=0;j<nbsol;j++)
2075     {
2076     if (solution->lire(i,j)<1e200)
2077     {
2078 francois 281 inoeud->Fields()[num]=(*itf).num;
2079 francois 259 inoeud->Values()[num]=solution->lire(i,j);
2080     num++;
2081 francois 281 }
2082     itf++;
2083 francois 259 }
2084     i++;
2085     }
2086 francois 309 LISTE_FEM_ELEMENT3::iterator ittet;
2087 francois 259 int num=0;
2088 francois 276 i=0;
2089 francois 309 for (FEM_ELEMENT3* tet=mai->get_premier_element3(ittet);tet!=NULL;tet=mai->get_suivant_element3(ittet))
2090 francois 259 {
2091 francois 276 int nbsolele=0;
2092     for (int j=0;j<nbsol;j++)
2093     {
2094     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001) nbsolele++;
2095     }
2096     IElementN xfemele(IElement::TETRAHEDRON,nbsolele);
2097 francois 259 num++;
2098     xfemele.num=num;
2099     xfemele.GetNode(0)=tet->get_fem_noeud(0)->get_id();
2100     xfemele.GetNode(1)=tet->get_fem_noeud(1)->get_id();
2101     xfemele.GetNode(2)=tet->get_fem_noeud(2)->get_id();
2102     xfemele.GetNode(3)=tet->get_fem_noeud(3)->get_id();
2103 francois 276 int num=0;
2104 francois 281 IBrep::iterator_fields itf=brep.begin_fields();
2105 francois 276 for (int j=0;j<nbsol;j++)
2106     {
2107     if (fabs(solution_ele->lire(i,j)-1.)<0.0000000001)
2108     {
2109 francois 281 xfemele.Fields()[num]=(*itf).num;
2110 francois 276 num++;
2111     }
2112 francois 281 itf++;
2113 francois 276 }
2114 francois 259 brep.AddElement(xfemele);
2115 francois 276 i++;
2116 francois 259 }
2117 francois 222
2118 francois 259
2119    
2120    
2121     std::ofstream output(chemin.c_str());
2122     output << brep << std::endl;
2123     output.close();
2124    
2125 francois 262
2126    
2127    
2128 francois 276 return brep;
2129 francois 259 }
2130    
2131    
2132    
2133 francois 309 void TOIBREP::ajouter_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_ELEMENT3* tet,double val)
2134 francois 222 {
2135 francois 309 pair<double,FEM_ELEMENT3*> p(val,tet);
2136 francois 222 LISTE_FM_TRI::iterator it=lst.insert(p);
2137     lstid[tet->get_id()]=it;
2138     }
2139    
2140 francois 309 void TOIBREP::supprimer_liste(LISTE_FM_TRI &lst,LISTE_FM_TRI_ID &lstid,FEM_ELEMENT3* tet)
2141 francois 222 {
2142     LISTE_FM_TRI::iterator it2=lstid[tet->get_id()];
2143     LISTE_FM_TRI_ID::iterator it3=lstid.find(tet->get_id());
2144     lstid.erase(it3);
2145     lst.erase(it2);
2146     }
2147    
2148 francois 309 void TOIBREP::ajouter_liste(LISTE_FM& lst,FEM_ELEMENT3* tet)
2149 francois 222 {
2150     lst.push_back(tet);
2151     }
2152    
2153 francois 309 void TOIBREP::supprimer_liste(LISTE_FM& lst,FEM_ELEMENT3* tet)
2154 francois 222 {
2155     LISTE_FM::iterator it=find(lst.begin(),lst.end(),tet);
2156     if (it!=lst.end()) lst.erase(it);
2157     }
2158    
2159    
2160    
2161 francois 309 double TOIBREP::resoudgradT(FEM_ELEMENT3* tet,int *signe)
2162 francois 222 {
2163     double j[9];
2164     double N[12];
2165     double jN[12]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
2166     double T[4];
2167     double uv[2]={0.25,0.25};
2168    
2169    
2170     tet->get_inverse_jacob(j,uv);
2171     for (int i=0;i<3;i++)
2172     for (int k=0;k<4;k++)
2173     N[i*4+k]=tet->get_fonction_derive_interpolation(k+1,i+1,uv);
2174     int premier=0;
2175     double tmin=1e300;
2176     double tmax=-1e300;
2177     for (int i=0;i<4;i++)
2178     {
2179     if (i==tet->get_numero()) continue;
2180     T[i]=tet->get_fem_noeud(i)->get_solution();
2181     if (fabs(T[i])>0.000001)
2182     {
2183     if (premier==0)
2184     if (T[i]>0) (*signe)=1; else (*signe)=-1;
2185     else if (T[i]*(*signe)<0) (*signe)=0;
2186     }
2187     T[i]=fabs(T[i]);
2188     if (tet->get_numero()!=i)
2189     {
2190     if (T[i]<tmin) tmin=T[i];
2191     if (T[i]>tmax) tmax=T[i];
2192     }
2193     premier=1;
2194     }
2195     for (int i=0;i<3;i++)
2196     for (int k=0;k<4;k++)
2197     for (int l=0;l<3;l++)
2198     jN[i*4+k]=jN[i*4+k]+j[i*3+l]*N[l*4+k];
2199     double a=0.,b=0.,c=-1.;
2200     for (int i=0;i<3;i++)
2201     {
2202     double coef=0.;
2203     double coefinc=0.;
2204     for (int l=0;l<4;l++)
2205     {
2206     if (tet->get_numero()!=l) coef=coef+jN[i*4+l]*T[l];
2207     else coefinc=coefinc+jN[i*4+l];
2208     }
2209     c=c+coef*coef;
2210     a=a+coefinc*coefinc;
2211     b=b+2*coef*coefinc;
2212     }
2213     /*if (*signe==0)
2214     cout << "attention " <<endl;*/
2215     double det=b*b-4.*a*c;
2216     if (det<0.) det=0.; else det=sqrt(det);
2217     double sol1=(-b-det)/2./a;
2218     double sol2=(-b+det)/2./a;
2219     double sol=sol1;
2220     if (sol2>sol1) sol=sol2;
2221     if (sol<tmin*0.99)
2222     sol=0.;
2223     sol=sol*(*signe);
2224     return sol;
2225     }