Coverage for rocketisp\rocket_isp.py : 91%

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
#!/usr/bin/env python # -*- coding: ascii -*-
RocketIsp calculates delivered Isp for liquid rocket thrust chambers.
RocketIsp uses a simplified JANNAF approach to calculate delivered specific impulse (Isp) for liquid rocket thrust chambers.
RocketIsp Copyright (C) 2020 Applied Python
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """
#exec( open(os.path.join( here,'_version.py' )).read() ) # creates local __version__ variable
#from rocketisp.nozzle.cd_throat import get_Cd
""" RocketIsp calculates delivered Isp for liquid rocket thrust chambers by simplified JANNAF method.
:param name: name of RocketThruster :param coreObj: CoreStream object :param injObj: Injector object (optional) :param noz_regen_eps: regen cooled nozzle area ratio :param pulse_sec: duration of pulsing engine (default = infinity) :param pulse_quality: on a scale of 0.0 to 1.0, how good is engine at pulsing :param isRegenCham: flag to indicate chamber is regen cooled :param calc_CdThroat: flag to trigger calc_CdThroat :type name: str :type coreObj: CoreStream :type injObj: Injector :type noz_regen_eps: float :type pulse_sec: float :type pulse_quality: float :type isRegenCham: bool :type calc_CdThroat: bool :return: RocketThruster object :rtype: RocketThruster """
""" Change the named efficiency model from the default model to a different model. For example, change from the simple nozzle divergence model (Div) to the Multi-Layer Perceptron (MLP) divergence model.
:param eff_name: name of efficiency (e.g. Div, BL, Kin) :param model_name: name of model to be used (must be in AVAIL_EFF_MODEL_D) :type eff_name: str :type model_name: str :return: None :rtype: None """ else: raise Exception('in set_eff_model, "%s" is not a recognized model name for %s.'%(model_name, eff_name) )
else: raise Exception('in set_eff_model, "%s" is not a recognized efficiency name'%eff_name)
coreObj=CoreStream(), injObj=None, noz_regen_eps=1.0, pulse_sec=float('inf'), pulse_quality=0.8, isRegenCham=0, calc_CdThroat=True): """ Calculate delivered thrust chamber Isp by simplified JANNAF method. """
""" Iterate on MRcore to find the peak Isp """ # get MR for equivalence ratio = 1 MRstart = self.coreObj.ceaObj.getMRforER( ERr=1.0 )
MRlo = MRstart / 3.0 MRhi = MRstart * 3.0
def get_ispdel( MR ): self.coreObj.reset_attr('MRcore', MR, re_evaluate=True) self.calc_all_eff() return self.coreObj.IspDel
MRcore_opt, IspMax = search_max(get_ispdel, MRlo, MRhi, tol=0.01) #print('MRcore_opt=%g, IspMax=%g sec'%(MRcore_opt, IspMax) ) # use MRcore_opt to reset everything self.coreObj.reset_attr('MRcore', MRcore_opt, re_evaluate=True) self.calc_all_eff()
return MRcore_opt
""" Adjust throat size in order to get total thrust at specified ambient pressure exactly
:param ThrustLbf: lbf, desired thrust at specified ambient pressure (Pamb) :param Pamb: psia, ambient pressure :param use_scipy: flag to indicate the need for more sophisticated root finder :type ThrustLbf: float :type Pamb: float :type use_scipy: bool :return: None :rtype: None """
#self.coreObj.evaluate()
# demand convergence to a tolerance with a root solver.
xtol=ThrustLbf/1.0E8, method='brentq') #print('sol.root=%g, sol.iterations=%g, sol.function_calls=%g'%(sol.root, sol.iterations, sol.function_calls)) else: # often converges in just a few iterations.
#print( 'self.coreObj.Fambient',self.coreObj.Fambient ) #print( 'self.coreObj.Fambient',self.coreObj.Fambient ) #print( 'self.coreObj.Fambient',self.coreObj.Fambient )
""" Looks at the efficiency object (effObj) and calculates those efficiencies that have not been set as constants by the user.
see: self.calc_CdThroat or effObj['XXX'].is_const for individual efficiencies """
#CdThroat = get_Cd( RWTU=self.geomObj.RupThroat, gamma=self.coreObj.gammaChm )
#if self.calc_effPulse:
#if self.calc_effDiv:
# AVAIL_EFF_MODEL_D['Div'] = ['simple fit', 'MLP fit']
elif selected_eff_modelD['Div'] == 'MLP fit': raise Exception('MLP fit not yet implemented for eff Div')
#if self.calc_effBL:
# AVAIL_EFF_MODEL_D['BL'] = ['MLP fit', 'NASA-SP8120']
Rthrt=self.geomObj.Rthrt, pcentBell=self.geomObj.pcentBell, TcCham=self.coreObj.TcODE )
#if self.calc_effKin: Rthrt=self.geomObj.Rthrt, pcentBell=self.geomObj.pcentBell, MR=self.coreObj.MRcore)
# coreObj has made IspODE calc already
#if self.calc_effEm:
#if self.calc_effMix:
#if self.calc_effVap:
# after all updates, re_evaluate
""" print to standard output, the current state of RocketThruster instance. """
CR=2.5, eps=150, pcentBell=80, RupThroat=1.5, RdwnThroat=1.0, RchmConv=1.0, cham_conv_deg=30, LchmOvrDt=3.10, LchmMin=2.0, LchamberInp=16)
#effObj.set_const('ERE', 0.98)
Pc=150, CdThroat=0.995, pcentFFC=14.0, ko=0.035)
fdPinjOx=0.25, fdPinjFuel=0.25, elemDensInp=None, NelementsInp=None, setNelementsBy='acoustics', # can be "acoustics", "density", "input" setAcousticFreqBy='mode', # can be "mode" or "freq" desAcousMode=0.8*4.2012, desFreqInp=2000, OxOrfPerEl=1.0, FuelOrfPerEl=1.0, lolFuelElem=True, CdOxOrf=0.75, CdFuelOrf=0.75, dropCorrOx=0.33, dropCorrFuel=0.33, DorfMin=0.008, LfanOvDorfOx=20.0, LfanOvDorfFuel=20.0)
#C.scale_Rt_to_Thrust( 10000.0, Pamb=0.0, use_scipy=False ) |