1*59599516SKenneth E. Jansen!************************************************************* 2*59599516SKenneth E. Jansen! RAMG Coarse: 3*59599516SKenneth E. Jansen! do C/F spliting and setup coarse matrix 4*59599516SKenneth E. Jansen!************************************************************** 5*59599516SKenneth E. Jansen! ramg: ramg_coarse_setup 6*59599516SKenneth E. Jansen! Input: amg_A matrix level1 7*59599516SKenneth E. Jansen! Output: I_h_H matrix level2 to level1 8*59599516SKenneth E. Jansen! I_H_h matrix level1 to level2 9*59599516SKenneth E. Jansen!************************************************************** 10*59599516SKenneth E. Jansen subroutine ramg_coarse_setup(level1,level2,eps_str, 11*59599516SKenneth E. Jansen & interp_flag,trunc_tol, 12*59599516SKenneth E. Jansen & ilwork,BC,iBC,iper)!,nshg,nlwork,ndofBC) 13*59599516SKenneth E. Jansen use ramg_data 14*59599516SKenneth E. Jansen include "common.h" 15*59599516SKenneth E. Jansen include "mpif.h" 16*59599516SKenneth E. Jansen include "auxmpi.h" 17*59599516SKenneth E. Jansen 18*59599516SKenneth E. Jansen! implicit none 19*59599516SKenneth E. Jansen 20*59599516SKenneth E. Jansen !******* parameters ******* 21*59599516SKenneth E. Jansen integer,intent(in) :: level1,level2 22*59599516SKenneth E. Jansen real(kind=8),intent(in) :: eps_str 23*59599516SKenneth E. Jansen integer,intent(in) :: interp_flag 24*59599516SKenneth E. Jansen real(kind=8),intent(in) :: trunc_tol 25*59599516SKenneth E. Jansen! integer,intent(in) :: nshg,nlwork,ndofBC 26*59599516SKenneth E. Jansen integer,intent(in),dimension(nlwork) :: ilwork 27*59599516SKenneth E. Jansen integer,intent(in),dimension(nshg) :: iBC,iper 28*59599516SKenneth E. Jansen real(kind=8),intent(in),dimension(nshg,ndofBC) :: BC 29*59599516SKenneth E. Jansen !******* temp variables ******* 30*59599516SKenneth E. Jansen integer,dimension(amg_nnz(level1)) :: amg_S,amg_Ip 31*59599516SKenneth E. Jansen integer,dimension(amg_nshg(level1)) :: amg_F,aLoc 32*59599516SKenneth E. Jansen real(kind=8),dimension(amg_nshg(level1)) :: amg_la 33*59599516SKenneth E. Jansen integer,dimension(amg_nshg(level1)) :: amg_Fn,amg_Fp 34*59599516SKenneth E. Jansen real(kind=8) :: alpha,beta,alphac,betac,diag,rtp 35*59599516SKenneth E. Jansen real(kind=8) :: tmp1,tmp2,tmp3,tmp4 36*59599516SKenneth E. Jansen ! AMG_F : 0: UNDECIDED, 1: COARSE, 2: FINE 37*59599516SKenneth E. Jansen integer :: I_nnz,ki,kj,jj 38*59599516SKenneth E. Jansen integer :: i,j,k,m,n,p,q 39*59599516SKenneth E. Jansen character :: fname*80 40*59599516SKenneth E. Jansen 41*59599516SKenneth E. Jansen integer :: numtask,itkbeg,numseg,iacc 42*59599516SKenneth E. Jansen integer,allocatable,dimension(:) :: subcf,subcfrev,subnei 43*59599516SKenneth E. Jansen 44*59599516SKenneth E. Jansen integer :: mnnz 45*59599516SKenneth E. Jansen integer :: cfilter 46*59599516SKenneth E. Jansen type(i2dd) :: amg_I_rowp 47*59599516SKenneth E. Jansen type(r2dd) :: amg_I 48*59599516SKenneth E. Jansen type(i1d) :: amg_I_colm 49*59599516SKenneth E. Jansen 50*59599516SKenneth E. Jansen 51*59599516SKenneth E. Jansen real,dimension(10) :: cpusec 52*59599516SKenneth E. Jansen logical :: ti_flag 53*59599516SKenneth E. Jansen integer :: mem_err,mem_err_s 54*59599516SKenneth E. Jansen !******* end of variables ******** 55*59599516SKenneth E. Jansen 56*59599516SKenneth E. Jansen call cpu_time(cpusec(1)) 57*59599516SKenneth E. Jansen 58*59599516SKenneth E. Jansen if (abs(trunc_tol).lt.1e-4) then 59*59599516SKenneth E. Jansen ti_flag = .false. 60*59599516SKenneth E. Jansen else 61*59599516SKenneth E. Jansen ti_flag = .true. 62*59599516SKenneth E. Jansen end if 63*59599516SKenneth E. Jansen 64*59599516SKenneth E. Jansen amg_S = 0 65*59599516SKenneth E. Jansen amg_F = 0 66*59599516SKenneth E. Jansen 67*59599516SKenneth E. Jansen if (numpe.ge.2) then 68*59599516SKenneth E. Jansen numtask = ilwork(1)+1 69*59599516SKenneth E. Jansen else 70*59599516SKenneth E. Jansen numtask = 1 71*59599516SKenneth E. Jansen endif 72*59599516SKenneth E. Jansen 73*59599516SKenneth E. Jansen IF ((iamg_reduce.le.1).or.(numpe.gt.1)) THEN 74*59599516SKenneth E. Jansen! IF (.TRUE.) THEN 75*59599516SKenneth E. Jansen allocate(subcfrev(numpe)) 76*59599516SKenneth E. Jansen subcfrev = 0 77*59599516SKenneth E. Jansen allocate(subcf(numtask)) 78*59599516SKenneth E. Jansen subcf = 0 79*59599516SKenneth E. Jansen allocate(subnei(numtask)) 80*59599516SKenneth E. Jansen subnei = 0 81*59599516SKenneth E. Jansen 82*59599516SKenneth E. Jansen subnei(1) = myrank+1 83*59599516SKenneth E. Jansen subcfrev(subnei(1))=1 84*59599516SKenneth E. Jansen itkbeg = 1 85*59599516SKenneth E. Jansen do i=2,numtask 86*59599516SKenneth E. Jansen subnei(i)=ilwork(itkbeg+3)+1 ! iother+1 87*59599516SKenneth E. Jansen subcfrev(subnei(i)) = i 88*59599516SKenneth E. Jansen itkbeg = itkbeg + 4 + 2*ilwork(itkbeg+4) 89*59599516SKenneth E. Jansen enddo 90*59599516SKenneth E. Jansen 91*59599516SKenneth E. Jansen ELSE !reduced 92*59599516SKenneth E. Jansen numtask = rmapmax-1 93*59599516SKenneth E. Jansen allocate(subcfrev(numtask)) 94*59599516SKenneth E. Jansen allocate(subcf(numtask)) 95*59599516SKenneth E. Jansen allocate(subnei(numtask)) 96*59599516SKenneth E. Jansen subcfrev = 0 97*59599516SKenneth E. Jansen subcf = 0 98*59599516SKenneth E. Jansen subnei = 0 99*59599516SKenneth E. Jansen do i=1,numtask 100*59599516SKenneth E. Jansen subcfrev(i) = i 101*59599516SKenneth E. Jansen enddo 102*59599516SKenneth E. Jansen END IF 103*59599516SKenneth E. Jansen 104*59599516SKenneth E. Jansen call ramg_CFsplit(amg_F,amg_S,amg_nshg(level1),amg_nnz(level1), 105*59599516SKenneth E. Jansen & amg_A_colm(level1)%p,amg_A_rowp(level1)%p, 106*59599516SKenneth E. Jansen & amg_A_lhs(level1)%p,amg_paramap(level1)%p, 107*59599516SKenneth E. Jansen & ilwork,BC,iBC,iper, 108*59599516SKenneth E. Jansen & eps_str,-1,0) 109*59599516SKenneth E. Jansen ! read FC spliting to file 110*59599516SKenneth E. Jansen if (level1.eq.1) then 111*59599516SKenneth E. Jansen ! write(fname,'((A7)(I1))')'GTG_FC_',level1 112*59599516SKenneth E. Jansen ! call ramg_readin_i(amg_F,amg_nshg(level1),fname) 113*59599516SKenneth E. Jansen ! write FC spliting to file 114*59599516SKenneth E. Jansen !write(fname,'((A7)(I1))')'amg_FC_',level1 115*59599516SKenneth E. Jansen !call ramg_dump_i(amg_F,amg_nshg(level1),1,fname) 116*59599516SKenneth E. Jansen endif 117*59599516SKenneth E. Jansen 118*59599516SKenneth E. Jansen call ramg_update_cfmap(amg_F,level1) 119*59599516SKenneth E. Jansen ! communication goes here 120*59599516SKenneth E. Jansen call MPI_Barrier(MPI_COMM_WORLD,ierr) 121*59599516SKenneth E. Jansen call commOut_i(amg_cfmap,ilwork,1,iper,iBC,BC) 122*59599516SKenneth E. Jansen call ramg_readin_cfmap(amg_F,level1) 123*59599516SKenneth E. Jansen 124*59599516SKenneth E. Jansen IF (.true.) THEN 125*59599516SKenneth E. Jansen subcf = 0 126*59599516SKenneth E. Jansen subnei = 0 127*59599516SKenneth E. Jansen do i = 1,amg_nshg(level1) 128*59599516SKenneth E. Jansen p = iabs(amg_paramap(level1)%p(i)) 129*59599516SKenneth E. Jansen p = subcfrev(p) 130*59599516SKenneth E. Jansen subnei(p) = subnei(p) + 1 131*59599516SKenneth E. Jansen if (amg_F(i).eq.1) then 132*59599516SKenneth E. Jansen subcf(p) = subcf(p) + 1 133*59599516SKenneth E. Jansen endif 134*59599516SKenneth E. Jansen enddo 135*59599516SKenneth E. Jansen do i = 1,numtask 136*59599516SKenneth E. Jansen enddo 137*59599516SKenneth E. Jansen ENDIF 138*59599516SKenneth E. Jansen 139*59599516SKenneth E. Jansen call cpu_time(cpusec(3)) 140*59599516SKenneth E. Jansen 141*59599516SKenneth E. Jansen deallocate(subcf) 142*59599516SKenneth E. Jansen deallocate(subcfrev) 143*59599516SKenneth E. Jansen deallocate(subnei) 144*59599516SKenneth E. Jansen 145*59599516SKenneth E. Jansen ! SETUP Smoothing ordering 146*59599516SKenneth E. Jansen allocate(CF_map(level1)%p(amg_nshg(level1))) 147*59599516SKenneth E. Jansen allocate(CF_revmap(level1)%p(amg_nshg(level1))) 148*59599516SKenneth E. Jansen 149*59599516SKenneth E. Jansen k = 1 150*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 151*59599516SKenneth E. Jansen if (amg_F(i).eq.1) then ! fine/coarse first 152*59599516SKenneth E. Jansen CF_map(level1)%p(k) = i 153*59599516SKenneth E. Jansen CF_revmap(level1)%p(i) = k 154*59599516SKenneth E. Jansen k = k+1 155*59599516SKenneth E. Jansen end if 156*59599516SKenneth E. Jansen enddo 157*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 158*59599516SKenneth E. Jansen if (amg_F(i).eq.2) then 159*59599516SKenneth E. Jansen CF_map(level1)%p(k) = i 160*59599516SKenneth E. Jansen CF_revmap(level1)%p(i) = k 161*59599516SKenneth E. Jansen k = k+1 162*59599516SKenneth E. Jansen end if 163*59599516SKenneth E. Jansen enddo 164*59599516SKenneth E. Jansen 165*59599516SKenneth E. Jansen if (level1.eq.-1) then 166*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 167*59599516SKenneth E. Jansen CF_map(level1)%p(i) = i 168*59599516SKenneth E. Jansen CF_revmap(level1)%p(i) = i 169*59599516SKenneth E. Jansen enddo 170*59599516SKenneth E. Jansen endif 171*59599516SKenneth E. Jansen 172*59599516SKenneth E. Jansen ! generate I := I_H_h, from coarse to fine 173*59599516SKenneth E. Jansen ! then TRANSPOSE and get I^T, from fine to coarse 174*59599516SKenneth E. Jansen 175*59599516SKenneth E. Jansen ! determine the size of second level 176*59599516SKenneth E. Jansen amg_nshg(level2) = 0 177*59599516SKenneth E. Jansen amg_Ip = 0 178*59599516SKenneth E. Jansen I_nnz = 0 179*59599516SKenneth E. Jansen do i = 1, amg_nshg(level1) 180*59599516SKenneth E. Jansen if (amg_F(i).eq.1) then 181*59599516SKenneth E. Jansen amg_nshg(level2) = amg_nshg(level2) + 1 182*59599516SKenneth E. Jansen I_nnz = I_nnz + 1 183*59599516SKenneth E. Jansen amg_Ip(i) = I_nnz 184*59599516SKenneth E. Jansen end if 185*59599516SKenneth E. Jansen enddo 186*59599516SKenneth E. Jansen 187*59599516SKenneth E. Jansen allocate(amg_paramap(level2)%p(amg_nshg(level2))) 188*59599516SKenneth E. Jansen allocate(amg_paraext(level2)%p(amg_nshg(level2))) 189*59599516SKenneth E. Jansen j = 1 190*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 191*59599516SKenneth E. Jansen if (amg_F(i).eq.1) then 192*59599516SKenneth E. Jansen amg_paramap(level2)%p(j) = amg_paramap(level1)%p(i) 193*59599516SKenneth E. Jansen amg_paraext(level2)%p(j) = amg_paraext(level1)%p(i) 194*59599516SKenneth E. Jansen j = j + 1 195*59599516SKenneth E. Jansen end if 196*59599516SKenneth E. Jansen enddo 197*59599516SKenneth E. Jansen 198*59599516SKenneth E. Jansen ! ALLOCATE I_H_h from coarse to fine 199*59599516SKenneth E. Jansen mem_err_s = 0 200*59599516SKenneth E. Jansen allocate(amg_I_colm%p(amg_nshg(level1)),stat=mem_err) 201*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 202*59599516SKenneth E. Jansen allocate(amg_I_rowp%pp(amg_nshg(level1)),stat=mem_err) 203*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 204*59599516SKenneth E. Jansen allocate(amg_I%pp(amg_nshg(level1)),stat=mem_err) 205*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 206*59599516SKenneth E. Jansen if (mem_err_s.ne.0) then 207*59599516SKenneth E. Jansen write(*,*)'Memory allocation error while geting I_H_h' 208*59599516SKenneth E. Jansen end if 209*59599516SKenneth E. Jansen 210*59599516SKenneth E. Jansen cpusec(4) = 0 211*59599516SKenneth E. Jansen cpusec(5) = 0 212*59599516SKenneth E. Jansen cpusec(8) = 0 213*59599516SKenneth E. Jansen mnnz = 0 214*59599516SKenneth E. Jansen aLoc = 0 215*59599516SKenneth E. Jansen loop_i: do i = 1, amg_nshg(level1) 216*59599516SKenneth E. Jansen call cpu_time(cpusec(6)) 217*59599516SKenneth E. Jansen cfilter = amg_paramap(level1)%p(i) 218*59599516SKenneth E. Jansen if (amg_F(i).eq.1) then ! i as a coarse node do trivial work 219*59599516SKenneth E. Jansen allocate(amg_I_rowp%pp(i)%p(1)) 220*59599516SKenneth E. Jansen allocate(amg_I%pp(i)%p(1)) 221*59599516SKenneth E. Jansen amg_I_colm%p(i) = 1 222*59599516SKenneth E. Jansen amg_I_rowp%pp(i)%p(1) = amg_Ip(i) 223*59599516SKenneth E. Jansen amg_I%pp(i)%p(1) = 1 224*59599516SKenneth E. Jansen mnnz = mnnz + 1 225*59599516SKenneth E. Jansen cycle loop_i 226*59599516SKenneth E. Jansen end if 227*59599516SKenneth E. Jansen n = 0 228*59599516SKenneth E. Jansen ! a-hat, P-hat, N-hat 229*59599516SKenneth E. Jansen ! amg_la ! a-hat 230*59599516SKenneth E. Jansen ! amg_Fn ! N-hat 231*59599516SKenneth E. Jansen ! amg_Fp ! P-hat 232*59599516SKenneth E. Jansen ! diagonal part 233*59599516SKenneth E. Jansen diag = -1.0d0/amg_A_lhs(level1)%p(amg_A_colm(level1)%p(i),1) 234*59599516SKenneth E. Jansen ! non-diagonal 235*59599516SKenneth E. Jansen do k = amg_A_colm(level1)%p(i)+1,amg_A_colm(level1)%p(i+1)-1 236*59599516SKenneth E. Jansen j = amg_A_rowp(level1)%p(k) 237*59599516SKenneth E. Jansen if (cfilter.eq.amg_paramap(level1)%p(j)) then 238*59599516SKenneth E. Jansen n = n + 1 239*59599516SKenneth E. Jansen if ( (amg_F(j).eq.1) .and. (mod(amg_S(k),2).eq.1) ) then 240*59599516SKenneth E. Jansen amg_Fp(n) = 1 241*59599516SKenneth E. Jansen else 242*59599516SKenneth E. Jansen amg_Fp(n) = 0 243*59599516SKenneth E. Jansen endif 244*59599516SKenneth E. Jansen amg_Fn(n) = j 245*59599516SKenneth E. Jansen amg_la(n) = amg_A_lhs(level1)%p(k,1) 246*59599516SKenneth E. Jansen aLoc(j) = n 247*59599516SKenneth E. Jansen end if 248*59599516SKenneth E. Jansen enddo 249*59599516SKenneth E. Jansen 250*59599516SKenneth E. Jansen ! standard interpolation here ! for parallel dont use 251*59599516SKenneth E. Jansen if ( interp_flag .eq. 1) then 252*59599516SKenneth E. Jansen do k=amg_A_colm(level1)%p(i)+1,amg_A_colm(level1)%p(i+1)-1 253*59599516SKenneth E. Jansen j = amg_A_rowp(level1)%p(k) 254*59599516SKenneth E. Jansen if ( (amg_F(j).eq.2) .and. (mod(amg_S(k),2).eq.1)) then 255*59599516SKenneth E. Jansen rtp = amg_A_lhs(level1)%p(amg_A_colm(level1)%p(j),1) 256*59599516SKenneth E. Jansen if (rtp.ne.0) then 257*59599516SKenneth E. Jansen rtp = amg_la(aLoc(j))/rtp 258*59599516SKenneth E. Jansen endif 259*59599516SKenneth E. Jansen do kj=amg_A_colm(level1)%p(j),amg_A_colm(level1)%p(j+1)-1 260*59599516SKenneth E. Jansen jj = amg_A_rowp(level1)%p(kj) 261*59599516SKenneth E. Jansen m = aLoc(jj) 262*59599516SKenneth E. Jansen if (m.eq.0) then 263*59599516SKenneth E. Jansen m = n+1 264*59599516SKenneth E. Jansen aLoc(jj) = m 265*59599516SKenneth E. Jansen amg_Fn(m) = jj 266*59599516SKenneth E. Jansen amg_Fp(m) = 0 267*59599516SKenneth E. Jansen amg_la(m) = 0 268*59599516SKenneth E. Jansen n = n+1 269*59599516SKenneth E. Jansen end if 270*59599516SKenneth E. Jansen amg_la(m) = amg_la(m) - rtp*amg_A_lhs(level1)%p(kj,1) 271*59599516SKenneth E. Jansen if ( (amg_F(jj).eq.1) .and. (mod(amg_S(kj),2).eq.1) ) then 272*59599516SKenneth E. Jansen amg_Fp(m) = 1 273*59599516SKenneth E. Jansen else 274*59599516SKenneth E. Jansen amg_Fp(m) = 0 275*59599516SKenneth E. Jansen endif 276*59599516SKenneth E. Jansen enddo 277*59599516SKenneth E. Jansen end if 278*59599516SKenneth E. Jansen enddo 279*59599516SKenneth E. Jansen endif 280*59599516SKenneth E. Jansen 281*59599516SKenneth E. Jansen call cpu_time(cpusec(7)) 282*59599516SKenneth E. Jansen cpusec(4) = cpusec(4) + cpusec(7)-cpusec(6) 283*59599516SKenneth E. Jansen ! calculate alpha, beta, nnz-in-row 284*59599516SKenneth E. Jansen alpha = 0 285*59599516SKenneth E. Jansen beta = 0 286*59599516SKenneth E. Jansen alphac = 0 287*59599516SKenneth E. Jansen betac = 0 288*59599516SKenneth E. Jansen I_nnz = 0 289*59599516SKenneth E. Jansen do k = 1,n ! all non diagonal 290*59599516SKenneth E. Jansen aLoc(amg_Fn(k))=0 291*59599516SKenneth E. Jansen ! in N-hat 292*59599516SKenneth E. Jansen if ( amg_la(k).lt.0 ) then ! a-hat < 0 293*59599516SKenneth E. Jansen alpha = alpha + amg_la(k) 294*59599516SKenneth E. Jansen else ! a-hat > 0 295*59599516SKenneth E. Jansen beta = beta + amg_la(k) 296*59599516SKenneth E. Jansen end if 297*59599516SKenneth E. Jansen ! in P-hat 298*59599516SKenneth E. Jansen if (amg_Fp(k).eq.1) then 299*59599516SKenneth E. Jansen I_nnz = I_nnz + 1 ! nonzero in I_h_H row 300*59599516SKenneth E. Jansen if (amg_la(k).lt.0) then ! a-hat < 0 in coarse 301*59599516SKenneth E. Jansen alphac = alphac + amg_la(k) 302*59599516SKenneth E. Jansen else ! a-hat > 0 in coarse 303*59599516SKenneth E. Jansen betac = betac + amg_la(k) 304*59599516SKenneth E. Jansen end if 305*59599516SKenneth E. Jansen amg_Fn(I_nnz) = amg_Fn(k) 306*59599516SKenneth E. Jansen amg_la(I_nnz) = amg_la(k) 307*59599516SKenneth E. Jansen end if 308*59599516SKenneth E. Jansen enddo 309*59599516SKenneth E. Jansen alpha = diag*alpha/alphac 310*59599516SKenneth E. Jansen beta = diag*beta/betac 311*59599516SKenneth E. Jansen rtp = 0 312*59599516SKenneth E. Jansen do k = 1,I_nnz 313*59599516SKenneth E. Jansen if ( amg_la(k).lt.0) then 314*59599516SKenneth E. Jansen amg_la(k) = amg_la(k)*alpha 315*59599516SKenneth E. Jansen else 316*59599516SKenneth E. Jansen amg_la(k) = amg_la(k)*beta 317*59599516SKenneth E. Jansen end if 318*59599516SKenneth E. Jansen rtp = max(rtp,abs(amg_la(k))) 319*59599516SKenneth E. Jansen enddo 320*59599516SKenneth E. Jansen if (ti_flag) then 321*59599516SKenneth E. Jansen n = I_nnz 322*59599516SKenneth E. Jansen I_nnz = 0 323*59599516SKenneth E. Jansen tmp1 = 0 324*59599516SKenneth E. Jansen tmp2 = 0 325*59599516SKenneth E. Jansen tmp3 = 0 326*59599516SKenneth E. Jansen tmp4 = 0 327*59599516SKenneth E. Jansen rtp = rtp*trunc_tol 328*59599516SKenneth E. Jansen do k=1,n 329*59599516SKenneth E. Jansen tmp3 = tmp3 + min(amg_la(k),zero) 330*59599516SKenneth E. Jansen tmp4 = tmp4 + max(amg_la(k),zero) 331*59599516SKenneth E. Jansen if (abs(amg_la(k)).gt.rtp) then 332*59599516SKenneth E. Jansen tmp1 = tmp1 + min(amg_la(k),zero) 333*59599516SKenneth E. Jansen tmp2 = tmp2 + max(amg_la(k),zero) 334*59599516SKenneth E. Jansen I_nnz = I_nnz + 1 335*59599516SKenneth E. Jansen amg_Fn(I_nnz) = amg_Fn(k) 336*59599516SKenneth E. Jansen amg_la(I_nnz) = amg_la(k) 337*59599516SKenneth E. Jansen end if 338*59599516SKenneth E. Jansen enddo 339*59599516SKenneth E. Jansen if ( abs(tmp1).gt.1e-5) tmp1 = tmp3/tmp1 340*59599516SKenneth E. Jansen if ( abs(tmp2).gt.1e-5) tmp2 = tmp4/tmp2 341*59599516SKenneth E. Jansen do k=1,I_nnz 342*59599516SKenneth E. Jansen if (amg_la(k).lt.0) then 343*59599516SKenneth E. Jansen amg_la(k) = amg_la(k)*tmp1 344*59599516SKenneth E. Jansen else 345*59599516SKenneth E. Jansen amg_la(k) = amg_la(k)*tmp2 346*59599516SKenneth E. Jansen end if 347*59599516SKenneth E. Jansen enddo 348*59599516SKenneth E. Jansen end if 349*59599516SKenneth E. Jansen ! put up I matrix row 350*59599516SKenneth E. Jansen call cpu_time(cpusec(6)) 351*59599516SKenneth E. Jansen cpusec(5) = cpusec(5) + cpusec(6)-cpusec(7) 352*59599516SKenneth E. Jansen mnnz = mnnz + I_nnz 353*59599516SKenneth E. Jansen amg_I_colm%p(i) = I_nnz 354*59599516SKenneth E. Jansen allocate(amg_I_rowp%pp(i)%p(I_nnz)) 355*59599516SKenneth E. Jansen allocate(amg_I%pp(i)%p(I_nnz)) 356*59599516SKenneth E. Jansen do k = 1,I_nnz ! scan over P-hat 357*59599516SKenneth E. Jansen amg_I_rowp%pp(i)%p(k) = amg_Ip(amg_Fn(k)) 358*59599516SKenneth E. Jansen ! put in rowp 359*59599516SKenneth E. Jansen if (amg_la(k).lt.0) then 360*59599516SKenneth E. Jansen amg_I%pp(i)%p(k) = amg_la(k) 361*59599516SKenneth E. Jansen else 362*59599516SKenneth E. Jansen amg_I%pp(i)%p(k) = amg_la(k) 363*59599516SKenneth E. Jansen endif 364*59599516SKenneth E. Jansen enddo 365*59599516SKenneth E. Jansen call cpu_time(cpusec(7)) 366*59599516SKenneth E. Jansen cpusec(8) = cpusec(8) + cpusec(7) - cpusec(6) 367*59599516SKenneth E. Jansen enddo loop_i ! Now we have I_H_h 368*59599516SKenneth E. Jansen 369*59599516SKenneth E. Jansen ! copy the data 370*59599516SKenneth E. Jansen mem_err_s = 0 371*59599516SKenneth E. Jansen allocate(I_cf_colm(level1)%p(amg_nshg(level1)+1),stat=mem_err) 372*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 373*59599516SKenneth E. Jansen allocate(I_cf_rowp(level1)%p(mnnz),stat=mem_err) 374*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 375*59599516SKenneth E. Jansen allocate(I_cf(level1)%p(mnnz),stat=mem_err) 376*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 377*59599516SKenneth E. Jansen if (mem_err_s .ne. 0 ) then 378*59599516SKenneth E. Jansen write(*,*)'allocation error in I_cf' 379*59599516SKenneth E. Jansen end if 380*59599516SKenneth E. Jansen mnnz = 0 381*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 382*59599516SKenneth E. Jansen I_cf_colm(level1)%p(i)=mnnz+1 383*59599516SKenneth E. Jansen do j=1,amg_I_colm%p(i) 384*59599516SKenneth E. Jansen I_cf_rowp(level1)%p(mnnz+j)=amg_I_rowp%pp(i)%p(j) 385*59599516SKenneth E. Jansen I_cf(level1)%p(mnnz+j)=amg_I%pp(i)%p(j) 386*59599516SKenneth E. Jansen enddo 387*59599516SKenneth E. Jansen mnnz = mnnz + amg_I_colm%p(i) 388*59599516SKenneth E. Jansen enddo 389*59599516SKenneth E. Jansen I_cf_colm(level1)%p(amg_nshg(level1)+1) = mnnz+1 390*59599516SKenneth E. Jansen 391*59599516SKenneth E. Jansen ! dump interpolator 392*59599516SKenneth E. Jansen! if (level1.eq.1) then 393*59599516SKenneth E. Jansen! write(fname,'((A4)(I1))')'Icf_',level1 394*59599516SKenneth E. Jansen! write(*,*)amg_nshg(level1),mnnz 395*59599516SKenneth E. Jansen! call ramg_dump_matlab_A(I_cf_colm(level1)%p,I_cf_rowp(level1)%p, 396*59599516SKenneth E. Jansen! & I_cf(level1)%p,amg_nshg(level1),mnnz,1,fname) 397*59599516SKenneth E. Jansen! endif 398*59599516SKenneth E. Jansen 399*59599516SKenneth E. Jansen mem_err_s = 0 400*59599516SKenneth E. Jansen do i = 1,amg_nshg(level1) 401*59599516SKenneth E. Jansen if (amg_I_colm%p(i).ne.0) then 402*59599516SKenneth E. Jansen deallocate(amg_I_rowp%pp(i)%p,stat=mem_err) 403*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 404*59599516SKenneth E. Jansen deallocate(amg_I%pp(i)%p,stat=mem_err) 405*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 406*59599516SKenneth E. Jansen end if 407*59599516SKenneth E. Jansen enddo 408*59599516SKenneth E. Jansen deallocate(amg_I_colm%p,stat=mem_err) 409*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 410*59599516SKenneth E. Jansen deallocate(amg_I_rowp%pp,stat=mem_err) 411*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 412*59599516SKenneth E. Jansen deallocate(amg_I%pp,stat=mem_err) 413*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 414*59599516SKenneth E. Jansen if (mem_err_s .ne. 0) then 415*59599516SKenneth E. Jansen write(*,*)'deallocation error in I_cf' 416*59599516SKenneth E. Jansen end if 417*59599516SKenneth E. Jansen 418*59599516SKenneth E. Jansen ! now build I_fc, inverse of I_cf 419*59599516SKenneth E. Jansen call cpu_time(cpusec(6)) 420*59599516SKenneth E. Jansen 421*59599516SKenneth E. Jansen mem_err_s = 0 422*59599516SKenneth E. Jansen allocate(I_fc_colm(level1)%p(amg_nshg(level2)+1),stat=mem_err) 423*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 424*59599516SKenneth E. Jansen allocate(I_fc_rowp(level1)%p(mnnz),stat=mem_err) 425*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 426*59599516SKenneth E. Jansen allocate(I_fc(level1)%p(mnnz),stat=mem_err) 427*59599516SKenneth E. Jansen mem_err_s = mem_err_s + mem_err 428*59599516SKenneth E. Jansen if (mem_err_s .ne. 0 ) then 429*59599516SKenneth E. Jansen write(*,*)'allocation error in I_fc' 430*59599516SKenneth E. Jansen end if 431*59599516SKenneth E. Jansen 432*59599516SKenneth E. Jansen I_fc_colm(level1)%p(1:amg_nshg(level2)+1) = 0 433*59599516SKenneth E. Jansen do i=1,mnnz 434*59599516SKenneth E. Jansen I_fc_colm(level1)%p(I_cf_rowp(level1)%p(i)) = 435*59599516SKenneth E. Jansen & I_fc_colm(level1)%p(I_cf_rowp(level1)%p(i)) + 1 436*59599516SKenneth E. Jansen enddo 437*59599516SKenneth E. Jansen mnnz = 1 438*59599516SKenneth E. Jansen do i=1,amg_nshg(level2) 439*59599516SKenneth E. Jansen j = I_fc_colm(level1)%p(i) 440*59599516SKenneth E. Jansen I_fc_colm(level1)%p(i) = mnnz 441*59599516SKenneth E. Jansen mnnz = mnnz + j 442*59599516SKenneth E. Jansen enddo 443*59599516SKenneth E. Jansen I_fc_colm(level1)%p(amg_nshg(level2)+1) = mnnz 444*59599516SKenneth E. Jansen 445*59599516SKenneth E. Jansen do i=1,amg_nshg(level1) 446*59599516SKenneth E. Jansen do k=I_cf_colm(level1)%p(i),I_cf_colm(level1)%p(i+1)-1 447*59599516SKenneth E. Jansen j = I_cf_rowp(level1)%p(k) 448*59599516SKenneth E. Jansen kj = I_fc_colm(level1)%p(j) 449*59599516SKenneth E. Jansen I_fc_colm(level1)%p(j) = I_fc_colm(level1)%p(j) + 1 450*59599516SKenneth E. Jansen I_fc_rowp(level1)%p(kj) = i 451*59599516SKenneth E. Jansen I_fc(level1)%p(kj) = I_cf(level1)%p(k) 452*59599516SKenneth E. Jansen enddo 453*59599516SKenneth E. Jansen enddo 454*59599516SKenneth E. Jansen 455*59599516SKenneth E. Jansen do i=amg_nshg(level2),2,-1 456*59599516SKenneth E. Jansen I_fc_colm(level1)%p(i) = I_fc_colm(level1)%p(i-1) 457*59599516SKenneth E. Jansen enddo 458*59599516SKenneth E. Jansen I_fc_colm(level1)%p(1) = 1 459*59599516SKenneth E. Jansen 460*59599516SKenneth E. Jansen call cpu_time(cpusec(10)) 461*59599516SKenneth E. Jansen 462*59599516SKenneth E. Jansen end subroutine!ramg_coarse_setup 463*59599516SKenneth E. Jansen 464*59599516SKenneth E. Jansen!************************************************************** 465*59599516SKenneth E. Jansen! Heap routines 466*59599516SKenneth E. Jansen!************************************************************** 467*59599516SKenneth E. Jansen subroutine ramg_initheap(heap,invMap,wght,nheaps,ilen) 468*59599516SKenneth E. Jansen implicit none 469*59599516SKenneth E. Jansen integer :: nheaps,ilen 470*59599516SKenneth E. Jansen integer,dimension(0:ilen-1),intent(inout) :: heap,invMap 471*59599516SKenneth E. Jansen real(kind=8),dimension(0:ilen-1),intent(in) :: wght 472*59599516SKenneth E. Jansen 473*59599516SKenneth E. Jansen integer :: i,j,k,t 474*59599516SKenneth E. Jansen 475*59599516SKenneth E. Jansen do i=0,nheaps-1 476*59599516SKenneth E. Jansen heap(i) = i 477*59599516SKenneth E. Jansen enddo 478*59599516SKenneth E. Jansen 479*59599516SKenneth E. Jansen do i=1,nheaps-1 480*59599516SKenneth E. Jansen k = i 481*59599516SKenneth E. Jansen j = ishft(k-1,-1) 482*59599516SKenneth E. Jansen do while ( ( k.gt.0 ).and.(wght(heap(k)).gt.wght(heap(j))) ) 483*59599516SKenneth E. Jansen t = heap(j) 484*59599516SKenneth E. Jansen heap(j) = heap(k) 485*59599516SKenneth E. Jansen heap(k) = t 486*59599516SKenneth E. Jansen k = j 487*59599516SKenneth E. Jansen j = ishft(j-1,-1) 488*59599516SKenneth E. Jansen enddo 489*59599516SKenneth E. Jansen enddo 490*59599516SKenneth E. Jansen 491*59599516SKenneth E. Jansen do i=0,nheaps-1 492*59599516SKenneth E. Jansen invmap(heap(i)) = i 493*59599516SKenneth E. Jansen enddo 494*59599516SKenneth E. Jansen 495*59599516SKenneth E. Jansen end subroutine ! ramg_initheap 496*59599516SKenneth E. Jansen 497*59599516SKenneth E. Jansen subroutine ramg_popheap(heap,invmap,wght,nheaps,popid,ilen) 498*59599516SKenneth E. Jansen implicit none 499*59599516SKenneth E. Jansen integer,intent(inout) :: nheaps 500*59599516SKenneth E. Jansen integer,intent(in) :: popid,ilen 501*59599516SKenneth E. Jansen real(kind=8),dimension(0:ilen-1),intent(in) :: wght 502*59599516SKenneth E. Jansen integer,dimension(0:ilen-1),intent(inout) :: heap,invmap 503*59599516SKenneth E. Jansen 504*59599516SKenneth E. Jansen integer i,j,k 505*59599516SKenneth E. Jansen nheaps = nheaps-1 506*59599516SKenneth E. Jansen heap(popid) = heap(nheaps) 507*59599516SKenneth E. Jansen invmap(heap(popid)) = popid 508*59599516SKenneth E. Jansen call ramg_adjheap(heap,invmap,wght,nheaps,popid,ilen) 509*59599516SKenneth E. Jansen 510*59599516SKenneth E. Jansen end subroutine !ramg_popheap 511*59599516SKenneth E. Jansen 512*59599516SKenneth E. Jansen subroutine ramg_adjheap(heap,invmap,wght,nheaps,popid,ilen) 513*59599516SKenneth E. Jansen implicit none 514*59599516SKenneth E. Jansen integer,intent(in) :: nheaps,ilen 515*59599516SKenneth E. Jansen integer,dimension(0:ilen-1),intent(inout) :: heap,invmap 516*59599516SKenneth E. Jansen real(kind=8),dimension(0:ilen-1),intent(in) :: wght 517*59599516SKenneth E. Jansen integer,intent(in) :: popid 518*59599516SKenneth E. Jansen 519*59599516SKenneth E. Jansen integer i,j,k,t 520*59599516SKenneth E. Jansen 521*59599516SKenneth E. Jansen i = popid 522*59599516SKenneth E. Jansen j = ishft(i-1,-1); 523*59599516SKenneth E. Jansen do while ( (i.gt.0).and.(wght(heap(j)).lt.wght(heap(i)))) 524*59599516SKenneth E. Jansen t = heap(i) 525*59599516SKenneth E. Jansen heap(i) = heap(j) 526*59599516SKenneth E. Jansen heap(j) = t 527*59599516SKenneth E. Jansen invmap(heap(i)) = i 528*59599516SKenneth E. Jansen invmap(heap(j)) = j 529*59599516SKenneth E. Jansen i = j 530*59599516SKenneth E. Jansen j = ishft(i-1,-1) 531*59599516SKenneth E. Jansen enddo 532*59599516SKenneth E. Jansen 533*59599516SKenneth E. Jansen i = popid 534*59599516SKenneth E. Jansen do while (i.lt.(nheaps/2)) 535*59599516SKenneth E. Jansen j = 2*i+1 536*59599516SKenneth E. Jansen if ((j.lt.(nheaps-1)).and.(wght(heap(j)).lt.wght(heap(j+1)))) 537*59599516SKenneth E. Jansen & then 538*59599516SKenneth E. Jansen j = j + 1 539*59599516SKenneth E. Jansen end if 540*59599516SKenneth E. Jansen if (wght(heap(i)).gt.wght(heap(j))) then 541*59599516SKenneth E. Jansen exit 542*59599516SKenneth E. Jansen end if 543*59599516SKenneth E. Jansen t = heap(i) 544*59599516SKenneth E. Jansen heap(i) = heap(j) 545*59599516SKenneth E. Jansen heap(j) = t 546*59599516SKenneth E. Jansen invmap(heap(i)) = i 547*59599516SKenneth E. Jansen invmap(heap(j)) = j 548*59599516SKenneth E. Jansen i = j 549*59599516SKenneth E. Jansen enddo 550*59599516SKenneth E. Jansen 551*59599516SKenneth E. Jansen end subroutine !ramg_adjheap 552*59599516SKenneth E. Jansen 553*59599516SKenneth E. Jansen!**************************************************** 554*59599516SKenneth E. Jansen! ramg_CFsplit: split coarse/fine nodes 555*59599516SKenneth E. Jansen! Input: matrix in sparse form 556*59599516SKenneth E. Jansen! parameters: (filter array)(aggressive/standard) 557*59599516SKenneth E. Jansen! Output: C/F splitting result, Strong corelation set amg_S 558*59599516SKenneth E. Jansen! within given filter subset 559*59599516SKenneth E. Jansen!**************************************************** 560*59599516SKenneth E. Jansen 561*59599516SKenneth E. Jansen subroutine ramg_CFsplit(amg_CF,amg_S,anshg,annz,acolm,arowp, 562*59599516SKenneth E. Jansen & alhs,afmap,ilwork,BC,iBC,iper, 563*59599516SKenneth E. Jansen & eps_str,afilter,spflag) 564*59599516SKenneth E. Jansen use ramg_data 565*59599516SKenneth E. Jansen 566*59599516SKenneth E. Jansen include "common.h" 567*59599516SKenneth E. Jansen include "mpif.h" 568*59599516SKenneth E. Jansen include "auxmpi.h" 569*59599516SKenneth E. Jansen 570*59599516SKenneth E. Jansen ! parameters 571*59599516SKenneth E. Jansen integer,intent(in) :: anshg,annz 572*59599516SKenneth E. Jansen integer,intent(inout),dimension(anshg) :: amg_CF 573*59599516SKenneth E. Jansen integer,intent(in),dimension(anshg+1) :: acolm 574*59599516SKenneth E. Jansen integer,intent(in),dimension(annz) :: arowp 575*59599516SKenneth E. Jansen integer,intent(inout),dimension(annz) :: amg_S 576*59599516SKenneth E. Jansen real(kind=8),intent(in),dimension(annz) :: alhs 577*59599516SKenneth E. Jansen integer,intent(in),dimension(anshg) :: afmap 578*59599516SKenneth E. Jansen integer,intent(in),dimension(nlwork) :: ilwork 579*59599516SKenneth E. Jansen integer,intent(in),dimension(nshg) :: iBC,iper 580*59599516SKenneth E. Jansen real(kind=8),intent(in),dimension(nshg,ndofBC) :: BC 581*59599516SKenneth E. Jansen 582*59599516SKenneth E. Jansen real(kind=8) :: eps_str 583*59599516SKenneth E. Jansen integer,intent(in) :: afilter,spflag 584*59599516SKenneth E. Jansen 585*59599516SKenneth E. Jansen ! afilter: indicating which subset of afmap for coarsening 586*59599516SKenneth E. Jansen ! -1 for self 587*59599516SKenneth E. Jansen ! spflag: aggressive or not 588*59599516SKenneth E. Jansen 589*59599516SKenneth E. Jansen integer :: i,j,k,n,m 590*59599516SKenneth E. Jansen integer,dimension(anshg) :: aheap,ainvheap 591*59599516SKenneth E. Jansen real(kind=8) :: Lmax 592*59599516SKenneth E. Jansen real(kind=8),dimension(anshg) :: amg_L 593*59599516SKenneth E. Jansen real(kind=8),dimension(anshg) :: rowmax,prowmax 594*59599516SKenneth E. Jansen real(kind=8) :: MSCALE,LSCALE,deltal 595*59599516SKenneth E. Jansen integer :: flagS,nheaps,cfilter 596*59599516SKenneth E. Jansen ! setup S, S^T matrix in amg_S 597*59599516SKenneth E. Jansen ! after this, S(i,j) = 1,3 : S 598*59599516SKenneth E. Jansen ! S(i,j) = 2,3 : S^T 599*59599516SKenneth E. Jansen 600*59599516SKenneth E. Jansen integer,allocatable,dimension(:) :: oneck 601*59599516SKenneth E. Jansen 602*59599516SKenneth E. Jansen !amg_S = 0 603*59599516SKenneth E. Jansen 604*59599516SKenneth E. Jansen allocate(oneck(numpe+1)) 605*59599516SKenneth E. Jansen oneck = 0 606*59599516SKenneth E. Jansen 607*59599516SKenneth E. Jansen LSCALE = 0.005 608*59599516SKenneth E. Jansen MSCALE = 0.1*LSCALE/anshg 609*59599516SKenneth E. Jansen 610*59599516SKenneth E. Jansen do i=1,anshg 611*59599516SKenneth E. Jansen cfilter = afmap(i) ! each row only deal with its own group 612*59599516SKenneth E. Jansen amg_CF(i) = 0 613*59599516SKenneth E. Jansen amg_L(i) = 0 614*59599516SKenneth E. Jansen rowmax(i) = 1E+10 615*59599516SKenneth E. Jansen prowmax(i) = -1e+10 616*59599516SKenneth E. Jansen do j=acolm(i)+1,acolm(i+1)-1 617*59599516SKenneth E. Jansen k = arowp(j) 618*59599516SKenneth E. Jansen if ((cfilter.eq.afmap(k)).and.(alhs(j).lt.rowmax(i))) then 619*59599516SKenneth E. Jansen rowmax(i) = alhs(j) 620*59599516SKenneth E. Jansen end if 621*59599516SKenneth E. Jansen if ((cfilter.eq.afmap(k)).and.(alhs(j).gt.prowmax(i))) then 622*59599516SKenneth E. Jansen prowmax(i) = alhs(j) 623*59599516SKenneth E. Jansen end if 624*59599516SKenneth E. Jansen enddo 625*59599516SKenneth E. Jansen rowmax(i) = eps_str*rowmax(i) 626*59599516SKenneth E. Jansen prowmax(i) = eps_str*prowmax(i) 627*59599516SKenneth E. Jansen ! if (anshg.lt.1000) then 628*59599516SKenneth E. Jansen !write(*,"((I5)(3E14.5))")i,rowmax(i),alhs(acolm(i)),prowmax(i) 629*59599516SKenneth E. Jansen ! endif 630*59599516SKenneth E. Jansen enddo 631*59599516SKenneth E. Jansen do i=1,anshg 632*59599516SKenneth E. Jansen cfilter = afmap(i) 633*59599516SKenneth E. Jansen p = iabs(cfilter) 634*59599516SKenneth E. Jansen oneck(p) = oneck(p)+1 635*59599516SKenneth E. Jansen do j=acolm(i)+1,acolm(i+1)-1 636*59599516SKenneth E. Jansen k = arowp(j) 637*59599516SKenneth E. Jansen if (cfilter.eq.afmap(k)) then ! same subset 638*59599516SKenneth E. Jansen if (alhs(j).lt.0) then ! negative entries 639*59599516SKenneth E. Jansen if (alhs(j) .lt. rowmax(i)) then 640*59599516SKenneth E. Jansen amg_S(j) = amg_S(j) + 1 641*59599516SKenneth E. Jansen end if 642*59599516SKenneth E. Jansen if (alhs(j) .lt. rowmax(k)) then 643*59599516SKenneth E. Jansen amg_S(j) = amg_S(j) + 2 644*59599516SKenneth E. Jansen end if 645*59599516SKenneth E. Jansen else ! positive entries 646*59599516SKenneth E. Jansen IF (.FALSE.) THEN 647*59599516SKenneth E. Jansen if (alhs(j) .gt. prowmax(i)) then 648*59599516SKenneth E. Jansen amg_S(j) = amg_S(j) + 1 649*59599516SKenneth E. Jansen end if 650*59599516SKenneth E. Jansen if (alhs(j) .gt. prowmax(k)) then 651*59599516SKenneth E. Jansen amg_S(j) = amg_S(j) + 2 652*59599516SKenneth E. Jansen end if 653*59599516SKenneth E. Jansen ENDIF 654*59599516SKenneth E. Jansen endif ! if negative or positive 655*59599516SKenneth E. Jansen endif 656*59599516SKenneth E. Jansen enddo 657*59599516SKenneth E. Jansen enddo 658*59599516SKenneth E. Jansen ! mark isolated unknowns "coarse", S^T=0, 659*59599516SKenneth E. Jansen ! keep territory which should not be coarsened "coarse" 660*59599516SKenneth E. Jansen ! keep slave coarse temporarily 661*59599516SKenneth E. Jansen do i=1,anshg 662*59599516SKenneth E. Jansen cfilter = afmap(i) 663*59599516SKenneth E. Jansen flagS = 0 664*59599516SKenneth E. Jansen do j=acolm(i),acolm(i+1)-1 665*59599516SKenneth E. Jansen k = arowp(j) 666*59599516SKenneth E. Jansen if ((amg_S(j).ne.0).and.(afmap(k).eq.cfilter)) then 667*59599516SKenneth E. Jansen flagS = 1 668*59599516SKenneth E. Jansen exit 669*59599516SKenneth E. Jansen end if 670*59599516SKenneth E. Jansen enddo 671*59599516SKenneth E. Jansen if ( flagS.eq.0) then 672*59599516SKenneth E. Jansen p = iabs(cfilter) 673*59599516SKenneth E. Jansen oneck(p) = oneck(p)-1 674*59599516SKenneth E. Jansen! if (oneck(p).gt.0) then 675*59599516SKenneth E. Jansen if (.false.) then 676*59599516SKenneth E. Jansen amg_CF(i) = 2 ! mark fine ! NO, should mark isolated coarse 677*59599516SKenneth E. Jansen else 678*59599516SKenneth E. Jansen amg_CF(i) = 1 ! last coarse ! everybody coarse 679*59599516SKenneth E. Jansen endif 680*59599516SKenneth E. Jansen end if 681*59599516SKenneth E. Jansen enddo 682*59599516SKenneth E. Jansen 683*59599516SKenneth E. Jansen k = 0 684*59599516SKenneth E. Jansen do i=1,anshg 685*59599516SKenneth E. Jansen if (amg_CF(i).eq.2) then 686*59599516SKenneth E. Jansen k = k+1 687*59599516SKenneth E. Jansen endif 688*59599516SKenneth E. Jansen enddo 689*59599516SKenneth E. Jansen if (k.eq.anshg) then 690*59599516SKenneth E. Jansen write(*,*)'mcheck coarsening error here' 691*59599516SKenneth E. Jansen stop 692*59599516SKenneth E. Jansen endif 693*59599516SKenneth E. Jansen ! setup initial lamda value 694*59599516SKenneth E. Jansen Lmax = -1.0e+6 ! Lmax stores max value of lambda, m points to it 695*59599516SKenneth E. Jansen do i=1,anshg 696*59599516SKenneth E. Jansen cfilter = afmap(i) 697*59599516SKenneth E. Jansen if (amg_CF(i).eq.0) then 698*59599516SKenneth E. Jansen ! unassigned with in the filter 699*59599516SKenneth E. Jansen amg_L(i) = i*MSCALE+iabs(cfilter) 700*59599516SKenneth E. Jansen do j=acolm(i),acolm(i+1)-1 701*59599516SKenneth E. Jansen k = arowp(j) 702*59599516SKenneth E. Jansen if ((afmap(k).eq.cfilter).and.(amg_S(j).ge.2)) then ! in S^T 703*59599516SKenneth E. Jansen deltal = 0 704*59599516SKenneth E. Jansen if (amg_CF(k).eq.0) then ! undecided 705*59599516SKenneth E. Jansen deltal = LSCALE 706*59599516SKenneth E. Jansen else if (amg_CF(k).eq.2) then ! free 707*59599516SKenneth E. Jansen deltal = 2*LSCALE 708*59599516SKenneth E. Jansen end if!filter 709*59599516SKenneth E. Jansen if (alhs(j).gt.0) deltal=-deltal 710*59599516SKenneth E. Jansen amg_L(i) = amg_L(i) + deltal 711*59599516SKenneth E. Jansen 712*59599516SKenneth E. Jansen !if (alhs(j).gt.0) then 713*59599516SKenneth E. Jansen ! write(*,*)'hooh: ',alhs(j) 714*59599516SKenneth E. Jansen !endif 715*59599516SKenneth E. Jansen ! this is to seperate nodes in each section 716*59599516SKenneth E. Jansen ! in the heap. e.g. 0-1000 for neighbour with proc 0, 717*59599516SKenneth E. Jansen ! 2000-3000 for neighbour with proc 1... 718*59599516SKenneth E. Jansen end if 719*59599516SKenneth E. Jansen enddo 720*59599516SKenneth E. Jansen if (amg_L(i).gt.Lmax) then 721*59599516SKenneth E. Jansen Lmax = amg_L(i) 722*59599516SKenneth E. Jansen m = i 723*59599516SKenneth E. Jansen end if 724*59599516SKenneth E. Jansen end if 725*59599516SKenneth E. Jansen enddo 726*59599516SKenneth E. Jansen ! aLoc: heap, amg_Fn: invheap 727*59599516SKenneth E. Jansen nheaps = anshg 728*59599516SKenneth E. Jansen call ramg_initheap(aheap,ainvheap,amg_L,nheaps,anshg) 729*59599516SKenneth E. Jansen !write(*,*)oneck 730*59599516SKenneth E. Jansen ! setup coarse/fine grid 731*59599516SKenneth E. Jansen do while (nheaps.gt.0) 732*59599516SKenneth E. Jansen m = aheap(1)+1 733*59599516SKenneth E. Jansen if (amg_CF(m).ne.0) then 734*59599516SKenneth E. Jansen amg_L(m) = 0 735*59599516SKenneth E. Jansen call ramg_popheap(aheap,ainvheap,amg_L,nheaps, 736*59599516SKenneth E. Jansen & ainvheap(m),anshg) 737*59599516SKenneth E. Jansen cycle 738*59599516SKenneth E. Jansen endif 739*59599516SKenneth E. Jansen Lmax = amg_L(m)-iabs(afmap(m))-m*MSCALE ! reuse Lmax 740*59599516SKenneth E. Jansen if (Lmax.lt.LSCALE) then 741*59599516SKenneth E. Jansen k = iabs(afmap(m)) 742*59599516SKenneth E. Jansen if (oneck(k).eq.1) then 743*59599516SKenneth E. Jansen amg_CF(m) = 1 744*59599516SKenneth E. Jansen else 745*59599516SKenneth E. Jansen amg_CF(m) = 2 746*59599516SKenneth E. Jansen endif 747*59599516SKenneth E. Jansen oneck(iabs(afmap(m)))=oneck(iabs(afmap(m)))-1 748*59599516SKenneth E. Jansen 749*59599516SKenneth E. Jansen amg_L(m) = 0!afmap(m)+m*MSCALE 750*59599516SKenneth E. Jansen call ramg_popheap(aheap,ainvheap,amg_L,nheaps, 751*59599516SKenneth E. Jansen & ainvheap(m),anshg) 752*59599516SKenneth E. Jansen cycle 753*59599516SKenneth E. Jansen end if 754*59599516SKenneth E. Jansen ! set coarse grid 755*59599516SKenneth E. Jansen amg_CF(m) = 1 ! mark coarse 756*59599516SKenneth E. Jansen amg_L(m) = 0!afmap(m)+m*MSCALE!0 !floor(amg_L(m)) 757*59599516SKenneth E. Jansen call ramg_popheap(aheap,ainvheap,amg_L,nheaps,ainvheap(m), 758*59599516SKenneth E. Jansen & anshg) 759*59599516SKenneth E. Jansen ! set fine grid 760*59599516SKenneth E. Jansen do j=acolm(m),acolm(m+1)-1 761*59599516SKenneth E. Jansen k = arowp(j) 762*59599516SKenneth E. Jansen if (afmap(k).eq.afmap(m)) then 763*59599516SKenneth E. Jansen if (amg_S(j).ge.2) then ! in m's S^T if !B 764*59599516SKenneth E. Jansen if (amg_CF(k).eq.0) then !not defined yet !if A 765*59599516SKenneth E. Jansen ! update flag 766*59599516SKenneth E. Jansen amg_CF(k) = 2 ! mark fine 767*59599516SKenneth E. Jansen amg_L(k) = 0!afmap(k)+k*MSCALE!0 !floor(amg_L(k)) 768*59599516SKenneth E. Jansen call ramg_popheap(aheap,ainvheap,amg_L,nheaps,ainvheap(k), 769*59599516SKenneth E. Jansen & anshg) 770*59599516SKenneth E. Jansen ! update lambda in k's S 771*59599516SKenneth E. Jansen do i = acolm(k),acolm(k+1)-1 772*59599516SKenneth E. Jansen n = arowp(i) 773*59599516SKenneth E. Jansen if (((amg_S(i).eq.1).or.(amg_S(i).eq.3)).and. 774*59599516SKenneth E. Jansen & (amg_CF(n).eq.0)) then 775*59599516SKenneth E. Jansen ! in k's S , U==>F 776*59599516SKenneth E. Jansen if (alhs(i).le.0) then ! negative 777*59599516SKenneth E. Jansen amg_L(n) = amg_L(n) + LSCALE 778*59599516SKenneth E. Jansen else ! positive 779*59599516SKenneth E. Jansen amg_L(n) = amg_L(n) - LSCALE 780*59599516SKenneth E. Jansen endif 781*59599516SKenneth E. Jansen call ramg_adjheap(aheap,ainvheap,amg_L,nheaps,ainvheap(n), 782*59599516SKenneth E. Jansen & anshg) 783*59599516SKenneth E. Jansen end if 784*59599516SKenneth E. Jansen enddo 785*59599516SKenneth E. Jansen end if ! if A 786*59599516SKenneth E. Jansen end if ! if B 787*59599516SKenneth E. Jansen if (mod(amg_S(j),2).eq.1) then !if B2 788*59599516SKenneth E. Jansen if (amg_CF(k).eq.0) then 789*59599516SKenneth E. Jansen if (alhs(j).le.0) then 790*59599516SKenneth E. Jansen amg_L(k) = amg_L(k) - LSCALE 791*59599516SKenneth E. Jansen else 792*59599516SKenneth E. Jansen amg_L(k) = amg_L(k) + LSCALE 793*59599516SKenneth E. Jansen endif 794*59599516SKenneth E. Jansen call ramg_adjheap(aheap,ainvheap,amg_L,nheaps,ainvheap(k), 795*59599516SKenneth E. Jansen & anshg) 796*59599516SKenneth E. Jansen end if 797*59599516SKenneth E. Jansen end if ! if B2 798*59599516SKenneth E. Jansen end if ! subset 799*59599516SKenneth E. Jansen enddo 800*59599516SKenneth E. Jansen enddo 801*59599516SKenneth E. Jansen k = 0 802*59599516SKenneth E. Jansen do i=1,anshg 803*59599516SKenneth E. Jansen if (amg_CF(i).eq.2) then 804*59599516SKenneth E. Jansen k = k+1 805*59599516SKenneth E. Jansen endif 806*59599516SKenneth E. Jansen enddo 807*59599516SKenneth E. Jansen if (k.eq.anshg) then 808*59599516SKenneth E. Jansen write(*,*)'mcheck coarsening error here,2' 809*59599516SKenneth E. Jansen stop 810*59599516SKenneth E. Jansen endif 811*59599516SKenneth E. Jansen !write(*,*)oneck 812*59599516SKenneth E. Jansen 813*59599516SKenneth E. Jansen ! any U left 814*59599516SKenneth E. Jansen j = 0 815*59599516SKenneth E. Jansen do i = 1,anshg 816*59599516SKenneth E. Jansen if (amg_CF(i).eq.0) then 817*59599516SKenneth E. Jansen amg_CF(i) = 1 ! Mark every node coarse if isolated 818*59599516SKenneth E. Jansen! amg_CF(i) = 2 ! Mark every node fine if isolated 819*59599516SKenneth E. Jansen end if 820*59599516SKenneth E. Jansen if (amg_CF(i).eq.1) then 821*59599516SKenneth E. Jansen j = j+1 822*59599516SKenneth E. Jansen endif 823*59599516SKenneth E. Jansen enddo 824*59599516SKenneth E. Jansen !write(*,*)'mcheck rank2b, j=',myrank,j 825*59599516SKenneth E. Jansen if (.false.) then 826*59599516SKenneth E. Jansen k = 0 827*59599516SKenneth E. Jansen do i=1,anshg 828*59599516SKenneth E. Jansen if (amg_CF(i).eq.1) then 829*59599516SKenneth E. Jansen k = k+1 830*59599516SKenneth E. Jansen do j=acolm(i)+1,acolm(i+1)-1 831*59599516SKenneth E. Jansen m = arowp(j) 832*59599516SKenneth E. Jansen if (amg_CF(m).eq.1) then ! two coarse connected 833*59599516SKenneth E. Jansen if (amg_S(j).ge.1) then 834*59599516SKenneth E. Jansen ! write(*,*)'mcheck err',alhs(j) 835*59599516SKenneth E. Jansen endif 836*59599516SKenneth E. Jansen endif 837*59599516SKenneth E. Jansen enddo 838*59599516SKenneth E. Jansen endif 839*59599516SKenneth E. Jansen enddo 840*59599516SKenneth E. Jansen if (k.eq.anshg) then 841*59599516SKenneth E. Jansen write(*,*)'mcheck coarsening error here,3,' 842*59599516SKenneth E. Jansen stop 843*59599516SKenneth E. Jansen endif 844*59599516SKenneth E. Jansen endif 845*59599516SKenneth E. Jansen !write(*,*)'mcheck end of cfsplit' 846*59599516SKenneth E. Jansen !call ramg_dump_i(amg_CF,anshg,1,'splitcf ') 847*59599516SKenneth E. Jansen deallocate(oneck) 848*59599516SKenneth E. Jansen 849*59599516SKenneth E. Jansen end subroutine !ramg_CFsplit 850*59599516SKenneth E. Jansen 851*59599516SKenneth E. Jansen subroutine ramg_update_cfmap(amg_CF,slevel) 852*59599516SKenneth E. Jansen use ramg_data 853*59599516SKenneth E. Jansen integer,intent(in) :: slevel 854*59599516SKenneth E. Jansen integer,intent(in),dimension(amg_nshg(slevel)) :: amg_CF 855*59599516SKenneth E. Jansen integer :: i,j,p 856*59599516SKenneth E. Jansen integer,dimension(amg_nshg(slevel)) :: revmap 857*59599516SKenneth E. Jansen 858*59599516SKenneth E. Jansen revmap = 0 859*59599516SKenneth E. Jansen j = 1 860*59599516SKenneth E. Jansen do i=1,amg_nshg(1) 861*59599516SKenneth E. Jansen if (amg_cfmap(i).eq.slevel) then 862*59599516SKenneth E. Jansen revmap(j) = i 863*59599516SKenneth E. Jansen j = j+1 864*59599516SKenneth E. Jansen end if 865*59599516SKenneth E. Jansen enddo 866*59599516SKenneth E. Jansen do i=1,j-1 867*59599516SKenneth E. Jansen if (amg_CF(i).eq.1) then 868*59599516SKenneth E. Jansen amg_cfmap(revmap(i)) = amg_cfmap(revmap(i)) + 1 869*59599516SKenneth E. Jansen end if 870*59599516SKenneth E. Jansen enddo 871*59599516SKenneth E. Jansen 872*59599516SKenneth E. Jansen end subroutine ! ramg_update_cfmap 873*59599516SKenneth E. Jansen 874*59599516SKenneth E. Jansen subroutine ramg_readin_cfmap(amg_CF,slevel) 875*59599516SKenneth E. Jansen use ramg_data 876*59599516SKenneth E. Jansen integer,intent(in) :: slevel 877*59599516SKenneth E. Jansen integer,intent(inout),dimension(amg_nshg(slevel)) :: amg_CF 878*59599516SKenneth E. Jansen integer :: i,j,p 879*59599516SKenneth E. Jansen 880*59599516SKenneth E. Jansen j = 1 881*59599516SKenneth E. Jansen do i=1,amg_nshg(1) 882*59599516SKenneth E. Jansen if (amg_cfmap(i).eq.slevel) then 883*59599516SKenneth E. Jansen amg_CF(j) = 2 ! fine 884*59599516SKenneth E. Jansen j = j + 1 885*59599516SKenneth E. Jansen else if (amg_cfmap(i).eq.(slevel+1)) then 886*59599516SKenneth E. Jansen amg_CF(j) = 1 ! coarse 887*59599516SKenneth E. Jansen j = j + 1 888*59599516SKenneth E. Jansen endif 889*59599516SKenneth E. Jansen enddo 890*59599516SKenneth E. Jansen 891*59599516SKenneth E. Jansen end subroutine ! ramg_readin_cfmap 892