Afivo 0.3
All Classes Namespaces Functions Variables Pages
amr_solid_body_rotation.f90
1#include "../src/cpp_macros.h"
2
3program solid_body_rotation
4 use m_af_all
5 implicit none
6
7 integer, parameter :: ncells = 8
8 integer :: iq, i_flux
9 integer, parameter :: coord_type = af_xyz
10 real(dp) :: l_max(NDIM), l_min(NDIM), error
11 integer :: grid(NDIM)
12 logical :: periodicBC(NDIM)
13
14 type(af_t) :: tree
15 real(dp) :: dt, time, end_time
16 integer :: t_iter
17 character(len=100) :: fname
18
19 !AMR related stuff
20 type(ref_info_t) :: refine_info
21 real(dp) :: dr_min(NDIM)
22
23 print *, "Running solid body rotation 2D"
24 print *, "Number of threads", af_get_max_threads()
25
26 !Setting up the domain and ncells
27 grid(:) = 4*ncells
28 l_max(:) = 1.0_dp
29 l_min(:) = -1.0_dp
30 periodicbc(:) = .false.
31
32
33 !Initialize the variables, boundary conditions and the tree
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)
37
38 call af_init(tree, ncells, l_max, grid, &
39 periodic = periodicbc, r_min = l_min, &
40 coord = coord_type)
41
42 !Setting the boundary conditions & fill ghost cells
43 call af_loop_box(tree, setinitconds)
44 call af_gc_tree(tree, [iq])
45 !One level of refinement
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])
49
50 !call af_write_silo(tree, "testsbr_amr", dir="output")
51 !Setting the time step data
52 time = 0.0
53 t_iter = 1
54 end_time = 0.5_dp*acos(-1.0_dp)
55
56 !Starting the time integration
57 do
58
59 dr_min = af_min_dr(tree)
60 dt = 0.5_dp/(sum(3.0_dp/dr_min) + epsilon(1.0_dp))
61
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)
66 end if
67
68
69 call af_loop_tree(tree, korenflux, .true.)
70 call af_consistent_fluxes(tree, [iq])
71 !print *, 'Finished Looping over tree'
72
73 call af_loop_box_arg(tree, updatesoln, [dt])
74 !print *, 'finished time stepping'
75 call af_restrict_tree(tree, [iq])
76
77 call af_gc_tree(tree, [iq])
78 !print *, 'Updating ghost cells'
79
80 call af_adjust_refinement(tree, refine_routine, refine_info, 1)
81
82 time = time + dt
83 t_iter = t_iter+1
84
85 !Checking for divergence
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!"
89 exit
90 end if
91
92 if (time > end_time) exit
93
94 end do
95 call af_destroy(tree)
96 !==============================================================================================================================
97contains
98
99 subroutine setinitconds( box )
100 type(box_t), intent(inout) :: box
101 integer :: IJK, nc
102 real(dp) :: rr(NDIM)
103
104 nc = box%n_cell
105 do kji_do(0, nc+1)
106 rr = af_r_cc(box, [ijk])
107 box%cc(ijk, iq) = solution(rr)
108 end do; close_do
109 end subroutine setinitconds
110
111 function solution( rr ) result(sol)
112 real(dp), intent(in) :: rr(NDIM)
113 real(dp) :: sol
114 real(dp) :: peak(NDIM), xLim(NDIM), yLim(NDIM)
115
116 peak(1) = 0.45_dp
117 peak(2) = 0.0_dp
118
119 xlim(1) = 0.1_dp
120 xlim(2) = 0.6_dp
121
122 ylim(1) = -0.25_dp
123 ylim(2) = 0.25_dp
124
125 if( xlim(1) < rr(1) .and. rr(1) < xlim(2) .and. ylim(1) < rr(2) &
126 .and. rr(2) < ylim(2) ) then
127 sol = 1.0_dp
128 else if (norm2(rr + peak) < 0.35_dp) then
129 sol = 1.0_dp - (norm2(rr + peak)/0.35_dp)
130 else
131 sol = 0.0_dp
132 end if
133
134 end function solution
135
136 !=============================================================================================
137 subroutine refine_routine( box, cell_flags )
138 type(box_t), intent(in) :: box
139 integer, intent(out) :: cell_flags(DTIMES(box%n_cell))
140 real(dp) :: diff
141 integer :: IJK, nc
142
143 nc = box%n_cell
144 do kji_do(1,nc)
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
151 else
152 cell_flags(ijk) = af_keep_ref
153 end if
154 end do; close_do
155 end subroutine refine_routine
156 !=============================================================================================
157 subroutine korenflux( tree, id )
159 type(af_t), intent(inout) :: tree
160 integer, intent(in) :: id
161 integer :: nc, IJK
162 real(dp), allocatable :: cc(DTIMES(:), :)
163 real(dp), allocatable :: v(DTIMES(:),:)
164 real(dp) :: rr(NDIM)
165
166 nc = tree%boxes(id)%n_cell
167 allocate(cc(dtimes(-1:nc+2), 1))
168 allocate(v(dtimes(1:nc+1), ndim))
169
170 !print *, "Inside Koren flux", id
171 call af_gc2_box(tree, id, [iq], cc)
172 !Computing the spatially varying velocities
173 do kji_do(1,nc+1)
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)
177 end do; close_do
178
179 call flux_koren_2d(cc(dtimes(:), 1), v, nc, 2)
180 tree%boxes(id)%fc(:,:,:,i_flux) = v
181
182 end subroutine korenflux
183 !=============================================================================================
184 subroutine updatesoln( box, dt )
185 type(box_t), intent(inout) :: box
186 real(dp), intent(in) :: dt(:)
187 real(dp) :: inv_dr(NDIM)
188 integer :: IJK, nc
189
190 nc = box%n_cell
191 inv_dr = 1/box%dr
192
193 do j=1,nc
194 do i=1,nc
195 box%cc(i,j,iq) = box%cc(i,j,iq) - dt(1) * ( &
196 inv_dr(1)* &
197 (box%fc(i+1,j,1,iq) - box%fc(i,j,1,iq)) &
198 + inv_dr(2)* &
199 (box%fc(i,j+1,2,iq) - box%fc(i,j,2,iq)))
200 end do
201 end do
202
203 end subroutine updatesoln
204
205end program solid_body_rotation
Module which contains all Afivo modules, so that a user does not have to include them separately.
Definition: m_af_all.f90:3
Module containing a couple flux schemes for solving hyperbolic problems explicitly,...