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
66 call
die_msg(546118086,
'unknown option: ' // trim(optopt))
69 call
die_msg(720731240,
'unhandled option: ' // trim(optopt))
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"
99 allocate(filename_list(0))
101 n_file =
size(filename_list)
103 "no NetCDF files found with prefix: " // trim(in_prefix))
106 bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
109 allocate(aero_dist(bin_grid%n_bin, n_file))
112 call
input_sectional(filename_list(i_file), index, time, del_t, uuid, &
113 bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
115 call
assert_msg(838088000, uuid == run_uuid, &
116 "UUID mismatch between " // trim(filename_list(1)) //
" and " &
117 // trim(filename_list(i_file)))
119 if (dist_type == dist_type_num)
then
120 aero_dist(:, i_file) = aero_binned%num_conc
121 elseif (dist_type == dist_type_mass)
then
122 do i_bin = 1,bin_grid%n_bin
123 aero_dist(i_bin, i_file) = sum(aero_binned%vol_conc(i_bin, :) &
131 write(*,
'(a)')
"Output file: " // trim(out_filename)
132 write(*,
'(a)')
" Each row of output is one size bin."
133 write(*,
'(a)')
" The columns of output are:"
134 write(*,
'(a)')
" column 1: bin center diameter (m)"
135 if (dist_type == dist_type_num)
then
136 write(*,
'(a)')
" column j+1: number concentration at time(j) (#/m^3)"
137 elseif (dist_type == dist_type_mass)
then
138 write(*,
'(a)')
" column j+1: mass concentration at time(j) (kg/m^3)"
140 write(*,
'(a)')
" Diameter bins have logarithmic width:"
141 write(*,
'(a,e20.10)')
" log_width = ln(diam(i+1)) - ln(diam(i)) =", &
145 do i_bin = 1,bin_grid%n_bin
146 write(out_unit,
'(e30.15e3)', advance=
'no') &
149 write(out_unit,
'(e30.15e3)', advance=
'no') aero_dist(i_bin, i_file)
151 write(out_unit,
'(a)')
''
155 deallocate(filename_list)
156 deallocate(aero_dist)
167 write(*,
'(a)')
'Usage: extract_sectional_aero_size [options] ' &
170 write(*,
'(a)')
'options are:'
171 write(*,
'(a)')
' -h, --help Print this help message.'
172 write(*,
'(a)')
' -n, --num Output number distribution.'
173 write(*,
'(a)')
' -m, --mass Output mass distribution.'
174 write(*,
'(a)')
' -o, --out <file> Output filename.'
176 write(*,
'(a)')
'Examples:'
177 write(*,
'(a)')
' extract_sectional_aero_size --num data_0001'
subroutine die_msg(code, error_msg)
Error immediately.
character function getopt(optstring, longopts)
subroutine input_filename_list(prefix, filename_list)
Find all NetCDF (.nc) filenames that match the given prefix.
subroutine close_file(unit)
Close a file and de-assign the unit.
real(kind=dp) elemental function rad2diam(r)
Convert radius (m) to diameter (m).
subroutine aero_binned_deallocate(aero_binned)
Free internal memory in an aero_binned_t structure.
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
subroutine aero_binned_allocate(aero_binned)
Allocate an aero_binned_t.
subroutine pmc_mpi_finalize()
Shut down MPI.
subroutine pmc_mpi_init()
Initialize MPI.
subroutine bin_grid_allocate(bin_grid)
Allocates a bin_grid.
subroutine aero_data_deallocate(aero_data)
Frees all storage.
Wrapper functions for MPI.
subroutine input_sectional(filename, index, time, del_t, uuid, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state)
Input sectional data.
1D grid, either logarithmic or linear.
subroutine die(code)
Error immediately.
The aero_binned_t structure and associated subroutines.
subroutine aero_data_allocate(aero_data)
Allocate storage for aero_data.
Aerosol material properties and associated data.
Write data in NetCDF format.
Aerosol number and volume distributions stored per bin.
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().