`impedanceR`

- an R package for simulating impedance spectra of equivalent circuits
This package contains a suite of functions for calculating and simulating electrical or electrochemical impedance spectra using the R programming language. The package contains functions for simulating the most common equivalent circuit elements, some convenient functions for constructing the circuits themselves, and other useful utility functions.

I used early versions of this code throughout my introduction to EIS pages to simulate equivalent circuits and create the interactive components of those pages.

For those interested, I have now released this code as a more convenient R package on GitHub, which also contains some improved functionality and additional equivalent circuit elements. This page gives some basic instructions on installation and usage.

You will need R and the `devtools`

package installed. I also recommend RStudio and the `tidyverse`

suite of add-on packages for working with data - I will use this in my examples. (The `impedanceR`

package also requires `magrittr`

which provides the pipe (`%>%`

) operator).

You can consult the R documentation (i.e., by using `?functionname`

) for more information on each specific function.

The following equivalent circuit elements and the arguments (i.e., parameters they take) are as follows:

`Z_R(R)`

- resistor

`Z_C(C, omega)`

- capacitor

`Z_L(L, omega)`

- inductor

`Z_Q(L, n, omega)`

- constant phase element

`Z_W(sigma, omega)`

- Warburg element

`Z_FLW(Z0, tau, omega)`

- Finite Length (“short”) Warburg element (FLW)

`Z_FSW(Z0, tau, omega)`

- Finite Space (“open”) Warburg element (FSW)

`Z_G(Z0, k, omega)`

- Infinite length Gerischer element

`Z_FLG(Z0, k, tau, omega)`

- Finite length Gerischer element

`trans_line(R, U, n)`

- transmission line

`para()`

- for adding any number of circuit elements in parallel

`omega_range()`

- for calculating a range of angular frequency values (necessary for all circuit elements, except resistors)

`Z_to_df()`

- convert a complex vector to a `data.frame`

of real and imaginary values

All of the equivalent circuit elements (except the resistor) take a vector of angular frequency values (`omega`

, that is, the frequency data points to be simulated) as an argument, and all output a vector of complex numbers as a result.

All the elements in the circuit need to use the same `omega`

values, so it is simplest to define these as its own variable at the start, using the `omega_range`

function:

This creates a set of values for angular frequency from 1 Hz to 10 kHz, with 12 points per decade of frequency.

Equivalent circuits can be calculated by mathematically adding them in series (with the `+`

operator) or in parallel (with the provided `para()`

function). Let’s consider a circuit with two parallel RC elements in series with each other:

We can check that the variable `a`

has the right form:

cplx [1:61] 25-0.3i 25-0.3i 25-0.4i ...

And this is the expected result - a vector of complex numbers. The provided `Z_to_df()`

function converts this to a data frame:

Re Im 1 24.99684 -0.2528585 2 24.99536 -0.3063226 3 24.99320 -0.3710783 4 24.99002 -0.4495006 5 24.98535 -0.5444561

And we can plot this (using, by convention, the negative imaginary part). If using `ggplot2`

, use the `coord_fixed()`

option to make sure that the axes are proportional!

We can also create Bode plots, but this requires adding the `omega`

variable (or frequency, which is `omega`

divided by 2π) to the data frame. I find the easiest way is to use `gather()`

from the `dplyr`

package:

and so forth.

One feature I will highlight in particular is the possibility to simulate transmission line style circuits, which are useful for example in modelling porous electrodes.

The basic function `trans_line()`

takes the form:

where in the equivalent circuit below, `R`

is the value of each individual resistor in one of the rails of the transmission line, `U`

is any other equivalent circuit unit which shorts the two rails together, and `n`

is the total number of R-U units linked together. The opposite rail has zero resistance (this is a limitation currently, I’m afraid).

So for example, we can simulate the classic de Levie transmission line as discussed in my page on diffusion resistance, where U is just a capacitor:

So now we are calculating the impedance of a transmission line where each resistor has a value of 2 Ω, the `U`

unit is a capacitor with a capacitance of 1 µF, and the total transmission line is 40 units long. If we plot this, we get:

And this result has the same shape as the finite space Warburg (FSW) element, where the Z_{0} parameter is equal to the sum of all the resistors in the rail.

Here’s a more complicated example. Let’s imagine a more complicated model where the `U`

unit in the transmission line is a modified Randles circuit (this is the sort of thing we might consider as a model for a battery electrode, for example). In 13 lines, I can simulate this equivalent circuit for several different lengths of transmission line, and make a basic plot of the data.

Give it a try! Any questions, feel free to contact me or ask in the comments below.

comments powered by Disqus