SCALE-RM
scale_matrix.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
9 !-------------------------------------------------------------------------------
10 #include "inc_openmp.h"
12  !-----------------------------------------------------------------------------
13  !
14  !++ used modules
15  !
16  use scale_precision
17  use scale_stdio
18  !-----------------------------------------------------------------------------
19  implicit none
20  private
21  !-----------------------------------------------------------------------------
22  !
23  !++ Public procedure
24  !
25  public :: matrix_solver_tridiagonal
26 
27  interface matrix_solver_tridiagonal
28  module procedure matrix_solver_tridiagonal_1d
29  module procedure matrix_solver_tridiagonal_3d
30  end interface matrix_solver_tridiagonal
31 
32  !-----------------------------------------------------------------------------
33  !
34  !++ Public parameters & variables
35  !
36  !-----------------------------------------------------------------------------
37  !
38  !++ Private procedure
39  !
40  !-----------------------------------------------------------------------------
41  !
42  !++ Private parameters & variables
43  !
44  !-----------------------------------------------------------------------------
45 contains
46  !-----------------------------------------------------------------------------
48  subroutine matrix_solver_tridiagonal_1d( &
49  KA, &
50  ud, &
51  md, &
52  ld, &
53  iv, &
54  ov )
55  implicit none
56 
57  integer, intent(in) :: KA ! array size
58  real(RP), intent(in) :: ud(KA) ! upper diagonal
59  real(RP), intent(in) :: md(KA) ! middle diagonal
60  real(RP), intent(in) :: ld(KA) ! lower diagonal
61  real(RP), intent(in) :: iv(KA) ! input vector
62  real(RP), intent(out) :: ov(KA) ! output vector
63 
64  real(RP) :: c(KA)
65  real(RP) :: d(KA)
66 
67  integer :: k
68  !---------------------------------------------------------------------------
69 
70  ! foward reduction
71  c(1) = ud(1) / md(1)
72  d(1) = iv(1) / md(1)
73  do k = 2, ka
74  c(k) = ud(k) / ( md(k) - ld(k) * c(k-1) )
75  d(k) = ( iv(k) - ld(k) * d(k-1) ) / ( md(k) - ld(k) * c(k-1) )
76  enddo
77 
78  ! backward substitution
79  ov(ka) = d(ka)
80  do k = ka-1, 1, -1
81  ov(k) = d(k) - c(k) * ov(k+1)
82  enddo
83 
84  return
85  end subroutine matrix_solver_tridiagonal_1d
86 
87  !-----------------------------------------------------------------------------
89  subroutine matrix_solver_tridiagonal_3d( &
90  KA, &
91  IA, IS, IE, &
92  JA, JS, JE, &
93  ud, &
94  md, &
95  ld, &
96  iv, &
97  ov )
98  implicit none
99 
100  integer, intent(in) :: KA ! array size
101  integer, intent(in) :: IA, IS, IE ! array size
102  integer, intent(in) :: JA, JS, JE ! array size
103  real(RP), intent(in) :: ud(KA,IA,JA) ! upper diagonal
104  real(RP), intent(in) :: md(KA,IA,JA) ! middle diagonal
105  real(RP), intent(in) :: ld(KA,IA,JA) ! lower diagonal
106  real(RP), intent(in) :: iv(KA,IA,JA) ! input vector
107  real(RP), intent(out) :: ov(KA,IA,JA) ! output vector
108 
109  real(RP) :: c(KA,IA,JA)
110  real(RP) :: d(KA,IA,JA)
111 
112  integer :: k, i, j
113  !---------------------------------------------------------------------------
114 
115  ! foward reduction
116  do j = js, je
117  do i = is, ie
118  c(1,i,j) = ud(1,i,j) / md(1,i,j)
119  d(1,i,j) = iv(1,i,j) / md(1,i,j)
120  enddo
121  enddo
122 
123  !$omp parallel do default(none) &
124  !$omp shared(JS,JE,IS,IE,KA,ud,md,ld,iv,c,d) &
125  !$omp private(i,j,k) OMP_SCHEDULE_ collapse(2)
126  do j = js, je
127  do i = is, ie
128  do k = 2, ka
129  c(k,i,j) = ud(k,i,j) &
130  / ( md(k,i,j) - ld(k,i,j) * c(k-1,i,j) )
131  d(k,i,j) = ( iv(k,i,j) - ld(k,i,j) * d(k-1,i,j) ) &
132  / ( md(k,i,j) - ld(k,i,j) * c(k-1,i,j) )
133  enddo
134  enddo
135  enddo
136 
137  ! backward substitution
138  do j = js, je
139  do i = is, ie
140  ov(ka,i,j) = d(ka,i,j)
141  enddo
142  enddo
143 
144  do j = js, je
145  do i = is, ie
146  do k = ka-1, 1, -1
147  ov(k,i,j) = d(k,i,j) - c(k,i,j) * ov(k+1,i,j)
148  enddo
149  enddo
150  enddo
151 
152  return
153  end subroutine matrix_solver_tridiagonal_3d
154 
155 end module scale_matrix
module STDIO
Definition: scale_stdio.F90:12
module MATRIX
module PRECISION