159599516SKenneth E. Jansen subroutine i3LU (Diag, r, code) 259599516SKenneth E. Jansenc 359599516SKenneth E. Jansenc---------------------------------------------------------------------- 459599516SKenneth E. Jansenc 559599516SKenneth E. Jansenc This routine performs a LU factorization/solve of a set of matrices, 659599516SKenneth E. Jansenc used for block diagonal preconditioning in the iterative driver. 759599516SKenneth E. Jansen 859599516SKenneth E. Jansenc input: 959599516SKenneth E. Jansenc Diag (nshg,nflow,nflow) : block diagonal (symmetric storage) 1059599516SKenneth E. Jansenc r (nshg,nflow) : residual 1159599516SKenneth E. Jansenc code : operation code 1259599516SKenneth E. Jansenc .eq. 'LU_Fact ', Cholesky Factor 1359599516SKenneth E. Jansenc .eq. 'forward ', forward reduction 1459599516SKenneth E. Jansenc .eq. 'backward', backward substitution 1559599516SKenneth E. Jansenc .eq. 'product ', product Diag.r 1659599516SKenneth E. Jansenc 1759599516SKenneth E. Jansenc output: 1859599516SKenneth E. Jansenc Diag (nshg,nflow,nflow) : LU decomp. of block diagonal 1959599516SKenneth E. Jansenc r (nshg,nflow) : reduced residual 2059599516SKenneth E. Jansenc 2159599516SKenneth E. Jansenc 2259599516SKenneth E. Jansenc Note: the formulation used here is taken from Golub's "Matrix 2359599516SKenneth E. Jansenc Computations" Book (1984), pages 82-85 algorithm P5.1-3. 2459599516SKenneth E. Jansenc 2559599516SKenneth E. Jansenc L and U overwrite Diag 2659599516SKenneth E. Jansenc 2759599516SKenneth E. Jansenc The diagonal terms (i,i) of U are stored in inverted form. 2859599516SKenneth E. Jansenc 2959599516SKenneth E. Jansenc 3059599516SKenneth E. Jansenc---------------------------------------------------------------------- 3159599516SKenneth E. Jansenc 3259599516SKenneth E. Jansen include "common.h" 3359599516SKenneth E. Jansenc 3459599516SKenneth E. Jansen dimension Diag(nshg,nflow,nflow), r(nshg,nflow) 3559599516SKenneth E. Jansenc 3659599516SKenneth E. Jansen character*8 code 3759599516SKenneth E. Jansen 3859599516SKenneth E. Jansenc 3959599516SKenneth E. Jansenc.... perform LU decomposition with the Diagonal terms inverted 4059599516SKenneth E. Jansenc 4159599516SKenneth E. Jansen if (code .eq. 'LU_Fact ') then 4259599516SKenneth E. Jansenc 4359599516SKenneth E. Jansen Diag(:,1,1) = one / Diag(:,1,1) 4459599516SKenneth E. Jansenc 4559599516SKenneth E. Jansen Diag(:,2,1) = Diag(:,1,1) * Diag(:,2,1) 4659599516SKenneth E. Jansen Diag(:,3,1) = Diag(:,1,1) * Diag(:,3,1) 4759599516SKenneth E. Jansen Diag(:,4,1) = Diag(:,1,1) * Diag(:,4,1) 4859599516SKenneth E. Jansen Diag(:,5,1) = Diag(:,1,1) * Diag(:,5,1) 4959599516SKenneth E. Jansenc 5059599516SKenneth E. Jansen Diag(:,2,2) = Diag(:,2,2) - Diag(:,2,1) * Diag(:,1,2) 5159599516SKenneth E. Jansen Diag(:,2,3) = Diag(:,2,3) - Diag(:,2,1) * Diag(:,1,3) 5259599516SKenneth E. Jansen Diag(:,2,4) = Diag(:,2,4) - Diag(:,2,1) * Diag(:,1,4) 5359599516SKenneth E. Jansen Diag(:,2,5) = Diag(:,2,5) - Diag(:,2,1) * Diag(:,1,5) 5459599516SKenneth E. Jansen Diag(:,2,2) = one / Diag(:,2,2) 5559599516SKenneth E. Jansenc 5659599516SKenneth E. Jansen Diag(:,3,2) = Diag(:,2,2)*(Diag(:,3,2) 5759599516SKenneth E. Jansen & - Diag(:,3,1) * Diag(:,1,2)) 5859599516SKenneth E. Jansen Diag(:,4,2) = Diag(:,2,2)*(Diag(:,4,2) 5959599516SKenneth E. Jansen & - Diag(:,4,1) * Diag(:,1,2)) 6059599516SKenneth E. Jansen Diag(:,5,2) = Diag(:,2,2)*(Diag(:,5,2) 6159599516SKenneth E. Jansen & - Diag(:,5,1) * Diag(:,1,2)) 6259599516SKenneth E. Jansenc 6359599516SKenneth E. Jansen 6459599516SKenneth E. Jansen Diag(:,3,3) = Diag(:,3,3) - Diag(:,3,1) * Diag(:,1,3) 6559599516SKenneth E. Jansen & - Diag(:,3,2) * Diag(:,2,3) 6659599516SKenneth E. Jansen Diag(:,3,4) = Diag(:,3,4) - Diag(:,3,1) * Diag(:,1,4) 6759599516SKenneth E. Jansen & - Diag(:,3,2) * Diag(:,2,4) 6859599516SKenneth E. Jansen Diag(:,3,5) = Diag(:,3,5) - Diag(:,3,1) * Diag(:,1,5) 6959599516SKenneth E. Jansen & - Diag(:,3,2) * Diag(:,2,5) 7059599516SKenneth E. Jansen Diag(:,3,3) = one / Diag(:,3,3) 7159599516SKenneth E. Jansenc 7259599516SKenneth E. Jansen Diag(:,4,3) = Diag(:,3,3) *(Diag(:,4,3) 7359599516SKenneth E. Jansen & - Diag(:,4,1) * Diag(:,1,3) 7459599516SKenneth E. Jansen & - Diag(:,4,2) * Diag(:,2,3)) 7559599516SKenneth E. Jansen Diag(:,5,3) = Diag(:,3,3) *(Diag(:,5,3) 7659599516SKenneth E. Jansen & - Diag(:,5,1) * Diag(:,1,3) 7759599516SKenneth E. Jansen & - Diag(:,5,2) * Diag(:,2,3)) 7859599516SKenneth E. Jansenc 7959599516SKenneth E. Jansen Diag(:,4,4) = Diag(:,4,4) - Diag(:,4,1) * Diag(:,1,4) 8059599516SKenneth E. Jansen & - Diag(:,4,2) * Diag(:,2,4) 8159599516SKenneth E. Jansen & - Diag(:,4,3) * Diag(:,3,4) 8259599516SKenneth E. Jansen Diag(:,4,4) = one / Diag(:,4,4) 8359599516SKenneth E. Jansenc 8459599516SKenneth E. Jansen Diag(:,5,4) = Diag(:,4,4) *(Diag(:,5,4) 8559599516SKenneth E. Jansen & - Diag(:,5,1) * Diag(:,1,4) 8659599516SKenneth E. Jansen & - Diag(:,5,2) * Diag(:,2,4) 8759599516SKenneth E. Jansen & - Diag(:,5,3) * Diag(:,3,4)) 8859599516SKenneth E. Jansenc 8959599516SKenneth E. Jansen Diag(:,5,5) = Diag(:,5,5) - Diag(:,5,1) * Diag(:,1,5) 9059599516SKenneth E. Jansen & - Diag(:,5,2) * Diag(:,2,5) 9159599516SKenneth E. Jansen & - Diag(:,5,3) * Diag(:,3,5) 9259599516SKenneth E. Jansen & - Diag(:,5,4) * Diag(:,4,5) 9359599516SKenneth E. Jansen Diag(:,5,5) = one / Diag(:,5,5) 9459599516SKenneth E. Jansenc 95*f4d0b58bSKenneth E. Jansenc INACCURATE NOW ! flops = flops + 110*nshg 9659599516SKenneth E. Jansenc 9759599516SKenneth E. Jansen return 9859599516SKenneth E. Jansen endif 9959599516SKenneth E. Jansenc 10059599516SKenneth E. Jansenc.... perform forward reduction 10159599516SKenneth E. Jansenc 10259599516SKenneth E. Jansen if (code .eq. 'forward ') then 10359599516SKenneth E. Jansenc 10459599516SKenneth E. Jansenc r(:,1) = r(:,1) !no-op 10559599516SKenneth E. Jansen r(:,2) = r(:,2) - Diag(:,2,1) * r(:,1) 10659599516SKenneth E. Jansen r(:,3) = r(:,3) - Diag(:,3,1) * r(:,1) 10759599516SKenneth E. Jansen & - Diag(:,3,2) * r(:,2) 10859599516SKenneth E. Jansen r(:,4) = r(:,4) - Diag(:,4,1) * r(:,1) 10959599516SKenneth E. Jansen & - Diag(:,4,2) * r(:,2) 11059599516SKenneth E. Jansen & - Diag(:,4,3) * r(:,3) 11159599516SKenneth E. Jansen r(:,5) = r(:,5) - Diag(:,5,1) * r(:,1) 11259599516SKenneth E. Jansen & - Diag(:,5,2) * r(:,2) 11359599516SKenneth E. Jansen & - Diag(:,5,3) * r(:,3) 11459599516SKenneth E. Jansen & - Diag(:,5,4) * r(:,4) 11559599516SKenneth E. Jansenc 11659599516SKenneth E. Jansenc.... flop count 11759599516SKenneth E. Jansenc 118*f4d0b58bSKenneth E. Jansenc INACCURATE ! flops = flops + 25*nshg 11959599516SKenneth E. Jansenc 12059599516SKenneth E. Jansen return 12159599516SKenneth E. Jansen endif 12259599516SKenneth E. Jansenc 12359599516SKenneth E. Jansenc.... perform backward substitution 12459599516SKenneth E. Jansenc 12559599516SKenneth E. Jansen if (code .eq. 'backward') then 12659599516SKenneth E. Jansenc 12759599516SKenneth E. Jansen r(:,5) = Diag(:,5,5) * r(:,5) 12859599516SKenneth E. Jansen r(:,4) = Diag(:,4,4) * ( r(:,4) 12959599516SKenneth E. Jansen & - r(:,5) * Diag(:,4,5) ) 13059599516SKenneth E. Jansen r(:,3) = Diag(:,3,3) * ( r(:,3) 13159599516SKenneth E. Jansen & - r(:,5) * Diag(:,3,5) 13259599516SKenneth E. Jansen & - r(:,4) * Diag(:,3,4) ) 13359599516SKenneth E. Jansen r(:,2) = Diag(:,2,2) * ( r(:,2) 13459599516SKenneth E. Jansen & - r(:,5) * Diag(:,2,5) 13559599516SKenneth E. Jansen & - r(:,4) * Diag(:,2,4) 13659599516SKenneth E. Jansen & - r(:,3) * Diag(:,2,3) ) 13759599516SKenneth E. Jansen r(:,1) = Diag(:,1,1) * ( r(:,1) 13859599516SKenneth E. Jansen & - r(:,5) * Diag(:,1,5) 13959599516SKenneth E. Jansen & - r(:,4) * Diag(:,1,4) 14059599516SKenneth E. Jansen & - r(:,3) * Diag(:,1,3) 14159599516SKenneth E. Jansen & - r(:,2) * Diag(:,1,2) ) 14259599516SKenneth E. Jansenc 14359599516SKenneth E. Jansenc.... flop count 14459599516SKenneth E. Jansenc 145*f4d0b58bSKenneth E. Jansen! flops = flops + 25*nshg 14659599516SKenneth E. Jansen 14759599516SKenneth E. Jansen return 14859599516SKenneth E. Jansen endif 14959599516SKenneth E. Jansenc 15059599516SKenneth E. Jansenc.... perform product U.r 15159599516SKenneth E. Jansenc 15259599516SKenneth E. Jansen if (code .eq. 'product ') then 15359599516SKenneth E. Jansenc 15459599516SKenneth E. Jansen r(:,1) = r(:,1) / Diag(:,1,1) + r(:,2) * Diag(:,1,2) + 15559599516SKenneth E. Jansen & r(:,3) * Diag(:,1,3) + r(:,4) * Diag(:,1,4) + 15659599516SKenneth E. Jansen & r(:,5) * Diag(:,1,5) 15759599516SKenneth E. Jansen r(:,2) = r(:,2) / Diag(:,2,2) + 15859599516SKenneth E. Jansen & r(:,3) * Diag(:,2,3) + r(:,4) * Diag(:,2,4) + 15959599516SKenneth E. Jansen & r(:,5) * Diag(:,2,5) 16059599516SKenneth E. Jansen r(:,3) = r(:,3) / Diag(:,3,3) + 16159599516SKenneth E. Jansen & r(:,4) * Diag(:,3,4) + 16259599516SKenneth E. Jansen & r(:,5) * Diag(:,3,5) 16359599516SKenneth E. Jansen r(:,4) = r(:,4) / Diag(:,4,4) + 16459599516SKenneth E. Jansen & r(:,5) * Diag(:,4,5) 16559599516SKenneth E. Jansen r(:,5) = r(:,5) / Diag(:,5,5) 16659599516SKenneth E. Jansenc 16759599516SKenneth E. Jansenc.... flop count 16859599516SKenneth E. Jansenc 169*f4d0b58bSKenneth E. Jansen! flops = flops + 40*nshg 17059599516SKenneth E. Jansen 17159599516SKenneth E. Jansen return 17259599516SKenneth E. Jansen endif 17359599516SKenneth E. Jansenc 17459599516SKenneth E. Jansen call error ('i3LU ', code, 0) 17559599516SKenneth E. Jansenc 17659599516SKenneth E. Jansenc.... return 17759599516SKenneth E. Jansenc 17859599516SKenneth E. Jansenc 17959599516SKenneth E. Jansen111 format(5(e14.7,2x)) 18059599516SKenneth E. Jansen return 18159599516SKenneth E. Jansen end 182