I want to model a simple heating system using ModelingToolkit.jl
. It consists of a thermal storage, a boiler and a heat consumer.
The following equations govern this model.
Thermal Storage
The thermal storage has one state variable and is modelled with
\frac{d}{dt}soc(t) = -\alpha soc(t) - \frac{1}{m_{max}}(\dot{m}_{in,A}(t) + \dot{m}_{out,B}(t))
where soc(t) is the state-of-charge of the thermal storage. \dot{m}_{in,A}(t) and \dot{m}_{out,B}(t) are the in and outflowing massflows of hot water.
Boiler
The boiler has no dynamics and is modelled with
\dot{m}_{in,b}(t)T_{in,b}c_p+\dot{m}_{out,b}(t)T_{out,b}c_p+\dot{Q}(t)=0
\dot{Q}(t) = k u(t)
\dot{m}_{in,b}(t)+\dot{m}_{out,b}(t) = 0
where \dot{m}_{in,b}(t)\leq0 and \dot{m}_{out,b}(t)\geq0 are the in and outflowing massflows of water. T_{in,b} and T_{out,b} are the respective temperatures and c_p is the specific heat capacity of water. u(t)\in(0,1) is the control input of the boiler. \dot{Q}(t)\geq0 is therefore the produced heat of the boiler.
Heat Consumer
The heat consumer has no dynamics and is modelled with
\dot{m}_{in,hc}(t)T_{in,hc}c_p+\dot{m}_{out,hc}(t)T_{out,hc}c_p-\dot{Q}_{demand}(t)=0
\dot{m}_{in,hc}(t)+\dot{m}_{out,hc}(t) = 0
where \dot{Q}_{demand}(t)\geq0 is the known heat demand of the cosumer. Again \dot{m}_{in,hc}(t)\leq0 and \dot{m}_{out,hc}(t)\geq0 are the in and outflowing massflows of water. T_{in,hc} and T_{out,hc} are the respective temperatures and c_p is the specific heat capacity of water.
Connections
\dot{m}_{out,B}(t) + \dot{m}_{in,hc}(t) = 0
\dot{m}_{out,b}(t) + \dot{m}_{in,A}(t) = 0
For this simple example the whole thing could be condensed into one single ODE
\frac{d}{dt}soc(t) = -\alpha soc(t) - \frac{1}{m_{max}}(\frac{1}{(T_{in,b}-T_{out,b})c_p}k u(t) + \frac{1}{(T_{in,hc}-T_{out,hc})c_p}\dot{Q}_{demand}(t))
but I want to automate that.
My questions?
- The ODE for the thermal storage is quite clear but how can I model the other to componets with
ModelingToolkit.jl
? Is this even possible since they have no state variables? - How would I provide known variables like \dot{Q}_{demand}(t) or u(t) using
ModelingToolkit.jl
? u(t) can only change a fixed time steps and \dot{Q}_{demand}(t) would have to be interpolated for a given t. I guess this is something for aPeriodicCallback
?
For the manual approach I have:
mutable struct SimType{T} <: DEDataVector{T}
x::Vector{T}
u::T
Qdot_hc::T
end
function f(du, u, p, t)
mdot_in_gb = k * u.u / (cp_W * (T_in_gb - T_out_gb))
mdot_out_hc = u.Qdot_hc / (cp_W * (T_in_hc - T_out_hc))
du[1] = - alpha * u[1] - 1 / m_max * (mdot_in_gb + mdot_out_hc)
return
end
function cb(int)
timestamp = t0 + int.t
int.u.u = # interpolate from data
int.u.Qdot_hc = # interpolate from data
return
end
u0 = SimType([0.5], 0.0, Qdot_hc_0)
tspan = (0.0, 900. * 96) # 24h @ 15min
prob = ODEProblem(f, u0, tspan)
sol = solve(prob, Tsit5(); callback = PeriodicCallback(cb, 900.))
However, I do not quite get the correct results. Is there any obvious mistake?
Thanks!