|
1 | 1 | using ModelingToolkit, SymbolicIndexingInterface, SciMLBase
|
2 | 2 | using ModelingToolkit: t_nounits as t, D_nounits as D
|
3 | 3 |
|
4 |
| -@parameters a b |
5 |
| -@variables x(t)=1.0 y(t)=2.0 xy(t) |
6 |
| -eqs = [D(x) ~ a * y + t, D(y) ~ b * t] |
7 |
| -@named odesys = ODESystem(eqs, t, [x, y], [a, b]; observed = [xy ~ x + y]) |
8 |
| - |
9 |
| -@test all(is_variable.((odesys,), [x, y, 1, 2, :x, :y])) |
10 |
| -@test all(.!is_variable.((odesys,), [a, b, t, 3, 0, :a, :b])) |
11 |
| -@test variable_index.((odesys,), [x, y, a, b, t, 1, 2, :x, :y, :a, :b]) == |
12 |
| - [1, 2, nothing, nothing, nothing, 1, 2, 1, 2, nothing, nothing] |
13 |
| -@test isequal(variable_symbols(odesys), [x, y]) |
14 |
| -@test all(is_parameter.((odesys,), [a, b, 1, 2, :a, :b])) |
15 |
| -@test all(.!is_parameter.((odesys,), [x, y, t, 3, 0, :x, :y])) |
16 |
| -@test parameter_index.((odesys,), [x, y, a, b, t, 1, 2, :x, :y, :a, :b]) == |
17 |
| - [nothing, nothing, 1, 2, nothing, 1, 2, nothing, nothing, 1, 2] |
18 |
| -@test isequal(parameter_symbols(odesys), [a, b]) |
19 |
| -@test all(is_independent_variable.((odesys,), [t, :t])) |
20 |
| -@test all(.!is_independent_variable.((odesys,), [x, y, a, :x, :y, :a])) |
21 |
| -@test isequal(independent_variable_symbols(odesys), [t]) |
22 |
| -@test is_time_dependent(odesys) |
23 |
| -@test constant_structure(odesys) |
24 |
| -@test !isempty(default_values(odesys)) |
25 |
| -@test default_values(odesys)[x] == 1.0 |
26 |
| -@test default_values(odesys)[y] == 2.0 |
27 |
| -@test isequal(default_values(odesys)[xy], x + y) |
28 |
| - |
29 |
| -@named odesys = ODESystem( |
30 |
| - eqs, t, [x, y], [a, b]; defaults = [xy => 3.0], observed = [xy ~ x + y]) |
31 |
| -@test default_values(odesys)[xy] == 3.0 |
32 |
| - |
33 |
| -@variables x y z |
34 |
| -@parameters σ ρ β |
35 |
| - |
36 |
| -eqs = [0 ~ σ * (y - x), |
37 |
| - 0 ~ x * (ρ - z) - y, |
38 |
| - 0 ~ x * y - β * z] |
39 |
| -@named ns = NonlinearSystem(eqs, [x, y, z], [σ, ρ, β]) |
40 |
| - |
41 |
| -@test !is_time_dependent(ns) |
42 |
| - |
43 |
| -@parameters x |
44 |
| -@variables u(..) |
45 |
| -Dxx = Differential(x)^2 |
46 |
| -Dtt = Differential(t)^2 |
47 |
| -Dt = D |
48 |
| - |
49 |
| -#2D PDE |
50 |
| -C = 1 |
51 |
| -eq = Dtt(u(t, x)) ~ C^2 * Dxx(u(t, x)) |
52 |
| - |
53 |
| -# Initial and boundary conditions |
54 |
| -bcs = [u(t, 0) ~ 0.0,# for all t > 0 |
55 |
| - u(t, 1) ~ 0.0,# for all t > 0 |
56 |
| - u(0, x) ~ x * (1.0 - x), #for all 0 < x < 1 |
57 |
| - Dt(u(0, x)) ~ 0.0] #for all 0 < x < 1] |
58 |
| - |
59 |
| -# Space and time domains |
60 |
| -domains = [t ∈ (0.0, 1.0), |
61 |
| - x ∈ (0.0, 1.0)] |
62 |
| - |
63 |
| -@named pde_system = PDESystem(eq, bcs, domains, [t, x], [u]) |
64 |
| - |
65 |
| -@test pde_system.ps == SciMLBase.NullParameters() |
66 |
| -@test parameter_symbols(pde_system) == [] |
67 |
| - |
68 |
| -@parameters x |
69 |
| -@constants h = 1 |
70 |
| -@variables u(..) |
71 |
| -Dt = D |
72 |
| -Dxx = Differential(x)^2 |
73 |
| -eq = Dt(u(t, x)) ~ h * Dxx(u(t, x)) |
74 |
| -bcs = [u(0, x) ~ -h * x * (x - 1) * sin(x), |
75 |
| - u(t, 0) ~ 0, u(t, 1) ~ 0] |
76 |
| - |
77 |
| -domains = [t ∈ (0.0, 1.0), |
78 |
| - x ∈ (0.0, 1.0)] |
79 |
| - |
80 |
| -analytic = [u(t, x) ~ -h * x * (x - 1) * sin(x) * exp(-2 * h * t)] |
81 |
| -analytic_function = (ps, t, x) -> -ps[1] * x * (x - 1) * sin(x) * exp(-2 * ps[1] * t) |
82 |
| - |
83 |
| -@named pdesys = PDESystem(eq, bcs, domains, [t, x], [u], [h], analytic = analytic) |
84 |
| - |
85 |
| -@test isequal(pdesys.ps, [h]) |
86 |
| -@test isequal(parameter_symbols(pdesys), [h]) |
87 |
| -@test isequal(parameters(pdesys), [h]) |
| 4 | +@testset "ODESystem" begin |
| 5 | + @parameters a b |
| 6 | + @variables x(t)=1.0 y(t)=2.0 xy(t) |
| 7 | + eqs = [D(x) ~ a * y + t, D(y) ~ b * t] |
| 8 | + @named odesys = ODESystem(eqs, t, [x, y], [a, b]; observed = [xy ~ x + y]) |
| 9 | + |
| 10 | + @test all(is_variable.((odesys,), [x, y, 1, 2, :x, :y])) |
| 11 | + @test all(.!is_variable.((odesys,), [a, b, t, 3, 0, :a, :b])) |
| 12 | + @test variable_index.((odesys,), [x, y, a, b, t, 1, 2, :x, :y, :a, :b]) == |
| 13 | + [1, 2, nothing, nothing, nothing, 1, 2, 1, 2, nothing, nothing] |
| 14 | + @test isequal(variable_symbols(odesys), [x, y]) |
| 15 | + @test all(is_parameter.((odesys,), [a, b, 1, 2, :a, :b])) |
| 16 | + @test all(.!is_parameter.((odesys,), [x, y, t, 3, 0, :x, :y])) |
| 17 | + @test parameter_index.((odesys,), [x, y, a, b, t, 1, 2, :x, :y, :a, :b]) == |
| 18 | + [nothing, nothing, 1, 2, nothing, 1, 2, nothing, nothing, 1, 2] |
| 19 | + @test isequal(parameter_symbols(odesys), [a, b]) |
| 20 | + @test all(is_independent_variable.((odesys,), [t, :t])) |
| 21 | + @test all(.!is_independent_variable.((odesys,), [x, y, a, :x, :y, :a])) |
| 22 | + @test isequal(independent_variable_symbols(odesys), [t]) |
| 23 | + @test is_time_dependent(odesys) |
| 24 | + @test constant_structure(odesys) |
| 25 | + @test !isempty(default_values(odesys)) |
| 26 | + @test default_values(odesys)[x] == 1.0 |
| 27 | + @test default_values(odesys)[y] == 2.0 |
| 28 | + @test isequal(default_values(odesys)[xy], x + y) |
| 29 | + |
| 30 | + @named odesys = ODESystem( |
| 31 | + eqs, t, [x, y], [a, b]; defaults = [xy => 3.0], observed = [xy ~ x + y]) |
| 32 | + @test default_values(odesys)[xy] == 3.0 |
| 33 | + pobs = parameter_observed(odesys, a + b) |
| 34 | + @test pobs.timeseries_idx === nothing |
| 35 | + @test pobs.observed_fn( |
| 36 | + ModelingToolkit.MTKParameters(odesys, [a => 1.0, b => 2.0]), 0.0) ≈ 3.0 |
| 37 | + pobs = parameter_observed(odesys, [a + b, a - b]) |
| 38 | + @test pobs.timeseries_idx === nothing |
| 39 | + @test pobs.observed_fn( |
| 40 | + ModelingToolkit.MTKParameters(odesys, [a => 1.0, b => 2.0]), 0.0) ≈ [3.0, -1.0] |
| 41 | +end |
| 42 | + |
| 43 | +@testset "Clock system" begin |
| 44 | + dt = 0.1 |
| 45 | + dt2 = 0.2 |
| 46 | + @variables x(t)=0 y(t)=0 u(t)=0 yd1(t)=0 ud1(t)=0 yd2(t)=0 ud2(t)=0 |
| 47 | + @parameters kp=1 r=1 |
| 48 | + |
| 49 | + eqs = [ |
| 50 | + # controller (time discrete part `dt=0.1`) |
| 51 | + yd1 ~ Sample(t, dt)(y) |
| 52 | + ud1 ~ kp * (r - yd1) |
| 53 | + # controller (time discrete part `dt=0.2`) |
| 54 | + yd2 ~ Sample(t, dt2)(y) |
| 55 | + ud2 ~ kp * (r - yd2) |
| 56 | + |
| 57 | + # plant (time continuous part) |
| 58 | + u ~ Hold(ud1) + Hold(ud2) |
| 59 | + D(x) ~ -x + u |
| 60 | + y ~ x] |
| 61 | + |
| 62 | + @mtkbuild cl = ODESystem(eqs, t) |
| 63 | + ts_params = [ |
| 64 | + Hold(ud1), Hold(ud2), Sample(t, dt)(y), Sample(t, dt2)(y), ud1, ud2, yd1, yd2] |
| 65 | + ts_idxs = [1, 2, 1, 2, 1, 2, 1, 2] |
| 66 | + @test all(Base.Fix1(is_timeseries_parameter, cl), |
| 67 | + [Hold(ud1), Hold(ud2), Sample(t, dt)(y), Sample(t, dt2)(y), ud1, ud2, yd1, yd2]) |
| 68 | + for (ts_param, ts_idx) in zip(ts_params[1:4], ts_idxs[1:4]) |
| 69 | + @test timeseries_parameter_index(cl, ts_param).timeseries_idx == ts_idx |
| 70 | + end |
| 71 | + ps = ModelingToolkit.MTKParameters(cl, [kp => 1.0, Sample(t, dt)(y) => 1.0]) |
| 72 | + pobs = parameter_observed(cl, Shift(t, 1)(yd1)) |
| 73 | + @test pobs.timeseries_idx == 1 |
| 74 | + @test pobs.observed_fn(ps, 0.0) == 1.0 |
| 75 | + pobs = parameter_observed(cl, [Shift(t, 1)(yd1), Shift(t, 1)(ud1)]) |
| 76 | + @test pobs.timeseries_idx == 1 |
| 77 | + @test pobs.observed_fn(ps, 0.0) == [1.0, 0.0] |
| 78 | + pobs = parameter_observed(cl, [Shift(t, 1)(yd1), Shift(t, 1)(ud2)]) |
| 79 | + @test pobs.timeseries_idx === nothing |
| 80 | + @test pobs.observed_fn(ps, 0.0) == [1.0, 1.0] |
| 81 | +end |
| 82 | + |
| 83 | +@testset "Nonlinear system" begin |
| 84 | + @variables x y z |
| 85 | + @parameters σ ρ β |
| 86 | + |
| 87 | + eqs = [0 ~ σ * (y - x), |
| 88 | + 0 ~ x * (ρ - z) - y, |
| 89 | + 0 ~ x * y - β * z] |
| 90 | + @named ns = NonlinearSystem(eqs, [x, y, z], [σ, ρ, β]) |
| 91 | + ns = complete(ns) |
| 92 | + @test !is_time_dependent(ns) |
| 93 | + ps = ModelingToolkit.MTKParameters(ns, [σ => 1.0, ρ => 2.0, β => 3.0]) |
| 94 | + pobs = parameter_observed(ns, σ + ρ) |
| 95 | + @test pobs.timeseries_idx === nothing |
| 96 | + @test pobs.observed_fn(ps) == 3.0 |
| 97 | + pobs = parameter_observed(ns, [σ + ρ, ρ + β]) |
| 98 | + @test pobs.timeseries_idx === nothing |
| 99 | + @test pobs.observed_fn(ps) == [3.0, 5.0] |
| 100 | +end |
| 101 | + |
| 102 | +@testset "PDESystem" begin |
| 103 | + @parameters x |
| 104 | + @variables u(..) |
| 105 | + Dxx = Differential(x)^2 |
| 106 | + Dtt = Differential(t)^2 |
| 107 | + Dt = D |
| 108 | + |
| 109 | + #2D PDE |
| 110 | + C = 1 |
| 111 | + eq = Dtt(u(t, x)) ~ C^2 * Dxx(u(t, x)) |
| 112 | + |
| 113 | + # Initial and boundary conditions |
| 114 | + bcs = [u(t, 0) ~ 0.0,# for all t > 0 |
| 115 | + u(t, 1) ~ 0.0,# for all t > 0 |
| 116 | + u(0, x) ~ x * (1.0 - x), #for all 0 < x < 1 |
| 117 | + Dt(u(0, x)) ~ 0.0] #for all 0 < x < 1] |
| 118 | + |
| 119 | + # Space and time domains |
| 120 | + domains = [t ∈ (0.0, 1.0), |
| 121 | + x ∈ (0.0, 1.0)] |
| 122 | + |
| 123 | + @named pde_system = PDESystem(eq, bcs, domains, [t, x], [u]) |
| 124 | + |
| 125 | + @test pde_system.ps == SciMLBase.NullParameters() |
| 126 | + @test parameter_symbols(pde_system) == [] |
| 127 | + |
| 128 | + @parameters x |
| 129 | + @constants h = 1 |
| 130 | + @variables u(..) |
| 131 | + Dt = D |
| 132 | + Dxx = Differential(x)^2 |
| 133 | + eq = Dt(u(t, x)) ~ h * Dxx(u(t, x)) |
| 134 | + bcs = [u(0, x) ~ -h * x * (x - 1) * sin(x), |
| 135 | + u(t, 0) ~ 0, u(t, 1) ~ 0] |
| 136 | + |
| 137 | + domains = [t ∈ (0.0, 1.0), |
| 138 | + x ∈ (0.0, 1.0)] |
| 139 | + |
| 140 | + analytic = [u(t, x) ~ -h * x * (x - 1) * sin(x) * exp(-2 * h * t)] |
| 141 | + analytic_function = (ps, t, x) -> -ps[1] * x * (x - 1) * sin(x) * exp(-2 * ps[1] * t) |
| 142 | + |
| 143 | + @named pdesys = PDESystem(eq, bcs, domains, [t, x], [u], [h], analytic = analytic) |
| 144 | + |
| 145 | + @test isequal(pdesys.ps, [h]) |
| 146 | + @test isequal(parameter_symbols(pdesys), [h]) |
| 147 | + @test isequal(parameters(pdesys), [h]) |
| 148 | +end |
0 commit comments