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

 

class Efficiency: 

""" 

Holds an individual efficiency that is coordinated by the Efficiencies object. 

 

:param name: name of efficiency (e.g. Div, BL, Kin, etc) 

:param value: initial value of efficiency (should be between 0.0 and 1.0) 

:param desc: long description of efficiency 

:param value_src: technical source of the efficiency (e.g. user input, NASA model, etc.) 

:type name: str 

:type value: float 

:type desc: str 

:type value_src: str 

:return: Efficiency object 

:rtype: Efficiency  

""" 

def __init__(self, name, value, desc, value_src): 

 

self.name = name 

self.value = value 

self.desc = desc 

self.value_src = value_src 

self.is_const = False 

 

def set_const(self, value): 

self.value = value 

self.value_src = 'constant' 

self.is_const = True 

 

def set_value(self, value, value_src): 

""" 

Every time a new value is set, the source of that value must be given. 

""" 

self.value = value 

self.value_src = value_src 

 

class Efficiencies: 

""" 

Holds all of the thrust chamber efficiencies and provides access to  

efficiency models in order to update each one. 

""" 

 

def __init__(self, **constD): 

 

self.effD = {} # index=eff name, value=Efficiency object 

 

# individual mechanism efficiencies 

self.effD['Div'] = Efficiency('Div', 1.0, 'Divergence Efficiency of Nozzle', 'default') 

self.effD['Kin'] = Efficiency('Kin', 1.0, 'Kinetic Efficiency of Nozzle', 'default') 

self.effD['BL'] = Efficiency('BL', 1.0, 'Boundary Layer Efficiency of Nozzle', 'default') 

self.effD['TP'] = Efficiency('TP', 1.0, 'Two Phase Efficiency of Nozzle', 'default') 

self.effD['Mix'] = Efficiency('Mix', 1.0, 'Inter-Element Mixing Efficiency of Injector', 'default') 

self.effD['Em'] = Efficiency('Em', 1.0, 'Intra-Element Mixing Efficiency of Injector', 'default') 

self.effD['Vap'] = Efficiency('Vap', 1.0, 'Vaporization Efficiency of Injector', 'default') 

self.effD['HL'] = Efficiency('HL', 1.0, 'Heat Loss Efficiency of Chamber', 'default') 

self.effD['FFC'] = Efficiency('FFC', 1.0, 'Fuel Film Cooling Efficiency of Chamber', 'default') 

self.effD['Pulse'] = Efficiency('Pulse', 1.0, 'Pulsing Efficiency of Thruster', 'default') 

 

self.nozzleL = ['Div','Kin','BL','TP'] 

self.chamberL = ['Mix','Em','Vap','HL','FFC'] 

self.toplevelL = ['Isp','IspPulsing'] 

 

# consolidated efficiencies (product of selected individual efficiencies) 

self.effD['ERE'] = Efficiency('ERE', 1.0, 'Energy Release Efficiency', '') 

self.effD['Noz'] = Efficiency('Noz', 1.0, 'Nozzle Efficiency', '') 

self.effD['Isp'] = Efficiency('Isp', 1.0, 'Overall Isp Efficiency', '') 

self.effD['IspPulsing'] = Efficiency('IspPulsing', 1.0, 'Pulsing Isp Efficiency', '') 

 

for name, value in constD.items(): 

if name in self.effD: 

self.set_const( name, value, re_evaluate=True) 

else: 

raise Exception('in Efficiencies, "%s" is not recognized as an efficiency'%name) 

 

 

def __getitem__(self, name): 

return self.effD[name] 

 

def __call__(self, name): 

return self.effD[name].value 

 

def set_const(self, name, value, re_evaluate=True): 

""" 

Give a new constant value to named efficiency. Call evaluate if re_evaluate is True. 

""" 

self.effD[name].set_const( value ) 

if re_evaluate: 

self.evaluate() 

 

def set_value(self, name, value, value_src='user input', re_evaluate=True): 

""" 

Give a new value to named efficiency. Call evaluate if re_evaluate is True. 

""" 

self.effD[name].set_value( value, value_src ) 

if re_evaluate: 

self.evaluate() 

 

 

def evaluate(self): 

""" 

Combines nozzle and chamber efficiencies into overall nozzle and  

over chamber efficiency. 

Gives overall Isp efficiency including any pulsing effects. 

""" 

if not self.effD['Isp'].is_const: 

enoz = self['Noz'] 

if enoz.is_const: 

effNoz = enoz.value 

else: 

effNoz = 1.0 

for name in self.nozzleL: # ['Div','Kin','BL','TP'] 

e = self.effD[name] 

effNoz *= e.value 

enoz.set_value( effNoz, '' ) 

 

eere = self['ERE'] 

if eere.is_const: 

effERE = eere.value 

else: 

effERE = 1.0 

for name in self.chamberL: # ['Mix','Em','Vap','HL','FFC'] 

e = self.effD[name] 

effERE *= e.value 

self.effD['ERE'].set_value( effERE, '' ) 

 

self.effD['Isp'].set_value( effERE * effNoz, '' ) 

 

if not self.effD['IspPulsing'].is_const: 

self.effD['IspPulsing'].set_value( self.effD['Isp'].value * self.effD['Pulse'].value, 

self['Pulse'].value_src ) 

 

 

def summ_print(self): 

""" 

print to standard output, the current state of Efficiencies instance. 

""" 

 

print('%s Thruster Efficiencies %s'%('='*12,'='*12)) 

 

# top level efficiencies 

e = self['Isp'] 

print('%s %.5f'%(' '*12,e.value), '%s'%( e.desc, ) ) 

 

if self.effD['Pulse'].value < 1.0: 

e = self['IspPulsing'] 

print('%s %.5f'%(' '*12,e.value), '%s (%s)'%( e.desc, e.value_src) ) 

 

if not self.effD['Isp'].is_const: 

# nozzle 

#print() 

e = self.effD['Noz'] 

if e.value_src: 

msg='(%s) '%e.value_src 

else: 

msg='' 

 

print('%s %.5f'%('-'*12,e.value), '%sNozzle Efficiency %s'%(msg,'-'*12,) ) 

if not e.is_const: 

for name in self.nozzleL: 

e = self.effD[name] 

print(' %10s ='%name, '%.5f'%e.value, '(%s)'%e.value_src, e.desc) 

 

# ERE 

#print() 

e = self.effD['ERE'] 

if e.value_src: 

msg='(%s) '%e.value_src 

else: 

msg='' 

 

print('%s %.5f'%('-'*12,e.value), '%sEnergy Release Efficiency %s'%(msg,'-'*12,) ) 

if not e.is_const: 

for name in self.chamberL: 

e = self.effD[name] 

print(' %10s ='%name, '%.5f'%e.value, '(%s)'%e.value_src, e.desc) 

 

# Pulsing 

e = self.effD['Pulse'] 

if e.value < 1.0: 

print() 

print('%s %.5f'%('-'*12,e.value), 'Pulsing Efficiency %s'%('-'*12,) ) 

 

 

if __name__ == '__main__': 

 

E = Efficiencies() 

E.set_const('Div', .9 ) 

E.set_const('Mix', .89 ) 

#E.set_const('Noz', .95 ) 

#E.set_const('ERE', .97 ) 

E.summ_print() 

print( 'E("Mix") =', E("Mix") ) 

print('='*66) 

E.set_value('Em', 0.99) 

E.set_value('Pulse', 0.99) 

E.summ_print()