FV3 Bundle
CRTM_SfcOptics_Define.f90
Go to the documentation of this file.
1 !
2 ! CRTM_SfcOptics_Define
3 !
4 ! Module defining the CRTM SfcOptics structure and containing
5 ! routines to manipulate it.
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Yong Han, NOAA/NESDIS; Yong.Han@noaa.gov
10 ! Quanhua Liu, QSS Group, Inc; Quanhua.Liu@noaa.gov
11 ! Paul van Delst, CIMSS/SSEC; paul.vandelst@ssec.wisc.edu
12 ! 02-Apr-2004
13 !
14 
16 
17  ! -----------------
18  ! Environment setup
19  ! -----------------
20  ! Module use
21  USE type_kinds , ONLY: fp
24  OPERATOR(.equalto.), &
26  USE crtm_parameters , ONLY: zero, one, set, not_set
27  ! Disable implicit typing
28  IMPLICIT NONE
29 
30 
31  ! ------------
32  ! Visibilities
33  ! ------------
34  ! Everything private by default
35  PRIVATE
36  ! Datatypes
37  PUBLIC :: crtm_sfcoptics_type
38  ! Operators
39  PUBLIC :: OPERATOR(==)
40  ! Procedures
42  PUBLIC :: crtm_sfcoptics_destroy
43  PUBLIC :: crtm_sfcoptics_create
44  PUBLIC :: crtm_sfcoptics_inspect
46  PUBLIC :: crtm_sfcoptics_compare
47 
48 
49  ! ---------------------
50  ! Procedure overloading
51  ! ---------------------
52  INTERFACE OPERATOR(==)
53  MODULE PROCEDURE crtm_sfcoptics_equal
54  END INTERFACE OPERATOR(==)
55 
56 
57  ! -----------------
58  ! Module parameters
59  ! -----------------
60  CHARACTER(*), PARAMETER :: module_version_id = &
61  '$Id: CRTM_SfcOptics_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
62 
63 
64  ! -----------------------------------
65  ! Surface optics data type definition
66  ! -----------------------------------
68  ! Allocation indicator
69  LOGICAL :: is_allocated = .false.
70  ! Dimensions
71  INTEGER :: n_angles = 0 ! I
72  INTEGER :: n_stokes = 0 ! Ls
73  ! Flag for SfcOptics computation
74  LOGICAL :: compute = .true.
75 
76  ! MW Water SfcOptics options
77  LOGICAL :: use_new_mwssem = .true. ! Flag for MW Water SfcOptics algorithm switch
78  REAL(fp) :: azimuth_angle = 999.9_fp ! Relative azimuth angle
79  REAL(fp) :: transmittance = zero ! Total atmospheric transmittance
80 
81  ! Index of the satellite view angle in the angle arrays
82  INTEGER :: index_sat_ang = 1
83  ! The counter for the m'th component of the Fourier exapnsion of
84  ! the radiance for azimuth angle
85  INTEGER :: mth_azi = 0
86  ! The weighted mean surface temperature
87  REAL(fp) :: surface_temperature = zero
88 
89  ! The stream angles and weights
90  REAL(fp), ALLOCATABLE :: angle(:) ! I
91  REAL(fp), ALLOCATABLE :: weight(:) ! I
92  ! The emissivities and reflectivities
93  REAL(fp), ALLOCATABLE :: emissivity(:,:) ! I x Ls
94  REAL(fp), ALLOCATABLE :: reflectivity(:,:,:,:) ! I x Ls x I x Ls
95  REAL(fp), ALLOCATABLE :: direct_reflectivity(:,:) ! I x Ls
96  END TYPE crtm_sfcoptics_type
97 
98  ! Some notes regarding the above definition:
99  !
100  ! 1) The physical meaning of Reflectivity(:,:,:,:) is the following:
101  !
102  ! Given a pair of polarization indices, ip and rp, for the incident and
103  ! reflected radiances respectively, assuming there are no cross contributions
104  ! from incident radiation with different polarization, Reflectivity(:, rp, :, ip)
105  ! is defined as a reflectivity matrix with
106  !
107  ! Reflectivity(:, rp, :, ip) = 0 ; if rp /= ip
108  !
109  ! and
110  !
111  ! I(angle_r, p) = SUM( Reflectivity(angle_r, p, :, p) * I(:, p)), if rp=ip=p
112  !
113  ! where I(angle_r, p) is the reflected radiance at zenith angle with index angle_r,
114  ! and I(:, p) are the incident radiances and the summation is over the number of
115  ! incident angles. Thus, if BRDF(angle_r, p, angle_in, p) is the bidirectional
116  ! reflectivity distribution function, then
117  !
118  ! Reflectivity(angle_r, p, angle_in, p) = &
119  ! BRDF(angle_r, p, angle_in, p)*cos(angle_in)*w(angle_in)
120  !
121  ! where w(angle_in) is the quadrature weight.
122  !
123  ! A SPECIAL CASE
124  ! --------------
125  ! For a Lambertian surface, if only one angle is given, then
126  !
127  ! I_r = Reflectivity(1, rp, 1, ip) * I_diff
128  !
129  ! where I_r is the reflected radiance, constant at all angles, I_diff
130  ! is the incident radiance at the diffusivity angle.
131  !
132  !
133  ! 2) Regarding the Direct_Reflectivity(:,:) component,
134  !
135  ! If I(angle_r, p) is the reflected radiance at the zenith angle with index
136  ! angle_r and F_direct(angle_in) is the direct incident irradiance at the surface,
137  ! then Direct_Reflectivity(angle_r, p) is defined as
138  !
139  ! I(angle_r, p) = Direct_Reflectivity(angle_r, p) * cos(angle_in) * F_direct(angle_in)
140  !
141 
142 
143 CONTAINS
144 
145 
146 !################################################################################
147 !################################################################################
148 !## ##
149 !## ## PUBLIC MODULE ROUTINES ## ##
150 !## ##
151 !################################################################################
152 !################################################################################
153 
154 !--------------------------------------------------------------------------------
155 !:sdoc+:
156 !
157 ! NAME:
158 ! CRTM_SfcOptics_Associated
159 !
160 ! PURPOSE:
161 ! Elemental function to test the status of the allocatable components
162 ! of a CRTM SfcOptics object.
163 !
164 ! CALLING SEQUENCE:
165 ! Status = CRTM_SfcOptics_Associated( SfcOptics )
166 !
167 ! OBJECTS:
168 ! SfcOptics: SfcOptics structure which is to have its member's
169 ! status tested.
170 ! UNITS: N/A
171 ! TYPE: CRTM_SfcOptics_type
172 ! DIMENSION: Scalar or any rank
173 ! ATTRIBUTES: INTENT(IN)
174 !
175 ! FUNCTION RESULT:
176 ! Status: The return value is a logical value indicating the
177 ! status of the SfcOptics members.
178 ! .TRUE. - if the array components are allocated.
179 ! .FALSE. - if the array components are not allocated.
180 ! UNITS: N/A
181 ! TYPE: LOGICAL
182 ! DIMENSION: Same as input SfcOptics argument
183 !
184 !:sdoc-:
185 !--------------------------------------------------------------------------------
186 
187  ELEMENTAL FUNCTION crtm_sfcoptics_associated( SfcOptics ) RESULT( Status )
188  TYPE(crtm_sfcoptics_type), INTENT(IN) :: sfcoptics
189  LOGICAL :: status
190  status = sfcoptics%Is_Allocated
191  END FUNCTION crtm_sfcoptics_associated
192 
193 
194 !--------------------------------------------------------------------------------
195 !:sdoc+:
196 !
197 ! NAME:
198 ! CRTM_SfcOptics_Destroy
199 !
200 ! PURPOSE:
201 ! Elemental subroutine to re-initialize CRTM SfcOptics objects.
202 !
203 ! CALLING SEQUENCE:
204 ! CALL CRTM_SfcOptics_Destroy( SfcOptics )
205 !
206 ! OBJECTS:
207 ! SfcOptics: Re-initialized SfcOptics structure.
208 ! UNITS: N/A
209 ! TYPE: CRTM_SfcOptics_type
210 ! DIMENSION: Scalar OR any rank
211 ! ATTRIBUTES: INTENT(OUT)
212 !
213 !:sdoc-:
214 !--------------------------------------------------------------------------------
215 
216  ELEMENTAL SUBROUTINE crtm_sfcoptics_destroy( SfcOptics )
217  TYPE(crtm_sfcoptics_type), INTENT(OUT) :: sfcoptics
218  sfcoptics%Is_Allocated = .false.
219  END SUBROUTINE crtm_sfcoptics_destroy
220 
221 
222 !--------------------------------------------------------------------------------
223 !:sdoc+:
224 !
225 ! NAME:
226 ! CRTM_SfcOptics_Create
227 !
228 ! PURPOSE:
229 ! Elemental subroutine to create an instance of the CRTM SfcOptics object.
230 !
231 ! CALLING SEQUENCE:
232 ! CALL CRTM_SfcOptics_Create( SfcOptics, n_Layers )
233 !
234 ! OBJECTS:
235 ! SfcOptics: SfcOptics structure.
236 ! UNITS: N/A
237 ! TYPE: CRTM_SfcOptics_type
238 ! DIMENSION: Scalar or any rank
239 ! ATTRIBUTES: INTENT(OUT)
240 !
241 ! INPUTS:
242 ! n_Layers: Number of layers for which there is SfcOptics data.
243 ! Must be > 0.
244 ! UNITS: N/A
245 ! TYPE: INTEGER
246 ! DIMENSION: Same as SfcOptics object
247 ! ATTRIBUTES: INTENT(IN)
248 !
249 !:sdoc-:
250 !--------------------------------------------------------------------------------
251 
252  ELEMENTAL SUBROUTINE crtm_sfcoptics_create( &
253  SfcOptics, &
254  n_Angles , &
255  n_Stokes )
256  ! Arguments
257  TYPE(crtm_sfcoptics_type), INTENT(OUT) :: sfcoptics
258  INTEGER, INTENT(IN) :: n_angles
259  INTEGER, INTENT(IN) :: n_stokes
260  ! Local variables
261  INTEGER :: alloc_stat
262 
263  ! Check input
264  IF ( n_angles < 1 .OR. n_stokes < 1 ) RETURN
265 
266  ! Perform the allocation
267  ALLOCATE( sfcoptics%Angle( n_angles ), &
268  sfcoptics%Weight( n_angles ), &
269  sfcoptics%Emissivity( n_angles, n_stokes ), &
270  sfcoptics%Reflectivity( n_angles, n_stokes, n_angles, n_stokes), &
271  sfcoptics%Direct_Reflectivity( n_angles, n_stokes ), &
272  stat = alloc_stat )
273  IF ( alloc_stat /= 0 ) RETURN
274 
275  ! Initialise
276  ! ...Dimensions
277  sfcoptics%n_Angles = n_angles
278  sfcoptics%n_Stokes = n_stokes
279  ! ...Arrays
280  sfcoptics%Angle = zero
281  sfcoptics%Weight = zero
282  sfcoptics%Emissivity = zero
283  sfcoptics%Reflectivity = zero
284  sfcoptics%Direct_Reflectivity = zero
285 
286  ! Set allocation indicator
287  sfcoptics%Is_Allocated = .true.
288 
289  END SUBROUTINE crtm_sfcoptics_create
290 
291 
292 !--------------------------------------------------------------------------------
293 !:sdoc+:
294 !
295 ! NAME:
296 ! CRTM_SfcOptics_Inspect
297 !
298 ! PURPOSE:
299 ! Subroutine to print the contents of a CRTM SfcOptics object to stdout.
300 !
301 ! CALLING SEQUENCE:
302 ! CALL CRTM_SfcOptics_Inspect( SfcOptics )
303 !
304 ! INPUTS:
305 ! SfcOptics: CRTM SfcOptics object to display.
306 ! UNITS: N/A
307 ! TYPE: CRTM_SfcOptics_type
308 ! DIMENSION: Scalar
309 ! ATTRIBUTES: INTENT(IN)
310 !
311 !:sdoc-:
312 !--------------------------------------------------------------------------------
313 
314  SUBROUTINE crtm_sfcoptics_inspect( SfcOptics )
315  TYPE(crtm_sfcoptics_type), INTENT(IN) :: sfcoptics
316 
317  WRITE(*, '(1x,"SfcOptics OBJECT")')
318  ! Dimensions
319  WRITE(*, '(3x,"n_Angles :",1x,i0)') sfcoptics%n_Angles
320  WRITE(*, '(3x,"n_Stokes :",1x,i0)') sfcoptics%n_Stokes
321  ! Display components
322  WRITE(*, '(3x,"Compute flag :",1x,l1)') sfcoptics%Compute
323  WRITE(*, '(3x,"Use_New_MWSSEM flag :",1x,l1)') sfcoptics%Use_New_MWSSEM
324  WRITE(*, '(3x," MWSSEM- azimuth angle :",1x,es13.6)') sfcoptics%Azimuth_Angle
325  WRITE(*, '(3x," MWSSEM- transmittance :",1x,es13.6)') sfcoptics%Transmittance
326  WRITE(*, '(3x,"Satellite view angle index:",1x,i0)') sfcoptics%Index_Sat_Ang
327  WRITE(*, '(3x,"Azimuth Fourier component :",1x,i0)') sfcoptics%mth_Azi
328  WRITE(*, '(3x,"Weighted mean Tsfc :",1x,es13.6)') sfcoptics%Surface_Temperature
329  IF ( .NOT. crtm_sfcoptics_associated(sfcoptics) ) RETURN
330  WRITE(*, '(3x,"Angle :")')
331  WRITE(*, '(5(1x,es13.6,:))') sfcoptics%Angle
332  WRITE(*, '(3x,"Weight :")')
333  WRITE(*, '(5(1x,es13.6,:))') sfcoptics%Weight
334  WRITE(*, '(3x,"Emissivity :")')
335  WRITE(*, '(5(1x,es13.6,:))') sfcoptics%Emissivity
336  WRITE(*, '(3x,"Reflectivity :")')
337  WRITE(*, '(5(1x,es13.6,:))') sfcoptics%Reflectivity
338  WRITE(*, '(3x,"Direct_Reflectivity :")')
339  WRITE(*, '(5(1x,es13.6,:))') sfcoptics%Direct_Reflectivity
340  END SUBROUTINE crtm_sfcoptics_inspect
341 
342 
343 !--------------------------------------------------------------------------------
344 !:sdoc+:
345 !
346 ! NAME:
347 ! CRTM_SfcOptics_DefineVersion
348 !
349 ! PURPOSE:
350 ! Subroutine to return the module version information.
351 !
352 ! CALLING SEQUENCE:
353 ! CALL CRTM_SfcOptics_DefineVersion( Id )
354 !
355 ! OUTPUTS:
356 ! Id: Character string containing the version Id information
357 ! for the module.
358 ! UNITS: N/A
359 ! TYPE: CHARACTER(*)
360 ! DIMENSION: Scalar
361 ! ATTRIBUTES: INTENT(OUT)
362 !
363 !:sdoc-:
364 !--------------------------------------------------------------------------------
365 
366  SUBROUTINE crtm_sfcoptics_defineversion( Id )
367  CHARACTER(*), INTENT(OUT) :: id
368  id = module_version_id
369  END SUBROUTINE crtm_sfcoptics_defineversion
370 
371 
372 !------------------------------------------------------------------------------
373 !:sdoc+:
374 ! NAME:
375 ! CRTM_SfcOptics_Compare
376 !
377 ! PURPOSE:
378 ! Elemental function to compare two CRTM_SfcOptics objects to within
379 ! a user specified number of significant figures.
380 !
381 ! CALLING SEQUENCE:
382 ! is_comparable = CRTM_SfcOptics_Compare( x, y, n_SigFig=n_SigFig )
383 !
384 ! OBJECTS:
385 ! x, y: Two CRTM SfcOptics objects to be compared.
386 ! UNITS: N/A
387 ! TYPE: CRTM_SfcOptics_type
388 ! DIMENSION: Scalar or any rank
389 ! ATTRIBUTES: INTENT(IN)
390 !
391 ! OPTIONAL INPUTS:
392 ! n_SigFig: Number of significant figure to compare floating point
393 ! components.
394 ! UNITS: N/A
395 ! TYPE: INTEGER
396 ! DIMENSION: Scalar or same as input
397 ! ATTRIBUTES: INTENT(IN), OPTIONAL
398 !
399 ! FUNCTION RESULT:
400 ! is_equal: Logical value indicating whether the inputs are equal.
401 ! UNITS: N/A
402 ! TYPE: LOGICAL
403 ! DIMENSION: Same as inputs.
404 !:sdoc-:
405 !------------------------------------------------------------------------------
406 
407  ELEMENTAL FUNCTION crtm_sfcoptics_compare( &
408  x, &
409  y, &
410  n_SigFig ) &
411  result( is_comparable )
412  TYPE(crtm_sfcoptics_type), INTENT(IN) :: x, y
413  INTEGER, OPTIONAL, INTENT(IN) :: n_sigfig
414  LOGICAL :: is_comparable
415  ! Variables
416  INTEGER :: n
417 
418  ! Set up
419  is_comparable = .false.
420  IF ( PRESENT(n_sigfig) ) THEN
421  n = abs(n_sigfig)
422  ELSE
423  n = default_n_sigfig
424  END IF
425 
426  ! Check the structure association status
427  IF ( (.NOT. crtm_sfcoptics_associated(x)) .OR. &
428  (.NOT. crtm_sfcoptics_associated(y)) ) RETURN
429 
430  ! Check dimensions
431  IF ( (x%n_Angles /= y%n_Angles) .OR. &
432  (x%n_Stokes /= y%n_Stokes) ) RETURN
433 
434  ! Check scalars
435  ! ...Logicals
436  IF ( (x%Compute .NEQV. y%Compute ) .OR. &
437  (x%Use_New_MWSSEM .NEQV. y%Use_New_MWSSEM) ) RETURN
438  ! ...Other types
439  IF ( (.NOT. compares_within_tolerance(x%Azimuth_Angle,y%Azimuth_Angle,n)) .OR. &
440  (.NOT. compares_within_tolerance(x%Transmittance,y%Transmittance,n)) .OR. &
441  (x%Index_Sat_Ang /= y%Index_Sat_Ang) .OR. &
442  (x%mth_Azi /= y%mth_Azi ) .OR. &
443  (.NOT. compares_within_tolerance(x%Surface_Temperature,y%Surface_Temperature,n)) ) RETURN
444 
445  ! Check arrays
446  IF ( (.NOT. all(compares_within_tolerance(x%Angle ,y%Angle ,n))) .OR. &
447  (.NOT. all(compares_within_tolerance(x%Weight ,y%Weight ,n))) .OR. &
448  (.NOT. all(compares_within_tolerance(x%Emissivity ,y%Emissivity ,n))) .OR. &
449  (.NOT. all(compares_within_tolerance(x%Reflectivity ,y%Reflectivity ,n))) .OR. &
450  (.NOT. all(compares_within_tolerance(x%Direct_Reflectivity,y%Direct_Reflectivity,n))) ) RETURN
451 
452  ! If we get here, the structures are comparable
453  is_comparable = .true.
454 
455  END FUNCTION crtm_sfcoptics_compare
456 
457 
458 !##################################################################################
459 !##################################################################################
460 !## ##
461 !## ## PRIVATE MODULE ROUTINES ## ##
462 !## ##
463 !##################################################################################
464 !##################################################################################
465 
466 !------------------------------------------------------------------------------
467 !
468 ! NAME:
469 ! CRTM_SfcOptics_Equal
470 !
471 ! PURPOSE:
472 ! Elemental function to test the equality of two CRTM_SfcOptics objects.
473 ! Used in OPERATOR(==) interface block.
474 !
475 ! CALLING SEQUENCE:
476 ! is_equal = CRTM_SfcOptics_Equal( x, y )
477 !
478 ! or
479 !
480 ! IF ( x == y ) THEN
481 ! ...
482 ! END IF
483 !
484 ! OBJECTS:
485 ! x, y: Two CRTM SfcOptics objects to be compared.
486 ! UNITS: N/A
487 ! TYPE: CRTM_SfcOptics_type
488 ! DIMENSION: Scalar or any rank
489 ! ATTRIBUTES: INTENT(IN)
490 !
491 ! FUNCTION RESULT:
492 ! is_equal: Logical value indicating whether the inputs are equal.
493 ! UNITS: N/A
494 ! TYPE: LOGICAL
495 ! DIMENSION: Same as inputs.
496 !
497 !------------------------------------------------------------------------------
498 
499  ELEMENTAL FUNCTION crtm_sfcoptics_equal( x, y ) RESULT( is_equal )
500  TYPE(crtm_sfcoptics_type), INTENT(IN) :: x, y
501  LOGICAL :: is_equal
502 
503  ! Set up
504  is_equal = .false.
505 
506  ! Check the structure association status
507  IF ( (.NOT. crtm_sfcoptics_associated(x)) .OR. &
508  (.NOT. crtm_sfcoptics_associated(y)) ) RETURN
509 
510  ! Check contents
511  ! ...Dimensions
512  IF ( (x%n_Angles /= y%n_Angles) .OR. &
513  (x%n_Stokes /= y%n_Stokes) ) RETURN
514  ! ...Everything else
515  IF ( (x%Compute .EQV. y%Compute ) .AND. &
516  (x%Use_New_MWSSEM .EQV. y%Use_New_MWSSEM ) .AND. &
517  (x%Azimuth_Angle .equalto. y%Azimuth_Angle ) .AND. &
518  (x%Transmittance .equalto. y%Transmittance ) .AND. &
519  (x%Index_Sat_Ang == y%Index_Sat_Ang ) .AND. &
520  (x%mth_Azi == y%mth_Azi ) .AND. &
521  (x%Surface_Temperature .equalto. y%Surface_Temperature) .AND. &
522  all(x%Angle .equalto. y%Angle ) .AND. &
523  all(x%Weight .equalto. y%Weight ) .AND. &
524  all(x%Emissivity .equalto. y%Emissivity ) .AND. &
525  all(x%Reflectivity .equalto. y%Reflectivity ) .AND. &
526  all(x%Direct_Reflectivity .equalto. y%Direct_Reflectivity) ) &
527  is_equal = .true.
528 
529  END FUNCTION crtm_sfcoptics_equal
530 
531 END MODULE crtm_sfcoptics_define
integer, parameter, public failure
integer, parameter, public set
real(fp), parameter, public zero
integer, parameter, public warning
integer, parameter, public fp
Definition: Type_Kinds.f90:124
elemental logical function crtm_sfcoptics_equal(x, y)
elemental subroutine, public crtm_sfcoptics_create(SfcOptics, n_Angles, n_Stokes)
integer, parameter, public not_set
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
elemental logical function, public crtm_sfcoptics_associated(SfcOptics)
elemental logical function, public crtm_sfcoptics_compare(x, y, n_SigFig)
integer, parameter, public default_n_sigfig
subroutine, public crtm_sfcoptics_inspect(SfcOptics)
elemental subroutine, public crtm_sfcoptics_destroy(SfcOptics)
character(*), parameter module_version_id
subroutine, public crtm_sfcoptics_defineversion(Id)
integer, parameter, public success
integer, parameter, public information