Skip to content

Commit 7ab8fbd

Browse files
committed
Add fallback incidence
Fixes #26, although somewhat unsatisfying, because we should be able to get this precise by improving irinterp.
1 parent c54a265 commit 7ab8fbd

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

Project.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,18 @@ Tracy = "e689c965-62c8-4b79-b2c5-8359227902fd"
4343
[weakdeps]
4444
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
4545

46+
[sources]
47+
DifferentiationInterface = {rev = "main", subdir = "DifferentiationInterface", url = "https://github.com/Keno/DifferentiationInterface.jl#main"}
48+
SimpleNonlinearSolve = {rev = "master", subdir = "lib/SimpleNonlinearSolve", url = "https://github.com/SciML/NonlinearSolve.jl.git"}
49+
StateSelection = {rev = "main", url = "https://github.com/JuliaComputing/StateSelection.jl.git"}
50+
4651
[compat]
4752
Accessors = "0.1.36"
4853
AutoHashEquals = "2.2.0"
4954
CentralizedCaches = "1.1.0"
5055
ChainRules = "1.50"
5156
ChainRulesCore = "1.20"
5257
Compiler = ">= 0.0.1"
53-
Cthulhu = "2.10.1"
5458
DiffEqBase = "6.149.2"
5559
DifferentiationInterface = "0.6.52"
5660
Diffractor = "0.2.7"

src/analysis/structural.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,15 +350,14 @@ function process_ipo_return!(𝕃, ultimate_rt::Incidence, eqclassification, var
350350
new_eq_row = _zero_row()
351351
for (v_offset, coeff) in zip(rowvals(ultimate_rt.row), nonzeros(ultimate_rt.row))
352352
v = v_offset - 1
353-
if varclassification[v] != External && coeff == nonlinear
353+
if v != 0 && varclassification[v] != External && coeff == nonlinear
354354
get_nonlinrepl()
355355
new_eq_row[v_offset] = nonlinear
356356
else
357357
new_row[v_offset] = coeff
358-
while true
358+
while v != 0 && v !== nothing
359359
varclassification[v] = External
360360
v = invview(var_to_diff)[v]
361-
v === nothing && break
362361
end
363362
end
364363
end
@@ -426,6 +425,17 @@ function add_internal_equations_to_structure!(refiner::StructuralRefiner, eqkind
426425
return true
427426
end
428427

428+
function process_ipo_return!(𝕃, ultimate_rt::Type, eqclassification, varclassification, var_to_diff, total_incidence, eq_callee_mapping)
429+
# If we don't have any internal variables (in which case we might have to to do a more aggressive rewrite), strengthen the incidence
430+
# by demoting to full incidence over the argument variables. Incidence is not allowed to propagate through global mutable state, so
431+
# the incidence of the return type is bounded by the incidence of the arguments in this case.
432+
if !all(==(External), varclassification)
433+
return ultimate_rt, 0
434+
end
435+
# TODO: Keep track of whether we have any time dependence?
436+
return Incidence(ultimate_rt, IncidenceVector(MAX_EQS, Int[1:length(varclassification)+1;], Union{Float64, NonLinear}[nonlinear for _ in 1:length(varclassification)+1])), 0
437+
end
438+
429439
function process_ipo_return!(𝕃, ultimate_rt::Eq, eqclassification, args...)
430440
eqclassification[ultimate_rt.id] = External
431441
return ultimate_rt, 0

test/regression.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,11 @@ end
7272
sol = solve(DAECProblem(tfb5, (1,) .=> 1.), IDA())
7373
@test all(map((x,y)->isapprox(x[], y, atol=1e-2), sol.u[:, 1], (sol.t .+ 1) .* log.(sol.t .+ 1) .+ 1 .- sol.t))
7474

75+
function tfb6()
76+
x = continuous()
77+
always!(ddt(x) - x^0.5)
78+
end
79+
sol = solve(DAECProblem(tfb6, (1,) .=> 1.), IDA())
80+
@test all(map((x,y)->isapprox(x[], y, atol=1e-2), sol.u[:, 1], 1/4 .* (sol.t .+ 2).^2))
81+
7582
end

0 commit comments

Comments
 (0)