-
-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathdesauty_dae_mwe.jl
64 lines (50 loc) · 2.11 KB
/
desauty_dae_mwe.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using ModelingToolkit, OrdinaryDiffEq
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks: Sine
using NonlinearSolve
import SciMLStructures as SS
import SciMLSensitivity
using Zygote
function create_model(; C₁ = 3e-5, C₂ = 1e-6)
@variables t
@named resistor1 = Resistor(R = 5.0)
@named resistor2 = Resistor(R = 2.0)
@named capacitor1 = Capacitor(C = C₁)
@named capacitor2 = Capacitor(C = C₂)
@named source = Voltage()
@named input_signal = Sine(frequency = 100.0)
@named ground = Ground()
@named ampermeter = CurrentSensor()
eqs = [connect(input_signal.output, source.V)
connect(source.p, capacitor1.n, capacitor2.n)
connect(source.n, resistor1.p, resistor2.p, ground.g)
connect(resistor1.n, capacitor1.p, ampermeter.n)
connect(resistor2.n, capacitor2.p, ampermeter.p)]
@named circuit_model = ODESystem(eqs, t,
systems = [
resistor1, resistor2, capacitor1, capacitor2,
source, input_signal, ground, ampermeter,
])
end
desauty_model = create_model()
sys = structural_simplify(desauty_model)
prob = ODEProblem(sys, [], (0.0, 0.1), guesses = [sys.resistor1.v => 1.])
iprob = prob.f.initialization_data.initializeprob
isys = iprob.f.sys
tunables, repack, aliases = SS.canonicalize(SS.Tunable(), parameter_values(iprob))
linsolve = LinearSolve.DefaultLinearSolver(LinearSolve.DefaultAlgorithmChoice.QRFactorization)
sensealg = SciMLSensitivity.SteadyStateAdjoint(autojacvec = SciMLSensitivity.ZygoteVJP(), linsolve = linsolve)
igs, = Zygote.gradient(tunables) do p
iprob2 = remake(iprob, p = repack(p))
sol = solve(iprob2,
sensealg = sensealg
)
sum(Array(sol))
end
@test !iszero(sum(igs))
# tunable_parameters(isys) .=> gs
# gradient_unk1_idx = only(findfirst(x -> isequal(x, Initial(sys.capacitor1.v)), tunable_parameters(isys)))
# gs[gradient_unk1_idx]
# prob.f.initialization_data.update_initializeprob!(iprob, prob)
# prob.f.initialization_data.update_initializeprob!(iprob, ::Vector)
# prob.f.initialization_data.update_initializeprob!(iprob, gs)