xref: /phasta/phSolver/AMG/ramg_coarse.f (revision 595995161822a203c8467e0e4a253d7bd7d6df32)
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