Hi everyone,
I am trying to reproduce a standing wave in a 2D fluid domain. I am having troubles to go past the discretization step with the ModelingToolkit.jl - hereafter you find a detailed description of the problem and of the error.
Versions:
julia 1.8.3
ModelingToolkit 8.34.0
The problem
It’s an inviscid problem, so once the potential \varphi [m^2/s] is found, I can find the fluid velocity by taking its gradients in the x and z directions, as
u [m/s] =\frac{\partial \varphi}{\partial x}
w [m/s] =\frac{\partial \varphi}{\partial z}
\eta[m] is the position of the water free surface (meaning, the deviation of the free surface from the z=0 plane). The tilde means that the potential is evaluated at the still water level, so \tilde\varphi = \varphi(t,x,z=0).
The usefulness of having this extra variable is that it helps the definition of the time stepping algorithm. The problem can be in fact time-stepped according to the following equations:
w = \frac {\partial \tilde\varphi}{\partial z} = \frac{\partial \eta}{\partial t}
This equation means that the variation in time of the free surface is a consequence of the vertical velocity of the fluid (which makes sense physically - the free surface rate of change is due to the fluid moving upwards).
The other evolution equation for the potential at the free surface is
-g \eta = \frac {\partial \tilde\varphi}{\partial t} .
This comes from a simplified (i.e. linearized) Bernoulli equation.
The problem here is that at every time step I need to solve the Laplace equation \nabla^2 \varphi = 0 in the whole fluid domain to evaluate the vertical gradient of the potential, to find w and to be able to step the free surface elevation forward.
My domain
The domain looks like in the following sketch.
There is a simple rectangular domain, with solid impermeable walls, that therefore can be treated as a zero-gradient boundary in the normal directions.
The starting conditions are zero potential everywhere (meaning, fluid in still position), and a known free surface.
The code
using ModelingToolkit, MethodOfLines, OrdinaryDiffEq, DomainSets, Debugger
g = 9.81
@parameters x z t
@variables φ(..) φ̃(..) η(..)
Dt = Differential(t)
Dx = Differential(x)
Dz = Differential(z)
Dxx = Differential(x)^2
Dzz = Differential(z)^2
eqs = [Dxx(φ(t, x, z)) + Dzz(φ(t, x, z)) ~ 0,
Dt(φ̃(t,x)) ~ -g*η(t,x),
Dt(η(t,x)) ~ Dz(φ(t, x, 1.))
]
bcs = [
φ(0, x, z) ~ 0,
φ̃(0., x) ~ 0.,
η(0., x) ~ cos(2*π*x),
φ(t, x, 1.) ~ φ̃(t, x),
Dx(φ(t, 0., z)) ~ 0.0,
Dx(φ(t, 1., z)) ~ 0.0,
Dz(φ(t, x, 0.)) ~ 0.0,
Dx(φ̃(t, 0.)) ~ 0.0,
Dx(φ̃(t, 1.)) ~ 0.0,
Dx(η(t, 0.)) ~ 0.0,
Dx(η(t, 1.)) ~ 0.0,
]
domains = [x ∈ Interval(0.0, 1.0),
z ∈ Interval(0.0, 1.0),
t ∈ Interval(0.0, 10.0)]
@named pdesys = PDESystem(eqs, bcs, domains, [t, x, z],
[φ(t, x, z), φ̃(t, x), η(t, x)])
dx = 0.1
dz = 0.1
order = 2
discretization = MOLFiniteDifference([x=>dx, z=>dz], t,
approx_order=order,
grid_align=center_align)
println("Discretization:")
prob = discretize(pdesys, discretization)
The Error
(More details in the appendix)
I think somehow the system gets confused by the fact that \tilde\varphi and \eta do not depend on z.
It could be that this is not the right way to specify the equations - is there a way where I can specify that a variable is nothing but a pointer to a part of a larger domain?
Any help would be greatly appreciated!
Fabio
Appendix
ERROR: KeyError: key z not found
Stacktrace:
[1] getindex
@ .\dict.jl:498 [inlined]
[2] (::MethodOfLines.var"#426#429"{Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}})(x::Sym{Real, Base.ImmutableDict{DataType, Any}})
@ MethodOfLines .\none:0
[3] iterate
@ .\generator.jl:47 [inlined]
[4] collect(itr::Base.Generator{Vector{Sym{Real, Base.ImmutableDict{DataType, Any}}}, MethodOfLines.var"#426#429"{Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}}})
@ Base .\array.jl:787
[5] boundary_value_maps(II::CartesianIndex{1}, s::MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, boundary::MethodOfLines.LowerBoundary, derivweights::MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}, indexmap::Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:82
[6] #413
@ C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:34 [inlined]
[7] (::MethodOfLines.var"#432#434"{CartesianIndex{1}})(f::MethodOfLines.var"#413#418"{MethodOfLines.LowerBoundary, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:98
[8] _mapreduce(f::MethodOfLines.var"#432#434"{CartesianIndex{1}}, op::typeof(vcat), #unused#::IndexLinear, A::Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2,
3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b})
@ Base .\reduce.jl:438
[9] _mapreduce_dim
@ .\reducedim.jl:365 [inlined]
[10] #mapreduce#765
@ .\reducedim.jl:357 [inlined]
[11] mapreduce
@ .\reducedim.jl:357 [inlined]
[12] (::MethodOfLines.var"#431#433"{MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b}, MethodOfLines.LowerBoundary, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, Equation})(II::CartesianIndex{1})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:98
[13] iterate
@ .\generator.jl:47 [inlined]
[14] _collect(c::Vector{CartesianIndex{1}}, itr::Base.Generator{Vector{CartesianIndex{1}}, MethodOfLines.var"#431#433"{MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b}, MethodOfLines.LowerBoundary, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, Equation}}, #unused#::Base.EltypeUnknown, isz::Base.HasShape{1})
@ Base .\array.jl:807
[15] collect_similar(cont::Vector{CartesianIndex{1}}, itr::Base.Generator{Vector{CartesianIndex{1}}, MethodOfLines.var"#431#433"{MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b}, MethodOfLines.LowerBoundary, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, Equation}})
@ Base .\array.jl:716
[16] map(f::Function, A::Vector{CartesianIndex{1}})
@ Base .\abstractarray.jl:2933
[17] generate_bc_eqs(s::MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, boundaryvalfuncs::Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b}, boundary::MethodOfLines.LowerBoundary, interiormap::MethodOfLines.InteriorMap, indexmap::Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:97
[18] generate_bc_eqs!(bceqs::Vector{Any}, s::MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, boundaryvalfuncs::Vector{MethodOfLines.var"#413#418"{b, MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}} where b}, interiormap::MethodOfLines.InteriorMap, boundary::MethodOfLines.LowerBoundary)
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\discretization\generate_bc_eqs.jl:4
[19] discretize_equation!(alleqs::Vector{Any}, bceqs::Vector{Any}, pde::Equation, interiormap::MethodOfLines.InteriorMap, eqvar::Term{Real, Base.ImmutableDict{DataType, Any}}, bcmap::Dict{Sym{SymbolicUtils.FnType{Tuple, Real}, Nothing}, Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Any}}}, depvars::Vector{Any}, s::MethodOfLines.DiscreteSpace{2, 3, MethodOfLines.CenterAlignedGrid}, derivweights::MethodOfLines.DifferentialDiscretizer{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Vector{Int64}}, Dict{Function, MethodOfLines.DerivativeOperator{Float64, Nothing, false, Float64, StaticArraysCore.SVector{3, Float64}, S2, S3, Nothing, Nothing} where {S2, S3}}, UpwindScheme}, indexmap::Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Int64}, pmap::MethodOfLines.PeriodicMap{Val{false}()})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\scalar_discretization.jl:9
[20] symbolic_discretize(pdesys::PDESystem, discretization::MOLFiniteDifference{MethodOfLines.CenterAlignedGrid, MethodOfLines.ScalarizedDiscretization})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\MOL_discretization.jl:119
[21] discretize(pdesys::PDESystem, discretization::MOLFiniteDifference{MethodOfLines.CenterAlignedGrid, MethodOfLines.ScalarizedDiscretization})
@ MethodOfLines C:\Users\fabpi\.julia\packages\MethodOfLines\kko34\src\MOL_discretization.jl:138
[22] top-level scope
@ Julia\matrixTests\linearWaveSolver.jl:51