PartMC 2.1.2
|
00001 ! Copyright (C) 2007-2011 Nicole Riemer and 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 partmc program. 00007 00008 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00009 00010 !> \mainpage PartMC Code Documentation 00011 !! 00012 !! \subpage input_format - Input file format description. 00013 !! 00014 !! \subpage output_format - Output file format description. 00015 !! 00016 !! \subpage module_diagram - Diagram of modules and dependencies. 00017 !! 00018 !! \subpage coding_style - Description of code conventions and style. 00019 !! 00020 !! \subpage publications - Publications about PartMC. 00021 00022 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00023 00024 !> \page input_format Input File Format 00025 !! 00026 !! The input file format is plain text: 00027 !! 00028 !! \subpage spec_file_format "Spec File Format" 00029 !! 00030 !! When running PartMC with the command <tt>partmc input.spec</tt> the 00031 !! first line of the <tt>input.spec</tt> file must define the \c 00032 !! run_type with: 00033 !! <pre> 00034 !! run_type <type> 00035 !! </pre> 00036 !! where <tt><type></tt> is one of \c particle, \c exact, or \c 00037 !! sectional. This determines the type of run as well as the format of the 00038 !! remainder of the spec file. The rest of the spec file is described by: 00039 !! 00040 !! \subpage input_format_particle "Particle-resolved simulation" 00041 !! 00042 !! \subpage input_format_exact "Exact (analytical) solution" 00043 !! 00044 !! \subpage input_format_sectional "Sectional model simulation" 00045 00046 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00047 00048 !> \page module_diagram Module Diagram 00049 !! 00050 !! \dotfile partmc_modules.gv 00051 00052 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00053 00054 !> \page coding_style Coding Style 00055 !! 00056 !! The code is mainly Fortran 90, with a few parts still clearly 00057 !! showing their Fortran 77 heritage. A few Fortran 95 and Fortran 00058 !! 2003 features are used (mainly the \c COMMAND_ARGUMENT_COUNT and \c 00059 !! GET_COMMAND_ARGUMENT intrinsics). The code needs to be processed 00060 !! with \c cpp or a compatible pre-processor. 00061 !! 00062 !! \section oo_fortran Object Oriented Fortran 00063 !! 00064 !! Extensive use is made of Fortran 90 derived types and pointers for 00065 !! dynamic memory allocation of arrays inside derived types. Derived 00066 !! types are named \c my_type_t and are generally defined in modules 00067 !! named \c pmc_my_type within files named \c my_type.F95. Each 00068 !! derived type has allocation and deallocation functions \c 00069 !! my_type_allocate() and \c my_type_deallocate(), where 00070 !! appropriate. Almost all subroutines and function in each \c 00071 !! my_type.F95 file have names of the form \c my_type_*() and take an 00072 !! object of type \c my_type_t (called \c my_type) as the first argument 00073 !! on which to operate. 00074 !! 00075 !! Module names are always the same as the name of the containing 00076 !! file, but prefixed with \c pmc_. Thus the module \c 00077 !! pmc_condense is contained in the file \c condense.F95. 00078 !! 00079 !! \section mem_manage Memory Management 00080 !! 00081 !! The memory allocation policy is that all functions must be called 00082 !! with an already allocated structure. That is, if a subroutine 00083 !! defines a variable of type \c my_type_t, then it must call \c 00084 !! my_type_allocate() or \c my_type_allocate_size() on it before 00085 !! passing it to any other subroutines or functions. The defining 00086 !! subroutine is also responsible for calling \c my_type_deallocate() 00087 !! on every variable it defines. 00088 !! 00089 !! Similarly, any subroutine that declares a pointer variable must 00090 !! allocate it and any data it points to before passing it to other 00091 !! subroutines or functions. If no specific length is known for an array 00092 !! pointer then it should be allocated to zero size. Any subsequent 00093 !! subroutines are free to deallocate and reallocate if they need to 00094 !! change the size. 00095 !! 00096 !! This means that every subroutine (except for allocate and 00097 !! deallocate routines) should contain matching \c 00098 !! allocate()/deallocate() and 00099 !! <tt>my_type_allocate()/my_type_deallocate()</tt> calls. 00100 00101 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00102 00103 !> \page publications PartMC Publications 00104 !! 00105 !! - R. A. Zaveri, J. C. Barnard, 00106 !! R. C. Easter, N. Riemer, and M. West (2010) 00107 !! Particle-resolved simulation of aerosol size, composition, 00108 !! mixing state, and the associated optical and cloud condensation 00109 !! nuclei activation properties in an evolving urban plume, 00110 !! <i>Journal of Geophysical Research</i> 115(D17210), DOI: <a 00111 !! href="http://dx.doi.org/10.1029/2009JD013616">10.1029/2009JD013616</a>. 00112 !! - N. Riemer, M. West, R. A. Zaveri, and 00113 !! R. C. Easter (2010) Estimating black carbon aging 00114 !! time-scales with a particle-resolved aerosol model, <i>Journal 00115 !! of Aerosol Science</i> 41(1), 143-158, DOI: <a 00116 !! href="http://dx.doi.org/10.1016/j.jaerosci.2009.08.009">10.1016/j.jaerosci.2009.08.009</a> 00117 !! - N. Riemer, M. West, R. A. Zaveri, and 00118 !! R. C. Easter (2009) Simulating the evolution of soot 00119 !! mixing state with a particle-resolved aerosol model, <i>Journal 00120 !! of Geophysical Research</i> 114(D09202), DOI: <a 00121 !! href="http://dx.doi.org/10.1029/2008JD011073">10.1029/2008JD011073</a> 00122 !! - R. McGraw, L. Leng, W. Zhu, N. Riemer, and 00123 !! M. West (2008) Aerosol dynamics using the quadrature 00124 !! method of moments: Comparing several quadrature schemes with 00125 !! particle-resolved simulation, <i>Journal of Physics: Conference 00126 !! Series</i> 125(012020), DOI: <a 00127 !! href="http://dx.doi.org/10.1088/1742-6596/125/1/012020">10.1088/1742-6596/125/1/012020</a> 00128 00129 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00130 00131 !> Top level driver. 00132 program partmc 00133 00134 use pmc_mpi 00135 use pmc_bin_grid 00136 use pmc_aero_state 00137 use pmc_aero_dist 00138 use pmc_aero_binned 00139 use pmc_coag_kernel 00140 use pmc_aero_data 00141 use pmc_aero_weight 00142 use pmc_env_data 00143 use pmc_env_state 00144 use pmc_run_part 00145 use pmc_run_exact 00146 use pmc_run_sect 00147 use pmc_spec_file 00148 use pmc_gas_data 00149 use pmc_gas_state 00150 use pmc_util 00151 #ifdef PMC_USE_SUNDIALS 00152 use pmc_condense 00153 #endif 00154 00155 character(len=300) :: spec_name 00156 00157 call pmc_mpi_init() 00158 00159 if (pmc_mpi_rank() == 0) then 00160 ! only the root process accesses the commandline 00161 00162 if (command_argument_count() /= 1) then 00163 call print_usage() 00164 call die_msg(739173192, "invalid commandline arguments") 00165 end if 00166 00167 call get_command_argument(1, spec_name) 00168 end if 00169 00170 call pmc_mpi_bcast_string(spec_name) 00171 call partmc_run(spec_name) 00172 00173 call pmc_mpi_finalize() 00174 00175 contains 00176 00177 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00178 00179 !> Print the usage text to stderr. 00180 subroutine print_usage() 00181 00182 write(*,*) 'Usage: partmc <spec-file>' 00183 00184 end subroutine print_usage 00185 00186 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00187 00188 !> Do a PartMC run. 00189 subroutine partmc_run(spec_name) 00190 00191 !> Spec filename. 00192 character(len=*), intent(in) :: spec_name 00193 00194 type(spec_file_t) :: file 00195 character(len=100) :: run_type 00196 integer :: i 00197 00198 ! check filename (must be "filename.spec") 00199 i = len_trim(spec_name) 00200 if (spec_name((i-4):i) /= '.spec') then 00201 call die_msg(710381938, "input filename must end in .spec") 00202 end if 00203 00204 if (pmc_mpi_rank() == 0) then 00205 ! only the root process does I/O 00206 call spec_file_open(spec_name, file) 00207 call spec_file_read_string(file, 'run_type', run_type) 00208 end if 00209 00210 call pmc_mpi_bcast_string(run_type) 00211 if (trim(run_type) == 'particle') then 00212 call partmc_part(file) 00213 elseif (trim(run_type) == 'exact') then 00214 call partmc_exact(file) 00215 elseif (trim(run_type) == 'sectional') then 00216 call partmc_sect(file) 00217 else 00218 call die_msg(719261940, "unknown run_type: " // trim(run_type)) 00219 end if 00220 00221 end subroutine partmc_run 00222 00223 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00224 00225 !> Run a Monte Carlo simulation. 00226 subroutine partmc_part(file) 00227 00228 !> Spec file. 00229 type(spec_file_t), intent(inout) :: file 00230 00231 type(gas_data_t) :: gas_data 00232 type(gas_state_t) :: gas_state 00233 type(gas_state_t) :: gas_state_init 00234 type(aero_data_t) :: aero_data 00235 type(aero_weight_t) :: aero_weight 00236 type(aero_dist_t) :: aero_dist_init 00237 type(aero_state_t) :: aero_state 00238 type(aero_state_t) :: aero_state_init 00239 type(env_data_t) :: env_data 00240 type(env_state_t) :: env_state 00241 type(env_state_t) :: env_state_init 00242 type(bin_grid_t) :: bin_grid 00243 type(run_part_opt_t) :: run_part_opt 00244 integer :: i_repeat 00245 integer :: rand_init 00246 character, allocatable :: buffer(:) 00247 integer :: buffer_size, max_buffer_size 00248 integer :: position 00249 logical :: do_restart, do_init_equilibriate 00250 character(len=PMC_MAX_FILENAME_LEN) :: restart_filename 00251 integer :: dummy_index, dummy_i_repeat 00252 real(kind=dp) :: dummy_time, dummy_del_t 00253 character(len=PMC_MAX_FILENAME_LEN) :: sub_filename 00254 type(spec_file_t) :: sub_file 00255 00256 !> \page input_format_particle Input File Format: Particle-Resolved Simulation 00257 !! 00258 !! See \ref spec_file_format for the input file text format. 00259 !! 00260 !! A particle-resolved simulation spec file has the parameters: 00261 !! - \b run_type (string): must be \c particle 00262 !! - \b output_prefix (string): prefix of the output filenames 00263 !! --- see \ref output_format for the full name format 00264 !! - \b n_repeat (integer): number of repeats 00265 !! - \b n_part (integer): number of computational particles to 00266 !! simulate (actual number used will vary between <tt>n_part / 00267 !! 2</tt> and <tt>n_part * 2</tt> if \c allow_doubling and \c 00268 !! allow_halving are \c yes) 00269 !! - \b restart (logical): whether to restart the simulation from 00270 !! a saved output data file. If \c restart is \c yes, then the 00271 !! following parameters must also be provided: 00272 !! - \b restart_file (string): name of file from which to load 00273 !! restart data, which must be a PartMC output NetCDF file 00274 !! - \b t_max (real, unit s): total simulation time 00275 !! - \b del_t (real, unit s): timestep size 00276 !! - \b t_output (real, unit s): the interval on which to 00277 !! output data to disk (see \ref output_format) 00278 !! - \b t_progress (real, unit s): the interval on which to 00279 !! write summary information to the screen while running 00280 !! - \subpage input_format_bin_grid --- only used for efficiency 00281 !! gains during coagulation 00282 !! - \subpage input_format_aero_weight (only provide if 00283 !! \c restart is \c no) 00284 !! - \b gas_data (string): name of file from which to read the gas 00285 !! material data (only provide if \c restart is \c no) --- the 00286 !! file format should be \subpage input_format_gas_data 00287 !! - \b gas_init (string): name of file from which to read the 00288 !! initial gas state at the start of the simulation (only 00289 !! provide option if \c restart is \c no) --- the file format 00290 !! should be \subpage input_format_gas_state 00291 !! - \b aerosol_data (string): name of file from which to read the 00292 !! aerosol material data (only provide if \c restart is \c no) 00293 !! --- the file format should be \subpage input_format_aero_data 00294 !! - \b aerosol_init (string): filename containing the initial 00295 !! aerosol state at the start of the simulation (only provide 00296 !! option if \c restart is \c no) --- the file format should 00297 !! be \subpage input_format_aero_dist 00298 !! - \subpage input_format_env_data 00299 !! - \subpage input_format_env_state 00300 !! - \b do_coagulation (logical): whether to perform particle 00301 !! coagulation. If \c do_coagulation is \c yes, then the 00302 !! following parameters must also be provided: 00303 !! - \subpage input_format_coag_kernel 00304 !! - \b do_condensation (logical): whether to perform explicit 00305 !! water condensation (requires SUNDIALS support to be compiled 00306 !! in; cannot be used simultaneously with MOSAIC). If \c 00307 !! do_condensation is \c yes, then the following parameters must 00308 !! also be provided: 00309 !! - \b do_init_equilibriate (logical): whether to equilibriate 00310 !! the water content of each particle before starting the 00311 !! simulation 00312 !! - \b do_mosaic (logical): whether to use the MOSAIC chemistry 00313 !! code (requires support to be compiled in; cannot be used 00314 !! simultaneously with condensation). If \c do_mosaic is \c 00315 !! yes, then the following parameters must also be provided: 00316 !! - \b do_optical (logical): whether to compute optical 00317 !! properties of the aersol particles for the output files --- 00318 !! see output_format_aero_state 00319 !! - \b do_nucleation (logical): whether to perform particle 00320 !! nucleation. If \c do_nucleation is \c yes, then the following 00321 !! parameters must also be provided: 00322 !! - \subpage input_format_nucleate 00323 !! - \b rand_init (integer): if greater than zero then use as 00324 !! the seed for the random number generator, or if zero then 00325 !! generate a random seed for the random number generator --- 00326 !! two simulations on the same machine with the same seed 00327 !! (greater than 0) will produce identical output 00328 !! - \b allow_doubling (logical): if \c yes, then whenever the 00329 !! number of simulated particles falls below <tt>n_part / 00330 !! 2</tt>, every particle is duplicated to give better 00331 !! statistics 00332 !! - \b allow_halving (logical): if \c yes, then whenever the 00333 !! number of simulated particles rises above <tt>n_part * 00334 !! 2</tt>, half of the particles are removed (chosen randomly) 00335 !! to reduce the computational expense 00336 !! - \b record_removals (logical): whether to record information 00337 !! about aerosol particles removed from the simulation --- see 00338 !! \ref output_format_aero_removed 00339 !! - \b do_parallel (logical): whether to run in parallel mode 00340 !! (requires MPI support to be compiled in). If \c do_parallel 00341 !! is \c yes, then the following parameters must also be 00342 !! provided: 00343 !! - \subpage input_format_output 00344 !! - \b mix_timescale (real, unit s): timescale on which to mix 00345 !! aerosol particle information amongst processes in an 00346 !! attempt to keep the aerosol state consistent (the mixing 00347 !! rate is inverse to \c mix_timescale) 00348 !! - \b gas_average (logical): whether to average the gas state 00349 !! amongst processes each timestep, to ensure uniform gas 00350 !! concentrations 00351 !! - \b env_average (logical): whether to average the 00352 !! environment state amongst processes each timestep, to 00353 !! ensure a uniform environment 00354 !! - \subpage input_format_parallel_coag 00355 00356 call gas_data_allocate(gas_data) 00357 call gas_state_allocate(gas_state) 00358 call gas_state_allocate(gas_state_init) 00359 call aero_data_allocate(aero_data) 00360 call aero_weight_allocate(aero_weight) 00361 call aero_dist_allocate(aero_dist_init) 00362 call aero_state_allocate(aero_state) 00363 call aero_state_allocate(aero_state_init) 00364 call env_data_allocate(env_data) 00365 call env_state_allocate(env_state) 00366 call env_state_allocate(env_state_init) 00367 call bin_grid_allocate(bin_grid) 00368 00369 if (pmc_mpi_rank() == 0) then 00370 ! only the root process does I/O 00371 00372 call spec_file_read_string(file, 'output_prefix', & 00373 run_part_opt%output_prefix) 00374 call spec_file_read_integer(file, 'n_repeat', run_part_opt%n_repeat) 00375 call spec_file_read_integer(file, 'n_part', run_part_opt%n_part_ideal) 00376 call spec_file_read_logical(file, 'restart', do_restart) 00377 if (do_restart) then 00378 call spec_file_read_string(file, 'restart_file', restart_filename) 00379 end if 00380 00381 call spec_file_read_real(file, 't_max', run_part_opt%t_max) 00382 call spec_file_read_real(file, 'del_t', run_part_opt%del_t) 00383 call spec_file_read_real(file, 't_output', run_part_opt%t_output) 00384 call spec_file_read_real(file, 't_progress', run_part_opt%t_progress) 00385 00386 call spec_file_read_bin_grid(file, bin_grid) 00387 00388 if (.not. do_restart) then 00389 call spec_file_read_aero_weight(file, aero_weight) 00390 end if 00391 00392 if (do_restart) then 00393 call input_state(restart_filename, bin_grid, aero_data, & 00394 aero_weight, aero_state_init, gas_data, gas_state_init, & 00395 env_state_init, dummy_index, dummy_time, dummy_del_t, & 00396 dummy_i_repeat, run_part_opt%uuid) 00397 end if 00398 00399 if (.not. do_restart) then 00400 call spec_file_read_string(file, 'gas_data', sub_filename) 00401 call spec_file_open(sub_filename, sub_file) 00402 call spec_file_read_gas_data(sub_file, gas_data) 00403 call spec_file_close(sub_file) 00404 00405 call spec_file_read_string(file, 'gas_init', sub_filename) 00406 call spec_file_open(sub_filename, sub_file) 00407 call spec_file_read_gas_state(sub_file, gas_data, & 00408 gas_state_init) 00409 call spec_file_close(sub_file) 00410 00411 call spec_file_read_string(file, 'aerosol_data', sub_filename) 00412 call spec_file_open(sub_filename, sub_file) 00413 call spec_file_read_aero_data(sub_file, aero_data) 00414 call spec_file_close(sub_file) 00415 00416 call spec_file_read_string(file, 'aerosol_init', sub_filename) 00417 call spec_file_open(sub_filename, sub_file) 00418 call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init) 00419 call spec_file_close(sub_file) 00420 end if 00421 00422 call spec_file_read_env_data(file, bin_grid, gas_data, aero_data, & 00423 env_data) 00424 call spec_file_read_env_state(file, env_state_init) 00425 00426 call spec_file_read_logical(file, 'do_coagulation', & 00427 run_part_opt%do_coagulation) 00428 if (run_part_opt%do_coagulation) then 00429 call spec_file_read_coag_kernel_type(file, & 00430 run_part_opt%coag_kernel_type) 00431 else 00432 run_part_opt%coag_kernel_type = COAG_KERNEL_TYPE_INVALID 00433 end if 00434 00435 call spec_file_read_logical(file, 'do_condensation', & 00436 run_part_opt%do_condensation) 00437 #ifndef PMC_USE_SUNDIALS 00438 call assert_msg(121370218, & 00439 run_part_opt%do_condensation .eqv. .false., & 00440 "cannot use condensation, SUNDIALS support is not compiled in") 00441 #endif 00442 if (run_part_opt%do_condensation) then 00443 call spec_file_read_logical(file, 'do_init_equilibriate', & 00444 do_init_equilibriate) 00445 else 00446 do_init_equilibriate = .false. 00447 end if 00448 00449 call spec_file_read_logical(file, 'do_mosaic', run_part_opt%do_mosaic) 00450 if (run_part_opt%do_mosaic .and. (.not. mosaic_support())) then 00451 call spec_file_die_msg(230495365, file, & 00452 'cannot use MOSAIC, support is not compiled in') 00453 end if 00454 if (run_part_opt%do_mosaic .and. run_part_opt%do_condensation) then 00455 call spec_file_die_msg(599877804, file, & 00456 'cannot use MOSAIC and condensation simultaneously') 00457 end if 00458 if (run_part_opt%do_mosaic) then 00459 call spec_file_read_logical(file, 'do_optical', & 00460 run_part_opt%do_optical) 00461 else 00462 run_part_opt%do_optical = .false. 00463 end if 00464 00465 call spec_file_read_logical(file, 'do_nucleation', & 00466 run_part_opt%do_nucleation) 00467 if (run_part_opt%do_nucleation) then 00468 call spec_file_read_nucleate_type(file, run_part_opt%nucleate_type) 00469 else 00470 run_part_opt%nucleate_type = NUCLEATE_TYPE_INVALID 00471 end if 00472 00473 call spec_file_read_integer(file, 'rand_init', rand_init) 00474 call spec_file_read_logical(file, 'allow_doubling', & 00475 run_part_opt%allow_doubling) 00476 call spec_file_read_logical(file, 'allow_halving', & 00477 run_part_opt%allow_halving) 00478 call spec_file_read_logical(file, 'record_removals', & 00479 run_part_opt%record_removals) 00480 00481 call spec_file_read_logical(file, 'do_parallel', & 00482 run_part_opt%do_parallel) 00483 if (run_part_opt%do_parallel) then 00484 #ifndef PMC_USE_MPI 00485 call spec_file_die_msg(929006383, file, & 00486 'cannot use parallel mode, support is not compiled in') 00487 #endif 00488 call spec_file_read_output_type(file, run_part_opt%output_type) 00489 call spec_file_read_real(file, 'mix_timescale', & 00490 run_part_opt%mix_timescale) 00491 call spec_file_read_logical(file, 'gas_average', & 00492 run_part_opt%gas_average) 00493 call spec_file_read_logical(file, 'env_average', & 00494 run_part_opt%env_average) 00495 call spec_file_read_parallel_coag_type(file, & 00496 run_part_opt%parallel_coag_type) 00497 else 00498 run_part_opt%output_type = OUTPUT_TYPE_SINGLE 00499 run_part_opt%mix_timescale = 0d0 00500 run_part_opt%gas_average = .false. 00501 run_part_opt%env_average = .false. 00502 run_part_opt%parallel_coag_type = PARALLEL_COAG_TYPE_LOCAL 00503 end if 00504 00505 call spec_file_close(file) 00506 end if 00507 00508 ! finished reading .spec data, now broadcast data 00509 00510 ! initialize RNG with random seed for UUID generation 00511 call pmc_srand(0, pmc_mpi_rank()) 00512 00513 if (.not. do_restart) then 00514 call uuid4_str(run_part_opt%uuid) 00515 end if 00516 00517 #ifdef PMC_USE_MPI 00518 if (pmc_mpi_rank() == 0) then 00519 ! root process determines size 00520 max_buffer_size = 0 00521 max_buffer_size = max_buffer_size & 00522 + pmc_mpi_pack_size_run_part_opt(run_part_opt) 00523 max_buffer_size = max_buffer_size & 00524 + pmc_mpi_pack_size_bin_grid(bin_grid) 00525 max_buffer_size = max_buffer_size & 00526 + pmc_mpi_pack_size_gas_data(gas_data) 00527 max_buffer_size = max_buffer_size & 00528 + pmc_mpi_pack_size_gas_state(gas_state_init) 00529 max_buffer_size = max_buffer_size & 00530 + pmc_mpi_pack_size_aero_data(aero_data) 00531 max_buffer_size = max_buffer_size & 00532 + pmc_mpi_pack_size_aero_weight(aero_weight) 00533 max_buffer_size = max_buffer_size & 00534 + pmc_mpi_pack_size_aero_dist(aero_dist_init) 00535 max_buffer_size = max_buffer_size & 00536 + pmc_mpi_pack_size_env_data(env_data) 00537 max_buffer_size = max_buffer_size & 00538 + pmc_mpi_pack_size_env_state(env_state_init) 00539 max_buffer_size = max_buffer_size & 00540 + pmc_mpi_pack_size_integer(rand_init) 00541 max_buffer_size = max_buffer_size & 00542 + pmc_mpi_pack_size_logical(do_restart) 00543 max_buffer_size = max_buffer_size & 00544 + pmc_mpi_pack_size_logical(do_init_equilibriate) 00545 max_buffer_size = max_buffer_size & 00546 + pmc_mpi_pack_size_aero_state(aero_state_init) 00547 00548 allocate(buffer(max_buffer_size)) 00549 00550 position = 0 00551 call pmc_mpi_pack_run_part_opt(buffer, position, run_part_opt) 00552 call pmc_mpi_pack_bin_grid(buffer, position, bin_grid) 00553 call pmc_mpi_pack_gas_data(buffer, position, gas_data) 00554 call pmc_mpi_pack_gas_state(buffer, position, gas_state_init) 00555 call pmc_mpi_pack_aero_data(buffer, position, aero_data) 00556 call pmc_mpi_pack_aero_weight(buffer, position, aero_weight) 00557 call pmc_mpi_pack_aero_dist(buffer, position, aero_dist_init) 00558 call pmc_mpi_pack_env_data(buffer, position, env_data) 00559 call pmc_mpi_pack_env_state(buffer, position, env_state_init) 00560 call pmc_mpi_pack_integer(buffer, position, rand_init) 00561 call pmc_mpi_pack_logical(buffer, position, do_restart) 00562 call pmc_mpi_pack_logical(buffer, position, do_init_equilibriate) 00563 call pmc_mpi_pack_aero_state(buffer, position, aero_state_init) 00564 call assert(181905491, position <= max_buffer_size) 00565 buffer_size = position ! might be less than we allocated 00566 end if 00567 00568 ! tell everyone the size 00569 call pmc_mpi_bcast_integer(buffer_size) 00570 00571 if (pmc_mpi_rank() /= 0) then 00572 ! non-root processes allocate space 00573 allocate(buffer(buffer_size)) 00574 end if 00575 00576 ! broadcast data to everyone 00577 call pmc_mpi_bcast_packed(buffer) 00578 00579 if (pmc_mpi_rank() /= 0) then 00580 ! non-root processes unpack data 00581 position = 0 00582 call pmc_mpi_unpack_run_part_opt(buffer, position, run_part_opt) 00583 call pmc_mpi_unpack_bin_grid(buffer, position, bin_grid) 00584 call pmc_mpi_unpack_gas_data(buffer, position, gas_data) 00585 call pmc_mpi_unpack_gas_state(buffer, position, gas_state_init) 00586 call pmc_mpi_unpack_aero_data(buffer, position, aero_data) 00587 call pmc_mpi_unpack_aero_weight(buffer, position, aero_weight) 00588 call pmc_mpi_unpack_aero_dist(buffer, position, aero_dist_init) 00589 call pmc_mpi_unpack_env_data(buffer, position, env_data) 00590 call pmc_mpi_unpack_env_state(buffer, position, env_state_init) 00591 call pmc_mpi_unpack_integer(buffer, position, rand_init) 00592 call pmc_mpi_unpack_logical(buffer, position, do_restart) 00593 call pmc_mpi_unpack_logical(buffer, position, do_init_equilibriate) 00594 call pmc_mpi_unpack_aero_state(buffer, position, aero_state_init) 00595 call assert(143770146, position == buffer_size) 00596 end if 00597 00598 ! free the buffer 00599 deallocate(buffer) 00600 #endif 00601 00602 ! re-initialize RNG with the given seed 00603 call pmc_rand_finalize() 00604 call pmc_srand(rand_init, pmc_mpi_rank()) 00605 00606 call gas_state_deallocate(gas_state) 00607 call gas_state_allocate_size(gas_state, gas_data%n_spec) 00608 call cpu_time(run_part_opt%t_wall_start) 00609 00610 do i_repeat = 1,run_part_opt%n_repeat 00611 run_part_opt%i_repeat = i_repeat 00612 00613 call gas_state_copy(gas_state_init, gas_state) 00614 if (do_restart) then 00615 call aero_state_copy(aero_state_init, aero_state) 00616 else 00617 call aero_state_deallocate(aero_state) 00618 call aero_state_allocate_size(aero_state, bin_grid%n_bin, & 00619 aero_data%n_spec, aero_data%n_source) 00620 aero_state%comp_vol = real(run_part_opt%n_part_ideal, kind=dp) / 00621 aero_dist_weighted_num_conc(aero_dist_init, aero_weight) 00622 call aero_state_add_aero_dist_sample(aero_state, bin_grid, & 00623 aero_data, aero_weight, aero_dist_init, 1d0, 0d0) 00624 end if 00625 call env_state_copy(env_state_init, env_state) 00626 call env_data_init_state(env_data, env_state, & 00627 env_state_init%elapsed_time) 00628 00629 #ifdef PMC_USE_SUNDIALS 00630 if (do_init_equilibriate) then 00631 call condense_equilib_particles(bin_grid, env_state, aero_data, & 00632 aero_weight, aero_state) 00633 end if 00634 #endif 00635 00636 call run_part(bin_grid, env_data, env_state, aero_data, aero_weight, & 00637 aero_state, gas_data, gas_state, run_part_opt) 00638 00639 end do 00640 00641 call gas_data_deallocate(gas_data) 00642 call gas_state_deallocate(gas_state) 00643 call gas_state_deallocate(gas_state_init) 00644 call aero_data_deallocate(aero_data) 00645 call aero_weight_deallocate(aero_weight) 00646 call aero_dist_deallocate(aero_dist_init) 00647 call aero_state_deallocate(aero_state) 00648 call aero_state_deallocate(aero_state_init) 00649 call env_data_deallocate(env_data) 00650 call env_state_deallocate(env_state) 00651 call env_state_deallocate(env_state_init) 00652 call bin_grid_deallocate(bin_grid) 00653 00654 call pmc_rand_finalize() 00655 00656 end subroutine partmc_part 00657 00658 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00659 00660 !> Run an exact solution simulation. 00661 subroutine partmc_exact(file) 00662 00663 !> Spec file. 00664 type(spec_file_t), intent(inout) :: file 00665 00666 character(len=100) :: soln_name 00667 type(aero_data_t) :: aero_data 00668 type(env_data_t) :: env_data 00669 type(env_state_t) :: env_state 00670 type(aero_dist_t) :: aero_dist_init 00671 type(run_exact_opt_t) :: run_exact_opt 00672 type(bin_grid_t) :: bin_grid 00673 type(gas_data_t) :: gas_data 00674 character(len=PMC_MAX_FILENAME_LEN) :: sub_filename 00675 type(spec_file_t) :: sub_file 00676 00677 !> \page input_format_exact Exact (Analytical) Solution 00678 !! 00679 !! The coagulation kernel and initial distribution must be matched 00680 !! for an exact solution to exist. The valid choices are: 00681 !! 00682 !! <table> 00683 !! <tr><th>Coagulation kernel</th> 00684 !! <th>Initial aerosol distribution</th></tr> 00685 !! <tr><td>Additive</td> 00686 !! <td>Single exponential mode</td></tr> 00687 !! <tr><td>Constant</td> 00688 !! <td>Single exponential mode</td></tr> 00689 !! <tr><td>Zero</td> 00690 !! <td>Anything</td></tr> 00691 !! </table> 00692 !! 00693 !! See \ref spec_file_format for the input file text format. 00694 !! 00695 !! An exact (analytical) simulation spec file has the parameters: 00696 !! - \b run_type (string): must be \c exact 00697 !! - \b output_prefix (string): prefix of the output filenames --- 00698 !! the filenames will be of the form \c PREFIX_SSSSSSSS.nc where 00699 !! \c SSSSSSSS is is the eight-digit output index (starting at 1 00700 !! and incremented each time the state is output) 00701 !! - \b t_max (real, unit s): total simulation time 00702 !! - \b t_output (real, unit s): the interval on which to output 00703 !! data to disk and to print progress information to the screen 00704 !! (see \ref output_format) 00705 !! - \subpage input_format_bin_grid 00706 !! - \b gas_data (string): name of file from which to read the 00707 !! gas material data --- the file format should be 00708 !! \subpage input_format_gas_data 00709 !! - \b aerosol_data (string): name of file from which to read the 00710 !! aerosol material data --- the file format should be 00711 !! \subpage input_format_aero_data 00712 !! - \b aerosol_init (string): filename containing the initial 00713 !! aerosol state at the start of the simulation --- the file 00714 !! format should be \subpage input_format_aero_dist 00715 !! - \subpage input_format_env_data 00716 !! - \subpage input_format_env_state 00717 !! - \b do_coagulation (logical): whether to perform particle 00718 !! coagulation. If \c do_coagulation is \c yes, then the 00719 !! following parameters must also be provided: 00720 !! - \subpage input_format_coag_kernel 00721 !! 00722 !! Example: 00723 !! <pre> 00724 !! run_type exact # exact solution 00725 !! output_prefix additive_exact # prefix of output files 00726 !! 00727 !! t_max 600 # total simulation time (s) 00728 !! t_output 60 # output interval (0 disables) (s) 00729 !! 00730 !! n_bin 160 # number of bins 00731 !! d_min 1e-8 # minimum diameter (m) 00732 !! d_max 1e-3 # maximum diameter (m) 00733 !! 00734 !! gas_data gas_data.dat # file containing gas data 00735 !! 00736 !! aerosol_data aero_data.dat # file containing aerosol data 00737 !! aerosol_init aero_init_dist.dat # aerosol initial condition file 00738 !! 00739 !! temp_profile temp.dat # temperature profile file 00740 !! height_profile height.dat # height profile file 00741 !! gas_emissions gas_emit.dat # gas emissions file 00742 !! gas_background gas_back.dat # background gas mixing ratios file 00743 !! aero_emissions aero_emit.dat # aerosol emissions file 00744 !! aero_background aero_back.dat # aerosol background file 00745 !! 00746 !! rel_humidity 0.999 # initial relative humidity (1) 00747 !! pressure 1e5 # initial pressure (Pa) 00748 !! latitude 0 # latitude (degrees, -90 to 90) 00749 !! longitude 0 # longitude (degrees, -180 to 180) 00750 !! altitude 0 # altitude (m) 00751 !! start_time 0 # start time (s since 00:00 UTC) 00752 !! start_day 1 # start day of year (UTC) 00753 !! 00754 !! do_coagulation yes # whether to do coagulation (yes/no) 00755 !! kernel additive # Additive coagulation kernel 00756 !! </pre> 00757 00758 ! only serial code here 00759 if (pmc_mpi_rank() /= 0) then 00760 return 00761 end if 00762 00763 call bin_grid_allocate(bin_grid) 00764 call gas_data_allocate(gas_data) 00765 call aero_data_allocate(aero_data) 00766 call env_data_allocate(env_data) 00767 call env_state_allocate(env_state) 00768 call aero_dist_allocate(aero_dist_init) 00769 00770 call spec_file_read_string(file, 'output_prefix', run_exact_opt%prefix) 00771 00772 call spec_file_read_real(file, 't_max', run_exact_opt%t_max) 00773 call spec_file_read_real(file, 't_output', run_exact_opt%t_output) 00774 00775 call spec_file_read_bin_grid(file, bin_grid) 00776 00777 call spec_file_read_string(file, 'gas_data', sub_filename) 00778 call spec_file_open(sub_filename, sub_file) 00779 call spec_file_read_gas_data(sub_file, gas_data) 00780 call spec_file_close(sub_file) 00781 00782 call spec_file_read_string(file, 'aerosol_data', sub_filename) 00783 call spec_file_open(sub_filename, sub_file) 00784 call spec_file_read_aero_data(sub_file, aero_data) 00785 call spec_file_close(sub_file) 00786 00787 call spec_file_read_string(file, 'aerosol_init', sub_filename) 00788 call spec_file_open(sub_filename, sub_file) 00789 call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init) 00790 call spec_file_close(sub_file) 00791 00792 call spec_file_read_env_data(file, bin_grid, gas_data, aero_data, & 00793 env_data) 00794 call spec_file_read_env_state(file, env_state) 00795 00796 call spec_file_read_logical(file, 'do_coagulation', & 00797 run_exact_opt%do_coagulation) 00798 if (run_exact_opt%do_coagulation) then 00799 call spec_file_read_coag_kernel_type(file, & 00800 run_exact_opt%coag_kernel_type) 00801 else 00802 run_exact_opt%coag_kernel_type = COAG_KERNEL_TYPE_INVALID 00803 end if 00804 00805 call spec_file_close(file) 00806 00807 ! finished reading .spec data, now do the run 00808 00809 call pmc_srand(0, 0) 00810 00811 call uuid4_str(run_exact_opt%uuid) 00812 00813 call env_data_init_state(env_data, env_state, 0d0) 00814 00815 call run_exact(bin_grid, env_data, env_state, aero_data, & 00816 aero_dist_init, run_exact_opt) 00817 00818 call aero_data_deallocate(aero_data) 00819 call env_data_deallocate(env_data) 00820 call env_state_deallocate(env_state) 00821 call bin_grid_deallocate(bin_grid) 00822 call gas_data_deallocate(gas_data) 00823 call aero_dist_deallocate(aero_dist_init) 00824 00825 call pmc_rand_finalize() 00826 00827 end subroutine partmc_exact 00828 00829 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00830 00831 !> Run a sectional code simulation. 00832 subroutine partmc_sect(file) 00833 00834 !> Spec file. 00835 type(spec_file_t), intent(inout) :: file 00836 00837 type(run_sect_opt_t) :: run_sect_opt 00838 type(aero_data_t) :: aero_data 00839 type(aero_dist_t) :: aero_dist_init 00840 type(aero_state_t) :: aero_init 00841 type(env_data_t) :: env_data 00842 type(env_state_t) :: env_state 00843 type(bin_grid_t) :: bin_grid 00844 type(gas_data_t) :: gas_data 00845 character(len=PMC_MAX_FILENAME_LEN) :: sub_filename 00846 type(spec_file_t) :: sub_file 00847 00848 !> \page input_format_sectional Sectional Model Simulation 00849 !! 00850 !! See \ref spec_file_format for the input file text format. 00851 !! 00852 !! A sectional simulation spec file has the parameters: 00853 !! - \b run_type (string): must be \c sectional 00854 !! - \b output_prefix (string): prefix of the output filenames --- 00855 !! the filenames will be of the form \c PREFIX_SSSSSSSS.nc where 00856 !! \c SSSSSSSS is is the eight-digit output index (starting at 1 00857 !! and incremented each time the state is output) 00858 !! - \b del_t (real, unit s): timestep size 00859 !! - \b t_output (real, unit s): the interval on which to 00860 !! output data to disk (see \ref output_format) 00861 !! - \b t_progress (real, unit s): the interval on which to 00862 !! write summary information to the screen while running 00863 !! - \subpage input_format_bin_grid 00864 !! - \b gas_data (string): name of file from which to read the 00865 !! gas material data --- the file format should be 00866 !! \subpage input_format_gas_data 00867 !! - \b aerosol_data (string): name of file from which to read the 00868 !! aerosol material data --- the file format should be 00869 !! \subpage input_format_aero_data 00870 !! - \b aerosol_init (string): filename containing the initial 00871 !! aerosol state at the start of the simulation --- the file 00872 !! format should be \subpage input_format_aero_dist 00873 !! - \subpage input_format_env_data 00874 !! - \subpage input_format_env_state 00875 !! - \b do_coagulation (logical): whether to perform particle 00876 !! coagulation. If \c do_coagulation is \c yes, then the 00877 !! following parameters must also be provided: 00878 !! - \subpage input_format_coag_kernel 00879 !! 00880 !! Example: 00881 !! <pre> 00882 !! run_type sectional # sectional code run 00883 !! output_prefix brown_sect # prefix of output files 00884 !! 00885 !! t_max 86400 # total simulation time (s) 00886 !! del_t 60 # timestep (s) 00887 !! t_output 3600 # output interval (0 disables) (s) 00888 !! t_progress 600 # progress printing interval (0 disables) (s) 00889 !! 00890 !! n_bin 220 # number of bins 00891 !! d_min 1e-10 # minimum diameter (m) 00892 !! d_max 1e-4 # maximum diameter (m) 00893 !! 00894 !! gas_data gas_data.dat # file containing gas data 00895 !! aerosol_data aero_data.dat # file containing aerosol data 00896 !! aerosol_init aero_init_dist.dat # initial aerosol distribution 00897 !! 00898 !! temp_profile temp.dat # temperature profile file 00899 !! height_profile height.dat # height profile file 00900 !! gas_emissions gas_emit.dat # gas emissions file 00901 !! gas_background gas_back.dat # background gas mixing ratios file 00902 !! aero_emissions aero_emit.dat # aerosol emissions file 00903 !! aero_background aero_back.dat # aerosol background file 00904 !! 00905 !! rel_humidity 0.999 # initial relative humidity (1) 00906 !! pressure 1e5 # initial pressure (Pa) 00907 !! latitude 0 # latitude (degrees_north, -90 to 90) 00908 !! longitude 0 # longitude (degrees_east, -180 to 180) 00909 !! altitude 0 # altitude (m) 00910 !! start_time 0 # start time (s since 00:00 UTC) 00911 !! start_day 1 # start day of year (UTC) 00912 !! 00913 !! do_coagulation yes # whether to do coagulation (yes/no) 00914 !! kernel brown # coagulation kernel 00915 !! </pre> 00916 00917 ! only serial code here 00918 if (pmc_mpi_rank() /= 0) then 00919 return 00920 end if 00921 00922 call aero_data_allocate(aero_data) 00923 call aero_dist_allocate(aero_dist_init) 00924 call env_state_allocate(env_state) 00925 call env_data_allocate(env_data) 00926 call bin_grid_allocate(bin_grid) 00927 call gas_data_allocate(gas_data) 00928 00929 call spec_file_read_string(file, 'output_prefix', run_sect_opt%prefix) 00930 00931 call spec_file_read_real(file, 't_max', run_sect_opt%t_max) 00932 call spec_file_read_real(file, 'del_t', run_sect_opt%del_t) 00933 call spec_file_read_real(file, 't_output', run_sect_opt%t_output) 00934 call spec_file_read_real(file, 't_progress', run_sect_opt%t_progress) 00935 00936 call spec_file_read_bin_grid(file, bin_grid) 00937 00938 call spec_file_read_string(file, 'gas_data', sub_filename) 00939 call spec_file_open(sub_filename, sub_file) 00940 call spec_file_read_gas_data(sub_file, gas_data) 00941 call spec_file_close(sub_file) 00942 00943 call spec_file_read_string(file, 'aerosol_data', sub_filename) 00944 call spec_file_open(sub_filename, sub_file) 00945 call spec_file_read_aero_data(sub_file, aero_data) 00946 call spec_file_close(sub_file) 00947 00948 call spec_file_read_string(file, 'aerosol_init', sub_filename) 00949 call spec_file_open(sub_filename, sub_file) 00950 call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init) 00951 call spec_file_close(sub_file) 00952 00953 call spec_file_read_env_data(file, bin_grid, gas_data, aero_data, & 00954 env_data) 00955 call spec_file_read_env_state(file, env_state) 00956 00957 call spec_file_read_logical(file, 'do_coagulation', & 00958 run_sect_opt%do_coagulation) 00959 if (run_sect_opt%do_coagulation) then 00960 call spec_file_read_coag_kernel_type(file, & 00961 run_sect_opt%coag_kernel_type) 00962 else 00963 run_sect_opt%coag_kernel_type = COAG_KERNEL_TYPE_INVALID 00964 end if 00965 00966 call spec_file_close(file) 00967 00968 ! finished reading .spec data, now do the run 00969 00970 call pmc_srand(0, 0) 00971 00972 call uuid4_str(run_sect_opt%uuid) 00973 00974 call env_data_init_state(env_data, env_state, 0d0) 00975 00976 call run_sect(bin_grid, gas_data, aero_data, aero_dist_init, env_data, & 00977 env_state, run_sect_opt) 00978 00979 call aero_data_deallocate(aero_data) 00980 call aero_dist_deallocate(aero_dist_init) 00981 call env_state_deallocate(env_state) 00982 call env_data_deallocate(env_data) 00983 call bin_grid_deallocate(bin_grid) 00984 call gas_data_deallocate(gas_data) 00985 00986 call pmc_rand_finalize() 00987 00988 end subroutine partmc_sect 00989 00990 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00991 00992 end program partmc