-
-
Notifications
You must be signed in to change notification settings - Fork 234
Add support for the initializealg argument in SciMLBase callbacks #3144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -867,6 +867,88 @@ end | |
| @test sign.(cos.(3 * (required_crossings_c2 .+ 1e-6))) == sign.(last.(cr2)) | ||
| end | ||
|
|
||
| @testset "Discrete event reinitialization (#3142)" begin | ||
| @connector LiquidPort begin | ||
| p(t)::Float64, [description = "Set pressure in bar", | ||
| guess = 1.01325] | ||
| Vdot(t)::Float64, | ||
| [description = "Volume flow rate in L/min", | ||
| guess = 0.0, | ||
| connect = Flow] | ||
| end | ||
|
|
||
| @mtkmodel PressureSource begin | ||
| @components begin | ||
| port = LiquidPort() | ||
| end | ||
| @parameters begin | ||
| p_set::Float64 = 1.01325, [description = "Set pressure in bar"] | ||
| end | ||
| @equations begin | ||
| port.p ~ p_set | ||
| end | ||
| end | ||
|
|
||
| @mtkmodel BinaryValve begin | ||
| @constants begin | ||
| p_ref::Float64 = 1.0, [description = "Reference pressure drop in bar"] | ||
| ρ_ref::Float64 = 1000.0, [description = "Reference density in kg/m^3"] | ||
| end | ||
| @components begin | ||
| port_in = LiquidPort() | ||
| port_out = LiquidPort() | ||
| end | ||
| @parameters begin | ||
| k_V::Float64 = 1.0, [description = "Valve coefficient in L/min/bar"] | ||
| k_leakage::Float64 = 1e-08, [description = "Leakage coefficient in L/min/bar"] | ||
| ρ::Float64 = 1000.0, [description = "Density in kg/m^3"] | ||
| end | ||
| @variables begin | ||
| S(t)::Float64, [description = "Valve state", guess = 1.0, irreducible = true] | ||
| Δp(t)::Float64, [description = "Pressure difference in bar", guess = 1.0] | ||
| Vdot(t)::Float64, [description = "Volume flow rate in L/min", guess = 1.0] | ||
| end | ||
| @equations begin | ||
| # Port handling | ||
| port_in.Vdot ~ -Vdot | ||
| port_out.Vdot ~ Vdot | ||
| Δp ~ port_in.p - port_out.p | ||
| # System behavior | ||
| D(S) ~ 0.0 | ||
| Vdot ~ S * k_V * sign(Δp) * sqrt(abs(Δp) / p_ref * ρ_ref / ρ) + k_leakage * Δp # softplus alpha function to avoid negative values under the sqrt | ||
| end | ||
| end | ||
|
|
||
| # Test System | ||
| @mtkmodel TestSystem begin | ||
| @components begin | ||
| pressure_source_1 = PressureSource(p_set = 2.0) | ||
| binary_valve_1 = BinaryValve(S = 1.0, k_leakage = 0.0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting the leakage streams to zero will potentially lead to inifite solutions for the value between the valves, because you have "dirichlet" boundary values at the input of the first valve and the output of the second valve. The pressure difference between is distributed based the implicit relationship Vdot = Sf(\Delta p) + k_leakage\Delta p . Thus, there is no clear solution if all "S" and "k_leakage" are 0. I am not sure how the Julia solver will deal with this kind of equation system breakdown. |
||
| binary_valve_2 = BinaryValve(S = 1.0, k_leakage = 0.0) | ||
| pressure_source_2 = PressureSource(p_set = 1.0) | ||
| end | ||
| @equations begin | ||
| connect(pressure_source_1.port, binary_valve_1.port_in) | ||
| connect(binary_valve_1.port_out, binary_valve_2.port_in) | ||
| connect(binary_valve_2.port_out, pressure_source_2.port) | ||
| end | ||
| @discrete_events begin | ||
| [30] => [binary_valve_1.S ~ 0.0, binary_valve_2.Δp ~ 0.0] | ||
| [60] => [ | ||
| binary_valve_1.S ~ 1.0, binary_valve_2.S ~ 0.0, binary_valve_2.Δp ~ 1.0] | ||
| [120] => [binary_valve_1.S ~ 0.0, binary_valve_2.Δp ~ 0.0] | ||
| end | ||
| end | ||
|
|
||
| # Test Simulation | ||
| @mtkbuild sys = TestSystem() | ||
|
|
||
| # Test Simulation | ||
| prob = ODEProblem(sys, [], (0.0, 150.0)) | ||
| sol = solve(prob) | ||
| @test sol[end] == [0.0, 0.0, 0.0] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me suggest a proper set of test conditions until tomorrow ;-). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, if I would test the behavior of the system, I would use the following checks. These numbers were calculated with NonlinearSolve assuming a k_leakage = 1e-08, furthermore I exchanged the valve equation to smooth its behavior. I'll make an extra post on that. |
||
| end | ||
|
|
||
| @testset "Discrete variable timeseries" begin | ||
| @variables x(t) | ||
| @parameters a(t) b(t) c(t) | ||
|
|
@@ -887,3 +969,22 @@ end | |
| @test sol[b] == [2.0, 5.0, 5.0] | ||
| @test sol[c] == [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] | ||
| end | ||
|
|
||
| @testset "Bump" begin | ||
| @variables x(t) [irreducible = true] y(t) [irreducible = true] | ||
| eqs = [x ~ y, D(x) ~ -1] | ||
| cb = [x ~ 0.0] => [x ~ 0, y ~ 1] | ||
| @mtkbuild pend = ODESystem(eqs, t; continuous_events = [cb]) | ||
| prob = ODEProblem(pend, [x => 1], (0.0, 3.0), guesses = [y => x]) | ||
| @test_throws "CheckInit specified but initialization" solve(prob, Rodas5()) | ||
|
|
||
| cb = [x ~ 0.0] => [y ~ 1] | ||
| @mtkbuild pend = ODESystem(eqs, t; continuous_events = [cb]) | ||
| prob = ODEProblem(pend, [x => 1], (0.0, 3.0), guesses = [y => x]) | ||
| @test_broken !SciMLBase.successful_retcode(solve(prob, Rodas5())) | ||
|
|
||
| cb = [x ~ 0.0] => [x ~ 1, y ~ 1] | ||
| @mtkbuild pend = ODESystem(eqs, t; continuous_events = [cb]) | ||
| prob = ODEProblem(pend, [x => 1], (0.0, 3.0), guesses = [y => x]) | ||
| @test all(≈(0.0; atol = 1e-9), solve(prob, Rodas5())[[x, y]][end]) | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smooth version of this equation