User gets no info when calculating single isoline fails.
This issue references issue jfreissmann/heatpumps#28.
In some cases, calling the calc_individual_isoline method of the FluidPropertyDiagram returns a fluid property dict of empty arrays. This happens, because one of the _single_isoline methods updating the CoolProp state fails and continues to fail through all iterations along the isoline. Each iteration contains a try-except-clause, that just continues when a ValueError is thrown. In the cases described here, this can happen throughout the whole isoline. See the _single_isentropic method for example:
Single Isentropic Method
def _single_isentropic(self, iterator, s):
"""Calculate an isoline of constant specific entropy."""
datapoints = {'h': [], 'T': [], 'v': [], 's': [], 'p': []}
for i, val in enumerate(iterator):
try:
self.state.update(CP.DmassSmass_INPUTS, val, s[i])
datapoints['T'] += [self.state.T()]
datapoints['p'] += [self.state.p()]
datapoints['v'] += [1 / val]
datapoints['s'] += [s[i]]
datapoints['h'] += [self.state.hmass()]
except ValueError:
pass
for key in datapoints.keys():
datapoints[key] = np.asarray(datapoints[key])
return datapoints
Something similar may have already come up with single isothermals, as their except-clause contains another try-except-block, using PropsSI to get better values for the state.update call. See below:
Single Isothermal Method
def _single_isothermal(self, iterator, T):
"""Calculate an isoline of constant temperature."""
datapoints = {'h': [], 'T': [], 'v': [], 's': [], 'p': [], 'Q': []}
if iterator[0] < iterator[-1]:
rising = True
else:
rising = False
for i, val in enumerate(iterator):
try:
self.state.update(CP.SmassT_INPUTS, val, T[i])
datapoints['T'] += [T[i]]
datapoints['p'] += [self.state.p()]
datapoints['v'] += [1 / self.state.rhomass()]
datapoints['s'] += [val]
datapoints['h'] += [self.state.hmass()]
if T[i] < self.T_crit:
datapoints['Q'] += [self.state.Q()]
else:
datapoints['Q'] += [-1]
except ValueError:
# for some reason PropSI inputs are way more stable here
try:
p = CP.CoolProp.PropsSI(
'P', 'T', T[i], 'S', val, self.fluid
)
self.state.update(CP.PSmass_INPUTS, val, p)
datapoints['T'] += [T[i]]
datapoints['p'] += [p]
datapoints['v'] += [1 / self.state.rhomass()]
datapoints['s'] += [val]
datapoints['h'] += [self.state.hmass()]
except ValueError:
pass
for key in datapoints.keys():
datapoints[key] = np.asarray(datapoints[key])
data = self._get_Q_crossings(datapoints, 'T', rising)
if len(data) == 0:
return datapoints
else:
Below is an example code snippet to recreate the issue, including the Traceback I get:
Reproduce the Issue
import json
import matplotlib.pyplot as plt
from heatpumps.models import HeatPumpIHX
from heatpumps.parameters import get_params
params = get_params('HeatPumpIHX')
params['setup']['refrig'] = 'SES36'
params['fluids']['wf'] = 'SES36'
print(json.dumps(params, indent=4))
hp = HeatPumpIHX(params=params)
hp.run_model()
hp.generate_state_diagram(savefig=False, open_file=False)
plt.show()
Traceback
Traceback (most recent call last):
File "c:\fluprodiatest.py", line 18, in <module>
hp.generate_state_diagram(savefig=False, open_file=False)
File "C:\envs\fptest\Lib\site-packages\heatpumps\models\HeatPumpBase.py", line 395, in generate_state_diagram
datapoints[var['x']][0], datapoints[var['y']][0],
~~~~~~~~~~~~~~~~~~~~^^^
IndexError: index 0 is out of bounds for axis 0 with size 0
Requirements
fluprodia==3.3
heatpumps==1.2.0
tespy==0.7.5
coolprop==6.6.0
numpy==2.0.0
matplotlib==3.9.1
As discussed in the issue within the heatpumps repository, this problem could very well stem from compression into the vapor-liquid-region. I was not able to find a setup in which this working fluid did not produce the issue, no matter how low the temperature lift and even with superheating via an IHX. In any case, fluprodia should certainly give the user feedback when most or all CoolProp calls fail, as the way it is handled now, you have to have it fail in your own code and dig deep into fluprodia to even understand which method exactly fails. What do you think?