17 integer,
parameter :: DIST_TYPE_NONE = 0
18 integer,
parameter :: DIST_TYPE_NUM = 1
19 integer,
parameter :: DIST_TYPE_MASS = 2
21 character(len=PMC_MAX_FILENAME_LEN) :: in_prefix, out_filename
22 character(len=PMC_MAX_FILENAME_LEN),
allocatable :: filename_list(:)
26 integer :: index, out_unit
27 integer :: i_file, n_file, i_bin, dist_type
28 real(kind=dp) :: time, del_t
29 character(len=PMC_UUID_LEN) :: uuid, run_uuid
30 real(kind=dp),
allocatable :: aero_dist(:,:)
35 opts(1) =
option_s(
"help", .false.,
'h')
36 opts(2) =
option_s(
"num", .false.,
'n')
37 opts(3) =
option_s(
"mass", .false.,
'm')
38 opts(4) =
option_s(
"output", .true.,
'o')
40 dist_type = dist_type_none
44 select case(
getopt(
"hnmo:", opts))
51 if (dist_type /= dist_type_none)
then 53 call die_msg(413086480,
'multiple distribution types selected')
55 dist_type = dist_type_num
57 if (dist_type /= dist_type_none)
then 59 call die_msg(528866290,
'multiple distribution types selected')
61 dist_type = dist_type_mass
73 if (
optind /= command_argument_count())
then 75 call die_msg(699147496,
'expected exactly one non-option prefix argument')
78 call get_command_argument(
optind, in_prefix)
80 if (dist_type == dist_type_none)
then 82 call die_msg(576941805,
'must select distribution type (--num or --mass)')
85 if (out_filename ==
"")
then 86 if (dist_type == dist_type_num)
then 87 out_filename = trim(in_prefix) //
"_aero_size_num.txt" 88 elseif (dist_type == dist_type_mass)
then 89 out_filename = trim(in_prefix) //
"_aero_size_mass.txt" 95 allocate(filename_list(0))
97 n_file =
size(filename_list)
99 "no NetCDF files found with prefix: " // trim(in_prefix))
102 bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
108 call input_sectional(filename_list(i_file), index, time, del_t, uuid, &
109 bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
111 call assert_msg(838088000, uuid == run_uuid, &
112 "UUID mismatch between " // trim(filename_list(1)) //
" and " &
113 // trim(filename_list(i_file)))
115 if (dist_type == dist_type_num)
then 116 aero_dist(:, i_file) = aero_binned%num_conc
117 elseif (dist_type == dist_type_mass)
then 119 aero_dist(i_bin, i_file) = sum(aero_binned%vol_conc(i_bin, :) &
127 write(*,
'(a)')
"Output file: " // trim(out_filename)
128 write(*,
'(a)')
" Each row of output is one size bin." 129 write(*,
'(a)')
" The columns of output are:" 130 write(*,
'(a)')
" column 1: bin center diameter (m)" 131 if (dist_type == dist_type_num)
then 132 write(*,
'(a)')
" column j+1: number concentration at time(j) (#/m^3)" 133 elseif (dist_type == dist_type_mass)
then 134 write(*,
'(a)')
" column j+1: mass concentration at time(j) (kg/m^3)" 136 write(*,
'(a)')
" Diameter bins have logarithmic width:" 137 write(*,
'(a,e20.10)')
" log_width = ln(diam(i+1)) - ln(diam(i)) =", &
142 write(out_unit,
'(e30.15e3)', advance=
'no') &
145 write(out_unit,
'(e30.15e3)', advance=
'no') aero_dist(i_bin, i_file)
147 write(out_unit,
'(a)')
'' 151 deallocate(filename_list)
152 deallocate(aero_dist)
160 write(*,
'(a)')
'Usage: extract_sectional_aero_size [options] ' &
163 write(*,
'(a)')
'options are:' 164 write(*,
'(a)')
' -h, --help Print this help message.' 165 write(*,
'(a)')
' -n, --num Output number distribution.' 166 write(*,
'(a)')
' -m, --mass Output mass distribution.' 167 write(*,
'(a)')
' -o, --out <file> Output filename.' 169 write(*,
'(a)')
'Examples:' 170 write(*,
'(a)')
' extract_sectional_aero_size --num data_0001' subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
subroutine die(code)
Error immediately.
subroutine close_file(unit)
Close a file and de-assign the unit.
character function getopt(optstring, longopts)
subroutine input_filename_list(prefix, filename_list)
Find all NetCDF (.nc) filenames that match the given prefix.
real(kind=dp) elemental function rad2diam(r)
Convert radius (m) to diameter (m).
subroutine die_msg(code, error_msg)
Error immediately.
Write data in NetCDF format.
subroutine input_sectional(filename, index, time, del_t, uuid, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state)
Input sectional data.
elemental integer function bin_grid_size(bin_grid)
Return the number of bins in the grid, or -1 if the bin grid is not allocated.
1D grid, either logarithmic or linear.
subroutine pmc_mpi_finalize()
Shut down MPI.
subroutine open_file_write(filename, unit)
Open a file for writing with an automatically assigned unit and test that it succeeds. The file should be closed with close_file().
subroutine pmc_mpi_init()
Initialize MPI.
Aerosol material properties and associated data.
The aero_binned_t structure and associated subroutines.
Wrapper functions for MPI.
Aerosol number and volume distributions stored per bin.