MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
selectgrids.t
Go to the documentation of this file.
1 !=============================================================================
2 subroutine selectgrids
3 
4 use mod_forest
6 integer :: iigrid, igrid, jgrid, kgrid, isave, my_isafety
7 integer, allocatable, dimension(:,:) :: isafety
8 
9 ! Set the number of safety-blocks (additional blocks after
10 ! flag_grid_usr):
11 integer, parameter :: nsafety = 1
12 integer :: ixO^L, ipe
13 type(tree_node_ptr) :: tree
14 integer :: igrid_active, userflag
15 !-----------------------------------------------------------------------------
16 if (.not. allocated(isafety)) &
17  allocate(isafety(max_blocks,0:npe-1))
18 
19 ! reset all grids to active:
20 neighbor_active = .true.
21 
22  jgrid=0
23  kgrid=0
24  isafety = -1
25  userflag = -1
26 
27 ! Check the user flag:
28  do iigrid=1,igridstail; igrid=igrids(iigrid);
29  userflag = igrid_active(igrid)
30  if (userflag <= 0) then
31  jgrid=jgrid+1
32  igrids_active(jgrid)=igrid
33  else
34  kgrid=kgrid+1
35  igrids_passive(kgrid)=igrid
36  end if
37  isafety(igrid,mype) = userflag
38  end do
39 
40  igridstail_active = jgrid
41  igridstail_passive = kgrid
42 
43 ! Check if user wants to deactivate grids at all and return if not:
44  if (userflag == -1) return
45 
46 ! Got the passive grids.
47 ! Now, we re-activate a safety belt of radius nsafety blocks.
48 
49 ! First communicate the current isafety buffer:
50  call mpi_allgather(isafety(:,mype),max_blocks,mpi_integer,isafety,&
51  max_blocks,mpi_integer,icomm,ierrmpi)
52 
53 ! Now check the distance of neighbors to the active zone:
54  do isave = 1, nsafety
55  do iigrid=1,igridstail_passive; igrid=igrids_passive(iigrid);
56  if ( isafety(igrid,mype) /= isave) cycle
57 ! Get the minimum neighbor isafety:
58  if(min_isafety_neighbor(igrid) >= isafety(igrid,mype)) then
59 ! Increment the buffer:
60  isafety(igrid,mype)=isafety(igrid,mype)+1
61  end if
62  end do
63 
64 ! Communicate the incremented buffers:
65  call mpi_allgather(isafety(:,mype),max_blocks,mpi_integer,isafety,&
66  max_blocks,mpi_integer,icomm,ierrmpi)
67  end do
68 
69 ! Update the active and passive arrays:
70  jgrid=0
71  kgrid=0
72  do iigrid=1,igridstail; igrid=igrids(iigrid);
73  if (isafety(igrid,mype) <= nsafety) then
74  jgrid=jgrid+1
75  igrids_active(jgrid)=igrid
76  else
77  kgrid=kgrid+1
78  igrids_passive(kgrid)=igrid
79  end if
80 ! Create the neighbor flags:
81  call set_neighbor_state(igrid)
82  end do
83  igridstail_active = jgrid
84  igridstail_passive = kgrid
85 
86 ! Update the tree:
87  nleafs_active = 0
88  do ipe=0,npe-1
89  do igrid=1,max_blocks
90  if (isafety(igrid,ipe) == -1) cycle
91  if (.not.associated(igrid_to_node(igrid,ipe)%node)) cycle
92  tree%node => igrid_to_node(igrid,ipe)%node
93  if (isafety(igrid,ipe) > nsafety) then
94  tree%node%active=.false.
95  else
96  tree%node%active=.true.
98  end if
99  end do
100  end do
101 
102 ! Just for output and testing:
103 ! ixO^L=ixG^LL^LSUBnghostcells;
104 ! do iigrid=1,igridstail; igrid=igrids(iigrid);
105 ! ps(igrid)%w(ixO^S,flg_) = dble(isafety(igrid,mype))
106 ! ps(igrid)%w(ixO^S,cpu_) = dble(mype)
107 ! end do
108 
109  contains
110 !=============================================================================
111 subroutine set_neighbor_state(igrid)
112 
113 integer, intent(in) :: igrid
114 integer :: my_neighbor_type, i^D, isafety_neighbor
115 !-----------------------------------------------------------------------------
116 
117 
118  {do i^db=-1,1\}
119  if (i^d==0|.and.) then
120  if (isafety(igrid,mype) > nsafety) &
121  neighbor_active(i^d,igrid) = .false.
122  end if
123  my_neighbor_type=neighbor_type(i^d,igrid)
124 
125  select case (my_neighbor_type)
126  case (neighbor_boundary) ! boundary
127  isafety_neighbor = nsafety+1
128  case (neighbor_coarse) ! fine-coarse
129  isafety_neighbor = isafety_fc(i^d,igrid)
130  case (neighbor_sibling) ! same level
131  isafety_neighbor = isafety_srl(i^d,igrid)
132  case (neighbor_fine) ! coarse-fine
133  isafety_neighbor = isafety_cf_max(i^d,igrid)
134  end select
135 
136  if (isafety_neighbor > nsafety) &
137  neighbor_active(i^d,igrid) = .false.
138 
139  {end do\}
140 
141 end subroutine set_neighbor_state
142 !=============================================================================
143 integer function min_isafety_neighbor(igrid)
144 
145 integer, intent(in) :: igrid
146 integer :: my_neighbor_type, i^d
147 !-----------------------------------------------------------------------------
148 
149 min_isafety_neighbor = biginteger
150 
151  {do i^db=-1,1\}
152  if (i^d==0|.and.) cycle
153  my_neighbor_type=neighbor_type(i^d,igrid)
154 
155  select case (my_neighbor_type)
156  case (neighbor_coarse) ! fine-coarse
157  min_isafety_neighbor = min(isafety_fc(i^d,igrid),&
159  case (neighbor_sibling) ! same level
160  min_isafety_neighbor = min(isafety_srl(i^d,igrid),&
162  case (neighbor_fine) ! coarse-fine
163  min_isafety_neighbor = min(isafety_cf_min(i^d,igrid),&
165  end select
166 
167  {end do\}
168 
169 end function min_isafety_neighbor
170 !=============================================================================
171 integer function isafety_fc(i^D,igrid)
172 
173 integer, intent(in) :: i^d, igrid
174 integer :: ineighbor, ipe_neighbor
175 !-----------------------------------------------------------------------------
176 ineighbor=neighbor(1,i^d,igrid)
177 ipe_neighbor=neighbor(2,i^d,igrid)
178 
179  isafety_fc = isafety(ineighbor,ipe_neighbor)
180 
181 end function isafety_fc
182 !=============================================================================
183 integer function isafety_srl(i^D,igrid)
184 
185 integer, intent(in) :: i^d, igrid
186 integer :: ineighbor, ipe_neighbor
187 !-----------------------------------------------------------------------------
188 ineighbor=neighbor(1,i^d,igrid)
189 ipe_neighbor=neighbor(2,i^d,igrid)
190 
191  isafety_srl = isafety(ineighbor,ipe_neighbor)
192 
193 end function isafety_srl
194 !=============================================================================
195 integer function isafety_cf_min(i^D,igrid)
196 
197 integer, intent(in) :: i^d, igrid
198 integer :: ic^d, inc^d
199 integer :: ineighbor, ipe_neighbor
200 !-----------------------------------------------------------------------------
201 
202 isafety_cf_min = biginteger
203 
204  {do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
205  inc^db=2*i^db+ic^db
206  \}
207  ineighbor = neighbor_child(1,inc^d,igrid)
208  ipe_neighbor = neighbor_child(2,inc^d,igrid)
209 
210  isafety_cf_min = min(isafety_cf_min,isafety(ineighbor,ipe_neighbor))
211 
212  {end do\}
213 
214 end function isafety_cf_min
215 !=============================================================================
216 integer function isafety_cf_max(i^D,igrid)
217 
218 integer, intent(in) :: i^d, igrid
219 integer :: ic^d, inc^d
220 integer :: ineighbor, ipe_neighbor
221 !-----------------------------------------------------------------------------
222 
223 isafety_cf_max = - biginteger
224 
225  {do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
226  inc^db=2*i^db+ic^db
227  \}
228  ineighbor = neighbor_child(1,inc^d,igrid)
229  ipe_neighbor = neighbor_child(2,inc^d,igrid)
230 
231  isafety_cf_max = max(isafety_cf_max,isafety(ineighbor,ipe_neighbor))
232 
233  {end do\}
234 
235 end function isafety_cf_max
236 !=============================================================================
237 end subroutine selectgrids
238 !=============================================================================
239 
240 integer function igrid_active(igrid)
241  use mod_usr_methods, only: usr_flag_grid
243 
244  integer, intent(in) :: igrid
245  integer :: ixo^l, flag
246  !-----------------------------------------------------------------------------
247  ixo^l=ixg^ll^lsubnghostcells;
248 
249  igrid_active = -1
250 
251  if (associated(usr_flag_grid)) then
252  call usr_flag_grid(global_time,ixg^ll,ixo^l,ps(igrid)%w,ps(igrid)%x,igrid_active)
253  end if
254 
255 end function igrid_active
256 !=============================================================================
257 
Module with basic grid data structures.
Definition: mod_forest.t:2
integer nleafs_active
Definition: mod_forest.t:78
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
Definition: mod_forest.t:32
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision global_time
The global simulation time.
integer icomm
The MPI communicator.
integer mype
The rank of the current MPI task.
integer ierrmpi
A global MPI error return code.
integer npe
The number of MPI tasks.
integer max_blocks
The maximum number of grid blocks in a processor.
Module with all the methods that users can customize in AMRVAC.
procedure(flag_grid), pointer usr_flag_grid
integer function min_isafety_neighbor(igrid)
Definition: selectgrids.t:144
integer function igrid_active(igrid)
Definition: selectgrids.t:241
integer function isafety_cf_min(iD, igrid)
Definition: selectgrids.t:196
subroutine set_neighbor_state(igrid)
Definition: selectgrids.t:112
integer function isafety_cf_max(iD, igrid)
Definition: selectgrids.t:217
integer function isafety_srl(iD, igrid)
Definition: selectgrids.t:184
subroutine selectgrids
Definition: selectgrids.t:3
integer function isafety_fc(iD, igrid)
Definition: selectgrids.t:172
Pointer to a tree_node.
Definition: mod_forest.t:6