29 integer,
parameter :: DEBUG = 0
30 logical,
parameter :: DEBUG_VECTOR = .false.
39 subroutine hecmw_mpc_mat_init(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc)
47 integer(kind=kint) :: totalmpc, mpc_method, solver_type
49 totalmpc = hecmesh%mpc%n_mpc
52 if (totalmpc == 0)
then
55 if (
present(conmat).and.
present(conmatmpc)) conmatmpc => conmat
59 call hecmw_mpc_scale(hecmesh)
62 if (mpc_method < 1 .or. 3 < mpc_method)
then
64 if (solver_type > 1)
then
72 if (mpc_method == 2)
then
73 write(*,*)
'WARNING: MPCMETHOD=2 (MPCCG) is deprecated; may not work correctly'
78 select case (mpc_method)
82 if (
present(conmat).and.
present(conmatmpc)) conmatmpc => conmat
86 if (
present(conmat).and.
present(conmatmpc)) conmatmpc => conmat
89 call hecmw_mpc_mesh_copy(hecmesh, hecmeshmpc)
92 if (
present(conmat).and.
present(conmatmpc))
then
110 integer(kind=kint) :: totalmpc, mpc_method
112 totalmpc = hecmesh%mpc%n_mpc
115 if (totalmpc == 0)
then
120 call hecmw_mpc_scale(hecmesh)
129 hecmatmpc%N = hecmat%N
130 hecmatmpc%NP = hecmat%NP
131 hecmatmpc%NDOF = hecmat%NDOF
132 allocate(hecmatmpc%B(
size(hecmat%B)))
133 allocate(hecmatmpc%X(
size(hecmat%X)))
148 integer(kind=kint) :: totalmpc, mpc_method
150 totalmpc = hecmesh%mpc%n_mpc
153 if (totalmpc == 0)
then
156 if (
present(conmatmpc))
nullify(conmatmpc)
162 select case (mpc_method)
166 if (
present(conmatmpc))
nullify(conmatmpc)
170 if (
present(conmatmpc))
nullify(conmatmpc)
172 call hecmw_mpc_mesh_free(hecmeshmpc)
173 deallocate(hecmeshmpc)
176 deallocate(hecmatmpc)
178 if (
present(conmatmpc))
then
180 deallocate(conmatmpc)
197 integer(kind=kint) :: totalmpc, mpc_method
199 totalmpc = hecmesh%mpc%n_mpc
202 if (totalmpc == 0)
then
209 select case (mpc_method)
216 deallocate(hecmatmpc)
227 subroutine hecmw_mpc_mat_ass(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc, hecLagMAT)
236 integer(kind=kint) :: totalmpc, mpc_method
238 totalmpc = hecmesh%mpc%n_mpc
241 if (totalmpc == 0)
return
245 select case (mpc_method)
254 if (
present(conmat).and.
present(conmatmpc).and.
present(heclagmat))
then
256 call resize_heclagmat(conmat%NP, conmatmpc%NP, conmat%NDOF, heclagmat)
263 subroutine resize_heclagmat(NP_orig, NP_new, ndof, hecLagMAT)
264 integer(kind=kint),
intent(in) :: np_orig, np_new, ndof
266 integer(kind=kint),
pointer :: itemp(:)
268 if (heclagmat%num_lagrange == 0)
return
270 allocate(itemp(0:np_new))
271 itemp(0:np_orig) = heclagmat%indexU_lagrange(0:np_orig)
272 itemp(np_orig+1:np_new) = heclagmat%indexU_lagrange(np_orig)
274 deallocate(heclagmat%indexU_lagrange)
275 heclagmat%indexU_lagrange => itemp
277 end subroutine resize_heclagmat
289 real(kind=
kreal),
allocatable :: btmp(:)
290 real(kind=
kreal) :: time_dumm
291 integer(kind=kint) :: totalmpc, mpc_method, i
293 totalmpc = hecmesh%mpc%n_mpc
296 if (totalmpc == 0)
return
300 select case (mpc_method)
304 allocate(btmp(hecmat%NP*hecmat%NDOF))
305 do i = 1, hecmat%NP*hecmat%NDOF
306 btmp(i) = hecmat%B(i)
308 call hecmw_trans_b(hecmesh, hecmat, btmp, hecmatmpc%B, time_dumm)
311 call hecmw_trans_b(hecmesh, hecmat, hecmat%B, hecmatmpc%B, time_dumm)
312 hecmatmpc%Iarray=hecmat%Iarray
313 hecmatmpc%Rarray=hecmat%Rarray
328 real(kind=
kreal) :: time_dumm
329 integer(kind=kint) :: totalmpc, mpc_method, i
330 integer(kind=kint) :: npndof, npndof_mpc, num_lagrange
332 totalmpc = hecmesh%mpc%n_mpc
335 if (totalmpc == 0)
return
339 select case (mpc_method)
343 call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
345 npndof = hecmat%NP * hecmat%NDOF
347 hecmat%X(i) = hecmatmpc%X(i)
349 call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
350 num_lagrange =
size(hecmat%X) - npndof
351 npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
352 do i = 1, num_lagrange
353 hecmat%X(npndof+i) = hecmatmpc%X(npndof_mpc+i)
355 hecmat%Iarray=hecmatmpc%Iarray
356 hecmat%Rarray=hecmatmpc%Rarray
369 real(kind=
kreal),
intent(inout) :: mass(:)
371 real(kind=
kreal),
allocatable :: mtmp(:)
372 real(kind=
kreal) :: time_dumm
373 integer(kind=kint) :: totalmpc, mpc_method, i
375 totalmpc = hecmesh%mpc%n_mpc
378 if (totalmpc == 0)
return
382 select case (mpc_method)
386 allocate(mtmp(hecmat%NP*hecmat%NDOF))
388 call hecmw_ttvec(hecmesh, hecmat%NDOF, mass, mtmp, time_dumm)
389 do i = 1, hecmat%NP*hecmat%NDOF
406 integer(kind=kint),
intent(in) :: neig
407 real(kind=
kreal),
intent(inout) :: eigvec(:,:)
409 real(kind=
kreal) :: time_dumm
410 integer(kind=kint) :: totalmpc, mpc_method, i
412 totalmpc = hecmesh%mpc%n_mpc
415 if (totalmpc == 0)
return
419 select case (mpc_method)
424 call hecmw_tback_x(hecmesh, hecmat%NDOF, eigvec(:,i), time_dumm)
439 integer(kind=kint),
intent(out) :: mark(:)
441 integer(kind=kint) :: ndof, i, j, k, kk
445 outer:
do i = 1, hecmesh%mpc%n_mpc
446 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
447 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
449 k = hecmesh%mpc%mpc_index(i-1)+1
450 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
460 subroutine hecmw_mpc_scale(hecMESH)
463 integer(kind=kint) :: i, j, k
464 real(kind=
kreal) :: wval
468 do i = 1, hecmesh%mpc%n_mpc
469 k = hecmesh%mpc%mpc_index(i-1)+1
470 wval = 1.d0 / hecmesh%mpc%mpc_val(k)
471 hecmesh%mpc%mpc_val(k) = 1.d0
472 do j = hecmesh%mpc%mpc_index(i-1)+2, hecmesh%mpc%mpc_index(i)
473 hecmesh%mpc%mpc_val(j) = hecmesh%mpc%mpc_val(j) * wval
475 hecmesh%mpc%mpc_const(i) = hecmesh%mpc%mpc_const(i) * wval
480 end subroutine hecmw_mpc_scale
488 subroutine hecmw_trans_b(hecMESH, hecMAT, B, BT, COMMtime)
492 real(kind=
kreal),
intent(in) :: b(:)
493 real(kind=
kreal),
intent(out),
target :: bt(:)
494 real(kind=
kreal),
intent(inout) :: commtime
496 real(kind=
kreal),
allocatable :: w(:)
497 real(kind=
kreal),
pointer :: xg(:)
498 integer(kind=kint) :: ndof, i, j, k, kk, flg_bak
502 call debug_write_vector(b,
'original RHS',
'B', ndof, hecmat%N, hecmat%NP, .true.)
504 allocate(w(hecmesh%n_node * ndof))
512 do i = 1, hecmat%N * ndof
519 outer:
do i = 1, hecmesh%mpc%n_mpc
520 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
521 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
523 k = hecmesh%mpc%mpc_index(i-1) + 1
524 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
525 xg(kk) = hecmesh%mpc%mpc_const(i)
541 call debug_write_vector(bt,
'transformed RHS',
'BT', ndof, hecmat%N, hecmat%NP, .true.)
542 end subroutine hecmw_trans_b
550 subroutine hecmw_tback_x(hecMESH, ndof, X, COMMtime)
553 integer(kind=kint),
intent(in) :: ndof
554 real(kind=
kreal),
intent(inout) :: x(:)
555 real(kind=
kreal),
intent(inout) :: commtime
557 real(kind=
kreal),
allocatable :: w(:)
558 integer(kind=kint) :: i, j, k, kk
560 call debug_write_vector(x,
'solution for transformed eqn',
'X', ndof, hecmesh%nn_internal, &
561 hecmesh%n_node, .true.)
563 allocate(w(hecmesh%n_node * ndof))
566 call hecmw_tvec(hecmesh, ndof, x, w, commtime)
571 do i= 1, hecmesh%nn_internal * ndof
577 outer:
do i = 1, hecmesh%mpc%n_mpc
578 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
579 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
581 k = hecmesh%mpc%mpc_index(i-1) + 1
582 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
583 x(kk) = x(kk) + hecmesh%mpc%mpc_const(i)
591 call debug_write_vector(x,
'recovered solution',
'X', ndof, hecmesh%nn_internal, &
592 hecmesh%n_node, .true.)
593 end subroutine hecmw_tback_x
601 real(kind=
kreal),
allocatable :: kx(:), ttkx(:), ttb(:), resid(:)
602 integer(kind=kint) :: ndof, nndof, npndof, i
603 real(kind=
kreal) :: bnrm, rnrm, commtime
606 nndof = hecmat%N * ndof
607 npndof = hecmat%NP * ndof
608 allocate(kx(npndof), ttkx(npndof), ttb(npndof), resid(npndof))
610 call hecmw_ttvec(hecmesh, ndof, kx, ttkx, commtime)
611 call hecmw_ttvec(hecmesh, ndof, hecmat%B, ttb, commtime)
613 resid(i) = ttb(i) - ttkx(i)
619 write(0,*)
'DEBUG: hecmw_mpc_check_solution: resid(abs), resid(rel):',rnrm, rnrm/bnrm
627 integer(kind=kint) :: ndof
628 integer(kind=kint) :: i, j, kk
629 real(kind=
kreal) :: xmax, sum, resid, resid_max
633 do i = 1, hecmesh%nn_internal * ndof
634 if (xmax < abs(hecmat%X(i))) xmax = abs(hecmat%X(i))
639 outer:
do i = 1, hecmesh%mpc%n_mpc
640 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
641 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
644 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
645 kk = ndof * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
646 sum = sum + hecmat%X(kk) * hecmesh%mpc%mpc_val(j)
648 resid = abs(hecmesh%mpc%mpc_const(i) - sum)
649 if (resid_max < resid) resid_max = resid
652 write(0,*)
'DEBUG: hecmw_mpc_check_equation: resid(abs), resid(rel):', resid_max, resid_max/xmax
655 subroutine hecmw_mpc_mesh_copy(src, dst)
660 dst%MPI_COMM = src%MPI_COMM
661 dst%PETOT = src%PETOT
662 dst%PEsmpTOT = src%PEsmpTOT
663 dst%my_rank = src%my_rank
664 dst%n_subdomain = src%n_subdomain
665 dst%n_node = src%n_node
666 dst%nn_internal = src%nn_internal
667 dst%n_elem = src%n_elem
668 dst%ne_internal = src%ne_internal
669 dst%n_elem_type = src%n_elem_type
670 dst%n_dof = src%n_dof
671 dst%n_neighbor_pe = src%n_neighbor_pe
672 if (src%n_neighbor_pe > 0)
then
673 allocate(dst%neighbor_pe(dst%n_neighbor_pe))
674 dst%neighbor_pe(:) = src%neighbor_pe(:)
675 allocate(dst%import_index(0:dst%n_neighbor_pe))
676 dst%import_index(:)= src%import_index(:)
677 allocate(dst%export_index(0:dst%n_neighbor_pe))
678 dst%export_index(:)= src%export_index(:)
679 allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
680 dst%import_item(:) = src%import_item(:)
681 allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
682 dst%export_item(:) = src%export_item(:)
684 allocate(dst%global_node_ID(dst%n_node))
685 dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:dst%n_node)
686 allocate(dst%node_ID(2*dst%n_node))
687 dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*dst%n_node)
688 allocate(dst%elem_type_item(dst%n_elem_type))
689 dst%elem_type_item(:) = src%elem_type_item(:)
691 dst%mpc%n_mpc = src%mpc%n_mpc
692 dst%mpc%mpc_index => src%mpc%mpc_index
693 dst%mpc%mpc_item => src%mpc%mpc_item
694 dst%mpc%mpc_dof => src%mpc%mpc_dof
695 dst%mpc%mpc_val => src%mpc%mpc_val
696 dst%mpc%mpc_const => src%mpc%mpc_const
698 dst%node_group%n_grp = src%node_group%n_grp
699 dst%node_group%n_bc = src%node_group%n_bc
700 dst%node_group%grp_name => src%node_group%grp_name
701 dst%node_group%grp_index => src%node_group%grp_index
702 dst%node_group%grp_item => src%node_group%grp_item
703 dst%node_group%bc_grp_ID => src%node_group%bc_grp_ID
704 dst%node_group%bc_grp_type => src%node_group%bc_grp_type
705 dst%node_group%bc_grp_index => src%node_group%bc_grp_index
706 dst%node_group%bc_grp_dof => src%node_group%bc_grp_dof
707 dst%node_group%bc_grp_val => src%node_group%bc_grp_val
710 end subroutine hecmw_mpc_mesh_copy
712 subroutine hecmw_mpc_mesh_free(hecMESH)
715 if (hecmesh%n_neighbor_pe > 1)
then
716 deallocate(hecmesh%neighbor_pe)
717 deallocate(hecmesh%import_index)
718 deallocate(hecmesh%export_index)
719 deallocate(hecmesh%import_item)
720 deallocate(hecmesh%export_item)
722 deallocate(hecmesh%global_node_ID)
723 deallocate(hecmesh%node_ID)
724 deallocate(hecmesh%elem_type_item)
725 end subroutine hecmw_mpc_mesh_free
729 subroutine debug_write_vector(Vec, label, name, ndof, N, &
730 NP, write_ext, slaves)
731 real(kind=
kreal),
intent(in) :: vec(:)
732 character(len=*),
intent(in) :: label
733 character(len=*),
intent(in) :: name
734 integer(kind=kint),
intent(in) :: ndof
735 integer(kind=kint),
intent(in) :: n
736 integer(kind=kint),
intent(in),
optional :: np
737 logical,
intent(in),
optional :: write_ext
738 integer(kind=kint),
intent(in),
optional :: slaves(:)
740 integer(kind=kint) :: iunit
741 character(len=128) :: fmt
743 if (.not. debug_vector)
return
745 write(fmt,
'(a,i0,a)')
'(',ndof,
'f12.3)'
748 write(iunit,*) trim(label),
'------------------------------------------------------------'
749 write(iunit,*)
'size of ',trim(name),
size(vec)
750 write(iunit,*) trim(name),
': 1-',n*ndof
751 write(iunit,fmt) vec(1:n*ndof)
752 if (
present(write_ext) .and.
present(np))
then
754 write(iunit,*) trim(name),
'(external): ',n*ndof+1,
'-',np*ndof
755 write(iunit,fmt) vec(n*ndof+1:np*ndof)
758 if (
present(slaves))
then
759 if (
size(slaves) > 0)
then
760 write(iunit,*) trim(name),
'(slave):',slaves(:)
761 write(iunit,fmt) vec(slaves(:))
764 end subroutine debug_write_vector