Due to the non-disipative nature of the shallow water equation, the time scale soley depends on input parameters containing a dimension of time ($\gamma$ and $\mu$), but not on the relaxation time $\tau$. That allows for cheap addaptive time-stepping like so:
Write a new presssure and friction force function
function filmpressure_dt!(state::LBM_state_1D, sys::SysConst_1D, dt::Float64)
# println("This is the pressure I am using!")
hip, him = viewneighbors_1D(state.dgrad)
# Straight elements j+1, i+1, i-1, j-1
circshift!(hip, state.height, 1)
circshift!(him, state.height, -1)
if sys.n==9 && sys.m==3
state.pressure .= -sys.γ*dt*dt .* (1 .- cospi.(sys.θ)) .* (sys.n - 1) .* (sys.m - 1) ./ ((sys.n - sys.m) * sys.hmin) .* Swalbe.fast_disj_93.(sys.hmin./(state.height .+ sys.hcrit))
elseif sys.n==3 && sys.m==2
state.pressure .= -sys.γ*dt*dt .* (1 .- cospi.(sys.θ)) .* (sys.n - 1) .* (sys.m - 1) ./ ((sys.n - sys.m) * sys.hmin) .* Swalbe.fast_disj_32.(sys.hmin./(state.height .+ sys.hcrit))
else
throw(DomainError((sys.n,sys.m), "This disjoining pressure is not implemented, Options currently are (n,m)=(9,3) or (n,m)=(3,2). Use those or implement a new option."))
end
state.pressure .-= sys.γ*dt*dt .* (hip .- 2 .* state.height .+ him)
return nothing
end
and
function slippage_dt!(state::LBM_state_1D, sys::SysConst_1D, dt::Float64)
state.slip .= (6*sys.μ*dt .* state.height .* state.vel) ./ (2 .* state.height.^2 .+ 6*sys.δ .* state.height .+ 3*sys.δ^2 )
return nothing
end
With those function a minimalistic siumlation run has to look like this:
using Pkg
Pkg.activate(".")
using Swalbe
function run(;
h=2,
eps=0.001,
Tmax=Int(1e8),
dumps=100,
tdump=Int(floor(Tmax/dumps)),
L=2^8,
delta=0.0,
n=9, m=3,
gamma=0.01,
theta=1/9,
data=dataall,
plot=true,
run=true,
hmin=0.2,
mu=1/6,
dt_init=1.0,
F_max=1e-4,
relax_F=1e-3,
dt_max=100
)
#Setup system
sys = Swalbe.SysConst_1D(L=L, Tmax=Tmax, tdump=tdump, γ=gamma, δ=delta, n=n, m=m, hmin=hmin, θ=theta, μ=mu)
state = Swalbe.Sys(sys)
state.height .= Swalbe.randominterface!(state.height, h, eps, L/2-L/10)
println("Starting LBM time loop")
t=0.0
dt=dt_init
i=0
while t<=sys.Tmax
if (t % sys.tdump + dt) >= sys.tdump
#Store data
#Plot data
if plot
end
#status report
println("Time step t=$(round(t,sigdigits=3)), mass m=$(round(sum(state.height),sigdigits=5)), diff d=$(round(maximum(state.height)-minimum(state.height), sigdigits=7)),dt=$(round(dt, sigdigits=3))")
i+=1
end
if run
Swalbe.filmpressure_dt!(state, sys, dt)
Swalbe.h∇p!(state)
Swalbe.slippage_dt!(state,sys, dt)
state.F .= -state.h∇p .- state.slip
Swalbe.equilibrium!(state)
Swalbe.BGKandStream!(state)
Swalbe.moments!(state)
dt = min(dt*(1+relax_F*(F_max - abs(maximum(state.F)))/F_max),dt_max)
end
t+=dt
end
end
run()
The idea is that numerical instability always comes from to high forcing, while to small forcing means that the code could be run faster. Thus setting a optimal force, that is numerically stable but not to small, and going up or down in the time step when the force becomes to small or to high will let the code run with the biggest possible time step without leading to too high forces. Then we have to multiply $\gamma$ by $dt^2$ and $\mu$ by $dt$ for dimensional reasons.
Tests
The insight is pretty new so I havn't tested much, but equilibrium properties of films should not be effected by $\gamma$ and $\mu$. Concerning time evolution the LSA of spinoidal rupture is fulfilled on small wavenumbers, there is just a lot more noise on the high wavenumbers. That was to be expected as we are permanently running at boaderline high forcing:
top left: film height, top right: FFT of filmheight vs LSA, bottom left: friction force, bottom right: pressure
![grafik](https://private-user-images.githubusercontent.com/80793262/283700326-7f950d78-295c-4c78-9be4-62b6e8723bf7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM3OTQ0NDUsIm5iZiI6MTcyMzc5NDE0NSwicGF0aCI6Ii84MDc5MzI2Mi8yODM3MDAzMjYtN2Y5NTBkNzgtMjk1Yy00Yzc4LTliZTQtNjJiNmU4NzIzYmY3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODE2VDA3NDIyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM5ODFiMzdiMjRmNDM4MmQ2MGFlMTkxNTZiMGRkZjAxYzNiM2UxZmMwZjg4OWY4NDU2YjU3MWNmMzM5NWE4NjQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.c_t_ff8T47XPjxH82F5NVB53gL44nihtnMFfZ-Ihe2s)
![grafik](https://private-user-images.githubusercontent.com/80793262/283699433-b54a478d-d8bf-4502-9510-a7d490e9756f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM3OTQ0NDUsIm5iZiI6MTcyMzc5NDE0NSwicGF0aCI6Ii84MDc5MzI2Mi8yODM2OTk0MzMtYjU0YTQ3OGQtZDhiZi00NTAyLTk1MTAtYTdkNDkwZTk3NTZmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODE2VDA3NDIyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI4NzY3YWQ5NDE3ODg2MTlhMTIyYTZkYzMyNGE1ODVkMThlMzA3OGUwMWNkNzI4YzUzNTAxYjdjYmU4OTAxMWYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.d8au5jstXFtlfLdTrtSLtsdtqAUiUHLfznhResRxKxc)
After Film rupture of course the LSA is not expected to fit the data anymore, but we can see how the firction force is kept at a level that is close to creating numerical problems but is still tolerable
![grafik](https://private-user-images.githubusercontent.com/80793262/283699928-8c152d0f-7433-41c9-ac8c-db1c265d00c2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM3OTQ0NDUsIm5iZiI6MTcyMzc5NDE0NSwicGF0aCI6Ii84MDc5MzI2Mi8yODM2OTk5MjgtOGMxNTJkMGYtNzQzMy00MWM5LWFjOGMtZGIxYzI2NWQwMGMyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODE2VDA3NDIyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM1MjM2YzIwMTI5NGMyY2Q0ZTAwYjRkMzU5Zjc4NGRkYTI3NTc5MmNhNzAyMzhlNmQzOTM1ZjhjMGU5OWZiZDAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.D8_XS3gYJa_wQKAUTgJQezH8Qh01CjBhCwu3UVq9NTY)
Time steps
Here is a plot of $dt$ indicating a speed up of factor almost 15 before film-rupture and 1.5 after film rupture for the parameters I have chosen
![grafik](https://private-user-images.githubusercontent.com/80793262/283700082-070f7011-1f39-4b40-ade7-c123ecad4eed.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM3OTQ0NDUsIm5iZiI6MTcyMzc5NDE0NSwicGF0aCI6Ii84MDc5MzI2Mi8yODM3MDAwODItMDcwZjcwMTEtMWYzOS00YjQwLWFkZTctYzEyM2VjYWQ0ZWVkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODE2VDA3NDIyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZjZDU5NzVmNDcxNDAzODQzNWMwOTljYTQ2MGU5NDdmYzljOGRiMzAwMDg1NWFjOWJkYjU5ZDcwMjQ5MmU0MDQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.CFDMDfuVxZq-B6g5UZ8kRTNtSiKNHgLquWqwtzhthnE)
F_max
It seems like $F_{\max}=10^{-4}$ seems to be the most that is feasible. Above the code crashes or produces unphysical output. But playing arround with paramaters one can try to figure out what works and what doesn't.