584
585
586
587 USE spmd_comm_world_mod, ONLY : spmd_comm_world
588#include "implicit_f.inc"
589#include "com01_c.inc"
590#include "task_c.inc"
591
592
593
594#include "spmd.inc"
595
596 class(t_cg_solver), INTENT(INOUT) :: this
597 INTEGER, INTENT(IN) :: DIM
598 DOUBLE PRECISION, DIMENSION(DIM), INTENT(OUT), TARGET :: SOL
599
600
601
602 INTEGER :: ITER, SYSTEM_SIZE, IRHS, II, I, J, MAT_NNZ
605
606 INTEGER :: MAX_ITER
608
609 tol = 1.d-8
610
611 system_size = dim / this%NRHS
612 max_iter = system_size
613
614
615
616 mat_nnz = this%MAT%GET_DIM()
617 DO ii = 1, mat_nnz
618 i = this%MAT%IROW(ii)
619 j = this%MAT%JCOL(ii)
620 IF (i == j) THEN
621 this%DIAG(i) = one / sqrt(this%MAT%VAL(ii))
622 ENDIF
623 ENDDO
624
625
626 DO irhs = 1, this%NRHS
627 this%SOL_VEC%VAL(1:system_size) = zero
628
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()
634 error = norm_init
635 iter = 0
636 DO WHILE (iter <= max_iter .AND. error > tol)
637 iter = iter + 1
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)
644 ENDDO
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)
650 ENDDO
651 error = this%R%NORM() / norm_init
652 ENDDO
653 sol(system_size * (irhs - 1) + 1:system_size * (irhs - 1) + system_size) =
654 . this%SOL_VEC%VAL(1:system_size)
655 ENDDO
656
657