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"
6 program poisson_benchmark
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
22 integer :: count_rate,t_start, t_end
24 print *,
"Running poisson_benchmark_" // dimname //
""
25 print *,
"Number of threads", af_get_max_threads()
28 n_args = command_argument_count()
31 call get_command_argument(1, arg_string)
32 read(arg_string, *) n_cell
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)"
41 call get_command_argument(2, arg_string)
42 read(arg_string, *) coarse_grid_size
48 call get_command_argument(3, arg_string)
49 read(arg_string, *) max_ref_lvl
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"
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
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)
75 [dtimes(coarse_grid_size)])
77 call system_clock(t_start, count_rate)
80 call af_loop_box(tree, set_init_cond)
86 call af_adjust_refinement(tree, ref_routine, ref_info)
89 if (ref_info%n_add == 0)
exit
91 call system_clock(t_end, count_rate)
93 write(*,
"(A,Es10.3,A)")
" Wall-clock time generating AMR grid: ", &
94 (t_end-t_start) / real(count_rate,dp),
" seconds"
96 call af_print_info(tree)
102 mg%sides_bc => af_bc_dirichlet_zero
108 call mg_init(tree, mg)
111 call mg_fas_fmg(tree, mg, .false., .false.)
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
123 n_iterations = ceiling((runtime/time) * mg_iter)
126 call system_clock(t_start, count_rate)
127 do mg_iter = 1, n_iterations
131 call mg_fas_fmg(tree, mg, .false., mg_iter>1)
141 call system_clock(t_end, count_rate)
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"
156 call af_destroy(tree)
161 subroutine ref_routine(box, cell_flags)
162 type(box_t),
intent(in) :: box
163 integer,
intent(out) :: cell_flags(DTIMES(box%n_cell))
166 if (box%lvl < max_ref_lvl)
then
167 cell_flags = af_do_ref
169 cell_flags = af_keep_ref
171 end subroutine ref_routine
174 subroutine set_init_cond(box)
175 type(box_t),
intent(inout) :: box
179 box%cc(dtimes(1:nc), i_rhs) = 1.0_dp
180 end subroutine set_init_cond
182 end program poisson_benchmark
Module which contains all Afivo modules, so that a user does not have to include them separately.