40#include "dmumps_struc.h"
56 INTEGER,
PRIVATE :: global_dimension
72 TYPE(dmumps_struc),
PRIVATE :: mumps_par
73 LOGICAL :: job_1_done = .false.
75 PROCEDURE, pass :: init_solver_mumps
76 PROCEDURE, pass :: set_matrix_mumps
77 PROCEDURE, pass :: set_rhs_mumps
78 PROCEDURE, pass :: solve_mumps
79 PROCEDURE, pass :: terminate_mumps
80 END TYPE t_mumps_solver
90 my_real,
DIMENSION(:),
ALLOCATABLE :: diag
135 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
136#include "implicit_f.inc"
153 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
154#include "implicit_f.inc"
156 INTEGER,
INTENT(IN) :: mat_dim
157 this%GLOBAL_DIMENSION = mat_dim
160 TYPE IS (t_mumps_solver)
161 CALL this%INIT_SOLVER_MUMPS(mat_dim)
164 CALL this%INIT_SOLVER_CG(mat_dim)
186 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
187#include "implicit_f.inc"
192 TYPE IS (t_mumps_solver)
193 CALL this%SET_MATRIX_MUMPS(mat)
196 CALL this%SET_MATRIX_CG(mat)
218 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
219#include "implicit_f.inc"
221 INTEGER,
INTENT(IN) :: NRHS
222 TYPE(
t_vector),
INTENT(INOUT) :: RHS
225 TYPE IS (t_mumps_solver)
226 CALL this%SET_RHS_MUMPS(nrhs, rhs)
229 CALL this%SET_RHS_CG(nrhs, rhs)
246 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
247#include "implicit_f.inc"
249 INTEGER,
INTENT(IN) :: DIM
250 DOUBLE PRECISION,
DIMENSION(DIM),
INTENT(OUT) :: SOL
253 TYPE IS (t_mumps_solver)
254 CALL this%SOLVE_MUMPS(sol, dim)
257 CALL this%SOLVE_CG(sol, dim)
274 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
275#include "implicit_f.inc"
279 TYPE IS (t_mumps_solver)
280 CALL this%TERMINATE_MUMPS()
283 CALL this%TERMINATE_CG()
302 SUBROUTINE init_solver_mumps(this, MAT_DIM)
306 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
307#include "implicit_f.inc"
313 class(t_mumps_solver),
INTENT(INOUT) :: this
314 INTEGER,
INTENT(IN) :: MAT_DIM
315 this%MUMPS_PAR%PAR = 1
317 this%MUMPS_PAR%COMM = spmd_comm_world
319 this%MUMPS_PAR%COMM = -1
321 this%mumps_par%job = -1
322 this%mumps_par%sym = 0
323 call dmumps(this%mumps_par)
326 this%MUMPS_PAR%ICNTL(5) = 0
328 this%MUMPS_PAR%ICNTL(18) = 3
330 this%MUMPS_PAR%N = mat_dim
332 this%MUMPS_PAR%SYM = 1
334 this%MUMPS_PAR%ICNTL(20) = 10
338 this%MUMPS_PAR%ICNTL(21) = 0
340 this%MUMPS_PAR%ICNTL(11) = 1
344 this%MUMPS_PAR%ICNTL(4) = 0
346 END SUBROUTINE init_solver_mumps
356 SUBROUTINE set_matrix_mumps(this, MAT)
364 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
365#include "implicit_f.inc"
366 class(t_mumps_solver),
INTENT(INOUT) :: this
368 CALL mat%MATRIX_ASSOCIATE(this%MUMPS_PAR%IRN_LOC, this%MUMPS_PAR%JCN_LOC, this%MUMPS_PAR%A_LOC)
369 this%MUMPS_PAR%NNZ_LOC = mat%GET_DIM()
370 END SUBROUTINE set_matrix_mumps
380 SUBROUTINE set_rhs_mumps(this, NRHS, RHS)
388 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
389#include "implicit_f.inc"
390 class(t_mumps_solver),
INTENT(INOUT) :: this
391 INTEGER,
INTENT(IN) :: NRHS
392 TYPE(
t_vector),
INTENT(INOUT) :: RHS
398 CALL rhs%ASSOCIATE(this%MUMPS_PAR%IRHS_LOC, this%MUMPS_PAR%RHS_LOC)
399 dim = rhs%GET_DIM() / nrhs
400 this%MUMPS_PAR%NRHS = nrhs
401 this%MUMPS_PAR%NLOC_RHS = dim
402 this%MUMPS_PAR%LRHS_LOC = dim
403 END SUBROUTINE set_rhs_mumps
413 SUBROUTINE solve_mumps(this, SOL, DIM)
417 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
418#include "implicit_f.inc"
419#include "com01_c.inc"
426 class(t_mumps_solver),
INTENT(INOUT) :: this
427 INTEGER,
INTENT(IN) :: DIM
429 DOUBLE PRECISION,
DIMENSION(DIM),
INTENT(OUT),
TARGET :: SOL
434 IF (dim /= this%MUMPS_PAR%N * this%MUMPS_PAR%NRHS)
THEN
435 print*,
"*** DIMENSION MISMATCH IN SOLUTION VECTOR"
438 IF (.NOT. this%JOB_1_DONE)
THEN
440 this%MUMPS_PAR%JOB = 1
441 CALL dmumps(this%MUMPS_PAR)
442 this%JOB_1_DONE = .true.
445 this%MUMPS_PAR%JOB = 2
446 CALL dmumps(this%MUMPS_PAR)
449 this%MUMPS_PAR%RHS => sol
450 this%MUMPS_PAR%LRHS = this%MUMPS_PAR%N
451 this%MUMPS_PAR%JOB = 3
452 CALL dmumps(this%MUMPS_PAR)
457 CALL mpi_bcast(sol, dim, real, 0, spmd_comm_world, ierr)
461 END SUBROUTINE solve_mumps
471 SUBROUTINE terminate_mumps(this)
475 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
476#include "implicit_f.inc"
482 class(t_mumps_solver),
INTENT(INOUT) :: this
484 this%MUMPS_PAR%JOB = -2
485 CALL dmumps(this%MUMPS_PAR)
487 END SUBROUTINE terminate_mumps
505 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
506#include "implicit_f.inc"
508 INTEGER,
INTENT(IN) :: MAT_DIM
510 CALL this%SOL_VEC%CREATE(mat_dim)
511 CALL this%R%CREATE(mat_dim)
512 CALL this%RNEW%CREATE(mat_dim)
513 CALL this%TEMP%CREATE(mat_dim)
514 CALL this%P%CREATE(mat_dim)
515 ALLOCATE(this%DIAG(mat_dim))
535 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
536#include "implicit_f.inc"
560 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
561#include "implicit_f.inc"
563 INTEGER,
INTENT(IN) :: NRHS
564 TYPE(
t_vector),
INTENT(INOUT),
TARGET :: RHS
587 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
588#include "implicit_f.inc"
589#include "com01_c.inc"
597 INTEGER,
INTENT(IN) :: DIM
598 DOUBLE PRECISION,
DIMENSION(DIM),
INTENT(OUT),
TARGET :: SOL
602 INTEGER :: ITER, SYSTEM_SIZE, IRHS, II, I, J, MAT_NNZ
611 system_size = dim / this%NRHS
612 max_iter = system_size
616 mat_nnz = this%MAT%GET_DIM()
618 i = this%MAT%IROW(ii)
619 j = this%MAT%JCOL(ii)
621 this%DIAG(i) = one / sqrt(this%MAT%VAL(ii))
626 DO irhs = 1, this%NRHS
627 this%SOL_VEC%VAL(1:system_size) = zero
629 CALL prod_vec(this%MAT, this%SOL_VEC, this%TEMP)
630 this%R%VAL(1:system_size) = this%RHS%VAL(system_size * (irhs - 1) + 1 : system_size * (irhs - 1) + system_size) -
631 . this%TEMP%VAL(1:system_size)
632 this%P%VAL(1:system_size) = this%R%VAL(1:system_size)
633 norm_init = this%R%NORM()
636 DO WHILE (iter <= max_iter .AND.
error > tol)
638 CALL prod_vec(this%MAT, this%P, this%TEMP)
639 alpha = dot_product(this%R%VAL(1:system_size),this% R%VAL(1:system_size)) /
640 . dot_product(this%TEMP%VAL(1:system_size), this%P%VAL(1:system_size))
641 DO ii = 1, system_size
642 this%SOL_VEC%VAL(ii) = this%SOL_VEC%VAL(ii) +
alpha * this%P%VAL(ii)
643 this%RNEW%VAL(ii) = this%R%VAL(ii) -
alpha * this%TEMP%VAL(ii)
645 beta = dot_product(this%RNEW%VAL(1:system_size), this%RNEW%VAL(1:system_size)) /
646 . dot_product(this%R%VAL(1:system_size), this%R%VAL(1:system_size))
647 DO ii = 1, system_size
648 this%P%VAL(ii) = this%RNEW%VAL(ii) + beta * this%P%VAL(ii)
649 this%R%VAL(ii) = this%RNEW%VAL(ii)
651 error = this%R%NORM() / norm_init
653 sol(system_size * (irhs - 1) + 1:system_size * (irhs - 1) + system_size) =
654 . this%SOL_VEC%VAL(1:system_size)
671 USE spmd_comm_world_mod,
ONLY : spmd_comm_world
672#include "implicit_f.inc"
674 CALL this%SOL_VEC%DESTROY()
675 CALL this%R%DESTROY()
676 CALL this%TEMP%DESTROY()
677 CALL this%P%DESTROY()
678 CALL this%RNEW%DESTROY()
679 DEALLOCATE(this%DIAG)
subroutine mpi_bcast(buffer, cnt, datatype, root, comm, ierr)
integer function get_global_dim(this)
subroutine set_matrix_cg(this, mat)
subroutine set_matrix(this, mat)
subroutine set_rhs_cg(this, nrhs, rhs)
subroutine terminate(this)
subroutine set_rhs(this, nrhs, rhs)
subroutine init_solver(this, mat_dim)
subroutine solve(this, sol, dim)
subroutine terminate_cg(this)
subroutine solve_cg(this, sol, dim)
subroutine init_solver_cg(this, mat_dim)