Skip to content

Commit 8c95503

Browse files
authored
Fix DETPFlash reduced Gibbs scaling for GammaPhi/PTFlashWrapper (#517)
* Fix DETPFlash reduced Gibbs scaling for GammaPhi/PTFlashWrapper - Fix DETPFlash objective scaling: accumulate phase reduced Gibbs (G/RT) and normalize by total moles to return molar reduced Gibbs g = G/(nRT) in Obj_de_tp_flash. - Previously: GammaPhi/PTFlashWrapper path produced reduced Gibbs, but the objective applied an extra /RT, causing inconsistent g vs RRTPFlash/MichelsenTPFlash. - Make __eval_G_DETPFlash(model::EoSModel, ...) return reduced Gibbs consistently (g/RT) to match PTFlashWrapper/GammaPhi path. - Fix gammaphi_gibbs empty-phase return: always return (g, v) tuple for sum(w)==0 to avoid type/unwrap inconsistency. - Refactor gammaphi_gibbs typing: introduce a single promoted eltype and reuse it for both g and v zeros. - Add minimal SASS ask–tell usage example at top of sass_at.jl. modified: src/methods/property_solvers/multicomponent/tp_flash/DifferentialEvolutiontp_flash.jl modified: src/models/CompositeModel/GammaPhi.jl modified: src/modules/solvers/metaheuristics/sass_at.jl modified: test/test_methods_api_flash.jl * fix CI
1 parent d6bdcb8 commit 8c95503

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

src/methods/property_solvers/multicomponent/tp_flash/DifferentialEvolutiontp_flash.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,31 +169,33 @@ function Obj_de_tp_flash(model,p,T,n,dividers,numphases,x,nvals,vcache,logspace
169169
#nvals = zeros(TT,numphases, numspecies)
170170
#Calculate partition of species into phases
171171
partition!(dividers,n,x,nvals)
172-
#Calculate Overall Gibbs energy (J)
172+
#Accumulate total reduced Gibbs energy, G/(RT)
173173
#If any errors are encountered, return a big number, ensuring point is discarded
174174
#by DE Algorithm
175175
G = _0
176176
for i 1:numphases
177177
ni = @view(nvals[i, :])
178-
gi,vi = __eval_G_DETPFlash(model,p,T,ni,equilibrium)
178+
gi_reduced,vi = __eval_G_DETPFlash(model,p,T,ni,equilibrium)
179179
vcache[i] = vi
180-
G += gi
180+
G += gi_reduced
181181
#calling with PTn calls the internal volume solver
182182
#if it returns an error, is a bug in our part.
183183
end
184184
if logspace
185185
dividers .= log.(dividers)
186186
end
187-
= Rgas(model)
188-
return ifelse(isnan(G),bignum,G//T)
187+
# Per the FlashData definition, return the molar reduced Gibbs energy (g = G/(nRT))
188+
∑n = sum(n)
189+
return ifelse(isnan(G),bignum,G/∑n)
189190
end
190191

191192
#indirection to allow overloading this evaluation in activity models
192193
function __eval_G_DETPFlash(model::EoSModel,p,T,ni,equilibrium)
193194
phase = is_lle(equilibrium) ? :liquid : :unknown
195+
RT = Rgas(model)*T
194196
vi = volume(model,p,T,ni;phase = phase)
195197
g = VT_gibbs_free_energy(model, vi, T, ni)
196-
return g,vi
198+
return g/RT,vi
197199
end
198200

199201
numphases(method::DETPFlash) = method.numphases

src/models/CompositeModel/GammaPhi.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,12 @@ end
279279

280280
function gammaphi_gibbs(wrapper::PTFlashWrapper,p,T,w,phase = :unknown,vol = NaN)
281281
model = wrapper.model
282+
TT = Base.promote_eltype(__γ_unwrap(model),p,T,w)
282283
RT = Rgas(model)*T
283284
∑w = sum(w)
284-
iszero(∑w) && return zero(Base.promote_eltype(model,p,T,w))
285-
g_ideal = sum(xlogx,w) - xlogx(sum(w))
286-
vl = zero(Base.promote_eltype(__γ_unwrap(model),p,T,w))
285+
iszero(∑w) && return zero(TT), zero(TT)
286+
g_ideal = sum(xlogx,w) - xlogx(∑w)
287+
vl = zero(TT)
287288
if is_liquid(phase)
288289
return excess_gibbs_free_energy(__γ_unwrap(model),p,T,w)/RT + g_ideal,vl
289290
elseif is_vapour(phase)

src/modules/solvers/metaheuristics/sass_at.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
"""
2+
Simple usage example:
3+
4+
```julia
5+
using Clapeyron
6+
const SOL = Clapeyron.Solvers
7+
8+
f(x) = sum(abs2, x)
9+
dim = 2
10+
lb = fill(-5.0, dim)
11+
ub = fill(5.0, dim)
12+
13+
algo = SOL.SASS(50, 10_000, lb, ub; seed = 1, stagnation_evals = 0, stagnation_tol = 0.0)
14+
while !SOL.isdone(algo)
15+
x = SOL.ask!(algo)
16+
y = f(x)
17+
SOL.tell!(algo, y)
18+
end
19+
20+
best_x, best_y = SOL.best(algo)
21+
```
22+
"""
23+
124
mutable struct Arch
225
max_npop::Int
326
x::Matrix{Float64}

test/test_methods_api_flash.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#https://julialang.zulipchat.com/#narrow/channel/265161-Clapeyron.2Ejl/topic/The.20meaning.20of.20subcooled.20liquid.20flash.20results/near/534216551
3636
model_zulip2 = PR(["n-butane", "n-pentane", "n-hexane", "n-heptane"])
3737
res3 = Clapeyron.tp_flash2(model_zulip2, 1e5 , 450, z_zulip1, RRTPFlash(equilibrium=:vle))
38-
38+
3939
if Clapeyron.numphases(res3) == 2
4040
@test isone(res3.fractions[2])
4141
@test res3.volumes[1] 0.03683358805181434 rtol = 1e-6
@@ -69,15 +69,15 @@
6969

7070
@testset "DE Algorithm" begin
7171
#VLLE eq
72-
@test Clapeyron.tp_flash(system, p, T, z, DETPFlash(numphases = 3))[3] -6.759674475174073 rtol = 1e-6
72+
@test Clapeyron.tp_flash(system, p, T, z, DETPFlash(numphases = 3))[3] -6.759674475174073 rtol = 1e-12
7373
#LLE eq with activities
7474
act_system = UNIFAC(["water","cyclohexane","propane"])
7575
flash0 = Clapeyron.tp_flash(act_system, p, T, [0.5,0.5,0.0], DETPFlash(equilibrium = :lle))
7676
act_x0 = activity_coefficient(act_system, p, T, flash0[1][1,:]) .* flash0[1][1,:]
7777
act_y0 = activity_coefficient(act_system, p, T, flash0[1][2,:]) .* flash0[1][2,:]
78-
@test Clapeyron.dnorm(act_x0,act_y0) < 1e-6
78+
@test Clapeyron.dnorm(act_x0,act_y0) < 1e-5
7979
flash_RR = Clapeyron.tp_flash(act_system, p, T, [0.5,0.5,0.0], RRTPFlash(equilibrium = :lle))
80-
@test flash0[3] flash_RR[3] rtol = 1e-12
80+
@test flash0[3] flash_RR[3] rtol = 1e-11
8181
end
8282

8383
@testset "Multiphase algorithm" begin
@@ -245,7 +245,7 @@
245245
flash4 = tp_flash(model_vle, 2500.0, 300.15, [0.9, 0.1], MichelsenTPFlash())
246246

247247
@test flash4[1]
248-
[0.9239684120579815 0.07603158794201849;
248+
[0.9239684120579815 0.07603158794201849;
249249
0.793479931206839 0.20652006879316098] rtol = 1e-6
250250
#test equality of activities does not make sense in VLE
251251
end
@@ -488,7 +488,7 @@ end
488488
h475 = Clapeyron.PS.enthalpy(fluid475,1.742722525216547e6,-89.04935789018991,[1.0,1.0])
489489
res475 = Clapeyron.PS.flash(fluid475,1.742722525216547e6,-89.04935789018991,[1.0,1.0])
490490
@test enthalpy(fluid475,res475) h475 rtol = 1e-6
491-
491+
492492
#issue 492
493493
fluid492 = GERG2008(["propane", "butane"])
494494
p492 = 1.5e6
@@ -503,7 +503,7 @@ end
503503
p_in_506 = 101325.0; z_506 = [1.0,1.0]
504504
T_in_506 = dew_temperature(fluid506,p_in_506,z_506)[1] + 10; # we are now pure vapour
505505
p_out_506 = 3.0*p_in_506
506-
h_in_506 = enthalpy(fluid506,p_in_506,T_in_506,z)
506+
h_in_506 = enthalpy(fluid506,p_in_506,T_in_506,z)
507507
s_in_506 = Clapeyron.PH.entropy(fluid506, p_in_506, h_in_506,z_506,phase = phase506)
508508
h_out_506 = Clapeyron.PS.enthalpy(fluid506, p_out_506, s_in_506,z_506,phase = phase506)
509509
s_out_506 = Clapeyron.PH.entropy(fluid506, p_out_506, h_out_506,z_506,phase = phase506)

0 commit comments

Comments
 (0)