PartMC  2.8.0
env_state.F90
Go to the documentation of this file.
1 ! Copyright (C) 2005-2012 Nicole Riemer and Matthew West
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The pmc_env_state module.
7 
8 !> The env_state_t structure and associated subroutines.
10 
11  use pmc_constants
12  use pmc_util
13  use pmc_spec_file
14  use pmc_mpi
15  use pmc_netcdf
16 #ifdef PMC_USE_CAMP
17  use camp_camp_state
18 #endif
19 #ifdef PMC_USE_MPI
20  use mpi
21 #endif
22 
23  !> Current environment state.
24  !!
25  !! All quantities are instantaneous, describing the state at a
26  !! particular instant of time. Constant data and other data not
27  !! associated with the current environment state is stored in
28  !! scenario_t.
30  !> Temperature (K).
31  real(kind=dp) :: temp
32  !> Relative humidity (1).
33  real(kind=dp) :: rel_humid
34  !> Ambient pressure (Pa).
35  real(kind=dp) :: pressure
36  !> Longitude (degrees).
37  real(kind=dp) :: longitude
38  !> Latitude (degrees).
39  real(kind=dp) :: latitude
40  !> Altitude (m).
41  real(kind=dp) :: altitude
42 #ifdef PMC_USE_WRF
43  !> Height of lower edge of grid cell (m).
44  real(kind=dp) :: z_min
45  !> Height of upper edge of grid cell (m).
46  real(kind=dp) :: z_max
47  !> Inverse density (m^3 kg^{-1}).
48  real(kind=dp) :: inverse_density
49  !> Grid cell volume.
50  real(kind=dp) :: cell_volume
51  !> East-West index for grid cell.
52  integer :: cell_ix
53  !> North-South index for grid cell.
54  integer :: cell_iy
55  !> Top-Bottom index for grid cell.
56  integer :: cell_iz
57  !> Eddy diffusivity coefficient (m^2 s^{-2}).
58  real(kind=dp) :: diff_coef
59  !> Transfer probability in all directions due to advection.
60  real(kind=dp), allocatable :: prob_advection(:,:,:,:)
61  !> Transfer probability in all directions due to diffusion.
62  real(kind=dp), allocatable :: prob_diffusion(:,:,:,:)
63  !> Transfer probability in vertical direction due to turbulent diffusion.
64  real(kind=dp), allocatable :: prob_vert_diffusion(:,:)
65 #endif
66  !> Start time (s since 00:00 UTC on \c start_day).
67  real(kind=dp) :: start_time
68  !> Start day of year (UTC).
69  integer :: start_day
70  !> Time since \c start_time (s).
71  real(kind=dp) :: elapsed_time
72  !> Solar zenith angle (radians from zenith).
73  real(kind=dp) :: solar_zenith_angle
74  !> Box height (m).
75  real(kind=dp) :: height
76  !> Scaling coefficient for additive coagulation kernel.
77  real(kind=dp) :: additive_kernel_coefficient
78  end type env_state_t
79 
80 contains
81 
82 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
83 
84  !> env_state += env_state_delta
85  subroutine env_state_add(env_state, env_state_delta)
86 
87  !> Environment.
88  type(env_state_t), intent(inout) :: env_state
89  !> Increment.
90  type(env_state_t), intent(in) :: env_state_delta
91 
92  env_state%temp = env_state%temp + env_state_delta%temp
93  env_state%rel_humid = env_state%rel_humid + env_state_delta%rel_humid
94  env_state%pressure = env_state%pressure + env_state_delta%pressure
95  env_state%longitude = env_state%longitude + env_state_delta%longitude
96  env_state%latitude = env_state%latitude + env_state_delta%latitude
97  env_state%altitude = env_state%altitude + env_state_delta%altitude
98  env_state%start_time = env_state%start_time + env_state_delta%start_time
99  env_state%start_day = env_state%start_day + env_state_delta%start_day
100  env_state%elapsed_time = env_state%elapsed_time &
101  + env_state_delta%elapsed_time
102  env_state%solar_zenith_angle = env_state%solar_zenith_angle &
103  + env_state_delta%solar_zenith_angle
104  env_state%height = env_state%height + env_state_delta%height
105 
106  end subroutine env_state_add
107 
108 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
109 
110  !> env_state *= alpha
111  subroutine env_state_scale(env_state, alpha)
112 
113  !> Environment.
114  type(env_state_t), intent(inout) :: env_state
115  !> Scale factor.
116  real(kind=dp), intent(in) :: alpha
117 
118  env_state%temp = env_state%temp * alpha
119  env_state%rel_humid = env_state%rel_humid * alpha
120  env_state%pressure = env_state%pressure * alpha
121  env_state%longitude = env_state%longitude * alpha
122  env_state%latitude = env_state%latitude * alpha
123  env_state%altitude = env_state%altitude * alpha
124  env_state%start_time = env_state%start_time * alpha
125  env_state%start_day = nint(real(env_state%start_day, kind=dp) * alpha)
126  env_state%elapsed_time = env_state%elapsed_time * alpha
127  env_state%solar_zenith_angle = env_state%solar_zenith_angle * alpha
128  env_state%height = env_state%height * alpha
129 
130  end subroutine env_state_scale
131 
132 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
133 
134  !> Adds the given water volume to the water vapor and updates all
135  !> environment quantities.
136  subroutine env_state_change_water_volume(env_state, dv)
137 
138  !> Environment state to update.
139  type(env_state_t), intent(inout) :: env_state
140  !> Volume concentration of water added (m^3/m^3).
141  real(kind=dp), intent(in) :: dv
142 
143  real(kind=dp) pmv ! ambient water vapor pressure (Pa)
144  real(kind=dp) mv ! ambient water vapor density (kg m^{-3})
145  ! pmv and mv are related by the factor molec_weight/(R*T)
146  real(kind=dp) dmv ! change of water density (kg m^{-3})
147 
148  dmv = dv * const%water_density
149  pmv = env_state_sat_vapor_pressure(env_state) * env_state%rel_humid
150  mv = const%water_molec_weight / (const%univ_gas_const*env_state%temp) * pmv
151  mv = mv - dmv
152  if (mv < 0d0) then
153  call warn_msg(980320483, "relative humidity tried to go negative")
154  mv = 0d0
155  end if
156  env_state%rel_humid = const%univ_gas_const * env_state%temp &
157  / const%water_molec_weight * mv &
158  / env_state_sat_vapor_pressure(env_state)
159 
160  end subroutine env_state_change_water_volume
161 
162 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
163 
164  !> Computes the current saturation vapor pressure (Pa).
165  real(kind=dp) function env_state_sat_vapor_pressure(env_state)
166 
167  !> Environment state.
168  type(env_state_t), intent(in) :: env_state
169 
170  env_state_sat_vapor_pressure = const%water_eq_vap_press &
171  * 10d0**(7.45d0 * (env_state%temp - const%water_freeze_temp) &
172  / (env_state%temp - 38d0))
173 
174  end function env_state_sat_vapor_pressure
175 
176 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
177 
178  !> Air density (kg m^{-3}).
179  real(kind=dp) function env_state_air_den(env_state)
180 
181  !> Environment state.
182  type(env_state_t), intent(in) :: env_state
183 
184  env_state_air_den = const%air_molec_weight &
185  * env_state_air_molar_den(env_state)
186 
187  end function env_state_air_den
188 
189 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
190 
191  !> Air molar density (mol m^{-3}).
192  real(kind=dp) function env_state_air_molar_den(env_state)
193 
194  !> Environment state.
195  type(env_state_t), intent(in) :: env_state
196 
197  env_state_air_molar_den = env_state%pressure &
198  / (const%univ_gas_const * env_state%temp)
199 
200  end function env_state_air_molar_den
201 
202 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
203 
204  !> Converts relative humidity (1) to water vapor mixing ratio (ppb).
205  !!
206  !! Uses equation (1.10) of Seinfeld and Pandis Atmospheric Chemistry and
207  !! Physics From Air Pollution to Climate Change Second Edition, 2006.
208  real(kind=dp) function env_state_rel_humid_to_mix_rat(env_state)
209 
210  !> Environment state.
211  type(env_state_t), intent(in) :: env_state
212 
213  real(kind=dp), parameter :: t_steam = 373.15 ! steam temperature (K)
214  real(kind=dp) :: a, water_vp
215 
216  a = 1.0 - t_steam / env_state%temp
217  a = (((-0.1299 * a - 0.6445) * a - 1.976) * a + 13.3185) * a
218  water_vp = 101325.0 * exp(a) ! (Pa)
219  env_state_rel_humid_to_mix_rat = env_state%rel_humid * water_vp * 1.0e9 &
220  / env_state%pressure ! (ppb)
221 
222  end function env_state_rel_humid_to_mix_rat
223 
224 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
225 
226  !> Condensation \f$A\f$ parameter.
227  real(kind=dp) function env_state_a(env_state)
228 
229  !> Environment state.
230  type(env_state_t), intent(in) :: env_state
231 
232  env_state_a = 4d0 * const%water_surf_eng * const%water_molec_weight &
233  / (const%univ_gas_const * env_state%temp * const%water_density)
234 
235  end function env_state_a
236 
237 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
238 
239  !> Convert (ppb) to (molecules m^{-3}).
240  real(kind=dp) function env_state_ppb_to_conc(env_state, ppb)
241 
242  !> Environment state.
243  type(env_state_t), intent(in) :: env_state
244  !> Mixing ratio (ppb).
245  real(kind=dp), intent(in) :: ppb
246 
247  env_state_ppb_to_conc = ppb / 1d9 * env_state_air_molar_den(env_state) &
248  * const%avagadro
249 
250  end function env_state_ppb_to_conc
251 
252 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
253 
254  !> Convert (molecules m^{-3}) to (ppb).
255  real(kind=dp) function env_state_conc_to_ppb(env_state, conc)
256 
257  !> Environment state.
258  type(env_state_t), intent(in) :: env_state
259  !> Concentration (molecules m^{-3}).
260  real(kind=dp), intent(in) :: conc
261 
262  env_state_conc_to_ppb = conc * 1d9 / env_state_air_molar_den(env_state) &
263  / const%avagadro
264 
265  end function env_state_conc_to_ppb
266 
267 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
268 
269 #ifdef PMC_USE_CAMP
270  !> Sets CAMP environmental variables from PartMC environmental variables.
271  subroutine env_state_set_camp_env_state(env_state, camp_state)
272 
273  !> Environment state.
274  type(env_state_t), intent(in) :: env_state
275  !> Environment state.
276  type(camp_state_t), intent(in) :: camp_state
277 
278 
279  camp_state%env_states(1)%val%rel_humid = env_state%rel_humid
280  camp_state%env_states(1)%val%temp = env_state%temp
281 
282 
283  end subroutine env_state_set_camp_env_state
284 #endif
285 
286 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
287 
288  !> Read environment specification from a spec file.
289  subroutine spec_file_read_env_state(file, env_state)
290 
291  !> Spec file.
292  type(spec_file_t), intent(inout) :: file
293  !> Environment data.
294  type(env_state_t), intent(inout) :: env_state
295 
296  !> \page input_format_env_state Input File Format: Environment State
297  !!
298  !! The environment parameters are divided into those specified at
299  !! the start of the simulation and then either held constant or
300  !! computed for the rest of the simulation, and those parameters
301  !! given as prescribed profiles for the entire simulation
302  !! duration. The variables below are for the first type --- for
303  !! the prescribed profiles see \ref input_format_scenario.
304  !!
305  !! The environment state is specified by the parameters:
306  !! - \b rel_humidity (real, dimensionless): the relative humidity
307  !! (0 is completely unsaturated and 1 is fully saturated)
308  !! - \b latitude (real, unit degrees_north): the latitude of the
309  !! simulation location
310  !! - \b longitude (real, unit degrees_east): the longitude of the
311  !! simulation location
312  !! - \b altitude (real, unit m): the altitude of the simulation
313  !! location
314  !! - \b start_time (real, unit s): the time-of-day of the start of
315  !! the simulation (in seconds past midnight)
316  !! - \b start_day (integer): the day-of-year of the start of the
317  !! simulation (starting from 1 on the first day of the year)
318  !!
319  !! See also:
320  !! - \ref spec_file_format --- the input file text format
321  !! - \ref output_format_env_state --- the corresponding output
322  !! format
323  !! - \ref input_format_scenario --- the prescribed profiles of
324  !! other environment data
325 
326  call spec_file_read_real(file, 'rel_humidity', env_state%rel_humid)
327  call spec_file_read_real(file, 'latitude', env_state%latitude)
328  call spec_file_read_real(file, 'longitude', env_state%longitude)
329  call spec_file_read_real(file, 'altitude', env_state%altitude)
330  call spec_file_read_real(file, 'start_time', env_state%start_time)
331  call spec_file_read_integer(file, 'start_day', env_state%start_day)
332 
333  end subroutine spec_file_read_env_state
334 
335 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
336 
337  !> Average val over all processes.
338  subroutine env_state_mix(val)
339 
340  !> Value to average.
341  type(env_state_t), intent(inout) :: val
342 
343 #ifdef PMC_USE_MPI
344  type(env_state_t) :: val_avg
345 
346  call pmc_mpi_allreduce_average_real(val%temp, val_avg%temp)
347  call pmc_mpi_allreduce_average_real(val%rel_humid, val_avg%rel_humid)
348  call pmc_mpi_allreduce_average_real(val%pressure, val_avg%pressure)
349  val%temp = val_avg%temp
350  val%rel_humid = val_avg%rel_humid
351  val%pressure = val_avg%pressure
352 #endif
353 
354  end subroutine env_state_mix
355 
356 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
357 
358  !> Average val over all processes, with the result only on the root
359  !> process.
360  subroutine env_state_reduce_avg(val)
361 
362  !> Value to average.
363  type(env_state_t), intent(inout) :: val
364 
365 #ifdef PMC_USE_MPI
366  type(env_state_t) :: val_avg
367 
368  call pmc_mpi_reduce_avg_real(val%temp, val_avg%temp)
369  call pmc_mpi_reduce_avg_real(val%rel_humid, val_avg%rel_humid)
370  call pmc_mpi_reduce_avg_real(val%pressure, val_avg%pressure)
371  if (pmc_mpi_rank() == 0) then
372  val%temp = val_avg%temp
373  val%rel_humid = val_avg%rel_humid
374  val%pressure = val_avg%pressure
375  end if
376 #endif
377 
378  end subroutine env_state_reduce_avg
379 
380 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
381 
382  !> Determines the number of bytes required to pack the given value.
383  integer function pmc_mpi_pack_size_env_state(val)
384 
385  !> Value to pack.
386  type(env_state_t), intent(in) :: val
387 
389  pmc_mpi_pack_size_real(val%temp) &
390  + pmc_mpi_pack_size_real(val%rel_humid) &
391  + pmc_mpi_pack_size_real(val%pressure) &
392  + pmc_mpi_pack_size_real(val%longitude) &
393  + pmc_mpi_pack_size_real(val%latitude) &
394  + pmc_mpi_pack_size_real(val%altitude) &
395 #ifdef PMC_USE_WRF
396  + pmc_mpi_pack_size_real(val%z_min) &
397  + pmc_mpi_pack_size_real(val%z_max) &
398  + pmc_mpi_pack_size_real(val%inverse_density) &
399  + pmc_mpi_pack_size_real(val%cell_volume) &
400  + pmc_mpi_pack_size_integer(val%cell_ix) &
401  + pmc_mpi_pack_size_integer(val%cell_iy) &
402  + pmc_mpi_pack_size_integer(val%cell_iz) &
403  + pmc_mpi_pack_size_real(val%diff_coef) &
404  + pmc_mpi_pack_size_real_array_4d(val%prob_advection) &
405  + pmc_mpi_pack_size_real_array_4d(val%prob_diffusion) &
406  + pmc_mpi_pack_size_real_array_2d(val%prob_vert_diffusion) &
407 #endif
408  + pmc_mpi_pack_size_real(val%start_time) &
409  + pmc_mpi_pack_size_integer(val%start_day) &
410  + pmc_mpi_pack_size_real(val%elapsed_time) &
411  + pmc_mpi_pack_size_real(val%solar_zenith_angle) &
412  + pmc_mpi_pack_size_real(val%height) &
413  + pmc_mpi_pack_size_real(val%additive_kernel_coefficient)
414 
415  end function pmc_mpi_pack_size_env_state
416 
417 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
418 
419  !> Packs the given value into the buffer, advancing position.
420  subroutine pmc_mpi_pack_env_state(buffer, position, val)
421 
422  !> Memory buffer.
423  character, intent(inout) :: buffer(:)
424  !> Current buffer position.
425  integer, intent(inout) :: position
426  !> Value to pack.
427  type(env_state_t), intent(in) :: val
428 
429 #ifdef PMC_USE_MPI
430  integer :: prev_position
431 
432  prev_position = position
433  call pmc_mpi_pack_real(buffer, position, val%temp)
434  call pmc_mpi_pack_real(buffer, position, val%rel_humid)
435  call pmc_mpi_pack_real(buffer, position, val%pressure)
436  call pmc_mpi_pack_real(buffer, position, val%longitude)
437  call pmc_mpi_pack_real(buffer, position, val%latitude)
438  call pmc_mpi_pack_real(buffer, position, val%altitude)
439 #ifdef PMC_USE_WRF
440  call pmc_mpi_pack_real(buffer, position, val%z_min)
441  call pmc_mpi_pack_real(buffer, position, val%z_max)
442  call pmc_mpi_pack_real(buffer, position, val%inverse_density)
443  call pmc_mpi_pack_real(buffer, position, val%cell_volume)
444  call pmc_mpi_pack_integer(buffer, position, val%cell_ix)
445  call pmc_mpi_pack_integer(buffer, position, val%cell_iy)
446  call pmc_mpi_pack_integer(buffer, position, val%cell_iz)
447  call pmc_mpi_pack_real(buffer, position, val%diff_coef)
448  call pmc_mpi_pack_real_array_4d(buffer, position, val%prob_advection)
449  call pmc_mpi_pack_real_array_4d(buffer, position, val%prob_diffusion)
450  call pmc_mpi_pack_real_array_2d(buffer, position, val%prob_vert_diffusion)
451 #endif
452  call pmc_mpi_pack_real(buffer, position, val%start_time)
453  call pmc_mpi_pack_integer(buffer, position, val%start_day)
454  call pmc_mpi_pack_real(buffer, position, val%elapsed_time)
455  call pmc_mpi_pack_real(buffer, position, val%solar_zenith_angle)
456  call pmc_mpi_pack_real(buffer, position, val%height)
457  call pmc_mpi_pack_real(buffer, position, val%additive_kernel_coefficient)
458  call assert(464101191, &
459  position - prev_position <= pmc_mpi_pack_size_env_state(val))
460 #endif
461 
462  end subroutine pmc_mpi_pack_env_state
463 
464 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
465 
466  !> Unpacks the given value from the buffer, advancing position.
467  subroutine pmc_mpi_unpack_env_state(buffer, position, val)
468 
469  !> Memory buffer.
470  character, intent(inout) :: buffer(:)
471  !> Current buffer position.
472  integer, intent(inout) :: position
473  !> Value to pack.
474  type(env_state_t), intent(inout) :: val
475 
476 #ifdef PMC_USE_MPI
477  integer :: prev_position
478 
479  prev_position = position
480  call pmc_mpi_unpack_real(buffer, position, val%temp)
481  call pmc_mpi_unpack_real(buffer, position, val%rel_humid)
482  call pmc_mpi_unpack_real(buffer, position, val%pressure)
483  call pmc_mpi_unpack_real(buffer, position, val%longitude)
484  call pmc_mpi_unpack_real(buffer, position, val%latitude)
485  call pmc_mpi_unpack_real(buffer, position, val%altitude)
486 #ifdef PMC_USE_WRF
487  call pmc_mpi_unpack_real(buffer, position, val%z_min)
488  call pmc_mpi_unpack_real(buffer, position, val%z_max)
489  call pmc_mpi_unpack_real(buffer, position, val%inverse_density)
490  call pmc_mpi_unpack_real(buffer, position, val%cell_volume)
491  call pmc_mpi_unpack_integer(buffer, position, val%cell_ix)
492  call pmc_mpi_unpack_integer(buffer, position, val%cell_iy)
493  call pmc_mpi_unpack_integer(buffer, position, val%cell_iz)
494  call pmc_mpi_unpack_real(buffer, position, val%diff_coef)
495  call pmc_mpi_unpack_real_array_4d(buffer, position, val%prob_advection)
496  call pmc_mpi_unpack_real_array_4d(buffer, position, val%prob_diffusion)
497  call pmc_mpi_unpack_real_array_2d(buffer, position, &
498  val%prob_vert_diffusion)
499 #endif
500  call pmc_mpi_unpack_real(buffer, position, val%start_time)
501  call pmc_mpi_unpack_integer(buffer, position, val%start_day)
502  call pmc_mpi_unpack_real(buffer, position, val%elapsed_time)
503  call pmc_mpi_unpack_real(buffer, position, val%solar_zenith_angle)
504  call pmc_mpi_unpack_real(buffer, position, val%height)
505  call pmc_mpi_unpack_real(buffer, position, val%additive_kernel_coefficient)
506  call assert(205696745, &
507  position - prev_position <= pmc_mpi_pack_size_env_state(val))
508 #endif
509 
510  end subroutine pmc_mpi_unpack_env_state
511 
512 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
513 
514  !> Computes the average of val across all processes, storing the
515  !> result in val_avg on the root process.
516  subroutine pmc_mpi_reduce_avg_env_state(val, val_avg)
517 
518  !> Value to average.
519  type(env_state_t), intent(in) :: val
520  !> Result.
521  type(env_state_t), intent(inout) :: val_avg
522 
523  val_avg = val
524  call pmc_mpi_reduce_avg_real(val%temp, val_avg%temp)
525  call pmc_mpi_reduce_avg_real(val%rel_humid, val_avg%rel_humid)
526  call pmc_mpi_reduce_avg_real(val%pressure, val_avg%pressure)
527 
528  end subroutine pmc_mpi_reduce_avg_env_state
529 
530 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
531 
532  !> Write full state.
533  subroutine env_state_output_netcdf(env_state, ncid)
534 
535  !> Environment state to write.
536  type(env_state_t), intent(in) :: env_state
537  !> NetCDF file ID, in data mode.
538  integer, intent(in) :: ncid
539 
540  !> \page output_format_env_state Output File Format: Environment State
541  !!
542  !! The environment state NetCDF variables are:
543  !! - \b temperature (unit K): current air temperature
544  !! - \b relative_humidity (dimensionless): current air
545  !! relative humidity (value of 1 means completely saturated)
546  !! - \b pressure (unit Pa): current air pressure
547  !! - \b longitude (unit degrees_east): longitude of simulation location
548  !! - \b latitude (unit degrees_north): latitude of simulation location
549  !! - \b altitude (unit m): altitude of simulation location
550  !! - \b start_time_of_day (unit s): time-of-day of the
551  !! simulation start measured in seconds after midnight UTC
552  !! - \b start_day_of_year: day-in-year number of the simulation start
553  !! (starting from 1 on the first day of the year)
554  !! - \b elapsed_time (unit s): elapsed time since the simulation start
555  !! - \b solar_zenith_angle (unit radians): current angle from
556  !! the zenith to the sun
557  !! - \b height (unit m): current boundary layer mixing height
558  !!
559  !! See also:
560  !! - \ref input_format_env_state and \ref input_format_scenario
561  !! --- the corresponding input formats
562 
563  call pmc_nc_write_real(ncid, env_state%temp, "temperature", unit="K", &
564  standard_name="air_temperature")
565  call pmc_nc_write_real(ncid, env_state%rel_humid, &
566  "relative_humidity", unit="1", standard_name="relative_humidity")
567  call pmc_nc_write_real(ncid, env_state%pressure, "pressure", unit="Pa", &
568  standard_name="air_pressure")
569  call pmc_nc_write_real(ncid, env_state%longitude, "longitude", &
570  unit="degree_east", standard_name="longitude")
571  call pmc_nc_write_real(ncid, env_state%latitude, "latitude", &
572  unit="degree_north", standard_name="latitude")
573  call pmc_nc_write_real(ncid, env_state%altitude, "altitude", unit="m", &
574  standard_name="altitude")
575 #ifdef PMC_USE_WRF
576  call pmc_nc_write_real(ncid, env_state%z_min, "bottom_boundary_altitude", &
577  unit="m", standard_name="bottom_altitude")
578  call pmc_nc_write_real(ncid, env_state%z_max, "top_boundary_altitude", &
579  unit="m", standard_name="top_altitude")
580  call pmc_nc_write_real(ncid, env_state%inverse_density, &
581  "inverse_density", unit="m3kg-1", standard_name="inverse_density")
582  call pmc_nc_write_real(ncid, env_state%cell_volume, "cell_volume", &
583  unit="m3", standard_name="cell_volume")
584  call pmc_nc_write_integer(ncid,env_state%cell_ix,"x_index", &
585  description="east-west index of WRF domain")
586  call pmc_nc_write_integer(ncid,env_state%cell_iy,"y_index", &
587  description="north-south index of WRF domain")
588  call pmc_nc_write_integer(ncid,env_state%cell_iz,"z_index", &
589  description="top-bottom index of WRF domain")
590  call pmc_nc_write_real(ncid, env_state%diff_coef, "eddy_diff", &
591  unit="m2s-1", description="eddy diffusion coefficient")
592 #endif
593  call pmc_nc_write_real(ncid, env_state%start_time, &
594  "start_time_of_day", unit="s", description="time-of-day of " &
595  // "simulation start in seconds since midnight")
596  call pmc_nc_write_integer(ncid, env_state%start_day, &
597  "start_day_of_year", &
598  description="day-of-year number of simulation start")
599  call pmc_nc_write_real(ncid, env_state%elapsed_time, "elapsed_time", &
600  unit="s", description="elapsed time since simulation start")
601  call pmc_nc_write_real(ncid, env_state%solar_zenith_angle, &
602  "solar_zenith_angle", unit="radian", &
603  description="current angle from the zenith to the sun")
604  call pmc_nc_write_real(ncid, env_state%height, "height", unit="m", &
605  long_name="boundary layer mixing height")
606 
607  end subroutine env_state_output_netcdf
608 
609 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
610 
611  !> Read full state.
612  subroutine env_state_input_netcdf(env_state, ncid)
613 
614  !> Environment state to read.
615  type(env_state_t), intent(inout) :: env_state
616  !> NetCDF file ID, in data mode.
617  integer, intent(in) :: ncid
618 
619  call pmc_nc_read_real(ncid, env_state%temp, "temperature")
620  call pmc_nc_read_real(ncid, env_state%rel_humid, "relative_humidity")
621  call pmc_nc_read_real(ncid, env_state%pressure, "pressure")
622  call pmc_nc_read_real(ncid, env_state%longitude, "longitude")
623  call pmc_nc_read_real(ncid, env_state%latitude, "latitude")
624  call pmc_nc_read_real(ncid, env_state%altitude, "altitude")
625 #ifdef PMC_USE_WRF
626  call pmc_nc_read_real(ncid, env_state%z_min, "bottom_boundary_altitude")
627  call pmc_nc_read_real(ncid, env_state%z_max, "top_boundary_altitude")
628  call pmc_nc_read_real(ncid, env_state%inverse_density, "inverse_density")
629  call pmc_nc_read_real(ncid, env_state%cell_volume, "cell_volume")
630  call pmc_nc_read_integer(ncid,env_state%cell_ix,"x_index")
631  call pmc_nc_read_integer(ncid,env_state%cell_iy,"y_index")
632  call pmc_nc_read_integer(ncid,env_state%cell_iz,"z_index")
633  call pmc_nc_read_real(ncid, env_state%diff_coef, "eddy_diff")
634 #endif
635  call pmc_nc_read_real(ncid, env_state%start_time, &
636  "start_time_of_day")
637  call pmc_nc_read_integer(ncid, env_state%start_day, &
638  "start_day_of_year")
639  call pmc_nc_read_real(ncid, env_state%elapsed_time, "elapsed_time")
640  call pmc_nc_read_real(ncid, env_state%solar_zenith_angle, &
641  "solar_zenith_angle")
642  call pmc_nc_read_real(ncid, env_state%height, "height")
643 
644  end subroutine env_state_input_netcdf
645 
646 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
647 
648 end module pmc_env_state
pmc_netcdf::pmc_nc_write_integer
subroutine pmc_nc_write_integer(ncid, var, name, unit, long_name, standard_name, description)
Write a single integer to a NetCDF file.
Definition: netcdf.F90:736
pmc_mpi
Wrapper functions for MPI.
Definition: mpi.F90:13
pmc_spec_file::spec_file_read_integer
subroutine spec_file_read_integer(file, name, var)
Read an integer from a spec file that must have the given name.
Definition: spec_file.F90:541
pmc_mpi::pmc_mpi_unpack_real_array_4d
subroutine pmc_mpi_unpack_real_array_4d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1487
pmc_mpi::pmc_mpi_pack_size_real
integer function pmc_mpi_pack_size_real(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:385
pmc_env_state::env_state_input_netcdf
subroutine env_state_input_netcdf(env_state, ncid)
Read full state.
Definition: env_state.F90:613
pmc_env_state::pmc_mpi_unpack_env_state
subroutine pmc_mpi_unpack_env_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: env_state.F90:468
pmc_mpi::pmc_mpi_reduce_avg_real
subroutine pmc_mpi_reduce_avg_real(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on the root process.
Definition: mpi.F90:1559
pmc_env_state::env_state_a
real(kind=dp) function env_state_a(env_state)
Condensation parameter.
Definition: env_state.F90:228
pmc_mpi::pmc_mpi_rank
integer function pmc_mpi_rank()
Returns the rank of the current process.
Definition: mpi.F90:117
pmc_netcdf
Wrapper functions for NetCDF. These all take a NetCDF ncid in data mode and return with it again in d...
Definition: netcdf.F90:11
pmc_env_state::env_state_mix
subroutine env_state_mix(val)
Average val over all processes.
Definition: env_state.F90:339
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_spec_file
Reading formatted text input.
Definition: spec_file.F90:43
pmc_env_state::env_state_t
Current environment state.
Definition: env_state.F90:29
pmc_mpi::pmc_mpi_pack_real
subroutine pmc_mpi_pack_real(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:761
pmc_util::assert
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition: util.F90:104
pmc_env_state::env_state_conc_to_ppb
real(kind=dp) function env_state_conc_to_ppb(env_state, conc)
Convert (molecules m^{-3}) to (ppb).
Definition: env_state.F90:256
pmc_netcdf::pmc_nc_read_integer
subroutine pmc_nc_read_integer(ncid, var, name, must_be_present)
Read a single integer from a NetCDF file.
Definition: netcdf.F90:185
pmc_spec_file::spec_file_t
An input file with extra data for printing messages.
Definition: spec_file.F90:59
pmc_env_state::env_state_add
subroutine env_state_add(env_state, env_state_delta)
env_state += env_state_delta
Definition: env_state.F90:86
pmc_env_state::env_state_reduce_avg
subroutine env_state_reduce_avg(val)
Average val over all processes, with the result only on the root process.
Definition: env_state.F90:361
pmc_mpi::pmc_mpi_pack_size_real_array_2d
integer function pmc_mpi_pack_size_real_array_2d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:581
pmc_env_state::pmc_mpi_pack_env_state
subroutine pmc_mpi_pack_env_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: env_state.F90:421
pmc_util::warn_msg
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
Definition: util.F90:38
pmc_env_state::env_state_rel_humid_to_mix_rat
real(kind=dp) function env_state_rel_humid_to_mix_rat(env_state)
Converts relative humidity (1) to water vapor mixing ratio (ppb).
Definition: env_state.F90:209
pmc_spec_file::spec_file_read_real
subroutine spec_file_read_real(file, name, var)
Read a real number from a spec file that must have the given name.
Definition: spec_file.F90:563
pmc_env_state::env_state_air_molar_den
real(kind=dp) function env_state_air_molar_den(env_state)
Air molar density (mol m^{-3}).
Definition: env_state.F90:193
pmc_mpi::pmc_mpi_pack_size_real_array_4d
integer function pmc_mpi_pack_size_real_array_4d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:644
pmc_netcdf::pmc_nc_write_real
subroutine pmc_nc_write_real(ncid, var, name, unit, long_name, standard_name, description)
Write a single real to a NetCDF file.
Definition: netcdf.F90:703
pmc_constants::const
type(const_t), save const
Fixed variable for accessing the constant's values.
Definition: constants.F90:75
pmc_env_state::env_state_change_water_volume
subroutine env_state_change_water_volume(env_state, dv)
Adds the given water volume to the water vapor and updates all environment quantities.
Definition: env_state.F90:137
pmc_mpi::pmc_mpi_pack_real_array_2d
subroutine pmc_mpi_pack_real_array_2d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:991
pmc_env_state::env_state_sat_vapor_pressure
real(kind=dp) function env_state_sat_vapor_pressure(env_state)
Computes the current saturation vapor pressure (Pa).
Definition: env_state.F90:166
pmc_env_state
The env_state_t structure and associated subroutines.
Definition: env_state.F90:9
pmc_env_state::env_state_scale
subroutine env_state_scale(env_state, alpha)
env_state *= alpha
Definition: env_state.F90:112
pmc_mpi::pmc_mpi_unpack_integer
subroutine pmc_mpi_unpack_integer(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1139
pmc_constants
Physical constants.
Definition: constants.F90:9
pmc_mpi::pmc_mpi_pack_real_array_4d
subroutine pmc_mpi_pack_real_array_4d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:1061
pmc_env_state::env_state_air_den
real(kind=dp) function env_state_air_den(env_state)
Air density (kg m^{-3}).
Definition: env_state.F90:180
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_mpi::pmc_mpi_unpack_real_array_2d
subroutine pmc_mpi_unpack_real_array_2d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1420
pmc_env_state::pmc_mpi_reduce_avg_env_state
subroutine pmc_mpi_reduce_avg_env_state(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on the root process.
Definition: env_state.F90:517
pmc_mpi::pmc_mpi_pack_size_integer
integer function pmc_mpi_pack_size_integer(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:345
pmc_mpi::pmc_mpi_pack_integer
subroutine pmc_mpi_pack_integer(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:711
pmc_netcdf::pmc_nc_read_real
subroutine pmc_nc_read_real(ncid, var, name, must_be_present)
Read a single real from a NetCDF file.
Definition: netcdf.F90:150
pmc_mpi::pmc_mpi_allreduce_average_real
subroutine pmc_mpi_allreduce_average_real(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on all processes.
Definition: mpi.F90:1764
pmc_env_state::pmc_mpi_pack_size_env_state
integer function pmc_mpi_pack_size_env_state(val)
Determines the number of bytes required to pack the given value.
Definition: env_state.F90:384
pmc_mpi::pmc_mpi_unpack_real
subroutine pmc_mpi_unpack_real(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1189
pmc_env_state::env_state_ppb_to_conc
real(kind=dp) function env_state_ppb_to_conc(env_state, ppb)
Convert (ppb) to (molecules m^{-3}).
Definition: env_state.F90:241