159599516SKenneth E. Jansen subroutine i3LDU (Diag, r, code) 259599516SKenneth E. Jansenc 359599516SKenneth E. Jansenc---------------------------------------------------------------------- 459599516SKenneth E. Jansenc 559599516SKenneth E. Jansenc This routine preforms a Cholesky factorization/solve of a set of 659599516SKenneth E. Jansenc symmetric matrices for 3-D computations, used for block diagonal 759599516SKenneth E. Jansenc preconditioning in the iterative driver. 859599516SKenneth E. Jansenc 959599516SKenneth E. Jansenc input: 1059599516SKenneth E. Jansenc Diag (numnp,nsymdf) : block diagonal (symmetric storage) 1159599516SKenneth E. Jansenc r (numnp,nflow) : residual 1259599516SKenneth E. Jansenc code : operation code 1359599516SKenneth E. Jansenc .eq. 'LDU_Fact', Cholesky Factor 1459599516SKenneth E. Jansenc .eq. 'forward ', forward reduction 1559599516SKenneth E. Jansenc .eq. 'backward', backward substitution 1659599516SKenneth E. Jansenc .eq. 'product ', product Diag.r 1759599516SKenneth E. Jansenc 1859599516SKenneth E. Jansenc output: 1959599516SKenneth E. Jansenc Diag (numnp,nsymdf) : Cholesky decomp. of block diagonal 2059599516SKenneth E. Jansenc r (numnp,nflow) : reduced residual 2159599516SKenneth E. Jansenc 2259599516SKenneth E. Jansenc 2359599516SKenneth E. Jansenc Note: the formulation used here to reduce the diagonal block to 2459599516SKenneth E. Jansenc symmetric Cholesky triangle is taken from Golub's "Matrix 2559599516SKenneth E. Jansenc Computations" Book, pages 89 algorithm 5.2-1. Followed by 2659599516SKenneth E. Jansenc standard solve. 2759599516SKenneth E. Jansenc 2859599516SKenneth E. Jansenc 2959599516SKenneth E. Jansenc Diag(1) Diag(2) Diag(4) Diag(7) Diag(11) 3059599516SKenneth E. Jansenc T 0 Diag(3) Diag(5) Diag(8) Diag(12) 3159599516SKenneth E. Jansenc L = U = 0 0 Diag(6) Diag(9) Diag(13) 3259599516SKenneth E. Jansenc 0 0 0 Diag(10) Diag(14) 3359599516SKenneth E. Jansenc 0 0 0 0 Diag(15) 3459599516SKenneth E. Jansenc 3559599516SKenneth E. Jansenc The diagonal terms 1, 3, 6, 10 and 15 are stored in inverted form. 3659599516SKenneth E. Jansenc 3759599516SKenneth E. Jansenc Farzin Shakib, Spring 1987. 3859599516SKenneth E. Jansenc Zdenek Johan, Fall 1989. (Modified for option 'product') 3959599516SKenneth E. Jansenc Zdenek Johan, Winter 1991. (Fortran 90) 4059599516SKenneth E. Jansenc---------------------------------------------------------------------- 4159599516SKenneth E. Jansenc 4259599516SKenneth E. Jansen include "common.h" 4359599516SKenneth E. Jansenc 4459599516SKenneth E. Jansen dimension Diag(nshg,nsymdf), r(nshg,nflow) 4559599516SKenneth E. Jansenc 4659599516SKenneth E. Jansen character*8 code 4759599516SKenneth E. Jansenc 4859599516SKenneth E. Jansenc.... perform Cholesky decomposition with the Diagonal terms inverted 4959599516SKenneth E. Jansenc 5059599516SKenneth E. Jansen if (code .eq. 'LDU_Fact') then 5159599516SKenneth E. Jansenc 5259599516SKenneth E. Jansen Diag(:, 1) = one / sqrt (Diag(:, 1)) 5359599516SKenneth E. Jansenc 5459599516SKenneth E. Jansen Diag(:, 2) = Diag(:, 1) * Diag(:, 2) 5559599516SKenneth E. Jansen Diag(:, 3) = Diag(:, 3) - Diag(:, 2) * Diag(:, 2) 5659599516SKenneth E. Jansen Diag(:, 3) = one / sqrt (Diag(:, 3)) 5759599516SKenneth E. Jansenc 5859599516SKenneth E. Jansen Diag(:, 4) = Diag(:, 1) * Diag(:, 4) 5959599516SKenneth E. Jansen Diag(:, 5) = Diag(:, 3) * (Diag(:, 5) 6059599516SKenneth E. Jansen & - Diag(:, 4) * Diag(:, 2)) 6159599516SKenneth E. Jansen Diag(:, 6) = Diag(:, 6) - Diag(:, 4) * Diag(:, 4) 6259599516SKenneth E. Jansen & - Diag(:, 5) * Diag(:, 5) 6359599516SKenneth E. Jansen Diag(:, 6) = one / sqrt (Diag(:, 6)) 6459599516SKenneth E. Jansenc 6559599516SKenneth E. Jansen Diag(:, 7) = Diag(:, 1) * Diag(:, 7) 6659599516SKenneth E. Jansen Diag(:, 8) = Diag(:, 3) * (Diag(:, 8) 6759599516SKenneth E. Jansen & - Diag(:, 7) * Diag(:, 2)) 6859599516SKenneth E. Jansen Diag(:, 9) = Diag(:, 6) * (Diag(:, 9) 6959599516SKenneth E. Jansen & - Diag(:, 7) * Diag(:, 4) 7059599516SKenneth E. Jansen & - Diag(:, 8) * Diag(:, 5)) 7159599516SKenneth E. Jansenc 7259599516SKenneth E. Jansen Diag(:,10) = Diag(:,10) - Diag(:, 7) * Diag(:, 7) 7359599516SKenneth E. Jansen & - Diag(:, 8) * Diag(:, 8) 7459599516SKenneth E. Jansen & - Diag(:, 9) * Diag(:, 9) 7559599516SKenneth E. Jansen Diag(:,10) = one / sqrt (Diag(:,10)) 7659599516SKenneth E. Jansenc 7759599516SKenneth E. Jansen Diag(:,11) = Diag(:, 1) * Diag(:,11) 7859599516SKenneth E. Jansen Diag(:,12) = Diag(:, 3) * (Diag(:,12) 7959599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 2)) 8059599516SKenneth E. Jansen Diag(:,13) = Diag(:, 6) * (Diag(:,13) 8159599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 4) 8259599516SKenneth E. Jansen & - Diag(:,12) * Diag(:, 5)) 8359599516SKenneth E. Jansen Diag(:,14) = Diag(:,10) * (Diag(:,14) 8459599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 7) 8559599516SKenneth E. Jansen & - Diag(:,12) * Diag(:, 8) 8659599516SKenneth E. Jansen & - Diag(:,13) * Diag(:, 9)) 8759599516SKenneth E. Jansenc 8859599516SKenneth E. Jansen Diag(:,15) = Diag(:,15) - Diag(:,11) * Diag(:,11) 8959599516SKenneth E. Jansen & - Diag(:,12) * Diag(:,12) 9059599516SKenneth E. Jansen & - Diag(:,13) * Diag(:,13) 9159599516SKenneth E. Jansen & - Diag(:,14) * Diag(:,14) 9259599516SKenneth E. Jansen Diag(:,15) = one / sqrt (Diag(:,15)) 9359599516SKenneth E. Jansenc 9459599516SKenneth E. Jansenc.... flop count 9559599516SKenneth E. Jansenc 96*f4d0b58bSKenneth E. Jansen! flops = flops + 110*nshg 9759599516SKenneth E. Jansenc 9859599516SKenneth E. Jansen return 9959599516SKenneth E. Jansen endif 10059599516SKenneth E. Jansenc 10159599516SKenneth E. Jansenc.... perform forward reduction 10259599516SKenneth E. Jansenc 10359599516SKenneth E. Jansen if (code .eq. 'forward ') then 10459599516SKenneth E. Jansenc 10559599516SKenneth E. Jansen r(:,1) = Diag(:, 1) * r(:,1) 10659599516SKenneth E. Jansen r(:,2) = Diag(:, 3) * ( r(:,2) 10759599516SKenneth E. Jansen & - r(:,1) * Diag(:, 2) ) 10859599516SKenneth E. Jansen r(:,3) = Diag(:, 6) * ( r(:,3) 10959599516SKenneth E. Jansen & - r(:,1) * Diag(:, 4) 11059599516SKenneth E. Jansen & - r(:,2) * Diag(:, 5) ) 11159599516SKenneth E. Jansen r(:,4) = Diag(:,10) * ( r(:,4) 11259599516SKenneth E. Jansen & - r(:,1) * Diag(:, 7) 11359599516SKenneth E. Jansen & - r(:,2) * Diag(:, 8) 11459599516SKenneth E. Jansen & - r(:,3) * Diag(:, 9) ) 11559599516SKenneth E. Jansen r(:,5) = Diag(:,15) * ( r(:,5) 11659599516SKenneth E. Jansen & - r(:,1) * Diag(:,11) 11759599516SKenneth E. Jansen & - r(:,2) * Diag(:,12) 11859599516SKenneth E. Jansen & - r(:,3) * Diag(:,13) 11959599516SKenneth E. Jansen & - r(:,4) * Diag(:,14) ) 12059599516SKenneth E. Jansenc 12159599516SKenneth E. Jansenc.... flop count 12259599516SKenneth E. Jansenc 123*f4d0b58bSKenneth E. Jansen! flops = flops + 25*nshg 12459599516SKenneth E. Jansenc 12559599516SKenneth E. Jansen return 12659599516SKenneth E. Jansen endif 12759599516SKenneth E. Jansenc 12859599516SKenneth E. Jansenc.... perform backward substitution 12959599516SKenneth E. Jansenc 13059599516SKenneth E. Jansen if (code .eq. 'backward') then 13159599516SKenneth E. Jansenc 13259599516SKenneth E. Jansen r(:,5) = Diag(:,15) * r(:,5) 13359599516SKenneth E. Jansen r(:,4) = Diag(:,10) * ( r(:,4) 13459599516SKenneth E. Jansen & - r(:,5) * Diag(:,14) ) 13559599516SKenneth E. Jansen r(:,3) = Diag(:, 6) * ( r(:,3) 13659599516SKenneth E. Jansen & - r(:,5) * Diag(:,13) 13759599516SKenneth E. Jansen & - r(:,4) * Diag(:, 9) ) 13859599516SKenneth E. Jansen r(:,2) = Diag(:, 3) * ( r(:,2) 13959599516SKenneth E. Jansen & - r(:,5) * Diag(:,12) 14059599516SKenneth E. Jansen & - r(:,4) * Diag(:, 8) 14159599516SKenneth E. Jansen & - r(:,3) * Diag(:, 5) ) 14259599516SKenneth E. Jansen r(:,1) = Diag(:, 1) * ( r(:,1) 14359599516SKenneth E. Jansen & - r(:,5) * Diag(:,11) 14459599516SKenneth E. Jansen & - r(:,4) * Diag(:, 7) 14559599516SKenneth E. Jansen & - r(:,3) * Diag(:, 4) 14659599516SKenneth E. Jansen & - r(:,2) * Diag(:, 2) ) 14759599516SKenneth E. Jansenc 14859599516SKenneth E. Jansenc.... flop count 14959599516SKenneth E. Jansenc 150*f4d0b58bSKenneth E. Jansen! flops = flops + 25*nshg 15159599516SKenneth E. Jansenc 15259599516SKenneth E. Jansen return 15359599516SKenneth E. Jansen endif 15459599516SKenneth E. Jansenc 15559599516SKenneth E. Jansenc.... perform product U.r 15659599516SKenneth E. Jansenc 15759599516SKenneth E. Jansen if (code .eq. 'product ') then 15859599516SKenneth E. Jansenc 15959599516SKenneth E. Jansen r(:,1) = r(:,1) / Diag(:, 1) + r(:,2) * Diag(:, 2) + 16059599516SKenneth E. Jansen & r(:,3) * Diag(:, 4) + r(:,4) * Diag(:, 7) + 16159599516SKenneth E. Jansen & r(:,5) * Diag(:,11) 16259599516SKenneth E. Jansen r(:,2) = r(:,2) / Diag(:, 3) + r(:,3) * Diag(:, 5) + 16359599516SKenneth E. Jansen & r(:,4) * Diag(:, 8) + r(:,5) * Diag(:,12) 16459599516SKenneth E. Jansen r(:,3) = r(:,3) / Diag(:, 6) + r(:,4) * Diag(:, 9) + 16559599516SKenneth E. Jansen & r(:,5) * Diag(:,13) 16659599516SKenneth E. Jansen r(:,4) = r(:,4) / Diag(:,10) + r(:,5) * Diag(:,14) 16759599516SKenneth E. Jansen r(:,5) = r(:,5) / Diag(:,15) 16859599516SKenneth E. Jansenc 16959599516SKenneth E. Jansenc.... flop count 17059599516SKenneth E. Jansenc 171*f4d0b58bSKenneth E. Jansen! flops = flops + 40*nshg 17259599516SKenneth E. Jansenc 17359599516SKenneth E. Jansen return 17459599516SKenneth E. Jansen endif 17559599516SKenneth E. Jansenc 17659599516SKenneth E. Jansen call error ('i3LDU ', code, 0) 17759599516SKenneth E. Jansenc 17859599516SKenneth E. Jansenc.... return 17959599516SKenneth E. Jansenc 18059599516SKenneth E. Jansen return 18159599516SKenneth E. Jansen end 182