Afivo  0.3
particles_to_grid.f90

Example showing how to map particles to a grid

1 #include "../src/cpp_macros.h"
2 
5 program particles_to_grid
6  use m_af_all
7 
8  implicit none
9 
10  integer, parameter :: box_size = 8
11  integer :: i_phi, i_tmp
12  integer, parameter :: n_particles = 1000*1000
13  real(dp), parameter :: r_max(NDIM) = 1.0_dp
14  real(dp), allocatable :: coordinates(:, :), weights(:)
15  integer :: coordinate_system = af_xyz
16  logical :: cylindrical = .false.
17  logical :: use_tmp_var = .false.
18 
19  type(af_t) :: tree
20  type(ref_info_t) :: refine_info
21  integer :: n
22  integer :: count_rate, t_start, t_end
23  real(dp) :: sum_density
24  character(len=10) :: tmp_string
25 
26  if (command_argument_count() > 0) then
27  call get_command_argument(1, tmp_string)
28  read(tmp_string, *) cylindrical
29  end if
30 
31  if (command_argument_count() > 1) then
32  call get_command_argument(2, tmp_string)
33  read(tmp_string, *) use_tmp_var
34  end if
35 
36  if (cylindrical) coordinate_system = af_cyl
37 
38  print *, "Running particles_to_grid_" // dimname // ""
39  print *, "Number of threads", af_get_max_threads()
40  print *, "Cylindrical", cylindrical
41  print *, "Number of particles", n_particles
42 
43  call af_add_cc_variable(tree, "phi", ix=i_phi)
44  call af_add_cc_variable(tree, "tmp", ix=i_tmp)
45 
46  call af_init(tree, box_size, r_max, [dtimes(box_size)], &
47  coord=coordinate_system)
48 
49  call af_set_cc_methods(tree, i_phi, af_bc_neumann_zero, af_gc_interp)
50 
51  do
52  call af_adjust_refinement(tree, refine_routine, refine_info, 0)
53  if (refine_info%n_add == 0) exit
54  end do
55 
56  allocate(coordinates(ndim, n_particles))
57  allocate(weights(n_particles))
58 
59  call random_number(coordinates(:, :))
60  weights(:) = 1.0_dp / n_particles
61 
62  if (cylindrical) then
63  coordinates(1, :) = sqrt(coordinates(1, :))
64  end if
65 
66  do n = 1, n_particles
67  coordinates(:, n) = 0.6_dp * coordinates(:, n) * r_max
68  end do
69 
70  call system_clock(t_start, count_rate)
71 
72  if (use_tmp_var) then
73  call af_particles_to_grid(tree, i_phi, n_particles, &
74  get_id, get_rw, 0, iv_tmp=i_tmp)
75  else
76  call af_particles_to_grid(tree, i_phi, n_particles, &
77  get_id, get_rw, 0)
78  end if
79 
80  call system_clock(t_end, count_rate)
81  call af_write_silo(tree, "output/particles_to_grid_" // dimname // "_0", 1, 0.0_dp)
82  call af_tree_sum_cc(tree, i_phi, sum_density)
83  print *, "zeroth order: ", (t_end-t_start) / real(count_rate, dp), " seconds"
84  print *, "integrated density: ", sum_density
85 
86  call af_tree_clear_cc(tree, i_phi)
87 
88  call system_clock(t_start, count_rate)
89 
90  if (use_tmp_var) then
91  call af_particles_to_grid(tree, i_phi, n_particles, &
92  get_id, get_rw, 1, iv_tmp=i_tmp)
93  else
94  call af_particles_to_grid(tree, i_phi, n_particles, &
95  get_id, get_rw, 1)
96  end if
97 
98  call system_clock(t_end, count_rate)
99  call af_write_silo(tree, "output/particles_to_grid_" // dimname // "_1", 1, 0.0_dp)
100  call af_tree_sum_cc(tree, i_phi, sum_density)
101  print *, "first order: ", (t_end-t_start) / real(count_rate, dp), " seconds"
102  print *, "integrated density: ", sum_density
103 
104 contains
105 
106  subroutine refine_routine(box, cell_flags)
107  type(box_t), intent(in) :: box
108  integer, intent(out) :: cell_flags(DTIMES(box%n_cell))
109 
110  if (all(box%r_min < 0.5_dp * r_max) .and. box%lvl <= 5) then
111  cell_flags(dtimes(:)) = af_do_ref
112  else
113  cell_flags(dtimes(:)) = af_keep_ref
114  end if
115  end subroutine refine_routine
116 
117  subroutine get_id(n, id)
118  integer, intent(in) :: n
119  integer, intent(out) :: id
120 
121  id = af_get_id_at(tree, coordinates(:, n))
122  end subroutine get_id
123 
124  subroutine get_rw(n, r, w)
125  integer, intent(in) :: n
126  real(dp), intent(out) :: r(NDIM)
127  real(dp), intent(out) :: w
128 
129  r = coordinates(:, n)
130  w = weights(n)
131  end subroutine get_rw
132 
133 end program particles_to_grid
Module which contains all Afivo modules, so that a user does not have to include them separately.
Definition: m_af_all.f90:3