FV3 Bundle
ODAS_AtmAbsorption.f90
Go to the documentation of this file.
1 !
2 ! ODAS_AtmAbsorption
3 !
4 ! Module containing routines to compute the optical depth profile
5 ! due to gaseous absorption for the Optical Depth Absorber Space (ODAS)
6 ! model.
7 !
8 !
9 ! CREATION HISTORY:
10 ! Written by: Paul van Delst, 13-May-2004
11 ! paul.vandelst@noaa.gov
12 !
13 ! Modifed by: Yong Han, 25-June-2008
14 ! yong.han@noaa.gov
15 !
16 
18 
19  ! -----------------
20  ! Environment setup
21  ! -----------------
22  ! Module use
23  USE type_kinds, ONLY: fp
25  USE crtm_parameters, ONLY: zero, &
26  max_n_layers, &
27  limit_exp, &
28  limit_log
33  USE odas_predictor, ONLY: max_n_absorbers, &
34  max_n_orders, &
37  USE odas_taucoeff, ONLY: tc, &
38  odas_taucoeff_type
39 
40  ! Disable implicit typing
41  IMPLICIT NONE
42 
43 
44  ! ------------
45  ! Visibilities
46  ! ------------
47  ! Everything private by default
48  PRIVATE
49  ! Science routines in this modules
53  ! Internal variable structure
54  PUBLIC :: ivar_type
55 
56  ! -----------------
57  ! Module parameters
58  ! -----------------
59  CHARACTER(*), PARAMETER :: module_version_id = &
60  '$Id: ODAS_AtmAbsorption.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
61 
62 
63  ! ------------------------------------------
64  ! Structure definition to hold forward model
65  ! variables across FWD, TL, and AD calls
66  ! ------------------------------------------
67  TYPE :: ivar_type
68  PRIVATE
69  REAL(fp), DIMENSION(MAX_N_LAYERS, & 0:MAX_N_PREDICTORS_USED, & MAX_N_ABSORBERS) :: b
70  REAL(fp), DIMENSION(MAX_N_LAYERS,MAX_N_ABSORBERS) :: ln_chi
71  REAL(fp), DIMENSION(MAX_N_LAYERS,MAX_N_ABSORBERS) :: chi
72  END TYPE ivar_type
73 
74 CONTAINS
75 
76 
77 !################################################################################
78 !################################################################################
79 !## ##
80 !## ## PUBLIC MODULE ROUTINES ## ##
81 !## ##
82 !################################################################################
83 !################################################################################
84 
85 !------------------------------------------------------------------------------
86 !:sdoc+:
87 !
88 ! NAME:
89 ! ODAS_Compute_AtmAbsorption
90 !
91 ! PURPOSE:
92 ! Subroutine to calculate the layer optical depths due to gaseous
93 ! absorption for a given sensor and channel and atmospheric profile
94 ! using the Optical Depth in Absorber Space (ODAS) algorithm).
95 !
96 ! CALLING SEQUENCE:
97 ! CALL ODAS_Compute_AtmAbsorption( TC , &
98 ! ChannelIndex, &
99 ! Predictor , &
100 ! AtmOptics , &
101 ! iVar )
102 !
103 ! INPUTS:
104 ! TC: Structure containing ODAS model coefficient data
105 ! for a sensor.
106 ! UNITS: N/A
107 ! TYPE: ODAS_TauCoeff_type
108 ! DIMENSION: Scalar
109 ! ATTRIBUTES: INTENT(IN OUT)
110 !
111 ! ChannelIndex: Channel index id. This is a unique index associated
112 ! with a (supported) sensor channel used to access the
113 ! shared coefficient data for a particular sensor's
114 ! channel.
115 ! See the SensorIndex argument.
116 ! UNITS: N/A
117 ! TYPE: INTEGER
118 ! DIMENSION: Scalar
119 ! ATTRIBUTES: INTENT(IN)
120 !
121 ! Predictor: Structure containing the ODAS model integrated
122 ! absorber and predictor profile data.
123 ! UNITS: N/A
124 ! TYPE: ODAS_Predictor_type
125 ! DIMENSION: Scalar
126 ! ATTRIBUTES: INTENT(IN)
127 !
128 ! OUTPUTS:
129 ! AtmOptics: Structure containing computed optical depth
130 ! profile data.
131 ! UNITS: N/A
132 ! TYPE: CRTM_AtmOptics_type
133 ! DIMENSION: Scalar
134 ! ATTRIBUTES: INTENT(IN OUT)
135 !
136 ! iVar: Structure containing internal variables required for
137 ! subsequent tangent-linear or adjoint model calls.
138 ! The contents of this structure are NOT accessible
139 ! outside of this module.
140 ! UNITS: N/A
141 ! TYPE: iVar_type
142 ! DIMENSION: Scalar
143 ! ATTRIBUTES: INTENT(IN OUT)
144 !
145 ! COMMENTS:
146 ! Note the INTENT on the output structure arguments are IN OUT to prevent
147 ! reinitialisation upon entry.
148 !
149 !:sdoc-:
150 !------------------------------------------------------------------------------
151 
152  SUBROUTINE odas_compute_atmabsorption( &
153  TC , & ! Input
154  ChannelIndex, & ! Input
155  Predictor , & ! Input
156  AtmOptics , & ! Output
157  iVar ) ! Internal variable output
158  ! Arguments
159  TYPE(odas_taucoeff_type) , INTENT(IN) :: tc
160  INTEGER , INTENT(IN) :: channelindex
161  TYPE(odas_predictor_type), INTENT(IN) :: predictor
162  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics
163  TYPE(ivar_type) , INTENT(IN OUT) :: ivar
164  ! Local variables
165  INTEGER :: l ! Channel index
166  INTEGER :: k ! Layer index
167  INTEGER :: j ! Absorber index
168  INTEGER :: i, ip ! Predictor index
169  INTEGER :: np ! # of predictors
170  INTEGER :: ps ! starting position of the coefficient subset for given j and l
171  INTEGER :: n_orders ! order of the polynomial function
172  INTEGER :: ic_0 ! the index of the first coefficient in the C coeff subset for deriving the B coeff.
173  INTEGER :: ic ! the index of the coefficients
174  REAL(fp) :: c ! a coefficient
175  INTEGER :: n_layers
176 
177 
178  ! Set up
179  ! ...Assign the indices to a short name
180  l = channelindex
181  n_layers = predictor%n_Layers
182  ! ...Initilise the optical depth
183  atmoptics%Optical_Depth = zero !! *** DOES THIS MAKE ROUTINE ORDER DEPENDENT? ***
184 
185 
186  ! Loop over each absorber for optical depth calculation
187  absorber_loop: DO j = 1, predictor%n_Absorbers
188 
189 
190  ! Check if there is any absorption for this
191  ! absorber/channel combination.
192  np = tc%Pre_Index(0,j,l)
193  IF ( np < 0 ) cycle absorber_loop
194 
195 
196  ! Compute the coefficients for use with the atmospheric predictors
197  !
198  ! For every atmospheric predictor, Pred(i), the coefficient
199  ! associated with it, b(i), at a particular absorber amount
200  ! level, k, is given by an N'th order polynomial,
201  !
202  ! __ N
203  ! \ np
204  ! b(i) = > c(np,i).k
205  ! /__
206  ! np=0
207  !
208  ps = tc%Pos_Index(j,l) ! starting position of the coefficient subset for given j and l
209  n_orders = tc%Order(j,l)
210  ! ...Compute b(0)
211  ic_0 = ps
212  ivar%b(1:n_layers,0,j) = tc%C(ic_0)
213  DO ic = 1, n_orders
214  c = tc%C(ic_0 + ic)
215  DO k = 1, n_layers
216  ivar%b(k,0,j) = ivar%b(k,0,j) + (c * predictor%Ap(k, ic, j))
217  END DO
218  END DO
219 
220 
221  ! compute b(i) coefficients (i > 0)
222  ! Compute the logarithm of the absorption coefficient
223  !
224  ! The logarithm of the absorption coefficient, LN(chi), is
225  ! determined from the regression equation,
226  !
227  ! __Iuse
228  ! \
229  ! LN(chi) = b(0) + > b(i).X(i)
230  ! /__
231  ! i=1
232  !
233  ! ...The b(0) contribution
234  ivar%LN_Chi(1:n_layers, j) = ivar%b(1:n_layers,0,j)
235  DO i = 1, np
236  ! ...b(i) term, i > 0
237  ic_0 = ps + i*(n_orders+1)
238  ivar%b(1:n_layers,i,j) = tc%C(ic_0)
239  DO ic = 1, n_orders
240  c = tc%C(ic_0 + ic)
241  DO k = 1, n_layers
242  ivar%b(k,i,j) = ivar%b(k,i,j) + (c * predictor%Ap(k, ic, j))
243  END DO
244  END DO
245  ! ...b(i) term contribution
246  ip = tc%Pre_Index(i,j,l)
247  DO k = 1, n_layers
248  ivar%LN_Chi(k,j) = ivar%LN_Chi(k,j) + (ivar%b(k, i, j) * predictor%X(k,ip))
249  END DO
250  END DO
251 
252 
253  ! Compute the optical depth profile
254  DO k = 1, n_layers
255  ! ...Compute the absorption coefficient
256  IF( ivar%LN_Chi(k,j) > limit_exp ) THEN
257  ivar%Chi(k,j) = limit_log
258  ELSE IF( ivar%LN_Chi(k,j) < -limit_exp ) THEN
259  ivar%Chi(k,j) = zero
260  ELSE
261  ivar%Chi(k,j) = exp(ivar%LN_Chi(k,j))
262  ENDIF
263 
264  atmoptics%Optical_Depth(k) = atmoptics%Optical_Depth(k) + (ivar%Chi(k,j) * predictor%dA(k,j))
265  END DO
266 
267  END DO absorber_loop
268 
269 
270  ! Scale the optical depth to nadir
271  atmoptics%Optical_Depth = atmoptics%Optical_Depth / predictor%Secant_Sensor_Zenith
272 
273  END SUBROUTINE odas_compute_atmabsorption
274 
275 
276 !------------------------------------------------------------------------------
277 !:sdoc+:
278 !
279 ! NAME:
280 ! ODAS_Compute_AtmAbsorption_TL
281 !
282 ! PURPOSE:
283 ! Subroutine to calculate the tangent-linear layer optical depths due
284 ! to gaseous absorption for a given sensor and channel and atmospheric
285 ! profile using the Optical Depth in Absorber Space (ODAS) algorithm).
286 !
287 ! CALLING SEQUENCE:
288 ! CALL ODAS_Compute_AtmAbsorption_TL( TC , &
289 ! ChannelIndex, &
290 ! Predictor , &
291 ! Predictor_TL, &
292 ! AtmOptics_TL, &
293 ! iVar )
294 !
295 ! INPUTS:
296 ! TC: Structure containing ODAS model coefficient data
297 ! for a sensor.
298 ! UNITS: N/A
299 ! TYPE: ODAS_TauCoeff_type
300 ! DIMENSION: Scalar
301 ! ATTRIBUTES: INTENT(IN)
302 !
303 ! ChannelIndex: Channel index id. This is a unique index associated
304 ! with a (supported) sensor channel used to access the
305 ! shared coefficient data for a particular sensor's
306 ! channel.
307 ! See the SensorIndex argument.
308 ! UNITS: N/A
309 ! TYPE: INTEGER
310 ! DIMENSION: Scalar
311 ! ATTRIBUTES: INTENT(IN)
312 !
313 ! Predictor: Structure containing the ODAS model integrated
314 ! absorber and predictor profile data.
315 ! UNITS: N/A
316 ! TYPE: ODAS_Predictor_type
317 ! DIMENSION: Scalar
318 ! ATTRIBUTES: INTENT(IN)
319 !
320 ! Predictor_TL: Structure containing the ODAS model tangent-linear
321 ! integrated absorber and predictor profile data.
322 ! UNITS: N/A
323 ! TYPE: ODAS_Predictor_type
324 ! DIMENSION: Scalar
325 ! ATTRIBUTES: INTENT(IN)
326 !
327 ! iVar: Structure containing internal variables required for
328 ! subsequent tangent-linear or adjoint model calls.
329 ! The contents of this structure are NOT accessible
330 ! outside of this module.
331 ! UNITS: N/A
332 ! TYPE: iVar_type
333 ! DIMENSION: Scalar
334 ! ATTRIBUTES: INTENT(IN)
335 !
336 ! OUTPUTS:
337 ! AtmOptics_TL: Structure containing the computed tangent-linear
338 ! optical depth profile data.
339 ! UNITS: N/A
340 ! TYPE: CRTM_AtmOptics_type
341 ! DIMENSION: Scalar
342 ! ATTRIBUTES: INTENT(IN OUT)
343 !
344 ! Note the INTENT on the output structure arguments are IN OUT to prevent
345 ! reinitialisation upon entry.
346 !
347 !:sdoc-:
348 !------------------------------------------------------------------------------
349 
350  SUBROUTINE odas_compute_atmabsorption_tl( &
351  TC , & ! Input
352  ChannelIndex, & ! Input
353  Predictor , & ! FWD Input
354  Predictor_TL, & ! TL Input
355  AtmOptics_TL, & ! TL Output
356  iVar ) ! Internal variable input
357  ! Arguments
358  TYPE(odas_taucoeff_type) , INTENT(IN) :: tc
359  INTEGER , INTENT(IN) :: channelindex
360  TYPE(odas_predictor_type), INTENT(IN) :: predictor
361  TYPE(odas_predictor_type), INTENT(IN) :: predictor_tl
362  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics_tl
363  TYPE(ivar_type) , INTENT(IN) :: ivar
364  ! Local variables
365  INTEGER :: l ! Channel index
366  INTEGER :: k ! Layer index
367  INTEGER :: j ! Absorber index
368  INTEGER :: i, ip ! Predictor index
369  INTEGER :: np ! # of predictors
370  INTEGER :: ps ! starting position of the coefficient subset for given j and l
371  INTEGER :: n_orders ! order of the polynomial function
372  INTEGER :: ic_0 ! the index of the first coefficient in the b coeff subset for deriving the b coeff.
373  INTEGER :: ic ! the index of the coefficients
374  REAL(fp) :: c ! a coefficient
375  REAL(fp) :: b_tl(predictor%n_layers)
376  REAL(fp) :: ln_chi_tl(predictor%n_layers)
377  REAL(fp) :: chi_tl
378  INTEGER :: n_layers
379 
380  ! Set up
381  ! ...Assign the indices to a short name
382  l = channelindex
383  n_layers = predictor%n_Layers
384  ! ...Initilise the tangent-linear optical depth
385  atmoptics_tl%Optical_Depth = zero
386 
387 
388  ! Loop over each absorber for optical depth calculation
389  absorber_loop: DO j = 1, predictor%n_Absorbers
390 
391 
392  ! Check if there is any absorption for this
393  ! absorber/channel combination.
394  np = tc%Pre_Index(0,j,l)
395  IF ( np < 0 ) cycle absorber_loop
396 
397 
398  ! Compute the coefficients for use with the atmospheric predictors
399  !
400  ! For every atmospheric predictor, Pred(i), the coefficient
401  ! associated with it, b(i), at a particular absorber amount
402  ! level, k, is given by an N'th order polynomial,
403  !
404  ! __ N
405  ! \ np
406  ! b(i) = > c(np,i).k
407  ! /__
408  ! np=0
409  !
410  ps = tc%Pos_Index(j,l) ! starting position of the coefficient subset f or given j and l
411  n_orders = tc%Order(j,l)
412  ! ...Compute b_TL(0)
413  ic_0 = ps
414  b_tl(1:n_layers) = zero
415  DO ic = 1, n_orders
416  c = tc%C(ic_0 + ic)
417  DO k = 1, n_layers
418  b_tl(k) = b_tl(k) + (c * predictor_tl%Ap(k, ic, j))
419  END DO
420  END DO
421 
422 
423  ! Compute the logarithm of the absorption coefficient
424  !
425  ! The logarithm of the absorption coefficient, LN(chi), is
426  ! determined from the regression equation,
427  !
428  ! __Iuse
429  ! \
430  ! LN(chi) = b(0) + > b(i).X(i)
431  ! /__
432  ! i=1
433  !
434  ! ...b_TL(0) term contribution
435  ln_chi_tl(1:n_layers) = b_tl(1:n_layers)
436  DO i = 1, np
437  ! ...b_TL(i) term, i > 0
438  ic_0 = ps + i*(n_orders+1)
439  b_tl(1:n_layers) = zero
440  DO ic = 1, n_orders
441  c = tc%C(ic_0 + ic)
442  DO k = 1, n_layers
443  b_tl(k) = b_tl(k) + (c * predictor_tl%Ap(k, ic, j))
444  END DO
445  END DO
446  ! b_TL(i) term contribution
447  ip = tc%Pre_Index(i,j,l)
448  DO k = 1, n_layers
449  ln_chi_tl(k) = ln_chi_tl(k) + (b_tl(k) * predictor%X(k,ip)) &
450  + (ivar%b(k,i,j) * predictor_tl%X(k,ip))
451  END DO
452  END DO
453 
454 
455  ! Compute the tangent-linear optical depth profile
456  DO k = 1, n_layers
457  ! ...Compute the tangent-linear absorption coefficient
458  IF( ivar%LN_Chi(k,j) > limit_exp ) THEN
459  chi_tl = zero
460  ELSE IF( ivar%LN_Chi(k,j) < -limit_exp ) THEN
461  chi_tl = zero
462  ELSE
463  chi_tl = ivar%Chi(k,j) * ln_chi_tl(k)
464  ENDIF
465 
466  atmoptics_tl%Optical_Depth(k) = atmoptics_tl%Optical_Depth(k) &
467  + (chi_tl * predictor%dA(k,j)) &
468  + (ivar%Chi(k,j) * predictor_tl%dA(k,j))
469  END DO
470 
471  END DO absorber_loop
472 
473 
474  ! Scale the tangent-linear optical depth to nadir
475  atmoptics_tl%Optical_Depth = atmoptics_tl%Optical_Depth / &
476  predictor%Secant_Sensor_Zenith
477 
478  END SUBROUTINE odas_compute_atmabsorption_tl
479 
480 
481 !--------------------------------------------------------------------------------
482 !:sdoc+:
483 !
484 ! NAME:
485 ! ODAS_Compute_AtmAbsorption_AD
486 !
487 ! PURPOSE:
488 ! Subroutine to calculate the adjoint of the layer optical depths due
489 ! to gaseous absorption for a given sensor and channel and atmospheric
490 ! profile using the Optical Depth in Absorber Space (ODAS) algorithm).
491 !
492 ! CALLING SEQUENCE:
493 ! CALL ODAS_Compute_AtmAbsorption_AD( TC , &
494 ! ChannelIndex, &
495 ! Predictor , &
496 ! AtmOptics_AD, &
497 ! Predictor_AD, &
498 ! iVar )
499 !
500 ! INPUTS:
501 ! TC: Structure containing ODAS model coefficient data
502 ! for a sensor.
503 ! UNITS: N/A
504 ! TYPE: ODAS_TauCoeff_type
505 ! DIMENSION: Scalar
506 ! ATTRIBUTES: INTENT(IN)
507 !
508 ! ChannelIndex: Channel index id. This is a unique index associated
509 ! with a (supported) sensor channel used to access the
510 ! shared coefficient data for a particular sensor's
511 ! channel.
512 ! UNITS: N/A
513 ! TYPE: INTEGER
514 ! DIMENSION: Scalar
515 ! ATTRIBUTES: INTENT(IN)
516 !
517 ! Predictor: Structure containing the ODAS model integrated
518 ! absorber and predictor profile data.
519 ! UNITS: N/A
520 ! TYPE: ODAS_Predictor_type
521 ! DIMENSION: Scalar
522 ! ATTRIBUTES: INTENT(IN)
523 !
524 ! AtmOptics_AD: Structure containing the adjoint optical depth
525 ! profile data.
526 ! *** NOTE: Optical depth component set to zero on output. ***
527 ! UNITS: N/A
528 ! TYPE: CRTM_AtmOptics_type
529 ! DIMENSION: Scalar
530 ! ATTRIBUTES: INTENT(IN OUT)
531 !
532 ! iVar: Structure containing internal variables required for
533 ! subsequent tangent-linear or adjoint model calls.
534 ! The contents of this structure are NOT accessible
535 ! outside of this module.
536 ! UNITS: N/A
537 ! TYPE: iVar_type
538 ! DIMENSION: Scalar
539 ! ATTRIBUTES: INTENT(IN)
540 !
541 ! OUTPUTS:
542 ! Predictor_AD: Structure containing the ODAS model adjoint
543 ! integrated absorber and predictor profile data.
544 ! *** NOTE: Must contain a value upon input. ***
545 ! UNITS: N/A
546 ! TYPE: ODAS_Predictor_type
547 ! DIMENSION: Scalar
548 ! ATTRIBUTES: INTENT(IN OUT)
549 !
550 ! SIDE EFFECTS:
551 ! Components of the AtmOptics_AD structure argument are modified
552 ! in this function.
553 !
554 !:sdoc-:
555 !------------------------------------------------------------------------------
556 
557  SUBROUTINE odas_compute_atmabsorption_ad( &
558  TC , & ! Input
559  ChannelIndex, & ! Input
560  Predictor , & ! FWD Input
561  AtmOptics_AD, & ! AD Input
562  Predictor_AD, & ! AD Output
563  iVar ) ! Internal variable input
564  ! Arguments
565  TYPE(odas_taucoeff_type) , INTENT(IN) :: tc
566  INTEGER , INTENT(IN) :: channelindex
567  TYPE(odas_predictor_type), INTENT(IN) :: predictor
568  TYPE(crtm_atmoptics_type), INTENT(IN OUT) :: atmoptics_ad
569  TYPE(odas_predictor_type), INTENT(IN OUT) :: predictor_ad
570  TYPE(ivar_type) , INTENT(IN) :: ivar
571  ! Local variables
572  INTEGER :: l ! Channel index
573  INTEGER :: k ! Layer index
574  INTEGER :: j ! Absorber index
575  INTEGER :: i, ip ! Predictor index
576  INTEGER :: np ! # of predictors
577  INTEGER :: ps ! starting position of the coefficient subset for given j and l
578  INTEGER :: n_orders ! order of the polynomial function
579  INTEGER :: ic_0 ! the index of the first coefficient in the b coeff subset for deriving the b coeff.
580  INTEGER :: ic ! the index of the coefficients
581  REAL(fp) :: c ! a coefficient
582  REAL(fp) :: b_ad(predictor%n_layers)
583  REAL(fp) :: ln_chi_ad(predictor%n_layers)
584  REAL(fp) :: chi_ad
585  INTEGER :: n_layers
586 
587 
588  ! Set up
589  ! ...Assign the indices to a short name
590  l = channelindex
591  n_layers = predictor%n_Layers
592  ! ...Initialise local adjoint variables
593  b_ad = zero
594  ln_chi_ad = zero
595  chi_ad = zero
596 
597 
598  ! Compute adjoint nadir optical depth profile
599  atmoptics_ad%Optical_Depth = atmoptics_ad%Optical_Depth / &
600  predictor%Secant_Sensor_Zenith
601 
602 
603  ! Loop over each absorber for optical depth calculation
604  absorber_loop: DO j = 1, predictor%n_Absorbers
605 
606 
607  ! Check if there is any absorption for this
608  ! absorber/channel combination.
609  np = tc%Pre_Index(0,j,l)
610  IF ( np < 0 ) cycle absorber_loop
611 
612  ! Starting position of the coefficient subset for given absorber (j) and channels(l)
613  ps = tc%Pos_Index(j,l)
614  n_orders = tc%Order(j,l)
615 
616 
617  ! Compute the adjoint of the optical depth profile
618  DO k = n_layers, 1, -1
619  predictor_ad%dA(k,j) = predictor_ad%dA(k,j) + &
620  (ivar%Chi(k,j) * atmoptics_ad%Optical_Depth(k))
621  chi_ad = chi_ad + (predictor%dA(k,j) * atmoptics_ad%Optical_Depth(k))
622 
623 
624  ! ...Compute the adjoint of the absorption coefficient
625  IF( ivar%LN_Chi(k,j) > limit_exp ) THEN
626  chi_ad = zero
627  ELSE IF( ivar%LN_Chi(k,j) < -limit_exp ) THEN
628  chi_ad = zero
629  ELSE
630  ln_chi_ad(k) = ln_chi_ad(k) + ivar%Chi(k,j) * chi_ad
631  chi_ad = zero
632  ENDIF
633  END DO
634 
635 
636  ! Compute the adjoint of the logarithm of the absorption coefficient
637  DO i = np, 1, -1
638  ! ...b(i) term contribution
639  ip = tc%Pre_Index(i,j,l)
640  DO k = n_layers, 1, -1
641  b_ad(k) = b_ad(k) + (ln_chi_ad(k) * predictor%X(k,ip))
642  predictor_ad%X(k,ip) = predictor_ad%X(k,ip) + (ivar%b(k,i,j) * ln_chi_ad(k))
643  END DO
644  ! ...b(i) term, i > 0
645  ic_0 = ps + i*(n_orders+1)
646  DO ic = n_orders, 1, -1
647  c = tc%C(ic_0 + ic)
648  DO k = n_layers, 1, -1
649  predictor_ad%Ap(k, ic, j) = predictor_ad%Ap(k, ic, j) + (c * b_ad(k))
650  END DO
651  END DO
652  b_ad(1:n_layers) = zero
653  END DO
654  b_ad(1:n_layers) = b_ad(1:n_layers) + ln_chi_ad(1:n_layers)
655  ln_chi_ad(1:n_layers) = zero
656 
657 
658  ! Compute the adjoint of the b(i) coefficients
659  ic_0 = ps
660  DO ic = n_orders, 1, -1
661  c = tc%C(ic_0 + ic)
662  DO k = n_layers, 1, -1
663  predictor_ad%Ap(k, ic, j) = predictor_ad%Ap(k, ic, j) + (c * b_ad(k))
664  END DO
665  END DO
666  b_ad(1:n_layers) = zero
667 
668  END DO absorber_loop
669 
670 
671  ! No more impact of optical depth on derivatives
672  atmoptics_ad%Optical_Depth = zero
673 
674  END SUBROUTINE odas_compute_atmabsorption_ad
675 
676 END MODULE odas_atmabsorption
677 
integer, parameter, public failure
real(fp), parameter, public zero
integer, parameter, public warning
integer, parameter, public fp
Definition: Type_Kinds.f90:124
subroutine, public odas_compute_atmabsorption_ad(TC, ChannelIndex, Predictor, AtmOptics_AD, Predictor_AD, iVar)
integer, parameter, public max_n_absorbers
real(fp), parameter, public limit_exp
real(fp), parameter, public limit_log
character(*), parameter module_version_id
subroutine, public odas_compute_atmabsorption_tl(TC, ChannelIndex, Predictor, Predictor_TL, AtmOptics_TL, iVar)
integer, parameter, public max_n_orders
integer, parameter, public max_n_predictors_used
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer, parameter, public max_n_layers
subroutine, public odas_compute_atmabsorption(TC, ChannelIndex, Predictor, AtmOptics, iVar)
type(odas_taucoeff_type), dimension(:), allocatable, target, save, public tc
integer, parameter, public success