xref: /phasta/phSolver/AMG/ramg_paratools.f (revision 595995161822a203c8467e0e4a253d7bd7d6df32)
1*59599516SKenneth E. Jansen
2*59599516SKenneth E. Jansen!**************************************************************
3*59599516SKenneth E. Jansen!      ramg_global_PPE
4*59599516SKenneth E. Jansen!       Make lhsP global complete
5*59599516SKenneth E. Jansen!**************************************************************
6*59599516SKenneth E. Jansen
7*59599516SKenneth E. Jansen      subroutine ramg_global_lhs(
8*59599516SKenneth E. Jansen     &               acolm,arowp,alhsP,annz_tot,
9*59599516SKenneth E. Jansen     &               lhsGPcolm,lhsGProwp,lhsGP,
10*59599516SKenneth E. Jansen     &               redun,
11*59599516SKenneth E. Jansen     &               ilwork,BC,iBC,iper)
12*59599516SKenneth E. Jansen      use ramg_data
13*59599516SKenneth E. Jansen      include "common.h"
14*59599516SKenneth E. Jansen      include "mpif.h"
15*59599516SKenneth E. Jansen      include "auxmpi.h"
16*59599516SKenneth E. Jansen
17*59599516SKenneth E. Jansen      integer,intent(in)            :: annz_tot
18*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg+1)            :: acolm
19*59599516SKenneth E. Jansen      integer,intent(in),dimension(annz_tot)           :: arowp
20*59599516SKenneth E. Jansen      integer,intent(in)                              :: redun
21*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(redun,annz_tot)    :: alhsP
22*59599516SKenneth E. Jansen!      real(kind=8),dimension(:,:),allocatable          :: lhsGP
23*59599516SKenneth E. Jansen!      integer,dimension(:),allocatable                 :: lhsGProwp
24*59599516SKenneth E. Jansen!      integer,dimension(:),allocatable                 :: lhsGPcolm
25*59599516SKenneth E. Jansen      type(r2d),intent(inout) :: lhsGP
26*59599516SKenneth E. Jansen      type(i1d),intent(inout) :: lhsGProwp,lhsGPcolm
27*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)            :: ilwork
28*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)              :: iBC,iper
29*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)  :: BC
30*59599516SKenneth E. Jansen
31*59599516SKenneth E. Jansen      integer           :: numtask,i,j,k,m,p,ki,kj,krowp,ierr
32*59599516SKenneth E. Jansen      integer           :: gi,gj,gk
33*59599516SKenneth E. Jansen      integer           :: itag,iacc,iother,numseg,isgbeg,itkbeg
34*59599516SKenneth E. Jansen      integer    :: stat(MPI_STATUS_SIZE,redun*numpe),req(redun*numpe)
35*59599516SKenneth E. Jansen      integer           :: mcheck
36*59599516SKenneth E. Jansen
37*59599516SKenneth E. Jansen      real(kind=8) :: swaptemp(redun)
38*59599516SKenneth E. Jansen
39*59599516SKenneth E. Jansen      character fname*10
40*59599516SKenneth E. Jansen
41*59599516SKenneth E. Jansen      ! temp variables, used for communication
42*59599516SKenneth E. Jansen
43*59599516SKenneth E. Jansen      ! each task has a set of storage rooms for the submatrix
44*59599516SKenneth E. Jansen      ! to communicate
45*59599516SKenneth E. Jansen
46*59599516SKenneth E. Jansen      integer,dimension(nshg) :: tmp_rowmap,tmp_revrmap
47*59599516SKenneth E. Jansen      real(kind=8),dimension(redun,nshg) :: tmp_rmtx
48*59599516SKenneth E. Jansen
49*59599516SKenneth E. Jansen      integer,dimension(nshg) :: Pflag
50*59599516SKenneth E. Jansen      integer,dimension(nshg+1) :: Pcolm
51*59599516SKenneth E. Jansen      type(i2dd) :: Prowp
52*59599516SKenneth E. Jansen      type(r12dd) :: Pmtx
53*59599516SKenneth E. Jansen      integer :: rownnz
54*59599516SKenneth E. Jansen
55*59599516SKenneth E. Jansen
56*59599516SKenneth E. Jansen      if (numpe .le. 1) then
57*59599516SKenneth E. Jansen          allocate(lhsGP%p(redun,annz_tot),stat=ierr)
58*59599516SKenneth E. Jansen          allocate(lhsGProwp%p(annz_tot))
59*59599516SKenneth E. Jansen          allocate(lhsGPcolm%p(nshg+1))
60*59599516SKenneth E. Jansen          lhsGP%p(:,:) = alhsP(:,:)
61*59599516SKenneth E. Jansen          lhsGProwp%p(:) = arowp(:)
62*59599516SKenneth E. Jansen          lhsGPcolm%p(:) = acolm(:)
63*59599516SKenneth E. Jansen          return
64*59599516SKenneth E. Jansen      end if
65*59599516SKenneth E. Jansen
66*59599516SKenneth E. Jansen      numtask = ilwork(1)
67*59599516SKenneth E. Jansen      m = 0
68*59599516SKenneth E. Jansen      itkbeg = 1
69*59599516SKenneth E. Jansen
70*59599516SKenneth E. Jansen      revmap = 0
71*59599516SKenneth E. Jansen
72*59599516SKenneth E. Jansen      allocate(sub_map%pp(numtask))
73*59599516SKenneth E. Jansen      allocate(sub_revmap%pp(numtask))
74*59599516SKenneth E. Jansen      allocate(sub_colm%pp(numtask))
75*59599516SKenneth E. Jansen      allocate(sub_colm2%pp(numtask))
76*59599516SKenneth E. Jansen      allocate(sub_rowp%pp(numtask))
77*59599516SKenneth E. Jansen      allocate(sub_rowp2%pp(numtask))
78*59599516SKenneth E. Jansen      allocate(sub_rowpmap%pp(numtask))
79*59599516SKenneth E. Jansen      allocate(sub_mtx%pp(numtask))
80*59599516SKenneth E. Jansen      allocate(sub_mtx2%pp(numtask))
81*59599516SKenneth E. Jansen      allocate(sub_nnz%p(numtask))
82*59599516SKenneth E. Jansen      allocate(sub_nnz2%p(numtask))
83*59599516SKenneth E. Jansen      allocate(sub_nshg%p(numtask))
84*59599516SKenneth E. Jansen
85*59599516SKenneth E. Jansen      ! submatrix : colm
86*59599516SKenneth E. Jansen      do i=1,numtask
87*59599516SKenneth E. Jansen
88*59599516SKenneth E. Jansen         ! Beginning of each task
89*59599516SKenneth E. Jansen         m = m+1
90*59599516SKenneth E. Jansen         ! Task head information, ref commu.f
91*59599516SKenneth E. Jansen         itag = ilwork(itkbeg+1)
92*59599516SKenneth E. Jansen         iacc = ilwork(itkbeg+2)
93*59599516SKenneth E. Jansen         iother = ilwork(itkbeg+3)
94*59599516SKenneth E. Jansen         numseg = ilwork(itkbeg+4)
95*59599516SKenneth E. Jansen         isgbeg = ilwork(itkbeg+5)
96*59599516SKenneth E. Jansen
97*59599516SKenneth E. Jansen         sub_nshg%p(i) = numseg
98*59599516SKenneth E. Jansen
99*59599516SKenneth E. Jansen         allocate(sub_map%pp(i)%p(numseg))
100*59599516SKenneth E. Jansen         allocate(sub_revmap%pp(i)%p(nshg))
101*59599516SKenneth E. Jansen
102*59599516SKenneth E. Jansen         sub_map%pp(i)%p = 0
103*59599516SKenneth E. Jansen         sub_revmap%pp(i)%p = 0
104*59599516SKenneth E. Jansen
105*59599516SKenneth E. Jansen         ! prepare vector mapping
106*59599516SKenneth E. Jansen         do j=1,numseg
107*59599516SKenneth E. Jansen            k = ilwork(itkbeg+3+2*j) ! row idx
108*59599516SKenneth E. Jansen            sub_map%pp(i)%p(j) = k
109*59599516SKenneth E. Jansen            sub_revmap%pp(i)%p(k) = j
110*59599516SKenneth E. Jansen!            if ((myrank.eq.1).and.(iother.eq.3)) then
111*59599516SKenneth E. Jansen!            write(*,*)'mcheck:',myrank,iother,j,k,ncorp_map(k)
112*59599516SKenneth E. Jansen!            endif
113*59599516SKenneth E. Jansen         enddo
114*59599516SKenneth E. Jansen
115*59599516SKenneth E. Jansen         allocate(sub_colm%pp(i)%p(numseg+1))
116*59599516SKenneth E. Jansen         allocate(sub_colm2%pp(i)%p(numseg+1))
117*59599516SKenneth E. Jansen
118*59599516SKenneth E. Jansen         ! prepare matrix mapping, sub matrix colm
119*59599516SKenneth E. Jansen         sub_nnz%p(i) = 0
120*59599516SKenneth E. Jansen         do j=1,numseg
121*59599516SKenneth E. Jansen            sub_colm%pp(i)%p(j) = sub_nnz%p(i) + 1
122*59599516SKenneth E. Jansen            ki = sub_map%pp(i)%p(j)
123*59599516SKenneth E. Jansen            do kj = acolm(ki),acolm(ki+1)-1
124*59599516SKenneth E. Jansen               krowp = arowp(kj)
125*59599516SKenneth E. Jansen               if (sub_revmap%pp(i)%p(krowp).ne.0) then
126*59599516SKenneth E. Jansen!      if ((ncorp_map(ki).eq.964)) then
127*59599516SKenneth E. Jansen!      if ((ncorp_map(krowp).eq.884)) then
128*59599516SKenneth E. Jansen!          write(*,*)'964/884 prepared in',myrank,i,iother
129*59599516SKenneth E. Jansen!      else
130*59599516SKenneth E. Jansen!          write(*,*)'line 964:',myrank,i,iother,ncorp_map(krowp)
131*59599516SKenneth E. Jansen!      endif
132*59599516SKenneth E. Jansen!      endif
133*59599516SKenneth E. Jansen                   sub_nnz%p(i) = sub_nnz%p(i) + 1
134*59599516SKenneth E. Jansen               end if
135*59599516SKenneth E. Jansen            enddo
136*59599516SKenneth E. Jansen            !write(*,*)'mcheck: ',myrank,j,sub_nnz
137*59599516SKenneth E. Jansen         enddo
138*59599516SKenneth E. Jansen         sub_colm%pp(i)%p(numseg+1) = sub_nnz%p(i) + 1
139*59599516SKenneth E. Jansen
140*59599516SKenneth E. Jansen         if (iacc.eq.0) then ! this task is a send, master
141*59599516SKenneth E. Jansen            call MPI_ISEND(sub_colm%pp(i)%p(1),numseg+1,MPI_INTEGER,
142*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
143*59599516SKenneth E. Jansen            call MPI_IRECV(sub_colm2%pp(i)%p(1),numseg+1,MPI_INTEGER,
144*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
145*59599516SKenneth E. Jansen
146*59599516SKenneth E. Jansen         else if (iacc.eq.1) then ! this task is a receive, slave
147*59599516SKenneth E. Jansen            call MPI_IRECV(sub_colm2%pp(i)%p(1),numseg+1,MPI_INTEGER,
148*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
149*59599516SKenneth E. Jansen            call MPI_ISEND(sub_colm%pp(i)%p(1),numseg+1,MPI_INTEGER,
150*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
151*59599516SKenneth E. Jansen
152*59599516SKenneth E. Jansen         end if
153*59599516SKenneth E. Jansen
154*59599516SKenneth E. Jansen         m = m + 1
155*59599516SKenneth E. Jansen
156*59599516SKenneth E. Jansen         ! Task end, next task
157*59599516SKenneth E. Jansen         itkbeg = itkbeg + 4 + 2*numseg
158*59599516SKenneth E. Jansen
159*59599516SKenneth E. Jansen      enddo
160*59599516SKenneth E. Jansen
161*59599516SKenneth E. Jansen      call MPI_WAITALL(m,req,stat,ierr)
162*59599516SKenneth E. Jansen
163*59599516SKenneth E. Jansen      do i=1,numtask
164*59599516SKenneth E. Jansen         sub_nnz2%p(i) = sub_colm2%pp(i)%p(sub_nshg%p(i)+1)-1
165*59599516SKenneth E. Jansen      enddo
166*59599516SKenneth E. Jansen
167*59599516SKenneth E. Jansen      ! sub matrix : rowp,mtx
168*59599516SKenneth E. Jansen      m = 0
169*59599516SKenneth E. Jansen      itkbeg = 1
170*59599516SKenneth E. Jansen      do i=1,numtask
171*59599516SKenneth E. Jansen
172*59599516SKenneth E. Jansen         ! Beginning of each task
173*59599516SKenneth E. Jansen         m = m+1
174*59599516SKenneth E. Jansen         ! Task head information, ref commu.f
175*59599516SKenneth E. Jansen         itag = ilwork(itkbeg+1)
176*59599516SKenneth E. Jansen         iacc = ilwork(itkbeg+2)
177*59599516SKenneth E. Jansen         iother = ilwork(itkbeg+3)
178*59599516SKenneth E. Jansen         numseg = ilwork(itkbeg+4)
179*59599516SKenneth E. Jansen         isgbeg = ilwork(itkbeg+5)
180*59599516SKenneth E. Jansen
181*59599516SKenneth E. Jansen         allocate(sub_rowp%pp(i)%p(sub_nnz%p(i)))
182*59599516SKenneth E. Jansen         allocate(sub_rowp2%pp(i)%p(sub_nnz2%p(i)))
183*59599516SKenneth E. Jansen         allocate(sub_rowpmap%pp(i)%p(sub_nnz%p(i)))
184*59599516SKenneth E. Jansen         allocate(sub_mtx%pp(i)%p(redun,sub_nnz%p(i)))
185*59599516SKenneth E. Jansen         allocate(sub_mtx2%pp(i)%p(redun,sub_nnz2%p(i)))
186*59599516SKenneth E. Jansen
187*59599516SKenneth E. Jansen         ! prepare matrix mapping, sub matrix rowp
188*59599516SKenneth E. Jansen         k = 0
189*59599516SKenneth E. Jansen         do j=1,numseg
190*59599516SKenneth E. Jansen            ki = sub_map%pp(i)%p(j)
191*59599516SKenneth E. Jansen            do kj = acolm(ki),acolm(ki+1)-1
192*59599516SKenneth E. Jansen               krowp = arowp(kj)
193*59599516SKenneth E. Jansen               if (sub_revmap%pp(i)%p(krowp).ne.0) then
194*59599516SKenneth E. Jansen                   k = k + 1
195*59599516SKenneth E. Jansen                   sub_rowp%pp(i)%p(k) = sub_revmap%pp(i)%p(krowp)
196*59599516SKenneth E. Jansen                   sub_rowpmap%pp(i)%p(k) = kj
197*59599516SKenneth E. Jansen                   do p=1,redun
198*59599516SKenneth E. Jansen                      sub_mtx%pp(i)%p(p,k) = alhsP(p,kj)
199*59599516SKenneth E. Jansen                   enddo
200*59599516SKenneth E. Jansen               end if
201*59599516SKenneth E. Jansen            enddo
202*59599516SKenneth E. Jansen         enddo
203*59599516SKenneth E. Jansen
204*59599516SKenneth E. Jansen         if (iacc.eq.0) then ! this task is a send, master
205*59599516SKenneth E. Jansen        call MPI_ISEND(sub_rowp%pp(i)%p(1),sub_nnz%p(i),MPI_INTEGER,
206*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
207*59599516SKenneth E. Jansen       call MPI_IRECV(sub_rowp2%pp(i)%p(1),sub_nnz2%p(i),MPI_INTEGER,
208*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
209*59599516SKenneth E. Jansen
210*59599516SKenneth E. Jansen         else if (iacc.eq.1) then ! this task is a receive, slave
211*59599516SKenneth E. Jansen       call MPI_IRECV(sub_rowp2%pp(i)%p(1),sub_nnz2%p(i),MPI_INTEGER,
212*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
213*59599516SKenneth E. Jansen        call MPI_ISEND(sub_rowp%pp(i)%p(1),sub_nnz%p(i),MPI_INTEGER,
214*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
215*59599516SKenneth E. Jansen         end if
216*59599516SKenneth E. Jansen         m = m + 2
217*59599516SKenneth E. Jansen         if (iacc.eq.0) then ! this task is a send, master
218*59599516SKenneth E. Jansen        call MPI_ISEND(sub_mtx%pp(i)%p(1,1),redun*sub_nnz%p(i),
219*59599516SKenneth E. Jansen     &            MPI_DOUBLE_PRECISION,
220*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
221*59599516SKenneth E. Jansen       call MPI_IRECV(sub_mtx2%pp(i)%p(1,1),redun*sub_nnz2%p(i),
222*59599516SKenneth E. Jansen     &            MPI_DOUBLE_PRECISION,
223*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
224*59599516SKenneth E. Jansen
225*59599516SKenneth E. Jansen         else if (iacc.eq.1) then ! this task is a receive, slave
226*59599516SKenneth E. Jansen        call MPI_IRECV(sub_mtx2%pp(i)%p(1,1),redun*sub_nnz2%p(i),
227*59599516SKenneth E. Jansen     &            MPI_DOUBLE_PRECISION,
228*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m),ierr)
229*59599516SKenneth E. Jansen        call MPI_ISEND(sub_mtx%pp(i)%p(1,1),redun*sub_nnz%p(i),
230*59599516SKenneth E. Jansen     &            MPI_DOUBLE_PRECISION,
231*59599516SKenneth E. Jansen     &            iother,itag,MPI_COMM_WORLD,req(m+1),ierr)
232*59599516SKenneth E. Jansen         end if
233*59599516SKenneth E. Jansen
234*59599516SKenneth E. Jansen         m = m + 1
235*59599516SKenneth E. Jansen
236*59599516SKenneth E. Jansen         ! Task end, next task
237*59599516SKenneth E. Jansen         itkbeg = itkbeg + 4 + 2*numseg
238*59599516SKenneth E. Jansen
239*59599516SKenneth E. Jansen      enddo
240*59599516SKenneth E. Jansen
241*59599516SKenneth E. Jansen      call MPI_WAITALL(m,req,stat,ierr)
242*59599516SKenneth E. Jansen
243*59599516SKenneth E. Jansen      if (.false.) then
244*59599516SKenneth E. Jansen      ! dump some matrices for matlab
245*59599516SKenneth E. Jansen      do i=1,numtask
246*59599516SKenneth E. Jansen       write(fname,'((A4)(I1)(A5))')'subP',i,'     '
247*59599516SKenneth E. Jansen       !call ramg_dump_i(ncorp_map,nshg,1,'pam_corpmd')
248*59599516SKenneth E. Jansen!       call ramg_dump_matlab_map(sub_colm%pp(i)%p,sub_rowp%pp(i)%p,
249*59599516SKenneth E. Jansen!     &      sub_mtx%pp(i)%p,sub_nshg%p(i),sub_nnz%p(i),4,
250*59599516SKenneth E. Jansen!     &      sub_map%pp(i)%p,fname)
251*59599516SKenneth E. Jansen!      enddo
252*59599516SKenneth E. Jansen!      do i=1,numtask
253*59599516SKenneth E. Jansen!       write(fname,'((A5)(I1)(A4))')'subPs',i,'    '
254*59599516SKenneth E. Jansen!       !call ramg_dump_i(ncorp_map,nshg,1,'pam_corpmd')
255*59599516SKenneth E. Jansen!       call ramg_dump_matlab_map(sub_colm2%pp(i)%p,sub_rowp2%pp(i)%p,
256*59599516SKenneth E. Jansen!     &      sub_mtx2%pp(i)%p,sub_nshg%p(i),sub_nnz2%p(i),4,
257*59599516SKenneth E. Jansen!     &      sub_map%pp(i)%p,fname)
258*59599516SKenneth E. Jansen      enddo
259*59599516SKenneth E. Jansen      endif ! dump? no dump?
260*59599516SKenneth E. Jansen
261*59599516SKenneth E. Jansen!      call ramg_dump_matlab_map(acolm,arowp,alhsP,nshg,annz_tot,redun,
262*59599516SKenneth E. Jansen!     &     'locallhsPb')
263*59599516SKenneth E. Jansen
264*59599516SKenneth E. Jansen      ! merge with extra entries
265*59599516SKenneth E. Jansen
266*59599516SKenneth E. Jansen      Pflag = 0
267*59599516SKenneth E. Jansen      allocate(Prowp%pp(nshg))
268*59599516SKenneth E. Jansen      allocate(Pmtx%pp(nshg))
269*59599516SKenneth E. Jansen      Pcolm = 0
270*59599516SKenneth E. Jansen
271*59599516SKenneth E. Jansen      do i=1,numtask ! each task
272*59599516SKenneth E. Jansen         do j=1,sub_nshg%p(i) ! each line
273*59599516SKenneth E. Jansen
274*59599516SKenneth E. Jansen            tmp_rowmap = 0
275*59599516SKenneth E. Jansen            tmp_revrmap = 0
276*59599516SKenneth E. Jansen            tmp_rmtx = 0
277*59599516SKenneth E. Jansen            rownnz = 0
278*59599516SKenneth E. Jansen
279*59599516SKenneth E. Jansen            ! Prepare
280*59599516SKenneth E. Jansen            ki = sub_map%pp(i)%p(j)
281*59599516SKenneth E. Jansen            if (Pflag(ki).eq.0) then ! a new line
282*59599516SKenneth E. Jansen                Pflag(ki) = 1
283*59599516SKenneth E. Jansen                do k=acolm(ki),acolm(ki+1)-1
284*59599516SKenneth E. Jansen                   kj = arowp(k)
285*59599516SKenneth E. Jansen                   tmp_rowmap(kj) = k-acolm(ki)+1
286*59599516SKenneth E. Jansen                   tmp_revrmap(k-acolm(ki)+1)=kj
287*59599516SKenneth E. Jansen                   tmp_rmtx(:,kj) = alhsP(:,k)
288*59599516SKenneth E. Jansen                enddo
289*59599516SKenneth E. Jansen                rownnz = rownnz+acolm(ki+1)-acolm(ki)
290*59599516SKenneth E. Jansen            else ! existing line
291*59599516SKenneth E. Jansen                ! expand sparse line to full line
292*59599516SKenneth E. Jansen                do k=1,Pcolm(ki)
293*59599516SKenneth E. Jansen                   kj = Prowp%pp(ki)%p(k)
294*59599516SKenneth E. Jansen                   tmp_rowmap(kj) = k
295*59599516SKenneth E. Jansen                   tmp_revrmap(k) = kj
296*59599516SKenneth E. Jansen                   tmp_rmtx(:,kj) = Pmtx%pp(ki)%p(:,k)
297*59599516SKenneth E. Jansen                enddo
298*59599516SKenneth E. Jansen                rownnz = rownnz+Pcolm(ki)
299*59599516SKenneth E. Jansen                deallocate(Prowp%pp(ki)%p)
300*59599516SKenneth E. Jansen                deallocate(Pmtx%pp(ki)%p)
301*59599516SKenneth E. Jansen            endif
302*59599516SKenneth E. Jansen
303*59599516SKenneth E. Jansen            ! Merge
304*59599516SKenneth E. Jansen            do ki = sub_colm2%pp(i)%p(j),sub_colm2%pp(i)%p(j+1)-1
305*59599516SKenneth E. Jansen            ! each entry in second mtx /slave
306*59599516SKenneth E. Jansen               krowp = sub_rowp2%pp(i)%p(ki)
307*59599516SKenneth E. Jansen               kj = sub_map%pp(i)%p(krowp)
308*59599516SKenneth E. Jansen               if (tmp_rowmap(kj).eq.0) then ! not yet occupied
309*59599516SKenneth E. Jansen               rownnz = rownnz+1
310*59599516SKenneth E. Jansen               tmp_rowmap(kj) = rownnz
311*59599516SKenneth E. Jansen               tmp_revrmap(rownnz) = kj
312*59599516SKenneth E. Jansen               endif
313*59599516SKenneth E. Jansen!         if ((ncorp_map(sub_map%pp(i)%p(j)).eq.964)) then
314*59599516SKenneth E. Jansen!         if ((ncorp_map(kj).eq.883)) then
315*59599516SKenneth E. Jansen!             write(*,*)'paramcheck',myrank,i,sub_mtx2%pp(i)%p(1,ki)
316*59599516SKenneth E. Jansen!         else
317*59599516SKenneth E. Jansen!             write(*,*)'paramcheck2',myrank,ncorp_map(kj)
318*59599516SKenneth E. Jansen!         endif
319*59599516SKenneth E. Jansen!         endif
320*59599516SKenneth E. Jansen              do p=1,redun
321*59599516SKenneth E. Jansen               tmp_rmtx(p,kj) = tmp_rmtx(p,kj)+sub_mtx2%pp(i)%p(p,ki)
322*59599516SKenneth E. Jansen               enddo
323*59599516SKenneth E. Jansen            enddo
324*59599516SKenneth E. Jansen
325*59599516SKenneth E. Jansen            ! Store
326*59599516SKenneth E. Jansen            ki = sub_map%pp(i)%p(j)
327*59599516SKenneth E. Jansen            Pcolm(ki) = rownnz
328*59599516SKenneth E. Jansen            allocate(Prowp%pp(ki)%p(rownnz))
329*59599516SKenneth E. Jansen            allocate(Pmtx%pp(ki)%p(redun,rownnz))
330*59599516SKenneth E. Jansen            do k=1,rownnz
331*59599516SKenneth E. Jansen               kj = tmp_revrmap(k)
332*59599516SKenneth E. Jansen               Prowp%pp(ki)%p(k) = kj
333*59599516SKenneth E. Jansen               Pmtx%pp(ki)%p(:,k) = tmp_rmtx(:,kj)
334*59599516SKenneth E. Jansen!               if ((ncorp_map(ki).eq.964)) then
335*59599516SKenneth E. Jansen!                   write(*,*)'paramcheck',myrank,i,k,kj,ncorp_map(kj)
336*59599516SKenneth E. Jansen!               endif
337*59599516SKenneth E. Jansen!         if ((ncorp_map(ki).eq.964).and.(ncorp_map(kj).eq.883)) then
338*59599516SKenneth E. Jansen!             write(*,*)'paramcheck',myrank,i,tmp_rmtx(1,kj)
339*59599516SKenneth E. Jansen!         endif
340*59599516SKenneth E. Jansen            enddo
341*59599516SKenneth E. Jansen
342*59599516SKenneth E. Jansen            !sort
343*59599516SKenneth E. Jansen            do gi=1,rownnz
344*59599516SKenneth E. Jansen            do gj=gi+1,rownnz
345*59599516SKenneth E. Jansen               if (Prowp%pp(ki)%p(gi).gt.Prowp%pp(ki)%p(gj)) then
346*59599516SKenneth E. Jansen                   gk = Prowp%pp(ki)%p(gj)
347*59599516SKenneth E. Jansen                   Prowp%pp(ki)%p(gj) = Prowp%pp(ki)%p(gi)
348*59599516SKenneth E. Jansen                   Prowp%pp(ki)%p(gi) = gk
349*59599516SKenneth E. Jansen                   swaptemp(:) = Pmtx%pp(ki)%p(:,gj)
350*59599516SKenneth E. Jansen                   Pmtx%pp(ki)%p(:,gj) = Pmtx%pp(ki)%p(:,gi)
351*59599516SKenneth E. Jansen                   Pmtx%pp(ki)%p(:,gi) = swaptemp(:)
352*59599516SKenneth E. Jansen               endif
353*59599516SKenneth E. Jansen            enddo
354*59599516SKenneth E. Jansen            enddo
355*59599516SKenneth E. Jansen
356*59599516SKenneth E. Jansen         enddo
357*59599516SKenneth E. Jansen      enddo
358*59599516SKenneth E. Jansen
359*59599516SKenneth E. Jansen      allocate(lhsGPcolm%p(nshg+1))
360*59599516SKenneth E. Jansen
361*59599516SKenneth E. Jansen      rownnz = 0
362*59599516SKenneth E. Jansen      k = 0
363*59599516SKenneth E. Jansen      lhsGPcolm%p(1) = 1
364*59599516SKenneth E. Jansen      do i=1,nshg
365*59599516SKenneth E. Jansen      ! colm
366*59599516SKenneth E. Jansen         if (Pflag(i).eq.0) then ! original lhsP
367*59599516SKenneth E. Jansen             rownnz = rownnz+acolm(i+1)-acolm(i)
368*59599516SKenneth E. Jansen         else ! new lhsP
369*59599516SKenneth E. Jansen             rownnz = rownnz+Pcolm(i)
370*59599516SKenneth E. Jansen             k = k+1
371*59599516SKenneth E. Jansen         endif
372*59599516SKenneth E. Jansen         lhsGPcolm%p(i+1)=rownnz+1
373*59599516SKenneth E. Jansen      enddo
374*59599516SKenneth E. Jansen
375*59599516SKenneth E. Jansen!      call ramg_dump_i(lhsGPcolm%p,nshg,1,'lhsGPcolm ')
376*59599516SKenneth E. Jansen
377*59599516SKenneth E. Jansen      allocate(lhsGProwp%p(rownnz))
378*59599516SKenneth E. Jansen      allocate(lhsGP%p(redun,rownnz))
379*59599516SKenneth E. Jansen
380*59599516SKenneth E. Jansen      rownnz = 1
381*59599516SKenneth E. Jansen      do i=1,nshg
382*59599516SKenneth E. Jansen      ! rowp & mtx.
383*59599516SKenneth E. Jansen         if (Pflag(i).eq.0) then ! original lhsP
384*59599516SKenneth E. Jansen             do j=acolm(i),acolm(i+1)-1
385*59599516SKenneth E. Jansen                lhsGProwp%p(rownnz) = arowp(j)
386*59599516SKenneth E. Jansen                lhsGP%p(:,rownnz) = alhsP(:,j)
387*59599516SKenneth E. Jansen                rownnz = rownnz + 1
388*59599516SKenneth E. Jansen             enddo
389*59599516SKenneth E. Jansen         else ! new lhsP
390*59599516SKenneth E. Jansen             do j=1,Pcolm(i)
391*59599516SKenneth E. Jansen                lhsGProwp%p(rownnz) = Prowp%pp(i)%p(j)
392*59599516SKenneth E. Jansen                lhsGP%p(:,rownnz) = Pmtx%pp(i)%p(:,j)
393*59599516SKenneth E. Jansen                rownnz = rownnz + 1
394*59599516SKenneth E. Jansen             enddo
395*59599516SKenneth E. Jansen         endif
396*59599516SKenneth E. Jansen      enddo
397*59599516SKenneth E. Jansen
398*59599516SKenneth E. Jansen      ! First entry be diagonal for PPE
399*59599516SKenneth E. Jansen      if (redun.eq.1) then
400*59599516SKenneth E. Jansen      loop_i: do i=1,nshg
401*59599516SKenneth E. Jansen         gi = lhsGPcolm%p(i)
402*59599516SKenneth E. Jansen         if (lhsGProwp%p(gi).ne.i) then
403*59599516SKenneth E. Jansen         do j=gi+1,lhsGPcolm%p(i+1)-1
404*59599516SKenneth E. Jansen            k = lhsGProwp%p(j)
405*59599516SKenneth E. Jansen            if (k.eq.i) then !swap first and k(diag)
406*59599516SKenneth E. Jansen!                 gj = lhsGProwp%p(gi)
407*59599516SKenneth E. Jansen                lhsGProwp%p(j) = lhsGProwp%p(gi)
408*59599516SKenneth E. Jansen                lhsGProwp%p(gi) = i
409*59599516SKenneth E. Jansen
410*59599516SKenneth E. Jansen                swaptemp(:) = lhsGP%p(:,gi)
411*59599516SKenneth E. Jansen                lhsGP%p(:,gi) = lhsGP%p(:,j)
412*59599516SKenneth E. Jansen                lhsGP%p(:,j) = swaptemp(:)
413*59599516SKenneth E. Jansen                cycle loop_i
414*59599516SKenneth E. Jansen            endif
415*59599516SKenneth E. Jansen         enddo
416*59599516SKenneth E. Jansen         endif
417*59599516SKenneth E. Jansen      enddo loop_i
418*59599516SKenneth E. Jansen      endif
419*59599516SKenneth E. Jansen
420*59599516SKenneth E. Jansen      if (redun.eq.1) then ! check PPE
421*59599516SKenneth E. Jansen      do i=1,nshg
422*59599516SKenneth E. Jansen         do j=lhsGPcolm%p(i),lhsGPcolm%p(i+1)-1
423*59599516SKenneth E. Jansen            k = lhsGProwp%p(j)
424*59599516SKenneth E. Jansen            gi = amg_paramap(1)%p(i)
425*59599516SKenneth E. Jansen            gk = amg_paramap(1)%p(k)
426*59599516SKenneth E. Jansen            if ((gi.eq.gk).and.(gi.lt.0) ) then
427*59599516SKenneth E. Jansen            !lhsGP%p(:,j) = 0
428*59599516SKenneth E. Jansen            endif
429*59599516SKenneth E. Jansen         enddo
430*59599516SKenneth E. Jansen      enddo
431*59599516SKenneth E. Jansen      endif
432*59599516SKenneth E. Jansen
433*59599516SKenneth E. Jansen!      call ramg_dump_matlab_map(lhsGPcolm%p,lhsGProwp%p,lhsGP%p,
434*59599516SKenneth E. Jansen!     &      nshg,rownnz-1,redun,'locallhsP ')
435*59599516SKenneth E. Jansen
436*59599516SKenneth E. Jansen!      write(*,*)'mcheck',myrank,nnz_tot,rownnz,k
437*59599516SKenneth E. Jansen
438*59599516SKenneth E. Jansen!      write(*,*)'mcheck,',myrank,'okay here'
439*59599516SKenneth E. Jansen
440*59599516SKenneth E. Jansen      ! Deallocate temporary arrays
441*59599516SKenneth E. Jansen      do i=1,nshg
442*59599516SKenneth E. Jansen         if (Pflag(i) .eq. 1) then
443*59599516SKenneth E. Jansen             deallocate(Prowp%pp(i)%p)
444*59599516SKenneth E. Jansen             deallocate(Pmtx%pp(i)%p)
445*59599516SKenneth E. Jansen         endif
446*59599516SKenneth E. Jansen      enddo
447*59599516SKenneth E. Jansen!          write(*,*)'mcheck deallocate,',myrank
448*59599516SKenneth E. Jansen
449*59599516SKenneth E. Jansen      deallocate(Prowp%pp)
450*59599516SKenneth E. Jansen      deallocate(Pmtx%pp)
451*59599516SKenneth E. Jansen
452*59599516SKenneth E. Jansen        do i=1,numtask
453*59599516SKenneth E. Jansen
454*59599516SKenneth E. Jansen           deallocate(sub_map%pp(i)%p)
455*59599516SKenneth E. Jansen           deallocate(sub_revmap%pp(i)%p)
456*59599516SKenneth E. Jansen           deallocate(sub_colm%pp(i)%p)
457*59599516SKenneth E. Jansen           deallocate(sub_colm2%pp(i)%p)
458*59599516SKenneth E. Jansen           deallocate(sub_rowp%pp(i)%p)
459*59599516SKenneth E. Jansen           deallocate(sub_rowp2%pp(i)%p)
460*59599516SKenneth E. Jansen           deallocate(sub_rowpmap%pp(i)%p)
461*59599516SKenneth E. Jansen           deallocate(sub_mtx%pp(i)%p)
462*59599516SKenneth E. Jansen           deallocate(sub_mtx2%pp(i)%p)
463*59599516SKenneth E. Jansen
464*59599516SKenneth E. Jansen         enddo
465*59599516SKenneth E. Jansen
466*59599516SKenneth E. Jansen        deallocate(sub_map%pp)
467*59599516SKenneth E. Jansen        deallocate(sub_revmap%pp)
468*59599516SKenneth E. Jansen        deallocate(sub_rowpmap%pp)
469*59599516SKenneth E. Jansen        deallocate(sub_nnz%p)
470*59599516SKenneth E. Jansen        deallocate(sub_nnz2%p)
471*59599516SKenneth E. Jansen        deallocate(sub_nshg%p)
472*59599516SKenneth E. Jansen        deallocate(sub_colm%pp)
473*59599516SKenneth E. Jansen        deallocate(sub_colm2%pp)
474*59599516SKenneth E. Jansen        deallocate(sub_rowp%pp)
475*59599516SKenneth E. Jansen        deallocate(sub_rowp2%pp)
476*59599516SKenneth E. Jansen        deallocate(sub_mtx%pp)
477*59599516SKenneth E. Jansen        deallocate(sub_mtx2%pp)
478*59599516SKenneth E. Jansen
479*59599516SKenneth E. Jansen      end subroutine ! ramg_global_lhs
480*59599516SKenneth E. Jansen
481*59599516SKenneth E. Jansen!*******************************************************************
482*59599516SKenneth E. Jansen!      ramg_PPEAp
483*59599516SKenneth E. Jansen!      produce parallel A-p product for PPE correctly
484*59599516SKenneth E. Jansen!      q = PPE * p without scaling
485*59599516SKenneth E. Jansen!*******************************************************************
486*59599516SKenneth E. Jansen      subroutine ramg_PPEAp(q,p,
487*59599516SKenneth E. Jansen     &                      colm,rowp,lhsK,lhsP,
488*59599516SKenneth E. Jansen     &                      ilwork,BC,iBC,iper)
489*59599516SKenneth E. Jansen      use ramg_data
490*59599516SKenneth E. Jansen      include "common.h"
491*59599516SKenneth E. Jansen
492*59599516SKenneth E. Jansen
493*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg)         :: p
494*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(nshg)      :: q
495*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg+1)            :: colm
496*59599516SKenneth E. Jansen      integer,intent(in),dimension(nnz_tot)           :: rowp
497*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(9,nnz_tot)    :: lhsK
498*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(4,nnz_tot)    :: lhsP
499*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)            :: ilwork
500*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)              :: iBC,iper
501*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)  :: BC
502*59599516SKenneth E. Jansen
503*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,1) :: t1,t1a
504*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,3) :: t2,t2a
505*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,4) :: t2b
506*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,4) :: diag
507*59599516SKenneth E. Jansen
508*59599516SKenneth E. Jansen      diag = ramg_flowDiag%p
509*59599516SKenneth E. Jansen
510*59599516SKenneth E. Jansen      ! scaling
511*59599516SKenneth E. Jansen      call fMtxVdimVecMult(p,amg_ppeDiag(1)%p,t1a,1,1,1,1,nshg)
512*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1a,diag(:,4),t1,1,1,1,1,nshg)
513*59599516SKenneth E. Jansen      !t1(:,1) = p
514*59599516SKenneth E. Jansen      ! G
515*59599516SKenneth E. Jansen      call commOut(t1,ilwork,1,iper,iBC,BC)
516*59599516SKenneth E. Jansen      call fLesSparseApG(colm,rowp,lhsP,t1,t2,nshg,nnz_tot)
517*59599516SKenneth E. Jansen      call commIn(t2,ilwork,3,iper,iBC,BC)
518*59599516SKenneth E. Jansen      ! K^{-1}
519*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2,diag,t2a,3,4,3,3,nshg)
520*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2a,diag,t2,3,4,3,3,nshg)
521*59599516SKenneth E. Jansen         ! note: different from lestools.c (3,4,4,3)
522*59599516SKenneth E. Jansen         ! t1 should be good to use by now
523*59599516SKenneth E. Jansen      ! G^T ... + C
524*59599516SKenneth E. Jansen      t2b(:,1:3) = -t2(:,1:3)
525*59599516SKenneth E. Jansen      t2b(:,4) = t1(:,1)
526*59599516SKenneth E. Jansen      call commOut(t2b,ilwork,4,iper,iBC,BC)
527*59599516SKenneth E. Jansen      call fLesSparseApNGtC(colm,rowp,lhsP,t2b,t1,nshg,nnz_tot)
528*59599516SKenneth E. Jansen      call commIn(t1,ilwork,1,iper,iBC,BC)
529*59599516SKenneth E. Jansen      !q = t1(:,1)
530*59599516SKenneth E. Jansen      ! scaling again
531*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1,diag(:,4),t1a,1,1,1,1,nshg)
532*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1a,amg_ppeDiag(1)%p,q,1,1,1,1,nshg)
533*59599516SKenneth E. Jansen
534*59599516SKenneth E. Jansen      end subroutine
535*59599516SKenneth E. Jansen
536*59599516SKenneth E. Jansen
537*59599516SKenneth E. Jansen!*******************************************************************
538*59599516SKenneth E. Jansen!      ramg_PPEAps
539*59599516SKenneth E. Jansen!      produce parallel A-p product for PPE correctly
540*59599516SKenneth E. Jansen!      q = PPE * p, WITH SCALING!
541*59599516SKenneth E. Jansen!*******************************************************************
542*59599516SKenneth E. Jansen      subroutine ramg_PPEAps(q,p,diag,
543*59599516SKenneth E. Jansen     &                      colm,rowp,lhsK,lhsP,
544*59599516SKenneth E. Jansen     &                      ilwork,BC,iBC,iper)
545*59599516SKenneth E. Jansen      use ramg_data
546*59599516SKenneth E. Jansen      include "common.h"
547*59599516SKenneth E. Jansen
548*59599516SKenneth E. Jansen
549*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg)         :: p
550*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(nshg)      :: q
551*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,4)            :: diag
552*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg+1)            :: colm
553*59599516SKenneth E. Jansen      integer,intent(in),dimension(nnz_tot)           :: rowp
554*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(9,nnz_tot)    :: lhsK
555*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(4,nnz_tot)    :: lhsP
556*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)            :: ilwork
557*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)              :: iBC,iper
558*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)  :: BC
559*59599516SKenneth E. Jansen
560*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,1) :: t1,t1a
561*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,3) :: t2,t2a
562*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,4) :: t2b
563*59599516SKenneth E. Jansen
564*59599516SKenneth E. Jansen      ! scaling
565*59599516SKenneth E. Jansen      call fMtxVdimVecMult(p,amg_ppeDiag(1)%p,t1a,1,1,1,1,nshg)
566*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1a,diag(:,4),t1,1,1,1,1,nshg)
567*59599516SKenneth E. Jansen      !call ramg_dump(t1,nshg,'ppe_t1_a  ')
568*59599516SKenneth E. Jansen      ! G
569*59599516SKenneth E. Jansen      call commOut(t1,ilwork,1,iper,iBC,BC)
570*59599516SKenneth E. Jansen      call fLesSparseApG(colm,rowp,lhsP,t1,t2,nshg,nnz_tot)
571*59599516SKenneth E. Jansen      call commIn(t2,ilwork,3,iper,iBC,BC)
572*59599516SKenneth E. Jansen      ! K^{-1}
573*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2,diag,t2a,3,4,3,3,nshg)
574*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2a,diag,t2,3,4,3,3,nshg)
575*59599516SKenneth E. Jansen         ! note: different from lestools.c (3,4,4,3)
576*59599516SKenneth E. Jansen         ! t1 should be good to use by now
577*59599516SKenneth E. Jansen      ! G^T ... + C
578*59599516SKenneth E. Jansen      t2b(:,1:3) = -t2(:,1:3)
579*59599516SKenneth E. Jansen      t2b(:,4) = t1(:,1)
580*59599516SKenneth E. Jansen      call commOut(t2b,ilwork,4,iper,iBC,BC)
581*59599516SKenneth E. Jansen      call fLesSparseApNGtC(colm,rowp,lhsP,t2b,t1,nshg,nnz_tot)
582*59599516SKenneth E. Jansen      call commIn(t1,ilwork,1,iper,iBC,BC)
583*59599516SKenneth E. Jansen      ! scaling again
584*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1,diag(:,4),t1a,1,1,1,1,nshg)
585*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t1a,amg_ppeDiag(1)%p,q,1,1,1,1,nshg)
586*59599516SKenneth E. Jansen
587*59599516SKenneth E. Jansen      end subroutine
588*59599516SKenneth E. Jansen
589*59599516SKenneth E. Jansen!*******************************************************************
590*59599516SKenneth E. Jansen!      ramg_PPErhs
591*59599516SKenneth E. Jansen!      produce a globally correct rhs
592*59599516SKenneth E. Jansen!*******************************************************************
593*59599516SKenneth E. Jansen      subroutine ramg_PPErhs(rhsp,rhsg,diag,
594*59599516SKenneth E. Jansen     &                      colm,rowp,lhsK,lhsP,
595*59599516SKenneth E. Jansen     &                      ilwork,BC,iBC,iper)
596*59599516SKenneth E. Jansen      use ramg_data
597*59599516SKenneth E. Jansen      include "common.h"
598*59599516SKenneth E. Jansen
599*59599516SKenneth E. Jansen
600*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(nshg)         :: rhsp
601*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,4)      :: rhsg
602*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,4)            :: diag
603*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg+1)            :: colm
604*59599516SKenneth E. Jansen      integer,intent(in),dimension(nnz_tot)           :: rowp
605*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(9,nnz_tot)    :: lhsK
606*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(4,nnz_tot)    :: lhsP
607*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)            :: ilwork
608*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)              :: iBC,iper
609*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)  :: BC
610*59599516SKenneth E. Jansen
611*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,1) :: t1
612*59599516SKenneth E. Jansen      real(kind=8),dimension(nshg,3) :: t2,t2a
613*59599516SKenneth E. Jansen
614*59599516SKenneth E. Jansen      ! scaling
615*59599516SKenneth E. Jansen      ! call fMtxVdimVecMult(rhsg,diag(:,4),t1,1,4,1,1,nshg)
616*59599516SKenneth E. Jansen      ! call ramg_dump(t1,nshg,'ppe_t1_a  ')
617*59599516SKenneth E. Jansen      ! G
618*59599516SKenneth E. Jansen      t2 = rhsg(:,1:3)
619*59599516SKenneth E. Jansen      t1 = rhsg(:,4:4)
620*59599516SKenneth E. Jansen      call commIn(t1,ilwork,1,iper,iBC,BC)
621*59599516SKenneth E. Jansen      call commOut(t1,ilwork,1,iper,iBC,BC)
622*59599516SKenneth E. Jansen      call commIn(t2,ilwork,3,iper,iBC,BC)
623*59599516SKenneth E. Jansen      call commOut(t2,ilwork,3,iper,iBC,BC)
624*59599516SKenneth E. Jansen      ! K^{-1}
625*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2,diag,t2a,3,4,3,3,nshg)
626*59599516SKenneth E. Jansen      call fMtxVdimVecMult(t2a,diag,t2,3,4,3,3,nshg)
627*59599516SKenneth E. Jansen      call commOut(t2,ilwork,3,iper,iBC,BC)
628*59599516SKenneth E. Jansen      call fLesSparseApNGt(colm,rowp,lhsP,t2,rhsp,nshg,nnz_tot)
629*59599516SKenneth E. Jansen      call commIn(rhsp,ilwork,1,iper,iBC,BC)
630*59599516SKenneth E. Jansen      call commOut(rhsp,ilwork,1,iper,iBC,BC)
631*59599516SKenneth E. Jansen      call ramg_zeroOut(rhsp,ilwork,BC,iBC,iper)
632*59599516SKenneth E. Jansen      ! -G^T ... + Rc
633*59599516SKenneth E. Jansen      rhsp = rhsp - t1(:,1)
634*59599516SKenneth E. Jansen      ! scaling again
635*59599516SKenneth E. Jansen      call fMtxVdimVecMult(rhsp,diag(:,4),t1,1,1,1,1,nshg)
636*59599516SKenneth E. Jansen      rhsp = t1(:,1)
637*59599516SKenneth E. Jansen
638*59599516SKenneth E. Jansen      end subroutine ! ramg_PPErhs
639*59599516SKenneth E. Jansen
640*59599516SKenneth E. Jansen!********************************************************
641*59599516SKenneth E. Jansen!     ramg_init_ilwork(ilwork,BC,iBC,iper)
642*59599516SKenneth E. Jansen!     Initialize amg_ilwork(level)%p(:) array
643*59599516SKenneth E. Jansen!     For each level, same structure as ilwork
644*59599516SKenneth E. Jansen!
645*59599516SKenneth E. Jansen!********************************************************
646*59599516SKenneth E. Jansen      subroutine ramg_init_ilwork(ilwork,BC,iBC,iper)
647*59599516SKenneth E. Jansen      use ramg_data
648*59599516SKenneth E. Jansen      include "common.h"
649*59599516SKenneth E. Jansen      include "mpif.h"
650*59599516SKenneth E. Jansen      include "auxmpi.h"
651*59599516SKenneth E. Jansen      integer, intent(in), dimension(nlwork)           :: ilwork
652*59599516SKenneth E. Jansen      integer, intent(in),dimension(nshg)              :: iBC,iper
653*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)   :: BC
654*59599516SKenneth E. Jansen
655*59599516SKenneth E. Jansen      integer :: lvl,i,j,iacc,iother,numseg,numtask,itkbeg,sigi,k
656*59599516SKenneth E. Jansen      integer :: tasknnztot,itask,amgseg
657*59599516SKenneth E. Jansen      integer,dimension(numpe) :: revp
658*59599516SKenneth E. Jansen      integer,dimension(ilwork(1)) :: tasknnz,iotherl
659*59599516SKenneth E. Jansen      type(i1d),dimension(ilwork(1)) :: taskfill
660*59599516SKenneth E. Jansen
661*59599516SKenneth E. Jansen      integer,dimension(nshg) :: lvlmap
662*59599516SKenneth E. Jansen
663*59599516SKenneth E. Jansen      character :: fname*80
664*59599516SKenneth E. Jansen
665*59599516SKenneth E. Jansen!      call ramg_dump_i(amg_cfmap,nshg,1,'amgcfmap  ')
666*59599516SKenneth E. Jansen      !write(*,*)'mcheck ilwork,',myrank,amg_nshg
667*59599516SKenneth E. Jansen
668*59599516SKenneth E. Jansen      if (numpe.le.1) return
669*59599516SKenneth E. Jansen
670*59599516SKenneth E. Jansen      if (ramg_setup_flag.ne.0) return
671*59599516SKenneth E. Jansen
672*59599516SKenneth E. Jansen      numtask = ilwork(1)
673*59599516SKenneth E. Jansen
674*59599516SKenneth E. Jansen      do lvl = 1,ramg_levelx
675*59599516SKenneth E. Jansen!         lvl = 1 ! test for 1 level only
676*59599516SKenneth E. Jansen
677*59599516SKenneth E. Jansen         ! Create mapping from base to coarse lvl
678*59599516SKenneth E. Jansen         ! lvlmap(baselevelindex) = coarselevelindex
679*59599516SKenneth E. Jansen         lvlmap=0
680*59599516SKenneth E. Jansen         k = 0
681*59599516SKenneth E. Jansen         do i=1,nshg
682*59599516SKenneth E. Jansen            if (amg_cfmap(i).ge.lvl) then
683*59599516SKenneth E. Jansen                k = k+1
684*59599516SKenneth E. Jansen                lvlmap(i) = k
685*59599516SKenneth E. Jansen            endif
686*59599516SKenneth E. Jansen         enddo
687*59599516SKenneth E. Jansen
688*59599516SKenneth E. Jansen         ! Count nnz for each task
689*59599516SKenneth E. Jansen         itkbeg=1
690*59599516SKenneth E. Jansen         tasknnz = 0
691*59599516SKenneth E. Jansen         do i=1,numtask
692*59599516SKenneth E. Jansen            iacc=ilwork(itkbeg+2)
693*59599516SKenneth E. Jansen            iother=ilwork(itkbeg+3) ! starts from 0
694*59599516SKenneth E. Jansen            numseg=ilwork(itkbeg+4)
695*59599516SKenneth E. Jansen            do j=1,numseg
696*59599516SKenneth E. Jansen               k=ilwork(itkbeg+3+2*j) ! row index
697*59599516SKenneth E. Jansen               if (amg_cfmap(k).ge.lvl) then
698*59599516SKenneth E. Jansen                   tasknnz(i) = tasknnz(i) + 1
699*59599516SKenneth E. Jansen               endif
700*59599516SKenneth E. Jansen            enddo
701*59599516SKenneth E. Jansen            itkbeg=itkbeg+4+2*numseg
702*59599516SKenneth E. Jansen         enddo
703*59599516SKenneth E. Jansen         tasknnztot = sum(tasknnz)
704*59599516SKenneth E. Jansen         !write(*,*)'mcheck ilwork',myrank,lvl,tasknnz
705*59599516SKenneth E. Jansen
706*59599516SKenneth E. Jansen         ! Fill in ilwork array at each lvl
707*59599516SKenneth E. Jansen
708*59599516SKenneth E. Jansen         amg_nlwork(lvl)=tasknnztot+1+2*numtask
709*59599516SKenneth E. Jansen         allocate(amg_ilwork(lvl)%p(tasknnztot+1+2*numtask))
710*59599516SKenneth E. Jansen         amg_ilwork(lvl)%p = 0
711*59599516SKenneth E. Jansen
712*59599516SKenneth E. Jansen         amg_ilwork(lvl)%p(1) = numtask
713*59599516SKenneth E. Jansen         itkbeg = 1
714*59599516SKenneth E. Jansen         kk = 1 ! pointer to amg_ilwork array
715*59599516SKenneth E. Jansen         do i=1,numtask
716*59599516SKenneth E. Jansen            iacc = ilwork(itkbeg+2)
717*59599516SKenneth E. Jansen            iother = ilwork(itkbeg+3)+1
718*59599516SKenneth E. Jansen            if (iacc.eq.0) iother=-iother
719*59599516SKenneth E. Jansen            kk = kk+1
720*59599516SKenneth E. Jansen            amg_ilwork(lvl)%p(kk) = iother  ! first put iother
721*59599516SKenneth E. Jansen            kk = kk+1
722*59599516SKenneth E. Jansen            amg_ilwork(lvl)%p(kk) = tasknnz(i) ! then numseg
723*59599516SKenneth E. Jansen            numseg = ilwork(itkbeg+4)
724*59599516SKenneth E. Jansen            do j=1,numseg
725*59599516SKenneth E. Jansen               k = ilwork(itkbeg+3+2*j)
726*59599516SKenneth E. Jansen               if (amg_cfmap(k).ge.lvl) then
727*59599516SKenneth E. Jansen                   kk = kk+1
728*59599516SKenneth E. Jansen                   amg_ilwork(lvl)%p(kk)=lvlmap(k)
729*59599516SKenneth E. Jansen               endif
730*59599516SKenneth E. Jansen            enddo
731*59599516SKenneth E. Jansen            itkbeg=itkbeg+4+2*numseg
732*59599516SKenneth E. Jansen         enddo
733*59599516SKenneth E. Jansen         !write(fname,'((A9)(I1))')'amgilwork',lvl
734*59599516SKenneth E. Jansen         !call ramg_dump_i(amg_ilwork(lvl)%p,amg_nlwork(lvl),1,fname)
735*59599516SKenneth E. Jansen      enddo
736*59599516SKenneth E. Jansen
737*59599516SKenneth E. Jansen      end subroutine ! ramg_init_ilwork
738*59599516SKenneth E. Jansen
739*59599516SKenneth E. Jansen
740*59599516SKenneth E. Jansen!*******************************************************
741*59599516SKenneth E. Jansen!      ramg_initBCflag: Setup amg_paramap on PPE level(level0)
742*59599516SKenneth E. Jansen!      -1: self, n: neighbour proc number
743*59599516SKenneth E. Jansen!*******************************************************
744*59599516SKenneth E. Jansen      subroutine ramg_initBCflag(flag,ilwork,BC,iBC,iper)
745*59599516SKenneth E. Jansen      use ramg_data
746*59599516SKenneth E. Jansen      include "common.h"
747*59599516SKenneth E. Jansen      include "mpif.h"
748*59599516SKenneth E. Jansen      include "auxmpi.h"
749*59599516SKenneth E. Jansen
750*59599516SKenneth E. Jansen      integer,intent(inout),dimension(nshg)            :: flag
751*59599516SKenneth E. Jansen
752*59599516SKenneth E. Jansen      integer, intent(in), dimension(nlwork)           :: ilwork
753*59599516SKenneth E. Jansen      integer, intent(in),dimension(nshg)              :: iBC,iper
754*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC)   :: BC
755*59599516SKenneth E. Jansen
756*59599516SKenneth E. Jansen      integer   :: numtask,itag,iacc,iother,numseg,isgbeg,itkbeg
757*59599516SKenneth E. Jansen      integer   :: i,j,k,lenseg,nr,nj,mi,mj
758*59599516SKenneth E. Jansen      integer,allocatable,dimension(:)    :: neimap
759*59599516SKenneth E. Jansen      character*5 cname
760*59599516SKenneth E. Jansen      character*255 fname,fname1
761*59599516SKenneth E. Jansen
762*59599516SKenneth E. Jansen      flag = myrank+1!note*
763*59599516SKenneth E. Jansen
764*59599516SKenneth E. Jansen      if (numpe.lt.2) then
765*59599516SKenneth E. Jansen          IF (iamg_reduce.gt.1) then
766*59599516SKenneth E. Jansen          ! this block of code create reduced case
767*59599516SKenneth E. Jansen              nr = iamg_reduce
768*59599516SKenneth E. Jansen              allocate(reducemap(nr,nr))
769*59599516SKenneth E. Jansen              allocate(rmap1d(2,nr*nr)) ! rmap1d(master,slave,rankid)
770*59599516SKenneth E. Jansen              reducemap = 0
771*59599516SKenneth E. Jansen              rmap1d = 0
772*59599516SKenneth E. Jansen              rmapmax = 1
773*59599516SKenneth E. Jansen              do i=1,nr
774*59599516SKenneth E. Jansen                 reducemap(i,i) = i
775*59599516SKenneth E. Jansen                 rmap1d(1,i) = i
776*59599516SKenneth E. Jansen                 rmap1d(2,i) = i
777*59599516SKenneth E. Jansen              enddo
778*59599516SKenneth E. Jansen              rmapmax = nr+1
779*59599516SKenneth E. Jansen              write(fname,"((I1)(A))")nr,'-procs_case/neimap.dat'
780*59599516SKenneth E. Jansen              !fname=trim(cname(nr))//'-proc_case/map_nproc.dat'
781*59599516SKenneth E. Jansen              fname=trim(fname)
782*59599516SKenneth E. Jansen              do i=1,nr
783*59599516SKenneth E. Jansen                 fname1 = trim(fname)//cname(i)
784*59599516SKenneth E. Jansen                 write(*,*)'mcheck reduced case:',fname1
785*59599516SKenneth E. Jansen                 open(264,file=trim(fname1),status='unknown')
786*59599516SKenneth E. Jansen                 read(264,*)nj
787*59599516SKenneth E. Jansen                 do j=1,nj
788*59599516SKenneth E. Jansen                    read(264,*)mi,mj
789*59599516SKenneth E. Jansen                    if (mj.gt.0) then
790*59599516SKenneth E. Jansen                        reducemap(i,mj) = rmapmax
791*59599516SKenneth E. Jansen                        reducemap(mj,i) = -rmapmax
792*59599516SKenneth E. Jansen                        write(*,*)'mcheck reducemap,',i,mj,rmapmax
793*59599516SKenneth E. Jansen                        rmap1d(1,rmapmax) = i
794*59599516SKenneth E. Jansen                        rmap1d(2,rmapmax) = mj
795*59599516SKenneth E. Jansen                        rmapmax = rmapmax + 1
796*59599516SKenneth E. Jansen                    end if
797*59599516SKenneth E. Jansen                 enddo
798*59599516SKenneth E. Jansen                 close(264)
799*59599516SKenneth E. Jansen              enddo
800*59599516SKenneth E. Jansen!              call ramg_dump_i(reducemap,nr,nr,'reducemap ')
801*59599516SKenneth E. Jansen              call ramg_dump_ic(rmap1d,2,rmapmax,'rmap1d    ')
802*59599516SKenneth E. Jansen              flag = 0
803*59599516SKenneth E. Jansen              write(fname,"((I1)(A))")nr,'-procs_case/map_nproc.dat'
804*59599516SKenneth E. Jansen              fname=trim(fname)
805*59599516SKenneth E. Jansen              do i=nr,1,-1
806*59599516SKenneth E. Jansen                 fname1 = trim(fname)//cname(i)
807*59599516SKenneth E. Jansen                 open(264,file=trim(fname1),status='unknown')
808*59599516SKenneth E. Jansen                 read(264,*)nj
809*59599516SKenneth E. Jansen                 do j=1,nj
810*59599516SKenneth E. Jansen                    read(264,*)mi,mj
811*59599516SKenneth E. Jansen                    if (flag(mj).eq.0) then
812*59599516SKenneth E. Jansen                        flag(mj) = i
813*59599516SKenneth E. Jansen                    else if (flag(mj).le.nr) then
814*59599516SKenneth E. Jansen                        !if ((flag(mj).eq.2).and.(i.eq.4)) then
815*59599516SKenneth E. Jansen                      !write(*,*)'mcheck!',mj,reducemap(flag(mj),i)
816*59599516SKenneth E. Jansen                        !endif
817*59599516SKenneth E. Jansen                        flag(mj) = iabs(reducemap(flag(mj),i))
818*59599516SKenneth E. Jansen                    end if
819*59599516SKenneth E. Jansen                 enddo
820*59599516SKenneth E. Jansen                 close(264)
821*59599516SKenneth E. Jansen              enddo
822*59599516SKenneth E. Jansen              call ramg_dump_i(flag,nshg,1,'initflagbc')
823*59599516SKenneth E. Jansen!              flag = myrank + 1
824*59599516SKenneth E. Jansen          ENDIF
825*59599516SKenneth E. Jansen          return
826*59599516SKenneth E. Jansen      end if
827*59599516SKenneth E. Jansen
828*59599516SKenneth E. Jansen      IF (numpe.gt.1) THEN
829*59599516SKenneth E. Jansen      numtask = ilwork(1)
830*59599516SKenneth E. Jansen      allocate(neimap(numtask))
831*59599516SKenneth E. Jansen      itkbeg = 1
832*59599516SKenneth E. Jansen      do i=1,numtask
833*59599516SKenneth E. Jansen         iacc = ilwork(itkbeg+2)
834*59599516SKenneth E. Jansen         iother = ilwork(itkbeg+3)
835*59599516SKenneth E. Jansen         numseg = ilwork(itkbeg+4)
836*59599516SKenneth E. Jansen         if (iacc.eq.0) then !slave
837*59599516SKenneth E. Jansen             neimap(i) = -(iother+1)
838*59599516SKenneth E. Jansen         else !master
839*59599516SKenneth E. Jansen             neimap(i) = (iother+1)
840*59599516SKenneth E. Jansen         endif
841*59599516SKenneth E. Jansen         do j=1,numseg
842*59599516SKenneth E. Jansen            isgbeg = ilwork(itkbeg+3+j*2)
843*59599516SKenneth E. Jansen            lenseg = ilwork(itkbeg+4+j*2)
844*59599516SKenneth E. Jansen            isgend = isgbeg + lenseg - 1
845*59599516SKenneth E. Jansen            flag(isgbeg:isgend) = neimap(i)!iother+1!note*
846*59599516SKenneth E. Jansen         enddo
847*59599516SKenneth E. Jansen         itkbeg = itkbeg + 4 + 2*numseg
848*59599516SKenneth E. Jansen      enddo
849*59599516SKenneth E. Jansen
850*59599516SKenneth E. Jansen      !call ramg_dump_i(flag,nshg,1,'amgparamap')
851*59599516SKenneth E. Jansen
852*59599516SKenneth E. Jansen      !if (iamg_reduce.gt.0) then
853*59599516SKenneth E. Jansen          !call ramg_dump_i(neimap,numtask,1,'neimap    ')
854*59599516SKenneth E. Jansen      !endif
855*59599516SKenneth E. Jansen      deallocate(neimap)
856*59599516SKenneth E. Jansen      ENDIF
857*59599516SKenneth E. Jansen
858*59599516SKenneth E. Jansen      ! note*: +1 to make paramap array range from 1 to numprocs
859*59599516SKenneth E. Jansen      ! this will avoid 0.
860*59599516SKenneth E. Jansen      ! n=proc indicates neighbour
861*59599516SKenneth E. Jansen      ! n=-proc indicates no coarsening necessary or other info
862*59599516SKenneth E. Jansen
863*59599516SKenneth E. Jansen
864*59599516SKenneth E. Jansen      end subroutine ! ramg_initBCflag
865*59599516SKenneth E. Jansen
866*59599516SKenneth E. Jansen!****************************************************************
867*59599516SKenneth E. Jansen!      commOut_i : commOut for integer arrays, pack commOut
868*59599516SKenneth E. Jansen!****************************************************************
869*59599516SKenneth E. Jansen      subroutine commOut_i(global,ilwork,n,iper,iBC,BC)
870*59599516SKenneth E. Jansen      include "common.h"
871*59599516SKenneth E. Jansen      integer global(nshg,n)
872*59599516SKenneth E. Jansen      real*8  BC(nshg,ndofBC)
873*59599516SKenneth E. Jansen      integer ilwork(nlwork),iper(nshg),iBC(nshg)
874*59599516SKenneth E. Jansen      ! temp array
875*59599516SKenneth E. Jansen      real(kind=8)  aglobal(nshg,n)
876*59599516SKenneth E. Jansen      integer i,j
877*59599516SKenneth E. Jansen      do i=1,nshg
878*59599516SKenneth E. Jansen      do j=1,n
879*59599516SKenneth E. Jansen         aglobal(i,j) = global(i,j)
880*59599516SKenneth E. Jansen      enddo
881*59599516SKenneth E. Jansen      enddo
882*59599516SKenneth E. Jansen      call commOut(aglobal,ilwork,n,iper,iBC,BC)
883*59599516SKenneth E. Jansen      do i=1,nshg
884*59599516SKenneth E. Jansen      do j=1,n
885*59599516SKenneth E. Jansen         global(i,j)=aglobal(i,j)
886*59599516SKenneth E. Jansen      enddo
887*59599516SKenneth E. Jansen      enddo
888*59599516SKenneth E. Jansen      end subroutine ! commOut_i
889*59599516SKenneth E. Jansen
890*59599516SKenneth E. Jansen!****************************************************************
891*59599516SKenneth E. Jansen!      ramg_commOut: commOut for amg array in higher level
892*59599516SKenneth E. Jansen!****************************************************************
893*59599516SKenneth E. Jansen      subroutine ramg_commOut(global,level,ilwork,redun,iper,iBC,BC)
894*59599516SKenneth E. Jansen      use ramg_data
895*59599516SKenneth E. Jansen      include "common.h"
896*59599516SKenneth E. Jansen      include "mpif.h"
897*59599516SKenneth E. Jansen      include "auxmpi.h"
898*59599516SKenneth E. Jansen
899*59599516SKenneth E. Jansen      integer,intent(in)                            :: level
900*59599516SKenneth E. Jansen      integer,intent(in) :: redun
901*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(amg_nshg(level),redun)
902*59599516SKenneth E. Jansen     &           :: global
903*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)        :: ilwork
904*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)            :: iBC,iper
905*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC) :: BC
906*59599516SKenneth E. Jansen
907*59599516SKenneth E. Jansen      integer :: numtask,iacc,itag(ilwork(1)),i,j,m,k
908*59599516SKenneth E. Jansen      integer :: iother(ilwork(1)),ierr,iotheri
909*59599516SKenneth E. Jansen      integer :: numseg(ilwork(1))
910*59599516SKenneth E. Jansen      integer :: mstat(MPI_STATUS_SIZE,ilwork(1))
911*59599516SKenneth E. Jansen      integer :: req(ilwork(1))
912*59599516SKenneth E. Jansen      type(r2d),dimension(ilwork(1)) :: tmparray
913*59599516SKenneth E. Jansen
914*59599516SKenneth E. Jansen      if (numpe.le.1) return
915*59599516SKenneth E. Jansen
916*59599516SKenneth E. Jansen      if (level.eq.1) then
917*59599516SKenneth E. Jansen         call commOut(global,ilwork,1,iper,iBC,BC)
918*59599516SKenneth E. Jansen         return
919*59599516SKenneth E. Jansen      endif
920*59599516SKenneth E. Jansen
921*59599516SKenneth E. Jansen      numtask = amg_ilwork(level)%p(1)
922*59599516SKenneth E. Jansen
923*59599516SKenneth E. Jansen      lother = -1
924*59599516SKenneth E. Jansen      itkbeg=1
925*59599516SKenneth E. Jansen      do i=1,numtask
926*59599516SKenneth E. Jansen         itag(i)=ilwork(itkbeg+1)
927*59599516SKenneth E. Jansen         itkbeg=itkbeg+4+2*ilwork(itkbeg+4)
928*59599516SKenneth E. Jansen      enddo
929*59599516SKenneth E. Jansen      itkbeg=1
930*59599516SKenneth E. Jansen      do i=1,numtask
931*59599516SKenneth E. Jansen         iother(i)=amg_ilwork(level)%p(itkbeg+1)
932*59599516SKenneth E. Jansen         numseg(i)=amg_ilwork(level)%p(itkbeg+2)
933*59599516SKenneth E. Jansen         allocate(tmparray(i)%p(numseg(i),redun))
934*59599516SKenneth E. Jansen         itkbeg=itkbeg+2
935*59599516SKenneth E. Jansen         do j=1,numseg(i)
936*59599516SKenneth E. Jansen            itkbeg=itkbeg+1
937*59599516SKenneth E. Jansen         tmparray(i)%p(j,:)=global(amg_ilwork(level)%p(itkbeg),:)
938*59599516SKenneth E. Jansen         enddo
939*59599516SKenneth E. Jansen      enddo
940*59599516SKenneth E. Jansen
941*59599516SKenneth E. Jansen      if ((myrank.eq.1).and.(level.eq.2)) then ! debug
942*59599516SKenneth E. Jansen!          write(*,*)'mcheck debug ilwork',amg_nlwork(2)
943*59599516SKenneth E. Jansen!          call ramg_dump(global,amg_nshg(level),'debuglobal')
944*59599516SKenneth E. Jansen!      call ramg_dump_i(amg_ilwork(2)%p,amg_nlwork(2),1,'debugilwok')
945*59599516SKenneth E. Jansen!          call ramg_dump(tmparray(1)%p,numseg(1),'debuglvl2 ')
946*59599516SKenneth E. Jansen      endif
947*59599516SKenneth E. Jansen
948*59599516SKenneth E. Jansen      IF (.TRUE.) THEN
949*59599516SKenneth E. Jansen      m =0
950*59599516SKenneth E. Jansen      do i=1,numtask
951*59599516SKenneth E. Jansen         m = m+1
952*59599516SKenneth E. Jansen         iotheri = iabs(iother(i))-1
953*59599516SKenneth E. Jansen         if (iother(i)>0) then ! master send
954*59599516SKenneth E. Jansen!      write(*,*)'mcheck commou send',myrank,iotheri,numseg(i),itag(i)
955*59599516SKenneth E. Jansen            call MPI_ISEND(tmparray(i)%p(1,1),redun*numseg(i),
956*59599516SKenneth E. Jansen     &      MPI_DOUBLE_PRECISION,iotheri,itag(i),MPI_COMM_WORLD,
957*59599516SKenneth E. Jansen     &      req(m),ierr)
958*59599516SKenneth E. Jansen         else ! slave receive
959*59599516SKenneth E. Jansen!      write(*,*)'mcheck commou recv',myrank,iotheri,numseg(i),itag(i)
960*59599516SKenneth E. Jansen            call MPI_IRECV(tmparray(i)%p(1,1),redun*numseg(i),
961*59599516SKenneth E. Jansen     &      MPI_DOUBLE_PRECISION,iotheri,itag(i),MPI_COMM_WORLD,
962*59599516SKenneth E. Jansen     &      req(m),ierr)
963*59599516SKenneth E. Jansen         endif
964*59599516SKenneth E. Jansen      enddo
965*59599516SKenneth E. Jansen
966*59599516SKenneth E. Jansen!      write(*,*)'mcheck commout m,',m
967*59599516SKenneth E. Jansen
968*59599516SKenneth E. Jansen      call MPI_WAITALL(m,req,mstat,ierr)
969*59599516SKenneth E. Jansen      ENDIF
970*59599516SKenneth E. Jansen
971*59599516SKenneth E. Jansen      ! put back
972*59599516SKenneth E. Jansen
973*59599516SKenneth E. Jansen      itkbeg=1
974*59599516SKenneth E. Jansen      do i=1,numtask
975*59599516SKenneth E. Jansen         numseg(i)=amg_ilwork(level)%p(itkbeg+2)
976*59599516SKenneth E. Jansen         itkbeg=itkbeg+2
977*59599516SKenneth E. Jansen         do j=1,numseg(i)
978*59599516SKenneth E. Jansen            itkbeg=itkbeg+1
979*59599516SKenneth E. Jansen            global(amg_ilwork(level)%p(itkbeg),:)=tmparray(i)%p(j,:)
980*59599516SKenneth E. Jansen         enddo
981*59599516SKenneth E. Jansen      enddo
982*59599516SKenneth E. Jansen
983*59599516SKenneth E. Jansen      do i=1,numtask
984*59599516SKenneth E. Jansen         deallocate(tmparray(i)%p)
985*59599516SKenneth E. Jansen      enddo
986*59599516SKenneth E. Jansen
987*59599516SKenneth E. Jansen      end subroutine ! ramg_commOut
988*59599516SKenneth E. Jansen
989*59599516SKenneth E. Jansen      subroutine ramg_commIn(global,level,ilwork,redun,iper,iBC,BC)
990*59599516SKenneth E. Jansen      use ramg_data
991*59599516SKenneth E. Jansen      include "common.h"
992*59599516SKenneth E. Jansen      include "mpif.h"
993*59599516SKenneth E. Jansen      include "auxmpi.h"
994*59599516SKenneth E. Jansen
995*59599516SKenneth E. Jansen      integer,intent(in)                            :: level
996*59599516SKenneth E. Jansen      integer,intent(in) :: redun
997*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(amg_nshg(level),redun)
998*59599516SKenneth E. Jansen     &           :: global
999*59599516SKenneth E. Jansen      integer,intent(in),dimension(nlwork)        :: ilwork
1000*59599516SKenneth E. Jansen      integer,intent(in),dimension(nshg)            :: iBC,iper
1001*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg,ndofBC) :: BC
1002*59599516SKenneth E. Jansen
1003*59599516SKenneth E. Jansen      integer :: numtask,iacc,itag(ilwork(1)),i,j,m,k
1004*59599516SKenneth E. Jansen      integer :: iother(ilwork(1)),ierr,iotheri
1005*59599516SKenneth E. Jansen      integer :: numseg(ilwork(1))
1006*59599516SKenneth E. Jansen      integer :: mstat(MPI_STATUS_SIZE,ilwork(1))
1007*59599516SKenneth E. Jansen      integer :: req(ilwork(1))
1008*59599516SKenneth E. Jansen      type(r2d),dimension(ilwork(1)) :: tmparray
1009*59599516SKenneth E. Jansen
1010*59599516SKenneth E. Jansen      if (numpe.le.1) return
1011*59599516SKenneth E. Jansen
1012*59599516SKenneth E. Jansen      if (level.eq.1) then
1013*59599516SKenneth E. Jansen         call commIn(global,ilwork,1,iper,iBC,BC)
1014*59599516SKenneth E. Jansen         return
1015*59599516SKenneth E. Jansen      endif
1016*59599516SKenneth E. Jansen
1017*59599516SKenneth E. Jansen      numtask = amg_ilwork(level)%p(1)
1018*59599516SKenneth E. Jansen
1019*59599516SKenneth E. Jansen      lother = -1
1020*59599516SKenneth E. Jansen      itkbeg=1
1021*59599516SKenneth E. Jansen      do i=1,numtask
1022*59599516SKenneth E. Jansen         itag(i)=ilwork(itkbeg+1)
1023*59599516SKenneth E. Jansen         itkbeg=itkbeg+4+2*ilwork(itkbeg+4)
1024*59599516SKenneth E. Jansen      enddo
1025*59599516SKenneth E. Jansen      itkbeg=1
1026*59599516SKenneth E. Jansen      do i=1,numtask
1027*59599516SKenneth E. Jansen         iother(i)=amg_ilwork(level)%p(itkbeg+1)
1028*59599516SKenneth E. Jansen         numseg(i)=amg_ilwork(level)%p(itkbeg+2)
1029*59599516SKenneth E. Jansen         allocate(tmparray(i)%p(numseg(i),redun))
1030*59599516SKenneth E. Jansen         itkbeg=itkbeg+2
1031*59599516SKenneth E. Jansen         do j=1,numseg(i)
1032*59599516SKenneth E. Jansen            itkbeg=itkbeg+1
1033*59599516SKenneth E. Jansen         tmparray(i)%p(j,:)=global(amg_ilwork(level)%p(itkbeg),:)
1034*59599516SKenneth E. Jansen         enddo
1035*59599516SKenneth E. Jansen      enddo
1036*59599516SKenneth E. Jansen
1037*59599516SKenneth E. Jansen      IF (.TRUE.) THEN
1038*59599516SKenneth E. Jansen      m =0
1039*59599516SKenneth E. Jansen      do i=1,numtask
1040*59599516SKenneth E. Jansen         m = m+1
1041*59599516SKenneth E. Jansen         iotheri = iabs(iother(i))-1
1042*59599516SKenneth E. Jansen         if (iother(i)>0) then ! master receive
1043*59599516SKenneth E. Jansen            call MPI_IRECV(tmparray(i)%p(1,1),redun*numseg(i),
1044*59599516SKenneth E. Jansen     &      MPI_DOUBLE_PRECISION,iotheri,itag(i),MPI_COMM_WORLD,
1045*59599516SKenneth E. Jansen     &      req(m),ierr)
1046*59599516SKenneth E. Jansen         else ! slave send
1047*59599516SKenneth E. Jansen            call MPI_ISEND(tmparray(i)%p(1,1),redun*numseg(i),
1048*59599516SKenneth E. Jansen     &      MPI_DOUBLE_PRECISION,iotheri,itag(i),MPI_COMM_WORLD,
1049*59599516SKenneth E. Jansen     &      req(m),ierr)
1050*59599516SKenneth E. Jansen         endif
1051*59599516SKenneth E. Jansen      enddo
1052*59599516SKenneth E. Jansen
1053*59599516SKenneth E. Jansen!      write(*,*)'mcheck commout m,',m
1054*59599516SKenneth E. Jansen
1055*59599516SKenneth E. Jansen      call MPI_WAITALL(m,req,mstat,ierr)
1056*59599516SKenneth E. Jansen      ENDIF
1057*59599516SKenneth E. Jansen
1058*59599516SKenneth E. Jansen      ! put back
1059*59599516SKenneth E. Jansen
1060*59599516SKenneth E. Jansen      itkbeg=1
1061*59599516SKenneth E. Jansen      do i=1,numtask
1062*59599516SKenneth E. Jansen         numseg(i)=amg_ilwork(level)%p(itkbeg+2)
1063*59599516SKenneth E. Jansen         itkbeg=itkbeg+2
1064*59599516SKenneth E. Jansen         do j=1,numseg(i)
1065*59599516SKenneth E. Jansen            itkbeg=itkbeg+1
1066*59599516SKenneth E. Jansen            if (iother(i)>0) then ! master
1067*59599516SKenneth E. Jansen            global(amg_ilwork(level)%p(itkbeg),:)=
1068*59599516SKenneth E. Jansen     &      global(amg_ilwork(level)%p(itkbeg),:)+tmparray(i)%p(j,:)
1069*59599516SKenneth E. Jansen            else
1070*59599516SKenneth E. Jansen            global(amg_ilwork(level)%p(itkbeg),:)=0
1071*59599516SKenneth E. Jansen            endif
1072*59599516SKenneth E. Jansen         enddo
1073*59599516SKenneth E. Jansen      enddo
1074*59599516SKenneth E. Jansen
1075*59599516SKenneth E. Jansen      do i=1,numtask
1076*59599516SKenneth E. Jansen         deallocate(tmparray(i)%p)
1077*59599516SKenneth E. Jansen      enddo
1078*59599516SKenneth E. Jansen
1079*59599516SKenneth E. Jansen      end subroutine ! ramg_commIn
1080*59599516SKenneth E. Jansen
1081*59599516SKenneth E. Jansen      subroutine ramg_mapv2g(level,carray,garray)
1082*59599516SKenneth E. Jansen      ! map to level 0 array
1083*59599516SKenneth E. Jansen      use ramg_data
1084*59599516SKenneth E. Jansen      include "common.h"
1085*59599516SKenneth E. Jansen      integer,intent(in)            :: level
1086*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(nshg) :: garray
1087*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(amg_nshg(level)) :: carray
1088*59599516SKenneth E. Jansen
1089*59599516SKenneth E. Jansen      integer :: i,j,k
1090*59599516SKenneth E. Jansen      integer,dimension(amg_nshg(level)) :: revmap
1091*59599516SKenneth E. Jansen      revmap = 0
1092*59599516SKenneth E. Jansen      garray(:) = 0
1093*59599516SKenneth E. Jansen      j = 1
1094*59599516SKenneth E. Jansen      do i=1,nshg
1095*59599516SKenneth E. Jansen         if (amg_cfmap(i).ge.level) then
1096*59599516SKenneth E. Jansen             revmap(j) = i
1097*59599516SKenneth E. Jansen             j = j+1
1098*59599516SKenneth E. Jansen         end if
1099*59599516SKenneth E. Jansen      enddo
1100*59599516SKenneth E. Jansen      do i=1,j-1
1101*59599516SKenneth E. Jansen         garray(revmap(i)) = carray(i)
1102*59599516SKenneth E. Jansen      enddo
1103*59599516SKenneth E. Jansen
1104*59599516SKenneth E. Jansen      end subroutine !ramg_mapv2g
1105*59599516SKenneth E. Jansen
1106*59599516SKenneth E. Jansen      subroutine ramg_mapg2v(level,carray,garray)
1107*59599516SKenneth E. Jansen      use ramg_data
1108*59599516SKenneth E. Jansen      include "common.h"
1109*59599516SKenneth E. Jansen      integer,intent(in)            :: level
1110*59599516SKenneth E. Jansen      real(kind=8),intent(in),dimension(nshg) :: garray
1111*59599516SKenneth E. Jansen      real(kind=8),intent(inout),dimension(amg_nshg(level)) ::carray
1112*59599516SKenneth E. Jansen      integer :: i,j,k
1113*59599516SKenneth E. Jansen      carray(:) = 0
1114*59599516SKenneth E. Jansen      j = 1
1115*59599516SKenneth E. Jansen      do i=1,nshg
1116*59599516SKenneth E. Jansen         if (amg_cfmap(i).ge.level) then
1117*59599516SKenneth E. Jansen             carray(j) = garray(i)
1118*59599516SKenneth E. Jansen             j = j+1
1119*59599516SKenneth E. Jansen         end if
1120*59599516SKenneth E. Jansen      enddo
1121*59599516SKenneth E. Jansen      end subroutine !ramg_mapg2v
1122