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