Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_properties(self):
"""
Test gas mixture fluid properties.
Test the CoolProp pseudo pure fluid dry air properties vs. mixture of
air components. Check enthalpy, entropy, specific volume, viscosity.
"""
funcs = {'h': fp.h_mix_pT,
's': fp.s_mix_pT,
'v': fp.v_mix_pT,
'visc': fp.visc_mix_pT}
for name, func in funcs.items():
# enthalpy and entropy need reference point definition
if name == 'h' or name == 's':
p_ref = 1e5
T_ref = 500
mix_ref = func([0, p_ref, 0, self.flow_mix[3]], T_ref)
pure_ref = func([0, p_ref, 0, self.flow_pure[3]], T_ref)
for p in self.p_range:
self.flow_mix[1] = p
self.flow_pure[1] = p
for T in self.T_range:
val_mix = func(self.flow_mix, T)
val_pure = func(self.flow_pure, T)
def setup(self):
fp.memorise.add_fluids({'Air': 'HEOS'})
fp.memorise.add_fluids({
'N2': 'HEOS', 'O2': 'HEOS', 'Ar': 'HEOS', 'CO2': 'HEOS'})
mix = {'N2': 0.7556, 'O2': 0.2315, 'Ar': 0.0129}
pure = {'Air': 1}
self.flow_mix = [0, 0, 0, mix]
self.flow_pure = [0, 0, 0, pure]
self.p_range = np.linspace(1e-2, 200, 40) * 1e5
self.T_range = np.linspace(220, 2220, 40)
self.errormsg = ('Relative deviation of fluid mixture to base '
'(CoolProp air) is too high: ')
if (np.absolute(self.vec_res[k]) > err ** 2 or
self.iter % 2 == 0):
self.vec_res[k] = c.h.val_SI - (
fp.h_mix_pQ(flow, c.x.val_SI))
if not self.vec_z_filter[col + 1]:
self.mat_deriv[k, col + 1] = -(
fp.dh_mix_dpQ(flow, c.x.val_SI))
self.mat_deriv[k, col + 2] = 1
k += 1
# volumetric flow
if c.v.val_set is True:
if (np.absolute(self.vec_res[k]) > err ** 2 or
self.iter % 2 == 0):
self.vec_res[k] = (
c.v.val_SI - fp.v_mix_ph(flow, T0=c.T.val_SI) *
c.m.val_SI)
self.mat_deriv[k, col] = -fp.v_mix_ph(flow, T0=c.T.val_SI)
self.mat_deriv[k, col + 1] = -(
fp.dv_mix_dph(flow, T0=c.T.val_SI) * c.m.val_SI)
self.mat_deriv[k, col + 2] = -(
fp.dv_mix_pdh(flow, T0=c.T.val_SI) * c.m.val_SI)
k += 1
# temperature difference to boiling point
if c.Td_bp.val_set is True:
if (np.absolute(self.vec_res[k]) > err ** 2 or
self.iter % 2 == 0):
self.vec_res[k] = (
fp.T_mix_ph(flow, T0=c.T.val_SI) - c.Td_bp.val_SI -
fp.T_bp_p(flow))
if not self.vec_z_filter[col + 1]:
'sure your network does not have any linear dependencies '
'in the parametrisation. Other reasons might be\n'
'-> given Temperature with given pressure in two phase '
'region, try setting enthalpy instead or '
'provide accurate starting value for pressure.\n'
'-> given logarithmic temperature differences '
'or kA-values for heat exchangers, \n'
'-> support better starting values.\n'
'-> bad starting value for fuel mass flow of '
'combustion chamber, provide small (near to zero, '
'but not zero) starting value.')
logging.error(msg)
return
self.post_processing()
fp.memorise.del_memory(self.fluids)
if not self.progress:
return
msg = 'Calculation complete.'
logging.info(msg)
# referenced temperature
if c.T.ref_set is True:
ref = c.T.ref
flow_ref = ref.obj.to_flow()
ref_col = ref.obj.conn_loc * self.num_conn_vars
self.residual[k] = fp.T_mix_ph(flow, T0=c.T.val_SI) - (
fp.T_mix_ph(flow_ref, T0=ref.obj.T.val_SI) *
ref.f + ref.d)
self.jacobian[k, col + 1] = (
fp.dT_mix_dph(flow, T0=c.T.val_SI))
self.jacobian[k, col + 2] = (
fp.dT_mix_pdh(flow, T0=c.T.val_SI))
self.jacobian[k, ref_col + 1] = -(
fp.dT_mix_dph(flow_ref, T0=ref.obj.T.val_SI) * ref.f)
self.jacobian[k, ref_col + 2] = -(
fp.dT_mix_pdh(flow_ref, T0=ref.obj.T.val_SI) * ref.f)
# dT / dFluid
if len(self.fluids) != 1:
col_s = c.conn_loc * self.num_conn_vars + 3
col_e = (c.conn_loc + 1) * self.num_conn_vars
ref_col_s = ref.obj.conn_loc * self.num_conn_vars + 3
ref_col_e = (ref.obj.conn_loc + 1) * self.num_conn_vars
if not all(self.increment_filter[col_s:col_e]):
self.jacobian[k, col_s:col_e] = (
fp.dT_mix_ph_dfluid(flow, T0=c.T.val_SI))
if not all(self.increment_filter[ref_col_s:ref_col_e]):
self.jacobian[k, ref_col_s:ref_col_e] = -(
fp.dT_mix_ph_dfluid(flow_ref, T0=ref.obj.T.val_SI))
k += 1
c.p.val_SI = fp.memorise.value_range[fl][0]
logging.debug(self.property_range_message(c, 'p'))
if c.p.val_SI > fp.memorise.value_range[fl][1] and not c.p.val_set:
c.p.val_SI = fp.memorise.value_range[fl][1]
logging.debug(self.property_range_message(c, 'p'))
# enthalpy
try:
hmin = fp.h_pT(
c.p.val_SI, fp.memorise.value_range[fl][2] * 1.001, fl)
except ValueError:
f = 1.05
hmin = fp.h_pT(
c.p.val_SI, fp.memorise.value_range[fl][2] * f, fl)
hmax = fp.h_pT(
c.p.val_SI, fp.memorise.value_range[fl][3], fl)
if c.h.val_SI < hmin and not c.h.val_set:
if hmin < 0:
c.h.val_SI = hmin * 0.9999
else:
c.h.val_SI = hmin * 1.0001
logging.debug(self.property_range_message(c, 'h'))
elif c.h.val_SI > hmax and not c.h.val_set:
c.h.val_SI = hmax * 0.9999
logging.debug(self.property_range_message(c, 'h'))
if ((c.Td_bp.val_set is True or c.state.is_set is True) and
c.h.val_set is False and self.iter < 3):
if (c.Td_bp.val_SI > 0 or
(c.state.val == 'g' and c.state.is_set is True)):
self.jacobian[k, col + 2] = -(
fp.dv_mix_pdh(flow, T0=c.T.val_SI) * c.m.val_SI)
k += 1
# temperature difference to boiling point
if c.Td_bp.val_set is True:
if (np.absolute(self.residual[k]) > err ** 2 or
self.iter % 2 == 0):
self.residual[k] = (
fp.T_mix_ph(flow, T0=c.T.val_SI) - c.Td_bp.val_SI -
fp.T_bp_p(flow))
if not self.increment_filter[col + 1]:
self.jacobian[k, col + 1] = (
fp.dT_mix_dph(flow, T0=c.T.val_SI) - fp.dT_bp_dp(flow))
if not self.increment_filter[col + 2]:
self.jacobian[k, col + 2] = fp.dT_mix_pdh(
flow, T0=c.T.val_SI)
k += 1
# fluid composition balance
if c.fluid.balance:
j = 0
res = 1
for f in self.fluids:
res -= c.fluid.val[f]
self.jacobian[k, c.conn_loc + 3 + j] = -1
j += 1
self.residual[k] = res
k += 1
# equations and derivatives for specified primary variables are static
cp.bus_func(b.comps.loc[cp]) /
abs(b.comps.loc[cp].char.evaluate(1)))
b.P.val += val
# connections
for c in self.conns.index:
c.T.val_SI = fp.T_mix_ph(c.to_flow(), T0=c.T.val_SI)
c.v.val_SI = fp.v_mix_ph(c.to_flow(), T0=c.T.val_SI) * c.m.val_SI
c.T.val = (c.T.val_SI / self.T[c.T.unit][1] - self.T[c.T.unit][0])
c.m.val = c.m.val_SI / self.m[c.m.unit]
c.p.val = c.p.val_SI / self.p[c.p.unit]
c.h.val = c.h.val_SI / self.h[c.h.unit]
c.v.val = c.v.val_SI / self.v[c.v.unit]
fluid = hlp.single_fluid(c.fluid.val)
if isinstance(fluid, str) and not c.x.val_set:
c.x.val_SI = fp.Q_ph(c.p.val_SI, c.h.val_SI, fluid)
c.x.val = c.x.val_SI
c.T.val0 = c.T.val
c.m.val0 = c.m.val
c.p.val0 = c.p.val
c.h.val0 = c.h.val
c.fluid.val0 = c.fluid.val.copy()
msg = 'Postprocessing complete.'
logging.info(msg)
if not self.vec_z_filter[col + 1]:
self.mat_deriv[k, col + 1] = -(
fp.dh_mix_dpQ(flow, c.x.val_SI))
self.mat_deriv[k, col + 2] = 1
k += 1
# volumetric flow
if c.v.val_set is True:
if (np.absolute(self.vec_res[k]) > err ** 2 or
self.iter % 2 == 0):
self.vec_res[k] = (
c.v.val_SI - fp.v_mix_ph(flow, T0=c.T.val_SI) *
c.m.val_SI)
self.mat_deriv[k, col] = -fp.v_mix_ph(flow, T0=c.T.val_SI)
self.mat_deriv[k, col + 1] = -(
fp.dv_mix_dph(flow, T0=c.T.val_SI) * c.m.val_SI)
self.mat_deriv[k, col + 2] = -(
fp.dv_mix_pdh(flow, T0=c.T.val_SI) * c.m.val_SI)
k += 1
# temperature difference to boiling point
if c.Td_bp.val_set is True:
if (np.absolute(self.vec_res[k]) > err ** 2 or
self.iter % 2 == 0):
self.vec_res[k] = (
fp.T_mix_ph(flow, T0=c.T.val_SI) - c.Td_bp.val_SI -
fp.T_bp_p(flow))
if not self.vec_z_filter[col + 1]:
self.mat_deriv[k, col + 1] = (
fp.dT_mix_dph(flow, T0=c.T.val_SI) - fp.dT_bp_dp(flow))
if not self.vec_z_filter[col + 2]:
self.mat_deriv[k, col + 2] = fp.dT_mix_pdh(
logging.debug(self.property_range_message(c, 'h'))
if c.h.val_SI > hmax and not c.h.val_set:
c.h.val_SI = hmax * 0.9
logging.debug(self.property_range_message(c, 'h'))
if ((c.Td_bp.val_set is True or c.state.is_set is True) and
c.h.val_set is False and self.iter < 3):
if (c.Td_bp.val_SI > 0 or
(c.state.val == 'g' and c.state.is_set is True)):
h = fp.h_mix_pQ(c.to_flow(), 1)
if c.h.val_SI < h:
c.h.val_SI = h * 1.02
logging.debug(self.property_range_message(c, 'h'))
elif (c.Td_bp.val_SI < 0 or
(c.state.val == 'l' and c.state.is_set is True)):
h = fp.h_mix_pQ(c.to_flow(), 0)
if c.h.val_SI > h:
c.h.val_SI = h * 0.98
logging.debug(self.property_range_message(c, 'h'))
elif self.iter < 4 and c.init_csv is False:
# pressure
if c.p.val_SI <= self.p_range_SI[0] and not c.p.val_set:
c.p.val_SI = self.p_range_SI[0]
logging.debug(self.property_range_message(c, 'p'))
if c.p.val_SI >= self.p_range_SI[1] and not c.p.val_set:
c.p.val_SI = self.p_range_SI[1]
logging.debug(self.property_range_message(c, 'p'))
# enthalpy
if c.h.val_SI < self.h_range_SI[0] and not c.h.val_set:
c.h.val_SI = self.h_range_SI[0]