Thin-Film Solar Cell Simulator
1D/2D Drift-Diffusion · Poisson · Mobile Ions · Transfer-Matrix Optics
Perovskite · CIGS · c-Si
Xuan-Yan Chen · Longhan Zhang · Zecheng Gan* · Chang Yan* · Tongyi Zhang*
The Hong Kong University of Science and Technology (Guangzhou)
| Section | Description | |
|---|---|---|
| 1 | Overview | What SolarLab does |
| 2 | Key Features | Capabilities at a glance |
| 3 | Repository Layout | Directory structure |
| 4 | Installation | Setup instructions |
| 5 | Running the Application | Backend + frontend startup |
| 6 | Physical Principles & Equations | Governing PDEs and physics |
| 7 | Numerical Method | Solver architecture |
| 8 | Validation & Model Scope | What current evidence does and does not certify |
| 9 | Using the Web UI | UI walkthrough |
| 10 | Shipped Device Presets | Available YAML configs |
| 11 | Testing | Test suite overview |
| 12 | References | Key literature |
SolarLab is a research-grade simulator for thin-film solar cells. The core is a one-dimensional drift-diffusion + Poisson + mobile-ion solver, with an experimental two-dimensional extension for lateral microstructure studies, backed by a FastAPI HTTP service and a Vite / TypeScript / Plotly single-page web application.
It reproduces the main thin-film characterisation experiments from a single device definition, grouped into four families:
| Family | Experiment | What it does |
|---|---|---|
| Illuminated J-V | J-V sweep | Forward + reverse scans with ionic memory preserved (hysteresis); optional current decomposition ( |
| Suns-Voc | Intensity sweep producing the Sinton pseudo-JV (immune to series resistance) and pseudo-FF upper bound | |
| Dark characterisation | Dark J-V | Injection-current diode curve with auto-selected linear window → ideality factor |
| Mott-Schottky (C-V) | Dark C-V + auto-windowed |
|
| Spectral | EQE / IPCE | Wavelength-resolved external quantum efficiency via monochromatic TMM; integrates against AM1.5G for |
| Transient | Impedance spectroscopy | Lock-in extraction of |
| Transient photovoltage (TPV) | Charge-conserving open-circuit light pulse with a matched unpulsed reference; a single-exponential relaxation time is reported only when identifiable | |
| Degradation | Long-time transient with a frozen-ion snapshot J-V at each probe, decoupling slow ionic drift from the instantaneous electronic response |
The simulator works for perovskite cells (with mobile ions), inorganic thin films (CIGS, CdTe-style stacks), and crystalline silicon homojunctions — all through the same YAML-based device schema. A separate 2T monolithic tandem driver performs a combined TMM over top + junction + bottom, runs independent sub-cell J-V sweeps, and series-matches at a common current grid.
The current technical reference is the SolarLab Technical and User Manual (2026-08-11), distributed separately from this repository. It records the solver-specific variable sets, validation gates, and limitations that do not fit in this overview.
| Capability | Details | |
|---|---|---|
| 🧮 | Drift-diffusion core | Scharfetter-Gummel face fluxes with nonuniform control-volume continuity balances; Method-of-Lines with Radau implicit time integration |
| ⚡ | Poisson solve | Finite-volume operator with pre-factored LAPACK tridiagonal dgttrf/dgttrs, reusing the factor while grid and permittivity stay fixed |
| 🔬 | Mobile ions | Finite-site modified-PNP flux with shared-site dual-ion support; legacy whole-flux regularization retained only for frozen comparisons |
| 🏗️ | Heterostacks | Band offsets from |
| Capability | Details | |
|---|---|---|
| 🌈 | Transfer-matrix optics | Coherent TMM for position-resolved |
| 🔥 | Interface transport | Default SG face with an optional thermionic cap; supported ion-free QF runs can instead use an exclusive zero-thickness interface boundary with reciprocal transport and shared interface-SRH occupancy |
| 💡 | Photon recycling | Yablonovitch single-pass escape probability |
| 🔁 | Self-consistent reabsorption | Per-RHS radiative reabsorption feeds the trapped emission fraction back into |
| 🌀 | Field-dependent mobility | Caughey-Thomas velocity saturation + Poole-Frenkel hopping applied per RHS from the Poisson face field (Phase 3.2, FULL only) |
| 🚪 | Selective / Schottky contacts | Robin-type flux |
| 🎯 | Position-dependent traps | Exponential or Gaussian defect profiles concentrated at transport-layer interfaces; |
| 🌡️ | Temperature scaling | Varshni bandgap shift referenced to 300 K and power-law |
| 🧭 | Explicit solver drivers | Transient, direct steady-state, cancellation-safe quasi-Fermi, QF frequency-domain, and 2D drivers keep distinct variable sets and fail closed on unsupported physics |
| Tier | Physics set | Use case |
|---|---|---|
| LEGACY | No TE, no TMM, uniform traps, |
Regression parity against published benchmarks |
| FAST | Permits build-once upgrades (TE, TMM, dual ions, trap profile, |
Selected by the SCAPS reference preset |
| FULL | Widest configured hook set, including per-RHS radiative reabsorption, |
Runs that require those hooks; accuracy still depends on driver support and validation |
The tier is a feature ceiling, not an accuracy grade. The selected experiment driver still determines the unknowns, supported physics, and required certification checks.
The Python DeviceStack default and resolve_mode(None) select FULL. Shipped presets override this explicitly. A permitted feature activates only when its required parameters are present; selecting FULL does not supply missing material data.
| Path | Interpretation |
|---|---|
transient |
Time-dependent density/ion state with Poisson solved within RHS evaluations; preserves the declared voltage history |
steady_state / quasi_fermi |
Explicit DC solve, returned through the backend with forward = reverse and zero scan hysteresis |
| Frequency-domain adapters | Linearize a qualified operating state; supported charge/storage/contact combinations are adapter-specific |
| 2D default | Extrudes the electrical stack and uses frozen ionic background for the historical parity lane |
| 2D research extensions | One positive mobile-ion species and optional two-sided interface SRH have explicit Neumann-lateral topology gates; dual mobile ions are rejected |
| DAE research backbone | Separate residual/Jacobian models and backward-Euler reference integrators; these are not silently substituted into production experiment routes |
The function named solve_equilibrium provides a quasi-neutral starting state; it does not by itself certify full ion-relaxed equilibrium. J-V certification is also explicit: strict mode raises on a failed local certificate, while diagnostic mode returns invalid/NaN values for failed dependent points. See the package guide for the detailed capability contracts.
| Capability | Details | |
|---|---|---|
| 📈 | J-V sweep | Forward + reverse scans with ionic memory preserved (hysteresis from physics, not post-processing); optional current decomposition and spatial-profile export |
| ☀️ | Suns-Voc | Intensity sweep → Sinton pseudo-JV (series-resistance-free) and pseudo-FF upper bound |
| 🌓 | Dark J-V | Auto-windowed linear fit on |
| 📊 | Mott-Schottky | Dark C-V with |
| 🌈 | EQE / IPCE | Wavelength-resolved external quantum efficiency via monochromatic TMM; AM1.5G integration yields |
| 🎵 | Impedance | Lock-in |
| ⚡ | Transient photovoltage | Open-circuit light pulse with a matched control and a qualified photovoltage relaxation fit |
| 🧊 | Frozen-ion degradation | Snapshot J-V with both ionic species frozen, preserving their populations and backgrounds while solving the electronic steady state |
| 🔗 | 2T tandem driver | Combined TMM over top + junction + bottom, independent sub-cell sweeps, series-matched on a common current grid |
| 🟦 | 2D J-V sweep | Tensor-product 2D extension for lateral-uniform parity checks and microstructure / grain-boundary studies |
| 🟪 | Voc(Lg) grain sweep | Repeats 2D J-V over grain sizes to quantify microstructure-driven open-circuit-voltage loss |
| Capability | Details | |
|---|---|---|
| 📏 | 1D drift-diffusion (default) | Supported 1D experiments use a tanh-clustered multilayer grid with the cached MaterialArrays hot path |
| 🟦 | 2D Stage A (lateral-uniform) | Tensor-product (Ny × Nx) grid with sparse 5-point Poisson, vectorised 2D Scharfetter-Gummel fluxes, periodic / Neumann lateral BCs; bootstraps from the 1D illuminated steady state and freezes ions as a static Poisson background. On a laterally-uniform stack the 2D solver reproduces the 1D J-V to within sub-mV tests/regression/test_twod_validation.py. Available as kind='jv_2d' from the backend and as the J-V Sweep (2D) entry in the workstation experiment selector. |
| 🟪 | 2D Stage B (microstructure) | Vertical grain boundaries are defined through a YAML microstructure: block. The current operator uses exact control-volume overlap fractions to mix bulk and grain-boundary recombination rates, avoiding whole-node lifetime painting. The historical nip_MAPbI3_singleGB test fixture (one centred GB, tests/regression/test_twod_microstructure.py. The headline voc_grain_sweep experiment maps kind='voc_grain_sweep' from the backend / Voc(L_g) Grain Sweep entry in the workstation. |
| Capability | Details | |
|---|---|---|
| 🖥️ | Interactive web UI | Live SSE streaming, grouped experiment dropdown, GoldenLayout dockable panes, Plotly plots, layer-builder editor |
| 🧪 | Full test suite | Unit, integration, and physics regression tests ( |
SolarLab/
docs/figures/ Curated README and comparison figures
perovskite-sim/
perovskite_sim/ Python models, physics, discretization,
solvers, experiments, 2D, and screening
backend/ FastAPI API and SSE job dispatch
frontend/ Vite/TypeScript/Plotly/GoldenLayout UI
configs/ Three shipped research YAMLs
tests/fixtures/configs/ Historical/test-only device definitions
reproducibility/ Schema, benchmark matrix, hashes, baselines
docs/ Current package capability contracts
scripts/ Experiments, imports, validation, plotting
tests/ Unit, integration, regression, validation
notebooks/ Exploratory workflows
pyproject.toml Core package and test dependencies
scripts/ Repository support utilities
docker-compose.yml Backend/frontend development stack
CLAUDE.md Repository guidance and archive location
README.md
The dated technical manual, historical planning records, and large generated results are maintained outside the current source tree. The repository retains curated figures and active package contracts; a local output directory is not automatically part of the published evidence.
- Python 3.11+ (the package metadata requirement; focused checks below used 3.13)
- Node.js 22.12+ with
npm; the locked Vite 8 engine range is^20.19.0 || >=22.12.0 - A C compiler + BLAS/LAPACK (bundled with
numpy/scipywheels on most platforms)
git clone https://github.com/ShaneLogic/SolarLab.git
cd SolarLabcd perovskite-sim
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
python -m pip install -r backend/requirements.txtThe editable core package installs NumPy, SciPy, PyYAML, Matplotlib, and the selected test dependencies. FastAPI/Uvicorn/Pydantic are supplied by the separate backend requirements command. Installing only .[dev] is not sufficient to start the HTTP service.
cd frontend
npm ci# From perovskite-sim/
python -m pytest -q # default non-slow suite
pytest -m validation -W error::RuntimeWarning # literature-informed lanes
pytest -m slow -W error::RuntimeWarning # heavy physics suite; can exceed 1 h
python scripts/verify_reproducibility.py --json # registry and frozen-baseline checksSolarLab runs as two processes: a FastAPI backend that executes the simulations, and a Vite dev server that serves the UI.
From the SolarLab root (not perovskite-sim/):
uvicorn backend.main:app \
--host 127.0.0.1 --port 8000 \
--app-dir perovskite-sim --reloadCheck it is alive:
curl http://127.0.0.1:8000/api/configsYou should get JSON listing the shipped presets.
In a second terminal:
cd perovskite-sim/frontend
npm run devOpen http://127.0.0.1:5173 in your browser. The frontend defaults to
http://127.0.0.1:8000 and can be pointed at another backend with
VITE_API_BASE. CORS is enabled for the local development and preview flows.
Run from perovskite-sim/ with the environment activated. This is a research sweep, not a minimal installation check. Its ordinary 0-to-V_max-and-back protocol differs from the original-paper comparison script.
from perovskite_sim.models.config_loader import load_device_from_yaml
from perovskite_sim.experiments.jv_sweep import run_jv_sweep
stack = load_device_from_yaml("configs/calado2016_fig1f.yaml")
result = run_jv_sweep(stack, N_grid=100, n_points=61, v_rate=0.04, V_max=1.2)
print(f"PCE: {result.metrics_fwd.PCE*100:.2f} %")
print(f"V_oc: {result.metrics_fwd.V_oc:.3f} V")
print(f"J_sc: {result.metrics_fwd.J_sc:.1f} A/m²")
print(f"FF: {result.metrics_fwd.FF:.3f}")
print(f"Hysteresis index: {result.hysteresis_index:.3f}")SolarLab solves the coupled Poisson + drift-diffusion + mobile-ion system on the default one-dimensional device axis. The 2D extension extrudes the same layer stack onto a tensor-product grid for lateral microstructure studies. State variables at every grid node are the electron density
The electrostatic potential
with Dirichlet boundaries
DeviceStack.compute_V_bi()), accounting for dgttrf), then solved at every RHS call with a single dgttrs sweep.
Electrons and holes obey
with the conventional drift-diffusion fluxes
Scharfetter–Gummel discretization. The flux between nodes
where
The net recombination rate is the sum of Shockley–Read–Hall, radiative (bimolecular), and Auger channels:
Interface recombination is applied at heterointerfaces via the per-interface surface-recombination velocities DeviceStack.interfaces.
For perovskite cells, the default finite-site modified Poisson-Nernst-Planck model applies lattice-gas crowding to chemical diffusion without multiplying the electrostatic drift. For one positive species,
Dual mobile species share the occupancy
legacy tier retains the
superseded whole-flux steric multiplier for frozen benchmark compatibility.
Non-perovskite stacks set
Two optional models share the same interface.
Beer–Lambert (default / fallback):
Transfer-matrix (coherent thin-film) optics. When any layer carries an optical_material key, physics/optics.py loads complex perovskite_sim/data/nk/, builds the layer transfer matrices against AM1.5G, and computes the position-resolved generation rate as
integrated over the AM1.5G spectrum. The G_TMM(x) is computed once during build_material_arrays and cached on MaterialArrays.G_optical — the hot path never recomputes optics.
The default density-variable discretization keeps one bidirectional
Scharfetter-Gummel face and may apply an empirical density-weighted thermionic
cap when a band offset exceeds 0.05 eV. The dimensionally normalized
Richardson-Dushman form is available through te_physical_norm, but remains
opt-in while strongly binding interface cases are still being conditioned:
For the supported ion-free local model, solver="quasi_fermi" with
interface_boundary=true instead removes the ordinary SG face and solves
reciprocal thermionic transport and shared-occupancy interface SRH on an
exclusive zero-thickness boundary. Unsupported physics fails before Newton
starts. The current CBO campaign certifies its numerical grid contraction, not
external SCAPS agreement; see Validation & Model Scope.
By default, each outer carrier contact is treated as ohmic: the boundary carrier densities are fixed to the thermal-equilibrium values computed from the outermost layers and the boundary-node time derivatives are pinned. In FULL mode, any configured selective-contact coefficient replaces that side/carrier pin with a Robin-type flux:
where S_n_left, S_p_left, S_n_right, S_p_right) or the readable nested form:
device:
mode: full
contacts:
left:
S_p: 1.0e3
S_n: 1.0e-3
right:
S_n: 1.0e3
S_p: 1.0e-3Missing or null means the default ohmic Dirichlet pin remains active for that carrier/side. A finite value activates the Robin flux; S = 0 is blocking, while large S approaches the ohmic limit. The same coefficients are mapped onto the top and bottom boundaries of the 2D solver.
The Poisson contact potential is configured independently through
built_in_potential_mode: new devices can derive the signed value from endpoint
semiconductor work functions or from two explicit metal work functions, while
legacy_manual preserves a published benchmark magnitude. Positive applied
bias reduces the built-in field for either contact orientation:
Ions are blocked at both contacts (
The 2D solver is an experimental extension for lateral microstructure effects, not a replacement for the default 1D workflow. It builds a tensor-product grid with lateral coordinate
2D presets live under perovskite-sim/configs/twod/ and are auto-discovered by the backend. Current entry points are kind='jv_2d' for a voltage sweep and kind='voc_grain_sweep' for a grain-size sweep. Microstructure is supplied by a YAML microstructure: block containing vertical grain boundaries; the solver paints reduced SRH lifetimes into the absorber through MaterialArrays2D.
| Ingredient | Choice |
|---|---|
| Driver topology | Explicit transient, direct steady-state, quasi-Fermi DC, QF frequency-domain, and 2D paths |
| 1D grid | Tanh-clustered multilayer grid (refined near interfaces and contacts) |
| 2D grid | Tensor-product lateral/vertical mesh for Stage A/B microstructure studies |
| Spatial | Exponentially fitted SG face fluxes and dual-cell continuity balances; finite-volume Poisson with harmonic-mean face permittivities |
| Transient | Method of Lines with scipy.integrate.solve_ivp and the Radau IIA 5th-order implicit method |
| Steady state | Direct density-log Newton or cancellation-safe quasi-Fermi Newton, selected explicitly |
| Poisson | LAPACK dgttrf/dgttrs tridiagonal LU, pre-factored once per run |
| Certification | Driver-specific residual, cell-current, all-face admittance, or lateral/vertical diagnostics |
| Safety cap | max_step capped on every run_transient sub-interval to prevent Radau from accepting a giant step near flat-band |
Device configuration uses immutable frozen dataclasses such as MaterialParams, LayerSpec, and DeviceStack. Update those records with dataclasses.replace(...); numerical arrays and runtime caches have their own mutability rules.
The production TMM-to-solver path integrates absorbed photons over each electrical control volume, then divides by its width. The point-sampled tmm_generation helper is for diagnostics and should not be substituted for this photon-conserving path. The standard YAML schema uses SI lengths, densities, mobilities, and currents; energy parameters such as chi and Eg are in eV. SCAPS-style YAML has a separate loader and unit conversion contract.
SolarLab keeps repository capability, internal numerical acceptance, and
external physical agreement as separate claims. The machine-readable registry
and reproduction commands live under
perovskite-sim/reproducibility/;
the full interpretation is in the
2026-08-11 manual (distributed separately).
The c-Si panels are internal numerical evidence for the restricted local QF model. They do not certify the general transient driver or fit an external c-Si device.
The physical-interface CBO scan passes its registered N=40/50/60 numerical
grid envelope, but the normalized SCAPS-shape error is 0.4744 against a 0.05
gate. Its result is numerical_certified=true and top-level
certified=false.
The registered 1D/2D comparison uses matched vertical grids, periodic lateral boundaries, frozen ions, and an interface-free preset. Mobile-ion dynamics and the 1D interface-SRH/physical-QF machinery are outside that parity claim.
The Calado 2016 Fig 1e/1f lane (configs/calado2016_fig1f.yaml, the paper's
SI Table 1 toy stack; scripts/plot_calado_fig1f.py, the paper's
−1 → +1.2 V / 3 s hold protocol at 40 mV s−1) is a partial
external comparison. The no-contact-SRH control loop closes (HI 0.007 vs
0.00) and the hysteretic reverse branch is quantitative (Jsc 16.0
vs ≈ 16 mA cm−2, Pmax 81 vs ≈ 85 W m−2,
Voc 0.78 vs ≈ 0.73 V), but the forward-scan collapse is about
2× too shallow: HI 0.44 against the paper's 1.84 in its
Pmax,rev/Pmax,fwd − 1 definition. The cause is open;
the preset header records the study.
A nine-rate ladder on the same preset (scripts/plot_calado_fig1f_scan_rate.py,
same protocol without the +1.2 V hold) gives the scan-rate bell: HI 0.001 at
1 mV s−1, a peak of 39 at 0.3 V s−1, and 0.06 at
100 V s−1, where ions stay frozen in the short-circuit state and
both branches collapse together. The paper's 1.84 at 40 mV s−1
falls between the 0.03 (0.28) and 0.1 V s−1 (5.8) rungs, so the
residual gap reads as a ≈2× shift of the ionic time scale; it stays open.
After launching the backend and frontend (see Running the Application), open http://127.0.0.1:5173. The UI is split into three regions.
| Element | Description |
|---|---|
| DEVICES | Active device tab with simulation tier (FAST / FULL / LEGACY). Click to focus configuration. |
| RESULTS / COMPARE | Completed runs are archived here. Select two or more to overlay plots. |
| Element | Description |
|---|---|
| Preset dropdown | Choose a shipped or user preset. Switching reloads the stack from YAML. |
| Reset | Discards unsaved edits and re-loads the last saved version. |
| Stack Visualizer | (Full tier) Vertical layer column — click to edit, + to insert, drag to reorder, x to delete. |
| Detail Editor | Collapsible groups: Geometry, Transport, Recombination, Ions & Optics. |
| TMM badge | Appears when any layer has a non-empty optical_material. |
| Save As | Save edited stack to configs/user/ or download YAML directly. |
Detail Editor parameter groups
- Geometry — thickness, grid density, role (contact / transport / absorber / substrate)
-
Transport —
$\mu_n$ ,$\mu_p$ ,$N_c$ ,$N_v$ ,$N_A$ ,$N_D$ ,$\chi$ ,$E_g$ ,$\varepsilon_r$ -
Recombination —
$\tau_n$ ,$\tau_p$ ,$k_{\text{rad}}$ ,$C_n$ ,$C_p$ ,$E_t$ -
Ions & Optics —
$D_{\text{ion}}$ ,$N_{\max}$ ,$P_0$ ,optical_material,n_optical,incoherentflag - Contacts / Advanced physics — optional Robin contact coefficients, field mobility, and FULL-tier hooks
Experiment panes share a common pattern: parameters form -> Run button -> live progress bar -> Plotly plot. The workstation includes the 1D characterisation experiments plus 2D J-V and grain-size studies.
| Parameter | Description |
|---|---|
| Number of spatial nodes | |
| V sample points | Number of voltage samples per scan direction |
| Scan rate (V/s) | Ionic memory effects — fast scans produce larger hysteresis |
| Upper voltage bound (defaults to |
|
| Decompose current | Per-face breakdown into |
| Save spatial profiles | Snapshot |
The experiment runs a forward scan (short-circuit to
The two optional output views (decomposition, spatial profiles) are mutually exclusive on a single run — pick one per sweep or re-run for the other.
| Parameter | Description |
|---|---|
| Frequency sweep |
|
| DC bias | Steady-state bias voltage |
| AC amplitude | Small-signal perturbation |
At each frequency, the solver integrates several AC cycles, then a lock-in amplifier extracts amplitude and phase. Displacement current
| Parameter | Description |
|---|---|
| Total time | Simulation duration |
| Number of probes | Snapshot count over the simulation |
| Probe bias | Voltage for snapshot J-V |
At each probe time, the solver takes a frozen-ion snapshot: both positive and negative ionic diffusivities are set to zero while their spatial populations, compensating backgrounds and site capacities remain fixed. The same frozen model solves the electronic steady state and reports its
| Parameter | Description |
|---|---|
| Number of spatial nodes | |
|
|
Fractional generation perturbation (e.g. 0.05 = 5% pulse) |
| Pulse duration | Duration of the light pulse [s] |
| Observation window | Total time including decay [s] |
The device is prepared at open circuit under steady illumination, then a small light pulse is applied. Terminal charge and voltage evolve together to preserve the open-circuit total-current condition. The pulse response is measured against an unpulsed trace with the same initial state, allowing slow background drift to remain visible. A single-exponential photovoltage relaxation time is reported only for an identifiable decay; otherwise tau is None (null in JSON) and a fit reason is retained. It is not automatically a microscopic recombination lifetime. See the TPV contract.
| Parameter | Description |
|---|---|
Nx, Ny_per_layer
|
Lateral and vertical mesh density |
| Lateral length | Width of the 2D domain |
| Microstructure | Optional grain_boundaries block painted into absorber lifetime fields |
| Grain sizes | Sequence used by voc_grain_sweep to compute |
The 2D J-V pane uses the same metric semantics as the 1D J-V sweep. If the voltage window does not bracket the zero-current crossing, the UI shows V_oc not bracketed and keeps raw data unchanged while offering an operational-range display clip.
The Tutorial pane is a guided walkthrough (Device Setup -> First Simulation -> Interpreting Results -> Advanced Topics). The Algorithm pane is a formal write-up of the PDEs, discretization, solver tiers, and the transfer-matrix optical model. Both are always available — no backend required.
perovskite-sim/configs/ currently contains three research YAMLs, all listed by the backend API. The frontend catalog displays scaps_mirror_v2 and calado2016_ion_sweep; the older calado2016_fig1f remains available through the API/scripts. The current registry covers 55 configurations: 3 shipped and 52 under tests/fixtures/configs/ (including four 2D fixtures). Fixture-only configurations are not served by the API.
| Preset | Material System | Ions | Optics | Notes |
|---|---|---|---|---|
scaps_mirror_v2 |
Glass / HTL / PVK / ETL | No | TMM | SCAPS parity study, Fast mode |
calado2016_fig1f |
Calado 2016 Fig. 1f toy device | Yes | Beer-Lambert | Original comparison lane, Legacy mode; external agreement remains partial |
calado2016_ion_sweep |
Internal dense ion-sweep figure | Yes | Uniform absorber generation in the declared waveform | Frontend ion study, Full mode; internal figure regression, not original-paper reproduction |
See Research Presets for protocols and limitations. Older benchmark figures and records elsewhere in this README describe their declared historical configurations. The new ion-sweep preset carries its own continuous waveform, preconditioning, and dark-turnaround settings; results must not be transferred between the two Calado-named protocols.
The 2026-10-01 documentation review ran six focused modules for research-preset inventory/API round trips, SCAPS inline configuration, Calado protocol helpers, mode defaults, ionic-flux Jacobians, and solver dispatch: 77 tests passed. This check did not rerun the full physics suite, historical grid campaigns, or external-solver comparisons quoted above.
# From perovskite-sim/: research-preset checks
python -m pytest -q tests/reproducibility/test_research_presets.py tests/unit/backend/test_scaps_inline_config.py tests/unit/experiments/test_plot_calado_fig1f.py
# Default non-slow lane (includes applicable regression/validation tests)
python -m pytest -q| Suite | Scope |
|---|---|
| Unit | Per-module physics + solver coverage |
| Integration | End-to-end experiment runs on shipped presets |
| Regression | Physical sanity envelopes (conftest.py
|
For repository maintenance and technical questions, contact Xuan-Yan Chen at xchen565@connect.hkust-gz.edu.cn. The contributor and corresponding-author addresses below remain separately attributed.
- Scharfetter, D. L. & Gummel, H. K. (1969) — Large-signal analysis of a silicon Read diode oscillator. Foundational SG flux scheme.
- Courtier, N. E. et al. (2019) — IonMonger: a free and fast planar perovskite solar cell simulator with coupled ion vacancy and charge carrier dynamics. J. Comput. Electron.
- Calado, P. et al. — Driftfusion: an open source code for simulating ordered semiconductor devices. Reference MATLAB implementation used for cross-checking.
- Pettersson, L. A. A. et al. (1999) — Modeling photocurrent action spectra of photovoltaic devices based on organic thin films. J. Appl. Phys.
- Burkhard, G. F. et al. (2010) — Accounting for interference, scattering, and electrode absorption to make accurate internal quantum efficiency measurements in organic and other thin solar cells. Adv. Mater.
- Richardson, G. et al. — Theoretical basis for ion-migration modelling in perovskite solar cells.
Authors
Xuan-Yan Chen · xchen565@connect.hkust-gz.edu.cn
Longhan Zhang · lzhang619@connect.hkust-gz.edu.cn
Zecheng Gan* · zechenggan@hkust-gz.edu.cn
Chang Yan* · changyan@hkust-gz.edu.cn
Tongyi Zhang* · mezhangt@hkust-gz.edu.cn
* Corresponding authors
The Hong Kong University of Science and Technology (Guangzhou)
Made with 🧪 and ☕ at HKUST Guangzhou · SolarLab








