11 public :: hecmwst_local_matrix
28 type hecmwst_local_matrix
29 integer :: nr, nc, nnz, ndof
30 integer(kind=kint),
pointer :: index(:)
31 integer(kind=kint),
pointer :: item(:)
32 real(kind=
kreal),
pointer :: a(:)
33 end type hecmwst_local_matrix
35 integer(kind=kint),
parameter :: cNCOL_ITEM = 3
36 integer(kind=kint),
parameter :: cLID = 1
37 integer(kind=kint),
parameter :: cRANK = 2
38 integer(kind=kint),
parameter :: cGID = 3
40 integer(kind=kint),
parameter :: DEBUG = 0
41 integer(kind=kint),
parameter :: DEBUG_MATRIX = 0
42 integer(kind=kint),
parameter :: TIMER = 0
48 type (hecmwst_local_matrix),
intent(in) :: tmat
49 integer(kind=kint),
intent(in) :: iunit
50 integer(kind=kint) :: nr, nc, nnz, ndof, ndof2, i, js, je, j, jj
51 character(len=64) :: fmt
57 write(iunit,
'(a,4i10)')
'nr, nc, nnz, ndof', nr, nc, nnz, ndof
58 write(iunit,
'(a)')
'i, j, A'
59 write(fmt,
'(a,i0,a)')
'(',ndof,
'f12.3)'
66 write(iunit,
'(2i10,f12.3)') i, jj, tmat%A(j)
68 write(iunit,
'(2i10)') i, jj
69 write(iunit,fmt) tmat%A((j-1)*ndof2+1:j*ndof2)
75 subroutine hecmw_localmat_write_size(Tmat,iunit)
77 type (hecmwst_local_matrix),
intent(in) :: tmat
78 integer(kind=kint),
intent(in) :: iunit
79 integer(kind=kint) :: nr, nc, nnz, ndof
84 write(iunit,
'(a,4i10)')
'nr, nc, nnz, ndof', nr, nc, nnz, ndof
85 end subroutine hecmw_localmat_write_size
87 subroutine hecmw_localmat_write_ij(Tmat,iunit)
89 type (hecmwst_local_matrix),
intent(in) :: tmat
90 integer(kind=kint),
intent(in) :: iunit
91 integer(kind=kint) :: nr, nc, nnz, ndof, i, js, je, j, jj
96 write(iunit,
'(a,4i10)')
'nr, nc, nnz, ndof', nr, nc, nnz, ndof
97 write(iunit,
'(a)')
'i, j'
103 write(iunit,
'(2i10)') i, jj
106 end subroutine hecmw_localmat_write_ij
110 type (hecmwst_local_matrix),
intent(in) :: tmat
111 integer,
intent(in) :: ndof
112 type (hecmwst_local_matrix),
intent(out) :: btmat
113 integer,
allocatable :: iw(:)
114 integer :: ndof2, i, icnt, idof, idx, ls, le, l, j, jb, k, lb0, jdof, ks, ke
117 if (mod(tmat%nr, ndof) /= 0 .or. mod(tmat%nc, ndof) /= 0)
then
118 write(0,*) tmat%nr, tmat%nc, ndof
119 stop
'ERROR: blocking_Tmat failed'
121 btmat%nr=tmat%nr/ndof
122 btmat%nc=tmat%nc/ndof
125 allocate(iw(btmat%nc))
126 allocate(btmat%index(0:btmat%nr))
133 ls=tmat%index(idx-1)+1
139 if (iw(k)==jb) cycle lcol
145 btmat%index(i)=btmat%index(i-1)+icnt
148 btmat%nnz=btmat%index(btmat%nr)
149 allocate(btmat%item(btmat%nnz))
150 allocate(btmat%A(btmat%nnz*ndof2))
157 ls=tmat%index(idx-1)+1
163 if (iw(k)==jb) cycle lcol2
173 btmat%item(lb0+k)=iw(k)
177 ls=tmat%index(idx-1)+1
182 jdof=mod((j-1), ndof)+1
183 ks=btmat%index(i-1)+1
186 if (btmat%item(k)==jb)
then
187 btmat%A((k-1)*ndof2+(idof-1)*ndof+jdof)=tmat%A(l)
191 stop
'ERROR: something wrong in blocking Tmat'
199 type (hecmwst_local_matrix),
intent(inout) :: tmat
200 deallocate(tmat%index)
201 if (
associated(tmat%item))
deallocate(tmat%item)
202 if (
associated(tmat%A))
deallocate(tmat%A)
210 iwS, num_lagrange, hecTKT)
214 type (hecmwst_local_matrix),
intent(inout) :: bttmat, btmat
216 integer(kind=kint),
intent(in) :: iws(:)
217 integer(kind=kint),
intent(in) :: num_lagrange
219 if (hecmesh%n_neighbor_pe == 0)
then
221 iws, num_lagrange, hectkt)
224 iws, num_lagrange, hectkt)
229 iwS, num_lagrange, hecTKT)
233 type (hecmwst_local_matrix),
intent(in) :: bttmat, btmat
235 integer(kind=kint),
intent(in) :: iws(:)
236 integer(kind=kint),
intent(in) :: num_lagrange
238 type (hecmwst_local_matrix) :: bttkt
239 real(kind=
kreal) :: num
243 call debug_write_matrix(bttkt,
'BTtKT(MPC)', debug_matrix)
248 call place_num_on_diag(bttkt, iws, num_lagrange, num)
249 call debug_write_matrix(bttkt,
'BTtKT(MPC) (place 1.0 on slave diag)', debug_matrix)
252 call make_new_hecmat(hecmat, bttkt, hectkt)
257 iwS, num_lagrange, hecTKT)
260 type (hecmwST_local_mesh),
intent(inout) :: hecMESH
261 type (hecmwST_local_matrix),
intent(inout) :: BTtmat, BTmat
262 type (hecmwST_matrix),
intent(in) :: hecMAT
263 integer(kind=kint),
intent(in) :: iwS(:)
264 integer(kind=kint),
intent(in) :: num_lagrange
265 type (hecmwST_matrix),
intent(inout) :: hecTKT
266 type (hecmwST_local_matrix) :: BKmat, BTtKmat, BTtKTmat
267 real(kind=
kreal) :: num
268 real(kind=
kreal) :: t0, t1
273 call debug_write_matrix(bkmat,
'BKmat (hecMAT)', debug_matrix)
275 if (timer >= 1)
write(0,
'(A,f10.4)')
"#### hecmw_trimatmul_TtKT_parallel (1) : ",t1-t0
279 if (debug >= 2)
write(0,*)
' DEBUG2: multiply Tt and K done'
280 call debug_write_matrix(bttkmat,
'BTtKmat', debug_matrix)
283 if (timer >= 1)
write(0,
'(A,f10.4)')
"#### hecmw_trimatmul_TtKT_parallel (2) : ",t1-t0
287 if (debug >= 2)
write(0,*)
' DEBUG2: multiply TtK and T done'
288 call debug_write_matrix(bttktmat,
'BTtKTmat', debug_matrix)
291 if (timer >= 1)
write(0,
'(A,f10.4)')
"#### hecmw_trimatmul_TtKT_parallel (3) : ",t1-t0
297 call place_num_on_diag(bttktmat, iws, num_lagrange, num)
305 call debug_write_matrix(bttktmat,
'BTtKTmat (place 1.0 on slave diag)', debug_matrix)
307 if (timer >= 1)
write(0,
'(A,f10.4)')
"#### hecmw_trimatmul_TtKT_parallel (4) : ",t1-t0
311 call make_new_hecmat(hecmat, bttktmat, hectkt)
314 if (timer >= 1)
write(0,
'(A,f10.4)')
"#### hecmw_trimatmul_TtKT_parallel (5) : ",t1-t0
319 type (hecmwST_local_matrix),
intent(in) :: BTtmat, BTmat
320 type (hecmwST_matrix),
intent(in) :: hecMAT
321 type (hecmwST_local_matrix),
intent(out) :: BTtKT
322 integer :: nr, nc, ndof, ndof2, i, icnt, js, je, j, jj, ks, ke, k, kk
323 integer :: ls, le, l, ll, m, ms, me, mm
324 integer,
allocatable :: iw(:)
325 real(kind=
kreal),
pointer :: ttp(:), kp(:), tp(:), ttktp(:)
336 allocate(bttkt%index(0:nr))
347 js=bttmat%index(i-1)+1
352 ks=hecmat%indexL(jj-1)+1
356 ls=btmat%index(kk-1)+1
361 if (iw(m)==ll) cycle ll1
369 ls=btmat%index(jj-1)+1
374 if (iw(m)==ll) cycle ll2
381 ks=hecmat%indexU(jj-1)+1
385 ls=btmat%index(kk-1)+1
390 if (iw(m)==ll) cycle ll3
398 if (icnt == 0) icnt=1
411 bttkt%index(i)=bttkt%index(i-1)+bttkt%index(i)
415 bttkt%nnz=bttkt%index(nr)
416 allocate(bttkt%item(bttkt%nnz))
417 allocate(bttkt%A(bttkt%nnz*ndof2))
430 ms=bttkt%index(i-1)+1
432 js=bttmat%index(i-1)+1
436 ttp=>bttmat%A((j-1)*ndof2+1:j*ndof2)
438 ks=hecmat%indexL(jj-1)+1
442 kp=>hecmat%AL((k-1)*ndof2+1:k*ndof2)
443 ls=btmat%index(kk-1)+1
447 tp=>btmat%A((l-1)*ndof2+1:l*ndof2)
451 if (bttkt%item(m)==ll) mm=m
459 ttktp=>bttkt%A((mm-1)*ndof2+1:mm*ndof2)
460 call blk_trimatmul_add(ndof, ttp, kp, tp, ttktp)
464 kp=>hecmat%D((jj-1)*ndof2+1:jj*ndof2)
465 ls=btmat%index(jj-1)+1
469 tp=>btmat%A((l-1)*ndof2+1:l*ndof2)
473 if (bttkt%item(m)==ll) mm=m
481 ttktp=>bttkt%A((mm-1)*ndof2+1:mm*ndof2)
482 call blk_trimatmul_add(ndof, ttp, kp, tp, ttktp)
485 ks=hecmat%indexU(jj-1)+1
489 kp=>hecmat%AU((k-1)*ndof2+1:k*ndof2)
490 ls=btmat%index(kk-1)+1
494 tp=>btmat%A((l-1)*ndof2+1:l*ndof2)
498 if (bttkt%item(m)==ll) mm=m
506 ttktp=>bttkt%A((mm-1)*ndof2+1:mm*ndof2)
507 call blk_trimatmul_add(ndof, ttp, kp, tp, ttktp)
518 if (ms-1+icnt /= bttkt%index(i)) stop
'ERROR: trimatmul'
527 subroutine blk_trimatmul_add(ndof, A, B, C, ABC)
529 integer,
intent(in) :: ndof
530 real(kind=
kreal),
intent(in) :: a(:), b(:), c(:)
531 real(kind=
kreal),
intent(inout) :: abc(:)
532 real(kind=
kreal),
allocatable :: ab(:)
533 integer :: ndof2, i, j, k, i0, j0, ij, ik, jk
547 ab(ik)=ab(ik)+a(ij)*b(jk)
560 abc(ik)=abc(ik)+ab(ij)*c(jk)
566 end subroutine blk_trimatmul_add
568 subroutine place_num_on_diag(BTtKT, iwS, num_lagrange, num)
570 type (hecmwST_local_matrix),
intent(inout) :: BTtKT
571 integer(kind=kint),
intent(in) :: iwS(:)
572 integer(kind=kint),
intent(in) :: num_lagrange
573 real(kind=
kreal),
intent(in) :: num
574 integer(kind=kint) :: ndof, ndof2, ilag, i, idof, js, je, j, jj
575 integer(kind=kint) :: nmissing, k, ks, ke
576 integer(kind=kint),
allocatable :: missing(:), cnt(:)
577 integer(kind=kint),
pointer :: index(:), item(:)
578 real(kind=
kreal),
pointer :: a(:)
584 allocate(missing(num_lagrange))
586 outer1:
do ilag=1,num_lagrange
587 i=(iws(ilag)-1)/ndof+1
588 idof=mod(iws(ilag)-1, ndof)+1
589 js=bttkt%index(i-1)+1
593 if (jj==i) cycle outer1
597 if (missing(k) == i) cycle outer1
599 nmissing = nmissing + 1
600 missing(nmissing) = i
604 if (nmissing > 0)
then
605 allocate(cnt(bttkt%nr))
606 allocate(index(0:bttkt%nr))
608 cnt(i) = bttkt%index(i) - bttkt%index(i-1)
611 cnt(missing(i)) = cnt(missing(i)) + 1
613 call make_index(bttkt%nr, cnt, index)
614 allocate(item(bttkt%nnz + nmissing))
615 allocate(a(ndof2 * (bttkt%nnz + nmissing)))
618 js=bttkt%index(i-1)+1
620 item(ks:ks+(je-js))=bttkt%item(js:je)
621 a(ndof2*(ks-1)+1:ndof2*(ks+(je-js)))=bttkt%A(ndof2*(js-1)+1:ndof2*je)
626 a(ndof2*(ke-1)+1:ndof2*ke)=0.d0
628 deallocate(bttkt%index)
629 deallocate(bttkt%item)
634 bttkt%nnz = index(bttkt%nr)
640 outer:
do ilag=1,num_lagrange
641 i=(iws(ilag)-1)/ndof+1
642 idof=mod(iws(ilag)-1, ndof)+1
643 js=bttkt%index(i-1)+1
649 bttkt%A((j-1)*ndof2+(idof-1)*ndof+idof)=num
654 end subroutine place_num_on_diag
656 subroutine replace_hecmat(hecMAT, BTtKT)
658 type (hecmwST_matrix),
intent(inout) :: hecMAT
659 type (hecmwST_local_matrix),
intent(in) :: BTtKT
660 integer :: nr, nc, ndof, ndof2, i, nl, nu, js, je, j, jj
661 integer :: ksl, ksu, k
669 if (
associated(hecmat%AL))
deallocate(hecmat%AL)
670 if (
associated(hecmat%AU))
deallocate(hecmat%AU)
671 if (
associated(hecmat%itemL))
deallocate(hecmat%itemL)
672 if (
associated(hecmat%itemU))
deallocate(hecmat%itemU)
683 js=bttkt%index(i-1)+1
704 hecmat%indexL(i)=hecmat%indexL(i-1)+hecmat%indexL(i)
705 hecmat%indexU(i)=hecmat%indexU(i-1)+hecmat%indexU(i)
707 hecmat%NPL=hecmat%indexL(nc)
708 hecmat%NPU=hecmat%indexU(nc)
711 allocate(hecmat%itemL(hecmat%NPL), hecmat%itemU(hecmat%NPU))
712 allocate(hecmat%AL(hecmat%NPL*ndof2), hecmat%AU(hecmat%NPU*ndof2))
726 js=bttkt%index(i-1)+1
728 ksl=hecmat%indexL(i-1)+1
729 ksu=hecmat%indexU(i-1)+1
735 hecmat%AL((k-1)*ndof2+1:k*ndof2)=bttkt%A((j-1)*ndof2+1:j*ndof2)
740 hecmat%AU((k-1)*ndof2+1:k*ndof2)=bttkt%A((j-1)*ndof2+1:j*ndof2)
743 hecmat%D((i-1)*ndof2+1:i*ndof2)=bttkt%A((j-1)*ndof2+1:j*ndof2)
760 end subroutine replace_hecmat
762 subroutine make_new_hecmat(hecMAT, BTtKT, hecTKT)
765 type(hecmwst_local_matrix),
intent(in) :: BTtKT
767 integer(kind=kint) :: nr, nc, ndof, ndof2
783 if (
associated(hectkt%D))
deallocate(hectkt%D)
784 allocate(hectkt%D(nc*ndof2))
786 if (
associated(hectkt%indexL))
deallocate(hectkt%indexL)
787 if (
associated(hectkt%indexU))
deallocate(hectkt%indexU)
788 allocate(hectkt%indexL(0:nc))
789 allocate(hectkt%indexU(0:nc))
791 hectkt%Iarray=hecmat%Iarray
792 hectkt%Rarray=hecmat%Rarray
794 call replace_hecmat(hectkt, bttkt)
795 end subroutine make_new_hecmat
799 type (hecmwst_local_matrix),
intent(in) :: btmat
800 real(kind=
kreal),
intent(in),
target :: v(:)
801 real(kind=
kreal),
intent(out),
target :: tv(:)
802 real(kind=
kreal),
pointer :: tvp(:), tp(:), vp(:)
803 integer :: nr, ndof, ndof2, i, js, je, j, jj, k, kl0, l
822 tvp=>tv((i-1)*ndof+1:i*ndof)
823 js=btmat%index(i-1)+1
827 tp=>btmat%A((j-1)*ndof2+1:j*ndof2)
828 vp=>v((jj-1)*ndof+1:jj*ndof)
832 tvp(k)=tvp(k)+tp(kl0+l)*vp(l)
846 type (hecmwst_local_matrix) :: btmat, bttmat
847 integer(kind=kint),
allocatable :: iws(:)
848 integer(kind=kint) :: ndof, n_mpc, i_mpc
849 integer(kind=kint) :: i, j, k, kk, ilag
850 integer(kind=kint) :: num_lagrange
851 real(kind=
kreal) :: t0, t1
855 outer:
do i=1,hecmesh%mpc%n_mpc
856 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
857 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
863 outer2:
do i=1,hecmesh%mpc%n_mpc
864 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
865 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer2
868 k=hecmesh%mpc%mpc_index(i-1)+1
869 kk=ndof*(hecmesh%mpc%mpc_item(k)-1)+hecmesh%mpc%mpc_dof(k)
876 if (timer >= 1)
write(0,
'(A,f10.4)')
"### hecmw_trimatmul_TtKT_mpc (1) : ",t1-t0
878 call make_btmat_mpc(hecmesh, ndof, btmat)
879 call debug_write_matrix(btmat,
'BTmat(MPC)', debug_matrix)
881 if (timer >= 1)
write(0,
'(A,f10.4)')
"### hecmw_trimatmul_TtKT_mpc (2) : ",t1-t0
890 call debug_write_matrix(bttmat,
'BTtmat(MPC)', debug_matrix)
894 do i=hecmesh%nn_internal+1, hecmesh%n_node
895 write(700+
hecmw_comm_get_rank(),*) i,hecmesh%node_ID(2*i-1),hecmesh%node_ID(2*i),hecmesh%global_node_ID(i)
899 if (timer >= 1)
write(0,
'(A,f10.4)')
"### hecmw_trimatmul_TtKT_mpc (3) : ",t1-t0
903 if (timer >= 1)
write(0,
'(A,f10.4)')
"### hecmw_trimatmul_TtKT_mpc (4) : ",t1-t0
907 do i=hecmesh%nn_internal+1, hecmesh%n_node
908 write(700+
hecmw_comm_get_rank(),*) i,hecmesh%node_ID(2*i-1),hecmesh%node_ID(2*i),hecmesh%global_node_ID(i)
912 if (
associated(hectkt%B))
deallocate(hectkt%B)
913 if (
associated(hectkt%X))
deallocate(hectkt%X)
914 num_lagrange =
size(hecmat%B) - hecmat%NP*ndof
915 allocate(hectkt%B(ndof*hectkt%NP + num_lagrange))
916 allocate(hectkt%X(ndof*hectkt%NP + num_lagrange))
919 do i=1, ndof*hecmat%NP
920 hectkt%B(i) = hecmat%B(i)
921 hectkt%X(i) = hecmat%X(i)
924 hectkt%B(ndof*hectkt%NP+i) = hecmat%B(ndof*hecmat%NP+i)
925 hectkt%X(ndof*hectkt%NP+i) = hecmat%X(ndof*hecmat%NP+i)
928 hectkt%X(iws(ilag)) = 0.d0
936 if (timer >= 1)
write(0,
'(A,f10.4)')
"### hecmw_trimatmul_TtKT_mpc (5) : ",t1-t0
939 subroutine make_btmat_mpc(hecMESH, ndof, BTmat)
942 integer(kind=kint),
intent(in) :: ndof
943 type (hecmwst_local_matrix),
intent(out) :: btmat
944 type (hecmwst_local_matrix) :: tmat
945 integer(kind=kint) :: n_mpc
946 integer(kind=kint) :: i,j,k,js,jj,kk
948 outer:
do i=1,hecmesh%mpc%n_mpc
949 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
950 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
954 tmat%nr=hecmesh%n_node*ndof
957 allocate(tmat%index(0:tmat%nr))
959 tmat%index(1:tmat%nr)=1
960 outer2:
do i=1,hecmesh%mpc%n_mpc
961 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
962 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer2
964 k=hecmesh%mpc%mpc_index(i-1)+1
965 kk=ndof*(hecmesh%mpc%mpc_item(k)-1)+hecmesh%mpc%mpc_dof(k)
966 tmat%index(kk)=hecmesh%mpc%mpc_index(i)-hecmesh%mpc%mpc_index(i-1)-1
971 tmat%index(i)=tmat%index(i-1)+tmat%index(i)
973 tmat%nnz=tmat%index(tmat%nr)
974 allocate(tmat%item(tmat%nnz), tmat%A(tmat%nnz))
982 outer3:
do i=1,hecmesh%mpc%n_mpc
983 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
984 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer3
986 k=hecmesh%mpc%mpc_index(i-1)+1
987 kk=ndof*(hecmesh%mpc%mpc_item(k)-1)+hecmesh%mpc%mpc_dof(k)
988 js=tmat%index(kk-1)+1
989 do j= hecmesh%mpc%mpc_index(i-1) + 2, hecmesh%mpc%mpc_index(i)
990 jj = ndof * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
992 tmat%A(js)=-hecmesh%mpc%mpc_val(j)
999 end subroutine make_btmat_mpc
1001 subroutine make_bttmat_mpc(hecMESH, ndof, BTtmat)
1004 integer(kind=kint),
intent(in) :: ndof
1005 type (hecmwst_local_matrix),
intent(out) :: bttmat
1006 type (hecmwst_local_matrix) :: ttmat
1007 integer(kind=kint) :: n_mpc
1008 integer(kind=kint) :: i,j,k,js,je,jj,kk
1009 integer(kind=kint),
allocatable :: iw(:)
1011 outer:
do i=1,hecmesh%mpc%n_mpc
1012 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
1013 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
1017 ttmat%nr=hecmesh%n_node*ndof
1020 allocate(ttmat%index(0:ttmat%nr))
1022 ttmat%index(1:ttmat%nr)=1
1023 outer2:
do i=1,hecmesh%mpc%n_mpc
1024 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
1025 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer2
1027 k=hecmesh%mpc%mpc_index(i-1)+1
1028 kk=ndof*(hecmesh%mpc%mpc_item(k)-1)+hecmesh%mpc%mpc_dof(k)
1030 do j= hecmesh%mpc%mpc_index(i-1) + 2, hecmesh%mpc%mpc_index(i)
1031 jj = ndof * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
1032 ttmat%index(jj)=ttmat%index(jj)+1
1038 ttmat%index(i)=ttmat%index(i-1)+ttmat%index(i)
1040 ttmat%nnz=ttmat%index(ttmat%nr)
1041 allocate(ttmat%item(ttmat%nnz), ttmat%A(ttmat%nnz))
1044 js=ttmat%index(i-1)+1
1052 allocate(iw(ttmat%nr))
1054 outer3:
do i=1,hecmesh%mpc%n_mpc
1055 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
1056 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer3
1058 k=hecmesh%mpc%mpc_index(i-1)+1
1059 kk=ndof*(hecmesh%mpc%mpc_item(k)-1)+hecmesh%mpc%mpc_dof(k)
1060 do j= hecmesh%mpc%mpc_index(i-1) + 2, hecmesh%mpc%mpc_index(i)
1061 jj = ndof * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
1062 js=ttmat%index(jj-1)+1+iw(jj)
1064 ttmat%A(js)=-hecmesh%mpc%mpc_val(j)
1072 end subroutine make_bttmat_mpc
1076 type (hecmwst_local_matrix),
intent(in) :: tmat
1077 type (hecmwst_local_matrix),
intent(out) :: ttmat
1078 integer(kind=kint),
allocatable :: iw(:)
1079 integer(kind=kint) :: i, j, jj, ndof, ndof2, k, idof, jdof
1080 allocate(iw(tmat%nc))
1083 do j = tmat%index(i-1)+1, tmat%index(i)
1090 ttmat%nnz = tmat%nnz
1091 ttmat%ndof = tmat%ndof
1094 allocate(ttmat%index(0:ttmat%nr))
1095 allocate(ttmat%item(ttmat%nnz))
1096 allocate(ttmat%A(ttmat%nnz*ndof2))
1099 ttmat%index(i) = ttmat%index(i-1) + iw(i)
1100 iw(i) = ttmat%index(i-1) + 1
1103 do j = tmat%index(i-1)+1, tmat%index(i)
1109 ttmat%A((k-1)*ndof2+(idof-1)*ndof+jdof) = &
1110 tmat%A((j-1)*ndof2+(jdof-1)*ndof+idof)
1118 function hecmw_localmat_equal(Tmat1, Tmat2)
1120 type (hecmwst_local_matrix),
intent(in) :: tmat1, tmat2
1121 integer(kind=kint) :: hecmw_localmat_equal
1122 integer(kind=kint) :: i, j, k0, k, ndof, ndof2
1123 hecmw_localmat_equal = 0
1124 if (tmat1%nr /= tmat2%nr)
return
1125 if (tmat1%nc /= tmat2%nc)
return
1126 if (tmat1%nnz /= tmat2%nnz)
return
1127 if (tmat1%ndof /= tmat2%ndof)
return
1131 if (tmat1%index(i) /= tmat2%index(i))
return
1132 do j = tmat1%index(i-1)+1, tmat1%index(i)
1133 if (tmat1%item(j) /= tmat2%item(j))
return
1136 if (tmat1%A(k0+k) /= tmat2%A(k0+k))
return
1140 hecmw_localmat_equal = 1
1141 end function hecmw_localmat_equal
1149 type (hecmwst_local_matrix),
intent(inout) :: btmat
1152 integer(kind=kint) :: nn_int, np, ndof, ndof2, nr_ext, nnz_ext
1153 integer(kind=kint),
allocatable :: exp_rows_index(:), exp_cols_index(:)
1154 integer(kind=kint),
allocatable :: exp_rows_item(:,:), exp_cols_item(:,:)
1155 type (hecmwst_local_matrix),
allocatable :: bt_ext(:)
1156 type (hecmwst_local_matrix) :: bt_int
1157 type (hecmwst_local_matrix) :: btnew
1159 if (debug >= 1)
write(0,*)
'DEBUG: nr,nc,nnz,ndof',btmat%nr,btmat%nc,btmat%nnz,btmat%ndof
1160 if (btmat%nr /= hecmesh%n_node) stop
'ERROR: invalid size in hecmw_localmat_assemble'
1162 nn_int = hecmesh%nn_internal
1167 nr_ext = np - nn_int
1168 nnz_ext = btmat%index(np) - btmat%index(nn_int)
1170 call prepare_bt_ext(btmat, hecmesh, exp_rows_index, exp_rows_item, bt_ext)
1171 if (debug >= 1)
write(0,*)
'DEBUG: prepare_BT_ext done'
1173 call prepare_column_info(hecmesh, bt_ext, exp_cols_index, exp_cols_item)
1174 if (debug >= 1)
write(0,*)
'DEBUG: prepare_column info done'
1176 call send_bt_ext_and_recv_bt_int(hecmesh, exp_rows_index, exp_rows_item, bt_ext, &
1177 exp_cols_index, exp_cols_item, bt_int, hecmeshnew)
1178 if (debug >= 1)
write(0,*)
'DEBUG: send BT_ext and recv BT_int done'
1182 if (debug >= 1)
write(0,*)
'DEBUG: localmat_add done'
1189 btmat%nnz = btnew%nnz
1190 btmat%ndof = btnew%ndof
1191 btmat%index => btnew%index
1192 btmat%item => btnew%item
1212 if (debug >= 1)
write(0,*)
'DEBUG: update BTmat and hecMESH done'
1215 subroutine prepare_bt_ext(BTmat, hecMESH, exp_rows_index, exp_rows_item, BT_ext)
1217 type (hecmwst_local_matrix),
intent(in) :: btmat
1219 integer(kind=kint),
allocatable,
intent(out) :: exp_rows_index(:)
1220 integer(kind=kint),
allocatable,
intent(out) :: exp_rows_item(:,:)
1221 type (hecmwst_local_matrix),
allocatable,
intent(out) :: bt_ext(:)
1222 integer(kind=kint),
allocatable :: incl_nz(:), exp_cols_per_row(:), exp_rows_per_rank(:)
1223 integer(kind=kint) :: nn_int
1224 logical,
parameter :: flg_check_nonzero_numerically = .true.
1225 nn_int = hecmesh%nn_internal
1227 if (flg_check_nonzero_numerically)
then
1230 call check_external_nz_blocks(btmat, nn_int, incl_nz)
1233 call incl_all_external_nz_blocks(btmat, nn_int, incl_nz)
1236 call count_ext_rows_with_nz(btmat, nn_int, incl_nz, exp_cols_per_row)
1238 call count_exp_rows_per_rank(hecmesh, exp_cols_per_row, exp_rows_per_rank)
1240 allocate(exp_rows_index(0:hecmesh%n_neighbor_pe))
1241 call make_index(hecmesh%n_neighbor_pe, exp_rows_per_rank, exp_rows_index)
1244 deallocate(exp_rows_per_rank)
1246 call make_exp_rows_item(hecmesh, exp_cols_per_row, exp_rows_index, exp_rows_item)
1248 deallocate(exp_cols_per_row)
1250 allocate(bt_ext(hecmesh%n_neighbor_pe))
1251 call extract_bt_ext(hecmesh, btmat, incl_nz, exp_rows_index, exp_rows_item, bt_ext)
1254 end subroutine prepare_bt_ext
1256 subroutine check_external_nz_blocks(BTmat, nn_internal, incl_nz)
1258 type (hecmwst_local_matrix),
intent(in) :: btmat
1259 integer(kind=kint),
intent(in) :: nn_internal
1260 integer(kind=kint),
allocatable,
intent(out) :: incl_nz(:)
1261 integer(kind=kint) :: ndof2, i0, nnz_ext, i, k, nnz_blk
1262 if (nn_internal > btmat%nr) stop
'ERROR: invalid nn_internal'
1263 ndof2 = btmat%ndof ** 2
1264 i0 = btmat%index(nn_internal)
1265 nnz_ext = btmat%index(btmat%nr) - i0
1266 allocate(incl_nz(nnz_ext))
1271 if (btmat%A(ndof2*(i0+i-1)+k) /= 0.0d0)
then
1273 nnz_blk = nnz_blk + 1
1278 if (debug >= 1)
write(0,*)
'DEBUG: nnz_blk',nnz_blk
1279 end subroutine check_external_nz_blocks
1281 subroutine incl_all_external_nz_blocks(BTmat, nn_internal, incl_nz)
1283 type (hecmwst_local_matrix),
intent(in) :: btmat
1284 integer(kind=kint),
intent(in) :: nn_internal
1285 integer(kind=kint),
allocatable,
intent(out) :: incl_nz(:)
1286 integer(kind=kint) :: i0, nnz_ext
1287 if (nn_internal > btmat%nr) stop
'ERROR: invalid nn_internal'
1288 i0 = btmat%index(nn_internal)
1289 nnz_ext = btmat%index(btmat%nr) - i0
1290 allocate(incl_nz(nnz_ext))
1291 incl_nz(1:nnz_ext) = 1
1292 end subroutine incl_all_external_nz_blocks
1294 subroutine count_ext_rows_with_nz(BTmat, nn_internal, incl_nz, exp_cols_per_row)
1296 type (hecmwst_local_matrix),
intent(in) :: btmat
1297 integer(kind=kint),
intent(in) :: nn_internal
1298 integer(kind=kint),
intent(in) :: incl_nz(:)
1299 integer(kind=kint),
allocatable,
intent(out) :: exp_cols_per_row(:)
1300 integer(kind=kint) :: nr_ext, nnz_int, i, irow, js, je, j, jcol
1301 nr_ext = btmat%nr - nn_internal
1302 nnz_int = btmat%index(nn_internal)
1303 allocate(exp_cols_per_row(nr_ext))
1304 exp_cols_per_row(:) = 0
1306 irow = nn_internal+i
1307 js = btmat%index(irow-1)+1
1308 je = btmat%index(irow)
1310 jcol = btmat%item(j)
1311 if (incl_nz(j-nnz_int) == 1) exp_cols_per_row(i) = exp_cols_per_row(i) + 1
1315 end subroutine count_ext_rows_with_nz
1317 subroutine count_exp_rows_per_rank(hecMESH, exp_cols_per_row, exp_rows_per_rank)
1320 integer(kind=kint),
intent(in) :: exp_cols_per_row(:)
1321 integer(kind=kint),
allocatable,
intent(out) :: exp_rows_per_rank(:)
1322 integer(kind=kint) :: nn_int, np, nr_ext, i, irow, exp_rank, idom
1323 allocate(exp_rows_per_rank(hecmesh%n_neighbor_pe))
1324 exp_rows_per_rank(1:hecmesh%n_neighbor_pe) = 0
1325 nn_int = hecmesh%nn_internal
1327 nr_ext = np - nn_int
1329 if (exp_cols_per_row(i) > 0)
then
1331 exp_rank = hecmesh%node_ID(2*irow)
1332 call rank_to_idom(hecmesh, exp_rank, idom)
1333 exp_rows_per_rank(idom) = exp_rows_per_rank(idom) + 1
1337 end subroutine count_exp_rows_per_rank
1339 subroutine rank_to_idom(hecMESH, rank, idom)
1342 integer(kind=kint),
intent(in) :: rank
1343 integer(kind=kint),
intent(out) :: idom
1344 integer(kind=kint) :: i
1345 do i = 1, hecmesh%n_neighbor_pe
1346 if (hecmesh%neighbor_pe(i) == rank)
then
1351 stop
'ERROR: exp_rank not found in neighbor_pe'
1352 end subroutine rank_to_idom
1354 subroutine make_index(len, cnt, index)
1356 integer(kind=kint),
intent(in) :: len
1357 integer(kind=kint),
intent(in) :: cnt(len)
1358 integer(kind=kint),
intent(out) :: index(0:)
1359 integer(kind=kint) :: i
1363 index(i) = index(i-1) + cnt(i)
1365 end subroutine make_index
1367 subroutine make_exp_rows_item(hecMESH, exp_cols_per_row, exp_rows_index, exp_rows_item)
1370 integer(kind=kint),
intent(in) :: exp_cols_per_row(:)
1371 integer(kind=kint),
allocatable,
intent(in) :: exp_rows_index(:)
1372 integer(kind=kint),
allocatable,
intent(out) :: exp_rows_item(:,:)
1373 integer(kind=kint),
allocatable :: cnt(:)
1374 integer(kind=kint) :: nn_int, np, nr_ext, i, irow, exp_rank, idom, idx
1375 allocate(exp_rows_item(2,exp_rows_index(hecmesh%n_neighbor_pe)))
1376 allocate(cnt(hecmesh%n_neighbor_pe))
1378 nn_int = hecmesh%nn_internal
1380 nr_ext = np - nn_int
1382 if (exp_cols_per_row(i) > 0)
then
1384 exp_rank = hecmesh%node_ID(2*irow)
1385 call rank_to_idom(hecmesh, exp_rank, idom)
1386 cnt(idom) = cnt(idom) + 1
1387 idx = exp_rows_index(idom-1) + cnt(idom)
1388 exp_rows_item(1,idx) = irow
1389 exp_rows_item(2,idx) = exp_cols_per_row(i)
1393 do idom = 1, hecmesh%n_neighbor_pe
1394 if (cnt(idom) /= exp_rows_index(idom)-exp_rows_index(idom-1)) stop
'ERROR: make exp_rows_item'
1398 end subroutine make_exp_rows_item
1400 subroutine extract_bt_ext(hecMESH, BTmat, incl_nz, exp_rows_index, exp_rows_item, BT_ext)
1403 type (hecmwst_local_matrix),
intent(in) :: btmat
1404 integer(kind=kint),
intent(in) :: incl_nz(:)
1405 integer(kind=kint),
allocatable,
intent(in) :: exp_rows_index(:)
1406 integer(kind=kint),
intent(in) :: exp_rows_item(:,:)
1407 type (hecmwst_local_matrix),
allocatable,
intent(out) :: bt_ext(:)
1408 integer(kind=kint) :: ndof, ndof2, nn_int, nnz_int, idom, j, idx, ncol, cnt, jrow, ks, ke, k, kcol
1409 allocate(bt_ext(hecmesh%n_neighbor_pe))
1412 nn_int = hecmesh%nn_internal
1413 nnz_int = btmat%index(nn_int)
1414 do idom = 1, hecmesh%n_neighbor_pe
1415 bt_ext(idom)%nr = exp_rows_index(idom) - exp_rows_index(idom-1)
1416 bt_ext(idom)%nc = btmat%nc
1417 bt_ext(idom)%nnz = 0
1418 bt_ext(idom)%ndof = ndof
1419 allocate(bt_ext(idom)%index(0:bt_ext(idom)%nr))
1420 bt_ext(idom)%index(0) = 0
1421 do j = 1, bt_ext(idom)%nr
1422 idx = exp_rows_index(idom-1) + j
1423 ncol = exp_rows_item(2,idx)
1424 bt_ext(idom)%index(j) = bt_ext(idom)%index(j-1) + ncol
1426 bt_ext(idom)%nnz = bt_ext(idom)%index(bt_ext(idom)%nr)
1427 if (debug >= 1)
write(0,*)
'DEBUG: idom,nr,nc,nnz,ndof', &
1428 idom,bt_ext(idom)%nr,bt_ext(idom)%nc,bt_ext(idom)%nnz,bt_ext(idom)%ndof
1429 allocate(bt_ext(idom)%item(bt_ext(idom)%nnz))
1430 allocate(bt_ext(idom)%A(bt_ext(idom)%nnz * ndof2))
1432 do j = 1, bt_ext(idom)%nr
1433 idx = exp_rows_index(idom-1) + j
1434 jrow = exp_rows_item(1,idx)
1435 if (jrow < 1 .or. btmat%nr < jrow) stop
'ERROR: extract BT_ext: jrow'
1436 ks = btmat%index(jrow-1)+1
1437 ke = btmat%index(jrow)
1439 kcol = btmat%item(k)
1440 if (incl_nz(k-nnz_int) == 0) cycle
1442 bt_ext(idom)%item(cnt) = kcol
1443 bt_ext(idom)%A(ndof2*(cnt-1)+1:ndof2*cnt) = btmat%A(ndof2*(k-1)+1:ndof2*k)
1445 if (cnt /= bt_ext(idom)%index(j)) stop
'ERROR: extract BT_ext'
1450 end subroutine extract_bt_ext
1452 subroutine prepare_column_info(hecMESH, BT_ext, exp_cols_index, exp_cols_item)
1455 type (hecmwst_local_matrix),
intent(in) :: bt_ext(:)
1456 integer(kind=kint),
allocatable,
intent(out) :: exp_cols_index(:)
1457 integer(kind=kint),
allocatable,
intent(out) :: exp_cols_item(:,:)
1459 call make_exp_cols_index(hecmesh%n_neighbor_pe, bt_ext, exp_cols_index)
1460 if (debug >= 2)
write(0,*)
' DEBUG2: make exp_cols_index done'
1461 if (debug >= 3)
write(0,*)
' DEBUG3: exp_cols_index', exp_cols_index(0:hecmesh%n_neighbor_pe)
1465 call make_exp_cols_item(hecmesh, bt_ext, exp_cols_index, exp_cols_item)
1466 if (debug >= 2)
write(0,*)
' DEBUG2: make exp_cols_item done'
1468 end subroutine prepare_column_info
1470 subroutine make_exp_cols_index(nnb, BT_ext, exp_cols_index)
1472 integer(kind=kint),
intent(in) :: nnb
1473 type (hecmwst_local_matrix),
intent(in) :: bt_ext(:)
1474 integer(kind=kint),
allocatable,
intent(out) :: exp_cols_index(:)
1475 integer(kind=kint) :: idom
1476 allocate(exp_cols_index(0:nnb))
1477 exp_cols_index(0) = 0
1479 exp_cols_index(idom) = exp_cols_index(idom-1) + bt_ext(idom)%nnz
1481 end subroutine make_exp_cols_index
1483 subroutine make_exp_cols_item(hecMESH, BT_ext, exp_cols_index, exp_cols_item)
1486 type (hecmwst_local_matrix),
intent(in) :: bt_ext(:)
1487 integer(kind=kint),
allocatable,
intent(in) :: exp_cols_index(:)
1488 integer(kind=kint),
allocatable,
intent(out) :: exp_cols_item(:,:)
1489 integer(kind=kint) :: cnt, idom, j, jcol
1490 allocate(exp_cols_item(cncol_item,exp_cols_index(hecmesh%n_neighbor_pe)))
1492 do idom = 1, hecmesh%n_neighbor_pe
1493 do j = 1, bt_ext(idom)%nnz
1495 jcol = bt_ext(idom)%item(j)
1501 exp_cols_item(clid,cnt) = hecmesh%node_ID(2*jcol-1)
1502 exp_cols_item(crank,cnt) = hecmesh%node_ID(2*jcol)
1503 if (cncol_item >= 3) exp_cols_item(cgid,cnt) = hecmesh%global_node_ID(jcol)
1506 if (cnt /= exp_cols_index(idom)) stop
'ERROR: make exp_cols_item'
1508 end subroutine make_exp_cols_item
1510 subroutine send_bt_ext_and_recv_bt_int(hecMESH, exp_rows_index, exp_rows_item, BT_ext, &
1511 exp_cols_index, exp_cols_item, BT_int, hecMESHnew)
1514 integer(kind=kint),
allocatable,
intent(inout) :: exp_rows_index(:), exp_cols_index(:)
1515 integer(kind=kint),
allocatable,
intent(inout) :: exp_rows_item(:,:), exp_cols_item(:,:)
1516 type (hecmwst_local_matrix),
allocatable,
intent(inout) :: bt_ext(:)
1517 type (hecmwst_local_matrix),
intent(out) :: bt_int
1519 integer(kind=kint),
allocatable :: imp_rows_index(:), imp_cols_index(:)
1520 integer(kind=kint),
allocatable :: imp_rows_item(:,:), imp_cols_item(:,:)
1521 real(kind=
kreal),
allocatable :: imp_vals_item(:)
1522 integer(kind=kint),
allocatable :: map(:), add_nodes(:,:)
1523 integer(kind=kint) :: ndof, ndof2, idom, n_add_node, i0
1524 if (hecmesh%n_neighbor_pe == 0)
return
1525 ndof = bt_ext(1)%ndof
1528 call convert_rowid_to_remote_localid(hecmesh, exp_rows_index(hecmesh%n_neighbor_pe), exp_rows_item)
1529 if (debug >= 2)
write(0,*)
' DEBUG2: convert rowID to remote localID done'
1531 call send_recv_bt_ext_nr_nnz(hecmesh, bt_ext, imp_rows_index, imp_cols_index)
1532 if (debug >= 2)
write(0,*)
' DEBUG2: send recv BT_ext nr and nnz done'
1535 exp_rows_index, exp_cols_index, exp_rows_item, exp_cols_item, &
1536 imp_rows_index, imp_cols_index, &
1537 imp_rows_item, imp_cols_item, imp_vals_item)
1538 if (debug >= 2)
write(0,*)
' DEBUG2: send recv BT_ext contents done'
1540 do idom = 1, hecmesh%n_neighbor_pe
1545 call allocate_bt_int(hecmesh, ndof, imp_rows_index, imp_rows_item, bt_int)
1546 if (debug >= 2)
write(0,*)
' DEBUG2: allocate BT_int done'
1551 call map_imported_cols(hecmeshnew, imp_cols_index(hecmesh%n_neighbor_pe), &
1552 imp_cols_item, n_add_node, add_nodes, map, i0)
1553 if (debug >= 2)
write(0,*)
' DEBUG2: map imported cols done'
1555 call update_comm_table(hecmeshnew, n_add_node, add_nodes, i0)
1556 if (debug >= 2)
write(0,*)
' DEBUG2: update comm_table done'
1558 bt_int%nc = hecmeshnew%n_node
1560 call copy_vals_to_bt_int(hecmesh%n_neighbor_pe, imp_rows_index, imp_cols_index, &
1561 imp_rows_item, map, ndof2, imp_vals_item, bt_int)
1562 if (debug >= 2)
write(0,*)
' DEBUG2: copy vals to BT_int done'
1564 deallocate(imp_rows_index)
1565 deallocate(imp_cols_index)
1566 deallocate(imp_rows_item)
1567 deallocate(imp_cols_item)
1568 deallocate(imp_vals_item)
1571 call sort_and_uniq_rows(bt_int)
1572 if (debug >= 2)
write(0,*)
' DEBUG2: sort and uniq rows of BT_int done'
1573 end subroutine send_bt_ext_and_recv_bt_int
1575 subroutine convert_rowid_to_remote_localid(hecMESH, len, exp_rows_item)
1578 integer(kind=kint),
intent(in) :: len
1579 integer(kind=kint),
intent(out) :: exp_rows_item(:,:)
1580 integer(kind=kint) :: i
1582 exp_rows_item(1,i) = hecmesh%node_ID(2 * exp_rows_item(1,i) - 1)
1584 end subroutine convert_rowid_to_remote_localid
1586 subroutine send_recv_bt_ext_nr_nnz(hecMESH, BT_ext, imp_rows_index, imp_cols_index)
1590 type (hecmwst_local_matrix),
intent(in) :: bt_ext(:)
1591 integer(kind=kint),
allocatable,
intent(out) :: imp_rows_index(:), imp_cols_index(:)
1592 integer(kind=kint) :: nnb, idom, irank, tag, recvbuf(2)
1593 integer(kind=kint),
allocatable :: sendbuf(:,:)
1594 integer(kind=kint),
allocatable :: requests(:)
1595 integer(kind=kint),
allocatable :: statuses(:,:)
1596 nnb = hecmesh%n_neighbor_pe
1597 allocate(imp_rows_index(0:nnb))
1598 allocate(imp_cols_index(0:nnb))
1599 allocate(requests(nnb))
1601 allocate(sendbuf(2,nnb))
1603 irank = hecmesh%neighbor_pe(idom)
1605 sendbuf(1,idom) = bt_ext(idom)%nr
1606 sendbuf(2,idom) = bt_ext(idom)%nnz
1608 call hecmw_isend_int(sendbuf(1,idom), 2, irank, tag, hecmesh%MPI_COMM, &
1611 imp_rows_index(0) = 0
1612 imp_cols_index(0) = 0
1614 irank = hecmesh%neighbor_pe(idom)
1617 hecmesh%MPI_COMM, statuses(:,1))
1618 imp_rows_index(idom) = imp_rows_index(idom-1) + recvbuf(1)
1619 imp_cols_index(idom) = imp_cols_index(idom-1) + recvbuf(2)
1622 deallocate(requests)
1623 deallocate(statuses)
1625 end subroutine send_recv_bt_ext_nr_nnz
1628 exp_rows_index, exp_cols_index, exp_rows_item, exp_cols_item, &
1629 imp_rows_index, imp_cols_index, &
1630 imp_rows_item, imp_cols_item, imp_vals_item)
1633 type (hecmwST_local_mesh),
intent(in) :: hecMESH
1634 type (hecmwST_local_matrix),
intent(in) :: BT_ext(:)
1635 integer(kind=kint),
allocatable,
intent(inout) :: exp_rows_index(:), exp_cols_index(:)
1636 integer(kind=kint),
allocatable,
intent(inout) :: exp_rows_item(:,:), exp_cols_item(:,:)
1637 integer(kind=kint),
allocatable,
intent(in) :: imp_rows_index(:), imp_cols_index(:)
1638 integer(kind=kint),
allocatable,
intent(out) :: imp_rows_item(:,:), imp_cols_item(:,:)
1639 real(kind=
kreal),
allocatable,
intent(out) :: imp_vals_item(:)
1640 integer(kind=kint) :: nnb, ndof2, n_send, idom, irank, tag, nr, nnz
1641 integer(kind=kint),
allocatable :: requests(:)
1642 integer(kind=kint),
allocatable :: statuses(:,:)
1643 nnb = hecmesh%n_neighbor_pe
1645 ndof2 = bt_ext(1)%ndof ** 2
1646 allocate(imp_rows_item(2,imp_rows_index(nnb)))
1647 allocate(imp_cols_item(cncol_item,imp_cols_index(nnb)))
1648 allocate(imp_vals_item(ndof2*imp_cols_index(nnb)))
1649 allocate(requests(3*nnb))
1653 irank = hecmesh%neighbor_pe(idom)
1654 if (bt_ext(idom)%nr > 0)
then
1658 2*bt_ext(idom)%nr, irank, tag, hecmesh%MPI_COMM, &
1663 cncol_item*bt_ext(idom)%nnz, irank, tag, hecmesh%MPI_COMM, &
1667 call hecmw_isend_r(bt_ext(idom)%A, ndof2*bt_ext(idom)%nnz, irank, &
1668 tag, hecmesh%MPI_COMM, requests(n_send))
1672 irank = hecmesh%neighbor_pe(idom)
1673 nr = imp_rows_index(idom) - imp_rows_index(idom-1)
1674 nnz = imp_cols_index(idom) - imp_cols_index(idom-1)
1678 2*nr, irank, tag, hecmesh%MPI_COMM, statuses(:,1))
1681 cncol_item*nnz, irank, tag, hecmesh%MPI_COMM, statuses(:,1))
1683 call hecmw_recv_r(imp_vals_item(ndof2*imp_cols_index(idom-1)+1), &
1684 ndof2*nnz, irank, tag, hecmesh%MPI_COMM, statuses(:,1))
1688 deallocate(exp_rows_index)
1689 deallocate(exp_rows_item)
1690 deallocate(exp_cols_index)
1691 deallocate(exp_cols_item)
1694 subroutine allocate_bt_int(hecMESH, ndof, imp_rows_index, imp_rows_item, BT_int)
1696 type (hecmwST_local_mesh),
intent(in) :: hecMESH
1697 integer(kind=kint),
intent(in) :: ndof
1698 integer(kind=kint),
allocatable,
intent(in) :: imp_rows_index(:), imp_rows_item(:,:)
1699 type (hecmwST_local_matrix),
intent(out) :: BT_int
1700 integer(kind=kint),
allocatable :: cnt(:)
1701 integer(kind=kint) :: idom, is, ie, i, irow, ncol, ndof2
1703 bt_int%nr = hecmesh%nn_internal
1704 bt_int%nc = hecmesh%n_node
1707 allocate(cnt(bt_int%nr))
1709 do idom = 1, hecmesh%n_neighbor_pe
1710 is = imp_rows_index(idom-1)+1
1711 ie = imp_rows_index(idom)
1713 irow = imp_rows_item(1,i)
1714 ncol = imp_rows_item(2,i)
1715 if (irow < 1 .or. bt_int%nr < irow) stop
'ERROR: allocate BT_int'
1716 cnt(irow) = cnt(irow) + ncol
1720 allocate(bt_int%index(0:bt_int%nr))
1721 call make_index(bt_int%nr, cnt, bt_int%index)
1723 bt_int%nnz = bt_int%index(bt_int%nr)
1724 allocate(bt_int%item(bt_int%nnz))
1725 allocate(bt_int%A(bt_int%nnz * ndof2))
1729 subroutine copy_mesh(src, dst)
1731 type (hecmwST_local_mesh),
intent(in) :: src
1732 type (hecmwST_local_mesh),
intent(out) :: dst
1734 dst%MPI_COMM = src%MPI_COMM
1735 dst%PETOT = src%PETOT
1736 dst%PEsmpTOT = src%PEsmpTOT
1737 dst%my_rank = src%my_rank
1738 dst%n_subdomain = src%n_subdomain
1739 dst%n_node = src%n_node
1740 dst%nn_internal = src%nn_internal
1741 dst%n_dof = src%n_dof
1742 dst%n_neighbor_pe = src%n_neighbor_pe
1743 allocate(dst%neighbor_pe(dst%n_neighbor_pe))
1744 dst%neighbor_pe(:) = src%neighbor_pe(:)
1745 allocate(dst%import_index(0:dst%n_neighbor_pe))
1746 allocate(dst%export_index(0:dst%n_neighbor_pe))
1747 dst%import_index(:)= src%import_index(:)
1748 dst%export_index(:)= src%export_index(:)
1749 allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
1750 dst%import_item(:) = src%import_item(:)
1751 allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
1752 dst%export_item(:) = src%export_item(:)
1753 allocate(dst%node_ID(2*dst%n_node))
1754 dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*src%n_node)
1755 allocate(dst%global_node_ID(dst%n_node))
1756 dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:src%n_node)
1758 dst%node => src%node
1759 end subroutine copy_mesh
1761 subroutine map_imported_cols(hecMESHnew, ncols, cols, n_add_node, add_nodes, map, i0)
1763 type (hecmwST_local_mesh),
intent(inout) :: hecMESHnew
1764 integer(kind=kint),
intent(in) :: ncols
1765 integer(kind=kint),
intent(in) :: cols(cNCOL_ITEM,ncols)
1766 integer(kind=kint),
allocatable,
intent(out) :: map(:)
1767 integer(kind=kint),
intent(out) :: n_add_node
1768 integer(kind=kint),
allocatable,
intent(out) :: add_nodes(:,:)
1769 integer(kind=kint),
intent(out) :: i0
1770 allocate(map(ncols))
1772 call map_present_nodes(hecmeshnew, ncols, cols, map, n_add_node)
1776 call extract_add_nodes(ncols, cols, map, n_add_node, add_nodes)
1778 call append_nodes(hecmeshnew, n_add_node, add_nodes, i0)
1780 call map_additional_nodes(ncols, cols, n_add_node, add_nodes, i0, map)
1781 end subroutine map_imported_cols
1783 subroutine map_present_nodes(hecMESH, ncols, cols, map, n_add_node)
1785 type (hecmwST_local_mesh),
intent(in) :: hecMESH
1786 integer(kind=kint),
intent(in) :: ncols
1787 integer(kind=kint),
intent(in) :: cols(cNCOL_ITEM,ncols)
1788 integer(kind=kint),
intent(out) :: map(ncols)
1789 integer(kind=kint),
intent(out) :: n_add_node
1790 integer(kind=kint) :: i, j, lid, rank, llid, n_ext_node, idx
1791 integer(kind=kint),
allocatable :: ext_node(:)
1792 type (hecmwST_pair_array) :: parray
1795 do i = hecmesh%nn_internal + 1, hecmesh%n_node
1802 allocate(ext_node(ncols))
1810 rank = cols(crank,i)
1812 if (rank == hecmesh%my_rank)
then
1816 n_ext_node = n_ext_node + 1
1824 do j = 1, n_ext_node
1827 rank = cols(crank,i)
1834 n_add_node = n_add_node + 1
1839 deallocate(ext_node)
1842 end subroutine map_present_nodes
1844 subroutine extract_add_nodes(ncols, cols, map, n_add_node, add_nodes)
1846 integer(kind=kint),
intent(in) :: ncols
1847 integer(kind=kint),
intent(in) :: cols(cNCOL_ITEM,ncols), map(ncols)
1848 integer(kind=kint),
intent(inout) :: n_add_node
1849 integer(kind=kint),
allocatable,
intent(out) :: add_nodes(:,:)
1850 integer(kind=kint) :: cnt, i
1851 allocate(add_nodes(cncol_item,n_add_node))
1854 if (map(i) == -1)
then
1856 add_nodes(1:cncol_item,cnt) = cols(1:cncol_item,i)
1859 if (cnt /= n_add_node) stop
'ERROR: extract add_nodes'
1860 call sort_and_uniq_add_nodes(n_add_node, add_nodes)
1861 end subroutine extract_add_nodes
1863 subroutine sort_and_uniq_add_nodes(n_add_node, add_nodes)
1865 integer(kind=kint),
intent(inout) :: n_add_node
1866 integer(kind=kint),
intent(inout) :: add_nodes(cNCOL_ITEM,n_add_node)
1867 integer(kind=kint) :: ndup
1868 call sort_add_nodes(add_nodes, 1, n_add_node)
1869 call uniq_add_nodes(add_nodes, n_add_node, ndup)
1870 n_add_node = n_add_node - ndup
1871 end subroutine sort_and_uniq_add_nodes
1873 recursive subroutine sort_add_nodes(add_nodes, id1, id2)
1875 integer(kind=kint),
intent(inout) :: add_nodes(:,:)
1876 integer(kind=kint),
intent(in) :: id1, id2
1877 integer(kind=kint) :: center, left, right
1878 integer(kind=kint) :: pivot(cNCOL_ITEM), tmp(cNCOL_ITEM)
1879 if (id1 >= id2)
return
1880 center = (id1 + id2) / 2
1881 pivot(1:cncol_item) = add_nodes(1:cncol_item,center)
1885 do while ((add_nodes(crank,left) < pivot(crank)) .or. &
1886 (add_nodes(crank,left) == pivot(crank) .and. add_nodes(clid,left) < pivot(clid)))
1889 do while ((pivot(crank) < add_nodes(crank,right)) .or. &
1890 (pivot(crank) == add_nodes(crank,right) .and. pivot(clid) < add_nodes(clid,right)))
1893 if (left >= right)
exit
1894 tmp(1:cncol_item) = add_nodes(1:cncol_item,left)
1895 add_nodes(1:cncol_item,left) = add_nodes(1:cncol_item,right)
1896 add_nodes(1:cncol_item,right) = tmp(1:cncol_item)
1900 if (id1 < left-1)
call sort_add_nodes(add_nodes, id1, left-1)
1901 if (right+1 < id2)
call sort_add_nodes(add_nodes, right+1, id2)
1903 end subroutine sort_add_nodes
1905 subroutine uniq_add_nodes(add_nodes, len, ndup)
1907 integer(kind=kint),
intent(inout) :: add_nodes(:,:)
1908 integer(kind=kint),
intent(in) :: len
1909 integer(kind=kint),
intent(out) :: ndup
1910 integer(kind=kint) :: i
1913 if (add_nodes(clid,i) == add_nodes(clid,i-1-ndup) .and. &
1914 add_nodes(crank,i) == add_nodes(crank,i-1-ndup))
then
1916 else if (ndup > 0)
then
1917 add_nodes(1:cncol_item,i-ndup) = add_nodes(1:cncol_item,i)
1920 end subroutine uniq_add_nodes
1922 subroutine search_add_nodes(n_add_node, add_nodes, rank, lid, idx)
1924 integer(kind=kint),
intent(in) :: n_add_node
1925 integer(kind=kint),
intent(in) :: add_nodes(cNCOL_ITEM,n_add_node)
1926 integer(kind=kint),
intent(in) :: rank
1927 integer(kind=kint),
intent(in) :: lid
1928 integer(kind=kint),
intent(out) :: idx
1929 integer(kind=kint) :: left, right, center
1932 do while (left <= right)
1933 center = (left + right) / 2
1934 if ((rank == add_nodes(crank,center)) .and. (lid == add_nodes(clid,center)))
then
1937 else if ((rank < add_nodes(crank,center)) .or. &
1938 (rank == add_nodes(crank,center) .and. lid < add_nodes(clid,center)))
then
1940 else if ((add_nodes(crank,center) < rank) .or. &
1941 (add_nodes(crank,center) == rank .and. add_nodes(clid,center) < lid))
then
1946 end subroutine search_add_nodes
1948 subroutine append_nodes(hecMESHnew, n_add_node, add_nodes, i0)
1950 type (hecmwST_local_mesh),
intent(inout) :: hecMESHnew
1951 integer(kind=kint),
intent(in) :: n_add_node
1952 integer(kind=kint),
intent(in) :: add_nodes(:,:)
1953 integer(kind=kint),
intent(out) :: i0
1954 integer(kind=kint) :: n_node, i, ii
1955 integer(kind=kint),
pointer :: node_ID(:), global_node_ID(:)
1956 i0 = hecmeshnew%n_node
1957 n_node = hecmeshnew%n_node + n_add_node
1958 allocate(node_id(2*n_node))
1959 allocate(global_node_id(n_node))
1960 do i = 1, hecmeshnew%n_node
1961 node_id(2*i-1) = hecmeshnew%node_ID(2*i-1)
1962 node_id(2*i ) = hecmeshnew%node_ID(2*i )
1963 global_node_id(i) = hecmeshnew%global_node_ID(i)
1965 do i = 1, n_add_node
1966 ii = hecmeshnew%n_node + i
1967 node_id(2*ii-1) = add_nodes(clid,i)
1968 node_id(2*ii ) = add_nodes(crank,i)
1969 if (cncol_item >= 3)
then
1970 global_node_id(ii) = add_nodes(cgid,i)
1972 global_node_id(ii) = -1
1975 deallocate(hecmeshnew%node_ID)
1976 deallocate(hecmeshnew%global_node_ID)
1977 hecmeshnew%n_node = n_node
1978 hecmeshnew%node_ID => node_id
1979 hecmeshnew%global_node_ID => global_node_id
1980 end subroutine append_nodes
1982 subroutine map_additional_nodes(ncols, cols, n_add_node, add_nodes, i0, map)
1984 integer(kind=kint),
intent(in) :: ncols
1985 integer(kind=kint),
intent(in) :: cols(cNCOL_ITEM,ncols)
1986 integer(kind=kint),
intent(in) :: n_add_node
1987 integer(kind=kint),
intent(in) :: add_nodes(cNCOL_ITEM,n_add_node)
1988 integer(kind=kint),
intent(in) :: i0
1989 integer(kind=kint),
intent(inout) :: map(ncols)
1990 integer(kind=kint) :: i, j
1992 if (map(i) > 0) cycle
1993 call search_add_nodes(n_add_node, add_nodes, cols(crank,i), cols(clid,i), j)
1994 if (j == -1) stop
'ERROR: map_additional_nodes'
1997 end subroutine map_additional_nodes
1999 subroutine update_comm_table(hecMESHnew, n_add_node, add_nodes, i0)
2002 type (hecmwST_local_mesh),
intent(inout) :: hecMESHnew
2003 integer(kind=kint),
intent(in) :: n_add_node
2004 integer(kind=kint),
allocatable,
intent(inout) :: add_nodes(:,:)
2005 integer(kind=kint),
intent(in) :: i0
2006 integer(kind=kint),
allocatable :: n_add_imp(:), add_imp_index(:)
2007 integer(kind=kint),
allocatable :: add_imp_item_remote(:), add_imp_item_local(:)
2008 integer(kind=kint),
allocatable :: n_add_exp(:), add_exp_index(:), add_exp_item(:)
2009 integer(kind=kint),
allocatable :: n_new_imp(:), n_new_exp(:)
2010 integer(kind=kint) :: npe, nnb, comm, new_nnb
2011 integer(kind=kint),
pointer :: nbpe(:), new_nbpe(:)
2012 integer(kind=kint),
pointer :: import_index(:), export_index(:), import_item(:), export_item(:)
2013 integer(kind=kint),
pointer :: new_import_index(:), new_export_index(:)
2014 integer(kind=kint),
pointer :: new_import_item(:), new_export_item(:)
2015 npe = hecmeshnew%PETOT
2016 nnb = hecmeshnew%n_neighbor_pe
2017 comm = hecmeshnew%MPI_COMM
2018 nbpe => hecmeshnew%neighbor_pe
2019 import_index => hecmeshnew%import_index
2020 export_index => hecmeshnew%export_index
2021 import_item => hecmeshnew%import_item
2022 export_item => hecmeshnew%export_item
2025 if (debug >= 3)
write(0,*)
' DEBUG3: count add_imp per rank done'
2027 allocate(add_imp_index(0:npe))
2028 call make_index(npe, n_add_imp, add_imp_index)
2029 if (debug >= 3)
write(0,*)
' DEBUG3: make add_imp_index done'
2031 call make_add_imp_item(n_add_node, add_nodes, npe, i0, add_imp_index, &
2032 add_imp_item_remote, add_imp_item_local)
2033 if (debug >= 3)
write(0,*)
' DEBUG3: make add_imp_item done'
2035 deallocate(add_nodes)
2039 allocate(n_add_exp(npe))
2041 if (debug >= 3)
write(0,*)
' DEBUG3: alltoall n_add_imp to n_add_exp done'
2043 allocate(add_exp_index(0:npe))
2044 call make_index(npe, n_add_exp, add_exp_index)
2045 if (debug >= 3)
write(0,*)
' DEBUG3: make add_exp_index done'
2047 call send_recv_add_imp_exp_item(npe, add_imp_index, add_imp_item_remote, &
2048 add_exp_index, add_exp_item, comm)
2049 if (debug >= 3)
write(0,*)
' DEBUG3: send recv add_imp/exp_item done'
2054 if (debug >= 3)
write(0,*)
' DEBUG3: count new comm_nodes (import) done'
2059 if (debug >= 3)
write(0,*)
' DEBUG3: count new comm_nodes (export) done'
2061 call update_neighbor_pe(npe, n_new_imp, n_new_exp, new_nnb, new_nbpe)
2062 if (debug >= 3)
write(0,*)
' DEBUG3: update neighbor_pe done'
2066 call merge_comm_table(npe, nnb, nbpe, import_index, import_item, &
2067 new_nnb, new_nbpe, add_imp_index, add_imp_item_local, n_add_imp, n_new_imp, &
2068 new_import_index, new_import_item)
2069 if (debug >= 3)
write(0,*)
' DEBUG3: merge comm_table (import) done'
2071 deallocate(n_add_imp)
2072 deallocate(add_imp_index)
2073 deallocate(add_imp_item_remote, add_imp_item_local)
2074 deallocate(n_new_imp)
2078 call merge_comm_table(npe, nnb, nbpe, export_index, export_item, &
2079 new_nnb, new_nbpe, add_exp_index, add_exp_item, n_add_exp, n_new_exp, &
2080 new_export_index, new_export_item)
2081 if (debug >= 3)
write(0,*)
' DEBUG3: merge comm_table (export) done'
2083 deallocate(n_add_exp)
2084 deallocate(add_exp_index)
2085 deallocate(add_exp_item)
2086 deallocate(n_new_exp)
2089 deallocate(import_index,import_item)
2090 deallocate(export_index,export_item)
2091 hecmeshnew%n_neighbor_pe = new_nnb
2092 hecmeshnew%neighbor_pe => new_nbpe
2093 hecmeshnew%import_index => new_import_index
2094 hecmeshnew%export_index => new_export_index
2095 hecmeshnew%import_item => new_import_item
2096 hecmeshnew%export_item => new_export_item
2097 end subroutine update_comm_table
2101 integer(kind=kint),
intent(in) :: n_add_node
2102 integer(kind=kint),
intent(in) :: add_nodes(cNCOL_ITEM,n_add_node)
2103 integer(kind=kint),
intent(in) :: npe
2104 integer(kind=kint),
allocatable,
intent(out) :: n_add_imp(:)
2105 integer(kind=kint) :: i, rank
2106 allocate(n_add_imp(npe))
2108 do i = 1, n_add_node
2109 rank = add_nodes(crank,i)
2110 n_add_imp(rank+1) = n_add_imp(rank+1) + 1
2114 subroutine make_add_imp_item(n_add_node, add_nodes, npe, i0, add_imp_index, &
2115 add_imp_item_remote, add_imp_item_local)
2117 integer(kind=kint),
intent(in) :: n_add_node
2118 integer(kind=kint),
intent(in) :: add_nodes(cNCOL_ITEM,n_add_node)
2119 integer(kind=kint),
intent(in) :: npe, i0
2120 integer(kind=kint),
allocatable,
intent(in) :: add_imp_index(:)
2121 integer(kind=kint),
allocatable,
intent(out) :: add_imp_item_remote(:), add_imp_item_local(:)
2122 integer(kind=kint),
allocatable :: cnt(:)
2123 integer(kind=kint) :: i, lid, rank, ipe
2124 allocate(add_imp_item_remote(add_imp_index(npe)))
2125 allocate(add_imp_item_local(add_imp_index(npe)))
2128 do i = 1, n_add_node
2129 lid = add_nodes(clid,i)
2130 rank = add_nodes(crank,i)
2132 cnt(ipe) = cnt(ipe) + 1
2133 add_imp_item_remote(add_imp_index(ipe-1) + cnt(ipe)) = lid
2134 add_imp_item_local(add_imp_index(ipe-1) + cnt(ipe)) = i0 + i
2137 end subroutine make_add_imp_item
2139 subroutine send_recv_add_imp_exp_item(npe, add_imp_index, add_imp_item_remote, &
2140 add_exp_index, add_exp_item, mpi_comm)
2143 integer(kind=kint),
intent(in) :: npe
2144 integer(kind=kint),
allocatable,
intent(in) :: add_imp_index(:), add_imp_item_remote(:)
2145 integer(kind=kint),
allocatable,
intent(in) :: add_exp_index(:)
2146 integer(kind=kint),
allocatable,
intent(out) :: add_exp_item(:)
2147 integer(kind=kint),
intent(in) :: mpi_comm
2148 integer(kind=kint) :: n_send, i, irank, is, ie, len, tag
2149 integer(kind=kint),
allocatable :: requests(:)
2150 integer(kind=kint),
allocatable :: statuses(:,:)
2151 allocate(add_exp_item(add_exp_index(npe)))
2152 allocate(requests(npe))
2157 is = add_imp_index(i-1)+1
2158 ie = add_imp_index(i)
2164 mpi_comm, requests(n_send))
2169 is = add_exp_index(i-1)+1
2170 ie = add_exp_index(i)
2175 mpi_comm, statuses(:,1))
2178 end subroutine send_recv_add_imp_exp_item
2182 integer(kind=kint),
intent(in) :: npe, org_nnb
2184 integer(kind=kint),
pointer,
intent(in) :: org_nbpe(:), org_index(:)
2185 integer(kind=kint),
intent(in) :: n_add(:)
2186 integer(kind=kint),
allocatable,
intent(out) :: n_new(:)
2187 integer(kind=kint) :: i, irank, n_org
2188 allocate(n_new(npe))
2192 n_org = org_index(i) - org_index(i-1)
2193 n_new(irank+1) = n_new(irank+1) + n_org
2197 subroutine update_neighbor_pe(npe, n_new_imp, n_new_exp, &
2200 integer(kind=kint),
intent(in) :: npe
2201 integer(kind=kint),
intent(in) :: n_new_imp(npe), n_new_exp(npe)
2202 integer(kind=kint),
intent(out) :: new_nnb
2203 integer(kind=kint),
pointer,
intent(out) :: new_nbpe(:)
2204 integer(kind=kint) :: i
2207 if (n_new_imp(i) > 0 .or. n_new_exp(i) > 0) new_nnb = new_nnb+1
2209 allocate(new_nbpe(new_nnb))
2212 if (n_new_imp(i) > 0 .or. n_new_exp(i) > 0)
then
2214 new_nbpe(new_nnb) = i-1
2217 end subroutine update_neighbor_pe
2219 subroutine merge_comm_table(npe, org_nnb, org_nbpe, org_index, org_item, &
2220 new_nnb, new_nbpe, add_index, add_item, n_add, n_new, new_index, new_item)
2222 integer(kind=kint),
intent(in) :: npe, org_nnb
2224 integer(kind=kint),
pointer,
intent(in) :: org_nbpe(:), org_index(:), org_item(:)
2225 integer(kind=kint),
intent(in) :: new_nnb
2227 integer(kind=kint),
pointer,
intent(in) :: new_nbpe(:)
2228 integer(kind=kint),
allocatable,
intent(in) :: add_index(:), add_item(:)
2229 integer(kind=kint),
intent(in) :: n_add(npe), n_new(npe)
2230 integer(kind=kint),
pointer,
intent(out) :: new_index(:), new_item(:)
2231 integer(kind=kint),
allocatable :: cnt(:)
2232 integer(kind=kint) :: i, irank, j, jrank, i0, j0, len
2235 allocate(new_index(0:new_nnb))
2239 new_index(i) = new_index(i-1) + n_new(irank+1)
2241 allocate(new_item(new_index(new_nnb)))
2247 if (org_index(i) - org_index(i-1) == 0) cycle
2249 do while (jrank < irank)
2251 if (j > new_nnb)
exit
2254 if (jrank /= irank) stop
'ERROR: merging comm table: org into new'
2256 len = org_index(i) - i0
2258 new_item(j0+1:j0+len) = org_item(i0+1:i0+len)
2264 if (n_add(i) == 0) cycle
2266 do while (jrank < irank)
2270 if (jrank /= irank) stop
'ERROR: merging comm table: add into new'
2272 len = add_index(i) - i0
2273 j0 = new_index(j-1) + cnt(jrank+1)
2274 new_item(j0+1:j0+len) = add_item(i0+1:i0+len)
2275 cnt(jrank+1) = cnt(jrank+1) + len
2276 if (cnt(jrank+1) /= new_index(j)-new_index(j-1)) stop
'ERROR: merging comm table'
2279 end subroutine merge_comm_table
2281 subroutine copy_vals_to_bt_int(nnb, imp_rows_index, imp_cols_index, &
2282 imp_rows_item, map, ndof2, imp_vals_item, BT_int)
2284 integer(kind=kint),
intent(in) :: nnb
2285 integer(kind=kint),
allocatable,
intent(in) :: imp_rows_index(:), imp_cols_index(:)
2286 integer(kind=kint),
intent(in) :: imp_rows_item(:,:), map(:)
2287 integer(kind=kint),
intent(in) :: ndof2
2288 real(kind=
kreal),
intent(in) :: imp_vals_item(:)
2289 type (hecmwST_local_matrix),
intent(inout) :: BT_int
2290 integer(kind=kint),
allocatable :: cnt(:)
2291 integer(kind=kint) :: idom, is, ie, ic0, i, irow, ncol, j0, j
2292 allocate(cnt(bt_int%nr))
2295 is = imp_rows_index(idom-1)+1
2296 ie = imp_rows_index(idom)
2297 ic0 = imp_cols_index(idom-1)
2299 irow = imp_rows_item(1,i)
2300 ncol = imp_rows_item(2,i)
2301 if (irow < 1 .or. bt_int%nr < irow) stop
'ERROR: copy vals to BT_int: irow'
2302 j0 = bt_int%index(irow-1) + cnt(irow)
2304 bt_int%item(j0+j) = map(ic0+j)
2305 bt_int%A(ndof2*(j0+j-1)+1:ndof2*(j0+j)) = imp_vals_item(ndof2*(ic0+j-1)+1:ndof2*(ic0+j))
2307 cnt(irow) = cnt(irow) + ncol
2310 if (ic0 /= imp_cols_index(idom)) stop
'ERROR: copy vals to BT_int: ic0'
2313 end subroutine copy_vals_to_bt_int
2315 subroutine sort_and_uniq_rows(BTmat)
2318 type (hecmwST_local_matrix),
intent(inout) :: BTmat
2319 integer(kind=kint) :: nr, ndof, ndof2
2320 integer(kind=kint) :: irow, is, ie, is_new, ie_new, i, i_new
2321 integer(kind=kint) :: ndup, ndup_tot
2322 integer(kind=kint) :: js, je, js_new, je_new
2323 integer(kind=kint) :: new_nnz
2324 integer(kind=kint),
allocatable :: cnt(:)
2325 integer(kind=kint),
pointer :: sort_item(:), new_index(:), new_item(:)
2326 real(kind=
kreal),
pointer :: new_a(:)
2328 real(kind=
kreal) :: t0, t1
2333 outer:
do irow = 1, nr
2334 is = btmat%index(irow-1)+1
2335 ie = btmat%index(irow)
2337 if (btmat%item(i) >= btmat%item(i+1))
then
2344 if (timer >= 4)
write(0,
'(A,f10.4,L2)')
"####### sort_and_uniq_rows (1) : ",t1-t0,sorted
2351 allocate(sort_item(btmat%nnz))
2353 sort_item(i) = btmat%item(i)
2364 is = btmat%index(irow-1)+1
2365 ie = btmat%index(irow)
2368 cnt(irow) = (ie-is+1) - ndup
2369 ndup_tot = ndup_tot + ndup
2373 if (timer >= 4)
write(0,
'(A,f10.4,I5)')
"####### sort_and_uniq_rows (2) : ",t1-t0,ndup_tot
2376 if (ndup_tot == 0)
then
2377 new_index => btmat%index
2379 new_item => sort_item
2381 allocate(new_index(0:nr))
2382 call make_index(nr, cnt, new_index)
2383 new_nnz = new_index(nr)
2384 allocate(new_item(new_nnz))
2386 is = btmat%index(irow-1)+1
2388 is_new = new_index(irow-1)+1
2389 ie_new = is_new+cnt(irow)-1
2390 new_item(is_new:ie_new) = sort_item(is:ie)
2392 deallocate(sort_item)
2396 if (timer >= 4)
write(0,
'(A,f10.4)')
"####### sort_and_uniq_rows (3) : ",t1-t0
2399 allocate(new_a(ndof2*new_nnz))
2407 is = btmat%index(irow-1)+1
2408 ie = btmat%index(irow)
2409 is_new = new_index(irow-1)+1
2410 ie_new = new_index(irow)
2415 if (i_new == -1) stop
'ERROR: sort_and_uniq_rows'
2418 js_new = ndof2*(i_new-1)+1
2419 je_new = ndof2*i_new
2420 new_a(js_new:je_new) = new_a(js_new:je_new) + btmat%A(js:je)
2425 if (timer >= 4)
write(0,
'(A,f10.4)')
"####### sort_and_uniq_rows (4) : ",t1-t0
2428 if (ndup_tot == 0)
then
2429 deallocate(btmat%item)
2430 btmat%item => new_item
2435 deallocate(btmat%index)
2436 btmat%index => new_index
2437 deallocate(btmat%item)
2438 btmat%item => new_item
2442 end subroutine sort_and_uniq_rows
2446 type (hecmwst_local_matrix),
intent(in) :: amat
2447 type (hecmwst_local_matrix),
intent(in) :: bmat
2448 type (hecmwst_local_matrix),
intent(out) :: cmat
2449 integer(kind=kint) :: ndof, ndof2, nr, nc, i, icnt, js, je, j, jcol, idx, i0, k
2450 integer(kind=kint),
allocatable :: iw(:)
2451 if (amat%ndof /= bmat%ndof) stop
'ERROR: hecmw_localmat_add: non-matching ndof'
2454 nr = min(amat%nr, bmat%nr)
2455 nc = max(amat%nc, bmat%nc)
2460 allocate(cmat%index(0:nr))
2466 js = amat%index(i-1)+1
2474 js = bmat%index(i-1)+1
2479 if (iw(k) == jcol) cycle lj1
2484 cmat%index(i) = cmat%index(i-1) + icnt
2486 cmat%nnz = cmat%index(nr)
2487 allocate(cmat%item(cmat%nnz))
2488 allocate(cmat%A(ndof2*cmat%nnz))
2490 i0 = cmat%index(i-1)
2493 js = amat%index(i-1)+1
2499 cmat%item(idx) = jcol
2500 cmat%A(ndof2*(idx-1)+1:ndof2*idx) = amat%A(ndof2*(j-1)+1:ndof2*j)
2503 js = bmat%index(i-1)+1
2509 if (cmat%item(idx) == jcol)
then
2510 cmat%A(ndof2*(idx-1)+1:ndof2*idx) = &
2511 cmat%A(ndof2*(idx-1)+1:ndof2*idx) + bmat%A(ndof2*(j-1)+1:ndof2*j)
2517 cmat%item(idx) = jcol
2518 cmat%A(ndof2*(idx-1)+1:ndof2*idx) = bmat%A(ndof2*(j-1)+1:ndof2*j)
2520 if (i0 + icnt /= cmat%index(i)) stop
'ERROR: merge localmat'
2522 call sort_and_uniq_rows(cmat)
2570 type (hecmwst_local_matrix),
intent(inout) :: bkmat
2572 integer(kind=kint),
optional,
intent(in) :: num_lagrange
2573 integer(kind=kint) :: ndof, ndof2, i, idx, idx2, js, je, j, k
2574 integer(kind=kint),
allocatable :: incl_nz(:), cnt(:)
2575 logical :: check_nonzero
2576 check_nonzero = .false.
2582 bkmat%nr = hecmat%NP
2583 bkmat%nc = hecmat%NP
2586 if (
present(num_lagrange))
then
2587 check_nonzero = .true.
2590 if (check_nonzero)
then
2591 allocate(incl_nz(hecmat%NPL + hecmat%NPU + hecmat%NP))
2592 allocate(cnt(bkmat%nr))
2599 idx = hecmat%indexL(i-1) + (i-1) + hecmat%indexU(i-1)
2602 js = hecmat%indexL(i-1)+1
2603 je = hecmat%indexL(i)
2607 if (hecmat%AL(ndof2*(j-1)+k) /= 0.0d0)
then
2617 if (hecmat%D(ndof2*(i-1)+k) /= 0.0d0)
then
2624 js = hecmat%indexU(i-1)+1
2625 je = hecmat%indexU(i)
2629 if (hecmat%AU(ndof2*(j-1)+k) /= 0.0d0)
then
2636 if (idx /= hecmat%indexL(i) + i + hecmat%indexU(i)) stop
'ERROR: hecmw_localmat_init_with_hecmat: count'
2641 allocate(bkmat%index(0:bkmat%nr))
2642 call make_index(bkmat%nr, cnt, bkmat%index)
2644 bkmat%nnz = bkmat%index(bkmat%nr)
2646 allocate(bkmat%item(bkmat%nnz))
2647 allocate(bkmat%A(ndof2 * bkmat%nnz))
2653 idx = hecmat%indexL(i-1) + (i-1) + hecmat%indexU(i-1)
2654 idx2 = bkmat%index(i-1)
2656 js = hecmat%indexL(i-1)+1
2657 je = hecmat%indexL(i)
2660 if (incl_nz(idx) == 1)
then
2662 bkmat%item(idx2) = hecmat%itemL(j)
2663 bkmat%A(ndof2*(idx2-1)+1:ndof2*idx2) = hecmat%AL(ndof2*(j-1)+1:ndof2*j)
2668 if (incl_nz(idx) == 1)
then
2670 bkmat%item(idx2) = i
2671 bkmat%A(ndof2*(idx2-1)+1:ndof2*idx2) = hecmat%D(ndof2*(i-1)+1:ndof2*i)
2674 js = hecmat%indexU(i-1)+1
2675 je = hecmat%indexU(i)
2678 if (incl_nz(idx) == 1)
then
2680 bkmat%item(idx2) = hecmat%itemU(j)
2681 bkmat%A(ndof2*(idx2-1)+1:ndof2*idx2) = hecmat%AU(ndof2*(j-1)+1:ndof2*j)
2684 if (idx /= hecmat%indexL(i) + i + hecmat%indexU(i)) stop
'ERROR: hecmw_localmat_init_with_hecmat: copy'
2685 if (idx2 /= bkmat%index(i)) stop
'ERROR: hecmw_localmat_init_with_hecmat: index'
2691 bkmat%nnz = hecmat%NPL + hecmat%NP + hecmat%NPU
2692 allocate(bkmat%index(0:bkmat%nr))
2693 allocate(bkmat%item(bkmat%nnz))
2694 allocate(bkmat%A(ndof2 * bkmat%nnz))
2700 idx = hecmat%indexL(i-1) + (i-1) + hecmat%indexU(i-1)
2702 js = hecmat%indexL(i-1)+1
2703 je = hecmat%indexL(i)
2706 bkmat%item(idx) = hecmat%itemL(j)
2707 bkmat%A(ndof2*(idx-1)+1:ndof2*idx) = hecmat%AL(ndof2*(j-1)+1:ndof2*j)
2712 bkmat%A(ndof2*(idx-1)+1:ndof2*idx) = hecmat%D(ndof2*(i-1)+1:ndof2*i)
2714 js = hecmat%indexU(i-1)+1
2715 je = hecmat%indexU(i)
2718 bkmat%item(idx) = hecmat%itemU(j)
2719 bkmat%A(ndof2*(idx-1)+1:ndof2*idx) = hecmat%AU(ndof2*(j-1)+1:ndof2*j)
2721 bkmat%index(i) = idx
2722 if (idx /= hecmat%indexL(i) + i + hecmat%indexU(i)) stop
'ERROR: hecmw_localmat_init_with_hecmat: copy'
2730 type (hecmwst_local_matrix),
intent(inout) :: bkmat
2732 type (hecmwst_local_matrix) :: w1mat, w2mat
2735 call debug_write_matrix(w1mat,
'BKmat (hecMAT)', debug_matrix)
2741 bkmat%nnz = w2mat%nnz
2742 bkmat%ndof = w2mat%ndof
2743 bkmat%index => w2mat%index
2744 bkmat%item => w2mat%item
2750 type (hecmwst_local_matrix),
intent(in) :: bkmat
2751 type (hecmwst_local_matrix),
intent(inout) :: btmat
2753 type (hecmwst_local_matrix),
intent(out) :: bktmat
2756 type (hecmwst_local_matrix),
allocatable :: bt_exp(:)
2757 type (hecmwst_local_matrix) :: bt_imp, bt_all
2758 integer(kind=kint),
allocatable :: exp_cols_index(:)
2759 integer(kind=kint),
allocatable :: exp_cols_item(:,:)
2760 real(kind=
kreal) :: t0, t1
2763 if (hecmesh%PETOT > 1)
then
2764 call make_comm_table(bkmat, hecmesh, heccomm)
2765 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: make_comm_table done'
2767 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (1) : ',t1-t0
2770 if (btmat%nr > hecmesh%nn_internal)
then
2772 if (debug >= 1)
write(0,
'(A)')
'DEBUG: hecmw_localmat_multmat: ignore external part of BTmat'
2773 btmat%nr = hecmesh%nn_internal
2774 btmat%nnz = btmat%index(btmat%nr)
2777 call extract_bt_exp(btmat, heccomm, bt_exp)
2778 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: extract_BT_exp done'
2780 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (2) : ',t1-t0
2783 call prepare_column_info(hecmesh, bt_exp, exp_cols_index, exp_cols_item)
2784 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: prepare column info done'
2786 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (3) : ',t1-t0
2789 call send_bt_exp_and_recv_bt_imp(hecmesh, heccomm, bt_exp, exp_cols_index, exp_cols_item, bt_imp, hecmeshnew)
2790 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: send BT_exp and recv BT_imp done'
2792 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (4) : ',t1-t0
2796 call concat_btmat_and_bt_imp(btmat, bt_imp, bt_all)
2797 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: concat BTmat and BT_imp into BT_all done'
2799 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (5) : ',t1-t0
2803 call multiply_mat_mat(bkmat, bt_all, bktmat)
2804 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: multiply BKmat and BT_all into BKTmat done'
2806 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (6) : ',t1-t0
2810 if (hecmesh%n_neighbor_pe > 0)
then
2811 hecmesh%n_node = hecmeshnew%n_node
2812 hecmesh%n_neighbor_pe = hecmeshnew%n_neighbor_pe
2813 deallocate(hecmesh%neighbor_pe)
2814 deallocate(hecmesh%import_index)
2815 deallocate(hecmesh%export_index)
2816 deallocate(hecmesh%import_item)
2817 deallocate(hecmesh%export_item)
2818 deallocate(hecmesh%node_ID)
2819 deallocate(hecmesh%global_node_ID)
2820 hecmesh%neighbor_pe => hecmeshnew%neighbor_pe
2821 hecmesh%import_index => hecmeshnew%import_index
2822 hecmesh%export_index => hecmeshnew%export_index
2823 hecmesh%import_item => hecmeshnew%import_item
2824 hecmesh%export_item => hecmeshnew%export_item
2825 hecmesh%node_ID => hecmeshnew%node_ID
2826 hecmesh%global_node_ID => hecmeshnew%global_node_ID
2827 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: update hecMESH done'
2829 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat (7) : ',t1-t0
2832 call multiply_mat_mat(bkmat, btmat, bktmat)
2833 if (debug >= 1)
write(0,*)
'DEBUG: hecmw_localmat_multmat: multiply BKmat and BTmat into BKTmat done'
2835 if (timer >= 2)
write(0,
'(A,f10.4)')
'##### hecmw_localmat_multmat : ',t1-t0
2839 subroutine make_comm_table(BKmat, hecMESH, hecCOMM)
2842 type (hecmwst_local_matrix),
intent(in) :: bkmat
2845 integer(kind=kint) :: nn_int, nn_ext, nnb, i, icol, irank, idom, idx, n_send, tag, js, je, len
2846 integer(kind=kint),
allocatable :: is_nz_col(:), imp_cnt(:), exp_cnt(:), import_item_remote(:)
2847 integer(kind=kint),
allocatable :: requests(:), statuses(:,:)
2848 heccomm%zero = hecmesh%zero
2849 heccomm%HECMW_COMM = hecmesh%MPI_COMM
2850 heccomm%PETOT = hecmesh%PETOT
2851 heccomm%PEsmpTOT = hecmesh%PEsmpTOT
2852 heccomm%my_rank = hecmesh%my_rank
2853 heccomm%errnof = hecmesh%errnof
2854 heccomm%n_subdomain = hecmesh%n_subdomain
2855 heccomm%n_neighbor_pe = hecmesh%n_neighbor_pe
2856 allocate(heccomm%neighbor_pe(heccomm%n_neighbor_pe))
2857 heccomm%neighbor_pe(:) = hecmesh%neighbor_pe(:)
2859 nn_int = hecmesh%nn_internal
2860 nn_ext = hecmesh%n_node - hecmesh%nn_internal
2861 nnb = heccomm%n_neighbor_pe
2864 allocate(is_nz_col(nn_ext))
2866 do i = 1, bkmat%index(nn_int)
2867 icol = bkmat%item(i)
2868 if (icol > nn_int) is_nz_col(icol - nn_int) = 1
2872 allocate(imp_cnt(nnb))
2875 if (is_nz_col(i) == 1)
then
2876 irank = hecmesh%node_ID(2*(nn_int+i))
2877 call rank_to_idom(hecmesh, irank, idom)
2878 imp_cnt(idom) = imp_cnt(idom) + 1
2881 if (debug >= 3)
write(0,*)
' DEBUG3: imp_cnt',imp_cnt(:)
2884 allocate(heccomm%import_index(0:nnb))
2885 call make_index(nnb, imp_cnt, heccomm%import_index)
2886 if (debug >= 3)
write(0,*)
' DEBUG3: import_index',heccomm%import_index(:)
2889 allocate(heccomm%import_item(heccomm%import_index(nnb)))
2892 if (is_nz_col(i) == 1)
then
2893 irank = hecmesh%node_ID(2*(nn_int+i))
2894 call rank_to_idom(hecmesh, irank, idom)
2895 imp_cnt(idom) = imp_cnt(idom) + 1
2896 idx = heccomm%import_index(idom-1)+imp_cnt(idom)
2897 heccomm%import_item(idx) = nn_int+i
2900 if (debug >= 3)
write(0,*)
' DEBUG3: import_item',heccomm%import_item(:)
2902 allocate(import_item_remote(heccomm%import_index(nnb)))
2903 do i = 1, heccomm%import_index(nnb)
2904 import_item_remote(i) = hecmesh%node_ID(2*heccomm%import_item(i)-1)
2906 if (debug >= 3)
write(0,*)
' DEBUG3: import_item_remote',import_item_remote(:)
2908 allocate(requests(2*nnb))
2914 irank = heccomm%neighbor_pe(idom)
2917 call hecmw_isend_int(imp_cnt(idom), 1, irank, tag, heccomm%HECMW_COMM, requests(n_send))
2918 if (imp_cnt(idom) > 0)
then
2919 js = heccomm%import_index(idom-1)+1
2920 je = heccomm%import_index(idom)
2925 heccomm%HECMW_COMM, requests(n_send))
2930 allocate(exp_cnt(nnb))
2932 irank = heccomm%neighbor_pe(idom)
2934 call hecmw_recv_int(exp_cnt(idom), 1, irank, tag, heccomm%HECMW_COMM, statuses(:,1))
2936 allocate(heccomm%export_index(0:nnb))
2937 call make_index(nnb, exp_cnt, heccomm%export_index)
2938 if (debug >= 3)
write(0,*)
' DEBUG3: export_index',heccomm%export_index(:)
2941 allocate(heccomm%export_item(heccomm%export_index(nnb)))
2943 if (exp_cnt(idom) <= 0) cycle
2944 irank = heccomm%neighbor_pe(idom)
2945 js = heccomm%export_index(idom-1)+1
2946 je = heccomm%export_index(idom)
2949 call hecmw_recv_int(heccomm%export_item(js:je), len, irank, tag, &
2950 heccomm%HECMW_COMM, statuses(:,1))
2952 if (debug >= 3)
write(0,*)
' DEBUG3: export_item',heccomm%export_item(:)
2957 deallocate(import_item_remote)
2958 end subroutine make_comm_table
2962 type (hecmwST_matrix_comm),
intent(inout) :: hecCOMM
2963 deallocate(heccomm%neighbor_pe)
2964 deallocate(heccomm%import_index)
2965 deallocate(heccomm%import_item)
2966 deallocate(heccomm%export_index)
2967 deallocate(heccomm%export_item)
2970 subroutine extract_bt_exp(BTmat, hecCOMM, BT_exp)
2972 type (hecmwST_local_matrix),
intent(in) :: BTmat
2973 type (hecmwST_matrix_comm),
intent(in) :: hecCOMM
2974 type (hecmwST_local_matrix),
allocatable,
intent(out) :: BT_exp(:)
2975 integer(kind=kint) :: ndof, ndof2, idom, idx_0, idx_n, j, jrow, nnz_row, idx, ks, ke, k
2976 if (heccomm%n_neighbor_pe == 0)
return
2977 allocate(bt_exp(heccomm%n_neighbor_pe))
2980 do idom = 1, heccomm%n_neighbor_pe
2981 idx_0 = heccomm%export_index(idom-1)
2982 idx_n = heccomm%export_index(idom)
2983 bt_exp(idom)%nr = idx_n - idx_0
2984 bt_exp(idom)%nc = btmat%nc
2985 bt_exp(idom)%nnz = 0
2986 bt_exp(idom)%ndof = ndof
2987 allocate(bt_exp(idom)%index(0:bt_exp(idom)%nr))
2988 bt_exp(idom)%index(0) = 0
2989 do j = 1, bt_exp(idom)%nr
2990 jrow = heccomm%export_item(idx_0 + j)
2991 nnz_row = btmat%index(jrow) - btmat%index(jrow-1)
2992 bt_exp(idom)%index(j) = bt_exp(idom)%index(j-1) + nnz_row
2994 bt_exp(idom)%nnz = bt_exp(idom)%index(bt_exp(idom)%nr)
2995 allocate(bt_exp(idom)%item(bt_exp(idom)%nnz))
2996 allocate(bt_exp(idom)%A(ndof2 * bt_exp(idom)%nnz))
2998 do j = 1, bt_exp(idom)%nr
2999 jrow = heccomm%export_item(idx_0 + j)
3000 ks = btmat%index(jrow-1) + 1
3001 ke = btmat%index(jrow)
3004 bt_exp(idom)%item(idx) = btmat%item(k)
3005 bt_exp(idom)%A(ndof2*(idx-1)+1:ndof2*idx) = btmat%A(ndof2*(k-1)+1:ndof2*k)
3007 if (idx /= bt_exp(idom)%index(j)) stop
'ERROR: extract BT_exp'
3010 end subroutine extract_bt_exp
3012 subroutine send_bt_exp_and_recv_bt_imp(hecMESH, hecCOMM, BT_exp, exp_cols_index, exp_cols_item, BT_imp, hecMESHnew)
3015 type (hecmwST_local_mesh),
intent(in) :: hecMESH
3016 type (hecmwST_matrix_comm),
intent(in) :: hecCOMM
3017 type (hecmwST_local_matrix),
allocatable,
intent(inout) :: BT_exp(:)
3018 integer(kind=kint),
allocatable,
intent(inout) :: exp_cols_index(:)
3019 integer(kind=kint),
allocatable,
intent(inout) :: exp_cols_item(:,:)
3020 type (hecmwST_local_matrix),
intent(out) :: BT_imp
3021 type (hecmwST_local_mesh),
intent(inout) :: hecMESHnew
3022 integer(kind=kint),
allocatable :: nnz_imp(:), cnt(:), index_imp(:)
3023 integer(kind=kint),
allocatable :: imp_cols_index(:)
3024 integer(kind=kint),
allocatable :: imp_cols_item(:,:)
3025 real(kind=
kreal),
allocatable :: imp_vals_item(:)
3026 integer(kind=kint) :: nnb, ndof, ndof2, idom, irank, nr, n_send, tag, idx_0, idx_n, j, jj, nnz
3027 integer(kind=kint),
allocatable :: requests(:)
3028 integer(kind=kint),
allocatable :: statuses(:,:)
3029 integer(kind=kint),
allocatable :: map(:), add_nodes(:,:)
3030 integer(kind=kint) :: n_add_node, i0
3031 nnb = heccomm%n_neighbor_pe
3037 allocate(bt_imp%index(0:0))
3041 ndof = bt_exp(1)%ndof
3043 allocate(requests(nnb*3))
3047 irank = heccomm%neighbor_pe(idom)
3048 nr = bt_exp(idom)%nr
3052 call hecmw_isend_int(bt_exp(idom)%index(0:bt_exp(idom)%nr), bt_exp(idom)%nr + 1, &
3053 irank, tag, heccomm%HECMW_COMM, requests(n_send))
3054 if (bt_exp(idom)%nnz == 0) cycle
3058 cncol_item * bt_exp(idom)%nnz, irank, tag, heccomm%HECMW_COMM, requests(n_send))
3061 call hecmw_isend_r(bt_exp(idom)%A, ndof2 * bt_exp(idom)%nnz, &
3062 irank, tag, heccomm%HECMW_COMM, requests(n_send))
3066 bt_imp%nr = hecmesh%n_node - hecmesh%nn_internal
3071 allocate(nnz_imp(nnb))
3072 allocate(cnt(bt_imp%nr))
3076 irank = heccomm%neighbor_pe(idom)
3077 idx_0 = heccomm%import_index(idom-1)
3078 idx_n = heccomm%import_index(idom)
3084 allocate(index_imp(0:nr))
3087 heccomm%HECMW_COMM, statuses(:,1))
3088 nnz_imp(idom) = index_imp(nr)
3090 jj = heccomm%import_item(idx_0 + j) - hecmesh%nn_internal
3091 if (jj < 1 .or. bt_imp%nr < jj) stop
'ERROR: jj out of range'
3092 if (cnt(jj) /= 0) stop
import rows?
'
3093 cnt(jj) = index_imp(j) - index_imp(j-1)
3095 deallocate(index_imp)
3098 allocate(imp_cols_index(0:nnb))
3099 call make_index(nnb, nnz_imp, imp_cols_index)
3102 allocate(BT_imp%index(0:BT_imp%nr))
3103 call make_index(BT_imp%nr, cnt, BT_imp%index)
3106 BT_imp%nnz = BT_imp%index(BT_imp%nr)
3107 if (BT_imp%nnz /= imp_cols_index(nnb)) &
3108 stop 'error: total num of nonzero of bt_imp
'
3110 allocate(imp_cols_item(cNCOL_ITEM, BT_imp%nnz))
3111 allocate(imp_vals_item(ndof2 * BT_imp%nnz))
3114 irank = hecCOMM%neighbor_pe(idom)
3115 idx_0 = imp_cols_index(idom-1)
3116 idx_n = imp_cols_index(idom)
3120 call HECMW_RECV_INT(imp_cols_item(1, idx_0 + 1), cNCOL_ITEM * nnz, &
3121 irank, tag, hecCOMM%HECMW_COMM, statuses(:,1))
3123 call HECMW_RECV_R(imp_vals_item(ndof2*idx_0 + 1), ndof2 * nnz, &
3124 irank, tag, hecCOMM%HECMW_COMM, statuses(:,1))
3126 call HECMW_Waitall(n_send, requests, statuses)
3127 if (DEBUG >= 2) write(0,*) ' debug2: send bt_imp and recv into temporary data done
'
3129 deallocate(requests)
3130 deallocate(statuses)
3133 call hecmw_localmat_free(BT_exp(idom))
3136 deallocate(exp_cols_index)
3137 deallocate(exp_cols_item)
3139 call copy_mesh(hecMESH, hecMESHnew)
3141 call map_imported_cols(hecMESHnew, imp_cols_index(nnb), imp_cols_item, n_add_node, add_nodes, map, i0)
3142 if (DEBUG >= 2) write(0,*) ' debug2: map imported cols done
'
3144 call update_comm_table(hecMESHnew, n_add_node, add_nodes, i0)
3145 if (DEBUG >= 2) write(0,*) ' debug2: update comm_table done
'
3147 BT_imp%nc = hecMESHnew%n_node
3149 allocate(BT_imp%item(BT_imp%nnz))
3150 allocate(BT_imp%A(ndof2 * BT_imp%nnz))
3151 call copy_vals_to_BT_imp(hecCOMM, hecMESH%nn_internal, imp_cols_index, map, imp_vals_item, BT_imp)
3152 if (DEBUG >= 2) write(0,*) ' debug2: copy vals to bt_imp done
'
3154 deallocate(imp_cols_index)
3155 deallocate(imp_cols_item)
3156 deallocate(imp_vals_item)
3158 end subroutine send_BT_exp_and_recv_BT_imp
3160 subroutine copy_vals_to_BT_imp(hecCOMM, nn_internal, imp_cols_index, map, imp_vals_item, BT_imp)
3162 type (hecmwST_matrix_comm), intent(in) :: hecCOMM
3163 integer(kind=kint), intent(in) :: nn_internal
3164 integer(kind=kint), allocatable, intent(in) :: imp_cols_index(:)
3165 integer(kind=kint), intent(in) :: map(:)
3166 real(kind=kreal), intent(in) :: imp_vals_item(:)
3167 type (hecmwST_local_matrix), intent(inout) :: BT_imp
3168 integer(kind=kint) :: nnb, ndof2, idx, idom, idx_0, idx_n, nr, j, jrow, ks, ke, k
3169 nnb = hecCOMM%n_neighbor_pe
3170 ndof2 = BT_imp%ndof ** 2
3173 idx_0 = hecCOMM%import_index(idom-1)
3174 idx_n = hecCOMM%import_index(idom)
3178 jrow = hecCOMM%import_item(idx_0 + j) - nn_internal
3179 ks = BT_imp%index(jrow-1)+1
3180 ke = BT_imp%index(jrow)
3183 BT_imp%item(k) = map(idx)
3184 BT_imp%A(ndof2*(k-1)+1:ndof2*k) = imp_vals_item(ndof2*(idx-1)+1:ndof2*idx)
3187 if (idx /= imp_cols_index(idom)) stop 'error: copy vals to bt_imp
'
3189 end subroutine copy_vals_to_BT_imp
3191 subroutine concat_BTmat_and_BT_imp(BTmat, BT_imp, BT_all)
3193 type (hecmwST_local_matrix), intent(in) :: BTmat
3194 type (hecmwST_local_matrix), intent(in) :: BT_imp
3195 type (hecmwST_local_matrix), intent(out) :: BT_all
3196 integer(kind=kint) :: ndof, ndof2, i, ii
3198 .and.
if (BT_imp%nr > 0 BT_imp%ndof /= ndof) stop 'error: concat btmat and bt_imp: ndof
'
3200 BT_all%nr = BTmat%nr + BT_imp%nr
3201 BT_all%nc = max(BTmat%nc, BT_imp%nc)
3202 BT_all%nnz = BTmat%nnz + BT_imp%nnz
3204 allocate(BT_all%index(0:BT_all%nr))
3205 allocate(BT_all%item(BT_all%nnz))
3206 allocate(BT_all%A(ndof2 * BT_all%nnz))
3209 BT_all%index(i) = BTmat%index(i)
3212 BT_all%index(BTmat%nr+i) = BT_all%index(BTmat%nr+i-1) + &
3213 BT_imp%index(i) - BT_imp%index(i-1)
3216 BT_all%item(i) = BTmat%item(i)
3217 BT_all%A(ndof2*(i-1)+1:ndof2*i) = BTmat%A(ndof2*(i-1)+1:ndof2*i)
3219 do i = 1, BT_imp%nnz
3221 BT_all%item(ii) = BT_imp%item(i)
3222 BT_all%A(ndof2*(ii-1)+1:ndof2*ii) = BT_imp%A(ndof2*(i-1)+1:ndof2*i)
3224 end subroutine concat_BTmat_and_BT_imp
3226 subroutine multiply_mat_mat(Amat, Bmat, Cmat)
3228 type (hecmwST_local_matrix), intent(in) :: Amat
3229 type (hecmwST_local_matrix), intent(in) :: Bmat
3230 type (hecmwST_local_matrix), intent(out) :: Cmat
3231 integer(kind=kint) :: ndof, ndof2, nr, nc, nnz, i, icnt
3232 integer(kind=kint) :: js, je, j, jj, ks, ke, k, kk, l, ll, l0
3233 integer(kind=kint), allocatable :: iw(:)
3234 real(kind=kreal), pointer :: Ap(:), Bp(:), Cp(:)
3235 real(kind=kreal) :: t0, t1
3237 if (Amat%ndof /= Bmat%ndof) stop 'error: multiply_mat_mat: unmatching ndof
'
3242 if (Amat%nc /= Bmat%nr) then
3243 write(0,*) 'amat: nr, nc =
', Amat%nr, Amat%nc
3244 write(0,*) 'bmat: nr, nc =
', Bmat%nr, Bmat%nc
3245 stop 'error: multiply_mat_mat: unmatching size
'
3250 allocate(Cmat%index(0:nr))
3252 !$omp parallel default(none), &
3253 !$omp& private(iw,i,icnt,js,je,j,jj,ks,ke,k,kk,l), &
3254 !$omp& shared(nr,nc,Amat,Bmat,Cmat)
3259 js = Amat%index(i-1)+1
3263 ks = Bmat%index(jj-1)+1
3268 if (iw(l) == kk) cycle kl1
3274 Cmat%index(i) = icnt
3280 Cmat%index(i) = Cmat%index(i-1) + Cmat%index(i)
3282 nnz = Cmat%index(nr)
3284 !write(0,*) 'nnz
',nnz
3286 if (TIMER >= 3) write(0, '(a,f10.4)
') "###### multiply_mat_mat (1) : ",t1-t0
3288 allocate(Cmat%item(nnz))
3289 allocate(Cmat%A(ndof2 * nnz))
3291 !$omp parallel default(none), &
3292 !$omp& private(i,icnt,l0,js,je,j,jj,Ap,ks,ke,k,kk,Bp,ll,l,Cp), &
3293 !$omp& shared(nr,Cmat,Amat,Bmat,ndof2,ndof)
3297 l0 = Cmat%index(i-1)
3299 js = Amat%index(i-1)+1
3303 Ap => Amat%A(ndof2*(j-1)+1:ndof2*j)
3304 ks = Bmat%index(jj-1)+1
3308 Bp => Bmat%A(ndof2*(k-1)+1:ndof2*k)
3311 if (Cmat%item(l0+l) == kk) then
3321 Cp => Cmat%A(ndof2*(ll-1)+1:ndof2*ll)
3322 call blk_matmul_add(ndof, Ap, Bp, Cp)
3325 !write(0,*) 'l0,icnt,index(i)
',Cmat%index(i-1),icnt,Cmat%index(i)
3326 if (l0+icnt /= Cmat%index(i)) stop 'error: multiply_mat_mat: unknown error
'
3331 if (TIMER >= 3) write(0, '(a,f10.4)
') "###### multiply_mat_mat (2) : ",t1-t0
3333 call sort_and_uniq_rows(Cmat)
3335 if (TIMER >= 3) write(0, '(a,f10.4)
') "###### multiply_mat_mat (3) : ",t1-t0
3336 end subroutine multiply_mat_mat
3338 subroutine blk_matmul_add(ndof, A, B, AB)
3340 integer, intent(in) :: ndof
3341 real(kind=kreal), intent(in) :: A(:), B(:)
3342 real(kind=kreal), intent(inout) :: AB(:)
3343 integer :: ndof2, i, j, k, i0, j0, ij, ik, jk
3354 AB(ik)=AB(ik)+A(ij)*B(jk)
3358 end subroutine blk_matmul_add
3360 subroutine hecmw_localmat_make_hecmat(hecMAT, BTtKTmat, hecTKT)
3362 type (hecmwST_matrix), intent(in) :: hecMAT
3363 type (hecmwST_local_matrix), intent(in) :: BTtKTmat
3364 type (hecmwST_matrix), intent(inout) :: hecTKT
3365 call make_new_hecmat(hecMAT, BTtKTmat, hecTKT)
3366 end subroutine hecmw_localmat_make_hecmat
3368 subroutine hecmw_localmat_shrink_comm_table(BKmat, hecMESH)
3370 type (hecmwST_local_matrix), intent(in) :: BKmat
3371 type (hecmwST_local_mesh), intent(inout) :: hecMESH
3372 type (hecmwST_matrix_comm) :: hecCOMM
3373 call make_comm_table(BKmat, hecMESH, hecCOMM)
3374 deallocate(hecMESH%import_index)
3375 deallocate(hecMESH%import_item)
3376 deallocate(hecMESH%export_index)
3377 deallocate(hecMESH%export_item)
3378 hecMESH%import_index => hecCOMM%import_index
3379 hecMESH%import_item => hecCOMM%import_item
3380 hecMESH%export_index => hecCOMM%export_index
3381 hecMESH%export_item => hecCOMM%export_item
3382 deallocate(hecCOMM%neighbor_pe)
3383 end subroutine hecmw_localmat_shrink_comm_table
3385 !> \brief Debug write matrix
3387 subroutine debug_write_matrix(Mat, label, level)
3388 type(hecmwST_local_matrix), intent(in) :: Mat !< matrix
3389 character(len=*), intent(in) :: label !< label for matrix
3390 integer(kind=kint), intent(in) :: level !< debug level
3392 integer(kind=kint) :: iunit
3394 if (level <= 0) return
3396 iunit = 700 + hecmw_comm_get_rank()
3397 write(iunit,'(a,a)
') trim(label),'============================================================
'
3398 if (level == 1) then
3399 call hecmw_localmat_write_size(Mat, iunit)
3400 else if (level == 2) then
3401 call hecmw_localmat_write_ij(Mat, iunit)
3403 call hecmw_localmat_write(Mat, iunit)
3405 end subroutine debug_write_matrix
3407 end module hecmw_local_matrix