Télécharger quali6.eso

Retour à la liste

Numérotation des lignes :

quali6
  1. C QUALI6 SOURCE GOUNAND 25/11/24 21:15:13 12406
  2. SUBROUTINE QUALI6(MELEMX,IELDEB,IELFIN,IMET,IMOMET,XDENS,KCMETR
  3. $ ,NKPVIR,XVTOL,MLREEL,NDQC)
  4. IMPLICIT REAL*8 (A-H,O-Z)
  5. IMPLICIT INTEGER (I-N)
  6. C***********************************************************************
  7. C NOM : QUALI6
  8. C DESCRIPTION : Etant donné un maillage volumique simple MELEMX,
  9. C on construit la qualité de chacun de ses éléments
  10. C dans un listreel MLREEL.
  11. C MELEMX est supposé actif.
  12. C MLREEL est rendu actif.
  13. C
  14. C Par rapport à quali2, on utilise xvtol pour mettre
  15. C le volume d'un élément à 0 s'il est petit.
  16. C Ceci est important car on utilise le signe pour dégrader la
  17. C qualité d'un élément (-1)
  18. C
  19. C Par rapport à quali3, MELEME devient un MELEMX, MLREEL est un
  20. C segment déjà existant et on introduit les éléments de début et de
  21. C fin IELDEB et IELFIN qui servent pour MELEMX ET MLREEL (qui sont
  22. C supposés de même dimension cf. trlver.eso.)
  23. * Pour MLREEL, comme on ne calcule pas la qualité des éléments
  24. * contenant le noeud virtuel, on a NDQC qui dit le nombre de qualité
  25. * calculés (IELDEB sert donc pour MELEMX et MLREEL mais IELFIN
  26. * uniquement pour MELEMX et NDQC uniquement pour MLREEL).
  27. C
  28. * Par rapport à quali5, on essaie de simplifier et de regrouper les
  29. * cas avec, sans métrique + un peu de ménage
  30. C
  31. C
  32. C
  33. C LANGAGE : ESOPE
  34. C AUTEUR : Stéphane GOUNAND (CEA/DEN/DM2S/SFME/LTMF)
  35. C mél : gounand@semt2.smts.cea.fr
  36. C***********************************************************************
  37. C VERSION : v1, 27/11/2017, version initiale
  38. C HISTORIQUE : v1, 27/11/2017, création
  39. C HISTORIQUE :
  40. C HISTORIQUE :
  41. C***********************************************************************
  42. -INC CCGEOME
  43. -INC PPARAM
  44. -INC CCOPTIO
  45. -INC CCREEL
  46. -INC SMCOORD
  47. -INC TMATOP1
  48. *-INC SMETRIQ
  49. POINTEUR KCMETR.METRIQ
  50. *-INC SMELEMX
  51. -INC SMLREEL
  52. PARAMETER(NMET=6)
  53. DIMENSION XMET(NMET)
  54. DIMENSION XMET2(2,2)
  55. DIMENSION XMET3(3,3)
  56. REAL*8 DXI(3)
  57. DIMENSION A(3,3),D(3),R(3,3)
  58. DIMENSION IDXSYM(3,3,3)
  59. DIMENSION INVSYM(2,6,3)
  60. *
  61. * Statement functions
  62. * DISTA(A,B,C,D)=SQRT((A-C)*(A-C)+(B-D)*(B-D))
  63. * DISTB(A,B,C,D,E,F)=SQRT((A-D)*(A-D)+(B-E)*(B-E)+(C-F)*(C-F))
  64. * DISTA(A,B)=SQRT(A*A+B*B)
  65. * DISTB(A,B,C)=SQRT(A*A+B*B+C*C)
  66. * DETTRI(A11,A12,A21,A22)=A11*A22-A21*A12
  67. DETTET(A11,A12,A13,A21,A22,A23,A31,A32,A33)=
  68. & A11*(A22*A33-A23*A32)
  69. & +A12*(A23*A31-A21*A33)
  70. & +A13*(A21*A32-A22*A31)
  71. *
  72. DATA ((A(I,J),I=1,3),J=1,3) /9*0.D0/
  73. DATA (D(I),I=1,3) /3*0.D0/
  74. DATA ((R(I,J),I=1,3),J=1,3) /9*0.D0/
  75. DATA (((IDXSYM(I,J,K),I=1,1),J=1,1),K=1,1) /1/
  76. DATA (((IDXSYM(I,J,K),I=1,2),J=1,2),K=2,2) /1,2,2,3/
  77. DATA (((IDXSYM(I,J,K),I=1,3),J=1,3),K=3,3) /1,2,4,2,3,5,4,5,6/
  78. *
  79. DATA (((INVSYM(I,J,K),I=1,2),J=1,1),K=1,1) /1,1/
  80. DATA (((INVSYM(I,J,K),I=1,2),J=1,3),K=2,2) /1,1,2,1,2,2/
  81. DATA (((INVSYM(I,J,K),I=1,2),J=1,6),K=3,3)
  82. $ /1,1,2,1,2,2,3,1,3,2,3,3/
  83. *
  84. * Executable statements
  85. *
  86. * write(ioimp,*) 'quali6: NKPVIR=',NKPVIR
  87. istneg=0
  88. xstmax=-xgrand
  89. xstmin=xgrand
  90. ISIGN=0
  91. NDQC=0
  92. IDIMP1=IDIM+1
  93. * NBNN=NUMX(/1)
  94. NBNN=NNCOU
  95. * NBELEM=NUMX(/2)
  96. *? JG=PROG(/1)
  97. * Trop de verif nuit...
  98. * IF (NBNN.NE.IDIMP1.OR.JG.NE.NBELEM) THEN
  99. IF (NBNN.NE.IDIMP1) THEN
  100. CALL ERREUR(5)
  101. RETURN
  102. ENDIF
  103. IF
  104. $ (.NOT.(IELDEB.GE.1.AND.IELFIN.GE.IELDEB.AND.NLCOU.GE.IELFIN
  105. $ .AND.NUMX(/2).GE.NLCOU)) THEN
  106. WRITE(IOIMP,*) 'coucou quali6'
  107. write(ioimp,*) 'IELDEB=',IELDEB
  108. write(ioimp,*) 'IELFIN=',IELFIN
  109. write(ioimp,*) 'NLCOU=',NLCOU
  110. write(ioimp,*) 'NUM2=',NUMX(/2)
  111. write(ioimp,*) 'MELEMX=',MELEMX
  112. CALL ECMELX(MELEMX,0)
  113. CALL ERREUR(5)
  114. RETURN
  115. ENDIF
  116. * NARET=(NBNN-1)*NBNN/2
  117. c$$$ nbnn=2
  118. c$$$ NARET=(NBNN-1)*(NBNN/2)
  119. c$$$ WRITE(IOIMP,*) 'NBNN,NARET=',NBNN,NARET
  120. c$$$ nbnn=3
  121. c$$$ NARET=(NBNN-1)*(NBNN/2)
  122. c$$$ WRITE(IOIMP,*) 'NBNN,NARET=',NBNN,NARET
  123. c$$$ nbnn=4
  124. c$$$ NARET=(NBNN-1)*(NBNN/2)
  125. c$$$ WRITE(IOIMP,*) 'NBNN,NARET=',NBNN,NARET
  126. c$$$ stop 16
  127. * 2017/08/28 La ligne ci-dessus peut-elle induire des bugs ?
  128. * Après test, non mais c'est chaud quand même...
  129. NARET=((NBNN-1)*NBNN)/2
  130. * Coefficient de normalisation
  131. I=IDIM
  132. XCOF=DFACT(I)*(SQRT((DBLE(2**I))/(DBLE(I+1))))
  133. *
  134. IF (IMET.EQ.1) XMETD=1.D0/DENSIT
  135. IF (IMET.EQ.2) XMETD=1.D0/XDENS
  136. IF (IMET.EQ.3) NFMET=1
  137. IF (IMET.EQ.4) NFMET=IDIM*(IDIM+1)/2
  138.  
  139. * DO 10 IBELEM=1,NUMX(/2)
  140. DO 10 IBELEM=IELDEB,IELFIN
  141. * WRITE(IOIMP,*) 'IBELEM=',IBELEM
  142. * Calcul de la métrique moyenne et de son déterminant suivant les
  143. * cas
  144. if (imet.gt.0) then
  145. IF (IMET.GE.1.AND.IMET.LE.3) THEN
  146. IF (IMET.EQ.3) THEN
  147. YDENS=0.D0
  148. *diag YDMIN=xgrand
  149. *diag YDMAX=-xgrand
  150. DO I=1,IDIMP1
  151. INO=NUMX(I,IBELEM)
  152. IF (NKPVIR.NE.0) THEN
  153. IF (INO.LE.NKPVIR) GOTO 10
  154. ENDIF
  155. * Ici on fait la moyenne arithmétique
  156. * mais kcmetr contient le log du tenseur si imomet=1
  157. YDENS=YDENS+KCMETR.XIN(1,INO)
  158. *diag YDMIN=MIN(YDMIN,KCMETR.XIN(1,INO))
  159. *diag YDMAX=MAX(YDMAX,KCMETR.XIN(1,INO))
  160. *impr write(ioimp,*) 'QUALI6: IBELEM,INO=',IBELEM,INO
  161. *impr write(ioimp,*) 'QUALI6: log metrique=',KCMETR.XIN(1
  162. *impr $ ,INO)
  163. ENDDO
  164. YDENS=YDENS/IDIMP1
  165. if (imomet.eq.1) then
  166. YDENS=EXP(YDENS)
  167. *diag YDMIN=EXP(YDMIN)
  168. *diag YDMAX=EXP(YDMAX)
  169. endif
  170. * write(ioimp,*) 'QUALI6: IBELEM=',IBELEM
  171. * write(ioimp,*) 'QUALI6: moyenne metrique=',ydens
  172. * write(ioimp,*) 'ydens,ydmin,ydmax=',ydens,ydmin,ydmax
  173. * YDENS=YDMIN
  174. if (.false.) then
  175. * ydens2=1.D0/SQRT(YDENS)
  176. ydens2=YDENS
  177. xxxx=abs(ydens2-densit)/densit
  178. if (xxxx.gt.xzprec) then
  179. write(ioimp,*) 'ydens2,densit,xxxx=',ydens2
  180. $ ,densit,xxxx
  181. call erreur(5)
  182. return
  183. endif
  184. endif
  185. * XMETD=1.D0/YDENS
  186. XMETD=SQRT(YDENS)
  187. ENDIF
  188. XDETMD=XMETD**IDIM
  189. ELSEIF (IMET.EQ.4) THEN
  190. DO J=1,NFMET
  191. XMET(J)=0.D0
  192. ENDDO
  193. DO I=1,IDIMP1
  194. INO=NUMX(I,IBELEM)
  195. IF (NKPVIR.NE.0) THEN
  196. IF (INO.LE.NKPVIR) GOTO 10
  197. ENDIF
  198. DO J=1,NFMET
  199. XMET(J)=XMET(J)+KCMETR.XIN(J,INO)
  200. ENDDO
  201. *impr write(ioimp,*) 'QUALI6: IBELEM,INO=',IBELEM,INO
  202. *impr write(ioimp,*) 'QUALI6: log metrique='
  203. *impr $ ,(kcmetr.xin(ll,ino),ll=1,nfmet)
  204. ENDDO
  205. DO J=1,NFMET
  206. XMET(J)=XMET(J)/IDIMP1
  207. ENDDO
  208. *
  209. if (imomet.eq.1) then
  210. DO J=1,IDIM
  211. DO I=1,IDIM
  212. A(I,J)=XMET(IDXSYM(I,J,IDIM))
  213. ENDDO
  214. ENDDO
  215. * Exponentielle du tenseur symétrique
  216. IOTENS=8
  217. IKAS=3
  218. CALL TENS2(IOTENS,IKAS,A,D,R)
  219. IF (IERR.NE.0) RETURN
  220. DO IFMET=1,NFMET
  221. I=INVSYM(1,IFMET,IDIM)
  222. J=INVSYM(2,IFMET,IDIM)
  223. XMET(IFMET)=R(I,J)
  224. ENDDO
  225. endif
  226. * write(ioimp,*) 'QUALI6: IBELEM=',IBELEM
  227. * write(ioimp,*) 'QUALI6: moyenne metrique=',(xmet(ll),ll=1
  228. * $ ,nfmet)
  229.  
  230. IF (IDIM.EQ.2) THEN
  231. XMET2(1,1)=XMET(1)
  232. XMET2(2,1)=XMET(2)
  233. XMET2(1,2)=XMET(2)
  234. XMET2(2,2)=XMET(3)
  235. XDETMD=XMET2(1,1)*XMET2(2,2)-XMET2(2,1)*XMET2(1,2)
  236. c$$$ if (xdetmd.lt.0.d0) then
  237. c$$$ write(ioimp,*) 'xdetmd=',xdetmd
  238. c$$$ write(ioimp,*) 'xmet=',(xmet(i),i=1,3)
  239. c$$$ write(ioimp,*) 'a=',((a(i,j),i=1,2),j=1,2)
  240. c$$$ write(ioimp,*) 'r=',((r(i,j),i=1,2),j=1,2)
  241. c$$$ endif
  242. XDETMD=SQRT(XDETMD)
  243. ELSEIF (IDIM.EQ.3) THEN
  244. XMET3(1,1)=XMET(1)
  245. XMET3(2,1)=XMET(2)
  246. XMET3(1,2)=XMET(2)
  247. XMET3(2,2)=XMET(3)
  248. XMET3(3,1)=XMET(4)
  249. XMET3(1,3)=XMET(4)
  250. XMET3(3,2)=XMET(5)
  251. XMET3(2,3)=XMET(5)
  252. XMET3(3,3)=XMET(6)
  253. XDETMD=DETTET(XMET3(1,1),XMET3(1,2),XMET3(1,3),XMET3(2
  254. $ ,1),XMET3(2,2),XMET3(2,3),XMET3(3,1),XMET3(3,2)
  255. $ ,XMET3(3,3))
  256. XDETMD=SQRT(XDETMD)
  257. ELSE
  258. WRITE(IOIMP,*) 'quali6 idim=',IDIM
  259. INTERR(1)=IDIM
  260. CALL ERREUR(709)
  261. RETURN
  262. ENDIF
  263. ELSE
  264. WRITE(IOIMP,*) 'quali6 imet=',IMET
  265. CALL ERREUR(5)
  266. RETURN
  267. ENDIF
  268. endif
  269. * Calcul des volumes
  270. * Volume d'un triangle
  271. IF (IDIM.EQ.2) THEN
  272. I0=NUMX(1,IBELEM)
  273. I1=NUMX(2,IBELEM)
  274. I2=NUMX(3,IBELEM)
  275. IF (NKPVIR.NE.0) THEN
  276. IF (I0.LE.NKPVIR.OR.I1.LE.NKPVIR.OR.I2.LE.NKPVIR) goto 10
  277. ENDIF
  278. IP0=(I0-1)*IDIMP1
  279. IP1=(I1-1)*IDIMP1
  280. IP2=(I2-1)*IDIMP1
  281. X10=XCOOR(IP1+1)-XCOOR(IP0+1)
  282. Y10=XCOOR(IP1+2)-XCOOR(IP0+2)
  283. X20=XCOOR(IP2+1)-XCOOR(IP0+1)
  284. Y20=XCOOR(IP2+2)-XCOOR(IP0+2)
  285. * XVOL=ABS(DETTRI(X10,Y10,X20,Y20))/2.D0
  286. * XVOL=ABS(X10*Y20-X20*Y10)/2.D0
  287. XVOLO=(X10*Y20-X20*Y10)/2.D0
  288. * sigvol=sign(1.d0,xvolo)
  289. * Volume d'un tétraèdre
  290. ELSEIF (IDIM.EQ.3) THEN
  291. I0=NUMX(1,IBELEM)
  292. I1=NUMX(2,IBELEM)
  293. I2=NUMX(3,IBELEM)
  294. I3=NUMX(4,IBELEM)
  295. IF (NKPVIR.NE.0) THEN
  296. IF (I0.LE.NKPVIR.OR.I1.LE.NKPVIR.OR.I2.LE.NKPVIR.OR.
  297. $ I3.LE.NKPVIR) goto 10
  298. ENDIF
  299. IP0=(I0-1)*IDIMP1
  300. IP1=(I1-1)*IDIMP1
  301. IP2=(I2-1)*IDIMP1
  302. IP3=(I3-1)*IDIMP1
  303. X10=XCOOR(IP1+1)-XCOOR(IP0+1)
  304. Y10=XCOOR(IP1+2)-XCOOR(IP0+2)
  305. Z10=XCOOR(IP1+3)-XCOOR(IP0+3)
  306. X20=XCOOR(IP2+1)-XCOOR(IP0+1)
  307. Y20=XCOOR(IP2+2)-XCOOR(IP0+2)
  308. Z20=XCOOR(IP2+3)-XCOOR(IP0+3)
  309. X30=XCOOR(IP3+1)-XCOOR(IP0+1)
  310. Y30=XCOOR(IP3+2)-XCOOR(IP0+2)
  311. Z30=XCOOR(IP3+3)-XCOOR(IP0+3)
  312. * XVOL=ABS(DETTET(X10,X20,X30,Y10,Y20,Y30,Z10,Z20,Z30))
  313. * $ /6.D0
  314. XVOLO=(DETTET(X10,X20,X30,Y10,Y20,Y30,Z10,Z20,Z30))
  315. $ /6.D0
  316. ENDIF
  317. * Déterminant de la métrique
  318. if (imet.gt.0) then
  319. XVOLO=XVOLO*XDETMD
  320. endif
  321. sigvol=sign(1.d0,xvolo+xvtol)
  322. if (sigvol.lt.0.d0) then
  323. istneg=istneg+1
  324. xstmax=max(xstmax,xvolo)
  325. xstmin=min(xstmin,xvolo)
  326. endif
  327. xvol=abs(xvolo)
  328. * Calcul des longueurs
  329. XLAR=0.D0
  330. XLAR2=0.D0
  331. IMEXP=IDIM
  332. XLAMAX=XPETIT**(1.D0/IMEXP)
  333. XLAMIN=XGRAND**(1.D0/IMEXP)
  334. DO IBNN=1,NBNN
  335. DO JBNN=IBNN+1,NBNN
  336. I0=NUMX(IBNN,IBELEM)
  337. I1=NUMX(JBNN,IBELEM)
  338. IP0=(I0-1)*IDIMP1
  339. IP1=(I1-1)*IDIMP1
  340. DO IIDIM=1,IDIM
  341. DXI(IIDIM)=XCOOR(IP1+IIDIM)-XCOOR(IP0+IIDIM)
  342. IF (IMET.GE.1.AND.IMET.LE.3) THEN
  343. *!
  344. *! MODIF !
  345. *!
  346. *! DXI(IIDIM)=DXI(IIDIM)*(1.D0/XMETD)
  347. DXI(IIDIM)=DXI(IIDIM)*XMETD
  348. ENDIF
  349. ENDDO
  350. DXLAR2=0.D0
  351. IF (IMET.EQ.4) THEN
  352. IF (IDIM.EQ.2) THEN
  353. DO J=1,IDIM
  354. DO I=1,IDIM
  355. DXLAR2=DXLAR2+XMET2(I,J)*DXI(I)*DXI(J)
  356. ENDDO
  357. ENDDO
  358. ELSEIF (IDIM.EQ.3) THEN
  359. DO J=1,IDIM
  360. DO I=1,IDIM
  361. DXLAR2=DXLAR2+XMET3(I,J)*DXI(I)*DXI(J)
  362. ENDDO
  363. ENDDO
  364. ELSE
  365. WRITE(IOIMP,*) 'quali6 idim=',IDIM
  366.  
  367. CALL ERREUR(5)
  368. RETURN
  369. ENDIF
  370. ELSE
  371. DO I=1,IDIM
  372. DXLAR2=DXLAR2+DXI(I)*DXI(I)
  373. ENDDO
  374. ENDIF
  375. DXLAR=SQRT(DXLAR2)
  376. XLAR=XLAR+DXLAR
  377. XLAR2=XLAR2+DXLAR2
  378. * XLAR2=XLAR2+(DXLAR**2)
  379. XLAMAX=MAX(XLAMAX,DXLAR)
  380. XLAMIN=MIN(XLAMIN,DXLAR)
  381. ENDDO
  382. ENDDO
  383. XLAMOY=XLAR/NARET
  384. if (imet.eq.0) then
  385. XQUAL=XVOL/(XLAMOY**IDIM)
  386. XQUALN=XQUAL*XCOF
  387. else
  388. XLAMO2=SQRT(XLAR2*(2.D0/(DBLE(IDIM)*DBLE(IDIM+1))))
  389. **tst 2017/08/29 XLAMO3 ne marche pas bien
  390. ** XLAMO3=SQRT(XLAMAX*XLAMIN)
  391. * N'a pas l'air de changer grand chose
  392. *!!! XLAD=XLAMO2**IMEXP
  393. XLAD=XLAMOY**IDIM
  394. *
  395. XLAMAD=XLAMAX**IMEXP
  396. XLAMID=XLAMIN**IMEXP
  397. XQUAL=XVOL/XLAD
  398. XQUALN=XQUAL*XCOF
  399. * PROG(IBELEM)=XQUALN
  400. * PROG(IBELEM)=MIN(XQUALN,XLAD,1.D0/XLAD)
  401. * Je n'aime pas trop ce critère
  402. * 2017/08/28 PROG(**)=MIN(XQUALN,XLAD,1.D0/XLAD)
  403. * write(ioimp,*) 'xqualn,xqual2=',xqualn,xqual2
  404. * write(ioimp,*) 'xlad=',xlad
  405. * xqual2=min(XLAD,1.D0/XLAD)
  406. * !!!! Semble meilleur sur mato-2d3
  407. xqualn=SQRT(XQUALN*(MIN(XLAD,1.D0/XLAD)))
  408. *!!! xqualn=MIN(XQUALN,(MIN(XLAD,1.D0/XLAD)**idim))
  409. *!!! xqualn=MIN(XQUALN,XLAD,1.D0/XLAD)
  410. *
  411. * xqualn=(XQUALN+MIN(XLAD,1.)+MIN(1.D0/XLAD,1.))/3.D0
  412. * xqualn=MIN(XQUALN,1.D0/XLAD)
  413. * xqualn=MIN(XQUALN,XLAD*1.1D0,1.D0/XLAD)
  414. * xqualn=MIN(XQUALN,XQUAL2)
  415. * write(ioimp,*) 'xqualn,xlamax,xlamin,xlamad,xlamid=',xqualn
  416. * $ ,xlamax,xlamin,min(XLAMAD,1.D0/XLAMAD),min(XLAMID,1.D0
  417. * $ /XLAMID)
  418. * xqual2=min(XLAMAD,1.D0/XLAMAD,XLAMID,1.D0/XLAMID)
  419. * xqual2=min(XLAMID,1.D0/XLAMID)
  420. * write(ioimp,*) 'xqualn,xqual2=',xqualn,xqual2
  421. *!
  422. *! MODIF !
  423. *!
  424. * xqualn=MIN(XQUALN,XLAMAD,1.D0/XLAMAD,XLAMID,1.D0/XLAMID)
  425. * xqualn=MIN(XQUALN,XQUAL2)
  426. endif
  427. if (isign.eq.1) then
  428. if (sigvol.lt.0.d0) xqualn=xqualn-1.d0
  429. endif
  430. * PROG(**)=XQUALN
  431. * faux PROG(IBELEM)=XQUALN
  432. PROG(IELDEB+NDQC)=XQUALN
  433. NDQC=NDQC+1
  434. 10 CONTINUE
  435.  
  436. * write(ioimp,*) 'quali6 : istneg=',istneg
  437. * write(ioimp,*) 'xstmin',xstmin,'xstmax',xstmax
  438.  
  439. RETURN
  440. *
  441. * formats
  442. *
  443. 188 FORMAT (2X,12(A6,'=',1PG12.5,2X))
  444. *
  445. * End of subroutine QUALI6
  446. *
  447. END
  448.  
  449.  

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