Afivo  0.3
m_a2_restrict.f90
1 
5 
6  use m_a2_types
7 
8  implicit none
9  private
10 
11  public :: a2_restrict_to_box
12  public :: a2_restrict_to_boxes
13  public :: a2_restrict_tree
14  public :: a2_restrict_box
15  ! public :: a2_restrict_box_face
16 
17 contains
18 
21  subroutine a2_restrict_to_box(boxes, id, iv, iv_to)
22  type(box2_t), intent(inout) :: boxes(:)
23  integer, intent(in) :: id
24  integer, intent(in) :: iv
25  integer, intent(in), optional :: iv_to
26  integer :: nc, i_c, c_id
27 
28  nc = boxes(id)%n_cell
29  do i_c = 1, a2_num_children
30  c_id = boxes(id)%children(i_c)
31  if (c_id == af_no_box) cycle
32  call a2_restrict_box(boxes(c_id), boxes(id), iv, iv_to)
33  end do
34  end subroutine a2_restrict_to_box
35 
37  subroutine a2_restrict_to_boxes(boxes, ids, iv, iv_to)
38  type(box2_t), intent(inout) :: boxes(:)
39  integer, intent(in) :: ids(:)
40  integer, intent(in) :: iv
41  integer, intent(in), optional :: iv_to
42  integer :: i
43 
44  !$omp parallel do
45  do i = 1, size(ids)
46  call a2_restrict_to_box(boxes, ids(i), iv, iv_to)
47  end do
48  !$omp end parallel do
49  end subroutine a2_restrict_to_boxes
50 
52  subroutine a2_restrict_tree(tree, iv, iv_to)
53  type(a2_t), intent(inout) :: tree
54  integer, intent(in) :: iv
55  integer, intent(in), optional :: iv_to
56  integer :: lvl
57 
58  if (.not. tree%ready) stop "Tree not ready"
59  do lvl = tree%highest_lvl-1, lbound(tree%lvls, 1), -1
60  call a2_restrict_to_boxes(tree%boxes, tree%lvls(lvl)%parents, iv, iv_to)
61  end do
62  end subroutine a2_restrict_tree
63 
65  subroutine a2_restrict_box(box_c, box_p, iv, iv_to, use_geometry)
66  type(box2_t), intent(in) :: box_c
67  type(box2_t), intent(inout) :: box_p
68  integer, intent(in) :: iv
69  integer, intent(in), optional :: iv_to
70  logical, intent(in), optional :: use_geometry
71  integer :: i, j, i_f, j_f, i_c, j_c, i_dest
72  integer :: hnc, ix_offset(2)
73  logical :: use_geom
74  real(dp) :: w1, w2
75 
76  hnc = ishft(box_c%n_cell, -1) ! n_cell / 2
77  ix_offset = a2_get_child_offset(box_c)
78 
79  if (present(iv_to)) then
80  i_dest = iv_to
81  else
82  i_dest = iv
83  end if
84 
85  if (present(use_geometry)) then
86  use_geom = use_geometry
87  else
88  use_geom = .true.
89  end if
90 
91  if (box_p%coord_t == af_cyl .and. use_geom) then
92  do j = 1, hnc
93  j_c = ix_offset(2) + j
94  j_f = 2 * j - 1
95  do i = 1, hnc
96  i_c = ix_offset(1) + i
97  i_f = 2 * i - 1
98 
99  call a2_cyl_child_weights(box_p, i, w1, w2)
100  box_p%cc(i_c, j_c, i_dest) = 0.25_dp * (&
101  w1 * sum(box_c%cc(i_f, j_f:j_f+1, iv)) + &
102  w2 * sum(box_c%cc(i_f+1, j_f:j_f+1, iv)))
103  end do
104  end do
105  else
106  do j = 1, hnc
107  j_c = ix_offset(2) + j
108  j_f = 2 * j - 1
109  do i = 1, hnc
110  i_c = ix_offset(1) + i
111  i_f = 2 * i - 1
112  box_p%cc(i_c, j_c, i_dest) = 0.25_dp * &
113  sum(box_c%cc(i_f:i_f+1, j_f:j_f+1, iv))
114  end do
115  end do
116  endif
117  end subroutine a2_restrict_box
118 
119 ! !> Restriction of face-centered variables from child to parent
120 ! subroutine a2_restrict_box_face(box_c, box_p, ivf, ivf_to)
121 ! type(box2_t), intent(in) :: box_c !< Child box to restrict
122 ! type(box2_t), intent(inout) :: box_p !< Parent box to restrict to
123 ! integer, intent(in) :: ivf !< Face-variable to restrict
124 ! integer, intent(in), optional :: ivf_to !< Destination (if /= ivf)
125 ! integer :: i, j, i_f, j_f, i_c, j_c, i_dest
126 ! integer :: hnc, ix_offset(2)
127 ! #if 2 == 3
128 ! integer :: k, k_f, k_c
129 ! #endif
130 
131 ! hnc = ishft(box_c%n_cell, -1) ! n_cell / 2
132 ! ix_offset = a2_get_child_offset(box_c)
133 
134 ! if (present(ivf_to)) then
135 ! i_dest = ivf_to
136 ! else
137 ! i_dest = ivf
138 ! end if
139 
140 ! if (box_p%coord_t == af_cyl) &
141 ! stop "restrict_box_face not implemented for cylindrical case"
142 
143 ! #if 2 == 2
144 ! do j = 1, hnc
145 ! j_c = ix_offset(2) + j
146 ! j_f = 2 * j - 1
147 ! do i = 1, hnc
148 ! i_c = ix_offset(1) + i
149 ! i_f = 2 * i - 1
150 
151 ! box_p%fc(i_c, j_c, 1, i_dest) = 0.5_dp * &
152 ! sum(box_c%fc(i_f, j_f:j_f+1, 1, ivf))
153 ! if (i == hnc) then
154 ! box_p%fc(i_c+1, j_c, 1, i_dest) = 0.5_dp * &
155 ! sum(box_c%fc(i_f+2, j_f:j_f+1, 1, ivf))
156 ! end if
157 
158 ! box_p%fc(i_c, j_c, 2, i_dest) = 0.5_dp * &
159 ! sum(box_c%fc(i_f:i_f+1, j_f, 2, ivf))
160 ! if (j == hnc) then
161 ! box_p%fc(i_c, j_c+1, 2, i_dest) = 0.5_dp * &
162 ! sum(box_c%fc(i_f:i_f+1, j_f+2, 2, ivf))
163 ! end if
164 
165 ! end do
166 ! end do
167 ! #elif 2 == 3
168 ! if (box_p%coord_t == af_cyl) &
169 ! stop "restrict_box_face not implemented for 3D case"
170 ! #endif
171 ! end subroutine a2_restrict_box_face
172 
173 end module m_a2_restrict
Type which stores all the boxes and levels, as well as some information about the number of boxes...
Definition: m_a2_types.f90:93
This module contains the basic types and constants that are used in the 2-dimensional version of Afiv...
Definition: m_a2_types.f90:5
This module contains routines for restriction: going from fine to coarse variables.
The basic building block of afivo: a box with cell-centered and face centered data, and information about its position, neighbors, children etc.
Definition: m_a2_types.f90:71