PartMC  2.8.0
ice_nucleation.F90
Go to the documentation of this file.
1 ! Copyright (C) 2024 University of Illinois at Urbana-Champaign
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_ice_nucleation module.
7 
10  use pmc_env_state
11  use pmc_aero_data
12  use pmc_util
14  use pmc_constants
15  use pmc_rand
16 
17  implicit none
18 
19  !> Type code for an undefined or invalid immersion freezing scheme.
20  integer, parameter :: immersion_freezing_scheme_invalid = 0
21  !> Type code for constant ice nucleation rate (J_het) immersion freezing
22  !> scheme.
23  integer, parameter :: immersion_freezing_scheme_const = 1
24  !> Type code for the singular (INAS) immersion freezing scheme.
25  integer, parameter :: immersion_freezing_scheme_singular = 2
26  !> Type code for the ABIFM immersion freezing scheme.
27  integer, parameter :: immersion_freezing_scheme_abifm = 3
28 
29 contains
30 
31 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
32 
33  !> Main subroutine for immersion freezing simulation.
34  subroutine ice_nucleation_immersion_freezing(aero_state, aero_data, &
35  env_state, del_t, immersion_freezing_scheme_type, &
36  freezing_rate, do_freezing_naive, INAS_a, INAS_b)
37 
38  !> Aerosol state.
39  type(aero_state_t), intent(inout) :: aero_state
40  !> Aerosol data.
41  type(aero_data_t), intent(in) :: aero_data
42  !> Environment state.
43  type(env_state_t), intent(inout) :: env_state
44  !> Total time to integrate.
45  real(kind=dp), intent(in) :: del_t
46  !> Immersion freezing scheme type.
47  integer, intent(in) :: immersion_freezing_scheme_type
48  !> Freezing rate (only used for the constant rate scheme).
49  real(kind=dp), intent(in) :: freezing_rate
50  !> Whether to use the naive algorithm for time-dependent scheme.
51  !> (If false, use the binned tau-leaping algorithm.)
52  logical, intent(in) :: do_freezing_naive
53  !> Slope parameter for the INAS parameterization (singular scheme only).
54  real(kind=dp), intent(in) :: inas_a
55  !> Intercept parameter for the INAS parameterization (singular scheme only).
56  real(kind=dp), intent(in) :: inas_b
57 
58  ! Call the immersion freezing subroutine according to the immersion
59  ! freezing scheme.
60  if (env_state%temp <= const%water_freeze_temp) then
61  if ((immersion_freezing_scheme_type == immersion_freezing_scheme_abifm) &
62  .OR. (immersion_freezing_scheme_type == &
64  if (do_freezing_naive) then
66  aero_state, aero_data, env_state, del_t, &
67  immersion_freezing_scheme_type, freezing_rate)
68  else
70  aero_state, aero_data, env_state, del_t, &
71  immersion_freezing_scheme_type, freezing_rate)
72  end if
73  else if (immersion_freezing_scheme_type == &
75  call ice_nucleation_singular_initialize(aero_state, aero_data, &
76  inas_a, inas_b)
78  aero_data, env_state)
79  else
80  call assert_msg(121370299, .false., &
81  'Invalid immersion freezing scheme type')
82  end if
83  end if
84 
86 
87 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
88 
89  !> Initialization for the singular scheme, sampling the freezing
90  !> temperature for each particle.
91  subroutine ice_nucleation_singular_initialize(aero_state, aero_data, &
92  INAS_a, INAS_b)
93 
94  !> Aerosol state.
95  type(aero_state_t), intent(inout) :: aero_state
96  !> Aerosol data.
97  type(aero_data_t), intent(in) :: aero_data
98  !> Slope parameter for the INAS parameterization.
99  real(kind=dp), intent(in) :: inas_a
100  !> Intercept parameter for the INAS parameterization.
101  real(kind=dp), intent(in) :: inas_b
102 
103  integer :: i_part
104  real(kind=dp) :: p, s, t0, temp
105  real(kind=dp) :: aerosol_diameter
106 
107  t0 = const%water_freeze_temp
108  do i_part = 1,aero_state_n_part(aero_state)
109  if (aero_state%apa%particle(i_part)%imf_temperature == 0d0) then
110  aerosol_diameter = aero_particle_dry_diameter( &
111  aero_state%apa%particle(i_part), aero_data)
112  s = const%pi * aerosol_diameter**2
113  p = pmc_random()
114  temp = (log(1d0 - p) + exp(-s * exp(-inas_a * t0 + inas_b))) / (-s)
115  aero_state%apa%particle(i_part)%imf_temperature = t0 + (log(temp) &
116  - inas_b) / inas_a
117  end if
118  end do
119 
121 
122 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
123 
124  !> Simulation for singular scheme, deciding whether to freeze for each
125  !> particle. Run in each time step.
127  aero_data, env_state)
128 
129  !> Aerosol state.
130  type(aero_state_t), intent(inout) :: aero_state
131  !> Aerosol data.
132  type(aero_data_t), intent(in) :: aero_data
133  !> Environment state.
134  type(env_state_t), intent(inout) :: env_state
135 
136  real(kind=dp), allocatable :: h2o_masses(:), total_masses(:), &
137  h2o_frac(:)
138  integer :: i_part
139 
140  ! Workaround: explicit allocate required before assignment to suppress
141  ! false-positive -Wuninitialized warnings from GCC
142  allocate(total_masses(aero_state_n_part(aero_state)))
143  allocate(h2o_masses(aero_state_n_part(aero_state)))
144  allocate(h2o_frac(aero_state_n_part(aero_state)))
145 
146  total_masses = aero_state_masses(aero_state, aero_data)
147  h2o_masses = aero_state_masses(aero_state, aero_data, include=["H2O"])
148  h2o_frac = h2o_masses / total_masses
149  do i_part = 1,aero_state_n_part(aero_state)
150  if (aero_state%apa%particle(i_part)%frozen) then
151  cycle
152  end if
153  if (h2o_frac(i_part) < const%imf_water_threshold) then
154  cycle
155  end if
156  if (env_state%temp <= &
157  aero_state%apa%particle(i_part)%imf_temperature) then
158  aero_state%apa%particle(i_part)%frozen = .true.
159  aero_state%apa%particle(i_part)%den_ice = &
160  const%reference_ice_density
161  aero_state%apa%particle(i_part)%ice_shape_phi = 1d0
162  end if
163  end do
164 
166 
167 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
168 
169  !> Simulation for time-dependent scheme (e.g., ABIFM, constant rate),
170  !> deciding whether to freeze for each particle. Run in each time step.
171  !> This subroutine applies the binned-tau leaping algorithm for speeding up.
173  aero_data, env_state, del_t, immersion_freezing_scheme_type, &
174  freezing_rate)
175 
176  !> Aerosol state.
177  type(aero_state_t), intent(inout) :: aero_state
178  !> Aerosol data.
179  type(aero_data_t), intent(in) :: aero_data
180  !> Environment state.
181  type(env_state_t), intent(inout) :: env_state
182  !> Total time to integrate.
183  real(kind=dp), intent(in) :: del_t
184  !> Freezing rate (only used for the constant rate scheme).
185  real(kind=dp), intent(in) :: freezing_rate
186  !> Immersion freezing scheme type.
187  integer, intent(in) :: immersion_freezing_scheme_type
188 
189  integer :: i_part, i_bin, i_class, n_bins, n_class
190  real(kind=dp) :: a_w_ice, pis, pvs
191  real(kind=dp) :: p_freeze
192 
193  real(kind=dp) :: p_freeze_max, radius_max, diameter_max
194 
195  integer :: k_th, n_parts_in_bin
196  real(kind=dp) :: rand
197  real(kind=dp), allocatable :: h2o_masses(:), total_masses(:), &
198  h2o_frac(:)
199  integer :: i_spec_max
200  real(kind=dp) :: j_het_max
201  integer :: rand_geo
202 
203  ! Workaround: explicit allocate required before assignment to suppress
204  ! false-positive -Wuninitialized warnings from GCC
205  allocate(total_masses(aero_state_n_part(aero_state)))
206  allocate(h2o_masses(aero_state_n_part(aero_state)))
207  allocate(h2o_frac(aero_state_n_part(aero_state)))
208 
209  call aero_state_sort(aero_state, aero_data)
210 
211  total_masses = aero_state_masses(aero_state, aero_data)
212  h2o_masses = aero_state_masses(aero_state, aero_data, include=["H2O"])
213  h2o_frac = h2o_masses / total_masses
215  pis = env_state_saturated_vapor_pressure_wrt_ice(env_state%temp)
216  a_w_ice = pis / pvs
217  if (immersion_freezing_scheme_type == immersion_freezing_scheme_abifm) then
218  call abifm_max_spec(aero_data, a_w_ice, i_spec_max, j_het_max)
219  end if
220 
221  n_bins = aero_sorted_n_bin(aero_state%aero_sorted)
222  n_class = aero_sorted_n_class(aero_state%aero_sorted)
223 
224  if (immersion_freezing_scheme_type == immersion_freezing_scheme_const) then
225  p_freeze_max = 1d0 - exp(-freezing_rate * del_t)
226  else
227  p_freeze_max = const%nan
228  end if
229 
230  loop_bins: do i_bin = 1,n_bins
231  loop_classes: do i_class = 1,n_class
232  n_parts_in_bin = integer_varray_n_entry(&
233  aero_state%aero_sorted%size_class%inverse(i_bin, i_class))
234  radius_max = aero_state%aero_sorted%bin_grid%edges(i_bin + 1)
235  diameter_max = radius_max * 2
236  if (immersion_freezing_scheme_type == &
238  p_freeze_max = abifm_pfrz_max(diameter_max, aero_data, &
239  j_het_max, del_t)
240  end if
241 
242  k_th = n_parts_in_bin + 1
243  loop_chosen_particles: do while(.true.)
244  rand_geo = rand_geometric(p_freeze_max)
245  k_th = k_th - rand_geo
246  if (k_th <= 0) then
247  EXIT loop_chosen_particles
248  end if
249  i_part = aero_state%aero_sorted%size_class &
250  %inverse(i_bin, i_class)%entry(k_th)
251  if (aero_state%apa%particle(i_part)%frozen) then
252  cycle
253  end if
254  if (h2o_frac(i_part) < const%imf_water_threshold) then
255  cycle
256  end if
257  if (immersion_freezing_scheme_type == &
259  p_freeze = abifm_pfrz_particle( &
260  aero_state%apa%particle(i_part), aero_data, a_w_ice, del_t)
261  call warn_assert_msg(301184565, p_freeze <= p_freeze_max,&
262  "p_freeze > p_freeze_max.")
263  rand = pmc_random()
264  if (rand < p_freeze / p_freeze_max) then
265  aero_state%apa%particle(i_part)%frozen = .true.
266  aero_state%apa%particle(i_part)%den_ice = &
267  const%reference_ice_density
268  aero_state%apa%particle(i_part)%ice_shape_phi = 1d0
269 
270  end if
271  else
272  aero_state%apa%particle(i_part)%frozen = .true.
273  aero_state%apa%particle(i_part)%den_ice = &
274  const%reference_ice_density
275  aero_state%apa%particle(i_part)%ice_shape_phi = 1d0
276  end if
277 
278  end do loop_chosen_particles
279  end do loop_classes
280  end do loop_bins
281 
283 
284 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285 
286  !> Simulation for time-dependent scheme (e.g., ABIFM, constant rate),
287  !> deciding whether to freeze for each particle. Run in each time step.
288  !> This subroutine applies the naive algorithm that checks each particle.
290  aero_state, aero_data, env_state, del_t, &
291  immersion_freezing_scheme_type, freezing_rate)
292 
293  !> Aerosol state.
294  type(aero_state_t), intent(inout) :: aero_state
295  !> Aerosol data.
296  type(aero_data_t), intent(in) :: aero_data
297  !> Environment state.
298  type(env_state_t), intent(inout) :: env_state
299  !> Total time to integrate.
300  real(kind=dp), intent(in) :: del_t
301  !> Type of the immersion freezing scheme
302  integer, intent(in) :: immersion_freezing_scheme_type
303  !> Freezing rate (only used for the constant rate scheme).
304  real(kind=dp), intent(in) :: freezing_rate
305 
306  integer :: i_part
307  real(kind=dp) :: a_w_ice, pis, pvs
308  real(kind=dp) :: p_freeze
309  real(kind=dp), allocatable :: h2o_masses(:), total_masses(:), &
310  h2o_frac(:)
311  real(kind=dp) :: rand
312 
313  ! Workaround: explicit allocate required before assignment to suppress
314  ! false-positive -Wuninitialized warnings from GCC
315  allocate(total_masses(aero_state_n_part(aero_state)))
316  allocate(h2o_masses(aero_state_n_part(aero_state)))
317  allocate(h2o_frac(aero_state_n_part(aero_state)))
318 
319  total_masses = aero_state_masses(aero_state, aero_data)
320  h2o_masses = aero_state_masses(aero_state, aero_data, include=["H2O"])
321  h2o_frac = h2o_masses / total_masses
322 
324  pis = env_state_saturated_vapor_pressure_wrt_ice(env_state%temp)
325  a_w_ice = pis / pvs
326 
327  if (immersion_freezing_scheme_type == immersion_freezing_scheme_const) then
328  p_freeze = 1d0 - exp(-freezing_rate * del_t)
329  else
330  p_freeze = const%nan
331  end if
332 
333  do i_part = 1,aero_state_n_part(aero_state)
334  if (aero_state%apa%particle(i_part)%frozen) cycle
335  if (h2o_frac(i_part) < const%imf_water_threshold) cycle
336  rand = pmc_random()
337 
338  if (immersion_freezing_scheme_type == &
340  p_freeze = abifm_pfrz_particle(aero_state%apa%particle(i_part), &
341  aero_data, a_w_ice, del_t)
342  end if
343 
344  if (rand < p_freeze) then
345  aero_state%apa%particle(i_part)%frozen = .true.
346  aero_state%apa%particle(i_part)%den_ice = &
347  const%reference_ice_density
348  aero_state%apa%particle(i_part)%ice_shape_phi = 1d0
349  end if
350  end do
351 
353 
354 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
355 
356  !> Simulates melting: if the environmental temperature is above the freezing
357  !> temperature of water, all particles are set to be unfrozen.
358  subroutine ice_nucleation_melting(aero_state, aero_data, env_state)
359 
360  !> Aerosol state.
361  type(aero_state_t), intent(inout) :: aero_state
362  !> Aerosol data.
363  type(aero_data_t), intent(in) :: aero_data
364  !> Environment state.
365  type(env_state_t), intent(inout) :: env_state
366 
367  integer :: i_part
368 
369  if (env_state%temp > const%water_freeze_temp) then
370  do i_part = 1,aero_state_n_part(aero_state)
371  aero_state%apa%particle(i_part)%frozen = .false.
372  aero_state%apa%particle(i_part)%den_ice = const%nan
373  aero_state%apa%particle(i_part)%ice_shape_phi = const%nan
374  end do
375  end if
376 
377  end subroutine ice_nucleation_melting
378 
379 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
380 
381  !> Calculating the freezing probability for the particle (i_part) using ABIFM
382  !> method (Knopf et al.,2013)
383  real(kind=dp) function abifm_pfrz_particle(aero_particle, aero_data, &
384  a_w_ice, del_t)
385 
386  !> Aerosol particle.
387  type(aero_particle_t), intent(in) :: aero_particle
388  !> Aerosol data.
389  type(aero_data_t), intent(in) :: aero_data
390  !> The water activity w.r.t. ice.
391  real(kind=dp), intent(in) :: a_w_ice
392  !> Time interval.
393  real(kind=dp), intent(in) :: del_t
394 
395  real(kind=dp) :: aerosol_diameter
396  real(kind=dp) :: immersed_surface_area
397  real(kind=dp) :: total_vol
398  real(kind=dp) :: surface_ratio
399  real(kind=dp) :: abifm_m, abifm_c
400  real(kind=dp) :: j_het, j_het_x_area
401  integer :: i_spec
402 
403  aerosol_diameter = aero_particle_dry_diameter(aero_particle, aero_data)
404  immersed_surface_area = const%pi * aerosol_diameter**2
405 
406  total_vol = aero_particle_dry_volume(aero_particle, aero_data)
407 
408  j_het_x_area = 0d0
409  do i_spec = 1,aero_data_n_spec(aero_data)
410  if (i_spec == aero_data%i_water) cycle
411  abifm_m = aero_data%abifm_m(i_spec)
412  abifm_c = aero_data%abifm_c(i_spec)
413  j_het = 10d0**(abifm_m * (1d0 - a_w_ice) + abifm_c) * 10000d0
414  surface_ratio = aero_particle%vol(i_spec) / total_vol
415  j_het_x_area = j_het_x_area + j_het * immersed_surface_area * &
416  surface_ratio
417  end do
418 
419  abifm_pfrz_particle = 1d0 - exp(-j_het_x_area * del_t)
420 
421  end function abifm_pfrz_particle
422 
423 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
424 
425  !> Finding the maximum heterogeneous ice nucleation rate coefficient.
426  subroutine abifm_max_spec(aero_data, a_w_ice, i_spec_max, j_het_max)
427 
428  !> Aerosol data.
429  type(aero_data_t), intent(in) :: aero_data
430  !> The water activity w.r.t. ice.
431  real(kind=dp), intent(in) :: a_w_ice
432  !> The index of the maximum J_het species.
433  integer, intent(out) :: i_spec_max
434  !> The maximum value of J_het among all species.
435  real(kind=dp), intent(out) :: j_het_max
436 
437  real(kind=dp) :: abifm_m, abifm_c
438  real(kind=dp) :: j_het
439  integer :: i_spec
440 
441  j_het_max = const%nan
442  do i_spec = 1,aero_data_n_spec(aero_data)
443  if (i_spec == aero_data%i_water) cycle
444  abifm_m = aero_data%abifm_m(i_spec)
445  abifm_c = aero_data%abifm_c(i_spec)
446  j_het = 10d0**(abifm_m * (1d0 - a_w_ice) + abifm_c) * 10000d0
447  if (j_het > j_het_max) then
448  j_het_max = j_het
449  i_spec_max = i_spec
450  end if
451  end do
452 
453  end subroutine abifm_max_spec
454 
455 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
456 
457  !> Calculating the maximum freezing probability for particles in
458  !> one bin using ABIFM method (Knopf et al.,2013). Only used by
459  !> the binned-tau leaping algorithm.
460  real(kind=dp) function abifm_pfrz_max(diameter_max, aero_data, j_het_max, &
461  del_t)
462 
463  !> Aerosol data.
464  type(aero_data_t), intent(in) :: aero_data
465  !> Maximum diameter.
466  real(kind=dp), intent(in) :: diameter_max
467  !> Time interval.
468  real(kind=dp), intent(in) :: del_t
469  !> Maximum J_het among all species.
470  real(kind=dp), intent(in) :: j_het_max
471 
472  real(kind=dp) :: immersed_surface_area
473 
474  immersed_surface_area = const%pi * diameter_max**2
475  abifm_pfrz_max = 1d0 - exp(-j_het_max * immersed_surface_area * del_t)
476 
477  end function abifm_pfrz_max
478 
479 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
480 
481  !> Read the specification for immersion freezing scheme.
482  subroutine spec_file_read_immersion_freezing_scheme_type(file, &
483  immersion_freezing_scheme_type)
484 
485  !> Spec file.
486  type(spec_file_t), intent(inout) :: file
487  !> Immersion freezing scheme type.
488  integer, intent(out) :: immersion_freezing_scheme_type
489 
490  character(len=SPEC_LINE_MAX_VAR_LEN) :: imf_scheme
491 
492  !> \page input_format_imf_scheme Input File Format: Immersion Freezing Scheme
493  !!
494  !! The immersion freezing scheme is specified by the parameter:
495  !! - \b immersion_freezing_scheme (string): the type of
496  !! immersion freezing scheme must be one of:
497  !! \c const for freezing with a constant freezing rate;
498  !! \c singular for the INAS scheme based on singular perspective;
499  !! \c ABIFM for the ABIFM scheme based on CNT perspective.
500  !!
501  !! If \c immersion_freezing_scheme is \c singular, the parameters INAS_a
502  !! and INAS_b need to be provided.
503  !! If \c immersion_freezing_scheme is \c const, the parameter freezing_rate
504  !! needs to be provided.
505  !! If \c immersion_freezing_scheme is \c ABIFM or \c const, a logical
506  !! variable \c do_freezing_naive needs to be provided.
507  !!
508  !! See also:
509  !! - \ref spec_file_format --- the input file text format
510 
511  call spec_file_read_string(file, 'immersion_freezing_scheme', imf_scheme)
512  if (trim(imf_scheme) == 'const') then
513  immersion_freezing_scheme_type = immersion_freezing_scheme_const
514  elseif (trim(imf_scheme) == 'singular') then
515  immersion_freezing_scheme_type = immersion_freezing_scheme_singular
516  elseif (trim(imf_scheme) == 'ABIFM') then
517  immersion_freezing_scheme_type = immersion_freezing_scheme_abifm
518  else
519  call spec_file_die_msg(920761229, file, &
520  "Unknown immersion freezing scheme: " // trim(imf_scheme))
521  end if
522 
523  end subroutine spec_file_read_immersion_freezing_scheme_type
524 
525 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
526 
527 end module pmc_ice_nucleation
pmc_aero_particle::aero_particle_t
Single aerosol particle data structure.
Definition: aero_particle.F90:30
pmc_rand::rand_geometric
integer function rand_geometric(p)
Generate a Geometric-distributed random number with the given probability.
Definition: rand.F90:708
pmc_ice_nucleation::immersion_freezing_scheme_abifm
integer, parameter immersion_freezing_scheme_abifm
Type code for the ABIFM immersion freezing scheme.
Definition: ice_nucleation.F90:27
pmc_ice_nucleation::immersion_freezing_scheme_invalid
integer, parameter immersion_freezing_scheme_invalid
Type code for an undefined or invalid immersion freezing scheme.
Definition: ice_nucleation.F90:20
pmc_aero_data::aero_data_n_spec
elemental integer function aero_data_n_spec(aero_data)
Return the number of aerosol species, or -1 if uninitialized.
Definition: aero_data.F90:250
pmc_aero_state::aero_state_n_part
elemental integer function aero_state_n_part(aero_state)
Return the current number of particles.
Definition: aero_state.F90:94
pmc_env_state::env_state_saturated_vapor_pressure_wrt_water
real(kind=dp) function env_state_saturated_vapor_pressure_wrt_water(T)
Computes saturated vapor pressure (Pa) with respect to water using Eq. (10) from Murphy & Koop,...
Definition: env_state.F90:652
pmc_aero_particle
The aero_particle_t structure and associated subroutines.
Definition: aero_particle.F90:9
pmc_ice_nucleation::immersion_freezing_scheme_singular
integer, parameter immersion_freezing_scheme_singular
Type code for the singular (INAS) immersion freezing scheme.
Definition: ice_nucleation.F90:25
pmc_ice_nucleation::ice_nucleation_singular_initialize
subroutine ice_nucleation_singular_initialize(aero_state, aero_data, INAS_a, INAS_b)
Initialization for the singular scheme, sampling the freezing temperature for each particle.
Definition: ice_nucleation.F90:93
pmc_ice_nucleation::ice_nucleation_immersion_freezing
subroutine ice_nucleation_immersion_freezing(aero_state, aero_data, env_state, del_t, immersion_freezing_scheme_type, freezing_rate, do_freezing_naive, INAS_a, INAS_b)
Main subroutine for immersion freezing simulation.
Definition: ice_nucleation.F90:37
pmc_util::warn_assert_msg
subroutine warn_assert_msg(code, condition_ok, warning_msg)
Prints a warning message if condition_ok is false.
Definition: util.F90:60
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_env_state::env_state_t
Current environment state.
Definition: env_state.F90:29
pmc_aero_state
The aero_state_t structure and assocated subroutines.
Definition: aero_state.F90:9
pmc_spec_file::spec_file_t
An input file with extra data for printing messages.
Definition: spec_file.F90:59
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:78
pmc_constants::const
type(const_t), save const
Fixed variable for accessing the constant's values.
Definition: constants.F90:81
pmc_env_state::env_state_saturated_vapor_pressure_wrt_ice
real(kind=dp) function env_state_saturated_vapor_pressure_wrt_ice(T)
Computes saturated vapor pressure (Pa) with respect to ice using Eq. (7) from Murphy & Koop,...
Definition: env_state.F90:678
pmc_ice_nucleation::immersion_freezing_scheme_const
integer, parameter immersion_freezing_scheme_const
Type code for constant ice nucleation rate (J_het) immersion freezing scheme.
Definition: ice_nucleation.F90:23
pmc_rand
Random number generators.
Definition: rand.F90:9
pmc_ice_nucleation::ice_nucleation_immersion_freezing_time_dependent_naive
subroutine ice_nucleation_immersion_freezing_time_dependent_naive(aero_state, aero_data, env_state, del_t, immersion_freezing_scheme_type, freezing_rate)
Simulation for time-dependent scheme (e.g., ABIFM, constant rate), deciding whether to freeze for eac...
Definition: ice_nucleation.F90:292
pmc_env_state
The env_state_t structure and associated subroutines.
Definition: env_state.F90:9
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:55
pmc_constants
Physical constants.
Definition: constants.F90:9
pmc_aero_particle::aero_particle_dry_diameter
elemental real(kind=dp) function aero_particle_dry_diameter(aero_particle, aero_data)
Total dry diameter of the particle (m).
Definition: aero_particle.F90:455
pmc_ice_nucleation::abifm_pfrz_particle
real(kind=dp) function abifm_pfrz_particle(aero_particle, aero_data, a_w_ice, del_t)
Calculating the freezing probability for the particle (i_part) using ABIFM method (Knopf et al....
Definition: ice_nucleation.F90:385
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_spec_file::spec_file_die_msg
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
Definition: spec_file.F90:74
pmc_aero_particle::aero_particle_dry_volume
elemental real(kind=dp) function aero_particle_dry_volume(aero_particle, aero_data)
Total dry volume of the particle (m^3).
Definition: aero_particle.F90:362
pmc_spec_file::spec_file_read_string
subroutine spec_file_read_string(file, name, var)
Read a string from a spec file that must have a given name.
Definition: spec_file.F90:605
pmc_aero_state::aero_state_masses
real(kind=dp) function, dimension(aero_state_n_part(aero_state)) aero_state_masses(aero_state, aero_data, include, exclude)
Returns the masses of all particles.
Definition: aero_state.F90:1187
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
pmc_ice_nucleation::abifm_pfrz_max
real(kind=dp) function abifm_pfrz_max(diameter_max, aero_data, j_het_max, del_t)
Calculating the maximum freezing probability for particles in one bin using ABIFM method (Knopf et al...
Definition: ice_nucleation.F90:462
pmc_ice_nucleation::ice_nucleation_melting
subroutine ice_nucleation_melting(aero_state, aero_data, env_state)
Simulates melting: if the environmental temperature is above the freezing temperature of water,...
Definition: ice_nucleation.F90:359
pmc_aero_state::aero_state_t
The current collection of aerosol particles.
Definition: aero_state.F90:69
pmc_aero_state::aero_state_sort
subroutine aero_state_sort(aero_state, aero_data, bin_grid, all_procs_same)
Sorts the particles if necessary.
Definition: aero_state.F90:3292
pmc_rand::pmc_random
real(kind=dp) function pmc_random()
Returns a random number between 0 and 1.
Definition: rand.F90:139
pmc_ice_nucleation::abifm_max_spec
subroutine abifm_max_spec(aero_data, a_w_ice, i_spec_max, j_het_max)
Finding the maximum heterogeneous ice nucleation rate coefficient.
Definition: ice_nucleation.F90:427
pmc_ice_nucleation::ice_nucleation_immersion_freezing_singular
subroutine ice_nucleation_immersion_freezing_singular(aero_state, aero_data, env_state)
Simulation for singular scheme, deciding whether to freeze for each particle. Run in each time step.
Definition: ice_nucleation.F90:128
pmc_ice_nucleation
Definition: ice_nucleation.F90:8
pmc_ice_nucleation::ice_nucleation_immersion_freezing_time_dependent
subroutine ice_nucleation_immersion_freezing_time_dependent(aero_state, aero_data, env_state, del_t, immersion_freezing_scheme_type, freezing_rate)
Simulation for time-dependent scheme (e.g., ABIFM, constant rate), deciding whether to freeze for eac...
Definition: ice_nucleation.F90:175