|
1 |
| -using ModelingToolkit |
| 1 | +using ModelingToolkit, OrdinaryDiffEq |
2 | 2 |
|
3 | 3 | @variables t
|
4 | 4 | sts = @variables x1(t) x2(t) x3(t) x4(t)
|
@@ -48,3 +48,166 @@ let al1 = alias_elimination(lorenz1)
|
48 | 48 | @test length(equations(lss)) == 2
|
49 | 49 | end
|
50 | 50 | end
|
| 51 | + |
| 52 | +# 1516 |
| 53 | +let |
| 54 | + @variables t |
| 55 | + D = Differential(t) |
| 56 | + |
| 57 | + @connector function Fluid_port(;name, p=101325.0, m=0.0, T=293.15) |
| 58 | + sts = @variables p(t)=p m(t)=m [connect=Flow] T(t)=T [connect=Stream] |
| 59 | + ODESystem(Equation[], t, sts, []; name=name) |
| 60 | + end |
| 61 | + |
| 62 | + #this one is for latter |
| 63 | + @connector function Heat_port(;name, Q=0.0, T=293.15) |
| 64 | + sts = @variables T(t)=T Q(t)=Q [connect=Flow] |
| 65 | + ODESystem(Equation[], t, sts, []; name=name) |
| 66 | + end |
| 67 | + |
| 68 | + # like ground but for fluid systems (fluid_port.m is expected to be zero in closed loop) |
| 69 | + function Compensator(;name, p=101325.0, T_back=273.15) |
| 70 | + @named fluid_port = Fluid_port() |
| 71 | + ps = @parameters p=p T_back=T_back |
| 72 | + eqs = [ |
| 73 | + fluid_port.p ~ p |
| 74 | + fluid_port.T ~ T_back |
| 75 | + ] |
| 76 | + compose(ODESystem(eqs, t, [], ps; name=name), fluid_port) |
| 77 | + end |
| 78 | + |
| 79 | + function Source(;name, delta_p=100, T_feed=293.15) |
| 80 | + @named supply_port = Fluid_port() # expected to feed connected pipe -> m<0 |
| 81 | + @named return_port = Fluid_port() # expected to receive from connected pipe -> m>0 |
| 82 | + ps = @parameters delta_p=delta_p T_feed=T_feed |
| 83 | + eqs = [ |
| 84 | + supply_port.m ~ -return_port.m |
| 85 | + supply_port.p ~ return_port.p + delta_p |
| 86 | + supply_port.T ~ instream(supply_port.T) |
| 87 | + return_port.T ~ T_feed |
| 88 | + ] |
| 89 | + compose(ODESystem(eqs, t, [], ps; name=name), [supply_port, return_port]) |
| 90 | + end |
| 91 | + |
| 92 | + function Substation(;name, T_return=343.15) |
| 93 | + @named supply_port = Fluid_port() # expected to receive from connected pipe -> m>0 |
| 94 | + @named return_port = Fluid_port() # expected to feed connected pipe -> m<0 |
| 95 | + ps = @parameters T_return=T_return |
| 96 | + eqs = [ |
| 97 | + supply_port.m ~ -return_port.m |
| 98 | + supply_port.p ~ return_port.p # zero pressure loss for now |
| 99 | + supply_port.T ~ instream(supply_port.T) |
| 100 | + return_port.T ~ T_return |
| 101 | + ] |
| 102 | + compose(ODESystem(eqs, t, [], ps; name=name), [supply_port, return_port]) |
| 103 | + end |
| 104 | + |
| 105 | + function Pipe(;name, L=1000, d=0.1, N=100, rho=1000, f=1) |
| 106 | + @named fluid_port_a = Fluid_port() |
| 107 | + @named fluid_port_b = Fluid_port() |
| 108 | + ps = @parameters L=L d=d rho=rho f=f N=N |
| 109 | + sts = @variables v(t)=0.0 dp_z(t)=0.0 |
| 110 | + eqs = [ |
| 111 | + fluid_port_a.m ~ -fluid_port_b.m |
| 112 | + fluid_port_a.T ~ instream(fluid_port_a.T) |
| 113 | + fluid_port_b.T ~ fluid_port_a.T |
| 114 | + v*pi*d^2/4*rho ~ fluid_port_a.m |
| 115 | + dp_z ~ abs(v)*v*0.5*rho*L/d*f # pressure loss |
| 116 | + D(v)*rho*L ~ (fluid_port_a.p - fluid_port_b.p - dp_z) # acceleration of fluid m*a=sum(F) |
| 117 | + ] |
| 118 | + compose(ODESystem(eqs, t, sts, ps; name=name), [fluid_port_a, fluid_port_b]) |
| 119 | + end |
| 120 | + function System(;name, L=10.0) |
| 121 | + @named compensator = Compensator() |
| 122 | + @named source = Source() |
| 123 | + @named substation = Substation() |
| 124 | + @named supply_pipe = Pipe(L=L) |
| 125 | + @named return_pipe = Pipe(L=L) |
| 126 | + subs = [compensator, source, substation, supply_pipe, return_pipe] |
| 127 | + ps = @parameters L=L |
| 128 | + eqs = [ |
| 129 | + connect(compensator.fluid_port, source.supply_port) |
| 130 | + connect(source.supply_port, supply_pipe.fluid_port_a) |
| 131 | + connect(supply_pipe.fluid_port_b, substation.supply_port) |
| 132 | + connect(substation.return_port, return_pipe.fluid_port_b) |
| 133 | + connect(return_pipe.fluid_port_a, source.return_port) |
| 134 | + ] |
| 135 | + compose(ODESystem(eqs, t, [], ps; name=name), subs) |
| 136 | + end |
| 137 | + |
| 138 | + @named system = System(L=10) |
| 139 | + @unpack supply_pipe = system |
| 140 | + sys = structural_simplify(system) |
| 141 | + u0 = [system.supply_pipe.v => 0.1, system.return_pipe.v => 0.1, D(supply_pipe.v) => 0.0] |
| 142 | + # This is actually an implicit DAE system |
| 143 | + @test_throws Any ODEProblem(sys, u0, (0.0, 10.0), []) |
| 144 | + @test_throws Any ODAEProblem(sys, u0, (0.0, 10.0), []) |
| 145 | + prob = DAEProblem(sys, D.(states(sys)) .=> 0.0, u0, (0.0, 10.0), []) |
| 146 | + @test solve(prob, DFBDF()).retcode == :Success |
| 147 | +end |
| 148 | + |
| 149 | +# 1537 |
| 150 | +let |
| 151 | + @variables t |
| 152 | + @variables begin |
| 153 | + p_1(t) |
| 154 | + p_2(t) |
| 155 | + rho_1(t) |
| 156 | + rho_2(t) |
| 157 | + rho_3(t) |
| 158 | + u_1(t) |
| 159 | + u_2(t) |
| 160 | + u_3(t) |
| 161 | + mo_1(t) |
| 162 | + mo_2(t) |
| 163 | + mo_3(t) |
| 164 | + Ek_1(t) |
| 165 | + Ek_2(t) |
| 166 | + Ek_3(t) |
| 167 | + end |
| 168 | + |
| 169 | + @parameters dx = 100 f = 0.3 pipe_D = 0.4 |
| 170 | + |
| 171 | + D = Differential(t) |
| 172 | + |
| 173 | + eqs = [ |
| 174 | + p_1 ~ 1.2e5 |
| 175 | + p_2 ~ 1e5 |
| 176 | + u_1 ~ 10 |
| 177 | + mo_1 ~ u_1 * rho_1 |
| 178 | + mo_2 ~ u_2 * rho_2 |
| 179 | + mo_3 ~ u_3 * rho_3 |
| 180 | + Ek_1 ~ rho_1 * u_1 * u_1 |
| 181 | + Ek_2 ~ rho_2 * u_2 * u_2 |
| 182 | + Ek_3 ~ rho_3 * u_3 * u_3 |
| 183 | + rho_1 ~ p_1 / 273.11 / 300 |
| 184 | + rho_2 ~ (p_1 + p_2) * 0.5 / 273.11 / 300 |
| 185 | + rho_3 ~ p_2 / 273.11 / 300 |
| 186 | + D(rho_2) ~ (mo_1 - mo_3) / dx |
| 187 | + D(mo_2) ~ (Ek_1 - Ek_3 + p_1 - p_2) / dx - f / 2 / pipe_D * u_2 * u_2 |
| 188 | + ] |
| 189 | + |
| 190 | + @named trans = ODESystem(eqs, t) |
| 191 | + |
| 192 | + sys = structural_simplify(trans) |
| 193 | + |
| 194 | + n = 3 |
| 195 | + u = 0 * ones(n) |
| 196 | + rho = 1.2 * ones(n) |
| 197 | + |
| 198 | + u0 = [ |
| 199 | + p_1 => 1.2e5 |
| 200 | + p_2 => 1e5 |
| 201 | + u_1 => 0 |
| 202 | + u_2 => 0.1 |
| 203 | + u_3 => 0.2 |
| 204 | + rho_1 => 1.1 |
| 205 | + rho_2 => 1.2 |
| 206 | + rho_3 => 1.3 |
| 207 | + mo_1 => 0 |
| 208 | + mo_2 => 1 |
| 209 | + mo_3 => 2 |
| 210 | + ] |
| 211 | + prob = ODAEProblem(sys, u0, (0.0, 0.1)) |
| 212 | + @test solve(prob, FBDF()).retcode == :Success |
| 213 | +end |
0 commit comments