1 #include "../src/cpp_macros.h"
2 program poisson_coarse_solver
8 integer,
parameter :: box_size = 8
9 integer,
parameter :: domain_size(NDIM) = 16
10 integer,
parameter :: n_iterations = 10
19 type(ref_info_t) :: refine_info
21 real(dp) :: residu(2), anal_err(2)
22 character(len=100) :: fname
25 integer :: count_rate,t_start,t_end
27 print *,
"Running poisson_coarse_solver_" // dimname
28 print *,
"Number of threads", af_get_max_threads()
35 call gauss_init(gs, [1.0_dp, 1.0_dp], [0.1_dp, 0.1_dp], &
36 reshape([dtimes(0.25_dp), &
37 dtimes(0.6_dp)], [ndim,2]))
41 call af_add_cc_variable(tree,
"phi", ix=i_phi)
42 call af_add_cc_variable(tree,
"rhs", ix=i_rhs)
43 call af_add_cc_variable(tree,
"err", ix=i_err)
44 call af_add_cc_variable(tree,
"tmp", ix=i_tmp)
45 call af_add_cc_variable(tree,
"Dx", ix=i_gradx)
46 call af_add_cc_variable(tree,
"eDx", ix=i_egradx)
55 call system_clock(t_start, count_rate)
59 call af_loop_box(tree, set_initial_condition)
65 call af_adjust_refinement(tree, refine_routine, refine_info)
68 if (refine_info%n_add == 0)
exit
71 call system_clock(t_end, count_rate)
73 write(*,
"(A,Es10.3,A)")
" Wall-clock time generating AMR grid: ", &
74 (t_end-t_start) / real(count_rate,dp),
" seconds"
76 call af_print_info(tree)
83 mg%sides_bc => sides_bc
88 call mg_init(tree, mg)
90 print *,
"Multigrid iteration | max residual | max error"
91 call system_clock(t_start, count_rate)
93 do mg_iter = 1, n_iterations
97 call mg_fas_fmg(tree, mg, set_residual=.true., have_guess=(mg_iter>1))
100 call af_loop_box(tree, set_error)
103 call af_tree_min_cc(tree, i_tmp, residu(1))
104 call af_tree_max_cc(tree, i_tmp, residu(2))
105 call af_tree_min_cc(tree, i_err, anal_err(1))
106 call af_tree_max_cc(tree, i_err, anal_err(2))
107 write(*,
"(I8,13x,2(Es14.5))") mg_iter, maxval(abs(residu)), &
108 maxval(abs(anal_err))
113 write(fname,
"(A,I0)")
"output/poisson_coarse_solver_" // dimname //
"_", mg_iter
114 call af_write_silo(tree, trim(fname))
117 call system_clock(t_end, count_rate)
119 write(*,
"(A,I0,A,E10.3,A)") &
120 " Wall-clock time after ", n_iterations, &
121 " iterations: ", (t_end-t_start) / real(count_rate, dp), &
126 call af_destroy(tree)
132 subroutine refine_routine(box, cell_flags)
133 type(box_t),
intent(in) :: box
134 integer,
intent(out) :: cell_flags(DTIMES(box%n_cell))
136 real(dp) :: rr(NDIM), dr2, drhs
139 dr2 = maxval(box%dr)**2
142 rr = af_r_cc(box, [ijk])
146 drhs = dr2 * box%cc(ijk, i_rhs)
148 if (abs(drhs) > 1e-3_dp .and. box%lvl < 5)
then
149 cell_flags(ijk) = af_do_ref
151 cell_flags(ijk) = af_keep_ref
154 end subroutine refine_routine
159 subroutine set_initial_condition(box)
160 type(box_t),
intent(inout) :: box
162 real(dp) :: rr(NDIM), grad(NDIM)
168 rr = af_r_cc(box, [ijk])
171 box%cc(ijk, i_rhs) = gauss_laplacian(gs, rr)
172 call gauss_gradient(gs, rr, grad)
173 box%cc(ijk, i_gradx) = grad(1)
175 end subroutine set_initial_condition
180 subroutine set_error(box)
181 type(box_t),
intent(inout) :: box
183 real(dp) :: rr(NDIM), gradx
188 rr = af_r_cc(box, [ijk])
189 box%cc(ijk, i_err) = box%cc(ijk, i_phi) - gauss_value(gs, rr)
191 gradx = 0.5_dp * (box%cc(i+1, i_phi) - &
192 box%cc(i-1, i_phi)) / box%dr(1)
194 gradx = 0.5_dp * (box%cc(i+1, j, i_phi) - &
195 box%cc(i-1, j, i_phi)) / box%dr(1)
197 gradx = 0.5_dp * (box%cc(i+1, j, k, i_phi) - &
198 box%cc(i-1, j, k, i_phi)) / box%dr(1)
200 box%cc(ijk, i_egradx) = gradx - box%cc(ijk, i_gradx)
203 end subroutine set_error
207 subroutine sides_bc(box, nb, iv, coords, bc_val, bc_type)
208 type(box_t),
intent(in) :: box
209 integer,
intent(in) :: nb
210 integer,
intent(in) :: iv
211 real(dp),
intent(in) :: coords(NDIM, box%n_cell**(NDIM-1))
212 real(dp),
intent(out) :: bc_val(box%n_cell**(NDIM-1))
213 integer,
intent(out) :: bc_type
217 bc_type = af_bc_dirichlet
220 do n = 1, box%n_cell**(ndim-1)
221 bc_val(n) = gauss_value(gs, coords(:, n))
223 end subroutine sides_bc
225 end program poisson_coarse_solver
Module which contains all Afivo modules, so that a user does not have to include them separately.
This module can be used to construct solutions consisting of one or more Gaussians.