22 USE iso_fortran_env ,
ONLY: output_unit
27 OPERATOR(.equalto.), &
55 PUBLIC ::
OPERATOR(==)
80 INTERFACE OPERATOR(==)
82 END INTERFACE OPERATOR(==)
86 END INTERFACE OPERATOR(+)
90 END INTERFACE OPERATOR(-)
103 '$Id: CRTM_Cloud_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
144 LOGICAL :: is_allocated = .false.
146 INTEGER :: max_layers = 0
147 INTEGER :: n_layers = 0
149 INTEGER :: n_added_layers = 0
153 REAL(fp),
ALLOCATABLE :: effective_radius(:)
154 REAL(fp),
ALLOCATABLE :: effective_variance(:)
155 REAL(fp),
ALLOCATABLE :: water_content(:)
180 CHARACTER(LEN(CLOUD_CATEGORY_NAME(1))) :: name
187 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: list(:)
189 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_CategoryList' 190 CHARACTER(ML) :: alloc_msg, msg
191 INTEGER :: alloc_stat
194 IF ( alloc_stat /= 0 )
THEN 196 msg =
'Cloud category list result not allocated -'//trim(alloc_msg)
240 status =
cloud%Is_Allocated
268 cloud%Is_Allocated = .false.
305 INTEGER,
INTENT(IN) :: n_layers
307 INTEGER :: alloc_stat
310 IF ( n_layers < 1 )
RETURN 313 ALLOCATE(
cloud%Effective_Radius( n_layers ), &
314 cloud%Effective_Variance( n_layers ), &
315 cloud%Water_Content( n_layers ), &
317 IF ( alloc_stat /= 0 )
RETURN 321 cloud%Max_Layers = n_layers
322 cloud%n_Layers = n_layers
329 cloud%Is_Allocated = .true.
379 INTEGER,
INTENT(IN) :: n_added_layers
383 INTEGER :: na, no, nt
386 na =
max(n_added_layers,0)
394 cld_out%n_Added_Layers = cld%n_Added_Layers+na
396 cld_out%Type = cld%Type
399 nt = cld_out%n_Layers
400 cld_out%Effective_Radius(na+1:nt) = cld%Effective_Radius(1:no)
401 cld_out%Effective_Variance(na+1:nt) = cld%Effective_Variance(1:no)
402 cld_out%Water_Content(na+1:nt) = cld%Water_Content(1:no)
488 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_IsValid' 495 msg =
'Cloud structure not allocated' 499 IF (
cloud%n_Layers < 1 )
THEN 500 msg =
'Cloud structure dimension invalid' 510 msg =
'Invalid cloud type' 515 IF ( any(
cloud%Effective_Radius <
zero ) )
THEN 516 msg =
'Negative cloud effective radius found' 520 IF ( any(
cloud%Effective_Variance <
zero ) )
THEN 521 msg =
'Negative cloud effective variance found' 525 IF ( any(
cloud%Water_Content <
zero ) )
THEN 526 msg =
'Negative cloud water content found' 567 TYPE(CRTM_Cloud_type),
INTENT(IN) :: Cloud
568 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
574 IF (
PRESENT(unit) )
THEN 579 WRITE(fid,
'(1x,"CLOUD OBJECT")')
580 WRITE(fid,
'(3x,"n_Layers :",1x,i0)')
cloud%n_Layers
583 WRITE(fid,
'(3x,"Effective radius:")')
584 WRITE(fid,
'(5(1x,es13.6,:))')
cloud%Effective_Radius
585 WRITE(fid,
'(3x,"Water content:")')
586 WRITE(fid,
'(5(1x,es13.6,:))')
cloud%Water_Content
590 TYPE(CRTM_Cloud_type),
INTENT(IN) :: Cloud(:)
591 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
595 IF (
PRESENT(unit) )
THEN 598 DO i = 1,
SIZE(
cloud)
599 WRITE(fid, fmt=
'(1x,"RANK-1 INDEX:",i0," - ")', advance=
'NO') i
605 TYPE(CRTM_Cloud_type),
INTENT(IN) :: Cloud(:,:)
606 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
610 IF (
PRESENT(unit) )
THEN 613 DO j = 1,
SIZE(
cloud,2)
614 DO i = 1,
SIZE(
cloud,1)
615 WRITE(fid, fmt=
'(1x,"RANK-2 INDEX:",i0,",",i0," - ")', advance=
'NO') i,j
646 CHARACTER(*),
INTENT(OUT) :: id
690 result( is_comparable )
692 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
693 LOGICAL :: is_comparable
698 is_comparable = .false.
699 IF (
PRESENT(n_sigfig) )
THEN 710 IF ( (x%n_Layers /= y%n_Layers) .OR. &
711 (x%Type /= y%Type ) )
RETURN 719 is_comparable = .true.
767 INTEGER,
INTENT(IN) :: n_layers
768 IF ( n_layers <
cloud%Max_Layers )
THEN 769 cloud%n_Layers = n_layers
822 CHARACTER(*),
INTENT(IN) :: filename
823 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_clouds
827 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_InquireFile' 830 CHARACTER(ML) :: io_msg
841 IF ( err_stat /=
success )
THEN 842 msg =
'Error opening '//trim(filename)
848 READ( fid,iostat=io_stat,iomsg=io_msg ) nc
849 IF ( io_stat /= 0 )
THEN 850 msg =
'Error reading n_Clouds dimension from '//trim(filename)//
' - '//trim(io_msg)
856 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
857 IF ( io_stat /= 0 )
THEN 858 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
864 IF (
PRESENT(n_clouds) ) n_clouds = nc
870 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
872 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
954 Quiet , & ! Optional input
955 No_Close, & ! Optional input
956 n_Clouds, & ! Optional output
960 CHARACTER(*),
INTENT(IN) :: filename
962 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
963 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
964 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_clouds
965 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
969 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_ReadFile' 972 CHARACTER(ML) :: io_msg
973 CHARACTER(ML) :: alloc_msg
975 INTEGER :: alloc_stat
986 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
989 IF (
PRESENT(no_close) ) yes_close = .NOT. no_close
991 IF (
PRESENT(debug) ) noisy = debug
998 INQUIRE( file=filename,number=fid )
999 IF ( fid == -1 )
THEN 1000 msg =
'Error inquiring '//trim(filename)//
' for its unit number' 1007 IF ( err_stat /=
success )
THEN 1008 msg =
'Error opening '//trim(filename)
1015 READ( fid,iostat=io_stat,iomsg=io_msg ) nc
1016 IF ( io_stat /= 0 )
THEN 1017 msg =
'Error reading n_Clouds data dimension from '//trim(filename)//
' - '//trim(io_msg)
1021 ALLOCATE(
cloud(nc), stat=alloc_stat, errmsg=alloc_msg)
1022 IF ( alloc_stat /= 0 )
THEN 1023 msg =
'Error allocating Cloud array - '//trim(alloc_msg)
1029 cloud_loop:
DO m = 1, nc
1031 IF ( err_stat /=
success )
THEN 1032 WRITE( msg,
'("Error reading Cloud element #",i0," from ",a)' ) m, trim(filename)
1039 IF ( yes_close )
THEN 1040 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1041 IF ( io_stat /= 0 )
THEN 1042 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1049 IF (
PRESENT(n_clouds) ) n_clouds = nc
1054 WRITE( msg,
'("Number of clouds read from ",a,": ",i0)' ) trim(filename), nc
1062 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1063 IF ( io_stat /= 0 ) &
1064 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1066 IF (
ALLOCATED(
cloud) )
THEN 1067 DEALLOCATE(
cloud, stat=alloc_stat, errmsg=alloc_msg)
1068 IF ( alloc_stat /= 0 ) &
1069 msg = trim(msg)//
'; Error deallocating Cloud array during error cleanup - '//&
1148 Quiet , & ! Optional input
1149 No_Close, & ! Optional input
1153 CHARACTER(*),
INTENT(IN) :: filename
1155 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1156 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
1157 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1161 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_WriteFile' 1163 CHARACTER(ML) :: msg
1164 CHARACTER(ML) :: io_msg
1167 LOGICAL :: yes_close
1175 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1178 IF (
PRESENT(no_close) ) yes_close = .NOT. no_close
1180 IF (
PRESENT(debug) ) noisy = debug
1184 IF ( any(
cloud%n_Layers < 1) )
THEN 1185 msg =
'Dimensions of Cloud structures are < or = 0.' 1193 INQUIRE( file=filename,number=fid )
1194 IF ( fid == -1 )
THEN 1195 msg =
'Error inquiring '//trim(filename)//
' for its unit number' 1201 IF ( err_stat /=
success )
THEN 1202 msg =
'Error opening '//trim(filename)
1210 WRITE( fid,iostat=io_stat,iomsg=io_msg ) nc
1211 IF ( io_stat /= 0 )
THEN 1212 msg =
'Error writing n_Clouds data dimension to '//trim(filename)//
'- '//trim(io_msg)
1218 cloud_loop:
DO m = 1, nc
1220 IF ( err_stat /=
success )
THEN 1221 WRITE( msg,
'("Error writing Cloud element #",i0," to ",a)' ) m, trim(filename)
1228 IF ( yes_close )
THEN 1229 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
1230 IF ( io_stat /= 0 )
THEN 1231 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
1239 WRITE( msg,
'("Number of clouds written to ",a,": ",i0)' ) trim(filename), nc
1248 IF ( io_stat /= 0 ) &
1249 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
1315 IF ( (x%n_Layers /= y%n_Layers) .OR. (x%Type /= y%Type) )
RETURN 1318 IF ( all(x%Effective_Radius(1:n) .equalto. y%Effective_Radius(1:n) ) .AND. &
1319 all(x%Effective_Variance(1:n) .equalto. y%Effective_Variance(1:n)) .AND. &
1320 all(x%Water_Content(1:n) .equalto. y%Water_Content(1:n) ) ) &
1369 IF ( cld1%Type /= cld2%Type .OR. &
1370 cld1%n_Layers /= cld2%n_Layers .OR. &
1371 cld1%n_Added_Layers /= cld2%n_Added_Layers )
RETURN 1378 cldsum%Effective_Radius(1:n) = cldsum%Effective_Radius(1:n) + cld2%Effective_Radius(1:n)
1379 cldsum%Effective_Variance(1:n) = cldsum%Effective_Variance(1:n) + cld2%Effective_Variance(1:n)
1380 cldsum%Water_Content(1:n) = cldsum%Water_Content(1:n) + cld2%Water_Content(1:n)
1428 IF ( cld1%Type /= cld2%Type .OR. &
1429 cld1%n_Layers /= cld2%n_Layers .OR. &
1430 cld1%n_Added_Layers /= cld2%n_Added_Layers )
RETURN 1437 clddiff%Effective_Radius(1:n) = clddiff%Effective_Radius(1:n) - cld2%Effective_Radius(1:n)
1438 clddiff%Effective_Variance(1:n) = clddiff%Effective_Variance(1:n) - cld2%Effective_Variance(1:n)
1439 clddiff%Water_Content(1:n) = clddiff%Water_Content(1:n) - cld2%Water_Content(1:n)
1457 INTEGER ,
INTENT(IN) :: fid
1462 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_ReadFile(Record)' 1464 CHARACTER(ML) :: msg
1465 CHARACTER(ML) :: io_msg
1474 READ( fid,iostat=io_stat,iomsg=io_msg ) n_layers
1475 IF ( io_stat /= 0 )
THEN 1476 msg =
'Error reading n_Layers dimension - '//trim(io_msg)
1484 msg =
'Cloud object allocation failed.' 1490 READ( fid,iostat=io_stat,iomsg=io_msg ) &
1492 cloud%Effective_Radius, &
1493 cloud%Effective_Variance, &
1495 IF ( io_stat /= 0 )
THEN 1496 msg =
'Error reading Cloud data - '//trim(io_msg)
1504 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1506 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
1527 INTEGER ,
INTENT(IN) :: fid
1532 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Cloud_WriteFile(Record)' 1534 CHARACTER(ML) :: msg
1535 CHARACTER(ML) :: io_msg
1541 msg =
'Input Cloud object is not used.' 1547 WRITE( fid,iostat=io_stat,iomsg=io_msg )
cloud%n_Layers
1548 IF ( io_stat /= 0 )
THEN 1549 msg =
'Error writing dimensions - '//trim(io_msg)
1555 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1558 cloud%Effective_Variance(1:
cloud%n_Layers), &
1560 IF ( io_stat /= 0 )
THEN 1561 msg =
'Error writing Cloud data - '//trim(io_msg)
1570 msg = trim(msg)//
'; Error closing file during error cleanup' integer, parameter, public ice_cloud
integer, parameter, public n_valid_cloud_categories
integer, parameter, public failure
pure integer function, public crtm_cloud_categoryid(cloud)
elemental type(crtm_cloud_type) function, public crtm_cloud_addlayercopy(cld, n_Added_Layers)
integer, parameter, public warning
integer function, public crtm_cloud_inquirefile(Filename, n_Clouds)
integer, parameter, public fp
integer function, public crtm_cloud_readfile(Filename, Cloud, Quiet, No_Close, n_Clouds, Debug)
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
integer, parameter, public rain_cloud
elemental subroutine, public crtm_cloud_create(Cloud, n_Layers)
integer function, public crtm_cloud_writefile(Filename, Cloud, Quiet, No_Close, Debug)
elemental logical function, public crtm_cloud_compare(x, y, n_SigFig)
integer, dimension(0:n_valid_cloud_categories), parameter cloud_category_list
subroutine scalar_inspect(Cloud, Unit)
subroutine inquire_cleanup()
integer, parameter, public invalid_cloud
character(*), dimension(0:n_valid_cloud_categories), parameter, public cloud_category_name
character(*), parameter write_error_status
elemental type(crtm_cloud_type) function crtm_cloud_subtract(cld1, cld2)
elemental subroutine, public crtm_cloud_setlayers(Cloud, n_Layers)
integer function read_record(fid, cloud)
subroutine read_cleanup()
subroutine write_cleanup()
subroutine rank1_inspect(Cloud, Unit)
elemental subroutine, public crtm_cloud_zero(Cloud)
subroutine read_record_cleanup()
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
elemental type(crtm_cloud_type) function crtm_cloud_add(cld1, cld2)
integer, parameter, public snow_cloud
integer, parameter, public default_n_sigfig
integer function, public crtm_cloud_categorylist(list)
integer, parameter, public hail_cloud
character(*), parameter module_version_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 logical function crtm_cloud_equal(x, y)
subroutine, public crtm_cloud_defineversion(Id)
elemental subroutine, public crtm_cloud_destroy(Cloud)
logical function, public crtm_cloud_isvalid(Cloud)
pure character(len(cloud_category_name(1))) function, public crtm_cloud_categoryname(cloud)
integer, parameter, public water_cloud
subroutine rank2_inspect(Cloud, Unit)
integer, parameter, public success
elemental logical function, public crtm_cloud_associated(Cloud)
integer, parameter, public information