6 program implicit_diffusion_3d
11 integer,
parameter :: box_size = 8
12 integer,
parameter :: i_phi = 1
13 integer,
parameter :: i_rhs = 2
14 integer,
parameter :: i_tmp = 3
15 integer,
parameter :: i_err = 4
17 real(dp),
parameter :: domain_len = 2 * acos(-1.0_dp)
18 real(dp),
parameter :: dr = domain_len / box_size
19 real(dp),
parameter :: diffusion_coeff = 1.0_dp
20 real(dp),
parameter :: solution_modes(3) = [1, 1, 0]
24 type(ref_info_t) :: refine_info
26 integer :: ix_list(3, 1)
27 integer :: nb_list(a3_num_neighbors, 1)
28 integer :: time_steps, output_cnt
29 real(dp) :: dt, time, end_time
30 character(len=100) :: fname
32 print *,
"Running implicit_diffusion_3d" 33 print *,
"Number of threads", af_get_max_threads()
36 call a3_init(tree, box_size, n_var_cell=4, n_var_face=1, dr=dr, &
37 cc_names=[
"phi",
"rhs",
"tmp",
"err"])
41 ix_list(:, id) = [1, 1, 1]
45 call a3_set_base(tree, 1, ix_list, nb_list)
46 call a3_print_info(tree)
52 call a3_loop_box(tree, set_initial_condition)
60 call a3_gc_tree(tree, i_phi, a3_gc_interp, a3_bc_dirichlet_zero)
68 call a3_adjust_refinement(tree, &
73 if (refine_info%n_add == 0)
exit 79 mg%sides_bc => a3_bc_dirichlet_zero
83 mg%box_op => box_op_diff
84 mg%box_gsrb => box_gsrb_diff
100 time_steps = time_steps + 1
102 output_cnt = output_cnt + 1
103 write(fname,
"(A,I0)")
"implicit_diffusion_3d_", output_cnt
106 call a3_loop_box_arg(tree, set_error, [time])
110 call a3_write_vtk(tree, trim(fname), output_cnt, time, dir=
"output")
112 if (time > end_time)
exit 115 call a3_loop_box(tree, set_rhs)
118 call mg3_fas_fmg(tree, &
120 set_residual = .true., &
129 subroutine refine_routine(box, cell_flags)
130 type(box3_t),
intent(in) :: box
131 integer,
intent(out) :: cell_flags(box%n_cell, box%n_cell, box%n_cell)
133 if (box%dr > 2e-2_dp * domain_len)
then 134 cell_flags = af_do_ref
136 cell_flags = af_keep_ref
138 end subroutine refine_routine
141 subroutine set_initial_condition(box)
142 type(box3_t),
intent(inout) :: box
143 integer :: i, j, k, nc
148 do k = 0, nc+1;
do j = 0, nc+1;
do i = 0, nc+1
149 rr = a3_r_cc(box, [i, j, k])
150 box%cc(i, j, k, i_phi) = solution(rr, 0.0_dp)
151 end do; end do; end do
152 end subroutine set_initial_condition
155 subroutine set_error(box, time)
156 type(box3_t),
intent(inout) :: box
157 real(dp),
intent(in) :: time(:)
158 integer :: i, j, k, nc
162 do k = 1, nc;
do j = 1, nc;
do i = 1, nc
163 rr = a3_r_cc(box, [i, j, k])
164 box%cc(i, j, k, i_err) = &
165 box%cc(i, j, k, i_phi) - solution(rr, time(1))
166 end do; end do; end do
167 end subroutine set_error
169 function solution(rr, t)
result(sol)
170 real(dp),
intent(in) :: rr(3), t
171 real(dp) :: sol, tmp(3)
173 tmp = solution_modes * rr
174 sol = 1 + product(cos(tmp)) * &
175 exp(-sum(solution_modes**2) * diffusion_coeff * t)
176 end function solution
179 subroutine set_rhs(box)
180 type(box3_t),
intent(inout) :: box
184 box%cc(1:nc, 1:nc, 1:nc, i_rhs) = box%cc(1:nc, 1:nc, 1:nc, i_phi)
185 end subroutine set_rhs
188 subroutine box_op_diff(box, i_out, mg)
189 type(box3_t),
intent(inout) :: box
190 integer,
intent(in) :: i_out
191 type(mg3_t),
intent(in) :: mg
192 integer :: i, j, k, nc, i_phi
196 tmp = diffusion_coeff * dt / box%dr**2
199 do k = 1, nc;
do j = 1, nc;
do i = 1, nc
200 box%cc(i, j, k, i_out) = tmp * ((6 + 1/tmp) * &
201 box%cc(i, j, k, i_phi) &
202 - box%cc(i-1, j, k, i_phi) &
203 - box%cc(i+1, j, k, i_phi) &
204 - box%cc(i, j-1, k, i_phi) &
205 - box%cc(i, j+1, k, i_phi) &
206 - box%cc(i, j, k-1, i_phi) &
207 - box%cc(i, j, k+1, i_phi))
208 end do; end do; end do
209 end subroutine box_op_diff
212 subroutine box_gsrb_diff(box, redblack_cntr, mg)
213 type(box3_t),
intent(inout) :: box
214 integer,
intent(in) :: redblack_cntr
215 type(mg3_t),
intent(in) :: mg
216 integer :: i, j, k, i0, nc, i_phi, i_rhs
219 tmp = diffusion_coeff * dt / box%dr**2
228 i0 = 2 - iand(ieor(redblack_cntr, k+j), 1)
230 box%cc(i, j, k, i_phi) = 1 / (6 + 1/tmp) * ( &
231 box%cc(i+1, j, k, i_phi) + box%cc(i-1, j, k, i_phi) + &
232 box%cc(i, j+1, k, i_phi) + box%cc(i, j-1, k, i_phi) + &
233 box%cc(i, j, k+1, i_phi) + box%cc(i, j, k-1, i_phi) + &
234 1/tmp * box%cc(i, j, k, i_rhs))
238 end subroutine box_gsrb_diff
240 end program implicit_diffusion_3d
Module which contains all Afivo modules, so that a user does not have to include them separately...