This program can be used to benchmark the multigrid routines. For simplicity, it does not compare results with a known solution.
This program can be used to benchmark the multigrid routines. For simplicity, it does not compare results with a known solution.
1#include "../src/cpp_macros.h"
2
3
4
5
6program poisson_benchmark
8
9 implicit none
10
11 integer :: i_phi
12 integer :: i_rhs
13 integer :: i_tmp
14
15 type(af_t) :: tree
16 type(ref_info_t) :: ref_info
17 integer :: mg_iter, n_args, coarse_grid_size
18 integer :: n_cell, n_iterations, max_ref_lvl
19 real(dp) :: time, runtime
20 character(len=100) :: arg_string
21 type(mg_t) :: mg
22 integer :: count_rate,t_start, t_end
23
24 print *, "Running poisson_benchmark_" // dimname // ""
25 print *, "Number of threads", af_get_max_threads()
26
27
28 n_args = command_argument_count()
29
30 if (n_args >= 1) then
31 call get_command_argument(1, arg_string)
32 read(arg_string, *) n_cell
33 else
34 print *, "No arguments specified, using default values"
35 print *, "Usage: ./poisson_benchmark_" // dimname // &
36 " n_cell coarse_grid_size max_ref_lvl runtime(s)"
37 n_cell = 16
38 end if
39
40 if (n_args >= 2) then
41 call get_command_argument(2, arg_string)
42 read(arg_string, *) coarse_grid_size
43 else
44 coarse_grid_size = 16
45 end if
46
47 if (n_args >= 3) then
48 call get_command_argument(3, arg_string)
49 read(arg_string, *) max_ref_lvl
50 else
51 max_ref_lvl = 2
52 end if
53
54 if (n_args >= 4) then
55 call get_command_argument(4, arg_string)
56 read(arg_string, *) runtime
57 if (runtime < 1e-3_dp) stop "Run time should be > 1e-3 seconds"
58 else
59 runtime = 0.2_dp
60 end if
61
62 print *, "Box size: ", n_cell
63 print *, "Coarse grid size: ", coarse_grid_size
64 print *, "Max refinement lvl: ", max_ref_lvl
65 print *, "Run time (s): ", runtime
66
67 call af_add_cc_variable(tree, "phi", ix=i_phi)
68 call af_add_cc_variable(tree, "rhs", ix=i_rhs)
69 call af_add_cc_variable(tree, "tmp", ix=i_tmp)
70
71
72 call af_init(tree, &
73 n_cell, &
74 [dtimes(1.0_dp)], &
75 [dtimes(coarse_grid_size)])
76
77 call system_clock(t_start, count_rate)
78 do
79
80 call af_loop_box(tree, set_init_cond)
81
82
83
84
85
86 call af_adjust_refinement(tree, ref_routine, ref_info)
87
88
89 if (ref_info%n_add == 0) exit
90 end do
91 call system_clock(t_end, count_rate)
92
93 write(*,"(A,Es10.3,A)") " Wall-clock time generating AMR grid: ", &
94 (t_end-t_start) / real(count_rate,dp), " seconds"
95
96 call af_print_info(tree)
97
98
99 mg%i_phi = i_phi
100 mg%i_rhs = i_rhs
101 mg%i_tmp = i_tmp
102 mg%sides_bc => af_bc_dirichlet_zero
103
104
105
106
107
108 call mg_init(tree, mg)
109
110
111 call mg_fas_fmg(tree, mg, .false., .false.)
112
113
114 n_iterations = 1000
115 call system_clock(t_start, count_rate)
116 do mg_iter = 1, n_iterations
117 call mg_fas_fmg(tree, mg, .false., mg_iter>1)
118 call system_clock(t_end, count_rate)
119 time = (t_end-t_start) / real(count_rate, dp)
120 if (time > 0.2_dp * runtime) exit
121 end do
122
123 n_iterations = ceiling((runtime/time) * mg_iter)
124
125
126 call system_clock(t_start, count_rate)
127 do mg_iter = 1, n_iterations
128
129
130
131 call mg_fas_fmg(tree, mg, .false., mg_iter>1)
132
133
134
135
136
137
138
139
140 end do
141 call system_clock(t_end, count_rate)
142
143 time = (t_end-t_start) / real(count_rate, dp)
144 write(*, "(A,I0,A,E10.3,A)") &
145 " Wall-clock time after ", n_iterations, &
146 " iterations: ", time, " seconds"
147 write(*, "(A,E10.3,A)") " Per iteration: ", time/n_iterations, " seconds"
148
149
150
151
152
153
154
155
156 call af_destroy(tree)
157
158contains
159
160
161 subroutine ref_routine(box, cell_flags)
162 type(box_t), intent(in) :: box
163 integer, intent(out) :: cell_flags(DTIMES(box%n_cell))
164
165
166 if (box%lvl < max_ref_lvl) then
167 cell_flags = af_do_ref
168 else
169 cell_flags = af_keep_ref
170 end if
171 end subroutine ref_routine
172
173
174 subroutine set_init_cond(box)
175 type(box_t), intent(inout) :: box
176 integer :: nc
177
178 nc = box%n_cell
179 box%cc(dtimes(1:nc), i_rhs) = 1.0_dp
180 end subroutine set_init_cond
181
182end program poisson_benchmark
Module which contains all Afivo modules, so that a user does not have to include them separately.