PartMC  2.2.1
extract_sectional_aero_size.F90
Go to the documentation of this file.
00001 ! Copyright (C) 2009-2012 Matthew West
00002 ! Licensed under the GNU General Public License version 2 or (at your
00003 ! option) any later version. See the file COPYING for details.
00004 
00005 !> \file
00006 !> The extract_sectional_aero_size program.
00007 
00008 !> Read NetCDF sectional output files and write out the aerosol size
00009 !> distribution in text format.
00010 program extract_sectional_aero_size
00011 
00012   use pmc_aero_binned
00013   use pmc_output
00014   use pmc_mpi
00015   use getopt_m
00016 
00017   integer, parameter :: DIST_TYPE_NONE = 0
00018   integer, parameter :: DIST_TYPE_NUM = 1
00019   integer, parameter :: DIST_TYPE_MASS = 2
00020 
00021   character(len=PMC_MAX_FILENAME_LEN) :: in_prefix, out_filename
00022   character(len=PMC_MAX_FILENAME_LEN), allocatable :: filename_list(:)
00023   type(bin_grid_t) :: bin_grid
00024   type(aero_data_t) :: aero_data
00025   type(aero_binned_t) :: aero_binned
00026   integer :: index, out_unit
00027   integer :: i_file, n_file, i_bin, dist_type
00028   real(kind=dp) :: time, del_t
00029   character(len=PMC_UUID_LEN) :: uuid, run_uuid
00030   real(kind=dp), allocatable :: aero_dist(:,:)
00031   type(option_s) :: opts(4)
00032 
00033   call pmc_mpi_init()
00034 
00035   opts(1) = option_s("help", .false., 'h')
00036   opts(2) = option_s("num", .false., 'n')
00037   opts(3) = option_s("mass", .false., 'm')
00038   opts(4) = option_s("output", .true., 'o')
00039 
00040   dist_type = DIST_TYPE_NONE
00041   out_filename = ""
00042 
00043   do
00044      select case(getopt("hnmo:", opts))
00045      case(char(0))
00046         exit
00047      case('h')
00048         call print_help()
00049         stop
00050      case('n')
00051         if (dist_type /= DIST_TYPE_NONE) then
00052            call print_help()
00053            call die_msg(413086480, 'multiple distribution types selected')
00054         end if
00055         dist_type = DIST_TYPE_NUM
00056      case('m')
00057         if (dist_type /= DIST_TYPE_NONE) then
00058            call print_help()
00059            call die_msg(528866290, 'multiple distribution types selected')
00060         end if
00061         dist_type = DIST_TYPE_MASS
00062      case('o')
00063         out_filename = optarg
00064      case( '?' )
00065         call print_help()
00066         call die_msg(546118086, 'unknown option: ' // trim(optopt))
00067      case default
00068         call print_help()
00069         call die_msg(720731240, 'unhandled option: ' // trim(optopt))
00070      end select
00071   end do
00072 
00073   if (optind /= command_argument_count()) then
00074      call print_help()
00075      call die_msg(699147496, 'expected exactly one non-option prefix argument')
00076   end if
00077 
00078   call get_command_argument(optind, in_prefix)
00079 
00080   if (dist_type == DIST_TYPE_NONE) then
00081      call print_help()
00082      call die_msg(576941805, 'must select distribution type (--num or --mass)')
00083   end if
00084 
00085   if (out_filename == "") then
00086      if (dist_type == DIST_TYPE_NUM) then
00087         out_filename = trim(in_prefix) // "_aero_size_num.txt"
00088      elseif (dist_type == DIST_TYPE_MASS) then
00089         out_filename = trim(in_prefix) // "_aero_size_mass.txt"
00090      else
00091         call die(767619107)
00092      end if
00093   end if
00094 
00095   call bin_grid_allocate(bin_grid)
00096   call aero_data_allocate(aero_data)
00097   call aero_binned_allocate(aero_binned)
00098 
00099   allocate(filename_list(0))
00100   call input_filename_list(in_prefix, filename_list)
00101   n_file = size(filename_list)
00102   call assert_msg(792400289, n_file > 0, &
00103        "no NetCDF files found with prefix: " // trim(in_prefix))
00104 
00105   call input_sectional(filename_list(1), index, time, del_t, uuid, &
00106        bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
00107   run_uuid = uuid
00108 
00109   allocate(aero_dist(bin_grid%n_bin, n_file))
00110 
00111   do i_file = 1,n_file
00112      call input_sectional(filename_list(i_file), index, time, del_t, uuid, &
00113           bin_grid=bin_grid, aero_data=aero_data, aero_binned=aero_binned)
00114 
00115      call assert_msg(838088000, uuid == run_uuid, &
00116           "UUID mismatch between " // trim(filename_list(1)) // " and " &
00117           // trim(filename_list(i_file)))
00118 
00119      if (dist_type == DIST_TYPE_NUM) then
00120         aero_dist(:, i_file) = aero_binned%num_conc
00121      elseif (dist_type == DIST_TYPE_MASS) then
00122         do i_bin = 1,bin_grid%n_bin
00123            aero_dist(i_bin, i_file) = sum(aero_binned%vol_conc(i_bin, :) &
00124                 * aero_data%density)
00125         end do
00126      else
00127         call die(141087960)
00128      end if
00129   end do
00130 
00131   write(*,'(a)') "Output file: " // trim(out_filename)
00132   write(*,'(a)') "  Each row of output is one size bin."
00133   write(*,'(a)') "  The columns of output are:"
00134   write(*,'(a)') "    column   1: bin center diameter (m)"
00135   if (dist_type == DIST_TYPE_NUM) then
00136      write(*,'(a)') "    column j+1: number concentration at time(j) (#/m^3)"
00137   elseif (dist_type == DIST_TYPE_MASS) then
00138      write(*,'(a)') "    column j+1: mass concentration at time(j) (kg/m^3)"
00139   end if
00140   write(*,'(a)') "  Diameter bins have logarithmic width:"
00141   write(*,'(a,e20.10)') "    log_width = ln(diam(i+1)) - ln(diam(i)) =", &
00142        bin_grid%log_width
00143 
00144   call open_file_write(out_filename, out_unit)
00145   do i_bin = 1,bin_grid%n_bin
00146      write(out_unit, '(e30.15e3)', advance='no') &
00147           rad2diam(bin_grid%center_radius(i_bin))
00148      do i_file = 1,n_file
00149         write(out_unit, '(e30.15e3)', advance='no') aero_dist(i_bin, i_file)
00150      end do
00151      write(out_unit, '(a)') ''
00152   end do
00153   call close_file(out_unit)
00154 
00155   deallocate(filename_list)
00156   deallocate(aero_dist)
00157   call bin_grid_allocate(bin_grid)
00158   call aero_data_deallocate(aero_data)
00159   call aero_binned_deallocate(aero_binned)
00160 
00161   call pmc_mpi_finalize()
00162 
00163 contains
00164 
00165   subroutine print_help()
00166 
00167     write(*,'(a)') 'Usage: extract_sectional_aero_size [options] <netcdf_prefix>'
00168     write(*,'(a)') ''
00169     write(*,'(a)') 'options are:'
00170     write(*,'(a)') '  -h, --help        Print this help message.'
00171     write(*,'(a)') '  -n, --num         Output number distribution.'
00172     write(*,'(a)') '  -m, --mass        Output mass distribution.'
00173     write(*,'(a)') '  -o, --out <file>  Output filename.'
00174     write(*,'(a)') ''
00175     write(*,'(a)') 'Examples:'
00176     write(*,'(a)') '  extract_sectional_aero_size --num data_0001'
00177     write(*,'(a)') ''
00178 
00179   end subroutine print_help
00180 
00181 end program extract_sectional_aero_size