Hi all,
I am looking to incorporate the following valve functions in MTK from a paper the images below give the mathematical description of the valves. The paper can be found here
The way I am trying to implement the code is as follows
function OnePort(;name)
@named in = Pin()
@named out = Pin()
sts = @variables Δp(t) = 0.0 q(t) = 0.0
eqs = [
Δp ~ out.p - in.p
0 ~ in.q + out.q
q ~ in.q
]
compose(ODESystem(eqs, t, sts, []; name=name), in, out)
end
function valvediff(Δp, AR, CQ)
q = (Δp ≤ 0.0) * CQ*AR*sqrt(sign(Δp)*Δp) +
(Δp > 0.0) * CQ*AR*sqrt(sign(Δp)*Δp)
return q
end
function ValveDiff(;name,CQ,Kp,Kf)
@named oneport = OnePort()
@unpack Δp, q = oneport
ps = @parameters CQ = CQ Kp = Kp Kf = Kf
sts = @variables θ1(t) = 0.0 θ2(t) = 0.0 AR(t) = 0.0
D = Differential(t)
eqs = [
D(θ1) ~ θ2
D(θ2) ~ (Δp ≤ 0.0) * Kp*Δp*cosd(θ1) - Kf*θ2 +
(Δp > 0.0) * Kp*Δp*cosd(θ1) - Kf*θ2
AR ~ ((1-cosd(θ1))^2)/((1-cosd(90.0))^2)
q ~ valvediff(Δp, AR, CQ)
]
extend(ODESystem(eqs, t, sts, ps; name=name), oneport)
end
I then call this function by
@named AV =ValveDiff(CQ=CQ_AV, Kp = Kp_av, Kf = Kf_av)
@named MV =ValveDiff(CQ=CQ_MV, Kp = Kp_mv, Kf = Kf_mv)
@named TV =ValveDiff(CQ=CQ_TV, Kp = Kp_tv, Kf = Kf_tv)
@named PV =ValveDiff(CQ=CQ_PV, Kp = Kp_pv, Kf = Kf_pv)
Which is then used in the connect statement as follows
circ_eqs = [
connect(LV.out, AV.in)
connect(AV.out, SAS.in)
connect(SAS.out, SAT.in)
connect(SAT.out, SAR.in)
connect(SAR.out, SCP.in)
connect(SCP.out, SVN.in)
connect(SVN.out, RA.in)
connect(RA.out, TV.in)
connect(TV.out, RV.in)
connect(RV.out, PV.in)
connect(PV.out, PAS.in)
connect(PAS.out, PAT.in)
connect(PAT.out, PAR.in)
connect(PAR.out, PCP.in)
connect(PCP.out, PVN.in)
connect(PVN.out, LA.in)
connect(LA.out, MV.in)
connect(MV.out, LV.in)
]
The equations for the valves when when generated look as follows
Differential(t)(AV₊θ1(t)) ~ AV₊θ2(t)
Differential(t)(AV₊θ2(t)) ~ AV₊Kp*AV₊Δp(t)*cosd(AV₊θ1(t))*(AV₊Δp(t) <= 0.0) + AV₊Kp*AV₊Δp(t)*cosd(AV₊θ1(t))*(AV₊Δp(t) > 0.0) - (2//1)*AV₊Kf*AV₊θ2(t)
Differential(t)(MV₊θ1(t)) ~ MV₊θ2(t)
Differential(t)(MV₊θ2(t)) ~ MV₊Kp*MV₊Δp(t)*cosd(MV₊θ1(t))*(MV₊Δp(t) <= 0.0) + MV₊Kp*MV₊Δp(t)*cosd(MV₊θ1(t))*(MV₊Δp(t) > 0.0) - (2//1)*MV₊Kf*MV₊θ2(t)
Differential(t)(PV₊θ1(t)) ~ PV₊θ2(t)
Differential(t)(PV₊θ2(t)) ~ PV₊Kp*PV₊Δp(t)*cosd(PV₊θ1(t))*(PV₊Δp(t) <= 0.0) + PV₊Kp*PV₊Δp(t)*cosd(PV₊θ1(t))*(PV₊Δp(t) > 0.0) - (2//1)*PV₊Kf*PV₊θ2(t)
Differential(t)(TV₊θ1(t)) ~ TV₊θ2(t)
Differential(t)(TV₊θ2(t)) ~ TV₊Kp*TV₊Δp(t)*cosd(TV₊θ1(t))*(TV₊Δp(t) <= 0.0) + TV₊Kp*TV₊Δp(t)*cosd(TV₊θ1(t))*(TV₊Δp(t) > 0.0) - (2//1)*TV₊Kf*TV₊θ2(t)
When this example is done with a valve function I know which works, the solution correctly matches the literature so I am certain that the problem lies within the definition of the valve function somewhere.
I could set this up in the traditional way with a load of coupled ODEs however would like to use MTK for this problem. I have racked my brains for a couple of weeks now but I can’t think of any intuitive way of including the ODE into the function.
The above ODEs have transformed into first order ODEs.
Any help appreciated, if any other info is needed please reach out - I posted the long message with detail as I think would serve well for others
Cheers,
Harry