21 USE iso_fortran_env ,
ONLY: output_unit
26 OPERATOR(.equalto.), &
56 PUBLIC ::
OPERATOR(==)
81 INTERFACE OPERATOR(==)
83 END INTERFACE OPERATOR(==)
87 END INTERFACE OPERATOR(+)
91 END INTERFACE OPERATOR(-)
104 '$Id: CRTM_Aerosol_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $' 129 'Sea salt (SSAM) ', &
130 'Sea salt (SSCM1)', &
131 'Sea salt (SSCM2)', &
132 'Sea salt (SSCM3)', &
137 REAL(fp),
PARAMETER ::
zero = 0.0_fp
138 REAL(fp),
PARAMETER ::
one = 1.0_fp
140 INTEGER,
PARAMETER ::
ml = 256
151 LOGICAL :: is_allocated = .false.
153 INTEGER :: max_layers = 0
154 INTEGER :: n_layers = 0
156 INTEGER :: n_added_layers = 0
160 REAL(fp),
ALLOCATABLE :: effective_radius(:)
161 REAL(fp),
ALLOCATABLE :: concentration(:)
186 CHARACTER(LEN(AEROSOL_CATEGORY_NAME(1))) :: name
193 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: list(:)
195 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_CategoryList' 196 CHARACTER(ML) :: alloc_msg, msg
197 INTEGER :: alloc_stat
200 IF ( alloc_stat /= 0 )
THEN 202 msg =
'Aerosol category list result not allocated -'//trim(alloc_msg)
246 status = aerosol%Is_Allocated
274 aerosol%Is_Allocated = .false.
311 INTEGER,
INTENT(IN) :: n_layers
313 INTEGER :: alloc_stat
316 IF ( n_layers < 1 )
RETURN 319 ALLOCATE( aerosol%Effective_Radius( n_layers ), &
320 aerosol%Concentration( n_layers ), &
322 IF ( alloc_stat /= 0 )
RETURN 326 aerosol%Max_Layers = n_layers
327 aerosol%n_Layers = n_layers
329 aerosol%Effective_Radius =
zero 330 aerosol%Concentration =
zero 333 aerosol%Is_Allocated = .true.
383 INTEGER,
INTENT(IN) :: n_added_layers
387 INTEGER :: na, no, nt
390 na =
max(n_added_layers,0)
397 aer_out%n_Added_Layers = aer%n_Added_Layers+na
399 aer_out%Type = aer%Type
402 nt = aer_out%n_Layers
403 aer_out%Effective_Radius(na+1:nt) = aer%Effective_Radius(1:no)
404 aer_out%Concentration(na+1:nt) = aer%Concentration(1:no)
441 aerosol%Effective_Radius =
zero 442 aerosol%Concentration =
zero 489 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_IsValid' 496 msg =
'Aerosol structure not allocated' 500 IF ( aerosol%n_Layers < 1 )
THEN 501 msg =
'Aerosol structure dimension invalid' 511 msg =
'Invalid Aerosol type' 516 IF ( any(aerosol%Effective_Radius <
zero ) )
THEN 517 msg =
'Negative Aerosol effective radius found' 521 IF ( any(aerosol%Concentration <
zero ) )
THEN 522 msg =
'Negative Aerosol concentration found' 564 TYPE(CRTM_Aerosol_type),
INTENT(IN) :: Aerosol
565 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
571 IF (
PRESENT(unit) )
THEN 576 WRITE(fid,
'(1x,"AEROSOL OBJECT")')
578 WRITE(fid,
'(3x,"n_Layers :",1x,i0)') aerosol%n_Layers
581 WRITE(fid,
'(3x,"Effective radius:")')
582 WRITE(fid,
'(5(1x,es13.6,:))') aerosol%Effective_Radius
583 WRITE(fid,
'(3x,"Concentration:")')
584 WRITE(fid,
'(5(1x,es13.6,:))') aerosol%Concentration
588 TYPE(CRTM_Aerosol_type),
INTENT(IN) :: Aerosol(:)
589 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
593 IF (
PRESENT(unit) )
THEN 596 DO i = 1,
SIZE(aerosol)
597 WRITE(fid, fmt=
'(1x,"RANK-1 INDEX:",i0," - ")', advance=
'NO') i
603 TYPE(CRTM_Aerosol_type),
INTENT(IN) :: Aerosol(:,:)
604 INTEGER,
OPTIONAL,
INTENT(IN) :: Unit
608 IF (
PRESENT(unit) )
THEN 611 DO j = 1,
SIZE(aerosol,2)
612 DO i = 1,
SIZE(aerosol,1)
613 WRITE(fid, fmt=
'(1x,"RANK-2 INDEX:",i0,",",i0," - ")', advance=
'NO') i,j
644 CHARACTER(*),
INTENT(OUT) :: id
688 result( is_comparable )
690 INTEGER,
OPTIONAL,
INTENT(IN) :: n_sigfig
691 LOGICAL :: is_comparable
696 is_comparable = .false.
697 IF (
PRESENT(n_sigfig) )
THEN 708 IF ( (x%n_Layers /= y%n_Layers) .OR. &
709 (x%Type /= y%Type ) )
RETURN 716 is_comparable = .true.
764 INTEGER,
INTENT(IN) :: n_layers
765 IF ( n_layers < aerosol%Max_Layers )
THEN 766 aerosol%n_Layers = n_layers
819 CHARACTER(*),
INTENT(IN) :: filename
820 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_aerosols
824 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_InquireFile' 827 CHARACTER(ML) :: io_msg
838 IF ( err_stat /=
success )
THEN 839 msg =
'Error opening '//trim(filename)
845 READ( fid,iostat=io_stat,iomsg=io_msg ) na
846 IF ( io_stat /= 0 )
THEN 847 msg =
'Error reading n_Aerosols dimension from '//trim(filename)//
' - '//trim(io_msg)
853 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
854 IF ( io_stat /= 0 )
THEN 855 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
861 IF (
PRESENT(n_aerosols) ) n_aerosols = na
867 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
869 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
951 Quiet , & ! Optional input
952 No_Close , & ! Optional input
953 n_Aerosols, & ! Optional output
957 CHARACTER(*),
INTENT(IN) :: filename
959 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
960 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
961 INTEGER,
OPTIONAL,
INTENT(OUT) :: n_aerosols
962 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
966 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_ReadFile' 969 CHARACTER(ML) :: io_msg
981 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
984 IF (
PRESENT(no_close) ) yes_close = .NOT. no_close
986 IF (
PRESENT(debug) ) noisy = debug
993 INQUIRE( file=filename,number=fid )
994 IF ( fid == -1 )
THEN 995 msg =
'Error inquiring '//trim(filename)//
' for its unit number' 1002 IF ( err_stat /=
success )
THEN 1003 msg =
'Error opening '//trim(filename)
1010 READ( fid,iostat=io_stat,iomsg=io_msg ) na
1011 IF ( io_stat /= 0 )
THEN 1012 msg =
'Error reading n_Aerosols data dimension from '//trim(filename)//
' - '//trim(io_msg)
1016 IF ( na >
SIZE(aerosol) )
THEN 1017 WRITE( msg,
'("Number of aerosols, ",i0," > size of the output ",& 1018 &"Aerosol object array, ",i0,".")' ) na,
SIZE(aerosol)
1024 aerosol_loop:
DO m = 1, na
1026 IF ( err_stat /=
success )
THEN 1027 WRITE( msg,
'("Error reading Aerosol element #",i0," from ",a)' ) m, trim(filename)
1034 IF ( yes_close )
THEN 1035 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1036 IF ( io_stat /= 0 )
THEN 1037 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1044 IF (
PRESENT(n_aerosols) ) n_aerosols = na
1049 WRITE( msg,
'("Number of aerosols read from ",a,": ",i0)' ) trim(filename), na
1057 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1058 IF ( io_stat /= 0 ) &
1059 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1138 Quiet , & ! Optional input
1139 No_Close, & ! Optional input
1143 CHARACTER(*),
INTENT(IN) :: filename
1145 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1146 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
1147 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1151 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_WriteFile' 1153 CHARACTER(ML) :: msg
1154 CHARACTER(ML) :: io_msg
1157 LOGICAL :: yes_close
1165 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1168 IF (
PRESENT(no_close) ) yes_close = .NOT. no_close
1170 IF (
PRESENT(debug) ) noisy = debug
1173 IF ( any(aerosol%n_Layers < 1) )
THEN 1174 msg =
'Dimensions of Aerosol structures are < or = 0.' 1182 INQUIRE( file=filename,number=fid )
1183 IF ( fid == -1 )
THEN 1184 msg =
'Error inquiring '//trim(filename)//
' for its unit number' 1190 IF ( err_stat /=
success )
THEN 1191 msg =
'Error opening '//trim(filename)
1199 WRITE( fid,iostat=io_stat,iomsg=io_msg ) na
1200 IF ( io_stat /= 0 )
THEN 1201 msg =
'Error writing n_Aerosols data dimension to '//trim(filename)//
'- '//trim(io_msg)
1207 aerosol_loop:
DO m = 1, na
1209 IF ( err_stat /=
success )
THEN 1210 WRITE( msg,
'("Error writing Aerosol element #",i0," to ",a)' ) m, trim(filename)
1217 IF ( yes_close )
THEN 1218 CLOSE( fid,status=
'KEEP',iostat=io_stat,iomsg=io_msg )
1219 IF ( io_stat /= 0 )
THEN 1220 msg =
'Error closing '//trim(filename)//
'- '//trim(io_msg)
1228 WRITE( msg,
'("Number of aerosols written to ",a,": ",i0)' ) trim(filename), na
1237 IF ( io_stat /= 0 ) &
1238 msg = trim(msg)//
'; Error deleting output file during error cleanup - '//trim(io_msg)
1304 IF ( (x%n_Layers /= y%n_Layers) .OR. (x%Type /= y%Type) )
RETURN 1307 IF ( all(x%Effective_Radius(1:n) .equalto. y%Effective_Radius(1:n) ) .AND. &
1308 all(x%Concentration(1:n) .equalto. y%Concentration(1:n) ) ) &
1357 IF ( aer1%Type /= aer2%Type .OR. &
1358 aer1%n_Layers /= aer2%n_Layers .OR. &
1359 aer1%n_Added_Layers /= aer2%n_Added_Layers )
RETURN 1366 aersum%Effective_Radius(1:n) = aersum%Effective_Radius(1:n) + aer2%Effective_Radius(1:n)
1367 aersum%Concentration(1:n) = aersum%Concentration(1:n) + aer2%Concentration(1:n)
1415 IF ( aer1%Type /= aer2%Type .OR. &
1416 aer1%n_Layers /= aer2%n_Layers .OR. &
1417 aer1%n_Added_Layers /= aer2%n_Added_Layers )
RETURN 1424 aerdiff%Effective_Radius(1:n) = aerdiff%Effective_Radius(1:n) - aer2%Effective_Radius(1:n)
1425 aerdiff%Concentration(1:n) = aerdiff%Concentration(1:n) - aer2%Concentration(1:n)
1446 INTEGER ,
INTENT(IN) :: fid
1451 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_ReadFile(Binary Record)' 1453 CHARACTER(ML) :: msg
1454 CHARACTER(ML) :: io_msg
1463 READ( fid,iostat=io_stat,iomsg=io_msg ) n_layers
1464 IF ( io_stat /= 0 )
THEN 1465 msg =
'Error reading n_Layers dimension - '//trim(io_msg)
1473 msg =
'Aerosol object allocation failed.' 1479 READ( fid,iostat=io_stat,iomsg=io_msg ) &
1481 aerosol%Effective_Radius, &
1482 aerosol%Concentration
1483 IF ( io_stat /= 0 )
THEN 1484 msg =
'Error reading Aerosol data - '//trim(io_msg)
1492 CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1494 msg = trim(msg)//
'; Error closing file during error cleanup - '//trim(io_msg)
1515 INTEGER ,
INTENT(IN) :: fid
1520 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_Aerosol_WriteFile(Binary Record)' 1522 CHARACTER(ML) :: msg
1523 CHARACTER(ML) :: io_msg
1529 msg =
'Input Aerosol object is not used.' 1535 WRITE( fid,iostat=io_stat,iomsg=io_msg ) aerosol%n_Layers
1536 IF ( io_stat /= 0 )
THEN 1537 msg =
'Error writing dimensions - '//trim(io_msg)
1543 WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1545 aerosol%Effective_Radius(1:aerosol%n_Layers), &
1546 aerosol%Concentration(1:aerosol%n_Layers)
1547 IF ( io_stat /= 0 )
THEN 1548 msg =
'Error writing Aerosol data - '//trim(io_msg)
1557 msg = trim(msg)//
'; Error closing file during error cleanup' integer, parameter, public dust_aerosol
integer, parameter, public failure
integer, parameter, public seasalt_sscm1_aerosol
integer, parameter, public warning
integer function read_record(fid, aerosol)
elemental subroutine, public crtm_aerosol_create(Aerosol, n_Layers)
character(*), parameter module_version_id
elemental type(crtm_aerosol_type) function crtm_aerosol_add(aer1, aer2)
integer, parameter, public fp
pure integer function, public crtm_aerosol_categoryid(aerosol)
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
character(*), parameter write_error_status
character(*), dimension(0:n_valid_aerosol_categories), parameter, public aerosol_category_name
elemental subroutine, public crtm_aerosol_destroy(Aerosol)
subroutine inquire_cleanup()
elemental type(crtm_aerosol_type) function crtm_aerosol_subtract(aer1, aer2)
subroutine scalar_inspect(Aerosol, Unit)
integer, parameter, public black_carbon_aerosol
subroutine read_cleanup()
elemental logical function crtm_aerosol_equal(x, y)
subroutine write_cleanup()
elemental subroutine, public crtm_aerosol_zero(Aerosol)
subroutine read_record_cleanup()
logical function, public crtm_aerosol_isvalid(Aerosol)
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
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 function, public crtm_aerosol_writefile(Filename, Aerosol, Quiet, No_Close, Debug)
integer, parameter, public default_n_sigfig
integer function, public crtm_aerosol_inquirefile(Filename, n_Aerosols)
subroutine rank2_inspect(Aerosol, Unit)
subroutine, public crtm_aerosol_defineversion(Id)
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
subroutine write_record_cleanup()
elemental subroutine, public crtm_aerosol_setlayers(Aerosol, n_Layers)
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 function, public crtm_aerosol_readfile(Filename, Aerosol, Quiet, No_Close, n_Aerosols, Debug)
integer, parameter, public n_valid_aerosol_categories
integer, parameter, public invalid_aerosol
integer function, public crtm_aerosol_categorylist(list)
integer, dimension(0:n_valid_aerosol_categories), parameter aerosol_category_list
integer, parameter, public seasalt_sscm3_aerosol
elemental logical function, public crtm_aerosol_associated(Aerosol)
integer, parameter, public organic_carbon_aerosol
integer, parameter, public sulfate_aerosol
integer, parameter, public seasalt_ssam_aerosol
subroutine rank1_inspect(Aerosol, Unit)
integer, parameter, public success
integer, parameter, public seasalt_sscm2_aerosol
integer, parameter, public information