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