From b93623111fdf72a4806bbb6fa071b649544a2b2e Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 10:19:15 +0530 Subject: [PATCH 1/8] fix: do not alias variables, return `nothing` from `set_parameter!` --- src/systems/parameter_buffer.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/systems/parameter_buffer.jl b/src/systems/parameter_buffer.jl index b7187bcd5b..9821731bcf 100644 --- a/src/systems/parameter_buffer.jl +++ b/src/systems/parameter_buffer.jl @@ -384,8 +384,8 @@ function SymbolicIndexingInterface.parameter_values(p::MTKParameters, pind::Para end function SymbolicIndexingInterface.set_parameter!( - p::MTKParameters, val, idx::ParameterIndex) - @unpack portion, idx, validate_size = idx + p::MTKParameters, val, pidx::ParameterIndex) + @unpack portion, idx, validate_size = pidx if portion isa SciMLStructures.Tunable if validate_size && size(val) !== size(idx) throw(InvalidParameterSizeException(size(idx), size(val))) @@ -428,6 +428,7 @@ function SymbolicIndexingInterface.set_parameter!( if p.dependent_update_iip !== nothing p.dependent_update_iip(ArrayPartition(p.dependent), p...) end + return nothing end function _set_parameter_unchecked!( From f8332826de3eff3cde95c07df6473f8d05f0cf17 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 15:17:28 +0530 Subject: [PATCH 2/8] fix: fix `parameter_index` for indexed tunable symbolic arrays --- src/systems/abstractsystem.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/systems/abstractsystem.jl b/src/systems/abstractsystem.jl index 44b7d0f0dc..4e18078282 100644 --- a/src/systems/abstractsystem.jl +++ b/src/systems/abstractsystem.jl @@ -563,8 +563,11 @@ function SymbolicIndexingInterface.parameter_index(sys::AbstractSystem, sym) if idx.portion isa SciMLStructures.Discrete && idx.idx[2] == idx.idx[3] == nothing return nothing + elseif idx.portion isa SciMLStructures.Tunable + return ParameterIndex( + idx.portion, idx.idx[arguments(sym)[(begin + 1):end]...]) else - ParameterIndex( + return ParameterIndex( idx.portion, (idx.idx..., arguments(sym)[(begin + 1):end]...)) end else From 2b2365234b3cd00e974d991cf5dbd2560f0e228d Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 15:18:46 +0530 Subject: [PATCH 3/8] refactor: better `getindex` and `length` for `MTKParameters` --- src/systems/parameter_buffer.jl | 70 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/systems/parameter_buffer.jl b/src/systems/parameter_buffer.jl index 9821731bcf..fe46d6a2db 100644 --- a/src/systems/parameter_buffer.jl +++ b/src/systems/parameter_buffer.jl @@ -159,7 +159,7 @@ function MTKParameters( end tunable_buffer = narrow_buffer_type(tunable_buffer) if isempty(tunable_buffer) - tunable_buffer = Float64[] + tunable_buffer = SizedVector{0, Float64}() end disc_buffer = broadcast.(narrow_buffer_type, disc_buffer) const_buffer = narrow_buffer_type.(const_buffer) @@ -668,40 +668,48 @@ function DiffEqBase.anyeltypedual(p::Type{<:MTKParameters{T}}, DiffEqBase.__anyeltypedual(T) end -_subarrays(v::AbstractVector) = isempty(v) ? () : (v,) -_subarrays(v::ArrayPartition) = v.x -_subarrays(v::Tuple) = v -_num_subarrays(v::AbstractVector) = 1 -_num_subarrays(v::ArrayPartition) = length(v.x) -_num_subarrays(v::Tuple) = length(v) # for compiling callbacks # getindex indexes the vectors, setindex! linearly indexes values # it's inconsistent, but we need it to be this way -function Base.getindex(buf::MTKParameters, i) - i_orig = i - if !isempty(buf.tunable) - i == 1 && return buf.tunable - i -= 1 - end - if !isempty(buf.discrete) - for clockbuf in buf.discrete - i <= _num_subarrays(clockbuf) && return _subarrays(clockbuf)[i] - i -= _num_subarrays(clockbuf) +@generated function Base.getindex( + ps::MTKParameters{T, D, C, E, N}, idx::Int) where {T, D, C, E, N} + paths = [] + if !(T <: SizedVector{0, Float64}) + push!(paths, :(ps.tunable)) + end + for i in 1:length(D) + for j in 1:fieldcount(eltype(D)) + push!(paths, :(ps.discrete[$i][$j])) end end - if !isempty(buf.constant) - i <= _num_subarrays(buf.constant) && return _subarrays(buf.constant)[i] - i -= _num_subarrays(buf.constant) + for i in 1:fieldcount(C) + push!(paths, :(ps.constant[$i])) end - if !isempty(buf.nonnumeric) - i <= _num_subarrays(buf.nonnumeric) && return _subarrays(buf.nonnumeric)[i] - i -= _num_subarrays(buf.nonnumeric) + for i in 1:fieldcount(E) + push!(paths, :(ps.dependent[$i])) end - if !isempty(buf.dependent) - i <= _num_subarrays(buf.dependent) && return _subarrays(buf.dependent)[i] - i -= _num_subarrays(buf.dependent) + for i in 1:fieldcount(N) + push!(paths, :(ps.nonnumeric[$i])) end - throw(BoundsError(buf, i_orig)) + expr = Expr(:if, :(idx == 1), :(return $(paths[1]))) + curexpr = expr + for i in 2:length(paths) + push!(curexpr.args, Expr(:elseif, :(idx == $i), :(return $(paths[i])))) + curexpr = curexpr.args[end] + end + return Expr(:block, expr, :(throw(BoundsError(ps, idx)))) +end + +@generated function Base.length(ps::MTKParameters{T, D, C, E, N}) where {T, D, C, E, N} + len = 0 + if !(T <: SizedVector{0, Float64}) + len += 1 + end + if length(D) > 0 + len += length(D) * fieldcount(eltype(D)) + end + len += fieldcount(C) + fieldcount(E) + fieldcount(N) + return len end Base.getindex(p::MTKParameters, pind::ParameterIndex) = parameter_values(p, pind) @@ -709,13 +717,7 @@ Base.getindex(p::MTKParameters, pind::ParameterIndex) = parameter_values(p, pind Base.setindex!(p::MTKParameters, val, pind::ParameterIndex) = set_parameter!(p, val, pind) function Base.iterate(buf::MTKParameters, state = 1) - total_len = Int(!isempty(buf.tunable)) # for tunables - for clockbuf in buf.discrete - total_len += _num_subarrays(clockbuf) - end - total_len += _num_subarrays(buf.constant) - total_len += _num_subarrays(buf.nonnumeric) - total_len += _num_subarrays(buf.dependent) + total_len = length(buf) if state <= total_len return (buf[state], state + 1) else From b4481dcaaac6f8cca940837e0ed1a16295a46f3e Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 15:19:09 +0530 Subject: [PATCH 4/8] test: move SciML Problem Input Test to SII set, uncomment testset --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 8cbca75641..1a5dab96df 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -43,7 +43,6 @@ end @safetestset "PDE Construction Test" include("pde.jl") @safetestset "JumpSystem Test" include("jumpsystem.jl") @safetestset "Constraints Test" include("constraints.jl") - @safetestset "SciML Problem Input Test" include("sciml_problem_inputs.jl") @safetestset "Reduction Test" include("reduction.jl") @safetestset "Split Parameters Test" include("split_parameters.jl") @safetestset "StaticArrays Test" include("static_arrays.jl") @@ -78,7 +77,8 @@ end end if GROUP == "All" || GROUP == "InterfaceI" || GROUP == "SymbolicIndexingInterface" - # @safetestset "SymbolicIndexingInterface test" include("symbolic_indexing_interface.jl") + @safetestset "SymbolicIndexingInterface test" include("symbolic_indexing_interface.jl") + @safetestset "SciML Problem Input Test" include("sciml_problem_inputs.jl") @safetestset "MTKParameters Test" include("mtkparameters.jl") end From b6b4cbc8a8d588a05eda21ba9c2941b3a120d8e0 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 16:31:37 +0530 Subject: [PATCH 5/8] fix: fix `namespace_callback` --- src/systems/callbacks.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systems/callbacks.jl b/src/systems/callbacks.jl index ab699b6166..993bee9040 100644 --- a/src/systems/callbacks.jl +++ b/src/systems/callbacks.jl @@ -190,8 +190,8 @@ namespace_affects(::Nothing, s) = nothing function namespace_callback(cb::SymbolicContinuousCallback, s)::SymbolicContinuousCallback SymbolicContinuousCallback( namespace_equation.(equations(cb), (s,)), - namespace_affects(affects(cb), s), - namespace_affects(affect_negs(cb), s)) + namespace_affects(affects(cb), s); + affect_neg = namespace_affects(affect_negs(cb), s)) end """ From 92bbc063e5cc9e0dbc16f5e9053f7611b68debd7 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 18:37:30 +0530 Subject: [PATCH 6/8] test: unmark `SciMLStructures.replace` inference tests as broken --- test/mtkparameters.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mtkparameters.jl b/test/mtkparameters.jl index 4b0f389282..024ffbdb4b 100644 --- a/test/mtkparameters.jl +++ b/test/mtkparameters.jl @@ -194,10 +194,10 @@ end # broken because dependent update functions break inference @test_call target_modules=(ModelingToolkit,) SciMLStructures.replace( portion, ps, ones(length(buffer))) - @test_throws Exception @inferred SciMLStructures.replace( + @inferred SciMLStructures.replace( portion, ps, ones(length(buffer))) @inferred MTKParameters SciMLStructures.replace(portion, ps, ones(length(buffer))) - @test_opt target_modules=(ModelingToolkit,) broken=true SciMLStructures.replace( + @test_opt target_modules=(ModelingToolkit,) SciMLStructures.replace( portion, ps, ones(length(buffer))) @test_call target_modules=(ModelingToolkit,) SciMLStructures.replace!( From 73107312cfdb1cd5cfc0edc806a0f35e81b73fae Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 18:37:50 +0530 Subject: [PATCH 7/8] fix: fix `SciMLStructures.replace` for `Discrete` portion --- src/systems/parameter_buffer.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/systems/parameter_buffer.jl b/src/systems/parameter_buffer.jl index fe46d6a2db..ebff9adf74 100644 --- a/src/systems/parameter_buffer.jl +++ b/src/systems/parameter_buffer.jl @@ -326,7 +326,14 @@ for (Portion, field, recurse) in [(SciMLStructures.Discrete, :discrete, 2) end @eval function SciMLStructures.replace(::$Portion, p::MTKParameters, newvals) - @set! p.$field = split_into_buffers(newvals, p.$field, Val($recurse)) + @set! p.$field = $( + if Portion == SciMLStructures.Discrete + :(SizedVector{length(p.discrete)}(split_into_buffers( + newvals, p.$field, Val($recurse)))) + else + :(split_into_buffers(newvals, p.$field, Val($recurse))) + end + ) if p.dependent_update_oop !== nothing raw = p.dependent_update_oop(p...) @set! p.dependent = split_into_buffers(raw, p.dependent, Val(false)) From 750e82fca5585b5aaff61e7f2c0be0c502d056ea Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 5 Aug 2024 19:46:04 +0530 Subject: [PATCH 8/8] refactor: remove dead clock-related code --- src/systems/clock_inference.jl | 138 ----------------------- src/systems/diffeqs/abstractodesystem.jl | 115 +------------------ src/systems/diffeqs/odesystem.jl | 9 -- 3 files changed, 3 insertions(+), 259 deletions(-) diff --git a/src/systems/clock_inference.jl b/src/systems/clock_inference.jl index dfdef69034..3e5239ab3d 100644 --- a/src/systems/clock_inference.jl +++ b/src/systems/clock_inference.jl @@ -195,141 +195,3 @@ function split_system(ci::ClockInference{S}) where {S} end return tss, inputs, continuous_id, id_to_clock end - -function generate_discrete_affect( - osys::AbstractODESystem, syss, inputs, continuous_id, id_to_clock; - checkbounds = true, - eval_module = @__MODULE__, eval_expression = false) - @static if VERSION < v"1.7" - error("The `generate_discrete_affect` function requires at least Julia 1.7") - end - has_index_cache(osys) && get_index_cache(osys) !== nothing || - error("Hybrid systems require `split = true`") - out = Sym{Any}(:out) - appended_parameters = full_parameters(syss[continuous_id]) - offset = length(appended_parameters) - param_to_idx = Dict{Any, ParameterIndex}(p => parameter_index(osys, p) - for p in appended_parameters) - affect_funs = [] - clocks = TimeDomain[] - for (i, (sys, input)) in enumerate(zip(syss, inputs)) - i == continuous_id && continue - push!(clocks, id_to_clock[i]) - subs = get_substitutions(sys) - assignments = map(s -> Assignment(s.lhs, s.rhs), subs.subs) - let_body = SetArray(!checkbounds, out, rhss(equations(sys))) - let_block = Let(assignments, let_body, false) - needed_cont_to_disc_obs = map(v -> arguments(v)[1], input) - # TODO: filter the needed ones - fullvars = Set{Any}(eq.lhs for eq in observed(sys)) - for s in unknowns(sys) - push!(fullvars, s) - end - needed_disc_to_cont_obs = [] - disc_to_cont_idxs = ParameterIndex[] - for v in inputs[continuous_id] - _v = arguments(v)[1] - if _v in fullvars - push!(needed_disc_to_cont_obs, _v) - push!(disc_to_cont_idxs, param_to_idx[v]) - continue - end - - # If the held quantity is calculated through observed - # it will be shifted forward by 1 - _v = Shift(get_iv(sys), 1)(_v) - if _v in fullvars - push!(needed_disc_to_cont_obs, _v) - push!(disc_to_cont_idxs, param_to_idx[v]) - continue - end - end - append!(appended_parameters, input) - cont_to_disc_obs = build_explicit_observed_function( - osys, - needed_cont_to_disc_obs, - throw = false, - expression = true, - output_type = SVector) - disc_to_cont_obs = build_explicit_observed_function(sys, needed_disc_to_cont_obs, - throw = false, - expression = true, - output_type = SVector, - op = Shift, - ps = reorder_parameters(osys, appended_parameters)) - ni = length(input) - ns = length(unknowns(sys)) - disc = Func( - [ - out, - DestructuredArgs(unknowns(osys)), - DestructuredArgs.(reorder_parameters(osys, full_parameters(osys)))..., - get_iv(sys) - ], - [], - let_block) |> toexpr - cont_to_disc_idxs = [parameter_index(osys, sym) for sym in input] - disc_range = [parameter_index(osys, sym) for sym in unknowns(sys)] - save_expr = :($(SciMLBase.save_discretes!)(integrator, $i)) - empty_disc = isempty(disc_range) - - # @show disc_to_cont_idxs - # @show cont_to_disc_idxs - # @show disc_range - affect! = :(function (integrator) - @unpack u, p, t = integrator - c2d_obs = $cont_to_disc_obs - d2c_obs = $disc_to_cont_obs - # TODO: find a way to do this without allocating - disc_unknowns = [$(parameter_values)(p, i) for i in $disc_range] - disc = $disc - - # Write continuous into to discrete: handles `Sample` - # Write discrete into to continuous - # Update discrete unknowns - - # At a tick, c2d must come first - # state update comes in the middle - # d2c comes last - # @show t - # @show "incoming", p - result = c2d_obs(u, p..., t) - for (val, i) in zip(result, $cont_to_disc_idxs) - $(_set_parameter_unchecked!)(p, val, i; update_dependent = false) - end - $(if !empty_disc - quote - disc(disc_unknowns, u, p..., t) - for (val, i) in zip(disc_unknowns, $disc_range) - $(_set_parameter_unchecked!)(p, val, i; update_dependent = false) - end - end - end) - # @show "after c2d", p - # @show "after state update", p - result = d2c_obs(disc_unknowns, p..., t) - for (val, i) in zip(result, $disc_to_cont_idxs) - $(_set_parameter_unchecked!)(p, val, i; update_dependent = false) - end - - $save_expr - - # @show "after d2c", p - discretes, repack, _ = $(SciMLStructures.canonicalize)( - $(SciMLStructures.Discrete()), p) - repack(discretes) - end) - - push!(affect_funs, affect!) - end - if eval_expression - affects = map(a -> eval_module.eval(toexpr(LiteralExpr(a))), affect_funs) - else - affects = map(affect_funs) do a - drop_expr(RuntimeGeneratedFunction( - eval_module, eval_module, toexpr(LiteralExpr(a)))) - end - end - defaults = Dict{Any, Any}(v => 0.0 for v in Iterators.flatten(inputs)) - return affects, clocks, appended_parameters, defaults -end diff --git a/src/systems/diffeqs/abstractodesystem.jl b/src/systems/diffeqs/abstractodesystem.jl index 1e3aff7106..18ec4e928a 100644 --- a/src/systems/diffeqs/abstractodesystem.jl +++ b/src/systems/diffeqs/abstractodesystem.jl @@ -782,12 +782,6 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap; varlist = collect(map(unwrap, dvs)) missingvars = setdiff(varlist, collect(keys(varmap))) - # Append zeros to the variables which are determined by the initialization system - # This essentially bypasses the check for if initial conditions are defined for DAEs - # since they will be checked in the initialization problem's construction - # TODO: make check for if a DAE cheaper than calculating the mass matrix a second time! - ci = infer_clocks!(ClockInference(TearingState(sys))) - if eltype(parammap) <: Pair parammap = Dict(unwrap(k) => v for (k, v) in todict(parammap)) elseif parammap isa AbstractArray @@ -798,38 +792,9 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap; end end - if has_discrete_subsystems(sys) && get_discrete_subsystems(sys) !== nothing - clockedparammap = Dict() - defs = ModelingToolkit.get_defaults(sys) - for v in ps - v = unwrap(v) - is_discrete_domain(v) || continue - op = operation(v) - if !isa(op, Symbolics.Operator) && parammap != SciMLBase.NullParameters() && - haskey(parammap, v) - error("Initial conditions for discrete variables must be for the past state of the unknown. Instead of providing the condition for $v, provide the condition for $(Shift(iv, -1)(v)).") - end - shiftedv = StructuralTransformations.simplify_shifts(Shift(iv, -1)(v)) - if parammap != SciMLBase.NullParameters() && - (val = get(parammap, shiftedv, nothing)) !== nothing - clockedparammap[v] = val - elseif op isa Shift - root = arguments(v)[1] - haskey(defs, root) || error("Initial condition for $v not provided.") - clockedparammap[v] = defs[root] - end - end - parammap = if parammap == SciMLBase.NullParameters() - clockedparammap - else - merge(parammap, clockedparammap) - end - end - # TODO: make it work with clocks # ModelingToolkit.get_tearing_state(sys) !== nothing => Requires structural_simplify first if sys isa ODESystem && build_initializeprob && (((implicit_dae || !isempty(missingvars)) && - all(==(Continuous), ci.var_domain) && ModelingToolkit.get_tearing_state(sys) !== nothing) || !isempty(initialization_equations(sys))) && t !== nothing if eltype(u0map) <: Number @@ -1010,29 +975,7 @@ function DiffEqBase.ODEProblem{iip, specialize}(sys::AbstractODESystem, u0map = t = tspan !== nothing ? tspan[1] : tspan, check_length, warn_initialize_determined, eval_expression, eval_module, kwargs...) cbs = process_events(sys; callback, eval_expression, eval_module, kwargs...) - inits = [] - if has_discrete_subsystems(sys) && (dss = get_discrete_subsystems(sys)) !== nothing - affects, clocks = ModelingToolkit.generate_discrete_affect( - sys, dss...; eval_expression, eval_module) - discrete_cbs = map(affects, clocks) do affect, clock - @match clock begin - PeriodicClock(dt, _...) => PeriodicCallback(affect, dt; - final_affect = true, initial_affect = true) - &SolverStepClock => DiscreteCallback(Returns(true), affect, - initialize = (c, u, t, integrator) -> affect(integrator)) - _ => error("$clock is not a supported clock type.") - end - end - if cbs === nothing - if length(discrete_cbs) == 1 - cbs = only(discrete_cbs) - else - cbs = CallbackSet(discrete_cbs...) - end - else - cbs = CallbackSet(cbs, discrete_cbs...) - end - end + kwargs = filter_kwargs(kwargs) pt = something(get_metadata(sys), StandardODEProblem()) @@ -1112,40 +1055,14 @@ function DiffEqBase.DDEProblem{iip}(sys::AbstractODESystem, u0map = [], h(p, t) = h_oop(p, t) h(p::MTKParameters, t) = h_oop(p..., t) u0 = h(p, tspan[1]) + cbs = process_events(sys; callback, eval_expression, eval_module, kwargs...) - if has_discrete_subsystems(sys) && (dss = get_discrete_subsystems(sys)) !== nothing - affects, clocks = ModelingToolkit.generate_discrete_affect( - sys, dss...; eval_expression, eval_module) - discrete_cbs = map(affects, clocks) do affect, clock - @match clock begin - PeriodicClock(dt, _...) => PeriodicCallback(affect, dt; - final_affect = true, initial_affect = true) - &SolverStepClock => DiscreteCallback(Returns(true), affect, - initialize = (c, u, t, integrator) -> affect(integrator)) - _ => error("$clock is not a supported clock type.") - end - end - if cbs === nothing - if length(discrete_cbs) == 1 - cbs = only(discrete_cbs) - else - cbs = CallbackSet(discrete_cbs...) - end - else - cbs = CallbackSet(cbs, discrete_cbs) - end - else - svs = nothing - end kwargs = filter_kwargs(kwargs) kwargs1 = (;) if cbs !== nothing kwargs1 = merge(kwargs1, (callback = cbs,)) end - if svs !== nothing - kwargs1 = merge(kwargs1, (disc_saved_values = svs,)) - end DDEProblem{iip}(f, u0, h, tspan, p; kwargs1..., kwargs...) end @@ -1175,40 +1092,14 @@ function DiffEqBase.SDDEProblem{iip}(sys::AbstractODESystem, u0map = [], h(p::MTKParameters, t) = h_oop(p..., t) h(out, p::MTKParameters, t) = h_iip(out, p..., t) u0 = h(p, tspan[1]) + cbs = process_events(sys; callback, eval_expression, eval_module, kwargs...) - if has_discrete_subsystems(sys) && (dss = get_discrete_subsystems(sys)) !== nothing - affects, clocks = ModelingToolkit.generate_discrete_affect( - sys, dss...; eval_expression, eval_module) - discrete_cbs = map(affects, clocks) do affect, clock - @match clock begin - PeriodicClock(dt, _...) => PeriodicCallback(affect, dt; - final_affect = true, initial_affect = true) - &SolverStepClock => DiscreteCallback(Returns(true), affect, - initialize = (c, u, t, integrator) -> affect(integrator)) - _ => error("$clock is not a supported clock type.") - end - end - if cbs === nothing - if length(discrete_cbs) == 1 - cbs = only(discrete_cbs) - else - cbs = CallbackSet(discrete_cbs...) - end - else - cbs = CallbackSet(cbs, discrete_cbs) - end - else - svs = nothing - end kwargs = filter_kwargs(kwargs) kwargs1 = (;) if cbs !== nothing kwargs1 = merge(kwargs1, (callback = cbs,)) end - if svs !== nothing - kwargs1 = merge(kwargs1, (disc_saved_values = svs,)) - end noiseeqs = get_noiseeqs(sys) sparsenoise === nothing && (sparsenoise = get(kwargs, :sparse, false)) diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index 264c00590b..fedc3a4c33 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -401,15 +401,6 @@ function build_explicit_observed_function(sys, ts; dep_vars = scalarize(setdiff(vars, ivs)) obs = param_only ? Equation[] : observed(sys) - if has_discrete_subsystems(sys) && (dss = get_discrete_subsystems(sys)) !== nothing - # each subsystem is topologically sorted independently. We can append the - # equations to override the `lhs ~ 0` equations in `observed(sys)` - syss, _, continuous_id, _... = dss - for (i, subsys) in enumerate(syss) - i == continuous_id && continue - append!(obs, observed(subsys)) - end - end cs = collect_constants(obs) if !isempty(cs) > 0