PartMC 2.1.3
env_data.F90
Go to the documentation of this file.
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&nbsp;K at the start of the
00402     !! simulation, rises to 290&nbsp;K after 10&nbsp;min, and then
00403     !! falls again to 280&nbsp;K at 30&nbsp;min. Between these times
00404     !! the temperature is linearly interpolated, while after
00405     !! 30&nbsp;min it is held constant at 280&nbsp;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&nbsp;m at the start
00435     !! of the simulation, rises to 1000&nbsp;m after 10&nbsp;min, and
00436     !! then falls again to 800&nbsp;m at 30&nbsp;min. Between these
00437     !! times the mixing layer height is linearly interpolated, while
00438     !! after 30&nbsp;min it is held constant at 800&nbsp;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