PartMC
2.2.1
|
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