FV3 Bundle
CRTM_Atmosphere.f90
Go to the documentation of this file.
1 !
2 ! CRTM_Atmosphere
3 !
4 ! Module for adding layers to the CRTM atmosphere structure as required.
5 !
6 !
7 ! CREATION HISTORY:
8 ! Written by: Paul van Delst, 29-Oct-2007
9 ! paul.vandelst@noaa.gov
10 !
11 
13 
14  ! -----------------
15  ! Environment setup
16  ! -----------------
17  ! Module use
18  USE type_kinds , ONLY: fp
20  USE crtm_parameters , ONLY: zero, one, point_5, set, &
21  toa_pressure , &
24  OPERATOR(==), &
25  OPERATOR(+), &
32  ! ...Internal variable definition module
33  USE iatm_define, ONLY: iatm_type , &
35  iatm_create , &
37 
38  ! Disable implicit typing
39  IMPLICIT NONE
40 
41 
42  ! ------------
43  ! Visibilities
44  ! ------------
45  ! Everything private by default
46  PRIVATE
47  ! Module procedures
51  ! iAtm entities
52  ! ...Structure
53  PUBLIC :: iatm_type
54  ! ...Procedures
55  PUBLIC :: iatm_associated
56  PUBLIC :: iatm_create
57  PUBLIC :: iatm_destroy
58 
59 
60  ! -----------------
61  ! Module parameters
62  ! -----------------
63  ! RCS Id for the module
64  CHARACTER(*), PARAMETER :: module_rcs_id = &
65  '$Id: CRTM_Atmosphere.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
66  ! Message string length
67  INTEGER, PARAMETER :: ml = 256
68 
69 
70 CONTAINS
71 
72 
73 !################################################################################
74 !################################################################################
75 !## ##
76 !## ## PUBLIC MODULE ROUTINES ## ##
77 !## ##
78 !################################################################################
79 !################################################################################
80 
81 !--------------------------------------------------------------------------------
82 !:sdoc+:
83 !
84 ! NAME:
85 ! CRTM_Atmosphere_AddLayers
86 !
87 ! PURPOSE:
88 ! Function to copy an atmosphere structure and adding extra layers from
89 ! climatology as required to supplement the upper atmosphere profile data.
90 !
91 ! CALLING SEQUENCE:
92 ! Error_Status = CRTM_Atmosphere_AddLayers( Atm_In , & ! Input
93 ! Atm_Out ) ! Output
94 !
95 ! INPUTS:
96 ! Atm_In: Atmosphere structure that is to be supplemented
97 ! or copied.
98 ! UNITS: N/A
99 ! TYPE: CRTM_Atmosphere_type
100 ! DIMENSION: Scalar
101 ! ATTRIBUTES: INTENT(IN)
102 !
103 ! OUTPUTS:
104 ! Atm_Out: Copy of the input atmosphere structure with extra upper
105 ! atmosphere layers added as required.
106 ! UNITS: N/A
107 ! TYPE: CRTM_Atmosphere_type
108 ! DIMENSION: Scalar
109 ! ATTRIBUTES: INTENT(IN OUT)
110 !
111 ! FUNCTION RESULT:
112 ! Error_Status: The return value is an integer defining the error status.
113 ! The error codes are defined in the Message_Handler module.
114 ! If == SUCCESS the operation was successful
115 ! == FAILURE an error occurred
116 ! UNITS: N/A
117 ! TYPE: INTEGER
118 ! DIMENSION: Scalar
119 !
120 !:sdoc-:
121 !--------------------------------------------------------------------------------
122 
123  FUNCTION crtm_atmosphere_addlayers( &
124  Atm_In , & ! Input
125  Atm_Out) & ! Output
126  result( err_stat )
127  ! Arguments
128  TYPE(crtm_atmosphere_type), INTENT(IN) :: atm_in
129  TYPE(crtm_atmosphere_type), INTENT(IN OUT) :: atm_out
130  ! Function result
131  INTEGER :: err_stat
132  ! Local parameters
133  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Atmosphere_AddLayers'
134  ! Local variables
135  CHARACTER(ML) :: msg
136  INTEGER :: i, j, k, n
137  TYPE(iatm_type) :: iatm
138 
139 
140  ! Set up
141  err_stat = success
142 
143 
144  ! If extra layers are NOT needed,
145  ! then simply copy the structure
146  IF ( atm_in%Level_Pressure(0) <= toa_pressure) THEN
147  atm_out = atm_in
148  IF ( .NOT. crtm_atmosphere_associated( atm_out ) ) THEN
149  err_stat = failure
150  msg = 'Error assigning Atmosphere structure with NO extra layers'
151  CALL display_message( routine_name, msg, err_stat )
152  END IF
153  RETURN
154  END IF
155 
156 
157  ! Determine the number of extra layers required
158  n = extra_layers( atm_in )
159  IF ( n < 1 ) THEN
160  err_stat = failure
161  msg = 'Error determining extra layer count'
162  CALL display_message( routine_name, msg, err_stat )
163  RETURN
164  END IF
165 
166 
167  ! Allocate the internal variable structure
168  CALL iatm_create( iatm, n, atm_in%n_Absorbers )
169  IF ( .NOT. iatm_associated( iatm ) ) THEN
170  err_stat = failure
171  msg = 'Error allocating iAtm internal structure'
172  CALL display_message( routine_name, msg, err_stat )
173  RETURN
174  END IF
175 
176 
177  ! Get the extra layer profiles
178  CALL crtm_get_model_profile( atm_in%Absorber_Id, &
179  iatm%pl, iatm%tl, iatm%al, &
180  model=atm_in%Climatology )
181 
182 
183  ! First interpolate the extra levels to the user top pressure
184  ! replacing the model data at that array index
185  CALL interp_lpoly( atm_in%Level_Pressure(0), iatm%pl(n-1:n), iatm%ilpoly )
186  iatm%plint_save = atm_in%Level_Pressure(0)
187  iatm%pln_save = iatm%pl(n)
188  iatm%pl(n) = iatm%plint_save
189  CALL interp_linear( iatm%ilpoly, iatm%tl(n-1:n), iatm%tlint_save )
190  iatm%tln_save = iatm%tl(n)
191  iatm%tl(n) = iatm%tlint_save
192  DO j = 1, atm_in%n_Absorbers
193  CALL interp_linear( iatm%ilpoly, iatm%al(n-1:n,j), iatm%alint_save(j) )
194  iatm%aln_save(j) = iatm%al(n,j)
195  iatm%al(n,j) = iatm%alint_save(j)
196  END DO
197 
198  ! Now compute the model profile layer averages
199  DO k = 1, n
200  CALL layer_p(iatm%pl(k-1:k), iatm%p(k))
201  CALL layer_x(iatm%tl(k-1:k), iatm%t(k))
202  END DO
203  DO j = 1, atm_in%n_Absorbers
204  DO k = 1, n
205  CALL layer_x(iatm%al(k-1:k,j), iatm%a(k,j))
206  END DO
207  END DO
208 
209 
210  ! Now, extrapolate user layer profile to get the "layer 0" value and
211  ! use it to shift the model profile to avoid a discontinuity at p(n)
212  CALL interp_lpoly( iatm%p(n), atm_in%Pressure(1:2), iatm%elpoly )
213  CALL shift_profile( iatm%elpoly, atm_in%Temperature(1:2), iatm%t )
214  DO j = 1, atm_in%n_Absorbers
215  CALL shift_profile( iatm%elpoly, atm_in%Absorber(1:2,j), iatm%a(:,j) )
216  END DO
217 
218 
219  ! Make sure the absorber amounts are not negative.
220  ! (Is a further, more physical, check needed here?)
221  iatm%a_save = iatm%a
222  WHERE (iatm%a_save < zero) iatm%a = minimum_absorber_amount
223 
224 
225  ! Copy over the atmosphere structure with extra layers
226  atm_out = crtm_atmosphere_addlayercopy( atm_in, n )
227  IF ( .NOT. crtm_atmosphere_associated( atm_out ) ) THEN
228  err_stat = failure
229  msg = 'Error copying Atmosphere structure with extra layers'
230  CALL display_message( routine_name, msg, err_stat )
231  RETURN
232  END IF
233 
234 
235  ! Slot the added layers into the output atmosphere structure
236  ! Note: Cloud and Aerosol assignments not really needed (the
237  ! zeroing is handled by the structure allocation) since
238  ! at TOA, typically, there are not any clouds and/or
239  ! aerosols.
240  ! ...Profile
241  atm_out%Level_Pressure(0:n) = iatm%pl
242  atm_out%Pressure(1:n) = iatm%p
243  atm_out%Temperature(1:n) = iatm%t
244  DO j = 1, atm_out%n_Absorbers
245  atm_out%Absorber(1:n,j) = iatm%a(:,j)
246  END DO
247  ! ...Clouds
248  IF ( atm_in%n_Clouds > 0 ) THEN
249  DO i = 1, atm_in%n_Clouds
250  atm_out%Cloud(i)%Effective_Radius(1:n) = zero
251  atm_out%Cloud(i)%Effective_Variance(1:n) = zero
252  atm_out%Cloud(i)%Water_Content(1:n) = zero
253  END DO
254  END IF
255  ! ...Aerosols
256  IF ( atm_in%n_Aerosols > 0 ) THEN
257  DO i = 1, atm_in%n_Aerosols
258  atm_out%Aerosol(i)%Effective_Radius(1:n) = zero
259  atm_out%Aerosol(i)%Concentration(1:n) = zero
260  END DO
261  END IF
262 
263 
264  ! Clean up
265  CALL iatm_destroy( iatm )
266 
267  END FUNCTION crtm_atmosphere_addlayers
268 
269 
270 !--------------------------------------------------------------------------------
271 !:sdoc+:
272 !
273 ! NAME:
274 ! CRTM_Atmosphere_AddLayers_TL
275 !
276 ! PURPOSE:
277 ! Function to copy a tangent-linear atmosphere structure and add extra
278 ! layers as required to supplement the upper atmosphere profile data.
279 !
280 ! CALLING SEQUENCE:
281 ! Error_Status = CRTM_Atmosphere_AddLayers_TL( Atm_In , & ! FWD Input
282 ! Atm_In_TL , & ! TL Input
283 ! Atm_Out_TL ) ! TL Output
284 !
285 ! INPUTS:
286 ! Atm_In: Forward model atmosphere structure.
287 ! UNITS: N/A
288 ! TYPE: CRTM_Atmosphere_type
289 ! DIMENSION: Scalar
290 ! ATTRIBUTES: INTENT(IN)
291 !
292 ! Atm_In_TL: Tangent-linear model atmosphere structure that is
293 ! to be copied.
294 ! UNITS: N/A
295 ! TYPE: CRTM_Atmosphere_type
296 ! DIMENSION: Scalar
297 ! ATTRIBUTES: INTENT(IN)
298 !
299 ! OUTPUTS:
300 ! Atm_Out_TL: Copy of the input tangent-linear atmosphere structure
301 ! with extra upper atmosphere layers added as required.
302 ! Note that the tangent-linear values of the added layers
303 ! is *always* zero.
304 ! UNITS: N/A
305 ! TYPE: CRTM_Atmosphere_type
306 ! DIMENSION: Scalar
307 ! ATTRIBUTES: INTENT(IN OUT)
308 !
309 ! FUNCTION RESULT:
310 ! Error_Status: The return value is an integer defining the error status.
311 ! The error codes are defined in the Message_Handler module.
312 ! If == SUCCESS the operation was successful
313 ! == FAILURE an error occurred
314 ! UNITS: N/A
315 ! TYPE: INTEGER
316 ! DIMENSION: Scalar
317 !
318 !:sdoc-:
319 !--------------------------------------------------------------------------------
320 
321  FUNCTION crtm_atmosphere_addlayers_tl( &
322  Atm_In , & ! FWD Input
323  Atm_In_TL , & ! TL Input
324  Atm_Out_TL) & ! TL Output
325  result( err_stat )
326  ! Arguments
327  TYPE(crtm_atmosphere_type), INTENT(IN) :: atm_in
328  TYPE(crtm_atmosphere_type), INTENT(IN) :: atm_in_tl
329  TYPE(crtm_atmosphere_type), INTENT(IN OUT) :: atm_out_tl
330  ! Function result
331  INTEGER :: err_stat
332  ! Local parameters
333  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Atmosphere_AddLayers_TL'
334  ! Local variables
335  CHARACTER(ML) :: msg
336  INTEGER :: n
337 
338 
339  ! Set up
340  err_stat = success
341 
342 
343  ! If extra layers are NOT needed,
344  ! then simply copy the structure
345  IF ( atm_in%Level_Pressure(0) <= toa_pressure) THEN
346  atm_out_tl = atm_in_tl
347  IF ( .NOT. crtm_atmosphere_associated( atm_out_tl ) ) THEN
348  err_stat = failure
349  msg = 'Error assigning Atmosphere structure with NO extra layers'
350  CALL display_message( routine_name, msg, err_stat )
351  END IF
352  RETURN
353  END IF
354 
355 
356  ! Determine how many extra layers are needed
357  n = extra_layers( atm_in )
358  IF ( n < 1 ) THEN
359  err_stat = failure
360  msg = 'Error determining extra layer count'
361  CALL display_message( routine_name, msg, err_stat )
362  RETURN
363  END IF
364 
365 
366  ! Copy over the atmosphere structure with extra layers
367  ! (which will be zero by definition)
368  atm_out_tl = crtm_atmosphere_addlayercopy( atm_in_tl, n )
369  IF ( .NOT. crtm_atmosphere_associated( atm_out_tl ) ) THEN
370  err_stat = failure
371  msg = 'Error copying Atmosphere structure with extra layers'
372  CALL display_message( routine_name, msg, err_stat )
373  RETURN
374  END IF
375 
376  END FUNCTION crtm_atmosphere_addlayers_tl
377 
378 
379 !--------------------------------------------------------------------------------
380 !:sdoc+:
381 !
382 ! NAME:
383 ! CRTM_Atmosphere_AddLayers_AD
384 !
385 ! PURPOSE:
386 ! Function to copy back an adjoint atmosphere structure removing added
387 ! extra layers as were required to supplement the upper atmosphere
388 ! profile data.
389 !
390 ! CALLING SEQUENCE:
391 ! Error_Status = CRTM_Atmosphere_AddLayers_AD( Atm_In , & ! FWD Input
392 ! Atm_Out_AD, & ! AD Input
393 ! Atm_In_AD ) ! AD Output
394 !
395 ! INPUTS:
396 ! Atm_In: Forward model atmosphere structure.
397 ! UNITS: N/A
398 ! TYPE: CRTM_Atmosphere_type
399 ! DIMENSION: Scalar
400 ! ATTRIBUTES: INTENT(IN)
401 !
402 ! Atm_Out_AD: Adjoint atmosphere structure that contains the added
403 ! extra layers.
404 ! ** SET TO ZERO ON EXIT **
405 ! UNITS: N/A
406 ! TYPE: CRTM_Atmosphere_type
407 ! DIMENSION: Scalar
408 ! ATTRIBUTES: INTENT(IN OUT)
409 !
410 ! OUTPUTS:
411 ! Atm_In_AD: Adjoint atmosphere structure at the original, user
412 ! specified layering.
413 ! ** MUST HAVE VALUE ON ENTRY **
414 ! UNITS: N/A
415 ! TYPE: CRTM_Atmosphere_type
416 ! DIMENSION: Scalar
417 ! ATTRIBUTES: INTENT(IN OUT)
418 !
419 ! FUNCTION RESULT:
420 ! Error_Status: The return value is an integer defining the error status.
421 ! The error codes are defined in the Message_Handler module.
422 ! If == SUCCESS the operation was successful
423 ! == FAILURE an error occurred
424 ! UNITS: N/A
425 ! TYPE: INTEGER
426 ! DIMENSION: Scalar
427 !
428 !:sdoc-:
429 !--------------------------------------------------------------------------------
430 
431  FUNCTION crtm_atmosphere_addlayers_ad( &
432  Atm_In , & ! FWD Input
433  Atm_Out_AD, & ! AD Input
434  Atm_In_AD ) & ! AD Output
435  result( err_stat )
436  ! Arguments
437  TYPE(crtm_atmosphere_type), INTENT(IN) :: atm_in
438  TYPE(crtm_atmosphere_type), INTENT(IN OUT) :: atm_out_ad
439  TYPE(crtm_atmosphere_type), INTENT(IN OUT) :: atm_in_ad
440  ! Function result
441  INTEGER :: err_stat
442  ! Local parameters
443  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Atmosphere_AddLayers_AD'
444  ! Local variables
445  CHARACTER(ML) :: msg
446  INTEGER :: i, j, n, no, nt
447 
448 
449  ! Set up
450  err_stat = success
451 
452 
453  ! If extra layers are NOT needed, then simply perform
454  ! the adjoint sum. Remember the TL form is
455  ! Atm_Out_TL = Atm_In_TL
456  ! so the adjoint form is
457  ! Atm_In_AD = Atm_In_AD + Atm_Out_AD
458  ! Atm_Out_AD = ZERO
459  IF ( atm_in%Level_Pressure(0) <= toa_pressure) THEN
460  atm_in_ad = atm_in_ad + atm_out_ad
461  CALL crtm_atmosphere_zero( atm_out_ad )
462  RETURN
463  END IF
464 
465 
466  ! Determine how many extra layers have been used
467  n = extra_layers( atm_in )
468  IF ( n < 1 ) THEN
469  err_stat = failure
470  msg = 'Error determining extra layer count'
471  CALL display_message( routine_name, msg, err_stat )
472  RETURN
473  END IF
474 
475 
476  ! Perform the adjoint summations
477  ! This is the adjoint equivalent of the TL Assign_Atmosphere
478  no = atm_in_ad%n_Layers
479  nt = n + no
480  ! ...Aerosols
481  IF ( atm_in_ad%n_Aerosols > 0 ) THEN
482  DO i = 1, atm_in_ad%n_Aerosols
483  atm_in_ad%Aerosol(i)%Concentration(1:no) = atm_in_ad%Aerosol(i)%Concentration(1:no) + &
484  atm_out_ad%Aerosol(i)%Concentration(n+1:nt)
485  atm_in_ad%Aerosol(i)%Effective_Radius(1:no) = atm_in_ad%Aerosol(i)%Effective_Radius(1:no) + &
486  atm_out_ad%Aerosol(i)%Effective_Radius(n+1:nt)
487  atm_in_ad%Aerosol(i)%Type = atm_out_ad%Aerosol(i)%Type
488  END DO
489  END IF
490  ! ...Clouds
491  IF ( atm_in_ad%n_Clouds > 0 ) THEN
492  DO i = 1, atm_in_ad%n_Clouds
493  atm_in_ad%Cloud(i)%Water_Content(1:no) = atm_in_ad%Cloud(i)%Water_Content(1:no) + &
494  atm_out_ad%Cloud(i)%Water_Content(n+1:nt)
495  atm_in_ad%Cloud(i)%Effective_Variance(1:no) = atm_in_ad%Cloud(i)%Effective_Variance(1:no) + &
496  atm_out_ad%Cloud(i)%Effective_Variance(n+1:nt)
497  atm_in_ad%Cloud(i)%Effective_Radius(1:no) = atm_in_ad%Cloud(i)%Effective_Radius(1:no) + &
498  atm_out_ad%Cloud(i)%Effective_Radius(n+1:nt)
499  atm_in_ad%Cloud(i)%Type = atm_out_ad%Cloud(i)%Type
500  END DO
501  END IF
502  ! ...Absorber data
503  DO j = 1, atm_in_ad%n_Absorbers
504  atm_in_ad%Absorber(1:no,j) = atm_in_ad%Absorber(1:no,j) + atm_out_ad%Absorber(n+1:nt,j)
505  END DO
506  ! ...Temperature data
507  atm_in_ad%Temperature(1:no) = atm_in_ad%Temperature(1:no) + atm_out_ad%Temperature(n+1:nt)
508  ! ...Pressure data
509  atm_in_ad%Pressure(1:no) = atm_in_ad%Pressure(1:no) + atm_out_ad%Pressure(n+1:nt)
510  atm_in_ad%Level_Pressure(0:no) = atm_in_ad%Level_Pressure(0:no) + atm_out_ad%Level_Pressure(n:nt)
511 
512 
513  ! Zero the output atmosphere structure
514  CALL crtm_atmosphere_zero( atm_out_ad )
515 
516  END FUNCTION crtm_atmosphere_addlayers_ad
517 
518 !##################################################################################
519 !##################################################################################
520 !## ##
521 !## ## PRIVATE MODULE ROUTINES ## ##
522 !## ##
523 !##################################################################################
524 !##################################################################################
525 
526  ! Subprogram to determine the number of extra layers required
527  FUNCTION extra_layers( Atm ) RESULT( n )
528  TYPE(crtm_atmosphere_type), INTENT(IN) :: atm
529  INTEGER :: n
530  DO n = 1, SIZE(model_level_pressure)
531  IF ( model_level_pressure(n) >= atm%Level_Pressure(0) ) RETURN
532  END DO
533  n = 0
534  END FUNCTION extra_layers
535 
536 
537  ! Subprogram to compute the average layer pressure
538  SUBROUTINE layer_p( p, p_layer )
539  REAL(fp), INTENT(IN) :: p(2) ! Input
540  REAL(fp), INTENT(OUT) :: p_layer ! Output
541  p_layer = (p(2)-p(1))/log(p(2)/p(1))
542  END SUBROUTINE layer_p
543 
544 
545  ! Subprogram to compute the average layer amount of X
546  SUBROUTINE layer_x( x, x_layer )
547  REAL(fp), INTENT(IN) :: x(2)
548  REAL(fp), INTENT(OUT) :: x_layer
549  x_layer = point_5*(x(1)+x(2))
550  END SUBROUTINE layer_x
551 
552 
553  ! Subprogram to compute the interpolating polynomial linear in log(p)
554  SUBROUTINE interp_lpoly( p_int, p, lpoly )
555  REAL(fp), INTENT(IN) :: p_int
556  REAL(fp), INTENT(IN) :: p(2)
557  REAL(fp), INTENT(OUT) :: lpoly
558  lpoly = (log(p_int)-log(p(1))) / (log(p(2))-log(p(1)))
559  END SUBROUTINE interp_lpoly
560 
561 
562  ! Subprogram to perform linear interpolation
563  SUBROUTINE interp_linear( lpoly, x, x_int )
564  REAL(fp), INTENT(IN) :: lpoly
565  REAL(fp), INTENT(IN) :: x(2)
566  REAL(fp), INTENT(OUT) :: x_int
567  x_int = (x(2)-x(1))*lpoly + x(1)
568  END SUBROUTINE interp_linear
569 
570 
571  ! Subprogram to shifted the added profile layers
572  SUBROUTINE shift_profile( lpoly, x_toa, x_shifted )
573  REAL(fp), INTENT(IN) :: lpoly
574  REAL(fp), INTENT(IN) :: x_toa(2)
575  REAL(fp), INTENT(IN OUT) :: x_shifted(:)
576  INTEGER :: n
577  REAL(fp) :: x_int, dx
578  n = SIZE(x_shifted)
579  CALL interp_linear( lpoly, x_toa, x_int )
580  dx = x_int - x_shifted(n)
581  x_shifted = x_shifted + dx
582  END SUBROUTINE shift_profile
583 
584 END MODULE crtm_atmosphere
subroutine layer_p(p, p_layer)
elemental type(crtm_atmosphere_type) function, public crtm_atmosphere_addlayercopy(atm, n_Added_Layers)
integer, parameter, public failure
integer function extra_layers(Atm)
integer, parameter, public set
real(fp), parameter, public zero
integer, parameter, public warning
subroutine interp_lpoly(p_int, p, lpoly)
integer function, public crtm_atmosphere_addlayers_tl(Atm_In, Atm_In_TL, Atm_Out_TL)
elemental logical function, public iatm_associated(self)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
elemental subroutine, public iatm_create(self, n_Layers, n_Absorbers)
subroutine interp_linear(lpoly, x, x_int)
real(fp), parameter, public toa_pressure
real(fp), parameter, public minimum_absorber_amount
elemental subroutine, public crtm_atmosphere_create(Atm, n_Layers, n_Absorbers, n_Clouds, n_Aerosols)
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer function, public crtm_atmosphere_addlayers_ad(Atm_In, Atm_Out_AD, Atm_In_AD)
subroutine shift_profile(lpoly, x_toa, x_shifted)
elemental subroutine, public iatm_destroy(self)
real(fp), parameter, public point_5
subroutine layer_x(x, x_layer)
integer, parameter ml
character(*), parameter module_rcs_id
elemental logical function, public crtm_atmosphere_associated(Atm)
integer function, public crtm_atmosphere_addlayers(Atm_In, Atm_Out)
real(fp), dimension(0:n_model_layers), parameter, public model_level_pressure
elemental subroutine, public crtm_atmosphere_zero(Atmosphere)
integer, parameter, public success
subroutine, public crtm_get_model_profile(absorber_id, p, t, a, Model)