BioSTEAMDevelopmentGroup / thermosteam

BioSTEAM's Premier Thermodynamic Engine
Other
57 stars 12 forks source link

[Feature request] auto-determine phases when creating `Stream` objects #59

Closed BenPortner closed 2 years ago

BenPortner commented 2 years ago

Dear developers,

First off, thanks for putting so much effort into developing thermosteam. I am still new but I already like it a lot!

Current behavior

Today I was surprised when I created a Stream object and checked the phase attribute. It seems the default assumption is that the phase is liquid. Clearly, this will not always be the case:

import thermosteam as tmo

chemicals = tmo.Chemicals(["CH4", "O2"])
tmo.settings.set_thermo(chemicals)

s=tmo.Stream(CH4=1, O2=6)
s.show()

"""
Stream: s1
 phase: 'l', T: 25 degC, P: 1.01325 bar
 composition: CH4  0.0771
              O2   0.923
              ---  0.0578 kg/s
"""

Expected behavior

The correct phase can be set manually by passing a phase attribute while creating the Stream object. However, I was expecting thermosteam to determine the correct phase automatically from the given temperature and pressure. This would be more convenient and also less error-prone, especially for new users:

import thermosteam as tmo

chemicals = tmo.Chemicals(["CH4", "O2"])
tmo.settings.set_thermo(chemicals)

s=tmo.Stream(CH4=1, O2=6)
s.show()

"""
Stream: s1
 phase: 'g', T: 25 degC, P: 1.01325 bar
 composition: CH4  0.0771
              O2   0.923
              ---  0.0578 kg/s
"""

Since I am new to thermosteam, I don't know how much work it would be to implement such a change. I assume, things could get tricky as soon as one enters multiphase regions. On the other hand, thermosteam already offers functions to calculate VLE and LLE. What do you think?

Best regards. Ben

yoelcortes commented 2 years ago

Hi Ben,

Thanks a lot for the detailed feature request! While it is not hard to implement this change, performing VLE and/or LLE adds a ton of overhead to calculations (~750 us in this example). Additionally, as more phase equilibrium capabilities get added into thermosteam (VLLE), there may be more overhead to find the number of phases that exist. Stream objects are created quickly (~15 us in this example) and only perform calculations per request. This is super helpful as streams can be created when needed without worrying for computation time (let's say in for loops).

One option is to have a setting where users can change the default behavior and save it for the next time they open Python (similar to https://biosteam.readthedocs.io/en/latest/tutorial/Preferences.html). Using this option would probably break some functionality for some biorefineries in the Bio-industrial park because some flow rates may have multiple phases (2d arrays instead of 1d) while doing calculations in custom unit operations.

If you feel this is something you'd really like to use, feel free to leave this feature request open and I may add it in the long run.

Thanks!

BenPortner commented 2 years ago

Hi @yoelcortes,

Thanks for your detailed answer. I understand that performance and backwards-compability is of primary importance. Here is another idea: One could add a boolean keyword argument determine_phases to the thermosteam.Stream constructor. The default value is False (thus preserving backward compability and performance). If explicitly switched to True, the phase of each chemical in the stream will be determined from the stream temperature and pressure.

yoelcortes commented 2 years ago

I like this idea, since we already have a phase='l' parameter, what would you think of thermosteam autodetermining the phases (and performing vle and lle) when user passes phase=None?

BenPortner commented 2 years ago

Sounds really good to me :)

yoelcortes commented 2 years ago

Hi Ben,

The new feature has been implemented, but using vlle as an extra argument for consistency with MultiStream objects which do not take in a phase parameter:

import thermosteam as tmo
chemicals = tmo.Chemicals(["CH4", "O2"])
tmo.settings.set_thermo(chemicals)
s=tmo.Stream(CH4=1, O2=6, vlle=True)
s.show()

Output:

Stream: s1
 phase: 'g', T: 298.15 K, P: 101325 Pa
 flow (kmol/hr): CH4  1
                 O2   6

You'll need the github versions to use this feature.

Thanks!