impedance: fitting electrochemical impedance spectra
Code author: Ueli Sauter, Peter Kraus
Including functions relevant for Electrochemical Impedance Spectroscopy (EIS):
evaluation of an equivalent circuit as well as the fitting of the circuit to data
(calc_circuit()
and
fit_circuit()
), and an interpolation function
to find the lowest_real_impedance()
in the data.
Functions
|
Calculates the complex impedance \(\text{Re}(Z)\) and \(-\text{Im}(Z)\) of the prescribed equivalent circuit as a function of frequency \(f\). |
|
Fits an equivalent circuit to the frequency-resolved EIS data. |
|
A function that finds and interpolates the lowest \(\text{Re}(Z)\) value at which the complex impedance \(Z = \text{Re}(Z) - j \text{Im}(Z)\) is a real number (i.e. \(\text{Im}(Z) \approx 0\)). |
Note
The functions in this module expect the whole EIS trace as input - the
\(\text{Re}(Z)\), \(-\text{Im}(Z)\) and \(f\) are expected to
be pint.Quantity
containing an np.ndarray
(or similar
list
-like object), which is then processed to a (set of) scalar
values. This means that for processing time resolved data, the functions
in this module have to be called on each timestep individually.
- dgpost.transform.impedance.fit_circuit(real: Quantity, imag: Quantity, freq: Quantity, circuit: str, initial_values: dict[str, float], fit_bounds: dict[str, tuple[float, float]] = None, fit_constants: list[str] = None, ignore_neg_res: bool = True, upper_freq: float = inf, lower_freq: float = 0, repeat: int = 1, output: str = 'fit_circuit') dict[str, int | str | Quantity]
Fits an equivalent circuit to the frequency-resolved EIS data.
For the fitting an equivalent circuit is needed, defined as a
str
. The circuit may be composed of multiple circuit elements. To combine elements in a series a dash (-
) is used. Elements in parallel are wrapped byp( , )
. An element is defined by an identifier (usually letters) followed by a digit. Already implemented elements are located in thecircuit_utils.circuit_components
module:Name
Symbol
Parameters
Bounds
Units
Resistor
R
R
(1e-6, 1e6)
Ω
Capacitance
C
C
(1e-20, 1)
F
Constant Phase Element
CPE
CPE_Q
(1e-20, 1)
Ω⁻¹sᵃ
CPE_a
(0, 1)
Warburg element
W
W
(0, 1e10)
Ω⁻¹s¹ᐟ²
Warburg short element
Ws
Ws_R
(0, 1e10)
Ω
Ws_T
(1e-10, 1e10)
s
Warburg open element
Wo
Wo_R
(0, 1e10)
Ω
Wo_T
(1e-10, 1e10)
s
Additionally an initial guess for the fitting parameters is needed. The initial guess is given as a
dict
where each key is the parameter name and the corresponding value is the initial value for the circuit.The bounds of each parameter can be customized by the
fit_bounds
parameter. This parameter is adict
, where each key is the parameter name and the value consists of atuple
for the lower and upper bound (lb, ub).To hold a parameter constant, add the name of the parameter to a
list
and pass it asfit_constants
- Parameters:
real – A
pint.Quantity
object containing the real part of the impedance data, \(\text{Re}(Z)\). The unit of the provided gets converted to ‘Ω’.imag – A
pint.Quantity
object containing the imaginary part of the impedance data, \(-\text{Im}(Z)\). The unit of the provided gets converted to ‘Ω’.freq – A
pint.Quantity
object containing the frequency \(f\) of the impedance data. The unit of the provided data should gets converted to ‘Hz’.circuit – A
str
description of the equivalent circuit.initial_values – A
dict
with the initial (guess) values. Structure: {“param name”: value, … }output – A
str
prefixfit_bounds – Custom bounds for a parameter if default bounds are not wanted Structure: {“param name”: (lower bound, upper bound), …} Default is ‘’None’’
fit_constants – list of parameters which should stay constant during fitting Structure: [“param name”, …] Default is ‘’None’’
ignore_neg_res – ignores impedance values with a negative real part
upper_freq – upper frequency bound to be considered for fitting
lower_freq – lower frequency bound to be considered for fitting
repeat – how many times
fit_routine
gets called
- Returns:
- A tuple containing two dicts.
parameters, contains all the values of the parameters accessible by their names
units, contains all the units of the parameters accessible by their names
- Return type:
(parameters, units)
- dgpost.transform.impedance.calc_circuit(freq: Quantity, circuit: str, parameters: dict[str, float], output: str = 'calc_circuit') tuple[dict[str, float], dict[str, str]]
Calculates the complex impedance \(\text{Re}(Z)\) and \(-\text{Im}(Z)\) of the prescribed equivalent circuit as a function of frequency \(f\).
- Parameters:
freq – A
pint.Quantity
containing the frequencies \(f\) at which the equivalent circuit is to be evaluated. The provided data should be in “Hz”.circuit – A
str
description of the equivalent circuit. For more details seefit_circuit()
.parameters – A
dict
containing the values defining the equivalent circuit. Structure: {“param name”: value, … }output – A
str
prefix for theRe(Z)
and-Im(Z)
values calculated in this function. Defaults to"calc_circuit"
.
- Returns:
retvals – A dictionary containing the
pint.Quantity
arrays with the output-prefixed \(\text{Re}(Z)\) and \(-\text{Im}(Z)\) as keys.- Return type:
dict[str, pint.Quantity]
- dgpost.transform.impedance.lowest_real_impedance(real: Quantity, imag: Quantity, threshold: float = 0.0, output: str = 'min Re(Z)') dict[str, int | str | Quantity]
A function that finds and interpolates the lowest \(\text{Re}(Z)\) value at which the complex impedance \(Z = \text{Re}(Z) - j \text{Im}(Z)\) is a real number (i.e. \(\text{Im}(Z) \approx 0\)). If the impedance does not cross the real-zero axis, the \(\text{Re}(Z)\) at which the \(\text{abs}(\text{Im}(Z))\) is the smallest is returned.
- Parameters:
real – A
pint.Quantity
object containing the real part of the impedance data, \(\text{Re}(Z)\). The units ofreal
andimag
are assumed to match.imag – A
pint.Quantity
object containing the imaginary part of the impedance data, \(-\text{Im}(Z)\). The units ofreal
andimag
are assumed to match.output – A
str
name for the output column, defaults to"min Re(Z)"
.
- Returns:
retvals – A dictionary containing the
pint.Quantity
values of the real impedances with the output as keys.- Return type:
dict[str, pint.Quantity]