Skip to content

Commit 89a375a

Browse files
committed
units for change of variables
1 parent 20b6035 commit 89a375a

File tree

3 files changed

+139
-110
lines changed

3 files changed

+139
-110
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,23 @@ function change_independent_variable(
126126
# Set up intermediate and final variables for the transformation
127127
iv1name = nameof(iv1) # e.g. :t
128128
iv2name = nameof(operation(iv2_of_iv1)) # e.g. :u
129-
iv2, = @independent_variables $iv2name # e.g. u
130-
iv1_of_iv2, = GlobalScope.(@variables $iv1name(iv2)) # inverse, e.g. t(u), global because iv1 has no namespacing in sys
131129
D1 = Differential(iv1) # e.g. d/d(t)
132-
div2_of_iv1 = GlobalScope(default_toterm(D1(iv2_of_iv1))) # e.g. uˍt(t)
130+
131+
# construct new terms, e.g:
132+
# iv2 -> u
133+
# iv1_of_iv2 -> t(u), (inverse, global because iv1 has no namespacing in sys)
134+
# div2_of_iv1 -> uˍt(t)
135+
iv2_unit = getmetadata(iv2_of_iv1, VariableUnit, nothing)
136+
if isnothing(iv2_unit)
137+
iv2, = @independent_variables $iv2name
138+
iv1_of_iv2, = GlobalScope.(@variables $iv1name(iv2))
139+
div2_of_iv1 = GlobalScope(default_toterm(D1(iv2_of_iv1)))
140+
else
141+
iv2, = @independent_variables $iv2name [unit = iv2_unit]
142+
iv1_of_iv2, = GlobalScope.(@variables $iv1name(iv2) [unit = get_unit(iv1)])
143+
div2_of_iv1 = GlobalScope(diff2term_with_unit(D1(iv2_of_iv1), iv1))
144+
end
145+
133146
div2_of_iv2 = substitute(div2_of_iv1, iv1 => iv2) # e.g. uˍt(u)
134147
div2_of_iv2_of_iv1 = substitute(div2_of_iv2, iv2 => iv2_of_iv1) # e.g. uˍt(u(t))
135148

test/basic_transformations.jl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ModelingToolkit, OrdinaryDiffEq, DataInterpolations, Test
1+
using ModelingToolkit, OrdinaryDiffEq, DataInterpolations, DynamicQuantities, Test
22

33
@independent_variables t
44
D = Differential(t)
@@ -215,3 +215,19 @@ end
215215
M = ODESystem([D(x(t)) ~ x(t - 1)], t; name = :M)
216216
@test_throws "DDE" change_independent_variable(M, x(t))
217217
end
218+
219+
@testset "Change independent variable w/ units (free fall with 2nd order horizontal equation)" begin
220+
@independent_variables t_units [unit = u"s"]
221+
D_units = Differential(t_units)
222+
@variables x(t_units) [unit = u"m"] y(t_units) [unit = u"m"]
223+
@parameters g = 9.81 [unit = u"m * s^-2"] # gravitational acceleration
224+
Mt = ODESystem([D_units(D_units(y)) ~ -g, D_units(D_units(x)) ~ 0], t_units; name = :M) # gives (x, y) as function of t, ...
225+
Mx = change_independent_variable(Mt, x; add_old_diff = true) # ... but we want y as a function of x
226+
Mx = structural_simplify(Mx; allow_symbolic = true)
227+
Dx = Differential(Mx.x)
228+
u0 = [Mx.y => 0.0, Dx(Mx.y) => 1.0, Mx.t_units => 0.0, Mx.xˍt_units => 10.0]
229+
prob = ODEProblem(Mx, u0, (0.0, 20.0), []) # 1 = dy/dx = (dy/dt)/(dx/dt) means equal initial horizontal and vertical velocities
230+
sol = solve(prob, Tsit5(); reltol = 1e-5)
231+
# compare to analytical solution (x(t) = v*t, y(t) = v*t - g*t^2/2)
232+
@test all(isapprox.(sol[Mx.y], sol[Mx.x - g * (Mx.t_units)^2 / 2]; atol = 1e-10))
233+
end

test/runtests.jl

Lines changed: 106 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -25,121 +25,121 @@ end
2525
@time begin
2626
if GROUP == "All" || GROUP == "InterfaceI"
2727
@testset "InterfaceI" begin
28-
# @safetestset "Linear Algebra Test" include("linalg.jl")
29-
# @safetestset "AbstractSystem Test" include("abstractsystem.jl")
30-
# @safetestset "Variable Scope Tests" include("variable_scope.jl")
31-
# @safetestset "Symbolic Parameters Test" include("symbolic_parameters.jl")
32-
# @safetestset "Parsing Test" include("variable_parsing.jl")
33-
# @safetestset "Simplify Test" include("simplify.jl")
34-
# @safetestset "Direct Usage Test" include("direct.jl")
35-
# @safetestset "System Linearity Test" include("linearity.jl")
36-
# @safetestset "Input Output Test" include("input_output_handling.jl")
37-
# @safetestset "Clock Test" include("clock.jl")
38-
# @safetestset "ODESystem Test" include("odesystem.jl")
39-
# @safetestset "Dynamic Quantities Test" include("dq_units.jl")
40-
# @safetestset "Unitful Quantities Test" include("units.jl")
41-
# @safetestset "Mass Matrix Test" include("mass_matrix.jl")
42-
# @safetestset "Reduction Test" include("reduction.jl")
43-
# @safetestset "Split Parameters Test" include("split_parameters.jl")
44-
# @safetestset "StaticArrays Test" include("static_arrays.jl")
45-
# @safetestset "Components Test" include("components.jl")
46-
# @safetestset "Model Parsing Test" include("model_parsing.jl")
47-
# @safetestset "Error Handling" include("error_handling.jl")
48-
# @safetestset "StructuralTransformations" include("structural_transformation/runtests.jl")
28+
@safetestset "Linear Algebra Test" include("linalg.jl")
29+
@safetestset "AbstractSystem Test" include("abstractsystem.jl")
30+
@safetestset "Variable Scope Tests" include("variable_scope.jl")
31+
@safetestset "Symbolic Parameters Test" include("symbolic_parameters.jl")
32+
@safetestset "Parsing Test" include("variable_parsing.jl")
33+
@safetestset "Simplify Test" include("simplify.jl")
34+
@safetestset "Direct Usage Test" include("direct.jl")
35+
@safetestset "System Linearity Test" include("linearity.jl")
36+
@safetestset "Input Output Test" include("input_output_handling.jl")
37+
@safetestset "Clock Test" include("clock.jl")
38+
@safetestset "ODESystem Test" include("odesystem.jl")
39+
@safetestset "Dynamic Quantities Test" include("dq_units.jl")
40+
@safetestset "Unitful Quantities Test" include("units.jl")
41+
@safetestset "Mass Matrix Test" include("mass_matrix.jl")
42+
@safetestset "Reduction Test" include("reduction.jl")
43+
@safetestset "Split Parameters Test" include("split_parameters.jl")
44+
@safetestset "StaticArrays Test" include("static_arrays.jl")
45+
@safetestset "Components Test" include("components.jl")
46+
@safetestset "Model Parsing Test" include("model_parsing.jl")
47+
@safetestset "Error Handling" include("error_handling.jl")
48+
@safetestset "StructuralTransformations" include("structural_transformation/runtests.jl")
4949
@safetestset "Basic transformations" include("basic_transformations.jl")
50-
# @safetestset "State Selection Test" include("state_selection.jl")
51-
# @safetestset "Symbolic Event Test" include("symbolic_events.jl")
52-
# @safetestset "Stream Connect Test" include("stream_connectors.jl")
53-
# @safetestset "Domain Connect Test" include("domain_connectors.jl")
54-
# @safetestset "Lowering Integration Test" include("lowering_solving.jl")
55-
# @safetestset "Dependency Graph Test" include("dep_graphs.jl")
56-
# @safetestset "Function Registration Test" include("function_registration.jl")
57-
# @safetestset "Precompiled Modules Test" include("precompile_test.jl")
58-
# @safetestset "DAE Jacobians Test" include("dae_jacobian.jl")
59-
# @safetestset "Jacobian Sparsity" include("jacobiansparsity.jl")
60-
# @safetestset "Modelingtoolkitize Test" include("modelingtoolkitize.jl")
61-
# @safetestset "FuncAffect Test" include("funcaffect.jl")
62-
# @safetestset "Constants Test" include("constants.jl")
63-
# @safetestset "Parameter Dependency Test" include("parameter_dependencies.jl")
64-
# @safetestset "Equation Type Accessors Test" include("equation_type_accessors.jl")
65-
# @safetestset "System Accessor Functions Test" include("accessor_functions.jl")
66-
# @safetestset "Equations with complex values" include("complex.jl")
50+
@safetestset "State Selection Test" include("state_selection.jl")
51+
@safetestset "Symbolic Event Test" include("symbolic_events.jl")
52+
@safetestset "Stream Connect Test" include("stream_connectors.jl")
53+
@safetestset "Domain Connect Test" include("domain_connectors.jl")
54+
@safetestset "Lowering Integration Test" include("lowering_solving.jl")
55+
@safetestset "Dependency Graph Test" include("dep_graphs.jl")
56+
@safetestset "Function Registration Test" include("function_registration.jl")
57+
@safetestset "Precompiled Modules Test" include("precompile_test.jl")
58+
@safetestset "DAE Jacobians Test" include("dae_jacobian.jl")
59+
@safetestset "Jacobian Sparsity" include("jacobiansparsity.jl")
60+
@safetestset "Modelingtoolkitize Test" include("modelingtoolkitize.jl")
61+
@safetestset "FuncAffect Test" include("funcaffect.jl")
62+
@safetestset "Constants Test" include("constants.jl")
63+
@safetestset "Parameter Dependency Test" include("parameter_dependencies.jl")
64+
@safetestset "Equation Type Accessors Test" include("equation_type_accessors.jl")
65+
@safetestset "System Accessor Functions Test" include("accessor_functions.jl")
66+
@safetestset "Equations with complex values" include("complex.jl")
6767
end
6868
end
6969

70-
# if GROUP == "All" || GROUP == "Initialization"
71-
# @safetestset "Guess Propagation" include("guess_propagation.jl")
72-
# @safetestset "Hierarchical Initialization Equations" include("hierarchical_initialization_eqs.jl")
73-
# @safetestset "InitializationSystem Test" include("initializationsystem.jl")
74-
# @safetestset "Initial Values Test" include("initial_values.jl")
75-
# end
70+
if GROUP == "All" || GROUP == "Initialization"
71+
@safetestset "Guess Propagation" include("guess_propagation.jl")
72+
@safetestset "Hierarchical Initialization Equations" include("hierarchical_initialization_eqs.jl")
73+
@safetestset "InitializationSystem Test" include("initializationsystem.jl")
74+
@safetestset "Initial Values Test" include("initial_values.jl")
75+
end
7676

77-
# if GROUP == "All" || GROUP == "InterfaceII"
78-
# @testset "InterfaceII" begin
79-
# @safetestset "Code Generation Test" include("code_generation.jl")
80-
# @safetestset "IndexCache Test" include("index_cache.jl")
81-
# @safetestset "Variable Utils Test" include("variable_utils.jl")
82-
# @safetestset "Variable Metadata Test" include("test_variable_metadata.jl")
83-
# @safetestset "OptimizationSystem Test" include("optimizationsystem.jl")
84-
# @safetestset "Discrete System" include("discrete_system.jl")
85-
# @safetestset "Implicit Discrete System" include("implicit_discrete_system.jl")
86-
# @safetestset "SteadyStateSystem Test" include("steadystatesystems.jl")
87-
# @safetestset "SDESystem Test" include("sdesystem.jl")
88-
# @safetestset "DDESystem Test" include("dde.jl")
89-
# @safetestset "NonlinearSystem Test" include("nonlinearsystem.jl")
90-
# @safetestset "SCCNonlinearProblem Test" include("scc_nonlinear_problem.jl")
91-
# @safetestset "PDE Construction Test" include("pdesystem.jl")
92-
# @safetestset "JumpSystem Test" include("jumpsystem.jl")
93-
# @safetestset "Optimal Control + Constraints Tests" include("optimal_control.jl")
94-
# @safetestset "print_tree" include("print_tree.jl")
95-
# @safetestset "Constraints Test" include("constraints.jl")
96-
# @safetestset "IfLifting Test" include("if_lifting.jl")
97-
# @safetestset "Analysis Points Test" include("analysis_points.jl")
98-
# @safetestset "Causal Variables Connection Test" include("causal_variables_connection.jl")
99-
# @safetestset "Debugging Test" include("debugging.jl")
100-
# @safetestset "Namespacing test" include("namespacing.jl")
101-
# @safetestset "Subsystem replacement" include("substitute_component.jl")
102-
# end
103-
# end
77+
if GROUP == "All" || GROUP == "InterfaceII"
78+
@testset "InterfaceII" begin
79+
@safetestset "Code Generation Test" include("code_generation.jl")
80+
@safetestset "IndexCache Test" include("index_cache.jl")
81+
@safetestset "Variable Utils Test" include("variable_utils.jl")
82+
@safetestset "Variable Metadata Test" include("test_variable_metadata.jl")
83+
@safetestset "OptimizationSystem Test" include("optimizationsystem.jl")
84+
@safetestset "Discrete System" include("discrete_system.jl")
85+
@safetestset "Implicit Discrete System" include("implicit_discrete_system.jl")
86+
@safetestset "SteadyStateSystem Test" include("steadystatesystems.jl")
87+
@safetestset "SDESystem Test" include("sdesystem.jl")
88+
@safetestset "DDESystem Test" include("dde.jl")
89+
@safetestset "NonlinearSystem Test" include("nonlinearsystem.jl")
90+
@safetestset "SCCNonlinearProblem Test" include("scc_nonlinear_problem.jl")
91+
@safetestset "PDE Construction Test" include("pdesystem.jl")
92+
@safetestset "JumpSystem Test" include("jumpsystem.jl")
93+
@safetestset "Optimal Control + Constraints Tests" include("optimal_control.jl")
94+
@safetestset "print_tree" include("print_tree.jl")
95+
@safetestset "Constraints Test" include("constraints.jl")
96+
@safetestset "IfLifting Test" include("if_lifting.jl")
97+
@safetestset "Analysis Points Test" include("analysis_points.jl")
98+
@safetestset "Causal Variables Connection Test" include("causal_variables_connection.jl")
99+
@safetestset "Debugging Test" include("debugging.jl")
100+
@safetestset "Namespacing test" include("namespacing.jl")
101+
@safetestset "Subsystem replacement" include("substitute_component.jl")
102+
end
103+
end
104104

105-
# if GROUP == "All" || GROUP == "SymbolicIndexingInterface"
106-
# @safetestset "SymbolicIndexingInterface test" include("symbolic_indexing_interface.jl")
107-
# @safetestset "SciML Problem Input Test" include("sciml_problem_inputs.jl")
108-
# @safetestset "MTKParameters Test" include("mtkparameters.jl")
109-
# end
105+
if GROUP == "All" || GROUP == "SymbolicIndexingInterface"
106+
@safetestset "SymbolicIndexingInterface test" include("symbolic_indexing_interface.jl")
107+
@safetestset "SciML Problem Input Test" include("sciml_problem_inputs.jl")
108+
@safetestset "MTKParameters Test" include("mtkparameters.jl")
109+
end
110110

111-
# if GROUP == "All" || GROUP == "Extended"
112-
# @safetestset "Test Big System Usage" include("bigsystem.jl")
113-
# println("C compilation test requires gcc available in the path!")
114-
# @safetestset "C Compilation Test" include("ccompile.jl")
115-
# @testset "Distributed Test" include("distributed.jl")
116-
# @testset "Serialization" include("serialization.jl")
117-
# end
111+
if GROUP == "All" || GROUP == "Extended"
112+
@safetestset "Test Big System Usage" include("bigsystem.jl")
113+
println("C compilation test requires gcc available in the path!")
114+
@safetestset "C Compilation Test" include("ccompile.jl")
115+
@testset "Distributed Test" include("distributed.jl")
116+
@testset "Serialization" include("serialization.jl")
117+
end
118118

119-
# if GROUP == "All" || GROUP == "RegressionI"
120-
# @safetestset "Latexify recipes Test" include("latexify.jl")
121-
# end
119+
if GROUP == "All" || GROUP == "RegressionI"
120+
@safetestset "Latexify recipes Test" include("latexify.jl")
121+
end
122122

123-
# if GROUP == "All" || GROUP == "Downstream"
124-
# activate_downstream_env()
125-
# @safetestset "Linearization Tests" include("downstream/linearize.jl")
126-
# @safetestset "Linearization Dummy Derivative Tests" include("downstream/linearization_dd.jl")
127-
# @safetestset "Inverse Models Test" include("downstream/inversemodel.jl")
128-
# @safetestset "Analysis Points Test" include("downstream/analysis_points.jl")
129-
# @safetestset "Analysis Points Test" include("downstream/test_disturbance_model.jl")
130-
# end
123+
if GROUP == "All" || GROUP == "Downstream"
124+
activate_downstream_env()
125+
@safetestset "Linearization Tests" include("downstream/linearize.jl")
126+
@safetestset "Linearization Dummy Derivative Tests" include("downstream/linearization_dd.jl")
127+
@safetestset "Inverse Models Test" include("downstream/inversemodel.jl")
128+
@safetestset "Analysis Points Test" include("downstream/analysis_points.jl")
129+
@safetestset "Analysis Points Test" include("downstream/test_disturbance_model.jl")
130+
end
131131

132-
# if GROUP == "All" || GROUP == "FMI"
133-
# activate_fmi_env()
134-
# @safetestset "FMI Extension Test" include("fmi/fmi.jl")
135-
# end
132+
if GROUP == "All" || GROUP == "FMI"
133+
activate_fmi_env()
134+
@safetestset "FMI Extension Test" include("fmi/fmi.jl")
135+
end
136136

137-
# if GROUP == "All" || GROUP == "Extensions"
138-
# activate_extensions_env()
139-
# @safetestset "HomotopyContinuation Extension Test" include("extensions/homotopy_continuation.jl")
140-
# @safetestset "Auto Differentiation Test" include("extensions/ad.jl")
141-
# @safetestset "LabelledArrays Test" include("labelledarrays.jl")
142-
# @safetestset "BifurcationKit Extension Test" include("extensions/bifurcationkit.jl")
143-
# @safetestset "InfiniteOpt Extension Test" include("extensions/test_infiniteopt.jl")
144-
# end
137+
if GROUP == "All" || GROUP == "Extensions"
138+
activate_extensions_env()
139+
@safetestset "HomotopyContinuation Extension Test" include("extensions/homotopy_continuation.jl")
140+
@safetestset "Auto Differentiation Test" include("extensions/ad.jl")
141+
@safetestset "LabelledArrays Test" include("labelledarrays.jl")
142+
@safetestset "BifurcationKit Extension Test" include("extensions/bifurcationkit.jl")
143+
@safetestset "InfiniteOpt Extension Test" include("extensions/test_infiniteopt.jl")
144+
end
145145
end

0 commit comments

Comments
 (0)