Skip to content

Commit

Permalink
Merge pull request #19 from se-schmitt/Database
Browse files Browse the repository at this point in the history
Add database, Revision of Docs and Readme
  • Loading branch information
se-schmitt authored Jan 3, 2025
2 parents 93d74a8 + 04ef18e commit b3a3521
Show file tree
Hide file tree
Showing 18 changed files with 728 additions and 107 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Manifest.toml
.vscode
docs/build/
docs/build/
scripts/
50 changes: 29 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,48 @@ using EntropyScaling

## Examples

**Chapman-Enskog viscosity of methane**
**Chapman-Enskog viscosity (zero-density limit) of methane**

```julia
using EntropyScaling
julia> using EntropyScaling

# Parameters from Poling et al. (2001)
σ = 3.758e-10 # size parameter ([σ] = m)
ε = 148.6*EntropyScaling.kB # energy parameter ([ε] = J)
Mw = 16.0425e-3 # molar mass ([Mw] = kg/mol)
julia> model = ChapmanEnskog("methane")
ChapmanEnskogModel{methane}
σ: [3.758] Å
ε: [148.6] K
M: [0.01604] kg/
Collision integral: KimMonroe

# Calculate gas viscosity of methane at 300 K
T = 300.
η = viscosity_CE(T, Mw, σ, ε)
julia> η = viscosity(model, NaN, 300.) # gas viscosity of methane at 300 K in Pa s
1.1189976373570321e-5
```

**Fitting a new entropy scaling model**

```julia
using EntropyScaling, Clapeyron
julia> using EntropyScaling, Clapeyron

julia> (T_exp,ϱ_exp,η_exp) = EntropyScaling.load_sample_data(); # Load sample data
┌ Info: Experimental data for the viscosity of n-butane.
└ Units: [T] = K, [ϱ] = mol/m³, [η] = Pa·s

# Load sample data
(T_exp,ϱ_exp,η_exp) = EntropyScaling.load_sample_data()
data = ViscosityData(T_exp, [], ϱ_exp, η_exp, :unknown)
julia> data = ViscosityData(T_exp, [], ϱ_exp, η_exp, :unknown)
TransportPropertyData{Viscosity}
15 data points.

# Create EOS model
eos_model = PCSAFT("butane")
julia> eos_model = PCSAFT("butane") # Clapeyron.jl EOS model
PCSAFT{BasicIdeal, Float64} with 1 component:
"butane"
Contains parameters: Mw, segment, sigma, epsilon, epsilon_assoc, bondvol

# Create entropy scaling model (fit of parameters)
model = FrameworkModel(eos_model, [data])
julia> model = FrameworkModel(eos_model, [data]) # Fit model parameters
FrameworkModel with 1 component:
"butane"
Available properties: viscosity
Equation of state: Clapeyron.EoSVectorParam{PCSAFT{BasicIdeal, Float64}}("butane")

# Calculation of the viscostiy at state
p = 0.1e6 # Pa
T = 300. # K
η = viscosity(model, p, T)
julia> η = viscosity(model, 1e5, 300.; phase=:liquid) # viscostiy at p=1 bar and T=300 K
0.0001605897169488518
```

[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg
Expand Down
227 changes: 227 additions & 0 deletions database/ChapmanEnskog.csv

Large diffs are not rendered by default.

152 changes: 152 additions & 0 deletions database/RefpropRES_viscosity.csv

Large diffs are not rendered by default.

32 changes: 25 additions & 7 deletions docs/src/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,42 @@ $$Y^{\rm s} = Y^{\rm s}\left(s_{\rm conf}\right).$$

Entropy scaling enables the prediction of transport porperties in all fluid phases.

### Available Models
### Models

All models are similarly structured with the following fields:

- `components::Vector{String}`: names of the chemical components of the system
- `params::Vector{ModelParams}`: vector of model-specific paramater objects
- `eos`: EOS model

The `ModelParams` are model-specific types containing all required parameters of the model.
They always contain the Chapman-Enskog model (`CE_model`) as well as base parameters (`base`)
which itself contains general parameters like the transport property or the molar mass.

All models share the contructor method `Model(eos, params::Dict{P})`, where params is a dict
containing the parameters with the respective transport property as key, e.g.,
`Dict(Viscosity() => [a_η, b_η, c_η], ThermalConductivity() => [a_λ, b_λ, c_λ])`.
Here, `a`, `b`, and `c` are the parameters (note that `a_η`, `b_η`, ... are vectors or matrices themselfs).
Lists of the parameters are given below in the repective 'Parameters' sections.
Additional model-specific constructors are also given below.

```@docs
EntropyScaling.FrameworkModel
EntropyScaling.RefpropRESModel
```

### Fitting Entropy Scaling Parameters

*[Work in progress]*
### Fitting Utilities

Some entropy scaling models allow the fitting of substance-specific parameters to experimental data.
Therefore, a unified interface is provided including the handling of the data and the fit options.

**Fitting Procedure**

1. Loading experimental data
2. Fitting
1. Loading experimental data and defining `TransportPropertyData`
2. Fitting (included in the model construction)
3. Plotting results and saving the parameters

**Example**
```@docs
EntropyScaling.TransportPropertyData
EntropyScaling.FitOptions
```
4 changes: 4 additions & 0 deletions ext/ClapeyronExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ ES._eos_cache(eos::EoSModel) = CL.EoSVectorParam(eos)
ES._eos_cache(eos::CL.EoSVectorParam) = eos
ES._eos_cache(eos::MultiFluid) = eos

# Model specific wrapper
ES.RefpropRESModel(comps::String) = RefpropRESModel([comps])
ES.RefpropRESModel(comps::Vector{String}) = RefpropRESModel(MultiFluid(comps), comps)

end #module
3 changes: 2 additions & 1 deletion src/EntropyScaling.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Z1 = FillArrays.Fill(1.0,1)
get_kBNAR() = (kB=1.380649e-23; NA=6.02214076e23; return (kB,NA,kB*NA))
const (kB, NA, R) = get_kBNAR()

const DB_PATH = normpath(Base.pkgdir(EntropyScaling),"data")
const DB_PATH = normpath(Base.pkgdir(EntropyScaling),"database")

#equivalent to a' * b, but with general iterators
function _dot(a,b)
Expand All @@ -29,6 +29,7 @@ include("general/properties.jl")
include("utils/data.jl")
include("utils/thermo.jl")
include("utils/misc.jl")
include("utils/database.jl")

# Models
include("models/base.jl")
Expand Down
Empty file removed src/database/RefpropRES.csv
Empty file.
47 changes: 40 additions & 7 deletions src/general/chapman_enskog.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,32 @@ Chapman-Enskog transport properties for the zero-density limit.
## Constructors
ChapmanEnskogModel(components; collision_integral=KimMonroe())*
ChapmanEnskogModel(components, σ, ε, Mw; collision_integral=KimMonroe())
ChapmanEnskogModel(components; collision_integral=KimMonroe())
ChapmanEnskogModel(components, σ, ε, Mw; collision_integral=KimMonroe(), ref="", ref_id="")
Input arguments can either be single values (pure) or vectors.
In case no parameters are provided, values are taken *Poling et al. (2001)* or *Yang et al. (2022)* (if available).
The keywords `ref` (short reference) and `ref_id` (DOI or ISBN) enable the specification of the reference.
Mixture properties are calculated according to the models from *Wilke (1950)* (viscosity), *Mason and Saxen (1958)* (thermal conductivity), and *Miller and Carman (1961)* (self-diffusion coefficient).
[* to be implemented]
## Example
```julia
using EntropyScaling
# Construction with custom parameters
σ, ε, Mw = 3.758e-10, 148.6*EntropyScaling.kB, 16.043e-3 # from Poling et al.
model_methane = ChapmanEnskogModel("methane",σ,ε,Mw)
η_mix = viscosity(model_methane, NaN, 300.)
D_mix = self_diffusion_coefficient(model_methane, NaN, 300.)
# Construction from database
model_mix = ChapmanEnskogModel(["butane","methanol"]; ref="Poling et al. (2001)")
η_mix = viscosity(model_mix, NaN, 300., [.5,.5])
D_mix = self_diffusion_coefficient(model_mix, NaN, 300., [.5,.5])
```
## References
1. B. E. Poling, J. M. Prausnitz, and J. P. O’Connell: The Properties of Gases and Liquids, 5th, ed. McGraw-Hill, New York (2001).
Expand All @@ -36,14 +55,28 @@ struct ChapmanEnskogModel{T,C} <: AbstractChapmanEnskogModel
σ::Vector{T}
ε::Vector{T}
Mw::Vector{T}
ref::Vector{Reference}
collision::C
end
function ChapmanEnskogModel(comps::Vector{String}, σ::Vector{T}::Vector{T},Mw::Vector{T};collision_integral=KimMonroe()) where {T}
return ChapmanEnskogModel(comps, σ,ε,Mw,collision_integral)

function ChapmanEnskogModel(comps::Vector{String}, σ::Vector{T}, ε::Vector{T}, Mw::Vector{T}; collision_integral=KimMonroe()) where {T}
return ChapmanEnskogModel(comps, σ, ε, Mw, Reference[], collision_integral)
end

function ChapmanEnskogModel(comps::String, σ::Float64, ε::Float64, Mw::Float64; collision_integral=KimMonroe())
return ChapmanEnskogModel([comps], [σ], [ε], [Mw], Reference[], collision_integral)
end
function ChapmanEnskogModel(comps::String, σ::Float64::Float64,Mw::Float64;collision_integral=KimMonroe())
return ChapmanEnskogModel([comps], [σ],[ε],[Mw],collision_integral)

ChapmanEnskogModel(comps::String; kwargs...) = ChapmanEnskogModel([comps]; kwargs...)
function ChapmanEnskogModel(comps::Vector{String}; Mw=[], ref="", ref_id="", collision_integral=KimMonroe())
out = load_params(ChapmanEnskogModel, "", comps; ref, ref_id)
Mw_db, ε, σ, refs = out
if isempty(Mw)
Mw = Mw_db
end
return ChapmanEnskogModel(comps, σ.*1e-10, ε.*kB, Mw, refs, collision_integral)
end

Base.length(model::AbstractChapmanEnskogModel) = length(model.Mw)

# Viscosity
Expand Down
4 changes: 2 additions & 2 deletions src/general/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ abstract type AbstractTransportPropertyMixing end

struct Reference
doi::String
shortref::String
short::String
end
Reference() = Reference("", "NA")

struct BaseParam{P} <: AbstractParam
prop::P
solute_name::Union{Missing,String}
Mw::Vector{Float64}
param_ref::Vector{Reference}
ref::Vector{Reference}
N_data::Int
T_range::Tuple{Float64,Float64}
p_range::Tuple{Float64,Float64}
Expand Down
15 changes: 5 additions & 10 deletions src/models/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,8 @@ end
function build_model(::Type{MODEL},eos,param_dict::Dict{P}) where {MODEL<:AbstractEntropyScalingModel,P<:AbstractTransportProperty}
params_vec = Any[]
PARAM = paramstype(MODEL)
for (prop, α) in param_dict
T = eltype(α)
if α isa Vector && length(eos) == 1
αx = convert(Array{T,2},reshape(α,length(α),1))
else
αx = convert(Array{T,2},α)
end
push!(params_vec, build_param(PARAM, prop, eos, αx))
for (prop, ps) in param_dict
push!(params_vec, build_param(PARAM, prop, eos, ps))
end
params = tuple(params_vec...)
return MODEL(eos, params)
Expand All @@ -161,13 +155,14 @@ build_model(MODEL,components,params,eos) = MODEL(components,params,eos)
build_model(::Type{MODEL},eos,params::Tuple) where MODEL = build_model(MODEL,get_components(eos),params,_eos_cache(eos))
build_model(::Type{MODEL},eos,params::AbstractVector) where MODEL = build_model(MODEL,eos,tuple(params...))
build_model(::Type{MODEL},eos,params::AbstractEntropyScalingParams) where MODEL = build_model(MODEL,get_components(eos),params,_eos_cache(eos))
function build_param(::Type{PARAM},prop::AbstractTransportProperty,eos,αx;kwargs...) where PARAM <: AbstractEntropyScalingParams
PARAM(prop,eos,αx,kwargs...)
function build_param(::Type{PARAM},prop::AbstractTransportProperty,eos,ps) where PARAM <: AbstractEntropyScalingParams
PARAM(prop,eos,ps...)
end

function paramstype end
#a macro that automates some definitions of model methods.
#TODO: handle fitting for arbitrary methods.
#TODO: check if all methods work
macro modelmethods(model,param)
return quote
EntropyScaling.paramstype(::Type{<:$model}) = $param
Expand Down
72 changes: 56 additions & 16 deletions src/models/framework.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
export FrameworkModel, FrameworkParams

"""
FrameworkParams{P<:AbstractTransportProperty,T<:Number}
Structure to store the parameters of the framework model. The parameters are:
- `α`: a matrix of size `(nparams,ncomponents)` containing the parameters of the corresponding transport property
- `m`: a vector of length `ncomponents` containing segment information
- `σ`: a vector of length `ncomponents` containing the molecular size parameters
- `ε`: a vector of length `ncomponents` containing the dispersion energies
- `Y₀⁺min`: vector of length `ncomponents` containing the minimum scaled property
- `base`: a `BaseParam` containing molecular weight, transport property and fitting information.
"""
struct FrameworkParams{P,T} <: AbstractEntropyScalingParams
α::Matrix{T}
m::Vector{Float64}
Expand Down Expand Up @@ -94,16 +83,68 @@ end
"""
FrameworkModel{T} <: AbstractEntropyScalingModel
A generic entropy scaling model.
Entropy scaling framework from *Schmitt et al. (2024)*.
The entropy scaling framework provides a physical way to model transport properties
(viscosity, thermal conductivity, diffusion coeffficients) based on molecular-based EOS.
It enables fitting new models using only few experimental data.
## Parameters
- `α::Matrix{T}`: component-specific parameters (size: `5 x N_components`)
`m` (segment parameter of molecular-based EOS) and `Y₀⁺min` (minimum of the scaled
zero-density transport property) are additional internal parameters (not to be set at
construction).
## Constructors
FrameworkModel(eos, params::Dict{P})
Default constructor (see above).
FrameworkModel(eos, datasets::Vector{TransportPropertyData};
opts::FitOptions=FitOptions(),
solute=nothing
)
Constructor for fitting new parameters `α` to experimental data (only applicable to pure components).
`datasets` needs to be a vector containing [`TransportPropertyData`](@ref).
`opts` enables controling the fitting procedure through [`FitOptions`](@ref).
`solute` should be an EOS model of the solute (only applicable when fitting diffusion coeffficients at infinite dilution).
## Example
```julia
using EntropyScaling, Clapeyron
# Load experimental sample data for n-butane
(T_exp,ϱ_exp,η_exp) = EntropyScaling.load_sample_data()
data = ViscosityData(T_exp, [], ϱ_exp, η_exp, :unknown)
# Create EOS model
eos_model = PCSAFT("butane")
# Create entropy scaling model (fit of parameters)
model = FrameworkModel(eos_model, [data])
# Calculation of the viscostiy at state
η = viscosity(model, 0.1e6, 300.)
```
## Reference
1. S. Schmitt, H. Hasse, and S. Stephan: Entropy Scaling Framework for Transport Properties Using Molecular-Based Equations of State, Journal of Molecular Liquids 395 (2024) 123811, DOI: https://doi.org/10.1016/j.molliq.2023.123811.
"""
struct FrameworkModel{E,FP} <: AbstractEntropyScalingModel
struct FrameworkModel{E,P} <: AbstractEntropyScalingModel
components::Vector{String}
params::FP
params::P
eos::E
end

@modelmethods FrameworkModel FrameworkParams

#TODO revise cite method (also cite parameters)
function cite_model(::FrameworkModel)
print("Entropy Scaling Framework:\n---\n" *
"(1) Schmitt, S.; Hasse, H.; Stephan, S. Entropy Scaling Framework for " *
Expand All @@ -113,7 +154,7 @@ function cite_model(::FrameworkModel)
return nothing
end


# Method for fitting parameters
function FrameworkModel(eos, datasets::Vector{TPD}; opts::FitOptions=FitOptions(),
solute=nothing) where TPD <: TransportPropertyData
# Check eos and solute
Expand Down Expand Up @@ -167,7 +208,6 @@ function FrameworkModel(eos, datasets::Vector{TPD}; opts::FitOptions=FitOptions(
return FrameworkModel(eos, params)
end


# Scaling model (correlation: Yˢ = Yˢ(sˢ,α,g))
function scaling_model(param::FrameworkParams{<:AbstractViscosity}, s, x=[1.])
g = (-1.6386, 1.3923)
Expand Down
Loading

0 comments on commit b3a3521

Please sign in to comment.