FV3 Bundle
CRTM_IR_Water_SfcOptics.f90
Go to the documentation of this file.
1 !
2 ! CRTM_IR_Water_SfcOptics
3 !
4 ! Module to compute the surface optical properties for WATER surfaces at
5 ! infrared frequencies required for determining the WATER surface
6 ! contribution to the radiative transfer.
7 !
8 ! This module is provided to allow developers to "wrap" their existing
9 ! codes inside the provided functions to simplify integration into
10 ! the main CRTM_SfcOptics module.
11 !
12 !
13 ! CREATION HISTORY:
14 ! Written by: Paul van Delst, 25-Jun-2005
15 ! paul.vandelst@noaa.gov
16 !
17 
19 
20  ! -----------------
21  ! Environment setup
22  ! -----------------
23  ! Module use
24  USE type_kinds, ONLY: fp
27  USE crtm_spccoeff, ONLY: sc, spccoeff_issolar
31  USE crtm_irssem, ONLY: irssem_type=>ivar_type, &
35  USE crtm_irwatercoeff, ONLY: irwaterc
36  ! Disable implicit typing
37  IMPLICIT NONE
38 
39 
40  ! ------------
41  ! Visibilities
42  ! ------------
43  ! Everything private by default
44  PRIVATE
45  ! Data types
46  PUBLIC :: ivar_type
47  ! Science routines
51 
52 
53  ! -----------------
54  ! Module parameters
55  ! -----------------
56  CHARACTER(*), PARAMETER :: module_version_id = &
57  '$Id: CRTM_IR_Water_SfcOptics.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
58  ! Coefficients for Sigma**2 in the Cox & Munk slope probability density function
59  REAL(fp), PARAMETER :: cm_1 = 0.003_fp, cm_2 = 5.12e-3_fp
60 
61 
62  ! --------------------------------------
63  ! Structure definition to hold forward
64  ! variables across FWD, TL, and AD calls
65  ! --------------------------------------
66  TYPE :: ivar_type
67  PRIVATE
68  ! Variables in routines rough sea BRDF
69  REAL(fp) :: pdf ! slope distribution function
70  REAL(fp) :: w ! BRDF = W*pdf
71  REAL(fp) :: tan2_theta_f ! tan(theta_f)**2
72  ! IRSSEM data structure
73  TYPE(irssem_type) :: irssem
74  END TYPE ivar_type
75 
76 
77 CONTAINS
78 
79 
80 !################################################################################
81 !################################################################################
82 !## ##
83 !## ## PUBLIC MODULE ROUTINES ## ##
84 !## ##
85 !################################################################################
86 !################################################################################
87 
88 !----------------------------------------------------------------------------------
89 !:sdoc+:
90 !
91 ! NAME:
92 ! Compute_IR_Water_SfcOptics
93 !
94 ! PURPOSE:
95 ! Function to compute the surface emissivity and reflectivity at infrared
96 ! frequencies over a water surface.
97 !
98 ! This function is a wrapper for third party code.
99 !
100 ! CALLING SEQUENCE:
101 ! Error_Status = Compute_IR_Water_SfcOptics( &
102 ! Surface , & ! Input
103 ! GeometryInfo, & ! Input
104 ! SensorIndex , & ! Input
105 ! ChannelIndex, & ! Output
106 ! SfcOptics , & ! Output
107 ! iVar ) ! Internal variable output
108 !
109 ! INPUTS:
110 ! Surface: CRTM_Surface structure containing the surface state
111 ! data.
112 ! UNITS: N/A
113 ! TYPE: CRTM_Surface_type
114 ! DIMENSION: Scalar
115 ! ATTRIBUTES: INTENT(IN)
116 !
117 ! GeometryInfo: CRTM_GeometryInfo structure containing the
118 ! view geometry information.
119 ! UNITS: N/A
120 ! TYPE: CRTM_GeometryInfo_type
121 ! DIMENSION: Scalar
122 ! ATTRIBUTES: INTENT(IN)
123 !
124 ! SensorIndex: Sensor index id. This is a unique index associated
125 ! with a (supported) sensor used to access the
126 ! shared coefficient data for a particular sensor.
127 ! See the ChannelIndex argument.
128 ! UNITS: N/A
129 ! TYPE: INTEGER
130 ! DIMENSION: Scalar
131 ! ATTRIBUTES: INTENT(IN)
132 !
133 ! ChannelIndex: Channel index id. This is a unique index associated
134 ! with a (supported) sensor channel used to access the
135 ! shared coefficient data for a particular sensor's
136 ! channel.
137 ! See the SensorIndex argument.
138 ! UNITS: N/A
139 ! TYPE: INTEGER
140 ! DIMENSION: Scalar
141 ! ATTRIBUTES: INTENT(IN)
142 !
143 ! OUTPUTS:
144 ! SfcOptics: CRTM_SfcOptics structure containing the surface
145 ! optical properties required for the radiative
146 ! transfer calculation. On input the Angle component
147 ! is assumed to contain data.
148 ! UNITS: N/A
149 ! TYPE: CRTM_SfcOptics_type
150 ! DIMENSION: Scalar
151 ! ATTRIBUTES: INTENT(IN OUT)
152 !
153 ! iVar: Structure containing internal variables required for
154 ! subsequent tangent-linear or adjoint model calls.
155 ! The contents of this structure are NOT accessible
156 ! outside of the CRTM_IR_Water_SfcOptics module.
157 ! UNITS: N/A
158 ! TYPE: iVar_type
159 ! DIMENSION: Scalar
160 ! ATTRIBUTES: INTENT(OUT)
161 !
162 ! FUNCTION RESULT:
163 ! Error_Status: The return value is an integer defining the error status.
164 ! The error codes are defined in the Message_Handler module.
165 ! If == SUCCESS the computation was sucessful
166 ! == FAILURE an unrecoverable error occurred
167 ! UNITS: N/A
168 ! TYPE: INTEGER
169 ! DIMENSION: Scalar
170 !
171 ! COMMENTS:
172 ! Note the INTENT on the output SfcOptics argument is IN OUT rather
173 ! than just OUT as it is assumed to contain some data upon input.
174 !
175 !:sdoc-:
176 !----------------------------------------------------------------------------------
177 
178  FUNCTION compute_ir_water_sfcoptics( &
179  Surface , & ! Input
180  GeometryInfo, & ! Input
181  SensorIndex , & ! Input
182  ChannelIndex, & ! Input
183  SfcOptics , & ! Output
184  iVar ) & ! Internal variable output
185  result( error_status )
186  ! Arguments
187  TYPE(crtm_surface_type), INTENT(IN) :: surface
188  TYPE(crtm_geometryinfo_type), INTENT(IN) :: geometryinfo
189  INTEGER, INTENT(IN) :: sensorindex
190  INTEGER, INTENT(IN) :: channelindex
191  TYPE(crtm_sfcoptics_type), INTENT(IN OUT) :: sfcoptics
192  TYPE(ivar_type), INTENT(IN OUT) :: ivar
193  ! Function result
194  INTEGER :: error_status
195  ! Local parameters
196  CHARACTER(*), PARAMETER :: routine_name = 'Compute_IR_Water_SfcOptics'
197  ! Local variables
198  INTEGER :: j, nz, iz
199  REAL(fp) :: frequency
200  REAL(fp) :: relative_azimuth_radian, brdf
201 
202 
203  ! Set up
204  error_status = success
205  ! ...Short name for angle dimensions
206  nz = sfcoptics%n_Angles
207  iz = sfcoptics%Index_Sat_Ang
208  ! ...Retrieve data from structures
209  frequency = sc(sensorindex)%Wavenumber(channelindex)
210 
211 
212  ! Compute IR sea surface emissivity
213  error_status = crtm_compute_irssem( &
214  irwaterc , & ! Input model coefficients
215  surface%Wind_Speed , & ! Input
216  frequency , & ! Input
217  sfcoptics%Angle(1:nz) , & ! Input
218  ivar%IRSSEM , & ! Internal variable output
219  sfcoptics%Emissivity(1:nz,1) ) ! Output
220  IF ( error_status /= success ) THEN
221  CALL display_message( routine_name, &
222  'Error computing IR sea surface emissivity', &
223  error_status )
224  RETURN
225  END IF
226 
227 
228  ! Compute the solar direct BRDF
229  IF ( spccoeff_issolar(sc(sensorindex), channelindex=channelindex) ) THEN
230 
231  IF( geometryinfo%Source_Zenith_Radian < pi/two ) THEN
232  relative_azimuth_radian = geometryinfo%Sensor_Azimuth_Radian - &
233  geometryinfo%Source_Azimuth_Radian
234  CALL brdf_rough_sea(sc(sensorindex)%Wavenumber(channelindex), &
235  geometryinfo%Source_Zenith_Radian, &
236  relative_azimuth_radian, &
237  geometryinfo%Sensor_Zenith_Radian, &
238  surface%Wind_Speed, &
239  brdf, &
240  ivar)
241  sfcoptics%Direct_Reflectivity(1:nz,1) = brdf
242  ELSE
243  sfcoptics%Direct_Reflectivity(1:nz,1) = zero
244  END IF
245 
246  END IF
247 
248  ! Surface reflectance (currently assumed to be specular ALWAYS)
249  DO j = 1, nz
250  sfcoptics%Reflectivity(j,1,j,1) = one-sfcoptics%Emissivity(j,1)
251  END DO
252 
253  END FUNCTION compute_ir_water_sfcoptics
254 
255 
256 !----------------------------------------------------------------------------------
257 !:sdoc+:
258 !
259 ! NAME:
260 ! Compute_IR_Water_SfcOptics_TL
261 !
262 ! PURPOSE:
263 ! Function to compute the tangent-linear surface emissivity and
264 ! reflectivity at infrared frequencies over a water surface.
265 !
266 ! This function is a wrapper for third party code.
267 !
268 ! CALLING SEQUENCE:
269 ! Error_Status = Compute_IR_Water_SfcOptics_TL( &
270 ! Surface , &
271 ! SfcOptics , &
272 ! Surface_TL , &
273 ! GeometryInfo, &
274 ! SensorIndex , &
275 ! ChannelIndex, &
276 ! SfcOptics_TL, &
277 ! iVar )
278 !
279 ! INPUTS:
280 ! Surface: CRTM_Surface structure containing the surface state
281 ! data.
282 ! UNITS: N/A
283 ! TYPE: CRTM_Surface_type
284 ! DIMENSION: Scalar
285 ! ATTRIBUTES: INTENT(IN)
286 !
287 ! Surface_TL: CRTM_Surface structure containing the tangent-linear
288 ! surface state data.
289 ! UNITS: N/A
290 ! TYPE: CRTM_Surface_type
291 ! DIMENSION: Scalar
292 ! ATTRIBUTES: INTENT(IN)
293 !
294 ! SfcOptics: CRTM_SfcOptics structure containing the surface
295 ! optical properties required for the radiative
296 ! transfer calculation.
297 ! UNITS: N/A
298 ! TYPE: CRTM_SfcOptics_type
299 ! DIMENSION: Scalar
300 ! ATTRIBUTES: INTENT(IN)
301 !
302 ! GeometryInfo: CRTM_GeometryInfo structure containing the
303 ! view geometry information.
304 ! UNITS: N/A
305 ! TYPE: CRTM_GeometryInfo_type
306 ! DIMENSION: Scalar
307 ! ATTRIBUTES: INTENT(IN)
308 !
309 ! SensorIndex: Sensor index id. This is a unique index associated
310 ! with a (supported) sensor used to access the
311 ! shared coefficient data for a particular sensor.
312 ! See the ChannelIndex argument.
313 ! UNITS: N/A
314 ! TYPE: INTEGER
315 ! DIMENSION: Scalar
316 ! ATTRIBUTES: INTENT(IN)
317 !
318 ! ChannelIndex: Channel index id. This is a unique index associated
319 ! with a (supported) sensor channel used to access the
320 ! shared coefficient data for a particular sensor's
321 ! channel.
322 ! See the SensorIndex argument.
323 ! UNITS: N/A
324 ! TYPE: INTEGER
325 ! DIMENSION: Scalar
326 ! ATTRIBUTES: INTENT(IN)
327 !
328 ! iVar: Structure containing internal variables required for
329 ! subsequent tangent-linear or adjoint model calls.
330 ! The contents of this structure are NOT accessible
331 ! outside of the CRTM_IR_Water_SfcOptics module.
332 ! UNITS: N/A
333 ! TYPE: iVar_type
334 ! DIMENSION: Scalar
335 ! ATTRIBUTES: INTENT(IN)
336 !
337 ! OUTPUTS:
338 ! SfcOptics_TL: CRTM_SfcOptics structure containing the tangent-linear
339 ! surface optical properties required for the tangent-
340 ! linear radiative transfer calculation.
341 ! UNITS: N/A
342 ! TYPE: CRTM_SfcOptics_type
343 ! DIMENSION: Scalar
344 ! ATTRIBUTES: INTENT(IN OUT)
345 !
346 ! FUNCTION RESULT:
347 ! Error_Status: The return value is an integer defining the error status.
348 ! The error codes are defined in the Message_Handler module.
349 ! If == SUCCESS the computation was sucessful
350 ! == FAILURE an unrecoverable error occurred
351 ! UNITS: N/A
352 ! TYPE: INTEGER
353 ! DIMENSION: Scalar
354 !
355 ! COMMENTS:
356 ! Note the INTENT on the output SfcOptics_TL argument is IN OUT rather
357 ! than just OUT. This is necessary because the argument may be defined
358 ! upon input.
359 !
360 !:sdoc-:
361 !----------------------------------------------------------------------------------
362 
364  Surface , & ! Input
365  SfcOptics , & ! Input
366  Surface_TL , & ! Input
367  GeometryInfo, & ! Input
368  SensorIndex , & ! Input
369  ChannelIndex, & ! Input
370  SfcOptics_TL, & ! Output
371  iVar ) & ! Internal variable input
372  result( error_status )
373  ! Arguments
374  TYPE(crtm_surface_type), INTENT(IN) :: surface
375  TYPE(crtm_surface_type), INTENT(IN) :: surface_tl
376  TYPE(crtm_sfcoptics_type), INTENT(IN) :: sfcoptics
377  TYPE(crtm_geometryinfo_type), INTENT(IN) :: geometryinfo
378  INTEGER, INTENT(IN) :: sensorindex
379  INTEGER, INTENT(IN) :: channelindex
380  TYPE(crtm_sfcoptics_type), INTENT(IN OUT) :: sfcoptics_tl
381  TYPE(ivar_type), INTENT(IN) :: ivar
382  ! Function result
383  INTEGER :: error_status
384  ! Local parameters
385  CHARACTER(*), PARAMETER :: routine_name = 'Compute_IR_Water_SfcOptics_TL'
386  ! Local variables
387  INTEGER :: j, nz, iz
388  REAL(fp) :: relative_azimuth_radian, brdf_tl
389 
390  ! Set up
391  error_status = success
392  ! ...Short name for angle dimensions
393  nz = sfcoptics%n_Angles
394  iz = sfcoptics%Index_Sat_Ang
395 
396  ! Compute tangent-linear IR sea surface emissivity
397  error_status = crtm_compute_irssem_tl( &
398  irwaterc , & ! Input model coefficients
399  surface_tl%Wind_Speed , & ! Input
400  ivar%IRSSEM , & ! Internal variable input
401  sfcoptics_tl%Emissivity(1:nz,1) ) ! Output
402  IF ( error_status /= success ) THEN
403  CALL display_message( routine_name, &
404  'Error computing Tangent_linear IR sea surface emissivity', &
405  error_status )
406  RETURN
407  END IF
408 
409 
410  ! Compute the tangent-linear solar direct BRDF
411  IF ( spccoeff_issolar(sc(sensorindex), channelindex=channelindex) ) THEN
412 
413  IF( geometryinfo%Source_Zenith_Radian < pi/two ) THEN
414  relative_azimuth_radian = geometryinfo%Sensor_Azimuth_Radian - &
415  geometryinfo%Source_Azimuth_Radian
416  CALL brdf_rough_sea_tl(surface%Wind_Speed, &
417  surface_tl%Wind_Speed, &
418  brdf_tl, &
419  ivar)
420  sfcoptics_tl%Direct_Reflectivity(1:nz,1) = brdf_tl
421  ELSE
422  sfcoptics_tl%Direct_Reflectivity(1:nz,1) = zero
423  END IF
424 
425  END IF
426 
427  ! Surface reflectance (currently assumed to be specular ALWAYS)
428  DO j = 1, nz
429  sfcoptics_tl%Reflectivity(j,1,j,1) = -sfcoptics_tl%Emissivity(j,1)
430  END DO
431 
432  END FUNCTION compute_ir_water_sfcoptics_tl
433 
434 
435 !----------------------------------------------------------------------------------
436 !:sdoc+:
437 !
438 ! NAME:
439 ! Compute_IR_Water_SfcOptics_AD
440 !
441 ! PURPOSE:
442 ! Function to compute the adjoint surface emissivity and
443 ! reflectivity at infrared frequencies over a water surface.
444 !
445 ! This function is a wrapper for third party code.
446 !
447 ! CALLING SEQUENCE:
448 ! Error_Status = Compute_IR_Water_SfcOptics_AD( &
449 ! Surface , &
450 ! SfcOptics , &
451 ! SfcOptics_AD, &
452 ! GeometryInfo, &
453 ! SensorIndex , &
454 ! ChannelIndex, &
455 ! Surface_AD , &
456 ! iVar )
457 !
458 ! INPUTS:
459 ! Surface: CRTM_Surface structure containing the surface state
460 ! data.
461 ! UNITS: N/A
462 ! TYPE: CRTM_Surface_type
463 ! DIMENSION: Scalar
464 ! ATTRIBUTES: INTENT(IN)
465 !
466 ! SfcOptics: CRTM_SfcOptics structure containing the surface
467 ! optical properties required for the radiative
468 ! transfer calculation.
469 ! UNITS: N/A
470 ! TYPE: CRTM_SfcOptics_type
471 ! DIMENSION: Scalar
472 ! ATTRIBUTES: INTENT(IN)
473 !
474 ! SfcOptics_AD: CRTM_SfcOptics structure containing the adjoint
475 ! surface optical properties required for the adjoint
476 ! radiative transfer calculation.
477 ! UNITS: N/A
478 ! TYPE: CRTM_SfcOptics_type
479 ! DIMENSION: Scalar
480 ! ATTRIBUTES: INTENT(IN OUT)
481 !
482 ! GeometryInfo: CRTM_GeometryInfo structure containing the
483 ! view geometry information.
484 ! UNITS: N/A
485 ! TYPE: CRTM_GeometryInfo_type
486 ! DIMENSION: Scalar
487 ! ATTRIBUTES: INTENT(IN)
488 !
489 ! SensorIndex: Sensor index id. This is a unique index associated
490 ! with a (supported) sensor used to access the
491 ! shared coefficient data for a particular sensor.
492 ! See the ChannelIndex argument.
493 ! UNITS: N/A
494 ! TYPE: INTEGER
495 ! DIMENSION: Scalar
496 ! ATTRIBUTES: INTENT(IN)
497 !
498 ! ChannelIndex: Channel index id. This is a unique index associated
499 ! with a (supported) sensor channel used to access the
500 ! shared coefficient data for a particular sensor's
501 ! channel.
502 ! See the SensorIndex argument.
503 ! UNITS: N/A
504 ! TYPE: INTEGER
505 ! DIMENSION: Scalar
506 ! ATTRIBUTES: INTENT(IN)
507 !
508 ! iVar: Structure containing internal variables required for
509 ! subsequent tangent-linear or adjoint model calls.
510 ! The contents of this structure are NOT accessible
511 ! outside of the CRTM_IR_Water_SfcOptics module.
512 ! UNITS: N/A
513 ! TYPE: iVar_type
514 ! DIMENSION: Scalar
515 ! ATTRIBUTES: INTENT(IN)
516 !
517 ! OUTPUTS:
518 ! Surface_AD: CRTM_Surface structure containing the adjoint
519 ! surface state data.
520 ! UNITS: N/A
521 ! TYPE: CRTM_Surface_type
522 ! DIMENSION: Scalar
523 ! ATTRIBUTES: INTENT(IN OUT)
524 !
525 ! FUNCTION RESULT:
526 ! Error_Status: The return value is an integer defining the error status.
527 ! The error codes are defined in the Message_Handler module.
528 ! If == SUCCESS the computation was sucessful
529 ! == FAILURE an unrecoverable error occurred
530 ! UNITS: N/A
531 ! TYPE: INTEGER
532 ! DIMENSION: Scalar
533 !
534 ! COMMENTS:
535 ! Note the INTENT on the input SfcOptics_AD argument is IN OUT rather
536 ! than just OUT. This is necessary because components of this argument
537 ! may need to be zeroed out upon output.
538 !
539 ! Note the INTENT on the output Surface_AD argument is IN OUT rather
540 ! than just OUT. This is necessary because the argument may be defined
541 ! upon input.
542 !
543 !:sdoc-:
544 !----------------------------------------------------------------------------------
545 
547  Surface , & ! Input
548  SfcOptics , & ! Input
549  SfcOptics_AD, & ! Input
550  GeometryInfo, & ! Input
551  SensorIndex , & ! Input
552  ChannelIndex, & ! Input
553  Surface_AD , & ! Output
554  iVar ) & ! Internal variable input
555  result( error_status )
556  ! Arguments
557  TYPE(crtm_surface_type), INTENT(IN) :: surface
558  TYPE(crtm_sfcoptics_type), INTENT(IN) :: sfcoptics
559  TYPE(crtm_sfcoptics_type), INTENT(IN OUT) :: sfcoptics_ad
560  TYPE(crtm_geometryinfo_type), INTENT(IN) :: geometryinfo
561  INTEGER, INTENT(IN) :: sensorindex
562  INTEGER, INTENT(IN) :: channelindex
563  TYPE(crtm_surface_type), INTENT(IN OUT) :: surface_ad
564  TYPE(ivar_type), INTENT(IN) :: ivar
565  ! Function result
566  INTEGER :: error_status
567  ! Local parameters
568  CHARACTER(*), PARAMETER :: routine_name = 'Compute_IR_Water_SfcOptics_AD'
569  ! Local variables
570  INTEGER :: j, nz, iz
571  REAL(fp) :: relative_azimuth_radian, brdf_ad
572 
573  ! Set up
574  error_status = success
575  ! ...Short name for angle dimensions
576  nz = sfcoptics%n_Angles
577  iz = sfcoptics%Index_Sat_Ang
578 
579  ! Surface reflectance (currently assumed to be specular ALWAYS)
580  DO j = nz, 1, -1
581  sfcoptics_ad%Emissivity(j,1) = sfcoptics_ad%Emissivity(j,1) - &
582  sfcoptics_ad%Reflectivity(j,1,j,1)
583  sfcoptics_ad%Reflectivity(j,1,j,1) = zero
584  END DO
585 
586  ! Solar direct BRDF
587  IF ( spccoeff_issolar(sc(sensorindex), channelindex=channelindex) ) THEN
588 
589  IF( geometryinfo%Source_Zenith_Radian < pi/two ) THEN
590 
591  relative_azimuth_radian = geometryinfo%Sensor_Azimuth_Radian - &
592  geometryinfo%Source_Azimuth_Radian
593 
594  brdf_ad = sum(sfcoptics_ad%Direct_Reflectivity(1:nz,1))
595  sfcoptics_ad%Direct_Reflectivity(1:nz,1) = zero
596  CALL brdf_rough_sea_ad(surface%Wind_Speed, &
597  brdf_ad, &
598  surface_ad%Wind_Speed, &
599  ivar)
600  END IF
601  sfcoptics_ad%Direct_Reflectivity(1:nz,1) = zero
602 
603  END IF
604 
605  ! Compute sdjoint IRSSEM sea surface emissivity
606  error_status = crtm_compute_irssem_ad( &
607  irwaterc , & ! Input model coefficients
608  sfcoptics_ad%Emissivity(1:nz,1), & ! Input
609  ivar%IRSSEM , & ! Internal Variable Input
610  surface_ad%Wind_Speed ) ! Output
611  IF ( error_status /= success ) THEN
612  CALL display_message( routine_name, &
613  'Error computing Adjoint IR sea surface emissivity', &
614  error_status )
615  RETURN
616  END IF
617 
618  END FUNCTION compute_ir_water_sfcoptics_ad
619 
620 
621 !##################################################################################
622 !##################################################################################
623 !## ##
624 !## ## PRIVATE MODULE ROUTINES ## ##
625 !## ##
626 !##################################################################################
627 !##################################################################################
628 
629  !--------------------------------------------------------------------
630  ! Compute rough sea Bi-directional Reflectance Distribution Function (BRDF)
631  ! for IR solar reflection
632  ! Inputs:
633  ! Frequency - Frequency (cm-1)
634  ! theta_s - sun zenith angle (Radian)
635  ! dphi - relative sun azimuth agnle, relative to the senosr's azimuth angle (Radian)
636  ! theta_r - senor zenith angle (Radian)
637  ! Wind_Speed - wind speed (m/s)
638  !
639  ! note: dphi is such defined that if the observation direction and the sun direction
640  ! ara in the same vertical plane, then dphi = 180 degree
641  !
642  ! sun Zenith sensor
643  ! \ | /
644  ! theta_s | Theta_r
645  ! \ | /
646  ! \ | /
647  ! \ | /
648  ! \ | /
649  ! \ |/
650  ! -------------------------
651  !
652  ! output:
653  ! brdf - value of the Bi-directional Reflectance Distribution Function at
654  ! the given condition.
655  ! In/out:
656  ! iVar - Structure containing internal variables required for
657  ! subsequent tangent-linear or adjoint model calls.
658  !
659  ! Written by Y. Han, May 5, 2009
660  !--------------------------------------------------------------------
661 
662  SUBROUTINE brdf_rough_sea(Frequency, theta_s, dphi, theta_r, Wind_Speed, &
663  brdf, iVar)
664  REAL(fp), INTENT(IN) :: Frequency
665  REAL(fp), INTENT(IN) :: theta_s
666  REAL(fp), INTENT(IN) :: dphi
667  REAL(fp), INTENT(IN) :: theta_r
668  REAL(fp), INTENT(IN) :: Wind_Speed
669  REAL(fp), INTENT(OUT) :: brdf
670  TYPE(iVar_type), INTENT(IN OUT) :: iVar
671 
672  ! LOCAL
673  REAL(fp), PARAMETER :: MIN_THETA = 1.0e-15_fp
674  REAL(fp) :: sin_theta_s, cos_theta_s, sin_theta_r, cos_theta_r, sin2_theta_s, &
675  sin2_theta_r, cos_dphi, CosSum2, sec4_theta_f, &
676  cos2_alpha, cos_alpha, alpha, rho
677 
678  ! various intermidiate variables
679  sin_theta_s = sin(theta_s)
680  cos_theta_s = max(cos(theta_s), min_theta) ! make sure COS(theta_s) > 0
681  sin_theta_r = sin(theta_r)
682  cos_theta_r = max(cos(theta_r), min_theta) ! make sure COS(theta_r) > 0
683  sin2_theta_s = sin_theta_s*sin_theta_s
684  sin2_theta_r = sin_theta_r*sin_theta_r
685  cos_dphi = cos(dphi)
686  cossum2 = (cos_theta_s + cos_theta_r)**2
687 
688  ! Compute specular reflection angle alpha
689  cos2_alpha = (one + sin_theta_s*sin_theta_r*cos_dphi + cos_theta_s*cos_theta_r)/two
690  cos_alpha = sqrt( cos2_alpha )
691  alpha = acos(min(cos_alpha, one))
692 
693  ! Compute Fresnel_reflectance
694  rho = fresnel_reflectance(frequency, alpha)
695 
696  ! Compute Tan(theta_f)**2, where theta_f is the zenith angle of the normal
697  ! of the facet at the point of reflection.
698  ivar%tan2_theta_f = (sin2_theta_s + sin2_theta_r &
699  + two*sin_theta_s*sin_theta_r*cos_dphi) &
700  / cossum2
701 
702  ! Compute splope probability density function
703  CALL slope_pdf(ivar%tan2_theta_f, wind_speed, ivar%pdf)
704 
705  ! Compute BRDF
706  sec4_theta_f = (ivar%tan2_theta_f + one)**2
707  ivar%W = pi * rho * sec4_theta_f / (four*cos_theta_r*cos_theta_s)
708  brdf = ivar%W * ivar%pdf
709 
710  END SUBROUTINE brdf_rough_sea
711 
712  SUBROUTINE brdf_rough_sea_tl(Wind_Speed, &
713  Wind_Speed_TL, brdf_TL, iVar)
714  REAL(fp), INTENT(IN) :: Wind_Speed
715  REAL(fp), INTENT(IN) :: Wind_Speed_TL
716  REAL(fp), INTENT(OUT) :: brdf_TL
717  TYPE(iVar_type), INTENT(IN) :: iVar
718 
719  ! LOCAL
720  REAL(fp) :: pdf_TL
721 
722  CALL slope_pdf_tl(ivar%tan2_theta_f, wind_speed, ivar%pdf, wind_speed_tl, pdf_tl)
723 
724  brdf_tl = ivar%W * pdf_tl
725 
726  END SUBROUTINE brdf_rough_sea_tl
727 
728  SUBROUTINE brdf_rough_sea_ad(Wind_Speed, &
729  brdf_AD, Wind_Speed_AD, iVar)
730  REAL(fp), INTENT(IN) :: Wind_Speed
731  REAL(fp), INTENT(INOUT) :: brdf_AD
732  REAL(fp), INTENT(INOUT) :: Wind_Speed_AD
733  TYPE(iVar_type), INTENT(IN) :: iVar
734 
735  ! LOCAL
736  REAL(fp) :: pdf_AD
737 
738  pdf_ad = ivar%W * brdf_ad
739  brdf_ad = zero
740 
741  CALL slope_pdf_ad(ivar%tan2_theta_f, wind_speed, ivar%pdf, pdf_ad, wind_speed_ad)
742 
743  END SUBROUTINE brdf_rough_sea_ad
744 
745  ! Compute facet slope distribution function (pdf)
746  ! Inputs: tan2_theta_f - tan(theta_f)**2
747  ! Wind_Speed (m/s)
748  ! Outputs: pdf
749 
750  SUBROUTINE slope_pdf(tan2_theta_f, Wind_Speed, pdf)
751  REAL(fp), INTENT(IN) :: tan2_theta_f
752  REAL(fp), INTENT(IN) :: Wind_Speed
753  REAL(fp), INTENT(OUT) :: pdf
754 
755  ! Local
756  REAL(fp) :: Sigma2
757 
758  ! Cox & Munk slope probability density function
759  sigma2 = cm_1 + cm_2*wind_speed
760  pdf = exp(-tan2_theta_f / sigma2) / (pi*sigma2)
761 
762  END SUBROUTINE slope_pdf
763 
764  SUBROUTINE slope_pdf_tl(tan2_theta_f, Wind_Speed, pdf, Wind_Speed_TL, pdf_TL)
765  REAL(fp), INTENT(IN) :: tan2_theta_f
766  REAL(fp), INTENT(IN) :: Wind_Speed
767  REAL(fp), INTENT(IN) :: pdf
768  REAL(fp), INTENT(IN) :: Wind_Speed_TL
769  REAL(fp), INTENT(OUT) :: pdf_TL
770 
771  ! LOCAL
772  REAL(fp) :: Sigma2, Sigma2_TL
773 
774  sigma2 = cm_1 + cm_2*wind_speed
775  sigma2_tl = cm_2*wind_speed_tl
776  pdf_tl = ( pdf*(tan2_theta_f/sigma2 - one)/sigma2 )*sigma2_tl
777 
778  END SUBROUTINE slope_pdf_tl
779 
780  SUBROUTINE slope_pdf_ad(tan2_theta_f, Wind_Speed, pdf, pdf_AD, Wind_Speed_AD)
781  REAL(fp), INTENT(IN) :: tan2_theta_f
782  REAL(fp), INTENT(IN) :: Wind_Speed
783  REAL(fp), INTENT(IN) :: pdf
784  REAL(fp), INTENT(IN OUT) :: pdf_AD
785  REAL(fp), INTENT(IN OUT) :: Wind_Speed_AD
786 
787  ! LOCAL
788  REAL(fp) :: Sigma2, Sigma2_AD
789 
790  sigma2 = cm_1 + cm_2*wind_speed
791  sigma2_ad = ( pdf*(tan2_theta_f/sigma2 - one)/sigma2 )*pdf_ad
792  pdf_ad = zero
793  wind_speed_ad = wind_speed_ad + 5.12e-3_fp*sigma2_ad
794 
795  END SUBROUTINE slope_pdf_ad
796 
797  !---------------------------------------------------------
798  ! Compute Fresnel sea surface reflectivity
799  ! Inputs:
800  ! Frequency - Frequency cm-1
801  ! Ang_i - incident angle (Radian)
802  ! output (as a function return):
803  ! r - Fresnel reflectivity
804  ! Written by Y. Han, May 5, 2009
805  !---------------------------------------------------------
806  FUNCTION fresnel_reflectance(Frequency, Ang_i) RESULT( r )
808  REAL(fp), INTENT(IN) :: frequency
809  REAL(fp), INTENT(IN) :: ang_i
810 
811  REAL(fp) :: r
812 
813  ! LOCAL
814  REAL(fp) :: rh, rv
815  COMPLEX(fp) :: ccos_i, ccos_t, n, z
816 
817  ! call function to compute complex refractive index
818  n = ref_index(frequency)
819 
820  ! Fresnel reflectivity
821 
822  z = cmplx(sin(ang_i), zero, fp)/n
823  ccos_t = sqrt(cmplx(one, zero, fp) - z*z)
824 
825  ccos_i = cmplx(cos(ang_i), zero, fp)
826 
827  rv = ( abs( (n*ccos_i - ccos_t) / (n*ccos_i + ccos_t) ) )**2
828  rh = ( abs( (ccos_i - n*ccos_t) / (ccos_i + n*ccos_t) ) )**2
829 
830  r = (rv + rh) / two
831 
832  END FUNCTION fresnel_reflectance
833 
834  !------------------------------------------------------------
835  ! Obtain IR refractive index
836  ! Input: Frequency - wavenumber cm-1, valid range 500 - 3500 cm-1
837  ! Return: complex refractive index
838  !------------------------------------------------------------
839  FUNCTION ref_index(Frequency) RESULT(ref)
840  REAL(fp), INTENT(IN) :: frequency
841 
842  COMPLEX(fp) :: ref
843 
844  !-------------------------------------------------------------------------
845  ! Refractive index of water from Wieliczka (1989), added
846  ! salinity and chlorinity CORRECTIONS from Friedman (1969). The resolution
847  ! of the Wieliczka data set is reduced to 20 cm-1. The frequancy range
848  ! of the Friedman starts at 666.67 cm-1. For frequency < 666.67 cm-1
849  ! the value at 666.67 is used.
850  !-------------------------------------------------------------------------
851  INTEGER, PARAMETER :: nf = 151
852  ! array holding wavenumbers at which the refractive indexes are given
853  REAL(fp), PARAMETER :: freq(nf) = (/ &
854  500.0, 520.0, 540.0, 560.0, 580.0, 600.0, 620.0, 640.0, 660.0, 680.0,&
855  700.0, 720.0, 740.0, 760.0, 780.0, 800.0, 820.0, 840.0, 860.0, 880.0,&
856  900.0, 920.0, 940.0, 960.0, 980.0, 1000.0, 1020.0, 1040.0, 1060.0, 1080.0,&
857  1100.0, 1120.0, 1140.0, 1160.0, 1180.0, 1200.0, 1220.0, 1240.0, 1260.0, 1280.0,&
858  1300.0, 1320.0, 1340.0, 1360.0, 1380.0, 1400.0, 1420.0, 1440.0, 1460.0, 1480.0,&
859  1500.0, 1520.0, 1540.0, 1560.0, 1580.0, 1600.0, 1620.0, 1640.0, 1660.0, 1680.0,&
860  1700.0, 1720.0, 1740.0, 1760.0, 1780.0, 1800.0, 1820.0, 1840.0, 1860.0, 1880.0,&
861  1900.0, 1920.0, 1940.0, 1960.0, 1980.0, 2000.0, 2020.0, 2040.0, 2060.0, 2080.0,&
862  2100.0, 2120.0, 2140.0, 2160.0, 2180.0, 2200.0, 2220.0, 2240.0, 2260.0, 2280.0,&
863  2300.0, 2320.0, 2340.0, 2360.0, 2380.0, 2400.0, 2420.0, 2440.0, 2460.0, 2480.0,&
864  2500.0, 2520.0, 2540.0, 2560.0, 2580.0, 2600.0, 2620.0, 2640.0, 2660.0, 2680.0,&
865  2700.0, 2720.0, 2740.0, 2760.0, 2780.0, 2800.0, 2820.0, 2840.0, 2860.0, 2880.0,&
866  2900.0, 2920.0, 2940.0, 2960.0, 2980.0, 3000.0, 3020.0, 3040.0, 3060.0, 3080.0,&
867  3100.0, 3120.0, 3140.0, 3160.0, 3180.0, 3200.0, 3220.0, 3240.0, 3260.0, 3280.0,&
868  3300.0, 3320.0, 3340.0, 3360.0, 3380.0, 3400.0, 3420.0, 3440.0, 3460.0, 3480.0,&
869  3500.0/)
870  ! real part of the refractive index
871  REAL(fp), PARAMETER :: nr(nf) = (/ &
872  1.5300, 1.5050, 1.4752, 1.4427, 1.4111, 1.3787, 1.3468, 1.3167, 1.2887, 1.2620,&
873  1.2348, 1.2077, 1.1823, 1.1596, 1.1417, 1.1268, 1.1152, 1.1143, 1.1229, 1.1327,&
874  1.1520, 1.1630, 1.1770, 1.1920, 1.2050, 1.2170, 1.2280, 1.2371, 1.2450, 1.2523,&
875  1.2580, 1.2636, 1.2680, 1.2740, 1.2780, 1.2820, 1.2850, 1.2880, 1.2910, 1.2940,&
876  1.2970, 1.3000, 1.3020, 1.3040, 1.3070, 1.3080, 1.3100, 1.3120, 1.3150, 1.3170,&
877  1.3200, 1.3230, 1.3280, 1.3350, 1.3490, 1.3530, 1.3430, 1.3080, 1.2630, 1.2460,&
878  1.2410, 1.2540, 1.2670, 1.2760, 1.2810, 1.2900, 1.2950, 1.3000, 1.3040, 1.3070,&
879  1.3100, 1.3130, 1.3160, 1.3180, 1.3200, 1.3210, 1.3220, 1.3240, 1.3240, 1.3250,&
880  1.3260, 1.3250, 1.3250, 1.3250, 1.3250, 1.3250, 1.3260, 1.3270, 1.3280, 1.3280,&
881  1.3290, 1.3300, 1.3310, 1.3330, 1.3350, 1.3360, 1.3380, 1.3400, 1.3410, 1.3430,&
882  1.3450, 1.3480, 1.3500, 1.3520, 1.3550, 1.3580, 1.3600, 1.3610, 1.3640, 1.3660,&
883  1.3680, 1.3710, 1.3740, 1.3770, 1.3810, 1.3850, 1.3890, 1.3940, 1.3980, 1.4020,&
884  1.4070, 1.4120, 1.4180, 1.4240, 1.4310, 1.4370, 1.4440, 1.4510, 1.4590, 1.4660,&
885  1.4720, 1.4780, 1.4840, 1.4830, 1.4820, 1.4750, 1.4690, 1.4580, 1.4390, 1.4230,&
886  1.4130, 1.3960, 1.3810, 1.3560, 1.3290, 1.2970, 1.2600, 1.2170, 1.1860, 1.1590,&
887  1.1410/)
888  ! imaginary part of the refractive index
889  REAL(fp), PARAMETER :: ni(nf) = (/ &
890  0.3874, 0.4031, 0.4149, 0.4213, 0.4243, 0.4227, 0.4180, 0.4105, 0.3997, 0.3877,&
891  0.3731, 0.3556, 0.3341, 0.3079, 0.2803, 0.2489, 0.2144, 0.1776, 0.1505, 0.1243,&
892  0.0970, 0.0822, 0.0693, 0.0593, 0.0517, 0.0469, 0.0432, 0.0404, 0.0384, 0.0369,&
893  0.0357, 0.0353, 0.0352, 0.0348, 0.0343, 0.0340, 0.0338, 0.0334, 0.0329, 0.0330,&
894  0.0329, 0.0326, 0.0323, 0.0320, 0.0318, 0.0317, 0.0316, 0.0317, 0.0323, 0.0329,&
895  0.0337, 0.0352, 0.0394, 0.0454, 0.0538, 0.0711, 0.1040, 0.1239, 0.1144, 0.0844,&
896  0.0539, 0.0364, 0.0264, 0.0177, 0.0145, 0.0127, 0.0117, 0.0108, 0.0104, 0.0103,&
897  0.0104, 0.0105, 0.0108, 0.0114, 0.0122, 0.0129, 0.0135, 0.0143, 0.0150, 0.0155,&
898  0.0156, 0.0155, 0.0152, 0.0148, 0.0140, 0.0132, 0.0123, 0.0115, 0.0106, 0.0098,&
899  0.0091, 0.0085, 0.0079, 0.0073, 0.0068, 0.0064, 0.0060, 0.0056, 0.0052, 0.0049,&
900  0.0046, 0.0043, 0.0041, 0.0039, 0.0038, 0.0037, 0.0036, 0.0036, 0.0037, 0.0038,&
901  0.0040, 0.0042, 0.0046, 0.0050, 0.0055, 0.0061, 0.0070, 0.0080, 0.0092, 0.0106,&
902  0.0124, 0.0146, 0.0174, 0.0197, 0.0259, 0.0350, 0.0429, 0.0476, 0.0541, 0.0655,&
903  0.0793, 0.0921, 0.1058, 0.1232, 0.1450, 0.1656, 0.1833, 0.1990, 0.2161, 0.2267,&
904  0.2369, 0.2487, 0.2606, 0.2740, 0.2819, 0.2854, 0.2826, 0.2765, 0.2637, 0.2451,&
905  0.2230/)
906  REAL(fp), PARAMETER :: df = freq(2) - freq(1)
907  INTEGER :: idx
908  REAL(fp) :: c
909 
910  IF(frequency < freq(1))THEN
911  ref = cmplx( nr(1), ni(1), fp )
912  ELSE IF( frequency > freq(nf) )THEN
913  ref = cmplx( nr(nf), ni(nf), fp )
914  ELSE
915  ! Linear interpolation
916  idx = int((frequency - freq(1))/df) + 1 ! find the starting index
917  c = (frequency - freq(idx))/(freq(idx+1) - freq(idx))
918  ref = cmplx( nr(idx) + c*(nr(idx+1) - nr(idx)), &
919  ni(idx) + c*(ni(idx+1) - ni(idx)), &
920  fp )
921  END IF
922 
923  END FUNCTION ref_index
924 
925 END MODULE crtm_ir_water_sfcoptics
real(fp) function fresnel_reflectance(Frequency, Ang_i)
real(fp), parameter, public zero
integer function, public compute_ir_water_sfcoptics_tl(Surface, SfcOptics, Surface_TL, GeometryInfo, SensorIndex, ChannelIndex, SfcOptics_TL, iVar)
subroutine slope_pdf_ad(tan2_theta_f, Wind_Speed, pdf, pdf_AD, Wind_Speed_AD)
type(irwatercoeff_type), save, public irwaterc
real(fp), parameter, public four
integer, parameter, public fp
Definition: Type_Kinds.f90:124
complex(fp) function ref_index(Frequency)
subroutine brdf_rough_sea(Frequency, theta_s, dphi, theta_r, Wind_Speed, brdf, iVar)
integer function, public compute_ir_water_sfcoptics(Surface, GeometryInfo, SensorIndex, ChannelIndex, SfcOptics, iVar)
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer function, public crtm_compute_irssem(IRwaterCoeff, Wind_Speed, Frequency, Angle, iVar, Emissivity)
real(fp), parameter, public two
subroutine slope_pdf(tan2_theta_f, Wind_Speed, pdf)
character(*), parameter module_version_id
real(fp), parameter, public degrees_to_radians
type(spccoeff_type), dimension(:), allocatable, save, public sc
integer function, public compute_ir_water_sfcoptics_ad(Surface, SfcOptics, SfcOptics_AD, GeometryInfo, SensorIndex, ChannelIndex, Surface_AD, iVar)
subroutine brdf_rough_sea_ad(Wind_Speed, brdf_AD, Wind_Speed_AD, iVar)
#define max(a, b)
Definition: mosaic_util.h:33
subroutine slope_pdf_tl(tan2_theta_f, Wind_Speed, pdf, Wind_Speed_TL, pdf_TL)
#define min(a, b)
Definition: mosaic_util.h:32
subroutine brdf_rough_sea_tl(Wind_Speed, Wind_Speed_TL, brdf_TL, iVar)
integer, parameter, public success
integer function, public crtm_compute_irssem_tl(IRwaterCoeff, Wind_Speed_TL, iVar, Emissivity_TL)
integer function, public crtm_compute_irssem_ad(IRwaterCoeff, Emissivity_AD, iVar, Wind_Speed_AD)
real(fp), parameter, public pi