1 Introduction

Over the past decade, charge transport modelling of perovskite solar cells (PSCs) has improved to a point where it can not only qualitatively reproduce most of the observed responses of these devices to a wide variety of experimental protocols but is also close to being predictive. Nevertheless there remain challenges, not only with the formulation of the charge transport model, but also with its accurate solution in parameter regimes of interest. The first published numerical scheme capable of solving such a model in relevant parameter regimes was presented in [20], while open sourceFootnote 1 software was made available only relatively recently by Courtier et al. [19] and Calado et al. [13]. The aim of this work is to publicise and describe an updated, and improved, version of the first of these two software packages.

The original version of the perovskite solar cell (PSC) simulation tool IonMonger [19] has been successfully used by numerous groups to simulate charge transport and cell performance in these devices. The main goal of the continuum models that IonMonger solves is to improve the understanding of PSCs and to predict device behaviour from its underlying physical properties. For example, IonMonger enables investigation of the effects of altering properties such as charge carrier diffusion lengths and recombination rates on current–voltage (or power) output. IonMonger includes a fully-coupled conservation equation for mobile ion migration in the perovskite layer of a three-layer PSC (see Fig. 1), which has been shown to play a dominant role in device behaviour [67], including steady-state performance [17, 18].

Fig. 1
figure 1

Schematic of the basic drift–diffusion model of a planar PSC upon which IonMonger v1.0 was based. The continuum variables modelled in each layer are shown. Carrier generation is assumed to occur only in the perovskite and recombination in the perovskite and at the interfaces between the perovskite and the transport layers

Simulation results obtained using IonMonger have enabled researchers to tackle a variety of questions relating to the performance and design of PSCs. Examples of such work include: (1) Cave et al. [15] demonstrated how to determine activation energies for ion vacancy migration in different perovskite compositions using the information contained in current–voltage (JV) measurements; (2) Courtier [17] used IonMonger to verify a novel theory, termed the ectypal diode theory, for the steady-state performance of a PSC, which is notable for its inclusion of mobile ions; (3) Bennett et al. [8] extended this theory to describe the electrochemical impedance response of a PSC and identify a measurable value, analogous to the ideality factor for conventional solar cells, that may be used to diagnose the limiting form of recombination; (4) Riquelme, Castro-Chong, Anta and co-workers [14, 54, 55] validated this approach by investigating trends in impedance spectra using a combination of IonMonger simulations and investigation of experimental measurements; (5) Diekmann, Le Corre, Stolterfoht and colleagues used IonMonger to study the maximum efficiencies attainable from PSCs incorporating mobile ions in the perovskite layer [23, 42], concluding that the presence of mobile ions is detrimental to power conversion efficiency (PCE); (6) Cordoba et al. [21] and Lin [45] evaluated another metric, namely the open-circuit voltage. Lin also simulated the impact of mobile ions on the short-circuit current [46]. (7) Li et al. [43] showed how ion migration can explain the light-soaking phenomenon observed in experiment [65]; and (8) García-Rodríguez et al. demonstrated that inverted hysteresis can be explained by the drift–diffusion model, comparing IonMonger simulations to experiment [27].

Despite the undoubted success of IonMonger v1.0, and its growing user base, significant issues with its performance and capabilities have been brought to our attention by its early users; these have motivated the improvements to the numerical solver described in this work. Chief amongst the issues identified, and addressed here, are problems with the stability of the code. In addition to performance issues the validity of the Boltzmann model for charge carrier dynamics in the transport layers (particularly where these are composed of organic materials) has been called into question. This has motivated an extension to IonMonger which allows for non-Boltzmann models of the transport layer charge carrier dynamics. From a practical perspective, many experiments are performed with white light and therefore IonMonger v2.0 incorporates a model of charge carrier generation based on multiple wavelength illumination. Furthermore, adapting IonMonger v1.0 to simulate impedance experiments is cumbersome and so version 2.0 includes a module that allows impedance plots to be generated automatically and efficiently.

A development cycle similar to IonMonger’s is being carried out to great effect in the field of lithium-ion battery modelling, by the PyBaMM community [34, 59]. This builds upon collaborations both within academia and between academia and industry in order to accelerate R &D and serves as a model for the future path of IonMonger. In order to progress towards the ultimate goal of developing stable and commercially viable PSCs, further advances in our understanding of the interplay between ionic and electronic mechanisms, including their effects on degradation, are required. It is envisaged that this goal can be furthered by providing sophisticated and easy-to-use open-source modelling tools [61]. As such, IonMonger 2.0 includes a host of advanced features along with a new user-friendly interface.

Table 1 A list of the model extensions offered as part of IonMonger 2.0 and the additional functions or parameters that must be specified to use each extension

Favourable comparisons have been made between IonMonger 1.0 and alternative simulation software such as Driftfusion [13], SCAPS (without mobile ions) [23] and a Python implementation of the IonMonger model [6]. As a consensus has not yet been reached on the correct model of charge transport in PSCs, it is vital that simulation software is open source to allow users to investigate the many proposed extensions to the model. The code presented in this paper, therefore is, to our knowledge, the most advanced open-source software for the simulation of charge transport and ion migration in standard three-layer planar PSCs available to-date.

Fig. 2
figure 2

a A schematic of a planar perovskite solar cell (PSC) with new additions to the IonMonger charge transport model labelled by green arrows. b A circuit representation for a PSC with series and shunt resistance. Here, the circle labelled “PSC” is used as a symbol for the current–voltage (\(J\)\(V\)) relation determined from a charge transport model for the motion of electrons, holes and halide ion vacancies in a PSC (Color figure online)

In the next section, Sect. 2, we introduce the impedance spectroscopy module, outlining its features and giving a cursory introduction to its use in practice (a full set of instructions are given in the users’ guide). Subsequently, in Sect. 3, we describe how the charge transport model has been extended to incorporate non-Boltzmann statistical models in the description of the transport layers. In Sect. 4, we discuss how steric effects have been accounted for in the equations defining the ion vacancy flux. The purpose of Sect. 5 is to introduce the remaining extensions to the charge transport model, namely; generation from light comprising a spectrum of wavelengths, Auger recombination, immobile ion distributions, parasitic series and shunt resistances (by embedding the charge transport model within an equivalent circuit), and metal contact band offsets. In Sect. 6, an introduction to IonMonger Lite is given. The penultimate section, Sect. 7, includes details of the improved numerical methods which give rise to better code performance, and how backwards compatibility with IonMonger 1.0 has been ensured. In Sect. 8 we draw our conclusions.

A complete statement of the charge transport model (system of PDEs) being solved in IonMonger 2.0 is given in “Appendix”. A schematic diagram showing the new additions to the model is shown in Fig. 2 and these additions are listed in Table 1.

2 Impedance spectroscopy module

Electrochemical impedance spectroscopy (IS) is a measurement technique that is widely used in the study of electrochemical systems [51]; including in batteries [44, 63] and fuel cells [32], where it is used to study corrosion and plating [38] and solar cells [8, 53, 54, 56] where it can be used to identify efficiency and monitor degradation. It is a particularly useful technique as it is non-destructive and relatively easy to perform both in the lab and in the field. In the context of PSCs, the interpretation of results is still relatively poorly understood, because of the novel complicating feature of ion motion, in addition to charge carrier motion. This motivates the need for accurate impedance simulations from a well-founded drift–diffusion model of the cell.

IS is performed by perturbing a device from steady state by applying a low-amplitude voltage oscillation (over a range of frequencies) and measuring the current response. This elicits valuable information due to the different physical processes stimulated at different frequencies, allowing their effects to be disentangled. The applied voltage typically consists of a constant (or ‘DC’) component and a sinusoidal (or ‘AC’) component,

$$\begin{aligned} V(t) = V_\text {DC} + V_\textrm{p} \sin (\omega t), \end{aligned}$$
(1)

where \(V_\text {DC}\) is the steady-state voltage, and \(V_\textrm{p}\) and \(\omega\) are the amplitude and the angular frequency of the voltage perturbation, respectively. Keeping the amplitude of the voltage perturbation small (here, typically, \(<20\) mV) ensures that the current response is an approximately linear function of the applied voltage, taking the general form

$$\begin{aligned} J(t) = J_\text {DC} + J_{p}(\omega ) \sin (\omega t - \theta (\omega )), \end{aligned}$$
(2)

where \(J_\text {DC}\) is the steady-state current, \(J_{p}\) is the amplitude of the sinusoidal component and \(\theta\) is the phase relative to the voltage. The complex impedance, \(Z(\omega )\), is the ratio between the complex representation of the voltage perturbation and that of the current, i.e.

$$\begin{aligned} Z(\omega ) = \frac{V_\textrm{p}}{J_{p}(\omega )}\, e^{i \theta (\omega )}. \end{aligned}$$
(3)
Fig. 3
figure 3

Decomposition of complex impedance into real and imaginary components with projections onto each of the three planes

A so-called impedance spectrum (i.e. the impedance as a function of frequency, f) is shown in Fig. 3. It is common to decompose the impedance into its real and imaginary components; i.e. the resistance R and the reactance X, respectively, such that \(Z(\omega ) = R(\omega ) + iX(\omega )\). The projection of a complex impedance curve onto the R-X plane forms a Nyquist plot, as shown in Fig. 4a. Nyquist plots restrict the frequency information that is displayed. Therefore, it is useful to display impedance spectra as their projection into the R-f and X-f planes, referred to here as frequency plots (Fig. 4b). Other representations of impedance such as Bode or capacitance plots can also be used to explicitly show the frequency dependence.

Generally, the impedance spectra of PSCs exhibit two semicircles on a Nyquist plot, one low- and one high-frequency feature. The two features indicate that there are (at least) two species of mobile charge (electronic charges and ionic charges) in a typical PSC [8, 53, 54]. The high-frequency feature excludes the transient effects of the slow-moving ionic charge and enables information to be obtained about the sources of electron and hole recombination (via the electronic ideality factor as defined in Bennett et al. [8]). The low-frequency feature captures how ions impact the cell response and provides information on the potential barrier to recombination (via the ectypal factor as defined in [17]) as well as the density and mobility of the ionic species [8, 54]. In addition to the low- and high-frequency features, other features have been observed in the Nyquist plots of impedance spectra for PSCs. For example, these include a third semicircle [5, 28] or a loop between the low- and high-frequency features [24, 31]. These less common features observed in experiment are reproduced by IonMonger for particular parameter regimes.

2.1 Simulating impedance spectra

IonMonger allows users to perform virtual IS measurements analogous to those performed by experiment. The voltage protocol is created via the applied_voltage input specified in the parameters file. An impedance simulation consists of the following steps. First, the cell is allowed to equilibrate at the DC voltage, thereby locating steady-state. IonMonger autonomously detects when the steady-state solution has been reached. This solution is then used as initial conditions for the transient stimulation at each different frequency. IonMonger then iterates over all sample frequencies, simulating the response to each voltage perturbation. Thus, an impedance protocol can be specified by six parameters: the minimum and maximum frequencies, the DC applied voltage, the AC voltage amplitude, the number of frequencies to be sampled and the number of complete periods to simulate. Detailed information on how to construct an impedance protocol from these six parameters can be found in the user guide (GUIDE.md).

Fig. 4
figure 4

a Nyquist and b frequency plots calculated using the template parameter set

The resulting structure array of solutions (one for each frequency) is passed to impedance_analysis.m to compute the impedance as a function of frequency. This is achieved by extracting the final two periodic cycles of the current density (at each frequency) and fitting a sinusoid to the data using FourierFit.m.

IS simulations are computed using the same numerical solver as transient simulations, meaning they not only achieve the same speed and accuracy, but are also fully compatible with additions to the charge transport model (detailed in Sects. 3, 4, 5). If MATLAB’s Parallel Computing toolbox is installed, the iterations will be executed on multiple parallel workers, decreasing the compute time. The impedance spectra shown in Fig. 4, are each made up of 100 sample frequencies and took an average time of 48.7s to compute on a desktop computer with a six-core Ryzen 5 5600X CPU. Functions for plotting IS simulations are detailed in Sect. 7.3.

3 Carrier statistics in the transport layers

In previous versions of IonMonger, electronic carriers in all three layers were assumed to follow Boltzmann statistics, as is common in semiconductor modelling. However, this assumption, in the context of PSCs, has been called into question by recent works [2, 61]. It is known that this assumption is not justified in the case of highly doped and/or organic materials, such as the transport layers [4, 33, 60]. To rectify this, IonMonger now allows carriers to be governed by more general band models, with the option of either a Fermi–Dirac or Boltzmann distribution. In this section we discuss the physical origin of statistical models and the specific options available in IonMonger 2.0 (see Table 2).

3.1 General statistical models

The density of free conduction electrons in a semiconductor is the product of the statistical distribution, f(E), and the conduction band density of states (DoS), \({\hat{g}}_\textrm{c}(E)\), integrated across all energies, i.e.

$$\begin{aligned} n = \int _{-\infty }^\infty f(E) {\hat{g}}_\textrm{c}(E) \textrm{d}E. \end{aligned}$$
(4)

Similarly, the density of valence band holes is

$$\begin{aligned} p = \int _{-\infty }^\infty (1-f(E)) {\hat{g}}_\textrm{v}(E) \textrm{d}E. \end{aligned}$$
(5)

These integrals (referred to as statistical integrals) define a relationship between carrier densities and quasi-Fermi levels. As Fermions, electrons adhere to a Fermi–Dirac statistical distribution [48], defined as

$$\begin{aligned} f(E) = \frac{1}{\exp \left( \frac{E-E_\textrm{f}}{k_BT}\right) +1}, \end{aligned}$$
(6)

where \(E_\textrm{f}\) is the Fermi level. In semiconductor modelling, it is common to approximate f(E) by a Boltzmann distribution [25, 30, 35, 37, 40, 61], and assume that the DoS is parabolic, resulting in the familiar densities

$$\begin{aligned} n&= g_\textrm{c} \, \exp \left( \frac{E_{\textrm{f}_n}-E_{\textrm{c}}}{k_BT} \right) , \end{aligned}$$
(7)
$$\begin{aligned} p&= g_\textrm{v} \, \exp \left( - \frac{E_{\textrm{f}_{p}} - E_\textrm{v}}{k_BT} \right) , \end{aligned}$$
(8)

where \(g_{\textrm{c},\textrm{v}}\) are the effective densities of states for the conduction and valence bands, respectively, \(E_{\textrm{f}_{n,p}}\) are the electron and hole quasi-Fermi levels (QFLs), and \(E_{\textrm{c},\textrm{v}}\) are band edges. This is known as the Boltzmann approximation. Employing a statistical integral that is analytical, differentiable and invertible results in drift–diffusion equations that are significantly easier to solve, leading to widespread adoption of the Boltzmann approximation in semiconductor modelling, including the charge transport model upon which previous versions of IonMonger were based.

However, the Boltzmann distribution fails as an approximation to the Fermi–Dirac distribution in the case of materials with high doping levels and/or non-parabolic band shapes, motivating a more general approach. Carrier densities in a general statistical model are given by [29]

$$\begin{aligned} n&= g_\textrm{c} \, {\mathcal {S}}\left( \frac{E_{\textrm{f}_n}-E_{\textrm{c}}}{k_BT} \right) , \end{aligned}$$
(9a)
$$\begin{aligned} p&= g_\textrm{v} \, {\mathcal {S}}\left( - \frac{E_{\textrm{f}_{p}} - E_\textrm{v}}{k_BT} \right) ,\end{aligned}$$
(9b)

where \({\mathcal {S}}\) is the statistical integral. The energies \(E_\textrm{c}\) and \(E_\textrm{v}\) will henceforth be referred to as reference energies to account for DoS functions that do not possess the same defined edge as parabolic bands.

Electron and hole currents in a semiconductor are driven by gradients in their quasi-Fermi levels, meaning the current densities are defined as

$$\begin{aligned} j^n&= \mu _n n \frac{\partial }{\partial x} E_{\textrm{f}_n},&j^p&= \mu _{p} p \frac{\partial }{\partial x} E_{\textrm{f}_{p}}, \end{aligned}$$
(10)

where \(\mu _n\) and \(\mu _{p}\) are the electron and hole mobilities, respectively. By rearranging (9), the quasi-Fermi levels can be written as functions of carrier density,

$$\begin{aligned} E_{\textrm{f}_n}&= E_{\textrm{c}} + k_BT {\mathcal {S}}^{-1} \left( \frac{n}{g_\textrm{c}} \right) , \end{aligned}$$
(11a)
$$\begin{aligned} E_{\textrm{f}_{p}}&= E_\textrm{v} - k_BT {\mathcal {S}}^{-1} \left( \frac{p}{g_\textrm{v}} \right) , \end{aligned}$$
(11b)

where \({\mathcal {S}}^{-1}\) is the inverse of \({\mathcal {S}}\) such that \({{\mathcal {S}}\big ( {\mathcal {S}}^{-1} (\cdot ) \big ) \equiv \cdot }\). The reference energies, \(E_{\textrm{c},\textrm{v}}\), are dependent on the local electric potential, leading to the phenomenon known as band-bending. Specifically, we assume that the reference energies take the form \(E_{\textrm{c},\textrm{v}} = \text {const.} - q \phi\). Combined with (11), this allows one to express the electronic current densities as functions of carrier density and electric potential,

$$\begin{aligned} {j^n}&= \mu _nk_BTn\frac{\partial }{\partial x} \left[ {\mathcal {S}}^{-1}\left( \frac{n}{g_\textrm{c}}\right) - \frac{q\phi }{k_BT}\right] \end{aligned}$$
(12)
$$\begin{aligned} {j^p}&= -\mu _{p}k_BTp\frac{\partial }{\partial x} \left[ {\mathcal {S}}^{-1}\left( \frac{p}{g_\textrm{v}}\right) + \frac{q\phi }{k_BT}\right] . \end{aligned}$$
(13)

Note that if carriers are assumed to be Boltzmann distributed in parabolic bands, the statistical integral is simply \({\mathcal {S}}(\cdot ) = \exp (\cdot )\) and the familiar expressions for current density,

$$\begin{aligned} {j^n}&= \mu _n k_BT \left[ \frac{\partial n}{\partial x} - \frac{qn}{k_BT} \frac{\partial \phi }{\partial x} \right] , \end{aligned}$$
(14)
$$\begin{aligned} {j^p}&= -\mu _{p} k_BT \left[ \frac{\partial p}{\partial x} + \frac{qp}{k_BT} \frac{\partial \phi }{\partial x} \right] , \end{aligned}$$
(15)

are recovered.

3.2 Statistical models in the PSC model

Carrier densities in the transport layers (TLs) of PSCs are typically several orders of magnitude larger than in the perovskite layer due to high effective doping levels and the band offsets between the layers. For this reason, the Boltzmann approximation cannot be guaranteed to be accurate in these layers and we adapt the charge transport model to allow for some general (possibly non-Boltzmann) statistical model. We assume that conduction electrons in the electron transport layer (ETL) are described by some statistical integral \({\mathcal {S}}_\textrm{E}\) and valence holes in the hole transport layer (HTL) by \({\mathcal {S}}_\textrm{H}\). Thus the equations for current densities in the transport layers must be updated to reflect the choice of statistical model. We now have

$$\begin{aligned} {j^n}= \mu _\textrm{E} k_BT n \frac{\partial }{\partial x} \left[ {\mathcal {S}}_\textrm{E}^{-1}\left( \frac{n}{g_\textrm{c}^\textrm{E}}\right) - \frac{q\phi }{k_BT}\right] \end{aligned}$$
(16)

in the ETL and

$$\begin{aligned} {j^p}= -\mu _\textrm{H} k_BT p \frac{\partial }{\partial x} \left[ {\mathcal {S}}_\textrm{H}^{-1}\left( \frac{p}{g_\textrm{v}^\textrm{H}}\right) + \frac{q\phi }{k_BT}\right] \end{aligned}$$
(17)

in the HTL.

The generalised statistical models necessitate that continuity conditions at the edges of the transport layers must be reconsidered. As in previous versions of the model [19], we enforce that the majority carriers’ QFLs are continuous across the interfaces between transport layers and the perovskite, \(E_{\textrm{f}_n}|_{x=0^-} = E_{\textrm{f}_n}|_{x=0^+}\) and \(E_{\textrm{f}_{p}}|_{x=b^-} = E_{\textrm{f}_{p}}|_{x=b^+}\). Using expressions for the QFLs in Boltzmann models (7), (8) in the perovskite and general statistical models (11) in the transport layers, we obtain the continuity conditions

$$\begin{aligned} n|_{x=0^+}&= g_\textrm{c} \exp \left[ \frac{E_\textrm{c}^\textrm{E}-E_\textrm{c}}{k_BT} + {\mathcal {S}}_\textrm{E}^{-1}\left( \frac{n|_{x=0^-}}{g_\textrm{c}}\right) \right] , \end{aligned}$$
(18)
$$\begin{aligned} p|_{x=b^-}&= g_\textrm{v} \exp \left[ \frac{E_\textrm{v}-E_\textrm{v}^\textrm{H}}{k_BT} + {\mathcal {S}}_\textrm{H}^{-1}\left( \frac{p|_{x=b^+}}{g_\textrm{v}^\textrm{H}}\right) \right] , \end{aligned}$$
(19)

where a superscript ‘\(+\)’ denotes a quantity on the right hand side of an interface and ‘−’ the left hand side. The ratios of carrier densities either side of the interfaces when the cell is in equilibrium with no potential difference across it are therefore

$$\begin{aligned}&k_\textrm{E} = \frac{g_\textrm{c}}{d_\textrm{E}} \exp \left[ \frac{E_\textrm{c}^\textrm{E}-E_\textrm{c}}{k_BT} + {\mathcal {S}}_\textrm{E}^{-1}\left( \frac{d_\textrm{E}}{g_\textrm{c}^\textrm{E}}\right) \right] , \end{aligned}$$
(20a)
$$\begin{aligned}&k_H = \frac{g_\textrm{v}}{d_H} \exp \left[ \frac{E_\textrm{v}-E_\textrm{v}^\textrm{H}}{k_BT} + {\mathcal {S}}_\textrm{H}^{-1}\left( \frac{d_H}{g_\textrm{v}^\textrm{H}}\right) \right] , \end{aligned}$$
(20b)

and we recast the continuity conditions in terms of these ratios as

$$\begin{aligned} n|_{x=0^+} = d_\textrm{E} k_\textrm{E} \exp \left[ {\mathcal {S}}_\textrm{E}^{-1} \left( \frac{n|_{x=0^-}}{g_\textrm{c}^\textrm{E}}\right) - {\mathcal {S}}_\textrm{E}^{-1} \left( \frac{d_\textrm{E}}{g_\textrm{c}^\textrm{E}}\right) \right] , \ \end{aligned}$$
(21)
$$\begin{aligned} p|_{x=b^-} = d_H k_H \exp \left[ {\mathcal {S}}_\textrm{H}^{-1} \left( \frac{p|_{x=b^+}}{g_\textrm{v}^\textrm{H}}\right) - {\mathcal {S}}_\textrm{H}^{-1} \left( \frac{d_H}{g_\textrm{v}^\textrm{H}}\right) \right] . \end{aligned}$$
(22)

This concludes the changes required to incorporate the option of simulating non-Boltzmann statistics in IonMonger. In the next section we describe the common statistical models that are built-in to IonMonger 2.0.

3.3 Available statistical models

In IonMonger 2.0, the user can choose statistical models from three possible band shapes, with either Fermi–Dirac or Boltzmann distributions, to apply to majority carriers in the transport layers. Note that statistical models, determined by the combination of a statistical distribution and a band shape, are commonly given names, summarised in Table 2. The two transport layers can be assigned different statistical models. Model parameters are used to create reference functions which enable quick and accurate evaluation of the statistical function and its inverse.

Table 2 Available statistical models determined by choices of statistical distribution f(E) and band shape \({\hat{g}}_{\textrm{c},\textrm{v}}(E)\)

Note that users who do not wish to make use of alternative statistical models can simply remove the ‘stats’ structure from the parameter file. In its absence, IonMonger will automatically employ Boltzmann distributions in parabolic bands, as was the case in previous versions of the software. For more information about specifying statistical models in simulations, see the user guide (GUIDE.md).

Users also have the option of creating their own statistical models by editing the create_stats_funcs.m file which serves as a template.

3.3.1 The parabolic model

The parabolic band model (shown in Fig. 5a) originates from a Taylor expansion of the dispersion relation near a turning point (see [48] §3.3.5). This Taylor expansion describes the DoS near the edges of the bands (where most carriers exist). This model is usually considered accurate in the case of ordered crystalline semiconductors (typically inorganic).

Fig. 5
figure 5

The parabolic statistical integral. a The parabolic DoS functions for the two bands where the reference energies are the band edges, located at \(E_\textrm{c}=-3.9\) eV and \(E_\textrm{v}=-5.1\) eV, and the effective DoS are \(g_\textrm{c}=g_\textrm{v}=10^{25}\) m\(^{-3}\). b The statistical integral versus dimensionless quasi-Fermi level. The solid blue line corresponds to Fermi–Dirac statistics and the dashed red line corresponds to the Boltzmann approximation. The pink shaded area is the region in which the Boltzmann approximation is commonly considered accurate (\(\xi <-3\)) (Color figure online)

The parabolic band structure is defined by the DoS functions

$$\begin{aligned} {\hat{g}}_\textrm{c}(E)&= {\left\{ \begin{array}{ll} 0 &{}\quad E<E_\textrm{c}\\ \displaystyle \frac{2g_\textrm{c}}{\sqrt{\pi }} \frac{1}{k_BT} \sqrt{\frac{E-E_\textrm{c}}{k_BT}} &{}\quad E \ge E_\textrm{c} \end{array}\right. } \end{aligned}$$
(23a)
$$\begin{aligned} {\hat{g}}_\textrm{v}(E)&= {\left\{ \begin{array}{ll} 0 &{}\quad E>E_\textrm{v}\\ \displaystyle \frac{2g_\textrm{v}}{\sqrt{\pi }} \frac{1}{k_BT} \sqrt{\frac{E_\textrm{v}-E}{k_BT}} &{}\quad E \le E_\textrm{v}. \end{array}\right. } \end{aligned}$$
(23b)

The conduction and valence bands have defined edges, denoted by \(E_\textrm{c}\) and \(E_\textrm{v}\), respectively. These are the reference energies. Under a Fermi–Dirac distribution, the statistical integral, often (somewhat confusingly) referred to as the Fermi–Dirac integral, is defined to be

$$\begin{aligned} {\mathcal {F}}(\xi ) = \int _0^\infty \frac{2}{\sqrt{\pi }} \frac{\sqrt{\eta }}{1+ \exp (\eta -\xi )} \textrm{d}\eta , \end{aligned}$$
(24)

where \(\xi\) and \(\eta\) are the dimensionless quasi-Fermi level and state energy, respectively, where both are relative to the band’s reference energy and measured in units of the thermal voltage. This function is plotted in Fig. 5b. To clarify the nomenclature, the Fermi–Dirac distribution is the statistical distribution obeyed by all Fermions and the Fermi–Dirac integral is the statistical integral to which only Fermions in parabolic bands adhere.

As discussed in the previous section, if carrier densities are approximated by a Boltzmann distribution, the statistical integral becomes \({\mathcal {S}}(\xi ) = \exp (\xi )\). Both the Fermi–Dirac integral and its Boltzmann approximation are shown in Fig. 5b. It is generally accepted that the Boltzmann approximation to the Fermi–Dirac integral is accurate for quasi-Fermi levels more than three thermal voltages from the band edge (or densities \(n<\frac{g_\textrm{c}}{20}\)) [3].

3.3.2 The Gaussian model

Weak molecular bonds in organic materials create a disordered structure in which electron transport takes the form of hopping between discrete molecular sites; this is in contrast to the band transport in ordered crystalline materials. For a system with a large number of molecules, this hopping transport resembles band transport in a Gaussian band [11, 22, 50, 60] where the width of the Gaussian corresponds to the level of disorder in the intermolecular structure. The Gaussian band structure is shown in Fig. 6a. The bands no longer have defined edges, hence the reference energies are now the centres of each Gaussian, denoted by \(E_{\textrm{c}}\) and \(E_\textrm{v}\), respectively. In organic materials, these are commonly referred to as the lowest unoccupied molecular orbital (LUMO) and the highest occupied molecular orbital (HOMO), and denoted by \(E_\textrm{L}\) and \(E_\textrm{H}\), respectively. This model requires a further parameter, s, to describe the width of the Gaussian (corresponding to the structural disorder). Note that s is dimensionless but is often given in its dimensional form, \(\sigma =s k_BT\). The Gaussian DoS functions are

$$\begin{aligned} {\hat{g}}_\textrm{c}(E)&= \frac{g_\textrm{c}}{\sqrt{2\pi } \sigma _\textrm{c}} \exp \left( \frac{-1}{2} \left( \frac{E-E_{\textrm{c}}}{\sigma _\textrm{c}}\right) ^2 \right) \end{aligned}$$
(25a)
$$\begin{aligned} {\hat{g}}_\textrm{v}(E)&= \frac{g_\textrm{v}}{\sqrt{2\pi } \sigma _\textrm{v}} \exp \left( \frac{-1}{2} \left( \frac{E-E_\textrm{v}}{\sigma _\textrm{v}}\right) ^2 \right) . \end{aligned}$$
(25b)

Under a Fermi–Dirac distribution, the statistical integral, referred to as the Gauss–Fermi integral [52], is defined as

$$\begin{aligned} {\mathcal {G}}_\textrm{s}(\xi ) = \frac{1}{s\sqrt{2\pi }} \int _{-\infty }^\infty \frac{\exp \big ( \frac{-1}{2} \big (\frac{\eta }{s}\big )^2 \big ) }{1 + \exp (\eta -\xi )}\textrm{d}\eta . \end{aligned}$$
(26)

If carriers are approximated by a Boltzmann distribution, the statistical integral becomes \({\mathcal {S}}(\xi ) = \exp (\xi + \frac{s}{2})\). Both the Gauss–Fermi statistical integral and its Boltzmann approximation are shown in Fig. 6b for different values of s. Note that the Boltzmann approximation to Gauss–Fermi statistics is far less accurate than the parabolic equivalent, and this is exacerbated for larger values of s. As shown in Fig. 6b, the Boltzmann approximation to \({\mathcal {G}}_8(\xi )\) is still highly inaccurate when the quasi-Fermi level is \(50k_BT\) from the reference energy, occurring at a dimensionless carrier density of approximately \(10^{-9}\). Measurements of the Gaussian disorder parameter in the bands of spiro-MeOTAD (a common HTL material for PSCs) have yielded \(s=3.38-4.08\) [39, 57, 66].

Fig. 6
figure 6

The Gauss–Fermi statistical integral. a The Gaussian DoS functions for the two bands where the reference energies are located at \(E_{\textrm{c}}=-3.9\,\) eV and \(E_\textrm{v}=-5.1\,\) eV, and the effective densities of states are \(g_\textrm{c}=g_\textrm{v}=10^{25}\,\)eV\(^{-1}\) m\(^{-3}\). Three values of the Gaussian width are shown. b the Gauss–Fermi statistical integral vs. dimensionless quasi-Fermi level for three different Gaussian widths. Solid lines correspond to the Gauss–Fermi integral and the dashed black lines correspond to the Boltzmann approximation. Note the vast difference in scales compared to Fig. 5b due to the wide spread of state energy levels into the band gap (particularly for large values of s)

3.3.3 The Blakemore model

In the limit of vanishing Gaussian width (\(s=0\)), the Gaussian DoS becomes a Dirac-\(\delta\) function,

$$\begin{aligned} {\hat{g}}_{\textrm{c},\textrm{v}}(E)&= g_{\textrm{c},\textrm{v}} \delta (E-E_{\textrm{c},\textrm{v}}), \end{aligned}$$
(27)

representing a density of \(g_{\textrm{c},\textrm{v}}\) states, all with identical energy \(E_{\textrm{c},\textrm{v}}\). This is equivalent to hopping transport in materials with no structural disorder. Under a Fermi–Dirac distribution, this DoS yields a statistical integral, referred to as the Blakemore function, and shown in Fig. 7 [9],

$$\begin{aligned} {\mathcal {B}}(\xi ) = \frac{1}{\exp (-\xi )+1}. \end{aligned}$$
(28)

If carriers are approximated by a Boltzmann distribution, the statistical integral becomes \({\mathcal {S}}(\xi ) = \exp (\xi )\) .

Fig. 7
figure 7

The Blakemore statistical integral. The solid line corresponds to Blakemore function and the dashed black line corresponds to the Boltzmann approximation

3.4 Quasi-Fermi level input

Under Boltzmann distributions, the conversion between a carrier density and a quasi-Fermi level is simple; meaning that users can easily convert experimental measurements of equilibrium quasi-Fermi levels into effective doping densities to use in the parameter set for simulations. To avoid requiring users to perform this conversion for non-Boltzmann statistical models, IonMonger 2.0 can accept either carrier densities or quasi-Fermi levels when setting the TL doping levels. When the user sets the QFLs for the TLs, the relevant doping densities are calculated according to the statistical model in that layer. The two layers are independent, meaning one could set the doping density for one and the QFL for the other.

Impact of statistical models on device performance. Finally, we note that the full charge transport model is sufficiently complex that it is impossible to predict how changes to the statistical model in one of the TLs might affect the model’s response to any general experimental protocol. While outside the scope of this work, the impact of transport layer statistical models on device-level modelling will be investigated in a forthcoming publication [16].

4 Steric effects

The standard Poisson–Nernst–Planck (PNP) system, used to govern ionic motion in the previous version of IonMonger  has an embedded assumption; namely that there is no shortage of lattice sites for ion vacancies to occupy, i.e. \(P \ll P_{\text {lim}}\) where \(P_{\text {lim}}\) is the density of anion sites (and so is equivalent to the maximum vacancy density).Footnote 2 However, in relatively extreme scenarios, e.g. at very large applied voltage and/or in the narrow Debye layers near the edges of the perovskite, it is possible that ion vacancy densities become sufficiently large that steric effects (i.e. ion vacancy crowding, also known as volume exclusion effects) cannot be duly neglected. In such scenarios, the standard PNP system must be amended and replaced with a nonlinear-PNP (nPNP) system with a modified ion flux [1]. Two forms of modified ion flux have been used in the literature, derived using different assumptions. One approach yields a nonlinear (in the vacancy density) drift term in the ion flux whilst the other gives a nonlinear diffusion term. Rather than stipulating one form (or the other) of the ion flux, we allow users to easily switch between the two. We shall now present the two formulations in turn.

Fig. 8
figure 8

Distribution of anion vacancies in the Debye layer near the ETL interface at steady state at an applied voltage of 1 V under different values of the limiting vacancy density

4.1 Modified drift

Bazant [7] presents a general theory for chemical kinetics which describes how an ion flux is driven by the product of the ion density, mobility and gradient of its electrochemical potential \(\mu = k_BT\ln \left( \gamma \frac{P}{P_{\text {lim}}} \right) + \phi\), where \(\gamma\) is termed the activity coefficient. For diffusion on a lattice, the activity coefficient is given by \(\gamma = (1-\frac{P}{P_{\text {lim}}})^{-1}\) and the mobility \(M = \gamma \frac{D_\textrm{I}}{k_BT}\), where \(D_\textrm{I}\) is a constant diffusion coefficient. This theory leads to the following formulation for the ion flux, with a nonlinear density-dependent drift term,

$$\begin{aligned} F^P = -D_\textrm{I} \left[ \frac{\partial P }{\partial x} + \frac{qP}{k_B T} \frac{\partial \phi }{\partial x} \left( 1 - \frac{P}{P_{\text {lim}}} \right) \right] . \end{aligned}$$
(29)

Another appealing justification for this formulation follows from work by Burger et al. [12]. This work considers a hopping model for the diffusion process that retains a non-zero probability that sites adjacent to the ion (or ion vacancy) in question are already occupied. In the derivation of the usual PNP system, this probability is set to zero. When incorporating steric effects, the probability of transition to an occupied site is zero, thereby enforcing that at most one ion can reside on any given lattice site. This constraint results in a density-dependent mobility and hence a modified drift term.

4.2 Nonlinear diffusion

Alternatively, steric effects can be modelled via a nonlinearity in the diffusion term, as proposed by Kralj-Iglic and Iglic [41] and Borukhov et al. [10] according to thermodynamic considerations (assuming a constant mobility). In this case, the ion flux is given by

$$\begin{aligned} F^P = -D_\textrm{I} \left[ \frac{\partial P }{\partial x} \left( 1 - \frac{P}{P_{\text {lim}}} \right) ^{-1} + \frac{qP}{k_B T} \frac{\partial \phi }{\partial x} \right] . \end{aligned}$$
(30)

Note that diffusion is “enhanced” as P approaches \(P_{\text {lim}}\). This formulation has previously been used in the context of PSC modelling [2, 13]. Abdel et al. [2] show that the form of diffusion enhancement depends on the choice of statistical function and that the formulation in (30) results from employing a Blakemore model (or, equivalently, a Fermi–Dirac integral of order − 1) to describe the movement of ions.

Fig. 9
figure 9

Timescales for the current density reaching steady state at an applied voltage of 1 V after a preconditioning step at 0.9 V with different vacancy limitation parameters. Modified drift (29) and diffusion terms (30) show different dynamics but reach the same steady state

Both expressions for the ion flux collapse to the form found in the usual PNP system on taking the limit \(P_{\text {lim}}\rightarrow \infty\). Furthermore, it is important to note that even though the two formulations predict the same steady state ((29) is identical to (30) on setting \(F^p \equiv 0\)), there are marked differences in their dynamics. Figure 8 shows how the dynamics are affected by variations in \(P_{\text {lim}}\) for the two models, whilst Fig. 9 verifies that IonMonger produces identical steady states for the two different nPNP models as expected.

Steric effects can be activated in IonMonger by setting ‘Plim’ to a numeric value and ‘NonlinearFP’ to a string value of either ‘Drift’ or ‘Diffusion’.

5 Other extensions to the model

In this section we briefly introduce a number of other extensions that have been added during the IonMonger update. See the User Guide for more information.

5.1 Absorption spectra

By default, the generation rate G(xt) follows the Beer-Lambert law of light absorption for a single wavelength and absorption coefficient [48], i.e.

$$\begin{aligned} G(x,t) = I_\textrm{s}(t)F_\textrm{ph} \alpha \exp \left( -\alpha \left[ \frac{b}{2}+l\left( x-\frac{b}{2}\right) \right] \right) , \end{aligned}$$
(31)

where \(F_\textrm{ph}\) is the flux of photons incident on the light-facing perovskite surface (after accounting for reflection) under the equivalent of 1 Sun illumination; \(\alpha\) is the light absorption coefficient of the perovskite; \(I_\textrm{s}(t)\) is the intensity of the illumination in Sun equivalents; and, the parameter l determines whether light enters through the ETL (\(l=1\)) or through the HTL (\(l=-1\)) for a so-called inverted architecture.

In IonMonger 2.0 the user now has the option, via the generation_profile function, to replace (31) with a Beer-Lambert generation profile for light that includes a range of wavelengths, by integrating an absorption coefficient spectrum versus photon energy as follows:

$$\begin{aligned} G(x,t)= & {} I_\textrm{s}(t)\int _{E_\text {min}}^{E_\text {max}}F_\textrm{ph}(E) \alpha (E) \exp \nonumber \\{} & {} \left( -\alpha (E)\left[ \frac{b}{2}+l\left( x-\frac{b}{2}\right) \right] \right) \,\textrm{d}E. \end{aligned}$$
(32)

In this expression, the incident photon flux and the absorption coefficients are now functions of photon energy. The function can be created from measurement data.

5.2 Auger recombination

The total bulk recombination rate R(np) can now include contributions from Auger recombination as well as bimolecular and/or SRH recombination. The Auger recombination rate takes the form

$$\begin{aligned}&R_\text {Auger} = (A_n n + A_{p} p)(np - n_i^2)\,, \end{aligned}$$
(33)

where \(A_n\) and \(A_{p}\) are the Auger coefficients (with units m\(^6\,\)s\(^{-1}\)). This choice ensures that \(R_\text {Auger} = 0\) at thermal equilibrium, i.e. when \(np = n_i^2\). The total bulk recombination rate is

$$\begin{aligned}&R(n,p) = R_\text {bim.}+R_\text {SRH}+R_\text {Auger}\,. \end{aligned}$$
(34)

The full expressions for each of these rates are given in the “Appendix”.

5.3 Immobile ions

IonMonger 2.0 allows for the possibility of immobilising ion vacancies (previously all anion vacancies were assumed to be mobile). The user may set the ion vacancy diffusion coefficient \(D_\textrm{I}\) equal to zero in order to fix them in their initial distribution. In previous versions, this would cause the characteristic timescale (by which time is re-scaled) to become infinite, preventing simulations from running. To correct for this, the numerical scheme now uses a characteristic timescale defined as follows.

$$\begin{aligned} \tau _\textrm{ion}= {\left\{ \begin{array}{ll} \displaystyle \frac{n_0}{G_0} = \frac{b g_\textrm{c}\exp {((E_\textrm{f}^\textrm{E}-E_\textrm{c})/V_T)}}{F^\textrm{ph}(1-\textrm{e}^{-\alpha b})}\,, &{} \text {if}\ D_\textrm{I}=0 \\ \displaystyle \frac{b}{D_\textrm{I}}\sqrt{\frac{V_T\varepsilon _A}{q\hat{N_0}}}, &{} \text {otherwise.} \end{array}\right. } \end{aligned}$$
(35)

The first option is a timescale for electron transport; the second is the ionic timescale used in IonMonger 1.0 [19].

5.4 Band offsets at metal contacts

Differences in the band energy levels between the transport layers and the metal contacts are modelled by updating the boundary condition on the majority carrier in each TL as follows.

$$\begin{aligned}&n|_{x=-b_\textrm{E}} = g_\textrm{c}^\textrm{E}{\mathcal {S}}_\textrm{E}\left( \frac{E_\textrm{ct} - E_\textrm{c}^\textrm{E}}{V_T}\right) , \end{aligned}$$
(36a)
$$\begin{aligned}&p|_{x=b+b_\textrm{H}} = g_\textrm{v}^\textrm{H}{\mathcal {S}}_\textrm{H}\left( \frac{E_\textrm{v}^\textrm{H} - E_\textrm{an}}{V_T}\right) . \end{aligned}$$
(36b)

If the cathode and anode workfunctions are not set, IonMonger 2.0 assumes flat-band conditions, as before, which are equivalent to setting

$$\begin{aligned}&E_\textrm{ct} = E_\textrm{f}^\textrm{E} = E_\textrm{c}^\textrm{E}+k_BT{\mathcal {S}}_\textrm{E}^{-1}\left( \frac{d_\textrm{E}}{g_\textrm{c}^\textrm{E}}\right) , \end{aligned}$$
(37a)
$$\begin{aligned}&E_\textrm{an} = E_\textrm{f}^\textrm{H} = E_\textrm{v}^\textrm{H}-k_BT{\mathcal {S}}_\textrm{H}^{-1}\left( \frac{d_\textrm{H}}{g_\textrm{v}^\textrm{H}}\right) . \end{aligned}$$
(37b)

5.5 Parasitic resistances

In order to model parasitic resistances, we follow the work of Neukom et al. [49] and embed the PSC drift–diffusion model in an external circuit containing two resistors, as shown in Fig. 2b. Even though this modelling approach (of appending resistors to the PSC element) is essentially ad-hoc, it does allow the model to capture parasitic series and shunt(/parallel) resistances which may be important in practice. An alternative approach to capturing these resistances would be to upgrade the model to include more spatial dimensions, more of the PSC architecture and a more complex (non-planar) geometry. However, such complexity would render the model significantly more costly to both solve and parameterise, nullifying some of the benefits of IonMonger.

The effect of the external circuit is taken account of through two modifications to the drift–diffusion model. Within the PSC, the total current density is independent of x and can be computed at any point in the cell from

$$\begin{aligned}&J(t) = -\frac{V_{\textrm{p}}}{AR_{\textrm{p}}} + \left\{ \begin{array}{c} \displaystyle {j^n}+{j^p}-\frac{\partial }{\partial t}\left( \varepsilon _A\frac{\partial \phi }{\partial x}\right) +q{{F}^P}\\ \qquad \qquad \text {for } 0<x<b, \\ \displaystyle {j^n}-\frac{\partial }{\partial t}\left( \varepsilon _\textrm{E}\frac{\partial \phi }{\partial x}\right) \qquad \qquad \\ \qquad \qquad \text { for } -b_\textrm{E}<x<0,\\ \displaystyle {j^p}-\frac{\partial }{\partial t}\left( \varepsilon _\textrm{H}\frac{\partial \phi }{\partial x}\right) \qquad \qquad \\ \qquad \qquad \text { for } b<x<b+b_\textrm{H}, \end{array} \right. \end{aligned}$$
(38)

where \(V_{\textrm{p}} = V_\textrm{bi}-\phi |_{x=-b_\textrm{E}}+\phi |_{x=b+b_\textrm{H}}\). The first term on the right-hand side accounts for current losses due to shunt resistance in the external circuit. \(V_{\textrm{p}}\) denotes the potential difference across the parallel resistor and, equivalently, the PSC element as shown in Fig. 2b. To minimise numerical error, IonMonger automatically calculates the current density at the midpoint of the perovskite layer, where the grid spacing is larger and the solution varies more smoothly. The terms involving time-derivatives give the displacement current density, which can become dominant during very high frequency (IS) measurements.

Secondly, we have to take account of the change in \(V_{\textrm{p}}\) due to the resistor in series. We choose to incorporate this change at the HTL/metal contact, leading to the boundary condition

$$\begin{aligned}&\phi |_{x=b+b_\textrm{H}} = -\frac{V_\textrm{bi}-V(t)}{2}-\frac{R_\textrm{s}[AR_{\textrm{p}}j^{p,H}- V(t)]}{R_{\textrm{p}}+R_\textrm{s}}, \end{aligned}$$
(39)

where \(R_\textrm{s}\) (Ohm) is the series resistance, \(R_{\textrm{p}}\) (Ohm) is the parallel resistance and A (cm\(^{-2}\)) is the cross-sectional area of the cell perpendicular to the current. We implicitly assume that the displacement current is negligible at the boundary. With these two modifications, the impact of parasitic resistances on cell performance and time-dependent behaviour can be easily investigated alongside the full set of cell parameters.

6 Easy access via IonMonger Lite

Previously, some knowledge of MATLAB syntax was required to edit the parameters file and run simulations. In contrast, IonMonger Lite (provided as part of IonMonger 2.0) is aimed at users with no expertise in the MATLAB language.

IonMonger Lite is a MATLAB live script, i.e. an interactive document that displays formatted text, equations and images [47]. The underlying code can be hidden, thereby providing a more accessible user-experience. The IonMonger Lite interface enables users to run two types of simulation: a single current–voltage (\(J\)\(V\)) sweep, preceded by a preconditioning step, or impedance spectroscopy (IS). The cell parameters and simulation protocol can be edited in text boxes and drop-down menus.

Figure 10 depicts the available protocols, including the adjustable parameters. For the \(J\)\(V\) sweep, the six parameters are the steady-state initial voltage, \(V_\textrm{init}\); the voltage at which the sweep begins, \(V_\textrm{pre}\); the target sweep voltage, \(V_\textrm{tar}\); the length of the preconditioning phase, \(t_\textrm{pre}\); the length of the sweep, \(t_\textrm{sweep}\); and the constant light intensity, L. For impedance spectroscopy, the adjustable parameters are the DC voltage, \(V_\textrm{DC}\); the AC voltage amplitude, \(V_{\textrm{p}}\); the minimum and maximum frequencies, \(f_{\min }\) and \(f_{\max }\); the number of sample frequencies, \(n_\textrm{f}\); and the constant light intensity, L.

Fig. 10
figure 10

The two types of experimental protocol available in IonMonger Lite. a Current–voltage sweep protocol with 6 adjustable parameters. b Impedance spectroscopy protocol with two variable voltage parameters, three frequency parameters and one light intensity parameter

Users are presented with a series of checkboxes to determine which plots will be produced at the end of the simulation. Possible plots for \(J\)\(V\) sweeps include the applied voltage and light intensity as functions of time; the current density as a function of either time or applied voltage; and distributions of the anion vacancy density, electron density, hole density or electric potential. For IS simulations, Nyquist and frequency plots such as those in Fig. 4 can be produced. For \(J\)\(V\) sweeps, there is also the option to automatically generate an animation of the solution using animate_sections.m (see Sect. 7.3).

While offering a simplified user experience, live scripts lack the flexibility of standard MATLAB code. For this reason, proficient users should continue to run simulations by editing a parameters file and running ‘master.m’ to make use of IonMonger’s full functionality. Useful features of the full version that are not possible in IonMonger Lite include:

  • advanced simulation protocols involving more sections, asymmetric sweeps, multiple consecutive sweeps, or time-dependent illumination intensity

  • open-circuit voltage tracking

  • non-Boltzmann statistical models in the transport layers

  • running batches of simulations where one or more variables are iterated through a list of values

  • changing the resolution and error tolerances of the solver

  • band offsets at the metal contacts

  • parasitic resistances

  • resuming saved simulations

IonMonger Lite uses the same numerical solver as the full version, meaning it achieves the same performance and accuracy. After the simulation, the solution file is saved in the same format as the full version; thus all of the same post-processing and analysis/plotting can be performed.

6.1 Importing data into Python

Once a simulation is complete, all the data, including the inputs, are saved in a single file. These data can then be imported into any software of the user’s choice for further analysis. The transfer of this data from MATLAB to Python is nontrivial because Python has no direct equivalent data type to the structures used by MATLAB. To aid this transfer, we include a Python file named IonMonger_import.py that can import a solution and unpack the data for analysis. This file contains functions to extract all major variables from a saved .mat file as well as example code to generate plots of the data and further instructions. Combined with IonMonger Lite, this function allows users with experience in Python but no expertise in MATLAB to design, run, and analyse simulations with IonMonger, an important step in making IonMonger accessible to a wider scientific community.

7 Performance, compatibility and accessibility

In this section, we give details of the features of IonMonger 2.0 that enable the improved performance, backwards compatibility and greater accessibility via new functionalities for both running the code and visualising the results.

7.1 Performance

In the original version of IonMonger, the Jacobian (\({\mathcal {J}}\)) of the DAE system was approximated numerically by ode15s. In IonMonger 2.0, performance is improved by analytic calculation of \({\mathcal {J}}\) in the function AnJac.m. Figure 11 demonstrates the resulting increase in performance for simulations of current–voltage sweeps using the default parameter set. The simulation time for an impedance spectrum with 60 sample frequencies is decreased from 61 to 31 s.

Similarly, IonMonger 2.0 benefits from improved stability in response to different parameter sets, due to many small changes that aid the solver, ode15s, in converging on a solution.

Fig. 11
figure 11

Comparison of performance between IonMonger versions 1.0 and 2.0. An identical parameter file is used for both versions. For each value of N, a preconditioning stage and 100 mV s\(^{-1}\) reverse and forward scans were simulated. Red lines correspond to 1.0 and blue lines to 2.0. Squares represent measurements on a laptop with a Ryzen 5 Microsoft Surface Edition CPU and crosses represent a desktop with a Ryzen 5 5600X CPU. Simulations were attempted for 40 values of N equally spaced between 20 and 800. Any missing data points are due to a solution not being obtained from the given parameter set (Color figure online)

7.1.1 Fast and accurate evaluation of statistical integrals and their inverses

The challenge of implementing alternative statistical models is the large number of comparatively costly evaluations of the inverse statistical integral, \({\mathcal {S}}^{-1}\) (47b,49b). In general, not only is the statistical integral non-invertible, but \({\mathcal {S}}\) also cannot be evaluated exactly. This is the case in both the Fermi–Dirac (24) and Gauss–Fermi (26) integrals. The simplest approach would be to evaluate the integrals numerically and invert the function with a root-finding algorithm. However, even with efficient functions to perform the integration and root-finding, this is computationally expensive and would result in \(J\)\(V\) simulations taking minutes to hours instead of seconds to minutes motivating the need for more efficient schemes.

Significant efforts have been made to find approximations to the Fermi–Dirac [9, 26, 64] and Gauss–Fermi integrals [52, 58]. However, most approximations are either computationally expensive or lack accuracy. Furthermore, attempts to approximate the inverses of these integrals are rare. In order to maximise both efficiency and accuracy, IonMonger 2.0 utilises interpolation of lookup tables of dimensionless quasi-Fermi levels and their corresponding dimensionless carrier densities, evaluated once at the start of a simulation by numerical integration using the trapezium rule on a high-resolution grid. This approach eliminates the need for a root-finding algorithm as the interpolation can be performed in either direction.

The inverted statistical integrals are evaluated inside an approximated derivative within the DAE system; therefore it is essential that the approximations have continuous first derivatives. For this reason, interpolation is performed using piecewise cubic Hermite interpolating polynomials (PCHIPs), rather than linear interpolation, via MATLAB’s interp1 function. This approach results in approximations for \({\mathcal {F}}(\xi )\) and \({\mathcal {G}}_\textrm{s}(\xi )\) with a relative error of less than 0.1% in the domains \(\{ \xi <6\}\) and \(\{ \xi < 2s \, , \, s\ge 1\}\), respectively.

Figure 12 shows the simulation times for a single current–voltage sweep with and without Boltzmann statistics in the transport layers for a range of spatial grid spacings. The time taken to create the lookup tables at the beginning of each simulation averaged 39 ms for the Fermi–Dirac, and 30 ms for the Gauss–Fermi integral. The average extra time taken for simulations of a 100 mV s\(^{-1}\) \(J\)\(V\) sweep of the template parameter set was just 0.54 s. Therefore the effects of alternative statistical models may be investigated using IonMonger without significant negative impact on computation time.

Fig. 12
figure 12

Time taken to compute a 100 mV s\(^{-1}\) \(J\)\(V\) sweep of the template parameter set with different statistical models across a range of grid resolutions. Red lines correspond to simulations using Fermi–Dirac statistics in the ETL and Gauss–Fermi in the HTL as the parameter set is based on an inorganic ETL and an organic HTL and blue lines correspond to simulations in which the Boltzmann approximation was employed in both transport layers. Circles were measured on a desktop with a Ryzen 5 5600X CPU and triangles were measured on a laptop with a Ryzen 5 Windows Surface Edition CPU (Color figure online)

7.2 Compatibility

IonMonger 2.0 is fully compatible and consistent with previous versions. Any parameter file from a previous version can be run using version 2.0. If any parameters required for additions to the model are not specified in the parameter file, they will automatically be replaced by their default values, listed in Table 1. An example of the verification that IonMonger 2.0 is indeed consistent with the initial release is shown in Fig. 13, where electric potential distributions calculated on high resolution grids from both versions are shown to overlap exactly. Though not shown, this verification has been performed on all output variables across multiple parameter sets.

Two tests for developers have been written using MATLAB’s testing framework. The aim of these tests is to verify that future versions of the code are consistent with the initial and subsequent releases. The first is a regression test that compares the output of an example simulation with saved data produced by the original code. The second is an integration test that checks that the current code runs successfully for two different experimental protocols that make use of different subroutines.

Fig. 13
figure 13

Verification of IonMonger 2.0 (dotted lines) against version 1.0 (solid lines) for solutions of electric potential during a voltage sweep on a high resolution grid. Note that the electric potential has been shifted such that \(\phi =0\) on the HTL contact for clarity and the spatial grid has been stretched such that grid points are linearly spaced in order to examine the behaviour in the Debye layers

7.3 New analysis tools

Five new analysis tools are provided as part of IonMonger 2.0 and can be found in the Code\Plotting folder.

7.3.1 Plotting functions

Four of these new tools are plotting functions. For more details, see the README file.

  • plot_recombination.m generates two figures showing the recombination rates as functions of time and space.

  • plot_dstrbns.m plots spatial distributions of the four model variables (\(P,\phi ,n,p\)).

  • plot_IS.m generates Nyquist and frequency plots as in Fig. 4, as well as a 3D plot of the impedance spectrum as shown in Fig. 3.

  • plot_bands.m generates a band diagram including the position of references energies and QFLs.

7.3.2 Animating solutions

The function animate_sections.m can be used to animate a solution and save the video as an MP4 file. Details of how to use the function and specify the parameters of the video (length, resolution, frame rate, etc) can be found in the user guide (GUIDE.md). Example videos can be found on the IonMonger Modelling YouTube channel [36] and one is included in the SI.

8 Conclusions

We have presented the second incarnation of the PSC simulation tool IonMonger, expanding on the success of the original software by: (1) augmenting the charge transport model to account for a diverse list of physical processes, including non-Boltzmann statistics, steric effects for mobile ions, absorption spectra, Auger recombination, and parasitic resistances; (2) adding additional functionality, particularly in regards to simulating impedance responses; (3) improving accessibility and lowering the barrier-to-entry via the introduction of IonMonger Lite (allowing users to leverage many features of the tool with little to no coding or MATLAB experience), and; (4) increased numerical performance and stability. In addition, the performance of the tool has been increased across the board, meaning decreased computation times. This is primarily due to the addition of an analytic Jacobian in the numerical scheme and enables the computation of full, well-resolved, impedance spectra on timescales of seconds to minutes and current–voltage sweeps on timescales of seconds on standard desktop computers.

The open-source nature of IonMonger is supported by a dedicated, free-to-join Slack community of users and developersFootnote 3 who will further develop both the charge transport model and the code in the future. Thus, the software provides an accessible in-silico laboratory for investigating the physics of PSCs, and it is the authors’ hope that it can contribute towards accelerating PSC development.