ClapeyronThermo / Clapeyron.jl

Clapeyron provides a framework for the development and use of fluid-thermodynamic models, including SAFT, cubic, activity, multi-parameter, and COSMO-SAC.
https://clapeyronthermo.github.io/Clapeyron.jl/
MIT License
210 stars 52 forks source link

Help - trying to make LLE with UNIFAC (Not an issue) #144

Closed SalvadorBrandolin closed 1 year ago

SalvadorBrandolin commented 1 year ago

Hello, we are trying to perform a liquid-liquid equilibria flash with UNIFAC. We have two problems:

The first one:

We perform the flash calculation with the default Clapeyron value for constants and options and then we tried to evaluate the activity in each phase after the flash calculation. We obtained different values...

using Clapeyron

model = UNIFAC(["water", "hexane"])

algorithm = MichelsenTPFlash(
    equilibrium = :lle, 
    K0 = [0.00001/0.99999, 0.99999/0.00001],
)

flash = tp_flash(model, 101325, 303.15, [0.5, 0.5], algorithm)

# Activity calculation on each phase

act_x = activity_coefficient(model, 101325, 303.15, flash[1][1,:]) .* flash[1][1,:]
act_y = activity_coefficient(model, 101325, 303.15, flash[1][2,:]) .* flash[1][2,:]

Output: ([0.9999900023219743, 0.062055849696312164], [0.0011464067122757193, 0.9999900003798906])

The second problem:

We tried to give to the MichelsenTPFlash the x0 and y0 values instead of K0 values. And we obtained an error.


algorithm = MichelsenTPFlash(
    equilibrium = :lle, 
    x0 = [0.99999, 0.00001],
    y0 = [0.00001, 0.00009]
)

flash = tp_flash(model, 101325, 303.15, [0.5, 0.5], algorithm)

act_x = activity_coefficient(model, 101325, 303.15, flash[1][1,:]) .* flash[1][1,:]
act_y = activity_coefficient(model, 101325, 303.15, flash[1][2,:]) .* flash[1][2,:]

act_x, act_y

Output:

MethodError: reducing over an empty collection is not allowed; consider supplying init to the reducer

Stacktrace: [1] mapreduce_empty(#unused#::typeof(identity), op::Function, T::Type) @ Base ./reduce.jl:367 [2] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(min)}, #unused#::Type{Float64}) @ Base ./reduce.jl:356 [3] reduce_empty_iter @ ./reduce.jl:379 [inlined] [4] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Float64}, ItrEltype::Base.HasEltype) @ Base ./reduce.jl:375 [5] _mapreduce(f::typeof(identity), op::typeof(min), #unused#::IndexLinear, A::Vector{Float64}) @ Base ./reduce.jl:427 [6] _mapreduce_dim @ ./reducedim.jl:365 [inlined] [7] #mapreduce#765 @ ./reducedim.jl:357 [inlined] [8] mapreduce @ ./reducedim.jl:357 [inlined] [9] #_minimum#787 @ ./reducedim.jl:999 [inlined] [10] _minimum @ ./reducedim.jl:999 [inlined] [11] #_minimum#786 @ ./reducedim.jl:998 [inlined] ... @ In[108]:7 [20] eval @ ./boot.jl:368 [inlined] [21] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String) @ Base ./loading.jl:1428

We don't know if in Clapeyron is possible to perform LLE calculations with Gibbs excess models. Thank you in advance.

pw0908 commented 1 year ago

Hi,

There is indeed a function to calculate LLE with activity coefficient models: LLE! You can see that the results do work out (with a good initial guess):

julia> using Clapeyron

julia> model = UNIFAC(["water", "hexane"])
UNIFAC{PR{BasicIdeal, PRAlpha, NoTranslation, vdW1fRule}} with 2 components:
 "water": "H2O" => 1
 "hexane": "CH3" => 2, "CH2" => 4
Group Type: UNIFACDortmund
Contains parameters: A, B, C, R, Q

julia> (x,xx) = LLE(model,303.15;v0=[0.9999,0.0001])
(0.9998391884629948, 0.009359875234386136)

julia> activity_coefficient(model,101325,303.15,[x,1-x]).*[x,1-x]
2-element Vector{Float64}:
 0.9998397884039265
 0.9909694650904838

julia> activity_coefficient(model,101325,303.15,[xx,1-xx]).*[xx,1-xx]
2-element Vector{Float64}:
 0.999839781366857
 0.9909694651241101

Everything seems to check out! We don't advertise the LLE method much since it isn't really consistent with everything else in the package.

Hope this helped!

SalvadorBrandolin commented 1 year ago

What are x and xx? It is possible to obtain the molar fractions of water and hexane on each phase? There is documentation of the LLE method?

pw0908 commented 1 year ago

x is the composition of species 1 in first phase and xx is the composition of species 1 in the second phase.

v0 in this case is the initial guess for the composition of the first component in each phase.

I've now checked and there's unfortunately no documentation for this function. We should probably add it.

longemen3000 commented 1 year ago

also, the init error is a genuine bug. (the flash fails in that case, but that is another matter)

SalvadorBrandolin commented 1 year ago

Ok! thank you very much.

longemen3000 commented 1 year ago

closed by #164