General remarks
All physical quantities are assumed to be consistently represented through their values expressed in basic SI units (m, kg, s, A, K, mol, cd), supported by the LessUnitful.jl package built on top of Unitful.jl.
Electrolyte data
LiquidElectrolytes.AbstractElectrolyteData
— Typeabstract type AbstractElectrolyteData
Abstract super type for electrolytes.
LiquidElectrolytes.ElectrolyteData
— Typemutable struct ElectrolyteData <: AbstractElectrolyteData
Data for electrolyte. It is defined using Base.@kwdef
allowing for keyword constructors like
ElectrolyteData(nc=3,z=[-1,2,1])
To see default values, just create an instance as ElectrolyteData()
. Fields (reserved fields are modified by some algorithms):
nc::Int64
: Number of ionic species.na::Int64
: Number of surface speciesiϕ::Int64
: Potential index in species list.ip::Int64
: Pressure index in species listD::Vector{Float64}
: Mobility coefficientz::Vector{Int64}
: Charge numbers of ionsM0::Float64
: Molar weight of solventM::Vector{Float64}
: Molar weights of ionsv0::Float64
: Molar volume of solventv::Vector{Float64}
: Molar volumes of ionsκ::Vector{Float64}
: Solvation numbers of ionsc_bulk::Vector{Float64}
: Bulk ion concentrationsϕ_bulk::Float64
: Bulk voltagep_bulk::Float64
: Bulk pressureΓ_bulk::Int64
: Bulk boundary numberϕ_we::Float64
: Working electrode voltage. Reserved. Used by sweep algorithms to pass boundary data.
Γ_we::Int64
: Working electrode boundary numberT::Float64
: TemperatureRT::Float64
: Molar gas constant scaled with temperatureF::Float64
: Faraday constantε::Float64
: Dielectric permittivity of solventε_0::Float64
: Dielectric permittivity of vacuumpscale::Float64
: Pressure scaling factoreneutral::Bool
: Local electroneutrality switchscheme::Symbol
: Flux caculation scheme This allows to choose between
solvepressure::Bool
: Solve for pressure.This is
true
by default. Setting this tofalse
can serve two purposes:- Take the pressure from the solution of a flow equation
- Ignore the pressure contribution to the excess chemical potential
weights::Vector{Float64}
: Species weights for norms in solver control.
edgevelocity::Union{Float64, Vector{Float64}}
: Edge velocity projection.
model::Symbol
: Electrolyte model
The default values for electrolyte data are those of an symmetric 0.1M aqueous binary electrolyte at 298.5K with solvation number κ=10, ion molar volumes and masses similar to those of water molecules and diffusion coefficients 2.0e-9 $m^2/s$. All values given in SI base units:
using LiquidElectrolytes
ElectrolyteData()
ElectrolyteData(2, 0, 3, 4, [2.0e-9, 2.0e-9], [1, -1], 0.0180153, [0.0180153, 0.0180153], 1.805054151624549e-5, [1.805054151624549e-5, 1.805054151624549e-5], [10.0, 10.0], [100.0, 100.0], 0.0, 0.0, 2, 0.0, 1, 298.15, 2478.957029602388, 96485.33212331001, 78.49, 8.8541878128e-12, 1.0e9, false, :μex, true, [1.805054151624549e-5, 1.805054151624549e-5, 1.0, 0.0], 0.0, :DGL)
LiquidElectrolytes.dlcap0
— Methoddlcap0(electrolyte)
Double layer capacitance at zero voltage for symmetric binary electrolyte.
Example
using LessUnitful
ely = ElectrolyteData(c_bulk=fill(0.01ufac"mol/dm^3",2))
round(dlcap0(ely),sigdigits=5) |> u"μF/cm^2"
# output
22.847 μF cm^-2
LiquidElectrolytes.debyelength
— Methoddebyelength(electrolyte)
Debye length.
using LessUnitful
ely = ElectrolyteData(c_bulk=fill(0.01ufac"mol/dm^3",2))
round(debyelength(ely),sigdigits=5) |> u"nm"
# output
4.3018 nm
LiquidElectrolytes.chargedensity
— Functionchargedensity(c,electrolyte)
Calculate charge density from vector of concentrations (in one grid point).
chargedensity(sol,electrolyte)
Calculate charge density vector from solution (on whole grid)
chargedensity(tsol,electrolyte)
Calculate charge densities from from time/voltage dependent solution solution (on whole grid)
LiquidElectrolytes.chemical_potential
— Function chemical_potential(c, barc, p, barv, electrolyte)
Calculate chemical potential of species with concentration c
\[ μ = \bar v(p-p_{ref}) + RT\log \frac{c}{\bar c}\]
LiquidElectrolytes.chemical_potentials!
— Functionchemical_potentials!(μ,u,electrolyte)
Calculate chemical potentials from concentrations.
Input:
μ
: memory for result (will be filled)u
: local solution vector (concentrations, potential, pressure)
Returns μ0, μ
: chemical potential of solvent and chemical potentials of ions.
using LessUnitful
ely = ElectrolyteData(c_bulk = fill(0.01ufac"mol/dm^3", 2))
μ0, μ = chemical_potentials!([0.0, 0.0], vcat(ely.c_bulk, [0, 0]), ely)
round(μ0, sigdigits = 5), round.(μ, sigdigits = 5)
# output
(-0.89834, [-21359.0, -21359.0])
This function has been corrected in version 0.3. Before it used the molar volume $v$ instead of the effective molar volume $\bar v = v + κv_0$ to calculate the ion chemical potentials. Examples with κ=0 are not affected.
LiquidElectrolytes.rrate
— Functionrrate(R0,β,A)
Reaction rate expression
rrate(R0,β,A)=R0*(exp(-β*A) - exp((1-β)*A))
LiquidElectrolytes.iselectroneutral
— Functioniselectroneutral(cx::Vector,celldata)
Check for electroneutrality of concentration vector
iselectroneutral(tsol::TransientSolution,celldata)
Check for electroneutrality of transient solution
LiquidElectrolytes.isincompressible
— Functionisincompressible(cx::Vector,celldata)
Check if the concentration vector fulfills incompressibility constraint, including the fact that the solvent concentration is nonnegative
isincompressible(tsol::TransientSolution,celldata)
Check for incompressibility of transient solution
LiquidElectrolytes.c0_barc
— Functionc0_barc(u,electrolyte)
Calculate solvent concentration $c_0$ and summary concentration $\bar c$ from vector of concentrations c
using the incompressibility constraint (assuming $κ_0=0$):
\[ \sum_{i=0}^N c_i (v_i + κ_iv_0) =1\]
This gives
\[ c_0v_0=1-\sum_{i=1}^N c_i (v_i+ κ_iv_0)\]
\[c_0= 1/v_0 - \sum_{i=1}^N c_i(\frac{v_i}{v_0}+κ_i)\]
Then we can calculate
\[ \bar c= \sum_{i=0}^N c_i\]
Poisson-Nernst-Planck system
LiquidElectrolytes.PNPSystem
— FunctionPNPSystem(grid;
celldata=ElectrolyteData(),
bcondition=(f, u, n, e)-> nothing,
reaction=(f, u, n, e)-> nothing,
kwargs...)
Create VoronoiFVM system for generalized Poisson-Nernst-Planck. Input:
grid
: discretization gridcelldata
: composite struct containing electrolyte databcondition
: boundary conditionreaction
: reactions of the bulk specieskwargs
: Keyword arguments of VoronoiFVM.System
LiquidElectrolytes.pnpunknowns
— Functionpnpunknowns(sys)
Return vector of unknowns initialized with bulk data.
LiquidElectrolytes.electrolytedata
— Functionelectrolytedata(sys)
Extract electrolyte data from system.
LiquidElectrolytes.solventconcentration
— Function solventconcentration(U::Array, electrolyte)
Calculate vector of solvent concentrations from solution array.
LiquidElectrolytes.chemical_potentials
— Functionchemical_potentials(solution, electrolyte)
Calculate chemical potentials from solution. Returns μ0, μ
, where μ0
is the vector of solvent chemical potentials, and μ
is the nc×nnodes
matrix of solute chemical potentials.
LiquidElectrolytes.electrochemical_potentials
— Functionelectrochemical_potentials(solution, electrolyte)
Calculate electrochemical potentials from solution. and return nc×nnodes
matrix of solute electrochemical potentials measured in Volts.
Poisson-Boltzmann system
LiquidElectrolytes.PBSystem
— FunctionPBSystem(grid;
celldata=ElectrolyteData(),
bcondition=(f, u, n, e)-> nothing,
kwargs...)
Create VoronoiFVM system generalized Poisson-Boltzmann. Input:
grid
: discretization gridcelldata
: composite struct containing electrolyte databcondition
: boundary conditionkwargs
: Keyword arguments of VoronoiFVM.System
Poisson-Nernst-Planck-Stokes system
LiquidElectrolytes.PNPStokesSolver
— Typestruct PNPStokesSolver{Tflow, Tpnp}
Stokes solver struct.
flowsolver::Any
pnpsolver::Any
Utilities
LiquidElectrolytes.RLog
— TypeRLog(eps)
Callable struct for regularized logarithm. Smooth linear continuation for x<eps
. This means we can calculate a "logarithm" of a small negative number. Objects mylog::RLog
of this type are meant to replace the logarithm function and allow to invoke mylog(x)
.
LiquidElectrolytes.rlog
— Functionrlog(x::Any)
Logarithm function used in LiquidElectrolytes.jl. Calls Base.log
by default.
This can be overwritten by defining e.g, LiquidElectrolytes.rlog(x::Number)=mylog(x)
where mylog=RLog()
.
LiquidElectrolytes.RExp
— TypeRExp(trunc)
Callable struct for regularized exponential. Linear continuation for x>trunc
, returns 1/rexp(-x) for x<-trunc
. Objects myexp::RExp
of this type are meant to replace the exponential function and allow to invoke myexp(x)
.
LiquidElectrolytes.rexp
— Functionrexp(x::Any)
Exponential function used in LiquidElectrolytes.jl. Calls Base.exp
by default.
This can be overwritten by defining e.g, LiquidElectrolytes.rexp(x::Number)=myexp(x)
where myexp=RExp()
.