Skip to content

Instantly share code, notes, and snippets.

@ketch
Last active February 21, 2017 21:31
Show Gist options
  • Save ketch/ad1b6459fb3debad86a3760edcbd81de to your computer and use it in GitHub Desktop.
Save ketch/ad1b6459fb3debad86a3760edcbd81de to your computer and use it in GitHub Desktop.
Comparison of some Riemann solvers for the variable speed-limit LWR traffic model
all: traffic_fwave_old.so traffic_fwave.so traffic_qwave.so
traffic_fwave_old.so: rp1_traffic_vc_tracer_fwave_old.f90
f2py -c rp1_traffic_vc_tracer_fwave_old.f90 -m traffic_fwave_old
traffic_fwave.so: rp1_traffic_vc_tracer_fwave.f90
f2py -c rp1_traffic_vc_tracer_fwave.f90 -m traffic_fwave
traffic_qwave.so: rp1_traffic_vc_tracer_qwave.f90
f2py -c rp1_traffic_vc_tracer_qwave.f90 -m traffic_qwave
clean:
rm *.so
! Riemann solver for the variable speed limit LWR traffic model
! with a tracer:
! q_t + (u_max q(1-q))_x = 0
! p_t + u_max(1-q) p_x = 0
! Here the speed limit u_max (stored in aux(1,i) may vary with x and t.
! waves: 2
! equations: 2
! aux fields: 1
! Conserved quantities:
! 1 q
! 2 p
! Auxiliary variables:
! 1 u_max
! See http://www.clawpack.org/riemann.html for a detailed explanation
! of the Riemann solver API.
subroutine rp1(maxm,num_eqn,num_waves,num_aux,num_ghost,num_cells, &
ql,qr,auxl,auxr,fwave,s,amdq,apdq)
implicit none
! Inputs
integer, intent(in) :: maxm, num_eqn, num_waves, num_aux, num_ghost, num_cells
double precision, intent(in), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: ql,qr
double precision, intent(in), dimension(num_aux, 1-num_ghost:maxm+num_ghost) :: auxl,auxr
! Outputs
double precision, intent(out) :: s(num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out) :: fwave(num_eqn,num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: amdq,apdq
! Locals
double precision :: fim1, fi, sim1, si, f0
integer :: i
do i = 2-num_ghost, num_cells+num_ghost
! Compute the wave, speeds, and flux difference
! compute characteristic speed in each cell:
sim1 = auxr(1,i-1)*(1.d0 - 2.d0*qr(1,i-1))
si = auxl(1,i )*(1.d0 - 2.d0*ql(1,i ))
s(2,i) = auxl(1,i) * (1.d0 - ql(1,i))
! compute flux in each cell and flux difference:
fim1 = auxr(1,i-1)*qr(1,i-1)*(1.d0 - qr(1,i-1))
fi = auxl(1,i )*ql(1,i )*(1.d0 - ql(1,i ))
fwave(1,1,i) = fi - fim1
fwave(2,1,i) = 0.d0
fwave(1,2,i) = 0.d0
fwave(2,2,i) = s(2,i)*(ql(2,i) - qr(2,i-1))
apdq(2,i) = fwave(2,2,i)
amdq(2,i) = 0.d0 ! Traffic always moves right
if (sim1 .lt. 0.d0 .and. si .le. 0.d0) then
! left-going
s(1,i) = sim1
amdq(1,i) = fwave(1,1,i)
apdq(1,i) = 0.d0
else if (sim1 .ge. 0.d0 .and. si .gt. 0.d0) then
! right-going
s(1,i) = si
amdq(1,i) = 0.d0
apdq(1,i) = fwave(1,1,i)
else if (sim1 .lt. 0.d0 .and. si .gt. 0.d0) then
! transonic rarefaction
s(1,i) = 0.5d0*(sim1 + si)
! entropy fix: (perhaps doesn't work for all cases!!!)
! This assumes the flux in the transonic case should
! correspond to q=0.5 on the side with the smaller umax value.
f0 = dmin1(auxr(1,i-1),auxl(1,i))*0.25d0
! split fwave between amdq and apdq:
amdq(1,i) = f0 - fim1
apdq(1,i) = fi - f0
else
! transonic shock
s(1,i) = 0.5d0*(sim1 + si)
if (fi-fim1 .lt. 0.d0) then
amdq(1,i) = fwave(1,1,i)
apdq(1,i) = 0.d0
else if (fi-fim1 .gt. 0.d0) then
amdq(1,i) = 0.d0
apdq(1,i) = fwave(1,1,i)
else
amdq(1,i) = 0.5d0 * fwave(1,1,i)
apdq(1,i) = 0.5d0 * fwave(1,1,i)
endif
endif
enddo
return
end
! Riemann solver for the variable speed limit LWR traffic model
! with a tracer:
! q_t + (u_max q(1-q))_x = 0
! p_t + u_max(1-q) p_x = 0
! Here the speed limit u_max (stored in aux(1,i) may vary with x and t.
! waves: 2
! equations: 2
! aux fields: 1
! Conserved quantities:
! 1 q
! 2 p
! Auxiliary variables:
! 1 u_max
! See http://www.clawpack.org/riemann.html for a detailed explanation
! of the Riemann solver API.
subroutine rp1(maxm,num_eqn,num_waves,num_aux,num_ghost,num_cells, &
ql,qr,auxl,auxr,fwave,s,amdq,apdq)
implicit none
! Inputs
integer, intent(in) :: maxm, num_eqn, num_waves, num_aux, num_ghost, num_cells
double precision, intent(in), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: ql,qr
double precision, intent(in), dimension(num_aux, 1-num_ghost:maxm+num_ghost) :: auxl,auxr
! Outputs
double precision, intent(out) :: s(num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out) :: fwave(num_eqn,num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: amdq,apdq
! Locals
double precision :: fim1, fi, sim1, si, f0
integer :: i
do i = 2-num_ghost, num_cells+num_ghost
! Compute the wave, speeds, and flux difference
! compute characteristic speed in each cell:
sim1 = auxr(1,i-1)*(1.d0 - 2.d0*qr(1,i-1))
si = auxl(1,i )*(1.d0 - 2.d0*ql(1,i ))
s(2,i) = auxl(1,i) * (1.d0 - ql(1,i))
! compute flux in each cell and flux difference:
fim1 = auxr(1,i-1)*qr(1,i-1)*(1.d0 - qr(1,i-1))
fi = auxl(1,i )*ql(1,i )*(1.d0 - ql(1,i ))
fwave(1,1,i) = fi - fim1
fwave(2,1,i) = 0.d0
fwave(1,2,i) = 0.d0
fwave(2,2,i) = s(2,i)*(ql(2,i) - qr(2,i-1))
apdq(2,i) = fwave(2,2,i)
amdq(2,i) = 0.d0 ! Traffic always moves right
if (sim1 .lt. 0.d0 .and. si .le. 0.d0) then
! left-going
s(1,i) = sim1
amdq(1,i) = fwave(1,1,i)
apdq(1,i) = 0.d0
else if (sim1 .ge. 0.d0 .and. si .gt. 0.d0) then
! right-going
s(1,i) = si
amdq(1,i) = 0.d0
apdq(1,i) = fwave(1,1,i)
else if (sim1 .lt. 0.d0 .and. si .gt. 0.d0) then
! transonic rarefaction
s(1,i) = 0.5d0*(sim1 + si)
! entropy fix: (perhaps doesn't work for all cases!!!)
! This assumes the flux in the transonic case should
! correspond to q=0.5 on the side with the smaller umax value.
f0 = dmin1(auxr(1,i-1),auxl(1,i))*0.25d0
! split fwave between amdq and apdq:
amdq(1,i) = f0 - fim1
apdq(1,i) = fi - f0
else
! transonic shock
s(1,i) = 0.5d0*(sim1 + si)
if (s(1,i) .lt. 0.d0) then
amdq(1,i) = fwave(1,1,i)
apdq(1,i) = 0.d0
else if (s(1,i) .gt. 0.d0) then
amdq(1,i) = 0.d0
apdq(1,i) = fwave(1,1,i)
else
amdq(1,i) = 0.5d0 * fwave(1,1,i)
apdq(1,i) = 0.5d0 * fwave(1,1,i)
endif
endif
enddo
return
end
! Riemann solver for the variable speed limit LWR traffic model
! with a tracer:
! q_t + (u_max q(1-q))_x = 0
! p_t + u_max(1-q) p_x = 0
! Here the speed limit u_max (stored in aux(1,i) may vary with x and t.
! waves: 2
! equations: 2
! aux fields: 1
! Conserved quantities:
! 1 q
! 2 p
! Auxiliary variables:
! 1 u_max
! See http://www.clawpack.org/riemann.html for a detailed explanation
! of the Riemann solver API.
subroutine rp1(maxm,num_eqn,num_waves,num_aux,num_ghost,num_cells, &
ql,qr,auxl,auxr,wave,s,amdq,apdq)
implicit none
! Inputs
integer, intent(in) :: maxm, num_eqn, num_waves, num_aux, num_ghost, num_cells
double precision, intent(in), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: ql,qr
double precision, intent(in), dimension(num_aux, 1-num_ghost:maxm+num_ghost) :: auxl,auxr
! Outputs
double precision, intent(out) :: s(num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out) :: wave(num_eqn,num_waves,1-num_ghost:num_cells+num_ghost)
double precision, intent(out), dimension(num_eqn, 1-num_ghost:maxm+num_ghost) :: amdq,apdq
! Locals
double precision :: f_l, f_r, s_l, s_r, f0, q_l, q_r, v_l, v_r
integer :: i
do i = 2-num_ghost, num_cells+num_ghost
q_r = ql(1,i)
q_l = qr(1,i-1)
v_r = auxl(1,i)
v_l = auxr(1,i-1)
! compute characteristic speed in each cell:
s_l = v_l*(1.d0 - 2.d0*q_l)
s_r = v_r*(1.d0 - 2.d0*q_r)
s(2,i) = v_r * (1.d0 - q_r)
! compute flux in each cell and flux difference:
f_l = v_l*q_l*(1.d0 - q_l)
f_r = v_r*q_r*(1.d0 - q_r)
wave(1,1,i) = q_r - q_l ! Trying this even though it's not right
wave(2,1,i) = 0.d0
wave(1,2,i) = 0.d0
wave(2,2,i) = s(2,i)*(ql(2,i) - qr(2,i-1))
if (q_r .ne. q_l) then
s(1,i) = (f_r-f_l)/(q_r - q_l)
else
s(1,i) = 0.d0
endif
apdq(2,i) = wave(2,2,i)
amdq(2,i) = 0.d0 ! Traffic always moves right
if ((f_l .ge. 0.25d0*v_r) .and. (s_r .gt. 0.d0)) then
! left-going shock, right-going rarefaction
f0 = 0.25d0*v_r
elseif ((f_r .ge. 0.25d0*v_l) .and. (s_l .lt. 0.d0)) then
! right-going shock, left-going rarefaction
f0 = 0.25d0*v_l
elseif ((s_r .le. 0.d0) .and. (f_l .gt. f_r)) then
! left-going shock
f0 = f_r
elseif ((s_l .ge. 0.d0) .and. (f_r .gt. f_l)) then
! right-going shock
f0 = f_l
elseif ((s_l .le. 0.d0) .and. (s_r .ge. 0.d0)) then
! Transonic rarefaction
if (v_r .le. v_l) then
f0 = 0.25d0*v_r
else
f0 = 0.25d0*v_l
endif
elseif (f_l .le. f_r) then
! left-going rarefaction
f0 = f_r
else
! right-going rarefaction
f0 = f_l
endif
amdq(1,i) = f0 - f_l
apdq(1,i) = f_r - f0
enddo
return
end
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment