FV3 Bundle
CRTM_AtmOptics.f90
Go to the documentation of this file.
1 !
2 ! CRTM_AtmOptics
3 !
4 ! Application module for AtmOptics objects.
5 !
6 ! CREATION HISTORY:
7 ! Written by: Quanhua Liu, quanhua.liu@noaa.gov
8 ! Yong Han, yong.han@noaa.gov
9 ! Paul van Delst, paul.vandelst@noaa.gov
10 ! 08-Jun-2005
11 !
12 
14 
15  ! ---------------
16  ! Environment setup
17  ! ---------------
18  ! Module use
19  USE type_kinds , ONLY: fp
21  USE crtm_parameters , ONLY: zero, one, point_5, &
22  max_n_layers, &
23  bs_threshold, &
26  ! Internal variable definition module
27  USE aovar_define, ONLY: aovar_type, &
29  aovar_destroy , &
31  ! Disable implicit typing
32  IMPLICIT NONE
33 
34 
35  ! ----------
36  ! Visibilities
37  ! ----------
38  ! Everything private by default
39  PRIVATE
40  ! Datatypes
41  PUBLIC :: aovar_type
42  ! Procedures
43  PUBLIC :: aovar_create
44  PUBLIC :: crtm_no_scattering
45  PUBLIC :: crtm_include_scattering
49  PUBLIC :: crtm_combine_atmoptics
52 
53 
54  ! ---------------
55  ! Module parameters
56  ! ---------------
57  CHARACTER(*), PARAMETER :: module_version_id = &
58  '$Id: CRTM_AtmOptics.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
59 
60 
61 CONTAINS
62 
63 
64 !################################################################################
65 !################################################################################
66 !## ##
67 !## ## PUBLIC MODULE ROUTINES ## ##
68 !## ##
69 !################################################################################
70 !################################################################################
71 
72 
73 !--------------------------------------------------------------------------------
74 !:sdoc+:
75 !
76 ! NAME:
77 ! CRTM_No_Scattering
78 !
79 ! PURPOSE:
80 ! Pure function to determine if scattering calculations will NOT be
81 ! performed.
82 !
83 ! CALLING SEQUENCE:
84 ! result = CRTM_No_Scattering( AtmOptics )
85 !
86 ! INPUTS:
87 ! AtmOptics: The atmospheric optical properties
88 ! UNITS: N/A
89 ! TYPE: CRTM_AtmOptics_type
90 ! DIMENSION: Scalar
91 ! ATTRIBUTES: INTENT(IN)
92 !
93 ! FUNCTION RESULT:
94 ! result: Returns
95 ! TRUE - if the maximum single scatter albedo profile
96 ! value is less than or equal to the scattering
97 ! albedo threshold, OR if the user explicitly
98 ! disbles scattering via the Include_Scattering
99 ! option.
100 ! FALSE - otherwise.
101 ! UNITS: N/A
102 ! TYPE: LOGICAL
103 ! DIMENSION: Scalar
104 !
105 !:sdoc-:
106 !--------------------------------------------------------------------------------
107 
108  PURE FUNCTION crtm_no_scattering(atmoptics) RESULT(no_scattering)
109  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
110  LOGICAL :: no_scattering
111  no_scattering = .NOT. crtm_include_scattering(atmoptics)
112  END FUNCTION crtm_no_scattering
113 
114 
115 !--------------------------------------------------------------------------------
116 !:sdoc+:
117 !
118 ! NAME:
119 ! CRTM_Include_Scattering
120 !
121 ! PURPOSE:
122 ! Pure function to determine if scattering calculations will be
123 ! performed.
124 !
125 ! CALLING SEQUENCE:
126 ! result = CRTM_Include_Scattering( AtmOptics )
127 !
128 ! INPUTS:
129 ! AtmOptics: The atmospheric optical properties
130 ! UNITS: N/A
131 ! TYPE: CRTM_AtmOptics_type
132 ! DIMENSION: Scalar
133 ! ATTRIBUTES: INTENT(IN)
134 !
135 ! FUNCTION RESULT:
136 ! result: Returns
137 ! TRUE - if the maximum single scatter albedo profile
138 ! value is greater than the scattering albedo
139 ! threshold, AND if the user has NOT explicitly
140 ! disbled scattering via the Include_Scattering
141 ! option.
142 ! FALSE - otherwise.
143 ! UNITS: N/A
144 ! TYPE: LOGICAL
145 ! DIMENSION: Scalar
146 !
147 !:sdoc-:
148 !--------------------------------------------------------------------------------
149 
150  PURE FUNCTION crtm_include_scattering(atmoptics) RESULT(include_scattering)
151  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
152  LOGICAL :: include_scattering
153  ! This test is different from previous incarnations in that before the
154  ! test turned OFF scattering if the AtmOptics single scatter albedo was
155  ! LESS THAN the threshold (i.e. greater than or equal to).
156  ! Now we include scattering if the AtmOptics single scatter albedo is
157  ! GREATER THAN (but NOT equal to) the threshold.
158  ! Confused? Sorry.
159  include_scattering = (maxval(atmoptics%Single_Scatter_Albedo) > scattering_albedo_threshold) .AND. &
160  atmoptics%Include_Scattering
161  END FUNCTION crtm_include_scattering
162 
163 
164 !--------------------------------------------------------------------------------
165 !:sdoc+:
166 !
167 ! NAME:
168 ! CRTM_Compute_Transmittance
169 !
170 ! PURPOSE:
171 ! Subroutine to compute the total atmospheric transmittance.
172 !
173 ! CALLING SEQUENCE:
174 ! CALL CRTM_Compute_Transmittance( AtmOptics, Transmittance )
175 !
176 ! INPUTS:
177 ! AtmOptics: The atmospheric optical properties
178 ! UNITS: N/A
179 ! TYPE: CRTM_AtmOptics_type
180 ! DIMENSION: Scalar
181 ! ATTRIBUTES: INTENT(IN)
182 !
183 ! OUTPUTS:
184 ! Transmittance: The total atmospheric transmittance derived from
185 ! the optical depth component of AtmOptics.
186 ! UNITS: N/A
187 ! TYPE: REAL(fp)
188 ! DIMENSION: Scalar
189 ! ATTRIBUTES: INTENT(OUT)
190 !
191 !:sdoc-:
192 !--------------------------------------------------------------------------------
193 
194  SUBROUTINE crtm_compute_transmittance( atmoptics, transmittance )
195  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
196  REAL(fp) , INTENT(OUT) :: transmittance
197  INTEGER :: k
198  k = atmoptics%n_layers
199  transmittance = exp(-one*sum(atmoptics%optical_depth(1:k)))
200  END SUBROUTINE crtm_compute_transmittance
201 
202 
203 !--------------------------------------------------------------------------------
204 !:sdoc+:
205 !
206 ! NAME:
207 ! CRTM_Compute_Transmittance_TL
208 !
209 ! PURPOSE:
210 ! Subroutine to compute the tangent-linear total atmospheric transmittance.
211 !
212 ! CALLING SEQUENCE:
213 ! CALL CRTM_Compute_Transmittance_TL( AtmOptics , &
214 ! AtmOptics_TL, &
215 ! Transmittance_TL )
216 !
217 ! INPUTS:
218 ! AtmOptics: The atmospheric optical properties
219 ! UNITS: N/A
220 ! TYPE: CRTM_AtmOptics_type
221 ! DIMENSION: Scalar
222 ! ATTRIBUTES: INTENT(IN)
223 !
224 ! AtmOptics_TL: The tangent-linear atmospheric optical properties
225 ! UNITS: N/A
226 ! TYPE: CRTM_AtmOptics_type
227 ! DIMENSION: Scalar
228 ! ATTRIBUTES: INTENT(IN)
229 !
230 ! OUTPUTS:
231 ! Transmittance_TL: The tangent-linear of the total atmospheric
232 ! transmittance derived from the optical depth
233 ! component of AtmOptics.
234 ! UNITS: N/A
235 ! TYPE: REAL(fp)
236 ! DIMENSION: Scalar
237 ! ATTRIBUTES: INTENT(OUT)
238 !
239 !:sdoc-:
240 !--------------------------------------------------------------------------------
241 
242  SUBROUTINE crtm_compute_transmittance_tl( &
243  atmoptics , & ! Input
244  atmoptics_TL , & ! Input
245  transmittance_TL ) ! Output
246  ! Arguments
247  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
248  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics_tl
249  REAL(fp) , INTENT(OUT) :: transmittance_tl
250  ! Local variables
251  INTEGER :: k
252  REAL(fp) :: transmittance
253 
254  k = atmoptics%n_layers
255  transmittance = exp(-one*sum(atmoptics%optical_depth(1:k)))
256  transmittance_tl = -transmittance * sum(atmoptics_tl%optical_depth(1:k))
257  END SUBROUTINE crtm_compute_transmittance_tl
258 
259 
260 !--------------------------------------------------------------------------------
261 !:sdoc+:
262 !
263 ! NAME:
264 ! CRTM_Compute_Transmittance_AD
265 !
266 ! PURPOSE:
267 ! Subroutine to compute the adjoint of the total atmospheric transmittance.
268 !
269 ! CALLING SEQUENCE:
270 ! CALL CRTM_Compute_Transmittance_AD( AtmOptics , &
271 ! Transmittance_AD, &
272 ! AtmOptics_AD )
273 !
274 ! INPUTS:
275 ! AtmOptics: The atmospheric optical properties
276 ! UNITS: N/A
277 ! TYPE: CRTM_AtmOptics_type
278 ! DIMENSION: Scalar
279 ! ATTRIBUTES: INTENT(IN)
280 !
281 ! Transmittance_AD: The adjoint of the total atmospheric transmittance.
282 ! *** Set to ZERO upon exit ***
283 ! UNITS: N/A
284 ! TYPE: REAL(fp)
285 ! DIMENSION: Scalar
286 ! ATTRIBUTES: INTENT(IN OUT)
287 !
288 ! OUTPUTS:
289 ! AtmOptics_AD: The adjoint atmospheric optical properties.
290 ! *** Must be defined upon input ***
291 ! UNITS: N/A
292 ! TYPE: CRTM_AtmOptics_type
293 ! DIMENSION: Scalar
294 ! ATTRIBUTES: INTENT(IN OUT)
295 !
296 !:sdoc-:
297 !--------------------------------------------------------------------------------
298 
299  SUBROUTINE crtm_compute_transmittance_ad( &
300  atmoptics , & ! Input
301  transmittance_AD, & ! Input
302  atmoptics_AD ) ! Output
303  ! Arguments
304  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
305  REAL(fp) , INTENT(IN OUT) :: transmittance_ad
306  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics_ad
307  ! Local variables
308  INTEGER :: k
309  REAL(fp) :: transmittance, t_delstar_t
310 
311  k = atmoptics%n_layers
312  transmittance = exp(-one*sum(atmoptics%optical_depth(1:k)))
313  t_delstar_t = transmittance*transmittance_ad
314  DO k = 1, atmoptics%n_layers
315  atmoptics_ad%optical_depth(k) = atmoptics_ad%optical_depth(k) - t_delstar_t
316  END DO
317  transmittance_ad = zero
318  END SUBROUTINE crtm_compute_transmittance_ad
319 
320 
321 !--------------------------------------------------------------------------------
322 !:sdoc+:
323 !
324 ! NAME:
325 ! CRTM_Combine_AtmOptics
326 !
327 ! PURPOSE:
328 ! Subroutine to combine the optical properties from AtmAbsorption,
329 ! CloudScatter, and AerosolScatter calculations.
330 !
331 ! CALLING SEQUENCE:
332 ! CALL CRTM_Combine_AtmOptics( AtmOptics, &
333 ! AOvar )
334 !
335 ! OUTPUTS:
336 ! AtmOptics: The combined atmospheric optical properties
337 ! UNITS: N/A
338 ! TYPE: CRTM_AtmOptics_type
339 ! DIMENSION: Scalar
340 ! ATTRIBUTES: INTENT(IN OUT)
341 !
342 ! AOvar: Structure containing internal variables required for
343 ! subsequent tangent-linear or adjoint model calls.
344 ! The contents of this structure are NOT accessible
345 ! outside of this module.
346 ! UNITS: N/A
347 ! TYPE: AOvar_type
348 ! DIMENSION: Scalar
349 ! ATTRIBUTES: INTENT(IN OUT)
350 !
351 !:sdoc-:
352 !--------------------------------------------------------------------------------
353 
354  SUBROUTINE crtm_combine_atmoptics( &
355  AtmOptics, & ! Output
356  AOvar ) ! Internal variable output
357  ! Arguments
358  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics
359  TYPE(aovar_type) , INTENT(IN OUT) :: aovar
360  ! Local parameters
361  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Combine_AtmOptics'
362  ! Local variables
363  INTEGER :: i, k, l
364 
365  ! Initialise scattering optical depth sum
366  atmoptics%Scattering_Optical_Depth = zero
367 
368 
369  ! No scattering case
370  IF( (.NOT. atmoptics%Include_Scattering) .OR. &
371  atmoptics%n_Legendre_Terms == 0 ) RETURN
372 
373 
374  ! Loop over atmospheric layers
375  layer_loop: DO k = 1, atmoptics%n_Layers
376 
377 
378  ! Save the unmodified optical parameters
379  aovar%Optical_Depth(k) = atmoptics%Optical_Depth(k)
380  aovar%bs(k) = atmoptics%Single_Scatter_Albedo(k)
381  ! ...Initialise scattering dependent terms
382  aovar%w(k) = zero
383 
384 
385  ! Only proceed if the total optical depth is significant
386  significant_scattering: IF( aovar%bs(k) > bs_threshold ) THEN
387 
388  aovar%w(k) = atmoptics%Single_Scatter_Albedo(k) / atmoptics%Optical_Depth(k)
389  DO i = 1, atmoptics%n_Phase_Elements
390  DO l = 1, atmoptics%n_Legendre_Terms
391  atmoptics%Phase_Coefficient(l,i,k) = atmoptics%Phase_Coefficient(l,i,k) / &
392  atmoptics%Single_Scatter_Albedo(k)
393  END DO
394  ! ...Normalization requirement for energy conservation
395  atmoptics%Phase_Coefficient(0,i,k) = point_5
396  END DO
397  atmoptics%Delta_Truncation(k) = atmoptics%Phase_Coefficient(atmoptics%n_Legendre_Terms,1,k)
398 
399 
400  ! Redfine the total optical depth and single scattering
401  ! albedo for the delta-function adjustment
402  atmoptics%Optical_Depth(k) = ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) )) * &
403  atmoptics%Optical_Depth(k)
404  atmoptics%Single_Scatter_Albedo(k) = ( one - atmoptics%Delta_Truncation(k) ) * aovar%w(k) / &
405  ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) )
406 
407  END IF significant_scattering
408 
409 
410  ! Compute the vertically integrated scattering optical depth
411  atmoptics%Scattering_Optical_Depth = atmoptics%Scattering_Optical_Depth + &
412  (aovar%w(k) * aovar%Optical_Depth(k))
413 
414  END DO layer_loop
415 
416 
417  END SUBROUTINE crtm_combine_atmoptics
418 
419 
420 
421 !--------------------------------------------------------------------------------
422 !:sdoc+:
423 !
424 ! NAME:
425 ! CRTM_Combine_AtmOptics_TL
426 !
427 ! PURPOSE:
428 ! Subroutine to combine the tangent-linear optical properties from
429 ! AtmAbsorption, CloudScatter, and AerosolScatter calculations.
430 !
431 ! CALLING SEQUENCE:
432 ! CALL CRTM_Combine_AtmOptics_TL( AtmOptics , &
433 ! AtmOptics_TL, &
434 ! AOvar )
435 ! INPUTS:
436 ! AtmOptics: Combined atmospheric optical properties.
437 ! UNITS: N/A
438 ! TYPE: CRTM_AtmOptics_type
439 ! DIMENSION: Scalar
440 ! ATTRIBUTES: INTENT(IN)
441 !
442 ! AOvar: Structure containing internal forward model variables
443 ! required for subsequent tangent-linear or adjoint model
444 ! calls. The contents of this structure are NOT accessible
445 ! outside of this module.
446 ! UNITS: N/A
447 ! TYPE: AOvar_type
448 ! DIMENSION: Scalar
449 ! ATTRIBUTES: INTENT(IN)
450 !
451 ! OUTPUT:
452 ! AtmOptics_TL: Tangent-linear combined atmospheric optical properties.
453 ! UNITS: N/A
454 ! TYPE: CRTM_AtmOptics_type
455 ! DIMENSION: Scalar
456 ! ATTRIBUTES: INTENT(IN OUT)
457 !
458 !:sdoc-:
459 !--------------------------------------------------------------------------------
460 
461  SUBROUTINE crtm_combine_atmoptics_tl( &
462  AtmOptics , & ! FWD Input
463  AtmOptics_TL, & ! TL Output
464  AOvar ) ! Internal variable input
465  ! Arguments
466  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
467  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics_tl
468  TYPE(aovar_type) , INTENT(IN) :: aovar
469  ! Local parameters
470  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Combine_AtmOptics_TL'
471  ! Local variables
472  INTEGER :: i, k, l
473  REAL(fp) :: optical_depth_tl
474  REAL(fp) :: w_tl
475 
476 
477  ! Initialise tangent-linear scattering optical depth sum
478  atmoptics_tl%Scattering_Optical_Depth = zero
479 
480 
481  ! No scattering case
482  IF( (.NOT. atmoptics%Include_Scattering) .OR. &
483  atmoptics%n_Legendre_Terms == 0 ) RETURN
484 
485 
486  ! Loop over atmospheric layers
487  layer_loop: DO k = 1, atmoptics%n_Layers
488 
489 
490  ! Save the unmodified optical parameters
491  optical_depth_tl = atmoptics_tl%Optical_Depth(k)
492  ! ...Initialise scattering dependent terms
493  w_tl = zero
494 
495 
496  ! Only proceed if the total optical depth is significant
497  significant_scattering: IF( aovar%bs(k) > bs_threshold ) THEN
498 
499 
500  w_tl = ( atmoptics_tl%Single_Scatter_Albedo(k) / aovar%Optical_Depth(k) ) - &
501  ( atmoptics_tl%Optical_Depth(k) * aovar%w(k) / aovar%Optical_Depth(k) )
502  DO i = 1, atmoptics%n_Phase_Elements
503  DO l = 1, atmoptics%n_Legendre_Terms
504  atmoptics_tl%Phase_Coefficient(l,i,k) = &
505  ( atmoptics_tl%Phase_Coefficient(l,i,k) - &
506  (atmoptics%Phase_Coefficient(l,i,k) * atmoptics_tl%Single_Scatter_Albedo(k)) ) / aovar%bs(k)
507  END DO
508  ! ...Normalization requirement for energy conservation
509  atmoptics_tl%Phase_Coefficient(0,i,k) = zero
510  END DO
511  atmoptics_tl%Delta_Truncation(k) = atmoptics_tl%Phase_Coefficient(atmoptics%n_Legendre_Terms,1,k)
512 
513 
514  ! Redefine the tangent-linear total optical depth and
515  ! single scattering albedo for the delta-function adjustment
516  !
517  ! The expressions below are ordered to make the adjoint
518  ! form easy to determine from the TL form.
519 
520 
521  ! The optical depth
522  !
523  ! tau = ( 1 - d.w ) . tau
524  !
525  ! so,
526  !
527  ! tau_TL = ( 1 - d.w ).tau_TL - d.tau.w_TL - w.tau.d_TL
528  !
529  ! Note that the optical depth from the AOvar structure is
530  ! used on the RHS of these expressions.
531  atmoptics_tl%Optical_Depth(k) = &
532  ( ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) ) * atmoptics_tl%Optical_Depth(k) ) - &
533  ( atmoptics%Delta_Truncation(k) * aovar%Optical_Depth(k) * w_tl ) - &
534  ( aovar%w(k) * aovar%Optical_Depth(k) * atmoptics_tl%Delta_Truncation(k) )
535 
536 
537  ! The single scatter albedo, SSA
538  !
539  ! (1 - d).w
540  ! SSA = -----------
541  ! 1 - d.w
542  !
543  ! so,
544  !
545  ! ( 1 - d + SSA.d ) ( SSA - 1 ).w
546  ! SSA_TL = ------------------- . w_TL + --------------- . d_TL
547  ! 1 - d.w 1 - d.w
548  !
549  atmoptics_tl%Single_Scatter_Albedo(k) = &
550  ( ( ( one - atmoptics%Delta_Truncation(k) + &
551  ( atmoptics%Single_Scatter_Albedo(k)*atmoptics%Delta_Truncation(k) ) ) * w_tl ) + &
552  ( ( atmoptics%Single_Scatter_Albedo(k) - one ) * aovar%w(k) * atmoptics_tl%Delta_Truncation(k) ) ) / &
553  ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) )
554 
555  END IF significant_scattering
556 
557 
558  ! Compute the tangent-linear vertically integrated scattering optical depth
559  atmoptics_tl%Scattering_Optical_Depth = atmoptics_tl%Scattering_Optical_Depth + &
560  (aovar%w(k) * optical_depth_tl) + &
561  (aovar%Optical_Depth(k) * w_tl)
562 
563  END DO layer_loop
564 
565  END SUBROUTINE crtm_combine_atmoptics_tl
566 
567 
568 
569 !--------------------------------------------------------------------------------
570 !:sdoc+:
571 !
572 ! NAME:
573 ! CRTM_Combine_AtmOptics_AD
574 !
575 ! PURPOSE:
576 ! Subroutine to compute the adjoint form of the optical properties
577 ! from AtmAbsorption, CloudScatter, and AerosolScatter calculations.
578 !
579 ! CALLING SEQUENCE:
580 ! CALL CRTM_Combine_AtmOptics_AD( AtmOptics, &
581 ! AtmOptics_AD, &
582 ! AOvar )
583 !
584 ! INPUTS:
585 ! AtmOptics: Structure containing the combined atmospheric optical
586 ! parameters
587 ! UNITS: N/A
588 ! TYPE: CRTM_AtmOptics_type
589 ! DIMENSION: Scalar
590 ! ATTRIBUTES: INTENT(IN)
591 !
592 ! AOvar: Structure containing internal forward model variables
593 ! required for subsequent tangent-linear or adjoint model
594 ! calls. The contents of this structure are NOT accessible
595 ! outside of the CRTM_AtmOptics module.
596 ! UNITS: N/A
597 ! TYPE: AOvar_type
598 ! DIMENSION: Scalar
599 ! ATTRIBUTES: INTENT(IN)
600 !
601 ! AtmOptics_AD: Structure containing the combined adjoint atmospheric
602 ! optical parameters.
603 ! NOTE: The components of this structures are all zeroed
604 ! upon exit from this routine.
605 ! UNITS: N/A
606 ! TYPE: CRTM_AtmOptics_type
607 ! DIMENSION: Scalar
608 ! ATTRIBUTES: INTENT(IN OUT)
609 !
610 !:sdoc-:
611 !--------------------------------------------------------------------------------
612 
613  SUBROUTINE crtm_combine_atmoptics_ad( &
614  AtmOptics , & ! FWD Input
615  AtmOptics_AD, & ! AD Input
616  AOvar ) ! Internal variable input
617  ! Arguments
618  TYPE(crtm_atmoptics_type), INTENT(IN) :: atmoptics
619  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics_ad
620  TYPE(aovar_type) , INTENT(IN) :: aovar
621  ! Local parameters
622  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Combine_AtmOptics_AD'
623  ! Local variables
624  INTEGER :: i, k, l
625  REAL(fp) :: w_ad
626 
627 
628  ! No scattering case
629  IF( (.NOT. atmoptics%Include_Scattering) .OR. &
630  atmoptics%n_Legendre_Terms == 0 ) RETURN
631 
632  ! Begin layer loop
633  layer_loop: DO k = atmoptics%n_Layers, 1, -1
634 
635  w_ad = zero
636 
637 
638  ! Only proceed if the scattering is significant
639  significant_scattering: IF( aovar%bs(k) > bs_threshold) THEN
640 
641 
642  ! Compute the adjoint total optical depth and single
643  ! scattering albedo for the delta function adjustment
644 
645  ! The tangent-linear single scatter albedo, SSA_TL
646  !
647  ! ( 1 - d + SSA.d ) ( SSA - 1 ).w
648  ! SSA_TL = ------------------- . w_TL + --------------- . d_TL
649  ! 1 - d.w 1 - d.w
650  !
651  ! so,
652  ! ( SSA - 1 ).w
653  ! d_AD = d_AD + ---------------- . SSA_AD
654  ! 1 - d.w
655  !
656  ! ( 1 - d + SSA.d )
657  ! w_AD = w_AD + ------------------- . SSA_AD
658  ! 1 - d.w
659  !
660  ! SSA_AD = 0
661 
662  atmoptics_ad%Delta_Truncation(k) = atmoptics_ad%Delta_Truncation(k) + &
663  ( ( atmoptics%Single_Scatter_Albedo(k) - one ) * aovar%w(k) * atmoptics_ad%Single_Scatter_Albedo(k) / &
664  ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) ) )
665 
666  w_ad = w_ad + ( ( one - atmoptics%Delta_Truncation(k) + &
667  ( atmoptics%Single_Scatter_Albedo(k)*atmoptics%Delta_Truncation(k) ) ) * &
668  atmoptics_ad%Single_Scatter_Albedo(k) / &
669  ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) ) )
670 
671  atmoptics_ad%Single_Scatter_Albedo(k) = zero
672 
673 
674  ! The tangent-linear optical depth, tau_TL
675  !
676  ! tau_TL = ( 1 - d.w ).tau_TL - d.tau.w_TL - w.tau.d_TL
677  !
678  ! so,
679  !
680  ! d_AD = d_AD - w.tau.tau_AD
681  !
682  ! w_AD = w_AD - d.tau.tau_AD
683  !
684  ! tau_AD = ( 1 - d.w ).tau_AD
685  !
686  ! Note that the optical depth from the AOvar structure is
687  ! used on the RHS of the above expressions.
688 
689  atmoptics_ad%Delta_Truncation(k) = atmoptics_ad%Delta_Truncation(k) - &
690  ( aovar%w(k) * & ! w
691  aovar%Optical_Depth(k) * & ! tau
692  atmoptics_ad%Optical_Depth(k) ) ! tau_AD
693 
694  w_ad = w_ad - ( atmoptics%Delta_Truncation(k) * & ! d
695  aovar%Optical_Depth(k) * & ! tau
696  atmoptics_ad%Optical_Depth(k) ) ! tau_AD
697 
698  atmoptics_ad%Optical_Depth(k) = ( one - ( atmoptics%Delta_Truncation(k) * aovar%w(k) ) ) * &
699  atmoptics_ad%Optical_Depth(k)
700 
701 
702  ! Delta truncation adjoint
703  l = atmoptics%n_Legendre_Terms
704  atmoptics_ad%Phase_Coefficient(l,1,k) = atmoptics_ad%Phase_Coefficient(l,1,k) + &
705  atmoptics_ad%Delta_Truncation(k)
706  atmoptics_ad%Delta_Truncation(k) = zero
707 
708  DO i = 1, atmoptics%n_Phase_Elements
709  ! Normalization requirement for energy conservation
710  atmoptics_ad%Phase_Coefficient(0,i,k) = zero
711  DO l = 1, atmoptics%n_Legendre_Terms
712  atmoptics_ad%Single_Scatter_Albedo(k) = atmoptics_ad%Single_Scatter_Albedo(k) - &
713  atmoptics%Phase_Coefficient(l,i,k)*atmoptics_ad%Phase_Coefficient(l,i,k)/aovar%bs(k)
714  atmoptics_ad%Phase_Coefficient(l,i,k) = ( atmoptics_ad%Phase_Coefficient(l,i,k)/aovar%bs(k) )
715  END DO
716  END DO
717 
718  atmoptics_ad%Single_Scatter_Albedo(k) = atmoptics_ad%Single_Scatter_Albedo(k) + &
719  w_ad / aovar%Optical_Depth(k)
720  atmoptics_ad%Optical_Depth(k) = atmoptics_ad%Optical_Depth(k) - &
721  w_ad*aovar%w(k) / aovar%Optical_Depth(k)
722 
723  END IF significant_scattering
724 
725  END DO layer_loop
726 
727  END SUBROUTINE crtm_combine_atmoptics_ad
728 
729 END MODULE crtm_atmoptics
subroutine, public crtm_compute_transmittance(atmoptics, transmittance)
integer, parameter, public failure
subroutine, public crtm_compute_transmittance_tl(atmoptics, atmoptics_TL, transmittance_TL)
real(fp), parameter, public zero
subroutine, public crtm_combine_atmoptics(AtmOptics, AOvar)
elemental subroutine, public aovar_destroy(self)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
real(fp), parameter, public scattering_albedo_threshold
subroutine, public crtm_combine_atmoptics_ad(AtmOptics, AtmOptics_AD, AOvar)
pure logical function, public crtm_include_scattering(atmoptics)
elemental logical function, public aovar_associated(self)
pure logical function, public crtm_no_scattering(atmoptics)
real(fp), parameter, public bs_threshold
real(fp), parameter, public one
character(*), parameter module_version_id
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
subroutine, public crtm_compute_transmittance_ad(atmoptics, transmittance_AD, atmoptics_AD)
integer, parameter, public max_n_layers
real(fp), parameter, public point_5
elemental subroutine, public aovar_create(self, n_Layers)
integer, parameter, public success
integer, parameter, public information
subroutine, public crtm_combine_atmoptics_tl(AtmOptics, AtmOptics_TL, AOvar)