Afivo  0.3
amr_solid_body_rotation.f90
1 #include "../src/cpp_macros.h"
2 
3 program 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  !==============================================================================================================================
97 contains
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 
205 end 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,...