1*59599516SKenneth E. Jansen subroutine i3LDU (Diag, r, code) 2*59599516SKenneth E. Jansenc 3*59599516SKenneth E. Jansenc---------------------------------------------------------------------- 4*59599516SKenneth E. Jansenc 5*59599516SKenneth E. Jansenc This routine preforms a Cholesky factorization/solve of a set of 6*59599516SKenneth E. Jansenc symmetric matrices for 3-D computations, used for block diagonal 7*59599516SKenneth E. Jansenc preconditioning in the iterative driver. 8*59599516SKenneth E. Jansenc 9*59599516SKenneth E. Jansenc input: 10*59599516SKenneth E. Jansenc Diag (numnp,nsymdf) : block diagonal (symmetric storage) 11*59599516SKenneth E. Jansenc r (numnp,nflow) : residual 12*59599516SKenneth E. Jansenc code : operation code 13*59599516SKenneth E. Jansenc .eq. 'LDU_Fact', Cholesky Factor 14*59599516SKenneth E. Jansenc .eq. 'forward ', forward reduction 15*59599516SKenneth E. Jansenc .eq. 'backward', backward substitution 16*59599516SKenneth E. Jansenc .eq. 'product ', product Diag.r 17*59599516SKenneth E. Jansenc 18*59599516SKenneth E. Jansenc output: 19*59599516SKenneth E. Jansenc Diag (numnp,nsymdf) : Cholesky decomp. of block diagonal 20*59599516SKenneth E. Jansenc r (numnp,nflow) : reduced residual 21*59599516SKenneth E. Jansenc 22*59599516SKenneth E. Jansenc 23*59599516SKenneth E. Jansenc Note: the formulation used here to reduce the diagonal block to 24*59599516SKenneth E. Jansenc symmetric Cholesky triangle is taken from Golub's "Matrix 25*59599516SKenneth E. Jansenc Computations" Book, pages 89 algorithm 5.2-1. Followed by 26*59599516SKenneth E. Jansenc standard solve. 27*59599516SKenneth E. Jansenc 28*59599516SKenneth E. Jansenc 29*59599516SKenneth E. Jansenc Diag(1) Diag(2) Diag(4) Diag(7) Diag(11) 30*59599516SKenneth E. Jansenc T 0 Diag(3) Diag(5) Diag(8) Diag(12) 31*59599516SKenneth E. Jansenc L = U = 0 0 Diag(6) Diag(9) Diag(13) 32*59599516SKenneth E. Jansenc 0 0 0 Diag(10) Diag(14) 33*59599516SKenneth E. Jansenc 0 0 0 0 Diag(15) 34*59599516SKenneth E. Jansenc 35*59599516SKenneth E. Jansenc The diagonal terms 1, 3, 6, 10 and 15 are stored in inverted form. 36*59599516SKenneth E. Jansenc 37*59599516SKenneth E. Jansenc Farzin Shakib, Spring 1987. 38*59599516SKenneth E. Jansenc Zdenek Johan, Fall 1989. (Modified for option 'product') 39*59599516SKenneth E. Jansenc Zdenek Johan, Winter 1991. (Fortran 90) 40*59599516SKenneth E. Jansenc---------------------------------------------------------------------- 41*59599516SKenneth E. Jansenc 42*59599516SKenneth E. Jansen include "common.h" 43*59599516SKenneth E. Jansenc 44*59599516SKenneth E. Jansen dimension Diag(nshg,nsymdf), r(nshg,nflow) 45*59599516SKenneth E. Jansenc 46*59599516SKenneth E. Jansen character*8 code 47*59599516SKenneth E. Jansenc 48*59599516SKenneth E. Jansenc.... perform Cholesky decomposition with the Diagonal terms inverted 49*59599516SKenneth E. Jansenc 50*59599516SKenneth E. Jansen if (code .eq. 'LDU_Fact') then 51*59599516SKenneth E. Jansenc 52*59599516SKenneth E. Jansen Diag(:, 1) = one / sqrt (Diag(:, 1)) 53*59599516SKenneth E. Jansenc 54*59599516SKenneth E. Jansen Diag(:, 2) = Diag(:, 1) * Diag(:, 2) 55*59599516SKenneth E. Jansen Diag(:, 3) = Diag(:, 3) - Diag(:, 2) * Diag(:, 2) 56*59599516SKenneth E. Jansen Diag(:, 3) = one / sqrt (Diag(:, 3)) 57*59599516SKenneth E. Jansenc 58*59599516SKenneth E. Jansen Diag(:, 4) = Diag(:, 1) * Diag(:, 4) 59*59599516SKenneth E. Jansen Diag(:, 5) = Diag(:, 3) * (Diag(:, 5) 60*59599516SKenneth E. Jansen & - Diag(:, 4) * Diag(:, 2)) 61*59599516SKenneth E. Jansen Diag(:, 6) = Diag(:, 6) - Diag(:, 4) * Diag(:, 4) 62*59599516SKenneth E. Jansen & - Diag(:, 5) * Diag(:, 5) 63*59599516SKenneth E. Jansen Diag(:, 6) = one / sqrt (Diag(:, 6)) 64*59599516SKenneth E. Jansenc 65*59599516SKenneth E. Jansen Diag(:, 7) = Diag(:, 1) * Diag(:, 7) 66*59599516SKenneth E. Jansen Diag(:, 8) = Diag(:, 3) * (Diag(:, 8) 67*59599516SKenneth E. Jansen & - Diag(:, 7) * Diag(:, 2)) 68*59599516SKenneth E. Jansen Diag(:, 9) = Diag(:, 6) * (Diag(:, 9) 69*59599516SKenneth E. Jansen & - Diag(:, 7) * Diag(:, 4) 70*59599516SKenneth E. Jansen & - Diag(:, 8) * Diag(:, 5)) 71*59599516SKenneth E. Jansenc 72*59599516SKenneth E. Jansen Diag(:,10) = Diag(:,10) - Diag(:, 7) * Diag(:, 7) 73*59599516SKenneth E. Jansen & - Diag(:, 8) * Diag(:, 8) 74*59599516SKenneth E. Jansen & - Diag(:, 9) * Diag(:, 9) 75*59599516SKenneth E. Jansen Diag(:,10) = one / sqrt (Diag(:,10)) 76*59599516SKenneth E. Jansenc 77*59599516SKenneth E. Jansen Diag(:,11) = Diag(:, 1) * Diag(:,11) 78*59599516SKenneth E. Jansen Diag(:,12) = Diag(:, 3) * (Diag(:,12) 79*59599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 2)) 80*59599516SKenneth E. Jansen Diag(:,13) = Diag(:, 6) * (Diag(:,13) 81*59599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 4) 82*59599516SKenneth E. Jansen & - Diag(:,12) * Diag(:, 5)) 83*59599516SKenneth E. Jansen Diag(:,14) = Diag(:,10) * (Diag(:,14) 84*59599516SKenneth E. Jansen & - Diag(:,11) * Diag(:, 7) 85*59599516SKenneth E. Jansen & - Diag(:,12) * Diag(:, 8) 86*59599516SKenneth E. Jansen & - Diag(:,13) * Diag(:, 9)) 87*59599516SKenneth E. Jansenc 88*59599516SKenneth E. Jansen Diag(:,15) = Diag(:,15) - Diag(:,11) * Diag(:,11) 89*59599516SKenneth E. Jansen & - Diag(:,12) * Diag(:,12) 90*59599516SKenneth E. Jansen & - Diag(:,13) * Diag(:,13) 91*59599516SKenneth E. Jansen & - Diag(:,14) * Diag(:,14) 92*59599516SKenneth E. Jansen Diag(:,15) = one / sqrt (Diag(:,15)) 93*59599516SKenneth E. Jansenc 94*59599516SKenneth E. Jansenc.... flop count 95*59599516SKenneth E. Jansenc 96*59599516SKenneth E. Jansen flops = flops + 110*nshg 97*59599516SKenneth E. Jansenc 98*59599516SKenneth E. Jansen return 99*59599516SKenneth E. Jansen endif 100*59599516SKenneth E. Jansenc 101*59599516SKenneth E. Jansenc.... perform forward reduction 102*59599516SKenneth E. Jansenc 103*59599516SKenneth E. Jansen if (code .eq. 'forward ') then 104*59599516SKenneth E. Jansenc 105*59599516SKenneth E. Jansen r(:,1) = Diag(:, 1) * r(:,1) 106*59599516SKenneth E. Jansen r(:,2) = Diag(:, 3) * ( r(:,2) 107*59599516SKenneth E. Jansen & - r(:,1) * Diag(:, 2) ) 108*59599516SKenneth E. Jansen r(:,3) = Diag(:, 6) * ( r(:,3) 109*59599516SKenneth E. Jansen & - r(:,1) * Diag(:, 4) 110*59599516SKenneth E. Jansen & - r(:,2) * Diag(:, 5) ) 111*59599516SKenneth E. Jansen r(:,4) = Diag(:,10) * ( r(:,4) 112*59599516SKenneth E. Jansen & - r(:,1) * Diag(:, 7) 113*59599516SKenneth E. Jansen & - r(:,2) * Diag(:, 8) 114*59599516SKenneth E. Jansen & - r(:,3) * Diag(:, 9) ) 115*59599516SKenneth E. Jansen r(:,5) = Diag(:,15) * ( r(:,5) 116*59599516SKenneth E. Jansen & - r(:,1) * Diag(:,11) 117*59599516SKenneth E. Jansen & - r(:,2) * Diag(:,12) 118*59599516SKenneth E. Jansen & - r(:,3) * Diag(:,13) 119*59599516SKenneth E. Jansen & - r(:,4) * Diag(:,14) ) 120*59599516SKenneth E. Jansenc 121*59599516SKenneth E. Jansenc.... flop count 122*59599516SKenneth E. Jansenc 123*59599516SKenneth E. Jansen flops = flops + 25*nshg 124*59599516SKenneth E. Jansenc 125*59599516SKenneth E. Jansen return 126*59599516SKenneth E. Jansen endif 127*59599516SKenneth E. Jansenc 128*59599516SKenneth E. Jansenc.... perform backward substitution 129*59599516SKenneth E. Jansenc 130*59599516SKenneth E. Jansen if (code .eq. 'backward') then 131*59599516SKenneth E. Jansenc 132*59599516SKenneth E. Jansen r(:,5) = Diag(:,15) * r(:,5) 133*59599516SKenneth E. Jansen r(:,4) = Diag(:,10) * ( r(:,4) 134*59599516SKenneth E. Jansen & - r(:,5) * Diag(:,14) ) 135*59599516SKenneth E. Jansen r(:,3) = Diag(:, 6) * ( r(:,3) 136*59599516SKenneth E. Jansen & - r(:,5) * Diag(:,13) 137*59599516SKenneth E. Jansen & - r(:,4) * Diag(:, 9) ) 138*59599516SKenneth E. Jansen r(:,2) = Diag(:, 3) * ( r(:,2) 139*59599516SKenneth E. Jansen & - r(:,5) * Diag(:,12) 140*59599516SKenneth E. Jansen & - r(:,4) * Diag(:, 8) 141*59599516SKenneth E. Jansen & - r(:,3) * Diag(:, 5) ) 142*59599516SKenneth E. Jansen r(:,1) = Diag(:, 1) * ( r(:,1) 143*59599516SKenneth E. Jansen & - r(:,5) * Diag(:,11) 144*59599516SKenneth E. Jansen & - r(:,4) * Diag(:, 7) 145*59599516SKenneth E. Jansen & - r(:,3) * Diag(:, 4) 146*59599516SKenneth E. Jansen & - r(:,2) * Diag(:, 2) ) 147*59599516SKenneth E. Jansenc 148*59599516SKenneth E. Jansenc.... flop count 149*59599516SKenneth E. Jansenc 150*59599516SKenneth E. Jansen flops = flops + 25*nshg 151*59599516SKenneth E. Jansenc 152*59599516SKenneth E. Jansen return 153*59599516SKenneth E. Jansen endif 154*59599516SKenneth E. Jansenc 155*59599516SKenneth E. Jansenc.... perform product U.r 156*59599516SKenneth E. Jansenc 157*59599516SKenneth E. Jansen if (code .eq. 'product ') then 158*59599516SKenneth E. Jansenc 159*59599516SKenneth E. Jansen r(:,1) = r(:,1) / Diag(:, 1) + r(:,2) * Diag(:, 2) + 160*59599516SKenneth E. Jansen & r(:,3) * Diag(:, 4) + r(:,4) * Diag(:, 7) + 161*59599516SKenneth E. Jansen & r(:,5) * Diag(:,11) 162*59599516SKenneth E. Jansen r(:,2) = r(:,2) / Diag(:, 3) + r(:,3) * Diag(:, 5) + 163*59599516SKenneth E. Jansen & r(:,4) * Diag(:, 8) + r(:,5) * Diag(:,12) 164*59599516SKenneth E. Jansen r(:,3) = r(:,3) / Diag(:, 6) + r(:,4) * Diag(:, 9) + 165*59599516SKenneth E. Jansen & r(:,5) * Diag(:,13) 166*59599516SKenneth E. Jansen r(:,4) = r(:,4) / Diag(:,10) + r(:,5) * Diag(:,14) 167*59599516SKenneth E. Jansen r(:,5) = r(:,5) / Diag(:,15) 168*59599516SKenneth E. Jansenc 169*59599516SKenneth E. Jansenc.... flop count 170*59599516SKenneth E. Jansenc 171*59599516SKenneth E. Jansen flops = flops + 40*nshg 172*59599516SKenneth E. Jansenc 173*59599516SKenneth E. Jansen return 174*59599516SKenneth E. Jansen endif 175*59599516SKenneth E. Jansenc 176*59599516SKenneth E. Jansen call error ('i3LDU ', code, 0) 177*59599516SKenneth E. Jansenc 178*59599516SKenneth E. Jansenc.... return 179*59599516SKenneth E. Jansenc 180*59599516SKenneth E. Jansen return 181*59599516SKenneth E. Jansen end 182