Follow-up from April 2021 discussion…
I am trying to move two quantities out of my component constructors: (i) a constant (gravity; should never be changed), and (ii) a shared liquid density (parameter, in principle, I would like to be able to change this).
Here is what I try to do:
# 1. Define parameter and constant:
@parameters rho = 1 [unit=u"kg/L", description="water density"]
@constants g = 98.1 [unit=u"dm/s^2", description="gravity"]
# 2. Give parameter and constant global scope
rho = GlobalScope(rho)
g = GlobalScope(g)
# Component constructor for open tank water level model
#
@component function Tank(; name, A=5, md_c=25, p_s=1e4, eps_v=1e-9)
#
# Symbolic model parameters
params = @parameters begin
A=A, [unit=u"m^2", description = "Cross sectional tank area"]
md_c=md_c, [unit=u"kg/s", description = "Effluent valve capacity"]
p_s=p_s, [unit=u"dPa", description = "Scaling pressure in valve model"]
eps_v=eps_v, [unit=u"1", description = "Softening parameter in valve model"]
end
# Symbolic model variables, with initial values needed
vars = @variables begin
m(t)=1.5*rho*A, [unit=u"kg", description = "Liquid mass"]
md_i(t), [unit=u"kg/s", description = "Influent mass flow rate"]
md_e(t), [unit=u"kg/s", description = "Effluent mass flow rate"]
V(t), [unit=u"L", description = "Liquid volume"]
h(t), [unit=u"dm", description = "level"]
Dp(t), [unit=u"dPa", description = "Pressure drop across valve"]
end
# Model equations
eqs = [
D(m) ~ md_i-md_e
m ~ rho*V
V ~ A*h
Dp ~ rho*g*h
md_e ~ md_c*s_ssqrt(Dp/p_s; eps=eps_v)
]
#
return ODESystem(eqs, t, vars, params; name = name)
end
I then build a system of two tanks…
@component function Sys2Tank(; name)
# Components used
subsys = @named begin
tank_1 = Tank()
tank_2 = Tank()
end
# Equations for connecting components
eqs = [
tank_1.md_i ~ md(t)
tank_2.md_i ~ tank_1.md_e
]
sys = ODESystem(eqs, t; name = name)
return compose(sys, subsys...)
end
I then simplify/compile the symbolic model:
@mtkcompile csys2tank = Sys2Tank()
and everything works so far.
But when I try to create a numeric problem, I get an error message that g and rho does not have a numeric value:
prob_sys = ODEProblem(csys2tank, [], tspan)
[Observe: I have set tspan = (0,10). Also, I need to specify function md(t) some place, and register it symbolically. Function s_ssqrt() is just a smoothed signed square root function.]
Some Questions:
- Does the above make sense?
- If I do
parameters(csys2tank), both g and rho are listed among the parameters. I am a little surprised that constant g is listed as a parameter?
- Clearly, setting values to
g and rho has not worked?
- How do I specify the values of
g and rho in the ODEProblem constructor?