Skip to content

Commit 16ea18b

Browse files
committed
begin refactor
1 parent 1656277 commit 16ea18b

File tree

1 file changed

+66
-63
lines changed

1 file changed

+66
-63
lines changed

src/structural_transformation/symbolics_tearing.jl

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,49 @@ function check_diff_graph(var_to_diff, fullvars)
237237
end
238238
=#
239239

240-
function substitute_lower_order!(state::TearingState)
241-
240+
241+
function substitute_dummy_derivatives!(fullvars, var_to_diff, diff_to_var, var_eq_matching, neweqs)
242+
# Dummy derivatives may determine that some differential variables are
243+
# algebraic variables in disguise. The derivative of such variables are
244+
# called dummy derivatives.
245+
246+
# Step 1:
247+
# Replace derivatives of non-selected unknown variables by dummy derivatives
248+
249+
dummy_sub = Dict()
250+
for var in 1:length(fullvars)
251+
dv = var_to_diff[var]
252+
dv === nothing && continue
253+
if var_eq_matching[var] !== SelectedState()
254+
dd = fullvars[dv]
255+
v_t = setio(diff2term_with_unit(unwrap(dd), unwrap(iv)), false, false)
256+
for eq in 𝑑neighbors(graph, dv)
257+
dummy_sub[dd] = v_t
258+
neweqs[eq] = fast_substitute(neweqs[eq], dd => v_t)
259+
end
260+
fullvars[dv] = v_t
261+
# If we have:
262+
# x -> D(x) -> D(D(x))
263+
# We need to to transform it to:
264+
# x x_t -> D(x_t)
265+
# update the structural information
266+
dx = dv
267+
x_t = v_t
268+
while (ddx = var_to_diff[dx]) !== nothing
269+
dx_t = D(x_t)
270+
for eq in 𝑑neighbors(graph, ddx)
271+
neweqs[eq] = fast_substitute(neweqs[eq], fullvars[ddx] => dx_t)
272+
end
273+
fullvars[ddx] = dx_t
274+
dx = ddx
275+
x_t = dx_t
276+
end
277+
diff_to_var[dv] = nothing
278+
end
279+
end
280+
end
281+
282+
function generate_derivative_variables!()
242283
end
243284

244285
# Documenting the differences to structural simplification for discrete systems:
@@ -281,88 +322,50 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
281322
end
282323
end
283324

284-
neweqs = collect(equations(state))
285-
lower_name = is_only_discrete(state.structure) ? lower_varname_withshift : lower_varname_with_unit
286-
287-
# Terminology and Definition:
288-
#
289-
# A general DAE is in the form of `F(u'(t), u(t), p, t) == 0`. We can
290-
# characterize variables in `u(t)` into two classes: differential variables
291-
# (denoted `v(t)`) and algebraic variables (denoted `z(t)`). Differential
292-
# variables are marked as `SelectedState` and they are differentiated in the
293-
# DAE system, i.e. `v'(t)` are all the variables in `u'(t)` that actually
294-
# appear in the system. Algebraic variables are variables that are not
295-
# differential variables.
296-
#
297-
# Dummy derivatives may determine that some differential variables are
298-
# algebraic variables in disguise. The derivative of such variables are
299-
# called dummy derivatives.
300-
301-
# Step 1:
302-
# Replace derivatives of non-selected unknown variables by dummy derivatives
303-
304325
if ModelingToolkit.has_iv(state.sys)
305326
iv = get_iv(state.sys)
306327
if is_only_discrete(state.structure)
307328
D = Shift(iv, 1)
329+
lower_name = lower_varname_withshift
330+
idx_to_lowest_shift = Dict{Int, Int}(var => 0 for var in 1:length(fullvars))
331+
for (i,var) in enumerate(fullvars)
332+
key = (operation(var) isa Shift) ? only(arguments(var)) : var
333+
idx_to_lowest_shift[i] = get(lowest_shift, key, 0)
334+
end
308335
else
309336
D = Differential(iv)
337+
lower_name = lower_varname_with_unit
310338
end
311339
else
312340
iv = D = nothing
341+
lower_name = lower_varname_with_unit
313342
end
343+
314344
diff_to_var = invview(var_to_diff)
345+
neweqs = collect(equations(state))
315346

316-
dummy_sub = Dict()
317-
for var in 1:length(fullvars)
318-
dv = var_to_diff[var]
319-
dv === nothing && continue
320-
if var_eq_matching[var] !== SelectedState()
321-
dd = fullvars[dv]
322-
v_t = setio(diff2term_with_unit(unwrap(dd), unwrap(iv)), false, false)
323-
for eq in 𝑑neighbors(graph, dv)
324-
dummy_sub[dd] = v_t
325-
neweqs[eq] = fast_substitute(neweqs[eq], dd => v_t)
326-
end
327-
fullvars[dv] = v_t
328-
# If we have:
329-
# x -> D(x) -> D(D(x))
330-
# We need to to transform it to:
331-
# x x_t -> D(x_t)
332-
# update the structural information
333-
dx = dv
334-
x_t = v_t
335-
while (ddx = var_to_diff[dx]) !== nothing
336-
dx_t = D(x_t)
337-
for eq in 𝑑neighbors(graph, ddx)
338-
neweqs[eq] = fast_substitute(neweqs[eq], fullvars[ddx] => dx_t)
339-
end
340-
fullvars[ddx] = dx_t
341-
dx = ddx
342-
x_t = dx_t
343-
end
344-
diff_to_var[dv] = nothing
345-
end
346-
end
347+
# Terminology and Definition:
348+
#
349+
# A general DAE is in the form of `F(u'(t), u(t), p, t) == 0`. We can
350+
# characterize variables in `u(t)` into two classes: differential variables
351+
# (denoted `v(t)`) and algebraic variables (denoted `z(t)`). Differential
352+
# variables are marked as `SelectedState` and they are differentiated in the
353+
# DAE system, i.e. `v'(t)` are all the variables in `u'(t)` that actually
354+
# appear in the system. Algebraic variables are variables that are not
355+
# differential variables.
347356

357+
substitute_dummy_derivatives!(fullvars, var_to_diff, diff_to_var, var_eq_matching, neweqs)
358+
348359
# `SelectedState` information is no longer needed past here. State selection
349360
# is done. All non-differentiated variables are algebraic variables, and all
350361
# variables that appear differentiated are differential variables.
351362

352-
### extract partition information
363+
### Extract partition information
353364
is_solvable = let solvable_graph = solvable_graph
354365
(eq, iv) -> eq isa Int && iv isa Int && BipartiteEdge(eq, iv) in solvable_graph
355366
end
356367

357-
if is_only_discrete(state.structure)
358-
idx_to_lowest_shift = Dict{Int, Int}(var => 0 for var in 1:length(fullvars))
359-
for (i,var) in enumerate(fullvars)
360-
key = (operation(var) isa Shift) ? only(arguments(var)) : var
361-
idx_to_lowest_shift[i] = get(lowest_shift, key, 0)
362-
end
363-
end
364-
365-
# if var is like D(x)
368+
# if var is like D(x) or Shift(t, 1)(x)
366369
isdervar = let diff_to_var = diff_to_var
367370
var -> diff_to_var[var] !== nothing
368371
end

0 commit comments

Comments
 (0)