We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
2 parents be151e3 + 9deb045 commit 5386832Copy full SHA for 5386832
src/structural_transformation/StructuralTransformations.jl
@@ -11,7 +11,7 @@ using SymbolicUtils: maketerm, iscall
11
12
using ModelingToolkit
13
using ModelingToolkit: ODESystem, AbstractSystem, var_from_nested_derivative, Differential,
14
- unknowns, equations, vars, Symbolic, diff2term, value,
+ unknowns, equations, vars, Symbolic, diff2term_with_unit, value,
15
operation, arguments, Sym, Term, simplify, symbolic_linear_solve,
16
isdiffeq, isdifferential, isirreducible,
17
empty_substitutions, get_substitutions,
@@ -22,7 +22,7 @@ using ModelingToolkit: ODESystem, AbstractSystem, var_from_nested_derivative, Di
22
get_postprocess_fbody, vars!,
23
IncrementalCycleTracker, add_edge_checked!, topological_sort,
24
invalidate_cache!, Substitutions, get_or_construct_tearing_state,
25
- filter_kwargs, lower_varname, setio, SparseMatrixCLIL,
+ filter_kwargs, lower_varname_with_unit, setio, SparseMatrixCLIL,
26
get_fullvars, has_equations, observed,
27
Schedule
28
src/structural_transformation/pantelides.jl
@@ -16,7 +16,8 @@ function pantelides_reassemble(state::TearingState, var_eq_matching)
fill!(out_vars, nothing)
out_vars[1:length(fullvars)] .= fullvars
18
19
- D = Differential(get_iv(sys))
+ iv = get_iv(sys)
20
+ D = Differential(iv)
21
for (varidx, diff) in edges(var_to_diff)
# fullvars[diff] = D(fullvars[var])
@@ -25,7 +26,7 @@ function pantelides_reassemble(state::TearingState, var_eq_matching)
# `fullvars[i]` needs to be not a `D(...)`, because we want the DAE to be
# first-order.
if isdifferential(vi)
- vi = out_vars[varidx] = diff2term(vi)
29
+ vi = out_vars[varidx] = diff2term_with_unit(vi, iv)
30
end
31
out_vars[diff] = D(vi)
32
src/structural_transformation/symbolics_tearing.jl
@@ -274,7 +274,7 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
274
dv === nothing && continue
275
if var_eq_matching[var] !== SelectedState()
276
dd = fullvars[dv]
277
- v_t = setio(diff2term(unwrap(dd)), false, false)
+ v_t = setio(diff2term_with_unit(unwrap(dd), unwrap(iv)), false, false)
278
for eq in 𝑑neighbors(graph, dv)
279
dummy_sub[dd] = v_t
280
neweqs[eq] = fast_substitute(neweqs[eq], dd => v_t)
src/structural_transformation/utils.jl
@@ -426,7 +426,7 @@ function lower_varname_withshift(var, iv, order)
426
op = operation(var)
427
return Shift(op.t, order)(var)
428
429
- return lower_varname(var, iv, order)
+ return lower_varname_with_unit(var, iv, order)
430
431
432
function isdoubleshift(var)
src/systems/diffeqs/abstractodesystem.jl
@@ -456,7 +456,7 @@ end
456
457
function DiffEqBase.DAEFunction{iip}(sys::AbstractODESystem, dvs = unknowns(sys),
458
ps = parameters(sys), u0 = nothing;
459
- ddvs = map(diff2term ∘ Differential(get_iv(sys)), dvs),
+ ddvs = map(Base.Fix2(diff2term, get_iv(sys)) ∘ Differential(get_iv(sys)), dvs),
460
version = nothing, p = nothing,
461
jac = false,
462
eval_expression = false,
src/systems/diffeqs/first_order_transform.jl
@@ -34,7 +34,7 @@ function ode_order_lowering(eqs, iv, unknown_vars)
34
var, maxorder = var_from_nested_derivative(eq.lhs)
35
maxorder > get(var_order, var, 1) && (var_order[var] = maxorder)
36
var′ = lower_varname(var, iv, maxorder - 1)
37
- rhs′ = diff2term(eq.rhs)
+ rhs′ = diff2term_with_unit(eq.rhs, iv)
38
push!(diff_vars, var′)
39
push!(diff_eqs, D(var′) ~ rhs′)
40
src/utils.jl
@@ -859,3 +859,16 @@ function eval_or_rgf(expr::Expr; eval_expression = false, eval_module = @__MODUL
859
return drop_expr(RuntimeGeneratedFunction(eval_module, eval_module, expr))
860
861
862
+
863
+function _with_unit(f, x, t, args...)
864
+ x = f(x, args...)
865
+ if hasmetadata(x, VariableUnit) && (t isa Symbolic && hasmetadata(t, VariableUnit))
866
+ xu = getmetadata(x, VariableUnit)
867
+ tu = getmetadata(t, VariableUnit)
868
+ x = setmetadata(x, VariableUnit, xu / tu)
869
+ end
870
+ return x
871
+end
872
873
+diff2term_with_unit(x, t) = _with_unit(diff2term, x, t)
874
+lower_varname_with_unit(var, iv, order) = _with_unit(lower_varname, var, iv, iv, order)
test/dq_units.jl
@@ -246,3 +246,31 @@ let
246
@test MT.get_unit(x_vec) == u"1"
247
@test MT.get_unit(x_mat) == u"1"
248
249
250
+module UnitTD
251
+using Test
252
+using ModelingToolkit
253
+using ModelingToolkit: t, D
254
+using DynamicQuantities
255
256
+@mtkmodel UnitsExample begin
257
+ @parameters begin
258
+ g, [unit = u"m/s^2"]
259
+ L = 1.0, [unit = u"m"]
260
261
+ @variables begin
262
+ x(t), [unit = u"m"]
263
+ y(t), [state_priority = 10, unit = u"m"]
264
+ λ(t), [unit = u"s^-2"]
265
266
+ @equations begin
267
+ D(D(x)) ~ λ * x
268
+ D(D(y)) ~ λ * y - g
269
+ x^2 + y^2 ~ L^2
270
271
272
273
+@mtkbuild pend = UnitsExample()
+@test ModelingToolkit.get_unit.(filter(x -> occursin("ˍt", string(x)), unknowns(pend))) ==
+ [u"m/s", u"m/s"]
0 commit comments