Télécharger rlenco.eso

Retour à la liste

Numérotation des lignes :

rlenco
  1. C RLENCO SOURCE CB215821 20/11/25 13:39:24 10792
  2. SUBROUTINE RLENCO(MELSOM,MELCEN,MELLI1,MELLI2,INORM,MLEPOI,MLECOE)
  3. C************************************************************************
  4. C
  5. C PROJET : CASTEM 2000
  6. C
  7. C NOM : RLENCO
  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 This subroutine computes the coefficients which allow to perform
  18. C a linear exact reconstruction of each 'sommet' (vertex) value
  19. C Indeed, given the i-th sommet (V=MELSOM.NUM(1,i)), given the list
  20. C of its neighbors MLEPOI.LECT(i), we have to compute the matrix of
  21. C coefficients a(i,j) such that
  22. C
  23. C VAL(MELSOM.NUM(1,i)) = \sum_{neig1} a(i,neig1) * VAL(neig1) +
  24. C \sum_{neig2} a(i,neig2) * VALNOR(neig2)
  25. C
  26. C where neig1 is a 'CENTRE' point or a 'Dirichlet boundary condition'
  27. C point, neig2 is a 'Von Neumann boundary condition' point, VAL(j)
  28. C is the value of the function in the j-th neighbor, VALNOR(j) is
  29. C the value of grad(VAL).n is the j-th neighbor.
  30. C
  31. C
  32. C To compute these coefficients, we impose that VAL is linear with
  33. C respect to the coordinates of V and its neighbor. Then, since
  34. C there are less unknowns than equations, we use a least square
  35. C method. If the neighbor is a 'CENTRE' point or a 'Dirichlet
  36. C boundary condition' point, we impose that
  37. C
  38. C A + B (x_{neig} - x_V) + C (y_{neig} - y_V) + D (z_{neig} - z_V)
  39. C = VAL(neig)
  40. C
  41. C If the neighbor is a 'von Neumann boundary condition' point,
  42. C we impose that
  43. C
  44. C |r_{neig} - r_V| (B nx_{neig} + C ny_{neig} + D nz_{neig}) =
  45. C VALNOR(neig) * |r_{neig} - r_V|
  46. C
  47. c r = (x,y,z)
  48. c n = (nx, ny, nz) is the normal to the surface
  49. C
  50. C To determine A, B, C, D we have to solve
  51. C
  52. C MATA . tran(A, B, C, D) = tran(VAL(1), VAL(2), ... , VALNOR(j) /
  53. C (r_{j} - r_V)
  54. C
  55. C with MATA(1,*) = (1,x_1-x_V,y_1-y_V,z_1-z_V)
  56. C MATA(2,*) = (1,x_2-x_V,y_2-y_V,z_2-z_V)
  57. C ...
  58. C MATA(j,*) = (0,nx_{j}, ny_{j}, nz_{j})
  59. C ...
  60. C
  61. C To determine a(i,neig) we have to solve a linear system (for each
  62. C neig). If the neighbor is a 'CENTRE' point or a 'Dirichlet boundary
  63. C condition' point we solve
  64. C
  65. C MATA . tran(a(i,neig), b(i,neig), c(i,neig), d(i,neig)) = e_{neig}
  66. C
  67. C with e_{neig} = tran (0,0,...,0,1,0,...) (1 in the neig position)
  68. C
  69. C If the neighbor is a 'von Neumann boundary condition' points,
  70. C we solve
  71. C
  72. C MATA . tran(a(i,neig), b(i,neig), c(i,neig), d(i,neig)) =
  73. C e_{neig} (r_{neig} - r_V)
  74. C
  75. C Since each linear system involves MATA, we have to "pseudoinvert"
  76. C it.
  77. C
  78. C**** Inputs:
  79. C
  80. C MELSOM = the 'SOMMET' meleme
  81. C MELCEN = the 'CENTRE' meleme
  82. C MELLI1 = the support of Dirichlet boundary conditions
  83. C MELLI2 = the support of von Neumann boundary conditions
  84. C INOMR = CHAMPOINT des normales aux faces
  85. C MLEPOI = list of integers.
  86. C MLEPOI.LECT(i) points to the list neighbors of
  87. C MELSOM.NUM(1,i)
  88. C
  89. C**** Output:
  90. C
  91. C MLECOE = list of integers.
  92. C
  93. C MLECOE.LECT(i) points to the MLREEL MLRCOE which
  94. C contain the a(i,neig)
  95. C
  96. C**** Variables de COOPTIO
  97. C
  98. C INTEGER IPLLB, IERPER, IERMAX, IERR, INTERR
  99. C & ,IOTER, IOLEC, IOIMP, IOCAR, IOACQ
  100. C & ,IOPER, IOSGB, IOGRA, IOSAU, IORES
  101. C & ,IECHO, IIMPI, IOSPI
  102. C & ,IDIM
  103. CC & ,MCOORD
  104. C & ,IFOMOD, NIFOUR, IFOUR, NSDPGE, IONIVE
  105. C & ,NGMAXY, IZROSF, ISOTYP, IOSCR,LTEXLU
  106. C & ,NORINC,NORVAL,NORIND,NORVAD
  107. C & ,NUCROU, IPSAUV, IFICLE, IPREFI
  108. C
  109. IMPLICIT INTEGER(I-N)
  110. INTEGER INORM, NSOMM, INOEU, NGS, IPCOOR, IVOI, NVOI, NGV, NLV
  111. & ,NLV1,NVMAX,NVMIN,IERSVD,IERR0,NLN
  112. & ,I1,I2,I3,I4
  113. REAL*8 XS,YS,ZS,XV,YV,ZV,DX,ERRTOL,SMAX,SMIN
  114. PARAMETER(ERRTOL=1.0D-16)
  115. CHARACTER*8 TYPE
  116. LOGICAL LOGSVD
  117.  
  118. -INC PPARAM
  119. -INC CCOPTIO
  120. -INC SMCOORD
  121. -INC SMELEME
  122. -INC SMLREEL
  123. -INC SMLENTI
  124. -INC SMCHPOI
  125. INTEGER JG
  126. INTEGER N1,N2
  127. SEGMENT MATRIX
  128. REAL*8 MAT(N1,N2)
  129. ENDSEGMENT
  130. POINTEUR MELSOM.MELEME, MLEPOI.MLENTI,MELLI1.MELEME,MELLI2.MELEME
  131. & ,MLELI1.MLENTI,MLELI2.MLENTI,MELCEN.MELEME,MLECEN.MLENTI
  132. & ,MPNORM.MPOVAL, MATA.MATRIX,MATU.MATRIX,MATV.MATRIX
  133. & ,MLRCOE.MLREEL,MLRSIG.MLREEL,MLRTRA.MLREEL
  134. & ,MTAA.MATRIX, MINTAA.MATRIX,MLRIN1.MLREEL,MLRIN2.MLREEL
  135. & ,MLRIN3.MLREEL, MLECOE.MLENTI, MLRB.MLREEL
  136. & ,MELFAC.MELEME,MLEFAC.MLENTI
  137. C
  138. C**** We create the MLENTI for the centers
  139. C
  140. CALL KRIPAD(MELCEN,MLECEN)
  141. IF(IERR .NE. 0)GOTO 9999
  142. C En KRIPAD
  143. C SEGACT MELCEN
  144. C SEGINI MLECEN
  145. C
  146. C**** We create the MLENTI for the BC
  147. C
  148. CALL KRIPAD(MELLI1,MLELI1)
  149. IF(IERR .NE. 0)GOTO 9999
  150. CALL KRIPAD(MELLI2,MLELI2)
  151. IF(IERR .NE. 0)GOTO 9999
  152. C SEGACT MELLI1
  153. C SEGINI MLELI1
  154. C SEGACT MELLI2
  155. C SEGINI MLELI2
  156. C
  157. SEGACT MELSOM
  158. NSOMM=MELSOM.NUM(/2)
  159. JG=NSOMM
  160. SEGINI MLECOE
  161. SEGACT MLEPOI
  162. C
  163. C**** Le MPOVAL des normales
  164. C
  165. CALL LICHT(INORM,MPNORM,TYPE,MELFAC)
  166. C SEGACT MPNORM
  167. C
  168. C**** We create the MLENTI for the MELFAC
  169. C
  170. CALL KRIPAD(MELFAC,MLEFAC)
  171. IF(IERR .NE. 0)GOTO 9999
  172. C SEGACT MELFAC
  173. C SEGINI MLEFAC
  174. C
  175. C**** Loop on the sommet to compute NVMAX
  176. C (maximum number of neighbors)
  177. C
  178. NVMAX=0
  179. DO INOEU=1,NSOMM,1
  180. C
  181. C******* The neighbors of NGS
  182. C
  183. MLENTI=MLEPOI.LECT(INOEU)
  184. SEGACT MLENTI
  185. NVOI=MLENTI.LECT(/1)
  186. NVMAX=MAX(NVMAX,NVOI)
  187. ENDDO
  188. C
  189. C MATA = matrix to "pseudoinvert" (NVMAX,IDIM+1)
  190. C MATU = matrix of the singular right eigenvectors of MATA
  191. C (NVMAX,IDIM+1)
  192. C MATV = matrix of the singular left eigenvectors of MATA
  193. C (IDIM+1,IDIM+1)
  194. C But in invsvd.eso, MATV dimensions are NVMAX,IDIM+1
  195. C MLRSIG = singular values of MATA (IDIM+1)
  196. C MLRB = vector (NVMAX)
  197. C MLRB.PROG(j) = 1 if j is a center point or a 'Dirichlet
  198. C boundary condition' point
  199. C MLRB.PROG(j) = (r_j - r_V) id j is a 'von Neumann
  200. C boundary condition point.
  201. C
  202. C N.B. MATA = MATU MATSIG t(MATV)
  203. C If MATA is non singular,
  204. C inv(MATA) = MATV inv(MATSIG) t(MATU)
  205. C
  206. C MLRTRA temporary vector of invsvd.eso
  207. C NVMIN = IDIM + 1 (the most little dimension of the matrices)
  208. C
  209. N1=NVMAX
  210. N2=IDIM+1
  211. SEGINI MATA
  212. SEGINI MATU
  213. SEGINI MATV
  214. JG=NVMAX
  215. SEGINI MLRB
  216. JG=IDIM+1
  217. SEGINI MLRSIG
  218. SEGINI MLRTRA
  219. NVMIN=N2
  220. C
  221. C MTAA : [t(MATA).MATA]
  222. C MINTAA : [inve(t(MATA) MATA)]
  223. C MLRIN1,2,3 : "temporary vectors"
  224. C
  225. N1=NVMIN
  226. N2=NVMIN
  227. SEGINI MTAA
  228. SEGINI MINTAA
  229. JG=NVMIN
  230. SEGINI MLRIN1
  231. SEGINI MLRIN2
  232. SEGINI MLRIN3
  233. C
  234. C**** Loop on the sommet to compute the coefficient
  235. C
  236.  
  237. DO INOEU=1,NSOMM,1
  238. NGS=MELSOM.NUM(1,INOEU)
  239. IPCOOR=((NGS-1)*(IDIM+1))+1
  240. XS=MCOORD.XCOOR(IPCOOR)
  241. YS=MCOORD.XCOOR(IPCOOR+1)
  242. IF(IDIM .EQ. 3) ZS=MCOORD.XCOOR(IPCOOR+2)
  243. C
  244. C******* The neighbors of NGS
  245. C
  246. MLENTI=MLEPOI.LECT(INOEU)
  247. NVOI=MLENTI.LECT(/1)
  248. C
  249. C******* The matrix where we store the coefficients
  250. C
  251. JG=NVOI
  252. SEGINI MLRCOE
  253. MLECOE.LECT(INOEU)=MLRCOE
  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. NLV=MLECEN.LECT(NGV)
  261. NLV1=MLELI1.LECT(NGV)
  262. IF((NLV .NE. 0) .OR. (NLV1 .NE. 0))THEN
  263. C
  264. C********** NGV is a 'centre' point or a Dirichlet point
  265. C
  266. IPCOOR=((NGV-1)*(IDIM+1))+1
  267. XV=MCOORD.XCOOR(IPCOOR)
  268. YV=MCOORD.XCOOR(IPCOOR+1)
  269. MATA.MAT(IVOI,1)=1
  270. MATA.MAT(IVOI,2)=XV-XS
  271. MATA.MAT(IVOI,3)=YV-YS
  272. IF(IDIM.EQ.3)THEN
  273. ZV=MCOORD.XCOOR(IPCOOR+2)
  274. MATA.MAT(IVOI,4)=ZV-ZS
  275. ENDIF
  276. MLRB.PROG(IVOI)=1.0D0
  277. ELSE
  278. NLV=MLELI2.LECT(NGV)
  279. IF(NLV .EQ. 0)THEN
  280. C
  281. C**************** NO B.C. specified on this point
  282. C
  283. WRITE(IOIMP,*) 'Boundary conditions ???'
  284. CALL ERREUR(21)
  285. GOTO 9999
  286. ELSE
  287. IPCOOR=((NGV-1)*(IDIM+1))+1
  288. XV=MCOORD.XCOOR(IPCOOR)
  289. YV=MCOORD.XCOOR(IPCOOR+1)
  290. DX=((XV - XS)**2)+((YV - YS)**2)
  291. IF(IDIM .EQ. 3)THEN
  292. ZV=MCOORD.XCOOR(IPCOOR+2)
  293. DX=DX+((ZV - ZS)**2)
  294. ENDIF
  295. NLN=MLEFAC.LECT(NGV)
  296. DX=DX**0.5D0
  297. MATA.MAT(IVOI,1)=0
  298. MATA.MAT(IVOI,2)=DX*MPNORM.VPOCHA(NLN,1)
  299. MATA.MAT(IVOI,3)=DX*MPNORM.VPOCHA(NLN,2)
  300. IF(IDIM .EQ. 3)THEN
  301. MATA.MAT(IVOI,4)=DX*MPNORM.VPOCHA(NLN,3)
  302. ENDIF
  303. MLRB.PROG(IVOI)=DX
  304. ENDIF
  305. ENDIF
  306. ENDDO
  307. C
  308. C TEST
  309. C do ivoi=1,nvoi,1
  310. C write(*,*)
  311. C & 'mata.mat(',ivoi,')=',(mata.mat(ivoi,i1),i1=1,nvmin,1)
  312. C write(*,*) 'b(',ivoi,')=',mlrb.prog(ivoi)
  313. C enddo
  314. C
  315. C
  316. C********** Now we have to invert this matrix
  317. C
  318. LOGSVD=.TRUE.
  319. CALL INVSVD( NVMAX, NVOI, NVMIN, MATA.MAT,
  320. & MLRSIG.PROG,.TRUE.,MATU.MAT,.TRUE.,MATV.MAT,IERSVD,
  321. & MLRTRA.PROG)
  322. IF(IERSVD.NE.0)THEN
  323. C
  324. C************* SVD decomposition of the matrix does not work
  325. C
  326. LOGSVD=.FALSE.
  327. ELSE
  328. C
  329. C************ We check the condition number of MATA
  330. C
  331. SMAX=0.0D0
  332. DO I1=1,NVMIN,1
  333. SMAX=MAX(SMAX,MLRSIG.PROG(I1))
  334. ENDDO
  335. SMIN=SMAX
  336. DO I1=1,NVMIN,1
  337. SMIN=MIN(SMIN,MLRSIG.PROG(I1))
  338. ENDDO
  339. IF((SMIN/SMAX) .LT. ERRTOL)THEN
  340. LOGSVD=.FALSE.
  341. ENDIF
  342. ENDIF
  343. C
  344. C TEST
  345. C write(*,*) 'LOGSVD=.FALSE.'
  346. C LOGSVD=.FALSE.
  347. C
  348. IF(LOGSVD)THEN
  349. C
  350. C********** INVSVD worked
  351. C
  352. C MATA = MATU MATSIG t(MATV)
  353. C inv(MATA) = MATV inv(MATSIG) t(MATU)
  354. C
  355. DO I4=1,NVMIN,1
  356. DO IVOI=1,NVOI,1
  357. DO I2=1,1,1
  358. C I2=1 is the only coefficient we are interested in
  359. MLRCOE.PROG(IVOI)=MLRCOE.PROG(IVOI)+
  360. & (MATV.MAT(I2,I4)*MATU.MAT(IVOI,I4)
  361. & *MLRB.PROG(IVOI)/MLRSIG.PROG(I4))
  362. ENDDO
  363. ENDDO
  364. ENDDO
  365. ELSE
  366. WRITE (IOIMP,*) 'rlenco.eso'
  367. C 22 0
  368. C Opération malvenue. Résultat douteux
  369. CALL ERREUR(22)
  370. C
  371. C********** INVSVD does not worked
  372. C For each neighbor k we have to compute the solution
  373. C of
  374. C
  375. C t(MATA) MATA x = t(MATA) * b
  376. C
  377. C where b= \sum_l e_l \delta(k,l) = e_k
  378. C
  379. C To do that, we compute
  380. C
  381. C X_0 = [inve(t(MATA) MATA)] [t(MATA) * b]
  382. C
  383. C X_1 = X_0 + [inve(t(MATA) MATA)] [t(MATA) * b -
  384. C [t(MATA) MATA] X_0]
  385. C
  386. C
  387. C********** We compute [t(MATA) MATA]
  388. C We store it in the upper triangle of MTAA(NVMIN,NVMIN)
  389. C
  390. DO I1=1,NVMIN,1
  391. DO I2=I1,NVMIN,1
  392. MTAA.MAT(I1,I2)=0.0D0
  393. ENDDO
  394. ENDDO
  395.  
  396. DO I1=1,NVMIN,1
  397. DO I2=I1,NVMIN,1
  398. DO I3=1,NVOI,1
  399. MTAA.MAT(I1,I2)=MTAA.MAT(I1,I2)+
  400. & (MATA.MAT(I3,I1)*MATA.MAT(I3,I2))
  401. ENDDO
  402. ENDDO
  403. ENDDO
  404. C
  405. C********** We compute [inve(t(MATA) MATA)]
  406. C CHOLDC stores it in the upper trianle of MINTAA(NVMIN,NVMIN)
  407. C
  408. CALL CHOLDC(NVMIN,NVMIN,MTAA.MAT,MLRIN1.PROG,MINTAA.MAT,
  409. & MLRIN2.PROG,IERR0)
  410. IF(IERR0.NE.0)THEN
  411. WRITE(IOIMP,*) 'subroutine rlenco.eso.'
  412. C 26 2
  413. C Tache impossible. Probablement données erronées
  414. CALL ERREUR(26)
  415. GOTO 9999
  416. ENDIF
  417. C
  418. C********** We complete MTAA and MINTAA
  419. C
  420. DO I1=1,NVMIN,1
  421. DO I2=I1+1,NVMIN,1
  422. MINTAA.MAT(I2,I1)=MINTAA.MAT(I1,I2)
  423. MTAA.MAT(I2,I1)=MTAA.MAT(I1,I2)
  424. ENDDO
  425. ENDDO
  426. C
  427. DO IVOI=1,NVOI,1
  428. C
  429. C************* We compute [t(MATA) . b] and we store it in MLRIN1.PROG
  430. C
  431. DO I1=1,NVMIN,1
  432. MLRIN1.PROG(I1)=MATA.MAT(IVOI,I1)*MLRB.PROG(IVOI)
  433. MLRIN2.PROG(I1)=0.0D0
  434. MLRIN3.PROG(I1)=0.0D0
  435. ENDDO
  436. C
  437. C************* X_0 = [inve(t(MATA) MATA)] [t(MATA) * b]
  438. C X_0(i1) into MLRIN2.PROG(I1)
  439. C
  440. DO I2=1,NVMIN,1
  441. DO I1=1,NVMIN,1
  442. MLRIN2.PROG(I1)=MLRIN2.PROG(I1)+
  443. & (MINTAA.MAT(I1,I2)*MLRIN1.PROG(I2))
  444. ENDDO
  445. ENDDO
  446. C
  447. C************ X_1 = X_0 + [inve(t(MATA) MATA)] [t(MATA) * b -
  448. C [t(MATA) MATA] X_0]
  449. C
  450. C [t(MATA) MATA] X_0 into MLRIN3.PROG
  451. C
  452. DO I2=1,NVMIN,1
  453. DO I1=1,NVMIN,1
  454. MLRIN3.PROG(I1)=MLRIN3.PROG(I1)+
  455. & (MTAA.MAT(I1,I2)*MLRIN2.PROG(I2))
  456. ENDDO
  457. ENDDO
  458. C
  459. C************* Now we have
  460. C [t(MATA) . b] in MLRIN1.PROG
  461. C X_0(i1) in MLRIN2.PROG(I1)
  462. C [t(MATA) MATA] X_0 in MLRIN3.PROG
  463. C
  464. C X_1(i1) in MLRCOE.MAT(i1,IVOI)
  465. C
  466. DO I1=1,1,1
  467. C The only interesting one is I1=1
  468. DO I2=1,NVMIN,1
  469. MLRCOE.PROG(IVOI)=MLRCOE.PROG(IVOI)+
  470. & (MINTAA.MAT(I1,I2)*
  471. & (MLRIN1.PROG(I2)-MLRIN3.PROG(I2)))
  472. ENDDO
  473. MLRCOE.PROG(IVOI)=MLRCOE.PROG(IVOI)+
  474. & MLRIN2.PROG(I1)
  475. ENDDO
  476. ENDDO
  477. ENDIF
  478. CC
  479. CC TEST
  480. C write(*,*) 'ngs =', NGS
  481. C write(*,*) 'invide',LOGSVD
  482. C write(*,*) 'nvois =',(mlenti.lect(ivoi),ivoi=1,nvoi,1)
  483. C write(*,*) 'coeff =',(mlrcoe.prog(ivoi),ivoi=1,nvoi,1)
  484. C dx=0.0D0
  485. C do ivoi=1,nvoi,1
  486. C dx=dx+mlrcoe.prog(ivoi)
  487. C enddo
  488. C write(*,*) 'sum=',dx
  489. MLENTI=MLEPOI.LECT(INOEU)
  490. SEGDES MLENTI
  491. MLRCOE=MLECOE.LECT(INOEU)
  492. SEGDES MLRCOE
  493. ENDDO
  494. C
  495. SEGDES MELCEN
  496. SEGSUP MLECEN
  497. C
  498. IF(MELLI1 .NE. 0) SEGDES MELLI1
  499. IF(MELLI2 .NE. 0) SEGDES MELLI2
  500. SEGSUP MLELI1
  501. SEGSUP MLELI2
  502. C
  503. SEGDES MELSOM
  504. C
  505. SEGDES MLECOE
  506. SEGDES MLEPOI
  507. C
  508. SEGSUP MATA
  509. SEGSUP MATU
  510. SEGSUP MATV
  511. SEGSUP MLRSIG
  512. SEGSUP MLRTRA
  513. SEGSUP MLRB
  514. C
  515. SEGSUP MTAA
  516. SEGSUP MINTAA
  517. SEGSUP MLRIN1
  518. SEGSUP MLRIN2
  519. SEGSUP MLRIN3
  520. C
  521. SEGDES MPNORM
  522. SEGDES MELFAC
  523. SEGSUP MLEFAC
  524. C
  525. 9999 CONTINUE
  526. RETURN
  527. END
  528.  
  529.  
  530.  
  531.  
  532.  

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