PartMC 2.1.4
|
00001 ! Copyright (C) 2005-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 pmc_env_data module. 00007 00008 !> The env_data_t structure and associated subroutines. 00009 module pmc_env_data 00010 00011 use pmc_gas_state 00012 use pmc_aero_dist 00013 use pmc_util 00014 use pmc_env_state 00015 use pmc_spec_file 00016 use pmc_bin_grid 00017 use pmc_aero_data 00018 use pmc_gas_data 00019 use pmc_mpi 00020 #ifdef PMC_USE_MPI 00021 use mpi 00022 #endif 00023 00024 !> Environment data. 00025 !! 00026 !! This is everything needed to support the current environment 00027 !! state. The environment data is not time-dependent, whereas the 00028 !! environment state in env_state_t is time-dependent. 00029 !! 00030 !! The temperature, emissions and background states are profiles 00031 !! prescribed as functions of time by giving a number of times and 00032 !! the corresponding data. Simple data such as temperature is 00033 !! linearly interpoloated between times, with constant interpolation 00034 !! outside of the range of times. Gases and aerosols are 00035 !! interpolated with gas_state_interp_1d() and 00036 !! aero_dist_interp_1d(), respectively. 00037 type env_data_t 00038 !> Temperature set-point times (s). 00039 real(kind=dp), pointer :: temp_time(:) 00040 !> Temperatures at set-points (K). 00041 real(kind=dp), pointer :: temp(:) 00042 00043 !> Height set-point times (s). 00044 real(kind=dp), pointer :: height_time(:) 00045 !> Heights at set-points (m). 00046 real(kind=dp), pointer :: height(:) 00047 00048 !> Gas emission set-point times (s). 00049 real(kind=dp), pointer :: gas_emission_time(:) 00050 !> Gas emisssion rates at set-points (s^{-1}). 00051 real(kind=dp), pointer :: gas_emission_rate(:) 00052 !> Gas emissions at set-points. 00053 type(gas_state_t), pointer :: gas_emission(:) 00054 00055 !> Gas-background dilution set-point times (s). 00056 real(kind=dp), pointer :: gas_dilution_time(:) 00057 !> Gas-background dilution rates at set-points (s^{-1}). 00058 real(kind=dp), pointer :: gas_dilution_rate(:) 00059 !> Background gas mixing ratios at set-points. 00060 type(gas_state_t), pointer :: gas_background(:) 00061 00062 !> Aerosol emission set-points times (s). 00063 real(kind=dp), pointer :: aero_emission_time(:) 00064 !> Aerosol emission rates at set-points (s^{-1}). 00065 real(kind=dp), pointer :: aero_emission_rate(:) 00066 !> Aerosol emissions at set-points. 00067 type(aero_dist_t), pointer :: aero_emission(:) 00068 00069 !> Aerosol-background dilution set-point times (s). 00070 real(kind=dp), pointer :: aero_dilution_time(:) 00071 !> Aerosol-background dilution rates at set-points (s^{-1}). 00072 real(kind=dp), pointer :: aero_dilution_rate(:) 00073 !> Aerosol background at set-points. 00074 type(aero_dist_t), pointer :: aero_background(:) 00075 end type env_data_t 00076 00077 contains 00078 00079 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00080 00081 !> Allocate an env_data. 00082 subroutine env_data_allocate(env_data) 00083 00084 !> Environment data. 00085 type(env_data_t), intent(out) :: env_data 00086 00087 allocate(env_data%temp_time(0)) 00088 allocate(env_data%temp(0)) 00089 00090 allocate(env_data%height_time(0)) 00091 allocate(env_data%height(0)) 00092 00093 allocate(env_data%gas_emission_time(0)) 00094 allocate(env_data%gas_emission_rate(0)) 00095 allocate(env_data%gas_emission(0)) 00096 00097 allocate(env_data%gas_dilution_time(0)) 00098 allocate(env_data%gas_dilution_rate(0)) 00099 allocate(env_data%gas_background(0)) 00100 00101 allocate(env_data%aero_emission_time(0)) 00102 allocate(env_data%aero_emission_rate(0)) 00103 allocate(env_data%aero_emission(0)) 00104 00105 allocate(env_data%aero_dilution_time(0)) 00106 allocate(env_data%aero_dilution_rate(0)) 00107 allocate(env_data%aero_background(0)) 00108 00109 end subroutine env_data_allocate 00110 00111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00112 00113 !> Free all storage. 00114 subroutine env_data_deallocate(env_data) 00115 00116 !> Environment data. 00117 type(env_data_t), intent(inout) :: env_data 00118 00119 integer :: i 00120 00121 deallocate(env_data%temp_time) 00122 deallocate(env_data%temp) 00123 00124 deallocate(env_data%height_time) 00125 deallocate(env_data%height) 00126 00127 do i = 1,size(env_data%gas_emission) 00128 call gas_state_deallocate(env_data%gas_emission(i)) 00129 end do 00130 deallocate(env_data%gas_emission_time) 00131 deallocate(env_data%gas_emission_rate) 00132 deallocate(env_data%gas_emission) 00133 00134 do i = 1,size(env_data%gas_background) 00135 call gas_state_deallocate(env_data%gas_background(i)) 00136 end do 00137 deallocate(env_data%gas_dilution_time) 00138 deallocate(env_data%gas_dilution_rate) 00139 deallocate(env_data%gas_background) 00140 00141 do i = 1,size(env_data%aero_emission) 00142 call aero_dist_deallocate(env_data%aero_emission(i)) 00143 end do 00144 deallocate(env_data%aero_emission_time) 00145 deallocate(env_data%aero_emission_rate) 00146 deallocate(env_data%aero_emission) 00147 00148 do i = 1,size(env_data%aero_background) 00149 call aero_dist_deallocate(env_data%aero_background(i)) 00150 end do 00151 deallocate(env_data%aero_dilution_time) 00152 deallocate(env_data%aero_dilution_rate) 00153 deallocate(env_data%aero_background) 00154 00155 end subroutine env_data_deallocate 00156 00157 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00158 00159 !> Copy structure. 00160 subroutine env_data_copy(env_data_from, env_data_to) 00161 00162 !> Source environment data. 00163 type(env_data_t), intent(in) :: env_data_from 00164 !> Destination environment data. 00165 type(env_data_t), intent(inout) :: env_data_to 00166 00167 integer :: i 00168 00169 call env_data_deallocate(env_data_to) 00170 00171 allocate(env_data_to%temp_time( & 00172 size(env_data_from%temp_time))) 00173 env_data_to%temp_time = env_data_from%temp_time 00174 allocate(env_data_to%temp( & 00175 size(env_data_from%temp))) 00176 env_data_to%temp = env_data_from%temp 00177 00178 allocate(env_data_to%height_time( & 00179 size(env_data_from%height_time))) 00180 env_data_to%height_time = env_data_from%height_time 00181 allocate(env_data_to%height( & 00182 size(env_data_from%height))) 00183 env_data_to%height = env_data_from%height 00184 00185 allocate(env_data_to%gas_emission_time( & 00186 size(env_data_from%gas_emission_time))) 00187 env_data_to%gas_emission_time = env_data_from%gas_emission_time 00188 allocate(env_data_to%gas_emission_rate( & 00189 size(env_data_from%gas_emission_rate))) 00190 env_data_to%gas_emission_rate = env_data_from%gas_emission_rate 00191 allocate(env_data_to%gas_emission( & 00192 size(env_data_from%gas_emission))) 00193 do i = 1,size(env_data_from%gas_emission) 00194 call gas_state_allocate(env_data_to%gas_emission(i)) 00195 call gas_state_copy(env_data_from%gas_emission(i), & 00196 env_data_to%gas_emission(i)) 00197 end do 00198 00199 allocate(env_data_to%gas_dilution_time( & 00200 size(env_data_from%gas_dilution_time))) 00201 env_data_to%gas_dilution_time = env_data_from%gas_dilution_time 00202 allocate(env_data_to%gas_dilution_rate( & 00203 size(env_data_from%gas_dilution_rate))) 00204 env_data_to%gas_dilution_rate = env_data_from%gas_dilution_rate 00205 allocate(env_data_to%gas_background( & 00206 size(env_data_from%gas_background))) 00207 do i = 1,size(env_data_from%gas_background) 00208 call gas_state_allocate(env_data_to%gas_background(i)) 00209 call gas_state_copy(env_data_from%gas_background(i), & 00210 env_data_to%gas_background(i)) 00211 end do 00212 00213 allocate(env_data_to%aero_emission_time( & 00214 size(env_data_from%aero_emission_time))) 00215 env_data_to%aero_emission_time = env_data_from%aero_emission_time 00216 allocate(env_data_to%aero_emission_rate( & 00217 size(env_data_from%aero_emission_rate))) 00218 env_data_to%aero_emission_rate = env_data_from%aero_emission_rate 00219 allocate(env_data_to%aero_emission( & 00220 size(env_data_from%aero_emission))) 00221 do i = 1,size(env_data_from%aero_emission) 00222 call aero_dist_allocate(env_data_to%aero_emission(i)) 00223 call aero_dist_copy(env_data_from%aero_emission(i), & 00224 env_data_to%aero_emission(i)) 00225 end do 00226 00227 allocate(env_data_to%aero_dilution_time( & 00228 size(env_data_from%aero_dilution_time))) 00229 env_data_to%aero_dilution_time = env_data_from%aero_dilution_time 00230 allocate(env_data_to%aero_dilution_rate( & 00231 size(env_data_from%aero_dilution_rate))) 00232 env_data_to%aero_dilution_rate = env_data_from%aero_dilution_rate 00233 allocate(env_data_to%aero_background( & 00234 size(env_data_from%aero_background))) 00235 do i = 1,size(env_data_from%aero_background) 00236 call aero_dist_allocate(env_data_to%aero_background(i)) 00237 call aero_dist_copy(env_data_from%aero_background(i), & 00238 env_data_to%aero_background(i)) 00239 end do 00240 00241 end subroutine env_data_copy 00242 00243 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00244 00245 !> Initialize the time-dependent contents of the 00246 !> environment. Thereafter env_data_update_state() should be used. 00247 subroutine env_data_init_state(env_data, env_state, time) 00248 00249 !> Environment data. 00250 type(env_data_t), intent(in) :: env_data 00251 !> Environment state to update. 00252 type(env_state_t), intent(inout) :: env_state 00253 !> Current time (s). 00254 real(kind=dp), intent(in) :: time 00255 00256 env_state%temp = interp_1d(env_data%temp_time, env_data%temp, time) 00257 env_state%height = interp_1d(env_data%height_time, env_data%height, time) 00258 env_state%elapsed_time = time 00259 00260 ! init gas and aerosol emissions and background 00261 call gas_state_interp_1d(env_data%gas_emission, & 00262 env_data%gas_emission_time, env_data%gas_emission_rate, & 00263 time, env_state%gas_emissions, env_state%gas_emission_rate) 00264 call gas_state_interp_1d(env_data%gas_background, & 00265 env_data%gas_dilution_time, env_data%gas_dilution_rate, & 00266 time, env_state%gas_background, env_state%gas_dilution_rate) 00267 call aero_dist_interp_1d(env_data%aero_emission, & 00268 env_data%aero_emission_time, env_data%aero_emission_rate, & 00269 time, env_state%aero_emissions, env_state%aero_emission_rate) 00270 call aero_dist_interp_1d(env_data%aero_background, & 00271 env_data%aero_dilution_time, env_data%aero_dilution_rate, & 00272 time, env_state%aero_background, env_state%aero_dilution_rate) 00273 00274 end subroutine env_data_init_state 00275 00276 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00277 00278 !> Update time-dependent contents of the environment. 00279 !> env_data_init_state() should have been called at the start. 00280 subroutine env_data_update_state(env_data, env_state, time, & 00281 update_rel_humid) 00282 00283 !> Environment data. 00284 type(env_data_t), intent(in) :: env_data 00285 !> Environment state to update. 00286 type(env_state_t), intent(inout) :: env_state 00287 !> Current time (s). 00288 real(kind=dp), intent(in) :: time 00289 !> Whether to update the relative humidity. 00290 logical, intent(in) :: update_rel_humid 00291 00292 !> Ambient water vapor pressure (Pa). 00293 real(kind=dp) :: pmv 00294 00295 ! Update temperature and adjust relative humidity to maintain 00296 ! water mixing ratio. This uses the fact that we keep the total 00297 ! pressure constant, so ambient water vapor pressure is also 00298 ! constant (whatever temperature and hence volume does). 00299 pmv = env_state_sat_vapor_pressure(env_state) * env_state%rel_humid 00300 env_state%temp = interp_1d(env_data%temp_time, env_data%temp, time) 00301 if (update_rel_humid) then 00302 env_state%rel_humid = pmv / env_state_sat_vapor_pressure(env_state) 00303 end if 00304 00305 env_state%height = interp_1d(env_data%height_time, env_data%height, time) 00306 env_state%elapsed_time = time 00307 00308 ! update gas and aerosol emissions and background 00309 call gas_state_interp_1d(env_data%gas_emission, & 00310 env_data%gas_emission_time, env_data%gas_emission_rate, & 00311 time, env_state%gas_emissions, env_state%gas_emission_rate) 00312 call gas_state_interp_1d(env_data%gas_background, & 00313 env_data%gas_dilution_time, env_data%gas_dilution_rate, & 00314 time, env_state%gas_background, env_state%gas_dilution_rate) 00315 call aero_dist_interp_1d(env_data%aero_emission, & 00316 env_data%aero_emission_time, env_data%aero_emission_rate, & 00317 time, env_state%aero_emissions, env_state%aero_emission_rate) 00318 call aero_dist_interp_1d(env_data%aero_background, & 00319 env_data%aero_dilution_time, env_data%aero_dilution_rate, & 00320 time, env_state%aero_background, env_state%aero_dilution_rate) 00321 00322 end subroutine env_data_update_state 00323 00324 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00325 00326 !> Read environment data from an spec file. 00327 subroutine spec_file_read_env_data(file, bin_grid, gas_data, & 00328 aero_data, env_data) 00329 00330 !> Spec file. 00331 type(spec_file_t), intent(inout) :: file 00332 !> Bin grid. 00333 type(bin_grid_t), intent(in) :: bin_grid 00334 !> Gas data values. 00335 type(gas_data_t), intent(in) :: gas_data 00336 !> Aerosol data. 00337 type(aero_data_t), intent(inout) :: aero_data 00338 !> Environment data. 00339 type(env_data_t), intent(inout) :: env_data 00340 00341 character(len=PMC_MAX_FILENAME_LEN) :: sub_filename 00342 type(spec_file_t) :: sub_file 00343 00344 ! note that we have to hard-code the list for doxygen below 00345 00346 !> \page input_format_env_data Input File Format: Environment Data 00347 !! 00348 !! The environment parameters are divided into those specified at 00349 !! the start of the simulation and then either held constant or 00350 !! computed for the rest of the simulation, and those parameters 00351 !! given as prescribed profiles for the entire simulation 00352 !! duration. The variables below are for the second type --- for 00353 !! the computed values see \ref input_format_env_state. 00354 !! 00355 !! The environment data parameters are: 00356 !! <ul> 00357 !! <li> \b temp_profile (string): the name of the file from which to 00358 !! read the temperature profile --- the file format should be 00359 !! \subpage input_format_temp_profile 00360 !! <li> \b height_profile (string): the name of the file from which 00361 !! to read the mixing layer height profile --- the file format 00362 !! should be \subpage input_format_height_profile 00363 !! <li> \b gas_emissions (string): the name of the file from which to 00364 !! read the gas emissions profile --- the file format should be 00365 !! \subpage input_format_gas_profile 00366 !! <li> \b gas_background (string): the name of the file from which 00367 !! to read the gas background profile --- the file format should 00368 !! be \subpage input_format_gas_profile 00369 !! <li> \b aero_emissions (string): the name of the file from which 00370 !! to read the aerosol emissions profile --- the file format 00371 !! should be \subpage input_format_aero_dist_profile 00372 !! <li> \b aero_background (string): the name of the file from which 00373 !! to read the aerosol background profile --- the file format 00374 !! should be \subpage input_format_aero_dist_profile 00375 !! </ul> 00376 !! 00377 !! See also: 00378 !! - \ref spec_file_format --- the input file text format 00379 00380 !> \page input_format_temp_profile Input File Format: Temperature Profile 00381 !! 00382 !! A temperature profile input file must consist of two lines: 00383 !! - the first line must begin with \c time and should be followed 00384 !! by \f$N\f$ space-separated real scalars, giving the times (in 00385 !! s after the start of the simulation) of the temperature set 00386 !! points --- the times must be in increasing order 00387 !! - the second line must begin with \c temp and should be followed 00388 !! by \f$N\f$ space-separated real scalars, giving the 00389 !! temperatures (in K) at the corresponding times 00390 !! 00391 !! The temperature profile is linearly interpolated between the 00392 !! specified times, while before the first time it takes the first 00393 !! temperature value and after the last time it takes the last 00394 !! temperature value. 00395 !! 00396 !! Example: 00397 !! <pre> 00398 !! time 0 600 1800 # time (in s) after simulation start 00399 !! temp 270 290 280 # temperature (in K) 00400 !! </pre> 00401 !! Here the temperature starts at 270 K at the start of the 00402 !! simulation, rises to 290 K after 10 min, and then 00403 !! falls again to 280 K at 30 min. Between these times 00404 !! the temperature is linearly interpolated, while after 00405 !! 30 min it is held constant at 280 K. 00406 !! 00407 !! See also: 00408 !! - \ref spec_file_format --- the input file text format 00409 !! - \ref input_format_env_data --- the environment data 00410 !! containing the temperature profile 00411 00412 !> \page input_format_height_profile Input File Format: Mixing Layer Height Profile 00413 !! 00414 !! A mixing layer height profile input file must consist of two 00415 !! lines: 00416 !! - the first line must begin with \c time and should be followed 00417 !! by \f$N\f$ space-separated real scalars, giving the times (in 00418 !! s after the start of the simulation) of the height set 00419 !! points --- the times must be in increasing order 00420 !! - the second line must begin with \c height and should be 00421 !! followed by \f$N\f$ space-separated real scalars, giving the 00422 !! mixing layer heights (in m) at the corresponding times 00423 !! 00424 !! The mixing layer height profile is linearly interpolated 00425 !! between the specified times, while before the first time it 00426 !! takes the first height value and after the last time it takes 00427 !! the last height value. 00428 !! 00429 !! Example: 00430 !! <pre> 00431 !! time 0 600 1800 # time (in s) after simulation start 00432 !! height 500 1000 800 # mixing layer height (in m) 00433 !! </pre> 00434 !! Here the mixing layer height starts at 500 m at the start 00435 !! of the simulation, rises to 1000 m after 10 min, and 00436 !! then falls again to 800 m at 30 min. Between these 00437 !! times the mixing layer height is linearly interpolated, while 00438 !! after 30 min it is held constant at 800 m. 00439 !! 00440 !! See also: 00441 !! - \ref spec_file_format --- the input file text format 00442 !! - \ref input_format_env_data --- the environment data 00443 !! containing the mixing layer height profile 00444 00445 ! temperature profile 00446 call spec_file_read_string(file, "temp_profile", sub_filename) 00447 call spec_file_open(sub_filename, sub_file) 00448 call spec_file_read_timed_real_array(sub_file, "temp", & 00449 env_data%temp_time, env_data%temp) 00450 call spec_file_close(sub_file) 00451 00452 ! height profile 00453 call spec_file_read_string(file, "height_profile", sub_filename) 00454 call spec_file_open(sub_filename, sub_file) 00455 call spec_file_read_timed_real_array(sub_file, "height", & 00456 env_data%height_time, env_data%height) 00457 call spec_file_close(sub_file) 00458 00459 ! gas emissions profile 00460 call spec_file_read_string(file, "gas_emissions", sub_filename) 00461 call spec_file_open(sub_filename, sub_file) 00462 call spec_file_read_gas_states_times_rates(sub_file, gas_data, & 00463 env_data%gas_emission_time, env_data%gas_emission_rate, & 00464 env_data%gas_emission) 00465 call spec_file_close(sub_file) 00466 00467 ! gas background profile 00468 call spec_file_read_string(file, "gas_background", sub_filename) 00469 call spec_file_open(sub_filename, sub_file) 00470 call spec_file_read_gas_states_times_rates(sub_file, gas_data, & 00471 env_data%gas_dilution_time, env_data%gas_dilution_rate, & 00472 env_data%gas_background) 00473 call spec_file_close(sub_file) 00474 00475 ! aerosol emissions profile 00476 call spec_file_read_string(file, "aero_emissions", sub_filename) 00477 call spec_file_open(sub_filename, sub_file) 00478 call spec_file_read_aero_dists_times_rates(sub_file, aero_data, & 00479 bin_grid, env_data%aero_emission_time, & 00480 env_data%aero_emission_rate, env_data%aero_emission) 00481 call spec_file_close(sub_file) 00482 00483 ! aerosol background profile 00484 call spec_file_read_string(file, "aero_background", sub_filename) 00485 call spec_file_open(sub_filename, sub_file) 00486 call spec_file_read_aero_dists_times_rates(sub_file, aero_data, & 00487 bin_grid, env_data%aero_dilution_time, & 00488 env_data%aero_dilution_rate, env_data%aero_background) 00489 call spec_file_close(sub_file) 00490 00491 end subroutine spec_file_read_env_data 00492 00493 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00494 00495 !> Determines the number of bytes required to pack the given value. 00496 integer function pmc_mpi_pack_size_env_data(val) 00497 00498 !> Value to pack. 00499 type(env_data_t), intent(in) :: val 00500 00501 integer :: total_size, i, n 00502 00503 total_size = & 00504 pmc_mpi_pack_size_real_array(val%temp_time) & 00505 + pmc_mpi_pack_size_real_array(val%temp) & 00506 + pmc_mpi_pack_size_real_array(val%height_time) & 00507 + pmc_mpi_pack_size_real_array(val%height) & 00508 + pmc_mpi_pack_size_real_array(val%gas_emission_time) & 00509 + pmc_mpi_pack_size_real_array(val%gas_emission_rate) & 00510 + pmc_mpi_pack_size_real_array(val%gas_dilution_time) & 00511 + pmc_mpi_pack_size_real_array(val%gas_dilution_rate) & 00512 + pmc_mpi_pack_size_real_array(val%aero_emission_time) & 00513 + pmc_mpi_pack_size_real_array(val%aero_emission_rate) & 00514 + pmc_mpi_pack_size_real_array(val%aero_dilution_time) & 00515 + pmc_mpi_pack_size_real_array(val%aero_dilution_rate) 00516 do i = 1,size(val%gas_emission) 00517 total_size = total_size & 00518 + pmc_mpi_pack_size_gas_state(val%gas_emission(i)) 00519 end do 00520 do i = 1,size(val%gas_background) 00521 total_size = total_size & 00522 + pmc_mpi_pack_size_gas_state(val%gas_background(i)) 00523 end do 00524 do i = 1,size(val%aero_emission) 00525 total_size = total_size & 00526 + pmc_mpi_pack_size_aero_dist(val%aero_emission(i)) 00527 end do 00528 do i = 1,size(val%aero_background) 00529 total_size = total_size & 00530 + pmc_mpi_pack_size_aero_dist(val%aero_background(i)) 00531 end do 00532 00533 pmc_mpi_pack_size_env_data = total_size 00534 00535 end function pmc_mpi_pack_size_env_data 00536 00537 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00538 00539 !> Packs the given value into the buffer, advancing position. 00540 subroutine pmc_mpi_pack_env_data(buffer, position, val) 00541 00542 !> Memory buffer. 00543 character, intent(inout) :: buffer(:) 00544 !> Current buffer position. 00545 integer, intent(inout) :: position 00546 !> Value to pack. 00547 type(env_data_t), intent(in) :: val 00548 00549 #ifdef PMC_USE_MPI 00550 integer :: prev_position, i 00551 00552 prev_position = position 00553 call pmc_mpi_pack_real_array(buffer, position, val%temp_time) 00554 call pmc_mpi_pack_real_array(buffer, position, val%temp) 00555 call pmc_mpi_pack_real_array(buffer, position, val%height_time) 00556 call pmc_mpi_pack_real_array(buffer, position, val%height) 00557 call pmc_mpi_pack_real_array(buffer, position, val%gas_emission_time) 00558 call pmc_mpi_pack_real_array(buffer, position, val%gas_emission_rate) 00559 call pmc_mpi_pack_real_array(buffer, position, val%gas_dilution_time) 00560 call pmc_mpi_pack_real_array(buffer, position, val%gas_dilution_rate) 00561 call pmc_mpi_pack_real_array(buffer, position, val%aero_emission_time) 00562 call pmc_mpi_pack_real_array(buffer, position, val%aero_emission_rate) 00563 call pmc_mpi_pack_real_array(buffer, position, val%aero_dilution_time) 00564 call pmc_mpi_pack_real_array(buffer, position, val%aero_dilution_rate) 00565 do i = 1,size(val%gas_emission) 00566 call pmc_mpi_pack_gas_state(buffer, position, val%gas_emission(i)) 00567 end do 00568 do i = 1,size(val%gas_background) 00569 call pmc_mpi_pack_gas_state(buffer, position, val%gas_background(i)) 00570 end do 00571 do i = 1,size(val%aero_emission) 00572 call pmc_mpi_pack_aero_dist(buffer, position, val%aero_emission(i)) 00573 end do 00574 do i = 1,size(val%aero_background) 00575 call pmc_mpi_pack_aero_dist(buffer, position, val%aero_background(i)) 00576 end do 00577 call assert(639466930, & 00578 position - prev_position <= pmc_mpi_pack_size_env_data(val)) 00579 #endif 00580 00581 end subroutine pmc_mpi_pack_env_data 00582 00583 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00584 00585 !> Unpacks the given value from the buffer, advancing position. 00586 subroutine pmc_mpi_unpack_env_data(buffer, position, val) 00587 00588 !> Memory buffer. 00589 character, intent(inout) :: buffer(:) 00590 !> Current buffer position. 00591 integer, intent(inout) :: position 00592 !> Value to pack. 00593 type(env_data_t), intent(inout) :: val 00594 00595 #ifdef PMC_USE_MPI 00596 integer :: prev_position, i 00597 00598 call env_data_deallocate(val) 00599 call env_data_allocate(val) 00600 prev_position = position 00601 call pmc_mpi_unpack_real_array(buffer, position, val%temp_time) 00602 call pmc_mpi_unpack_real_array(buffer, position, val%temp) 00603 call pmc_mpi_unpack_real_array(buffer, position, val%height_time) 00604 call pmc_mpi_unpack_real_array(buffer, position, val%height) 00605 call pmc_mpi_unpack_real_array(buffer, position, val%gas_emission_time) 00606 call pmc_mpi_unpack_real_array(buffer, position, val%gas_emission_rate) 00607 call pmc_mpi_unpack_real_array(buffer, position, val%gas_dilution_time) 00608 call pmc_mpi_unpack_real_array(buffer, position, val%gas_dilution_rate) 00609 call pmc_mpi_unpack_real_array(buffer, position, val%aero_emission_time) 00610 call pmc_mpi_unpack_real_array(buffer, position, val%aero_emission_rate) 00611 call pmc_mpi_unpack_real_array(buffer, position, val%aero_dilution_time) 00612 call pmc_mpi_unpack_real_array(buffer, position, val%aero_dilution_rate) 00613 deallocate(val%gas_emission) 00614 deallocate(val%gas_background) 00615 deallocate(val%aero_emission) 00616 deallocate(val%aero_background) 00617 allocate(val%gas_emission(size(val%gas_emission_time))) 00618 allocate(val%gas_background(size(val%gas_dilution_time))) 00619 allocate(val%aero_emission(size(val%aero_emission_time))) 00620 allocate(val%aero_background(size(val%aero_dilution_time))) 00621 do i = 1,size(val%gas_emission) 00622 call gas_state_allocate(val%gas_emission(i)) 00623 call pmc_mpi_unpack_gas_state(buffer, position, val%gas_emission(i)) 00624 end do 00625 do i = 1,size(val%gas_background) 00626 call gas_state_allocate(val%gas_background(i)) 00627 call pmc_mpi_unpack_gas_state(buffer, position, val%gas_background(i)) 00628 end do 00629 do i = 1,size(val%aero_emission) 00630 call aero_dist_allocate(val%aero_emission(i)) 00631 call pmc_mpi_unpack_aero_dist(buffer, position, val%aero_emission(i)) 00632 end do 00633 do i = 1,size(val%aero_background) 00634 call aero_dist_allocate(val%aero_background(i)) 00635 call pmc_mpi_unpack_aero_dist(buffer, position, val%aero_background(i)) 00636 end do 00637 call assert(611542570, & 00638 position - prev_position <= pmc_mpi_pack_size_env_data(val)) 00639 #endif 00640 00641 end subroutine pmc_mpi_unpack_env_data 00642 00643 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00644 00645 end module pmc_env_data