19 USE iso_fortran_env ,
ONLY: output_unit
24 OPERATOR(.equalto.), &
99 PUBLIC ::
OPERATOR(==)
100 PUBLIC ::
OPERATOR(+)
101 PUBLIC ::
OPERATOR(-)
212 INTERFACE OPERATOR(==)
214 END INTERFACE OPERATOR(==)
216 INTERFACE OPERATOR(+)
218 END INTERFACE OPERATOR(+)
220 INTERFACE OPERATOR(-)
222 END INTERFACE OPERATOR(-)
245 '$Id: CRTM_Atmosphere_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $' 282 CHARACTER(*),
PARAMETER,
DIMENSION( 0:N_VALID_ABSORBER_IDS ) :: &
284 'H2O ',
'CO2 ',
'O3 ',
'N2O ', &
285 'CO ',
'CH4 ',
'O2 ',
'NO ', &
286 'SO2 ',
'NO2 ',
'NH3 ',
'HNO3 ', &
287 'OH ',
'HF ',
'HCl ',
'HBr ', &
288 'HI ',
'ClO ',
'OCS ',
'H2CO ', &
289 'HOCl ',
'N2 ',
'HCN ',
'CH3Cl ', &
290 'H2O2 ',
'C2H2 ',
'C2H6 ',
'PH3 ', &
291 'COF2 ',
'SF6 ',
'H2S ',
'HCOOH ' /)
306 CHARACTER(*),
PARAMETER,
DIMENSION( 0:N_VALID_ABSORBER_UNITS ) :: &
308 'Volume mixing ratio, ppmv ', &
309 'Number density, cm^-3 ', &
310 'Mass mixing ratio, g/kg ', &
311 'Mass density, g.m^-3 ', &
312 'Partial pressure, hPa ', &
313 'Dewpoint temperature, K (H2O ONLY)', &
314 'Dewpoint temperature, C (H2O ONLY)', &
315 'Relative humidity, % (H2O ONLY)', &
316 'Specific amount, g/g ', &
317 'Integrated path, mm ' /)
318 INTEGER,
PARAMETER,
DIMENSION( 0:N_VALID_ABSORBER_UNITS ) :: &
340 CHARACTER(*),
PARAMETER,
DIMENSION( 0:N_VALID_CLIMATOLOGY_MODELS ) :: &
343 'Midlatitude summer ', &
344 'Midlatitude winter ', &
345 'Subarctic summer ', &
346 'Subarctic winter ', &
347 'U.S. Standard Atmosphere' /)
349 REAL(fp),
PARAMETER ::
zero = 0.0_fp
350 REAL(fp),
PARAMETER ::
one = 1.0_fp
352 INTEGER,
PARAMETER ::
ml = 256
363 LOGICAL :: is_allocated = .false.
365 INTEGER :: max_layers = 0
366 INTEGER :: n_layers = 0
367 INTEGER :: n_absorbers = 0
368 INTEGER :: max_clouds = 0
369 INTEGER :: n_clouds = 0
370 INTEGER :: max_aerosols = 0
371 INTEGER :: n_aerosols = 0
373 INTEGER :: n_added_layers = 0
377 INTEGER,
ALLOCATABLE :: absorber_id(:)
378 INTEGER,
ALLOCATABLE :: absorber_units(:)
380 REAL(fp),
ALLOCATABLE :: level_pressure(:)
381 REAL(fp),
ALLOCATABLE :: pressure(:)
382 REAL(fp),
ALLOCATABLE :: temperature(:)
383 REAL(fp),
ALLOCATABLE :: absorber(:,:)
442 status = atm%Is_Allocated
444 IF ( atm%n_Clouds > 0 .AND.
ALLOCATED(atm%Cloud) ) &
447 IF ( atm%n_Aerosols > 0 .AND.
ALLOCATED(atm%Aerosol) ) &
477 atm%Is_Allocated = .false.
539 n_Absorbers, & ! Input
544 INTEGER ,
INTENT(IN) :: n_layers
545 INTEGER ,
INTENT(IN) :: n_absorbers
546 INTEGER ,
INTENT(IN) :: n_clouds
547 INTEGER ,
INTENT(IN) :: n_aerosols
549 INTEGER :: alloc_stat
552 IF ( n_layers < 1 .OR. n_absorbers < 1 )
RETURN 553 IF ( n_clouds < 0 .OR. n_aerosols < 0 )
RETURN 556 ALLOCATE( atm%Absorber_ID( n_absorbers ), &
557 atm%Absorber_Units( n_absorbers ), &
558 atm%Level_Pressure( 0:n_layers ), &
559 atm%Pressure( n_layers ), &
560 atm%Temperature( n_layers ), &
561 atm%Absorber( n_layers, n_absorbers ), &
563 IF ( alloc_stat /= 0 )
RETURN 567 IF ( n_clouds > 0 )
THEN 569 ALLOCATE( atm%Cloud( n_clouds ), stat = alloc_stat )
570 IF ( alloc_stat /= 0 )
THEN 578 IF ( n_aerosols > 0 )
THEN 580 ALLOCATE( atm%Aerosol( n_aerosols ), stat = alloc_stat )
581 IF ( alloc_stat /= 0 )
THEN 591 atm%Max_Layers = n_layers
592 atm%n_Layers = n_layers
593 atm%n_Absorbers = n_absorbers
594 atm%Max_Clouds = n_clouds
595 atm%n_Clouds = n_clouds
596 atm%Max_Aerosols = n_aerosols
597 atm%n_Aerosols = n_aerosols
598 atm%n_Added_Layers = 0
602 atm%Level_Pressure =
zero 604 atm%Temperature =
zero 608 atm%Is_Allocated = .true.
659 INTEGER,
INTENT(IN) :: n_added_layers
663 INTEGER :: i, na, no, nt
666 na =
max(n_added_layers,0)
677 atm_out%n_Added_Layers = atm%n_Added_Layers+na
679 atm_out%Climatology = atm%Climatology
680 atm_out%Absorber_ID = atm%Absorber_ID
681 atm_out%Absorber_Units = atm%Absorber_Units
684 nt = atm_out%n_Layers
685 atm_out%Level_Pressure(na:nt) = atm%Level_Pressure(0:no)
686 atm_out%Pressure(na+1:nt) = atm%Pressure(1:no)
687 atm_out%Temperature(na+1:nt) = atm%Temperature(1:no)
688 atm_out%Absorber(na+1:nt,:) = atm%Absorber(1:no,:)
690 IF ( atm%n_Clouds > 0 )
THEN 691 DO i = 1, atm%n_Clouds
696 IF ( atm%n_Aerosols > 0 )
THEN 697 DO i = 1, atm%n_Aerosols
741 atmosphere%n_Added_Layers = 0
744 atmosphere%Level_Pressure =
zero 745 atmosphere%Pressure =
zero 746 atmosphere%Temperature =
zero 747 atmosphere%Absorber =
zero 750 IF ( atmosphere%n_Clouds > 0 )
CALL crtm_cloud_zero( atmosphere%Cloud )
799 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_IsValid' 807 msg =
'Atmosphere structure not allocated' 811 IF ( atm%n_Layers < 1 .OR. atm%n_Absorbers < 1 )
THEN 812 msg =
'Atmosphere structure dimensions invalid' 817 WRITE(msg,
'("No. of atmosphere structure layers [",i0,"(added:",i0,& 818 &")] is larger than maximum allowed [",i0,"]")') &
829 msg =
'Invalid climatology' 835 msg =
'Invalid absorber ID' 853 msg =
'Invalid absorber units ID' 858 IF ( any(atm%Level_Pressure <
zero ) )
THEN 859 msg =
'Negative level pressure found' 863 IF ( any(atm%Pressure <
zero ) )
THEN 864 msg =
'Negative layer pressure found' 868 IF ( any(atm%Temperature <
zero ) )
THEN 869 msg =
'Negative layer temperature found' 873 IF ( any(atm%Absorber <
zero ) )
THEN 874 msg =
'Negative level absorber found' 879 IF ( atm%n_Clouds > 0 )
THEN 880 DO nc = 1, atm%n_Clouds
884 IF ( atm%n_Aerosols > 0 )
THEN 885 DO na = 1, atm%n_Aerosols
893 INTEGER,
INTENT(IN) :: id
895 ispresent = any(atm%Absorber_ID == id)
935 TYPE(CRTM_Atmosphere_type),
INTENT(IN) :: Atm
936 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
939 INTEGER :: lClimatology
944 IF (
PRESENT(unit) )
THEN 949 WRITE(fid,
'(1x,"ATMOSPHERE OBJECT")')
951 WRITE(fid,
'(3x,"n_Layers :",1x,i0)') atm%n_Layers
952 WRITE(fid,
'(3x,"n_Absorbers :",1x,i0)') atm%n_Absorbers
953 WRITE(fid,
'(3x,"n_Clouds :",1x,i0)') atm%n_Clouds
954 WRITE(fid,
'(3x,"n_Aerosols :",1x,i0)') atm%n_Aerosols
956 lclimatology = atm%Climatology
957 IF ( lclimatology < 1 .OR. &
963 WRITE(fid,
'(3x,"Level pressure:")')
964 WRITE(fid,
'(5(1x,es13.6,:))') atm%Level_Pressure(0:k)
965 WRITE(fid,
'(3x,"Layer pressure:")')
966 WRITE(fid,
'(5(1x,es13.6,:))') atm%Pressure(1:k)
967 WRITE(fid,
'(3x,"Layer temperature:")')
968 WRITE(fid,
'(5(1x,es13.6,:))') atm%Temperature(1:k)
969 WRITE(fid,
'(3x,"Layer absorber:")')
970 DO j = 1, atm%n_Absorbers
971 WRITE(fid,
'(5x,a,"(",a,")")') trim(
absorber_id_name(atm%Absorber_Id(j))), &
973 WRITE(fid,
'(5(1x,es13.6,:))') atm%Absorber(1:k,j)
982 TYPE(CRTM_Atmosphere_type),
INTENT(IN) :: Atmosphere(:)
983 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
987 IF (
PRESENT(unit) )
THEN 990 DO i = 1,
SIZE(atmosphere)
991 WRITE(fid, fmt=
'(1x,"RANK-1 INDEX:",i0," - ")', advance=
'NO') i
997 TYPE(CRTM_Atmosphere_type),
INTENT(IN) :: Atmosphere(:,:)
998 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
1002 IF (
PRESENT(unit) )
THEN 1005 DO j = 1,
SIZE(atmosphere,2)
1006 DO i = 1,
SIZE(atmosphere,1)
1007 WRITE(fid, fmt=
'(1x,"RANK-2 INDEX:",i0,",",i0," - ")', advance=
'NO') i,j
1038 CHARACTER(*),
INTENT(OUT) :: id
1082 result( is_comparable )
1084 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
1085 LOGICAL :: is_comparable
1091 is_comparable = .false.
1092 IF (
PRESENT(n_sigfig) )
THEN 1103 IF ( (x%n_Layers /= y%n_Layers ) .OR. &
1104 (x%n_Absorbers /= y%n_Absorbers) .OR. &
1105 (x%n_Clouds /= y%n_Clouds ) .OR. &
1106 (x%n_Aerosols /= y%n_Aerosols ) .OR. &
1107 (x%Climatology /= y%Climatology) )
RETURN 1111 IF ( any(x%Absorber_ID(1:j) /= y%Absorber_ID(1:j) ) .OR. &
1112 any(x%Absorber_Units(1:j) /= y%Absorber_Units(1:j)) )
RETURN 1121 IF ( x%n_Clouds > 0 )
THEN 1126 IF ( x%n_Aerosols > 0 )
THEN 1131 is_comparable = .true.
1179 INTEGER ,
INTENT(IN) :: absorberid
1181 INTEGER :: absorberidx
1183 INTEGER :: j, idx(1)
1188 IF ( count(atm%Absorber_ID == absorberid) /= 1 )
RETURN 1190 idx = pack((/(j,j=1,atm%n_Absorbers)/), atm%Absorber_ID==absorberid)
1238 REAL(fp) ,
INTENT(IN) :: level_pressure
1240 INTEGER :: level_idx
1244 level_idx = minloc(abs(atm%Level_Pressure - level_pressure), dim=1) - 1
1294 INTEGER,
INTENT(IN) :: n_layers
1296 INTEGER :: n_absorbers
1297 INTEGER :: max_clouds, n_clouds
1298 INTEGER :: max_aerosols, n_aerosols
1300 IF ( n_layers < atmosphere%Max_Layers )
THEN 1302 atmosphere%n_Layers = n_layers
1309 n_absorbers = atmosphere%n_Absorbers
1310 max_clouds =
max(atmosphere%n_Clouds, atmosphere%Max_Clouds)
1311 n_clouds =
min(atmosphere%n_Clouds, atmosphere%Max_Clouds)
1312 max_aerosols =
max(atmosphere%n_Aerosols, atmosphere%Max_Aerosols)
1313 n_aerosols =
min(atmosphere%n_Aerosols, atmosphere%Max_Aerosols)
1318 atmosphere%n_Clouds = n_clouds
1319 atmosphere%n_Aerosols = n_aerosols
1375 Filename , & ! Input
1376 n_Channels , & ! Optional output
1380 CHARACTER(*),
INTENT(IN) :: filename
1381 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_channels
1382 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_profiles
1386 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_InquireFile' 1388 CHARACTER(ML) :: msg
1389 CHARACTER(ML) :: io_msg
1399 IF ( err_stat /=
success )
THEN 1400 msg =
'Error opening '//trim(filename)
1405 READ( fid,iostat=io_stat,iomsg=io_msg ) l, m
1406 IF ( io_stat /= 0 )
THEN 1407 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
1413 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1414 IF ( io_stat /= 0 )
THEN 1415 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1421 IF (
PRESENT(n_channels) ) n_channels = l
1422 IF (
PRESENT(n_profiles) ) n_profiles = m
1428 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1430 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1523 Filename , & ! Input
1524 Atmosphere , & ! Output
1525 Quiet , & ! Optional input
1526 n_Channels , & ! Optional output
1527 n_Profiles , & ! Optional output
1531 CHARACTER(*),
INTENT(IN) :: filename
1533 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1534 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_channels
1535 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_profiles
1536 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1540 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_ReadFile(M)' 1542 CHARACTER(ML) :: msg
1543 CHARACTER(ML) :: io_msg
1544 CHARACTER(ML) :: alloc_msg
1546 INTEGER :: alloc_stat
1549 INTEGER :: n_input_channels
1550 INTEGER :: m, n_input_profiles
1557 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1559 IF (
PRESENT(debug) ) noisy = debug
1564 IF ( err_stat /=
success )
THEN 1565 msg =
'Error opening '//trim(filename)
1571 READ( fid,iostat=io_stat,iomsg=io_msg ) n_input_channels, n_input_profiles
1572 IF ( io_stat /= 0 )
THEN 1573 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
1577 IF ( n_input_channels /= 0 )
THEN 1578 msg =
'n_Channels dimensions in '//trim(filename)//
' is not zero for a rank-1 '//&
1579 '(i.e. profiles only) Atmosphere read.' 1583 ALLOCATE(atmosphere(n_input_profiles), stat=alloc_stat, errmsg=alloc_msg)
1584 IF ( alloc_stat /= 0 )
THEN 1585 msg =
'Error allocating Atmosphere array - '//trim(alloc_msg)
1591 profile_loop:
DO m = 1, n_input_profiles
1595 IF ( err_stat /=
success )
THEN 1596 WRITE( msg,
'("Error reading Atmosphere element (",i0,") from ",a)' ) m, trim(filename)
1603 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1604 IF ( io_stat /= 0 )
THEN 1605 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1611 IF (
PRESENT(n_channels) ) n_channels = 0
1612 IF (
PRESENT(n_profiles) ) n_profiles = n_input_profiles
1617 WRITE( msg,
'("Number of profiles read from ",a,": ",i0)' ) trim(filename), n_input_profiles
1625 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1626 IF ( io_stat /= 0 ) &
1627 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1629 IF (
ALLOCATED(atmosphere) )
THEN 1630 DEALLOCATE(atmosphere, stat=alloc_stat, errmsg=alloc_msg)
1631 IF ( alloc_stat /= 0 ) &
1632 msg = trim(msg)//
'; Error deallocating Atmosphere array during error cleanup - '//&
1643 Filename , & ! Input
1644 Atmosphere , & ! Output
1645 Quiet , & ! Optional input
1646 n_Channels , & ! Optional output
1647 n_Profiles , & ! Optional output
1651 CHARACTER(*),
INTENT(IN) :: filename
1653 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1654 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_channels
1655 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_profiles
1656 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1660 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_ReadFile(L x M)' 1662 CHARACTER(ML) :: msg
1663 CHARACTER(ML) :: io_msg
1664 CHARACTER(ML) :: alloc_msg
1666 INTEGER :: alloc_stat
1669 INTEGER :: l, n_input_channels
1670 INTEGER :: m, n_input_profiles
1677 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1679 IF (
PRESENT(debug) ) noisy = debug
1684 IF ( err_stat /=
success )
THEN 1685 msg =
'Error opening '//trim(filename)
1691 READ( fid,iostat=io_stat,iomsg=io_msg ) n_input_channels, n_input_profiles
1692 IF ( io_stat /= 0 )
THEN 1693 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
1697 ALLOCATE(atmosphere(n_input_channels, n_input_profiles), &
1698 stat=alloc_stat, errmsg=alloc_msg)
1699 IF ( alloc_stat /= 0 )
THEN 1700 msg =
'Error allocating Atmosphere array - '//trim(alloc_msg)
1706 profile_loop:
DO m = 1, n_input_profiles
1707 channel_loop:
DO l = 1, n_input_channels
1711 IF ( err_stat /=
success )
THEN 1712 WRITE( msg,
'("Error reading Atmosphere element (",i0,",",i0,") from ",a)' ) l, m, trim(filename)
1720 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1721 IF ( io_stat /= 0 )
THEN 1722 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1728 IF (
PRESENT(n_channels) ) n_channels = n_input_channels
1729 IF (
PRESENT(n_profiles) ) n_profiles = n_input_profiles
1734 WRITE( msg,
'("Number of channels and profiles read from ",a,": ",i0,1x,i0)' ) &
1735 trim(filename), n_input_channels, n_input_profiles
1743 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1744 IF ( io_stat /= 0 ) &
1745 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1747 IF (
ALLOCATED(atmosphere) )
THEN 1748 DEALLOCATE(atmosphere, stat=alloc_stat, errmsg=alloc_msg)
1749 IF ( alloc_stat /= 0 ) &
1750 msg = trim(msg)//
'; Error deallocating Atmosphere array during error cleanup - '//&
1832 Filename , & ! Input
1833 Atmosphere , & ! Input
1834 Quiet , & ! Optional input
1838 CHARACTER(*),
INTENT(IN) :: filename
1840 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1841 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1845 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_WriteFile(M)' 1847 CHARACTER(ML) :: msg
1848 CHARACTER(ML) :: io_msg
1852 INTEGER :: m, n_output_profiles
1858 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1860 IF (
PRESENT(debug) ) noisy = debug
1864 IF ( any(atmosphere%n_Layers == 0 .OR. &
1865 atmosphere%n_Absorbers == 0 ) )
THEN 1866 msg =
'Zero dimension profiles in input!' 1869 n_output_profiles =
SIZE(atmosphere)
1874 IF ( err_stat /=
success )
THEN 1875 msg =
'Error opening '//trim(filename)
1881 WRITE( fid,iostat=io_stat,iomsg=io_msg ) 0, n_output_profiles
1882 IF ( io_stat /= 0 )
THEN 1883 msg =
'Error writing dimensions to '//trim(filename)//
'- '//trim(io_msg)
1889 profile_loop:
DO m = 1, n_output_profiles
1893 IF ( err_stat /=
success )
THEN 1894 WRITE( msg,
'("Error writing Atmosphere element (",i0,") to ",a)' ) m, trim(filename)
1901 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
1902 IF ( io_stat /= 0 )
THEN 1903 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
1910 WRITE( msg,
'("Number of profiles written to ",a,": ",i0)' ) trim(filename), n_output_profiles
1919 IF ( io_stat /= 0 ) &
1920 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
1930 Filename , & ! Input
1931 Atmosphere , & ! Input
1932 Quiet , & ! Optional input
1936 CHARACTER(*),
INTENT(IN) :: filename
1938 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1939 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1943 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_WriteFile(L x M)' 1945 CHARACTER(ML) :: msg
1946 CHARACTER(ML) :: io_msg
1950 INTEGER :: l, n_output_channels
1951 INTEGER :: m, n_output_profiles
1957 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1959 IF (
PRESENT(debug) ) noisy = debug
1963 IF ( any(atmosphere%n_Layers == 0 .OR. &
1964 atmosphere%n_Absorbers == 0 ) )
THEN 1965 msg =
'Zero dimension profiles in input!' 1968 n_output_channels =
SIZE(atmosphere,dim=1)
1969 n_output_profiles =
SIZE(atmosphere,dim=2)
1974 IF ( err_stat /=
success )
THEN 1975 msg =
'Error opening '//trim(filename)
1981 WRITE( fid,iostat=io_stat,iomsg=io_msg ) n_output_channels, n_output_profiles
1982 IF ( io_stat /= 0 )
THEN 1983 msg =
'Error writing dimensions to '//trim(filename)//
'- '//trim(io_msg)
1989 profile_loop:
DO m = 1, n_output_profiles
1990 channel_loop:
DO l = 1, n_output_channels
1994 IF ( err_stat /=
success )
THEN 1995 WRITE( msg,
'("Error writing Atmosphere element (",i0,",",i0,") to ",a)' ) l, m, trim(filename)
2003 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
2004 IF ( io_stat /= 0 )
THEN 2005 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
2012 WRITE( msg,
'("Number of channels and profiles written to ",a,": ",i0,1x,i0 )' ) &
2013 trim(filename), n_output_channels, n_output_profiles
2022 IF ( io_stat /= 0 ) &
2023 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
2089 IF ( (x%n_Layers /= y%n_Layers ) .OR. &
2090 (x%n_Absorbers /= y%n_Absorbers) .OR. &
2091 (x%n_Clouds /= y%n_Clouds ) .OR. &
2092 (x%n_Aerosols /= y%n_Aerosols ) .OR. &
2093 (x%Climatology /= y%Climatology) )
RETURN 2097 IF ( all(x%Absorber_ID(1:j) == y%Absorber_ID(1:j) ) .AND. &
2098 all(x%Absorber_Units(1:j) == y%Absorber_Units(1:j)) .AND. &
2099 all(x%Level_Pressure(0:) .equalto. y%Level_Pressure(0:)) .AND. &
2100 all(x%Pressure(1:k) .equalto. y%Pressure(1:k) ) .AND. &
2101 all(x%Temperature(1:k) .equalto. y%Temperature(1:k) ) .AND. &
2102 all(x%Absorber(1:k,1:j) .equalto. y%Absorber(1:k,1:j) ) ) is_equal = .true.
2104 IF ( x%n_Clouds > 0 )
THEN 2106 is_equal = is_equal .AND. all(x%Cloud == y%Cloud)
2109 IF ( x%n_Aerosols > 0 )
THEN 2111 is_equal = is_equal .AND. all(x%Aerosol == y%Aerosol)
2160 IF ( atm1%Climatology /= atm2%Climatology .OR. &
2161 atm1%n_Layers /= atm2%n_Layers .OR. &
2162 atm1%n_Absorbers /= atm2%n_Absorbers .OR. &
2163 atm1%n_Clouds /= atm2%n_Clouds .OR. &
2164 atm1%n_Aerosols /= atm2%n_Aerosols .OR. &
2165 atm1%n_Added_Layers /= atm2%n_Added_Layers )
RETURN 2167 IF ( any(atm1%Absorber_ID /= atm2%Absorber_ID ) .OR. &
2168 any(atm1%Absorber_Units /= atm2%Absorber_Units) )
RETURN 2175 j = atm1%n_Absorbers
2176 atmsum%Level_Pressure(0:k) = atmsum%Level_Pressure(0:k) + atm2%Level_Pressure(0:k)
2177 atmsum%Pressure(1:k) = atmsum%Pressure(1:k) + atm2%Pressure(1:k)
2178 atmsum%Temperature(1:k) = atmsum%Temperature(1:k) + atm2%Temperature(1:k)
2179 atmsum%Absorber(1:k,1:j) = atmsum%Absorber(1:k,1:j) + atm2%Absorber(1:k,1:j)
2181 IF ( atm1%n_Clouds > 0 )
THEN 2182 DO i = 1, atm1%n_Clouds
2183 atmsum%Cloud(i) = atmsum%Cloud(i) + atm2%Cloud(i)
2187 IF ( atm1%n_Aerosols > 0 )
THEN 2188 DO i = 1, atm1%n_Aerosols
2189 atmsum%Aerosol(i) = atmsum%Aerosol(i) + atm2%Aerosol(i)
2240 IF ( atm1%Climatology /= atm2%Climatology .OR. &
2241 atm1%n_Layers /= atm2%n_Layers .OR. &
2242 atm1%n_Absorbers /= atm2%n_Absorbers .OR. &
2243 atm1%n_Clouds /= atm2%n_Clouds .OR. &
2244 atm1%n_Aerosols /= atm2%n_Aerosols .OR. &
2245 atm1%n_Added_Layers /= atm2%n_Added_Layers )
RETURN 2247 IF ( any(atm1%Absorber_ID /= atm2%Absorber_ID ) .OR. &
2248 any(atm1%Absorber_Units /= atm2%Absorber_Units) )
RETURN 2255 j = atm1%n_Absorbers
2256 atmdiff%Level_Pressure(0:k) = atmdiff%Level_Pressure(0:k) - atm2%Level_Pressure(0:k)
2257 atmdiff%Pressure(1:k) = atmdiff%Pressure(1:k) - atm2%Pressure(1:k)
2258 atmdiff%Temperature(1:k) = atmdiff%Temperature(1:k) - atm2%Temperature(1:k)
2259 atmdiff%Absorber(1:k,1:j) = atmdiff%Absorber(1:k,1:j) - atm2%Absorber(1:k,1:j)
2261 IF ( atm1%n_Clouds > 0 )
THEN 2262 DO i = 1, atm1%n_Clouds
2263 atmdiff%Cloud(i) = atmdiff%Cloud(i) - atm2%Cloud(i)
2267 IF ( atm1%n_Aerosols > 0 )
THEN 2268 DO i = 1, atm1%n_Aerosols
2269 atmdiff%Aerosol(i) = atmdiff%Aerosol(i) - atm2%Aerosol(i)
2287 Quiet , & ! Optional input
2291 INTEGER,
INTENT(IN) :: fid
2293 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
2294 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
2298 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_ReadFile(Record)' 2300 CHARACTER(ML) :: fname
2301 CHARACTER(ML) :: msg
2302 CHARACTER(ML) :: io_msg
2305 INTEGER :: n_absorbers
2307 INTEGER :: n_aerosols
2314 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2319 IF ( io_stat /= 0 )
THEN 2320 msg =
'Error reading dimensions - '//trim(io_msg)
2332 msg =
'Error creating output object.' 2338 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2342 IF ( io_stat /= 0 )
THEN 2343 msg =
'Error reading atmosphere climatology and absorber IDs - '//trim(io_msg)
2349 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2350 atm%Level_Pressure, &
2354 IF ( io_stat /= 0 )
THEN 2355 msg =
'Error reading atmospheric profile data - '//trim(io_msg)
2361 IF ( n_clouds > 0 )
THEN 2362 INQUIRE( unit=fid,name=fname )
2366 no_close = .true., &
2368 IF ( err_stat /=
success )
THEN 2369 msg =
'Error reading cloud data' 2376 IF ( n_aerosols > 0 )
THEN 2377 INQUIRE( unit=fid,name=fname )
2381 no_close = .true., &
2383 IF ( err_stat /=
success )
THEN 2384 msg =
'Error reading aerosol data' 2393 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
2395 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
2414 Quiet, & ! Optional input
2418 INTEGER,
INTENT(IN) :: fid
2420 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
2421 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
2425 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Atmosphere_WriteFile(Record)' 2427 CHARACTER(ML) :: fname
2428 CHARACTER(ML) :: msg
2429 CHARACTER(ML) :: io_msg
2435 msg =
'Input Atmosphere object is not used.' 2441 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2446 IF ( io_stat /= 0 )
THEN 2447 msg =
'Error writing dimensions - '//trim(io_msg)
2453 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2457 IF ( io_stat /= 0 )
THEN 2458 msg =
'Error writing atmosphere climatology and absorber IDs - '//trim(io_msg)
2464 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2465 atm%Level_Pressure(0:atm%n_Layers), &
2466 atm%Pressure(1:atm%n_Layers), &
2467 atm%Temperature(1:atm%n_Layers), &
2468 atm%Absorber(1:atm%n_Layers,:)
2469 IF ( io_stat /= 0 )
THEN 2470 msg =
'Error writing atmospheric profile data - '//trim(io_msg)
2476 IF ( atm%n_Clouds > 0 )
THEN 2477 INQUIRE( unit=fid,name=fname )
2479 atm%Cloud(1:atm%n_Clouds), &
2481 no_close = .true., &
2483 IF ( err_stat /=
success )
THEN 2484 msg =
'Error writing cloud data' 2491 IF ( atm%n_Aerosols > 0 )
THEN 2492 INQUIRE( unit=fid,name=fname )
2494 atm%Aerosol(1:atm%n_Aerosols), &
2496 no_close = .true., &
2498 IF ( err_stat /=
success )
THEN 2499 msg =
'Error writing aerosol data' 2509 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
integer, parameter, public ice_cloud
integer, parameter, public n_valid_cloud_categories
integer, parameter, public h2o2_id
integer, parameter, public n2o_id
elemental type(crtm_atmosphere_type) function, public crtm_atmosphere_addlayercopy(atm, n_Added_Layers)
integer, parameter, public ph3_id
integer, parameter, public dust_aerosol
integer, parameter, public ch4_id
integer, parameter, public failure
pure integer function, public crtm_cloud_categoryid(cloud)
integer, parameter, public n_valid_climatology_models
integer, parameter, public seasalt_sscm1_aerosol
integer, parameter, public hcn_id
elemental type(crtm_cloud_type) function, public crtm_cloud_addlayercopy(cld, n_Added_Layers)
integer, parameter, public warning
elemental subroutine, public crtm_aerosol_create(Aerosol, n_Layers)
integer, parameter, public integrated_path_units
integer, parameter, public ch3l_id
character(*), dimension(0:n_valid_absorber_units), parameter, public absorber_units_name
integer, parameter, public sf6_id
integer, parameter, public fp
pure integer function, public crtm_aerosol_categoryid(aerosol)
character(*), parameter write_error_status
integer, parameter, public mass_density_units
elemental subroutine, public crtm_atmosphere_destroy(Atm)
integer, parameter, public number_density_units
integer function, public crtm_cloud_readfile(Filename, Cloud, Quiet, No_Close, n_Clouds, Debug)
integer, parameter, public specific_amount_units
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
integer, parameter, public co2_id
integer, parameter, public no_id
character(*), parameter module_version_id
integer function, public crtm_atmosphere_inquirefile(Filename, n_Channels, n_Profiles)
integer, parameter, public h2o_id
integer, parameter, public rain_cloud
elemental subroutine, public crtm_cloud_create(Cloud, n_Layers)
character(*), dimension(0:n_valid_climatology_models), parameter, public climatology_model_name
integer, parameter, public c2h2_id
integer function, public crtm_cloud_writefile(Filename, Cloud, Quiet, No_Close, Debug)
integer function write_atmosphere_rank2(Filename, Atmosphere, Quiet, Debug)
elemental logical function, public crtm_cloud_compare(x, y, n_SigFig)
integer, parameter, public dewpoint_temperature_c_units
logical function, public crtm_atmosphere_isvalid(Atm)
character(*), dimension(0:n_valid_aerosol_categories), parameter, public aerosol_category_name
elemental subroutine, public crtm_aerosol_destroy(Aerosol)
integer, parameter, public hf_id
integer, parameter, public hi_id
integer, dimension(0:n_valid_absorber_units), parameter, public h2o_only_units_flag
subroutine inquire_cleanup()
integer, parameter, public invalid_absorber_units
integer, parameter, public cof2_id
integer function read_atmosphere_rank2(Filename, Atmosphere, Quiet, n_Channels, n_Profiles, Debug)
integer, parameter, public h2s_id
integer, parameter, public ocs_id
integer, parameter, public invalid_cloud
character(*), dimension(0:n_valid_cloud_categories), parameter, public cloud_category_name
integer, parameter, public n_valid_absorber_ids
integer, parameter, public hcl_id
integer, parameter, public black_carbon_aerosol
elemental logical function, public crtm_atmosphere_compare(x, y, n_SigFig)
integer, parameter, public nh3_id
elemental subroutine, public crtm_cloud_setlayers(Cloud, n_Layers)
subroutine read_cleanup()
integer, parameter, public no2_id
integer, parameter, public hno3_id
integer, parameter, public tropical
subroutine write_cleanup()
elemental subroutine, public crtm_cloud_zero(Cloud)
integer, parameter, public volume_mixing_ratio_units
elemental subroutine, public crtm_aerosol_zero(Aerosol)
integer, parameter, public invalid_model
integer, parameter, public clo_id
subroutine read_record_cleanup()
logical function, public crtm_aerosol_isvalid(Aerosol)
integer, parameter, public h2co_id
elemental type(crtm_atmosphere_type) function crtm_atmosphere_add(atm1, atm2)
integer, parameter, public n2_id
integer function write_atmosphere_rank1(Filename, Atmosphere, Quiet, Debug)
integer, parameter, public hcooh_id
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
elemental subroutine, public crtm_atmosphere_create(Atm, n_Layers, n_Absorbers, n_Clouds, n_Aerosols)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
pure character(len(aerosol_category_name(1))) function, public crtm_aerosol_categoryname(aerosol)
integer, parameter, public c2h6_id
integer, parameter, public o3_id
integer, parameter, public snow_cloud
integer, parameter, public n_valid_absorber_units
integer, parameter, public us_standard_atmosphere
integer function, public crtm_aerosol_writefile(Filename, Aerosol, Quiet, No_Close, Debug)
integer, parameter, public subarctic_winter
integer, parameter, public midlatitude_winter
logical function absorber_id_ispresent(Id)
elemental type(crtm_atmosphere_type) function crtm_atmosphere_subtract(atm1, atm2)
integer, parameter, public oh_id
integer, parameter, public mass_mixing_ratio_units
subroutine, public crtm_atmosphere_defineversion(Id)
elemental logical function crtm_atmosphere_equal(x, y)
integer, parameter, public invalid_absorber_id
integer, parameter, public default_n_sigfig
integer function, public crtm_cloud_categorylist(list)
integer, parameter, public hail_cloud
integer, parameter, public co_id
integer, parameter, public subarctic_summer
integer function read_record(fid, atm, Quiet, Debug)
integer, parameter, public max_n_layers
integer, parameter, public so2_id
subroutine scalar_inspect(Atm, Unit)
subroutine, public crtm_aerosol_defineversion(Id)
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
integer, parameter, public graupel_cloud
subroutine write_record_cleanup()
elemental subroutine, public crtm_aerosol_setlayers(Aerosol, n_Layers)
subroutine, public crtm_cloud_defineversion(Id)
integer function read_atmosphere_rank1(Filename, Atmosphere, Quiet, n_Channels, n_Profiles, Debug)
elemental subroutine, public crtm_cloud_destroy(Cloud)
logical function, public crtm_cloud_isvalid(Cloud)
elemental type(crtm_aerosol_type) function, public crtm_aerosol_addlayercopy(aer, n_Added_Layers)
elemental logical function, public crtm_aerosol_compare(x, y, n_SigFig)
integer, parameter, public hbr_id
integer function, public crtm_aerosol_readfile(Filename, Aerosol, Quiet, No_Close, n_Aerosols, Debug)
integer, parameter, public n_valid_aerosol_categories
elemental logical function, public crtm_atmosphere_associated(Atm)
integer, parameter, public o2_id
integer, parameter, public invalid_aerosol
elemental subroutine, public crtm_atmosphere_setlayers(Atmosphere, n_Layers)
pure character(len(cloud_category_name(1))) function, public crtm_cloud_categoryname(cloud)
integer, parameter, public midlatitude_summer
integer function, public crtm_aerosol_categorylist(list)
integer function, public crtm_get_absorberidx(Atm, AbsorberId)
integer, parameter, public water_cloud
integer, parameter, public partial_pressure_units
integer, parameter, public seasalt_sscm3_aerosol
subroutine rank2_inspect(Atmosphere, Unit)
elemental logical function, public crtm_aerosol_associated(Aerosol)
integer, parameter, public organic_carbon_aerosol
integer, parameter, public sulfate_aerosol
character(*), dimension(0:n_valid_absorber_ids), parameter, public absorber_id_name
integer, parameter, public seasalt_ssam_aerosol
elemental subroutine, public crtm_atmosphere_zero(Atmosphere)
integer, parameter, public success
integer, parameter, public dewpoint_temperature_k_units
integer, parameter, public seasalt_sscm2_aerosol
subroutine rank1_inspect(Atmosphere, Unit)
integer, parameter, public relative_humidity_units
elemental logical function, public crtm_cloud_associated(Cloud)
integer, parameter, public information
integer, parameter, public hocl_id
integer function, public crtm_get_pressurelevelidx(Atm, Level_Pressure)