55 logical :: coag_kernel_bounds_valid
58 real(kind=dp),
allocatable,
dimension(:,:) :: coag_kernel_min
61 real(kind=dp),
allocatable,
dimension(:,:) :: coag_kernel_max
63 logical :: removal_rate_bounds_valid
65 real(kind=dp),
allocatable,
dimension(:) :: removal_rate_max
123 integer,
intent(in) :: n_group
125 integer,
intent(in) :: n_class
132 aero_sorted%coag_kernel_bounds_valid = .false.
133 if (
allocated(aero_sorted%coag_kernel_min))
then 134 deallocate(aero_sorted%coag_kernel_min)
136 allocate(aero_sorted%coag_kernel_min(n_bin, n_bin))
137 if (
allocated(aero_sorted%coag_kernel_max))
then 138 deallocate(aero_sorted%coag_kernel_max)
140 allocate(aero_sorted%coag_kernel_max(n_bin, n_bin))
141 aero_sorted%removal_rate_bounds_valid = .false.
142 if (
allocated(aero_sorted%removal_rate_max))
then 143 deallocate(aero_sorted%removal_rate_max)
145 allocate(aero_sorted%removal_rate_max(n_bin))
146 aero_sorted%bin_grid = bin_grid
154 aero_particle_array, aero_data)
163 integer :: i_part, i_bin
167 do i_part = aero_particle_array%n_part,1,-1
169 aero_particle_array%particle(i_part), aero_data)
170 if ((i_bin < 1) .or. (i_bin >
bin_grid_size(aero_sorted%bin_grid)))
then 171 call warn_msg(954800836,
"particle ID " &
173 aero_particle_array%particle(i_part)%id)) &
174 //
" outside of bin_grid, discarding")
195 integer :: i_part, i_bin, i_group, i_class
200 do i_part = 1,aero_particle_array%n_part
202 aero_particle_array%particle(i_part), aero_data)
203 i_group = aero_particle_array%particle(i_part)%weight_group
204 i_class = aero_particle_array%particle(i_part)%weight_class
215 aero_data, valid_sort, n_group, n_class, bin_grid, all_procs_same)
224 logical,
intent(in) :: valid_sort
226 integer,
optional,
intent(in) :: n_group
228 integer,
optional,
intent(in) :: n_class
230 type(
bin_grid_t),
optional,
intent(in) :: bin_grid
232 logical,
optional,
intent(in) :: all_procs_same
234 integer :: i_bin, i_bin_min, i_bin_max, i_part, n_bin, use_n_group
235 integer :: use_n_class
236 real(kind=dp) :: r, r_min, r_max, grid_r_min, grid_r_max
237 real(kind=dp) :: local_r_min, local_r_max
238 logical :: need_new_bin_grid
241 if (
present(n_group))
then 242 call assert(267881270,
present(n_class))
243 use_n_group = n_group
244 use_n_class = n_class
246 call assert(352582858, valid_sort)
251 if (
present(bin_grid))
then 255 aero_particle_array, aero_data)
261 need_new_bin_grid = .false.
272 aero_sorted%size_class%inverse(i_bin, :))) > 0)
then 273 if (i_bin_min == 0)
then 280 if (i_bin_min == 0)
then 282 call assert(333430891, i_bin_max == 0)
285 r_min = aero_sorted%bin_grid%edges( &
287 r_max = aero_sorted%bin_grid%edges(1)
290 r_min = aero_sorted%bin_grid%edges(i_bin_min)
291 r_max = aero_sorted%bin_grid%edges(i_bin_max + 1)
295 do i_part = 1,aero_particle_array%n_part
298 if (i_part == 1)
then 302 r_min = min(r_min, r)
303 r_max = max(r_max, r)
308 if (
present(all_procs_same))
then 309 if (all_procs_same)
then 314 if (r_min == 0d0)
then 323 need_new_bin_grid = .true.
329 if (r_max == 0d0)
then 330 if (valid_sort)
return 339 need_new_bin_grid = .true.
341 grid_r_min = aero_sorted%bin_grid%edges(1)
342 grid_r_max = aero_sorted%bin_grid%edges( &
350 need_new_bin_grid = .true.
354 if (need_new_bin_grid)
then 357 n_bin = ceiling((log10(grid_r_max) - log10(grid_r_min)) &
367 if (.not. valid_sort)
then 398 aero_particle, aero_data, allow_resort)
409 logical,
optional,
intent(in) :: allow_resort
411 integer :: i_bin, i_group, i_class, n_bin, n_group, n_class
415 i_group = aero_particle%weight_group
416 i_class = aero_particle%weight_class
421 call assert(417177855, (i_group >= 1) .and. (i_group <= n_group))
422 call assert(233133947, (i_class >= 1) .and. (i_class <= n_class))
427 if ((i_bin < 1) .or. (i_bin > n_bin))
then 432 if (
present(allow_resort))
then 433 if (.not. allow_resort)
then 437 call die_msg(134572570,
"particle outside of bin_grid: " &
438 //
"try reducing the timestep del_t")
442 aero_data, valid_sort=.false., n_group=n_group, n_class=n_class)
463 integer,
intent(in) :: i_part
476 new_group, new_class)
481 integer,
intent(in) :: i_part
483 integer,
intent(in) :: new_bin
485 integer,
intent(in) :: new_group
487 integer,
intent(in) :: new_class
500 aero_data, n_group, n_class, continue_on_error)
509 integer,
optional,
intent(in) :: n_group
511 integer,
optional,
intent(in) :: n_class
513 logical,
intent(in) :: continue_on_error
515 integer :: i_part, i_bin
518 n_domain=aero_particle_array%n_part, &
519 n_range_1=
bin_grid_size(aero_sorted%bin_grid), n_range_2=n_class, &
520 continue_on_error=continue_on_error)
521 do i_part = 1,aero_particle_array%n_part
523 aero_particle_array%particle(i_part), aero_data)
524 if ((i_bin /= aero_sorted%size_class%forward1%entry(i_part)) &
525 .or. (i_bin /= aero_sorted%size_class%forward1%entry(i_part)))
then 526 write(0,*)
'ERROR aero_sorted A: ',
"size_class" 527 write(0,*)
'i_part', i_part
528 write(0,*)
'i_bin', i_bin
529 write(0,*)
'aero_sorted%size_class%forward1%entry(i_part)', &
530 aero_sorted%size_class%forward1%entry(i_part)
531 write(0,*)
'aero_sorted%size_class%forward2%entry(i_part)', &
532 aero_sorted%size_class%forward2%entry(i_part)
533 call assert(565030916, continue_on_error)
538 n_domain=aero_particle_array%n_part, &
539 n_range_1=n_group, n_range_2=n_class, &
540 continue_on_error=continue_on_error)
541 do i_part = 1,aero_particle_array%n_part
542 if ((aero_particle_array%particle(i_part)%weight_group &
543 /= aero_sorted%group_class%forward1%entry(i_part)) &
544 .or. (aero_particle_array%particle(i_part)%weight_class &
545 /= aero_sorted%group_class%forward2%entry(i_part)))
then 546 write(0,*)
'ERROR aero_sorted B: ',
"group_class" 547 write(0,*)
'i_part', i_part
548 write(0,*)
'aero_particle_array%particle(i_part)%weight_group', &
549 aero_particle_array%particle(i_part)%weight_group
550 write(0,*)
'aero_particle_array%particle(i_part)%weight_class', &
551 aero_particle_array%particle(i_part)%weight_class
552 write(0,*)
'aero_sorted%group_class%forward1%entry(i_part)', &
553 aero_sorted%group_class%forward1%entry(i_part)
554 write(0,*)
'aero_sorted%group_class%forward2%entry(i_part)', &
555 aero_sorted%group_class%forward2%entry(i_part)
556 call assert(803595412, continue_on_error)
570 integer :: total_size
586 character,
intent(inout) :: buffer(:)
588 integer,
intent(inout) :: position
593 integer :: prev_position
595 prev_position = position
611 character,
intent(inout) :: buffer(:)
613 integer,
intent(inout) :: position
618 integer :: prev_position, n_bin, n_group, n_class
620 prev_position = position
elemental real(kind=dp) function aero_particle_radius(aero_particle, aero_data)
Total radius of the particle (m).
subroutine pmc_mpi_pack_bin_grid(buffer, position, val)
Packs the given value into the buffer, advancing position.
subroutine pmc_mpi_pack_integer_rmap2(buffer, position, val)
Packs the given value into the buffer, advancing position.
integer function pmc_mpi_pack_size_bin_grid(val)
Determines the number of bytes required to pack the given value.
1-D array of particles, used by aero_state to store the particles.
subroutine aero_sorted_discard_outside_grid(aero_sorted, aero_particle_array, aero_data)
Discard particles that don't fit the bin grid.
subroutine pmc_mpi_unpack_aero_sorted(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
subroutine aero_sorted_remake_if_needed(aero_sorted, aero_particle_array, aero_data, valid_sort, n_group, n_class, bin_grid, all_procs_same)
Remake a sorting if particles are getting too close to the edges.
The integer_rmap_t structure and assocated subroutines.
The bin_grid_t structure and associated subroutines.
The aero_particle_array_t structure and assoicated subroutines.
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
elemental integer function integer_varray_n_entry(integer_varray)
Return the current number of entries.
integer function aero_sorted_n_class(aero_sorted)
Returns the number of weight classes.
integer function aero_sorted_n_bin(aero_sorted)
Returns the number of size bins.
subroutine aero_particle_array_remove_particle(aero_particle_array, index)
Removes the particle at the given index.
The aero_particle_t structure and associated subroutines.
subroutine pmc_mpi_pack_aero_sorted(buffer, position, val)
Packs the given value into the buffer, advancing position.
The aero_sorted_t structure and assocated subroutines.
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
subroutine aero_sorted_sort_particles(aero_sorted, aero_particle_array, aero_data)
Sort the particles.
subroutine integer_rmap2_append(integer_rmap2, i_range_1, i_range_2)
Set the map value of the next free domain value to (i_range_1, i_range_2.
integer function aero_sorted_particle_in_bin(aero_sorted, aero_particle, aero_data)
Find the bin number that contains a given particle.
integer function aero_sorted_n_group(aero_sorted)
Returns the number of weight groups.
subroutine integer_rmap2_check(integer_rmap2, name, n_domain, n_range_1, n_range_2, continue_on_error)
Check that the data is consistent.
integer function pmc_mpi_pack_size_integer_rmap2(val)
Determines the number of bytes required to pack the given value.
A map , together with its multi-valued inverse.
subroutine integer_rmap2_change(integer_rmap2, i_domain, i_range_1, i_range_2)
Change the map value of i_domain to (i_range_1, i_range_2).
subroutine die_msg(code, error_msg)
Error immediately.
elemental integer function bin_grid_size(bin_grid)
Return the number of bins in the grid, or -1 if the bin grid is not allocated.
subroutine aero_sorted_check(aero_sorted, aero_particle_array, aero_data, n_group, n_class, continue_on_error)
Check sorting.
real(kind=dp), parameter aero_sorted_bin_over_factor
Factor to extend size grid beyond largest/smallest particles.
The integer_varray_t structure and assocated subroutines.
The aero_data_t structure and associated subroutines.
integer function pmc_mpi_pack_size_aero_sorted(val)
Determines the number of bytes required to pack the given value.
Single aerosol particle data structure.
1D grid, either logarithmic or linear.
subroutine bin_grid_make(bin_grid, type, n_bin, min, max)
Generates the bin grid given the range and number of bins.
subroutine pmc_mpi_allreduce_max_real(val, val_max)
Computes the maximum of val across all processes, storing the result in val_max on all processes...
logical function pmc_mpi_allequal_bin_grid(val)
Check whether all processors have the same value.
integer function bin_grid_find(bin_grid, val)
Find the bin number that contains a given value.
subroutine aero_sorted_remove_particle(aero_sorted, aero_particle_array, i_part)
Remove a particle from both an aero_sorted and the corresponding aero_particle_array.
real(kind=dp), parameter aero_sorted_bins_per_decade
How many size bins to use per decade of particle radius.
Sorting of particles into bins.
subroutine pmc_mpi_unpack_integer_rmap2(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
subroutine pmc_mpi_allreduce_min_real(val, val_min)
Computes the minimum of val across all processes, storing the result in val_min on all processes...
subroutine integer_rmap2_remove(integer_rmap2, i_domain)
Replace the map at the given i_domain with the map value of the last entry, and delete the last entry...
subroutine aero_sorted_set_bin_grid(aero_sorted, bin_grid, n_group, n_class)
Set the bin grid to be used for sorting.
The integer_rmap2_t structure and assocated subroutines.
elemental subroutine integer_rmap2_zero(integer_rmap2)
Resets an integer_rmap2 to have no mappings.
subroutine pmc_mpi_unpack_bin_grid(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
integer, parameter bin_grid_type_log
Logarithmically spaced bin grid.
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Aerosol material properties and associated data.
real(kind=dp), parameter aero_sorted_bin_safety_factor
Size grid extension factor when we should regenerate grid.
Wrapper functions for MPI.
elemental subroutine integer_rmap2_set_ranges(integer_rmap2, n_range_1, n_range_2)
Sets the maximum ranges of the forward map.
subroutine aero_sorted_move_particle(aero_sorted, i_part, new_bin, new_group, new_class)
Move a particle to a different bin and group.
subroutine aero_sorted_add_particle(aero_sorted, aero_particle_array, aero_particle, aero_data, allow_resort)
Add a new particle to both an aero_sorted and the corresponding aero_particle_array.
subroutine aero_particle_array_add_particle(aero_particle_array, aero_particle)
Adds the given particle to the end of the array.