thermofluids 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- thermofluids/Base/Quantity.py +16 -0
- thermofluids/Base/Statepoint.py +1191 -0
- thermofluids/Base/__init__.py +0 -0
- thermofluids/Base/thermofluids_registry.txt +5 -0
- thermofluids/Fluids/Drag.py +169 -0
- thermofluids/Fluids/Moody.py +57 -0
- thermofluids/Fluids/PressureDrop.py +322 -0
- thermofluids/Fluids/Re.py +88 -0
- thermofluids/Fluids/__init__.py +4 -0
- thermofluids/HeatTransfer/Gr.py +12 -0
- thermofluids/HeatTransfer/NTU.py +45 -0
- thermofluids/HeatTransfer/Nusselt.py +59 -0
- thermofluids/HeatTransfer/Ra.py +22 -0
- thermofluids/HeatTransfer/TwoPhase.py +249 -0
- thermofluids/HeatTransfer/__init__.py +6 -0
- thermofluids/HeatTransfer/lmtd.py +32 -0
- thermofluids/ProcessEquipment/Column.py +1004 -0
- thermofluids/ProcessEquipment/Compressor.py +167 -0
- thermofluids/ProcessEquipment/Ejector.py +145 -0
- thermofluids/ProcessEquipment/HeatExchanger.py +109 -0
- thermofluids/ProcessEquipment/IsoCompressor.py +124 -0
- thermofluids/ProcessEquipment/Pipe.py +21 -0
- thermofluids/ProcessEquipment/Pump.py +109 -0
- thermofluids/ProcessEquipment/Turbine.py +53 -0
- thermofluids/ProcessEquipment/Valve.py +35 -0
- thermofluids/ProcessEquipment/__init__.py +3 -0
- thermofluids/Utilities/FlowDiagram.py +111 -0
- thermofluids/Utilities/__init__.py +1 -0
- thermofluids/__init__.py +3 -0
- thermofluids-2.0.0.dist-info/METADATA +29 -0
- thermofluids-2.0.0.dist-info/RECORD +32 -0
- thermofluids-2.0.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
from thermofluids import Statepoint, Quantity
|
|
2
|
+
from CoolProp.CoolProp import PropsSI
|
|
3
|
+
import math
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Compressor():
|
|
8
|
+
"""
|
|
9
|
+
Models a Compressor or Pump
|
|
10
|
+
:param inlet: [Statepoint] compressor inlet statepoint
|
|
11
|
+
:param eta: [Quantity] or [float] icentropic efficiency of turbo equipment
|
|
12
|
+
:param Pout: [Quantity] or [float] pressure at outlet of compressor or pump
|
|
13
|
+
:return: [Statepoint] compressor outlet statepoint
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, inlet=None, inject=None, eta=None, Pout=None, output_name=None, work=None):
|
|
16
|
+
self.inject = inject
|
|
17
|
+
self.inlet = inlet
|
|
18
|
+
self.eta = eta
|
|
19
|
+
self.Pout = Pout
|
|
20
|
+
self.output_name = output_name
|
|
21
|
+
self._work = work
|
|
22
|
+
self._outlet = None
|
|
23
|
+
|
|
24
|
+
def set_inlet(self, inlet):
|
|
25
|
+
self.inlet = inlet
|
|
26
|
+
|
|
27
|
+
def set_eta(self, eta):
|
|
28
|
+
self.eta = eta
|
|
29
|
+
|
|
30
|
+
def set_Pout(self, Pout):
|
|
31
|
+
self.Pout = Pout
|
|
32
|
+
|
|
33
|
+
def set_output(self, output_name):
|
|
34
|
+
self.output_name = output_name
|
|
35
|
+
|
|
36
|
+
def get_Ns_Ds(self,rpm,D_rotor,n_comps,n_stages):
|
|
37
|
+
omega = rpm*2.0*math.pi/60.0
|
|
38
|
+
self.V_dot_CFS = (self.inlet.m/n_comps/self.inlet.rho).to('ft^3*s^-1')
|
|
39
|
+
gamma = self.inlet.cp / self.inlet.cv
|
|
40
|
+
ZRTMW = self.inlet.Z*Quantity(8.3144598,'J*K^-1*mol^-1')*self.inlet.t.to('K') / self.inlet.MW
|
|
41
|
+
adiabatic_head = (gamma*ZRTMW/(gamma-1.0)*(((self.Pout.to('Pa')/self.inlet.p.to('Pa'))/n_stages)**((gamma-1.0)/gamma)-1.0)).to('ft*lbf*lbm^-1')
|
|
42
|
+
|
|
43
|
+
self.Ns = rpm * self.V_dot_CFS**0.5 / (adiabatic_head**0.75)
|
|
44
|
+
self.Ds = D_rotor.to('ft')*adiabatic_head**0.25/(self.V_dot_CFS**0.5)
|
|
45
|
+
self.omega_tip = omega*D_rotor/2.0
|
|
46
|
+
self.machN = self.omega_tip/self.inlet.ss
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def work(self):
|
|
50
|
+
if self._work is None:
|
|
51
|
+
self.get_outlet()
|
|
52
|
+
return self._work
|
|
53
|
+
|
|
54
|
+
def get_outlet(self):
|
|
55
|
+
if self._outlet is not None:
|
|
56
|
+
return self._outlet
|
|
57
|
+
|
|
58
|
+
assert isinstance(self.inlet, Statepoint), '\'inlet\' must be set to a Statepoint'
|
|
59
|
+
self._outlet = Statepoint(name=self.output_name, fluid=self.inlet.fluid)
|
|
60
|
+
self._outlet.set_source(self.inlet)
|
|
61
|
+
self._outlet.set_m(self.inlet.m)
|
|
62
|
+
self._outlet.set_p(self.Pout)
|
|
63
|
+
if "HEOS" in self.inlet.fluid:
|
|
64
|
+
# mixtures don't have H(P,S) or T(P,S) available, so you have to manually solve for the temperature then enthalpy
|
|
65
|
+
res = 1.
|
|
66
|
+
s_target = inlet.s.magnitude
|
|
67
|
+
t_guess = Statepoint(fluid=inlet.fluid, p=self.Pout, x=1.).t
|
|
68
|
+
n = 0
|
|
69
|
+
while res > 0.001:
|
|
70
|
+
s_check = Statepoint(fluid=inlet.fluid, p=self.Pout, t=t_guess).s
|
|
71
|
+
res = abs(s_target - s_check.magnitude) / s_target
|
|
72
|
+
t_guess = (t_guess.to('K') * s_target / s_check.magnitude).to('degC')
|
|
73
|
+
h_out_s = Statepoint(fluid=inlet.fluid, p=self.Pout, t=t_guess).h
|
|
74
|
+
n += 1
|
|
75
|
+
if n > 100:
|
|
76
|
+
ValueError('Mixture solver timed out')
|
|
77
|
+
elif hasattr(self.inlet,'c'):
|
|
78
|
+
self._outlet.set_c(self.inlet.c)
|
|
79
|
+
h_out_s = Statepoint(fluid=self.inlet.fluid, c=self.inlet.c, p=self.Pout, s=self.inlet.s).h
|
|
80
|
+
else:
|
|
81
|
+
h_out_s = Statepoint(fluid=self.inlet.fluid, p=self.Pout.to_base_units(), s=self.inlet.s).h
|
|
82
|
+
h_out = ((h_out_s - self.inlet.h)/self.eta + self.inlet.h)
|
|
83
|
+
self._work = self._outlet.m*(h_out - self.inlet.h)
|
|
84
|
+
self._outlet.set_h(h_out)
|
|
85
|
+
self.m_cool = 0. #this line is not used in this code, but make this code compatible with calls to isocompressor
|
|
86
|
+
|
|
87
|
+
self.CFM = (self.inlet.m/self.inlet.rho).to('ft^3/min')
|
|
88
|
+
|
|
89
|
+
return self._outlet
|
|
90
|
+
|
|
91
|
+
def get_isothermal_outlet(self):
|
|
92
|
+
assert isinstance(self.inlet, Statepoint), '\'inlet\' must be set to a Statepoint'
|
|
93
|
+
assert isinstance(self.inject, Statepoint), '\'inject\' must be set to a Statepoint'
|
|
94
|
+
|
|
95
|
+
#guess inlet flow rate
|
|
96
|
+
self.inject.set_m(self.inlet.m/4.)
|
|
97
|
+
res=1000.
|
|
98
|
+
count = 0
|
|
99
|
+
self._outlet = Statepoint(name=self.output_name, fluid=self.inlet.fluid)
|
|
100
|
+
inject_vap = Statepoint(name='inject_vap', fluid=self.inject.fluid)
|
|
101
|
+
outlet_isen = Statepoint(name='outlet_isen', fluid=self.inlet.fluid)
|
|
102
|
+
outlet_adia = Statepoint(name='outlet_adia', fluid=self.inlet.fluid)
|
|
103
|
+
|
|
104
|
+
while res>0.01:
|
|
105
|
+
c_mix = (self.inlet.c*self.inlet.m + self.inject.c*self.inject.m)/(self.inlet.m+self.inject.m)
|
|
106
|
+
|
|
107
|
+
inject_vap.set_x(1.)
|
|
108
|
+
inject_vap.set_m(self.inject.m)
|
|
109
|
+
inject_vap.set_p(self.inject.p)
|
|
110
|
+
inject_vap.set_c(self.inject.c)
|
|
111
|
+
|
|
112
|
+
h_vap = inject_vap.h - self.inject.h
|
|
113
|
+
outlet_isen.set_m(self.inlet.m + self.inject.m)
|
|
114
|
+
outlet_isen.set_p(self.Pout)
|
|
115
|
+
|
|
116
|
+
outlet_isen.set_c(c_mix)
|
|
117
|
+
outlet_isen.set_s(self.inlet.s)
|
|
118
|
+
|
|
119
|
+
outlet_adia.set_c(c_mix)
|
|
120
|
+
outlet_adia.set_p(self.Pout)
|
|
121
|
+
outlet_adia.set_m(self.inlet.m + self.inject.m)
|
|
122
|
+
outlet_adia.set_h((outlet_isen.h - self.inlet.h)/self.eta + self.inlet.h)
|
|
123
|
+
|
|
124
|
+
W_isen = self.inlet.m*(outlet_adia.h - self.inlet.h) + self.inject.m*(outlet_isen.h - self.inject.h)
|
|
125
|
+
#print self.inlet.m, outlet_isen.h, self.inlet.h, self.inject.m, self.inject.h
|
|
126
|
+
|
|
127
|
+
self._outlet.set_m(self.inlet.m + self.inject.m)
|
|
128
|
+
self._outlet.set_p(self.Pout)
|
|
129
|
+
outlet_isen.set_c(c_mix)
|
|
130
|
+
self._outlet.set_c(c_mix)
|
|
131
|
+
self._outlet.set_x(1.) #assume the outlet is saturated
|
|
132
|
+
W_iso = self.inlet.m*(self._outlet.h - self.inlet.h) + self.inject.m*(self._outlet.h - self.inject.h)
|
|
133
|
+
Q_cooling = W_isen - W_iso
|
|
134
|
+
self.m_cool = Q_cooling/h_vap
|
|
135
|
+
res = abs((self.inject.m - self.m_cool)/self.inject.m)
|
|
136
|
+
self.inject.set_m(self.m_cool)
|
|
137
|
+
if count>500:
|
|
138
|
+
warnings.warn('isothermal compressor injection flow rate did not converge after 500 iterations')
|
|
139
|
+
raise Exception()
|
|
140
|
+
|
|
141
|
+
self._work = W_iso
|
|
142
|
+
self.CFM = (self.inlet.m/self.inlet.rho).to('ft^3/min')
|
|
143
|
+
return self._outlet
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__=='__main__':
|
|
147
|
+
FPS = 'REFPROP-MIX:AMMONIA&WATER'
|
|
148
|
+
inlet = Statepoint(name='inlet', fluid=FPS)
|
|
149
|
+
inlet.set_m(Quantity(0.001,'kg*s^-1'))
|
|
150
|
+
inlet.set_x(Quantity(1.,''))
|
|
151
|
+
inlet.set_c(Quantity(1.,''))
|
|
152
|
+
inlet.set_p(Quantity(1,'bar'))
|
|
153
|
+
|
|
154
|
+
eta_comp = .8
|
|
155
|
+
P_comp = Quantity(2.5,'bar')
|
|
156
|
+
|
|
157
|
+
comp = Compressor(inlet=inlet, eta=eta_comp, Pout=P_comp)
|
|
158
|
+
comp.get_outlet()
|
|
159
|
+
W_comp = comp.work
|
|
160
|
+
print(comp.outlet.h, comp.outlet.p, comp.outlet.c, comp.outlet.m, W_comp)
|
|
161
|
+
|
|
162
|
+
# fluid = "HEOS::R32[0.689]&R1234yf[0.311]"
|
|
163
|
+
# inlet = Statepoint(fluid=fluid, p=7., t=20., m=0.4)
|
|
164
|
+
# comp = Compressor(inlet=inlet, eta=0.8, Pout=19.)
|
|
165
|
+
# print(comp.get_outlet())
|
|
166
|
+
# print(comp.work)
|
|
167
|
+
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Model of jet ejector based on http://ijlct.oxfordjournals.org/content/early/2009/01/01/ijlct.ctn001.full
|
|
3
|
+
|
|
4
|
+
Fundamentally, an ejector converts thermal energy to kinetic energy by expanding a motive gas to high velocity and low pressure.
|
|
5
|
+
The low pressure gas entrains a secondary fluid, transferring kinetic energy from the motive to the secondary gas.
|
|
6
|
+
Then, the kinetic energy is converted back to thermal energy which increases the pressure and reduces the velocity.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from math import sqrt
|
|
12
|
+
from thermofluids import Statepoint
|
|
13
|
+
from CoolProp.CoolProp import PropsSI
|
|
14
|
+
|
|
15
|
+
# refrigerants = ['R23', 'R32', 'R41', 'R125', 'R134a', 'R143a', 'R152a', 'R161', 'R227ea', 'R236ea', 'R236fa', 'R245ca', 'R245fa', 'R365mfc', 'R1233zd(E)', 'R1234yf', 'R1234ze(E)',
|
|
16
|
+
# 'RE143a', 'RE245cb2', 'RE245fa2', 'RE347mcc',
|
|
17
|
+
# 'R21', 'R22', 'R123', 'R124', 'R141b', 'R142b',
|
|
18
|
+
# 'R11', 'R12', 'R13', 'R113', 'R114', 'R115',
|
|
19
|
+
# 'R14', 'R116', 'R218', 'R1216', 'C4F10', 'C5F12', 'RC318',
|
|
20
|
+
# 'Novec649']
|
|
21
|
+
#
|
|
22
|
+
# for fluid in refrigerants:
|
|
23
|
+
# try:
|
|
24
|
+
# # print fluid, '\t', PropsSI('T', 'Q', 0.5, 'P', 0.4e5, 'REFPROP::'+fluid)-273.15
|
|
25
|
+
# h_vap = PropsSI('H', 'Q', 1., 'T', 60.+273., 'REFPROP::'+fluid) - PropsSI('H', 'Q', 0., 'T', 60.+273., 'REFPROP::'+fluid)
|
|
26
|
+
# P_sat = PropsSI('P', 'Q', 0.5, 'T', 60.+273., 'REFPROP::'+fluid)/1.e5
|
|
27
|
+
# s_ref = PropsSI('S', 'Q', 1., 'P', P_sat*1.e5, 'REFPROP::'+fluid)
|
|
28
|
+
# T_exp = PropsSI('T', 'S', s_ref, 'P', 0.2e5, 'REFPROP::'+fluid) - 273.15
|
|
29
|
+
# print fluid, '\t', P_sat, '\t', h_vap/1000., T_exp
|
|
30
|
+
# except:
|
|
31
|
+
# print fluid, 'failed'
|
|
32
|
+
#
|
|
33
|
+
# print
|
|
34
|
+
# print
|
|
35
|
+
# print
|
|
36
|
+
|
|
37
|
+
mot_fluid = 'REFPROP::Novec649'
|
|
38
|
+
entr_fluid = 'Ammonia'
|
|
39
|
+
|
|
40
|
+
eta_nozzle = 0.9
|
|
41
|
+
entr_ratio = 0.3
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
"Motive fluid from superheater to expansion nozzle"
|
|
45
|
+
inlet = Statepoint(name='inlet', fluid=mot_fluid)
|
|
46
|
+
inlet.set_p(1.45)
|
|
47
|
+
inlet.set_t(PropsSI('T', 'Q', 0.5, 'P', inlet.p*1.e5, mot_fluid)-273.15 + 3.) # 3C superheat
|
|
48
|
+
inlet.set_m(0.27 / entr_ratio)
|
|
49
|
+
print('Evaporator:', PropsSI('T', 'Q', 0.5, 'P', inlet.p*1.e5, mot_fluid)-273.15)
|
|
50
|
+
|
|
51
|
+
"Motive fluid isentropic expansion"
|
|
52
|
+
nozzle_s = Statepoint(name='nozzle_s')
|
|
53
|
+
nozzle_s.set_source(inlet, ('fluid', 'm', 's')) # isentropic expansion
|
|
54
|
+
nozzle_s.set_p(0.2)
|
|
55
|
+
|
|
56
|
+
"Motive fluid real expansion"
|
|
57
|
+
nozzle = Statepoint(name='nozzle')
|
|
58
|
+
nozzle.set_source(inlet, ('fluid', 'm'))
|
|
59
|
+
nozzle.set_p(nozzle_s.p)
|
|
60
|
+
nozzle.set_h(nozzle.source[0].h - eta_nozzle * (nozzle.source[0].h - nozzle_s.h))
|
|
61
|
+
nozzle.vel = sqrt(2.*(nozzle.source[0].h - nozzle.h)*1000.) # convert thermal energy to kinetic energy
|
|
62
|
+
nozzle.Ma = nozzle.vel / nozzle.ss
|
|
63
|
+
if PropsSI('T', 'Q', 0.5, 'P', nozzle.p*1.e5, mot_fluid)-273.15 >= nozzle.t:
|
|
64
|
+
raise Exception('Motive fluid condensing in primary nozzle')
|
|
65
|
+
print('Motive Ma:', nozzle.vel / nozzle.ss)
|
|
66
|
+
|
|
67
|
+
"Entrained fluid from boiler to entrainment"
|
|
68
|
+
entr_inlet = Statepoint(name='entr_inlet', fluid=entr_fluid)
|
|
69
|
+
entr_inlet.set_p(nozzle.p)
|
|
70
|
+
entr_inlet.set_x(1.) # saturated vapor inlet
|
|
71
|
+
entr_inlet.set_m(inlet.m * entr_ratio)
|
|
72
|
+
|
|
73
|
+
"Motive fluid after mixing"
|
|
74
|
+
mix_mot = Statepoint(name='mix_mot')
|
|
75
|
+
mix_mot.set_source(nozzle, ('fluid', 'm', 'p', 'h'))
|
|
76
|
+
mix_mot.vel = mix_mot.source[0].m / (mix_mot.source[0].m + entr_inlet.m) * mix_mot.source[0].vel
|
|
77
|
+
|
|
78
|
+
"Entrained fluid after mixing"
|
|
79
|
+
mix_entr = Statepoint(name='mix_entr')
|
|
80
|
+
mix_entr.set_source(entr_inlet, ('fluid', 'm', 'p', 'h'))
|
|
81
|
+
mix_entr.vel = mix_mot.vel
|
|
82
|
+
|
|
83
|
+
mix_ss = (1.-entr_ratio)*mix_mot.ss + entr_ratio*mix_entr.ss
|
|
84
|
+
print('Mixture Ma:', mix_mot.vel / mix_ss)
|
|
85
|
+
print('Mixture:', mix_mot.t, mix_entr.t)
|
|
86
|
+
|
|
87
|
+
"Motive fluid through con-di nozzle"
|
|
88
|
+
mot_recomp = Statepoint('mot_recomp')
|
|
89
|
+
mot_recomp.set_source(mix_mot, ('fluid', 'm'))
|
|
90
|
+
mot_recomp.set_h(mot_recomp.source[0].h + 0.5*mot_recomp.source[0].vel**2./1000.)
|
|
91
|
+
mot_recomp.set_s(mot_recomp.source[0].s)
|
|
92
|
+
|
|
93
|
+
"Entrained fluid through con-di nozzle"
|
|
94
|
+
entr_recomp = Statepoint('entr_recomp')
|
|
95
|
+
entr_recomp.set_source(mix_entr, ('fluid', 'm'))
|
|
96
|
+
entr_recomp.set_h(entr_recomp.source[0].h + 0.5*entr_recomp.source[0].vel**2./1000.)
|
|
97
|
+
entr_recomp.set_s(entr_recomp.source[0].s)
|
|
98
|
+
W_comp = entr_recomp.m * (entr_recomp.h - entr_recomp.source[0].h)
|
|
99
|
+
print('Compression work:', W_comp)
|
|
100
|
+
|
|
101
|
+
"Motive fluid condensation"
|
|
102
|
+
mot_cond = Statepoint('mot_cond')
|
|
103
|
+
mot_cond.set_source(mot_recomp, ('fluid', 'm', 'p'))
|
|
104
|
+
mot_cond.set_x(0.)
|
|
105
|
+
print('Condenser:', mot_cond.t, mot_cond.p)
|
|
106
|
+
|
|
107
|
+
"Entrained fluid condensation"
|
|
108
|
+
entr_cond = Statepoint('entr_cond')
|
|
109
|
+
entr_cond.set_source(entr_recomp, ('fluid', 'm', 'p'))
|
|
110
|
+
entr_cond.set_t(mot_cond.t)
|
|
111
|
+
|
|
112
|
+
Q_cond = mot_cond.m * (mot_cond.source[0].h - mot_cond.h) + entr_cond.m * (entr_cond.source[0].h - entr_cond.h)
|
|
113
|
+
print('Condenser load:', Q_cond)
|
|
114
|
+
|
|
115
|
+
"Pump motive fluid"
|
|
116
|
+
mot_pump = Statepoint('mot_pump')
|
|
117
|
+
mot_pump.set_source(mot_cond, ('fluid', 'm', 's'))
|
|
118
|
+
mot_pump.set_p(inlet.p)
|
|
119
|
+
|
|
120
|
+
"Pump entrained fluid"
|
|
121
|
+
entr_pump = Statepoint('entr_pump')
|
|
122
|
+
entr_pump.set_source(entr_cond, ('fluid', 'm', 's'))
|
|
123
|
+
entr_pump.set_p(1.)
|
|
124
|
+
|
|
125
|
+
W_pump = mot_pump.m * (mot_pump.h - mot_pump.source[0].h) + entr_pump.m * (entr_pump.h - entr_pump.source[0].h)
|
|
126
|
+
print('Pump work:', W_pump)
|
|
127
|
+
|
|
128
|
+
"Preheat motive fluid"
|
|
129
|
+
mot_preheat = Statepoint('mot_preheat')
|
|
130
|
+
mot_preheat.set_source(mot_pump, ('fluid', 'm', 'p'))
|
|
131
|
+
mot_preheat.set_x(0.)
|
|
132
|
+
Q_preheat = mot_preheat.m * (mot_preheat.h - mot_preheat.source[0].h)
|
|
133
|
+
print('Preheat load:', Q_preheat)
|
|
134
|
+
|
|
135
|
+
"Boil motive fluid"
|
|
136
|
+
mot_boil = inlet
|
|
137
|
+
mot_boil.set_source(mot_preheat)
|
|
138
|
+
Q_boil = mot_boil.m * (mot_boil.h - mot_boil.source[0].h)
|
|
139
|
+
print('Boiler load:', Q_boil)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
eta_carnot = 1. - (mot_cond.t+273.15) / (inlet.t+273.15)
|
|
143
|
+
print('Actual efficiency:', W_comp / (Q_boil+Q_preheat))
|
|
144
|
+
print('Carnot efficiency:', eta_carnot)
|
|
145
|
+
print('Percent carnot:', (W_comp / (Q_boil+Q_preheat)) / eta_carnot)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from thermofluids.Base import Statepoint
|
|
2
|
+
from thermofluids.Base import Quantity
|
|
3
|
+
import types
|
|
4
|
+
from CoolProp.CoolProp import PropsSI
|
|
5
|
+
|
|
6
|
+
class HX_Energy():
|
|
7
|
+
def __init__(self, cold_inlet=None, hot_inlet=None, cold_outlet=None, hot_outlet=None, pinch=None,
|
|
8
|
+
cold_inlet_name='cold_inlet', cold_outlet_name='cold_outlet', hot_inlet_name='hot_inlet', hot_outlet_name='hot_outlet'):
|
|
9
|
+
"""
|
|
10
|
+
Models a HX using an energy balance only. Any 3 of the following must be supplied:
|
|
11
|
+
hot inlet, hot outlet, cold inlet, cold outlet, or Pinch
|
|
12
|
+
:param cold_inlet: [Statepoint] HX cold inlet
|
|
13
|
+
:param hot_inlet: [Statepoint] HX hot inlet
|
|
14
|
+
:param cold_outlet: [Statepoint] HX cold outlet
|
|
15
|
+
:param hot_outlet: [Statepoint] HX hot outlet
|
|
16
|
+
:param pinch: [Quantity] or [float] Smallest pinch point at outlet of HX
|
|
17
|
+
:param cold_inlet_name: [string] name for cold inlet statepoint
|
|
18
|
+
:param cold_out_name: [string] name for cold outlet statepoint
|
|
19
|
+
:param hot_inlet_name: [string] name for hot inlet statepoint
|
|
20
|
+
:param hot_outlet_name: [string] name for hot outlet statepoint
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
self.cold_inlet = cold_inlet
|
|
24
|
+
self.hot_inlet = hot_inlet
|
|
25
|
+
self.cold_outlet = cold_outlet
|
|
26
|
+
self.hot_outlet = hot_outlet
|
|
27
|
+
self.pinch = pinch
|
|
28
|
+
self.cold_inlet_name = cold_inlet_name
|
|
29
|
+
self.cold_outlet_name = cold_outlet_name
|
|
30
|
+
self.hot_inlet_name = hot_inlet_name
|
|
31
|
+
self.hot_outlet_name = hot_outlet_name
|
|
32
|
+
|
|
33
|
+
def get_states(self):
|
|
34
|
+
flag_co = 0
|
|
35
|
+
flag_ci = 0
|
|
36
|
+
flag_ho = 0
|
|
37
|
+
flag_hi = 0
|
|
38
|
+
flag_p = 0
|
|
39
|
+
|
|
40
|
+
if self.cold_outlet is None:
|
|
41
|
+
flag_co=1
|
|
42
|
+
self.cold_outlet = Statepoint(name=self.cold_outlet_name, fluid=self.cold_inlet.fluid)
|
|
43
|
+
self.cold_outlet.set_t(max(self.cold_inlet.t, self.hot_inlet.t))
|
|
44
|
+
self.cold_outlet.set_m(self.cold_inlet.m)
|
|
45
|
+
self.cold_outlet.set_p(self.cold_inlet.p)
|
|
46
|
+
self.cold_outlet.set_c(self.cold_inlet.c)
|
|
47
|
+
if self.cold_inlet is None:
|
|
48
|
+
flag_ci=1
|
|
49
|
+
self.cold_inlet = Statepoint(name=self.cold_inlet_name, fluid=self.cold_outlet.fluid)
|
|
50
|
+
self.cold_inlet.set_t(min(self.hot_outlet.t, self.cold_outlet.t))
|
|
51
|
+
self.cold_inlet.set_m(self.cold_outlet.m)
|
|
52
|
+
self.cold_inlet.set_p(self.cold_outlet.p)
|
|
53
|
+
self.cold_inlet.set_c(self.cold_outlet.c)
|
|
54
|
+
if self.hot_outlet is None:
|
|
55
|
+
flag_ho=1
|
|
56
|
+
self.hot_outlet = Statepoint(name=self.hot_outlet_name, fluid=self.hot_inlet.fluid)
|
|
57
|
+
self.hot_outlet.set_t(min(self.cold_inlet.t, self.hot_inlet.t))
|
|
58
|
+
self.hot_outlet.set_m(self.hot_inlet.m)
|
|
59
|
+
self.hot_outlet.set_p(self.hot_inlet.p)
|
|
60
|
+
self.hot_outlet.set_c(self.hot_inlet.c)
|
|
61
|
+
if self.hot_inlet is None:
|
|
62
|
+
flag_hi=1
|
|
63
|
+
self.hot_inlet = Statepoint(name=self.hot_inlet_name, fluid=self.hot_outlet.fluid)
|
|
64
|
+
self.hot_inlet.set_t(max(self.cold_outlet.t, self.hot_outlet.t))
|
|
65
|
+
self.hot_inlet.set_m(self.hot_outlet.m)
|
|
66
|
+
self.hot_inlet.set_p(self.hot_outlet.p)
|
|
67
|
+
self.hot_inlet.set_c(self.hot_outlet.c)
|
|
68
|
+
if self.pinch is None:
|
|
69
|
+
flag_p=1
|
|
70
|
+
|
|
71
|
+
C_cold = self.cold_inlet.m * self.cold_inlet.cp
|
|
72
|
+
C_hot = self.hot_inlet.m * self.hot_inlet.cp
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if (float(C_cold) > float(C_hot)) and (flag_ho > 0) and (flag_p == 0):
|
|
76
|
+
self.hot_outlet.update_prop(prop_val=self.cold_inlet.t + self.pinch, prop_name='T')
|
|
77
|
+
elif (float(C_cold) > float(C_hot)) and (flag_ci > 0) and (flag_p == 0):
|
|
78
|
+
self.cold_inlet.update_prop(prop_val=self.hot_outlet.t - self.pinch, prop_name='T')
|
|
79
|
+
elif (float(C_cold) <= float(C_hot)) and (flag_hi > 0) and (flag_p == 0):
|
|
80
|
+
self.hot_inlet.update_prop(prop_val=self.cold_outlet.t + self.pinch, prop_name='T')
|
|
81
|
+
elif (float(C_cold) <= float(C_hot)) and (flag_co > 0) and (flag_p == 0):
|
|
82
|
+
self.cold_outlet.update_prop(prop_val=self.hot_inlet.t - self.pinch, prop_name='T')
|
|
83
|
+
|
|
84
|
+
Q_HX_cold = self.cold_outlet.m*(self.cold_outlet.h-self.cold_inlet.h)
|
|
85
|
+
Q_HX_hot = self.hot_outlet.m*(self.hot_inlet.h-self.hot_outlet.h)
|
|
86
|
+
self.Q_HX = max(Q_HX_cold, Q_HX_hot)
|
|
87
|
+
|
|
88
|
+
if (flag_ho > 0) and (float(C_cold) <= float(C_hot)):
|
|
89
|
+
self.hot_outlet.update_prop(prop_val=self.hot_inlet.t - Q_HX_cold/(self.hot_inlet.m * self.hot_inlet.cp), prop_name='T')
|
|
90
|
+
if (flag_hi > 0) and (float(C_cold) > float(C_hot)):
|
|
91
|
+
self.hot_inlet.update_prop(prop_val=self.hot_outlet.t + Q_HX_cold/(self.hot_outlet.m * self.hot_outlet.cp), prop_name='T')
|
|
92
|
+
if (flag_ci > 0) and (float(C_cold) <= float(C_hot)):
|
|
93
|
+
self.cold_inlet.update_prop(prop_val=self.cold_outlet.t - Q_HX_hot/(self.cold_outlet.m * self.cold_outlet.cp), prop_name='T')
|
|
94
|
+
if(flag_co > 0) and (float(C_cold) > float(C_hot)):
|
|
95
|
+
self.cold_outlet.update_prop(prop_val=self.cold_inlet.t + Q_HX_hot/(self.cold_inlet.m * self.cold_inlet.cp), prop_name='T')
|
|
96
|
+
|
|
97
|
+
if (flag_p > 0):
|
|
98
|
+
if (float(C_cold) > float(C_hot)):
|
|
99
|
+
self.pinch = self.hot_outlet.t - self.cold_inlet.t
|
|
100
|
+
else:
|
|
101
|
+
self.pinch = self.hot_inlet.t - self.cold_outlet.t
|
|
102
|
+
if (flag_ho > 0):
|
|
103
|
+
self.hot_outlet.update_prop(prop_val=self.hot_inlet.t - Q_HX_cold/(self.hot_inlet.m * self.hot_inlet.cp), prop_name='T')
|
|
104
|
+
if (flag_hi > 0):
|
|
105
|
+
self.hot_inlet.update_prop(prop_val=self.hot_outlet.t + Q_HX_cold/(self.hot_outlet.m * self.hot_outlet.cp), prop_name='T')
|
|
106
|
+
if (flag_ci > 0):
|
|
107
|
+
self.cold_inlet.update_prop(prop_val=self.cold_outlet.t - Q_HX_hot/(self.cold_outlet.m * self.cold_outlet.cp), prop_name='T')
|
|
108
|
+
if(flag_co > 0):
|
|
109
|
+
self.cold_outlet.update_prop(prop_val=self.cold_inlet.t + Q_HX_hot/(self.cold_inlet.m * self.cold_inlet.cp), prop_name='T')
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
from thermofluids.Base import Quantity
|
|
4
|
+
from thermofluids.Base import Statepoint
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IsoCompressor():
|
|
9
|
+
def __init__(self, inlet=None, inject=None, Pout=None, output_name=None, work=None, eta=None):
|
|
10
|
+
"""
|
|
11
|
+
Models an Isothermal Compressor or Pump
|
|
12
|
+
:param inlet: [Statepoint] compressor inlet statepoint
|
|
13
|
+
:param injeciton: [Statepoint] cooling injection stream
|
|
14
|
+
:param eta: [Quantity] or [float] icentropic efficiency of turbo equipment
|
|
15
|
+
:param Pout: [Quantity] or [float] pressure at outlet of compressor or pump
|
|
16
|
+
:return: [Statepoint] compressor outlet statepoint
|
|
17
|
+
"""
|
|
18
|
+
self.inject = inject
|
|
19
|
+
self.inlet = inlet
|
|
20
|
+
self.Pout = Pout
|
|
21
|
+
self.output_name = output_name
|
|
22
|
+
self.work = work
|
|
23
|
+
self.eta = eta
|
|
24
|
+
print(self.inlet)
|
|
25
|
+
|
|
26
|
+
def set_inlet(self, inlet):
|
|
27
|
+
self.inlet = inlet
|
|
28
|
+
|
|
29
|
+
def set_eta(self, eta):
|
|
30
|
+
self.eta = eta
|
|
31
|
+
|
|
32
|
+
def set_Pout(self, Pout):
|
|
33
|
+
self.Pout = Pout
|
|
34
|
+
|
|
35
|
+
def set_output_name(self, output_name):
|
|
36
|
+
self.output_name = output_name
|
|
37
|
+
|
|
38
|
+
def get_Ns_Ds(self, rpm, D_rotor, n_comps, n_stages):
|
|
39
|
+
omega = rpm * 2.0 * math.pi / 60.0
|
|
40
|
+
self.V_dot_CFS = (self.inlet.m / n_comps / self.inlet.rho).to('ft^3*s^-1')
|
|
41
|
+
gamma = self.inlet.cp / self.inlet.cv
|
|
42
|
+
ZRTMW = self.inlet.Z * Quantity(8.3144598, 'J*K^-1*mol^-1') * self.inlet.t.to('K') / self.inlet.MW
|
|
43
|
+
adiabatic_head = (gamma * ZRTMW / (gamma - 1.0) * (
|
|
44
|
+
((self.Pout.to('Pa') / self.inlet.p.to('Pa')) / n_stages) ** (
|
|
45
|
+
(gamma - 1.0) / gamma) - 1.0)).to('ft*lbf*lbm^-1')
|
|
46
|
+
|
|
47
|
+
self.Ns = rpm * self.V_dot_CFS ** 0.5 / (adiabatic_head ** 0.75)
|
|
48
|
+
self.Ds = D_rotor.to('ft') * adiabatic_head ** 0.25 / (self.V_dot_CFS ** 0.5)
|
|
49
|
+
self.omega_tip = omega * D_rotor / 2.0
|
|
50
|
+
self.machN = self.omega_tip / self.inlet.ss
|
|
51
|
+
|
|
52
|
+
def get_outlet(self):
|
|
53
|
+
|
|
54
|
+
assert isinstance(self.inlet, Statepoint), '\'inlet\' must be set to a Statepoint'
|
|
55
|
+
assert isinstance(self.inject, Statepoint), '\'inject\' must be set to a Statepoint'
|
|
56
|
+
|
|
57
|
+
#guess inlet flow rate
|
|
58
|
+
self.inject.set_m(self.inlet.m/4.)
|
|
59
|
+
res=1000.
|
|
60
|
+
count = 0
|
|
61
|
+
self.outlet = Statepoint(name=self.output_name, fluid=self.inlet.fluid)
|
|
62
|
+
inject_vap = Statepoint(name='inject_vap', fluid=self.inject.fluid)
|
|
63
|
+
outlet_isen = Statepoint(name='outlet_isen', fluid=self.inlet.fluid)
|
|
64
|
+
outlet_adia = Statepoint(name='outlet_adia', fluid=self.inlet.fluid)
|
|
65
|
+
|
|
66
|
+
while res>0.01:
|
|
67
|
+
c_mix = (self.inlet.c*self.inlet.m + self.inject.c*self.inject.m)/(self.inlet.m+self.inject.m)
|
|
68
|
+
|
|
69
|
+
inject_vap.set_x(1.)
|
|
70
|
+
inject_vap.set_m(self.inject.m)
|
|
71
|
+
inject_vap.set_p(self.inject.p)
|
|
72
|
+
inject_vap.set_c(self.inject.c)
|
|
73
|
+
|
|
74
|
+
h_vap = inject_vap.h - self.inject.h
|
|
75
|
+
outlet_isen.set_m(self.inlet.m + self.inject.m)
|
|
76
|
+
outlet_isen.set_p(self.Pout)
|
|
77
|
+
|
|
78
|
+
outlet_isen.set_c(c_mix)
|
|
79
|
+
outlet_isen.set_s(self.inlet.s)
|
|
80
|
+
|
|
81
|
+
outlet_adia.set_c(c_mix)
|
|
82
|
+
outlet_adia.set_p(self.Pout)
|
|
83
|
+
outlet_adia.set_m(self.inlet.m + self.inject.m)
|
|
84
|
+
print(outlet_isen.h, self.inlet.h, self.eta, self.inlet.h)
|
|
85
|
+
outlet_adia.set_h((outlet_isen.h - self.inlet.h)/self.eta + self.inlet.h)
|
|
86
|
+
|
|
87
|
+
W_isen = self.inlet.m*(outlet_adia.h - self.inlet.h) + self.inject.m*(outlet_isen.h - self.inject.h)
|
|
88
|
+
#print self.inlet.m, outlet_isen.h, self.inlet.h, self.inject.m, self.inject.h
|
|
89
|
+
|
|
90
|
+
self.outlet.set_m(self.inlet.m + self.inject.m)
|
|
91
|
+
self.outlet.set_p(self.Pout)
|
|
92
|
+
outlet_isen.set_c(c_mix)
|
|
93
|
+
self.outlet.set_c(c_mix)
|
|
94
|
+
self.outlet.set_x(1.) #assume the outlet is saturated
|
|
95
|
+
W_iso = self.inlet.m*(self.outlet.h - self.inlet.h) + self.inject.m*(self.outlet.h - self.inject.h)
|
|
96
|
+
Q_cooling = W_isen - W_iso
|
|
97
|
+
self.m_cool = Q_cooling/h_vap
|
|
98
|
+
res = abs((self.inject.m - self.m_cool)/self.inject.m)
|
|
99
|
+
self.inject.set_m(self.m_cool)
|
|
100
|
+
if count>500:
|
|
101
|
+
warnings.warn('isothermal compressor injection flow rate did not converge after 500 iterations')
|
|
102
|
+
raise Exception()
|
|
103
|
+
|
|
104
|
+
self.work = W_iso
|
|
105
|
+
self.CFM = Quantity(float(self.inlet.m/self.inlet.rho)*2118.88,'ft^3/min')
|
|
106
|
+
return self.outlet
|
|
107
|
+
|
|
108
|
+
if __name__=='__main__':
|
|
109
|
+
#inputs
|
|
110
|
+
R_HX = 1.
|
|
111
|
+
FPS = 'REFPROP-MIX:METHANOL&WATER'
|
|
112
|
+
inject = Statepoint(name='inject', fluid=FPS)
|
|
113
|
+
inlet = Statepoint(name='inlet', fluid=FPS)
|
|
114
|
+
inject.set_x(.0)
|
|
115
|
+
inject.set_c(.72)
|
|
116
|
+
inject.set_p(1.0)
|
|
117
|
+
|
|
118
|
+
inlet.set_x(1.)
|
|
119
|
+
inlet.set_c(0.72)
|
|
120
|
+
inlet.set_p(1.0)
|
|
121
|
+
inlet.set_m(0.035)
|
|
122
|
+
comp = IsoCompressor(inlet=inlet, inject=inject, Pout=2., eta=1)
|
|
123
|
+
comp.get_outlet()
|
|
124
|
+
print(comp.work)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from thermofluids.Base import Statepoint
|
|
2
|
+
|
|
3
|
+
class Pipe():
|
|
4
|
+
def __init__(self, inlet=None):
|
|
5
|
+
self.inlet = inlet
|
|
6
|
+
|
|
7
|
+
def get_outlet(self):
|
|
8
|
+
outlet = Statepoint()
|
|
9
|
+
outlet.set_source(self.inlet, ('fluid', 'm', 'h', 'p'))
|
|
10
|
+
|
|
11
|
+
return outlet
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
inlet = Statepoint()
|
|
15
|
+
inlet.set_fluid("water")
|
|
16
|
+
inlet.set_p(1.)
|
|
17
|
+
inlet.set_m(1.)
|
|
18
|
+
inlet.set_t(25.)
|
|
19
|
+
|
|
20
|
+
pipe = Pipe(inlet)
|
|
21
|
+
print(pipe.get_outlet())
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from thermofluids.Base import Statepoint
|
|
2
|
+
from thermofluids.Base import Quantity
|
|
3
|
+
from CoolProp.CoolProp import PropsSI
|
|
4
|
+
from thermofluids.Properties.BrineProps import get_c_freeze, get_h_f, get_T_liq_sat, get_T_vap_sat, get_h_mix, get_C_vap_sat, get_C_liq_sat, get_c_satliq_at_t, get_c_satvap_at_t
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
# these values are taken from the manufacterers speck. Flow must be in m^3/s and pressure in bara.
|
|
8
|
+
PUMP_CURVE_DIC = {"IWAKI_M251": {"NPSHr": {
|
|
9
|
+
"flow": [0.000145517,0.00024495,0.00037565,0.000571933,0.001,0.0009168,0.001111983,0.0012997,0.001454833,0.001599733,0.001789267,0.001951767,0.00213965,0.002287983,0.0024091,0.00254205],
|
|
10
|
+
"pressure": [0.424, 0.348, 0.295, 0.231, 0.203, 0.205, 0.225, 0.268, 0.306, 0.356, 0.421, 0.481, 0.547, 0.600,0.639, 0.654]},
|
|
11
|
+
"pump_curve": {
|
|
12
|
+
"flow": [0.000166667,0.0005,0.000824567,0.001087717,0.001324567,0.001526317,0.001745617,0.001956133,0.00214035,0.002324567,0.002535083],
|
|
13
|
+
"pressure": [3.052436053,3.032940359,2.994046941,2.942025769,2.883636658,2.825149578,2.747166805,2.662718123,2.57836741,2.487354852,2.376944569]}}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class Pump():
|
|
17
|
+
|
|
18
|
+
def __init__(self, inlet=None, outlet_P=None, name=None):
|
|
19
|
+
self.name = name
|
|
20
|
+
self.inlet = inlet
|
|
21
|
+
self.outlet_P = outlet_P
|
|
22
|
+
self.max_flow = 0
|
|
23
|
+
self.max_P = 0
|
|
24
|
+
self.NPSHr=0
|
|
25
|
+
|
|
26
|
+
def set_outlet_P(self,outlet_P):
|
|
27
|
+
self.outlet_P = outlet_P
|
|
28
|
+
|
|
29
|
+
def set_inlet(self,inlet):
|
|
30
|
+
self.inlet = inlet
|
|
31
|
+
|
|
32
|
+
def set_name(self, name):
|
|
33
|
+
self.name = name
|
|
34
|
+
|
|
35
|
+
def flow_at_outlet_P(self):
|
|
36
|
+
x = 0
|
|
37
|
+
if(self.name=="M251" or self.name=="iwaki-M251" or self.name=="IWAKI-M251" or self.name=="Iwaki-M251" or self.name=="m251"):
|
|
38
|
+
pump_key = "IWAKI_M251"
|
|
39
|
+
if PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][0]<self.outlet_P:
|
|
40
|
+
warnings.warn('specified pump can reach max head of '+str(PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][0])+'bar and cannot meet the required head of '+str(self.outlet_P))
|
|
41
|
+
else:
|
|
42
|
+
while x < len(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"]):
|
|
43
|
+
print(PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x], self.outlet_P)
|
|
44
|
+
if(PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x]<self.outlet_P):
|
|
45
|
+
P_right = PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x]
|
|
46
|
+
P_left = PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x-1]
|
|
47
|
+
flow_right = PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x]
|
|
48
|
+
flow_left = PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x-1]
|
|
49
|
+
self.maxFlow = Quantity(flow_left + (self.outlet_P.magnitude - P_left) / (P_right - P_left) * (flow_right - flow_left),'m^3/s')
|
|
50
|
+
x = 100000
|
|
51
|
+
if(x==len(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"])):
|
|
52
|
+
self.maxFlow = flow_right = PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x-1]
|
|
53
|
+
x = 100000
|
|
54
|
+
x = x + 1
|
|
55
|
+
|
|
56
|
+
x = 0
|
|
57
|
+
while x < len(PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"]):
|
|
58
|
+
if (PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x] > self.maxFlow):
|
|
59
|
+
P_right = PUMP_CURVE_DIC[pump_key]["NPSHr"]["pressure"][x]
|
|
60
|
+
P_left = PUMP_CURVE_DIC[pump_key]["NPSHr"]["pressure"][x - 1]
|
|
61
|
+
flow_right = PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x]
|
|
62
|
+
flow_left = PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x - 1]
|
|
63
|
+
self.NPSHr = Quantity(
|
|
64
|
+
0.0597216 + P_left + (inlet_flow.magnitude - flow_left) / (flow_right - flow_left) * (P_right - P_left), 'bar')
|
|
65
|
+
x = 100000
|
|
66
|
+
x = x + 1
|
|
67
|
+
|
|
68
|
+
def P_at_inlet_flow(self):
|
|
69
|
+
inlet_flow = self.inlet.m/self.inlet.rho
|
|
70
|
+
x=0
|
|
71
|
+
if(self.name=="M251" or self.name=="iwaki-M251" or self.name=="IWAKI-M251" or self.name=="Iwaki-M251" or self.name=="m251"):
|
|
72
|
+
pump_key = "IWAKI_M251"
|
|
73
|
+
if PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][len(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"])-1]<inlet_flow:
|
|
74
|
+
warnings.warn('specified pump can reach max flow of '+PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][len(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"])-1]+'m^3/s and cannot meet the required head of '+intlet_flows)
|
|
75
|
+
else:
|
|
76
|
+
while x<len(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"]):
|
|
77
|
+
if(PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x]>inlet_flow):
|
|
78
|
+
P_right = PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x]
|
|
79
|
+
P_left = PUMP_CURVE_DIC[pump_key]["pump_curve"]["pressure"][x-1]
|
|
80
|
+
flow_right = PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x]
|
|
81
|
+
flow_left = PUMP_CURVE_DIC[pump_key]["pump_curve"]["flow"][x-1]
|
|
82
|
+
self.max_P = Quantity(P_left + (inlet_flow.magnitude - flow_left)/(flow_right-flow_left)*(P_right-P_left),'bar')
|
|
83
|
+
#print (self.max_P-1.0)*401.0/12.,P_left, P_right, flow_left, flow_right, inlet_flow.magnitude, x
|
|
84
|
+
x = 100000
|
|
85
|
+
x=x+1
|
|
86
|
+
|
|
87
|
+
x=0
|
|
88
|
+
while x<len(PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"]):
|
|
89
|
+
if(PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x]>inlet_flow):
|
|
90
|
+
P_right = PUMP_CURVE_DIC[pump_key]["NPSHr"]["pressure"][x]
|
|
91
|
+
P_left = PUMP_CURVE_DIC[pump_key]["NPSHr"]["pressure"][x-1]
|
|
92
|
+
flow_right = PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x]
|
|
93
|
+
flow_left = PUMP_CURVE_DIC[pump_key]["NPSHr"]["flow"][x-1]
|
|
94
|
+
self.NPSHr = Quantity(0.0597216 + P_left + (inlet_flow.magnitude - flow_left)/(flow_right-flow_left)*(P_right-P_left),'bar')
|
|
95
|
+
x = 100000
|
|
96
|
+
x=x+1
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def get_outlet_SP(self):
|
|
102
|
+
self.outlet = Statepoint()
|
|
103
|
+
self.outlet.set_fluid(self.inlet.fluid)
|
|
104
|
+
self.outlet.set_p(self.inlet.p)
|
|
105
|
+
self.outlet.set_t(self.inlet.t)
|
|
106
|
+
self.outlet.set_m(outlet.set_m)
|
|
107
|
+
|
|
108
|
+
if __name__=='__main__':
|
|
109
|
+
print(test(2.))
|