API Reference
Input
SFEModeling.ExtractionCurve — Type
ExtractionCurve(; data, ...)Experimental extraction curve data and operating conditions for one experiment.
Required keyword arguments
data::Matrix{Float64}: table with column 1 = extraction times (min) and columns 2:N = cumulative extracted mass for each replicate (g). AMatrixcan be read from files withTextTableorExcelTable.porosity::Float64: bed porosity (dimensionless)x0::Float64: total extractable yield (mass fraction, kg/kg)solid_density::Float64: solid density (g/cm³)solvent_density::Float64: solvent density (g/cm³)flow_rate::Float64: solvent mass flow rate (g/min)bed_height::Float64: bed height (cm)bed_diameter::Float64: bed diameter (cm)particle_diameter::Float64: particle diameter (cm)solid_mass::Float64: mass of solid (g)solubility::Float64: solubility (kg/kg)
Optional keyword arguments
nh::Int: spatial discretization steps (default: 5)nt::Int: temporal discretization steps (default: 2500)
Example
data = TextTable("experiment.txt") # or ExcelTable("experiment.xlsx")
curve = ExtractionCurve(data=data, porosity=0.4, ...)Data readers
SFEModeling.TextTable — Function
TextTable(filename; kwargs...)Read a delimited text file and return a Matrix{Float64}. The expected format is one time column followed by one or more replicate columns:
# t (min) rep1 (g) rep2 (g)
0.0 0.000 0.000
5.0 0.110 0.094
10.0 0.257 0.227Lines starting with # are ignored. Keyword arguments are passed to DelimitedFiles.readdlm.
Example
data = TextTable("experiment.txt")
curve = ExtractionCurve(data=data, temperature=313.15, ...)SFEModeling.ExcelTable — Function
ExcelTable(filename; sheet=1, header=true)Read an Excel .xlsx file and return a Matrix{Float64}. The expected format is one time column followed by one or more replicate columns.
Arguments
filename: path to the.xlsxfile.sheet: sheet index (default:1) or name (String).header: whether the first row contains column headers to skip (default:true).
Example
data = ExcelTable("experiment.xlsx")
curve = ExtractionCurve(data=data, temperature=313.15, ...)Fitting
SFEModeling.fit_model — Function
fit_model(curve; kwargs...) → ModelFitResult{Sovova}
fit_model(curves; kwargs...) → ModelFitResult{Sovova}
fit_model(Sovova(), curve; kwargs...) → ModelFitResult{Sovova}
fit_model(model, curve; kwargs...) → ModelFitResult{M}
fit_model(model, curves; kwargs...) → ModelFitResult{M}Fit a kinetic SFE model to one or more extraction curves.
When called without a model (or with Sovova()), fits the Sovová PDE model and returns a ModelFitResult{Sovova}. Each curve gets its own kya and kxa; the ratio xk/x0 is shared across all curves.
When called with any other model type M, fits that empirical model with all parameters shared across curves, and returns a ModelFitResult{M}.
Arguments
model: kinetic model instance. Defaults toSovova()when omitted. Empirical options:Esquivel(),Zekovic(),PKM(),SplineModel().curve/curves: a singleExtractionCurveor aVectorof them.
Keyword arguments — Sovová model
kya_bounds::Tuple{Float64,Float64}: bounds for kya (default:(0.0, 0.05))kxa_bounds::Tuple{Float64,Float64}: bounds for kxa (default:(0.0, 0.005))xk_ratio_bounds::Tuple{Float64,Float64}: bounds for xk/x0 (default:(0.0, 1.0))maxevals::Int: maximum function evaluations (default:50_000)tracemode::Symbol: optimizer verbosity —:silent,:compact, or:verbose(default::silent)
Keyword arguments — empirical models
param_bounds::Vector{Tuple{Float64,Float64}}: one bound per parameter; defaults to the values fromparam_specmaxevals::Int: maximum function evaluations (default:50_000)tracemode::Symbol: optimizer verbosity (default::silent)
Examples
# Sovová PDE model (default)
result = fit_model(curve)
result = fit_model(Sovova(), curve)
# Empirical model
result = fit_model(PKM(), curve)
result = fit_model(PKM(), [curve1, curve2])SFEModeling.param_spec — Function
param_spec(model) -> Vector{ParamSpec}Return the parameter specification for model: a vector of ParamSpec values, each describing a parameter's name, human-readable label, and default lower/upper bounds.
Used internally by fit_model to set the search range for the optimizer. Inspect it to see parameter order and default bounds:
param_spec(PKM())
# 3-element Vector{ParamSpec}:
# "k1" k₁ — easily accessible fraction (—) [0.0, 1.0]
# "k2" k₂ — fluid-phase rate constant (1/s) [0.0, 0.05]
# "k3" k₃ — solid-phase rate constant (1/s) [0.0, 0.005]Available model types (pass an instance as the first argument to fit_model; omit for the default Sovová PDE model):
SFEModeling.Sovova — Type
Sovova()Sovová PDE supercritical extraction model. This is the default model used when calling fit_model without an explicit model argument.
Fits per-curve parameters kya (fluid-phase mass transfer coefficient, 1/s) and kxa (solid-phase mass transfer coefficient, 1/s), plus a shared xk/x0 ratio (easily accessible solute fraction).
Returns a ModelFitResult.
SFEModeling.ShrinkingCoreModel — Type
ShrinkingCoreModel()Shrinking Core Model for supercritical fluid extraction (Moreno-Pulido et al., 2026).
The model describes diffusion-limited leaching from a spherical solid particle whose extractable core shrinks as solute is removed. The pseudo-steady-state (PSS) analytical solution relates the core radius $s$ to non-dimensional time via
\[\frac{s^3 - 1}{3} - \frac{s^2 - 1}{2} - \frac{s - 1}{T_m} = t\]
Two fitted parameters:
Tm— Thiele modulus $T_m = R k / D$ (—)tau_g— growth time-scale $\tau_g$ (s), used to convert experimental time to non-dimensional time: $t = t_{\mathrm{dim}} / \tau_g$
SFEModeling.Esquivel — Type
Esquivel()Single-exponential model (Esquível & Bernardo-Gil, 1999):
\[m_e(t) = m_{total}\,(1 - e^{-k_1 t})\]
One fitted parameter: k1 — rate constant (1/s).
SFEModeling.Zekovic — Type
Zekovic()Two-parameter accessible-fraction model (Žeković et al., 2003):
\[m_e(t) = m_{total}\, k_1\,(1 - e^{-k_2 t})\]
Two fitted parameters: k1 — accessible yield fraction (—); k2 — rate constant (1/s).
SFEModeling.PKM — Type
PKM()Parallel-kinetics model (Fiori et al., 2012):
\[m_e(t) = m_{total}\left[k_1(1 - e^{-k_2 t}) + (1-k_1)(1 - e^{-k_3 t})\right]\]
Three fitted parameters: k1 — easily accessible fraction (—); k2 — fluid-phase rate constant (1/s); k3 — solid-phase rate constant (1/s).
SFEModeling.SplineModel — Type
SplineModel()Piecewise-linear CER/FER/DC model:
- CER phase (0 ≤ t ≤ k₂): $m_e = m_{total}\,k_1\,t$
- FER phase (k₂ < t ≤ k₄): $m_e = m_{CER} + m_{total}\,k_3\,(t - k_2)$
- DC phase (t > k₄): $m_e = m_{FER}$ (constant)
Four fitted parameters: k1 — CER rate (1/s); k2 — CER end time (s); k3 — FER rate (1/s); k4 — FER end time (s).
Output
SFEModeling.ModelFitResult — Type
ModelFitResult{M<:ExtractionModel}Result of fitting kinetic model M to one or more extraction curves.
All models return a ModelFitResult{M}.
Common fields
model: the fitted model instanceycal::Vector{Vector{Float64}}: calculated extraction curves (kg), one per input curveobjective::Float64: sum of squared residuals (SSR) at the optimum
Sovová-specific properties (accessed via result.field)
kya, kxa, xk_ratio, xk, tcer
Empirical-model properties (accessed via result.field)
params, spec
SFEModeling.export_results — Function
export_results(filename, result, curve)
export_results(filename, result, curves)Export fitting results to a file. The format is inferred from the extension:
.xlsx— Excel workbook (one sheet per curve). Parameters occupy columns A–B; the data table (time, experimental replicates, calculated values) starts at column C.- anything else — space-delimited text. Parameters are written as
#-comment lines (readable byTextTable), followed by the data table.
Example
result = fit_model(curve)
export_results("results.txt", result, curve)
export_results("results.xlsx", result, curve)Graphical Interface
See the GUI page.
Utilities
SFEModeling.create_shortcut — Function
create_shortcut(; location=:desktop, port=9876, name="SFEModeling")Create a launcher shortcut for the SFEModeling GUI. Supports Windows, macOS, and Linux.
Keyword arguments
location: where to install the shortcut:- Windows:
:desktop(default) or:startmenu - macOS:
:desktop(default) or:applications(/Applications) - Linux:
:desktop(default) or:applications(~/.local/share/applications)
- Windows:
port: port passed to the app (default:9876).name: shortcut name (default:"SFEModeling").
Example
using SFEModeling
create_shortcut() # desktop shortcut, default port
create_shortcut(location=:applications) # app menu entry
create_shortcut(port=8080, name="SFE Fit")