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
```python
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
```python
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
```python
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
```python
Traceback (most recent call last):
File "c:\fluprodiatest.py", line 18, in
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?
This issue references issue jfreissmann/heatpumps#28.
In some cases, calling the
calc_individual_isoline
method of theFluidPropertyDiagram
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 atry
-except
-clause, that just continues when aValueError
is thrown. In the cases described here, this can happen throughout the whole isoline. See the_single_isentropic
method for example:Single Isentropic Method
```python 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 anothertry
-except
-block, usingPropsSI
to get better values for thestate.update
call. See below:Single Isothermal Method
```python 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
```python 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
```python Traceback (most recent call last): File "c:\fluprodiatest.py", line 18, inRequirements
``` 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 allCoolProp
calls fail, as the way it is handled now, you have to have it fail in your own code and dig deep intofluprodia
to even understand which method exactly fails. What do you think?