Skip to content

Commit 08f49bc

Browse files
Improved management of phases included in fluid data
1 parent 373b4d7 commit 08f49bc

3 files changed

Lines changed: 226 additions & 79 deletions

File tree

Common/DataDrivenConfig.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ class Config_NICFD(Config):
6262
__viscosity_model:str = DefaultSettings_NICFD.viscosity_model
6363
__conductivity_model:str = DefaultSettings_NICFD.conductivity_model
6464

65+
# Phases to include in fluid data.
66+
__gasphase:bool = True
6567
__twophase:bool = False
68+
__liquidphase:bool = False
69+
__supercritical:bool = True
6670

6771
__EOS_type:str=DefaultSettings_NICFD.EOS_type # Equation of state used by CoolProp
6872
__fluid_mole_fractions:list[float] = [1.0] # Mole fractions for components in fluid mixture.
@@ -282,6 +286,17 @@ def GetViscosityModel(self):
282286
"""
283287
return self.__viscosity_model
284288

289+
def EnableGasPhase(self, gas_phase:bool=True):
290+
self.__gasphase = gas_phase
291+
return
292+
293+
def GasPhase(self):
294+
return self.__gasphase
295+
296+
def EnableSuperCritical(self, supercritical:bool=True):
297+
self.__supercritical = supercritical
298+
return
299+
285300
def EnableTwophase(self, two_phase:bool=False):
286301
"""Include two-phase region in fluid data.
287302
@@ -291,9 +306,24 @@ def EnableTwophase(self, two_phase:bool=False):
291306
self.__twophase = two_phase
292307
return
293308

309+
def EnableLiquidPhase(self, liquid_phase:bool=False):
310+
"""Include thermodynamic state data from fluid in the liquid phase.
311+
312+
:param liquid_phase: include liquid-phase data, defaults to False
313+
:type liquid_phase: bool, optional
314+
"""
315+
self.__liquidphase = liquid_phase
316+
return
317+
294318
def TwoPhase(self):
295319
return self.__twophase
296320

321+
def LiquidPhase(self):
322+
return self.__liquidphase
323+
324+
def SuperCritical(self):
325+
return self.__supercritical
326+
297327
def GetEquationOfState(self):
298328
"""Retrieve the equation of state backend used by CoolProp for fluid data calculations.
299329

Data_Generation/DataGenerator_NICFD.py

Lines changed: 151 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class DataGenerator_CoolProp(DataGenerator_Base):
4747
"""
4848
_Config:Config_NICFD
4949
fluid = None
50-
__accepted_phases:list[int] = [CoolP.iphase_gas, CoolP.iphase_supercritical_gas, CoolP.iphase_supercritical,CoolP.iphase_supercritical_liquid]
50+
__accepted_phases:list[int] = []
5151
# Pressure and temperature limits
5252
__use_PT:bool = DefaultSettings_NICFD.use_PT_grid
5353
__T_min:float = DefaultSettings_NICFD.T_min
@@ -91,9 +91,11 @@ def __init__(self, Config_in:Config_NICFD=None):
9191
if len(self._Config.GetFluidNames()) > 1:
9292
self.__mixture = True
9393

94-
self.__two_phase = self._Config.TwoPhase()
95-
if self.__two_phase:
96-
self.__accepted_phases.append(CoolP.iphase_twophase)
94+
# Define phases for which to generate fluid data.
95+
self.EnableTwophase(self._Config.TwoPhase())
96+
self.EnableLiquidPhase(self._Config.LiquidPhase())
97+
self.EnableGasPhase(self._Config.GasPhase())
98+
self.EnableSuperCritical(self._Config.SuperCritical())
9799

98100
self.fluid = CP.AbstractState(self._Config.GetEquationOfState(), self._Config.GetFluid())
99101
self.__auto_range = self._Config.GetAutoRange()
@@ -351,6 +353,31 @@ def IncludeTransportProperties(self, calc_transport_properties:bool=False):
351353
def CalcTransportProperties(self):
352354
return self._Config.CalcTransportProperties()
353355

356+
def EnableGasPhase(self, gas_phase:bool=True):
357+
"""Include thermophysical data of the fluid in gas phase.
358+
359+
:param gas_phase: include gas phase data, defaults to True
360+
:type gas_phase: bool, optional
361+
"""
362+
self._Config.EnableGasPhase(gas_phase)
363+
if self._Config.GasPhase() and CoolP.iphase_gas not in self.__accepted_phases:
364+
self.__accepted_phases.append(CoolP.iphase_gas)
365+
if self._Config.SuperCritical():
366+
self.__accepted_phases.append(CoolP.iphase_supercritical_gas)
367+
if not self._Config.GasPhase() and CoolP.iphase_gas in self.__accepted_phases:
368+
self.__accepted_phases.remove(CoolP.iphase_gas)
369+
if CoolP.iphase_supercritical_gas in self.__accepted_phases:
370+
self.__accepted_phases.remove(CoolP.iphase_supercritical_gas)
371+
return
372+
373+
def GasPhase(self):
374+
"""Whether gas phase data are included in the fluid data set.
375+
376+
:return: gas phase data included in fluid data set.
377+
:rtype: bool
378+
"""
379+
return self._Config.GasPhase()
380+
354381
def EnableTwophase(self, two_phase:bool=False):
355382
"""Include two-phase region in fluid data.
356383
@@ -367,6 +394,55 @@ def EnableTwophase(self, two_phase:bool=False):
367394
def TwoPhase(self):
368395
return self._Config.TwoPhase()
369396

397+
def EnableLiquidPhase(self, liquid_phase:bool=False):
398+
"""Include thermophysical data of the fluid in liquid phase.
399+
400+
:param liquid_phase: include liquid phase fluid data, defaults to False
401+
:type liquid_phase: bool, optional
402+
"""
403+
self._Config.EnableLiquidPhase(liquid_phase)
404+
if self._Config.LiquidPhase() and CoolP.iphase_liquid not in self.__accepted_phases:
405+
self.__accepted_phases.append(CoolP.iphase_liquid)
406+
if self._Config.SuperCritical():
407+
self.__accepted_phases.append(CoolP.iphase_supercritical_liquid)
408+
if not self._Config.LiquidPhase() and CoolP.iphase_liquid in self.__accepted_phases:
409+
self.__accepted_phases.remove(CoolP.iphase_liquid)
410+
if CoolP.iphase_supercritical_liquid in self.__accepted_phases:
411+
self.__accepted_phases.remove(CoolP.iphase_supercritical_liquid)
412+
return
413+
414+
def LiquidPhase(self):
415+
"""Whether to include fluid data in liquid phase.
416+
417+
:return: liquid phase data are included in the data set.
418+
:rtype: bool
419+
"""
420+
return self._Config.LiquidPhase()
421+
422+
def EnableSuperCritical(self, supercritical:bool=True):
423+
"""Whether to include fluid data in the supercritical phase in the data set.
424+
425+
:param supercritical: include data in the supercritical phase, defaults to True
426+
:type supercritical: bool, optional
427+
"""
428+
self._Config.EnableSuperCritical(supercritical)
429+
if self._Config.SuperCritical():
430+
if CoolP.iphase_supercritical not in self.__accepted_phases:
431+
self.__accepted_phases.append(CoolP.iphase_supercritical)
432+
if CoolP.iphase_gas in self.__accepted_phases and CoolP.iphase_supercritical_gas not in self.__accepted_phases:
433+
self.__accepted_phases.append(CoolP.iphase_supercritical_gas)
434+
if (CoolP.iphase_liquid in self.__accepted_phases) and (CoolP.iphase_supercritical_liquid not in self.__accepted_phases):
435+
self.__accepted_phases.append(CoolP.iphase_supercritical_liquid)
436+
437+
else:
438+
if CoolP.iphase_supercritical in self.__accepted_phases:
439+
self.__accepted_phases.remove(CoolP.iphase_supercritical)
440+
if CoolP.iphase_supercritical_gas in self.__accepted_phases:
441+
self.__accepted_phases.remove(CoolP.iphase_supercritical_gas)
442+
if CoolP.iphase_supercritical_liquid in self.__accepted_phases:
443+
self.__accepted_phases.remove(CoolP.iphase_supercritical_liquid)
444+
return
445+
370446
def SetConductivityModel(self, conductivity_model:str=DefaultSettings_NICFD.conductivity_model):
371447
"""Specify the two-phase conductivity model.
372448
@@ -483,7 +559,58 @@ def __TransportProperties(self, q:float):
483559
conductivity = self.fluid.conductivity()
484560
return viscosity, conductivity, vapor_q
485561

486-
def __EntropicEoS(self, s:float, rho:float, e:float, derivs:dict, state_vector_struct:dict):
562+
def __EntropicEoS(self, rho, e, s, derivs, state_vector_struct:dict):
563+
state_vector_struct[EntropicVars.Density.name] = rho
564+
state_vector_struct[EntropicVars.Energy.name] = e
565+
state_vector_struct[EntropicVars.s.name] = s
566+
dsdrho_e = derivs["dsdrho_e"]
567+
state_vector_struct[EntropicVars.dsdrho_e.name] = dsdrho_e
568+
dsde_rho = derivs["dsde_rho"]
569+
state_vector_struct[EntropicVars.dsde_rho.name] = dsde_rho
570+
d2sdrho2 = derivs["d2sdrho2"]
571+
state_vector_struct[EntropicVars.d2sdrho2.name] = d2sdrho2
572+
d2sde2 = derivs["d2sde2"]
573+
state_vector_struct[EntropicVars.d2sde2.name] = d2sde2
574+
d2sdedrho = derivs["d2sdedrho"]
575+
state_vector_struct[EntropicVars.d2sdedrho.name] = d2sdedrho
576+
Temperature = pow(dsde_rho, -1)
577+
state_vector_struct[EntropicVars.T.name] = Temperature
578+
Pressure = -rho * rho * Temperature * dsdrho_e
579+
state_vector_struct[EntropicVars.p.name] = Pressure
580+
dPde_rho = -rho*rho * Temperature * (-Temperature * (d2sde2 * dsdrho_e) + d2sdedrho)
581+
state_vector_struct[EntropicVars.dpde_rho.name] = dPde_rho
582+
dPdrho_e = - rho * Temperature * (dsdrho_e * (2 - rho * Temperature * d2sdedrho) + rho * d2sdrho2)
583+
state_vector_struct[EntropicVars.dpdrho_e.name] = dPdrho_e
584+
SoundSpeed2 = dPdrho_e - (dsdrho_e / dsde_rho) * dPde_rho
585+
state_vector_struct[EntropicVars.c2.name] = SoundSpeed2
586+
dTde_rho = -Temperature * Temperature * d2sde2
587+
state_vector_struct[EntropicVars.dTde_rho.name] = dTde_rho
588+
dTdrho_e = -Temperature * Temperature * d2sdedrho
589+
state_vector_struct[EntropicVars.dTdrho_e.name] = dTdrho_e
590+
drhode_p = -dPde_rho / dPdrho_e
591+
dhde_rho = 1 + dPde_rho / rho
592+
dhdrho_e = -Pressure * np.power(rho, -2) + dPdrho_e / rho
593+
state_vector_struct[EntropicVars.dhde_rho.name] = dhdrho_e
594+
state_vector_struct[EntropicVars.dhdrho_e.name] = dhde_rho
595+
dTde_p = dTde_rho + dTdrho_e * drhode_p
596+
dhde_p = dhde_rho + drhode_p*dhdrho_e
597+
Cp = dhde_p / dTde_p
598+
Cv = 1 / (dTde_rho+1e-16)
599+
state_vector_struct[EntropicVars.cp.name] = Cp
600+
state_vector_struct[EntropicVars.cv.name] = Cv
601+
dhdrho_P = dhdrho_e - dhde_rho * (1 / dPde_rho) * dPdrho_e
602+
dhdP_rho = dhde_rho * (1 / dPde_rho)
603+
dsdrho_P = dsdrho_e - dPdrho_e * (1 / dPde_rho) * dsde_rho
604+
dsdP_rho = dsde_rho / dPde_rho
605+
state_vector_struct[EntropicVars.dhdrho_p.name] = dhdrho_P
606+
state_vector_struct[EntropicVars.dhdp_rho.name] = dhdP_rho
607+
state_vector_struct[EntropicVars.dsdrho_p.name] = dsdrho_P
608+
state_vector_struct[EntropicVars.dsdp_rho.name] = dsdP_rho
609+
return
610+
611+
612+
613+
def __EquationofState(self, s:float, rho:float, e:float, derivs:dict, state_vector_struct:dict):
487614
"""Calculate thermodynamic state variables with entropic equation of state
488615
489616
:param s: fluid entropy
@@ -523,65 +650,23 @@ def __EntropicEoS(self, s:float, rho:float, e:float, derivs:dict, state_vector_s
523650
Enthalpy = self.fluid.hmass()
524651
state_vector_struct[EntropicVars.Enthalpy.name] = Enthalpy
525652

526-
phase = self.fluid.phase()
527-
if phase == CoolP.iphase_twophase:
528-
dPde_rho = -rho*rho * Temperature * (-Temperature * (d2sde2 * dsdrho_e) + d2sdedrho)
529-
dPdrho_e = - rho * Temperature * (dsdrho_e * (2 - rho * Temperature * d2sdedrho) + rho * d2sdrho2)
530-
SoundSpeed2 = dPdrho_e - (dsdrho_e / dsde_rho) * dPde_rho
531-
dTde_rho = -Temperature * Temperature * d2sde2
532-
dTdrho_e = -Temperature * Temperature * d2sdedrho
533-
drhode_p = -dPde_rho / dPdrho_e
534-
dhde_rho = 1 + dPde_rho / rho
535-
dhdrho_e = -Pressure * np.power(rho, -2) + dPdrho_e / rho
536-
dTde_p = dTde_rho + dTdrho_e * drhode_p
537-
dhde_p = dhde_rho + drhode_p*dhdrho_e
538-
Cp = dhde_p / dTde_p
539-
Cv = 1 / (dTde_rho+1e-16)
540-
dhdrho_P = dhdrho_e - dhde_rho * (1 / dPde_rho) * dPdrho_e
541-
dhdP_rho = dhde_rho * (1 / dPde_rho)
542-
dsdrho_P = dsdrho_e - dPdrho_e * (1 / dPde_rho) * dsde_rho
543-
dsdP_rho = dsde_rho / dPde_rho
544-
545-
X = self.fluid.Q()
546-
self.fluid.update(CoolP.PQ_INPUTS, Pressure, 1)
547-
cp_vap = self.fluid.cpmass()
548-
cv_vap = self.fluid.cvmass()
549-
rho_vap = self.fluid.rhomass()
550-
self.fluid.update(CoolP.PQ_INPUTS, Pressure,0)
551-
cp_liq = self.fluid.cpmass()
552-
cv_liq = self.fluid.cvmass()
553-
alpha=X*rho / rho_vap
554-
Cp = alpha * cp_vap + (1-alpha)*cp_liq
555-
Cv = alpha * cv_vap + (1-alpha)*cv_liq
556-
self.fluid.update(CoolP.DmassUmass_INPUTS, rho, e)
653+
X = self.fluid.Q()
654+
if X<=0 or X>=1:
655+
state_vector_struct[EntropicVars.dpde_rho.name] = self.fluid.first_partial_deriv(CP.iP, CP.iUmass, CP.iDmass)
656+
state_vector_struct[EntropicVars.dpdrho_e.name] = self.fluid.first_partial_deriv(CP.iP, CP.iDmass, CP.iUmass)
657+
state_vector_struct[EntropicVars.c2.name] = self.fluid.speed_sound()**2
658+
state_vector_struct[EntropicVars.dTde_rho.name] = self.fluid.first_partial_deriv(CP.iT, CP.iUmass, CP.iDmass)
659+
state_vector_struct[EntropicVars.dTdrho_e.name] = self.fluid.first_partial_deriv(CP.iT, CP.iDmass, CP.iUmass)
660+
state_vector_struct[EntropicVars.cp.name] = self.fluid.cpmass()
661+
state_vector_struct[EntropicVars.cv.name] = self.fluid.cvmass()
662+
state_vector_struct[EntropicVars.dhdrho_e.name] = self.fluid.first_partial_deriv(CP.iHmass, CP.iDmass, CP.iUmass)
663+
state_vector_struct[EntropicVars.dhde_rho.name] = self.fluid.first_partial_deriv(CP.iHmass, CP.iUmass, CP.iDmass)
664+
state_vector_struct[EntropicVars.dhdrho_p.name] = self.fluid.first_partial_deriv(CP.iHmass, CP.iDmass, CP.iP)
665+
state_vector_struct[EntropicVars.dhdp_rho.name] = self.fluid.first_partial_deriv(CP.iHmass, CP.iP, CP.iDmass)
666+
state_vector_struct[EntropicVars.dsdrho_p.name] = self.fluid.first_partial_deriv(CP.iSmass, CP.iDmass, CP.iP)
667+
state_vector_struct[EntropicVars.dsdp_rho.name] = self.fluid.first_partial_deriv(CP.iSmass, CP.iP, CP.iDmass)
557668
else:
558-
dPde_rho = self.fluid.first_partial_deriv(CP.iP, CP.iUmass, CP.iDmass)
559-
dPdrho_e = self.fluid.first_partial_deriv(CP.iP, CP.iDmass, CP.iUmass)
560-
SoundSpeed2 = self.fluid.speed_sound()**2
561-
dTde_rho = self.fluid.first_partial_deriv(CP.iT, CP.iUmass, CP.iDmass)
562-
dTdrho_e = self.fluid.first_partial_deriv(CP.iT, CP.iDmass, CP.iUmass)
563-
Cp = self.fluid.cpmass()
564-
Cv = self.fluid.cvmass()
565-
dhdrho_e = self.fluid.first_partial_deriv(CP.iHmass, CP.iDmass, CP.iUmass)
566-
dhde_rho = self.fluid.first_partial_deriv(CP.iHmass, CP.iUmass, CP.iDmass)
567-
dhdrho_P = self.fluid.first_partial_deriv(CP.iHmass, CP.iDmass, CP.iP)
568-
dhdP_rho = self.fluid.first_partial_deriv(CP.iHmass, CP.iP, CP.iDmass)
569-
dsdrho_P = self.fluid.first_partial_deriv(CP.iSmass, CP.iDmass, CP.iP)
570-
dsdP_rho = self.fluid.first_partial_deriv(CP.iSmass, CP.iP, CP.iDmass)
571-
572-
state_vector_struct[EntropicVars.dTde_rho.name] = dTde_rho
573-
state_vector_struct[EntropicVars.dTdrho_e.name] = dTdrho_e
574-
state_vector_struct[EntropicVars.dpde_rho.name] = dPde_rho
575-
state_vector_struct[EntropicVars.dpdrho_e.name] = dPdrho_e
576-
state_vector_struct[EntropicVars.c2.name] = SoundSpeed2
577-
state_vector_struct[EntropicVars.cp.name] = Cp
578-
state_vector_struct[EntropicVars.cv.name] = Cv
579-
state_vector_struct[EntropicVars.dhdrho_p.name] = dhdrho_P
580-
state_vector_struct[EntropicVars.dhdp_rho.name] = dhdP_rho
581-
state_vector_struct[EntropicVars.dsdrho_p.name] = dsdrho_P
582-
state_vector_struct[EntropicVars.dsdp_rho.name] = dsdP_rho
583-
state_vector_struct[EntropicVars.dhde_rho.name] = dhde_rho
584-
state_vector_struct[EntropicVars.dhdrho_e.name] = dhdrho_e
669+
self.__EntropicEoS(rho, e, s, derivs, state_vector_struct)
585670
return
586671

587672
def __ThermodynamicState(self):
@@ -615,7 +700,7 @@ def __ThermodynamicState(self):
615700
derivs["d2sdedrho"] = self.fluid.second_partial_deriv(CP.iSmass, CP.iUmass, CP.iDmass, CP.iDmass, CP.iUmass)
616701

617702
# Calculate thermodynamic state variables with entropy-based equation of state
618-
self.__EntropicEoS(s, rho, e, derivs, state_vector_vals)
703+
self.__EquationofState(s, rho, e, derivs, state_vector_vals)
619704

620705
return state_vector_vals
621706

@@ -864,8 +949,8 @@ def __compute_derivatives_fd(self, rho:float, e:float, s_center:float):
864949
"""
865950

866951
# Compute step sizes
867-
drho = max(rho * self.__fd_step_size_rho, 1e-6) # Minimum absolute step
868-
de = max(abs(e) * self.__fd_step_size_e, 1.0) # Minimum 1 J/kg step
952+
drho = rho * self.__fd_step_size_rho#max(rho * self.__fd_step_size_rho, 1e-6) # Minimum absolute step
953+
de = abs(e) * self.__fd_step_size_e#max(abs(e) * self.__fd_step_size_e, 1.0) # Minimum 1 J/kg step
869954

870955
# Get entropy at stencil points for first derivatives (central difference)
871956
s_rho_plus = self.__get_entropy_safe(rho + drho, e)

0 commit comments

Comments
 (0)