Variables are Missing from Variable map in PDE

Hello,

I am trying to solve a set of coupled PDEs using MethodOfLines.jl, but I am new to both PDE solving and Julia in general. The code is based on one of the MethodOfLines.jl tutorials:

using MethodOfLines, ModelingToolkit, OrdinaryDiffEq, DomainSets

N = 2

@parameters x t
@variables ϕ(..)[1:N]
Dt = Differential(t)
Dx = Differential(x)
Dtt = Differential(t)^2
Dxx = Differential(x)^2

γ = 0.01
α = 0.05
S = -0.499997
l = 5

bc = 0

x_min = t_min = 0
x_max = l
t_max = 20


J(ϕ) = Dtt(ϕ) + α*Dt(ϕ) - γ

eq1 = [Dxx(ϕ(x,t)[1]) ~ J(ϕ(x,t)[1]) + S*J(ϕ(x,t)[2])]
eqmid = [Dxx(ϕ(x,t)[i]) ~ S*J(ϕ(x,t)[i-1]) + J(ϕ(x,t)[i]) + S*J(ϕ(x,t)[i+1]) for i in 2:(N-1)]
eqN = [Dxx(ϕ(x,t)[N]) ~ S*J(ϕ(x,t)[N-1]) + J(ϕ(x,t)[N])]
eq = [eq1, eqmid, eqN]

eq = reduce(vcat,eq)

domains = [x ∈ Interval(x_min, x_max),
      t ∈ Interval(t_min, t_max)]


bcs = [[Dx(ϕ(x_min,t)[i]) ~ bc,
      Dx(ϕ(x_max,t)[i]) ~ bc,
      ϕ(x,t_min)[i] ~ bc,
      Dt(ϕ(x,t_min)[i]) ~ bc] for i in 1:N]
bcs = reduce(vcat,bcs)

@named pdesys = PDESystem(eq,bcs,domains,[x,t],[ϕ(x,t)[i] for i in 1:N])

Nd = 8

order = 2

discretization = MOLFiniteDifference([x=>Nd],t,approx_order=order)

println("Discretization:")
@time prob = discretize(pdesys,discretization)

This isn’t the full problem, but it results in the same error as the full problem. The error report is as follows:

ArgumentError: SymbolicUtils.BasicSymbolic{Real}[var"var\"ϕ_Any[1]\"(t)[2]ˍtt", var"var\"ϕ_Any[1]\"(t)[3]ˍtt", var"var\"ϕ_Any[1]\"(t)[4]ˍtt", var"var\"ϕ_Any[1]\"(t)[5]ˍtt", var"var\"ϕ_Any[1]\"(t)[6]ˍtt", var"var\"ϕ_Any[1]\"(t)[7]ˍtt"] are missing from the variable map.

Stacktrace:
  [1] throw_missingvars(vars::Vector{SymbolicUtils.BasicSymbolic{Real}})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/variables.jl:122
  [2] _varmap_to_vars(varmap::Dict{Any, Any}, varlist::Vector{SymbolicUtils.BasicSymbolic{Real}}; defaults::Dict{Any, Any}, check::Bool, toterm::typeof(ModelingToolkit.default_toterm))
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/variables.jl:116
  [3] varmap_to_vars(varmap::Vector{Pair}, varlist::Vector{SymbolicUtils.BasicSymbolic{Real}}; defaults::Dict{Any, Any}, check::Bool, toterm::Function, promotetoconcrete::Nothing, tofloat::Bool, use_union::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/variables.jl:85
  [4] get_u0_p(sys::ODESystem, u0map::Vector{Pair}, parammap::SciMLBase.NullParameters; use_union::Bool, tofloat::Bool, symbolic_u0::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:787
  [5] get_u0_p
    @ ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:769 [inlined]
  [6] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{Pair}, parammap::SciMLBase.NullParameters; implicit_dae::Bool, du0map::Nothing, version::Nothing, tgrad::Bool, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, use_union::Bool, tofloat::Bool, symbolic_u0::Bool, u0_constructor::typeof(identity), kwargs::@Kwargs{t::Int64, has_difference::Bool, check_length::Bool})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:812
  [7] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair}, tspan::Tuple{Int64, Int64}, parammap::SciMLBase.NullParameters; callback::Nothing, check_length::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:937
  [8] ODEProblem
    @ ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:930 [inlined]
  [9] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair}, tspan::Tuple{Int64, Int64})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:930
 [10] (ODEProblem{true})(::ODESystem, ::Vector{Pair}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:917
 [11] (ODEProblem{true})(::ODESystem, ::Vector{Pair}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:916
...
    @ PDEBase ~/.julia/packages/PDEBase/Aqj4G/src/discretization_state.jl:55
 [16] macro expansion
    @ ./timing.jl:279 [inlined]

Based on other posts I’ve read, the issue has to do with the boundary conditions (or lack thereof) but I can’t figure out how to get the problem to discretize even with additional BCs (the conditions at t=0 aren’t part of the problem statement). It seems to work fine if I simply don’t couple the two equations, but that honestly confuses me more.

Any help would be greatly appreciated!

From your equations don’t you need an initial condition for the second derivative in time?

That makes sense to me, based on the error message and what I haven’t forgotten from my math classes, but adding the boundary condition Dtt(ϕ(x,t_min)[i]) ~ γ doesn’t stop the error from occurring.

Edit: Interestingly, I just double checked what would happen while the equations were uncoupled (i.e. setting S = 0), and adding Dtt(ϕ(x,t_min)[i]) ~ γ to the BCs actually stopped the PDE from discretizing, resulting in the following error message:

ArgumentError: Any[(1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(0.7142857142857143, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(1.4285714285714286, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(2.142857142857143, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(2.857142857142857, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(3.5714285714285716, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[1]"(4.285714285714286, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(0.7142857142857143, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(1.4285714285714286, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(2.142857142857143, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(2.857142857142857, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(3.5714285714285716, 0)))), (1//0)*(-0.01 + Differential(t)(Differential(t)(var"ϕ_Any[2]"(4.285714285714286, 0))))] are either missing from the variable map or missing from the system's states/parameters list.

Stacktrace:
  [1] throw_missingvars_in_sys(vars::Vector{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/utils.jl:650
  [2] promote_to_concrete(vs::Vector{Any}; tofloat::Bool, use_union::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/utils.jl:667
  [3] varmap_to_vars(varmap::Vector{Pair}, varlist::Vector{SymbolicUtils.BasicSymbolic{Real}}; defaults::Dict{Any, Any}, check::Bool, toterm::Function, promotetoconcrete::Nothing, tofloat::Bool, use_union::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/variables.jl:93
  [4] get_u0_p(sys::ODESystem, u0map::Vector{Pair}, parammap::SciMLBase.NullParameters; use_union::Bool, tofloat::Bool, symbolic_u0::Bool)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:787
  [5] get_u0_p
    @ ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:769 [inlined]
  [6] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{Pair}, parammap::SciMLBase.NullParameters; implicit_dae::Bool, du0map::Nothing, version::Nothing, tgrad::Bool, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, use_union::Bool, tofloat::Bool, symbolic_u0::Bool, u0_constructor::typeof(identity), kwargs::@Kwargs{t::Int64, has_difference::Bool, check_length::Bool})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:812
  [7] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair}, tspan::Tuple{Int64, Int64}, parammap::SciMLBase.NullParameters; callback::Nothing, check_length::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:937
  [8] ODEProblem
    @ ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:930 [inlined]
  [9] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair}, tspan::Tuple{Int64, Int64})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:930
 [10] (ODEProblem{true})(::ODESystem, ::Vector{Pair}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:917
 [11] (ODEProblem{true})(::ODESystem, ::Vector{Pair}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/Nsxrf/src/systems/diffeqs/abstractodesystem.jl:916
...
    @ PDEBase ~/.julia/packages/PDEBase/Aqj4G/src/discretization_state.jl:55
 [16] macro expansion
    @ ./timing.jl:279 [inlined]

Okay, I ended up figuring out a workaround; not one that I’d prefer, as it seems to impact performance, but I can now discretize and find a solution.

After following the call stack and tooling with structural_simplify, it seemed that the error had specifically to do with time, and not space. So, I tried treating time and space equivalently, and it seems to have worked! Specifically, before discretize() is called, I altered the MOLFiniteDifference call to be:

discretization = MOLFiniteDifference([x=>Nd,t=>Nd],approx_order=order)

and it seems to work! Now I’m just working on getting it to solve in a reasonable time.

Seems like a bug. Open an issue.