MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_boundary_conditions.t
Go to the documentation of this file.
2
3 implicit none
4 private
5
6 public :: bc_phys
7 public :: getintbc
8
9contains
10
11 !> fill ghost cells at a physical boundary
12 subroutine bc_phys(iside,idims,time,qdt,s,ixG^L,ixB^L)
14 use mod_bc_data, only: bc_data_set
16 use mod_physics
18 use mod_comm_lib, only: mpistop
19
20 integer, intent(in) :: iside, idims, ixg^l,ixb^l
21 double precision, intent(in) :: time,qdt
22 type(state), intent(inout) :: s
23
24 double precision :: q(ixg^s),qp(ixg^s)
25 integer :: idir, ixos^l,hxo^l,jxo^l
26 integer :: iw, ib, ix^d, ixo^l
27
28 associate(x=>s%x,w=>s%w,ws=>s%ws)
29 select case (idims)
30 {case (^d)
31 if (iside==2) then
32 ! maximal boundary
33 ib=2*^d
34 ixomin^dd=ixbmax^d+1-nghostcells^d%ixOmin^dd=ixbmin^dd;
35 ixomax^dd=ixbmax^dd;
36 ! cont/symm/asymm types
37 do iw=1,nwflux+nwaux
38 select case (typeboundary(iw,ib))
39 case (bc_special)
40 ! skip it here, do AFTER all normal type boundaries are set
41 case (bc_cont)
42 do ix^d=ixomin^d,ixomax^d
43 w(ix^d^d%ixO^s,iw) = w(ixomin^d-1^d%ixO^s,iw)
44 end do
45 case (bc_symm)
46 w(ixo^s,iw) = w(ixomin^d-1:ixomin^d-nghostcells:-1^d%ixO^s,iw)
47 case (bc_asymm)
48 w(ixo^s,iw) =-w(ixomin^d-1:ixomin^d-nghostcells:-1^d%ixO^s,iw)
49 case (bc_periodic)
50 ! skip it here, periodic bc info should come from neighbors
51 case(bc_noinflow)
52 if (iw==1+^d)then
53 do ix^d=ixomin^d,ixomax^d
54 w(ix^d^d%ixO^s,iw) = max(w(ixomin^d-1^d%ixO^s,iw),zero)
55 end do
56 else
57 do ix^d=ixomin^d,ixomax^d
58 w(ix^d^d%ixO^s,iw) = w(ixomin^d-1^d%ixO^s,iw)
59 end do
60 end if
61 case (bc_aperiodic)
62 !this just multiplies the variables with (-), they have been set from neighbors just like periodic.
63 w(ixo^s,iw) = - w(ixo^s,iw)
64 case (bc_data)
65 ! skip it here, do AFTER all normal type boundaries are set
66 case (bc_icarus)
67 ! skip it here, do AFTER all normal type boundaries are set
68 case (bc_character)
69 ! skip it here, do AFTER all normal type boundaries are set
70 case default
71 write (unitterm,*) "Undefined boundarytype found in bc_phys", &
72 "for variable iw=",iw," and side iB=",ib
73 end select
74 end do
75 if(stagger_grid) then
76 do idir=1,nws
77 ! At this stage, extrapolation is applied only to the tangential components
78 if(idir==^d) cycle
79 ixosmax^dd=ixomax^dd;
80 ixosmin^dd=ixomin^dd-kr(^dd,idir);
81 select case(typeboundary(iw_mag(idir),ib))
82 case (bc_special)
83 ! skip it here, do AFTER all normal type boundaries are set
84 case (bc_cont)
85 do ix^d=ixosmin^d,ixosmax^d
86 ws(ix^d^d%ixOs^s,idir) = ws(ixosmin^d-1^d%ixOs^s,idir)
87 end do
88 case (bc_symm)
89 ws(ixos^s,idir) = ws(ixosmin^d-1:ixosmin^d-nghostcells:-1^d%ixOs^s,idir)
90 case (bc_asymm)
91 ws(ixos^s,idir) =-ws(ixosmin^d-1:ixosmin^d-nghostcells:-1^d%ixOs^s,idir)
92 case (bc_periodic)
93 case default
94 write (unitterm,*) "Undefined boundarytype found in bc_phys", &
95 "for variable iw=",iw," and side iB=",ib
96 end select
97 end do
98 ! Now that the tangential components are set,
99 ! fill the normal components using a prescription for the divergence.
100 ! This prescription is given by the typeB for the normal component.
101 do idir=1,nws
102 ! Consider only normal direction
103 if (idir/=^d) cycle
104 ixos^l=ixo^l;
105 select case(typeboundary(iw_mag(idir),ib))
106 case(bc_cont)
107 hxo^l=ixo^l-nghostcells*kr(^dd,^d);
108 ! Calculate divergence and partial divergence
109 call get_divb(s%w,ixg^l,hxo^l,q)
110 ws(ixos^s,idir)=zero
111 do ix^d=0,nghostcells-1
112 call get_divb(s%w,ixg^l,ixo^l,qp)
113 ws(ixosmin^d+ix^d^d%ixOs^s,idir)=&
114 (q(hxomax^d^d%hxO^s)*s%dvolume(hxomax^d^d%hxO^s)&
115 -qp(ixomin^d+ix^d^d%ixO^s)*s%dvolume(ixomin^d+ix^d^d%ixO^s))&
116 /s%surfaceC(ixosmin^d+ix^d^d%ixOs^s,^d)
117 end do
118 ! Fill cell averages
119 call phys_face_to_center(ixo^l,s)
120 case(bc_symm)
121 ! (a)symmetric normal B ensures symmetric divB
122 ws(ixos^s,idir)= ws(ixosmin^d-2:ixosmin^d-nghostcells-1:-1^d%ixOs^s,idir)
123 ! Fill cell averages
124 call phys_face_to_center(ixo^l,s)
125 case(bc_asymm)
126 ! (a)symmetric normal B ensures symmetric divB
127 ws(ixos^s,idir)=-ws(ixosmin^d-2:ixosmin^d-nghostcells-1:-1^d%ixOs^s,idir)
128 ! Fill cell averages
129 call phys_face_to_center(ixo^l,s)
130 case(bc_periodic)
131 ! Fill cell averages
132 call phys_face_to_center(ixo^l,s)
133 end select
134 end do
135 end if
136 else
137 ! minimal boundary
138 ib=2*^d-1
139 ixomin^dd=ixbmin^dd;
140 ixomax^dd=ixbmin^d-1+nghostcells^d%ixOmax^dd=ixbmax^dd;
141 ! cont/symm/asymm types
142 do iw=1,nwflux+nwaux
143 select case (typeboundary(iw,ib))
144 case (bc_special)
145 ! skip it here, do AFTER all normal type boundaries are set
146 case (bc_cont)
147 do ix^d=ixomin^d,ixomax^d
148 w(ix^d^d%ixO^s,iw) = w(ixomax^d+1^d%ixO^s,iw)
149 end do
150 case (bc_symm)
151 w(ixo^s,iw) = w(ixomax^d+nghostcells:ixomax^d+1:-1^d%ixO^s,iw)
152 case (bc_asymm)
153 w(ixo^s,iw) =-w(ixomax^d+nghostcells:ixomax^d+1:-1^d%ixO^s,iw)
154 case (bc_periodic)
155 ! skip it here, periodic bc info should come from neighbors
156 case(bc_noinflow)
157 if (iw==1+^d)then
158 do ix^d=ixomin^d,ixomax^d
159 w(ix^d^d%ixO^s,iw) = min(w(ixomax^d+1^d%ixO^s,iw),zero)
160 end do
161 else
162 do ix^d=ixomin^d,ixomax^d
163 w(ix^d^d%ixO^s,iw) = w(ixomax^d+1^d%ixO^s,iw)
164 end do
165 end if
166 case (bc_aperiodic)
167 !this just multiplies the variables with (-), they have been set from neighbors just like periodic.
168 w(ixo^s,iw) = - w(ixo^s,iw)
169 case (bc_data)
170 ! skip it here, do AFTER all normal type boundaries are set
171 case (bc_icarus)
172 ! skip it here, do AFTER all normal type boundaries are set
173 case (bc_character)
174 ! skip it here, do AFTER all normal type boundaries are set
175 case default
176 write (unitterm,*) "Undefined boundarytype found in bc_phys", &
177 "for variable iw=",iw," and side iB=",ib
178 end select
179 end do
180 if(stagger_grid) then
181 do idir=1,nws
182 ! At this stage, extrapolation is applied only to the tangential components
183 if(idir==^d) cycle
184 ixosmax^dd=ixomax^dd;
185 ixosmin^dd=ixomin^dd-kr(^dd,idir);
186 select case(typeboundary(iw_mag(idir),ib))
187 case (bc_special)
188 ! skip it here, periodic bc info should come from neighbors
189 case (bc_cont)
190 do ix^d=ixosmin^d,ixosmax^d
191 ws(ix^d^d%ixOs^s,idir) = ws(ixosmax^d+1^d%ixOs^s,idir)
192 end do
193 case (bc_symm)
194 ws(ixos^s,idir) = ws(ixosmax^d+nghostcells:ixosmax^d+1:-1^d%ixOs^s,idir)
195 case (bc_asymm)
196 ws(ixos^s,idir) =-ws(ixosmax^d+nghostcells:ixosmax^d+1:-1^d%ixOs^s,idir)
197 case (bc_periodic)
198 case default
199 write (unitterm,*) "Undefined boundarytype in bc_phys", &
200 "for variable iw=",iw," and side iB=",ib
201 end select
202 end do
203 ! Now that the tangential components are set,
204 ! fill the normal components using a prescription for the divergence.
205 ! This prescription is given by the typeB for the normal component.
206 do idir=1,nws
207 ! Consider only normal direction
208 if (idir/=^d) cycle
209 ixos^l=ixo^l-kr(^dd,^d);
210 select case(typeboundary(iw_mag(idir),ib))
211 case(bc_cont)
212 jxo^l=ixo^l+nghostcells*kr(^dd,^d);
213 ! Calculate divergence and partial divergence
214 call get_divb(s%w,ixg^l,jxo^l,q)
215 ws(ixos^s,idir)=zero
216 do ix^d=0,nghostcells-1
217 call get_divb(s%w,ixg^l,ixo^l,qp)
218 ws(ixosmax^d-ix^d^d%ixOs^s,idir)=&
219 -(q(jxomin^d^d%jxO^s)*s%dvolume(jxomin^d^d%jxO^s)&
220 -qp(ixomax^d-ix^d^d%ixO^s)*s%dvolume(ixomax^d-ix^d^d%ixO^s))&
221 /s%surfaceC(ixosmax^d-ix^d^d%ixOs^s,^d)
222 end do
223 ! Fill cell averages
224 call phys_face_to_center(ixo^l,s)
225 case(bc_symm)
226 ! (a)symmetric normal B ensures symmetric divB
227 ws(ixos^s,idir)= ws(ixosmax^d+nghostcells+1:ixosmax^d+2:-1^d%ixOs^s,idir)
228 ! Fill cell averages
229 call phys_face_to_center(ixo^l,s)
230 case(bc_asymm)
231 ! (a)symmetric normal B ensures symmetric divB
232 ws(ixos^s,idir)=-ws(ixosmax^d+nghostcells+1:ixosmax^d+2:-1^d%ixOs^s,idir)
233 ! Fill cell averages
234 call phys_face_to_center(ixo^l,s)
235 case(bc_periodic)
236 ! Fill cell averages
237 call phys_face_to_center(ixo^l,s)
238 end select
239 end do
240 end if
241 end if \}
242 end select
243
244 ! do user defined special boundary conditions
245 if (any(typeboundary(1:nwflux+nwaux,ib)==bc_special)) then
246 if (.not. associated(usr_special_bc)) &
247 call mpistop("usr_special_bc not defined")
248 call usr_special_bc(time,ixg^l,ixo^l,ib,w,x)
249 end if
250
251 ! fill boundary conditions from external data vtk files
252 if (any(typeboundary(1:nwflux+nwaux,ib)==bc_data)) then
253 call bc_data_set(time,ixg^l,ixo^l,ib,w,x)
254 end if
255
256 ! fill boundary conditions from external data vtk files and do user defined special boundary conditions
257 if (any(typeboundary(1:nwflux+nwaux,ib)==bc_icarus)) then
258 call bc_data_set(time,ixg^l,ixo^l,ib,w,x)
259 if (.not. associated(usr_special_bc)) &
260 call mpistop("usr_special_bc not defined")
261 call usr_special_bc(time,ixg^l,ixo^l,ib,w,x)
262 end if
263
264 end associate
265 end subroutine bc_phys
266
267 !> fill inner boundary values
268 subroutine getintbc(time,ixG^L)
271
272 double precision, intent(in) :: time
273 integer, intent(in) :: ixg^l
274
275 integer :: iigrid, igrid, ixo^l
276
277 ixo^l=ixg^l^lsubnghostcells;
278
279 !$OMP PARALLEL DO SCHEDULE(dynamic) PRIVATE(igrid)
280 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
281 block=>ps(igrid)
282 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
283
284 if (associated(usr_internal_bc)) then
285 call usr_internal_bc(node(plevel_,igrid),time,ixg^l,ixo^l,ps(igrid)%w,ps(igrid)%x)
286 end if
287 end do
288 !$OMP END PARALLEL DO
289
290 end subroutine getintbc
291
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.
subroutine, public getintbc(time, ixgl)
fill inner boundary values
subroutine, public bc_phys(iside, idims, time, qdt, s, ixgl, ixbl)
fill ghost cells at a physical boundary
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
subroutine, public get_divb(w, ixil, ixol, divb, nth_in)
Calculate div B within ixO.
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, 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.
double precision, 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 nghostcells
Number of ghost cells surrounding a grid.
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
integer, parameter bc_aperiodic
integer, dimension(:,:), allocatable node
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:81
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