PartMC  2.2.0
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_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&nbsp;K at the start of the
00417     !! simulation, rises to 290&nbsp;K after 10&nbsp;min, and then
00418     !! falls again to 280&nbsp;K at 30&nbsp;min. Between these times
00419     !! the temperature is linearly interpolated, while after
00420     !! 30&nbsp;min it is held constant at 280&nbsp;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&nbsp;m at the start
00450     !! of the simulation, rises to 1000&nbsp;m after 10&nbsp;min, and
00451     !! then falls again to 800&nbsp;m at 30&nbsp;min. Between these
00452     !! times the mixing layer height is linearly interpolated, while
00453     !! after 30&nbsp;min it is held constant at 800&nbsp;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