Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

 

from math import log10 

from rocketprops.rocket_prop import Propellant 

from rocketprops.unit_conv_data import get_value 

from rocketprops.InterpProp_scipy import InterpProp 

 

# properties and standard state of MMH 

class Prop( Propellant ): 

 

def __init__(self): 

 

Propellant.__init__(self, name='MMH') 

 

def set_std_state(self): 

"""Set properties and standard state of Propellant, MMH""" 

 

self.dataSrc = 'RocketProps' 

self.T = 527.67 # degR 

self.P = 14.6959 # psia 

self.Pvap = 0.7274133154081348 # psia 

self.Pc = 1195 # psia 

self.Tc = 1053.67 # degR 

self.Zc = 0.26338938217655683 # Z at critical pt 

self.omega = 0.28680344162000093 # define: omega = -1.0 - log10( Pvap(0.7 * Tc) / Pc ) 

self.SG = 0.8798394613717013 # SG 

self.visc = 0.008448662042797346 # poise 

self.cond = 0.1441577322485178 # BTU/hr/ft/delF 

self.Tnbp = 649.47 # degR 

self.Tfreeze = 397.37 # degR 

self.Ttriple = 397.37 # degR 

self.Cp = 0.6998597443550909 # BTU/lbm/delF 

self.MolWt = 46.0724 # g/gmole 

self.Hvap = 377.0000676611555 # BTU/lbm 

self.surf = 0.0001958767819978368 # lbf/in 

 

# ======= saturation curves ========= 

self.NsatPts = 21 

self.trL = [0.37712946178594814, 0.40827298869665074, 0.43941651560735334, 0.47056004251805594, 0.5017035694287585, 0.5328470963394611, 0.5639906232501637, 0.5951341501608662, 0.6262776770715689, 0.6574212039822714, 0.6885647308929741, 0.7197082578036766, 0.7508517847143792, 0.7819953116250818, 0.8131388385357844, 0.844282365446487, 0.8754258923571896, 0.9065694192678921, 0.9377129461785947, 0.9688564730892975, 1.0] 

self.tL = [397.37, 430.185, 463.0, 495.81500000000005, 528.63, 561.445, 594.26, 627.0749999999999, 659.89, 692.705, 725.5200000000001, 758.335, 791.15, 823.965, 856.78, 889.595, 922.41, 955.225, 988.04, 1020.8550000000001, 1053.67] 

 

self.log10pL = [-2.7414245983651573, -1.8969622355445945, -1.1998753409681648, -0.6173095335605722, -0.12491607939372697, 0.2956521263307987, 0.6584149592273555, 0.9742137488433035, 1.2515172475935756, 1.4969985348874384, 1.7159553841688089, 1.9126215141023268, 2.0904004111403727, 2.2520433164695888, 2.399786355376714, 2.5354573662946125, 2.660559973463536, 2.7763403336152015, 2.88384036144323, 2.983939199343523, 3.0773679052841563] 

self.log10viscL = [-0.9391471874522483, -1.3584368889154772, -1.698012257181378, -1.9069846696138069, -2.077788493504421, -2.2214664725059734, -2.3361283238028787, -2.428034709227801, -2.5112618913128895, -2.594391687406626, -2.6806220552644864, -2.7626773049148983, -2.8408039779944603, -2.915360767989803, -2.986660161069911, -3.0549744352014288, -3.1205439894712383, -3.183580485966125, -3.2442727004626097, -3.3027885305315534, -3.35927881111061] 

self.condL = [0.14622268231888433, 0.14622268231888433, 0.14621874233903867, 0.1454637065008603, 0.14410789679121955, 0.14178169514978442, 0.13872690550770228, 0.1349148630626086, 0.13045559210661903, 0.12491120911388866, 0.11872028820705269, 0.112358422713997, 0.10631977887082497, 0.10044419622388734, 0.09477759908731866, 0.08828987439874897, 0.08019576075457142, 0.0704944520480966, 0.06139900945140393, 0.0631658424722527, 0.07195174501123086] 

self.cpL = [0.679002254699395, 0.6822173051394047, 0.6878912076082673, 0.6939645966695106, 0.7000312721473902, 0.7056811552554715, 0.7119511993160879, 0.7188815287189327, 0.7258411031080202, 0.7335411672856395, 0.7437820469108334, 0.7580463337994104, 0.7763467437540109, 0.8000295795944691, 0.831734626373075, 0.8737636062796494, 0.9346515231172009, 1.0193397482246895, 1.1740925844929717, 1.6244001121861613, 28.51320767547775] 

self.hvapL = [410.4289109307158, 402.42277728498755, 394.15511010507146, 385.6020247568183, 376.73588852068605, 367.5244550381481, 357.9297260123787, 347.90642786430845, 337.39993222270573, 326.3433517544488, 314.6533756152855, 302.2241090604686, 288.91761670844727, 274.54873743516646, 258.8592991821347, 241.47108983967755, 221.79152865212245, 198.79740828481428, 170.42600255711332, 131.07880318952033, 0.0] 

self.surfL = [0.00023546774034859848, 0.0002262240672637695, 0.00021609637894753154, 0.00020588161003298982, 0.0001955738493356034, 0.00018516629922811593, 0.0001746512649107268, 0.00016401977237298084, 0.0001532614183445943, 0.0001423638625945411, 0.0001313123238447862, 0.00012008884722193538, 0.00010867097096871818, 9.703032081257124e-05, 8.512917954268118e-05, 7.291654182991242e-05, 6.0317595919164714e-05, 4.721681912390367e-05, 3.3405811951332886e-05, 1.8424845754659776e-05, 0.0] 

self.SG_liqL = [0.9448242110819741, 0.9289699636107457, 0.9127916978570874, 0.8962594490421218, 0.879338562404805, 0.8619886111919051, 0.8441619736432548, 0.8258019284460081, 0.8068400544230196, 0.7871925981223978, 0.7667552631151755, 0.7453954982816801, 0.7229406517394681, 0.699158931994362, 0.6737270398759856, 0.6461710364871962, 0.6157474706139564, 0.5811699641425555, 0.5398355238453286, 0.4846236916789145, 0.2961834064047918] 

self.log10SG_vapL = [-6.5030943572871704, -5.692997994813139, -5.027559061120656, -4.474060476490519, -4.008110366284448, -3.611161747842198, -3.2688808897348394, -2.97004899050083, -2.705799229354191, -2.4690655073176893, -2.254167803795137, -2.0564893444234964, -1.872217900517997, -1.698132063081089, -1.5314165526085628, -1.3694901013589051, -1.2098247386394294, -1.0497230782508136, -0.8859908381277022, -0.7143690092507525, -0.528439276364106] 

 

# ========== save dataSrc for each value =========== 

data_srcD = {} # index=parameter, value=data source 

data_srcD["main"] = "RocketProps" 

data_srcD["T"] = "RocketProps" # degR 

data_srcD["P"] = "RocketProps" # psia 

data_srcD["Pvap"] = "RocketProps" # psia 

data_srcD["Pc"] = "RocketProps" # psia 

data_srcD["Tc"] = "RocketProps" # degR 

data_srcD["Zc"] = "RocketProps" # Z at critical pt 

data_srcD["omega"] = "RocketProps" # define: omega = -1.0 - log10( Pvap(0.7 * Tc) / Pc ) 

data_srcD["SG"] = "RocketProps" # SG 

data_srcD["visc"] = "RocketProps" # poise 

data_srcD["cond"] = "RocketProps" # BTU/hr/ft/delF 

data_srcD["Tnbp"] = "RocketProps" # degR 

data_srcD["Tfreeze"] = "RocketProps" # degR 

data_srcD["Ttriple"] = "RocketProps" # degR 

data_srcD["Cp"] = "RocketProps" # BTU/lbm/delF 

data_srcD["MolWt"] = "RocketProps" # g/gmole 

data_srcD["Hvap"] = "RocketProps" # BTU/lbm 

data_srcD["surf"] = "RocketProps" # lbf/in 

 

data_srcD["trL"] = "RocketProps" 

data_srcD["tL"] = "RocketProps" 

 

data_srcD["log10pL"] = "RocketProps" 

data_srcD["log10viscL"] = "RocketProps" 

data_srcD["condL"] = "RocketProps" 

data_srcD["cpL"] = "RocketProps" 

data_srcD["hvapL"] = "RocketProps" 

data_srcD["surfL"] = "RocketProps" 

data_srcD["SG_liqL"] = "RocketProps" 

data_srcD["log10SG_vapL"] = "RocketProps" 

self.data_srcD = data_srcD 

 

 

# ========== initialize saturation interpolators =========== 

self.log10p_terp = InterpProp(self.trL, self.log10pL, extrapOK=False) 

try: 

self.log10visc_terp = InterpProp(self.trL, self.log10viscL, extrapOK=False) 

except: 

pass 

try: 

self.cond_terp = InterpProp(self.trL, self.condL, extrapOK=False) 

except: 

pass 

self.cp_terp = InterpProp(self.trL, self.cpL, extrapOK=False) 

self.hvap_terp = InterpProp(self.trL, self.hvapL, extrapOK=False) 

self.surf_terp = InterpProp(self.trL, self.surfL, extrapOK=False) 

self.SG_liq_terp = InterpProp(self.trL, self.SG_liqL, extrapOK=False) 

self.log10SG_vap_terp = InterpProp(self.trL, self.log10SG_vapL, extrapOK=False) 

 

def SG_compressed(self, TdegR, Ppsia): 

'''Calculates compressed-liquid specific gravity from curve fit of  

RefProp calculations for MMH (MonoMethylHydrazine).  

 

The fitted equation is a modified, polynomial version of the Tait equation 

see: equation 4-12.2 in the 5th Ed. of Gases and Liquids. 

or: https://en.wikipedia.org/wiki/Tait_equation 

 

:param TdegR: temperature in degR 

:param Ppsia: pressure in psia 

:type TdegR: float 

:type Ppsia: float 

:return: specific gravity at (TdegR, Ppsia) in g/ml 

''' 

 

Tr = TdegR / self.Tc 

Psat = self.PvapAtTr( Tr ) 

dP = max(0.0, Ppsia - Psat) # don't let dP fall below zero 

 

trL = [0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0] 

 

# build a list of (SG - SGsat)/SG vs Tr 

dsg_o_sgL = [] 

 

# build interpolator for (SG - SGsat)/SG vs Tr at Ppsia 

 

psat = self.PvapAtTr( 0.4 ) # saturation pressure at Tr=0.4 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (10589.569810046796 + psat)) # Fit Standard Deviation = 5.412853307430722e-09 

dsg_o_sgL.append( 0.03637202072794378*log10x + 0.03433360832953265*log10x**2 + 0.01755389602818833*log10x**3 ) 

 

psat = self.PvapAtTr( 0.45 ) # saturation pressure at Tr=0.45 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (8209.80212388197 + psat)) # Fit Standard Deviation = 1.3732567299692015e-08 

dsg_o_sgL.append( 0.03424745204142822*log10x + 0.0326132859006542*log10x**2 + 0.017305252406757534*log10x**3 ) 

 

psat = self.PvapAtTr( 0.5 ) # saturation pressure at Tr=0.5 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (6177.069852339128 + psat)) # Fit Standard Deviation = 3.649801671155937e-08 

dsg_o_sgL.append( 0.031731611035634225*log10x + 0.030522365461474306*log10x**2 + 0.017017316090043155*log10x**3 ) 

 

psat = self.PvapAtTr( 0.55 ) # saturation pressure at Tr=0.55 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (4463.447278953207 + psat)) # Fit Standard Deviation = 1.0250653986950578e-07 

dsg_o_sgL.append( 0.028755239731389402*log10x + 0.027958102774981296*log10x**2 + 0.01668944740664264*log10x**3 ) 

 

psat = self.PvapAtTr( 0.6 ) # saturation pressure at Tr=0.6 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (3051.3681793762908 + psat)) # Fit Standard Deviation = 3.0549534026969583e-07 

dsg_o_sgL.append( 0.02526304170957798*log10x + 0.024783327342416634*log10x**2 + 0.01631462420624741*log10x**3 ) 

 

psat = self.PvapAtTr( 0.65 ) # saturation pressure at Tr=0.65 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (1924.4267211664935 + psat)) # Fit Standard Deviation = 9.661687227198927e-07 

dsg_o_sgL.append( 0.021233944430324954*log10x + 0.0208076386225839*log10x**2 + 0.015868935317814522*log10x**3 ) 

 

psat = self.PvapAtTr( 0.7 ) # saturation pressure at Tr=0.7 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (9663.41884523568 + psat)) # Fit Standard Deviation = 7.925895276324919e-08 

dsg_o_sgL.append( 0.14427357034611538*log10x + 0.03617415930108113*log10x**2 + -0.00496049708979845*log10x**3 ) 

 

psat = self.PvapAtTr( 0.75 ) # saturation pressure at Tr=0.75 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (6561.907880284143 + psat)) # Fit Standard Deviation = 2.1772650245162727e-07 

dsg_o_sgL.append( 0.14187820777474008*log10x + 0.03594946846548841*log10x**2 + -0.005501754517593817*log10x**3 ) 

 

psat = self.PvapAtTr( 0.8 ) # saturation pressure at Tr=0.8 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (4085.12881682702 + psat)) # Fit Standard Deviation = 6.299833364242372e-07 

dsg_o_sgL.append( 0.13926949995690333*log10x + 0.03608588889026804*log10x**2 + -0.006229042313223188*log10x**3 ) 

 

psat = self.PvapAtTr( 0.85 ) # saturation pressure at Tr=0.85 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (2149.871388014923 + psat)) # Fit Standard Deviation = 1.9123738833081077e-06 

dsg_o_sgL.append( 0.13561384760517012*log10x + 0.036899881106801515*log10x**2 + -0.0071107633320449636*log10x**3 ) 

 

psat = self.PvapAtTr( 0.9 ) # saturation pressure at Tr=0.9 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (682.8908382720118 + psat)) # Fit Standard Deviation = 5.984463062913862e-06 

dsg_o_sgL.append( 0.12877682269857624*log10x + 0.03887229569815003*log10x**2 + -0.0080205562404789*log10x**3 ) 

 

psat = self.PvapAtTr( 0.95 ) # saturation pressure at Tr=0.95 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (5.920969290175338e-07 + psat)) # Fit Standard Deviation = 0.00017512560120193173 

dsg_o_sgL.append( 0.2245552477733884*log10x + -0.045290544198862547*log10x**2 + 0.0192201152457745*log10x**3 ) 

 

psat = self.PvapAtTr( 1.0 ) # saturation pressure at Tr=1.0 

dp = max(0.0, Ppsia - psat) 

log10x = log10(1 + dp / (9.225720702300927e-09 + psat)) # Fit Standard Deviation = 0.04316871431359113 

dsg_o_sgL.append( 2.778463860710788*log10x + -4.862787854598258*log10x**2 + 2.7425312824163206*log10x**3 ) 

 

sgratio_terp = InterpProp( trL, dsg_o_sgL, extrapOK=True ) 

 

SGratio = sgratio_terp( Tr ) 

SGsat = self.SGLiqAtTr( Tr ) 

SG = SGsat / ( 1.0 - SGratio ) 

 

return SG 

 

if __name__ == '__main__': 

from rocketprops.unit_conv_data import get_value 

C = Prop() 

print('T = %g R = %g K'%( C.T, C.T/1.8 )) 

print('SurfaceTension = %g lbf/in'%C.surf, ' = ', get_value(C.surf, 'lbf/in', 'mN/m'), 'mN/m' ) 

 

print() 

print(' Tr_data_range =', C.Tr_data_range()) 

print(' T_data_range=',C.T_data_range()) 

print(' P_data_range=', C.P_data_range()) 

 

print( 'omega =%s'%C.omega ) 

 

C.plot_sat_props()