Télécharger rlencf.eso

Retour à la liste

Numérotation des lignes :

rlencf
  1. C RLENCF SOURCE CB215821 20/11/25 13:39:23 10792
  2. SUBROUTINE RLENCF(MELFL,MELFP,MLEPOI,MLECOE)
  3. C************************************************************************
  4. C
  5. C PROJET : CASTEM 2000
  6. C
  7. C NOM : RLENCF
  8. C
  9. C DESCRIPTION : Appelle par GRADI2
  10. C
  11. C LANGAGE : FORTRAN 77 + ESOPE 2000 (avec extensions CISI)
  12. C
  13. C AUTEUR : A. BECCANTINI
  14. C
  15. C************************************************************************
  16. C
  17. C Inputs:
  18. C
  19. C MLESCF : list of SOMMET points and their CENTRE neighbors
  20. C
  21. C MATCOE : coeff. for linear exact reconstruction of MLESCF
  22. C
  23. C MLEFSC : list of FACES points and their neighbors (CENTRE and SOMMET
  24. C points)
  25. C
  26. C MACOE1 : coeff. for linear exact reconstruction of MLEFSC
  27. C
  28. C Output
  29. C
  30. C MLEFC : list of FACES points and their neighbors (CENTRE points only)
  31. C
  32. C MACOE2 : coeff. for linear exact reconstruction of MLEFC
  33. C
  34. C This subroutine computes the coefficients to compute the gradient
  35. C at intefaces with respect to the values on its neighbors.
  36. C The neighbors are 'CENTRE' points (in FACEL) ore 'SOMMET' points
  37. C (in FACEP). which allow to perform
  38. C A linear exact reconstruction is performed via a least square
  39. C method.
  40. C
  41. C**** Inputs:
  42. C
  43. C MELFL = the 'FACEL' meleme
  44. C MELFP = the 'FACEP' meleme
  45. C
  46. C**** Output:
  47. C
  48. C MLEPOI = list of integers.
  49. C MLEPOI.LECT(i) points to the list neighbors of
  50. C MELFL.NUM(2,i)
  51. C MLECOE = list of integers.
  52. C MLECOE.LECT(i) points to the matrix of coeffients to
  53. C compute the gradient
  54. C
  55. C**** Variables de COOPTIO
  56. C
  57. C INTEGER IPLLB, IERPER, IERMAX, IERR, INTERR
  58. C & ,IOTER, IOLEC, IOIMP, IOCAR, IOACQ
  59. C & ,IOPER, IOSGB, IOGRA, IOSAU, IORES
  60. C & ,IECHO, IIMPI, IOSPI
  61. C & ,IDIM
  62. CC & ,MCOORD
  63. C & ,IFOMOD, NIFOUR, IFOUR, NSDPGE, IONIVE
  64. C & ,NGMAXY, IZROSF, ISOTYP, IOSCR,LTEXLU
  65. C & ,NORINC,NORVAL,NORIND,NORVAD
  66. C & ,NUCROU, IPSAUV, IFICLE, IPREFI
  67. C
  68. IMPLICIT INTEGER(I-N)
  69. INTEGER NBSOUS,ISOUS,NBELEM,NBNO,NVMAX,NVMIN,NFAC,IFAC,IELEM
  70. & ,NGF,NGF1,NGC1,NGC2,INOEU,NGS,IPCOOR,NVOI,IVOI,NGV
  71. & ,IERSVD,IERR0
  72. & ,I1,I2,I3,I4
  73.  
  74. REAL*8 XF,YF,ZF, XV, YV, ZV,SMAX,SMIN,ERRTOL
  75. PARAMETER(ERRTOL=1.0D-16)
  76. LOGICAL LOGSVD
  77.  
  78. -INC PPARAM
  79. -INC CCOPTIO
  80. -INC SMCOORD
  81. -INC SMELEME
  82. -INC SMLREEL
  83. -INC SMLENTI
  84. -INC SMCHPOI
  85. INTEGER JG
  86. INTEGER N1,N2
  87. SEGMENT MATRIX
  88. REAL*8 MAT(N1,N2)
  89. ENDSEGMENT
  90. POINTEUR MELFL.MELEME, MELFP.MELEME, MLEPOI.MLENTI,MLECOE.MLENTI
  91. & , MATA.MATRIX,MATU.MATRIX,MATV.MATRIX
  92. & ,MATCOE.MATRIX,MLRSIG.MLREEL,MLRTRA.MLREEL
  93. & ,MTAA.MATRIX, MINTAA.MATRIX,MLRIN1.MLREEL,MLRIN2.MLREEL
  94. & ,MLRIN3.MLREEL,MLEFP.MLENTI,MELFP1.MELEME
  95. C
  96. SEGACT MELFP
  97. C
  98. C
  99. C**** En 2D MELFP est un maillage elementaire
  100. C En 3D pas à priori
  101. C -> MLEFP contains the list of LISOUS
  102. C
  103. NBSOUS=MELFP.LISOUS(/1)
  104. C NBSOUS=0 fais un peux chier!
  105. JG=MAX(NBSOUS,1)
  106. SEGINI MLEFP
  107. IF(NBSOUS .EQ. 0)THEN
  108. MLEFP.LECT(1)=MELFP
  109. ELSE
  110. DO ISOUS=1,NBSOUS,1
  111. MLEFP.LECT(ISOUS)=MELFP.LISOUS(ISOUS)
  112. ENDDO
  113. ENDIF
  114. SEGDES MELFP
  115. SEGACT MELFL
  116. NFAC=MELFL.NUM(/2)
  117. JG=NFAC
  118. SEGINI MLEPOI
  119. SEGINI MLECOE
  120. C
  121. C**** Loop on the faces to compute NVMAX
  122. C (maximum number of neighbors)
  123. C
  124. NBSOUS=MLEFP.LECT(/1)
  125. NVMAX=0
  126. DO ISOUS = 1, NBSOUS, 1
  127. MELFP1=MLEFP.LECT(ISOUS)
  128. SEGACT MELFP1
  129. NBELEM=MELFP1.NUM(/2)
  130. NBNO=MELFP1.NUM(/1) - 1
  131. C
  132. C The ISOUS elementary meleme of 'FACEP' has NBELEM elements
  133. C which contain NBNO sommets and one point face. Each face has
  134. C NBNO 'SOMMET' neighbors and 2 'CENTRE' neighbors.
  135. C
  136. NVMAX=MAX(NVMAX,NBNO+2)
  137. ENDDO
  138. C
  139. C MATA = matrix to "pseudoinvert" (NVMAX,IDIM+1)
  140. C MATU = matrix of the singular right eigenvectors of MATA
  141. C (NVMAX,IDIM+1)
  142. C MATV = matrix of the singular left eigenvectors of MATA
  143. C (IDIM+1,IDIM+1)
  144. C But in invsvd.eso, MATV dimensions are NVMAX,IDIM+1
  145. C MLRSIG = singular values of MATA (IDIM+1)
  146. C
  147. C N.B. MATA = MATU MATSIG t(MATV)
  148. C If MATA is non singular,
  149. C inv(MATA) = MATV inv(MATSIG) t(MATU)
  150. C
  151. C MLRTRA temporary vector of invsvd.eso
  152. C NVMIN = IDIM + 1 (the most little dimension of the matrices)
  153. C
  154. N1=NVMAX
  155. N2=IDIM+1
  156. SEGINI MATA
  157. SEGINI MATU
  158. SEGINI MATV
  159. JG=IDIM+1
  160. SEGINI MLRSIG
  161. SEGINI MLRTRA
  162. NVMIN=N2
  163. C
  164. C MTAA : [t(MATA).MATA]
  165. C MINTAA : [inve(t(MATA) MATA)]
  166. C MLRIN1,2,3 : "temporary vectors"
  167. C
  168. N1=NVMIN
  169. N2=NVMIN
  170. SEGINI MTAA
  171. SEGINI MINTAA
  172. JG=NVMIN
  173. SEGINI MLRIN1
  174. SEGINI MLRIN2
  175. SEGINI MLRIN3
  176. C
  177. C**** Loop on faces to compute the coefficient
  178. C
  179. NBSOUS=MLEFP.LECT(/1)
  180. IFAC=0
  181. DO ISOUS = 1, NBSOUS, 1
  182. MELFP1=MLEFP.LECT(ISOUS)
  183. NBELEM=MELFP1.NUM(/2)
  184. NBNO=MELFP1.NUM(/1) - 1
  185. DO IELEM=1,NBELEM,1
  186. IFAC=IFAC+1
  187. NGF=MELFP1.NUM(NBNO+1,IELEM)
  188. NGF1=MELFL.NUM(2,IFAC)
  189. NGC1=MELFL.NUM(1,IFAC)
  190. NGC2=MELFL.NUM(3,IFAC)
  191. IF(NGF .NE. NGF1)THEN
  192. WRITE(IOIMP,*) 'Subroutine rlencf.eso'
  193. CALL ERREUR(5)
  194. GOTO 9999
  195. ENDIF
  196. IF(NGC1 .EQ. NGC2)THEN
  197. JG=NBNO+1
  198. ELSE
  199. JG=NBNO+2
  200. ENDIF
  201. C
  202. C********** We create the list of neighbors.
  203. C
  204. SEGINI MLENTI
  205. MLEPOI.LECT(IFAC)=MLENTI
  206. C
  207. C********** We create the matrix of coefficients.
  208. C
  209. N2=JG
  210. N1=NVMIN
  211. SEGINI MATCOE
  212. MLECOE.LECT(IFAC)=MATCOE
  213. C
  214. C********** We fill the list of neighbors.
  215. C
  216. DO INOEU=1,NBNO,1
  217. NGS=MELFP1.NUM(INOEU,IELEM)
  218. MLENTI.LECT(INOEU)=NGS
  219. ENDDO
  220. MLENTI.LECT(NBNO+1)=NGC1
  221. IF(NGC1 .NE. NGC2) MLENTI.LECT(NBNO+2)=NGC2
  222. ENDDO
  223. SEGDES MELFP1
  224. ENDDO
  225. C
  226. C**** Test for MLEPOI
  227. C
  228. C do ifac=1,nfac,1
  229. C mlenti=mlepoi.lect(ifac)
  230. C nbno=mlenti.lect(/1)
  231. C write(*,*) 'ngf=',melfl.num(2,ifac)
  232. C write(*,*) 'nvoi=',nbno
  233. C write(*,*) (mlenti.lect(inoeu),inoeu=1,nbno,1)
  234. C enddo
  235. C
  236. C**** We have to fill the matrix coefficient
  237. C
  238. NFAC=MELFL.NUM(/2)
  239. DO IFAC=1,NFAC,1
  240. NGF=MELFL.NUM(2,IFAC)
  241. IPCOOR=((NGF-1)*(IDIM+1))+1
  242. XF=MCOORD.XCOOR(IPCOOR)
  243. YF=MCOORD.XCOOR(IPCOOR+1)
  244. IF(IDIM .EQ. 3) ZF=MCOORD.XCOOR(IPCOOR+2)
  245. C
  246. C******* The neighbors of NGF
  247. C
  248. MLENTI=MLEPOI.LECT(IFAC)
  249. NVOI=MLENTI.LECT(/1)
  250. C
  251. C******* The matrix where we store the coefficients
  252. C
  253. MATCOE=MLECOE.LECT(IFAC)
  254. C
  255. C******* Loop involving the neighbors
  256. C We create the matrix to "pseudoinvert"
  257. C
  258. DO IVOI=1,NVOI,1
  259. NGV=MLENTI.LECT(IVOI)
  260. IPCOOR=((NGV-1)*(IDIM+1))+1
  261. XV=MCOORD.XCOOR(IPCOOR)
  262. YV=MCOORD.XCOOR(IPCOOR+1)
  263. MATA.MAT(IVOI,1)=1
  264. MATA.MAT(IVOI,2)=XV-XF
  265. MATA.MAT(IVOI,3)=YV-YF
  266. IF(IDIM.EQ.3)THEN
  267. ZV=MCOORD.XCOOR(IPCOOR+2)
  268. MATA.MAT(IVOI,4)=ZV-ZF
  269. ENDIF
  270. ENDDO
  271. C
  272. C********** Now we have to invert this matrix
  273. C
  274. LOGSVD=.TRUE.
  275. CALL INVSVD( NVMAX, NVOI, NVMIN, MATA.MAT,
  276. & MLRSIG.PROG,.TRUE.,MATU.MAT,.TRUE.,MATV.MAT,IERSVD,
  277. & MLRTRA.PROG)
  278. IF(IERSVD.NE.0)THEN
  279. C
  280. C************* SVD decomposition of the matrix does not work
  281. C
  282. LOGSVD=.FALSE.
  283. ELSE
  284. C
  285. C************ We check the condition number of MATA
  286. C
  287. SMAX=0.0D0
  288. DO I1=1,NVMIN,1
  289. SMAX=MAX(SMAX,MLRSIG.PROG(I1))
  290. ENDDO
  291. SMIN=SMAX
  292. DO I1=1,NVMIN,1
  293. SMIN=MIN(SMIN,MLRSIG.PROG(I1))
  294. ENDDO
  295. IF((SMIN/SMAX) .LT. ERRTOL)THEN
  296. LOGSVD=.FALSE.
  297. ENDIF
  298. ENDIF
  299. C
  300. CC TEST
  301. C write(*,*) 'LOGSVD=.FALSE.'
  302. C LOGSVD=.FALSE.
  303. C
  304. IF(LOGSVD)THEN
  305. C
  306. C********** INVSVD worked
  307. C
  308. C MATA = MATU MATSIG t(MATV)
  309. C inv(MATA) = MATV inv(MATSIG) t(MATU)
  310. C
  311. DO I4=1,NVMIN,1
  312. DO IVOI=1,NVOI,1
  313. DO I2=1,IDIM+1,1
  314. C I2=1 is the only coefficient we are not interested
  315. C in. But we computed it to verify that
  316. C sum_ivoi MATCOE.MAT(ivoi,1) = 1
  317. C
  318. MATCOE.MAT(I2,IVOI)=MATCOE.MAT(I2,IVOI)+
  319. & (MATV.MAT(I2,I4)*MATU.MAT(IVOI,I4)
  320. & /MLRSIG.PROG(I4))
  321. ENDDO
  322. ENDDO
  323. ENDDO
  324. ELSE
  325. WRITE (IOIMP,*) 'rlencf.eso'
  326. C 22 0
  327. C Opération malvenue. Résultat douteux
  328. CALL ERREUR(22)
  329. C
  330. C********** INVSVD does not worked
  331. C For each neighbor k we have to compute the solution
  332. C of
  333. C
  334. C t(MATA) MATA x = t(MATA) * b
  335. C
  336. C where b= \sum_l e_l \delta(k,l) = e_k
  337. C
  338. C To do that, we compute
  339. C
  340. C X_0 = [inve(t(MATA) MATA)] [t(MATA) * b]
  341. C
  342. C X_1 = X_0 + [inve(t(MATA) MATA)] [t(MATA) * b -
  343. C [t(MATA) MATA] X_0]
  344. C
  345. C
  346. C********** We compute [t(MATA) MATA]
  347. C We store it in the upper triangle of MTAA(NVMIN,NVMIN)
  348. C
  349. DO I1=1,NVMIN,1
  350. DO I2=I1,NVMIN,1
  351. MTAA.MAT(I1,I2)=0.0D0
  352. ENDDO
  353. ENDDO
  354. C
  355. DO I1=1,NVMIN,1
  356. DO I2=I1,NVMIN,1
  357. DO I3=1,NVOI,1
  358. MTAA.MAT(I1,I2)=MTAA.MAT(I1,I2)+
  359. & (MATA.MAT(I3,I1)*MATA.MAT(I3,I2))
  360. ENDDO
  361. ENDDO
  362. ENDDO
  363. C
  364. C********** We compute [inve(t(MATA) MATA)]
  365. C CHOLDC stores it in the upper trianle of MINTAA(NVMIN,NVMIN)
  366. C
  367. CALL CHOLDC(NVMIN,NVMIN,MTAA.MAT,MLRIN1.PROG,MINTAA.MAT,
  368. & MLRIN2.PROG,IERR0)
  369. IF(IERR0.NE.0)THEN
  370. WRITE(IOIMP,*) 'subroutine rlencf.eso.'
  371. C 26 2
  372. C Tache impossible. Probablement données erronées
  373. CALL ERREUR(26)
  374. GOTO 9999
  375. ENDIF
  376. C
  377. C********** We complete MTAA and MINTAA
  378. C
  379. DO I1=1,NVMIN,1
  380. DO I2=I1+1,NVMIN,1
  381. MINTAA.MAT(I2,I1)=MINTAA.MAT(I1,I2)
  382. MTAA.MAT(I2,I1)=MTAA.MAT(I1,I2)
  383. ENDDO
  384. ENDDO
  385. C
  386. DO IVOI=1,NVOI,1
  387. C
  388. C************* We compute [t(MATA) . b] and we store it in MLRIN1.PROG
  389. C
  390. DO I1=1,NVMIN,1
  391. MLRIN1.PROG(I1)=MATA.MAT(IVOI,I1)
  392. MLRIN2.PROG(I1)=0.0D0
  393. MLRIN3.PROG(I1)=0.0D0
  394. ENDDO
  395. C
  396. C************* X_0 = [inve(t(MATA) MATA)] [t(MATA) * b]
  397. C X_0(i1) into MLRIN2.PROG(I1)
  398. C
  399. DO I2=1,NVMIN,1
  400. DO I1=1,NVMIN,1
  401. MLRIN2.PROG(I1)=MLRIN2.PROG(I1)+
  402. & (MINTAA.MAT(I1,I2)*MLRIN1.PROG(I2))
  403. ENDDO
  404. ENDDO
  405. C
  406. C************ X_1 = X_0 + [inve(t(MATA) MATA)] [t(MATA) * b -
  407. C [t(MATA) MATA] X_0]
  408. C
  409. C [t(MATA) MATA] X_0 into MLRIN3.PROG
  410. C
  411. DO I2=1,NVMIN,1
  412. DO I1=1,NVMIN,1
  413. MLRIN3.PROG(I1)=MLRIN3.PROG(I1)+
  414. & (MTAA.MAT(I1,I2)*MLRIN2.PROG(I2))
  415. ENDDO
  416. ENDDO
  417. C
  418. C************* Now we have
  419. C [t(MATA) . b] in MLRIN1.PROG
  420. C X_0(i1) in MLRIN2.PROG(I1)
  421. C [t(MATA) MATA] X_0 in MLRIN3.PROG
  422. C
  423. C X_1(i1) in MATCOE.MAT(IVOI,i1)
  424. C
  425. DO I1=1,IDIM+1,1
  426. C The only unuseful one is I1=1
  427. DO I2=1,NVMIN,1
  428. MATCOE.MAT(I1,IVOI)=MATCOE.MAT(I1,IVOI)+
  429. & (MINTAA.MAT(I1,I2)*
  430. & (MLRIN1.PROG(I2)-MLRIN3.PROG(I2)))
  431. ENDDO
  432. MATCOE.MAT(I1,IVOI)=MATCOE.MAT(I1,IVOI)+
  433. & MLRIN2.PROG(I1)
  434. ENDDO
  435. ENDDO
  436. ENDIF
  437. CC
  438. CC TEST
  439. C write(*,*) 'ngf =', NGF
  440. C write(*,*) 'invide',LOGSVD
  441. C write(*,*) 'nvois =',(mlenti.lect(ivoi),ivoi=1,nvoi,1)
  442. C write(*,*) 'coeff(1) =',(matcoe.mat(1,ivoi),ivoi=1,nvoi,1)
  443. C write(*,*) 'coeff(2) =',(matcoe.mat(2,ivoi),ivoi=1,nvoi,1)
  444. C write(*,*) 'coeff(3) =',(matcoe.mat(3,ivoi),ivoi=1,nvoi,1)
  445. C if(idim.eq.3) write(*,*) 'coeff(4)=',
  446. C & (matcoe.mat(4,ivoi),ivoi=1,nvoi,1)
  447. C xv=0.0D0
  448. C do ivoi=1,nvoi,1
  449. C xv=xv+matcoe.mat(1,ivoi)
  450. C enddo
  451. C write(*,*) 'sum=',xv
  452. CC
  453. MLENTI=MLEPOI.LECT(IFAC)
  454. SEGDES MLENTI
  455. MATCOE=MLECOE.LECT(IFAC)
  456. SEGDES MATCOE
  457. ENDDO
  458. C
  459. SEGDES MATCOE
  460. SEGDES MLEPOI
  461. C
  462. SEGDES MELFL
  463. SEGSUP MLEFP
  464. C
  465. SEGSUP MATA
  466. SEGSUP MATU
  467. SEGSUP MATV
  468. SEGSUP MLRSIG
  469. SEGSUP MLRTRA
  470. C
  471. SEGSUP MTAA
  472. SEGSUP MINTAA
  473. SEGSUP MLRIN1
  474. SEGSUP MLRIN2
  475. SEGSUP MLRIN3
  476. C
  477. 9999 CONTINUE
  478. RETURN
  479. END
  480.  
  481.  
  482.  
  483.  
  484.  

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