CalebBell / thermo

Thermodynamics and Phase Equilibrium component of Chemical Engineering Design Library (ChEDL)
MIT License
594 stars 114 forks source link

Thermo v. 0.2.26 flash_vl - Raising Exception on PH flash #144

Closed mikeyj777 closed 8 months ago

mikeyj777 commented 8 months ago

I am combining multiple streams, one is vapor and liquid in equilibrium, another is air (modeling as nitrogen).

To force one stream to vapor and the other liquid, I've adjusted the temperatures by 0.01 deg K in the appropriate directions.

To determine the final state of the mixed streams, I'm first iterating across each stream and totalizing the enthalpy of each stream (source_inputs is a list of custom objects which contain stream state):

all_energy_in = 0
for strm in source_inputs: 
    if ignore_air and strm.description == 'air':
        continue
    s = Stream(IDs = strm.chem_mix, ws=strm.mass_composition, m=strm.mass_flow_kg_s, T=strm.temp_k, P=p_pa)
    all_energy_in += s.H

I am then setting up a flash_vl object per the documentation:

constants, properties = ChemicalConstantsPackage.from_IDs(mix)
kijs = IPDB.get_ip_asymmetric_matrix('ChemSep PR', constants.CASs, 'kij')
eos_kwargs = {'Pcs': constants.Pcs, 'Tcs': constants.Tcs, 'omegas': constants.omegas, 'kijs': kijs}
gas = CEOSGas(PRMIX, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
liquid = CEOSLiquid(PRMIX, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
flasher = FlashVL(constants, properties, liquid=liquid, gas=gas)

ph = flasher.flash(P=101325, H=all_energy_in, zs=zs)

This was my guess as to how to approach combining the streams and doing a flash to find current state. Let me know if there is a better method. I thought the failure that I was seeing may be due to such a wide range of high and low boiling, but removing the air does not get it to solve.

As far as the exception that was raised, in thermo/flash/flash_vl.py, the exception is on line 950, that it is unable to find the parameter "guess".

sln = nonlin_spec_NP(guess, fixed_val, spec_val, zs, [xs, ys], [1.0-VF, VF],
                             [self.liquids[0], self.gas], iter_var=iter_var, fixed_var=fixed_var, spec=spec,
                             maxiter=self.TPV_HSGUA_NEWTON_MAXITER, tol=self.TPV_HSGUA_NEWTON_XTOL,
                             trivial_solution_tol=1e-5, ref_phase=-1,
                             method=self.TPV_HSGUA_NEWTON_SOLVER,
                             solve_kwargs=None, debug=False,
                             analytical_jac=self.HSGUA_NEWTON_ANALYTICAL_JAC)

It appears that secant method could not improve on a solution, and the code fell thru thusly.

Full exception trace:

File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_vl.py", line 888, in flash_TPV_HSGUA res, flash_convergence = self.solve_PT_HSGUA_NP_guess_bisect(zs, fixed_val, spec_val, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_vl.py", line 1019, in solve_PT_HSGUA_NP_guess_bisect sln_val = secant(to_solve, guess, xtol=self.TPV_HSGUA_BISECT_XTOL, ytol=ytol,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:[my_long_folder]\venv\Lib\site-packages\fluids\numerics__init__.py", line 2543, in secant raise SamePointError("Convergence failed - previous points are the same", q1=q1, p1=p1, q0=q0, p0=p0) fluids.numerics.SamePointError: Convergence failed - previous points are the same

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\python\python_3_11_4\Lib\runpy.py", line 198, in _run_module_as_main return _run_code(code, main_globals, None, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\python\python_3_11_4\Lib\runpy.py", line 88, in _run_code exec(code, run_globals) File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy__main__.py", line 39, in cli.main() File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 430, in main run() File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 284, in run_file runpy.run_path(target, run_name="main") File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy_vendored\pydevd_pydevd_bundle\pydevd_runpy.py", line 321, in run_path
return _run_module_code(code, init_globals, run_name, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy_vendored\pydevd_pydevd_bundle\pydevd_runpy.py", line 135, in _run_module_code _run_code(code, mod_globals, init_globals, File "c:\Users\u773253.vscode\extensions\ms-python.python-2023.14.0\pythonFiles\lib\python\debugpy_vendored\pydevd_pydevd_bundle\pydevd_runpy.py", line 124, in _run_code
exec(code, run_globals) File "C:[my_long_folder]\small_tests_indoor_modeling.py", line 50, in ph = flasher.flash(P=101325, H=all_energy_in, zs=zs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_base.py", line 436, in flash raise e File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_base.py", line 430, in flash g, ls, ss, betas, flash_convergence = self.flash_TPV_HSGUA(fixed_var_val, spec_val, fixed_var, spec, iter_var, zs=zs, solution=solution, hot_start=hot_start, spec_fun=spec_fun) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_vl.py", line 893, in flash_TPV_HSGUA g, ls, ss, betas, flash_convergence = self.solve_PT_HSGUA_NP_guess_newton_2P(zs, fixed_val, spec_val, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:[my_long_folder]\venv\Lib\site-packages\thermo\flash\flash_vl.py", line 950, in solve_PT_HSGUA_NP_guess_newton_2P sln = nonlin_spec_NP(guess, fixed_val, spec_val, zs, [xs, ys], [1.0-VF, VF], ^^^^^ UnboundLocalError: cannot access local variable 'guess' where it is not associated with a value

CalebBell commented 8 months ago

Hi @mikeyj777,

The legacy Stream interface doesn't use the same enthalpy basis as the new Phase/flasher-based stuff, would not recommend trying to use them together. EquilibriumStream is the replacement for Stream. I have put off documenting it & don't have a tutorial; however, to combine to EquilibriumStream objects, you would add their flow rates (.ns attribute) and energy (.energy atribute) and provide them as input to a new EquilibriumStream object, as well as the pressure & the flasher object.

Here's a brief example

from thermo import *
constants, properties = ChemicalConstantsPackage.from_IDs(['methane', 'ethane', 'nitrogen'])
eos_kwargs = {'Pcs': constants.Pcs, 'Tcs': constants.Tcs, 'omegas': constants.omegas}
gas = CEOSGas(PRMIX, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
liquid = CEOSLiquid(PRMIX, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
flasher = FlashVL(constants, properties, liquid=liquid, gas=gas)
S1 = EquilibriumStream(flasher=flasher, T=300, P=1e5, ns=[1,2,3])
S2 = EquilibriumStream(flasher=flasher, T=305, P=1e5, ns=[.5,.3,.8])

ns_out = [na+nb for na, nb in zip(S1.ns, S2.ns)]
S3 = EquilibriumStream(flasher=flasher, P=1e5, ns=ns_out, energy=S1.energy+S2.energy)
S3.T, S3.ns

(300.9985275567583, [1.5, 2.2999999999999994, 3.7999999999999994])

Sincerely, Caleb

mikeyj777 commented 8 months ago

thank you so much for the great support! I will give it a go and comment back with any issues.

mikeyj777 commented 8 months ago

How would you recommend working with a pure component stream? the equilibrium stream failed with a div by zero error in property_package.py, line 455

CalebBell commented 8 months ago

Pure components should work fine but instead of FlashVL you need to use FlashPureVLS: https://thermo.readthedocs.io/thermo.flash.html#thermo.flash.FlashPureVLS