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)
287 call hecmw_trans_b(hecmesh, hecmat, hecmat%B, hecmatmpc%B, time_dumm)
288 hecmatmpc%Iarray=hecmat%Iarray
289 hecmatmpc%Rarray=hecmat%Rarray
292 hecmatmpc%symmetric=hecmat%symmetric
307 real(kind=
kreal) :: time_dumm
308 integer(kind=kint) :: totalmpc, mpc_method, i
309 integer(kind=kint) :: npndof, npndof_mpc, num_lagrange
311 totalmpc = hecmesh%mpc%n_mpc
314 if (totalmpc == 0)
return
318 select case (mpc_method)
322 npndof = hecmat%NP * hecmat%NDOF
324 hecmat%X(i) = hecmatmpc%X(i)
327 call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
328 num_lagrange =
size(hecmat%X) - npndof
329 npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
330 do i = 1, num_lagrange
331 hecmat%X(npndof+i) = hecmatmpc%X(npndof_mpc+i)
333 hecmat%Iarray=hecmatmpc%Iarray
334 hecmat%Rarray=hecmatmpc%Rarray
348 real(kind=
kreal),
pointer :: mass(:)
350 real(kind=
kreal),
allocatable :: w(:), mtmp(:)
351 real(kind=
kreal) :: time_dumm
352 integer(kind=kint) :: totalmpc, mpc_method, i
353 integer(kind=kint) :: npndof, npndof_mpc
355 totalmpc = hecmesh%mpc%n_mpc
358 if (totalmpc == 0)
return
362 select case (mpc_method)
366 npndof = hecmat%NP * hecmat%NDOF
367 npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
369 allocate(mtmp(npndof))
374 call hecmw_tvec(hecmesh, hecmat%NDOF, mtmp, w, time_dumm)
377 w(i) = mass(i) * w(i)
380 call hecmw_ttvec(hecmesh, hecmat%NDOF, w, mtmp, time_dumm)
383 allocate(mass(npndof_mpc))
403 integer(kind=kint),
intent(in) :: neig
404 real(kind=
kreal),
intent(inout) :: eigvec(:,:)
406 real(kind=
kreal) :: time_dumm
407 integer(kind=kint) :: totalmpc, mpc_method, i
409 totalmpc = hecmesh%mpc%n_mpc
412 if (totalmpc == 0)
return
416 select case (mpc_method)
422 call hecmw_tback_x(hecmesh, hecmat%NDOF, eigvec(:,i), time_dumm)
437 integer(kind=kint),
intent(out) :: mark(:)
439 integer(kind=kint) :: ndof, i, j, k, kk
443 outer:
do i = 1, hecmesh%mpc%n_mpc
444 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
445 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
447 k = hecmesh%mpc%mpc_index(i-1)+1
448 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
458 subroutine hecmw_mpc_scale(hecMESH)
461 integer(kind=kint) :: i, j, k
462 real(kind=
kreal) :: wval
466 do i = 1, hecmesh%mpc%n_mpc
467 k = hecmesh%mpc%mpc_index(i-1)+1
468 wval = 1.d0 / hecmesh%mpc%mpc_val(k)
469 hecmesh%mpc%mpc_val(k) = 1.d0
470 do j = hecmesh%mpc%mpc_index(i-1)+2, hecmesh%mpc%mpc_index(i)
471 hecmesh%mpc%mpc_val(j) = hecmesh%mpc%mpc_val(j) * wval
473 hecmesh%mpc%mpc_const(i) = hecmesh%mpc%mpc_const(i) * wval
478 end subroutine hecmw_mpc_scale
486 subroutine hecmw_trans_b(hecMESH, hecMAT, B, BT, COMMtime)
490 real(kind=
kreal),
intent(in) :: b(:)
491 real(kind=
kreal),
intent(out),
target :: bt(:)
492 real(kind=
kreal),
intent(inout) :: commtime
494 real(kind=
kreal),
allocatable :: w(:)
495 real(kind=
kreal),
pointer :: xg(:)
496 integer(kind=kint) :: ndof, i, j, k, kk
500 call debug_write_vector(b,
'original RHS',
'B', ndof, hecmat%N, hecmat%NP, .true.)
502 allocate(w(hecmesh%n_node * ndof))
510 do i = 1, hecmat%N * ndof
517 outer:
do i = 1, hecmesh%mpc%n_mpc
518 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
519 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
521 k = hecmesh%mpc%mpc_index(i-1) + 1
522 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
523 xg(kk) = hecmesh%mpc%mpc_const(i)
536 call debug_write_vector(bt,
'transformed RHS',
'BT', ndof, hecmat%N, hecmat%NP, .true.)
537 end subroutine hecmw_trans_b
545 subroutine hecmw_tback_x(hecMESH, ndof, X, COMMtime)
548 integer(kind=kint),
intent(in) :: ndof
549 real(kind=
kreal),
intent(inout) :: x(:)
550 real(kind=
kreal),
intent(inout) :: commtime
552 real(kind=
kreal),
allocatable :: w(:)
553 integer(kind=kint) :: i, j, k, kk
555 call debug_write_vector(x,
'solution for transformed eqn',
'X', ndof, hecmesh%nn_internal, &
556 hecmesh%n_node, .true.)
558 allocate(w(hecmesh%n_node * ndof))
561 call hecmw_tvec(hecmesh, ndof, x, w, commtime)
566 do i= 1, hecmesh%nn_internal * ndof
572 outer:
do i = 1, hecmesh%mpc%n_mpc
573 do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
574 if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
576 k = hecmesh%mpc%mpc_index(i-1) + 1
577 kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
578 x(kk) = x(kk) + hecmesh%mpc%mpc_const(i)
586 call debug_write_vector(x,
'recovered solution',
'X', ndof, hecmesh%nn_internal, &
587 hecmesh%n_node, .true.)
588 end subroutine hecmw_tback_x
590 subroutine hecmw_mpc_mesh_copy(src, dst)
595 dst%MPI_COMM = src%MPI_COMM
596 dst%PETOT = src%PETOT
597 dst%PEsmpTOT = src%PEsmpTOT
598 dst%my_rank = src%my_rank
599 dst%n_subdomain = src%n_subdomain
600 dst%n_node = src%n_node
601 dst%nn_internal = src%nn_internal
602 dst%n_elem = src%n_elem
603 dst%ne_internal = src%ne_internal
604 dst%n_elem_type = src%n_elem_type
605 dst%n_dof = src%n_dof
606 dst%n_neighbor_pe = src%n_neighbor_pe
607 if (src%n_neighbor_pe > 0)
then
608 allocate(dst%neighbor_pe(dst%n_neighbor_pe))
609 dst%neighbor_pe(:) = src%neighbor_pe(:)
610 allocate(dst%import_index(0:dst%n_neighbor_pe))
611 dst%import_index(:)= src%import_index(:)
612 allocate(dst%export_index(0:dst%n_neighbor_pe))
613 dst%export_index(:)= src%export_index(:)
614 allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
615 dst%import_item(:) = src%import_item(:)
616 allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
617 dst%export_item(:) = src%export_item(:)
619 allocate(dst%global_node_ID(dst%n_node))
620 dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:dst%n_node)
621 allocate(dst%node_ID(2*dst%n_node))
622 dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*dst%n_node)
623 allocate(dst%elem_type_item(dst%n_elem_type))
624 dst%elem_type_item(:) = src%elem_type_item(:)
626 dst%mpc%n_mpc = src%mpc%n_mpc
627 dst%mpc%mpc_index => src%mpc%mpc_index
628 dst%mpc%mpc_item => src%mpc%mpc_item
629 dst%mpc%mpc_dof => src%mpc%mpc_dof
630 dst%mpc%mpc_val => src%mpc%mpc_val
631 dst%mpc%mpc_const => src%mpc%mpc_const
633 dst%node_group%n_grp = src%node_group%n_grp
634 dst%node_group%n_bc = src%node_group%n_bc
635 dst%node_group%grp_name => src%node_group%grp_name
636 dst%node_group%grp_index => src%node_group%grp_index
637 dst%node_group%grp_item => src%node_group%grp_item
638 dst%node_group%bc_grp_ID => src%node_group%bc_grp_ID
639 dst%node_group%bc_grp_type => src%node_group%bc_grp_type
640 dst%node_group%bc_grp_index => src%node_group%bc_grp_index
641 dst%node_group%bc_grp_dof => src%node_group%bc_grp_dof
642 dst%node_group%bc_grp_val => src%node_group%bc_grp_val
645 dst%elem_type_index => src%elem_type_index
646 dst%elem_node_index => src%elem_node_index
647 dst%elem_node_item => src%elem_node_item
648 end subroutine hecmw_mpc_mesh_copy
650 subroutine hecmw_mpc_mesh_free(hecMESH)
653 if (hecmesh%n_neighbor_pe > 0)
then
654 deallocate(hecmesh%neighbor_pe)
655 deallocate(hecmesh%import_index)
656 deallocate(hecmesh%export_index)
657 deallocate(hecmesh%import_item)
658 deallocate(hecmesh%export_item)
660 deallocate(hecmesh%global_node_ID)
661 deallocate(hecmesh%node_ID)
662 deallocate(hecmesh%elem_type_item)
663 end subroutine hecmw_mpc_mesh_free
667 subroutine debug_write_vector(Vec, label, name, ndof, N, &
668 NP, write_ext, slaves)
669 real(kind=
kreal),
intent(in) :: vec(:)
670 character(len=*),
intent(in) :: label
671 character(len=*),
intent(in) :: name
672 integer(kind=kint),
intent(in) :: ndof
673 integer(kind=kint),
intent(in) :: n
674 integer(kind=kint),
intent(in),
optional :: np
675 logical,
intent(in),
optional :: write_ext
676 integer(kind=kint),
intent(in),
optional :: slaves(:)
678 integer(kind=kint) :: iunit
679 character(len=128) :: fmt
681 if (.not. debug_vector)
return
683 write(fmt,
'(a,i0,a)')
'(',ndof,
'f12.3)'
686 write(iunit,*) trim(label),
'------------------------------------------------------------'
687 write(iunit,*)
'size of ',trim(name),
size(vec)
688 write(iunit,*) trim(name),
': 1-',n*ndof
689 write(iunit,fmt) vec(1:n*ndof)
690 if (
present(write_ext) .and.
present(np))
then
692 write(iunit,*) trim(name),
'(external): ',n*ndof+1,
'-',np*ndof
693 write(iunit,fmt) vec(n*ndof+1:np*ndof)
696 if (
present(slaves))
then
697 if (
size(slaves) > 0)
then
698 write(iunit,*) trim(name),
'(slave):',slaves(:)
699 write(iunit,fmt) vec(slaves(:))
702 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...