Пример #1
0
def GetFluidProperties(Pressure=None,Temperature=None,Enthalpy=None,InternalEnergy=None,Entropy=None,Density=None,ExtendedProperties=False,TransportProperties=True,SaturateEnthalpy=False):	#all properties must be provided in base SI units. not really interpolating here but keeping the name for now for compatibility with table lookups.

	Properties={}

	#remember what the fluid is for future activities like plotting
	#note, need to decide when is best to read from CycleInputParameters and when is best to use this value
	Properties['FluidName']=FluidName
	Properties['PercentExcessOxygen']=CurrentPercentExcessOxygen

	#first get the properties, converting units as necessary to work with refprop which deals in mols and sometimes kilo, micro, units or grams instead of kg. (what does sometimes kilo, micro units mean?????????????)
	#assume only two things are defined. if more than two are defined then the first combination that the logic below gets to is used. don't know why more than two would ever be provided though.
	if (Enthalpy is not None) and (Entropy is not None):
		PropertiesFromREFPROP=PyREFPROP.flsh(u'HS',float(Enthalpy*MolecularWeight/1000),float(Entropy*MolecularWeight/1000),MoleFractions)			#don't know why u is needed. don't know why MoleFractions is needed for pure fluids. also may want to look into other flsh functions.
	elif (Pressure is not None) and (Temperature is not None):
		PropertiesFromREFPROP=PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)							#same notes as above
	elif (Pressure is not None) and (Entropy is not None):
		PropertiesFromREFPROP=PyREFPROP.flsh(u'PS',float(Pressure/1000),float(Entropy*MolecularWeight/1000),MoleFractions)					#same notes as above
	elif (Pressure is not None) and (Density is not None):
		PropertiesFromREFPROP=PyREFPROP.flsh(u'PD',float(Pressure/1000),float(Density/MolecularWeight),MoleFractions)						#same notes as above
	elif (Temperature is not None) and (Density is not None):
		PropertiesFromREFPROP=PyREFPROP.flsh(u'TD',float(Temperature),float(Density/MolecularWeight),MoleFractions)						#same notes as above
	elif (Pressure is not None) and (InternalEnergy is not None):
#should the internal energy be saturated like the enthalpy is??????
		PropertiesFromREFPROP=PyREFPROP.flsh(u'PE',float(Pressure/1000),float(InternalEnergy*MolecularWeight/1000),MoleFractions)				#same notes as above
	elif (Pressure is not None) and (Enthalpy is not None):
		if (SaturateEnthalpy) and (Enthalpy>MaxEnthalpy):	#saturate enthalpy to value defined above, as a workaround so bad heat exchanger solutions don't error out, but just realize they are bad and try a different technique
			Enthalpy=MaxEnthalpy
		PropertiesFromREFPROP=PyREFPROP.flsh(u'PH',float(Pressure/1000),float(Enthalpy*MolecularWeight/1000),MoleFractions)					#same notes as above
	else:
		raise Exception('need temperature or entropy or enthalpy given a certain pressure or enthalpy and entropy')

	#then convert units and populate the Properties dictionary and determine dynamic viscocity and thermal conductivity
	Properties['Temperature']=float(PropertiesFromREFPROP['t'])
	Properties['Pressure']=float(PropertiesFromREFPROP['p']*1000)
	Properties['Enthalpy']=float(PropertiesFromREFPROP['h']*1000/MolecularWeight)
	Properties['Entropy']=float(PropertiesFromREFPROP['s']*1000/MolecularWeight)
	Properties['InternalEnergy']=float(PropertiesFromREFPROP['e']*1000/MolecularWeight)
	Properties['Density']=float(PropertiesFromREFPROP['D']*MolecularWeight)
	if ExtendedProperties:
		Properties['SpeedOfSound']=float(PropertiesFromREFPROP['w'])
		Properties['cp']=float(PropertiesFromREFPROP['cp']*1000/MolecularWeight)
		Properties['cv']=float(PropertiesFromREFPROP['cv']*1000/MolecularWeight)

		#compute the derived quantity, gamma, the ratio of specific heats
		Properties['gamma']=float(PropertiesFromREFPROP['cp']/PropertiesFromREFPROP['cv'])

		if TransportProperties:		#make a way to skip transport properties if explicitly told to because they don't seem to be possible with mixtures of water, but default to getting transport properties with extended properties.
			#need to run another function to get dynamic viscocity and thermal conductivity.
			TransportPropertiesFromREFPROP=PyREFPROP.trnprp(PropertiesFromREFPROP['t'],PropertiesFromREFPROP['D'],MoleFractions)
			#convert units and populate Properties dictionary
			Properties['DynamicViscocity']=float(TransportPropertiesFromREFPROP['eta']/1e6)
			Properties['ThermalConductivity']=float(TransportPropertiesFromREFPROP['tcx'])

		#need to run another function to get the dimensionless compressibility factor, Z
		Properties['Z']=float(PyREFPROP.therm2(PropertiesFromREFPROP['t'],PropertiesFromREFPROP['D'],MoleFractions)['Z'])



	return Properties		#all properties are returned in base SI units.
Пример #2
0
def TemperatureFromEnthalpyEntropySimple(Enthalpy,Entropy): return float((PyREFPROP.flsh(u'HS',float(Enthalpy*MolecularWeight/1000),float(Entropy*MolecularWeight/1000),MoleFractions)['t']))
TemperatureFromEnthalpyEntropy=numpy.vectorize(TemperatureFromEnthalpyEntropySimple)
Пример #3
0
def DensityFromEnthalpyEntropySimple(Enthalpy,Entropy): return float((PyREFPROP.flsh(u'HS',float(Enthalpy*MolecularWeight/1000),float(Entropy*MolecularWeight/1000),MoleFractions)['D'])*MolecularWeight)
DensityFromEnthalpyEntropy=numpy.vectorize(DensityFromEnthalpyEntropySimple)
Пример #4
0
def DensityFromTemperatureEntropySimple(Temperature,Entropy): return float((PyREFPROP.flsh(u'TS',float(Temperature),float(Entropy*MolecularWeight/1000),MoleFractions)['D'])*MolecularWeight)
DensityFromTemperatureEntropy=numpy.vectorize(DensityFromTemperatureEntropySimple)
Пример #5
0
def gammaFromTemperatureEntropySimple(Temperature,Entropy):
	PropertiesFromREFPROP=PyREFPROP.flsh(u'TS',float(Temperature),float(Entropy*MolecularWeight/1000),MoleFractions)
	return float(PropertiesFromREFPROP['cp']/PropertiesFromREFPROP['cv'])
Пример #6
0
def gammaFromTemperaturePressureSimple(Temperature,Pressure):
	PropertiesFromREFPROP=PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)
	return float(PropertiesFromREFPROP['cp']/PropertiesFromREFPROP['cv'])
Пример #7
0
def TemperatureFromInternalEnergyPressureSimple(InternalEnergy,Pressure): return float(PyREFPROP.flsh(u'PE',float(Pressure/1000),float(InternalEnergy*MolecularWeight/1000),MoleFractions)['t'])
TemperatureFromInternalEnergyPressure=numpy.vectorize(TemperatureFromInternalEnergyPressureSimple)
Пример #8
0
def PressureFromTemperatureEntropySimple(Temperature,Entropy): return float((PyREFPROP.flsh(u'TS',float(Temperature),float(Entropy*MolecularWeight/1000),MoleFractions)['p'])*1000)
PressureFromTemperatureEntropy=numpy.vectorize(PressureFromTemperatureEntropySimple)
Пример #9
0
def DensityFromTemperaturePressureSimple(Temperature,Pressure): return float((PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)['D'])*MolecularWeight)
DensityFromTemperaturePressure=numpy.vectorize(DensityFromTemperaturePressureSimple)
Пример #10
0
def EntropyFromTemperaturePressureSimple(Temperature,Pressure): return float((PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)['s'])*1000/MolecularWeight)
EntropyFromTemperaturePressure=numpy.vectorize(EntropyFromTemperaturePressureSimple)
Пример #11
0
def EnthalpyFromTemperatureEntropySimple(Temperature,Entropy): return float((PyREFPROP.flsh(u'TS',float(Temperature),float(Entropy*MolecularWeight/1000),MoleFractions)['h'])*1000/MolecularWeight)
EnthalpyFromTemperatureEntropy=numpy.vectorize(EnthalpyFromTemperatureEntropySimple)
Пример #12
0
def InternalEnergyFromTemperaturePressureSimple(Temperature,Pressure): return float((PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)['e'])*1000/MolecularWeight)
InternalEnergyFromTemperaturePressure=numpy.vectorize(InternalEnergyFromTemperaturePressureSimple)
Пример #13
0
def EnthalpyFromTemperatureDensitySimple(Temperature,Density): return float((PyREFPROP.flsh(u'TD',float(Temperature),float(Density/MolecularWeight),MoleFractions)['h'])*1000/MolecularWeight)
EnthalpyFromTemperatureDensity=numpy.vectorize(EnthalpyFromTemperatureDensitySimple)
Пример #14
0
def PressureFromTemperatureDensitySimple(Temperature,Density): return float((PyREFPROP.flsh(u'TD',float(Temperature),float(Density/MolecularWeight),MoleFractions)['p'])*1000)
PressureFromTemperatureDensity=numpy.vectorize(PressureFromTemperatureDensitySimple)
Пример #15
0
def SpeedOfSoundFromTemperaturePressureSimple(Temperature,Pressure): return float((PyREFPROP.flsh(u'TP',float(Temperature),float(Pressure/1000),MoleFractions)['w']))
SpeedOfSoundFromTemperaturePressure=numpy.vectorize(SpeedOfSoundFromTemperaturePressureSimple)
Пример #16
0
def TemperatureFromEnthalpyPressureSimple(Enthalpy,Pressure): return float(PyREFPROP.flsh(u'PH',float(Pressure/1000),float(Enthalpy*MolecularWeight/1000),MoleFractions)['t'])
TemperatureFromEnthalpyPressure=numpy.vectorize(TemperatureFromEnthalpyPressureSimple)
Пример #17
0
def SetupFluid(FluidSimpleName,PercentExcessOxygen=None):		#methane, CH4
#see warnings below about how this currently has limited result when running after initial importation.

	#note, refprop psuedo pure fluids basically treat a mixture as a pure fluid. i guess they have done testing of those mixtures specifically or use a different (possibly less general) model. the main advantage is psuedo pure fluids are faster to compute.
	#don't know why the u prefix (unicode formating syntax?) is needed with REFPROP functions

	#not using mole fractions defined by predefined mixtures. instead just passing the mixture components explictely and then manually
	#calculating the mole fractions (since mole fractions aren't returned at all when passing mixture components explicitely).
	#the species concentration in the mixture files is pretty much a reference that they will just read for you.
	#apparently the fortran code does not persist this information, so the mole fractions in the predefined mixtures have to be manually stored and passed later after initially setting the mixture.
	#most likely, the mole fractions were added to the mixture files much later in the code developement and
	#they were too lazy to make that option persist as the species themselves do.
	#also, pure fluids don't return a mole fraction either. so that case has to be handled as well because you still need to pass a mole fraction
	#for pure fluids to most functions.

	#make some variables global so they will persist after each run without having to catch them and set them each time the function is run.
	global MoleFractions, MolecularWeight, CriticalPressure, CriticalTemperature, CriticalDensity, CriticalEntropy, CriticalEnthalpy, FluidName, CurrentPercentExcessOxygen

	FluidName=FluidSimpleName
	CurrentPercentExcessOxygen=PercentExcessOxygen

	#make some smarter shortcuts so don't have to remember every common mixture used species', concentrations, etc..
	if FluidSimpleName == 'air':
		FluidNames=[u'nitrogen',u'oxygen']
		Moles=MolesAir
	elif FluidSimpleName == 'CombustionProducts':
		FluidNames=[u'CO2',u'water',u'oxygen',u'nitrogen']
		# general reaction for complete lean combustion of methane with no Argon assumed in the air:
		# CH4+a(O2+(79/21)N2)-->CO2+2H2O+bO2+(79/21)aN2
		# 2b=2a-4, and b=a-2 and for stoichiometric, a=2
		if PercentExcessOxygen is None:
			raise Exception('PercentExcessOxygen must be defined')
		MolesOfOxygenPerMoleOfFuel=ComputeMolesOfOxygenPerMoleOfFuel(ComputeMassOfAirToMassOfFuelRatio(ComputeEquivalenceRatio(PercentExcessOxygen),ComputeStoichiometricMassOfAirToMassOfFuelRatio()))
		Moles=[1.,2.,MolesOfOxygenPerMoleOfFuel-2,MolesAir[0]/MolesAir[1]*MolesOfOxygenPerMoleOfFuel]
	elif FluidSimpleName == 'methane':
		FluidNames=[u'methane']
		Moles=[1.]
	elif FluidSimpleName == 'CO2':
		FluidNames=[u'CO2']
		Moles=[1.]
	else:
		raise Exception('no matching fluid shortcut defined')


	#assign the fluid and then get fluid properties

	FluidSetup=PyREFPROP.setup(u'def',FluidNames)				#don't know why the u is needed. 'def' is Default reference state as specified in fluid file is applied to each pure component. you have to specify a reference state. it isn't smart enough to use the default as the default.

	MoleFractions=ComputeMoleFractions(Moles)
	EnthalpyOfFormation={}
	EnthalpyOfFormation[ReferenceTemperature1]=ComputeCombinedEnthalpyOfFormation(FluidNames,MoleFractions,ReferenceTemperature1)			#J/molemix, don't think this one is actually used for anything????
	EnthalpyOfFormation[ReferenceTemperature2]=ComputeCombinedEnthalpyOfFormation(FluidNames,MoleFractions,ReferenceTemperature2)			#J/molemix
	
	#get the mixture [average] molecular weight so can later do unit conversions (or is it really molecular mass?)
	MolecularWeight=PyREFPROP.wmol(MoleFractions)['wmix']		#[g/molmix]

	#set the reference enthalpy to the enthalpy of formation so that chemical reactions can be done easily
	if FluidSimpleName != 'CO2':		#don't mess with pure CO2, because all the plot axis ranges will have to be redone and it isn't used for any reactions.
		PyREFPROP.setref(hrf=u'OTH', ixflag=2, x0=MoleFractions, h0=EnthalpyOfFormation[ReferenceTemperature2], s0=EnthalpiesOfFormation[ReferenceTemperature2]['entropy']*MolecularWeight/MolecularWeight_Air, t0=ReferenceTemperature2, p0=ReferencePressure/1000)		#entropy reference value is the same as the standard for air in refprop at the reference temperature and pressure

	if FluidSimpleName == 'CombustionProducts':
		#REFPROP can't seem to find the critical point of this mixture????


		pass


#need to clear these variables out?????



	else:
		#get the critical temperature and pressure. note info() above (actually, info is no longer used anymore in the script) does return critical temperature, but there is a bug and it doesn't return critical pressure, but the following does, so just using it instead of fixing the bug
		CriticalPressure=float((PyREFPROP.critp(MoleFractions)['pcrit'])*1000)
		#note, just calling this twice instead of calling once, assigning a variable, and then defining the two separately.
		#can't find a good way to extract a subset of a dictionary in one line of code. best thing found was http://stackoverflow.com/questions/5352546/best-way-to-extract-subset-of-key-value-pairs-from-python-dictionary-object, but it
		#still would make double call or require a definition of a separate variable anyway.
		CriticalTemperature=float(PyREFPROP.critp(MoleFractions)['tcrit'])
		#calculate the entropy at the critical point using the density at the critical point because that is more stable since it is one of the primitive variables?
		#don't know why critp() doesn't return this already?
		CriticalDensity=float((PyREFPROP.critp(MoleFractions)['Dcrit'])*MolecularWeight)
		CriticalEntropy=float((PyREFPROP.flsh(u'TD',float(CriticalTemperature),CriticalDensity/MolecularWeight,MoleFractions)['s'])*1000/MolecularWeight)	#again, not a real efficient way to do this, but it is only done once
		CriticalEnthalpy=float((PyREFPROP.flsh(u'TD',float(CriticalTemperature),CriticalDensity/MolecularWeight,MoleFractions)['h'])*1000/MolecularWeight)	#again, not a real efficient way to do this, but it is only done once

		##print out some reference information
		#print "Molecular Weight :     "+str(MolecularWeight)
		#print "Critical Pressure :    "+str(CriticalPressure)
		#print "Critical Temperature : "+str(CriticalTemperature)


	return