@inline function mysign_zero(a)
return (1.0.*(a .> 0.0) + (-1.0).* (a .< 0.0))
end
@inline function minmod(a, b)
return 0.5*(mysign_zero(a)+mysign_zero(b))*min(abs(a), abs(b))
end
@inline function minmod(a, b, c)
sgnbc = (mysign_zero(b)+mysign_zero(c))
sgnac = (mysign_zero(a)+mysign_zero(c))
return 0.25*sgnbc*abs(sgnac)*min(abs(a), abs(b),abs(c))
end
@inline function minmod(a,b,c,d)
return 0.125*(mysign_zero(a)+mysign_zero(b))*(abs((mysign_zero(a)+mysign_zero(c))*(mysign_zero(a)+mysign_zero(d))))*min(abs(a),abs(b),abs(c), abs(d))
end
function MM3(a::AbstractFloat, b::AbstractFloat, c::AbstractFloat, weight::AbstractFloat)
weight = weight * 2.
if (abs(a) <= (weight*abs(b)))
return (abs(a) <= (weight*abs(c))) ? abs(a)*.5 : abs(c)
else
return (abs(b) <= abs(c)) ? abs(b) : abs(c)
end
end
function MM3N(a::AbstractFloat, b::AbstractFloat, c::AbstractFloat)
if (abs(a) <= abs(b))
return (abs(a) <= abs(c)) ? abs(a) : abs(c)
else
return (abs(b) <= abs(c)) ? abs(b) : abs(c)
end
end
function DMM(a::AbstractFloat, b::AbstractFloat)
return 0.5 * (mysign_zero(a) + mysign_zero(b)) * minimum([abs(a),abs(b)])
end
function DM4(a::AbstractFloat, b::AbstractFloat, c::AbstractFloat, d::AbstractFloat)
return 0.125 * (mysign_zero(a) + mysign_zero(b)) * abs((mysign_zero(a) + mysign_zero(c)) * (mysign_zero(a) + mysign_zero(d))) * minimum([abs(a),abs(b),abs(c),abs(d)])
end
function KT!(dfields, fields, par, t)
eqpars, h::Float64, θ::Float64, Fx!, MaxSpeed, N::Int64, N_FIELDS::Int32, auxvectors = par
Dm, D, Dp, u_mm, u_mp, u_pm, u_pp, F_mm, F_mp, F_pm, F_pp, H_m, H_p = auxvectors
for idx in 1:N
idxll = mod(((idx-2) - 1),N) + 1
idxl = mod(((idx-1) - 1),N) + 1
idxr = mod(((idx+1) - 1),N) + 1
idxrr = mod(((idx+2) - 1),N) + 1
fll = @view fields[idxll,:]
fl = @view fields[idxl,:]
f = @view fields[idx,:]
fr = @view fields[idxr,:]
frr = @view fields[idxrr,:]
@. Dm = minmod(0.5 *(f - fll), θ*(f-fl), θ*(fl-fll))
@. D = minmod(0.5 *(fr - fl), θ*(fr-f), θ*(f-fl))
@. Dp = minmod(0.5*(frr-f), θ*(frr-fr), θ*(fr-f))
@. u_mm = fl + 0.5*Dm
@. u_mp = f - 0.5*D
@. u_pm = f + 0.5*D
@. u_pp = fr - 0.5*Dp
Fx!(F_mm, u_mm, eqpars)
Fx!(F_mp, u_mp, eqpars)
Fx!(F_pm, u_pm, eqpars)
Fx!(F_pp, u_pp, eqpars)
a_m::Float64 = max(MaxSpeed(u_mm, eqpars), MaxSpeed(u_mp, eqpars))
a_p::Float64 = max(MaxSpeed(u_pm, eqpars), MaxSpeed(u_pp, eqpars))
@. H_m = 0.5 * (F_mp + F_mm) - 0.5 * a_m * (u_mp - u_mm)
@. H_p = 0.5 * (F_pp + F_pm) - 0.5 * a_p * (u_pp - u_pm)
@. dfields[idx, :] = -h*(H_p - H_m)
end
end
function createKTauxvectors(N_FIELDS)
D = Array{Float64}(undef, N_FIELDS)
Dm = copy(D)
Dp = copy(D)
umm = copy(D)
ump = copy(D)
upm = copy(D)
upp = copy(D)
Fmm = copy(D)
Fmp = copy(D)
Fpm = copy(D)
Fpp = copy(D)
Hm = copy(D)
Hp = copy(D)
return (Dm, D, Dp, umm, ump, upm, upp, Fmm, Fmp, Fpm, Fpp, Hm, Hp)
end
function MP5reconstruction!(Vl, Vjmm, Vjm, Vj, Vjp, Vjpp, N_Fields)
B1 = 0.0166666666666666667
B2 = 1.3333333333333333333
eps = 1e-10
ALPHA = 4.0
for i in 1:N_Fields
Vor = B1*(2.0*Vjmm[i] - 13.0*Vjm[i] + 47.0*Vj[i] + 27*Vjp[i] - 3.0*Vjpp[i])
Vmp = Vj[i] + minmod(Vjp[i]-Vj[i], ALPHA*(Vj[i]-Vjm[i]))
if ((Vor-Vj[i])*(Vor-Vmp)) < eps
Vl[i] = Vor
else
djm1 = Vjmm[i] - 2.0*Vjm[i] + Vj[i]
dj = Vjm[i] - 2*Vj[i] + Vjp[i]
djp1 = Vj[i] - 2.0*Vjp[i] + Vjpp[i]
dm4jph = minmod(4*dj - djp1, 4*djp1-dj, dj, djp1)
dm4jmh = minmod(4*dj - djm1, 4*djm1-dj, dj, djm1)
Vul = Vj[i] + ALPHA*(Vj[i] - Vjm[i])
Vav = 0.5*(Vj[i] + Vjp[i])
Vmd = Vav - 0.5*dm4jph
Vlc = Vj[i] + 0.5*(Vj[i]-Vjm[i]) + B2*dm4jmh
Vmin = max(min(Vj[i], Vjp[i], Vmd), min(Vj[i], Vul, Vlc));
Vmax = min(max(Vj[i], Vjp[i], Vmd), max(Vj[i], Vul, Vlc));
Vl[i] = Vor + minmod(Vmin-Vor, Vmax-Vor)
end
end
end
function mp5!(dfields, fields, par, t)
par_eq, h, N, N_Fields, Fx!, Speed_max, auxvectors = par
F_Mm3, F_Mm2, F_Mm1, F_M, F_Mp1, F_Mp2, F_Mp3, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, F_Pp3, F_LP, F_LM, F_RP, F_RM, H_m, H_p = auxvectors
for idx in 1:N
idxm3 = mod(((idx-3) - 1),N) + 1
idxm2 = mod(((idx-2) - 1),N) + 1
idxm1 = mod(((idx-1) - 1),N) + 1
idxp1 = mod(((idx+1) - 1),N) + 1
idxp2 = mod(((idx+2) - 1),N) + 1
idxp3 = mod(((idx+3) - 1),N) + 1
um3 = @view fields[idxm3,:]
um2 = @view fields[idxm2,:]
um1 = @view fields[idxm1,:]
u = @view fields[idx,:]
up1 = @view fields[idxp1,:]
up2 = @view fields[idxp2,:]
up3 = @view fields[idxp3,:]
S_MAX = max(Speed_max(up3, par_eq), Speed_max(um3, par_eq),
Speed_max(up2, par_eq), Speed_max(um2, par_eq), Speed_max(up1, par_eq),
Speed_max(um1, par_eq), Speed_max(u, par_eq))
Fx!(F_Pm3, um3, par_eq)
Fx!(F_Pm2, um2, par_eq)
Fx!(F_Pm1, um1, par_eq)
Fx!(F_P, u, par_eq)
Fx!(F_Pp1, up1, par_eq)
Fx!(F_Pp2, up2, par_eq)
Fx!(F_Pp3, up3, par_eq)
@. F_Mm3 = 0.5 * (F_Pm3 - S_MAX * um3)
@. F_Mm2 = 0.5 * (F_Pm2 - S_MAX * um2)
@. F_Mm1 = 0.5 * (F_Pm1 - S_MAX * um1)
@. F_M = 0.5 * (F_P - S_MAX * u)
@. F_Mp1 = 0.5 * (F_Pp1 - S_MAX * up1)
@. F_Mp2 = 0.5 * (F_Pp2 - S_MAX * up2)
@. F_Mp3 = 0.5 * (F_Pp3 - S_MAX * up3)
@. F_Pm3 = 0.5 * (F_Pm3 + S_MAX * um3)
@. F_Pm2 = 0.5 * (F_Pm2 + S_MAX * um2)
@. F_Pm1 = 0.5 * (F_Pm1 + S_MAX * um1)
@. F_P = 0.5 * (F_P + S_MAX * u)
@. F_Pp1 = 0.5 * (F_Pp1 + S_MAX * up1)
@. F_Pp2 = 0.5 * (F_Pp2 + S_MAX * up2)
@. F_Pp3 = 0.5 * (F_Pp3 + S_MAX * up3)
MP5reconstruction!(F_RM, F_Mp2, F_Mp1, F_M, F_Mm1, F_Mm2, N_Fields)
MP5reconstruction!(F_LM, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, N_Fields)
MP5reconstruction!(F_LP, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, N_Fields)
MP5reconstruction!(F_RP, F_Mp3, F_Mp2, F_Mp1, F_M, F_Mm1, N_Fields)
@. H_p = F_LP + F_RP
@. H_m = F_LM + F_RM
@. dfields[idx, :] = -h*(H_p - H_m)
end
end
function createMP5auxvectors(N_FIELDS)
F_P = Array{Float64}(undef, N_FIELDS)
F_P = copy(F_P)
F_M = copy(F_P)
F_Pm3 = copy(F_P)
F_Pm2 = copy(F_P)
F_Pm1 = copy(F_P)
F_Pp1 = copy(F_P)
F_Pp2 = copy(F_P)
F_Pp3 = copy(F_P)
F_Mm3 = copy(F_P)
F_Mm2 = copy(F_P)
F_Mm1 = copy(F_P)
F_Mp1 = copy(F_P)
F_Mp2 = copy(F_P)
F_Mp3 = copy(F_P)
F_LP = copy(F_P)
F_LM = copy(F_P)
F_RM = copy(F_P)
F_RP = copy(F_P)
H_m = copy(F_P)
H_p = copy(F_P)
return (F_Mm3, F_Mm2, F_Mm1, F_M, F_Mp1, F_Mp2, F_Mp3, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, F_Pp3, F_LP, F_LM, F_RP, F_RM, H_m, H_p)
end
function createWENOZvectors(N_FIELDS)
F_Mm3 = Array{Float64}(undef, N_FIELDS)
F_Mm2 = copy(F_Mm3)
F_Mm1 = copy(F_Mm3)
F_M = copy(F_Mm3)
F_Mp1 = copy(F_Mm3)
F_Mp2 = copy(F_Mm3)
F_Mp3 = copy(F_Mm3)
F_Pm3 = copy(F_Mm3)
F_Pm2 = copy(F_Mm3)
F_Pm1 = copy(F_Mm3)
F_P = copy(F_Mm3)
F_Pp1 = copy(F_Mm3)
F_Pp2 = copy(F_Mm3)
F_Pp3 = copy(F_Mm3)
F_LP = copy(F_Mm3)
F_LM = copy(F_Mm3)
F_RP = copy(F_Mm3)
F_RM = copy(F_Mm3)
H_m = copy(F_Mm3)
H_p = copy(F_Mm3)
sourcevec = copy(F_Mm3)
return (F_Mm3, F_Mm2, F_Mm1, F_M, F_Mp1, F_Mp2, F_Mp3, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, F_Pp3, F_LP, F_LM, F_RP, F_RM, H_m, H_p, sourcevec)
end
function WENOZreconstruction!(Vl, Vjmm, Vjm, Vj, Vjp, Vjpp, N_Fields)
B1 = 1.0833333333333333333
B2 = 0.1666666666666666666
eps = 1e-40
for i in 1:N_Fields
Q0 = 2.0*Vj[i] +5.0*Vjp[i] - 1.0*Vjpp[i]
Q1 = -Vjm[i] + 5.0*Vj[i] + 2.0*Vjp[i]
Q2 = 2.0*Vjmm[i] - 7.0*Vjm[i] + 11* Vj[i]
β0 = B1*(Vj[i] - 2*Vjp[i] + Vjpp[i])^2 + 0.25*(3*Vj[i] - 4*Vjp[i]+ Vjpp[i])^2
β1 = B1*(Vjm[i] - 2*Vj[i] + Vjp[i])^2 + 0.25*(Vjm[i] - Vjp[i])^2
β2 = B1*(Vjmm[i] - 2*Vjm[i] + Vj[i])^2 + 0.25*(Vjmm[i] - 4*Vjm[i]+ 3*Vj[i])^2
τ5 = abs(β2 - β0)
α0 = 0.3*(1.0 + (τ5/(β0 + eps))^2)
α1 = 0.6*(1.0 + (τ5/(β1 + eps))^2)
α2 = 0.1*(1.0 + (τ5/(β2 + eps))^2)
alphasum = (α0 + α1 + α2)
Vl[i] = (α0*Q0 + α1*Q1 + α2*Q2)*B2/alphasum
end
end
function wenoz!(dfields, fields, par, t)
par_eq, h, N, N_Fields, Fx!, Speed_max, auxvecs = par
F_Mm3, F_Mm2, F_Mm1, F_M, F_Mp1, F_Mp2, F_Mp3, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, F_Pp3, F_LP, F_LM, F_RP, F_RM, H_m, H_p, sourcevec = auxvecs
for idx in 1:N
idxm3 = mod(((idx-3) - 1),N) + 1
idxm2 = mod(((idx-2) - 1),N) + 1
idxm1 = mod(((idx-1) - 1),N) + 1
idxp1 = mod(((idx+1) - 1),N) + 1
idxp2 = mod(((idx+2) - 1),N) + 1
idxp3 = mod(((idx+3) - 1),N) + 1
um3 = @view fields[idxm3,:]
um2 = @view fields[idxm2,:]
um1 = @view fields[idxm1,:]
u = @view fields[idx,:]
up1 = @view fields[idxp1,:]
up2 = @view fields[idxp2,:]
up3 = @view fields[idxp3,:]
S_MAX = max(Speed_max(up3, par_eq), Speed_max(um3, par_eq),
Speed_max(up2, par_eq), Speed_max(um2, par_eq), Speed_max(up1, par_eq),
Speed_max(um1, par_eq), Speed_max(u, par_eq))
Fx!(F_Pm3, um3, par_eq)
Fx!(F_Pm2, um2, par_eq)
Fx!(F_Pm1, um1, par_eq)
Fx!(F_P, u, par_eq)
Fx!(F_Pp1, up1, par_eq)
Fx!(F_Pp2, up2, par_eq)
Fx!(F_Pp3, up3, par_eq)
@. F_Mm3 = 0.5 * (F_Pm3 - S_MAX * um3)
@. F_Mm2 = 0.5 * (F_Pm2 - S_MAX * um2)
@. F_Mm1 = 0.5 * (F_Pm1 - S_MAX * um1)
@. F_M = 0.5 * (F_P - S_MAX * u)
@. F_Mp1 = 0.5 * (F_Pp1 - S_MAX * up1)
@. F_Mp2 = 0.5 * (F_Pp2 - S_MAX * up2)
@. F_Mp3 = 0.5 * (F_Pp3 - S_MAX * up3)
@. F_Pm3 = 0.5 * (F_Pm3 + S_MAX * um3)
@. F_Pm2 = 0.5 * (F_Pm2 + S_MAX * um2)
@. F_Pm1 = 0.5 * (F_Pm1 + S_MAX * um1)
@. F_P = 0.5 * (F_P + S_MAX * u)
@. F_Pp1 = 0.5 * (F_Pp1 + S_MAX * up1)
@. F_Pp2 = 0.5 * (F_Pp2 + S_MAX * up2)
@. F_Pp3 = 0.5 * (F_Pp3 + S_MAX * up3)
WENOZreconstruction!(F_RM, F_Mp2, F_Mp1, F_M, F_Mm1, F_Mm2, N_Fields)
WENOZreconstruction!(F_LM, F_Pm3, F_Pm2, F_Pm1, F_P, F_Pp1, N_Fields)
WENOZreconstruction!(F_LP, F_Pm2, F_Pm1, F_P, F_Pp1, F_Pp2, N_Fields)
WENOZreconstruction!(F_RP, F_Mp3, F_Mp2, F_Mp1, F_M, F_Mm1, N_Fields)
@. H_p = F_LP + F_RP
@. H_m = F_LM + F_RM
@. dfields[idx, :] = -h*(H_p - H_m)
end
end