PartMC  2.3.0
extract_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_aero_time program.
7 
8 !> Read NetCDF output files and write out the time evolution of
9 !> aerosol number and mass concentrations in text format.
11 
12  use pmc_aero_state
14  use pmc_output
15  use pmc_mpi
16  use getopt_m
17 
18  character(len=PMC_MAX_FILENAME_LEN) :: in_prefix, out_filename
19  character(len=PMC_MAX_FILENAME_LEN), allocatable :: filename_list(:)
20  character(len=1000) :: tmp_str
21  type(aero_data_t) :: aero_data
22  type(aero_state_t) :: aero_state
23  integer :: index, i_repeat, i_spec, out_unit
24  integer :: i_file, n_file
25  real(kind=dp) :: time, del_t
26  character(len=PMC_UUID_LEN) :: uuid, run_uuid
27  real(kind=dp), allocatable :: particle_num_concs(:), particle_masses(:)
28  real(kind=dp), allocatable :: times(:), time_num_concs(:), time_mass_concs(:)
29  real(kind=dp), allocatable :: time_species_concs(:,:)
30  type(option_s) :: opts(2)
31 
32  call pmc_mpi_init()
33 
34  opts(1) = option_s("help", .false., 'h')
35  opts(2) = option_s("output", .true., 'o')
36 
37  out_filename = ""
38 
39  do
40  select case(getopt("ho:", opts))
41  case(char(0))
42  exit
43  case('h')
44  call print_help()
45  stop
46  case('o')
47  out_filename = optarg
48  case( '?' )
49  call print_help()
50  call die_msg(514364550, 'unknown option: ' // trim(optopt))
51  case default
52  call print_help()
53  call die_msg(603100341, 'unhandled option: ' // trim(optopt))
54  end select
55  end do
56 
57  if (optind /= command_argument_count()) then
58  call print_help()
59  call die_msg(967032896, 'expected exactly one non-option prefix argument')
60  end if
61 
62  call get_command_argument(optind, in_prefix)
63 
64  if (out_filename == "") then
65  out_filename = trim(in_prefix) // "_aero_time.txt"
66  end if
67 
68  call aero_data_allocate(aero_data)
69  call aero_state_allocate(aero_state)
70 
71  allocate(filename_list(0))
72  call input_filename_list(in_prefix, filename_list)
73  n_file = size(filename_list)
74  call assert_msg(323514871, n_file > 0, &
75  "no NetCDF files found with prefix: " // trim(in_prefix))
76 
77  call input_state(filename_list(1), index, time, del_t, i_repeat, uuid, &
78  aero_data=aero_data, aero_state=aero_state)
79  run_uuid = uuid
80 
81  allocate(times(n_file))
82  allocate(time_num_concs(n_file))
83  allocate(time_mass_concs(n_file))
84  allocate(time_species_concs(n_file, aero_data%n_spec))
85 
86  do i_file = 1,n_file
87  call input_state(filename_list(i_file), index, time, del_t, i_repeat, &
88  uuid, aero_data=aero_data, aero_state=aero_state)
89 
90  call assert_msg(397906326, uuid == run_uuid, &
91  "UUID mismatch between " // trim(filename_list(1)) // " and " &
92  // trim(filename_list(i_file)))
93 
94  times(i_file) = time
95  particle_num_concs = aero_state_num_concs(aero_state)
96  time_num_concs(i_file) = sum(particle_num_concs)
97  particle_masses = aero_state_masses(aero_state, aero_data)
98  time_mass_concs(i_file) = sum(particle_masses * particle_num_concs)
99  do i_spec = 1,aero_data%n_spec
100  particle_masses = aero_state_masses(aero_state, aero_data, &
101  include=(/aero_data%name(i_spec)/))
102  time_species_concs(i_file, i_spec) &
103  = sum(particle_masses * particle_num_concs)
104  end do
105  end do
106 
107  write(*,'(a,a)') "Output file: ", trim(out_filename)
108  write(*,'(a)') " Each row of output is one time."
109  write(*,'(a)') " The columns of output are:"
110  write(*,'(a)') " column 1: time (s)"
111  write(*,'(a)') " column 2: aerosol number concentration (#/m^3)"
112  write(*,'(a)') " column 3: aerosol mass concentration (kg/m^3)"
113  do i_spec = 1,aero_data%n_spec
114  write(*,'(a,i2,a,a,a)') " column ", i_spec + 3, ": aerosol ", &
115  trim(aero_data%name(i_spec)), " concentration (kg/m^3)"
116  end do
117 
118  call open_file_write(out_filename, out_unit)
119  do i_file = 1,n_file
120  write(out_unit, '(e30.15e3)', advance='no') times(i_file)
121  write(out_unit, '(e30.15e3)', advance='no') time_num_concs(i_file)
122  write(out_unit, '(e30.15e3)', advance='no') time_mass_concs(i_file)
123  do i_spec = 1,aero_data%n_spec
124  write(out_unit, '(e30.15e3)', advance='no') &
125  time_species_concs(i_file, i_spec)
126  end do
127  write(out_unit, '(a)') ''
128  end do
129  call close_file(out_unit)
130 
131  deallocate(times)
132  deallocate(time_num_concs)
133  deallocate(time_mass_concs)
134  deallocate(time_species_concs)
135  deallocate(filename_list)
136  call aero_data_deallocate(aero_data)
137  call aero_state_deallocate(aero_state)
138 
139  call pmc_mpi_finalize()
140 
141 contains
142 
143  subroutine print_help()
144 
145  write(*,'(a)') 'Usage: extract_aero_time [options] <netcdf_prefix>'
146  write(*,'(a)') ''
147  write(*,'(a)') 'options are:'
148  write(*,'(a)') ' -h, --help Print this help message.'
149  write(*,'(a)') ' -o, --out <file> Output filename.'
150  write(*,'(a)') ''
151  write(*,'(a)') 'Examples:'
152  write(*,'(a)') ' extract_aero_time data_0001'
153  write(*,'(a)') ''
154 
155  end subroutine print_help
156 
157 end program extract_aero_time
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.
Definition: output.F90:509
program extract_aero_time
Read NetCDF output files and write out the time evolution of aerosol number and mass concentrations i...
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
The aero_particle_t structure and associated subroutines.
subroutine aero_state_allocate(aero_state)
Allocates aerosol arrays.
Definition: aero_state.F90:83
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:76
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.
Definition: mpi.F90:88
subroutine pmc_mpi_init()
Initialize MPI.
Definition: mpi.F90:55
subroutine aero_data_deallocate(aero_data)
Frees all storage.
Definition: aero_data.F90:116
The aero_state_t structure and assocated subroutines.
Definition: aero_state.F90:9
Wrapper functions for MPI.
Definition: mpi.F90:13
The current collection of aerosol particles.
Definition: aero_state.F90:63
subroutine aero_state_deallocate(aero_state)
Deallocates a previously allocated aerosol.
Definition: aero_state.F90:100
subroutine print_help()
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.
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
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