|
bc2amr.f90.html |
|
|
Source file: bc2amr.f90
|
|
Directory: /Users/rjl/clawpack_src/clawpack_master/amrclaw/examples/advection_2d_inflow
|
|
Converted: Mon Feb 19 2024 at 17:58:02
using clawcode2html
|
|
This documentation file will
not reflect any later changes in the source file.
|
! :::::::::: bc2amr ::::::::::::::::::::::::::::::::::::::::::::::;
!> \callgraph
!! \callergraph
!! Take a grid patch with mesh widths **hx**,**hy**, of dimensions **nrow** by
!! **ncol**, and set the values of any piece of
!! of the patch which extends outside the physical domain
!! using the boundary conditions.
!!
!! ### Standard boundary condition choices for amr2ez in clawpack
!!
!! At each boundary k = 1 (left), 2 (right), 3 (bottom), 4 (top):
!!
!! mthbc(k) =
!! * 0 for user-supplied BC's (must be inserted!)
!! * 1 for zero-order extrapolation
!! * 2 for periodic boundary conditions
!! * 3 for solid walls, assuming this can be implemented
!! by reflecting the data about the boundary and then
!! negating the 2'nd (for k=1,2) or 3'rd (for k=3,4)
!! component of q.
!! * 4 for sphere bcs (left half maps to right half of same side, and vice versa), as if domain folded in half
!!
!! The corners of the grid patch are at
!! (xlo_patch,ylo_patch) -- lower left corner
!! (xhi_patch,yhi_patch) -- upper right corner
!!
!! The physical domain itself is a rectangle bounded by
!! (xlower,ylower) -- lower left corner
!! (xupper,yupper) -- upper right corner
!!
! This figure below does not work with doxygen
! the picture is the following:
! ____________________________________________________
!
! _____________________ (xupper,yupper)
! | |
! ____|____ (xhi_patch,yhi_patch)
! | | | |
! | | | |
! | | | |
! |___|____| |
! (xlo_patch,ylo_patch) | |
! | |
! |_____________________|
! (xlower,ylower)
! ____________________________________________________
!!
!!
!> Any cells that lie outside the physical domain are ghost cells whose
!! values should be set in this routine. This is tested for by comparing
!! xlo_patch with xlower to see if values need to be set at the left
! as in the figure above,
!
!> and similarly at the other boundaries.
!! Patches are guaranteed to have at least 1 row of cells filled
!! with interior values so it is possible to extrapolate.
!! Fix [trimbd()](@ref trimbd) if you want more than 1 row pre-set.
!!
!! Make sure the order the boundaries are specified is correct
!! so that diagonal corner cells are also properly taken care of.
!!
!! Periodic boundaries are set before calling this routine, so if the
!! domain is periodic in one direction only you
!! can safely extrapolate in the other direction.
!!
!! Don't overwrite ghost cells in periodic directions!
!!
!! \param val data array for solution \f$q \f$ (cover the whole grid **msrc**)
!! \param aux data array for auxiliary variables
!! \param nrow number of cells in *i* direction on this grid
!! \param ncol number of cells in *j* direction on this grid
!! \param meqn number of equations for the system
!! \param naux number of auxiliary variables
!! \param hx spacing (mesh size) in *i* direction
!! \param hy spacing (mesh size) in *j* direction
!! \param level AMR level of this grid
!! \param time setting ghost cell values at time **time**
!! \param xlo_patch left bound of the input grid
!! \param xhi_patch right bound of the input grid
!! \param ylo_patch lower bound of the input grid
!! \param yhi_patch upper bound of the input grid
! ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
subroutine bc2amr(val,aux,nrow,ncol,meqn,naux, hx, hy, level, time, &
xlo_patch, xhi_patch, ylo_patch, yhi_patch)
use amr_module, only: mthbc, xlower, ylower, xupper, yupper
use amr_module, only: xperdom, yperdom, spheredom
implicit none
! Input/Output
integer, intent(in) :: nrow, ncol, meqn, naux, level
real(kind=8), intent(in) :: hx, hy, time
real(kind=8), intent(in) :: xlo_patch, xhi_patch
real(kind=8), intent(in) :: ylo_patch, yhi_patch
real(kind=8), intent(in out) :: val(meqn, nrow, ncol)
real(kind=8), intent(in out) :: aux(naux, nrow, ncol)
! Local storag
integer :: i, j, ibeg, jbeg, nxl, nxr, nyb, nyt
real(kind=8) :: hxmarg, hymarg
! Inflow boundary condition variables
real(kind=8) :: x, y, tau, x0, y0
! True solution for BCs
interface
real(kind=8) pure function qtrue(x, y ,t)
implicit none
real(kind=8), intent(in) :: x, y ,t
end function qtrue
end interface
! Common block parameters
real(kind=8) :: ubar, vbar
common /cparam/ ubar, vbar
hxmarg = hx * .01d0
hymarg = hy * .01d0
! Use periodic boundary condition specialized code only, if only one
! boundary is periodic we still proceed below
if (xperdom .and. (yperdom .or. spheredom)) then
return
end if
! Each check has an initial check to ensure that the boundary is a real
! boundary condition and otherwise skips the code. Otherwise
!-------------------------------------------------------
! Left boundary:
!-------------------------------------------------------
if (xlo_patch < xlower-hxmarg) then
! number of grid cells from this patch lying outside physical domain:
nxl = int((xlower + hxmarg - xlo_patch) / hx)
select case(mthbc(1))
case(0) ! User defined boundary condition
! Inflow boundary condition
if (ubar < 0.1d0 * vbar) then
stop "Inflow BCs at left boundary assume ubar >= vbar / 10"
end if
do j = 1, ncol
y = ylo_patch + (j - 0.5d0) * hy
if (nxl >= 1) then
! First ghost cell
tau = hx / (2.d0 * ubar)
val(1,nxl,j) = qtrue(0.d0, y + vbar * tau, time + tau)
end if
if (nxl == 2) then
! second ghost cell:
tau = 3.d0 * hx / (2.d0 * ubar)
val(1,1,j) = qtrue(0.d0, y + vbar * tau, time + tau)
end if
end do
case(1) ! Zero-order extrapolation
do j = 1, ncol
do i=1, nxl
val(:, i, j) = val(:, nxl + 1, j)
end do
end do
case(2) ! Periodic boundary condition
continue
case(3) ! Wall boundary conditions
do j = 1, ncol
do i=1, nxl
val(:, i, j) = val(:, 2 * nxl + 1 - i, j)
end do
end do
! negate the normal velocity:
do j = 1, ncol
do i=1, nxl
val(2, i, j) = -val(2, i, j)
end do
end do
case(4) ! Spherical domain
continue
case default
print *, "Invalid boundary condition requested."
stop
end select
end if
!-------------------------------------------------------
! Right boundary:
!-------------------------------------------------------
if (xhi_patch > xupper+hxmarg) then
! number of grid cells lying outside physical domain:
nxr = int((xhi_patch - xupper + hxmarg) / hx)
ibeg = max(nrow - nxr + 1, 1)
select case(mthbc(2))
case(0) ! User defined boundary condition
! Replace this code with a user defined boundary condition
stop "A user defined boundary condition was not provided."
case(1) ! Zero-order extrapolation
do i = ibeg, nrow
do j = 1, ncol
val(:, i, j) = val(:, ibeg - 1, j)
end do
end do
case(2) ! Periodic boundary condition
continue
case(3) ! Wall boundary conditions
do i=ibeg, nrow
do j = 1, ncol
val(:, i, j) = val(:, 2 * ibeg - 1 - i, j)
end do
end do
! negate the normal velocity:
do i = ibeg, nrow
do j = 1, ncol
val(2, i, j) = -val(2, i, j)
end do
end do
case(4) ! Spherical domain
continue
case default
print *, "Invalid boundary condition requested."
stop
end select
end if
!-------------------------------------------------------
! Bottom boundary:
!-------------------------------------------------------
if (ylo_patch < ylower - hymarg) then
! number of grid cells lying outside physical domain:
nyb = int((ylower + hymarg - ylo_patch) / hy)
select case(mthbc(3))
case(0) ! User defined boundary condition
! Inflow boundary condition
if (vbar < 0.1d0 * ubar) then
stop "Inflow BCs at bottom boundary assume vbar >= ubar / 10"
end if
do i = 1, nrow
x = xlo_patch + (i - 0.5d0) * hx
if (nyb >= 1) then
! First ghost cell
tau = hy / (2.d0 * vbar)
val(1,i,nyb) = qtrue(x + vbar * tau, 0.d0, time + tau)
end if
if (nyb == 2) then
! second ghost cell:
tau = 3.d0 * hy / (2.d0 * vbar)
val(1,i,1) = qtrue(x + ubar * tau, 0.d0, time + tau)
end if
end do
case(1) ! Zero-order extrapolation
do j = 1, nyb
do i = 1, nrow
val(:,i,j) = val(:, i, nyb + 1)
end do
end do
case(2) ! Periodic boundary condition
continue
case(3) ! Wall boundary conditions
do j = 1, nyb
do i = 1, nrow
val(:,i,j) = val(:, i, 2 * nyb + 1 - j)
end do
end do
! negate the normal velocity:
do j = 1, nyb
do i = 1, nrow
val(3,i,j) = -val(3, i, j)
end do
end do
case(4) ! Spherical domain
continue
case default
print *, "Invalid boundary condition requested."
stop
end select
end if
!-------------------------------------------------------
! Top boundary:
!-------------------------------------------------------
if (yhi_patch > yupper + hymarg) then
! number of grid cells lying outside physical domain:
nyt = int((yhi_patch - yupper + hymarg) / hy)
jbeg = max(ncol - nyt + 1, 1)
select case(mthbc(4))
case(0) ! User defined boundary condition
! Replace this code with a user defined boundary condition
stop "A user defined boundary condition was not provided."
case(1) ! Zero-order extrapolation
do j = jbeg, ncol
do i = 1, nrow
val(:, i, j) = val(:, i, jbeg - 1)
end do
end do
case(2) ! Periodic boundary condition
continue
case(3) ! Wall boundary conditions
do j = jbeg, ncol
do i = 1, nrow
val(:, i, j) = val(:, i, 2 * jbeg - 1 - j)
end do
end do
! negate the normal velocity:
do j = jbeg, ncol
do i = 1, nrow
val(3, i, j) = -val(3, i, j)
end do
end do
case(4) ! Spherical domain
continue
case default
print *, "Invalid boundary condition requested."
stop
end select
end if
end subroutine bc2amr