1 #include "../src/cpp_macros.h"
3 program solid_body_rotation
7 integer,
parameter :: ncells = 8
9 integer,
parameter :: coord_type = af_xyz
10 real(dp) :: l_max(NDIM), l_min(NDIM), error
12 logical :: periodicBC(NDIM)
15 real(dp) :: dt, time, end_time
17 character(len=100) :: fname
20 type(ref_info_t) :: refine_info
21 real(dp) :: dr_min(NDIM)
23 print *,
"Running solid body rotation 2D"
24 print *,
"Number of threads", af_get_max_threads()
30 periodicbc(:) = .false.
34 call af_add_cc_variable(tree,
"q", ix=iq)
35 call af_add_fc_variable(tree,
"flux", ix=i_flux)
36 call af_set_cc_methods(tree, iq, af_bc_dirichlet_zero)
38 call af_init(tree, ncells, l_max, grid, &
39 periodic = periodicbc, r_min = l_min, &
43 call af_loop_box(tree, setinitconds)
44 call af_gc_tree(tree, [iq])
46 call af_adjust_refinement(tree, refine_routine, refine_info, 1)
47 call af_restrict_tree(tree, [iq])
48 call af_gc_tree(tree, [iq])
54 end_time = 0.5_dp*acos(-1.0_dp)
59 dr_min = af_min_dr(tree)
60 dt = 0.5_dp/(sum(3.0_dp/dr_min) + epsilon(1.0_dp))
62 if (mod(t_iter, 50) == 0)
then
63 write(fname,
"(A,I0)")
"output/amr_solid_body_rotation_" // &
64 dimname //
"_", t_iter
65 call af_write_silo(tree, trim(fname), t_iter, time)
69 call af_loop_tree(tree, korenflux, .true.)
70 call af_consistent_fluxes(tree, [iq])
73 call af_loop_box_arg(tree, updatesoln, [dt])
75 call af_restrict_tree(tree, [iq])
77 call af_gc_tree(tree, [iq])
80 call af_adjust_refinement(tree, refine_routine, refine_info, 1)
86 call af_tree_maxabs_cc(tree, iq, error)
87 if (error > 5.0_dp .or. dt < 1e-6_dp)
then
88 print *,
"Solution diverging!"
92 if (time > end_time)
exit
99 subroutine setinitconds( box )
100 type(box_t),
intent(inout) :: box
106 rr = af_r_cc(box, [ijk])
107 box%cc(ijk, iq) = solution(rr)
109 end subroutine setinitconds
111 function solution( rr )
result(sol)
112 real(dp),
intent(in) :: rr(NDIM)
114 real(dp) :: peak(NDIM), xLim(NDIM), yLim(NDIM)
125 if( xlim(1) < rr(1) .and. rr(1) < xlim(2) .and. ylim(1) < rr(2) &
126 .and. rr(2) < ylim(2) )
then
128 else if (norm2(rr + peak) < 0.35_dp)
then
129 sol = 1.0_dp - (norm2(rr + peak)/0.35_dp)
134 end function solution
137 subroutine refine_routine( box, cell_flags )
138 type(box_t),
intent(in) :: box
139 integer,
intent(out) :: cell_flags(DTIMES(box%n_cell))
145 diff = box%dr(1)**2*abs(box%cc(i+1,j,iq)+box%cc(i-1,j,iq)-2*box%cc(i,j,iq)) + &
146 box%dr(2)**2*abs(box%cc(i,j+1,iq)+box%cc(i,j-1,iq)-2*box%cc(i,j,iq))
147 if (diff > 1.0e-5_dp .and. box%lvl .le. 3)
then
148 cell_flags(ijk) = af_do_ref
149 else if (diff < 0.1_dp*1.0e-5_dp)
then
150 cell_flags(ijk) = af_rm_ref
152 cell_flags(ijk) = af_keep_ref
155 end subroutine refine_routine
157 subroutine korenflux( tree, id )
159 type(af_t),
intent(inout) :: tree
160 integer,
intent(in) :: id
162 real(dp),
allocatable :: cc(DTIMES(:), :)
163 real(dp),
allocatable :: v(DTIMES(:),:)
166 nc = tree%boxes(id)%n_cell
167 allocate(cc(dtimes(-1:nc+2), 1))
168 allocate(v(dtimes(1:nc+1), ndim))
171 call af_gc2_box(tree, id, [iq], cc)
174 rr = af_r_cc(tree%boxes(id), [ijk]) - 0.5_dp*tree%boxes(id)%dr
175 v(ijk, 1) = 2.0_dp*rr(2)
176 v(ijk, 2) = -2.0_dp*rr(1)
179 call flux_koren_2d(cc(dtimes(:), 1), v, nc, 2)
180 tree%boxes(id)%fc(:,:,:,i_flux) = v
182 end subroutine korenflux
184 subroutine updatesoln( box, dt )
185 type(box_t),
intent(inout) :: box
186 real(dp),
intent(in) :: dt(:)
187 real(dp) :: inv_dr(NDIM)
195 box%cc(i,j,iq) = box%cc(i,j,iq) - dt(1) * ( &
197 (box%fc(i+1,j,1,iq) - box%fc(i,j,1,iq)) &
199 (box%fc(i,j+1,2,iq) - box%fc(i,j,2,iq)))
203 end subroutine updatesoln
205 end program solid_body_rotation
Module which contains all Afivo modules, so that a user does not have to include them separately.
Module containing a couple flux schemes for solving hyperbolic problems explicitly,...