FV3 Bundle
Reflection_Correction_Module.f90
Go to the documentation of this file.
1 !
2 ! Helper module conmtaining the reflection correction routines for the
3 ! CRTM implementation of FASTEM4 and FASTEM5
4 !
5 !
6 ! CREATION HISTORY:
7 ! Written by: Original FASTEM1/2/3 authors
8 !
9 ! Modified by: Quanhua Liu, Quanhua.Liu@noaa.gov
10 ! Stephen English, Stephen.English@metoffice.gov.uk
11 ! July, 2009
12 !
13 ! Modified by: Quanhua Liu, Quanhua.Liu@noaa.gov
14 ! Stephen English, Stephen.English@metoffice.gov.uk
15 ! August 16, 2011
16 !
17 ! Refactored by: Paul van Delst, November 2011
18 ! paul.vandelst@noaa.gov
19 !
20 
22 
23  ! -----------------
24  ! Environment setup
25  ! -----------------
26  ! Module use
27  USE type_kinds , ONLY: fp
28  USE slope_variance , ONLY: svvar_type => ivar_type, &
33  ! Disable implicit typing
34  IMPLICIT NONE
35 
36 
37  ! ------------
38  ! Visibilities
39  ! ------------
40  PRIVATE
41  ! Data types
42  PUBLIC :: ivar_type
43  ! Science routines
44  PUBLIC :: reflection_correction
45  PUBLIC :: reflection_correction_tl
46  PUBLIC :: reflection_correction_ad
47 
48 
49  ! -----------------
50  ! Module parameters
51  ! -----------------
52  CHARACTER(*), PARAMETER :: module_version_id = &
53  '$Id: Reflection_Correction_Module.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
54 
55  ! Literal constants
56  REAL(fp), PARAMETER :: zero = 0.0_fp
57  REAL(fp), PARAMETER :: one = 1.0_fp
58  REAL(fp), PARAMETER :: two = 2.0_fp
59 
60  ! Rx_Rough regression equation parameters
61  ! ...Number of predictors
62  INTEGER, PARAMETER :: n_predictors = 7
63  ! ...Number of summation loops and equation terms
64  INTEGER, PARAMETER :: n_terms = 3
65 
66 
67  ! --------------------------------------
68  ! Structure definition to hold internal
69  ! variables across FWD, TL, and AD calls
70  ! --------------------------------------
71  TYPE :: ivar_type
72  PRIVATE
73  ! Forward model input values
74  REAL(fp) :: transmittance = zero
75  REAL(fp) :: wind_speed = zero
76  REAL(fp) :: cos_z = zero
77  REAL(fp) :: frequency = zero
78  ! Optical depth
79  REAL(fp) :: od = zero
80  ! Predictors
81  REAL(fp) :: odx(n_terms-1) = zero
82  REAL(fp) :: zx(n_predictors) = zero
83  ! Reflectance variables
84  REAL(fp) :: rv_rough = zero
85  REAL(fp) :: rh_rough = zero
86  REAL(fp) :: rv_mod = zero
87  REAL(fp) :: rh_mod = zero
88  ! Components
89  TYPE(svvar_type) :: svvar
90  END TYPE ivar_type
91 
92 
93 CONTAINS
94 
95 
96  ! ===============================================================
97  ! Use the transmittance to compute anisotropic downward radiation
98  ! effect through a corrected surface reflection.
99  ! ===============================================================
100 
101  ! Forward model
102  SUBROUTINE reflection_correction( &
103  RCCoeff , & ! Input
104  Frequency , & ! Input
105  cos_z , & ! Input
106  Wind_Speed , & ! Input
107  Transmittance, & ! Input
108  Rv_Mod , & ! Output
109  Rh_Mod , & ! Output
110  iVar ) ! Internal variable output
111  ! Arguments
112  TYPE(fitcoeff_3d_type), INTENT(IN) :: rccoeff
113  REAL(fp) , INTENT(IN) :: frequency
114  REAL(fp) , INTENT(IN) :: cos_z
115  REAL(fp) , INTENT(IN) :: wind_speed
116  REAL(fp) , INTENT(IN) :: transmittance
117  REAL(fp) , INTENT(OUT) :: rv_mod
118  REAL(fp) , INTENT(OUT) :: rh_mod
119  TYPE(ivar_type) , INTENT(IN OUT) :: ivar
120  ! Local variables
121  REAL(fp) :: variance
122  INTEGER :: i
123 
124 
125  ! Save forward input variables for TL and AD calculations
126  ivar%Transmittance = transmittance
127  ivar%Wind_Speed = wind_speed
128  ivar%cos_z = cos_z
129  ivar%Frequency = frequency
130 
131 
132  ! Compute the wave slope variance
133  CALL compute_slope_variance( frequency, wind_speed, ivar%svVar, variance )
134 
135 
136  ! Compute surface to space optical depth predictors
137  ivar%od = -log(transmittance) * cos_z
138  ivar%odx(1) = log(ivar%od)
139  ivar%odx(2) = ivar%odx(1)**2
140 
141 
142  ! Compute effective angle predictors
143  ivar%zx(1) = one
144  ivar%zx(2) = variance
145  ivar%zx(4) = one / cos_z
146  ivar%zx(3) = ivar%zx(2) * ivar%zx(4)
147  ivar%zx(5) = ivar%zx(3) * ivar%zx(3)
148  ivar%zx(6) = ivar%zx(4) * ivar%zx(4)
149  ivar%zx(7) = ivar%zx(2) * ivar%zx(2)
150 
151 
152  ! Compute the rough surface reflectivity
153  ivar%Rv_Rough = one
154  ivar%Rh_Rough = one
155  DO i = 1, n_predictors
156  ivar%Rv_Rough = ivar%Rv_Rough + ivar%zx(i) * ( rccoeff%C(1,i,1) + &
157  ivar%odx(1)*rccoeff%C(2,i,1) + &
158  ivar%odx(2)*rccoeff%C(3,i,1) )
159 
160  ivar%Rh_Rough = ivar%Rh_Rough + ivar%zx(i) * ( rccoeff%C(1,i,2) + &
161  ivar%odx(1)*rccoeff%C(2,i,2) + &
162  ivar%odx(2)*rccoeff%C(3,i,2) )
163  END DO
164 
165 
166  ! Compute the reflectivity modifier
167  rv_mod = (one - transmittance**ivar%Rv_Rough) / (one - transmittance)
168  rh_mod = (one - transmittance**ivar%Rh_Rough) / (one - transmittance)
169  ! ...and save it
170  ivar%Rv_Mod = rv_mod
171  ivar%Rh_Mod = rh_mod
172 
173  END SUBROUTINE reflection_correction
174 
175 
176  ! Tangent-linear model
177  SUBROUTINE reflection_correction_tl( &
178  RCCoeff , & ! Input
179  Wind_Speed_TL , & ! Input
180  Transmittance_TL, & ! Input
181  Rv_Mod_TL , & ! Output
182  Rh_Mod_TL , & ! Output
183  iVar ) ! Internal variable input
184  ! Arguments
185  TYPE(fitcoeff_3d_type), INTENT(IN) :: rccoeff
186  REAL(fp) , INTENT(IN) :: wind_speed_tl
187  REAL(fp) , INTENT(IN) :: transmittance_tl
188  REAL(fp) , INTENT(OUT) :: rv_mod_tl
189  REAL(fp) , INTENT(OUT) :: rh_mod_tl
190  TYPE(ivar_type) , INTENT(IN) :: ivar
191  ! Local variables
192  REAL(fp) :: variance_tl, od_tl
193  REAL(fp) :: odx_tl(n_terms-1), zx_tl(n_predictors)
194  REAL(fp) :: rv_rough_tl, rh_rough_tl
195  INTEGER :: i
196 
197 
198  ! Compute the wave slope variance
199  CALL compute_slope_variance_tl( wind_speed_tl, ivar%svVar, variance_tl )
200 
201 
202  ! Compute surface to space optical depth predictors
203  od_tl = -transmittance_tl * ivar%cos_z / ivar%Transmittance
204  odx_tl(1) = od_tl / ivar%od
205  odx_tl(2) = two * odx_tl(1) * ivar%odx(1)
206 
207 
208  ! Compute effective angle predictors
209  zx_tl = zero
210  zx_tl(1) = zero
211  zx_tl(2) = variance_tl
212  zx_tl(4) = zero
213  zx_tl(3) = zx_tl(2) * ivar%zx(4)
214  zx_tl(5) = two * zx_tl(3) * ivar%zx(3)
215  zx_tl(6) = two * zx_tl(4) * ivar%zx(4)
216  zx_tl(7) = two * zx_tl(2) * ivar%zx(2)
217 
218 
219  ! Compute the rough surface reflectivity
220  rv_rough_tl = zero
221  rh_rough_tl = zero
222  DO i = 1, n_predictors
223  rv_rough_tl = rv_rough_tl + zx_tl(i) * ( rccoeff%C(1,i,1) + &
224  ivar%odx(1)*rccoeff%C(2,i,1) + &
225  ivar%odx(2)*rccoeff%C(3,i,1) ) + &
226  ivar%zx(i) * (odx_tl(1)*rccoeff%C(2,i,1) + &
227  odx_tl(2)*rccoeff%C(3,i,1) )
228 
229  rh_rough_tl = rh_rough_tl + zx_tl(i) * ( rccoeff%C(1,i,2) + &
230  ivar%odx(1)*rccoeff%C(2,i,2) + &
231  ivar%odx(2)*rccoeff%C(3,i,2) ) + &
232  ivar%zx(i) * (odx_tl(1)*rccoeff%C(2,i,2) + &
233  odx_tl(2)*rccoeff%C(3,i,2) )
234  END DO
235 
236 
237  ! Compute the reflectivity modifier
238  rv_mod_tl = ((ivar%Rv_Mod - ivar%Rv_Rough*(ivar%Transmittance**(ivar%Rv_Rough-one)))*transmittance_tl - &
239  (log(ivar%Transmittance)*(ivar%Transmittance**ivar%Rv_Rough))*rv_rough_tl) / &
240  (one - ivar%Transmittance)
241  rh_mod_tl = ((ivar%Rh_Mod - ivar%Rh_Rough*(ivar%Transmittance**(ivar%Rh_Rough-one)))*transmittance_tl - &
242  (log(ivar%Transmittance)*(ivar%Transmittance**ivar%Rh_Rough))*rh_rough_tl) / &
243  (one - ivar%Transmittance)
244 
245  END SUBROUTINE reflection_correction_tl
246 
247 
248  ! Adjoint model
249  SUBROUTINE reflection_correction_ad( &
250  RCCoeff , & ! Input
251  Rv_Mod_AD , & ! Input
252  Rh_Mod_AD , & ! Input
253  Wind_Speed_AD , & ! Output
254  Transmittance_AD, & ! Output
255  iVar ) ! Internal variable input
256  ! Arguments
257  TYPE(fitcoeff_3d_type), INTENT(IN) :: rccoeff
258  REAL(fp) , INTENT(IN OUT) :: rv_mod_ad
259  REAL(fp) , INTENT(IN OUT) :: rh_mod_ad
260  REAL(fp) , INTENT(IN OUT) :: transmittance_ad
261  REAL(fp) , INTENT(IN OUT) :: wind_speed_ad
262  TYPE(ivar_type) , INTENT(IN) :: ivar
263  ! Local variables
264  INTEGER :: i
265  REAL(fp) :: rv_rough_ad, rh_rough_ad
266  REAL(fp) :: odx_ad(n_terms-1), zx_ad(n_predictors)
267  REAL(fp) :: od_ad
268  REAL(fp) :: variance_ad
269 
270 
271  ! Compute the reflectivity modifier
272  rv_rough_ad = zero
273  rh_rough_ad = zero
274  ! ...for Rh_Mod
275  transmittance_ad = transmittance_ad + &
276  (ivar%Rh_Mod - ivar%Rh_Rough * ivar%Transmittance**(ivar%Rh_Rough-one)) * rh_mod_ad / &
277  (one - ivar%Transmittance)
278  rh_rough_ad = rh_rough_ad - &
279  (ivar%Transmittance**ivar%Rh_Rough * log(ivar%Transmittance)) * rh_mod_ad / &
280  (one - ivar%Transmittance)
281  rh_mod_ad = zero
282  ! ...for Rv_Mod
283  transmittance_ad = transmittance_ad + &
284  (ivar%Rv_Mod - ivar%Rv_Rough * ivar%Transmittance**(ivar%Rv_Rough-one)) * rv_mod_ad / &
285  (one - ivar%Transmittance)
286  rv_rough_ad = rv_rough_ad - &
287  (ivar%Transmittance**ivar%Rv_Rough * log(ivar%Transmittance)) * rv_mod_ad / &
288  (one - ivar%Transmittance)
289  rv_mod_ad = zero
290 
291 
292  ! Compute the rough surface reflectivity
293  odx_ad = zero
294  zx_ad = zero
295  DO i = 1, n_predictors
296  ! ...Rh_Rough components
297  odx_ad(2) = odx_ad(2) + ivar%zx(i)*rccoeff%C(3,i,2)*rh_rough_ad
298  odx_ad(1) = odx_ad(1) + ivar%zx(i)*rccoeff%C(2,i,2)*rh_rough_ad
299  zx_ad(i) = zx_ad(i) + ( rccoeff%C(1,i,2) + &
300  ivar%odx(1)*rccoeff%C(2,i,2) + &
301  ivar%odx(2)*rccoeff%C(3,i,2) )*rh_rough_ad
302  ! ...Rv_Rough components
303  odx_ad(2) = odx_ad(2) + ivar%zx(i)*rccoeff%C(3,i,1)*rv_rough_ad
304  odx_ad(1) = odx_ad(1) + ivar%zx(i)*rccoeff%C(2,i,1)*rv_rough_ad
305  zx_ad(i) = zx_ad(i) + ( rccoeff%C(1,i,1) + &
306  ivar%odx(1)*rccoeff%C(2,i,1) + &
307  ivar%odx(2)*rccoeff%C(3,i,1) )*rv_rough_ad
308  END DO
309  rv_rough_ad = zero
310  rh_rough_ad = zero
311 
312 
313  ! Compute adjoint of effective angle predictors
314  ! ...(7)
315  zx_ad(2) = zx_ad(2) + two*ivar%zx(2)*zx_ad(7)
316  zx_ad(7) = zero
317  ! ...(6)
318  zx_ad(4) = zx_ad(4) + two*ivar%zx(4)*zx_ad(6)
319  zx_ad(6) = zero
320  ! ...(5)
321  zx_ad(3) = zx_ad(3) + two*ivar%zx(3)*zx_ad(5)
322  zx_ad(5) = zero
323  ! ...(3)
324  zx_ad(2) = zx_ad(2) + ivar%zx(4)*zx_ad(3)
325  zx_ad(3) = zero
326  ! ...(4)
327  zx_ad(4) = zero
328  ! ...(2)
329  variance_ad = zx_ad(2)
330  zx_ad(2) = zero
331  ! ...(1)
332  zx_ad(1) = zero
333 
334 
335  ! Compute adjoint of surface to space optical depth predictors
336  odx_ad(1) = odx_ad(1) + two*ivar%odx(1)*odx_ad(2)
337  odx_ad(2) = zero
338  od_ad = odx_ad(1) / ivar%od
339  odx_ad(1) = zero
340  transmittance_ad = transmittance_ad - od_ad*ivar%cos_z/ivar%Transmittance
341 
342 
343  ! Compute the wave slope variance
344  CALL compute_slope_variance_ad( variance_ad, ivar%svVar, wind_speed_ad )
345 
346  END SUBROUTINE reflection_correction_ad
347 
real(fp), parameter, public zero
integer, parameter, public fp
Definition: Type_Kinds.f90:124
subroutine, public compute_slope_variance(Frequency, Wind_Speed, iVar, Variance)
subroutine, public reflection_correction_ad(RCCoeff, Rv_Mod_AD, Rh_Mod_AD, Wind_Speed_AD, Transmittance_AD, iVar)
real(fp), parameter, public one
real(fp), parameter, public two
subroutine, public reflection_correction_tl(RCCoeff, Wind_Speed_TL, Transmittance_TL, Rv_Mod_TL, Rh_Mod_TL, iVar)
subroutine, public compute_slope_variance_tl(Wind_Speed_TL, iVar, Variance_TL)
subroutine, public compute_slope_variance_ad(Variance_AD, iVar, Wind_Speed_AD)
subroutine, public reflection_correction(RCCoeff, Frequency, cos_z, Wind_Speed, Transmittance, Rv_Mod, Rh_Mod, iVar)