51 type(aero_particle_t) :: local_aero_particle
54 integer :: remote_proc
73 request%active = .false.
85 request%active = .false.
105 aero_state, del_t, tot_n_samp, tot_n_coag)
108 integer,
intent(in) :: coag_kernel_type
116 real(kind=
dp),
intent(in) :: del_t
118 integer,
intent(out) :: tot_n_samp
120 integer,
intent(out) :: tot_n_coag
122 integer,
parameter :: s1 = 1
123 integer,
parameter :: s2 = 1
124 integer,
parameter :: sc = 1
127 logical :: samps_remaining, sent_dones
128 integer :: i_bin, j_bin, n_samp, i_samp, i_proc, n_proc
129 integer :: ierr, status(MPI_STATUS_SIZE), current_i, current_j, i_req
130 real(kind=
dp) :: n_samp_real, f_max
131 integer,
allocatable :: n_parts(:,:)
132 real(kind=
dp),
allocatable :: magnitudes(:,:)
134 integer,
allocatable :: n_samps(:,:)
135 real(kind=
dp),
allocatable :: accept_factors(:,:), k_max(:,:)
136 logical,
allocatable :: procs_done(:)
137 integer,
allocatable :: outgoing_buffer(:)
138 integer :: outgoing_buffer_size_check
142 aero_sorted_n_class(aero_state%aero_sorted) == 1, &
143 "FIXME: mc_coag_dist() can only handle one weight class")
152 if (.not. aero_state%aero_sorted%coag_kernel_bounds_valid)
then
153 call est_k_minmax_binned_unweighted(aero_state%aero_sorted%bin_grid, &
154 coag_kernel_type, aero_data, env_state, &
155 aero_state%aero_sorted%coag_kernel_min, &
156 aero_state%aero_sorted%coag_kernel_max)
157 aero_state%aero_sorted%coag_kernel_bounds_valid = .true.
160 allocate(n_samps(
bin_grid_size(aero_state%aero_sorted%bin_grid), &
162 allocate(accept_factors(
bin_grid_size(aero_state%aero_sorted%bin_grid), &
165 allocate(n_parts(
bin_grid_size(aero_state%aero_sorted%bin_grid), n_proc))
167 aero_state%aero_sorted%size_class%inverse(:, s1)), n_parts)
169 allocate(magnitudes(
size(aero_state%awa%weight), n_proc))
173 aero_weight_total = aero_state%awa
174 aero_weight_total%weight(:, s1)%magnitude = 1d0 / sum(1d0 / magnitudes, 2)
176 allocate(k_max(
bin_grid_size(aero_state%aero_sorted%bin_grid), &
180 call max_coag_num_conc_factor(aero_weight_total, &
181 aero_data, aero_state%aero_sorted%bin_grid, &
182 i_bin, j_bin, s1, s2, sc, f_max)
183 k_max(i_bin, j_bin) &
184 = aero_state%aero_sorted%coag_kernel_max(i_bin, j_bin) * f_max
189 aero_weight_total, k_max, n_samps, accept_factors)
190 tot_n_samp = sum(n_samps)
197 samps_remaining = .true.
200 allocate(procs_done(n_proc))
203 call mpi_buffer_attach(outgoing_buffer, &
206 do while (.not. all(procs_done))
209 current_i, current_j, n_samps, samps_remaining)
212 if (.not. sent_dones)
then
215 do i_proc = 0, (n_proc - 1)
222 call coag_dist_recv(requests, env_state, aero_weight_total, aero_data, &
223 aero_state, accept_factors, coag_kernel_type, tot_n_coag, &
224 magnitudes, procs_done)
231 deallocate(procs_done)
233 deallocate(accept_factors)
235 deallocate(magnitudes)
236 call mpi_buffer_detach(outgoing_buffer, &
237 outgoing_buffer_size_check, ierr)
241 deallocate(outgoing_buffer)
249 aero_data, aero_state, accept_factors, coag_kernel_type, tot_n_coag, &
250 magnitudes, procs_done)
253 type(
request_t),
intent(inout) :: requests(COAG_DIST_MAX_REQUESTS)
263 real(kind=
dp),
intent(in) :: accept_factors(:,:)
265 integer,
intent(in) :: coag_kernel_type
267 integer,
intent(inout) :: tot_n_coag
269 real(kind=
dp),
intent(in) :: magnitudes(:,:)
271 logical,
intent(inout) :: procs_done(:)
274 integer :: status(MPI_STATUS_SIZE), ierr
276 call mpi_probe(mpi_any_source, mpi_any_tag, mpi_comm_world, &
283 aero_data, aero_state, accept_factors, coag_kernel_type, &
284 tot_n_coag, magnitudes)
302 local_bin, remote_bin, n_samps, samps_remaining)
307 type(
request_t),
intent(inout) :: requests(COAG_DIST_MAX_REQUESTS)
309 integer,
intent(in) :: n_parts(:,:)
311 integer,
intent(inout) :: local_bin
313 integer,
intent(inout) :: remote_bin
315 integer,
intent(inout) :: n_samps(:,:)
317 logical,
intent(inout) :: samps_remaining
319 integer,
parameter :: s1 = 1
320 integer,
parameter :: s2 = 1
321 integer,
parameter :: sc = 1
325 if (.not. samps_remaining)
return
327 outer:
do i_req = 1,coag_dist_max_requests
332 if (.not. samps_remaining)
exit outer
333 if (integer_varray_n_entry( &
334 aero_state%aero_sorted%size_class%inverse(local_bin, s2)) &
337 requests(i_req)%remote_proc)
338 requests(i_req)%active = .true.
339 requests(i_req)%local_bin = local_bin
340 requests(i_req)%remote_bin = remote_bin
342 local_bin, s2, requests(i_req)%local_aero_particle)
344 requests(i_req)%remote_bin)
379 integer,
intent(in) :: n_parts(:,:)
381 integer,
intent(in) :: remote_bin
383 integer,
intent(out) :: remote_proc
397 integer,
intent(inout) :: n_samps(:,:)
399 integer,
intent(inout) :: local_bin
401 integer,
intent(inout) :: remote_bin
403 logical,
intent(inout) :: samps_remaining
407 if (.not. samps_remaining)
return
409 n_bin =
size(n_samps, 1)
411 if (n_samps(local_bin, remote_bin) > 0)
exit
413 remote_bin = remote_bin + 1
414 if (remote_bin > n_bin)
then
416 local_bin = local_bin + 1
418 if (local_bin > n_bin)
exit
421 if (local_bin > n_bin)
then
422 samps_remaining = .false.
424 n_samps(local_bin, remote_bin) = n_samps(local_bin, remote_bin) - 1
434 integer,
intent(in) :: remote_proc
436 integer,
intent(in) :: remote_bin
439 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
440 integer :: buffer_size, max_buffer_size, position, ierr
444 call assert(893545122, max_buffer_size <= coag_dist_max_buffer_size)
447 call assert(610314213, position <= max_buffer_size)
448 buffer_size = position
449 call mpi_bsend(buffer, buffer_size, mpi_character, remote_proc, &
463 integer,
parameter :: s1 = 1
464 integer,
parameter :: s2 = 1
465 integer,
parameter :: sc = 1
468 integer :: buffer_size, position, request_bin, sent_proc
469 integer :: ierr, remote_proc, status(MPI_STATUS_SIZE)
470 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
471 type(aero_particle_t) :: aero_particle
474 call mpi_recv(buffer, coag_dist_max_buffer_size, mpi_character, &
478 call assert(920139874, status(mpi_tag) &
480 call mpi_get_count(status, mpi_character, buffer_size, ierr)
482 call assert(190658659, buffer_size <= coag_dist_max_buffer_size)
483 remote_proc = status(mpi_source)
488 call assert(895128380, position == buffer_size)
491 if (integer_varray_n_entry( &
492 aero_state%aero_sorted%size_class%inverse(request_bin, s1)) == 0)
then
496 request_bin, s1, aero_particle)
509 integer,
intent(in) :: dest_proc
511 integer,
intent(in) :: i_bin
514 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
515 integer :: buffer_size, max_buffer_size, position, ierr
519 call assert(744787119, max_buffer_size <= coag_dist_max_buffer_size)
522 call assert(445960340, position <= max_buffer_size)
523 buffer_size = position
524 call mpi_bsend(buffer, buffer_size, mpi_character, dest_proc, &
536 type(
request_t),
intent(inout) :: requests(COAG_DIST_MAX_REQUESTS)
543 logical :: found_request
544 integer :: buffer_size, position, sent_bin, sent_proc, i_req
545 integer :: ierr, status(MPI_STATUS_SIZE)
546 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
549 call mpi_recv(buffer, coag_dist_max_buffer_size, mpi_character, &
551 mpi_comm_world, status, ierr)
553 call assert(918153221, status(mpi_tag) &
555 call mpi_get_count(status, mpi_character, buffer_size, ierr)
557 call assert(461111487, buffer_size <= coag_dist_max_buffer_size)
558 sent_proc = status(mpi_source)
563 call assert(518172999, position == buffer_size)
566 found_request = .false.
567 do i_req = 1,coag_dist_max_requests
568 if ((requests(i_req)%remote_proc == sent_proc) &
569 .and. (requests(i_req)%remote_bin == sent_bin))
then
570 found_request = .true.
574 call assert(215612776, found_request)
580 requests(i_req)%local_aero_particle, aero_data, &
581 allow_resort=.false.)
593 type(aero_particle_t),
intent(in) :: aero_particle
595 integer,
intent(in) :: i_bin
597 integer,
intent(in) :: dest_proc
600 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
601 integer :: buffer_size, max_buffer_size, position, ierr
605 max_buffer_size = max_buffer_size &
606 + pmc_mpi_pack_size_aero_particle(aero_particle)
607 call assert(496283814, max_buffer_size <= coag_dist_max_buffer_size)
610 call pmc_mpi_pack_aero_particle(buffer, position, aero_particle)
611 call assert(263666386, position <= max_buffer_size)
612 buffer_size = position
613 call mpi_bsend(buffer, buffer_size, mpi_character, dest_proc, &
623 aero_data, aero_state, accept_factors, coag_kernel_type, tot_n_coag, &
627 type(
request_t),
intent(inout) :: requests(COAG_DIST_MAX_REQUESTS)
637 real(kind=
dp),
intent(in) :: accept_factors(:,:)
639 integer,
intent(in) :: coag_kernel_type
641 integer,
intent(inout) :: tot_n_coag
643 real(kind=
dp),
intent(in) :: magnitudes(:,:)
645 integer,
parameter :: s1 = 1
646 integer,
parameter :: s2 = 1
647 integer,
parameter :: sc = 1
650 logical :: found_request, remove_1, remove_2
651 integer :: buffer_size, position, sent_bin, sent_proc, i_req
652 integer :: ierr, status(MPI_STATUS_SIZE)
653 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
654 type(aero_particle_t) :: sent_aero_particle
655 real(kind=
dp) :: k, p
658 call mpi_recv(buffer, coag_dist_max_buffer_size, mpi_character, &
660 mpi_comm_world, status, ierr)
662 call assert(133285061, status(mpi_tag) &
664 call mpi_get_count(status, mpi_character, buffer_size, ierr)
666 call assert(563012836, buffer_size <= coag_dist_max_buffer_size)
667 sent_proc = status(mpi_source)
672 call pmc_mpi_unpack_aero_particle(buffer, position, sent_aero_particle)
673 call assert(753356021, position == buffer_size)
676 found_request = .false.
677 do i_req = 1,coag_dist_max_requests
678 if ((requests(i_req)%remote_proc == sent_proc) &
679 .and. (requests(i_req)%remote_bin == sent_bin))
then
680 found_request = .true.
684 call assert(579308475, found_request)
687 call num_conc_weighted_kernel(coag_kernel_type, &
688 requests(i_req)%local_aero_particle, sent_aero_particle, &
689 s1, s2, sc, aero_data, aero_weight_total, env_state, k)
690 p = k * accept_factors(requests(i_req)%local_bin, sent_bin)
694 tot_n_coag = tot_n_coag + 1
696 requests(i_req)%local_aero_particle, sent_aero_particle, &
697 sent_proc, aero_weight_total, magnitudes, remove_1, remove_2)
704 if (.not. remove_1)
then
708 requests(i_req)%local_aero_particle, aero_data, &
709 allow_resort=.false.)
711 if (.not. remove_2)
then
726 type(aero_particle_t),
intent(in) :: aero_particle
728 integer,
intent(in) :: dest_proc
732 integer :: buffer_size, max_buffer_size, position, ierr
735 max_buffer_size = max_buffer_size &
736 + pmc_mpi_pack_size_aero_particle(aero_particle)
739 call pmc_mpi_pack_aero_particle(buffer, position, aero_particle)
740 call assert(898537822, position <= max_buffer_size)
741 buffer_size = position
742 call mpi_bsend(buffer, buffer_size, mpi_character, dest_proc, &
759 logical :: found_request
760 integer :: buffer_size, position, sent_proc, ierr
761 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
762 type(aero_particle_t) :: aero_particle
763 integer :: status(MPI_STATUS_SIZE), send_proc
766 call mpi_recv(buffer, coag_dist_max_buffer_size, mpi_character, &
768 mpi_comm_world, status, ierr)
770 call assert(496247788, status(mpi_tag) &
772 call mpi_get_count(status, mpi_character, buffer_size, ierr)
774 call assert(590644042, buffer_size <= coag_dist_max_buffer_size)
775 sent_proc = status(mpi_source)
779 call pmc_mpi_unpack_aero_particle(buffer, position, aero_particle)
780 call assert(833588594, position == buffer_size)
784 allow_resort=.false.)
796 integer,
intent(in) :: dest_proc
799 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
800 integer :: buffer_size, ierr
803 call mpi_bsend(buffer, buffer_size, mpi_character, dest_proc, &
816 logical,
intent(inout) :: procs_done(:)
819 integer :: buffer_size, sent_proc, ierr
820 character :: buffer(COAG_DIST_MAX_BUFFER_SIZE)
821 integer :: status(MPI_STATUS_SIZE)
824 call mpi_recv(buffer, coag_dist_max_buffer_size, mpi_character, &
828 call assert(348737947, status(mpi_tag) &
830 call mpi_get_count(status, mpi_character, buffer_size, ierr)
832 call assert(214904056, buffer_size == 0)
833 sent_proc = status(mpi_source)
836 procs_done(sent_proc + 1) = .true.
845 k_max, n_samps, accept_factors)
848 integer,
intent(in) :: n_parts(:,:)
850 real(kind=
dp),
intent(in) :: del_t
856 real(kind=
dp),
intent(in) :: k_max(:,:)
858 integer,
intent(out) :: n_samps(:,:)
860 real(kind=
dp),
intent(out) :: accept_factors(:,:)
862 integer :: i_bin, j_bin, rank, n_bin
863 real(kind=
dp) :: n_samp_mean
865 n_bin =
size(k_max, 1)
869 if (n_parts(i_bin, rank + 1) == 0) &
871 do j_bin = i_bin,n_bin
873 sum(n_parts(j_bin, :)), (i_bin == j_bin), &
874 k_max(i_bin, j_bin), del_t, n_samp_mean, &
875 n_samps(i_bin, j_bin), accept_factors(i_bin, j_bin))
884 aero_particle_2, remote_proc, aero_weight_total, magnitudes, &
892 type(aero_particle_t),
intent(in) :: aero_particle_1
894 type(aero_particle_t),
intent(in) :: aero_particle_2
896 integer,
intent(in) :: remote_proc
900 real(kind=
dp),
intent(in) :: magnitudes(:,:)
902 logical,
intent(out) :: remove_1
904 logical,
intent(out) :: remove_2
906 integer,
parameter :: s1 = 1
907 integer,
parameter :: s2 = 1
908 integer,
parameter :: sc = 1
910 type(aero_particle_t) :: aero_particle_new
911 integer :: new_proc, new_group
912 type(aero_info_t) :: aero_info_1, aero_info_2
913 logical :: create_new, id_1_lost, id_2_lost
916 aero_particle_new, s1, s2, sc, aero_data, aero_state%awa, &
917 remove_1, remove_2, create_new, id_1_lost, id_2_lost, &
918 aero_info_1, aero_info_2)
921 call aero_info_array_add_aero_info(aero_state%aero_info_array, &
925 call aero_info_array_add_aero_info(aero_state%aero_info_array, &
932 aero_particle_radius(aero_particle_new, aero_data))
933 aero_particle_new%weight_group = new_group