21 USE iso_fortran_env ,
ONLY: output_unit
26 OPERATOR(.equalto.), &
56 PUBLIC ::
OPERATOR(==)
101 INTERFACE OPERATOR(==)
103 END INTERFACE OPERATOR(==)
105 INTERFACE OPERATOR(+)
107 END INTERFACE OPERATOR(+)
109 INTERFACE OPERATOR(-)
111 END INTERFACE OPERATOR(-)
128 '$Id: CRTM_Surface_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $' 130 REAL(fp),
PARAMETER ::
zero = 0.0_fp
131 REAL(fp),
PARAMETER ::
one = 1.0_fp
133 INTEGER,
PARAMETER ::
ml = 256
149 CHARACTER(*),
PARAMETER,
DIMENSION( 0:N_VALID_SURFACE_TYPES ) :: &
157 'Land + water + snow ', &
161 'Land + water + ice ', &
163 'Land + snow + ice ', &
164 'Water + snow + ice ', &
165 'Land + water + snow + ice' /)
204 LOGICAL :: is_allocated = .true.
208 REAL(fp) :: land_coverage =
zero 209 REAL(fp) :: water_coverage =
zero 210 REAL(fp) :: snow_coverage =
zero 211 REAL(fp) :: ice_coverage =
zero 294 status = sfc%Is_Allocated
325 sfc%Is_Allocated = .true.
366 INTEGER ,
INTENT(IN) :: n_channels
369 IF ( n_channels < 0 )
RETURN 376 sfc%Is_Allocated = .true.
414 sfc%Land_Coverage =
zero 415 sfc%Water_Coverage =
zero 416 sfc%Snow_Coverage =
zero 417 sfc%Ice_Coverage =
zero 473 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_IsValid' 478 IF ( .NOT. isvalid )
THEN 479 msg =
'Invalid surface coverage fraction(s) found' 532 INTEGER,
OPTIONAL,
INTENT(IN) :: unit
538 IF (
PRESENT(unit) )
THEN 543 WRITE(fid,
'(1x,"Surface OBJECT")')
545 WRITE(fid,
'(3x,"Land Coverage :",1x,f6.3)') sfc%Land_Coverage
546 WRITE(fid,
'(3x,"Water Coverage:",1x,f6.3)') sfc%Water_Coverage
547 WRITE(fid,
'(3x,"Snow Coverage :",1x,f6.3)') sfc%Snow_Coverage
548 WRITE(fid,
'(3x,"Ice Coverage :",1x,f6.3)') sfc%Ice_Coverage
597 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_IsCoverageValid' 598 REAL(fp) ,
PARAMETER ::
tolerance = 1.0e-6_fp
600 REAL(fp) :: total_coverage
603 total_coverage = sfc%Land_Coverage + sfc%Water_Coverage + &
604 sfc%Snow_Coverage + sfc%Ice_Coverage
614 WRITE( msg,
'("Total coverage fraction does not sum to 1 +/- ",2es13.6)' )
tolerance, total_coverage-
one 622 REAL(fp) ,
INTENT(IN) :: coverage
623 CHARACTER(*),
INTENT(IN) :: name
630 WRITE( msg,
'(a," coverage fraction is < ",es13.6)' ) trim(name), -
tolerance 637 WRITE( msg,
'(a," coverage fraction is > 1 +",es13.6)' ) trim(name),
tolerance 684 INTEGER :: coverage_type
688 IF ( sfc%Snow_Coverage >
zero ) coverage_type = coverage_type +
snow_surface 689 IF ( sfc%Ice_Coverage >
zero ) coverage_type = coverage_type +
ice_surface 717 CHARACTER(*),
INTENT(OUT) :: id
761 result( is_comparable )
763 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
764 LOGICAL :: is_comparable
769 is_comparable = .false.
770 IF (
PRESENT(n_sigfig) )
THEN 801 is_comparable = .true.
858 n_Channels , & ! Optional output
862 CHARACTER(*),
INTENT(IN) :: filename
863 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_channels
864 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_profiles
868 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_InquireFile' 871 CHARACTER(ML) :: io_msg
880 msg =
'File '//trim(filename)//
' not found.' 886 IF ( err_stat /=
success )
THEN 887 msg =
'Error opening '//trim(filename)
892 READ( fid, iostat=io_stat,iomsg=io_msg ) l, m
893 IF ( io_stat /= 0 )
THEN 894 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
899 CLOSE( fid, iostat=io_stat,iomsg=io_msg )
900 IF ( io_stat /= 0 )
THEN 901 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
906 IF (
PRESENT(n_channels) ) n_channels = l
907 IF (
PRESENT(n_profiles) ) n_profiles = m
913 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
915 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1008 Filename , & ! Input
1009 Surface , & ! Output
1010 Quiet , & ! Optional input
1011 n_Channels, & ! Optional output
1012 n_Profiles, & ! Optional output
1016 CHARACTER(*),
INTENT(IN) :: filename
1018 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1019 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_channels
1020 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_profiles
1021 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1025 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_ReadFile(M)' 1027 CHARACTER(ML) :: msg
1028 CHARACTER(ML) :: io_msg
1029 CHARACTER(ML) :: alloc_msg
1031 INTEGER :: alloc_stat
1034 INTEGER :: n_input_channels
1035 INTEGER :: m, n_input_profiles
1042 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1044 IF (
PRESENT(debug) ) noisy = debug
1049 IF ( err_stat /=
success )
THEN 1050 msg =
'Error opening '//trim(filename)
1056 READ( fid,iostat=io_stat,iomsg=io_msg ) n_input_channels, n_input_profiles
1057 IF ( io_stat /= 0 )
THEN 1058 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
1062 IF ( n_input_channels /= 0 )
THEN 1063 msg =
'n_Channels dimensions in '//trim(filename)//
' is not zero for a rank-1 '//&
1064 '(i.e. profiles only) Surface read.' 1068 ALLOCATE(surface(n_input_profiles), stat=alloc_stat, errmsg=alloc_msg)
1069 IF ( alloc_stat /= 0 )
THEN 1070 msg =
'Error allocating Surface array - '//trim(alloc_msg)
1076 profile_loop:
DO m = 1, n_input_profiles
1080 IF ( err_stat /=
success )
THEN 1081 WRITE( msg,
'("Error reading Surface element (",i0,") from ",a)' ) m, trim(filename)
1088 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1089 IF ( io_stat /= 0 )
THEN 1090 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1096 IF (
PRESENT(n_channels) ) n_channels = 0
1097 IF (
PRESENT(n_profiles) ) n_profiles = n_input_profiles
1102 WRITE( msg,
'("Number of profiles read from ",a,": ",i0)' ) trim(filename), n_input_profiles
1110 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1111 IF ( io_stat /= 0 ) &
1112 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1114 IF (
ALLOCATED(surface) )
THEN 1115 DEALLOCATE(surface, stat=alloc_stat, errmsg=alloc_msg)
1116 IF ( alloc_stat /= 0 ) &
1117 msg = trim(msg)//
'; Error deallocating Surface array during error cleanup - '//&
1128 Filename , & ! Input
1129 Surface , & ! Output
1130 Quiet , & ! Optional input
1131 n_Channels, & ! Optional output
1132 n_Profiles, & ! Optional output
1136 CHARACTER(*),
INTENT(IN) :: filename
1138 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1139 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_channels
1140 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_profiles
1141 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1145 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_ReadFile(L x M)' 1147 CHARACTER(ML) :: msg
1148 CHARACTER(ML) :: io_msg
1149 CHARACTER(ML) :: alloc_msg
1151 INTEGER :: alloc_stat
1154 INTEGER :: l, n_input_channels
1155 INTEGER :: m, n_input_profiles
1162 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1164 IF (
PRESENT(debug) ) noisy = debug
1169 IF ( err_stat /=
success )
THEN 1170 msg =
'Error opening '//trim(filename)
1176 READ( fid,iostat=io_stat,iomsg=io_msg ) n_input_channels, n_input_profiles
1177 IF ( io_stat /= 0 )
THEN 1178 msg =
'Error reading dimensions from '//trim(filename)//
' - '//trim(io_msg)
1182 ALLOCATE(surface(n_input_channels, n_input_profiles), stat=alloc_stat, errmsg=alloc_msg)
1183 IF ( alloc_stat /= 0 )
THEN 1184 msg =
'Error allocating Surface array - '//trim(alloc_msg)
1190 profile_loop:
DO m = 1, n_input_profiles
1191 channel_loop:
DO l = 1, n_input_channels
1195 IF ( err_stat /=
success )
THEN 1196 WRITE( msg,
'("Error reading Surface element (",i0,",",i0,") from ",a)' ) &
1197 l, m, trim(filename)
1205 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1206 IF ( io_stat /= 0 )
THEN 1207 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1213 IF (
PRESENT(n_channels) ) n_channels = n_input_channels
1214 IF (
PRESENT(n_profiles) ) n_profiles = n_input_profiles
1219 WRITE( msg,
'("Number of channels and profiles read from ",a,": ",i0,1x,i0)' ) &
1220 trim(filename), n_input_channels, n_input_profiles
1228 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1229 IF ( io_stat /= 0 ) &
1230 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1232 IF (
ALLOCATED(surface) )
THEN 1233 DEALLOCATE(surface, stat=alloc_stat, errmsg=alloc_msg)
1234 IF ( alloc_stat /= 0 ) &
1235 msg = trim(msg)//
'; Error deallocating Surface array during error cleanup - '//&
1319 Quiet , & ! Optional input
1323 CHARACTER(*),
INTENT(IN) :: filename
1325 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1326 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1330 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_WriteFile(M)' 1332 CHARACTER(ML) :: msg
1333 CHARACTER(ML) :: io_msg
1337 INTEGER :: m, n_output_profiles
1343 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1345 IF (
PRESENT(debug) )
THEN 1346 IF ( debug ) noisy = .true.
1349 n_output_profiles =
SIZE(surface)
1354 IF ( err_stat /=
success )
THEN 1355 msg =
'Error opening '//trim(filename)
1361 WRITE( fid,iostat=io_stat,iomsg=io_msg ) 0, n_output_profiles
1362 IF ( io_stat /= 0 )
THEN 1363 msg =
'Error writing dimensions to '//trim(filename)//
'- '//trim(io_msg)
1369 profile_loop:
DO m = 1, n_output_profiles
1373 IF ( err_stat /=
success )
THEN 1374 WRITE( msg,
'("Error writing Surface element (",i0,") to ",a)' ) m, trim(filename)
1381 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
1382 IF ( io_stat /= 0 )
THEN 1383 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
1390 WRITE( msg,
'("Number of profiles written to ",a,": ",i0)' ) &
1391 trim(filename), n_output_profiles
1400 IF ( io_stat /= 0 ) &
1401 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
1413 Quiet , & ! Optional input
1417 CHARACTER(*),
INTENT(IN) :: filename
1419 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1420 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1424 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_WriteFile(L x M)' 1426 CHARACTER(ML) :: msg
1427 CHARACTER(ML) :: io_msg
1431 INTEGER :: l, n_output_channels
1432 INTEGER :: m, n_output_profiles
1438 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1440 IF (
PRESENT(debug) )
THEN 1441 IF ( debug ) noisy = .true.
1444 n_output_channels =
SIZE(surface,dim=1)
1445 n_output_profiles =
SIZE(surface,dim=2)
1450 IF ( err_stat /=
success )
THEN 1451 msg =
'Error opening '//trim(filename)
1457 WRITE( fid,iostat=io_stat,iomsg=io_msg ) n_output_channels, n_output_profiles
1458 IF ( io_stat /= 0 )
THEN 1459 msg =
'Error writing dimensions to '//trim(filename)//
'- '//trim(io_msg)
1465 profile_loop:
DO m = 1, n_output_profiles
1466 channel_loop:
DO l = 1, n_output_channels
1470 IF ( err_stat /=
success )
THEN 1471 WRITE( msg,
'("Error writing Surface element (",i0,",",i0,") to ",a)' ) &
1472 l, m, trim(filename)
1480 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
1481 IF ( io_stat /= 0 )
THEN 1482 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
1489 WRITE( msg,
'("Number of channels and profiles written to ",a,": ",i0,1x,i0 )' ) &
1490 trim(filename), n_output_channels, n_output_profiles
1499 IF ( io_stat /= 0 ) &
1500 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
1556 is_equal = ( (x%Land_Coverage .equalto. y%Land_Coverage ) .AND. &
1557 (x%Water_Coverage .equalto. y%Water_Coverage) .AND. &
1558 (x%Snow_Coverage .equalto. y%Snow_Coverage ) .AND. &
1559 (x%Ice_Coverage .equalto. y%Ice_Coverage ) )
1560 IF ( .NOT. is_equal )
RETURN 1564 IF ( .NOT. is_equal )
RETURN 1568 IF ( .NOT. is_equal )
RETURN 1572 IF ( .NOT. is_equal )
RETURN 1576 IF ( .NOT. is_equal )
RETURN 1581 is_equal = is_equal .AND. (x%SensorData == y%SensorData)
1627 sfcsum%Land_Temperature = sfcsum%Land_Temperature + sfc2%Land_Temperature
1628 sfcsum%Soil_Moisture_Content = sfcsum%Soil_Moisture_Content + sfc2%Soil_Moisture_Content
1629 sfcsum%Canopy_Water_Content = sfcsum%Canopy_Water_Content + sfc2%Canopy_Water_Content
1630 sfcsum%Vegetation_Fraction = sfcsum%Vegetation_Fraction + sfc2%Vegetation_Fraction
1631 sfcsum%Soil_Temperature = sfcsum%Soil_Temperature + sfc2%Soil_Temperature
1632 sfcsum%LAI = sfcsum%LAI + sfc2%LAI
1633 sfcsum%Water_Temperature = sfcsum%Water_Temperature + sfc2%Water_Temperature
1634 sfcsum%Wind_Speed = sfcsum%Wind_Speed + sfc2%Wind_Speed
1635 sfcsum%Wind_Direction = sfcsum%Wind_Direction + sfc2%Wind_Direction
1636 sfcsum%Salinity = sfcsum%Salinity + sfc2%Salinity
1637 sfcsum%Snow_Temperature = sfcsum%Snow_Temperature + sfc2%Snow_Temperature
1638 sfcsum%Snow_Depth = sfcsum%Snow_Depth + sfc2%Snow_Depth
1639 sfcsum%Snow_Density = sfcsum%Snow_Density + sfc2%Snow_Density
1640 sfcsum%Snow_Grain_Size = sfcsum%Snow_Grain_Size + sfc2%Snow_Grain_Size
1641 sfcsum%Ice_Temperature = sfcsum%Ice_Temperature + sfc2%Ice_Temperature
1642 sfcsum%Ice_Thickness = sfcsum%Ice_Thickness + sfc2%Ice_Thickness
1643 sfcsum%Ice_Density = sfcsum%Ice_Density + sfc2%Ice_Density
1644 sfcsum%Ice_Roughness = sfcsum%Ice_Roughness + sfc2%Ice_Roughness
1648 sfcsum%SensorData = sfcsum%SensorData + sfc2%SensorData
1694 sfcdiff%Land_Temperature = sfcdiff%Land_Temperature - sfc2%Land_Temperature
1695 sfcdiff%Soil_Moisture_Content = sfcdiff%Soil_Moisture_Content - sfc2%Soil_Moisture_Content
1696 sfcdiff%Canopy_Water_Content = sfcdiff%Canopy_Water_Content - sfc2%Canopy_Water_Content
1697 sfcdiff%Vegetation_Fraction = sfcdiff%Vegetation_Fraction - sfc2%Vegetation_Fraction
1698 sfcdiff%Soil_Temperature = sfcdiff%Soil_Temperature - sfc2%Soil_Temperature
1699 sfcdiff%LAI = sfcdiff%LAI - sfc2%LAI
1700 sfcdiff%Water_Temperature = sfcdiff%Water_Temperature - sfc2%Water_Temperature
1701 sfcdiff%Wind_Speed = sfcdiff%Wind_Speed - sfc2%Wind_Speed
1702 sfcdiff%Wind_Direction = sfcdiff%Wind_Direction - sfc2%Wind_Direction
1703 sfcdiff%Salinity = sfcdiff%Salinity - sfc2%Salinity
1704 sfcdiff%Snow_Temperature = sfcdiff%Snow_Temperature - sfc2%Snow_Temperature
1705 sfcdiff%Snow_Depth = sfcdiff%Snow_Depth - sfc2%Snow_Depth
1706 sfcdiff%Snow_Density = sfcdiff%Snow_Density - sfc2%Snow_Density
1707 sfcdiff%Snow_Grain_Size = sfcdiff%Snow_Grain_Size - sfc2%Snow_Grain_Size
1708 sfcdiff%Ice_Temperature = sfcdiff%Ice_Temperature - sfc2%Ice_Temperature
1709 sfcdiff%Ice_Thickness = sfcdiff%Ice_Thickness - sfc2%Ice_Thickness
1710 sfcdiff%Ice_Density = sfcdiff%Ice_Density - sfc2%Ice_Density
1711 sfcdiff%Ice_Roughness = sfcdiff%Ice_Roughness - sfc2%Ice_Roughness
1715 sfcdiff%SensorData = sfcdiff%SensorData - sfc2%SensorData
1736 sfc%Land_Temperature =
zero 1737 sfc%Soil_Moisture_Content =
zero 1738 sfc%Canopy_Water_Content =
zero 1739 sfc%Vegetation_Fraction =
zero 1740 sfc%Soil_Temperature =
zero 1748 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_LandSurface_IsValid' 1749 CHARACTER(ML) :: msg
1755 IF ( sfc%Land_Type < 1 )
THEN 1756 msg =
'Invalid Land Surface type' 1760 IF ( sfc%Land_Temperature <
zero .OR. &
1761 sfc%Soil_Moisture_Content <
zero .OR. &
1762 sfc%Canopy_Water_Content <
zero .OR. &
1763 sfc%Vegetation_Fraction <
zero .OR. &
1764 sfc%Soil_Temperature <
zero .OR. &
1765 sfc%LAI <
zero )
THEN 1766 msg =
'Invalid Land Surface data' 1775 TYPE(CRTM_Surface_type),
INTENT(IN) :: Sfc
1776 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
1779 IF (
PRESENT(unit) )
THEN 1782 WRITE(fid,
'(3x,"Land type index :",1x,i0)') sfc%Land_Type
1783 WRITE(fid,
'(3x,"Land Temperature :",1x,es13.6)') sfc%Land_Temperature
1784 WRITE(fid,
'(3x,"Soil Moisture Content:",1x,es13.6)') sfc%Soil_Moisture_Content
1785 WRITE(fid,
'(3x,"Canopy Water Content :",1x,es13.6)') sfc%Canopy_Water_Content
1786 WRITE(fid,
'(3x,"Vegetation Fraction :",1x,es13.6)') sfc%Vegetation_Fraction
1787 WRITE(fid,
'(3x,"Soil Temperature :",1x,es13.6)') sfc%Soil_Temperature
1788 WRITE(fid,
'(3x,"Leaf Area Index :",1x,es13.6)') sfc%LAI
1789 WRITE(fid,
'(3x,"Soil type index :",1x,i0)') sfc%Soil_Type
1790 WRITE(fid,
'(3x,"Vegetation type index:",1x,i0)') sfc%Vegetation_Type
1796 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
1797 LOGICAL :: is_comparable
1802 is_comparable = .false.
1803 IF (
PRESENT(n_sigfig) )
THEN 1810 IF ( x%Land_Type /= y%Land_Type .OR. &
1811 x%Soil_Type /= y%Soil_Type .OR. &
1812 x%Vegetation_Type /= y%Vegetation_Type )
RETURN 1823 is_comparable = .true.
1831 is_equal = ( (x%Land_Type == y%Land_Type ) .AND. &
1832 (x%Land_Temperature .equalto. y%Land_Temperature ) .AND. &
1833 (x%Soil_Moisture_Content .equalto. y%Soil_Moisture_Content) .AND. &
1834 (x%Canopy_Water_Content .equalto. y%Canopy_Water_Content ) .AND. &
1835 (x%Vegetation_Fraction .equalto. y%Vegetation_Fraction ) .AND. &
1836 (x%Soil_Temperature .equalto. y%Soil_Temperature ) .AND. &
1837 (x%LAI .equalto. y%LAI ) .AND. &
1838 (x%Soil_Type == y%Soil_Type ) .AND. &
1839 (x%Vegetation_Type == y%Vegetation_Type ) )
1849 sfc%Water_Temperature =
zero 1850 sfc%Wind_Speed =
zero 1851 sfc%Wind_Direction =
zero 1859 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_WaterSurface_IsValid' 1860 CHARACTER(ML) :: msg
1866 IF ( sfc%Water_Type < 1 )
THEN 1867 msg =
'Invalid Water Surface type' 1871 IF ( sfc%Water_Temperature <
zero .OR. &
1872 sfc%Wind_Speed <
zero .OR. &
1873 sfc%Wind_Direction <
zero .OR. &
1874 sfc%Salinity <
zero )
THEN 1875 msg =
'Invalid Water Surface data' 1884 TYPE(CRTM_Surface_type),
INTENT(IN) :: Sfc
1885 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
1888 IF (
PRESENT(unit) )
THEN 1891 WRITE(fid,
'(3x,"Water Type index :",1x,i0)') sfc%Water_Type
1892 WRITE(fid,
'(3x,"Water Temperature:",1x,es13.6)') sfc%Water_Temperature
1893 WRITE(fid,
'(3x,"Wind Speed :",1x,es13.6)') sfc%Wind_Speed
1894 WRITE(fid,
'(3x,"Wind Direction :",1x,es13.6)') sfc%Wind_Direction
1895 WRITE(fid,
'(3x,"Salinity :",1x,es13.6)') sfc%Salinity
1901 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
1902 LOGICAL :: is_comparable
1907 is_comparable = .false.
1908 IF (
PRESENT(n_sigfig) )
THEN 1915 IF ( x%Water_Type /= y%Water_Type )
RETURN 1924 is_comparable = .true.
1932 is_equal = ( (x%Water_Type == y%Water_Type ) .AND. &
1933 (x%Water_Temperature .equalto. y%Water_Temperature) .AND. &
1934 (x%Wind_Speed .equalto. y%Wind_Speed ) .AND. &
1935 (x%Wind_Direction .equalto. y%Wind_Direction ) .AND. &
1936 (x%Salinity .equalto. y%Salinity ) )
1946 sfc%Snow_Temperature =
zero 1947 sfc%Snow_Depth =
zero 1948 sfc%Snow_Density =
zero 1949 sfc%Snow_Grain_Size =
zero 1956 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_SnowSurface_IsValid' 1957 CHARACTER(ML) :: msg
1963 IF ( sfc%Snow_Type < 1 )
THEN 1964 msg =
'Invalid Snow Surface type' 1968 IF ( sfc%Snow_Temperature <
zero .OR. &
1969 sfc%Snow_Depth <
zero .OR. &
1970 sfc%Snow_Density <
zero .OR. &
1971 sfc%Snow_Grain_Size <
zero )
THEN 1972 msg =
'Invalid Snow Surface data' 1981 TYPE(CRTM_Surface_type),
INTENT(IN) :: Sfc
1982 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
1985 IF (
PRESENT(unit) )
THEN 1988 WRITE(fid,
'(3x,"Snow Type index :",1x,i0)') sfc%Snow_Type
1989 WRITE(fid,
'(3x,"Snow Temperature:",1x,es13.6)') sfc%Snow_Temperature
1990 WRITE(fid,
'(3x,"Snow Depth :",1x,es13.6)') sfc%Snow_Depth
1991 WRITE(fid,
'(3x,"Snow Density :",1x,es13.6)') sfc%Snow_Density
1992 WRITE(fid,
'(3x,"Snow Grain_Size :",1x,es13.6)') sfc%Snow_Grain_Size
1998 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
1999 LOGICAL :: is_comparable
2004 is_comparable = .false.
2005 IF (
PRESENT(n_sigfig) )
THEN 2012 IF ( x%Snow_Type /= y%Snow_Type )
RETURN 2021 is_comparable = .true.
2029 is_equal = ( (x%Snow_Type == y%Snow_Type ) .AND. &
2030 (x%Snow_Temperature .equalto. y%Snow_Temperature) .AND. &
2031 (x%Snow_Depth .equalto. y%Snow_Depth ) .AND. &
2032 (x%Snow_Density .equalto. y%Snow_Density ) .AND. &
2033 (x%Snow_Grain_Size .equalto. y%Snow_Grain_Size ) )
2043 sfc%Ice_Temperature =
zero 2044 sfc%Ice_Thickness =
zero 2045 sfc%Ice_Density =
zero 2046 sfc%Ice_Roughness =
zero 2053 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_IceSurface_IsValid' 2054 CHARACTER(ML) :: msg
2060 IF ( sfc%Ice_Type < 1 )
THEN 2061 msg =
'Invalid Ice Surface type' 2065 IF ( sfc%Ice_Temperature <
zero .OR. &
2066 sfc%Ice_Thickness <
zero .OR. &
2067 sfc%Ice_Density <
zero .OR. &
2068 sfc%Ice_Roughness <
zero )
THEN 2069 msg =
'Invalid Ice Surface data' 2078 TYPE(CRTM_Surface_type),
INTENT(IN) :: Sfc
2079 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
2082 IF (
PRESENT(unit) )
THEN 2085 WRITE(fid,
'(3x,"Ice Type index :",1x,i0)') sfc%Ice_Type
2086 WRITE(fid,
'(3x,"Ice Temperature:",1x,es13.6)') sfc%Ice_Temperature
2087 WRITE(fid,
'(3x,"Ice Thickness :",1x,es13.6)') sfc%Ice_Thickness
2088 WRITE(fid,
'(3x,"Ice Density :",1x,es13.6)') sfc%Ice_Density
2089 WRITE(fid,
'(3x,"Ice Roughness :",1x,es13.6)') sfc%Ice_Roughness
2095 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
2096 LOGICAL :: is_comparable
2101 is_comparable = .false.
2102 IF (
PRESENT(n_sigfig) )
THEN 2109 IF ( x%Ice_Type /= y%Ice_Type )
RETURN 2118 is_comparable = .true.
2126 is_equal = ( (x%Ice_Type == y%Ice_Type ) .AND. &
2127 (x%Ice_Temperature .equalto. y%Ice_Temperature) .AND. &
2128 (x%Ice_Thickness .equalto. y%Ice_Thickness ) .AND. &
2129 (x%Ice_Density .equalto. y%Ice_Density ) .AND. &
2130 (x%Ice_Roughness .equalto. y%Ice_Roughness ) )
2145 Quiet , & ! Optional input
2149 INTEGER,
INTENT(IN) :: fid
2151 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
2152 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
2156 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_ReadFile(Record)' 2158 CHARACTER(ML) :: msg
2159 CHARACTER(ML) :: io_msg
2162 INTEGER :: coverage_type
2163 INTEGER :: n_channels
2169 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
2171 IF (
PRESENT(debug) )
THEN 2172 IF ( debug ) noisy = .true.
2177 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2179 sfc%Land_Coverage, &
2180 sfc%Water_Coverage, &
2181 sfc%Snow_Coverage, &
2183 IF ( io_stat /= 0 )
THEN 2184 msg =
'Error reading gross surface type data - '//trim(io_msg)
2189 msg =
'Invalid surface coverage fraction(s) found' 2194 msg =
'Coverage surface type, '//&
2196 ', inconsistent with that specified in file.' 2202 READ( fid,iostat=io_stat,iomsg=io_msg ) sfc%Wind_Speed
2203 IF ( io_stat /= 0 )
THEN 2204 msg =
'Error reading surface type independent data - '//trim(io_msg)
2210 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2212 sfc%Land_Temperature, &
2213 sfc%Soil_Moisture_Content, &
2214 sfc%Canopy_Water_Content , &
2215 sfc%Vegetation_Fraction, &
2216 sfc%Soil_Temperature, &
2218 IF ( io_stat /= 0 )
THEN 2219 msg =
'Error reading land surface type data - '//trim(io_msg)
2225 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2227 sfc%Water_Temperature, &
2228 sfc%Wind_Direction, &
2230 IF ( io_stat /= 0 )
THEN 2231 msg =
'Error reading water surface type data - '//trim(io_msg)
2237 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2239 sfc%Snow_Temperature, &
2243 IF ( io_stat /= 0 )
THEN 2244 msg =
'Error reading snow surface type data - '//trim(io_msg)
2250 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2252 sfc%Ice_Temperature, &
2253 sfc%Ice_Thickness, &
2256 IF ( io_stat /= 0 )
THEN 2257 msg =
'Error reading ice surface type data - '//trim(io_msg)
2264 READ( fid,iostat=io_stat,iomsg=io_msg ) n_channels
2265 IF ( io_stat /= 0 )
THEN 2266 msg =
'Error reading SensorData dimensions - '//trim(io_msg)
2270 IF ( n_channels > 0 )
THEN 2273 msg =
'Error creating SensorData object.' 2276 READ( fid,iostat=io_stat,iomsg=io_msg ) &
2277 sfc%SensorData%Sensor_ID , &
2278 sfc%SensorData%WMO_Satellite_ID, &
2279 sfc%SensorData%WMO_Sensor_ID , &
2280 sfc%SensorData%Sensor_Channel , &
2282 IF ( io_stat /= 0 )
THEN 2283 msg =
'Error reading SensorData - '//trim(io_msg)
2292 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
2294 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
2313 Quiet, & ! Optional input
2317 INTEGER,
INTENT(IN) :: fid
2319 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
2320 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
2324 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Surface_WriteFile(Record)' 2326 CHARACTER(ML) :: msg
2327 CHARACTER(ML) :: io_msg
2336 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
2338 IF (
PRESENT(debug) )
THEN 2339 IF ( debug ) noisy = .true.
2344 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2346 sfc%Land_Coverage, &
2347 sfc%Water_Coverage, &
2348 sfc%Snow_Coverage, &
2350 IF ( io_stat /= 0 )
THEN 2351 msg =
'Error writing gross surface type data - '//trim(io_msg)
2357 WRITE( fid,iostat=io_stat,iomsg=io_msg ) sfc%Wind_Speed
2358 IF ( io_stat /= 0 )
THEN 2359 msg =
'Error writing surface type independent data - '//trim(io_msg)
2365 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2367 sfc%Land_Temperature, &
2368 sfc%Soil_Moisture_Content, &
2369 sfc%Canopy_Water_Content, &
2370 sfc%Vegetation_Fraction, &
2371 sfc%Soil_Temperature, &
2373 IF ( io_stat /= 0 )
THEN 2374 msg =
'Error writing land surface type data - '//trim(io_msg)
2380 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2382 sfc%Water_Temperature, &
2383 sfc%Wind_Direction, &
2385 IF ( io_stat /= 0 )
THEN 2386 msg =
'Error writing water surface type data - '//trim(io_msg)
2392 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2394 sfc%Snow_Temperature, &
2398 IF ( io_stat /= 0 )
THEN 2399 msg =
'Error writing snow surface type data - '//trim(io_msg)
2405 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2407 sfc%Ice_Temperature, &
2408 sfc%Ice_Thickness, &
2411 IF ( io_stat /= 0 )
THEN 2412 msg =
'Error writing ice surface type data - '//trim(io_msg)
2419 WRITE( fid,iostat=io_stat,iomsg=io_msg ) sfc%SensorData%n_Channels
2420 IF ( io_stat /= 0 )
THEN 2421 msg =
'Error writing SensorData dimensions - '//trim(io_msg)
2425 IF ( sfc%SensorData%n_Channels > 0 )
THEN 2426 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
2427 sfc%SensorData%Sensor_ID , &
2428 sfc%SensorData%WMO_Satellite_ID, &
2429 sfc%SensorData%WMO_Sensor_ID , &
2430 sfc%SensorData%Sensor_Channel , &
2432 IF ( io_stat /= 0 )
THEN 2433 msg =
'Error writing SensorData - '//trim(io_msg)
2443 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
logical function crtm_watersurface_isvalid(Sfc)
integer, parameter default_vegetation_type
real(fp), parameter default_vegetation_fraction
elemental subroutine, public crtm_sensordata_create(SensorData, n_Channels)
elemental subroutine crtm_landsurface_zero(Sfc)
integer, parameter, public failure
subroutine, public crtm_surface_inspect(Sfc, Unit)
subroutine, public crtm_sensordata_inspect(SensorData, Unit)
elemental integer function, public crtm_surface_coveragetype(sfc)
integer, parameter, public warning
real(fp), parameter default_snow_temperature
elemental logical function crtm_watersurface_equal(x, y)
real(fp), parameter default_ice_roughness
logical function crtm_icesurface_isvalid(Sfc)
integer, parameter, public fp
elemental logical function, public crtm_sensordata_associated(SensorData)
character(*), parameter module_version_id
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
elemental logical function crtm_icesurface_equal(x, y)
subroutine crtm_watersurface_inspect(Sfc, Unit)
elemental logical function, public crtm_sensordata_compare(x, y, n_SigFig)
integer, parameter default_land_type
integer function, public crtm_sensordata_writefile(Filename, SensorData, Quiet, No_Close, Debug)
integer function, public crtm_surface_inquirefile(Filename, n_Channels, n_Profiles)
real(fp), parameter default_land_temperature
real(fp), parameter default_snow_grain_size
integer, parameter, public ice_surface
elemental logical function crtm_surface_equal(x, y)
real(fp), parameter default_soil_temperature
real(fp), parameter default_wind_speed
elemental logical function crtm_snowsurface_compare(x, y, n_SigFig)
subroutine inquire_cleanup()
elemental logical function crtm_landsurface_compare(x, y, n_SigFig)
integer function read_record(fid, sfc, Quiet, Debug)
logical function, public crtm_sensordata_isvalid(SensorData)
integer, parameter, public n_valid_surface_types
character(*), dimension(0:n_valid_surface_types), parameter, public surface_type_name
elemental subroutine crtm_watersurface_zero(Sfc)
real(fp), parameter default_ice_temperature
character(*), parameter write_error_status
subroutine read_cleanup()
elemental subroutine, public crtm_sensordata_destroy(SensorData)
integer, parameter, public invalid_surface
subroutine write_cleanup()
real(fp), parameter default_snow_depth
elemental subroutine, public crtm_sensordata_zero(SensorData)
subroutine read_record_cleanup()
elemental logical function crtm_icesurface_compare(x, y, n_SigFig)
elemental subroutine crtm_snowsurface_zero(Sfc)
elemental subroutine, public crtm_surface_destroy(Sfc)
elemental logical function, public crtm_surface_associated(Sfc)
real(fp), parameter default_wind_direction
real(fp), parameter default_soil_moisture_content
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
real(fp), parameter default_water_temperature
integer, parameter default_soil_type
elemental subroutine crtm_icesurface_zero(Sfc)
logical function, public crtm_surface_iscoveragevalid(Sfc)
elemental subroutine, public crtm_surface_zero(Sfc)
elemental logical function crtm_snowsurface_equal(x, y)
integer, parameter default_water_type
integer, parameter default_ice_type
logical function, public crtm_surface_isvalid(Sfc)
integer function write_surface_rank1(Filename, Surface, Quiet, Debug)
integer, parameter, public land_surface
elemental logical function crtm_watersurface_compare(x, y, n_SigFig)
integer, parameter, public default_n_sigfig
logical function iscoveragevalid(Coverage, Name)
real(fp), parameter default_canopy_water_content
subroutine crtm_snowsurface_inspect(Sfc, Unit)
elemental logical function crtm_landsurface_equal(x, y)
elemental type(crtm_surface_type) function crtm_surface_subtract(sfc1, sfc2)
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
subroutine, public crtm_sensordata_defineversion(Id)
integer function write_surface_rank2(Filename, Surface, Quiet, Debug)
subroutine write_record_cleanup()
real(fp), parameter default_snow_density
integer function read_surface_rank2(Filename, Surface, Quiet, n_Channels, n_Profiles, Debug)
real(fp), parameter default_ice_density
integer function read_surface_rank1(Filename, Surface, Quiet, n_Channels, n_Profiles, Debug)
integer, parameter default_snow_type
subroutine, public crtm_surface_defineversion(Id)
integer function, public crtm_sensordata_readfile(Filename, SensorData, Quiet, No_Close, n_DataSets, Debug)
logical function crtm_landsurface_isvalid(Sfc)
subroutine crtm_icesurface_inspect(Sfc, Unit)
elemental logical function, public crtm_surface_compare(x, y, n_SigFig)
subroutine crtm_landsurface_inspect(Sfc, Unit)
real(fp), parameter default_ice_thickness
elemental type(crtm_surface_type) function crtm_surface_add(sfc1, sfc2)
logical function crtm_snowsurface_isvalid(Sfc)
real(fp), parameter default_salinity
integer, parameter, public water_surface
elemental subroutine, public crtm_surface_create(Sfc, n_Channels)
real(fp), parameter default_lai
integer, parameter, public success
integer, parameter, public snow_surface
integer, parameter, public information