161 lines
4.6 KiB
Fortran
Executable File
161 lines
4.6 KiB
Fortran
Executable File
|
|
! gfortran -cpp -O3 -flto ex_6.f90 -o ex_6
|
|
! ./ex_6
|
|
|
|
! 1d scalar transport in a periodic domain. Fluxes are
|
|
! computed in a flux-form semi-lagrangian sense --
|
|
! integrating over the upwind regions "swept" by edges
|
|
! in each time-step. This implementation requires CFL<1,
|
|
! with the upwind regions covering adjacent cells only.
|
|
! A CFL>=1 variant could be constructed using RMAP1D().
|
|
!
|
|
|
|
# include "../src/ppr_1d.f90"
|
|
|
|
program ex
|
|
|
|
use ppr_1d
|
|
|
|
implicit none
|
|
|
|
integer, parameter :: halo = 4 ! halo cells at boundary
|
|
integer, parameter :: npos = 51 ! no. edge
|
|
integer, parameter :: nvar = 1 ! no. tracers to trnsprt
|
|
integer, parameter :: ndof = 1 ! no. FV DoF per cell
|
|
integer :: ipos,il,ir,step
|
|
|
|
!------------------------------- domain discretisation !
|
|
real*8 :: xpos(1-halo:npos+halo)
|
|
real*8 :: xmid,xdel(1),tDEL
|
|
|
|
!-------------------------------- finite-volume arrays !
|
|
|
|
! INIT: initial cell-wise finite-volume profile
|
|
! QBAR: dynamic cell-wise finite-volume profile
|
|
! MASK: cell-wise "land" mask (all TRUE here)
|
|
! UVEL: edge-wise velocity distribution
|
|
! FLUX: edge-wise distribution of upwind fluxes
|
|
! QDIV: cell-wise distribution of divergence
|
|
|
|
real*8 :: init(ndof,nvar,1-halo:npos+halo-1)
|
|
real*8 :: qbar(ndof,nvar,1-halo:npos+halo-1)
|
|
logical :: mask( 1-halo:npos+halo-1)
|
|
real*8 :: uvel( 1-halo:npos+halo)
|
|
real*8 :: flux( nvar,1-halo:npos+halo)
|
|
real*8 :: qdiv( nvar,1-halo:npos+halo-1)
|
|
|
|
|
|
!------------------------------ method data-structures !
|
|
type(rmap_work) :: work
|
|
type(rmap_opts) :: opts
|
|
type(rcon_ends) :: bc_l(nvar)
|
|
type(rcon_ends) :: bc_r(nvar)
|
|
|
|
!------------------------------ define a simple domain !
|
|
|
|
il = + 1 ! 1st real interior cell
|
|
ir = npos - 1 ! Nth real interior cell
|
|
|
|
xpos(il+0) = 0.0d+00
|
|
xpos(ir+1) = 1.0d+00
|
|
|
|
xdel(1) = (xpos(ir+1)-xpos(il+0))/(npos-1)
|
|
|
|
do ipos = il+1, ir-0
|
|
|
|
xpos(ipos) = (ipos-1) * xdel(1)
|
|
|
|
end do
|
|
|
|
!------------------------------ setup some simple data !
|
|
|
|
uvel = +1.0d+0
|
|
mask = .true.
|
|
|
|
tDEL = +1.0d-2
|
|
|
|
do ipos = +1, npos-1
|
|
|
|
xmid = xpos(ipos+0)* 0.5d+00 &
|
|
& + xpos(ipos+1)* 0.5d+00
|
|
|
|
init(1,1,ipos) = &
|
|
& .8d+0 * exp( -75.0d+0 * (xmid - 0.275d+0) ** 2 ) &
|
|
& + .9d+0 * exp(-100.0d+0 * (xmid - 0.500d+0) ** 2 ) &
|
|
& + 1.d+0 * exp(-125.0d+0 * (xmid - 0.725d+0) ** 2 )
|
|
|
|
end do
|
|
|
|
!------------------------------ specify method options !
|
|
|
|
opts%edge_meth = p3e_method ! 3rd-order edge interp.
|
|
opts%cell_meth = ppm_method ! PPM method in cells
|
|
opts%cell_lims = weno_limit ! "non-oscillatory" lim.
|
|
|
|
!------------------------------ set BC.'s at endpoints !
|
|
|
|
bc_l%bcopt = bcon_loose ! "loose" = extrapolate
|
|
bc_r%bcopt = bcon_loose
|
|
|
|
!------------------------------ init. method workspace !
|
|
|
|
call work%init(npos+2*halo,nvar,opts)
|
|
|
|
!------------------------------ calc. scalar transport !
|
|
|
|
qbar = init
|
|
|
|
do step = +1, +100 ! 100 steps => full loop
|
|
|
|
!------------------------------ periodicity via halo's !
|
|
|
|
qbar(1,:,il-halo:il-1) = &
|
|
& qbar(1,:,ir-halo+1:ir)
|
|
qbar(1,:,ir+1:ir+halo) = &
|
|
& qbar(1,:,il:il+halo-1)
|
|
|
|
!------------------------------ form lagrangian fluxes !
|
|
|
|
call ffsl1d (npos+2*halo,nvar, &
|
|
& ndof,xdel,tDEL,mask,uvel, &
|
|
& qbar,flux,bc_l,bc_r,work, &
|
|
& opts)
|
|
|
|
|
|
!------------------------------ flux divergence eval's !
|
|
qdiv( 1,il:ir) = &
|
|
& flux(1,il+1:ir+1) &
|
|
& - flux(1,il+0:ir+0)
|
|
|
|
!------------------------------ take a single timestep !
|
|
|
|
qbar(1,1,il:ir) = &
|
|
& qbar(1,1,il:ir) - &
|
|
& qdiv(1,il:ir) / xdel(1)
|
|
|
|
end do
|
|
|
|
!------------------------------ clear method workspace !
|
|
|
|
call work%free()
|
|
|
|
!------------------------------ dump results to stdout !
|
|
|
|
print*,"End timestep profile : "
|
|
|
|
do ipos = il+0, ir-0
|
|
|
|
print *, init(1,:,ipos) &
|
|
& , qbar(1,:,ipos)
|
|
|
|
end do
|
|
|
|
print*,"Conservation defect := " &
|
|
& , sum(init(1,:,il:ir)) &
|
|
& - sum(qbar(1,:,il:ir))
|
|
|
|
end program
|
|
|
|
|
|
|