Afivo  0.3
m_af_restrict.f90
1 #include "cpp_macros.h"
2 
5 
6  use m_af_types
7 
8  implicit none
9  private
10 
11  public :: af_restrict_to_box
12  public :: af_restrict_to_boxes
13  public :: af_restrict_tree
14  public :: af_restrict_box
15  public :: af_restrict_ref_boundary
16  ! public :: af_restrict_box_face
17 
18 contains
19 
22  subroutine af_restrict_to_box(boxes, id, ivs)
23  type(box_t), intent(inout) :: boxes(:)
24  integer, intent(in) :: id
25  integer, intent(in) :: ivs(:)
26  integer :: nc, i_c, c_id
27 
28  nc = boxes(id)%n_cell
29  do i_c = 1, af_num_children
30  c_id = boxes(id)%children(i_c)
31  if (c_id == af_no_box) cycle
32  call af_restrict_box(boxes(c_id), boxes(id), ivs)
33  end do
34  end subroutine af_restrict_to_box
35 
37  subroutine af_restrict_to_boxes(boxes, ids, ivs)
38  type(box_t), intent(inout) :: boxes(:)
39  integer, intent(in) :: ids(:)
40  integer, intent(in) :: ivs(:)
41  integer :: i
42 
43  !$omp parallel do
44  do i = 1, size(ids)
45  call af_restrict_to_box(boxes, ids(i), ivs)
46  end do
47  !$omp end parallel do
48  end subroutine af_restrict_to_boxes
49 
51  subroutine af_restrict_tree(tree, ivs)
52  type(af_t), intent(inout) :: tree
53  integer, intent(in) :: ivs(:)
54  integer :: lvl
55 
56  if (.not. tree%ready) stop "Tree not ready"
57  do lvl = tree%highest_lvl-1, 1, -1
58  call af_restrict_to_boxes(tree%boxes, tree%lvls(lvl)%parents, ivs)
59  end do
60  end subroutine af_restrict_tree
61 
63  subroutine af_restrict_box(box_c, box_p, ivs, use_geometry)
64  type(box_t), intent(in) :: box_c
65  type(box_t), intent(inout) :: box_p
66  integer, intent(in) :: ivs(:)
67  logical, intent(in), optional :: use_geometry
68  integer :: ijk, ijk_(c), ijk_(f), n, iv
69  integer :: hnc, ix_offset(ndim)
70  logical :: use_geom
71 #if NDIM == 2
72  real(dp) :: w1, w2
73 #endif
74 
75  hnc = ishft(box_c%n_cell, -1) ! n_cell / 2
76  ix_offset = af_get_child_offset(box_c)
77 
78  if (present(use_geometry)) then
79  use_geom = use_geometry
80  else
81  use_geom = .true.
82  end if
83 
84  do n = 1, size(ivs)
85  iv = ivs(n)
86 #if NDIM == 1
87  do i = 1, hnc
88  i_c = ix_offset(1) + i
89  i_f = 2 * i - 1
90  box_p%cc(i_c, iv) = 0.5_dp * &
91  sum(box_c%cc(i_f:i_f+1, iv))
92  end do
93 #elif NDIM == 2
94  if (box_p%coord_t == af_cyl .and. use_geom) then
95  do j = 1, hnc
96  j_c = ix_offset(2) + j
97  j_f = 2 * j - 1
98  do i = 1, hnc
99  i_c = ix_offset(1) + i
100  i_f = 2 * i - 1
101 
102  call af_cyl_child_weights(box_p, i_c, w1, w2)
103  box_p%cc(i_c, j_c, iv) = 0.25_dp * (&
104  w1 * sum(box_c%cc(i_f, j_f:j_f+1, iv)) + &
105  w2 * sum(box_c%cc(i_f+1, j_f:j_f+1, iv)))
106  end do
107  end do
108  else
109  do j = 1, hnc
110  j_c = ix_offset(2) + j
111  j_f = 2 * j - 1
112  do i = 1, hnc
113  i_c = ix_offset(1) + i
114  i_f = 2 * i - 1
115  box_p%cc(i_c, j_c, iv) = 0.25_dp * &
116  sum(box_c%cc(i_f:i_f+1, j_f:j_f+1, iv))
117  end do
118  end do
119  endif
120 #elif NDIM == 3
121  do k = 1, hnc
122  k_c = ix_offset(3) + k
123  k_f = 2 * k - 1
124  do j = 1, hnc
125  j_c = ix_offset(2) + j
126  j_f = 2 * j - 1
127  do i = 1, hnc
128  i_c = ix_offset(1) + i
129  i_f = 2 * i - 1
130  box_p%cc(i_c, j_c, k_c, iv) = 0.125_dp * &
131  sum(box_c%cc(i_f:i_f+1, j_f:j_f+1, k_f:k_f+1, iv))
132  end do
133  end do
134  end do
135 #endif
136  end do
137  end subroutine af_restrict_box
138 
141  subroutine af_restrict_ref_boundary(tree, ivs)
142  type(af_t), intent(inout) :: tree
143  integer, intent(in) :: ivs(:)
144  integer :: lvl, i, id, p_id
145 
146  !$omp parallel private(lvl, i, id, p_id)
147  do lvl = 1, tree%highest_lvl
148  !$omp do
149  do i = 1, size(tree%lvls(lvl)%leaves)
150  id = tree%lvls(lvl)%leaves(i)
151  p_id = tree%boxes(id)%parent
152 
153  ! Only restrict near refinement boundaries
154  if (p_id > af_no_box .and. &
155  any(tree%boxes(id)%neighbors == af_no_box)) then
156  call af_restrict_box(tree%boxes(id), tree%boxes(p_id), ivs)
157  end if
158  end do
159  !$omp end do
160  end do
161  !$omp end parallel
162  end subroutine af_restrict_ref_boundary
163 
164 ! !> Restriction of face-centered variables from child to parent
165 ! subroutine af_restrict_box_face(box_c, box_p, ivf, ivf_to)
166 ! type(box_t), intent(in) :: box_c !< Child box to restrict
167 ! type(box_t), intent(inout) :: box_p !< Parent box to restrict to
168 ! integer, intent(in) :: ivf !< Face-variable to restrict
169 ! integer, intent(in), optional :: ivf_to !< Destination (if /= ivf)
170 ! integer :: i, j, i_f, j_f, i_c, j_c, i_dest
171 ! integer :: hnc, ix_offset(NDIM)
172 ! #if NDIM == 3
173 ! integer :: k, k_f, k_c
174 ! #endif
175 
176 ! hnc = ishft(box_c%n_cell, -1) ! n_cell / 2
177 ! ix_offset = af_get_child_offset(box_c)
178 
179 ! if (present(ivf_to)) then
180 ! i_dest = ivf_to
181 ! else
182 ! i_dest = ivf
183 ! end if
184 
185 ! if (box_p%coord_t == af_cyl) &
186 ! stop "restrict_box_face not implemented for cylindrical case"
187 
188 ! #if NDIM == 2
189 ! do j = 1, hnc
190 ! j_c = ix_offset(2) + j
191 ! j_f = 2 * j - 1
192 ! do i = 1, hnc
193 ! i_c = ix_offset(1) + i
194 ! i_f = 2 * i - 1
195 
196 ! box_p%fc(i_c, j_c, 1, i_dest) = 0.5_dp * &
197 ! sum(box_c%fc(i_f, j_f:j_f+1, 1, ivf))
198 ! if (i == hnc) then
199 ! box_p%fc(i_c+1, j_c, 1, i_dest) = 0.5_dp * &
200 ! sum(box_c%fc(i_f+2, j_f:j_f+1, 1, ivf))
201 ! end if
202 
203 ! box_p%fc(i_c, j_c, 2, i_dest) = 0.5_dp * &
204 ! sum(box_c%fc(i_f:i_f+1, j_f, 2, ivf))
205 ! if (j == hnc) then
206 ! box_p%fc(i_c, j_c+1, 2, i_dest) = 0.5_dp * &
207 ! sum(box_c%fc(i_f:i_f+1, j_f+2, 2, ivf))
208 ! end if
209 
210 ! end do
211 ! end do
212 ! #elif NDIM == 3
213 ! if (box_p%coord_t == af_cyl) &
214 ! stop "restrict_box_face not implemented for 3D case"
215 ! #endif
216 ! end subroutine af_restrict_box_face
217 
218 end module m_af_restrict
This module contains routines for restriction: going from fine to coarse variables.
This module contains the basic types and constants that are used in the NDIM-dimensional version of A...
Definition: m_af_types.f90:4
Type which stores all the boxes and levels, as well as some information about the number of boxes,...
Definition: m_af_types.f90:326
The basic building block of afivo: a box with cell-centered and face centered data,...
Definition: m_af_types.f90:286