@@ -1440,3 +1440,83 @@ end
14401440 @mtkcompile sys = MWE ()
14411441 @test_nowarn ODEProblem (sys, [], (0.0 , 1.0 ))
14421442end
1443+
1444+
1445+ @testset " Automatic inference of `discrete_parameters`" begin
1446+
1447+ # Basic case, checks for both types of events (in combination and isolation).
1448+ let
1449+ # Creates models with continuous, discrete, or both types of events
1450+ @variables X (t) Y (t)
1451+ @parameters p1 (t) p2 (t) d1 d2
1452+ eqs = [
1453+ D (X) ~ p1 - d1* X,
1454+ D (Y) ~ p2 - d2* Y
1455+ ]
1456+ cevent = [[t ~ 1.0 ] => [p1 ~ 2 * Pre (p1)]]
1457+ devent = [[1.0 ] => [p2 ~ 2 * Pre (p2)]]
1458+ @mtkcompile sys_c = System (eqs, t; continuous_events = cevent)
1459+ @mtkcompile sys_d = System (eqs, t; discrete_events = devent)
1460+ @mtkcompile sys_cd = System (eqs, t; discrete_events = devent, continuous_events = cevent)
1461+
1462+ # Simulates them all. They should start at steady states (X = Y = 1).
1463+ # If event triggers, the variable should become 2 (after some wait).
1464+ sim_cond = [X => 1.0 , Y => 1.0 , p1 => 1.0 , p2 => 1.0 , d1 => 1.0 , d2 => 1.0 ]
1465+ prob_c = ODEProblem (sys_c, sim_cond, 100.0 )
1466+ prob_d = ODEProblem (sys_d, sim_cond, 100.0 )
1467+ prob_cd = ODEProblem (sys_cd, sim_cond, 100.0 )
1468+ sol_c = solve (prob_c, Rosenbrock23 ())
1469+ sol_d = solve (prob_d, Rosenbrock23 ())
1470+ sol_cd = solve (prob_cd, Rosenbrock23 ())
1471+ @test sol_c[X][end ] ≈ 2.0 atol = 1e-3 rtol = 1e-3
1472+ @test sol_c[Y][end ] ≈ 1.0 atol = 1e-3 rtol = 1e-3
1473+ @test sol_d[X][end ] ≈ 1.0 atol = 1e-3 rtol = 1e-3
1474+ @test sol_d[Y][end ] ≈ 2.0 atol = 1e-3 rtol = 1e-3
1475+ @test sol_cd[Y][end ] ≈ 2.0 atol = 1e-3 rtol = 1e-3
1476+ @test sol_cd[Y][end ] ≈ 2.0 atol = 1e-3 rtol = 1e-3
1477+ end
1478+
1479+ # Complicated and multiple events.
1480+ # All should trigger. Modified parameters (and only those) should get non-zero values.
1481+ let
1482+ # Declares the model. `k` parameters depend on time, but should not actually be updated.
1483+ us = @variables X1 (t) X2 (t) X3 (t) X4 (t) X5 (t)
1484+ ps = @parameters p1 (t) p2 (t) p3 (t) p4 (t) p5 (t) k1 (t) k2 (t) k3 (t) k4 (t) k5 (t) d1 d2 d3 d4 d5
1485+ eqs = [
1486+ D (X1) ~ p1 + k1 - d1* X1,
1487+ D (X2) ~ p2 + k2 - d2* X2,
1488+ D (X3) ~ p3 + k3 - d3* X3,
1489+ D (X4) ~ p4 + k4 - d4* X4,
1490+ D (X5) ~ p4 + k4 - d4* X5,
1491+ ]
1492+ cevents = [[t + d1 + k1 ~ 0.5 ] => [Pre (X1)* (p1 + 5 + Pre (X2)) + Pre (k1) ~ Pre (3 X2 + k2)]]
1493+ devents = [
1494+ 2.0 => [exp (p2 + Pre (p2)) ~ 5.0 ],
1495+ [1.0 ] => [(4 + Pre (k2) + Pre (k4) + Pre (k3))^ 3 + exp (1 + Pre (k3)) ~ (3 + p3 + Pre (k2))^ 3 ],
1496+ (t == 1.5 ) => [
1497+ Pre (k2) + Pre (k3) ~ p4 * (2 + Pre (k1)) + 3 ,
1498+ Pre (p5) + 2 + 3 Pre (k4) + Pre (p5) ~ exp (p5)
1499+ ]
1500+ ]
1501+ @mtkcompile sys = System (eqs, t, us, ps; continuous_events = cevents, discrete_events = devents)
1502+
1503+ # Simulates system so that all events trigger.
1504+ sim_cond = [
1505+ X1 => 1.0 , X2 => 1.0 , X3 => 1.0 , X4 => 1.0 , X5 => 1.0 ,
1506+ p1 => 0.0 , p2 => 0.0 , p3 => 0.0 , p4 => 0.0 , p5 => 0.0 ,
1507+ k1 => 0.0 , k2 => 0.0 , k3 => 0.0 , k4 => 0.0 , k5 => 0.0 ,
1508+ d1 => 0.0 , d2 => 0.0 , d3 => 0.0 , d4 => 0.0 , d5 => 0.0
1509+ ]
1510+ prob = ODEProblem (sys, sim_cond, 3.0 )
1511+ sol = solve (prob, tstops = [1.5 ])
1512+
1513+ # Check that the correct parameters have been modified.
1514+ @test sol. ps[p1][end ] != 0.0
1515+ @test sol. ps[p2][end ] != 0.0
1516+ @test sol. ps[p3][end ] != 0.0
1517+ @test sol. ps[p4][end ] != 0.0
1518+ @test sol. ps[p5][end ] != 0.0
1519+ @test sol. ps[k1] == sol. ps[k2] == sol. ps[k3] == sol. ps[k4] == sol. ps[k5] == 0.0
1520+ @test sol. ps[d1] == sol. ps[d2] == sol. ps[d3] == sol. ps[d4] == sol. ps[d5] == 0.0
1521+ end
1522+ end
0 commit comments