# Complex equations

After >20 years working with MODELICA I tried to use Complex equations in `MTK`.

In a simple example an ohmic resistor and a inductor are connected in series to a constant voltage source. I used per unit system with space-phasors and variable speed of reference frame `@parameters wReference`.

``````using ModelingToolkit
using DifferentialEquations
using Plots

frequency = 50.0
Omegarated = frequency*2pi
JJ = 1.0im

function NewVars(eqName::String, CCX::Vector{Complex{Num}})::Tuple{Expr, Expr}
vari::String = "newVariables = @variables "
substi::String = ""
for cx in CCX
stcx = string(cx)[1:end-3]  # without '(t)'
vari = string(vari,stcx*"₋re(t) ",stcx*"₋im(t) ")
substi = string(substi,"\$eqName = substitute(\$eqName,(real(\$stcx)=>\$(stcx)₋re)); ")
substi = string(substi,"\$eqName = substitute(\$eqName,(imag(\$stcx)=>\$(stcx)₋im)); ")
end
return (Meta.parse(vari), Meta.parse(substi))
end

CX = @variables begin
deri(t)::ComplexF64
amps(t)::ComplexF64
gridVolts(t)::ComplexF64
end

@parameters  x r wReference = 1.0

D = Differential(t)
# DiffC(cpx) =  Complex(D(real(cpx)),D(imag(cpx)))  # used for testing

#NOTE
#NOTE  this line was added in Symbolics - diff.jl
# (D::Differential)(x::Complex{Num}) = Num(D(real(x)))+Num(D(imag(x)))*im
#NOTE

eqs1 = [ D(amps) ~ deri*Omegarated
gridVolts ~ x*(deri + wReference*amps*JJ) + r*amps
w ~ Omegarated*(1.0-wReference)
]

eqs=deepcopy(eqs1)

(Bvaria, Bsubst) = NewVars("eqs",CX)
eval(Bvaria) # create new variables
eval(Bsubst) # substitute

pr = 0.3; px = 0.1
u0 = [0.0, 0.0, 0.0]
p = [x => px, r=> pr, wReference => 1.0]

# exact solution
strom = (1.0+0im)/(pr+JJ*px)
println("exact solution: amps = \$(strom)")

@named model = ODESystem(eqs)
sys = structural_simplify(model)

prob = ODEProblem(sys, u0, (0., 1.0/frequency), p)
sol = solve(prob, Tsit5())
plot(sol)
``````

## my approach

### (D::Differential)(x::Complex{Num}

an additional line in `diff.jl`
`(D::Differential)(x::Complex{Num}) = Num(D(real(x)))+Num(D(imag(x)))*im`

### substitute real(x), imag(x)

`real(x), imag(x)` are replaced by new @variables x_re x_im

## Questions

• This works with monolithic models. But how to do with component based models? (e.g. `connect()` and `Flow` )

### backup alternative

To split Complex equations manually. This works, but `Symbolics` should do this for me.

Thanks

It should, that’s just not all complete yet. For now the splitting needs to be done manually, but it’s on the menu.