PartMC  2.3.0
extract_sectional_aero_time.F90
Go to the documentation of this file.
1 ! Copyright (C) 2009-2012 Matthew West
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The extract_sectional_aero_time program.
7 
8 !> Read NetCDF sectional output files and write out the time evolution of
9 !> aerosol number and mass concentrations in text format.
11 
12  use pmc_aero_binned
13  use pmc_output
14  use pmc_mpi
15  use getopt_m
16 
17  character(len=PMC_MAX_FILENAME_LEN) :: in_prefix, out_filename
18  character(len=PMC_MAX_FILENAME_LEN), allocatable :: filename_list(:)
19  type(bin_grid_t) :: bin_grid
20  type(aero_data_t) :: aero_data
21  type(aero_binned_t) :: aero_binned
22  integer :: index, out_unit
23  integer :: i_file, n_file, i_spec
24  real(kind=dp) :: time, del_t
25  character(len=PMC_UUID_LEN) :: uuid, run_uuid
26  real(kind=dp), allocatable :: times(:), time_num_concs(:), time_mass_concs(:)
27  real(kind=dp), allocatable :: time_species_concs(:,:)
28  type(option_s) :: opts(2)
29 
30  call pmc_mpi_init()
31 
32  opts(1) = option_s("help", .false., 'h')
33  opts(2) = option_s("output", .true., 'o')
34 
35  out_filename = ""
36 
37  do
38  select case(getopt("ho:", opts))
39  case(char(0))
40  exit
41  case('h')
42  call print_help()
43  stop
44  case('o')
45  out_filename = optarg
46  case( '?' )
47  call print_help()
48  call die_msg(559277549, 'unknown option: ' // trim(optopt))
49  case default
50  call print_help()
51  call die_msg(247146202, 'unhandled option: ' // trim(optopt))
52  end select
53  end do
54 
55  if (optind /= command_argument_count()) then
56  call print_help()
57  call die_msg(959981535, 'expected exactly one non-option prefix argument')
58  end if
59 
60  call get_command_argument(optind, in_prefix)
61 
62  if (out_filename == "") then
63  out_filename = trim(in_prefix) // "_aero_time.txt"
64  end if
65 
66  call bin_grid_allocate(bin_grid)
67  call aero_data_allocate(aero_data)
68  call aero_binned_allocate(aero_binned)
69 
70  allocate(filename_list(0))
71  call input_filename_list(in_prefix, filename_list)
72  n_file = size(filename_list)
73  call assert_msg(875939143, n_file > 0, &
74  "no NetCDF files found with prefix: " // trim(in_prefix))
75 
76  call input_sectional(filename_list(1), index, time, del_t, uuid, &
77  bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
78  run_uuid = uuid
79 
80  allocate(times(n_file))
81  allocate(time_num_concs(n_file))
82  allocate(time_mass_concs(n_file))
83  allocate(time_species_concs(n_file, aero_data%n_spec))
84 
85  do i_file = 1,n_file
86  call input_sectional(filename_list(i_file), index, time, del_t, uuid, &
87  bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
88 
89  call assert_msg(865522513, uuid == run_uuid, &
90  "UUID mismatch between " // trim(filename_list(1)) // " and " &
91  // trim(filename_list(i_file)))
92 
93  times(i_file) = time
94  time_num_concs(i_file) = sum(aero_binned%num_conc * bin_grid%widths)
95  ! FIXME: line below assumes bin_grid%widths is constant
96  time_species_concs(i_file, :) = sum(aero_binned%vol_conc &
97  * bin_grid%widths(1), 1) * aero_data%density
98  time_mass_concs(i_file) = sum(time_species_concs(i_file, :))
99  end do
100 
101  write(*,'(a,a)') "Output file: ", trim(out_filename)
102  write(*,'(a)') " Each row of output is one time."
103  write(*,'(a)') " The columns of output are:"
104  write(*,'(a)') " column 1: time (s)"
105  write(*,'(a)') " column 2: aerosol number concentration (#/m^3)"
106  write(*,'(a)') " column 3: aerosol mass concentration (kg/m^3)"
107  do i_spec = 1,aero_data%n_spec
108  write(*,'(a,i2,a,a,a)') " column ", i_spec + 3, ": aerosol ", &
109  trim(aero_data%name(i_spec)), " concentration (kg/m^3)"
110  end do
111 
112  call open_file_write(out_filename, out_unit)
113  do i_file = 1,n_file
114  write(out_unit, '(e30.15e3)', advance='no') times(i_file)
115  write(out_unit, '(e30.15e3)', advance='no') time_num_concs(i_file)
116  write(out_unit, '(e30.15e3)', advance='no') time_mass_concs(i_file)
117  do i_spec = 1,aero_data%n_spec
118  write(out_unit, '(e30.15e3)', advance='no') &
119  time_species_concs(i_file, i_spec)
120  end do
121  write(out_unit, '(a)') ''
122  end do
123  call close_file(out_unit)
124 
125  deallocate(times)
126  deallocate(time_num_concs)
127  deallocate(time_mass_concs)
128  deallocate(time_species_concs)
129  deallocate(filename_list)
130  call bin_grid_allocate(bin_grid)
131  call aero_data_deallocate(aero_data)
132  call aero_binned_deallocate(aero_binned)
133 
134  call pmc_mpi_finalize()
135 
136 contains
137 
138  subroutine print_help()
139 
140  write(*,'(a)') 'Usage: extract_sectional_aero_time [options] ' &
141  // '<netcdf_prefix>'
142  write(*,'(a)') ''
143  write(*,'(a)') 'options are:'
144  write(*,'(a)') ' -h, --help Print this help message.'
145  write(*,'(a)') ' -n, --num Output number distribution.'
146  write(*,'(a)') ' -m, --mass Output mass distribution.'
147  write(*,'(a)') ' -o, --out <file> Output filename.'
148  write(*,'(a)') ''
149  write(*,'(a)') 'Examples:'
150  write(*,'(a)') ' extract_sectional_aero_time --num data_0001'
151  write(*,'(a)') ''
152 
153  end subroutine print_help
154 
155 end program extract_sectional_aero_time
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:133
character function getopt(optstring, longopts)
Definition: getopt.F90:131
subroutine input_filename_list(prefix, filename_list)
Find all NetCDF (.nc) filenames that match the given prefix.
Definition: output.F90:580
subroutine close_file(unit)
Close a file and de-assign the unit.
Definition: util.F90:225
subroutine aero_binned_deallocate(aero_binned)
Free internal memory in an aero_binned_t structure.
Definition: aero_binned.F90:79
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:76
subroutine aero_binned_allocate(aero_binned)
Allocate an aero_binned_t.
Definition: aero_binned.F90:47
program extract_sectional_aero_time
Read NetCDF sectional output files and write out the time evolution of aerosol number and mass concen...
subroutine pmc_mpi_finalize()
Shut down MPI.
Definition: mpi.F90:88
subroutine pmc_mpi_init()
Initialize MPI.
Definition: mpi.F90:55
subroutine bin_grid_allocate(bin_grid)
Allocates a bin_grid.
Definition: bin_grid.F90:51
subroutine aero_data_deallocate(aero_data)
Frees all storage.
Definition: aero_data.F90:116
Wrapper functions for MPI.
Definition: mpi.F90:13
subroutine input_sectional(filename, index, time, del_t, uuid, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state)
Input sectional data.
Definition: output.F90:727
1D grid, either logarithmic or linear.
Definition: bin_grid.F90:33
subroutine print_help()
The aero_binned_t structure and associated subroutines.
Definition: aero_binned.F90:9
subroutine aero_data_allocate(aero_data)
Allocate storage for aero_data.
Definition: aero_data.F90:69
Aerosol material properties and associated data.
Definition: aero_data.F90:40
Write data in NetCDF format.
Definition: output.F90:68
Aerosol number and volume distributions stored per bin.
Definition: aero_binned.F90:33
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().
Definition: util.F90:205