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, imag, freq, circuit, initial_values, fit_bounds=None, fit_constants=None, ignore_neg_res=True, upper_freq=inf, lower_freq=0, repeat=1, output='fit_circuit')
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_componentsmodule:Name
Symbol
Parameters
Bounds
Units
Resistor
RR(1e-6, 1e6)
Ω
Capacitance
CC(1e-20, 1)
F
Constant Phase Element
CPECPE_Q(1e-20, 1)
Ω⁻¹sᵃ
CPE_a(0, 1)
Warburg element
WW(0, 1e10)
Ω⁻¹s¹ᐟ²
Warburg short element
WsWs_R(0, 1e10)
Ω
Ws_T(1e-10, 1e10)
s
Warburg open element
WoWo_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
dictwhere 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_boundsparameter. This parameter is adict, where each key is the parameter name and the value consists of atuplefor the lower and upper bound (lb, ub).To hold a parameter constant, add the name of the parameter to a
listand pass it asfit_constants- Parameters:
real (
Quantity) – Apint.Quantityobject containing the real part of the impedance data, \(\text{Re}(Z)\). The unit of the provided gets converted to ‘Ω’.imag (
Quantity) – Apint.Quantityobject containing the imaginary part of the impedance data, \(-\text{Im}(Z)\). The unit of the provided gets converted to ‘Ω’.freq (
Quantity) – Apint.Quantityobject containing the frequency \(f\) of the impedance data. The unit of the provided data should gets converted to ‘Hz’.circuit (
str) – Astrdescription of the equivalent circuit.initial_values (
dict[str,float]) – Adictwith the initial (guess) values. Structure: {“param name”: value, … }output (
str) – Astrprefixfit_bounds (
Optional[dict[str,tuple[float,float]]]) – Custom bounds for a parameter if default bounds are not wanted Structure: {“param name”: (lower bound, upper bound), …} Default is ‘’None’’fit_constants (
Optional[list[str]]) – list of parameters which should stay constant during fitting Structure: [“param name”, …] Default is ‘’None’’ignore_neg_res (
bool) – ignores impedance values with a negative real partupper_freq (
float) – upper frequency bound to be considered for fittinglower_freq (
float) – lower frequency bound to be considered for fittingrepeat (
int) – how many timesfit_routinegets 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, circuit, parameters, output='calc_circuit')
Calculates the complex impedance \(\text{Re}(Z)\) and \(-\text{Im}(Z)\) of the prescribed equivalent circuit as a function of frequency \(f\).
- Parameters:
freq (
Quantity) – Apint.Quantitycontaining the frequencies \(f\) at which the equivalent circuit is to be evaluated. The provided data should be in “Hz”.circuit (
str) – Astrdescription of the equivalent circuit. For more details seefit_circuit().parameters (
dict[str,float]) – Adictcontaining the values defining the equivalent circuit. Structure: {“param name”: value, … }output (
str) – Astrprefix for theRe(Z)and-Im(Z)values calculated in this function. Defaults to"calc_circuit".
- Returns:
retvals – A dictionary containing the
pint.Quantityarrays 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, imag, threshold=0.0, output='min Re(Z)')
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 (
Quantity) – Apint.Quantityobject containing the real part of the impedance data, \(\text{Re}(Z)\). The units ofrealandimagare assumed to match.imag (
Quantity) – Apint.Quantityobject containing the imaginary part of the impedance data, \(-\text{Im}(Z)\). The units ofrealandimagare assumed to match.output (
str) – Astrname for the output column, defaults to"min Re(Z)".
- Returns:
retvals – A dictionary containing the
pint.Quantityvalues of the real impedances with the output as keys.- Return type:
dict[str, pint.Quantity]