12 integer,
parameter :: box_size = 8
13 integer,
parameter :: n_boxes_base = 1
14 integer,
parameter :: n_iterations = 10
15 integer,
parameter :: n_var_cell = 4
16 integer,
parameter :: i_phi = 1
17 integer,
parameter :: i_rhs = 2
18 integer,
parameter :: i_err = 3
19 integer,
parameter :: i_tmp = 4
20 real(dp),
parameter :: lambda2 = 1000.0_dp
23 type(ref_info_t) :: ref_info
25 integer :: ix_list(2, n_boxes_base)
26 real(dp) :: dr, residu(2), anal_err(2)
27 character(len=100) :: fname
30 integer :: count_rate,t_start, t_end
32 print *,
"Running helmholtz_cyl" 33 print *,
"Number of threads", af_get_max_threads()
36 call gauss_init(gs, [1.0_dp, 1.0_dp], [0.01_dp, 0.04_dp], &
37 reshape([0.0_dp, 0.25_dp, 0.1_dp, 0.75_dp], [2,2]))
40 dr = 1.0_dp / box_size
50 cc_names=[
"phi",
"rhs",
"err",
"tmp"])
57 call a2_set_base(tree, 1, ix_list)
58 call a2_print_info(tree)
60 call system_clock(t_start, count_rate)
63 call a2_loop_box(tree, set_init_cond)
66 call a2_adjust_refinement(tree, ref_routine, ref_info)
69 if (ref_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 a2_print_info(tree)
82 mg%sides_bc => sides_bc
85 mg%box_op => helmholtz_cyl_operator
86 mg%box_gsrb => helmholtz_cyl_gsrb
87 mg%box_corr => mg2_auto_corr
95 print *,
"Multigrid iteration | max residual | max error" 96 call system_clock(t_start, count_rate)
98 do mg_iter = 1, n_iterations
102 call mg2_fas_fmg(tree, mg, .true., mg_iter>1)
105 call a2_loop_box(tree, set_err)
108 call a2_tree_min_cc(tree, i_tmp, residu(1))
109 call a2_tree_max_cc(tree, i_tmp, residu(2))
110 call a2_tree_min_cc(tree, i_err, anal_err(1))
111 call a2_tree_max_cc(tree, i_err, anal_err(2))
112 write(*,
"(I8,2Es14.5)") mg_iter, maxval(abs(residu)), &
113 maxval(abs(anal_err))
115 write(fname,
"(A,I0)")
"helmholtz_cyl_", mg_iter
116 call a2_write_vtk(tree, trim(fname), dir=
"output")
118 call system_clock(t_end, count_rate)
120 write(*,
"(A,I0,A,E10.3,A)") &
121 " Wall-clock time after ", n_iterations, &
122 " iterations: ", (t_end-t_start) /
real(count_rate, dp), &
127 call a2_destroy(tree)
132 subroutine ref_routine(box, cell_flags)
133 type(box2_t),
intent(in) :: box
134 integer,
intent(out) :: cell_flags(box%n_cell, box%n_cell)
143 crv = box%dr**2 * abs(box%cc(i, j, i_rhs))
146 if (crv > 5.0e-4_dp)
then 147 cell_flags(i, j) = af_do_ref
149 cell_flags(i, j) = af_keep_ref
158 end subroutine ref_routine
161 subroutine set_init_cond(box)
162 type(box2_t),
intent(inout) :: box
170 rz = a2_r_cc(box, [i,j])
171 box%cc(i, j, i_rhs) = gauss_laplacian_cyl(gs, rz) - &
172 lambda2 * gauss_value(gs, rz)
175 end subroutine set_init_cond
178 subroutine set_err(box)
179 type(box2_t),
intent(inout) :: box
186 rz = a2_r_cc(box, [i,j])
187 box%cc(i, j, i_err) = box%cc(i, j, i_phi) - gauss_value(gs, rz)
190 end subroutine set_err
196 subroutine sides_bc(box, nb, iv, bc_type)
197 type(box2_t),
intent(inout) :: box
198 integer,
intent(in) :: nb
199 integer,
intent(in) :: iv
200 integer,
intent(out) :: bc_type
207 case (a2_neighb_lowx)
208 bc_type = af_bc_neumann
209 box%cc(0, 1:nc, iv) = 0
210 case (a2_neighb_highx)
211 bc_type = af_bc_dirichlet
213 rz = a2_rr_cc(box, [nc+0.5_dp,
real(n, dp)])
214 box%cc(nc+1, n, iv) = gauss_value(gs, rz)
216 case (a2_neighb_lowy)
217 bc_type = af_bc_dirichlet
219 rz = a2_rr_cc(box, [
real(n, dp), 0.5_dp])
220 box%cc(n, 0, iv) = gauss_value(gs, rz)
222 case (a2_neighb_highy)
223 bc_type = af_bc_dirichlet
225 rz = a2_rr_cc(box, [
real(n, dp), nc+0.5_dp])
226 box%cc(n, nc+1, iv) = gauss_value(gs, rz)
229 end subroutine sides_bc
232 subroutine helmholtz_cyl_operator(box, i_out, mg)
233 type(box2_t),
intent(inout) :: box
234 integer,
intent(in) :: i_out
235 type(mg2_t),
intent(in) :: mg
236 integer :: i, j, nc, i_phi, ioff
237 real(dp) :: inv_dr_sq, rfac(2)
240 inv_dr_sq = 1 / box%dr**2
242 ioff = (box%ix(1)-1) * nc
246 rfac = [i+ioff-1, i+ioff] / (i+ioff-0.5_dp)
247 box%cc(i, j, i_out) = ( &
248 rfac(1) * box%cc(i-1, j, i_phi) + &
249 rfac(2) * box%cc(i+1, j, i_phi) + &
250 box%cc(i, j-1, i_phi) + box%cc(i, j+1, i_phi) - &
251 4 * box%cc(i, j, i_phi)) * inv_dr_sq - &
252 lambda2 * box%cc(i, j, i_phi)
255 end subroutine helmholtz_cyl_operator
258 subroutine helmholtz_cyl_gsrb(box, redblack_cntr, mg)
259 type(box2_t),
intent(inout) :: box
260 integer,
intent(in) :: redblack_cntr
261 type(mg2_t),
intent(in) :: mg
262 integer :: i, i0, j, nc, i_phi, i_rhs, ioff
263 real(dp) :: dx2, rfac(2)
269 ioff = (box%ix(1)-1) * nc
274 i0 = 2 - iand(ieor(redblack_cntr, j), 1)
276 rfac = [i+ioff-1, i+ioff] / (i+ioff-0.5_dp)
277 box%cc(i, j, i_phi) = 1/(4 + lambda2 * dx2) * ( &
278 rfac(1) * box%cc(i-1, j, i_phi) + &
279 rfac(2) * box%cc(i+1, j, i_phi) + &
280 box%cc(i, j+1, i_phi) + box%cc(i, j-1, i_phi) - &
281 dx2 * box%cc(i, j, i_rhs))
284 end subroutine helmholtz_cyl_gsrb
286 end program helmholtz_cyl
This module can be used to construct solutions consisting of one or more Gaussians.
Module which contains all Afivo modules, so that a user does not have to include them separately...