CalebBell / thermo

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

New function - calculate bubble point temperature + minor edit to chemicals #6

Closed cintronej closed 7 years ago

cintronej commented 7 years ago

Hi Caleb,

This project is really nice! I found your project just last week or so, and have been playing around with it since. I'm amazed at the work you have here.

This pull request adds a function that calculates the bubble point temperature given a composition and pressure. In the process, I noticed that the chemicals test failed to initialize temperature for some components and fails. A small tweak fixes the issue, however, I'm not sure if the original placement was intentional.

I hope this helps. I'm greatly interested in helping out this project where and when I can.

-Enrique

P.S. Apologies for all the whitespace changes. My editor automatically removes them on saving. I can see about disabling that for future submissions.

coveralls commented 7 years ago

Coverage Status

Coverage decreased (-0.002%) to 92.662% when pulling 80c233511088987cb3a5d14da2ff2498efc7e66a on cintronej:master into 3069c0e51558df69c4cb3b8c78983f543e7afa4f on CalebBell:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.005%) to 92.67% when pulling 80c233511088987cb3a5d14da2ff2498efc7e66a on cintronej:master into 3069c0e51558df69c4cb3b8c78983f543e7afa4f on CalebBell:master.

CalebBell commented 7 years ago

Hello Enrique,

I am glad you have found thermo of use to you. I am accepting the pull with gratitude, especially for finding the currently failing test. The bubble P solution function is nice, and I really appreciate the effort you have put into adding the test and the documentation.

I have been working on a rigorous module, thermo.property_package, which will allow for a wide range of flash specifications. Currently, the ideal package, and two UNIFAC variants are implemented. I cannot make a prediction about when it will be finished or what it will include when it is done. I hope to tie it into the Mixture framework smoothly. An example of using it is below. If you have any feedback on the interface, I would be happy to hear it. Eventually after the interface is stabilized, the individual functions such as bubble_at_P will be marked as deprecated and/or removed as they are less capable.

One thing that is key to a good flash solver is using a bounded optimization method. For instance, your method would not work if the critical temperatures of all the species in the mixture were under 300 K.

from thermo import *
from thermo.property_package import *
m = Mixture(['ethanol', 'water'], zs=[0.5, 0.5], P=5000, T=298.15)

vodka = Ideal_PP(m.VaporPressures, m.Tms, m.Tcs, m.Pcs)
# TVF flash
vodka.flash(T=300, VF=.5, zs=m.zs)
print(vodka.xs, vodka.ys, vodka.phase)
print(vodka.P, vodka.T)
# Bubble P flash 
vodka.flash(T=300, VF=0, zs=m.zs)
print(vodka.P)
# Dew P flash 
vodka.flash(T=300, VF=1, zs=m.zs)
print(vodka.P)
# PVF flash
vodka.flash(P=6000, VF=.5, zs=m.zs)
print(vodka.xs, vodka.ys, vodka.phase)
print(vodka.P, vodka.T)

([0.3885191285816652, 0.6114808714183347], [0.6114808714183351, 0.38851912858166493], 'l/g')
(5561.948292104799, 300)
6143.86706855
5035.14618055
([0.3887947733015589, 0.6112052266984411], [0.6112052266984462, 0.38879477330155365], 'l/g')
(6000, 301.3162713676123)
cintronej commented 7 years ago

Thank you Caleb, I very much appreciate the your speedy response and feedback! I was on vacation over the weekend and haven't found time to respond until today.

I agree, using a fixed 300 K was an oversight on my part. I was too focused on my current problem rather than thinking about a general case. I should expand the test coverage for this function, but probably only for other basic cases given its scheduled deprecation.

I've only had a brief chance to go over the new property_package so I don't have much input to add yet. I like where its going. My only suggestion would be to return the calculated values directly and possibly divide up some of the function calls. The idea being to make the vle package more standalone for when mixtures aren't fully needed. Returning a namedtuple would allow usage like this:

from thermo import *
from thermo.property_package import *
from other_package import column
m = Mixture(['ethanol', 'water'], zs=[0.5, 0.5], P=5000, T=298.15)

kset_ideal = Ideal_PP(m.VaporPressures, m.Tms, m.Tcs, m.Pcs)

kset_ideal.flash(T=300, VF=.5, zs=[0.5, 0.5])
# Flash_Props(P=5000, T=300, phase='l/g', xs=[0.3885191285816652, 0.6114808714183347], ys=[0.6114808714183351, 0.38851912858166493], V_over_F=0.5)

kset_ideal.flash(T=300, VF=.5, zs=[0.5, 0.5]).T
# 300

# calculate K values across column simulation
stage_temps =  [kset_ideal.flash(P=pressure, VF=0, zs=stage_zs).T
                for pressure, stage_zs in zip(column.pressures, column.zs)]