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-1
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  d(ke) = ( iv(ke) - ld(ke) * d(ke-1) ) / ( md(ke) - ld(ke) * c(ke-1) )
79 
80  ! backward substitution
81  ov(ke) = d(ke)
82  do k = ke-1, ks, -1
83  ov(k) = d(k) - c(k) * ov(k+1)
84  enddo
85 
86  return
87  end subroutine matrix_solver_tridiagonal_1d
88 
89  !-----------------------------------------------------------------------------
91  subroutine matrix_solver_tridiagonal_3d( &
92  KA, KS, KE, &
93  IA, IS, IE, &
94  JA, JS, JE, &
95  ud, &
96  md, &
97  ld, &
98  iv, &
99  ov, &
100  mask )
101  implicit none
102 
103  integer, intent(in) :: KA, KS, KE ! array size
104  integer, intent(in) :: IA, IS, IE ! array size
105  integer, intent(in) :: JA, JS, JE ! array size
106  real(RP), intent(in) :: ud(KA,IA,JA) ! upper diagonal
107  real(RP), intent(in) :: md(KA,IA,JA) ! middle diagonal
108  real(RP), intent(in) :: ld(KA,IA,JA) ! lower diagonal
109  real(RP), intent(in) :: iv(KA,IA,JA) ! input vector
110  real(RP), intent(out) :: ov(KA,IA,JA) ! output vector
111 
112  logical, intent(in), optional :: mask(IA,JA)
113 
114  integer :: i, j
115  !---------------------------------------------------------------------------
116 
117  if ( present(mask) ) then
118  !$omp parallel do default(none) OMP_SCHEDULE_ collapse(2) &
119  !$omp shared(JS,JE,IS,IE,KA,KS,KE,ud,md,ld,iv,ov,mask) &
120  !$omp private(i,j)
121  do j = js, je
122  do i = is, ie
123  if ( mask(i,j) ) then
124  call matrix_solver_tridiagonal_1d( ka, ks, ke, &
125  ud(:,i,j), md(:,i,j), ld(:,i,j), & ! (in)
126  iv(:,i,j), & ! (in)
127  ov(:,i,j) ) ! (out)
128  end if
129  enddo
130  enddo
131  else
132  !$omp parallel do default(none) OMP_SCHEDULE_ collapse(2) &
133  !$omp shared(JS,JE,IS,IE,KA,KS,KE,ud,md,ld,iv,ov) &
134  !$omp private(i,j)
135  do j = js, je
136  do i = is, ie
137  call matrix_solver_tridiagonal_1d( ka, ks, ke, &
138  ud(:,i,j), md(:,i,j), ld(:,i,j), & ! (in)
139  iv(:,i,j), & ! (in)
140  ov(:,i,j) ) ! (out)
141  enddo
142  enddo
143  end if
144 
145  return
146  end subroutine matrix_solver_tridiagonal_3d
147 
148 end module scale_matrix
scale_precision
module PRECISION
Definition: scale_precision.F90:14
scale_io
module STDIO
Definition: scale_io.F90:10
scale_prof
module profiler
Definition: scale_prof.F90:11
scale_matrix
module MATRIX
Definition: scale_matrix.F90:11