fwitte / fluprodia

Fluid property diagrams
https://fluprodia.readthedocs.io
MIT License
27 stars 2 forks source link

User gets no info when calculating single isoline fails. #12

Open jfreissmann opened 4 months ago

jfreissmann commented 4 months ago

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?