Replies: 10 comments 22 replies
-
I have some notes here: #70 Some notes:
In things I wish to implement someday:
|
Beta Was this translation helpful? Give feedback.
-
Thank very much @longemen3000 for your insights, it is really helpful! |
Beta Was this translation helpful? Give feedback.
-
there is also this paper, https://pubs.acs.org/doi/10.1021/acs.iecr.2c02723 that has an alternative way (and by the looks of it, a faster one) to solve association, but that requires having the association strength defined for each site instead of defined for each site pair. if there was a way to convert between those, that would speed up the calculations a lot |
Beta Was this translation helpful? Give feedback.
-
@longemen3000 We wrote a little python script to do the D matrix construction of Langenbach. It took us a lot of time, it is not so obvious, but it also in the end is quite straightforward to understand once you know exactly what you are doing. And you can do it quite generically, with as many sites as you like. I think this is what we will implement in teqp. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Ok, good, I think we were intending to try that with the pure fluid association starting values, but you think we should just start with association fractions of zero? |
Beta Was this translation helpful? Give feedback.
-
Where are the routines in Clapeyron for association calculations? I poked around and had a hard time finding them. |
Beta Was this translation helpful? Give feedback.
-
Our python code for the Langenbach method (the other methods not included) looks like: interaction_partners = {
'B': ('N', 'P', 'B'),
'N': ('P', 'B'),
'P': ('N', 'B')
}
def get_DIJ(I, J):
"""
Return the value of an entry in the D_{IJ} matrix
"""
i, typei = inv_mapping[I]
j, typej = inv_mapping[J]
if typej in interaction_partners[typei]:
return counts[(j, typej)]
return 0 Operating with strings as site keys is no downside since this only happens at model instantiation and thereafter everything is with integers |
Beta Was this translation helpful? Give feedback.
-
Just an idea i'm working on. technically solving association is solving a system of polynomial equations. An homotopy continuation method could be used to solve the problem, allowing a fast newton solver to be used while having the good convergence properties of the damped SS method. a proof of concept: julia> using Clapeyron, HomotopyContinuation
julia> model = PCSAFT(["water","ethanol"],assoc_options = AssocOptions(combining = :cr1))
PCSAFT{BasicIdeal, Float64} with 2 components:
"water"
"ethanol"
Contains parameters: Mw, segment, sigma, epsilon, epsilon_assoc, bondvol
julia> A = Clapeyron.assoc_site_matrix(model,0.03,373.15,[0.4,0.6])
4×4 Matrix{Float64}:
0.0 0.0061563 0.0 0.0118999
0.0061563 0.0 0.0118999 0.0
0.0 0.00793324 0.0 0.015334
0.00793324 0.0 0.015334 0.0
julia> X = Clapeyron.X(model,0.03,373.15,[0.4,0.6]).v #solves association, returns raw vector
4-element Vector{Float64}:
0.982623238409625
0.982623238409625
0.9777200008431199
0.9777200008431199
julia> @var x1 x2 x3 x4 #define variables
(x1, x2, x3, x4)
julia> x = [x1,x2,x3,x4]
4-element Vector{Variable}:
x1
x2
x3
x4
julia> system = System(A*x .* x + x - ones(Int,4)) #quadratic polynomial system to solve
System of length 4
4 variables: x1, x2, x3, x4
-1 + x1 + x1*(0.0061563003744746*x2 + 0.0118998581866071*x4)
-1 + x2 + x2*(0.0061563003744746*x1 + 0.0118998581866071*x3)
-1 + x3 + x3*(0.00793323879107139*x2 + 0.0153339652426488*x4)
-1 + x4 + x4*(0.00793323879107139*x1 + 0.0153339652426488*x3)
julia> result = solve(system) #solve system
Result with 6 solutions
=======================
• 6 paths tracked
• 6 non-singular solutions (6 real)
• random_seed: 0x8fc22b3a
• start_system: :polyhedral
julia> real_solutions(result)
6-element Vector{Vector{Float64}}:
[4.649456560860215, -121.03902836969094, -87.13425260084185, -3.3419293138077375]
[0.9826232384090261, 0.9826232384090261, 0.9777200008421453, 0.9777200008421454]
[4.70277979831464, 4.702779798314639, -68.59842529822113, -68.59842529822114]
[875900.535060796, 875900.535060796, -453224.4591725971, -453224.4591725971]
[-156.9584505920934, -156.9584505920934, -3.368758186430234, -3.3687581864302336]
[-121.03902836969094, 4.649456560860218, -3.3419293138077384, -87.13425260084185]
julia> real_solutions(result)[2] - X
4-element Vector{Float64}:
-5.988542994828094e-13
-5.988542994828094e-13
-9.74664793318425e-13
-9.745537710159624e-13 |
Beta Was this translation helpful? Give feedback.
-
Some updates: Michelsen was right all along, the newton minimization method is faster, even with the increased allocations (1 matrix, one vector of integers to perform LU, two support vectors). LU factorization is necessary, gauss-seidel or jacobi iterations to solve the linear system eat away the speed-up. on successive substitution, one way to accelerate the iterations is to reuse the results in each iteration, instead of:
we can do something like:
This is similar to one technique used to accelerate COSMOSAC iterative calculations. on the AD part, there are two ways to propagate derivative information.
|
Beta Was this translation helpful? Give feedback.
-
With a colleague we are working on adding association to teqp. As you have implemented this into Clapeyron.jl already, we plan to mirror your implementation quite closely since we can easily test against it in julia and jupyter.
Before we begin, are there any places there where you wish you had done something different from the beginning so that we can avoid needing to learn the same hard lessons as you? Is it sufficient to have only electron donors and acceptors in the full generality? I guess perhaps one could consider to do something similar with halogen bonding, at least in principle?
Beta Was this translation helpful? Give feedback.
All reactions