Skip to content

Commit 85729d8

Browse files
author
Brad Carman
committed
working Pipe model
1 parent cc46e36 commit 85729d8

File tree

8 files changed

+203
-112
lines changed

8 files changed

+203
-112
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@named sae_30_oil_20C = FluidType()
2+
const sae_30_oil_20C_type = typeof(get_fluid(sae_30_oil_20C))
3+
4+
# https://wiki.anton-paar.com/us-en/engine-oil/ at 20C
5+
density(::sae_30_oil_20C_type) = 881.5
6+
bulk_modulus(::sae_30_oil_20C_type) = 1.5e9
7+
viscosity(::sae_30_oil_20C_type) = 0.23939

src/Hydraulic/IsothermalCompressible/Fluids/water_10C.jl

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@named water_20C = FluidType()
2+
const water_20C_type = typeof(get_fluid(water_20C))
3+
4+
density(::water_20C_type) = 997 # [kg/m^3]
5+
bulk_modulus(::water_20C_type) = 2.09e9 # [Pa]
6+
viscosity(::water_20C_type) = 0.0010016 # [Pa*s] or [kg/m-s]

src/Hydraulic/IsothermalCompressible/Fluids/water_30C.jl

Whitespace-only changes.

src/Hydraulic/IsothermalCompressible/IsothermalCompressible.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Library to model iso-thermal compressible fluid flow
2+
Library to model iso-thermal compressible liquid fluid flow
33
"""
44
module IsothermalCompressible
55

@@ -12,7 +12,7 @@ D = Differential(t)
1212
export HydraulicPort
1313
include("utils.jl")
1414

15-
export Source, FixedVolume, LaminarResistance
15+
export Source, InputSource, FixedVolume, Pipe
1616
include("components.jl")
1717

1818

src/Hydraulic/IsothermalCompressible/components.jl

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ end
3131

3232

3333

34-
function InputSource(;name, p)
34+
function InputSource(;name, p_int)
3535
pars = @parameters begin
36-
p = p
36+
p_int = p_int
3737
end
3838

3939
vars = []
4040

4141
systems = @named begin
42-
port = HydraulicPort(; p_int = p)
42+
port = HydraulicPort(; p_int)
4343
input = RealInput()
4444
end
4545

@@ -98,7 +98,7 @@ end
9898
"""
9999
LaminarResistance(fluid, shape=:circle; name, p_int, area, length, perimeter=2*sqrt(area*pi))
100100
101-
fixed fluid volume
101+
laminar pipe resistance
102102
103103
# Parameters:
104104
@@ -110,7 +110,7 @@ fixed fluid volume
110110
111111
- `port`: hydraulic port
112112
"""
113-
function LaminarResistance(;fluid, shape=Shapes.circle, name, p_int, area, length, perimeter=2*sqrt(area*pi))
113+
function PipeBase(;name, fluid, shape=Shapes.circle, p_int, area, length, perimeter=2*sqrt(area*pi))
114114
pars = @parameters begin
115115
p_int = p_int
116116
area = area
@@ -120,9 +120,7 @@ function LaminarResistance(;fluid, shape=Shapes.circle, name, p_int, area, lengt
120120
shape=shape
121121
end
122122

123-
vars = @variables begin
124-
v(t) = 0
125-
end
123+
vars = []
126124

127125
systems = @named begin
128126
port_a = HydraulicPort(; p_int)
@@ -133,19 +131,69 @@ function LaminarResistance(;fluid, shape=Shapes.circle, name, p_int, area, lengt
133131
# let ----------------------
134132
Δp = port_a.p - port_b.p
135133
dm = port_a.dm
134+
p = (port_a.p + port_b.p)/2
136135

137136
d_h = 4*area/perimeter
138-
rho = density(fluid, port_a.p)
139-
Re = rho*v*d_h/viscosity(fluid)
140-
f = friction_factor(shape)/Re
141-
137+
138+
ρ = density(fluid, p)
139+
μ = viscosity(fluid)
140+
Φ = shape_factor(shape)
141+
f = friction_factor(dm, area, d_h, ρ, μ, Φ)
142+
u = dm/*area)
142143

143144
eqs = [
144-
Δp ~ 1/2 * rho * v^2 * f * length
145-
dm ~ rho*v*area
146-
0 ~ port_a.dm - port_b.dm
145+
Δp ~ 1/2 * ρ * u^2 * f * (length/d_h)
146+
0 ~ port_a.dm + port_b.dm
147147
]
148148

149149
ODESystem(eqs, t, vars, pars; name, systems)
150150
end
151151

152+
function Pipe(N; name, fluid, shape=Shapes.circle, p_int, area, length, perimeter=2*sqrt(area*pi))
153+
154+
@assert(N>1, "the pipe component must be defined with more than 1 segment (i.e. N>1), found N=$N")
155+
156+
pars = @parameters begin
157+
p_int = p_int
158+
area = area
159+
length = length
160+
perimeter = perimeter
161+
fluid=fluid
162+
shape=shape
163+
end
164+
165+
vars = []
166+
167+
ports = @named begin
168+
port_a = HydraulicPort(; p_int)
169+
port_b = HydraulicPort(; p_int)
170+
end
171+
172+
173+
pipe_bases = []
174+
for i=1:N-1
175+
x = PipeBase(;name=Symbol("p$i"), fluid=ParentScope(fluid), shape=ParentScope(shape), p_int=ParentScope(p_int), area=ParentScope(area), length=ParentScope(length)/(N-1), perimeter=ParentScope(perimeter))
176+
push!(pipe_bases, x)
177+
end
178+
179+
volumes = []
180+
for i=1:N
181+
x = FixedVolume(; name=Symbol("v$i"), fluid=ParentScope(fluid), vol=ParentScope(area)*ParentScope(length)/N, p_int=ParentScope(p_int))
182+
push!(volumes, x)
183+
end
184+
185+
186+
eqs = [
187+
connect(volumes[1].port, pipe_bases[1].port_a, port_a)
188+
connect(volumes[end].port, pipe_bases[end].port_b, port_b)
189+
]
190+
191+
for i=2:N-1
192+
eq = connect(volumes[i].port, pipe_bases[i-1].port_b, pipe_bases[i].port_a)
193+
push!(eqs, eq)
194+
end
195+
196+
197+
ODESystem(eqs, t, vars, pars; name, systems=[ports; pipe_bases; volumes])
198+
end
199+

src/Hydraulic/IsothermalCompressible/utils.jl

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ Base.@doc """
1212
port for hydraulic components
1313
1414
# States:
15-
- `p`: [Pa] pressure
15+
- `p`: [Pa] gage pressure
1616
- `dm`: [kg/s] mass flow
1717
""" HydraulicPort
1818

1919

2020
struct FluidType
2121
name::Symbol
22-
value::Int
22+
value::Float64
2323
end
24-
FluidType(value; name) = FluidType(name, value)
24+
FluidType(; name) = FluidType(name, float(hash(name)))
2525

2626

2727
Base.float(x::FluidType) = Base.float(x.value)
28-
Base.eltype(x::FluidType) = Int
29-
Base.promote_type(x::Type{FluidType}, y::Type{Int64}) = Int64
28+
Base.eltype(x::FluidType) = Float64
29+
# Base.promote_type(x::Type{FluidType}, y::Type{Int64}) = Int64
3030
Base.promote_type(x::Type{FluidType}, y::Type{Float64}) = Float64
3131
Base.convert(T::Type{Float64}, x::FluidType) = float(x)
3232

@@ -35,20 +35,10 @@ function Base.show(io::IO, ::MIME"text/plain", x::FluidType)
3535
print(io, "$(x.name)::FluidType")
3636
end
3737

38-
get_fluid(x::Float64) = Val(round(Int, x))
39-
get_fluid(x::Int) = Val(x)
38+
get_fluid(x::Float64) = Val(x)
4039
get_fluid(x::FluidType) = Val(x.value)
4140

4241

43-
module Fluids
44-
import ..IsothermalCompressible: FluidType
45-
using ModelingToolkit
46-
@named water = FluidType(0)
47-
@named sae_30_oil = FluidType(1)
48-
end
49-
50-
51-
5242
density(fluid) = density(get_fluid(fluid))
5343
@register_symbolic density(fluid)
5444

@@ -59,18 +49,12 @@ viscosity(fluid) = viscosity(get_fluid(fluid))
5949
@register_symbolic viscosity(fluid)
6050

6151

62-
density(::Val{Fluids.water.value}) = 997 # [kg/m^3]
63-
bulk_modulus(::Val{Fluids.water.value}) = 2.09e9 # [Pa]
64-
viscosity(::Val{Fluids.water.value}) = 0.0010016 # [Pa*s] or [kg/m-s]
65-
66-
# https://wiki.anton-paar.com/us-en/engine-oil/ at 20C
67-
density(::Val{Fluids.sae_30_oil.value}) = 881.5
68-
bulk_modulus(::Val{Fluids.sae_30_oil.value}) = 1.5e9
69-
viscosity(::Val{Fluids.sae_30_oil.value}) = 0.23939
70-
71-
7252
density(fluid, p) = density(fluid)*(1 + p/bulk_modulus(fluid))
7353

54+
# Fluids
55+
include("Fluids/water_20C.jl")
56+
include("Fluids/sae_30_oil_20C.jl")
57+
7458

7559

7660

@@ -101,11 +85,57 @@ module Shapes
10185
import ..IsothermalCompressible: ShapeType
10286
using ModelingToolkit
10387
@named circle = ShapeType(0)
104-
@named triangle = ShapeType(1)
88+
@named square = ShapeType(1)
89+
@named triangle = ShapeType(2)
90+
@named rectangle_r2 = ShapeType(3)
91+
@named rectangle_r3 = ShapeType(4)
92+
@named rectangle_r4 = ShapeType(5)
93+
@named rectangle_r8 = ShapeType(6)
94+
@named rectangle_rinf = ShapeType(7)
10595
end
10696

97+
shape_factor(shape) = shape_factor(get_shape(shape))
98+
@register_symbolic shape_factor(shape)
99+
100+
shape_factor(::Val{Shapes.circle.value}) = 64
101+
shape_factor(::Val{Shapes.square.value}) = 57
102+
shape_factor(::Val{Shapes.triangle.value}) = 53
103+
shape_factor(::Val{Shapes.rectangle_r2.value}) = 62
104+
shape_factor(::Val{Shapes.rectangle_r3.value}) = 69
105+
shape_factor(::Val{Shapes.rectangle_r4.value}) = 73
106+
shape_factor(::Val{Shapes.rectangle_r8.value}) = 82
107+
shape_factor(::Val{Shapes.rectangle_rinf.value}) = 96
108+
109+
function friction_factor(dm, area, d_h, rho, mu, shape_factor)
110+
111+
u = abs(dm)/(rho*area)
112+
Re = maximum([rho*u*d_h/mu, 1])
113+
114+
f_laminar = shape_factor/Re
115+
116+
117+
f_turbulent = (0.79*log(Re)-1.64)^(-2)
118+
119+
f = transition(2000, 3000, f_laminar, f_turbulent, Re)
120+
121+
return f
122+
end
123+
@register_symbolic friction_factor(dm, area, d_h, rho, mu, shape_factor)
124+
125+
126+
127+
function transition(x1,x2,y1,y2,x)
128+
129+
if x < x1
130+
return y1
131+
elseif x > x2
132+
return y2
133+
else
134+
u = (x-x1)/(x2-x1)
135+
blend = 3*u^2 - 2*u^3;
136+
return (1-blend)*y1 + blend*y2;
137+
end
138+
139+
end
107140

108-
friction_factor(shape) = friction_factor(get_shape(shape))
109-
@register_symbolic friction_factor(shape)
110141

111-
friction_factor(::Val{Shapes.circle.value}) = 64

0 commit comments

Comments
 (0)