module_vertmx_wrf.F
References to this file elsewhere.
1 MODULE module_vertmx_wrf
2
3 CONTAINS
4
5 SUBROUTINE vertmx(dt,phi,kt_turb,zsigma,zsigma_half,vd,kts,kte)
6 ! !! to calculate change in time of phi due to vertical mixing
7 ! !! Mariusz Pagowski, March 2001
8 ! !! conventions used:
9 ! !! input is lower case
10 ! !! output is upper case
11 ! .. Scalar Arguments ..
12 REAL :: dt, vd
13 INTEGER :: kts,kte
14 ! ..
15 ! .. Array Arguments ..
16 REAL, DIMENSION (kts:kte+1) :: kt_turb, zsigma
17 REAL, DIMENSION (kts:kte) :: phi, zsigma_half
18 ! ..
19 ! .. Local Scalars ..
20 INTEGER :: k
21 ! ..
22 ! .. Local Arrays ..
23 REAL, DIMENSION (kts:kte+1) :: a_coeff
24 REAL, DIMENSION (kts:kte) :: b_coeff, lhs1, lhs2, lhs3, rhs
25 ! ..
26 ! .. External Subroutines ..
27 ! EXTERNAL coeffs, rlhside, tridiag
28 ! ..
29 CALL coeffs(kts,kte+1,zsigma,zsigma_half,a_coeff,b_coeff)
30
31 CALL rlhside(kts,kte+1,kt_turb,a_coeff,b_coeff,phi,dt,vd,rhs,lhs1,lhs2,lhs3)
32
33 CALL tridiag(kts,kte,lhs1,lhs2,lhs3,rhs)
34
35 DO k = kts,kte
36 phi(k) = rhs(k)
37 END DO
38
39 END SUBROUTINE vertmx
40 SUBROUTINE rlhside(kts,kte,k_turb,a_coeff,b_coeff,phi,dt,vd,rhs,lhs1,lhs2,lhs3)
41 !! to calculate right and left hand sides in diffusion equation
42 !! for the tridiagonal solver
43 !! Mariusz Pagowski, March 2001
44 !! conventions used:
45 !! input is lower case
46 !! output is upper case
47 ! .. Scalar Arguments ..
48 REAL :: dt, vd
49 INTEGER :: kts,kte
50 ! ..
51 ! .. Array Arguments ..
52 REAL, DIMENSION (kts:kte) :: a_coeff, k_turb
53 REAL, DIMENSION (kts:kte-1) :: b_coeff, lhs1, lhs2, lhs3, phi, rhs
54 ! ..
55 ! .. Local Scalars ..
56 REAL :: a1, a2, alfa_explicit = .25, beta_implicit = .75
57 INTEGER :: i
58 ! ..
59 ! rhs(1)=phi(1) !! this should be really the n+1 step
60 rhs(1) = 0.
61 rhs(1) = (1./(dt*b_coeff(1))-alfa_explicit*(a_coeff(2)*k_turb(2)+vd))* &
62 phi(1) + alfa_explicit*a_coeff(2)*k_turb(2)*phi(2)
63 lhs1(1) = 0.
64 ! lhs2(1)=1.
65 ! lhs3(1)=0.
66 ! lhs3(1)=-1.
67 lhs2(1) = 1./(dt*b_coeff(1)) + beta_implicit*(a_coeff(2)*k_turb(2)+vd)
68 lhs3(1) = -beta_implicit*a_coeff(2)*k_turb(2)
69
70 DO i = kts+1, kte - 2
71 a1 = a_coeff(i)*k_turb(i)
72 a2 = a_coeff(i+1)*k_turb(i+1)
73 rhs(i) = (1./(dt*b_coeff(i))-alfa_explicit*(a1+a2))*phi(i) + &
74 alfa_explicit*(a1*phi(i-1)+a2*phi(i+1))
75
76 lhs1(i) = -beta_implicit*a1
77 lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(a1+a2)
78 lhs3(i) = -beta_implicit*a2
79 END DO
80
81 !! zero flux at the top
82
83 rhs(kte-1) = 0.
84 lhs1(kte-1) = 1.
85 lhs2(kte-1) = -1.
86 lhs3(kte-1) = 0.
87
88 END SUBROUTINE rlhside
89
90
91
92
93
94
95
96
97
98
99 SUBROUTINE tridiag(kts,kte,a,b,c,f)
100 !! to solve system of linear eqs on tridiagonal matrix n times n
101 !! after Peaceman and Rachford, 1955
102 !! a,b,c,F - are vectors of order n
103 !! a,b,c - are coefficients on the LHS
104 !! F - is initially RHS on the output becomes a solution vector
105 !! Mariusz Pagowski, March 2001
106 !! conventions used:
107 !! input is lower case
108 !! output is upper case
109 ! .. Scalar Arguments ..
110 INTEGER :: kts,kte
111 ! ..
112 ! .. Array Arguments ..
113 REAL, DIMENSION (kts:kte) :: a, b, c, f
114 ! ..
115 ! .. Local Scalars ..
116 REAL :: p
117 INTEGER :: i
118 ! ..
119 ! .. Local Arrays ..
120 REAL, DIMENSION (kts:kte) :: q
121 ! ..
122 c(kte) = 0.
123 q(1) = -c(1)/b(1)
124 f(1) = f(1)/b(1)
125
126 DO i = kts+1, kte
127 p = 1./(b(i)+a(i)*q(i-1))
128 q(i) = -c(i)*p
129 f(i) = (f(i)-a(i)*f(i-1))*p
130 END DO
131
132 DO i = kte - 1, kts, -1
133 f(i) = f(i) + q(i)*f(i+1)
134 END DO
135
136 END SUBROUTINE tridiag
137
138
139
140
141
142
143
144 SUBROUTINE coeffs(kts,kte,z_sigma,z_sigma_half,a_coeff,b_coeff)
145 ! !! to calculate coefficients in diffusion equation
146 ! !! Mariusz Pagowski, March 2001
147 ! !! conventions used:
148 ! !! input is lower case
149 ! !! output is upper case
150 ! .. Scalar Arguments ..
151 INTEGER :: kts,kte
152 ! ..
153 ! .. Array Arguments ..
154 REAL, DIMENSION (kts:kte) :: a_coeff, z_sigma
155 REAL, DIMENSION (kts:kte-1) :: b_coeff, z_sigma_half
156 ! ..
157 ! .. Local Scalars ..
158 REAL :: any
159 INTEGER :: i
160 ! ..
161 any = 1.
162
163 a_coeff(1) = any
164 b_coeff(1) = 1./(z_sigma(2)-z_sigma(1))
165
166 DO i = kts+1, kte - 1
167 a_coeff(i) = 1./(z_sigma_half(i)-z_sigma_half(i-1))
168 b_coeff(i) = 1./(z_sigma(i+1)-z_sigma(i))
169 END DO
170
171 a_coeff(kte) = any
172
173 END SUBROUTINE coeffs
174 END MODULE module_vertmx_wrf