MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
boundary_conditions.t
Go to the documentation of this file.
1 !> fill ghost cells at a physical boundary
2 subroutine bc_phys(iside,idims,time,qdt,s,ixG^L,ixB^L)
4  use mod_bc_data, only: bc_data_set
6  use mod_physics
7  use mod_mhd_phys, only: get_divb
8 
9  integer, intent(in) :: iside, idims, ixG^L,ixB^L
10  double precision, intent(in) :: time,qdt
11  type(state), intent(inout) :: s
12  double precision :: wtmp(ixG^S,1:nwflux)
13 
14  integer :: idir, is
15  integer :: ixOs^L,hxO^L,jxO^L
16  double precision :: Q(ixG^S),Qp(ixG^S)
17  integer :: iw, iB, ix^D, ixO^L, ixM^L, nghostcellsi,iib^D
18  logical :: isphysbound
19 
20  associate(x=>s%x,w=>s%w,ws=>s%ws)
21  select case (idims)
22  {case (^d)
23  if (iside==2) then
24  ! maximal boundary
25  ib=2*^d
26  ixomin^dd=ixbmax^d+1-nghostcells^d%ixOmin^dd=ixbmin^dd;
27  ixomax^dd=ixbmax^dd;
28  ! cont/symm/asymm types
29  do iw=1,nwflux+nwaux
30  select case (typeboundary(iw,ib))
31  case (bc_special)
32  ! skip it here, do AFTER all normal type boundaries are set
33  case (bc_cont)
34  do ix^d=ixomin^d,ixomax^d
35  w(ix^d^d%ixO^s,iw) = w(ixomin^d-1^d%ixO^s,iw)
36  end do
37  case (bc_symm)
38  w(ixo^s,iw) = w(ixomin^d-1:ixomin^d-nghostcells:-1^d%ixO^s,iw)
39  case (bc_asymm)
40  w(ixo^s,iw) =-w(ixomin^d-1:ixomin^d-nghostcells:-1^d%ixO^s,iw)
41  case (bc_periodic)
42  ! skip it here, periodic bc info should come from neighbors
43  case(bc_noinflow)
44  if (iw==1+^d)then
45  do ix^d=ixomin^d,ixomax^d
46  w(ix^d^d%ixO^s,iw) = max(w(ixomin^d-1^d%ixO^s,iw),zero)
47  end do
48  else
49  do ix^d=ixomin^d,ixomax^d
50  w(ix^d^d%ixO^s,iw) = w(ixomin^d-1^d%ixO^s,iw)
51  end do
52  end if
53  case (bc_aperiodic)
54  !this just multiplies the variables with (-), they have been set from neighbors just like periodic.
55  w(ixo^s,iw) = - w(ixo^s,iw)
56  case (bc_data)
57  ! skip it here, do AFTER all normal type boundaries are set
58  case (bc_character)
59  ! skip it here, do AFTER all normal type boundaries are set
60  case default
61  write (unitterm,*) "Undefined boundarytype found in bc_phys", &
62  "for variable iw=",iw," and side iB=",ib
63  end select
64  end do
65  if(stagger_grid) then
66  do idir=1,nws
67  ! At this stage, extrapolation is applied only to the tangential components
68  if(idir==^d) cycle
69  ixosmax^dd=ixomax^dd;
70  ixosmin^dd=ixomin^dd-kr(^dd,idir);
71  select case(typeboundary(iw_mag(idir),ib))
72  case (bc_special)
73  ! skip it here, do AFTER all normal type boundaries are set
74  case (bc_cont)
75  do ix^d=ixosmin^d,ixosmax^d
76  ws(ix^d^d%ixOs^s,idir) = ws(ixosmin^d-1^d%ixOs^s,idir)
77  end do
78  case (bc_symm)
79  ws(ixos^s,idir) = ws(ixosmin^d-1:ixosmin^d-nghostcells:-1^d%ixOs^s,idir)
80  case (bc_asymm)
81  ws(ixos^s,idir) =-ws(ixosmin^d-1:ixosmin^d-nghostcells:-1^d%ixOs^s,idir)
82  case (bc_periodic)
83  case default
84  write (unitterm,*) "Undefined boundarytype found in bc_phys", &
85  "for variable iw=",iw," and side iB=",ib
86  end select
87  end do
88  ! Now that the tangential components are set,
89  ! fill the normal components using a prescription for the divergence.
90  ! This prescription is given by the typeB for the normal component.
91  do idir=1,nws
92  ! Consider only normal direction
93  if (idir/=^d) cycle
94  ixos^l=ixo^l;
95  select case(typeboundary(iw_mag(idir),ib))
96  case(bc_cont)
97  hxo^l=ixo^l-nghostcells*kr(^dd,^d);
98  ! Calculate divergence and partial divergence
99  call get_divb(s%w,ixg^l,hxo^l,q)
100  ws(ixos^s,idir)=zero
101  do ix^d=0,nghostcells-1
102  call get_divb(s%w,ixg^l,ixo^l,qp)
103  ws(ixosmin^d+ix^d^d%ixOs^s,idir)=&
104  (q(hxomax^d^d%hxO^s)*s%dvolume(hxomax^d^d%hxO^s)&
105  -qp(ixomin^d+ix^d^d%ixO^s)*s%dvolume(ixomin^d+ix^d^d%ixO^s))&
106  /s%surfaceC(ixosmin^d+ix^d^d%ixOs^s,^d)
107  end do
108  case(bc_symm)
109  ! (a)symmetric normal B ensures symmetric divB
110  ws(ixos^s,idir)= ws(ixosmin^d-2:ixosmin^d-nghostcells-1:-1^d%ixOs^s,idir)
111  case(bc_asymm)
112  ! (a)symmetric normal B ensures symmetric divB
113  ws(ixos^s,idir)=-ws(ixosmin^d-2:ixosmin^d-nghostcells-1:-1^d%ixOs^s,idir)
114  case(bc_periodic)
115  end select
116  end do
117  ! Fill cell averages
118  call phys_face_to_center(ixo^l,s)
119  end if
120  else
121  ! minimal boundary
122  ib=2*^d-1
123  ixomin^dd=ixbmin^dd;
124  ixomax^dd=ixbmin^d-1+nghostcells^d%ixOmax^dd=ixbmax^dd;
125  ! cont/symm/asymm types
126  do iw=1,nwflux+nwaux
127  select case (typeboundary(iw,ib))
128  case (bc_special)
129  ! skip it here, do AFTER all normal type boundaries are set
130  case (bc_cont)
131  do ix^d=ixomin^d,ixomax^d
132  w(ix^d^d%ixO^s,iw) = w(ixomax^d+1^d%ixO^s,iw)
133  end do
134  case (bc_symm)
135  w(ixo^s,iw) = w(ixomax^d+nghostcells:ixomax^d+1:-1^d%ixO^s,iw)
136  case (bc_asymm)
137  w(ixo^s,iw) =-w(ixomax^d+nghostcells:ixomax^d+1:-1^d%ixO^s,iw)
138  case (bc_periodic)
139  ! skip it here, periodic bc info should come from neighbors
140  case(bc_noinflow)
141  if (iw==1+^d)then
142  do ix^d=ixomin^d,ixomax^d
143  w(ix^d^d%ixO^s,iw) = min(w(ixomax^d+1^d%ixO^s,iw),zero)
144  end do
145  else
146  do ix^d=ixomin^d,ixomax^d
147  w(ix^d^d%ixO^s,iw) = w(ixomax^d+1^d%ixO^s,iw)
148  end do
149  end if
150  case (bc_aperiodic)
151  !this just multiplies the variables with (-), they have been set from neighbors just like periodic.
152  w(ixo^s,iw) = - w(ixo^s,iw)
153  case (bc_data)
154  ! skip it here, do AFTER all normal type boundaries are set
155  case (bc_character)
156  ! skip it here, do AFTER all normal type boundaries are set
157  case default
158  write (unitterm,*) "Undefined boundarytype found in bc_phys", &
159  "for variable iw=",iw," and side iB=",ib
160  end select
161  end do
162  if(stagger_grid) then
163  do idir=1,nws
164  ! At this stage, extrapolation is applied only to the tangential components
165  if(idir==^d) cycle
166  ixosmax^dd=ixomax^dd;
167  ixosmin^dd=ixomin^dd-kr(^dd,idir);
168  select case(typeboundary(iw_mag(idir),ib))
169  case (bc_special)
170  ! skip it here, periodic bc info should come from neighbors
171  case (bc_cont)
172  do ix^d=ixosmin^d,ixosmax^d
173  ws(ix^d^d%ixOs^s,idir) = ws(ixosmax^d+1^d%ixOs^s,idir)
174  end do
175  case (bc_symm)
176  ws(ixos^s,idir) = ws(ixosmax^d+nghostcells:ixosmax^d+1:-1^d%ixOs^s,idir)
177  case (bc_asymm)
178  ws(ixos^s,idir) =-ws(ixosmax^d+nghostcells:ixosmax^d+1:-1^d%ixOs^s,idir)
179  case (bc_periodic)
180  case default
181  write (unitterm,*) "Undefined boundarytype in bc_phys", &
182  "for variable iw=",iw," and side iB=",ib
183  end select
184  end do
185  ! Now that the tangential components are set,
186  ! fill the normal components using a prescription for the divergence.
187  ! This prescription is given by the typeB for the normal component.
188  do idir=1,nws
189  ! Consider only normal direction
190  if (idir/=^d) cycle
191  ixos^l=ixo^l-kr(^dd,^d);
192  select case(typeboundary(iw_mag(idir),ib))
193  case(bc_cont)
194  jxo^l=ixo^l+nghostcells*kr(^dd,^d);
195  ! Calculate divergence and partial divergence
196  call get_divb(s%w,ixg^l,jxo^l,q)
197  ws(ixos^s,idir)=zero
198  do ix^d=0,nghostcells-1
199  call get_divb(s%w,ixg^l,ixo^l,qp)
200  ws(ixosmax^d-ix^d^d%ixOs^s,idir)=&
201  -(q(jxomin^d^d%jxO^s)*s%dvolume(jxomin^d^d%jxO^s)&
202  -qp(ixomax^d-ix^d^d%ixO^s)*s%dvolume(ixomax^d-ix^d^d%ixO^s))&
203  /s%surfaceC(ixosmax^d-ix^d^d%ixOs^s,^d)
204  end do
205  case(bc_symm)
206  ! (a)symmetric normal B ensures symmetric divB
207  ws(ixos^s,idir)= ws(ixosmax^d+nghostcells+1:ixosmax^d+2:-1^d%ixOs^s,idir)
208  case(bc_asymm)
209  ! (a)symmetric normal B ensures symmetric divB
210  ws(ixos^s,idir)=-ws(ixosmax^d+nghostcells+1:ixosmax^d+2:-1^d%ixOs^s,idir)
211  case(bc_periodic)
212  end select
213  end do
214  ! Fill cell averages
215  call phys_face_to_center(ixo^l,s)
216  end if
217  end if \}
218  end select
219 
220  ! do user defined special boundary conditions
221  if (any(typeboundary(1:nwflux+nwaux,ib)==bc_special)) then
222  if (.not. associated(usr_special_bc)) &
223  call mpistop("usr_special_bc not defined")
224  call usr_special_bc(time,ixg^l,ixo^l,ib,w,x)
225  end if
226 
227  ! fill boundary conditions from external data vtk files
228  if (any(typeboundary(1:nwflux+nwaux,ib)==bc_data)) then
229  call bc_data_set(time,ixg^l,ixo^l,ib,w,x)
230  end if
231 
232  {#IFDEF EVOLVINGBOUNDARY
233  if (any(typeboundary(1:nwflux,ib)==bc_character)) then
234  ixm^l=ixm^ll;
235  if(ixgmax1==ixghi1) then
236  nghostcellsi=nghostcells
237  else
238  nghostcellsi=ceiling(nghostcells*0.5d0)
239  end if
240  select case (idims)
241  {case (^d)
242  if (iside==2) then
243  ! maximal boundary
244  ixomin^dd=ixgmax^d+1-nghostcellsi^d%ixOmin^dd=ixbmin^dd;
245  ixomax^dd=ixbmax^dd;
246  if(all(w(ixo^s,1:nwflux)==0.d0)) then
247  do ix^d=ixomin^d,ixomax^d
248  w(ix^d^d%ixO^s,1:nwflux) = w(ixomin^d-1^d%ixO^s,1:nwflux)
249  end do
250  end if
251  if(qdt>0.d0.and.ixgmax^d==ixghi^d) then
252  ixomin^dd=ixomin^d^d%ixOmin^dd=ixmmin^dd;
253  ixomax^dd=ixomax^d^d%ixOmax^dd=ixmmax^dd;
254  wtmp(ixg^s,1:nw)=pso(block%igrid)%w(ixg^s,1:nw)
255  call characteristic_project(idims,iside,ixg^l,ixo^l,wtmp,x,dxlevel,qdt)
256  w(ixo^s,1:nwflux)=wtmp(ixo^s,1:nwflux)
257  end if
258  else
259  ! minimal boundary
260  ixomin^dd=ixbmin^dd;
261  ixomax^dd=ixgmin^d-1+nghostcellsi^d%ixOmax^dd=ixbmax^dd;
262  if(all(w(ixo^s,1:nwflux)==0.d0)) then
263  do ix^d=ixomin^d,ixomax^d
264  w(ix^d^d%ixO^s,1:nwflux) = w(ixomax^d+1^d%ixO^s,1:nwflux)
265  end do
266  end if
267  if(qdt>0.d0.and.ixgmax^d==ixghi^d) then
268  ixomin^dd=ixomin^d^d%ixOmin^dd=ixmmin^dd;
269  ixomax^dd=ixomax^d^d%ixOmax^dd=ixmmax^dd;
270  wtmp(ixg^s,1:nw)=pso(block%igrid)%w(ixg^s,1:nw)
271  call characteristic_project(idims,iside,ixg^l,ixo^l,wtmp,x,dxlevel,qdt)
272  w(ixo^s,1:nwflux)=wtmp(ixo^s,1:nwflux)
273  end if
274  end if \}
275  end select
276  if(ixgmax1==ixghi1) then
277  call identifyphysbound(block%igrid,isphysbound,iib^d)
278  if(iib1==-1.and.iib2==-1) then
279  do ix2=nghostcells,1,-1
280  do ix1=nghostcells,1,-1
281  w(ix^d,1:nwflux)=(w(ix1+1,ix2+1,1:nwflux)+w(ix1+1,ix2,1:nwflux)+w(ix1,ix2+1,1:nwflux))/3.d0
282  end do
283  end do
284  end if
285  if(iib1== 1.and.iib2==-1) then
286  do ix2=nghostcells,1,-1
287  do ix1=ixmmax1+1,ixgmax1
288  w(ix^d,1:nwflux)=(w(ix1-1,ix2+1,1:nwflux)+w(ix1-1,ix2,1:nwflux)+w(ix1,ix2+1,1:nwflux))/3.d0
289  end do
290  end do
291  end if
292  if(iib1==-1.and.iib2== 1) then
293  do ix2=ixmmax2+1,ixgmax2
294  do ix1=nghostcells,1,-1
295  w(ix^d,1:nwflux)=(w(ix1+1,ix2-1,1:nwflux)+w(ix1+1,ix2,1:nwflux)+w(ix1,ix2-1,1:nwflux))/3.d0
296  end do
297  end do
298  end if
299  if(iib1== 1.and.iib2== 1) then
300  do ix2=ixmmax2+1,ixgmax2
301  do ix1=ixmmax1+1,ixgmax1
302  w(ix^d,1:nwflux)=(w(ix1-1,ix2-1,1:nwflux)+w(ix1-1,ix2,1:nwflux)+w(ix1,ix2-1,1:nwflux))/3.d0
303  end do
304  end do
305  end if
306  end if
307  end if
308  }
309  !end do
310 
311  end associate
312 end subroutine bc_phys
313 
314 !> fill inner boundary values
315 subroutine getintbc(time,ixG^L)
318 
319  double precision, intent(in) :: time
320  integer, intent(in) :: ixG^L
321 
322  integer :: iigrid, igrid, ixO^L
323 
324  ixo^l=ixg^l^lsubnghostcells;
325 
326  !$OMP PARALLEL DO SCHEDULE(dynamic) PRIVATE(igrid)
327  do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
328  block=>ps(igrid)
329  ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
330 
331  if (associated(usr_internal_bc)) then
332  call usr_internal_bc(node(plevel_,igrid),time,ixg^l,ixo^l,ps(igrid)%w,ps(igrid)%x)
333  end if
334  end do
335  !$OMP END PARALLEL DO
336 
337 end subroutine getintbc
subroutine bc_phys(iside, idims, time, qdt, s, ixGL, ixBL)
fill ghost cells at a physical boundary
subroutine getintbc(time, ixGL)
fill inner boundary values
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
Definition: comm_lib.t:194
Module to set boundary conditions from user data.
Definition: mod_bc_data.t:2
subroutine, public bc_data_set(qt, ixIL, ixOL, iB, w, x)
Set boundary conditions according to user data.
Definition: mod_bc_data.t:140
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
integer, parameter bc_noinflow
integer ixghi
Upper index of grid block arrays.
integer, parameter bc_asymm
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer, parameter bc_character
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
logical stagger_grid
True for using stagger grid.
integer, parameter bc_data
integer, parameter plevel_
integer, dimension(:), allocatable, parameter d
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
integer, parameter unitterm
Unit for standard output.
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
integer, parameter bc_cont
integer nghostcells
Number of ghost cells surrounding a grid.
integer, parameter bc_symm
integer, parameter bc_aperiodic
integer, dimension(:,:), allocatable node
double precision, dimension(ndim) dxlevel
Magneto-hydrodynamics module.
Definition: mod_mhd_phys.t:2
subroutine, public get_divb(w, ixIL, ixOL, divb, fourthorder)
Calculate div B within ixO.
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition: mod_physics.t:4
procedure(sub_face_to_center), pointer phys_face_to_center
Definition: mod_physics.t:84
Module with all the methods that users can customize in AMRVAC.
procedure(special_bc), pointer usr_special_bc
procedure(internal_bc), pointer usr_internal_bc