BioSTEAMDevelopmentGroup / Bioindustrial-Park

BioSTEAM's Premier Repository for Biorefinery Models and Results
MIT License
36 stars 17 forks source link

Consultation about Flash error #86

Closed zasddsgg closed 9 months ago

zasddsgg commented 9 months ago

Hello, I encountered the following error when calling Flash, I tried various ways, while still no solution, could I consult you how to solve it? Thanks for your help. Wish you a good day.

a) According to line 74 error information "return H_ref + H_int_T_ref_to_Tm_s + Hfus + H_int_Tm_to_Tb_l + Hvap_Tb + Cn_g.T_dependent_property_integral(Tb, T)", It seems that riboflavin becomes a gas, could I consult you why does riboflavin become a gas (the temperature T(453.15K) I set does not reach Tc(923.15K) of riboflavin)? b) For line 116 error information “if self.force_gas_critical_phase and T > self.Tc: phase = 'g'”, when T > self.Tc, why is the chemical in the gas state? c) In addition, error information "TypeError: unsupported operand type(s) for +: 'float' and 'NoneType'" seems to indicate that H_int_T_ref_to_Tm_s and H_int_Tm_to_Tb_l are of type “None” caused by False Cns and Cnl as in https://biosteam.readthedocs.io/en/latest/_modules/thermosteam/_chemical.html#Chemical.get_property:~:text=else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20H_int_Tm_to_Tb_l,S_int_T_ref_to_Tm_s%20%3D%20None, could I consult you how to solve this problem? I tried to call Riboflavin.Cn('s', 298.15), it is valid. So I do not know where is the error from. d) Also, riboflavin has a Hfus of 0, which doesn't seem right? e) Could I confirm with you is Tc a fixed value, just like the boiling point, and not related to the reference phase of the chemical?

The code is as follows:

import biosteam as bst
bst.nbtutorial()
from biosteam import settings
from biosteam import units
import thermosteam as tmo

Riboflavin = bst.Chemical('Riboflavin', Hf=-55700, Tc=650+273.15, Tb=240+273.15)
Ethanol = bst.Chemical('Ethanol')

bst.settings.set_thermo([Riboflavin, Ethanol])

riboflavin = bst.Stream(
    ID='riboflavin',
    price=0.0916,  
    total_flow=1000,
    units='kg/hr',
    Riboflavin=1,
    T=300+273.15,
    P=7500000,
)

Ethanol = bst.Stream(
    ID='Ethanol',
    price=0.0416,  
    total_flow=1000,
    units='kg/hr',
    Ethanol=1,
    T=300+273.15,
    P=7500000,
)

M101 = units.Mixer('M101', ins=(riboflavin, Ethanol))
F101 = units.Flash('F101', M101-0, outs=('vapor', 'liquid'), T=180+273.15, P=101000)

Riboflavin_sys = bst.main_flowsheet.create_system('Riboflavin_sys')
Riboflavin_sys.simulate()

The error information is as follows:

TypeError                                 Traceback (most recent call last)
Cell In[2], line 57
     53 F101 = units.Flash('F101', M101-0, outs=('vapor', 'liquid'), T=180+273.15, P=101000)
     56 Riboflavin_sys = bst.main_flowsheet.create_system('Riboflavin_sys')
---> 57 Riboflavin_sys.simulate()

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_system.py:2176, in System.simulate(self, update_configuration, units, **kwargs)
   2157 def simulate(self, update_configuration: Optional[bool]=False, units=None, **kwargs):
   2158     """
   2159     If system is dynamic, run the system dynamically. Otherwise, converge 
   2160     the path of unit operations to steady state. After running/converging 
   (...)
   2174         
   2175     """
-> 2176     with self.flowsheet.temporary():
   2177         specifications = self._specifications
   2178         if specifications and not self._running_specifications:

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_flowsheet.py:36, in TemporaryFlowsheet.__exit__(self, type, exception, traceback)
     34 def __exit__(self, type, exception, traceback):
     35     main_flowsheet.set_flowsheet(self.original)
---> 36     if exception: raise exception

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_system.py:2200, in System.simulate(self, update_configuration, units, **kwargs)
   2198         outputs = self.simulate(update_configuration=True, **kwargs)
   2199     else:
-> 2200         raise error
   2201 else:
   2202     if (not update_configuration # Avoid infinite loop
   2203         and self._connections != [i.get_connection() for i in self.streams]):
   2204         # Connections has been updated within simulation.

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_system.py:2192, in System.simulate(self, update_configuration, units, **kwargs)
   2190 try:
   2191     outputs = self.converge(**kwargs)
-> 2192     self._summary()
   2193 except Exception as error:
   2194     if update_configuration: raise error # Avoid infinite loop

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_system.py:1933, in System._summary(self)
   1931         if i in simulated_units: continue
   1932         simulated_units.add(i)
-> 1933     f(i, i._summary)
   1934 for i in self._facilities:
   1935     if isa(i, Unit): f(i, i.simulate)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\exceptions.py:90, in try_method_with_object_stamp(object, method, args)
     88     raise StampedKeyError(message_with_object_stamp(object, repr(error.args[0])))
     89 except Exception as error:
---> 90     raise_error_with_object_stamp(object, error)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\exceptions.py:80, in raise_error_with_object_stamp(object, error)
     78     error.args = (message_with_object_stamp(object, msg), *args)
     79 except: pass
---> 80 raise error

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\exceptions.py:84, in try_method_with_object_stamp(object, method, args)
     82 def try_method_with_object_stamp(object, method, args=()):
     83     try:
---> 84         return method(*args)
     85     except StampedKeyError as error:
     86         raise StampedKeyError(message_with_object_stamp(object, error.args[0]))

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\_unit.py:1341, in Unit._summary(self, design_kwargs, cost_kwargs, lca_kwargs)
   1339 self._check_run()
   1340 if not (self._design or self._cost): return
-> 1341 self._design(**design_kwargs) if design_kwargs else self._design()
   1342 self._cost(**cost_kwargs) if cost_kwargs else self._cost()
   1343 self._lca(**lca_kwargs) if lca_kwargs else self._lca()

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\units\_flash.py:283, in Flash._design(self)
    281     self.heat_exchanger._setup() # Removes results
    282 else:
--> 283     self.heat_exchanger.simulate_as_auxiliary_exchanger(self.ins, [self._multi_stream])

File D:\anaconda\envs\zzz\lib\site-packages\biosteam\units\heat_exchange.py:410, in HXutility.simulate_as_auxiliary_exchanger(self, ins, outs, duty, vle, scale, hxn_ok)
    408 outlet.mix_from(outs)
    409 if duty is None: 
--> 410     duty = outlet.Hnet - inlet.Hnet
    411 elif vle: 
    412     outlet.vle(H=inlet.H + duty, P=inlet.P)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\_stream.py:1107, in Stream.Hnet(self)
   1104 @property
   1105 def Hnet(self) -> float:
   1106     """Total enthalpy flow rate (including heats of formation) [kJ/hr]."""
-> 1107     return self.H + self.Hf

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\_multi_stream.py:476, in MultiStream.H(self)
    473 @property
    474 def H(self) -> float:
    475     """Enthalpy flow rate [kJ/hr]."""
--> 476     return self._get_property('H', True)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\_multi_stream.py:327, in MultiStream._get_property(self, name, flow, nophase)
    325 else:
    326     calculate = getattr(self.mixture, 'x' + name)
--> 327     self._property_cache[name] = value = calculate(
    328         zip(imol._phases, composition), *self.thermal_condition
    329     )
    330 return value * total if flow else value

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\mixture\mixture.py:398, in Mixture.xH(self, phase_mol, T, P)
    396 H = self._H
    397 phase_mol = tuple(phase_mol)
--> 398 H_total = sum([H(phase, mol, T, P) for phase, mol in phase_mol])
    399 if self.include_excess_energies:
    400     H_excess = self._H_excess

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\mixture\mixture.py:398, in <listcomp>(.0)
    396 H = self._H
    397 phase_mol = tuple(phase_mol)
--> 398 H_total = sum([H(phase, mol, T, P) for phase, mol in phase_mol])
    399 if self.include_excess_energies:
    400     H_excess = self._H_excess

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\mixture\ideal_mixture_model.py:62, in IdealTPMixtureModel.__call__(self, phase, mol, T, P)
     60 if mol.__class__ is not SparseVector: mol = SparseVector(mol)
     61 models = self.models
---> 62 return sum([j * models[i](phase, T, P) for i, j in mol.dct.items()])

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\mixture\ideal_mixture_model.py:62, in <listcomp>(.0)
     60 if mol.__class__ is not SparseVector: mol = SparseVector(mol)
     61 models = self.models
---> 62 return sum([j * models[i](phase, T, P) for i, j in mol.dct.items()])

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\base\phase_handle.py:117, in PhaseTPHandle.__call__(self, phase, T, P)
    115 def __call__(self, phase, T, P=None):
    116     if self.force_gas_critical_phase and T > self.Tc: phase = 'g'
--> 117     return getattr(self, phase)(T, P)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\base\functor.py:309, in TPFunctor.__call__(self, T, P)
    308 def __call__(self, T, P):
--> 309     return self.function(T, P, **self.__dict__)

File D:\anaconda\envs\zzz\lib\site-packages\thermosteam\free_energy.py:74, in Gas_Enthalpy_Ref_Solid(T, P, Cn_g, H_int_T_ref_to_Tm_s, Hfus, H_int_Tm_to_Tb_l, Hvap_Tb, Tb, H_ref)
     71 @functor(var='H.g')
     72 def Gas_Enthalpy_Ref_Solid(T, P, Cn_g, H_int_T_ref_to_Tm_s, Hfus,
     73                            H_int_Tm_to_Tb_l, Hvap_Tb, Tb, H_ref):
---> 74     return H_ref + H_int_T_ref_to_Tm_s + Hfus + H_int_Tm_to_Tb_l + Hvap_Tb + Cn_g.T_dependent_property_integral(Tb, T)

TypeError: <Flash: F101> unsupported operand type(s) for +: 'float' and 'NoneType'
yoelcortes commented 9 months ago

@zasddsgg,

As long as there is a vapor pressure and a gas phase, there will always be a small amount of that chemical in the gas phase (that's part of the reason there is moisture in the air):

import biosteam as bst
Riboflavin = bst.Chemical('Riboflavin', Hf=-55700, Tc=650+273.15, Tb=240+273.15)
Riboflavin.Psat(453.15) # -> 42750

The error is a result of not having a Hvap model:

import biosteam as bst
Riboflavin = bst.Chemical('Riboflavin', Hf=-55700, Tc=650+273.15, Tb=240+273.15)
Riboflavin.H.g # ->
"""
Functor: Gas_Enthalpy_Ref_Solid(T, P) -> H.g [J/mol]
 Cn_g: HeatCapacityGas(T)
 H_int_T_ref_to_Tm_s: 1.5409e+05 J/mol
 Hfus: 0 J/mol
 H_int_Tm_to_Tb_l: -30866 J/mol
 Hvap_Tb: None
 Tb: 513.15 K
 H_ref: 0 J/mol
"""

Yes, Hfus of 0 is not correct, feel free to change it!

Tc is the critical temperature, the reference phase is based only on Tm, Tb, and Tref (298.15 K in BioSTEAM).

Thanks!