18 integer,
parameter :: dist_type_none = 0
19 integer,
parameter :: dist_type_num = 1
20 integer,
parameter :: dist_type_mass = 2
22 character(len=PMC_MAX_FILENAME_LEN) :: in_prefix, out_filename
23 character(len=PMC_MAX_FILENAME_LEN),
allocatable :: filename_list(:)
24 character(len=1000) :: tmp_str
28 integer :: index, i_repeat, i_part, i_spec, out_unit
29 integer :: i_file, n_file, i_bin, n_bin, dist_type
30 real(kind=dp) :: time, del_t
32 real(kind=dp) :: d_min, d_max, diam, volume
33 character(len=PMC_UUID_LEN) :: uuid, run_uuid
34 real(kind=dp),
allocatable :: diameters(:), num_concs(:), masses(:), hist(:)
35 real(kind=dp),
allocatable :: aero_dist(:,:)
40 opts(1) =
option_s(
"help", .false.,
'h')
41 opts(2) =
option_s(
"num", .false.,
'n')
42 opts(3) =
option_s(
"mass", .false.,
'm')
43 opts(4) =
option_s(
"dmin", .true.,
'N')
44 opts(5) =
option_s(
"dmax", .true.,
'X')
45 opts(6) =
option_s(
"nbin", .true.,
'b')
46 opts(7) =
option_s(
"output", .true.,
'o')
48 dist_type = dist_type_none
55 select case(
getopt(
"hnmN:X:b:o:", opts))
62 if (dist_type /= dist_type_none)
then
64 call
die_msg(525113814,
'multiple distribution types selected')
66 dist_type = dist_type_num
68 if (dist_type /= dist_type_none)
then
70 call
die_msg(155494931,
'multiple distribution types selected')
72 dist_type = dist_type_mass
83 call
die_msg(956456220,
'unknown option: ' // trim(optopt))
86 call
die_msg(203991511,
'unhandled option: ' // trim(optopt))
90 if (optind /= command_argument_count())
then
92 call
die_msg(533171694,
'expected exactly one non-option prefix argument')
95 call get_command_argument(optind, in_prefix)
97 if (dist_type == dist_type_none)
then
99 call
die_msg(540839314,
'must select distribution type (--num or --mass)')
102 if (out_filename ==
"")
then
103 if (dist_type == dist_type_num)
then
104 out_filename = trim(in_prefix) //
"_aero_size_num.txt"
105 elseif (dist_type == dist_type_mass)
then
106 out_filename = trim(in_prefix) //
"_aero_size_mass.txt"
116 allocate(filename_list(0))
118 n_file =
size(filename_list)
120 "no NetCDF files found with prefix: " // trim(in_prefix))
122 call
bin_grid_make(diam_grid, bin_grid_type_log, n_bin, d_min, d_max)
123 allocate(aero_dist(n_bin, n_file))
126 call
input_state(filename_list(i_file), index, time, del_t, i_repeat, &
127 uuid, aero_data=aero_data, aero_state=aero_state)
129 if (i_file == 1)
then
132 call
assert_msg(657993562, uuid == run_uuid, &
133 "UUID mismatch between " // trim(filename_list(1)) //
" and " &
134 // trim(filename_list(i_file)))
139 if (dist_type == dist_type_num)
then
141 elseif (dist_type == dist_type_mass)
then
147 aero_dist(:, i_file) = hist
150 write(*,
'(a)')
"Output file: " // trim(out_filename)
151 write(*,
'(a)')
" Each row of output is one size bin."
152 write(*,
'(a)')
" The columns of output are:"
153 write(*,
'(a)')
" column 1: bin center diameter (m)"
154 if (dist_type == dist_type_num)
then
155 write(*,
'(a)')
" column j+1: number concentration at time(j) (#/m^3)"
156 elseif (dist_type == dist_type_mass)
then
157 write(*,
'(a)')
" column j+1: mass concentration at time(j) (kg/m^3)"
159 write(*,
'(a)')
" Diameter bins have logarithmic width:"
160 write(*,
'(a,e20.10)')
" log_width = ln(diam(i+1)) - ln(diam(i)) =", &
165 write(out_unit,
'(e30.15e3)', advance=
'no') diam_grid%centers(i_bin)
167 write(out_unit,
'(e30.15e3)', advance=
'no') aero_dist(i_bin, i_file)
169 write(out_unit,
'(a)')
''
173 deallocate(filename_list)
174 deallocate(aero_dist)
185 write(*,
'(a)')
'Usage: extract_aero_size [options] <netcdf_prefix>'
187 write(*,
'(a)')
'options are:'
188 write(*,
'(a)')
' -h, --help Print this help message.'
189 write(*,
'(a)')
' -n, --num Output number distribution.'
190 write(*,
'(a)')
' -m, --mass Output mass distribution.'
191 write(*,
'(a)')
' -N, --dmin <D> Minimum diameter (m).'
192 write(*,
'(a)')
' -X, --dmax <D> Maximum diameter (m).'
193 write(*,
'(a)')
' -b, --nbin <N> Number of size bins.'
194 write(*,
'(a)')
' -o, --out <file> Output filename.'
196 write(*,
'(a)')
'Examples:'
197 write(*,
'(a)')
' extract_aero_size --num data_0001'
199 ' extract_aero_size --mass --dmin 1e-8 --dmax 1e-4 data_0001'
subroutine input_state(filename, index, time, del_t, i_repeat, uuid, aero_data, aero_state, gas_data, gas_state, env_state)
Read the current state.
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.
real(kind=dp) function, dimension(x_bin_grid%n_bin) bin_grid_histogram_1d(x_bin_grid, x_data, weight_data)
Make a histogram with of the given weighted data, scaled by the bin sizes.
subroutine close_file(unit)
Close a file and de-assign the unit.
The aero_particle_t structure and associated subroutines.
subroutine aero_state_allocate(aero_state)
Allocates aerosol arrays.
subroutine bin_grid_make(bin_grid, type, n_bin, min, max)
Generates the bin grid given the range and number of bins.
real(kind=dp) function, dimension(aero_state%apa%n_part) aero_state_diameters(aero_state)
Returns the diameters of all particles.
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
real(kind=dp) function, dimension(aero_state%apa%n_part) aero_state_masses(aero_state, aero_data, include, exclude)
Returns the masses of all particles.
subroutine pmc_mpi_finalize()
Shut down MPI.
subroutine pmc_mpi_init()
Initialize MPI.
subroutine bin_grid_allocate(bin_grid)
Allocates a bin_grid.
integer function string_to_integer(string)
Convert a string to an integer.
subroutine aero_data_deallocate(aero_data)
Frees all storage.
The aero_state_t structure and assocated subroutines.
Wrapper functions for MPI.
The current collection of aerosol particles.
Single aerosol particle data structure.
1D grid, either logarithmic or linear.
subroutine aero_state_deallocate(aero_state)
Deallocates a previously allocated aerosol.
subroutine die(code)
Error immediately.
real(kind=dp) function, dimension(aero_state%apa%n_part) aero_state_num_concs(aero_state)
Returns the number concentrations of all particles.
subroutine aero_data_allocate(aero_data)
Allocate storage for aero_data.
Aerosol material properties and associated data.
real(kind=dp) function string_to_real(string)
Convert a string to a real.
Write data in NetCDF format.
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().