Télécharger toposurf.procedur

Retour à la liste

Numérotation des lignes :

  1. * TOPOSURF PROCEDUR FD218221 25/12/04 21:15:03 12414
  2.  
  3. ************************************************************************
  4. ** Extraction procedure of a smoothed surface from a topology
  5. **
  6. ** Author:
  7. ** Guenhael Le Quilliec (LaMe - Polytech Tours)
  8. **
  9. ** Version:
  10. ** 3.2 2025/10/13 Updated to improve the output compatibility with
  11. ** SURF in 2D
  12. ** 3.1 2020/04/13 Updated to make it compatible with thermic models
  13. ** and fix an issue when OPTI ELEM is not defined
  14. ** 3.0 2018/01/29 Updated to make it independant of TOPOPTIM version,
  15. ** fix some issues with PYR5 and PRI6 elements,
  16. ** compatibility with quadratic elements,
  17. ** the model is no longer an input argument,
  18. ** all input arguments are now provided in a table
  19. ** 2.0 2018/01/26 Updated to make it compatible with TOPOPTIM V2.1
  20. ** 1.0 2016/12/13 Original version compatible with TOPOPTIM V1.0
  21. ************************************************************************
  22.  
  23. DEBP TOPOSURF tab0*'TABLE' ;
  24.  
  25. **********************************************************************
  26. * INPUT *
  27. **********************************************************************
  28.  
  29. * Topology
  30. Topo0 = tab0.'TOPOLOGIE' ;
  31.  
  32. * Model
  33. Mod0 = tab0.'MODELE' ;
  34.  
  35. * Filter rate
  36. SI (NON (EXIS tab0 'TAUX_FILTRAGE')) ;
  37. tab0.'TAUX_FILTRAGE' = 1 ;
  38. FINS ;
  39. Filter0 = tab0.'TAUX_FILTRAGE' ;
  40.  
  41. * Isovalue
  42. SI (NON (EXIS tab0 'ISOVALEUR')) ;
  43. tab0.'ISOVALEUR' = 0.5 ;
  44. FINS ;
  45. Iso0 = tab0.'ISOVALEUR' ;
  46.  
  47. * Default minimum size of the output surface elements
  48. SI (NON (EXIS tab0 'ELIMINATION')) ;
  49. tab0.'ELIMINATION' = 1.0e-6 ;
  50. FINS ;
  51. Elim0 = tab0.'ELIMINATION' ;
  52.  
  53. * Orientation of the output surface will be applied by default
  54. SI (NON (EXIS tab0 'ORIENTATION')) ;
  55. tab0.'ORIENTATION' = VRAI ;
  56. FINS ;
  57. Orie0 = tab0.'ORIENTATION' ;
  58.  
  59. * Default value of the extra thickness
  60. * This value should be very low compared to the element size
  61. * when the domain is not convex.
  62. * If not, Enve1 might be wrong and GRAD won't work
  63. SI (NON (EXIS tab0 'SUREPAISSEUR')) ;
  64. tab0.'SUREPAISSEUR' = 1.0e-3 ;
  65. FINS ;
  66. Shift0 = tab0.'SUREPAISSEUR' ;
  67.  
  68. * Default value of the thickness of the output mesh when the input
  69. * model is 2D
  70. SI (NON (EXIS tab0 'EPAISSEUR')) ;
  71. tab0.'EPAISSEUR' = 1.0 ;
  72. FINS ;
  73. Thick0 = tab0.'EPAISSEUR' ;
  74.  
  75. **********************************************************************
  76. * PREPROCESSING *
  77. **********************************************************************
  78.  
  79. * Mesh
  80. Msh0 = EXTR Mod0 'MAIL' ;
  81.  
  82. * Types of elements
  83. Type0 = Msh0 ELEM 'TYPE' ;
  84.  
  85. * If the model is mechanical
  86. SI (EXIS Mod0 'FORM' 'MECANIQUE') ;
  87. * Create a random material
  88. Mat0 = MATE Mod0 'RHO' 1.0 ;
  89. * Unitary field
  90. un1 = MANU 'CHML' Mod0 'SCAL' 1.0 'TYPE' 'SCALAIRE' 'GRAVITE' ;
  91. * Volume of each element
  92. volEl1 = INTG 'ELEM' un1 Mod0 Mat0 ;
  93. SINO ;
  94. * Random mechanical model
  95. Mod0 = MODE Msh0 'MECANIQUE' 'ELASTIQUE' 'ISOTROPE' ;
  96. * Create a random material
  97. Mat0 = MATE Mod0 'RHO' 1.0 ;
  98. * Unitary field
  99. un1 = MANU 'CHML' Mod0 'SCAL' 1.0 'TYPE' 'SCALAIRE' 'GRAVITE' ;
  100. * Volume of each element
  101. volEl1 = INTG 'ELEM' un1 Mod0 Mat0 ;
  102. * Express the input topology element field at the barycenters of the
  103. * elements of the model Mod0
  104. Topo0 = TOPOCHAN Topo0 Mod0 (volEl1 POIN 'SUPE' -1.0) ;
  105. Topo0 = CHAN 'TYPE' Topo0 'SCALAIRE' ;
  106. FINS ;
  107.  
  108. * Make sure that the topology field is not composed of zones where
  109. * the values are constant so that to avoid problems with the function
  110. * POIN 'SUPE'
  111. Topo0 = (INTG 'ELEM' Topo0 Mod0 Mat0) / volEl1 ;
  112.  
  113. * If the mesh is quadratic
  114. SI (EXIS Type0 (MOTS 'TRI6' 'QUA8' 'CU20' 'TE10' 'PR15' 'PY13') 'OU');
  115. * Change it to linear
  116. Msh0 = CHAN 'LINE' Msh0 ;
  117. * Update types of elements
  118. Type0 = Msh0 ELEM 'TYPE' ;
  119. * Create a random model
  120. Mod0 = MODE Msh0 'MECANIQUE' 'ELASTIQUE' 'ISOTROPE' ;
  121. * Update the random material
  122. Mat0 = MATE Mod0 'YOUN' 1.0 'NU' 0.3 ;
  123. * Update the unitary field
  124. un1 = MANU 'CHML' Mod0 'SCAL' 1.0 'TYPE' 'SCALAIRE' 'GRAVITE' ;
  125. * Update the volume of each element
  126. volEl1 = INTG 'ELEM' un1 Mod0 Mat0 ;
  127. * Express the input topology element field at the barycenters of the
  128. * elements of the model Mod0
  129. Topo0 = TOPOCHAN Topo0 Mod0 (volEl1 POIN 'SUPE' -1.0) ;
  130. Topo0 = CHAN 'TYPE' Topo0 'SCALAIRE' ;
  131. FINS ;
  132.  
  133. * Filtering the topology field
  134. SI (Filter0 > 0) ;
  135. REPE Loop1 Filter0 ;
  136. Topo0 = CHAN 'CHAM' (CHAN 'CHPO' Mod0 Topo0 'MOYE')
  137. Mod0 'GRAVITE' ;
  138. FIN Loop1 ;
  139. FINS ;
  140.  
  141. * Node topology field
  142. Ch0 = CHAN 'CHPO' Topo0 Mod0 'MOYE' ;
  143. Ch0 = Ch0 * (1.0 / (MAXI Ch0)) ;
  144.  
  145. * Save the options 'DIME', 'MODE', 'ELEM'
  146. Dime0 = VALE 'DIME' ;
  147. Mode0 = VALE 'MODE' ;
  148. ElemOpt0 = VALE 'ELEM' ;
  149.  
  150. * 2D Topology
  151. SI (EXIS Type0 (MOTS 'TRI3' 'QUA4') 'OU') ;
  152. * TODO Make it compatible with 3D in case of shell elements
  153. * Switch to 2D
  154. OPTI 'DIME' 2 'MODE' 'PLAN' 'CONT' ;
  155. * If the result has to stay in 2D
  156. SI ((ABS Thick0) < 1.0e-9) ;
  157. Type3D = FAUX ;
  158. * Change option 'ELEM' to TRI3
  159. OPTI 'ELEM' TRI3 ;
  160. * Change the element type of the mesh
  161. Msh0 = CHAN 'TRI3' Msh0 ;
  162. * Domain boundary
  163. Cont0 = CONT Msh0 ;
  164. * Shifted boundary
  165. Norm0 = PRES 'MASS' Mod0 (-1.0 * Shift0) Cont0 ;
  166. Norm0 = CHAN 'COMP' (MOTS 'FX' 'FY') (MOTS 'UX' 'UY')
  167. Norm0 ;
  168. Cont1 = Cont0 PLUS Norm0 ;
  169. * External layer of elements
  170. Layer0 = Cont0 REGL 1 Cont1 ;
  171. * Add a field for the shifted boundary
  172. Ch0 = Ch0 ET (MANU 'CHPO' Cont1 1 'SCAL' -1.0e7 'NATURE' 'DIFFUS') ;
  173. * New model
  174. Mod1 = MODE (Msh0 ET Layer0) 'MECANIQUE' 'ELASTIQUE' ;
  175. * Element field
  176. MCh0 = CHAN 'CHAM' Ch0 Mod1 'NOEUD' ;
  177. * Extract the iso surface
  178. Surf0 = (ISOV MCh0 Iso0) ELEM SEG2 ;
  179. * Fuse the nodes
  180. ELIM Surf0 Elim0 ;
  181. * If the surface has to be oriented
  182. SI Orie0 ;
  183. * Fuse any superimposed element
  184. Surf1 = TABL ;
  185. REPE Loop1 (NBEL Surf0) ;
  186. * Considered element
  187. Elem0 = Surf0 ELEM &Loop1 ;
  188. P0 = CHAN POI1 Elem0 ;
  189. SI (EGA (NBEL P0) 2) ;
  190. N1 = NOEU (P0 POIN 1) ;
  191. N2 = NOEU (P0 POIN 2) ;
  192. SI (N1 > N2) ;
  193. N0 = N2 ;
  194. N2 = N1 ;
  195. N1 = N0 ;
  196. FINS ;
  197. Surf1.(CHAI N1 '-' N2) = Elem0 ;
  198. FINS ;
  199. FIN Loop1 ;
  200. Ind0 = INDE Surf1 ;
  201. Surf0 = Surf1.(Ind0.(DIME Ind0)) ;
  202. REPE Loop1 ((DIME Ind0) - 1) ;
  203. Surf0 = Surf0 ET Surf1.(Ind0.&Loop1) ;
  204. FIN Loop1 ;
  205. * Create the gradient field giving the orientation
  206. Ch0 = (REDU Ch0 Msh0) ET (MANU 'CHPO' Cont1 1 'SCAL'
  207. -1.0 'NATURE' 'DIFFUS') ;
  208. Mod1 = MODE (Msh0 ET Layer0) 'THERMIQUE' ;
  209. Grad0 = -1.0 * (GRAD Mod1 (CHAN 'COMP' 'T' Ch0)) ;
  210. Grad0 = CHAN 'NOEUD' Mod1 Grad0 ;
  211. * Centers of mass
  212. REPE Loop1 (NBEL Surf0) ;
  213. Elem0 = Surf0 ELEM &Loop1 ;
  214. SI (&Loop1 NEG 1) ;
  215. Pts0 = Pts0 ET (BARY Elem0) ;
  216. SINO ;
  217. Pts0 = BARY Elem0 ;
  218. FINS ;
  219. FIN Loop1 ;
  220. * Projection of the gradient on the centers of mass
  221. Grad0 = PROI Pts0 Grad0 ;
  222. * Initialization of the loop on each elements
  223. Inv0 = (0.0 0.0) ET (0.0 0.0) ;
  224. * Loop on each element of the surface
  225. REPE Loop1 (NBEL Surf0) ;
  226. * Considered element
  227. Elem0 = Surf0 ELEM &Loop1 ;
  228. * Compute the normal direction of the element
  229. P0 = CHAN POI1 Elem0 ;
  230. P1 = P0 POIN 1 ;
  231. P2 = P0 POIN 2 ;
  232. N0 = (P2 MOIN P1) TOUR 90.0 (0.0 0.0) ;
  233. * Center of mass
  234. Bary0 = Pts0 POIN &Loop1 ;
  235. * Desired orientation
  236. G1 = EXTR Grad0 'T,X' Bary0 ;
  237. G2 = EXTR Grad0 'T,Y' Bary0 ;
  238. G0 = (G1 G2) ;
  239. * Add the element to inverse
  240. SI ((N0 PSCA G0) < 0.0) ;
  241. Inv0 = Inv0 ET Elem0 ;
  242. FINS ;
  243. FIN Loop1 ;
  244. * If there are some elements to invert
  245. SI ((NBEL Inv0) > 2) ;
  246. Inv0 = Inv0 ELEM SEG2 ;
  247. Surf0 = (DIFF Surf0 Inv0) ET (INVE Inv0) ;
  248. FINS ;
  249. FINS ;
  250. * Give information about the output mesh quality
  251. VERM Surf0 ;
  252. SINO ;
  253. Type3D = VRAI ;
  254. * Force the option 'DIME' to 3D
  255. Dime0 = 3 ;
  256. * Switch to 3D
  257. OPTI 'DIME' 3 ;
  258. * Change option 'ELEM' to CUB8
  259. OPTI 'ELEM' CUB8 ;
  260. * Create the second side of the 3D mesh from the 2D mesh
  261. Recto0 ChR0 = Msh0 Ch0 PLUS (0.0 0.0 Thick0) ;
  262. * Create the 3D mesh
  263. Msh0 = Msh0 VOLU 1 Recto0 ;
  264. * Create the 3D topology field
  265. Ch0 = Ch0 ET ChR0 ;
  266. * Create the 3D model
  267. Mod0 = MODE Msh0 'MECANIQUE' 'ELASTIQUE' 'ISOTROPE' ;
  268. FINS ;
  269. SINO ;
  270. Type3D = VRAI ;
  271. FINS ;
  272.  
  273. * 3D Topology
  274. SI Type3D ;
  275. * Change option 'ELEM' to CUB8
  276. OPTI 'ELEM' CUB8 ;
  277. * Domain boundary
  278. Enve0 = ENVE Msh0 ;
  279. * Normal direction on the domain boundary
  280. Norm0 = PRES 'MASS' Mod0 (-1.0 * Shift0) Enve0 ;
  281. Norm0 = CHAN 'COMP' (MOTS 'FX' 'FY' 'FZ')
  282. (MOTS 'UX' 'UY' 'UZ') Norm0 ;
  283. * Partitionate the surfaces
  284. NbPart0 = 32 ;
  285. SI (NbPart0 > (NBEL Enve0)) ;
  286. NbPart0 = 16 ;
  287. FINS ;
  288. SI (NbPart0 > (NBEL Enve0)) ;
  289. NbPart0 = 8 ;
  290. FINS ;
  291. PEnve0 = PART 'OPTI' NbPart0 Enve0 ;
  292. * Since PART does not always respect NbPart0, we redefine it
  293. NbPart0 = DIME PEnve0 ;
  294. REPE Loop1 NbPart0 ;
  295. SI (EXIS PEnve0 NbPart0) ;
  296. QUIT Loop1 ;
  297. FINS ;
  298. NbPart0 = NbPart0 - 1 ;
  299. FIN Loop1 ;
  300. * External layer of elements
  301. Layer0 = TABL 'ESCLAVE' ;
  302. * Loop on each entry of PEnve0
  303. REPE Loop1 NbPart0 ;
  304. PEnve1 = PEnve0.&Loop1 PLUS (REDU Norm0 PEnve0.&Loop1) ;
  305. Layer0.&Loop1 = PEnve0.&Loop1 VOLU 1 PEnve1 ;
  306. SI (&Loop1 > 1) ;
  307. Enve1 = Enve1 ET PEnve1 ;
  308. ELIM Enve1 PEnve1 Elim0 ;
  309. SINO ;
  310. Enve1 = PEnve1 ;
  311. FINS ;
  312. FIN Loop1 ;
  313. Layer0 = ETG Layer0 ;
  314. * Add a field for the shifted boundary
  315. Ch0 = Ch0 ET (MANU 'CHPO' Enve1 1 'SCAL' -1.0e7 'NATURE' 'DIFFUS') ;
  316. * Create a mesh that will be compatible with ISOV
  317. IsoMsh0 = Msh0 ET Layer0 ;
  318. Type0 = IsoMsh0 ELEM 'TYPE' ;
  319. IsoMail1 = TABL 'ESCLAVE' ;
  320. REPE Loop1 (DIME Type0) ;
  321. Type1 = EXTR Type0 &Loop1 ;
  322. SI ((EGA Type1 'TET4') OU (EGA Type1 'CUB8')) ;
  323. IsoMail1.&Loop1 = IsoMsh0 ELEM Type1 ;
  324. SINO ;
  325. * Using CHAN 'TET4' is not a good option as the edges
  326. * of the new elements won't necessary share the edges
  327. * of the neigbor elements and this may create holes
  328. * after using ISOV.
  329. * IsoMail1.&Loop1 = CHAN TET4 (IsoMsh0 ELEM Type1) ;
  330. * We change incompatible elements with ISOV by CUB8
  331. * ****
  332. Volu0 = IsoMsh0 ELEM Type1 ;
  333. Volu1 = VIDE 'MAILLAGE'/'CUB8' ;
  334. SI (EGA Type1 PRI6) ;
  335. * Loop on each element
  336. REPE Loop2 (NBEL Volu0) ;
  337. * Considered element
  338. Elem0 = Volu0 ELEM &Loop2 ;
  339. * Nodes of the element
  340. P0 = CHAN POI1 Elem0 ;
  341. P1 = P0 POIN 1 ;
  342. P2 = P0 POIN 2 ;
  343. P3 = P0 POIN 3 ;
  344. P4 = P0 POIN 4 ;
  345. P5 = P0 POIN 5 ;
  346. P6 = P0 POIN 6 ;
  347. * Manualy change this PRI6 by a CUB8
  348. Volu1 = Volu1 ET
  349. (MANU CUB8 P1 P2 P3 P3 P4 P5 P6 P6) ;
  350. FIN Loop2 ;
  351. FINS ;
  352. SI (EGA Type1 PYR5) ;
  353. * Loop on each element
  354. REPE Loop2 (NBEL Volu0) ;
  355. * Considered element
  356. Elem0 = Volu0 ELEM &Loop2 ;
  357. * Nodes of the element
  358. P0 = CHAN POI1 Elem0 ;
  359. P1 = P0 POIN 1 ;
  360. P2 = P0 POIN 2 ;
  361. P3 = P0 POIN 3 ;
  362. P4 = P0 POIN 4 ;
  363. P5 = P0 POIN 5 ;
  364. * Manualy change this PYR5 by a CUB8
  365. Volu1 = Volu1 ET
  366. (MANU CUB8 P1 P2 P3 P4 P5 P5 P5 P5) ;
  367. FIN Loop2 ;
  368. FINS ;
  369. IsoMail1.&Loop1 = Volu1 ;
  370. * ****
  371. FINS ;
  372. FIN Loop1 ;
  373. IsoMsh0 = ETG IsoMail1 ;
  374. * New model
  375. Mod1 = MODE IsoMsh0 'MECANIQUE' 'ELASTIQUE' ;
  376. * Element field
  377. MCh0 = CHAN 'CHAM' Ch0 Mod1 'NOEUD' ;
  378. * Extract the iso surface
  379. Surf0 = ISOV MCh0 Iso0 ;
  380. * Change the surface to TRI3
  381. Type0 = Surf0 ELEM 'TYPE' ;
  382. Surf1 = TABL 'ESCLAVE' ;
  383. REPE Loop1 (DIME Type0) ;
  384. Type1 = EXTR Type0 &Loop1 ;
  385. SI (EGA Type1 'TRI3') ;
  386. Surf1.&Loop1 = Surf0 ELEM Type1 ;
  387. SINO ;
  388. SI (NEG Type1 'POI1') ;
  389. Surf1.&Loop1 = CHAN 'TRI3' (Surf0 ELEM Type1) ;
  390. FINS ;
  391. FINS ;
  392. FIN Loop1 ;
  393. Surf0 = ETG Surf1 ;
  394. * Fuse the nodes
  395. ELIM Surf0 Elim0 ;
  396. * Remove any elements with fused nodes
  397. Elem1 = LECT ;
  398. REPE Loop1 (NBEL Surf0) ;
  399. SI (NEG (NBNO (Surf0 ELEM &Loop1)) 3) ;
  400. Elem1 = Elem1 ET (LECT &Loop1) ;
  401. FINS ;
  402. FIN Loop1 ;
  403. Elem0 = LECT 1 'PAS' 1 (NBEL Surf0) ;
  404. SI ((DIME Elem1) > 0) ;
  405. Surf0 = Surf0 ELEM (ENLE Elem0 Elem1) ;
  406. FINS ;
  407. * If the surface has to be oriented
  408. SI Orie0 ;
  409. * Fuse any superimposed element
  410. Surf1 = TABL ;
  411. REPE Loop1 (NBEL Surf0) ;
  412. * Considered element
  413. Elem0 = Surf0 ELEM &Loop1 ;
  414. P0 = CHAN POI1 Elem0 ;
  415. SI (EGA (NBEL P0) 3) ;
  416. N1 = NOEU (P0 POIN 1) ;
  417. N2 = NOEU (P0 POIN 2) ;
  418. N3 = NOEU (P0 POIN 3) ;
  419. N0 = ORDO (LECT N1 N2 N3) 'CROI' ;
  420. Surf1.(CHAI (EXTR N0 1) '-' (EXTR N0 2)
  421. '-' (EXTR N0 3)) = Elem0 ;
  422. FINS ;
  423. FIN Loop1 ;
  424. Ind0 = INDE Surf1 ;
  425. Surf0 = Surf1.(Ind0.(DIME Ind0)) ;
  426. REPE Loop1 ((DIME Ind0) - 1) ;
  427. Surf0 = Surf0 ET Surf1.(Ind0.&Loop1) ;
  428. FIN Loop1 ;
  429. * Create the gradient field giving the orientation
  430. Ch0 = (REDU Ch0 Msh0) ET
  431. (MANU 'CHPO' Enve1 1 'SCAL' -1.0 'NATURE' 'DIFFUS') ;
  432. Mod1 = MODE (Msh0 ET Layer0) 'THERMIQUE' ;
  433. Grad0 = -1.0 * (GRAD Mod1 (CHAN 'COMP' 'T' Ch0)) ;
  434. Grad0 = CHAN 'NOEUD' Mod1 Grad0 ;
  435. * Centers of mass
  436. REPE Loop1 (NBEL Surf0) ;
  437. Elem0 = Surf0 ELEM &Loop1 ;
  438. SI (&Loop1 NEG 1) ;
  439. Pts0 = Pts0 ET (BARY Elem0) ;
  440. SINO ;
  441. Pts0 = BARY Elem0 ;
  442. FINS ;
  443. FIN Loop1 ;
  444. * Projection of the gradient on the centers of mass
  445. Grad0 = PROI Pts0 Grad0 ;
  446. * Initialization of the loop on each elements
  447. Inv0 = (0.0 0.0 0.0) ET (0.0 0.0 0.0) ;
  448. * Loop on each element of the surface
  449. REPE Loop1 (NBEL Surf0) ;
  450. * Considered element
  451. Elem0 = Surf0 ELEM &Loop1 ;
  452. * Compute the normal direction of the element
  453. P0 = CHAN POI1 Elem0 ;
  454. P1 = P0 POIN 1 ;
  455. P2 = P0 POIN 2 ;
  456. P3 = P0 POIN 3 ;
  457. N0 = (P2 MOIN P1) PVEC (P3 MOIN P2) ;
  458. * Center of mass
  459. Bary0 = Pts0 POIN &Loop1 ;
  460. * Desired orientation
  461. G1 = EXTR Grad0 'T,X' Bary0 ;
  462. G2 = EXTR Grad0 'T,Y' Bary0 ;
  463. G3 = EXTR Grad0 'T,Z' Bary0 ;
  464. G0 = (G1 G2 G3) ;
  465. * Add the element to inverse
  466. SI ((N0 PSCA G0) < 0.0) ;
  467. Inv0 = Inv0 ET Elem0 ;
  468. FINS ;
  469. FIN Loop1 ;
  470. * If there are some elements to invert
  471. SI ((NBEL Inv0) > 2) ;
  472. Inv0 = Inv0 ELEM TRI3 ;
  473. Surf0 = (DIFF Surf0 Inv0) ET (INVE Inv0) ;
  474. FINS ;
  475. FINS ;
  476. * Give information about the output mesh quality
  477. VERM Surf0 ;
  478. FINS ;
  479.  
  480. * Restore the initial options
  481. OPTI 'DIME' Dime0 'MODE' Mode0 ;
  482. SI (NEG ElemOpt0 ' ') ;
  483. OPTI 'ELEM' ElemOpt0 ;
  484. FINS ;
  485.  
  486. FINP Surf0 ;
  487.  
  488.  
  489.  

© Cast3M 2003 - Tous droits réservés.
Mentions légales