Need Gibbs Seawater (GSW) Equation of State to be ported to Julia

The Gibb Seawater Equation of State (GSW) is what oceanographers use to calculate fundamental properties of seawater. Currently there are a couple implementation of the C version of the library in Julia but none of them are working with macOS. If someone can help me develop a version fo macOS, it would be very appreciate. Thanks!

1 Like

im working with Helmholtz EOS, I have the IAPWS95-2018 (just water) and the GERG2008 (natural gas) implemented. (working on a PT solver too). i can help you.

1 Like

looking at this paper. a lot of implementations use the IAPWS95 + a correction term. so implementing the correction terms is whats missing

Sounds like you are doing a Julia native implementation?

Always wanted to see an implementation of GERG! Any chance you could share?

of helmholtz EOS, mainly. the idea i have is an agnostic EOS system. the derivatives are calculated via ForwardDiff and i’m working on a PT solver (multicomponent, i haven’t did anything with monocomponent, like IAPWS95), there are good tools to work on that

of course, check this:
https://github.com/longemen3000/LavoisierCore.jl/blob/master/src/gerg2008.jl
my idea is that the EOS is a struct, and you pass the struct to calculate a property: for example:

mymodel = GERG2008(:CH4,:H2O,:CO2)
pressure(mymodel,2u"kg/m^3",300u"K",[0.1,0.2,0.7])

1 Like

Wow! I admire your tenacity thank you. I will have to fork this and play with it a bit.

1 Like

for all 21 compunds, it takes around 121 μs per helmholtz evaluation, a binary one takes around 4μs (IAPWS95 takes around the same as a binary GERG). if you need properties, you just differenciate the helmholtz function with ForwardDiff (zygote is too slow in this case)

1 Like

Could you try this ?
This is just a wrapper and I don’t have an OSX environment, but it seem to be successful to build on the travis (osx) now.

4 Likes

Thanks @kouketsu!!! I just installed your GSW.jl package and it works! The installation went without a hitch on a new macOS machine but on my old machine I had to manually remove a previous non-working installation to make it precompile correctly. Thanks again!

Longeman I really love the scope your package is aiming for but I tried to use it with a GERG mixture of 2 components and got an array out of bounds error.

how you are calling it?
when you call model = GERG2008() , you call it with all 21 compounds in the order of the kunst paper. if you want a custom order, you can call GERG2008(compounds...), where the list of accepted compounds are:

symvalues = [:CH4, :N2, :CO2, :C2, :C3, :nC4, :iC4, :nC5, :iC5, :C6, :C7, :C8, :C9, :C10, 
    :H2, :O2, :CO, :H2O, :H2S, :He, :Ar]

for example: a water-H2S mixture can be called via:

model = GERG2008(:H2O,:H2S)
core_pressure(model,0.01,373,[0.9,0.1])

I don’t have the code right now, I think I ran it like this,

m = GERG2008(:CH4, :C3)
density(m,2u"kg/m^3",300u"K",[0.1,0.2])

and it gave me an array out of bounds error, something like “tried to access index 3 of a 2 index array”

Maybe I cloned master at an inopportune time though

I have density? I dont remember coding that lol

Give me a moment and i will give you proper molar_density and mass_density

:laughing: Think I meant pressure sorry! Density would be awesome though!

You can check how many compounds yor model have with length(model)

let me try again I cannot find where I cloned it to!

julia> pressure(m,2u"kg/m^3",300u"K",[0.1,0.2])
ERROR: BoundsError: attempt to access 2-element Array{Float64,1} at index [6]
Stacktrace:
 [1] getindex at ./array.jl:731 [inlined]
 [2] _fr2(::GERG2008, ::ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2}, ::ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2}, ::Array{Float64,1}) at /home/caseykneale/try/LavoisierCore.jl/src/gerg2008.jl:626
 [3] core_helmholtz(::GERG2008, ::ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2}, ::ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2}, ::Array{Float64,1}) at /home/caseykneale/try/LavoisierCore.jl/src/gerg2008.jl:671
 [4] vector_mode_gradient(::getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}}, ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2,Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2},1}}) at /home/caseykneale/try/LavoisierCore.jl/src/core.jl:74
 [5] gradient(::Function, ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2,Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2},1}}, ::Val{true}) at /home/caseykneale/.julia/packages/ForwardDiff/N0wMF/src/gradient.jl:17
 [6] gradient(::Function, ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2,Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(LavoisierCore, Symbol("##37#38")){GERG2008,Array{Float64,1}},Float64},Float64,2},1}}) at /home/caseykneale/.julia/packages/ForwardDiff/N0wMF/src/gradient.jl:15 (repeats 2 times)
 [7] core_grad_vt at /home/caseykneale/try/LavoisierCore.jl/src/core.jl:75 [inlined]
 [8] core_pressure(::GERG2008, ::Float64, ::Int64, ::Array{Float64,1}) at /home/caseykneale/try/LavoisierCore.jl/src/core.jl:161
 [9] pressure(::GERG2008, ::Quantity{Int64,𝐌*𝐋^-3,Unitful.FreeUnits{(kg, m^-3),𝐌*𝐋^-3,nothing}}, ::Quantity{Int64,𝚯,Unitful.FreeUnits{(K,),𝚯,nothing}}, ::Array{Float64,1}) at /home/caseykneale/try/LavoisierCore.jl/src/core.jl:170
 [10] top-level scope at none:0

julia> length(m)
2