27 integer,
parameter :: DEBUG = 0
28 logical,
parameter :: DEBUG_VECTOR = .false.
45 integer(kind=kint) :: totalmpc, mpc_method, solver_type
47 totalmpc = hecmesh%mpc%n_mpc
50 if (totalmpc == 0)
then
53 if (
present(conmat).and.
present(conmatmpc)) conmatmpc => conmat
57 call hecmw_mpc_scale(hecmesh)
60 if (mpc_method == 2 .and. hecmesh%my_rank == 0)
then
61 write(*,*)
'WARNING: MPCMETHOD=2 (MPCCG) has been removed; falling back to the default'
63 if (mpc_method /= 1 .and. mpc_method /= 3)
then
65 if (solver_type > 1)
then
73 select case (mpc_method)
77 if (
present(conmat).and.
present(conmatmpc)) conmatmpc => conmat
80 call hecmw_mpc_mesh_copy(hecmesh, hecmeshmpc)
83 if (
present(conmat).and.
present(conmatmpc))
then
101 integer(kind=kint) :: totalmpc, mpc_method
103 totalmpc = hecmesh%mpc%n_mpc
106 if (totalmpc == 0)
then
111 call hecmw_mpc_scale(hecmesh)
120 hecmatmpc%N = hecmat%N
121 hecmatmpc%NP = hecmat%NP
122 hecmatmpc%NDOF = hecmat%NDOF
123 allocate(hecmatmpc%B(
size(hecmat%B)))
124 allocate(hecmatmpc%X(
size(hecmat%X)))
139 integer(kind=kint) :: totalmpc, mpc_method
141 totalmpc = hecmesh%mpc%n_mpc
144 if (totalmpc == 0)
then
147 if (
present(conmatmpc))
nullify(conmatmpc)
153 select case (mpc_method)
157 if (
present(conmatmpc))
nullify(conmatmpc)
159 call hecmw_mpc_mesh_free(hecmeshmpc)
160 deallocate(hecmeshmpc)
163 deallocate(hecmatmpc)
165 if (
present(conmatmpc))
then
167 deallocate(conmatmpc)
184 integer(kind=kint) :: totalmpc, mpc_method
186 totalmpc = hecmesh%mpc%n_mpc
189 if (totalmpc == 0)
then
196 select case (mpc_method)
201 deallocate(hecmatmpc)
212 subroutine hecmw_mpc_mat_ass(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc, hecLagMAT)
221 integer(kind=kint) :: totalmpc, mpc_method
223 totalmpc = hecmesh%mpc%n_mpc
226 if (totalmpc == 0)
return
230 select case (mpc_method)
237 if (
present(conmat).and.
present(conmatmpc).and.
present(heclagmat))
then
239 call resize_heclagmat(conmat%NP, conmatmpc%NP, conmat%NDOF, heclagmat)
246 subroutine resize_heclagmat(NP_orig, NP_new, ndof, hecLagMAT)
247 integer(kind=kint),
intent(in) :: np_orig, np_new, ndof
249 integer(kind=kint),
pointer :: itemp(:)
251 if (heclagmat%num_lagrange == 0)
return
253 allocate(itemp(0:np_new))
254 itemp(0:np_orig) = heclagmat%indexU_lagrange(0:np_orig)
255 itemp(np_orig+1:np_new) = heclagmat%indexU_lagrange(np_orig)
257 deallocate(heclagmat%indexU_lagrange)
258 heclagmat%indexU_lagrange => itemp
260 end subroutine resize_heclagmat
272 real(kind=
kreal) :: time_dumm
273 integer(kind=kint) :: totalmpc, mpc_method
275 totalmpc = hecmesh%mpc%n_mpc
278 if (totalmpc == 0)
return
282 select case (mpc_method)
286 call hecmw_trans_b(hecmesh, hecmat, hecmat%B, hecmatmpc%B, time_dumm)
287 hecmatmpc%Iarray=hecmat%Iarray
288 hecmatmpc%Rarray=hecmat%Rarray
291 hecmatmpc%symmetric=hecmat%symmetric
306 real(kind=
kreal) :: time_dumm
307 integer(kind=kint) :: totalmpc, mpc_method, i
308 integer(kind=kint) :: npndof, npndof_mpc, num_lagrange
310 totalmpc = hecmesh%mpc%n_mpc
313 if (totalmpc == 0)
return
317 select case (mpc_method)
321 npndof = hecmat%NP * hecmat%NDOF
323 hecmat%X(i) = hecmatmpc%X(i)
325 call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
326 num_lagrange =
size(hecmat%X) - npndof
327 npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
328 do i = 1, num_lagrange
329 hecmat%X(npndof+i) = hecmatmpc%X(npndof_mpc+i)
331 hecmat%Iarray=hecmatmpc%Iarray
332 hecmat%Rarray=hecmatmpc%Rarray
346 real(kind=
kreal),
pointer :: mass(:)
348 real(kind=
kreal),
allocatable :: w(:), mtmp(:)
349 real(kind=
kreal) :: time_dumm
350 integer(kind=kint) :: totalmpc, mpc_method, i
351 integer(kind=kint) :: npndof, npndof_mpc
353 totalmpc = hecmesh%mpc%n_mpc
356 if (totalmpc == 0)
return
360 select case (mpc_method)
364 npndof = hecmat%NP * hecmat%NDOF
365 npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
367 allocate(mtmp(npndof))
371 call hecmw_tvec(hecmesh, hecmat%NDOF, mtmp, w, time_dumm)
374 w(i) = mass(i) * w(i)
377 call hecmw_ttvec(hecmesh, hecmat%NDOF, w, mtmp, time_dumm)
380 allocate(mass(npndof_mpc))
400 integer(kind=kint),
intent(in) :: neig
401 real(kind=
kreal),
intent(inout) :: eigvec(:,:)
403 real(kind=
kreal) :: time_dumm
404 integer(kind=kint) :: totalmpc, mpc_method, i
406 totalmpc = hecmesh%mpc%n_mpc
409 if (totalmpc == 0)
return
413 select case (mpc_method)
418 call hecmw_tback_x(hecmesh, hecmat%NDOF, eigvec(:,i), time_dumm)
433 integer(kind=kint),
intent(out) :: mark(:)
435 integer(kind=kint) :: ndof, i, j, k, kk
439 outer:
do i = 1, hecmesh%mpc%n_mpc
440 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
441 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
443 k = hecmesh%mpc%mpc_index(i-1)+1
444 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
454 subroutine hecmw_mpc_scale(hecMESH)
457 integer(kind=kint) :: i, j, k
458 real(kind=
kreal) :: wval
462 do i = 1, hecmesh%mpc%n_mpc
463 k = hecmesh%mpc%mpc_index(i-1)+1
464 wval = 1.d0 / hecmesh%mpc%mpc_val(k)
465 hecmesh%mpc%mpc_val(k) = 1.d0
466 do j = hecmesh%mpc%mpc_index(i-1)+2, hecmesh%mpc%mpc_index(i)
467 hecmesh%mpc%mpc_val(j) = hecmesh%mpc%mpc_val(j) * wval
469 hecmesh%mpc%mpc_const(i) = hecmesh%mpc%mpc_const(i) * wval
474 end subroutine hecmw_mpc_scale
482 subroutine hecmw_trans_b(hecMESH, hecMAT, B, BT, COMMtime)
486 real(kind=
kreal),
intent(in) :: b(:)
487 real(kind=
kreal),
intent(out),
target :: bt(:)
488 real(kind=
kreal),
intent(inout) :: commtime
490 real(kind=
kreal),
allocatable :: w(:)
491 real(kind=
kreal),
pointer :: xg(:)
492 integer(kind=kint) :: ndof, i, j, k, kk
496 call debug_write_vector(b,
'original RHS',
'B', ndof, hecmat%N, hecmat%NP, .true.)
498 allocate(w(hecmesh%n_node * ndof))
506 do i = 1, hecmat%N * ndof
513 outer:
do i = 1, hecmesh%mpc%n_mpc
514 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
515 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
517 k = hecmesh%mpc%mpc_index(i-1) + 1
518 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
519 xg(kk) = hecmesh%mpc%mpc_const(i)
532 call debug_write_vector(bt,
'transformed RHS',
'BT', ndof, hecmat%N, hecmat%NP, .true.)
533 end subroutine hecmw_trans_b
541 subroutine hecmw_tback_x(hecMESH, ndof, X, COMMtime)
544 integer(kind=kint),
intent(in) :: ndof
545 real(kind=
kreal),
intent(inout) :: x(:)
546 real(kind=
kreal),
intent(inout) :: commtime
548 real(kind=
kreal),
allocatable :: w(:)
549 integer(kind=kint) :: i, j, k, kk
551 call debug_write_vector(x,
'solution for transformed eqn',
'X', ndof, hecmesh%nn_internal, &
552 hecmesh%n_node, .true.)
554 allocate(w(hecmesh%n_node * ndof))
557 call hecmw_tvec(hecmesh, ndof, x, w, commtime)
562 do i= 1, hecmesh%nn_internal * ndof
568 outer:
do i = 1, hecmesh%mpc%n_mpc
569 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
570 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
572 k = hecmesh%mpc%mpc_index(i-1) + 1
573 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
574 x(kk) = x(kk) + hecmesh%mpc%mpc_const(i)
582 call debug_write_vector(x,
'recovered solution',
'X', ndof, hecmesh%nn_internal, &
583 hecmesh%n_node, .true.)
584 end subroutine hecmw_tback_x
586 subroutine hecmw_mpc_mesh_copy(src, dst)
591 dst%MPI_COMM = src%MPI_COMM
592 dst%PETOT = src%PETOT
593 dst%PEsmpTOT = src%PEsmpTOT
594 dst%my_rank = src%my_rank
595 dst%n_subdomain = src%n_subdomain
596 dst%n_node = src%n_node
597 dst%nn_internal = src%nn_internal
598 dst%n_elem = src%n_elem
599 dst%ne_internal = src%ne_internal
600 dst%n_elem_type = src%n_elem_type
601 dst%n_dof = src%n_dof
602 dst%n_neighbor_pe = src%n_neighbor_pe
603 if (src%n_neighbor_pe > 0)
then
604 allocate(dst%neighbor_pe(dst%n_neighbor_pe))
605 dst%neighbor_pe(:) = src%neighbor_pe(:)
606 allocate(dst%import_index(0:dst%n_neighbor_pe))
607 dst%import_index(:)= src%import_index(:)
608 allocate(dst%export_index(0:dst%n_neighbor_pe))
609 dst%export_index(:)= src%export_index(:)
610 allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
611 dst%import_item(:) = src%import_item(:)
612 allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
613 dst%export_item(:) = src%export_item(:)
615 allocate(dst%global_node_ID(dst%n_node))
616 dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:dst%n_node)
617 allocate(dst%node_ID(2*dst%n_node))
618 dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*dst%n_node)
619 allocate(dst%elem_type_item(dst%n_elem_type))
620 dst%elem_type_item(:) = src%elem_type_item(:)
622 dst%mpc%n_mpc = src%mpc%n_mpc
623 dst%mpc%mpc_index => src%mpc%mpc_index
624 dst%mpc%mpc_item => src%mpc%mpc_item
625 dst%mpc%mpc_dof => src%mpc%mpc_dof
626 dst%mpc%mpc_val => src%mpc%mpc_val
627 dst%mpc%mpc_const => src%mpc%mpc_const
629 dst%node_group%n_grp = src%node_group%n_grp
630 dst%node_group%n_bc = src%node_group%n_bc
631 dst%node_group%grp_name => src%node_group%grp_name
632 dst%node_group%grp_index => src%node_group%grp_index
633 dst%node_group%grp_item => src%node_group%grp_item
634 dst%node_group%bc_grp_ID => src%node_group%bc_grp_ID
635 dst%node_group%bc_grp_type => src%node_group%bc_grp_type
636 dst%node_group%bc_grp_index => src%node_group%bc_grp_index
637 dst%node_group%bc_grp_dof => src%node_group%bc_grp_dof
638 dst%node_group%bc_grp_val => src%node_group%bc_grp_val
641 end subroutine hecmw_mpc_mesh_copy
643 subroutine hecmw_mpc_mesh_free(hecMESH)
646 if (hecmesh%n_neighbor_pe > 1)
then
647 deallocate(hecmesh%neighbor_pe)
648 deallocate(hecmesh%import_index)
649 deallocate(hecmesh%export_index)
650 deallocate(hecmesh%import_item)
651 deallocate(hecmesh%export_item)
653 deallocate(hecmesh%global_node_ID)
654 deallocate(hecmesh%node_ID)
655 deallocate(hecmesh%elem_type_item)
656 end subroutine hecmw_mpc_mesh_free
660 subroutine debug_write_vector(Vec, label, name, ndof, N, &
661 NP, write_ext, slaves)
662 real(kind=
kreal),
intent(in) :: vec(:)
663 character(len=*),
intent(in) :: label
664 character(len=*),
intent(in) :: name
665 integer(kind=kint),
intent(in) :: ndof
666 integer(kind=kint),
intent(in) :: n
667 integer(kind=kint),
intent(in),
optional :: np
668 logical,
intent(in),
optional :: write_ext
669 integer(kind=kint),
intent(in),
optional :: slaves(:)
671 integer(kind=kint) :: iunit
672 character(len=128) :: fmt
674 if (.not. debug_vector)
return
676 write(fmt,
'(a,i0,a)')
'(',ndof,
'f12.3)'
679 write(iunit,*) trim(label),
'------------------------------------------------------------'
680 write(iunit,*)
'size of ',trim(name),
size(vec)
681 write(iunit,*) trim(name),
': 1-',n*ndof
682 write(iunit,fmt) vec(1:n*ndof)
683 if (
present(write_ext) .and.
present(np))
then
685 write(iunit,*) trim(name),
'(external): ',n*ndof+1,
'-',np*ndof
686 write(iunit,fmt) vec(n*ndof+1:np*ndof)
689 if (
present(slaves))
then
690 if (
size(slaves) > 0)
then
691 write(iunit,*) trim(name),
'(slave):',slaves(:)
692 write(iunit,fmt) vec(slaves(:))
695 end subroutine debug_write_vector
subroutine, public hecmw_trimatmul_ttkt_mpc(hecMESH, hecMAT, hecTKT)
subroutine, public hecmw_mat_ass_equation_rhs(hecMESH, hecMAT)
subroutine, public hecmw_mat_ass_equation(hecMESH, hecMAT)
integer(kind=kint) function, public hecmw_mat_get_solver_type(hecMAT)
subroutine, public hecmw_mat_init(hecMAT)
subroutine, public hecmw_mat_finalize(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_mpc_method(hecMAT)
subroutine, public hecmw_mat_set_mpc_method(hecMAT, mpc_method)
subroutine, public hecmw_mpc_tback_sol(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_trans_mass(hecMESH, hecMAT, hecMATmpc, mass)
subroutine, public hecmw_mpc_mat_init_explicit(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mat_finalize_explicit(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mat_init(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc)
subroutine, public hecmw_mpc_mat_ass(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc, hecLagMAT)
subroutine, public hecmw_mpc_mat_finalize(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMATmpc)
subroutine, public hecmw_mpc_tback_eigvec(hecMESH, hecMAT, neig, eigvec)
subroutine, public hecmw_mpc_trans_rhs(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mark_slave(hecMESH, hecMAT, mark)
subroutine, public hecmw_ttvec(hecMESH, ndof, X, Y, COMMtime)
subroutine, public hecmw_tvec(hecMESH, ndof, X, Y, COMMtime)
subroutine, public hecmw_matresid(hecMESH, hecMAT, X, B, R, COMMtime)
integer(kind=kint), parameter hecmw_sum
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_allreduce_i1(hecMESH, s, ntag)
Structure for Lagrange multiplier-related part of stiffness matrix (Lagrange multiplier-related matri...