What is good practice when it comes to use of @parameters and kwargs in “component types”?
To make my question concrete, consider the following “component type” (is that the proper term? – this is not meant as a “serious” component, just a simple example):
# Component type for open tank water level model
#
@component function Tank(; name, rho=1, A=5, md_c=25, p_s=1e4, eps_v=1e-6)
# Computing numeric parameters prior to introducing symbolic parameters
# Initial mass
m0 = 1.5*rho*A
# Symbolic model parameters
params = @parameters begin
rho=rho, [unit=u"kg/L", description = "Liquid density"]
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"]
g = 98.1, [unit=u"dm/s^2", description = "Gravitational acceleration"]
end
# Symbolic model variables, with initial values needed
vars = @variables begin
m(t)=m0, [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*soft_sqrtabs(Dp/p_s; eps_v=eps_v)
]
#
return System(eqs, t, vars, params; name = name)
end
My rationale for the above:
- I only transfer parameters via kwargs that the user should be able to choose.
- Specifically, the user should not need to bother about natural constants (e.g.,
g) – what in Modelica is aconstant. So I lean towards not including such values as kwargs. - I introduce @parameters so that the model, when listed by MTK, contains parameter symbols, and not numeric values.
My questions are related to – what is good practice when it comes to:
a. Names of kwargs. Observe that I have used the same identifier for the kwargs (numeric variables) and the symbolic variables in the @parameters block. This is probably not good practice. To me, it makes sense to change the kwargs and not the symbolic parameters.
- What is a good, systematic convention for naming the kwargs? Google’s AI tool suggests “parameter_val”, e.g.,
A_val,rho_val, etc. To me, this looks “clumsy” – I prefer simpler notation. I could use_A,_rho, etc., orA_,rho_, etc., but I don’t know whether that is “nice” as kwargs. I could usep_A,p_rhoorA_p,rho_p(“p” for parameter"). Etc. - Any other systematic choices that makes sense?
b. My idea is to only use this special notation of kwargs (p_A, or what not) for “model” parameters, i.e., parameters that have similar symbolic names in the @parameters block. So:
- I do not see the need to have symbolic parameters for purely numeric numbers such as
eps_v, which is an accuracy parameter in the indicatedsoft_sqrtabsfunction (essentially a soft approximation tosqrt(abs(x))) - Likewise, I would not use a symbolic parameter for, say the number
Nof discretization cells in PDEs, etc.
Suggestions for good practice are welcome! Key to me is:
- It should be systematic, which makes it simpler for the user, and
- It should be simple to maintain and not break any Julia conventions, and
- It should make sense in the MTK eco system
[Observe that my example “component type” above only works properly if initial mass m0 at the above location, i.e., prior to the @parameters block. If I put the definition of m0 after the @parameters block, this makes m0 symbolic instead of numeric, and messes up the possibility to properly initialize the system. This messing up would disappear if I use different names for symbolic parameters and kwargs.]