📖 Introduction

Particle-In-Cell / Monte Carlo Collision (PIC-MCC) solvers have been used extensively over the last two decades to study the physics of low-temperature plasmas. Thanks to these kinetic models, many complex phenomena central to practical plasma applications — electron power absorption in capacitively and inductively coupled discharges, instabilities in the magnetized plasmas of electric thrusters and magnetrons, the influence of secondary electron emission on wall sheaths and plasma potential, pattern formation and striations in plasma columns, and more — are now far better understood.

JC-PIC was created with three goals in mind:

  1. Explore the physics. Revisit the physics of low-temperature plasmas in the light of the kinetic PIC-MCC simulations published in recent years — reproducing and summarizing the key conclusions of many of these papers (here, in one dimension).
  2. Open it to everyone. Provide a fully user-friendly code, usable without any background in modelling — by experimentalists, students, researchers and teachers alike — so that a non-expert can reproduce and understand a large body of published results without writing a single line of code.
  3. Build it with AI. Meet the challenge of developing the code and its unusually complete graphical environment entirely with the help of Anthropic's Claude AI — the route that made a tool of this scope feasible at all.

JC-PIC is a one-dimensional, three-velocity-component (1D3V) particle-in-cell code with Monte Carlo collisions, designed for the simulation of low-pressure, weakly ionized plasmas — the kind of discharges encountered in plasma processing, gaseous electronics, and many laboratory and industrial applications.

What truly sets JC-PIC apart is not the method — the PIC-MCC scheme it implements is well established and shared with many other codes — but the breadth and polish of the interface built around it, and the way that interface came to exist. A research code with this degree of usability would normally cost a working scientist many months of tedious interface programming, time most are unwilling or unable to spend; JC-PIC was instead written almost entirely by an artificial intelligence — Anthropic's Claude Opus — working under the author's scientific direction. This is the genuine originality of the project, and the "An AI-Driven Development" section below tells the story in full.

The geometry is one-dimensional in space — a single coordinate x across a plasma column or between two parallel electrodes — but the code tracks the three velocity components of every super-particle, which means it correctly handles magnetic fields and the full angular distribution of collisions. The physics is electrostatic (any magnetic field is treated as external, not self-generated), the integration is fully explicit, and the collisions with the neutral background are treated by the standard PIC-MCC framework reviewed in the Theory section. The simulation engine is written in modern Fortran and parallelized with OpenMP, so it automatically makes use of every available core on a multi-core CPU; a typical capacitive-RF case runs in a few hours on an ordinary desktop.

A typical use case is to set up a discharge in the Conditions dialog (gas, pressure, electrode voltages, frequency), choose a few diagnostics, click Run, and watch the plasma evolve through one of the bundled viewers — density profiles, electron energy probability functions, ion fluxes at the walls, position–time diagrams, and so on. Results are written to disk continuously and survive across restarts; a paused or stopped simulation can be resumed at any later time, even on another machine.

The quickest way to get started, though, is not to build a discharge from a blank configuration but to load one of the bundled test cases (Input → Load Test Cases…) and run it — or simply open its precomputed snapshot. The case library is meant to be the natural entry point: pick a case close to what you have in mind, reproduce it, then vary the parameters from there. The Test Cases & Browser chapter describes the library in full.

What JC-PIC Does

JC-PIC handles a broad range of low-pressure discharge configurations. The most common are radio-frequency capacitively coupled discharges, both single-frequency and multi-frequency, driven through prescribed voltage waveforms applied to the two electrodes. Direct-current discharges are equally supported, with or without an additional RF component superimposed on the DC bias. The positive column of a long DC or RF discharge can be modelled in periodic-boundary mode, where the simulation domain represents one period of the axial structure and the global current rather than a fixed voltage drives the dynamics — the natural setting for studies of striations and other axial instabilities.

A weak external magnetic field (radial or axial, constant or modulated) can be added when the geometry calls for it. Secondary electron emission at the walls is included with user-controlled coefficients for both ion and electron impact, as is electron emission from the cathode (cold-cathode, beam and thermionic). Both electrons and ions experience Monte Carlo collisions with the neutral gas — elastic, excitation and ionization for the electrons, elastic and resonant charge exchange for the ions — using cross-section tables loaded at startup from external data files.

Beyond steady discharges, the same engine covers emission-limited and thermionic diodes (space-charge-limited current, virtual-cathode oscillations), magnetized E×B configurations relevant to Hall thrusters, and the classic kinetic beam instabilities (two-stream, Buneman) in periodic mode. This breadth is best appreciated through the bundled case library, which is organized exactly along these topics.

A full diagnostic suite is built in: time-averaged 1D profiles, position–time diagrams, phase-space plots, electron and ion energy distributions both in the bulk and at the walls, particle and current histories, the Schulze power decomposition, and several others. Each diagnostic has its own standalone viewer that can be opened from the GUI; viewers reload their data from disk on every refresh, which means the user can inspect any quantity at any time during a run, including from a second machine pointing to the same working directory.

JC-PIC also carries a companion Swarm mode (Files → Mode): an autonomous Monte-Carlo electron-transport solver — no grid, no Poisson equation, no ions — that computes the swarm and transport coefficients of a gas (drift velocity, diffusion, ionization and rate coefficients, EEPF) as a function of E/N in a uniform field, from the same cross-section files as the discharge engine. It is the natural tool for checking a cross-section set, for producing the coefficients a fluid model needs, and for the swarm-physics cases of the library; switching modes replaces the menu bar, and the footer of the main window always shows which model is active. It has its own group of chapters at the end of this manual — see Swarm Mode Overview.

Validation

JC-PIC has been extensively validated, along three independent routes. First, its results have been cross-checked against J-PIC, the author's own earlier particle-in-cell code, which has been used and verified in several published studies. Second, it reproduces the standard four-case capacitively-coupled RF benchmark of Turner et al. (Phys. Plasmas, 2013), the reference test that every modern low-temperature PIC code is expected to pass. Third, and most broadly, JC-PIC reproduces a large body of PIC-MCC results published in the literature — across emissive cathodes, DC and RF discharges, striations, magnetized E×B plasmas and beam instabilities — most of which are bundled, ready to run, in the test-case library. This combination of an independent in-house code, a community benchmark, and the published record gives confidence that the physics delivered through the friendly interface is quantitatively correct, not merely plausible.

A Short History of PIC Simulation

The particle-in-cell method that JC-PIC implements is not new — it is one of the oldest and most successful tools of computational plasma physics, in continuous use since the 1950s and 1960s. The earliest plasma simulations represented the plasma by one-dimensional sheets of charge (the "sheet models" of Oscar Buneman and John Dawson); by the mid-1960s, once fast Poisson solvers on a spatial mesh became available, particles were coupled to a grid — the particle-in-cell, or cloud-in-cell, scheme. Buneman, who had already computed magnetron electron orbits by numerical integration with Douglas Hartree in the 1940s, discovered the two-stream instability in 1959 and is widely regarded as the founding father of the particle simulation of plasmas.

The field was shaped above all by the Berkeley–Livermore school: Charles K. ("Ned") Birdsall's Plasma Theory and Simulation Group at the University of California, Berkeley, and A. Bruce Langdon at Lawrence Livermore, whose textbook Plasma Physics via Computer Simulation (Birdsall & Langdon, 1985) — universally known as the "bible" of PIC — became, together with Hockney & Eastwood's Computer Simulation Using Particles (1981), the canonical reference of the field. A remarkable feature of the method, which Birdsall liked to stress, is how close it stays to first principles: the super-particles simply obey the Newton–Lorentz equation of motion, the fields obey Maxwell's (here Poisson's) equations, and almost no ad hoc physics is needed.

For the low-pressure, collisional discharges that JC-PIC targets, the decisive ingredient was the addition of Monte Carlo collisions with the neutral gas — the PIC-MCC method, reviewed and named by Birdsall in 1991. The Berkeley group also built the first widely distributed, user-oriented codes for bounded plasmas (the one-dimensional PDP1 family, and later the object-oriented OOPIC/XOOPIC of John Verboncoeur, Langdon and Gladd, 1995), which carried these simulations well beyond a handful of specialists. That accessibility had an explicitly pedagogical purpose: Birdsall and his colleagues used one-dimensional PIC on ordinary PCs to teach plasma physics hands-on — the two-stream instability, Landau damping, sheath formation, the sheath–plasma series resonance — the very phenomena that fill JC-PIC's case library.

📚 For the history and the foundations: O. Buneman and the founders (R. Buneman et al., IEEE Trans. Plasma Sci. 22, 22, 1994); C.K. Birdsall & A.B. Langdon, Plasma Physics via Computer Simulation (1985); R.W. Hockney & J.W. Eastwood, Computer Simulation Using Particles (1981); C.K. Birdsall, "PIC-MCC", IEEE Trans. Plasma Sci. 19, 65 (1991); J.P. Verboncoeur, A.B. Langdon & N.T. Gladd, "An object-oriented electromagnetic PIC code", Comput. Phys. Commun. 87, 199 (1995); C.K. Birdsall & E.T. Estacio, "Discoveries in plasmas while teaching simulation", Comput. Phys. Commun. 164, 189 (2004); A.B. Langdon, "Evolution of Particle-in-Cell Plasma Simulation", IEEE Trans. Plasma Sci. 42, 1317 (2014).

JC-PIC's Place and Purpose

JC-PIC is a modest continuation of this long line of particle-in-cell simulation — the tradition of Buneman, Dawson, Birdsall, Langdon and Verboncoeur sketched in the previous section. It adds nothing fundamentally new to the method; what it offers is the pioneers' pedagogical and research aim pursued with an unusually friendly tool. A good part of its bundled case library, in fact, reproduces recent low-temperature-plasma PIC-MCC publications, so that loading a case is often a way to step straight into a current paper. Among them: the four-case capacitive RF benchmark of Turner et al. (Phys. Plasmas, 2013) and the eduPIC reference of Donkó et al. (Plasma Sources Sci. Technol., 2021); emissive and thermionic cathodes and their temperature-limited, anode-glow and self-oscillating regimes (Campanell & Umansky, Plasma Sources Sci. Technol., 2017; Campanell et al., Phys. Rev. Lett., 2025); plasma-immersion ion implantation with its fast high-voltage sheath expansion (after Stewart & Lieberman, J. Appl. Phys., 1991); the tailoring of the ion energy and angle distributions delivered to a substrate through custom voltage waveforms and the electrical asymmetry effect in dual-frequency discharges (introduced by Heil et al., J. Phys. D, 2008, and modelled by Donkó et al., J. Phys. D, 2009); the electron power-absorption analysis across pressure (Schulze et al., Plasma Sources Sci. Technol., 2018); axial ionization waves (striations) in DC and RF columns (Boeuf, Phys. Plasmas, 2022; Dosbolayev et al., Phys. Plasmas, 2024); and the Electron Cyclotron Drift Instability (ECDI) — the E×B instability responsible for anomalous electron transport in partially magnetized Hall-thruster plasmas (Smolyakov et al., Plasma Phys. Rep., 2020; Boeuf & Smolyakov, J. Plasma Phys., 2023). The collision physics throughout follows the standard Monte Carlo model of Vahedi & Surendra (Comput. Phys. Commun., 1995). JC-PIC's only ambition is to let a student or a researcher get to the physics of all of this faster.

One thing has changed since the pioneers, though: the expectations of usability. Birdsall and his colleagues were the first to turn PIC into a genuine teaching instrument, and the small educational codes they distributed (the ES1 and XPDP1 families) introduced generations of students to kinetic plasma physics — but that effort now dates back several decades, and those codes, physically excellent as they are, feel austere by today's standards of user-friendliness. More recently Donkó and co-workers released eduPIC (2021), a beautifully documented open-source teaching code whose full source is provided — but it is addressed to people who already model: its value lies in reading and adapting the code itself. JC-PIC's aim is deliberately different and broader. It is meant to be usable by everyone — modellers, of course, but equally experimentalists with no background in simulation, theoreticians, and researchers coming from any direction — through a graphical, hands-on interface that asks for no programming at all. The physics is the same as the pioneers'; the door to it is simply made wider.

And that wider door is itself the product of the development method described in the next section. An interface this comprehensive — a tabbed Conditions dialog over dozens of parameters, a curated case browser, a dozen live viewers, persistent state across sessions — sitting on top of a parallelized Fortran engine, represents an amount of software-engineering effort that a single plasma physicist could not realistically have produced alone. It became possible only because the bulk of that work was carried out by an AI partner working under scientific direction. In a very direct sense, then, the accessibility that defines JC-PIC is AI-enabled: the power of the tool and the way it was built are inseparable.

An AI-Driven Development

JC-PIC has the unusual distinction of having been written, in its entirety, by an artificial intelligence — Anthropic's Claude Opus, in its successive versions 4.7 and 4.8 as the models evolved over the course of the project — working under the scientific direction of the author. The Fortran/OpenMP simulation engine, the Python/Tkinter graphical interface, the dozen specialized viewers, the case browser, the build pipeline and even the present manual were produced by the AI from natural-language specifications, with the human contribution focused on the physics requirements, the validation against published benchmarks, and the iterative refinement of the user experience.

The motivation for this division of labour was practical. Building a comprehensive, polished graphical interface around a research code is notoriously time-consuming and not particularly intellectually rewarding for a working scientist; it routinely consumes months that would be better spent on the underlying physics. Delegating the bulk of that work to an AI partner — while keeping tight control over the algorithms and the validation — turned out to be remarkably effective. The AI grasped the physics requirements with very little guidance, suggested clean designs for the data structures and the user interface, and produced code that compiles and runs correctly far more often than not. Months of development effort were compressed into a few weeks. Equally striking was the AI's ability to implement the physics itself accurately on the first attempt: the Boris pusher, the null-collision MCC algorithm, the Thomas Poisson solver, the secondary-emission model and the various accumulators were all delivered in close to their final form, with only minor refinements needed afterwards.

The pay-off for the user is a degree of polish in the interface that is uncommon in research codes: a unified main window, a tabbed Conditions dialog that organizes dozens of physical and numerical parameters into intuitive categories, a curated browser of preconfigured cases with Markdown descriptions, persistent simulation state across sessions, twelve dedicated viewers for the various diagnostics, and a consistent visual style throughout. The code is not a thin wrapper around a numerical library that the user must learn; it is a plasma simulation that behaves like a numerical experiment, with the same kind of interaction one would have with a piece of laboratory hardware.

ℹ️ The intended audience is therefore quite broad. A student approaching plasma kinetics for the first time can run a benchmark case in minutes, watch the bulk density build up and the sheaths form, and develop physical intuition before opening a textbook. An experienced researcher can use JC-PIC to reproduce a published result, sweep a parameter, or set up a new study without spending weeks on infrastructure. The same tool serves both.

Bundled Case Library and Benchmarks

JC-PIC ships with a curated, openly extensible library of ready-to-run test cases that span the topics of low-temperature plasma physics — emission and diodes, DC and RF discharges, positive columns and striations, magnetized and Hall-thruster plasmas, kinetic beam instabilities. It is the recommended starting point for any new study. Many of these cases reproduce the recent PIC-MCC publications cited in the history section above; the Test Cases & Browser chapter then gives the full, rubric-by-rubric tour, with the parameters and the reference of every case. The rest of this section describes what a case is and how the library is meant to be used.

Each test case is a self-contained folder bundling an input namelist, an optional precomputed snapshot, and a Markdown description (_info.md) that summarizes the original publication, the parameters used, the expected results and the bibliographic reference. Loading a case from the browser copies it to a working directory of the user's choice and switches the simulation to those conditions; from there the user can either run the case from scratch and reproduce the published result, or pick up from the bundled snapshot for an immediate quasi-steady comparison.

This dual role makes JC-PIC simultaneously a pedagogical platform and a benchmarking tool. As a pedagogical platform, a student can read about a published experiment, then load the corresponding simulation, run it, look at the diagnostics, and develop a physical intuition that no static figure can convey. As a benchmarking tool, the user can directly compare the predictions of JC-PIC with those of the original codes used in the literature, exercising the same gas, pressure, voltage and frequency on identical conditions. A review paper extending these comparisons across a large corpus of published results will be submitted shortly, illustrating various aspects of the physics of low-temperature plasmas through the lens of JC-PIC.

💡 New to JC-PIC? Start here. Go to Input → Load Test Cases…, pick a case, choose a working directory, and run it (or open its precomputed snapshot). The library is also collaborative and extensible: a case you build and find interesting can later be folded into the shared library for other users. See the Test Cases & Browser chapter for the full procedure and a tour of every rubric.

Design Principles

JC-PIC follows three guiding principles that distinguish it from larger or more general-purpose simulation packages.

Local-first. Everything runs on the user's own computer. There is no cloud component, no telemetry, no account to create, and the code does not need an internet connection to function. Each simulation lives as a folder on the local disk containing the input file, the snapshots and the diagnostics; the user has full control over the data at all times.

Self-contained cases. A simulation case is a folder. The input namelist, the GUI configuration, the snapshot files, the case description and any associated metadata all live together. To back up a case, the user copies the folder. To share it with a colleague, the user sends the folder. To move it to another computer, the user moves the folder. There is no proprietary database, no hidden state, and no separate "library" file to manage.

Transparent file formats. Configuration files are plain Fortran namelists, case descriptions are plain Markdown, metadata is plain JSON, and the binary snapshots use a documented structure that any other tool can read. If the user ever decides to stop using JC-PIC, the data remains fully accessible.

System Requirements

JC-PIC is distributed as a single Windows installer that bundles the simulation engine, the graphical interface, the cross-section data files for the supported gases and the test-case library. The installation does not require administrator privileges and does not modify any system component beyond placing the executable, its data files and a desktop shortcut.

Hardware-wise, any reasonably modern desktop or laptop running Windows 10 or later is sufficient. A typical capacitive RF benchmark case completes in a few hours on a multi-core CPU; the engine is parallelized through OpenMP and benefits from any additional core available. Eight gigabytes of system memory are comfortable for most cases, although small studies can run on machines with as little as four. Cases involving the highest-resolution Turner benchmarks at low pressure may require longer runs and are best left running overnight on a workstation.

The bundled computation engine is compiled for a portable instruction set (x86-64-v2): one and the same executable runs on any 64-bit Intel or AMD processor sold since roughly 2009 — no particular CPU generation or instruction-set extension is required.

💻 Installation

JC-PIC is distributed as a single Windows installer, JC-PIC_Setup_vX.Y.exe, downloaded from jc-pic.org. It runs on Windows 10 and 11 (64-bit), does not require administrator privileges, and does not modify any system component: everything lives inside one folder that you choose, plus a desktop shortcut.

⚠️ Windows SmartScreen — a blue screen on first run, and what to do. The first time you run the installer, Windows very probably shows a full-screen blue panel headed "Windows protected your PC", offering a single Don't run button. Do not stop there: click the small More info link under the message, check that the file name it then reveals is the one you downloaded, and click Run anyway. This is not a virus detection — SmartScreen simply has no download history for a program published by one academic group, and it says so in those words if you read the expanded panel. To be sure you have the authentic installer, download JC-PIC only from jc-pic.org.

Two components of the system are used if they are present and installed if they are not: the Microsoft Edge WebView2 runtime, which draws the main window, and the .NET runtime that bridges it to the application. Both ship with an up-to-date Windows 11; the installer checks for them.

License

JC-PIC is free of charge for any use — research, teaching, engineering or commercial — under a short end-user licence that you accept when installing it. Its essentials: the program may be installed on any number of your computers but not redistributed, modified or decompiled, and not embedded into another product or service without a separate agreement; it is provided as is, without warranty of any kind, and its author accepts no liability for the use of its results — checking a simulation before relying on it is the user's responsibility. The bundled test-case library and its companion book are, separately, under CC BY 4.0. The full text is installed as LICENSE.txt (open it) and can be opened at any time from JC-PIC → License & Disclaimer…; it also asks that publications using JC-PIC cite the companion book, doi:10.5281/zenodo.22258142.

The Setup Wizard

The wizard takes under a minute. After choosing the language (English or French) and accepting the licence, you are asked for an installation location: the default is fine, but you may prefer a data disk (D:\, …) — researchers often keep simulations off the system drive. A JC-PIC folder is always created at the chosen location, so picking D:\ installs into D:\JC-PIC.

One page asks whether to download the pre-computed results for the test-case library (a few hundred MB, requires an Internet connection). The full library — descriptions, input files and plot layouts for every case — is always installed; the optional pack adds the converged results of every case (about 330 MB) so that each case opens its plots immediately, without being run first. Those results are for viewing and post-processing: continuing a converged run needs its restart point, which is fetched case by case from the case browser. If you skip the pack (no Internet, metered connection), nothing is lost: every case can be run as-is on your machine, and the results can be fetched later, case by case or all at once, from the case browser itself — see Stored results in the Test Cases & Browser chapter.

The last screen offers two things, both ticked by default: launching JC-PIC, and opening the Quick Start — a short page naming the folder you just installed into, what each of its sub-folders is for, and the few rules that matter before a first run. It stays available afterwards from the Start Menu and from the JC-PIC menu of the application.

What Gets Installed

The installation folder is self-describing: BIN holds the program itself — JC-PIC.exe next to a hidden _internal folder carrying the several hundred runtime files it needs, which is why BIN should be left alone (re-running the installer repairs it without touching your work), DATA the electron and ion cross-section files, CASES the test-case library (see Test Cases & Browser), HELP this manual and the short Quick Start page, JSON the global configuration files, and RUN the starter working folders — including Turner_Case2, the RF benchmark the application opens on first launch. The Start Menu gains three shortcuts: JC-PIC (the full application), JC-PIC Viewer, a read-only companion that browses the test-case library with the same plotting tools but cannot run or modify anything, and JC-PIC Quick Start, the short page described below.

ℹ️ The installer also writes a small bootstrap file, path.json, in your Windows user profile (%APPDATA%\JC-PIC\). It simply tells the application where its data folder is — this is how JC-PIC finds CASES, DATA and friends no matter how it is launched.

First Launch

On the very first start, a one-time activation dialog appears: enter your name and e-mail address, and an activation key is sent to you by mail within moments. Paste the key into the dialog and you are done — the check is local afterwards, and JC-PIC never needs the network again.

The application then opens directly in the RUN\Turner_Case2 working folder, a ready-to-run capacitive RF benchmark. The quickest sanity check is therefore one click: press Run, and within seconds the density should start building up between the electrodes. From there, the Quick Start section takes over.

Afterwards JC-PIC reopens the working folder you last used. If that folder has been deleted or renamed outside the application, it opens RUN\Turner_Case2 again rather than starting nowhere — the folder in use is always the one shown at the top of the window.

⚠️ If the application does not start at all: the Mark of the Web. Windows tags every file written by an installer that was itself downloaded from the Internet with a hidden zone identifier, and does the same for files unpacked from a downloaded ZIP. The .NET runtime then refuses to load a marked assembly, the Python bridge cannot start, and JC-PIC dies at startup with Failed to resolve Python.Runtime.Loader.Initialize. Nothing is actually wrong with the installation: the mark is the only defect. The installer clears it on every file it writes as its last step, so a normal install is not affected — but an installation made by unzipping a downloaded archive by hand, or one interrupted before that step, will be. The repair takes one line in PowerShell (adjust the path if you installed elsewhere):
Get-ChildItem -LiteralPath C:\JC-PIC -Recurse -File | Unblock-File

Updating

To update, download the new installer and run it over the existing installation (same folder). Your data is preserved by design: the working folders in RUN, your own cases and groups in CASES, and your settings in JSON are never overwritten — only the program, the cross sections, the manual and the library's bundled case descriptions are refreshed. Your activation also carries over; there is nothing to re-enter.

Uninstalling

Use Uninstall JC-PIC in the Start Menu (or Windows' Apps & features). The uninstaller removes the program and its data files but deliberately leaves your work in place: the CASES, RUN and JSON folders survive, so a later reinstall finds everything where you left it. If you want a complete removal, simply delete the remaining JC-PIC folder afterwards.

🚀 Quick Start

The fastest way to see a working plasma — and the recommended way to start — is not to build a discharge from scratch but to load one of the bundled test cases and run it. This takes only a few minutes and requires no prior knowledge of the parameters. The walk-through below does exactly that.

Where your runs live

JC-PIC always works out of a working directory — the folder that holds the current input.nml, the snap/ outputs and all the diagnostics of the run in progress. The footer at the bottom of the main window always shows which folder is active.

JC-PIC's data folder (typically C:\JC-PIC) contains a RUN subfolder meant precisely for this. The recommended habit is to create a new subfolder of RUN for each study — for example C:\JC-PIC\RUN\my_first_run — but you are free to put working folders anywhere on your disk.

⚠️ Do not work directly inside the CASES library (C:\JC-PIC\CASES\…). That is the read-only reference library: loading a case always makes an independent copy elsewhere, and running inside the library would overwrite the reference data. Always run from a folder of your own (ideally under RUN).

Step by step

  1. Launch JC-PIC from the desktop shortcut or the Start menu. The main window opens: a menu bar along the top, a status area in the middle, and the footer showing the simulation mode and the active working directory.
  2. Open the case library. Choose Input → Load Test Cases…. The case browser opens in its own window. Walk the tree on the left (rubric → sub-rubric → case); selecting a case shows its description on the right. For a first run pick a simple, well-documented case — for example one of the capacitive RF benchmarks (Turner) or the eduPIC reference — then click Load selected case.
  3. Choose a working directory. JC-PIC's own compact folder browser opens (the same one used by Files → Working Directory), starting in the parent of the current working directory so a sibling folder is one click away. Create or select an empty folder for this run — ideally a new subfolder of RUN, e.g. C:\JC-PIC\RUN\turner_case1 (not a folder inside CASES); the browser can create the new folder in place.
    • If the folder you pick already contains a run, JC-PIC warns: "ALL existing files in this folder will be deleted and replaced by the test case contents. Continue?". Click Yes to proceed, or Cancel and choose an empty folder instead.
  4. The case is copied in. JC-PIC copies the case — its input.nml, its saved configuration, any input-data files, and its stored results (the already-computed run, when the case shows ● or ◐ in the Results column; if it shows ○, click Get results first) — into your folder, and switches the working directory to it (you will see the new path in the footer). The case's description pops up.
  5. See the precomputed result right away. Because the case comes with its stored results, you do not need to run anything to look at it. Open a viewer from the Graphics menu — for instance 1D Profiles → Densities & Field or Position-Time Contours → Electron Density — and the published steady state appears at once.
  6. Run it yourself. Click Run.
    • With Initialization left unticked (the checkbox on the bottom bar of the Conditions dialog, mirrored on the Control tab), the run continues from the loaded snapshot, extending it.
    • If you tick Initialization first, Run does a Fresh Start: it wipes the snapshot and recomputes from t = 0, so you can watch the discharge build up from nothing.
    • Use Pause and Run to pause and resume. The run is written to disk continuously, so you can stop and come back to it later — even on another machine.
  7. Explore. Open Input → Conditions…, change a parameter — the pressure, the voltage, the frequency — click OK, and Run again to see how the discharge responds. Starting from a known reference case and varying it from there is the whole idea.

Changing the working directory later

You can switch working directory at any time from Files → Working Directory. What happens depends on the folder you pick:

💡 Keep one run per folder. Giving each study its own subfolder of RUN keeps its snapshot, configuration and diagnostics separate, and makes a study trivial to back up or share — just copy the folder. The original case in the CASES library is never touched by any of this.

🪟 Main Window & Menus

The main window is the control centre of JC-PIC. It is intentionally compact: the bulk of the screen is given over to specialized viewers that open in their own windows, while the main window itself acts as the hub from which simulations are configured, started, paused, and inspected. From the moment the application launches, the user interacts almost exclusively through this window.

The window is organized vertically. A native menu bar sits along the top edge and exposes every action the application can perform. Immediately below it lies the status bar area — initially hidden, made visible from the Bar menu — which displays live diagnostics from the running simulation. The middle of the window is intentionally empty (it can be populated with embedded plots in a future version). At the bottom, a thin footer shows the current simulation mode (PIC-MCC 1D or Swarm) and the path to the active working directory.

The main JC-PIC window
The main JC-PIC window in its compact state: the menu bar across the top (Files, Input, Bar, Parameters, Run, Pause, Graphics, …) and, at the bottom, the status bar showing the engine label and the working-directory path. This is how the window opens, before any run bar is shown.
The main JC-PIC window with the run bar expanded
The same window with the run bar expanded (Bar menu). The added panel reports live run diagnostics — the per-thread super-particle counts and the CPU profiling buckets — so the load balance across threads and the cost breakdown can be watched while the simulation runs.
ℹ️ The viewers (profiles, X-T diagrams, EEPF, IFEDF, currents, history, etc.) all open in separate top-level windows that the user can drag, resize, minimize and arrange independently. The main window remains in place and continues to control the simulation.

Files Menu

The Files menu groups the actions related to where the simulation runs and which mode it operates in.

Working Directory

Opens JC-PIC's compact folder browser — it starts in the parent of the current working directory (so a sibling run folder is one click away) and can create a new folder in place. JC-PIC reads input.nml, writes snapshots and stores all diagnostics inside the chosen directory. When changing to a new working directory, a dialog asks whether to copy the current configuration over or to start fresh from whatever the destination folder already contains. The footer at the bottom of the main window always shows the current directory. The same browser is used when loading a test case.

Mode → PIC-MCC / Swarm

Switches between the two simulation modes JC-PIC supports. PIC-MCC is the default and the topic of most of this manual: a self-consistent kinetic simulation of a discharge. Swarm mode is a complete, autonomous Monte-Carlo transport solver: it runs the same MCC machinery on a population of electrons in a uniform applied field, with no Poisson solve, and computes electron transport coefficients (drift velocity, characteristic energy, diffusion, ionization and attachment rates, rate coefficients, EEPF and its Legendre components) as a function of E/N, with statistical error bars. Switching to Swarm replaces the menu bar with the swarm-specific menus (Conditions, Run/Pause, Graphics, Tables, Progress). The choice is reflected in the footer label. Swarm mode is documented in its own group of chapters — see Swarm Mode Overview.

Exit

Closes the main window cleanly, terminating any running simulation, closing the open viewers, and saving the GUI state to the working directory. The same action is also available as a standalone Exit button at the right end of the menu bar, for quick access.

Input Menu

The Input menu is where the simulation is configured before it runs. Every physical and numerical parameter of a case can be edited from here without ever touching input.nml by hand.

Conditions…

Opens the Conditions dialog, a tabbed window that exposes all of the physical parameters of the simulation: initial densities and temperatures, electrode voltages and frequencies, heating, secondary emission, diagnostics, collisions, magnetic field, and external sources. Edits made here are written to input.nml when the dialog is closed with OK. See the dedicated "Conditions Dialog" chapter for a tab-by-tab walk-through.

Advanced…

Opens the Advanced dialog, the second half of the same input editor. It carries the settings a routine discharge simulation never needs — beam and Langmuir seeding, the external volume source, the heating models, the external circuit, the specialised collision models and the numerical accelerators. Both dialogs read and write the same input.nml, and each writes only its own keys, so they can be left open side by side. See the "Advanced Dialog" chapter.

Browse Cases Online…

Opens the public case library at jc-pic.org in a window: the same descriptions as the bundled library, rendered with their figures and their mathematics. It is a reading view — it does not load anything into a working directory. Use it to find the case you want, then load it locally with the entry below.

Load Test Cases…

Opens the case browser, which displays the bundled library of preconfigured cases (Turner benchmarks, eduPIC reference, Schulze power-absorption series, Donkó SEE, dual-frequency studies, magnetized cases, positive columns, and so on). Selecting a case copies its input file, configuration and any precomputed snapshot into a working directory chosen by the user, then switches the active simulation to those conditions. See "Test Cases & Browser" for the detail of the procedure and the contents of the library.

Plot Cross Sections → Electrons / Ions

Launches the cross-section viewer on either the electron or the ion cross-section set currently loaded for the gas of the active case. The viewer displays the partial cross sections (elastic, excitation, ionization for electrons; elastic and charge exchange for ions) as a function of energy, with linear or logarithmic axes, and highlights the threshold energies of the inelastic channels. Useful before launching a run to check that the right gas and the right cross-section file are in use.

The cross sections shipped with JC-PIC were retrieved from LXCat in June 2013. To compare a run with a published result, use the cross sections of that published work, and for a gas other than the rare gases check www.lxcat.net for the set that is recommended today. Note also that ELECSCAT.DAT covers eighteen gases while IONSCAT.DAT covers only four (He, Ne, Ar, Xe): in any other gas the ion cross sections must be supplied by the user, with the Build table… button of the Conditions dialog (General tab). See “Collisions and Cross Sections” in the case library for the detail.

Single-Particle Motion…

Opens the Single-Particle Motion module: the trajectory of one charged particle in imposed electric and magnetic fields — gyration, E×B drift, magnetic mirror, grad-B drift, and the effect of real collisions on transport across B. It is not a plasma simulation and it does not use the engine: no run, no working directory, and the answer redraws in milliseconds. See the "Single-Particle Motion" chapter.

Collisions and Cross Sections…

Opens the Collisions and Cross Sections module: the one physical ingredient JC-PIC does not compute but reads from a file. Seven views take the cross-section tables apart — σ(ε) per process, mean free path and collision frequency, the null-collision method and its νmax, the distribution of free-flight times drawn by the real collision loop, what a single collision does to the energy and the direction, and the Maxwellian rate coefficients. Same standalone behaviour as above. See the "Collisions and Cross Sections" chapter.

Palette Editor…

Opens the palette editor, a small standalone tool that lets the user define and save the colour palettes used by the 2D viewers (X-T diagrams, EEPF 2D, phase-space plots). The colour scales are stored alongside the GUI configuration and are applied uniformly across all viewers.

Bar Menu (live diagnostics)

The Bar entry on the menu bar is not a drop-down but a single-action button: each click cycles the status bar of the main window through three states. The status bar is the live read-out of the running simulation, and it is the easiest way to keep an eye on what the engine is doing without opening any viewer.

StateWhat is shownWindow height
0 — Hidden The status bar is not displayed at all. The main window stays at its minimum size and only shows the menu bar and the footer. compact
1 — Compact A single horizontal line showing: iteration count, simulation time (with adaptive unit), current Δt in nanoseconds, total electron and ion super-particle counts, and the number of OpenMP threads in use. moderate
2 — Expanded The compact line plus the per-thread breakdown (electrons and ions per thread) and the per-step CPU profiling: total CPU time, time per step and throughput in million particles per second — both computed instantaneously over the last refresh interval, so they react immediately to load changes — and the time fraction spent in each major bucket: Push El, Push Ion, Col El, Col Ion, Poisson, Grid/Dg, Diag, I/O, plus Main and an Other bucket for the residual overhead. tall

The window automatically resizes itself to fit each state, so the status bar never overflows or leaves blank space. The expanded state (2) is particularly useful when tuning a simulation: an unbalanced thread distribution or an unexpectedly large bucket (for example a Diag percentage above 50 %) usually signals a configuration that can be optimized.

💡 The CPU profiling buckets follow the convention introduced in 2026: Diag includes all profile, X-T, current and EEPF accumulation (which is computation, not disk activity), while I/O is reserved for actual disk writes — snapshots, checkpoints, deletes. This split makes the bar an honest indicator of where the engine spends its time.

Parameters Menu

The Parameters entry, like Bar, is a single-action button. Pressing it opens (or closes, when pressed again) the parameters viewer — a separate read-only window that displays the numerical parameters in effect for the current simulation: cell size and grid count, time step bounds (dt_min, dt_max, current dt, the reference dt_cfl), particle-thinning thresholds, smoothing coefficients, and the diagnostic intervals. The viewer refreshes continuously while the simulation runs, so the user can watch how Δt evolves and confirm that the explicit-scheme constraints are respected. Three on-demand panels, Power balance ▸, Particle balance ▸ and Collisions ▸, extend it into a live bookkeeping tool — every power channel in W/m² (with a residual line), every particle source/sink in A/m² and as a percentage of the species' production, and the collision frequencies and mean free paths per process, instantaneous or time-averaged. See the "Params Viewer" section for further detail.

Run and Pause Menus

Both Run and Pause are single-action buttons.

Run launches the simulation. What "Run" does precisely depends on the current state of the working directory and on whether the Init flag is set in the Conditions dialog (Control tab). If the directory contains a checkpoint and Init is unchecked, Run resumes from that checkpoint and preserves history.dat — this is the Continue mode. If the directory contains a checkpoint and Init is checked, Run wipes everything and restarts at t=0 — the Fresh Start mode. If a previous Run has been paused (rather than stopped), pressing Run again resumes execution exactly where it left off. The "Run / Stop / Pause Modes" section discusses these three workflows in detail.

Pause halts the running simulation immediately, freezing the engine after the current time step. The state is kept in memory, so a subsequent press of Run resumes the simulation without rereading the checkpoint or wiping any accumulator. While the simulation is paused the viewers remain functional and reflect the frozen state, which is convenient for inspection.

ℹ️ The visual state of the simulation — Running, Paused, or idle — is shown in a small banner that appears at the top of the main window when the simulation starts.

Graphics Menu

The Graphics menu is the launcher for all the diagnostic viewers. Each entry opens an independent viewer window that reads the relevant data files from the working directory and refreshes itself periodically. The viewers can be opened in any combination, and a final entry — Close All — closes them all at once.

The menu is organized by diagnostic family.

1D Profiles

Time-averaged spatial profiles displayed in the profile viewer. The entries are labelled with the quantities they plot: Densities - Field (nₑ, nᵢ, E), Densities - Potential (nₑ, nᵢ, φ), Densities - Mean Electron Energy (nₑ, nᵢ, εₑ), Mean Energy - Ionization Rate (εₑ, nₑνᵢ), Mean Energy - Ionization Freq. (εₑ, νᵢ), and the absorbed power. An Electron & Ion Energy / Temperature sub-menu opens the same viewer on the kinetic moments: Mean Energy (εₑ, εᵢ), Electron Temperature (Tₑ, Tₑ∥, Tₑ⊥), Ion Temperature (Tᵢ, Tᵢ∥, Tᵢ⊥) — drift-subtracted, per-cell temperatures — and Electron & Ion Velocities (⟨vₓ⟩ₑ, ⟨vₓ⟩ᵢ), the mean axial velocities of both species. A Collision Frequencies (all processes) entry opens the dedicated collision-frequency viewer with the per-process electron collision frequencies ν(x) — see the "Collision Frequencies" chapter. A separate entry launches the heating viewer with the Schulze decomposition of the electron power. Finally, below a separator, Custom - choose L/R quantities… opens the Custom 1D Profile viewer, where any of the 22 profile quantities can be placed on the left or right axis and several runs can be overlaid — see the "Custom 1D Profile" chapter.

Position-Time Contours

Spatio-temporal diagrams over one (or several) RF periods, opened in the X-T viewer: electron and ion densities, electric field, mean electron energy, ionization rate, electron power, and a sub-menu for the full Schulze power decomposition (Ptot, Pohm, Ppress, Ppress,T, Ppress,n, Pin, Pmag).

The last entry, Pmag, only appears when the case has a magnetic field, and it needs heating_diag = 1 like the rest of the decomposition — see the X-T viewer chapter.

Phase Space

Phase-space distributions f(x, vx) and f(x, ε) for both electrons and ions, opened in the phase-space viewer. Useful for visualizing the sheath dynamics, the formation of beams, and the thermalization of the bulk.

EEPF / IFEDF

Electron energy distributions in the bulk: EEPF(ε) integrated over space and EEPF(x, ε) resolved in space, opened in the EEPF viewer and EEPF 2D viewer respectively. Plus the ion flux–energy distribution at the walls, opened in the IFEDF viewer.

Current

Opens the currents viewer, which displays the time evolution of the discharge current and the applied voltage over the most recent RF periods. In self-adjusting axial-heating mode, the same viewer shows Ez(t) and Jz(t) instead.

Particle History & Energy History

Two views of history.dat in the history viewer: one focused on particle counts (electrons, ions, fluxes at the walls) and the other on global energies (mean kinetic energy of each species, total energy, energy gained from the field). Both share the same time base and survive across restarts in Continue mode.

Figure Layout…

Opens the Figure Layout page, on which the plots copied from the viewers are composed into a single publication figure — a 2×2 panel, a column of three, a panel with an inset and an arrow. It is a document, not a viewer: it has no data of its own, it holds what the viewers hand it. See the "Figure Layout" chapter.

Close All

Closes every viewer that is currently open and frees the corresponding subprocesses. The simulation itself is not affected.

The viewers themselves are described one by one in the "Viewers" chapter.

Exit Menu

The Exit entry quits the application. Because the simulation state is checkpointed continuously to snap/, a run in progress can be resumed later from the same working directory (see Restart & Checkpoints).

Window Menu

The Window menu acts on the diagnostic viewers as a group.

The Window menu
The Window menu: one entry opens the manager panel, the others act on every open viewer at once — follow-the-main-window toggle, collective recording, Raise All / Hide All / Close All.

Manage Viewer Windows…

Opens a small Viewer Windows panel docked to the main window. It lists every viewer currently open — each row carries Raise, Min (send to the taskbar) and close (✕) buttons — and gives one-click control over all of them at once: Tile arranges the open viewers side by side, Cascade stacks them with a uniform offset, Raise all / Min all / Close all act on the whole set, the Viewers follow the main window checkbox makes the set move with the main window when you drag it, and the pad at the bottom lets you move every viewer together (drag) or resize them all (scroll). Secondary analysis windows such as the FFT windows (see the FFT Analysis chapter) appear as their own indented rows (↳ FFT — …) and participate in Tile/Cascade and the collective actions. It is the quickest way to tidy a screen cluttered with a dozen diagnostic windows. See Working with Viewers for the full walk-through.

The Viewer Windows manager panel
The Viewer Windows panel with five viewers open. Each row controls one window (Raise / Min / ); the buttons below act on the whole set, and the dashed pad moves (drag) or resizes (scroll) all the viewers together.

Viewers Follow Main Window (on/off)

Toggles the same "follow" behaviour as the checkbox in the manager panel, without opening it: when enabled, dragging the main window moves every open viewer along with it, keeping your screen layout intact.

Record All Viewers…

Opens the ensemble-recording dialog: one click starts a synchronized GIF/MP4 recording of every open viewer, with a common format, frame rate and optional simulation-time window [t start, t end]. Start / Pause / Resume / Stop-All buttons and a live aggregated frame counter control the whole set; on Stop-All a prompt asks whether to save the recorded movies. Individual recordings land in the images/ folder of the working directory. See Working with Viewers → Saving, exporting and recording.

The Record All Viewers dialog
The Record All Viewers dialog. Here it is armed to record every open viewer as a GIF between t = 0 and 20 µs of simulation time: frames can be grabbed at a wall-clock rate (FPS, real time) or once every N simulated microseconds, and Playback FPS sets the speed of the saved movie. Files are auto-saved to images\, one per viewer; leave the t fields empty to record until Stop All.

Raise All / Hide All

Raise All brings every open viewer (and its FFT windows) to the front, restoring any that were minimised; Hide All sends them all to the taskbar. Handy for switching between the simulation screen and other work without closing anything.

Close All

Closes every viewer currently open and frees the corresponding subprocesses; the simulation itself is unaffected. The same action is also available as Graphics → Close All.

JC-PIC Menu

The rightmost entry of the menu bar groups the application-level information.

About…

Opens a small dialog showing the version of JC-PIC, the author and his contact addresses, and links to the project pages and to the licence. The same dialog can be summoned at any time without affecting the running simulation.

License & Disclaimer…

Opens LICENSE.txt (read it here), the end-user licence accepted at installation: what you may do with the program, the absence of warranty and the limitation of liability, the CC BY 4.0 licence of the case library, and the citation request. See Installation → License.

Quick Start

Opens HELP\JC-PIC_Quick_Start.html, a short Read Me First page: what the installation folder contains, the three rules about working directories, and a first case in six steps. It is the page the installer offers to open on its last screen; this entry brings it back at any time.

User Manual

Opens this manual in the system default web browser. The manual is bundled with the installation and works offline.

Footer

At the very bottom of the main window, a single line shows the current simulation mode (PIC-MCC 1D or Swarm) on the left and the absolute path of the active working directory on the right. The footer is always visible — even when the status bar is hidden — and is the quickest way to confirm that a Run will operate on the case the user expects.

⚙️ Conditions Dialog

The Conditions dialog is where the everyday parameters of a run are set. It is opened from Input → Conditions… and is organized into seven tabs, visited roughly in the order one sets up an experiment: General (gas, neutral background, domain and grid), Initial (starting density, temperatures and density profile), Walls (cathode electron injection and secondary emission), Voltage (the applied waveform), B Field (an optional magnetic field), Control (fresh-start vs. continue, end time) and Diagnostics (which diagnostics are recorded and how often). All edits are held in the dialog and written to input.nml only when it is closed with OK; Cancel discards them.

💡 The specialized models — an initial beam or two-stream, the Langmuir seed, the external volume source, electron heating and the Laplace field, the external circuit, and the ionization/loss/anomalous-collision and Coulomb options — now live in a separate Input → Advanced… dialog (see the Advanced Dialog chapter). Both dialogs read and write the same input.nml: each one edits only its own fields and passes the rest through untouched, so they can even be open at the same time.

A bar at the bottom of the dialog is always visible, independent of the selected tab. It carries the Initialization checkbox and the End Time (µs) field — the two controls that decide whether the next Run starts fresh or continues, and when it stops — together with the OK and Cancel buttons; these are described under the Control tab below.

Conditions dialog with the General tab open
The Conditions dialog. The row of seven tab headers groups the parameters by physical role; the bottom bar (Initialization, End Time, OK/Cancel) stays visible on every tab.

General Tab

The General tab gathers the global properties that define the physical system and its numerical resolution: the working gas and its cross-sections, the neutral background (pressure, density and temperature), the ion mass, the length of the gap and the number of grid cells, and the number of CPU threads. These are the parameters that change least often within a study but determine what is being simulated and how finely.

Fieldinput.nml keyMeaning
Number of threads nthreads Number of OpenMP threads the engine uses. The label to the right reports the machine maximum and the number currently available. Defaults to the detected CPU count. The super-particles are partitioned evenly across threads, so a value close to the physical core count usually gives the best throughput; the per-thread balance can be watched live in the expanded status bar.
Gas gas The working neutral gas (default Ar). It selects the electron–neutral cross-section set read from ELECSCAT.DAT and the ion–neutral set from IONSCAT.DAT. The cross-sections themselves can be inspected from Graphics → Cross-sections. The list of shipped gases, the origin of the data and how to add a gas are in Cross-Section Files (DATA).
Mass ratio M/m mass_ratio_override The ion-to-electron mass ratio. The grey read-out shows the value currently in ELECSCAT.DAT for the selected gas. Tick Change to and enter a number to override it — for example a reduced ratio to speed up the (otherwise slow) ion dynamics in a quick test. Left unticked, or set to 0, the file value is used. The override is the single source of truth for the ion mass and propagates everywhere it matters: the ion push, the cyclotron frequency, the Bohm speed, the thermal velocities, the MCC energy transfer and the wall-impact energy.
Build / Edit ion table… (writes DATA/ION_.DAT) A panel that appears only when the selected gas is not covered by IONSCAT.DAT. The button opens an editor in which the user supplies the ion–neutral charge-exchange and isotropic cross-sections; it writes a per-gas ION_.DAT file in the format the engine parses. When such a file already exists, the panel turns into a green "Edit table…" confirmation.
Gas density (m−3) (derived) The neutral number density n = p / (kBT). Display-and-sync only: editing it back-computes the pressures. It is not stored on its own — it is recomputed from pressure and temperature when the dialog re-opens.
Gas pressure (Pa) (derived) The same neutral pressure expressed in pascals. Display-and-sync only.
Gas pressure (torr) pressure The neutral pressure in torr. This is the canonical value actually written to input.nml; the density and the pascal field are derived from it and the temperature.
Gas temperature (K) gas_temp The neutral gas temperature (default 300 K). It fixes the neutral density at a given pressure and sets the thermal velocity of the neutrals and ions. Together with pressure it is one of the two stored quantities of the pressure block.
X dimension (m) gap The electrode gap, i.e. the length L of the one-dimensional domain along x (default 0.03 m). The cathode sits at x=0 and the anode at x=L.
# cells in X ngrid The number of grid cells; the cell size is dx = L / ngrid (default 256). The grid must resolve the Debye length (see the note below). The compile-time ceiling is ng_max = 4096.
Auto-adapt (Debye) auto_adapt_ngrid When ticked, the engine watches the ratio λD/dx every diagnostic step and doubles ngrid (up to 4096) if it falls below ≈1.5, keeping the particles and restarting the running averages. Hysteresis prevents it from oscillating. Leave it off for fixed-grid benchmark comparisons where the resolution must stay constant.
💡 The three pressure/density fields and the temperature are live-synchronized: editing any one of density, pressure (Pa), pressure (torr) or temperature instantly recomputes the others so they always describe the same neutral background. Only pressure (in torr) and gas_temp are saved; the density and the pascal value are reconstructed on the next open.
💡 A grid that does not resolve the Debye length (dx larger than about λD) causes spurious numerical heating and unphysical results. If unsure, enable Auto-adapt (Debye) for exploratory runs and switch to a fixed ngrid once the required resolution is known.

Initial Tab

The Initial tab defines the state of the plasma at t = 0: how dense the charged population is and where it sits in the gap, the temperatures and shape of its velocity distribution, how many super-particles represent it, and the population-control thresholds that keep the super-particle count within bounds as the run proceeds. The density set here is the plasma (charged-particle) density — not to be confused with the neutral gas density of the General tab.

Initial tab of the Conditions dialog (core)
The Initial tab: plasma density and temperatures, initial profile and velocity distribution, and the super-particle population controls.
Fieldinput.nml keyMeaning
Max electron and ion densities, ne = ni (m−3) density0 The peak initial plasma density, taken equal for electrons and ions so the start is quasi-neutral. Inside the profile interval the density follows the chosen shape and reaches this value at its peak. This is the charged-particle density and is independent of the neutral gas density on the General tab.
Maxwellian temperatures Te, Ti (eV) te_init, ti_init The initial electron and ion temperatures, in electron-volts, of the Maxwellian distributions used to draw the starting velocities (defaults 2 eV for electrons and 0.026 eV ≈ 300 K for ions).
Density profile interval [x1/xmax, x2/xmax] x1_profile, x2_profile The sub-interval of the domain, expressed as fractions of the gap length L, over which the initial plasma is placed. [0, 1] fills the whole gap; a narrower interval seeds a localized slab between x1 and x2.
Profile shape in [x1, x2] profile_type The shape of the initial density inside the interval. Five options (the same set is offered for the external source and the electron-heating profiles): Uniform on [x1, x2] (0), Sine on [x1,x2] (1, a half-sine that vanishes at the interval edges), Raised cosine 0.5(1+cos X) (3), Gaussian σ [x1,x2] (4, a Gaussian centred on the interval with σ set by its width), or External file (2), which reads a two-column init.inp table of (reduced position, density). The Edit button next to the selector — enabled only when External file is chosen — opens init.inp for editing.
Initial particle count (electrons = ions) npart (= count ÷ ngrid) The total number of electron super-particles placed at t=0 (ions get the same count). The dialog shows the total, but it is stored per cell as npart = count ÷ ngrid. The grey read-out just below reports the resulting macro-particle weight, and — when wall electron injection is active — the number of plasma macros actually placed at start-up.
Max # particles npart_trigger The upper bound on the super-particle count. When electrons or ions exceed it, thinning is triggered. The compile-time array ceiling is np_max = 2×106; a larger value is clamped to 0.8·np_max with a warning.
Thinning removal (%) thin_remove The percentage of super-particles randomly discarded at each thinning event (e.g. 20% removes 1 in 5). The weights of the survivors are rescaled so the physical density and energy are conserved. Stored internally as a fraction (the value ÷ 100).
Min # particles npart_min The lower bound. When the count drops below it the particles are doubled (each split in two, weight halved), restoring statistics in a rarefying plasma while preserving the density. Set to 0 to disable auto-splitting. Keep it well below Max # (the engine also guards against thin↔split oscillation).
💡 A superimposed beam or two counter-streaming Maxwellians (two-stream), and the charge-conserving Langmuir seed that launches a clean electron plasma wave, are set on the Advanced dialog’s Initial tab, not here.

Walls Tab

The Walls tab collects what happens at the two electrodes: an optional constant-current electron injection from the cathode, and the secondary electron emission released when electrons or ions strike a surface. (The external volume source that used to share this tab now lives on the Advanced dialog’s Sources tab.)

💡 Despite its name, this tab does not set the electrical condition on the walls (grounded vs. floating, symmetry plane, periodic). Those live on the Voltage/heating tab (right_bc_type, periodic_bc). The Boundaries tab is about particles at the boundaries, not the electrostatic potential.
Walls tab of the Conditions dialog
The Boundaries tab and its three sub-tabs: electron injection at the cathode, volumetric/loss-driven sources, and secondary electron emission at the electrodes.

Electron Injection sub-tab

Injects electrons at the left electrode (cold-cathode emission). Four mutually exclusive modes are offered; the parameters of a mode are active only while that mode's radio button is selected.

Fieldinput.nml keyMeaning
Injection mode einj_left_mode 0 — no injection (default). 1 — constant electron current at the left electrode. 2 — neutralizing cathode current (a GUI placeholder, not yet wired in the engine; it is forced back to 0 on save). 3 — virtual perpendicular (z) length, for azimuthal Hall-thruster runs.
Electron current (A/m²) einj_jcurr (mode 1) The injected electron current density at the left electrode.
Distribution einj_vdist (mode 1) Beam (drift + spread) (0): vx = drift + a symmetric Gaussian spread set by Temperature, truncated to vx>0, with vy=vz=0 (Temperature 0 gives a monoenergetic beam). Thermal source (flux) (1): a flux-weighted half-Maxwellian — the physically correct effusive emitter; with Directed energy 0 it is a source at rest.
Temperature (eV) einj_te (mode 1) In beam mode, the energy spread of the beam (0 = monoenergetic). In thermal-source mode, the temperature of the emitted Maxwellian.
Directed energy (eV) / Velocity (m/s) einj_eparr (mode 1) The drift (directed) energy of the injected electrons, equivalently their drift velocity — the two fields are linked by v = √(2eE/me). In thermal-source mode, 0 means an emitter at rest.
Virtual length in z (m) einj_vlen (mode 3) Once an electron has drifted this far along the perpendicular (z) direction, its energy is reset by resampling its full velocity from a Maxwellian at te_init. This emulates the finite acceleration region in one-dimensional azimuthal (E×B) Hall-thruster simulations.
💡 In mode 1 a live read-out under the fields shows the resulting injection rate (macro-particles per time step), recomputed as you edit the current, temperature or energy. Mode 2 is a visible placeholder only — selecting it has no effect on the run.

Secondary Emission sub-tab

Controls secondary electron emission (SEE) from the electrodes, through two independent mechanisms — emission under electron impact and under ion impact — each enabled and parametrized separately.

Secondary Emission sub-tab
The Secondary Emission sub-tab. The two mechanisms are independent: the upper block is the Vahedi–Surendra electron-impact yield, the lower one the constant ion-impact coefficient γ that sustains a DC glow.

Electron-impact SEE uses the Vahedi–Surendra yield γ₁ = σ₀ + (1 − σ₀)·ε/ε*, where ε is the incident electron energy. The way γ₁ is interpreted depends on its value: when γ₁ < 1 the incident electron is reflected with probability γ₁ (keeping its energy, reversing its normal velocity) and otherwise absorbed, with no new electron created; when γ₁ ≥ 1 the incident electron is always reflected and (γ₁ − 1) true secondaries are emitted as a half-Maxwellian at the chosen temperature. The two limiting cases are worth noting: with ε* = 0 and σ₀ > 0 the yield reduces to a constant reflection probability σ₀ (no Maxwellian secondaries), and with both σ₀ = 0 and ε* = 0 the mechanism is off — every incident electron is absorbed (full absorption).

Fieldinput.nml keyMeaning
σ₀ see_sigma0_in The yield at zero energy; doubles as the reflection probability when ε* = 0.
ε* (eV) see_epsstar_in The characteristic energy of the yield growth. Set it to 0 to fall back to constant-probability reflection (see above).
T of emitted e⁻ (eV) te_see_elec_in The temperature of the half-Maxwellian used for the true secondaries (γ₁ ≥ 1 case).
Left / Right Electrode see_elec_left_in, see_elec_right_in Enable electron-impact SEE independently on each wall.

Ion-impact SEE emits, on average, γ secondary electrons per incident ion, with a separate yield for each electrode and a shared emission temperature.

Fieldinput.nml keyMeaning
γ (left electrode) gamma_left The secondary-electron yield per ion hitting the left electrode.
γ (right electrode) gamma_right The same for the right electrode.
T of emitted e⁻ (both electrodes) tsee_left, tsee_right The temperature of the secondaries emitted under ion impact. The dialog uses a single field and writes the same value to both walls.

Voltage / Current Tab

The Voltage / Current tab defines the electrical drive of the discharge. A Source selector first chooses what is imposed: the voltage between the electrodes (the usual case) or the RF current density through the discharge. The tab then holds the periodic-boundary switch, the DC and up to two RF components of the applied waveform, an arbitrary V(t) read from a file, and the choice of the right electrode’s boundary condition. (Electron heating and the external circuit, which used to share this tab, are now on the Advanced dialog.)

Voltage/heating tab of the Conditions dialog
The Voltage/heating tab with its three sub-tabs: the applied voltage, the optional electron heating, and the external circuit.

Source. The two radio buttons at the top of the tab select the drive variable. With Voltage source (V) — the default — the electrode potential is imposed and the current is a result of the simulation. With Current source (A/m²) the roles are exchanged: the current density J(t) = JDC + JRF1 cos(2πF1t + θ) + JRF2 cos(2πF2t) is imposed exactly, and the electrode potential V(t) becomes an output of the simulation, recorded as the applied voltage and displayed in the Currents viewer. The three amplitude fields relabel from VDC/VRF1/VRF2 to JDC/JRF1/JRF2, and each source remembers its own amplitudes when you switch back and forth; the frequencies F1, F2 and the phase θ are shared. In current mode the drive is necessarily the formula waveform against a grounded right electrode, so the external-file and periodic options and the E = 0 right boundary are greyed out.

In voltage mode the discharge is driven in one of three mutually exclusive ways, chosen by the radio buttons: an analytic formula waveform, a tabulated waveform read from an external file, or periodic boundaries with no electrodes (the positive-column / current-driven mode). The condition on the right electrode is set just below.

Fieldinput.nml keyMeaning
Source drive_mode The drive variable: Voltage source (V) (0, default) or Current source (A/m²) (1). With a current source the formula below is a current density and the electrode potential becomes an output. Changing the source requires a Fresh Start.
Driving mode vprofile, periodic_bc Selects the drive: Formula (the V(t) expression below), External file (a tabulated V(t)), or Periodic boundary conditions (no electrodes and no applied voltage — the domain is one period of a positive column, driven by the global current). The choice is stored as two flags: periodic_bc = 1 for periodic, otherwise vprofile = 0 (formula) or 1 (file).
VDC (V) voltage The DC component of the applied waveform.
VRF1 (V), F1 (MHz) voltage_rf, freq_mhz The amplitude and frequency of the first (fundamental) RF component.
VRF2 (V), F2 (MHz), θ (°) voltage_rf2, freq_mhz2, theta_deg The amplitude and frequency of a second RF component, for dual-frequency discharges, and the phase θ of the first component relative to the second. Leave VRF2 = 0 for a single-frequency drive.
JDC, JRF1, JRF2 (A/m²) cur_dc, cur_rf, cur_rf2 (current source) The DC and two RF amplitudes of the imposed current density, entered in the same three fields, which relabel when the source is switched; the frequencies F1, F2 and the phase θ are the same keys as in voltage mode. For orientation, a single-frequency capacitive discharge at 13.56 MHz typically draws a few to a few tens of A/m².
V(t) from an external file vfile_name_in, vfile_loop (file mode) Reads the waveform from a two-column (time, voltage) file; Edit opens it. Loop repeats the table periodically, with the implicit frequency 1/(tlasttfirst) shown in the adjacent read-only field. The file is watched and re-read automatically if edited externally.
Right electrode right_bc_type The condition on the right wall when electrodes are present: V = 0 (grounded) — a standard Dirichlet ground (0); or E = 0 (insulated / Neumann) — a symmetry plane (1), at which particles are specularly reflected (no wall loss and no secondary emission there). Choosing the Neumann symmetry plane also makes the heating region span the whole gap and disables the right-wall secondary-emission settings, since they would be meaningless.
💡 In formula mode the applied potential on the left electrode is V(t) = VDC + VRF1 cos(2πF1t + θ) + VRF2 cos(2πF2t). Periodic mode removes the electrodes entirely: there is no applied voltage and the dynamics are driven by the global current — the natural setting for positive-column and striation studies.

How the current source works. JC-PIC implements an ideal RF current source following Verboncoeur et al. [J. Comput. Phys. 104, 321 (1993)]: the imposed current J(t) is integrated analytically into the surface charge σ of the powered electrode, every charged particle collected by (or emitted from) that electrode is added to σ as well, and the field at the electrode is set by the Neumann condition E = σ/ε₀. The total current — conduction plus displacement — then equals J(t) exactly at every time step, and the electrode potential adjusts self-consistently. Everything a real current-driven discharge does appears by itself: the voltage waveform develops harmonics from the nonlinear sheaths, and in an asymmetric configuration a DC self-bias builds up naturally in σ, with no blocking-capacitor iteration needed.

ℹ️ In current mode the “applied voltage” recorded in cur.bin and plotted in the Currents viewer is the measured electrode potential — that is where to read the V(t) answer: its amplitude, its harmonic content and its DC component (the self-bias). The Plot button next to the formula plots the imposed current waveform instead of a voltage.
⚠️ Switching between voltage and current source requires a Fresh Start (the electrode surface charge must be initialized). The current source is incompatible with periodic boundaries, with the E = 0 (Neumann) right electrode, with the external V(t) file and with the Laplace / no-Poisson and swarm modes — the GUI greys those options out, and if such a namelist is forced by hand the engine falls back to the voltage drive with a [DRIVE] message in fortran.log. The external-circuit elements of the Advanced dialog (series RC, DC self-bias capacitor) are ignored as well: an ideal current source fixes the current whatever is placed in series. The amplitudes cur_dc, cur_rf, cur_rf2 can be changed during a run (hot reload); the source type itself cannot.

B Field Tab

This tab adds an optional static magnetic field. JC-PIC resolves only one spatial dimension but keeps all three velocity components (1D3V), so a magnetic field — although it does no electrostatic work — rotates the velocity components through the Boris pusher and produces the drifts (E×B and others) that are central to magnetized discharges, magnetrons and Hall-thruster studies. The field is constant in time but may vary along x; its shape is given either by a built-in two-sided Gaussian profile or read from a file, and a live preview of B(x) is shown beside the parameters.

B Field tab of the Conditions dialog
The B Field tab: orientation and profile choice on the left, a live preview of the magnetic-field profile B(x) on the right.
Fieldinput.nml keyMeaning
Orientation btype No magnetic field (0); Perpendicular B field Y (1) or Z (2) — a field transverse to the simulation axis, which magnetizes the in-plane motion and drives the E×B drift; Parallel B field X (3) — along the axis, which rotates the transverse velocity components; or Oblique B field (x-y plane) (4), described below.
Angle to the wall (deg) bfield_angle Only used by the Oblique orientation. The angle α between B and the wall — not the normal — so that α = 90° means B along x and reproduces the Parallel case exactly, and α → 0 is grazing incidence. The field is placed in the x-y plane with Bx = B sin α and By = B cos α. Clamped to [0°, 90°]; default 90°.
Non magnetized ions ion_unmag When ticked, only the electrons feel the field; the ions are left unmagnetized. This is the usual choice when the ion gyroradius is much larger than the domain — for instance in azimuthal (E×B) Hall-thruster simulations.
Profile bprofile Gaussian profile (0) — the analytic two-sided shape parametrized below; or External file (1) — read BField.inp, a two-column table of reduced position and field (in tesla), loaded once at start-up.
Bmax (mT) bmag The peak field, reached at the position xBmax.
B field at x=0 (mT) bleft The field value at the left wall.
B field at x=xmax (mT) bright The field value at the right wall.
σ1 / xmax bsigma1 The width of the left Gaussian branch, as a fraction of the gap length. Setting it to 0 makes that side a linear ramp instead.
σ2 / xmax bsigma2 The width of the right Gaussian branch, as a fraction of the gap. 0 gives a linear ramp on that side.
xBmax / xmax bcenter The position of the peak, as a fraction of the gap length.
💡 The Gaussian profile is B(x) = ak exp(−(xxBmax)² / 2σk²) + bk, with branch k = 1 for xxBmax (width σ1, tending to bleft) and k = 2 for xxBmax (width σ2, tending to bright); a zero σ on a side replaces that branch by a linear ramp. A uniform field is obtained simply by setting Bmax = B(x=0) = B(x=xmax).
💡 Field values are entered here in millitesla for readability but stored in tesla in input.nml (and the BField.inp file is in tesla). The preview plot on the right redraws live as you change any parameter, so you can shape the profile by eye before running.
ℹ️ The oblique field, and why 1D3V is enough for it. The other three orientations put B along one axis. The Oblique option tilts it inside the x-y plane by the angle α measured from the wall, and this is what opens the magnetized-sheath problem: with B neither along the wall normal nor parallel to the wall, an ion arriving at the surface must be turned from the direction of B into the direction of the normal, and it does so in a layer of its own — the Chodura layer, a few ion gyroradii thick and quasi-neutral, sitting between the collisional presheath and the Debye sheath. There are then two sonic conditions instead of one: the Chodura criterion vcs along B at the entrance of the magnetic presheath, and the ordinary Bohm criterion vxcs normal to the wall at the entrance of the Debye sheath. All of it is a matter of the three velocity components, not of a second spatial dimension, which is exactly what a 1D3V code carries. The bundled case is Sheath in an Oblique Magnetic Field (rubric 01), and the limit α = 90° recovers the unmagnetized-sheath case of the same rubric — a useful consistency check.
⚠️ The ions must be magnetized for the oblique geometry to mean anything: leave Non magnetized ions unticked. It is the ion gyromotion that builds the Chodura layer, so with unmagnetized ions the layer simply does not exist and the run silently reduces to a tilted-field version of the ordinary sheath. Note also that an existing input.nml that has no bfield_angle key behaves exactly as before — the oblique branch is never taken unless the orientation is set to 4.

Control Tab

The Control tab holds the numerical run controls — chiefly the time step and how it is chosen — together with density smoothing, ion subcycling and a one-off particle-count rescaling. Two further controls that decide how a run begins and ends, Initialization and End Time, sit on the dialog's persistent bottom bar (visible from every tab); they are listed here as well because they belong with the run control.

Control tab of the Conditions dialog
The Control tab: time-step control and other numerical run settings. Initialization and End Time live on the bottom bar.
Fieldinput.nml keyMeaning
Initialization (bottom bar) istart_mode When ticked, the next Run starts fresh: the working directory is wiped and the simulation restarts at t = 0. When unticked, the run continues from the existing checkpoint. The two workflows are detailed in the "Run / Stop / Pause Modes" chapter.
End Time (µs) (bottom bar) end_time_us The simulation time at which the run stops automatically. Once a run has reached it, the engine refuses to go further until this value is increased.
Maximum time step — mode dt_mode Imposed by user (0): the time step is fixed to the value below, bypassing the adaptive logic — useful for benchmark reproducibility. Imposed by code (1): the engine chooses Δt adaptively from the CFL constraints (plasma frequency ωpe, cyclotron ωce, the MCC null-collision rate and the Courant condition) and relaxes toward it with the smoothing time, while still respecting the maximum below.
Maximum / fixed Δt (s) dtmax In user mode, the fixed time step; in code mode, the upper bound on the adaptive time step.
Smoothing dt over (µs) dt_smooth_us (code mode) The time constant over which the adaptive time step relaxes toward its target, which damps abrupt changes (typical 0.1–10 µs).
Smooth electron and ion density nsmooth The number of binomial smoothing passes applied to ne and ni after charge deposition, to reduce grid noise (0 = none, up to 10).
Ion subcycling factor (dtion/dt) nsub_ion Ions are pushed once every nsub_ion electron time steps (1 = every step). Larger values speed the run up when the ion motion is slow compared with the electrons.
Increase/decrease # particles by factor part_factor A one-off rescaling applied once at the start of the next run: the electron and ion counts are multiplied by this factor (greater than 1 duplicates particles, less than 1 removes them at random), with weights adjusted to conserve the charge. 1 leaves the count unchanged.
Random number generator rng_type The pseudo-random generator used by the Monte-Carlo machinery: xorshift32 (0, default — the historical generator) or SplitMix64 (1 — a 64-bit generator with a much longer period and better statistical quality). Results are statistically equivalent for typical runs; switching generators is a convenient robustness check that a marginal result is not an artefact of the RNG stream.
💡 Use the user-fixed time step when you need an exactly reproducible run (benchmarks); the code-adaptive mode is convenient for exploration, where it finds a safe Δt on its own. The current time step is always visible live in the status bar and the Parameters dialog.
💡 The particle-count factor is a one-time rescaling at run start — distinct from the automatic thinning/splitting on the Initial tab, which keeps the count between bounds throughout the run. It is handy for stepping a converged run up or down in statistical resolution.

Diagnostics Tab

The Diagnostics tab decides which diagnostics the engine records and how often. It is divided into five sub-tabs: General (time-averaged profiles), Position-Time (the (x,t) contour data), Energy Distribution (the EEPF and IFEDF, plus the phase-space resolution), Current (the discharge current), and Write/Store (the file-writing cadences). Recording a diagnostic always costs some CPU and disk, so each one is enabled individually and given a start time, after which only the quasi-steady regime is captured.

Diagnostics tab of the Conditions dialog
The Diagnostics tab: five sub-tabs selecting what is recorded and how often.
💡 Several diagnostics share the same Periodic vs. Transient choice. In Periodic mode the data is accumulated by RF phase and averaged over a number of cycles — the right setting for a converged RF discharge. In Transient/DC mode the data is a sliding time window of the last N microseconds, continuously overwritten — the right setting for a DC discharge or a run that has not yet reached a periodic steady state. When no RF is present (all frequencies zero) the Transient mode is selected automatically, since there is no fundamental period to average over.

General sub-tab

Controls the time-averaged plasma-property profiles (density, field, energy, ionization rate, power) read by the Profile viewers.

Fieldinput.nml keyMeaning
Time average profiles calculated — after time (µs) avg_enable, diag_start_time Enables the time-averaged profile accumulation and sets the time after which it begins (so the start-up transient is excluded from the average).
Sum plasma properties every avg_interval, avg_unit How often the instantaneous profiles are added into the running average, in time steps or nanoseconds. More frequent accumulation gives a smoother average at a modest CPU cost.
Time average profiles over (µs) diag_avg_time The time constant of an exponential moving average (EMA). 0 means a flat average since the last reset; the resulting smoothing factor α is shown live beside the field.
Reset average properties (immediate) Zeroes the averaged profiles at once (the box auto-unchecks). Useful to restart the average after the discharge has converged. Takes effect without closing the dialog.
Electron heating decomposition heating_diag A read-only mirror of the toggle on the Position-Time sub-tab, shown here for reference; change it there.
No XT / EEPF / phase diag before time (µs) nodiag_before Skips the heavy per-particle recording diagnostics — the (x,t) accumulation, the EEPF/IFEDF histograms and the live phase-space — while the simulation time is below this value. The cheap diagnostics (profiles, history, currents) keep running. Useful to speed up the long transient of a slow discharge before the interesting regime is reached. 0 disables the gate.

Position-Time sub-tab

Controls the (x,t) diagnostics — the two-dimensional position–time matrices (density, field, ionization rate, power…) shown by the X-T viewer.

Position-Time sub-tab
The Position-Time sub-tab. The choice between the periodic block, which folds the samples by RF phase over a number of cycles, and the transient block, which integrates over the last few microseconds, is what decides whether the X-T map shows one averaged RF period or a stretch of real time.
Fieldinput.nml keyMeaning
Perform (x,t) diagnostics — after time (µs) xt_enable, xt_start Enables the (x,t) accumulators and sets when they start.
Number of grid points / # of points in time xt_nx, xt_nt The spatial resolution (up to 511) and the time/phase resolution (up to 512) of the (x,t) grid — coarser than the main PIC grid to keep the matrices small.
Reset (x,t) diagnostics (immediate) Zeroes the (x,t) matrices at the next accumulation step (auto-unchecks).
Periodic / Transient mode xt_mode, xt_ncycles, xt_window Periodic (0): accumulate by RF phase over xt_ncycles cycles. Transient/DC (1): keep a sliding window of the last xt_window microseconds. (See the note above.)
Electron heating decomposition heating_diag Additionally accumulates the moments of the electron momentum equation, enabling the Schulze / Lafleur power decomposition (Ptot, Pohm, Ppress, Pinert) in the X-T and Heating viewers. Adds per-electron CPU work, so it is off by default.

Energy Distribution sub-tab

Controls the electron energy probability function (EEPF, accumulated in the bulk), the ion flux energy distribution (IFEDF, accumulated at the electrodes), and the resolution of the live phase-space histograms.

Energy Distribution sub-tab
The Energy Distribution sub-tab. The maximum energies set here are hard ceilings: an EEPF whose tail is cut flat at the top of the plot usually means this field, not the physics.
Fieldinput.nml keyMeaning
Calculate EEPF / IFEDF — after time (µs) edf_enable, edf_start Enables both distributions (they share the time-integration settings below) and sets when they start.
Max energy Elec / Ions (eV) edf_emax_val, ifedf_emax The upper energy of the EEPF and IFEDF histograms.
Bins Elec / Ions edf_nbins, ifedf_nbins The number of energy bins for each.
Spatial bins (Elec) edf_nxbins The number of spatial slices for the position-resolved EEPF (the EEPF 2D viewer, f(x, ε)).
Phase Space resolution (Bins x/vx) nx_phase_in, nv_phase_in The resolution of the live (x, vx) and (x, ε) phase-space histograms (each hard-clamped to 16–256). Higher is sharper but noisier per bin — aim for ≳10 macro-particles per bin.
Time integration: T integration / Sum every edf_tavg_enable, edf_tavg_interval, edf_tavg_unit Whether to accumulate the distributions over time, and how often (in nanoseconds or time steps).
From time / Over time (µs) edf_tmin, edf_avg_window From time: accumulate from a fixed start to the end of the run. Over time: a sliding window of the last W µs that refreshes as time advances (only one of the two is active per run).

Current sub-tab

Controls the total discharge current diagnostic read by the Currents viewer.

Current sub-tab
The Current sub-tab. It offers the same periodic / transient choice as the Position-Time sub-tab, and for the same reason.
Fieldinput.nml keyMeaning
Accumulate total current j_T(t) — after time (µs) cur_enable, cur_start Stores the gap-averaged total current density jT = je + ji + ε0 dE/dt together with the applied voltage V(t). The spatial average is low-noise because ∇·jT = 0.
Number of time points cur_nt The number of time samples stored over the display window.
Periodic / Transient mode cur_mode, cur_ncycles, cur_window Periodic (0): average jT(t) and V(t) by RF phase over cur_ncycles cycles (the display covers one cycle of the lowest frequency). Transient/DC (1): a sliding window of the last cur_window microseconds. Forced to Transient when there is no RF.

Write/Store sub-tab

Sets the cadences at which the engine writes its various files, plus the live-viewer refresh rate.

Write/Store sub-tab
The Write/Store sub-tab: how often each file is written, and the one-shot Reset Time action.
Fieldinput.nml keyMeaning
Reset Time A one-shot action, not a stored setting: ticking the box re-zeros the simulation clock and the box unticks itself. All particle positions and velocities are kept, so the plasma is untouched — this is how you re-zero time on an established discharge before the production part of a run. It takes effect during a run, within about a third of a second, as well as at the next Run. Green text beside the box reports what became of the order: requested…, then either done — clock restarted or armed — applies at the next Run. See Run / Stop / Pause Modes for what exactly is re-anchored.
Write Results every ndiagnostic How often (in time steps) the scalar history (particle counts, energies…) is appended to history.dat, read by the History and Energy viewers.
Store particles every ncheckpoint How often a full checkpoint (every particle position and velocity) is written to checkpoint.bin for restart. A checkpoint is also written on exit.
Refresh Run bar every nbar How often (in time steps) the progress bar is updated and the engine checks for stop/pause commands. Smaller values make the controls more responsive at a tiny overhead.
Write snapshots every nsnapshot How often the full snapshot profiles are written and the (x,t) and EEPF accumulators are updated. This is the "Calculate plasma properties every" value referenced on the General sub-tab.
Live 1D refresh rate (fps) live_fps How many times per second the live 1D Profile viewers redraw. Higher is smoother but uses more CPU.
History samplingnhistDedicated cadence, in time steps, at which snap/history.dat is written for the Energy- and Particle-History viewers. 0 (default) means it follows the “Write Results every” interval above; a small value (e.g. 100) resolves fast transients — such as the field-energy oscillations of a plasma wave — without changing any other diagnostic. Requires a recompiled engine.

🔬 Advanced Dialog

The Advanced dialog, opened from Input → Advanced…, holds the specialized models that are not needed for an ordinary discharge and would otherwise clutter the Conditions dialog. It has six tabs: Initial (a superimposed beam, two-stream, or the Langmuir seed), Sources (an external volume source of electron–ion pairs, optionally modulated in time), Heating (electron heating by an applied field, absorbed power or a mid-plane thermostat, and the electrons-only Laplace-field mode), Circuit (an external series RC circuit and DC self-bias), Special (ionization energy sharing, volume loss and anomalous-collision frequencies, and the ion-mass convergence accelerator) and Collisions (electron–electron Coulomb collisions and anisotropic electron–neutral scattering).

💡 Advanced and Conditions edit the same input.nml. Each dialog owns a disjoint set of keys and rewrites only those, so opening Advanced never disturbs the values set in Conditions and vice-versa. A field left at its neutral value (a zero amplitude, “None”, an unticked box) simply switches the corresponding model off.

Initial Tab

This tab superimposes a directed population on top of the thermal Maxwellian set in the Conditions dialog, or seeds a coherent wave. All of it is applied at t = 0 on a fresh start and leaves the background density unchanged.

Initial tab of the Advanced dialog
The Advanced dialog’s Initial tab: beam energy and fraction, the two-stream option, and the Langmuir-seed controls (mode number and amplitude).
Fieldinput.nml keyMeaning
Beam energy / Drift velocity drift_energy The drift energy of the electrons in eV, or equivalently the drift velocity in m/s — the two fields are linked live by v = √(2eE/me), so editing either updates the other. Its precise role depends on the beam percentage and the two-stream flag below.
Beam electron percentage (%) beam_fraction If 0, every electron is drawn from a single Maxwellian at te_init shifted by the drift velocity. If greater than 0, that percentage of electrons is monoenergetic at the beam energy while the rest stay thermal at te_init. Stored as a percentage (0–100).
Two opposite drifted Maxwellians (symmetric two-stream) two_stream When ticked, the electrons are seeded as two equal-density Maxwellians drifting at +v and −v (each half the density) — the classic symmetric two-stream initial condition. It is only meaningful with beam % = 0 and a non-zero drift, and the checkbox is automatically greyed out while a monoenergetic beam fraction is set.
Langmuir seed — mode number mpert_modeSeeds a single-mode electron density wave by displacing every electron sinusoidally, δx = (A/k) sin(kx) with k = 2π m/L — a charge-conserving perturbation (no particle is added, the ions are left uniform) of amplitude δn/n = A cos(kx). The integer m is the number of wavelengths in the periodic box and fixes k λDe, hence the whole linear behaviour of the wave. 0 disables the seed. Requires periodic boundaries and a fresh start.
Langmuir seed — amplitude δn/npert_ampThe peak relative density perturbation A of the seed above. A small value (≈0.02) stays in the linear regime (Bohm-Gross oscillation and Landau damping); a large value (0.2–0.4) drives particle trapping and phase-space “cat’s-eye” vortices. Values approaching 1 cause wave-breaking and should be avoided.

Sources Tab

Sources tab of the Advanced dialog
The Advanced dialog’s Sources tab: the external volume source S(x)·[J₀+J₁·f(t)], its spatial profile and optional time modulation from a file.

Adds electron–ion pairs in the volume of the discharge, either at a prescribed constant rate or one pair at a time to replace particles lost at the walls. Three mutually exclusive modes are available, with a common block of parameters (interval, profile, temperatures) shared by the two active modes.

Fieldinput.nml keyMeaning
Source mode ext_src_mode 0 — no external source (default). 1 — constant volumetric source at a prescribed current. 2 — re-injection: a new pair is created each time a particle of the chosen species is lost at a wall.
Source current (A/m²) ext_jsrc (mode 1) The integral of the volumetric source term, i.e. the total pair-creation rate expressed as a current density.
Percentage of injected ions (%) ext_pct_ions_in (mode 1) The percentage (0–100, default 100) of the source injected as ions.
Re-injection trigger reinj_trig (mode 2) The species whose loss triggers a replacement pair — Ion or Electron. In this mode ionization is automatically treated as excitation (so it does not itself create pairs), keeping the particle balance controlled by the re-injection alone.
Interval [x1/xmax, x2/xmax] ext_x1_in, ext_x2_in (modes 1 & 2) The spatial interval, as fractions of the gap length, in which the pairs are placed.
Profile in [x1, x2] ext_prof_type (modes 1 & 2) The spatial shape of the source — same five options as the initial-density profile: Uniform (0), Sine on [x1,x2] (1), Raised cosine (3), Gaussian σ (4), or External file (2), which reads a Src.inp table (an Edit button opens it).
Injected temperatures Te, Ti (eV) ext_te_in, ext_ti_in (modes 1 & 2) The temperatures of the injected electrons and ions.
Modulate source from file src_mod_on, srcmod_file_in, src_mod_loop (mode 1) Adds a time-dependent term to the constant source current, read from a two-column text file (time [s], current [A/m²]) — the exact mirror of the voltage-from-file mechanism. The Edit button opens the file (default source_mod.inp) with a ready-made template. Before the first table time the modulation holds its first value; with Loop ticked the interval [t₁, t₂] repeats periodically (the read-only Frequency (MHz) field shows 1/(t₂−t₁)), otherwise the last value is held. The total injected current is the constant value plus the modulation, floored at zero.
ℹ️ Point source. Setting the interval to a single point (x1 = x2) turns the volumetric source into a localized plane source: pairs are injected at that plane as flux-Maxwellians, half emitted toward the left and half toward the right. Combined with the time modulation above, this makes a convenient localized, pulsed plasma source — e.g. for launching ion-acoustic perturbations or soliton studies.
💡 Re-injection (mode 2) is the natural way to hold the total particle number fixed — for example in a positive-column or current-driven study — since every lost particle is immediately replaced by a fresh pair. Because of that, ionization in this mode is counted as a pure energy loss (excitation) rather than as a pair source.

Heating Tab

An optional supplementary mechanism that heats the electrons directly, independent of the electrode voltage. It is used to model heating localized to a region or a direction — for instance an externally imposed field in a magnetized column, or a prescribed absorbed-power profile.

Heating tab of the Advanced dialog
The Electron heating sub-tab, here configured for a positive-column striations case — where the electrons are heated directly rather than through an electrode voltage. The heating type and its parameters (field amplitude or absorbed power, frequency, direction, spatial window) are set here.
Fieldinput.nml keyMeaning
Heating type heating_type None (0); DC or RF electric field (1), parallel or perpendicular; Maxwellian heating by absorbed power (2); or Electron thermalization (3) toward a target temperature.
Field (V/m) or Absorbed power (W/m²) heating_field The amplitude of the imposed field (type 1) or the absorbed power density (type 2).
Frequency (MHz) heating_freq The frequency of the RF field, the heating, or the thermalization, depending on the chosen type. Use 0 for a DC field.
Direction: // (X) or ⊥ (Z) heating_dir Whether the field is applied parallel to the simulation axis x (0) or perpendicular, along z (1).
Self-adjust perpendicular field Ez heating_self_adjust For a radial positive column: scales the perpendicular field over time as Ez(t) = Ez0·n0/n(t) (with n0 = density0) so the heating tracks the density, and forces the heating region to span the whole gap.
Thermalization temperature (eV) heating_temp The target temperature toward which the electrons relax in the thermalization type (3).
Interval [x1/xmax, x2/xmax] heating_x1, heating_x2 The spatial interval, as fractions of the gap length, over which the heating is applied. With thermalization (type 3) and a single-point interval (x1 = x2), the heating becomes a mid-plane thermostat: every electron crossing that plane is re-emitted as a flux-Maxwellian at the target temperature, driving the population toward an isotropic Maxwellian — a clean way to sustain a bulk plasma without a volumetric field.
Spatial profile g(x) over [x1,x2] (modes 1,2) heating_profile, heating_profile_file The spatial shape of the heating inside the interval — same five options as the initial-density profile: Uniform on [x1, x2], Sine on [x1,x2], Raised cosine 0.5(1+cos X), Gaussian σ [x1,x2], or External file heating.inp (an Edit button opens the file). The applied field or absorbed power is weighted by g(x).
Laplace field — no Poisson, ELECTRONS ONLY no_poisson Replaces the self-consistent Poisson solve by the vacuum (Laplace) field: E = V(t)/L between the electrodes (or the imposed field in periodic mode), and the simulation carries electrons only — space charge is ignored. This turns the full 1D machinery into a uniform-field swarm / steady-state-Townsend (SST) experiment: for an SST run apply V < 0 and inject electrons at the left electrode. A Fresh Start is required when toggling this option; the parameters window hides the Debye/ωpe indicators, which are meaningless here.
💡 In the Maxwellian electron heating — absorbed power mode the Thermalization temperature field is greyed out and left empty: the temperature is not imposed in this mode. The engine re-Maxwellianizes the electrons at a local temperature computed self-consistently from the measured mean energy and the power to be deposited, so that exactly the requested absorbed power (W/m²) is delivered.

Laplace field — no Poisson, electrons only. The checkbox at the bottom of the tab (no_poisson) replaces the self-consistent Poisson field by the vacuum (Laplace) field of the applied voltage, E = V(t)/L uniform between the electrodes (or E = 0 with periodic boundaries, leaving only the imposed heating field). Ions are neither loaded nor created and the ion push and MCC are skipped — the run follows the electrons alone. It turns the full 1D machinery into a uniform-field swarm / steady-state-Townsend solver. A fresh start is required.

Circuit Tab

Circuit tab of the Advanced dialog
The Advanced dialog’s Circuit tab: the external series capacitor and resistor, and the DC self-bias / blocking-capacitor controls.

The external electrical circuit placed in series with the discharge. It currently holds two elements — a series RC and a DC self-bias (blocking capacitor) — gathered here so the Voltage sub-tab keeps to the applied waveform; the layout leaves room for a fuller circuit model in a future version.

Fieldinput.nml keyMeaning
Series Capacitance (nF/m²) series_cap A capacitor in series between the source and the powered electrode.
Series Resistance (Ω·m²) series_res A resistor in series with the discharge.
Bias-cap Cᵢ (nF/m²) bias_cap The iterative DC self-bias produced by a blocking capacitor (the EAE / Heil–Czarnetzki scheme): once per fundamental period the DC voltage is nudged so the period-averaged current tends to zero, letting the self-bias build up naturally as on a real capacitively coupled electrode. 0 disables it (≈10 is a typical value).
N periods avg n_avg_bias_in The number of RF periods over which the charge is integrated before each self-bias update. 1 updates every period; 3–5 averages out the fluctuations and gives a smoother VDC, at the cost of slower convergence.
💡 The DC self-bias only makes sense when the discharge is driven by the formula waveform, so its two fields are greyed out in external-file and periodic modes (and the engine forces bias_cap = 0 for a file-driven waveform). The series RC, by contrast, stays active in every driving mode.
ℹ️ With a Current source drive (Conditions → Voltage / Current tab) this whole tab is ignored and shown greyed out: an ideal current source imposes the current whatever is placed in series with the discharge, and the DC self-bias develops naturally in the electrode surface charge without a blocking capacitor.

Special Tab

The Special tab collects a few less-common controls that alter the collisional and source behaviour of the model: how energy is shared after an ionizing collision, an artificial particle-loss term, how ionization events are treated, an anomalous (artificial) electron collision frequency, electron–electron Coulomb collisions, the anisotropic electron–neutral scattering model, and an ion-mass convergence accelerator for steady-state Townsend runs. Most of these are used for specific benchmarks, or to mimic effects — such as anomalous transport — that a one-dimensional model cannot capture from first principles. For an ordinary discharge they are left at their defaults (losses and anomalous frequency at 0, ionization Normal, Coulomb and anisotropy off, ion mass physical).

Special tab of the Advanced dialog
The Special tab: energy sharing, artificial losses, ionization treatment, anomalous collisions, and the ion-mass accelerator.
Fieldinput.nml keyMeaning
Energy sharing after ionization energy_share_type, energy_share_r, energy_share_w How the energy left after an ionizing collision is split between the scattered and the ejected electron. Constant ratio r (type 0): the ejected electron takes a fixed fraction r (0 < r < 1; 0.5 is equal sharing). The Vahedi et al. (1995) model (type 1, parameter w in eV) is reserved in the interface but not yet active in the engine.
Charged particle loss frequency (MHz): elec / ion loss_freq_elec, loss_freq_ion An artificial volumetric loss term: electrons and ions are removed at random, uniformly within the interval below, each at its own prescribed rate. Leave at 0 for no artificial loss.
Loss interval [x1/xmax, x2/xmax] loss_x1, loss_x2 The region, as fractions of the gap length, over which the artificial loss is applied.
Ionization ioniz_mode Normal (0): each ionizing collision creates a new electron–ion pair. As excitation (1): no particle is created — only the energy loss and the change of direction are kept. Balanced by uniform losses (2): a pair is created at the ionization site, then one electron and one ion are removed at random and uniformly over the whole domain, so the total electron and ion counts stay constant.
Anomalous collision frequency (MHz) anom_freq An artificial electron-scattering rate applied within the interval below, used to mimic the anomalous (e.g. turbulence-driven) transport that a one-dimensional simulation cannot resolve. 0 disables it.
Anomalous interval [x1/xmax, x2/xmax] anom_x1, anom_x2 The region over which the anomalous collisions are applied.
Profile of anomalous collision freq. anom_profile The spatial shape of the anomalous frequency inside its interval: Uniform (0), Cosine (1) or Parabolic (2).
Ion mass divided by (1 = physical) ion_mass_factor Convergence accelerator for steady-state Townsend runs (and any case whose convergence time is set by the ion transit). The ions — and their collision targets, which keeps the charge-exchange kinematics exact — are integrated with the mass M/f. The ion energy distribution is rigorously invariant, so the ion flux Γi, the electron density, the Townsend coefficient α, the discharge current and the IFEDF are unchanged, while ion velocities scale as √f, the ion transit time as 1/√f and ni (hence the macro-ion count) as 1/√f — a total CPU gain of order f. Default 1 (existing runs are bit-identical); clamped to [1, 10⁶]; forced to 1 in swarm mode; activation requires a Fresh Start. Not to be confused with mass_ratio_override (General tab), which really changes the gas.
⚠️ Where the ion-mass accelerator is legitimate — and where it is not. Use it only when (i) the space charge is negligible — ni is divided by √f, so the trick masks any field distortion; when approaching the Townsend-to-glow transition, re-run the highest-current point at factor 1 — (ii) there is no magnetic fieldci ∝ 1/m), and (iii) only the steady state is of interest: every ionic time scale (transit instabilities, striations, RC oscillations) is shifted by √f. Mass-derived ion diagnostics (Bohm speed, ωci, ωpi) display the fictitious values; the ion energies (IFEDF, Ti, ⟨ε⟩i) remain the true ones. Recommended protocol: scan with f = 100–1000, then confirm one point at f = 1.
💡 The As excitation ionization mode is also switched on automatically when the re-injection external source is active (Boundaries → External Source), so that ionization does not double-count as a second pair source. The Balanced by uniform losses mode is the usual way to hold ne = ni fixed for a steady-state benchmark.

Collisions Tab

The last tab groups the two optional collision models — the ones that replace or supplement the standard electron–neutral Monte-Carlo treatment described in Theory → MC Collisions. Both are off by default, and both change the physics rather than the numerics, so both require a Fresh Start. The ordinary cross-section-driven collisions are not configured here at all: they are switched on and off in Conditions → General and read from the data files.

Collisions tab of the Advanced dialog
The Collisions tab: electron–electron Coulomb collisions above, anisotropic electron–neutral scattering below.
Fieldinput.nml keyMeaning
Enable electron-electron Coulomb collisions (Nanbu) coulomb_ee Switches on electron–electron Coulomb collisions, implemented with the Nanbu cumulative small-angle scattering model. Off by default — the usual choice for low-density, weakly coupled discharges — but essential when e-e thermalization matters (e.g. EEPF Maxwellianization at high density). When enabled, the parameters window gains a dedicated Coulomb e-e diagnostic block and the power balance includes the corresponding term. The model is described in Theory → MC Collisions → Electron–electron Coulomb collisions.
Coulomb density-scale factor (≥1) coulomb_factor A multiplicative factor applied to the density seen by the Coulomb operator, letting you amplify the e-e collisionality without changing the plasma itself (1 = physical rate). Useful to accelerate e-e relaxation studies.
Coulomb sub-cycle (steps/collision) + Auto coulomb_nsub Applies the Coulomb operator once every n time steps (with the collision probability scaled accordingly), which saves CPU when the Coulomb time scale is long compared with Δt. The parameters window shows the resulting per-application scattering parameter s and advises keeping s ≲ 0.05. Tick Auto (stored as coulomb_nsub = 0) to let the engine adjust n itself toward that target, at a bounded cadence with hysteresis, logging every change — see Theory → MC Collisions → Sub-cycling. Use a fixed value for bit-reproducible runs.
Coulomb log lnΛ (≤0 = auto) coulomb_lnlam The Coulomb logarithm. Leave at 0 (or negative) to let the engine compute it from the local density and temperature; set a positive value to impose it.
Anisotropic scattering: Elastic / Excitation / Ionization products aniso_elastic, aniso_exc, aniso_ioniz Three independent switches replacing the isotropic angle draw by the forward-peaked screened-Coulomb distribution (Okhrimovskyy), per collision family. For elastic collisions the rate is simultaneously switched from σm to the effective total cross section σeleff, so the momentum transfer — mobility, diffusion, elastic energy-loss rate — is preserved exactly; the Collisions diagnostics then report the (larger) effective elastic frequency. For ionization, both product electrons are deflected at their own post-collision energy about the incident direction (no effect when the energy sharing is set to the Donkó correlated model, which keeps its own angles). All off by default; activation requires a Fresh Start. The physics, the sampling formulas and the consistency rule are described in Theory → MC Collisions → Anisotropic scattering.
Anisotropy energy e* (eV) aniso_estar The screening parameter of the model: ξ = ε/e*. Larger e* = weaker anisotropy; the default 12.5 eV corresponds to the Eaniso = 8e* = 100 eV used for helium by Carlsson et al. (2017). Adjust per gas — it is the natural knob for sensitivity studies.
Small-angle cutoff χmin (deg, elastic) aniso_chimin Elastic deflections below χmin are not generated and σeleff is bounded accordingly — the momentum transfer stays exact for any value, so this is purely a cost/resolution trade-off (recommended 5–10°, default 8°; clamped to [0, 45]).
ℹ️ Why these two live together. Both answer the same question — what happens to the direction of an electron — at the two ends of the impact-parameter range. Anisotropic electron–neutral scattering describes a single close encounter with a screened nucleus; the Nanbu Coulomb operator accumulates the countless distant encounters with the other electrons, none of which deflects appreciably on its own. Switching either on makes the electron distribution less isotropic, or more, and both are worth checking together when an EEPF refuses to look like the published one.
💡 The Collisions and Cross Sections module (Input → Collisions and Cross Sections…) shows what the anisotropic draw actually does: its view 5 samples cos χ from the same aniso_coschi routine the engine uses, for the isotropic and the screened-Coulomb models side by side, at an energy you choose. It is the quickest way to see what e* and χmin are worth before committing a run to them.

📚 Test Cases & Browser

JC-PIC ships with a growing library of ready-to-run test cases, organized by topic. Input → Load Test Cases… opens a browser that walks the case tree and copies the selected case into a working directory of your choice.

Introduction

The case library is meant to serve four complementary purposes:

JC-PIC case browser
The case browser. The tree on the left walks the bundled CASES library, with the Results column (● view + continue, ◐ view, ○ not stored); selecting a case shows its description rendered as Markdown on the right and, under it, the strip that says what is stored and offers what the case is missing. The Load button copies the case to a working directory.

Browse the Library Online

The case descriptions can also be read without installing anything: the full library — same tree, same descriptions, figures and animations as in the application — is published on the JC-PIC website in two forms, reachable from the Browse and Book entries of the site menu (Home · Gallery · Browse · Book · Manual).

ℹ️ Browsejc-pic.org/library.html: the cases one by one, in the same tree as the application. Each case has a shareable address (the link updates as you select a case), handy for pointing a student or a colleague to a specific case. To actually run a case, use Input → Load Test Cases… in the application.
ℹ️ Bookjc-pic.org/library_article.html: the whole library as one continuous document, Physics of Low Temperature Plasmas via Particle Simulation — chapter introductions, every case description and its figures, and a single reference list. The same document is archived on Zenodo under the persistent identifier doi:10.5281/zenodo.22258142 (licence CC BY 4.0), which is the address to cite when referring to the library in a publication; the DOI always resolves to the latest version.

How to Load a Case

  1. Open Input → Load Test Cases…. The case browser opens in a separate window.
  2. Walk the tree (rubric → sub-rubric → case) and select a case. Its Markdown description appears in the right-hand panel. The Tree −/+ and Text −/+ buttons at the bottom (or Ctrl+wheel over the tree or over the description) change the text size of each column independently, and both sizes are remembered; an HTML button that opens the description in a dedicated window with fully rendered mathematics (MathJax).
  3. Click Load selected case and choose a working directory. The chooser is JC-PIC's own folder browser (the same as Files → Working Directory), titled with the case name and opened on the parent of the current working directory — create a fresh sibling folder for the case in one click.
  4. JC-PIC copies the case folder — input.nml, the saved GUI state, and the stored results (snap/) if the case has them — into that directory and switches to it. Run then continues from the stored restart point (if present), or starts from t = 0 if you tick Initialization first.

Four kinds of case

The steps above describe the ordinary case — the one that feeds the 1D discharge engine. The library holds four kinds in total, told apart by the input file each folder carries and marked accordingly in the tree:

Input file in the folderMarker in the treeWhat Load does
input.nmlCopies the case into a working directory and configures the PIC-MCC 1D engine, as described above.
input_swarm.nml[swarm]Same copy, but switches the application to Swarm mode with the case's conditions — see the Swarm chapters.
input_motion.json[motion]Opens the Single-Particle Motion module on that case's settings.
input_xsec.json[xsec]Opens the Collisions and Cross Sections module on that case's settings.
ℹ️ A [motion] or [xsec] case does not ask for a working directory and copies nothing. There is no run to launch and no data file to produce: the module simply opens on the case's settings, locked, with a banner naming the case and an Unlock button. Locked means the controls are read-only, so the case shows exactly what it is meant to show; unlocking turns it into a free exploration, and the case in the library is unaffected either way. These two kinds live in rubric 11 — Appendix.
ℹ️ The loaded case is an independent copy. You can change it freely in its working directory; the original in the library is never touched. A case folder holds an input.nml (all the parameters), an optional saved GUI state, a Markdown description, a small _meta.json (display name and ordering — kept in the library, not copied), and optionally its stored results (a snap/ folder) for an instant quasi-steady comparison. The stored results, when present, live in a snap/ folder of the case, as described above.

Your own cases in the library

The distributed library is read-only: its cases and rubrics can be loaded, never renamed, deleted or edited, so that the reference cases stay identical on every installation (the developer's copy is the exception). Nothing stops you from adding to it. Right-click a rubric (or the empty part of the tree) to create a group of your own, and use Add my case… — the button at the bottom of the browser, or the same entry of the right-click menu on a group — to turn the current working folder into a case of that group: the input file, the saved GUI state, the auxiliary input files and, if you tick the box, the results (snap/) are copied in, and a starter _info.md is written with the main parameters read from the namelist. Your working folder is left as it is. Edit info then opens the description in the Markdown editor to complete it; figures go into an images/ sub-folder and are referenced as ![caption](images/name.png).

Cases and groups you add are yours: they can be renamed and deleted from the right-click menu, they show ● or ○ in the Results column like any other case, and they are loaded the same way — copied out to a working folder, never run in place. An update of JC-PIC refreshes the distributed cases and leaves yours untouched. If a case of yours turns out to be worth sharing, see Contributing a Case below.

Stored results — the Results column

A case folder in the library ships with its description and its input files, but not with its converged run: the results are a separate download, offered once by the installer and available at any time from the browser. Across the library the diagnostic files weigh about 4 MB per case while the restart point adds another 17 MB on average, up to 95 MB — forcing everyone to take both would turn a 450 MB library into a 2.5 GB one. Every case that can have a run therefore shows one of three symbols in the narrow Results column of the tree (the legend sits next to the Test cases title):

SymbolStateWhat loading the case gives
not storedThe setup only. Every plot opens empty until you run the case yourself.
viewThe diagnostic files are there: every viewer opens straight away. But pressing Run restarts the case from t = 0, because the particle state is not there.
view + continueThe restart point is there too: the plots open at once and Run carries on from the converged state.

Cases that never have a run — the [motion] and [xsec] cases, computed on the fly by their own module — show nothing in that column. Selecting a case shows a coloured strip under its description that says the same thing in words and offers exactly what the case is missing: Get results (the diagnostic files, with their size), Results + restart or Add restart point (the checkpoint, to be able to continue the run). To free the disk, right-click the case and choose Remove stored results… — the case keeps its setup and its description, and the results can be downloaded again at any time. A download runs in the background with a progress window and can be cancelled; the case row is refreshed when it finishes.

The Get all results… button at the bottom of the browser fetches the view pack of every case that has none, in one go, after telling you how much it will transfer. It is meant for the user who unticked the box during installation, or who wiped a working folder: without it the only way back to a full library used to be re-running the installer. The restart points are deliberately not included — they are the large part — and are added one case at a time.

ℹ️ Everything works offline except the transfer itself. The symbols are read from the disk, so the tree is always coloured; the published index (file sizes) is cached under JSON\ after the first successful fetch, so sizes still display without a connection. If the index cannot be reached, the tree and the strip still work — only the sizes and the download buttons go away.

The Case Library

Rubrics are numbered, which sets their display order. The library keeps growing, and a few entries are aliases — pointers to the canonical copy of a case that lives in another rubric. Most cases have stored results — the converged run — that can be fetched from the browser (see Stored results above), so they can be visualized immediately after loading without re-running. The tour below follows the rubric order; the references are those cited in each case's own description.

💡 In the parameter columns below, pressures are quoted as the value stored in input.nml (in torr) with the approximate Pa equivalent; magnetic fields are given in gauss (100 G = 0.01 T). These are the bundled reference values — the whole point is then to vary them.

01 — Basic Plasma Physics

The teaching rubric: the most elementary, cleanest illustrations of the physics a PIC-MCC code captures, each meant to be understood in full before moving to a real discharge. Seven sub-rubrics, in this order — the sheath and plasma potential, the sheath in an oblique magnetic field (placed right after the unmagnetized sheath it extends), collisional diffusion, electron plasma (Langmuir) waves, ion-acoustic waves, plasma expansion, and the link between PIC and the 0D global model. Most are collisionless and periodic or source-driven, and each ships with a detailed description that derives the theory the simulation then verifies.

💡 If this is your first contact with the library, the elementary material now sits one rubric further on: 11 — Appendix opens with four pages of definitions (lengths, frequencies, velocities, and how the physical scales fix the grid and the time step) and continues with two interactive rubrics that need no simulation at all. Rubric 01 assumes those are known.
Sub-rubric / caseWhat it showsKey parameters
Plasma sheath – plasma potential — how the wall sheath and the plasma potential are set by the electron temperature (Bohm criterion, presheath). Refs: Riemann (1991); Lieberman & Lichtenberg.
Uniform Collisionless Plasma SourceA uniformly sourced collisionless plasma between grounded walls: the space-charge sheaths, the plasma potential Φp ≈ 5 Te, and the ion flux reaching the Bohm speed at the sheath edge.He, gap 5 cm, collisionless (p = 0), n0 = 1014 m⁻³, Te = 2 eV, mid-gap refluxing heating.
Limited Collisionless Plasma SourceThe same physics with the source confined to part of the gap, showing how the presheath extends over the source-free region.As above, source over a central sub-interval.
Influence of CollisionsThe collisional modification of the sheath and presheath when a finite gas pressure is added.He at finite pressure, otherwise as the uniform case.
Collisional plasma diffusion — ambipolar transport. Ref: the classic ambipolar-diffusion theory.
Ambipolar DiffusionA source-sustained collisional plasma diffusing to absorbing walls at the common ambipolar rate; verifies the cosine density profile and the ambipolar coefficient Da.He, collisional, central volume source + thermalization, absorbing walls.
Langmuir waves — electron plasma waves, from linear Landau damping to nonlinear trapping. Refs: Landau (1946); O'Neil (1965); Bernstein-Greene-Kruskal (1957).
Bohm-Gross WaveA small (2%) single-mode seed: a standing Langmuir wave at the kinetic frequency (just above Bohm-Gross) that decays by collisionless Landau damping — a straight line on a log-U plot.Periodic, L = 6 cm, n0 = 2×1014 m⁻³, Te = 3 eV, immobile ions, mode m = 4, δn/n = 2%.
Non-linear Electron WaveThe same plasma and mode at δn/n = 30%: electron trapping, four cat's-eye BGK vortices per side, O'Neil envelope rebound, an EEPF plateau — Landau damping quenched.As Bohm-Gross but δn/n = 30% (single parameter changed).
Ion-acoustic waves — the low-frequency ion branch. Refs: Chen.
Generation of Ion Acoustic WavesA periodic central source launches ion-acoustic wave packets; the (k, ω) spectrum lands on the ion-acoustic dispersion ω = k cs/√(1+k²λDe²).He, gap 20 cm, p = 0, half-sine source at mid-gap every 1 µs over 11 µs (4 mm raised-cosine profile).
Wave BreakingThe same drive at large amplitude, driven into nonlinear steepening and wave breaking.As above, larger source amplitude.
Plasma expansion — the collisionless expansion of a bounded plasma. Refs: the self-similar plasma-expansion / ion-front theory.
Plasma Expansion in VacuumA dense plasma slab released into vacuum: the ambipolar field at the edge accelerates a supersonic ion front — the kinetic result a fluid model misses.He slab, Te = 3 eV, Ti = 0.026 eV, absorbing walls, released at t = 0.
Influence of CollisionsThe same expansion with a finite gas pressure, showing how collisions slow and reshape the front.As above, finite pressure.
PIC-MCC and the global model — the bridge from the full kinetic simulation to the 0D power/particle balance.
Global ModelA steady RF-heated discharge compared against the 0D global model: particle balance fixes Te, power balance fixes n0; the PIC Te, density and power/particle budgets are read against the analytic prediction. Ref: Lieberman & Lichtenberg.Ar, gap 4 cm, 50 mTorr, Maxwellian power deposition.
Sheath in an oblique magnetic field — the magnetized sheath and the Chodura layer: three nested scales, λD ≪ ρs ≪ L. The ion flow enters the magnetic presheath at the Chodura level cs sin α along the wall normal and leaves it at the Bohm level cs at the entrance of the Debye sheath; the total potential drop hardly depends on the angle (4.0–4.4 Te throughout), the wall flux follows sin α. Five runs that differ by one line of the namelist. Common settings: He, collisionless, Te = 2 eV, n0 = 1015 m⁻³, B = 500 G, gap 18 cm, 1080 cells, dt = 20 ps, source confined to the central fifth of the gap, electron thermostat at mid-plane, btype = 4 with bfield_angle (angle from the wall). Refs: Chodura, Phys. Fluids 25, 1628 (1982); Riemann (1994); Coulette & Manfredi (2015); Moritz et al., Phys. Plasmas 28, 083501 (2021).
Case 1 — reference, B at 30°The case the others are read against: both layers visible at once. Plateau of the normal ion velocity at 0.53 cs (Chodura level 0.50), Bohm crossed at 11 λDe, source-free ion flux constant to ±5 % — the check that certifies convergence.α = 30°, 300 µs (≈58 ion gyroperiods).
Case 2 — B at 60°Near-normal field: the plateau rises to 0.81 cs (0.87 predicted), the presheath width matches √6 ρs sin ψ to 1 %, the wall flux is the parallel flux times sin α to 4 %, and the potential barrier does not move.α = 60°, 481 µs.
Case 3 — grazing, B at 5°The divertor limit: a plateau at 0.10 cs, a presheath 20 mm wide, half the potential drop spread over 23 λDe, and the slowest convergence of the series (~400 µs) — a run that looks finished but is not can give the wrong sign.α = 5°, 494 µs.
Case 4 — cold ions, 30°First arm of the width test: Ti = 0.026 eV lowers cs and ρs (7.7 → 5.8 mm) and leaves λDe untouched. Without ion pressure the Chodura plateau disappears — the velocity rises through cs sin α without pausing.As Case 1, Ti = 0.026 eV.
Case 5 — low density, 30°Second arm: the density divided by 6.4 multiplies λDe by 2.5 and leaves ρs alone. Counted in Debye lengths the sheath of Case 5 lies on top of that of Case 4 — the space-charge layer is a Debye object whatever the obliquity; the magnetic field adds a presheath in front of it.As Case 4, n0 = 1014 m⁻³, 400 cells, 150 µs.
ℹ️ The oblique-field sub-rubric is also reachable as an alias under rubric 08 — Magnetized Plasmas. Its GUI counterpart is the Oblique B field (x-y plane) orientation of Conditions → B Field, and case 4 of the Single-Particle Motion module shows the same geometry on a single particle.

02 — Swarm Physics

The electron-swarm rubric, run in JC-PIC's dedicated Swarm mode (a homogeneous, field-driven electron gas — no space charge). It computes transport and rate coefficients as functions of the reduced field E/N and reproduces the classic swarm experiments. Loading one of these cases switches the application to Swarm mode automatically (they carry an input_swarm.nml and are flagged [swarm] in the browser). See the Swarm Mode chapters for the method.

Sub-rubric / caseWhat it showsKey parameters
Collisions and cross sections — an alias to the interactive rubric of the Appendix (11/03). The swarm coefficients are integrals over the cross sections, so the rubric opens with the chance to look at them first.
Calculation of swarm parameters — drift velocity, diffusion and rate coefficients vs E/N from the steady swarm.
Swarm Parameters in NeonA complete sweep of the transport and rate coefficients of an electron swarm in neon, with measured error bars on every number, ending on the coefficient that decides whether a plasma stays uniform (DT/µ).Neon, swarm mode, E/N swept.
Comparisons with MCIGThe swarm mode against MCIG, Hagelaar's Monte-Carlo companion to BOLSIG+ (2025): same sampling at tentative collisions, same renormalization of ionization and attachment, same displacement-based diffusion. The bundled run is oxygen (17 processes, attachment below 30 Td); neon, argon, N₂ and CF₄ use identical settings.O₂, 30 values of E/N from 1 to 2000 Td, 48 × 2000 replicas, PT growth mode.
Swarm experiments — the drift tubes themselves, simulated with the 1D PIC engine (electrodes, finite length, injected current), to see what a measurement actually returns.
Pulsed TownsendThe time-resolved relaxation of a released electron pulse — the pulsed-Townsend way of extracting transport and ionization coefficients.Neon, pulsed release.
Steady-State TownsendThe spatial growth of a continuously injected swarm — the steady-state-Townsend geometry.Continuous injection.
Franck-Hertz experimentThe founding experiment of quantum physics read as a steady-state Townsend discharge below the ionization threshold: the mean electron energy oscillates in space with a period of 3.72 cm, i.e. 18.6 eV — above the 16.6 eV first threshold of neon, and the description says why.Ne 1 Torr, gap 40 cm, −200 V (E/N = 15.5 Td), 1 eV beam of 10⁻³ A/m², Laplace mode (no_poisson = 1).

03 — Electron Emission from Cathode

Emission-limited diodes and self-sustained thermionic discharges, illustrating space-charge-limited current and the temperature-limited, anode-glow and self-oscillating regimes.

CaseWhat it showsKey parameters
Vacuum Diode — a plane diode in vacuum (cathode at −V, grounded anode).
Child–LangmuirThe Child–Langmuir space-charge-limited current for monoenergetic electrons. Refs: Child (1911); Langmuir (1913).Vacuum, V = 50 V, gap 2 cm, injection energy 5 eV.
Thermionic EmissionStable thermionic emission (half-Maxwellian flux with optional drift), no oscillation: part of the emitted electrons are turned back by the potential minimum near the cathode.Vacuum, V = −50 V, gap 2 cm, J = 50 A/m², Te = 3 eV.
Thermionic Emission Test CaseVerification against Turner's exact kinetic solution for Maxwellian emission between two grounded walls: the potential well Φm and the transmitted current depend on the gap in Debye lengths only. JC-PIC gives φmin = −23.9 V against −24.0 V and J = 79 against 77 A/m².Λ = L/λD = 20, T0 = 10 eV, n0 = 1016 m⁻³, both walls grounded.
Virtual Cathode OscillationsA beam injected above the space-charge limit forms a virtual cathode and, beyond a second threshold, oscillates.Vacuum, V = 50 V, gap 2 cm, beam 50 A/m² at 20 eV.
Thermionic Discharge — collisional, self-sustained; illustrates the TLM, anode-glow and self-oscillating regimes. Refs: Greiner et al. (1993, 1995); Campanell & Umansky (2017); Campanell et al. (2025).
Temperature-Limited Current (TLM)The temperature-limited regime with a classical ion-rich sheath.He ≈2 Pa, gap 15 cm, V = −40 V, J = 0.2 A/m².
TLM with Beam-Plasma InstabilityA TLM in which the sheath-accelerated beam drives a beam-plasma (Langmuir-wave) instability.He ≈0.67 Pa (50 mTorr), gap 15 cm, J = 2 A/m².
Anode Glow Mode (AGM)The low-current regime with an inverted cathode sheath and ionization confined near the anode.He ≈1.07 Pa (8 mTorr), gap 10 cm, V = −27 V.
AGM Self-OscillationsThe same conditions run long enough to show low-frequency relaxation oscillations (internal double layer).As AGM, extended over hundreds of µs.

04 — DC and Transient Glow Discharges

Classical DC glow discharges and pulsed plasma-immersion ion implantation.

CaseWhat it showsKey parameters
Helium Glow DischargeA DC glow discharge in helium with secondary electron emission.He ≈1 Torr, gap 4 cm, V = −160 V, γSEE = 0.32.
GD BenchmarkThe DC helium glow-discharge benchmark of Carlsson et al., PSST 26, 014003 (2017) (EDIPIC vs LSP, validated against the Lawler experiment), with Okhrimovskyy anisotropic scattering, the negative-glow trapped electrons and the convergence question they raise.He 3.5 Torr, gap 6 mm, V = −211 V, 1024 cells.
Supersonic PIIIPlasma-immersion ion implantation: a fast high-voltage pulse drives a supersonic sheath expansion and a near-monoenergetic ion flux. Ref: Stewart & Lieberman (1991).He 1 mTorr, gap 1 cm, pulse 0→−1 kV in 50 ns.
Subsonic PIIIThe subsonic regime (pre-sheath, ions reaching the Bohm speed), driven by an external voltage waveform.He 1 mTorr, gap 1 cm, voltage from file.

05 — RF Capacitive Discharges

The richest rubric: capacitively coupled RF discharges, with benchmarks, the eduPIC reference, dual-frequency electrical asymmetry, power-absorption analysis, frequency effects and magnetized variants.

Sub-rubric / caseWhat it showsKey parameters
Benchmarks — the four reference RF discharges. Ref: Turner et al., Phys. Plasmas 20, 013507 (2013). All in helium, gap 6.7 cm, 13.56 MHz.
Case 1Lowest pressure, highest voltage: a single central ionization maximum, the non-local regime.He 0.030 Torr (≈4 Pa), VRF = 450 V.
Case 2 / 3 / 4Increasing pressure, decreasing voltage along the benchmark series — the central maximum turns into two sheath-edge peaks as the energy relaxation length drops below the gap.He 0.10 / 0.30 / 1.0 Torr; VRF = 200 / 150 / 120 V.
Case 2 — current driven, 10 A/m²Case 2 turned around: the RF current density is imposed and the voltage is the answer. A worked example of the current-source drive (Conditions → Voltage / Current) and a closure test — driven at the 9.26 A/m² fundamental measured on the voltage-driven run, the discharge returns 196 V against the 200 V imposed.As Case 2, J1 = 9.26 A/m² at 13.56 MHz; requires a Fresh Start.
JC-PIC vs BenchmarkNo case to run: the four time-averaged profiles (ionization rate, electron and ion power, density) on the axes of the paper's Figs. 3–5, for a comparison at a glance. Density agreement within 2.7 % on the worst case.Reading only.
EduPIC — the reference discharge of the open-source eduPIC code, used above all to illustrate numerical convergence: because of the Ramsauer minimum the cold trapped electrons are extremely sensitive to the grid and to the number of particles per cell. Ref: Donkó et al., PSST 30, 095017 (2021). Argon 10 Pa, gap 2.5 cm, 250 V, 13.56 MHz.
Argon 10 Pa 250 V 13.56 MHzThe reference at the resolution of the paper (400 grid points, ≈275 ions per cell): a code-to-code comparison at matched resolution, and the starting point of the convergence study.Ar 0.075 Torr, 400 cells, ≈275 ions/cell.
Sensitivity/AccuracyThe same discharge well resolved — 800 points and ≈1000 ions per cell — so every difference is numerical. Also the worked example of how a number of particles per cell is imposed with Max # particles and thinning. Long run (~300 µs).Ar 0.075 Torr, 800 cells, ≈1000 ions/cell.
Pressure effect — Godyak et al. — one argon discharge followed across three decades of pressure at fixed current, and what the electrons do: the effective temperature is non-monotonic, with a minimum near 10 mTorr where the EEPF is two-temperature (a cold group trapped in the Ramsauer window), then a steep heating-mode transition between 40 and 100 mTorr. Helium, without a Ramsauer minimum, is the control. Refs: Godyak, Piejak & Alexandrovich, PSST 1, 36 (1992); Phys. Rev. Lett. 65, 996 (1990). Gap 6.7 cm, 13.56 MHz, current-driven at 10 A/m².
Ar 10 mTorr 10 A/m²The bottom of the scan, stochastically heated: the two-temperature EEPF and the abnormally low effective temperature. The point most sensitive to numerical noise — see the convergence warning in the description.Ar 10 mTorr, J = 10 A/m².
Ar 100 mTorr 10 A/m²Ten times the pressure, just past the transition: the cold peak has gone, Teff ≈ 3 eV, quantitative agreement with the measurement.Ar 100 mTorr, J = 10 A/m².
He 30 mTorr 10 A/m²The control gas: no Ramsauer minimum, so an ordinary, monotonic behaviour at a pressure higher than the anomalous argon point.He 30 mTorr, J = 10 A/m².
Dual frequency — electrical asymmetry effect: the phase θ between 13.56 and 27.12 MHz sets the DC self-bias. Refs: Heil et al. (2008); Donkó et al., J. Phys. D 42 (2009). Argon 0.02 Torr, gap 6.7 cm, 315 V each.
Phase shift 90° / 60° / 45° / 0°A sweep of the phase angle θ showing how the self-bias and the ion energy at each electrode follow it. The agreement with Donkó et al. is quantitative: η = −212.5 V at θ = 0° against their −213 V, and the asymmetry parameter ε(θ) = 0.74 / 0.93 / 1.07 / 1.32 against 0.74 / 0.95 / 1.06 / 1.33.θ = 90°, 60°, 45°, 0°.
Power absorption — electron-power decomposition (Schulze analysis) versus pressure. Ref: Schulze et al., PSST 27, 055010 (2018). Argon, gap 5 cm, 400 V, 13.56 MHz.
50 / 20 / 5 / 1 PaFour cases sweeping the pressure, to be read with the Heating viewer's ohmic / pressure decomposition.Ar 0.375 / 0.15 / 0.0375 / 0.0075 Torr.
Frequency effects — controlling density and ion energy independently through frequency and voltage at very low pressure: at fixed voltage the density stays on a constant-density plateau over a range of frequencies while the ion energy rises, then climbs steeply above a transition while the ion energy stops moving. Refs: Sharma et al., Phys. Plasmas 25, 080705 (2018); Sharma et al., Phys. Plasmas 23, 110701 (2016). Argon 5 mTorr, gap 3.2 cm, 512 cells, 100 particles/cell, no secondary emission.
Cases 1 / 2 / 3 — 100 V at 27.12 / 40 / 70 MHzThe frequency scan at 100 V (seven runs in the description, three shipped): 27.12 and 40 MHz are the two ends of the plateau — same density to 3 %, ion energy up 23 % — and 70 MHz is above the transition, 5.3 times the plateau density at the ion energy of 27.12 MHz. JC-PIC leaves the plateau one step earlier than the reference (between 40 and 50 MHz).100 V; 27.12, 40, 70 MHz.
Cases 4 / 5 — 50 and 150 V at 27.12 MHzThe voltage series at the reference frequency, the closest agreement of the section: the most probable ion energy within 2–3 % of the paper at all three voltages (45.5, 65.5, 84.5 eV), density ×7 for voltage ×3.27.12 MHz; 50, 150 V.
Cases 6 / 7 — 50 V at 45 and 50 MHzThe transition of the 50 V branch, built to test where the plateau ends: the discharge leaves it exactly where the reference does, between 40 and 45 MHz. The best-converged runs of the series.50 V; 45, 50 MHz.
Magnetized RF — the magnetic asymmetry effect: a transverse field graded across the gap creates a DC self-bias, the magnetic analogue of the electrical asymmetry effect. Refs: Yang et al. (2017); Sharma et al. (2018). Argon 0.03 Torr, gap 2.5 cm, 150 V, 13.56 MHz.
Cases 1–3: Yang 0–100 / 10–100 / 50–100 GA ramp of the field from the powered electrode to 100 G at ground, swept at the powered end. The plasma structure agrees closely with Yang et al. — density peak at x/L = 0.60 and 0.56, peak densities within a quarter, plasma potential 58–63 V — and the shape of the bias-versus-field curve is reproduced, while the self-bias itself differs by a factor of about two throughout the series; the sub-rubric description presents the two remarks that may locate the difference (the accuracy of the Heil estimate, the resolution of the sheath edges) as open points that a joint comparison of the two codes would settle.Bleft = 0, 10, 50 G; Bright = 100 G.
Case 4: Sharma B = 35 GA uniform transverse field with no blocking capacitor, so the self-bias is imposed to be zero: the asymmetry then shows up in the plasma itself, as a spontaneous breaking of the π-rotation symmetry about B. The description also carries a section on what a one-dimensional model cannot see here.He, gap 10 cm, 1000 V at 27.12 MHz, 10 mTorr, uniform 35 G, bias_cap = 0.
💡 The uniform-field member of the graded series (100 G on both sides) is an internal check: symmetry requires a strictly zero bias, and JC-PIC returns a bias below 0.2 V on a 150 V drive, with a density profile that coincides with its own mirror image to 0.23 % rms.

06 — Positive Column

The positive column of a long discharge, modelled in periodic mode (one axial period) or in a slab: ionization waves (striations), radial non-equilibrium, and the Hall effect.

Sub-rubric / caseWhat it showsKey parameters
Striations — axial ionization waves. Refs: Boeuf, Phys. Plasmas 29, 022105 (2022); Dosbolayev et al., Phys. Plasmas 31, 073509 (2024).
DC PeriodicA DC neon column in periodic mode with a fixed axial field and wall losses by random pair removal.Ne 1 Torr, gap 6 cm, periodic, E = −600 V/m.
RF boundedStanding striations in a tubular RF discharge (imposed radial losses).Ar 0.1 Torr, gap 10 cm, 300 V, 10 MHz.
Positive Column in a slab — the transition from local to non-local electron kinetics, at fixed geometry, with the pressure as the only knob. Ref: Nakamura & Ingold, J. Phys. D 34, 3150 (2001). Argon, slab 5 cm, self-adjusted axial field.
Case 1 — Ar 100 mTorr, collisionalThe local regime: Ez settles at 90 V/m (28 Td), collisions carry the losses (collision/wall power ratio 45), and the mean electron energy falls from 5.5 eV on axis to 2.1 eV at the edge.Ar 0.1 Torr, 300 cells, self-adjust on.
Case 2 — Ar 1.2 mTorr, non-localThe non-local regime: dividing N·d by 80 multiplies the reduced field by 16 (18.4 V/m, 460 Td), the power ratio drops from 45 to 1.5, and the mean-energy profile becomes flatter, not more peaked — the energy relaxation length now exceeds the slab. The ions arrive as a beam: IFEDF peaked at the full 18.5 V drop, T below 0.12 eV.Ar 1.24 mTorr, same gap and grid, 400 particles/cell.
A caveat the two cases settle: the EEPF plotted against total energy collapses onto one curve at both pressures, to 4–5 % over four decades, so that test does not separate the regimes. What has to exceed the discharge size is the energy relaxation length λ/√δ — two hundred mean free paths in argon, i.e. 68 cm at 100 mTorr against a 5 cm slab.
Hall Effect — a transverse B field drives an E×B drift and a transverse Hall field. Ref: Boeuf & Smolyakov, Phys. Plasmas 30, 050901 (2023). Argon 0.1 Torr, gap 5 cm.
B = 0 / 50 / 100 / 150 GA field sweep showing the onset of the Hall field and the E×B drift.B = 0, 50, 100, 150 G.

08 — Magnetized Plasmas

Four magnetized configurations: the azimuthal Hall-thruster E×B instability — a series of its own — and three aliases to series that live elsewhere: the Hall effect in a positive column (rubric 06), the magnetized RF discharge (rubric 05) and the sheath in an oblique field (rubric 01). The chapter description puts numbers on the one asymmetry everything here comes from: the field acts on the electrons long before it acts on the ions.

Sub-rubric / caseWhat it showsKey parameters
Hall Thruster – E×B Instability (ECDI) — the electron-cyclotron drift instability in the azimuthal direction of a Hall thruster, and the anomalous axial transport it produces. Refs: Boeuf & Smolyakov, Phys. Plasmas 30, 050901 (2023); Charoy et al., PSST 28, 105010 (2019); Lafleur, Baalrud & Chabert (2016). Periodic, collisionless, B = 200 G, particles renewed after a virtual axial length of 1 cm; box = 15 resonant wavelengths λ₁ = 2πvEce (the distance an electron drifts during one gyration) except in Case 0.
Case 0 — quick look, argonThe same instability in about a quarter of an hour instead of half a day, by combining four independent savings (argon, 6 wavelengths, 150 particles/cell, 8 ps). It saturates at 82–85 eV of mean electron energy against 81 eV for the reference in the same box, so the coarser sampling does not change the saturated state.Ar, 432 cells, 150 ppc, dt = 8 ps, 6 µs.
Case 1 — xenon, E = 20 kV/m (reference)The reference run. Dominant wavelength 1.787 mm (mode m = 15, the cyclotron prediction to a part in a thousand), phase velocity ≈8×10³ m/s — an ion-acoustic wave selected by the electron cyclotron resonance — and the anomalous axial transport it produces. The turbulence is intermittent, and the inverse cascade reaches the box scale near 23 µs.Xe, n0 = 1017 m⁻³, 1080 cells, 781 ppc, dt = 5 ps, gap 26.8 mm.
Case 2 — E = 10 kV/mThe low point of the field scan. λ₁ is proportional to E, so the box halves to keep fifteen wavelengths; the spectrum peaks again at m = 15 — the mode number did not move, the wavelength followed the field.Xe, 540 cells, gap 13.4 mm, 27 µs.
Cases 3 / 3b — E = 40 kV/m (diverged)The high point of the scan, kept as a counter-example: the inverse cascade reaches the longest mode of the box within about 2 µs and the electron energy runs away to several keV. Case 3b, rerun with an adaptive time step, diverges identically — the runaway is the physics of a fifteen-wavelength box at this field, not the numerics. The cure would be a box of thirty wavelengths.Xe, 2160 cells, gap 53.6 mm.
Cases 4 / 5 — n = 5×10¹⁶ and 2×10¹⁷ m⁻³The density scan, the most direct test of the cyclotron nature of the instability: λ₁ depends on the fields alone, so it must not move with the density, while an ion-acoustic turbulence would follow the Debye length (m ≈ 10.6 and 21). Both runs peak at m = 15. Case 4 has the cleanest spectrum of the section; Case 5 is contaminated by the box mode over its diagnostic window, because the cascade is faster at higher density.Xe, 768 and 1536 cells, dt = 5 and 3.5 ps, gap 26.8 mm.
Hall Effect in Positive ColumnThe four B-field cases (0 / 50 / 100 / 150 G) — an alias of the series under rubric 06.Ar, transverse B.
Magnetized RF DischargeThe Yang graded-field series and the Sharma uniform-field case — an alias of the sub-rubric under rubric 05.Ar / He, RF, transverse B.
Sheath in an Oblique Magnetic Field (Chodura)The five Chodura cases — an alias of the sub-rubric under rubric 01.He, B = 500 G, α = 5–60°.

10 — Plasma Instabilities

Kinetic beam-driven instabilities in their cleanest, periodic form.

CaseWhat it showsKey parameters
Two-stream instability — beam–plasma, Buneman and symmetric two-stream. Refs: Chen (2016); Birdsall & Langdon (2004); Krall & Trivelpiece (1986).
Beam-Plasma Instability (periodic)A dilute (5%) beam in a Maxwellian background resonating with Langmuir waves, forming phase-space holes. Ships with the t = 0 state only — meant to be run.Periodic, gap 2 cm, beam 10 eV at 5%, bulk Te = 5 eV.
Beam-Plasma Instability (bounded)The same beam-plasma resonance in a bounded (electrode) geometry rather than periodic, closer to a real injected-beam experiment.Bounded gap, beam in a Maxwellian background.
Buneman InstabilityThe electron–ion instability driven by a global electron drift exceeding the thermal speed (anomalous resistivity).Periodic, gap 6 cm, electron drift 10 eV, Te = 5 eV.
Symmetric Two-StreamTwo identical counter-propagating electron beams (the classic symmetric two-stream setup).Periodic, gap 3.5 cm, drifts ±2 eV, two_stream = 1.
Sheath Oscillations — virtual-cathode oscillations and the anode glow mode. Both entries are aliases of the corresponding cases under rubric 03 (Electron Emission).
Positive-column striations — the two ionization-wave cases (DC periodic, RF bounded), an alias of the sub-rubric under rubric 06 (Positive Column), so they also appear among the instabilities.
ECDI – Hall thrusters — the electron-cyclotron drift instability: the whole Hall-thruster series (Cases 0–5), an alias of the sub-rubric under rubric 08 — Magnetized Plasmas. The chapter description classifies the instabilities by their source of free energy — directed motion (two-stream, ECDI) or the ionization–field coupling (striations).
ℹ️ A few entries are aliases (a small pointer file rather than a full case) so the same physics can appear under more than one rubric — for example the bounded beam-plasma case and the sheath-oscillation cases point to their canonical copies under "Electron Emission". Loading an alias loads the case it points to.

11 — Appendix

The rubric that has no simulation in it. It gathers what the rest of the library assumes you already know, and what JC-PIC reads rather than computes. Its first sub-rubric is four pages of reading; the other two are interactive — every one of their cases opens a module, not a run, and answers in milliseconds. Nothing here needs a working directory, and nothing here writes anything.

Sub-rubric / caseWhat it showsKind
01 — Basic Concepts and Definitions — the vocabulary, in four pages, each self-contained.
Lengths — Debye shieldingThe Debye length, the plasma parameter, the sheath thickness, the mean free path and the Larmor radius: which one is the small one, and when.reading
Frequencies — plasma, cyclotron, collisionωpe, ωpi, ωce, ωci and ν, and the dimensionless ratios (Hall parameter, ωce/ν) that decide the regime.reading
Velocities, temperatures and distributionsThermal speed, drift, Bohm speed; Maxwellian and Druyvesteyn; what an EEPF is and why it is plotted the way it is.reading
From physical scales to numerical onesHow the three previous pages fix Δx, Δt and the number of particles per cell — the bridge to PIC in a Nutshell.reading
02 — Single-Particle Motion — eight cases opening the Single-Particle Motion module, marked [motion].
Cases 1–8Gyration in a uniform field (with an explicit-Euler counter-example); the E×B drift with an electron and an ion together; E along B; the oblique Chodura geometry; the grad-B drift; the magnetic mirror and its loss cone; collisions across B with real argon cross sections; and a free exploration.interactive
03 — Collisions and Cross Sections — seven cases opening the Collisions and Cross Sections module, marked [xsec]. Aliased at the head of rubric 02 (Swarm Physics).
Views 1–7σ(ε) per process and the Ramsauer minimum; mean free path and collision frequency; the null-collision method and its νmax; the distribution of free-flight times; what one collision does; the Maxwellian rate coefficients k(Te) and the energy cost of an electron–ion pair; and a free exploration. The sub-rubric description carries the classical two-body theory, with three diagrams.interactive
💡 Two ways in. Input → Load Test Cases… then 11 — Appendix opens each module locked on a prepared configuration, which is the teaching path. Input → Single-Particle Motion… and Input → Collisions and Cross Sections… open the same modules unlocked, on whatever you last did with them.

Contributing a Case

The library is meant to grow with its users. A case you build and find worth sharing — a configuration from your own work, a published result you have reproduced, a clean illustration of an effect — can be folded into the distributed library: prepare it with Add my case…, complete its description, and send the folder to the author (addresses in JC-PIC → About… and on jc-pic.org). A case that is integrated is published under your name, as its author, in the application, on the website and in the book. What makes it publishable is less the run than its description: the _info.md of the folder is what the browser renders, what the website shows and what the book is built from, so it follows a few conventions that are worth knowing before writing one.

ConventionWhy
One Markdown file, _info.md, per case and per sub-rubric, with the usual sections: what the case shows, the simulation conditions (gas, pressure, gap, voltage, grid, time step, particles per cell, duration and averaging window), the results with their figures, what the case establishes, and numbered references.The same file feeds three readers — the browser pane, the website page and the book — through the same Markdown exporter, so a description written once looks right everywhere. Mathematics is written in LaTeX between $…$ and rendered with MathJax; tables are inserted as images rather than Markdown tables, which the browser pane cannot render.
Figures are 8 cm wide when they hold one plot across, 16 cm when they hold two or more, white margins trimmed, with the physical width stamped into the PNG itself (its dpi metadata, 200 dpi at full resolution).This is what makes the figures land at the same size on the website, in the book and in Word: each reader trusts the width written in the file. Label fonts are sized so that they print at about 12 pt whatever the figure size — for a 16 cm figure drawn 10 in wide that means 20 pt labels. A figure that does not follow the rule is normalized by the maintainer's tools when the case enters the library.
Describe the physics, not the work. A description never refers to its own history — no "now converged", "earlier analysis", "this run removes that doubt".A reader opens a case months later; what was uncertain last week is either a physical property or a general caveat, and is written as such.
Say what a run is worth. The averaging window, the convergence check that certifies it (constancy of a conserved flux, stationarity of the monitored quantities), and any known limitation of the run.It is what lets a reader use the numbers — and rerun the case at another setting with a fair idea of what to expect.
💡 The library's own build tools live with the maintainer: the book and the website are regenerated from the CASES tree by scripts that also read the figure widths back from the files and can re-stamp them (the book, opened with #edit appended to its address, offers a right-click menu to try a width and prints the command that makes it permanent). None of this is needed to write a case — a folder with an input.nml, an _info.md and its figures is a complete contribution.

🖱️ Working with Viewers

JC-PIC ships with a dozen diagnostic viewers — density profiles, position–time contours, phase space, energy distributions, currents, and so on. They all share the same window framework and the same interaction model, so once you are comfortable with one, you know them all. This chapter describes that common behaviour — the settings panel, rearranging a plot with the mouse, adding text, saving, exporting and recording. Each viewer's own chapter then only covers what it plots and the controls specific to it.

Every viewer is an independent window, opened from the Graphics menu of the main window, and several copies of the same viewer can be open at once. Viewers update themselves continuously while a simulation runs and also work on a stopped or paused run, where they simply show the last available frame.

The settings panel (⚙)

A viewer has no conventional menu bar. Instead, a single gear button at the top toggles a floating Settings panel that holds every control. The panel docks to the right of the viewer window and follows it when you move the window; click ⚙ again, or the panel's close box, to hide it. Changes are applied when you press Enter in any field or click Apply (labelled OK in earlier versions).

The panel groups its controls into rows. The exact set depends on the viewer, but the recurring ones are:

ControlWhat it does
min / max / stepThe range and tick spacing of each axis. Type a number, or leave auto for automatic scaling.
Log + decSwitch an axis to a logarithmic scale. The range rule (uniform across viewers): with min and max both auto, the top decade is the data maximum and dec sets how many decades are shown below it; an explicit min or max overrides the corresponding end (and dec is ignored when min is explicit).
Auto / FixAuto returns every range to automatic; Fix freezes the current ranges as fixed numbers.
GridToggles the background grid.
Labels: Full / No titles / BareHow much annotation is drawn — everything, axis labels and ticks only, or a bare plot (useful when you will caption the figure elsewhere).
Line −/+, Font −/+, Plot size −/+Line thickness, text size (the window grows so the plot keeps its size), and the size of the plot area within the window.
ColoursA swatch per curve opens a colour picker; 2D viewers instead offer a colour-map picker and a Flip button.
Rst Pos / Rst AllRst Pos restores the default element positions; Rst All is a full factory reset (it also clears text labels).
→ All …Propagates the common look (window size, fonts, margins, label mode) to every other open viewer of the same family at once.

Rearranging the plot with the mouse

The layout of a plot is fully adjustable by direct manipulation, and every change is remembered per viewer and restored next time.

Rst Pos in the settings panel undoes any of these positional changes at once.

Adding and editing text

You can drop free text anywhere on a plot — to label a feature, note a parameter, or annotate a figure for a paper.

⚠️ The × factor deliberately does two things not. The tick positions do not move — they stay where matplotlib put them for the raw values and merely re-read themselves; if that leaves you with awkward numbers, use the tick-spacing field, which is in the same dialog. And the axis title is not rewritten: it is up to you to retype V (kV) or f (MHz) — including the ×10n of a colour bar, which becomes wrong the moment the scale changes. Rewriting a title the user has customized would do more damage than service.

Text labels are saved with the viewer and reappear the next time it is opened.

Saving, exporting and recording

💡 Record All Viewers. To film every open viewer at once, use Window → Record All Viewers…: one dialog sets a common format, rate and optional simulation-time window, and its Start / Pause / Resume / Stop All buttons drive the recordings of all open viewers in step, with a live aggregated frame counter. On Stop-All you are asked whether to save the movies.
💡 Several viewers add their own direct interactions on top of this common base — for example, right-clicking an X-T or EEPF-2D contour map opens a 1D slice in which Ctrl+right-click pins several curves with a legend. Those viewer-specific gestures are described in each viewer's own chapter.
💡 The live refresh rate of the 1D Profile viewers is set by Live 1D refresh rate (fps) on Conditions → Diagnostics → Write/Store. A viewer opened on a stopped run shows the last frame written to disk.

The Averaged checkbox, and when it is greyed out

The profile viewers plot either the latest snapshot or the running time-average of the same quantity, chosen with the Avg / Averaged checkbox. The averaging is done by the engine, not by the viewer, and it only starts at the instant set by Conditions → Diagnostics → General → Averaging start time.

Before that instant there is nothing to show, so the checkbox is greyed out, with a tooltip saying why. It ungreys by itself as soon as a running simulation crosses the start time — no need to close and reopen the viewer. The guard is deliberately double: it takes both a non-zero accumulation counter and a displayed time beyond the start time. The second half matters in two situations that used to show a frozen average as if it were current — a restart with Reset Time, where the clock goes back but the counter is restored from the checkpoint, and a start time raised from the Conditions dialog during a run, where the engine stops accumulating but the counter stays standing. In the second case the engine now also clears the accumulators, so the average restarts cleanly at the new instant instead of decaying out of stale values.

The rule applies to the Profile, Custom 1D Profile and Collision Frequencies viewers, and to the ASCII export of the averaged profiles, which used to write the frozen file too.

The interactive modules follow the same conventions

The two standalone modules — Single-Particle Motion and Collisions and Cross Sections — are built on the same framework: draggable and editable titles and legends, ⚙ settings, ● Rec with the same recording dialog, and the same Save/Export behaviour. They add a set of mouse gestures of their own, described once in the Single-Particle Motion chapter and identical in both. What they do not share is the data model: they have no working directory, no snapshot and no live refresh, because there is no simulation behind them.

Managing several viewers at once

Because every diagnostic is its own window and several can be open together, a busy session quickly fills the screen. Window → Manage Viewer Windows… opens a compact Viewer Windows panel, docked to the main window, that controls the whole set at once.

The Viewer Windows manager panel
The Viewer Windows panel (Window → Manage Viewer Windows…): one row per open viewer (Raise/Min/), the Tile/Cascade and Raise all/Min all/Close all buttons, the follow-the-main-window toggle, and the pad that moves or resizes every viewer at once.
💡 The same Window menu also offers Close All, which closes every open viewer at once (also available as Graphics → Close All), and Record All Viewers… for synchronized recordings.

📈 Profile Viewer

The profile viewer is the workhorse of one-dimensional diagnostics in JC-PIC. It displays time-averaged radial profiles along the spatial coordinate x for a set of pre-selected combinations of physical quantities. One instance is available per Graphics → 1D Profiles entry, and they all share the same code and the same interaction conventions; only the data plotted differs. A separate viewer for the Schulze power decomposition (Pe ohmic, pressure, etc.) is described in the "Heating Viewer" section; and when none of the fixed pairings fits, the Custom 1D Profile viewer lets you place any profile quantity on either axis and overlay several runs.

Profile viewer showing densities and electric field
Profile viewer in Densities & Field mode, for a dual-frequency capacitively-coupled RF discharge. Time-averaged electron and ion densities on the left axis, electric field on the right axis. The two density curves overlay closely in the bulk and separate in the sheaths where the ion density exceeds the electron density; the two driving frequencies make the discharge asymmetric, so the two sheaths differ.

What can be plotted

Each of the six modes superimposes two y-axes — left for the densities, right for the chosen accompanying quantity — over the same x-axis. The accompanying quantity is what gives each mode its identity:

Menu entryModeLeft axisRight axis
Densities - Field (nₑ, nᵢ, E)fieldne, niElectric field E(x)
Densities - Potential (nₑ, nᵢ, φ)potentialne, niPotential Φ(x)
Densities - Mean Electron Energy (nₑ, nᵢ, εₑ)energyne, niMean electron energy ε(x)
Mean Energy - Ionization Rate (εₑ, nₑνᵢ)ionizMean electron energy ε(x)Ionization rate Si(x)
Power AbsorbedpowerElectron power Pe(x) and ion power Pi(x)
Mean Energy - Ionization Freq. (εₑ, νᵢ)nuionizMean electron energy ε(x)Ionization frequency νi(x)
Mean Energy (εₑ, εᵢ)meanenergyMean electron energy εe(x)Mean ion energy εi(x)
Electron Temperature (Tₑ, Tₑ∥, Tₑ⊥)etempPer-cell, drift-subtracted electron temperatures: total Te (red), parallel Te∥ (blue) and perpendicular Te⊥ (cyan); a Curves selector chooses which are shown
Ion Temperature (Tᵢ, Tᵢ∥, Tᵢ⊥)itempSame for the ions
Electron & Ion Velocities (⟨vₓ⟩ₑ, ⟨vₓ⟩ᵢ)velocitiesMean axial velocities of both species (electrons cyan, ions blue); a Normalize group plots e⁻ as vx/vth and ions as vx/cs for direct comparison with the Bohm speed

Each viewer instance reads the binary diagnostic files written by the engine and refreshes itself automatically while the simulation is running, at the rate set by Live 1D refresh rate on Conditions → Diagnostics → Write/Store (default 10 Hz). The viewer can also be opened on a stopped or paused run, in which case it simply displays the last available frame.

Controls specific to the profile viewer

The profile viewer follows the common window framework described in Working with Viewers — the gear (⚙) settings panel, dragging titles and plot edges, double-click text labels, Save to PNG/PDF/SVG, and so on. The controls particular to this viewer are:

ControlWhat it does
AvgShow the time-averaged profile or, unchecked, the instantaneous profile of the latest snapshot. Every viewer opens unchecked the first time in a JC-PIC session; reopened during the same session it comes back as you left it.
Rst AvgDiscard the running time-average and restart it from the next snapshot — useful after changing a parameter mid-run. It signals the engine to reset its averaging accumulators.
Log + dec, per axisThe left axis (densities) and the right axis (the accompanying quantity) each have their own independent log scale and decade count.
TimeOverlays the current simulation time in a corner of the plot (draggable and editable, like any label).
Hide cells with n < … % of ⟨n⟩/cellOn the mean-quantity modes (energies, temperatures, velocities, νi, Si), masks the cells whose particle count is below the given percentage of the average count per cell. Per-cell means computed from a handful of particles are pure noise (typically in the sheaths); the mask blanks them instead of letting them dominate the plot. A small hysteresis prevents cells from flickering in and out.
nᵢ−nₑReplaces the two density curves by the single space-charge density nine — the natural quantity for sheath and double-layer studies.
Overlay: Heat / SrcIn the Power Absorbed mode, overlays the spatial shapes of the electron-heating profile and/or the external-source profile, as set in the Conditions dialog, so the deposited power can be compared with where it was injected. A mid-plane thermostat appears as a delta-like half-line.
Full height / Show L / R / Grid RFull height makes the right-axis quantity (field or potential) span the full plot height; E_min/φ_min entries control its lower bound. Show L / R selects which of the two axes are displayed on bi-axis modes. Grid R adds horizontal grid lines tied to the right axis.
→ All 1DPropagate the look (axis ranges, colours, line width, font, label mode…) to all open profile viewers at once.
ExportWrite the profiles as a multi-column ASCII table — columns x, ne, ni, E, Φ, ε, Si, Pe, Pi. Both the instantaneous and the time-averaged profiles are written, to profiles_instant.dat and profiles_averaged.dat.
● RecRecord the live plot to an animated GIF or MP4 — see Working with Viewers → Saving, exporting and recording.
💡 The → All 1D button is handy when preparing a multi-panel figure for a paper or a presentation: set up one viewer with the colours, fonts and ranges you want, propagate to the other five with one click, then export each panel with Save and assemble them in your layout tool.

🧩 Custom 1D Profile Viewer

Where the Profile viewer offers fixed pairings of quantities, the Custom 1D Profile viewer lets you compose your own plot: any of the 22 quantities of the 1D profile diagnostics — plus, when the run records the collision-frequency diagnostics, the whole set of per-process collision frequencies — can be assigned to the left axis, the right axis, or turned off, in any combination — two temperatures against a density, a power against a velocity, whatever the physics of the moment calls for. It is opened from Graphics → 1D Profiles → Custom - choose L/R quantities… (the last entry of the sub-menu, below Electron Power Decomposition). It is also the viewer to use to overlay several runs: the Compare… button superimposes the same quantities read from any number of other working directories.

Custom 1D Profile viewer with two quantities on the left axis and one on the right
The Custom 1D Profile viewer: each quantity of the palette is sent to the left axis, the right axis, or hidden, from the off / L / R selector of the settings window.

Choosing the quantities

The settings window lists the whole palette, grouped by family; each row carries an off / L / R selector and a colour swatch (left-click to change the colour, right-click to reset):

FamilyQuantities
Densitiesne, ni, and the space charge ni−ne
Potential / fieldΦ, E
Energies / temperatures⟨ε⟩e, ⟨ε⟩i, Te, Ti, Te∥, Te⊥, Ti∥, Ti⊥
RatesIonization rate Siz
PowersPe, Pi, and the Schulze components Pohm, Ppress,T, Ppress,n, Pinert
Velocities⟨vxe, ⟨vxi
Collision frequenciesνi = Siz/ne, the family totals νel, νexc, νiz (and νatt for an attaching gas) and one entry per individual process, labelled as in the Collision Frequencies viewer. These entries appear only when the run wrote snap/collfreq.bin. Note that νi = ⟨S⟩/⟨n⟩ (a ratio of separately averaged profiles) and the collfreq route ⟨S/n⟩ (the per-electron frequency) are different averages: in an RF discharge they can legitimately differ by tens of percent — both are available, with explicit labels.

An Avg checkbox switches between the instantaneous profile of the latest snapshot and the time-averaged one. Like every viewer it starts unchecked the first time it is opened in a session (and remembers your choice within the session); tick it to plot the same accumulated averages as the dedicated 1D viewers — an instantaneous Pe, for example, is a single-timestep quantity and does not match the Absorbed Power viewer. The status line states explicitly which of the two is displayed ([avg] / [inst.]), and an average that has accumulated nothing yet falls back to the instantaneous arrays instead of drawing zeros. The mean ion energy ⟨ε⟩i and Ti use the engine's own accumulated average. For the quantities the engine does not average — Te∥, Te⊥, Ti∥, Ti⊥ and the mean velocities ⟨vx⟩ — the viewer averages on its own side, over the distinct frames it has seen (as the 1D Profile viewer does): on a running simulation the average converges as frames arrive, on a frozen run it is the single frame, and unticking Avg clears it; the Schulze power components are by nature time-averaged, and they are dropped — with a note in the status line — when the run was made without the heating decomposition, rather than drawn as flat zeros.

A low-population mask (check-box + threshold in % of the peak density) blanks the per-particle quantities — energies, temperatures, collision frequencies — in the regions where the density has fallen below the threshold, typically inside the sheaths, where these averages rest on a handful of particles and read as noise. The viewer follows a running simulation through the live data stream, and otherwise reads the newest snapshot by file date, so a leftover snapshot from an older run cannot shadow the current one.

Axes, scales and scientific labels

Mixing quantities of different units — normalization

When quantities with different units share the same (linear) axis, the viewer normalizes each curve so that the axis maximum reads 1, and asks — once per quantity — for the reference value that corresponds to 1 (pre-filled with the automatic maximum; the answer is remembered). The axis title then spells out every reference, e.g. "ne (2.5×10¹⁵ m⁻³),  ε (10 eV)", so the plot stays quantitative. To change a reference later, double-click the L/R selector of that quantity: the prompt reopens and the axis title is rewritten accordingly.

Comparing several runs

Custom viewer comparing the same quantities across several runs
Multi-run comparison: the current run (#1, solid) overlaid with two comparison runs, distinguished by line style and markers. The legend groups, on a single line per quantity, one line-sample per run.

The Compare… button (in the header of the settings window) adds a comparison run: it opens the same working-directory dialog as the rest of the interface, and the selected directory's profiles are overlaid for exactly the quantities currently on display, with the same axis scaling — every click adds one more run. The current run is #1; each comparison gets a numbered row in the Line styles / markers section at the bottom of the panel, with a × button at the end of the row to remove it.

All the settings of this viewer — selection, colours, ranges, normalization references, comparison list and styles, annotations and layout — persist in the xprofile section of jcpic_config.json.

Exporting the plotted curves

The Export button writes the figure's content as one ASCII table: the position x (cm) in the first column, then one column per plotted quantity — left axis first, then right axis — in physical units (not the normalized or rescaled display values). The file matches the figure exactly: same instantaneous/averaged choice, and the low-population mask writes nan in the blanked cells. When comparison runs are displayed, their curves are appended as further columns, suffixed with the comparison's name and interpolated onto the main run's grid when the grids differ. The file carries no header — data columns only, directly loadable by any plotting tool — and the column list is printed to the console at export time. The dialog defaults to the ascii/ subfolder of the working directory.

💡 The Compare machinery makes this viewer the natural tool for parameter scans: run the same case at, say, three pressures in three working directories, open the Custom viewer on one of them, add the other two with Compare…, and export a publication-ready overlay — same quantities, same scales, one style per run.

💫 Collision Frequencies Viewer

The collision-frequency viewer displays the spatial profiles of the electron collision frequencies, per collision process: νj(x) = ⟨N·σj(ε)·v⟩ in s⁻¹, where the average runs over the electrons of each cell, σj is the cross section of process j (elastic, each excitation channel, ionization…) and N is the neutral gas density. It answers at a glance the questions "which process dominates where?" and "how collisional is the sheath compared with the bulk?". It is opened from Graphics → 1D Profiles → Collision Frequencies (all processes) and reads snap/collfreq.bin, written by the engine alongside the other profile diagnostics.

Collision-frequency viewer
Per-process electron collision frequencies νj(x). The elastic channel usually dominates; the inelastic channels switch on where the mean electron energy exceeds their thresholds.

What it plots

One curve per process of the loaded electron cross-section set, each labelled with the process name and threshold from the cross-section file, plus the total. Because the frequencies span several orders of magnitude, the y-axis defaults to logarithmic.

Controls

ControlWhat it does
Instantaneous / Time-averagedSwitches between the latest snapshot and the running time-average of the frequencies (same averaging window as the other profile diagnostics).
Avg / Rst AvgToggle the average display and reset the averaging accumulator, as in the profile viewer.
Per-curve visibility and coloursEach process can be shown or hidden and recoloured individually from the settings panel.

The viewer otherwise follows the common framework of Working with Viewers: ⚙ settings panel with Apply, log/dec rules, draggable and editable titles and labels, Save / Export / ● Rec.

🌊 X-T Viewer

The X-T viewer displays a colour map of any 1D plasma quantity as a function of position x (horizontal axis) and time t (vertical axis), the standard format for visualizing the time-resolved structure of an RF discharge. One frame typically covers one or several RF periods of the lowest applied frequency, so the viewer is the most natural tool to spot sheath dynamics, electric-field reversals, ionization bursts and propagating disturbances. A separate viewer instance is opened for each quantity through Graphics → Position-Time Contours; multiple instances can run side-by-side.

X-T viewer showing electron density
Position–time diagram of the electron density for the dual-frequency capacitive discharge. The horizontal coordinate is position (cm), the vertical coordinate is time (one RF period). The expansion and compression of the sheaths at each electrode is visible as the V-shaped low-density patterns, asymmetric between the two electrodes.

What can be plotted

The X-T viewer supports thirteen quantities. Six are the standard "primary" diagnostics, available as long as the X-T accumulator is enabled in the Conditions dialog; the other seven are the Schulze power decomposition components, available only when heating diagnostics are enabled (heating_flag = 1 in the xt_diag.bin trailer). The latter are reached through the Electron Power Decomposition sub-menu of Graphics → Position-Time Contours.

GroupMenu entrySymbolUnit
PrimaryElectron Densitynem−3
Ion Densitynim−3
Electric FieldE(x, t)V/m
Mean Electron Energy⟨εeeV
Ionization RateSizm−3 s−1
Electron PowerPeW/m3
SchulzePtotTotal electron powerW/m3
PohmOhmic componentW/m3
PpressTotal pressure componentW/m3
Ppress,TPressure (temperature term)W/m3
Ppress,nPressure (density term)W/m3
PinInertial componentW/m3
PmagMagnetic projection term, only when B ≠ 0W/m3

Each viewer instance saves its layout and styling to its own section of jcpic_config.json (xt_ne, xt_ni, xt_ef, …), so the appearance of each quantity can be tuned independently. The viewer refreshes itself live during a run, polling at the same rate as the other viewers, and works equally well on a stopped or paused simulation.

Pmag — the magnetized power balance

In a magnetized discharge the electron power balance built from the x-projected momentum-transfer equation does not close without one more term,

pmag(x) = − e n(xuz(xBy(x),

which the menu offers as Pmag, after Pin, and only when the case actually has a magnetic field. With it the balance closes to better than 1 %. In the bundled magnetized-RF cases Pmag turns out to be comparable to Ptot itself, while the ohmic term is only some 7 % of it — the heating there is not ohmic, contrary to what one might expect.

⚠️ Two conditions, and both are silent when they fail. First, Pmag is deposited only if heating_diag = 1: with the heating diagnostics off it is identically zero and the plot is a flat line, with no warning. The key is hot-reloadable from Conditions → Diagnostics → General, so it can be switched on without restarting — but the accumulation only begins then. Second, on a run resumed from a checkpoint the underlying n·uz accumulator is not rebuilt, because no such matrix is stored, so Pmag comes out under-estimated until the X-T accumulators are cleared: set xt_reset = 1 (Conditions → Diagnostics → Position-Time) on the first restart.
ℹ️ A word on the name. The magnetic force does no work — J·(u×B) vanishes identically — so Pmag is not "the missing magnetic heating". It is the bookkeeping term that appears when the vector momentum equation is projected on x, and it is what makes the one-dimensional balance add up.

Controls specific to the X-T viewer

The common framework — the gear (⚙) settings panel, dragging titles and plot edges, double-click text labels, Save to PNG/PDF/SVG — is described in Working with Viewers. The Save dialog proposes a default file name built from the displayed quantity — XT_Electron_density, XT_Electric_potential, XT_P_ohm, … — and the 1D slice popup likewise proposes XT__slice (the FFT window proposes fft_). Being a 2D colour map, the X-T panel adds:

ControlWhat it does
Cmap / FlipA visual colour-map picker showing every palette as a gradient — the standard matplotlib maps (viridis, plasma, inferno, jet, turbo, coolwarm, RdBu_r, seismic…) plus any custom palette from the Palette Editor; Flip reverses the current map. Custom palettes appear in their own section of the list.
Colorbar / dtickShow or hide the colour bar and set its tick spacing.
z min / z max, Log, decThe data range spanned by the colour scale (either may be auto), a logarithmic scale and its decade count. Bipolar quantities (field, power) automatically use a symmetric scale around zero with a divergent map.
< zmin / > zmaxTwo swatches set the colour given to values below / above the scale (the "under" / "over" colours); right-click a swatch to clear it.
ContourOverlay iso-value contour lines — an automatic count N or an explicit list of levels, with a chosen colour and width.
smoothA Gaussian spatial smoothing (sigma) applied before display — useful for noisy quantities such as the ionization rate at low statistics. 0 = none.
TransposeSwap the x and t axes.
→ All XTApply the current look (colour map, scale, contour, smoothing, fonts…) to every open X-T viewer at once — for a consistent multi-quantity figure.
ExportWrite the full xt matrix as an ASCII grid (Origin-compatible) for external analysis.
FFTOpens the FFT window — the Fourier analysis of the displayed quantity: full 2D (k, ω) spectrum, frequency spectrum at a fixed position, or wavenumber spectrum at a fixed time, with an optional ion-acoustic dispersion overlay. See the dedicated FFT Analysis chapter.
● RecRecord the live map to GIF/MP4 — useful to film the construction of a transient X-T window (see Working with Viewers → Saving, exporting and recording).

Probing and slicing

On top of the common gestures (moving titles, creating text, resizing the plot — see Working with Viewers), the X-T map adds two actions that turn it into a quantitative tool, plus a colour-bar shortcut.

The slice popup can hold several curves at once: a plain right-click on the map draws one slice and replaces it, while Ctrl+right-click pins the current slice — cycling its colour and adding it to the legend — and starts a new one, so you can overlay the profile at several instants. Toggle the legend with Legend; click the legend text to size it, and click a legend line to recolour that curve. Export then writes one data column per pinned curve.

ℹ️ Probe and slice are complementary: the probe is fast and stays inside the X-T window, while the slice opens a separate plot you can keep open, re-anchor at different times, overlay several profiles on, and export. Both share the X-T plot's time scale.
💡 For a spectral view of the same data — which wavelengths and frequencies carry the fluctuations, and whether they sit on the ion-acoustic dispersion — press the FFT button and see the FFT Analysis chapter.

Choosing the X-T resolution

The size of the accumulator is set by xt_nx and xt_nt (Conditions → Diagnostics → Position-Time), with a ceiling of 512 in each direction. Going from 200×200 to 400×400 costs nothing in memory — the engine's arrays are dimensioned at the ceiling either way — but it costs in two other currencies, and both are worth knowing before asking for it.

The first is statistics: four times as many bins means four times fewer counts in each, so the map is twice as noisy. The second is rendering. Below 40 000 cells the map is drawn with Gouraud shading, which interpolates smoothly across each cell; above it the viewer switches automatically to flat shading, because Gouraud costs about seven times more and a 400×400 redraw would take some 600 ms. The switch is invisible in practice — at 400×400 on an 800-pixel axis a cell is two pixels wide, so there is nothing left to interpolate, and the flat rendering is if anything slightly crisper.

ℹ️ Why that threshold exists. Before the automatic switch, a 400×400 map made the window hard to resize and — more puzzling — killed the double-click: the title dialogs would not open, and a title would move instead. The cause was not the event handling but the redraw time. Tk only synthesizes a double-click event if the two clicks are less than 500 ms apart, and it timestamps a click when it processes it; a 600 ms redraw triggered between the two clicks pushed the second one past that window, so no double-click was ever generated. Anything that makes a redraw longer than half a second has the same effect, which is worth remembering if it is ever seen again.
⚠️ Changing xt_nx or xt_nt invalidates snap/xt_accum.bin: the size check is exact, and the accumulator is silently reset. Change the resolution at the start of a run, not in the middle of one you intend to average.

🌀 Phase Space Viewer

The phase-space viewer displays the distribution function of a charged species as a colour map over a two-dimensional phase plane, with the spatial coordinate x on the horizontal axis and either the velocity component vx or the kinetic energy ε on the vertical axis. It is one of the most direct ways to visualize the kinetic structure of a discharge — beam acceleration in the sheaths, the formation of low-energy bulk populations, runaway tails, or the asymmetry of the ion distribution between the two electrodes. Each viewer instance is opened from Graphics → Phase Space and is dedicated to one of the four available combinations.

Electron phase space — animation of the Buneman instability
Electron phase space f(x, vx), shown here as an animation of the Buneman instability (a current-driven two-stream instability). The initially streaming electron population bunches and rolls up into the characteristic phase-space vortices as the instability grows and saturates. See the Two-stream / Buneman entry in the glossary and the Theory chapter.

What can be plotted

Menu entryModeDistributionWhat it shows
Electrons f(x, vx)e_xvxfe(x, vx)Velocity-resolved electron distribution. Bipolar in vx, so beams accelerated by the sheath at one wall appear as a positive-velocity arc, the symmetric beam from the other wall as a negative-velocity arc.
Ions f(x, vx)i_xvxfi(x, vx)Same for the ions. The slow bulk distribution sits near vx=0; the high-velocity tails accelerated towards each wall are clearly visible across the sheaths.
Electrons f(x, ε)e_xepsfe(x, ε)Energy-resolved electron distribution at each position. Useful for comparing the bulk and sheath EEDFs at a glance, and for spotting non-Maxwellian tails.
Ions f(x, ε)i_xepsfi(x, ε)Energy-resolved ion distribution. Reveals the build-up of the ion energy distribution along the sheath drop and the contribution of charge-exchange collisions.

The four modes share the same underlying accumulator written by the Fortran engine, so all four are populated as soon as the phase-space diagnostic is enabled on Conditions → Diagnostics → Energy Distribution. Each viewer instance has its own section in jcpic_config.json, so the colour map, axis ranges and contour settings of each mode can be tuned independently.

Controls specific to the phase-space viewer

The common framework — the gear (⚙) settings panel, dragging titles and plot edges, double-click text labels, Save — is described in Working with Viewers. This is a 2D colour map and the only live, memory-mapped viewer (it follows the run frame by frame), so its panel adds:

ControlWhat it does
AvgShow the instantaneous distribution (latest frame) or the time-averaged accumulator.
Rst AvgDiscard the running time-average and restart it (it signals the engine through a flag file) — use it after the discharge has converged, or after changing a parameter mid-run.
Cmap / Flip / CbarThe visual colour-map picker (standard and custom palettes), map reversal, and colour-bar on/off.
z min / z max, Log, decThe colour-scale range and an optional logarithmic scale with its decade count.
vx max / ε maxThe vertical-axis range — the half-range of the (symmetric) velocity axis in the vx modes, or the upper energy bound in the ε modes. In auto mode the axis only ever grows, so the time-average stays coherent; raise this value if the high-energy tail looks clipped.
Contour / SmoothIso-density contour lines (count, colour, width) and an optional Gaussian smoothing of the map.
vx=0 axis colourA swatch sets the colour of the reference line drawn at vx = 0 (in the velocity modes).
TimeOverlays the current simulation time in a corner of the plot (draggable, like any label).
→ All PSApply the current look to all four phase-space viewers at once.
● RecRecord the live phase plane to an animated GIF or MP4 (see Working with Viewers → Saving, exporting and recording). With a slow Capture FPS this is the easiest way to film beam formation or an instability developing.

Right-clicking the colour bar cycles palettes (top → next, bottom → previous, middle → flip), and the bar can be dragged to reposition and resize it. The phase plane is itself the diagnostic, so — unlike the X-T viewer — it has no probe or 1D-slice popup.

📊 EEPF Viewer

The EEPF viewer plots the electron energy probability function f(ε) at one or more selected positions across the discharge gap, as a function of the kinetic energy ε in electronvolts. The EEPF — the EEDF normalized by ε1/2 — is the standard observable for assessing whether the electron distribution is Maxwellian (a straight line on a semilog plot) or departs from it, which is the rule rather than the exception in low-pressure RF discharges. The viewer is opened from Graphics → EEPF / IFEDF → EEPF(ε); a separate 2D viewer (EEPF(x, ε)) showing the same quantity resolved as a colour map is described in the next section.

EEPF viewer with multiple position curves
EEPF at three spatial positions, here for a positive-column striations case. Each curve is normalised to unit area, so on this semilog scale a Maxwellian is a straight line; the departures from it reveal the non-thermal structure carried by the striations. (The 2-D map below uses a different, density-weighted normalisation.)

What can be plotted

The viewer overlays one EEPF curve per chosen position, all on the same semilog axes. Positions are given in centimetres from the left wall, as a comma-separated list; each value is snapped to the nearest spatial bin and the curve is labelled with that bin's real position, e.g. x = 1.52 cm. This is the same convention as the right-click read-out of the 2D viewers, so a position picked off the EEPF-2D map can be reproduced here exactly. A Space avg option replaces the per-position curves with a single curve averaged over the whole gap, useful when the local distributions are noisy or only the global EEPF is wanted.

The data come from the eepf.bin accumulator, which must be enabled on Conditions → Diagnostics → Energy Distribution; it accumulates over the same window as the other distribution diagnostics. The viewer refreshes itself live during a run.

Controls specific to the EEPF viewer

The common framework (gear ⚙ panel, dragging titles, text labels, Save to PNG/PDF/SVG) is described in Working with Viewers. Specific to this viewer:

ControlWhat it does
x positions (cm)The comma-separated list of positions to plot (default 0.5, 1.0, 1.5, 2.0). Up to about a dozen curves, each with its own colour and legend entry.
Space avgReplace the per-position curves with a single gap-averaged EEPF.
ε max, f min, f maxThe energy-axis upper bound (eV) and the limits of the logarithmic probability axis. f min defaults to 10−8 to show the full high-energy tail.
LegendA draggable legend listing each curve by its real x value, colour-matched to the lines; toggle on/off.
ExportWrite the data as an ASCII table — an energy column plus one f_x…cm column per position.
Compare…Superimpose the EEPFs of other runs, chosen with the usual working-directory browser. Any number of runs can be added; each gets its own row in the panel with a line style, a marker glyph, a marker count and a colour swatch. See below.
→ All 1DPropagate the style (fonts, line width, label mode, ranges) to the other 1D viewers.
💡 The default f min = 10−8 reaches down to where the statistical noise floor of a 105–106 super-particle run becomes visible. If the EEPF flattens or wiggles near the bottom of the plot, that is the noise floor — run longer, or use Space avg to reduce the fluctuations.

Comparing runs, and the offset (waterfall) view

These two features are shared, control for control, with the IFEDF viewer; what follows applies to both.

Compare. The Compare… button adds the distribution of another run to the plot. The comparison runs are re-read on every redraw, so a case that is still running keeps refreshing alongside the current one — the natural way to watch two pressures, two voltages or two collision models converge side by side. Every curve, the main one included, has its own line style, marker glyph (● ○ ■ □ ▲ △ ▼ ▽ ◆ ◇ ★ ✕ + •), number of markers — spaced evenly to the eye whatever the underlying mesh — and colour, with a right-click on a swatch returning it to the default. The main curve keeps its row even when nothing is being compared, which is how you restyle a single-run plot.

Offset (waterfall). The Offset checkbox stacks the curves instead of overlaying them, in the manner of figure 7 of Donkó et al. — the standard way of showing a family of distributions that would otherwise lie on top of one another. and df set the shift applied from one curve to the next; on a logarithmic axis df is a number of decades, on a linear axis an additive offset. Fit fills both with a readable stacking, rounding df to a whole number of decades so that the ticks of every frame line up with those of the main axis.

CheckboxWhat it does
OffsetTurn the stacking on. / df set the step between curves; Fit computes a sensible pair.
AxesGive each shifted curve its own (ε, f) frame — a vertical axis, a horizontal axis and ticks that reuse the formatters of the main axis, so every frame is in the same unit with the same factored power of ten.
LblLabel those per-curve frames.
MaskHidden-line removal: each curve is painted opaque down to the bottom of the figure, so a curve in front hides the ones behind it — axes and labels included.
BoxDraw a rectangle enclosing the whole stack.
Curve orderEach row of the Compare panel starts with a number. Changing it swaps the two curves — the requested slot is always already taken. The order drives the stacking, the masking and the legend, and the main curve can be moved anywhere in it.
💡 Giving both f min and f max switches the stack to a common frame: every curve is then scaled over exactly the same interval, translated by its own offset. Each curve is cut at its own f min — beyond it, it would leave its frame and cross the curves below — the left axis is bounded strictly to [f min, f max], which is the frame of curve #1, and the horizontal axis stops at ε max, the space to its right belonging to the stacked frames.
⚠️ The ASCII export and Ctrl+C of these two viewers currently write the main run only — the comparison curves are drawn but not exported. Save the figure itself, or export each run from its own working directory.

🗺️ EEPF 2D Viewer

The EEPF 2D viewer displays the same electron energy probability function as the 1D viewer, but resolved as a colour map over the (x, ε) plane — the position across the discharge on the horizontal axis, the kinetic energy in eV on the vertical axis. It is the diagnostic of choice when the spatial structure of the high-energy tail matters: where the secondary-electron beams from each electrode dump their energy, where the bulk Maxwellian gives way to a tail-heated population, or how the EEPF is locally distorted by an electric-field reversal. The viewer is opened from Graphics → EEPF / IFEDF → EEPF(x, ε).

EEPF 2D color map
Position-resolved electron energy distribution for the same positive-column striations case, shown as log10[f(x, ε)·ne(x)] — i.e. weighted by the local density, unlike the 1-D EEPFs above, which are each normalised to unit area. The periodic striation pattern modulates both the density and the energy distribution along the column.

What it plots

The viewer shows the position-resolved EEPF f(x, ε) as a colour map, always time-averaged and on a logarithmic colour scale. Two normalizations are offered at the top of the settings panel: Normalized f(ε,x), where the distribution integrates to one at every position, and f(ε,x) × ne(x), which folds in the density profile to give the absolute electron population. The energy axis runs from 0 to a user-set bound (default 60 eV). The data come from the same eepf.bin accumulator as the 1D EEPF viewer, so both can be open at once on the same case for cross-reference, and the viewer refreshes live during a run.

Controls specific to the EEPF-2D viewer

The common framework is described in Working with Viewers; being a 2D colour map, this viewer's panel offers the same family of controls as the X-T viewer:

ControlWhat it does
NormalizationChoose between the normalized f(ε,x) and f(ε,x) × ne(x).
Cmap / Flip / Colorbar / dtickThe visual colour-map picker (standard and custom palettes), map reversal, colour-bar on/off and tick spacing.
z min / z max, Log, decThe colour-scale range and decade count; the scale is logarithmic by default, since the EEPF spans many orders of magnitude.
< zmin / > zmaxOut-of-range "under" / "over" colours; right-click a swatch to clear it.
ε maxThe upper bound of the energy axis.
Contour / smooth / TransposeIso-value contour lines, a Gaussian smoothing of the map, and swapping the x and ε axes.
Hide x-cells with n < … % of ⟨n⟩Masks the columns of the map whose electron count is below the given percentage of the average per cell — the same low-statistics mask as in the profile viewer, which blanks the noisy sheath columns instead of letting them pollute the colour scale.
TimeOverlays the current simulation time on the map (draggable, like any label).
ExportWrite the full x–ε grid as an ASCII file.
● RecRecord the live map to GIF/MP4 (see Working with Viewers → Saving, exporting and recording).

Slicing

Beyond the common gestures (see Working with Viewers), right-clicking the map opens a 1D slice showing f(ε) at the clicked position x — a vertical cut through the map; a line marks the cut, and holding and dragging re-slices in real time. The slice opens on the same vertical scale as the map and is itself a small 1D viewer, with its own ⚙ panel, text labels and an Export button.

The slice popup can hold several curves at once: Ctrl+right-click pins the current slice — cycling its colour and adding it to the legend — so you can compare f(ε) at several positions, while a plain right-click replaces the single active curve. Export then writes one column per pinned curve. Right-clicking the colour bar cycles palettes.

📐 IFEDF Viewer

The IFEDF viewer plots the Ion Flux–Energy Distribution Function at the two electrodes of the discharge, that is, the energy distribution of the ions that actually reach each wall, weighted by their flux. This is the primary diagnostic for plasma-processing applications, where the energy spectrum of the ions impinging on a substrate sets the etch and deposition rates. The viewer is opened from Graphics → EEPF / IFEDF → IFEDF.

IFEDF viewer at left and right walls
Ion flux–energy distribution at the two walls of the dual-frequency capacitive discharge. Because the two driving frequencies make the discharge asymmetric, the IFEDFs at the two electrodes differ; the structure on each curve reflects charge-exchange collisions in the sheath.

What can be plotted

Two curves are available: the IFEDF at the left electrode (x = 0) and at the right electrode (x = L). Each can be turned on or off independently and assigned its own colour, so that asymmetries between the two walls — for instance in a DC-biased single-frequency discharge or in a magnetized configuration — show up immediately when both curves are overlaid. The probability axis can be linear (the default for benchmarks where the flux density at high energy is the focus) or logarithmic (better for displaying the full range of the distribution down to the noise floor).

The data come from the ifedf.bin accumulator written by the engine. The accumulator must be enabled on Conditions → Diagnostics → Energy Distribution (the Calculate EEPF / IFEDF option, shared with the EEPF) and accumulates over the same averaging window as the other diagnostics. The viewer refreshes itself live during a run.

Controls specific to the IFEDF viewer

The common framework (gear ⚙ panel, dragging titles, text labels, Save to PNG/PDF/SVG) is described in Working with Viewers. Specific to this viewer:

ControlWhat it does
Left (x=0) / Right (x=L)A visibility checkbox and a colour swatch for each electrode's curve, so asymmetries between the two walls (a DC-biased or magnetized discharge) show up immediately when both are overlaid.
Log FSwitch the probability axis to logarithmic. In linear mode with auto-scaling, F min is anchored at zero (the IFEDF is non-negative).
ε min/max/dε, F min/max/dFThe energy and probability axis ranges and tick spacings.
LegendToggle the "Left" / "Right" legend.
Compare… and OffsetSuperimpose the IFEDFs of other runs, and stack them in the waterfall view. Identical, control for control, to the EEPF viewer's — see Comparing runs, and the offset (waterfall) view there.
💡 Switch to Log F when the high-energy structure is the focus — for instance the discrete charge-exchange peaks of a low-pressure argon discharge, which sit several decades below the bulk and are invisible on a linear scale.
ℹ️ The IFEDF viewer offers Save (PNG/PDF/SVG) but no ASCII export and no GIF/MP4 recording. To work with the numbers directly, use Ctrl+C on the plot (the figure) or ask the author for the record layout of ifedf.bin; an ASCII export is planned.
ℹ️ The time-integrated IFEDF now survives a restart. Up to the July 2026 fix, the accumulated distribution silently restarted from zero on every Continue, because the restore was guarded by a test on a simulation clock that had not yet been read. A long IFEDF accumulation can therefore be split over several sessions, as the other diagnostics already could.

Currents Viewer

The currents viewer overlays the time evolution of the discharge current and the applied voltage on a single plot with two y-axes — voltage on the left, current density on the right. It is the everyday read-out for capacitive RF discharges: the in-phase / out-of-phase relationship between V(t) and jT(t) tells the user at a glance whether the simulation has reached steady state, whether the impedance is mostly capacitive or resistive, and whether self-bias is present in an asymmetric configuration. The viewer is opened from Graphics → Current-VoltageTotal current & Voltage for the standard view, or Charged particle currents for the per-species (per-wall) view.

Currents viewer with V(t) and j(t)
Voltage and total current over one RF period of the dual-frequency capacitive discharge. The current leads the voltage by approximately π/2, with a small in-phase component reflecting the dissipative part of the impedance.

What can be plotted

Two curves are drawn on the same time axis. The left y-axis carries the voltage, the right y-axis the current density; both are colour-coded and have user-customizable colours. What the curves actually represent depends on the mode of the discharge:

ConfigurationLeft axisRight axisTime window
Standard discharge (default) V(t) — applied voltage between the electrodes jT(t) — total current density (conduction + displacement) One or several RF periods (Periodic mode), or last cur_window microseconds (Transient / DC mode)
Self-adjusting axial heating (heating_dir = 1, iheat_self_adj = 1) Ez(t) — effective axial field Jz(t) — axial current density Last cur_window microseconds

The mode of acquisition is selected on Conditions → Diagnostics → Current, and is written into cur.bin by the engine (the viewer follows it automatically). Two acquisition modes are available:

Periodic. Each time step is binned by phase over the RF period, and the displayed waveform is the running average over the last cur_ncycles cycles. The viewer always shows exactly one period of the lowest applied frequency. This is the right mode for a steady-state RF discharge: the curve evolves smoothly towards its asymptotic shape as cycles accumulate, with no visible jumps at cycle boundaries.

Transient / DC. Time is the actual simulation time, and the displayed window is the last cur_window microseconds before the current instant. This is the right mode for a DC discharge, for a transient phase before steady state, or for any non-periodic configuration. JC-PIC automatically forces this mode when all configured frequencies are zero.

The data come from the cur.bin accumulator, which the engine writes continuously. The accumulator's state survives restarts via the cur_accum.bin trailer (v3 format), so a paused or stopped simulation can be resumed without losing the running averages. The viewer refreshes itself live.

ℹ️ With a current source drive (Conditions → Voltage / Current tab), the two curves swap roles: the right-axis current is the imposed waveform, reproduced exactly by construction, and the left-axis “applied voltage” is the measured electrode potential — the quantity of interest. Its shape is the discharge’s answer to the imposed current: harmonics betray the nonlinear sheaths, and a DC component is the self-bias.

Controls specific to the currents viewer

The common framework (gear ⚙ panel, dragging titles and plot edges, double-click text labels — handy for marking phases on the waveform — and Save to PNG/PDF/SVG) is described in Working with Viewers. Specific to this viewer:

ControlWhat it does
t / V / J rangesIndependent min/max/tick controls for the time axis and the two y-axes (voltage on the left, current on the right). In self-adjust axial-heating mode the left/right axes automatically become Ez and Jz. The voltage axis switches automatically to kV (or MV) above 1000 V.
Log |J|Plots the magnitude of the current density on a logarithmic axis — useful when the conduction current spans several decades over a period, e.g. in a breakdown transient.
V / j coloursA colour swatch for each curve. In the per-species launch mode the viewer instead shows four wall currents (electron and ion, left and right) each with its own swatch.
FFTOpens the FFT window with the frequency spectra of the recorded traces (V, J, per-wall currents…), with RF-harmonic markers — see the FFT Analysis chapter.
● RecRecord the live waveforms to GIF/MP4 (see Working with Viewers).
ℹ️ The currents viewer offers Save (PNG/PDF/SVG) but no ASCII export of the waveforms themselves (the FFT window has its own Export for the spectra). The raw waveforms are in cur.bin, a binary file whose record layout is available from the author on request; an ASCII export is planned. The accumulator state survives restarts (the cur_accum.bin trailer), so a paused or resumed run keeps its running averages.

📶 FFT Analysis

Two viewers carry an FFT button in their settings panel that opens a dedicated FFT window: the X-T viewer (spectral analysis of any position–time map) and the currents viewer (frequency spectra of the recorded waveforms). The FFT window is a full-fledged viewer in its own right — draggable and editable titles and colorbar label, palette picker with right-click cycling, font and plot-size steps, free-text annotations, Save and ASCII Export — and it appears in the Manage Viewer Windows panel like any other window. Its floating ⚙ settings panel docks to the right of the window and follows it.

FFT of an X-T map

Press FFT in the settings panel of any X-T viewer. The window analyses the currently displayed quantity (ne, ni, E, φ, ⟨εe⟩, …) over the valid time bins of the X-T accumulator, after removing the time-averaged profile — so what is transformed is the fluctuation δq(x, t) = q − ⟨q⟩t. Three modes are offered:

ModeWhat it computesTypical use
2D (k, ω)The full two-dimensional Fourier transform |δq̂(k, ω)|², displayed as a colour map with the wavenumber on the horizontal axis and the frequency on the vertical axis.Dispersion analysis: propagating waves appear as ridges along their dispersion curve ω(k); standing structures sit on the axes.
ω @ xThe frequency spectrum of the signal at a fixed position x0 (optionally averaged over ±n neighbouring cells), with a marker at the RF fundamental.What frequencies does the plasma oscillate at, at this location? Harmonics, sidebands, low-frequency instabilities.
k @ tThe wavenumber spectrum of the spatial profile at a fixed time t0.Dominant wavelength of a pattern (striations, solitons) at a given instant.
FFT window: 2D k-omega spectrum
The FFT window in 2D (k, ω) mode, here on the Generation of Ion Acoustic Waves test case: the fluctuation energy of the ion density concentrates along the ion-acoustic branch in the (k, ω) plane — the signature of the propagating mode. The dashed overlay is the theoretical ion-acoustic dispersion, and the IA% box reports the fraction of fluctuation energy lying on it.

Axes and units

By default the axes are physical: 1/λ in mm⁻¹ and f in MHz. The Axes: kλ_De, ω/ω_pi option switches to the normalized units of plasma-wave theory — the wavenumber in units of the inverse electron Debye length and the frequency in units of the ion plasma frequency. The normalization needs the electron temperature and density: Te is pre-filled with the value measured by the engine (the same figure shown in the parameters window) and stays editable; the mean density is taken from the analysed window; the ion mass is read from the run itself (the gas — or the mass-ratio override — set in Conditions/General) and displayed read-only. The info bar at the bottom reports the sampling (Δt, Nyquist frequency, Δx) and the derived λ_De and ω_pi.

Ion-acoustic dispersion overlay

For studies of ion-acoustic fluctuations and instabilities (e.g. in presheaths), ticking IA dispersion overlays the ion-acoustic dispersion relation ω = k·Vi ± k·cs/√(1+(kλDe)²) on the 2D spectrum — with cs from the (editable) Te and Vi an optional ion drift for the Doppler shift — and reports IA%, the fraction of the fluctuation spectral energy (|δn̂|²/k²) lying within a band around that curve: the metric used by Beving et al. (2021) to quantify the instability level. The displayed map switches to the energy-weighted |δq̂|²/k² while the overlay is active. This option is specific to ion-acoustic physics; leave it off for general spectral analysis.

Electron plasma (Langmuir / Bohm-Gross) waves

The same 2D (k, ω) transform reveals the electron branch when the analysed quantity carries an electron plasma wave — the Langmuir-wave test cases (the Bohm-Gross and large-amplitude cases, and the beam-plasma / two-stream instabilities). There the fluctuation energy concentrates on the Bohm-Gross parabola ω² = ωpe²(1 + 3k²λDe²), at frequencies at and above fpe — two to three orders of magnitude higher than the ion-acoustic branch. Two practical points follow. First, transform the potential rather than the density: PIC shot-noise is white in density but the potential weights it by 1/k², so the seeded long-wavelength mode stands an order of magnitude above the noise (the same mode can be invisible in a density map). Second, keep the axes physical (MHz, mm⁻¹) for these cases — the normalized ω/ωpi scaling of the axis option is built for the ion branch and pushes the electron branch far off the top of the plot. Sample fast enough that the Nyquist frequency clears fpe: with an electron wave near 130 MHz a transient X-T window of ≲ 0.2 µs at xt_nt = 512 (≈0.4 ns bins, Nyquist ≈1.3 GHz) resolves it cleanly, and the thermal PIC noise then traces the whole Bohm-Gross curve for free — every k oscillating at its own Langmuir frequency.

Controls

ControlWhat it does
Mode2D (k,ω) / ω @ x / k @ t (see above). The x0, ±cells and t0 fields apply to the 1D modes.
x-window (cm)Restricts the analysis to a spatial sub-interval — e.g. the presheath only. Blank = the full gap.
HannApplies a Hann window before transforming (on by default), which suppresses the spectral leakage of the finite window at the cost of a slightly wider peak.
log + decLogarithmic colour scale (2D) or y-axis (1D); dec sets the displayed decades of the 2D map.
f/ω max, k maxDisplay limits (blank = auto up to Nyquist).
cmap / Flip / Font / PlotThe palette (picker + right-click cycling on the colorbar, exactly as in the X-T viewer) and the usual font and plot-size steps.
Apply / Save / ExportRecompute, save the figure (PNG/PDF), or export the spectrum as ASCII — two columns in the 1D modes, the full (k, ω) matrix in 2D.
💡 Capturing good data for the FFT. The spectral ranges are set by the X-T sampling: the frequency axis reaches ½ of 1/Δt (with Δt = xt_window/xt_nt) and the wavenumber axis ½ of 1/Δx. For wave studies, record the X-T diagnostic in Transient mode with a window of a few microseconds and xt_nt at its maximum (512): e.g. xt_window = 2 µs gives ≈4 ns bins, resolving frequencies up to ≈128 MHz — ample for ion-scale waves. In Periodic mode the transform describes one RF cycle, so the spectrum reduces to the RF harmonics.

FFT of the current / voltage traces

Press FFT in the currents viewer to open the spectrum of the recorded waveforms. Tick the traces to analyse — applied voltage, total current density, the series-capacitor and self-bias voltages, and the per-wall electron/ion currents when present in cur.bin (absent traces are greyed out). Each selected trace is transformed (Hann window, mean removed) and plotted against frequency in MHz on a common — usually logarithmic — axis, with dotted vertical markers at the harmonics of the RF fundamental. The harmonic content of J(t) is a direct measure of the nonlinearity of the sheaths; inter-harmonic peaks reveal low-frequency dynamics or instabilities.

FFT of the current and voltage traces
Spectra of the applied voltage and total current in a dual-frequency capacitive RF discharge driven at 13.56 and 27.12 MHz, computed over 10 periods of the fundamental (transient current diagnostic). The voltage spectrum contains only the two applied lines; the current carries, in addition, the higher harmonics generated by the nonlinear sheaths and the broadband particle-noise floor.

The window offers the full interactive framework of the 1D viewers: the plot title and axis titles can be dragged anywhere and edited by double-click (text, size, colour, bold/italic — with an Auto reset), the tick labels resized by double-click and their spacing adjusted by dragging, the four plot edges dragged to reshape the plot rectangle, and a double-click inside the plot drops a draggable text annotation. If a dragged title crosses the window border, the window grows to contain it without changing the plot size. The floating panel adds the usual steppers — Font ± (all fonts at once), Plot ± (plot rectangle inside the fixed window), Line ± (curve width) — and a dec field giving the number of decades displayed below the spectrum maximum in log mode (blank = auto). Everything, including the legend position, persists in jcpic_config.json.

ℹ️ Both FFT windows remember their settings (mode, windows, palette, layout, annotations) in jcpic_config.json and are managed like any other window: they are listed in Window → Manage Viewer Windows… (as indented ↳ FFT rows), participate in Tile/Cascade/Raise All/Hide All, and close with their parent viewer. Ctrl+C pressed in an FFT window copies the displayed spectrum to the clipboard, exactly as it copies the main figure in the parent viewer.

🔥 Heating Viewer

Heating viewer showing Schulze power decomposition
Schulze decomposition of the electron heating power in the dual-frequency capacitive discharge. The total (black) is the sum of the ohmic component (which dominates in the bulk) and the pressure component (which dominates near the sheath edge), with the inertial component as a small correction.

The heating viewer shows the spatial decomposition of the electron power absorption following the momentum-equation analysis of Schulze and Lafleur. Where the Profile viewer's Power Absorbed mode shows the total absorbed power, this viewer splits it into the physically distinct mechanisms — ohmic heating, pressure heating and inertia — so you can see which process heats the electrons, and where. The curves are profiles along x, time-averaged over the diagnostic window, in kW/m³.

What it plots

CurveMechanism
PtotThe total absorbed power, ⟨Je·E⟩ — the same quantity as the Profile viewer's electron power.
PohmOhmic (collisional) heating, mene νm vx²⟩ — dominant in the bulk.
PpressThe pressure-heating term (the sum of the two below) — dominant near the sheath edges, where it captures the "stochastic" / pressure-driven heating.
Ppress,TThe temperature-gradient part of the pressure term, ⟨ve ne eTe/∂x⟩.
Ppress,nThe density-gradient part, ⟨ve e Tene/∂x⟩.
PinertThe inertia (acceleration) term — usually a small correction.

To the accuracy of the decomposition, Ptot ≈ Pohm + Ppress,T + Ppress,n + Pinert; this identity holds best once the discharge has reached a periodic steady state (the terms are averaged over the diagnostic window). The viewer reads the moment data from snap/xt_diag.bin, the same file as the X-T viewer.

⚠️ The decomposition is only computed when Electron heating decomposition is enabled on Conditions → Diagnostics → Position-Time (it adds some per-electron CPU work, so it is off by default). If it is off, the viewer shows a message inviting you to enable it and re-run or Continue, rather than any curves.

Controls specific to the heating viewer

The common framework (gear ⚙ panel, dragging titles and plot edges, double-click text labels, Save) is described in Working with Viewers. Specific to this viewer:

ControlWhat it does
CurvesA show checkbox and a colour swatch for each of the six curves, so you can plot only the components of interest and recolour them. Rst Colors restores the defaults.
LegendA proper per-curve legend that can be toggled on/off; drag a legend entry (its marker or its text) to move the whole legend, click the text to set its font size, and click a legend line to recolour that curve. A separate Legend font −/+ sizes the legend text independently of the axis labels.
LogA symmetric-log (symlog) scale, appropriate because the terms change sign around zero.
Export…Write the curves as a CSV table — columns x_cm, P_tot, P_ohm, P_press, P_press_T, P_press_n, P_inert (in kW/m³).
ℹ️ This viewer plots line profiles, so it has no colour map and (unlike the Profile and Phase-space viewers) no GIF/MP4 recording.

🕰️ History Viewer

Two complementary diagnostics share the "History" label, both drawn from the global time history written by the engine to history.dat. The file accumulates one row per major time step throughout the run, with the iteration number, the simulation time, the time step, the total electron and ion super-particle counts, the mean kinetic energies, the cumulative ionization and secondary-emission counts, the maximum density, and the super-particle weight. The history is preserved across Stop+Run / Continue restarts (since the May 2026 fix) and is only wiped when the user explicitly chooses Fresh Start.

Two menu entries open the corresponding plots:

Menu entryWindowQuantities
Particle HistoryStandalone viewer (separate window with floating settings panel)Ne(t), Ni(t) — total super-particle counts of each species
Energy HistoryStandalone viewer — see the Energy Viewer chapter⟨ε⟩e(t), ⟨ε⟩i(t), total kinetic energy and field energy
Particle History viewer with Ne(t) and Ni(t)
Total electron and ion super-particle counts over time, for the dual-frequency capacitive run. After a brief transient (~5–15 µs) both curves plateau, indicating that the ionization rate balances the wall losses.

Particle History — what can be plotted

The Particle History viewer overlays two curves on the same time axis: the total electron super-particle count Ne(t) and the total ion count Ni(t), in counts (not densities). It is the primary read-out for monitoring the global state of the simulation: a steady-state RF discharge shows Ne and Ni stabilizing at comparable values; a runaway ionization shows both counts climbing exponentially; a thinning event shows a sharp drop with the same fractional change on both species. The viewer is opened from Graphics → Particle History, refreshes itself live during a run, and works equally on a stopped simulation.

Controls specific to the Particle History viewer

The common framework (gear ⚙ panel, dragging titles, text labels, Save to PNG/PDF/SVG) is described in Working with Viewers. The viewer-specific controls are the time and particle-count axis ranges, a colour swatch for each of the two curves (Ne, Ni), and a Log checkbox that switches the count axis to logarithmic — the natural scale for growth or decay over several orders of magnitude, e.g. an avalanche or an afterglow. The viewer also carries the common ● Rec button.

💡 Energy History on the Graphics menu opens the standalone Energy Viewer (next chapter), which tracks the energy balance — mean energies, total kinetic energy and field energy. Particle History (counts) and the Energy Viewer together give the full picture: a discharge is in steady state only when both the particle balance and the energy balance have plateaued.

⚖️ Energy Viewer

The Energy Viewer is the natural companion to the Particle History viewer. While the latter monitors the global particle balance through Ne(t) and Ni(t), the Energy Viewer monitors the global energy balance — both the kinetic energy of the simulated species and the electrostatic energy stored in the field. It is the easiest way to confirm that a discharge has reached an energy steady state, and the natural starting point for diagnosing energy-conservation issues. The viewer is opened from Graphics → Energy History.

Energy History viewer with four plateaued curves
A healthy dual-frequency capacitive run in steady state. The four curves plateau by t ≈ 10 µs; from there on, the discharge is in a stationary regime and the other diagnostics are representative.

What can be plotted

Four curves are drawn on a single plot with two y-axes. The mean kinetic energy per particle goes on the left axis in eV; the total kinetic and field energies, both quantities per unit electrode area, go on the right axis in 10n J/m² with an automatic decade scaling.

CurveSymbolAxisDefinition
⟨ε⟩e eke / Ne / e Left (eV) Mean kinetic energy per electron, in eV. Tracks the effective electron temperature.
⟨ε⟩i eki / Ni / e Left (eV) Mean kinetic energy per ion, in eV. Stays small in low-pressure RF (charge-exchange–dominated).
KE (eke + ekiw Right (J/m²) Total kinetic energy of the simulated plasma per unit electrode area. w is the super-particle weight (real particles per super-particle per m²).
Ufield 0/2) ∫ E² dx Right (J/m²) Electrostatic energy stored in the field configuration, per unit electrode area. Mostly carried by the sheaths.

The data come from history.dat as written by the engine. The u_field column was added on 2026-05-02; if a viewer is opened on an older case whose history.dat has only 11 columns, Ufield falls back to zero. The viewer refreshes itself live during a run.

ℹ️ Why per m²? JC-PIC is one-dimensional, so the only direct way to express absolute energies in a quantity that doesn't depend on the simulated particle count is to normalize per unit electrode area. To get total joules in your discharge, multiply the right-axis values by your physical electrode area (e.g. × 10−2 m² for a 100 cm² electrode).

Controls specific to the Energy viewer

The common framework (gear ⚙ panel, dragging titles and plot edges, double-click text labels, Save to PNG/PDF/SVG) is described in Working with Viewers. Specific to this viewer:

ControlWhat it does
Show ⟨ε⟩e / ⟨ε⟩i / KE / UA visibility checkbox and a colour swatch for each of the four curves, so you can focus on, say, just Ufield and ⟨ε⟩e when debugging.
t / ε / U rangesIndependent min/max/tick controls for the time axis, the left mean-energy axis (eV) and the right energy axis (J/m²).
Smooth U (+ N)Replace Ufield by a causal moving average over the last N samples (default on, N = 200) — see the tip below. Turn it off to see the raw 2ωRF oscillation.
Log UPut the right-hand energy axis (KE and Ufield) on a logarithmic scale, leaving the left mean-energy axis linear. Off by default. This is the natural scale for a decaying or growing wave: the exponential Landau damping of a Langmuir or ion-acoustic wave, or the exponential rise of a two-stream / beam-plasma instability, becomes a straight line whose slope is the damping or growth rate — read directly off the Ufield curve (turn Smooth U off first, so the raw oscillation envelope is visible).
Compare…Superimpose the same curves read from another run's working directory, drawn dashed over the current run. The comparison directory is chosen with the usual working-directory dialog and remembered; a colour swatch and a line-style menu control how the comparison is drawn (leave the colour empty to reuse each curve's own colour, distinguished by the dashes). Ideal for before/after parameter checks — e.g. two voltages, two pressures, or two RNGs.
LegendA colour-coded legend that can be shown or hidden, dragged anywhere, and edited by double-click (per-entry text and font size).

The axes adapt to the selection: when both mean-energy curves are hidden, the KE and Ufield curves take over the left axis (with its ticks and title), so a single-quantity plot — say Ufield alone on a log scale for a damping-rate measurement — uses the full frame.

💡 About Smooth U. The raw Ufield(t) oscillates at 2ωRF (it is quadratic in E) and is sampled at the diagnostic interval, which is generally not synchronized with the RF period — so the raw curve appears as a noisy band that masks the trend. The causal moving average uses only past samples, so the displayed curve stays stable from one refresh to the next; the only cost is a small lag of about N/2 diagnostic intervals, invisible at steady state.

Reading the plot

A healthy run shows a clean exponential-like relaxation from the initial seeded conditions to a plateau, with all four curves stabilizing at approximately the same time (typically within 5–15 µs for a Turner benchmark). Once the plateau is reached, all the other diagnostics are representative of the steady-state discharge.

The following observations on the plot are useful indicators of the simulation's quality.

ObservationInterpretation
All four curves plateau by 5–15 µs.Healthy: discharge has reached a steady state. EEPF, IFEDF, X-T diagnostics from this point on are representative of the stationary regime.
⟨ε⟩e ≫ ⟨ε⟩i (typically a factor 10–20).Healthy: low-pressure RF in non-equilibrium, ions thermalized by charge exchange.
KE and ⟨ε⟩e share the same temporal shape.Healthy: Ne is constant (steady ionization–wall-loss balance), so KE is a multiple of ⟨ε⟩e.
Ufield shows an initial bump above its plateau, then settles.Healthy: sheath formation transient, the field is temporarily stronger than at equilibrium.
Continuous drift of any curve after the apparent plateau.Anomalous Numerical heating, miscalibrated SEE, or finite-grid instability (Δx > λD). Phase 2 of the diagnostic (cumulative power balance) will quantify this drift directly.
KE growing exponentially.Anomalous Runaway ionization. Causes: SEE too high, sheath under-resolved, Δt too large.
Both KE and Ufield falling toward zero.Anomalous The discharge is dying out. Voltage too low, pressure out of operating range, or insufficient seeding.
⟨ε⟩i rising toward several eV.Possibly anomalous Ions heating up. Either physical (extreme voltage with sub-RF ion transit time) or a bug in the ion push.
Sudden jump in ⟨ε⟩e.Anomalous Particle thinning should preserve the velocity distribution; a jump indicates biased thinning.
Plateau values far from published reference (e.g. Turner benchmarks).Anomalous Cross-section file mismatch, gas-density miscalculation, or unit error somewhere. Compare against the reference table in the upcoming review paper.
💡 The combination Particle History + Energy History gives a complete picture of whether the simulation has reached steady state. Particle History tells you the particle balance is stable (Ne and Ni constant); Energy History tells you the energy balance is stable (KE + Ufield constant). Both are necessary; either alone can be misleading.

🎯 Cross-Section Viewer

Cross-section viewer for argon electrons
Electron–argon cross sections, log-log axes. The legend in the bottom-left lists each channel; the discrete thresholds of the excitation lines and the ionization channel are clearly visible as the curves rise from zero at their respective onsets.

The viewer shows the tables exactly as the engine parsed them from ELECSCAT.DAT and IONSCAT.DAT. Where these files come from, which gases they cover and how to extend them: Cross-Section Files (DATA).

The cross-section viewer plots the collision cross sections σ(ε) used by the Monte-Carlo collision model, against energy, on log–log axes. It is the way to check that the right data set is loaded for the chosen gas and to see the thresholds and magnitudes that drive the ionization, excitation and scattering rates. It reads the same LXCat-format files the engine uses — ELECSCAT.DAT for electron–neutral collisions and IONSCAT.DAT for ion–neutral collisions, both in the DATA folder — and is opened from Input → Plot Cross Sections (Electrons or Ions).

What it plots

All the channels of the current gas and species are overlaid on one plot, each in its own colour, with a legend. For electrons these are the elastic / effective / momentum-transfer cross section, the excitation channels (each with its own threshold), the ionization channel and, where present, attachment. For ions they are the elastic and backward-scattering (charge-exchange) cross sections.

Controls

ControlWhat it does
Electrons / IonsA toggle switching between the electron–neutral and ion–neutral data sets.
GasA drop-down selecting which gas's cross sections to show.
Log ε / Log σIndependent logarithmic scales for the energy and cross-section axes (log–log by default).
ε / σ ranges, Grid, LegendThe usual axis ranges, grid and legend toggle, plus the title and text dragging common to all viewers (see Working with Viewers).
ℹ️ The viewer reflects the files on disk, so the curves are exactly what the engine interpolates at run time. If you build a gas's ion cross sections from the Conditions dialog (General → ion cross-section panel), reopen or refresh the viewer to see them.
ℹ️ This viewer and the Collisions module are complementary, and the difference matters. This one plots each block of the file as written and never sums anything — which is exactly what you want when checking a data set, because it shows you what is in the file rather than what the code makes of it. The Collisions and Cross Sections module shows the other side: the totals the engine builds — with the EFFECTIVE/MOMENTUM subtraction applied, so its σtot is legitimately smaller than the sum of the curves plotted here — plus the mean free path, the collision frequency, νmax, the draws themselves and the rate coefficients, none of which is in the file at all.

📋 Params Viewer

Parameters viewer (read-only display)
Parameters viewer on a running positive-column (striations) case. Top: the derived plasma parameters (frequencies, ω·Δt products, collision frequencies, Te, Debye length, per-cell statistics…). Bottom: the dt limits section with the constraint currently binding, here the Courant limit. The two buttons at the bottom open the Power balance and Particle balance panels.

The Params viewer is a small, read-only window that shows the live numerical state of the running simulation — the derived plasma parameters and the time-step constraints — refreshed about twice a second from snap/status.bin. It has no plot; it is a monitor, the quickest way to confirm that a run is well resolved. It is opened from the Parameters menu. Beyond the passive read-out, three expandable panels — Power balance ▸, Particle balance ▸ and Collisions ▸, described below — turn it into a quantitative bookkeeping tool for the energy, particle and collision budgets of the discharge.

What it shows

The upper section lists the derived plasma quantities: the simulation time and dissipated power; the plasma, electron-cyclotron and ion-cyclotron frequencies ωpe, ωce, ωci and their products with the time step (ω·Δt, which should stay well below 1); the elastic and ionization collision frequencies; the electron temperature and excitation temperature; the Bohm velocity; the electron and ion Larmor radii; the Debye length λD; the peak ion density; the cell size Δx and the number of grid points; the total electron and ion super-particle counts and the average number of electrons per cell; and the relative growth rate (1/N) dN/dt.

The lower dt limits section shows the current time step alongside the constraints that bound it — the plasma-frequency, cyclotron, collision and RF-period limits — with the currently constraining one highlighted. Lines that do not apply are hidden: the cyclotron line without a magnetic field, the RF line without an RF source, the collision line without a gas, and the Debye/ωpe indicators in the Laplace (no-Poisson) mode, where they are meaningless. The Courant line is shown for information (it does not drive Δt — see Field Solver & Time Step), evaluated against the robust cutoff speed v*, not the raw maximum.

A separate fast e⁻ step read-out answers the question the bare Courant number cannot: does the field change appreciably over the distance a fast electron covers in one step? It reports two numbers — the displacement v*·Δt as a fraction of a cell (context) and, more usefully, as a fraction of the field scaleE = (φmax−φmin)/|E|max, roughly the sheath thickness. It is this second fraction that decides whether a trajectory is well resolved: a value well below 1 means even the fast electrons see a smoothly varying field within a step, so the large cell-crossing count that a Debye-resolved grid inevitably produces in a hot discharge is harmless. (The naive "fraction of electrons crossing a cell" reads ≈100 % in any DC glow by construction — the grid is sized by the cold bulk's Debye length while the ionization is done by a hot beam — and is not reported for that reason.)

Power, particle and collision panels

Three on-demand panels turn the monitor into a quantitative bookkeeping tool. Power balance ▸ opens a table of every power channel in W/m² — input from the field and the applied voltage, losses at each wall, collisional losses (with a separate Coulomb e-e line when Coulomb collisions are enabled), and a Residual = in+app − wall − coll line that should hover near zero in steady state. A second column expresses each channel as a percentage of the total input power (Source + Heating + Applied I·V — the input side of the residual identity): the inputs sum to 100 %, wall plus collision losses approach 100 % at steady state, the residual percentage is the convergence metric, and the Pe,f/Pi,f rows read as the sharing of the applied power between the species (their remainder to 100 % being dU/dt). An Averaged toggle shows running time-averages instead of instantaneous values, with a Reset avg button. Particle balance ▸ does the same for the particle channels — ionization source, SEE, external source and injection, wall losses (shown negative) — summing to dN/dt. Each channel is shown both as an equivalent current density in A/m² (rate × e) and as a percentage of the species' total production: the creation channels of each species sum to 100 %, so the relative weight of ionization vs. secondary emission is read directly, and at steady state the wall loss reads ≈ −100 %.

Power balance panel
Power balance (W/m²) on a running RF positive-column case, in Averaged mode. Input (field → electrons/ions, applied I·V) balances the wall and collision losses; the residual here is 0.06 W/m² for ≈94 W/m² applied — 0.07 %. Rows that do not apply (no external source here) show a dash.
Particle balance panel
Particle balance on the same run (Averaged): for each species, the creation channels against the losses (walls, shown negative), each given as an equivalent current density in A/m² and as a percentage of the species' total production — the creation channels sum to 100 %, the wall loss approaches −100 % at steady state. The residual — channels minus the measured dN/dt — sits many orders of magnitude below the production, i.e. every particle is accounted for.

When electron-electron Coulomb collisions are active, an additional Coulomb e-e block reports the sub-cycling diagnostic — the effective scattering parameter s per application — and advises keeping s ≲ 0.05 (increase coulomb_nsub otherwise). The block is hidden when Coulomb collisions are off.

The third panel, Collisions ▸, summarizes the collisionality of the discharge in one table: for the electrons and, below, for the ions, it lists the collision frequency ν and the mean free path λ of each process (elastic, excitation, ionization; isotropic scattering and charge exchange for the ions) together with the totals and the mean speed, evaluated over the central 20 % of the gap. For threshold processes the mean free path is threshold-weighted — it averages λ(v) = 1/(Nσ(v)) over the particles that actually participate (those above the threshold), so λioniz describes the fast electrons that ionize rather than dividing a bulk speed by a tail rate. A final block of ratios answers the practical questions directly: λe/gap and λi/gap (is the discharge collisional?), λi/field-scale (is the sheath collisional? — this controls the broadening of the IFEDF), and λe/Δx. The ion lines are greyed out when ion collisions are disabled, and a note appears when no ion cross-section data are available (the engine then falls back to constant cross sections). The panel reads snap/collisions.dat, computed by the engine itself. Note that with anisotropic elastic scattering enabled (Advanced → Special) the elastic line reports the effective frequency νeleff — larger than νm, since the anisotropic scheme trades more collisions for smaller deflections at exactly constant momentum transfer.

ℹ️ Reading the Averaged residual in RF. The elementary accumulation box is one RF cycle, closed at the first time step that crosses the cycle boundary; the instantaneous applied power I·V carries a large reactive component at 2ω, so the per-box residual fluctuates. "Averaged" integrates every term cumulatively from the last Reset avg, and the leftover oscillation of the residual decays as 1/Tavg with a phase-dependent amplitude — expect it to alternate between small and larger values while shrinking as the averaging window grows. Judge convergence on a long window, or Reset avg once the discharge is established.
💡 A quick health check: ωpe·Δt should be well below 1, there should be at least several electrons per cell, and Δx should be no larger than the Debye length. The highlighted dt limit tells you what is currently setting the time step — the collision rate, the plasma frequency, the cyclotron motion or the RF period. In steady state, the power-balance Residual should be a small fraction of the input power.

🎨 Palette Editor

Palette editor for 2D colour maps
The curve editor of the palette editor (here viridis, RGB mode): drag the control points of the active channel, Double them to refine without losing the current shape, Create to save the result as a custom palette. Custom palettes then appear in the colour-map picker of the X-T viewer (under the "Custom" separator).

The palette editor creates and edits the custom colour maps used by the 2D viewers (X-T, EEPF-2D and phase space). Palettes saved here are written to custom_palettes.json and then appear, together with their inverted variants, in the colour-map picker of every 2D viewer (under the "Custom" separator). It is opened from the Input menu.

Choosing a palette to edit

The window has two panels, each as wide as its content and each with its own scrollbar, and the mouse wheel scrolls whichever of the two the pointer is over. The upper one lists the built-in matplotlib palettes as gradient bars; clicking a bar opens it in the curve editor. Every bar is split in two: click the left half to edit in RGB, the right half to edit in CIELAB, a perceptually uniform space in which L* is lightness and a*, b* the two chromatic axes. The lower My Palettes panel lists your own palettes, each with a gradient bar (click to edit), a name (click to rename) and a ✖ to delete it.

ℹ️ CIELAB used to be unreachable in the packaged application: the mode was guarded by an optional scikit-image import that is not bundled, so the right half of a bar silently fell back to RGB. The conversions are now written directly in NumPy — validated against scikit-image to the last bit on rgb2lab — so the mode works identically whether JC-PIC runs from the sources or from the installed executable, and there is no optional dependency left.

The curve editor

The curve editor shows the colour channels (RGB or L*a*b*) as editable curves over the 0–1 span of the colour map, with a live preview of the resulting gradient. You shape each channel by dragging its control points; the interpolation between them can be switched between Spline, Linear and Rectangular (stepped). Two buttons commit the result: Create always saves a new palette, while Save replaces the one being edited in place — the latter is enabled only for your own palettes, since the built-in maps are read-only.

Three controls of the bottom bar govern the control points themselves:

ControlWhat it does
Points − nn +Resample the original palette on a uniform grid of nn points. Useful to start over ("give me back 12 evenly spaced points on the palette I opened") but note that it therefore discards the edits made so far.
DoubleInsert one control point in the middle of every interval, on all three channels at once, without changing the palette: n points become 2n−1 (20 → 39 → 77 → 153). Each inserted point takes the value of the current interpolant at the midpoint — not the average of its neighbours — which is what makes the operation exact, in all three interpolation modes, spline included. Unlike Points −/+ it keeps all the work already done, so this is the button to use when the overall shape is right and you want finer handles to sculpt one region. The ceiling is 256 points; a doubling that would exceed it is refused with a message and changes nothing.
R | G | B (or L* | a* | b*)The active channel selector, in the colour of each curve. The selected channel is drawn on top, opaque, with larger handles, and it is the one a drag grabs; the other two are dimmed. This matters wherever control points coincide — on any grey, white or black part of a palette all three channels sit exactly on top of each other, and in CIELAB a* and b* coincide over the whole neutral range. A point that is not covered stays directly grabbable whatever the selector says, and grabbing it promotes its channel.
💡 To recolour a 2D viewer with a palette you have just made: create it here (it is written to custom_palettes.json automatically), then open the viewer's colour-map picker (the Cmap button) and pick it from the Custom section.

🖼️ Figure Layout

Figure Layout is the page on which the plots produced by the viewers are assembled into a single figure for a paper or a talk — a 2×2 panel, a column of three, a large map with an inset and an arrow pointing at it. It is opened from Graphics → Figure Layout…, in all three menu sets (PIC, Viewer and Swarm mode). It holds no data of its own: what it composes is what the viewers hand it through the clipboard.

The Figure Layout page
Four X-T maps composed into one publication figure. Each tile keeps its source resolution and is resampled once, when the page is rendered.

Why it is a page and not a canvas

Two decisions shape everything else. The page is measured in millimetres and its text in points, never in screen pixels, so the same document exports correctly at 150, 300, 600 or 1200 dpi — asking for a higher resolution gives more pixels, not smaller text. And each source image keeps its own resolution and is resampled exactly once, when the page is rendered at the requested size, so nothing is degraded by being moved around. The on-screen preview is that same rendering call at screen resolution, which is what makes it faithful.

Getting the plots in

Copy a figure from any viewer with Ctrl+Shift+C — the 600 dpi copy — and paste it here with Ctrl+V. Tiles are placed in flow, two per row, so four pasted panels land as a 2×2 immediately. Replace by clipboard swaps the bitmap of a selected tile while keeping its box, which is how a panel is updated after re-running a case. Each tile remembers where it came from.

Arranging

ActionHow
SelectClick. Shift+click or Ctrl+click adds to or removes from the selection, a rubber band on the background selects everything it touches, and Ctrl+A takes all.
MoveDrag any selected object and the whole selection follows. The arrow keys nudge by 0.5 mm, or 0.1 mm with Shift.
ResizeEight handles. The four corners scale the tile with its aspect ratio locked; the four edges change one dimension only — which necessarily releases the aspect lock, the alternative being a gesture that does nothing.
Align / DistributeThe Align L C R | T M B row aligns the selection on its own bounding box, not on the page. Distribute ↔ ↕ equalizes the gaps, not the centres — the only definition that is correct when the panels have different widths.
CropA non-destructive crop mode, plus percentage fields and an Uncrop. The crop is stored as fractions of the source, never as a re-encoded bitmap: the render cuts an exact selection of pixels and then resizes once. Cropping removes content, it does not zoom, and it survives Replace by clipboard.
Copy / paste / duplicateCtrl+C and Ctrl+V work inside the page, on an internal clipboard, and Ctrl+D duplicates in place. Ctrl+Shift+V and the toolbar's Paste always go to the Windows clipboard instead — that is how you bring a viewer figure in when something of your own is on the internal one.
Escape / DeleteEsc is contextual: it cancels a crop in progress, otherwise disarms the drawing tool, otherwise drops the selection. Del always deletes.

Text and drawings

A vertical tool palette down the left edge carries selection, text, arrow, line, rectangle and ellipse. One tool is armed at a time, and the page returns to Selection after a shape is drawn or on Esc. Shapes are drawn by dragging, live, and their properties — stroke colour, width in points so it is invariant under the export resolution, optional fill with its own colour and opacity, and free rotation — are edited from the toolbar. Text has a size in points, a free angle, bold, italic, colour, six font families with automatic fallback, an optional white halo, and $…$ mathematics rendered by the same engine the case descriptions use.

Exporting and saving

Export PNG writes the page at the chosen dpi. Save writes a .jcfig file — self-contained JSON with the images embedded, so a layout can be archived or sent to someone else and reopened with Open… exactly as it was. The format is forward-compatible: a file written before the crop feature existed reopens and renders identically.

ℹ️ Not yet implemented, and worth knowing so you do not look for them: vector PDF export, magnetic alignment guides while dragging, and regenerating a tile from its recorded source at the export resolution. The page format is ready for all three.

🧲 Single-Particle Motion

This module integrates the equation of motion of one charged particle in imposed electric and magnetic fields. It is not a plasma simulation: there is no grid, no Poisson solve, no self-consistency and no working directory. What it does have is the two things that make it honest — the Boris pusher, the very scheme the engine uses, and the real cross sections read from ELECSCAT.DAT and IONSCAT.DAT. It answers in milliseconds, so every parameter is a slider and the trajectory redraws as you move it.

ℹ️ Why a separate module. A cycloid in a PIC run would cost hours of computing to show something that follows from three lines of mechanics, and it would be buried in the noise of a discharge. The complementary view — the same cycloid found inside a real simulation — belongs to the phase-space viewer and to the tagged-particle diagnostics; this module is the clean statement of what the motion is, before the plasma complicates it.
The Single-Particle Motion module
Case 2, the E×B drift: electron and ion gyrate in opposite senses with radii in the ratio √(M/m), and drift at the same velocity in the same direction — the statement that vE = E/B depends on neither mass, nor charge, nor energy.

Opening it

The eight cases

#CaseWhat it is meant to show
1Gyration in a uniform fieldThe Larmor radius r = mv/qB and the period 2πm/qB — the radius depends on the velocity, the period does not. Adding a parallel velocity gives the helix. An optional explicit Euler integrator is offered as a counter-example: the same orbit spirals out, which is the clearest possible argument for the Boris scheme.
2The E×B driftThe cycloid, and vE = E/B. Electron and ion are drawn together: opposite gyration senses, radii in the ratio √(M/m), and the same drift, in the same direction. Independence from mass, charge and energy is a two-line proof at the blackboard; here it is a picture.
3E along BFree acceleration along the field line, gyration unchanged. The contrast with case 2 is the whole subject of magnetic confinement.
4Oblique field — the Chodura geometryE at an angle to B, decomposed into a parallel acceleration and a perpendicular drift. This is exactly the configuration of the Sheath in an Oblique Magnetic Field case and of the btype = 4 option of the B Field tab.
5Grad-B driftA non-uniform field, built with the same profile formula the engine uses. The drift is opposite for electrons and ions — a charge separation, which is the seed of the whole zoology of E×B instabilities in the library.
6The magnetic mirrorA field with a minimum: the bounce, the invariance of µ, and the loss cone sin²θ = Bmin/Bmax. The read-out gives the loss-cone angle and says whether the particle is inside it.
7Collisions across BThe same E×B configuration, in argon, with real cross sections. The guiding centre performs a random walk across the field, and sweeping the pressure walks the transverse mobility µ = µ/(1 + ωc²/ν²) from the magnetized limit to the collisional one — cross-field transport in a single picture.
8Free explorationEvery control unlocked, nothing preset.

The control panel

A scrolling column on the left. Only the controls that act on the selected case are shown, which is what keeps eight cases in one window without it becoming a cockpit. Depending on the case you will find: the Case and Gas lists (19 gases); sliders for the magnetic and electric field, the angle between them, the initial energy, the pitch angle, the pressure, the gradient scale length, the mirror ratio, the starting position, the length of the window in cyclotron periods, and the film's frames, trail and fps; a plot list choosing the pair of axes (or auto, or space (3D window)); a scales list (1:1, fill the window, or a fixed ratio); the corner in which the field diagram sits; and check boxes for showing the ion, the guiding centre and the field on the plot, enabling collisions, measuring lengths in Larmor radii, giving both species the same perpendicular velocity, switching to Euler, and redrawing a new random trajectory on each loop of the film.

The read-out panel

Under the plot, a panel gives the numbers of the figure being shown — Larmor radius, cyclotron period, drift velocity, loss-cone angle, collision frequency ν, the ratio ωc/ν and the resulting µ/µ — so that the picture and the formula can be checked against each other without leaving the window. It is also where the module warns you, in words rather than by drawing something misleading: that the gradient is too steep for a guiding-centre drift to mean anything, that the trajectory is too elongated to keep the axes equal, that a quantity you are watching is in fact constant, or that the time window had to be cut short by the ceiling on the step.

Mouse gestures

These are the same in this module and in Collisions and Cross Sections. Legends and titles keep the ordinary behaviour of the other viewers — drag to move, double-click to edit.

WhereGestureEffect
On the x tick banddragMove the origin along x.
wheelChange the x scale.
On the y tick banddrag / wheelThe same, for y.
Inside the plotdragMove both origins together.
wheelZoom about the pointer.
double-clickBack to automatic scaling.
Anywhereright-button dragMove the plot frame itself (or the field diagram).
drag an edge or a cornerResize the frame. Alt+drag and Alt+wheel do the same, with Ctrl for width only and Shift for height only.

The film and the 3D window

Play animates the trajectory, and any parameter can be moved while it runs — it simply continues on the new trajectory. ● Rec opens the usual recording dialog (GIF or MP4): Start, Play, then Stop & Save.

The 3D button — or the space (3D window) entry of the plot list — opens the trajectory in space in a window of its own, rotatable with the mouse, with the field lines as dashed curves (exact, and flux-conserving in the mirror case) and the guiding centre as a heavy line. Proportions are true unless the aspect ratio would exceed 8, at which point a flat axis is given a readable scale rather than a magnified view of round-off noise. The window is live: it follows the sliders, it has its own Play using the frames / fps / trail settings of the main panel, collisions are marked in red as they occur, and it has its own ● Rec.

The 3D trajectory window
The 3D window on the magnetic mirror. The field lines are drawn exactly and conserve the flux, so the pitch of the helix and the convergence of the lines can be read against each other.

State

On closing, everything is written to C:\JC-PIC\JSON\motion_viewer.json — case, gas, every slider and switch, the scales, limits and ticks, the titles with the positions you dragged them to, the curve styles, the plot frame, the diagram corner, and the random seed. A collisional trajectory therefore comes back identical, not merely similar, which is what makes it usable as a figure. The one deliberate exception: a case opened from the library does not overwrite that state.

💡 Case 7 is the natural companion to the Anisotropic scattering option of the Advanced dialog and to the transverse-transport discussion of the magnetized cases. Case 4 is the companion to the oblique B field of Conditions → B Field; case 5 to the E×B instabilities of rubrics 08 and 10.

💥 Collisions and Cross Sections

This module opens up the one physical ingredient JC-PIC does not compute but reads from a file. Everything a PIC-MCC run does with collisions — how often they happen, which process is drawn, what the particle looks like afterwards — follows from the cross-section tables, and this module shows each of those steps as a picture. Its architecture is that of Single-Particle Motion: a scrolling panel showing only the controls that act, the same mouse gestures, a movable diagram, loadable cases that open locked, and the same recording engine. It reads the cross-section files through the same code, so the two modules can never disagree about a gas. The files themselves — format, shipped gases, how to add your own — are described in Cross-Section Files (DATA).

The Collisions and Cross Sections module
View 1 on argon: the elastic momentum-transfer cross section with its deep Ramsauer minimum, the excitation channels switching on at their thresholds, and ionization above 15.8 eV.

Opening it

The seven views

#ViewWhat it shows
1σ(ε) of the gasEvery process of the selected gas and their sum, for electrons or for ions, with a second gas available for comparison. This is where the Ramsauer minimum of argon becomes an object rather than a word — and where it becomes clear why argon is not a gas like the others.
2Mean free path and collision frequencyλ(ε), ν(ε), the reduced ν/N, and the ratio of λ to the size of the simulation box — the number that decides whether a case is collisional at all.
3The null-collision methodν(ε) against the constant νmax, the fraction of draws that are real collisions, the number of trials per real collision, the resulting ceiling 0.2/νmax on the time step, and what the method does above the top of the table. The method itself is described in Theory → MC Collisions; this is the same thing seen from outside.
4Time between two collisionsA histogram of free-flight times drawn by the real null-collision loop, against the exponential law ν exp(−νt). Play accumulates draws and shows the histogram converging onto the law — and a time step above the ceiling makes it depart from it, visibly.
5What a collision doesThe energy after the collision, cos χ, and the share taken by each process, sampled with the engine's own routines: isotropic or screened-Coulomb (the aniso_coschi of the Advanced dialog), equal or OPB ionization sharing. The place to look before turning the anisotropic option on.
6Maxwellian rate coefficientsk(Te) = ⟨σv⟩ for each process, and the energy cost εc of creating one electron–ion pair — 41 eV in argon at 3 eV, the value quoted in the literature. This is the bridge to the 0D global model of rubric 01.
7Free explorationEvery control unlocked.

The description of the library rubric carries the classical theory the views illustrate: the two-body collision in the laboratory and centre-of-mass frames, the reduced mass, the energy transfer 2mM/(m+M)² (1 − cos χ) whose two limits — 2m/M for an electron, ½ for an ion in its parent gas — explain by themselves why a discharge has hot electrons and cold ions; the differential, total and momentum-transfer cross sections; and Coulomb collisions, with lnΛ, the dominance of small angles, and why the null-collision method does not apply to them.

View 4: the free-flight time histogram converging
View 4 under Play: the times drawn by the real null-collision loop converging onto ν exp(−νt). Raising the time step above 0.2/νmax makes the histogram visibly leave the law.

Three computed diagrams illustrate it — none of them drawn by eye. The first shows the same elastic collision twice: in the laboratory frame, with the impact parameter, the scattering angle and the recoil angle, and in the centre-of-mass frame, where nothing happens but a rotation through χ. The second shows the impact parameter setting the deflection, with four exact Coulomb orbits, and the ring b, b+db becoming the cone χ, χ+dχ — which is the definition of the differential cross section. The third shows why a Coulomb collision is not an event: the deflection falls off as 1/b while the number of encounters grows as b db, so every decade of impact parameter contributes equally to the accumulated square deflection. The sum diverges logarithmically and is cut off at the Debye length — and that is what lnΛ counts.

How this differs from the Cross-Section Viewer

ℹ️ The Cross-Section Viewer plots the tables as they are written in the file, block by block, and never sums anything. This module shows what the engine makes of them — including the EFFECTIVE subtraction described below — and adds everything that is derived from them: λ, ν, νmax, the random draws and the rate coefficients. Use the viewer to check a data file, and this module to understand a run.
⚠️ A word on EFFECTIVE data, because it is a genuine trap. Some gases are tabulated with an ELASTIC block, which is the purely elastic momentum transfer; others — argon, F₂, H₂, HCl, O₂, SF₆, and CH₄ through a MOMENTUM block — with an EFFECTIVE block, which is the total momentum transfer, elastic plus inelastic. Summing the blocks of the second kind counts the inelastic channels twice: in argon at 30 eV that is a total cross section 37 % too large. The engine has always subtracted correctly (σelastic = max(0, σeffective − Σσinelastic), the BOLSIG+ convention, announced by a [XSEC] EFFECTIVE data line in fortran.log) — no run has ever been affected — and this module does the same. The rule is stated in Theory → MC Collisions → Cross-section data (DATA) → File format.
💡 Views 3 and 4 are the practical answer to "what should my time step be?". The collisional ceiling 0.2/νmax read there is one of the three constraints of the Pusher, Poisson, dt chapter, and it is the one that bites in a high-pressure case. View 6 is the natural entry to Swarm mode, which computes the same coefficients over the real, non-Maxwellian distribution the field produces.

▶️ Run / Stop / Pause Modes

A simulation always runs out of its working directory, and how it starts depends on the state of that directory and on the Initialization checkbox (on the bottom bar of the Conditions dialog, mirrored on the Control tab). There are three workflows.

User actionResulting modeEffect
Init checked + RunFresh StartEverything reset to t = 0; checkpoint, history.dat and accumulators wiped.
Init unchecked + Run (run had ended/closed)ContinueRestart from the checkpoint; history and running averages preserved.
Pause, then RunResumePick up exactly where it left off, no reload.

Fresh Start. Tick Initialization and click Run: JC-PIC wipes the working directory's run state — the checkpoint, history.dat and every accumulator — and starts the discharge from t = 0 using the initial conditions of the Initial tab. This is how you compute a case from scratch, or start over after a change of physics.

Continue. Leave Initialization unticked and click Run when the directory already holds a checkpoint — a freshly loaded case, or a run that has ended or been closed: the engine resumes from that checkpoint, keeps the history and the running averages, and simply carries on. A run ends on its own when it reaches its End Time, or when you close JC-PIC — which first writes a final checkpoint, so a Continue later loses nothing.

Resume. If you Pause a running simulation, clicking Run again picks it up exactly where it left off, with no reload — the engine was only suspended, not stopped. Pausing is the natural way to freeze a run while you study a viewer; resuming is near-instant.

💡 Once a run has reached its End Time, Run will not go further until you raise End Time (µs) in the Conditions dialog. This prevents accidentally overrunning a finished benchmark — increase the End Time and Run again to extend it (in Continue mode).

Resetting the clock without losing the plasma

There is a fourth, narrower operation: keep the discharge exactly as it is and set t back to zero. It is what you want once a case has reached its steady state and you would like the production part of the run — the averages, the position-time window, the distributions — to start from a clean origin. The control is the Reset Time checkbox on Conditions → Diagnostics → Write/Store.

It is a one-shot action, not a stored parameter: ticking it issues the order and the box unticks itself, exactly like the other reset buttons. It is honoured during a run — the engine picks it up within about twenty iterations, roughly a third of a second — as well as at the next Run. A line of green text appears beside the box saying what became of it: requested…, then either done — clock restarted, meaning a running engine consumed it, or armed — applies at the next Run.

The reset is complete, which matters more than it sounds. Along with t and the iteration counter, it re-anchors the averaging window and the distribution-function window (which would otherwise be left pointing at the old clock, giving a negative integration window), arms the resets of the running averages, of the position-time accumulators and of the distribution functions, rewrites history.dat down to its header so the time axis is consistent, and neutralizes an End Time that would now lie behind the new clock.

ℹ️ The RF phase is preserved. The clock does not restart at a bare zero but at the beginning of the RF period in progress, tt mod (1/fref), with fref the lowest frequency involved — the fundamental, the second frequency of a dual-frequency case, or the frequency of an external waveform file. cos(2πft + θ) is then rigorously unchanged, so there is no phase jump and no artificial transient. The residue is at most one period — 74 ns at 13.56 MHz, that is 0.07 % of a 100 µs convergence study — and with no RF drive it is exactly zero.
⚠️ If no green text appears next to the box, the dialog you are using is an older frozen copy that only knows the former namelist key, and the order will have no effect during a run. Rebuild, or run the GUI from the sources.

💾 Restart & Checkpoints

JC-PIC's ability to pause, stop and resume — even across sessions, or on another machine — rests on a single restart file plus a set of persistent accumulators, all kept in the working directory's snap/ folder.

The checkpoint

The complete state of the simulation is saved to checkpoint.bin: the electron and ion counts, the simulation time, the current time step and the super-particle weight, followed by every electron's position and three velocity components, then every ion's. It is written every Store particles every steps (Conditions → Diagnostics → Write/Store, the ncheckpoint interval) and again, automatically, whenever the engine shuts down cleanly. A Continue reads it back; a Fresh Start overwrites it.

Persistent accumulators

The time-averaged diagnostics would lose their running averages on every restart if they lived only in memory, so they are checkpointed too: the position–time matrices (xt_accum.bin) and the current/voltage accumulators (cur_accum.bin) carry their state across a Continue, so a resumed run keeps building the same average instead of starting it over. This is why a long benchmark can be run in several sessions and still converge as if it had run in one.

A run driven by a current source (drive_mode = 1) carries one more piece of state that must survive a stop: the surface charge σ of the powered electrode, which holds the integrated current history — including any DC self-bias the discharge has built up. It is saved inside the checkpoint, so Pause/Stop and Continue are seamless: the imposed current resumes locked in phase and the bias is not lost. Continuing a current-driven run from a checkpoint written by an older JC-PIC version (which lacks this record) restarts σ from zero with a warning in fortran.log; a Fresh Start is the cleaner choice in that case.

Safe shutdown

Closing JC-PIC mid-run is safe. The engine is told to stop, finishes its current step, writes a final checkpoint and the accumulators, and signals that it is done before exiting — JC-PIC waits for that signal rather than force-killing the engine, so the binary files are never left half-written. If JC-PIC is closed abruptly (a crash, or the window manager killing it), a watchdog in the engine notices that the GUI's heartbeat has gone stale and performs the same graceful shutdown, so the simulation never keeps running orphaned in the background.

The heartbeat is a small file the interface rewrites every two seconds. The watchdog is deliberately slow to believe it: it requires the file to be more than 90 seconds old on three consecutive readings — some hundred seconds in all — before it concludes that the interface is gone, and a single fresh reading resets the count. A timestamp outside any plausible range is treated as unreadable rather than as very old, which neutralizes a file caught half-written. Each stale reading is logged as a strike n/3 line. The tolerance is not academic: an earlier, tighter rule (one reading, 25 s) was occasionally tripped by a machine going to sleep or a clock correction, and stopped long runs after several hours with nothing wrong.

ℹ️ The engine no longer stops without saying why. If it exits when no stop was requested, the reason is printed on the console — the [WATCHDOG] lines, or the exit code with the last lines of the log — and written to snap/stop_reason.txt. That file is the first thing to read when a run is found stopped and nobody stopped it.
ℹ️ If a checkpoint turns out to be unusable on a Continue — truncated, or holding more particles than the current build's arrays can accommodate — the engine falls back to a Fresh Start rather than loading corrupt data, and it preserves the existing history.dat so the scalar history is not lost. The fortran.log records what happened (look for [HIST] lines).

🎛️ Self-Adjust Ez

Self-Adjust Ez is a specialized heating mode for modelling the radial positive column of a long discharge in one dimension. In that geometry the simulation coordinate x is the radius, and the field that heats the electrons is the axial field Ez — perpendicular to x — which drives the current along the column. It is switched on by the Self-adjust perpendicular field Ez checkbox on Conditions → Voltage/heating → Electron heating (namelist key heating_self_adjust) and acts on the perpendicular heating field (heating_dir = ⊥).

The purpose of the mode is to keep the heating self-consistent with the plasma as it evolves. Instead of holding the axial field fixed, the engine rescales it in time as

Ez(t) = Ez0 · n0 / n(t)

where Ez0 is the field you entered, n0 is the reference density (density0 from the Initial tab), and n(t) is the current plasma density — lightly smoothed in time (an exponential moving average on the ion density) so the field reacts to the trend, not to the statistical noise. As the column fills up or depletes, the axial field follows, so the power coupled into the electrons tracks the density the way the real ambipolar column does. When the mode is on, the heating region is automatically taken to span the whole gap.

💡 This mode is meant specifically for positive-column studies; for an ordinary bounded discharge driven through the electrodes, leave it off and set the field or absorbed power directly on the Electron heating sub-tab. The bundled Positive Column cases are worked examples.

🗂️ Snapshots & History

Everything the engine produces is written into a single subfolder of the working directory, snap/. This is what makes a run persistent: the diagnostics are read from these files by the viewers (live, while the run proceeds, or later on a stopped run), the run can be resumed from them after a pause or a restart, and the whole state can be inspected from another machine simply by pointing it at the same folder. The files fall into four groups.

Restart state

checkpoint.bin holds the complete particle state — every electron and ion position and velocity, plus the simulation time, time step and super-particle weight — written periodically (the Store particles every interval) and again on a clean exit. A Continue run picks up from it; a Fresh Start deletes it and begins at t = 0. The diagnostic accumulators keep their own restart state alongside (for example xt_accum.bin for the position–time matrices and the current/EEPF accumulators), so a resumed run does not lose its running averages.

Diagnostic data (read by the viewers)

FileContents / viewer
history.datThe scalar time history — particle counts, mean energies, field energy, ionization and emission counts — as a plain-text table, one row per write. Read by the History and Energy viewers.
live_data.bin, snap_*.binThe full 1D profiles (densities, field, potential, energy, ionization, power). live_data.bin is memory-mapped for the live Profile and Heating viewers; the numbered snap_*.bin are periodic full snapshots.
live_phase.bin, phase_accum.binThe phase-space histograms f(x,vx) and f(x,ε), live and time-averaged. Read by the Phase Space viewer.
xt_diag.bin, xt_accum.binThe position–time matrices (and the moment data for the Schulze power decomposition). Read by the X-T and Heating viewers.
eepf.binThe electron energy probability function, bulk and position-resolved. Read by the EEPF and EEPF-2D viewers.
ifedf.binThe ion flux–energy distribution at each electrode. Read by the IFEDF viewer.
cur.bin, cur_accum.binThe discharge current and applied voltage waveforms. Read by the Currents viewer and its FFT window.
collfreq.binThe per-process electron collision-frequency profiles νj(x). Read by the Collision Frequencies viewer.
status.bin, runbar.binThe live plasma parameters (for the Params viewer) and the main-window progress bar.
💡 The snapshot format now also carries the per-cell mean axial velocities ⟨vxe and ⟨vxi (snapshot v6), used by the Electron & Ion Velocities profile mode. Viewer recordings (GIF/MP4) are saved in a separate images/ folder of the working directory, not in snap/.

Control and handshake files

A handful of tiny files coordinate the GUI and the engine, which communicate only through the disk: control.dat carries the run / pause / stop command; gui_alive.txt is the GUI heartbeat (if it goes stale the engine shuts itself down gracefully); done.flag signals that a clean shutdown has finished; reread_nml.flag (with nml_delta.txt) requests a hot reload of changed parameters; and a few reset_*.flag files zero a given accumulator on the fly — reset_time.flag for the simulation clock, reset_edf.flag for the distribution functions, and so on. One more file is written rather than read: stop_reason.txt, which the interface fills in when the engine exits without having been asked to. You never edit any of these by hand.

Where a case folder puts what

The viewers create two folders in the working directory the first time they are used, so that a case tidies itself:

FolderContents
images\Everything visual: figures saved from a viewer (PNG, PDF, SVG) and the GIF/MP4 recordings, including those made by Record All Viewers. This is the default folder of every Save dialog.
ascii\Everything numeric: the ASCII/CSV tables written by the Export buttons — profiles, slices, spectra. This is the default folder of every Export dialog.

The only exception is the Cross-Section Viewer, which is not attached to a case and therefore has no working directory to write into.

Where JC-PIC keeps its own paths

Two different locations are involved, and confusing them is the usual cause of "it started in the wrong folder":

ℹ️ If the saved working directory has been renamed or deleted, JC-PIC says so and falls back to C:\JC-PIC\RUN. A candidate folder must exist, lie outside the Windows and Program Files trees, and actually accept a write — the check is a real temporary file, not a guess. This is what prevents the application from being left in the directory Windows hands a shortcut, typically C:\Windows\System32, where every write it attempts is refused.

Log

fortran.log captures everything the engine prints — start-up parameters, periodic status lines, warnings and errors. It is the first place to look if a run behaves unexpectedly.

ℹ️ The binary files are little-endian with a fixed, documented header; their record layouts are not reproduced in this manual but are available from the author on request. The numbers you need are normally obtained through the viewers' Export buttons (ASCII/CSV tables written in ascii\). The plain-text history.dat can be opened directly in any plotting program. To reset a run completely, delete snap/ (or use Fresh Start); the case's input.nml is untouched.

📂 Cross-Section Files (DATA)

As noted above, JC-PIC hard-codes no cross section: at start-up it reads them from external tabulated data files — the electron set ELECSCAT.DAT and the ion set IONSCAT.DAT — and interpolates them on the fly for every collision test. Keeping the data outside the engine makes the collision physics fully transparent and lets a user swap in their own cross sections, or add a new gas, without recompiling anything.

The data live in the DATA folder of the JC-PIC installation — the folder you chose at first launch (default C:\JC-PIC\DATA). Two shared files hold everything: ELECSCAT.DAT for the electron–neutral sets (one block per gas, all gases in the same file) and IONSCAT.DAT for the ion–neutral sets; an optional per-gas ION_.DAT can supplement the latter (see "Adding a gas" below). The engine locates the folder through the data_dir namelist key, overridden by the JCPIC_DATA_DIR environment variable that the GUI sets automatically — so in normal use nothing needs configuring. If neither points to a valid file the engine falls back to an ELECSCAT.DAT in the working directory (with a loud warning: a stale local copy is a classic source of wrong collision rates).

The Gas menu of the Conditions dialog is not a hard-coded list: it shows exactly the gases found in ELECSCAT.DAT, so the file is the single source of truth. The data are in the LXCat / BOLSIG+ text format, and each gas block carries its own free-form header where the origin of the set (database, publication) is recorded — consult those header lines for the reference behind each shipped set, and keep the habit of citing them in publications.

ℹ️ Origin of the shipped data. The electron-neutral scattering cross sections included with JC-PIC are those from the SIGLO database (electron-Helium cross-sections are from Biagi-v7.1) on LxCat, an open source database available at www.lxcat.net. Many other databases as well as references can be found on LXCat. Please acknowledge LxCat and the database used in any publication based on these data.

What is shipped, and what is not. ELECSCAT.DAT carries electron sets for eighteen gases — He, Ne, Ar, Kr, Xe, H₂, N₂, O₂, CO₂, CH₄, CF₄, SiH₄, SF₆, Cl₂, F₂, HCl, Hg and Cu — so any of them can be selected in the Gas menu. IONSCAT.DAT, on the other hand, carries ion–neutral sets for the rare gases only (He, Ar and Xe from the Phelps database on LxCat; Ne from Piscitelli, Phelps, de Urquijo, Basurto & Pitchford, Phys. Rev. E 68, 046408, 2003). For every other gas the electrons collide normally but the ions fly collisionless: the engine writes a warning in fortran.log and carries on, which is fine for a quick look at the electron kinetics and wrong for anything that depends on the ion transport (sheath structure, ion energy at the walls, pressure effects). Before using such a gas in earnest, add its ion–neutral cross sections yourself, as described below — the two files are plain text and are meant to be extended.

⚠️ An update of JC-PIC refreshes the shipped ELECSCAT.DAT and IONSCAT.DAT, so a gas block you appended to either file is overwritten. Keep your additions in a copy, or — for the ions — in a per-gas ION_.DAT file, which the installer never touches.

File format

ELECSCAT.DAT follows the LXCat/BOLSIG+ block structure. Each gas is a sequence of process blocks preceded by a small gas header:

COMMENT
Ar                          ← gas name — exactly what the Gas menu shows

-----
ELASTIC                     ← process keyword
Ar                          (label line, ignored)
1.36e-5                     ← 3rd line: me/M mass ratio (elastic block)

-----
 1.000e-3   7.500e-20       ← data table: energy (eV), cross section (m²)
 ...
-----
EXCITATION
Ar
11.55                       ← 3rd line: threshold energy (eV)
...

The rules the reader applies:

IONSCAT.DAT uses the same skeleton, with three differences that matter when you write a block yourself. Each gas has exactly two process blocks, ELASTIC and BACKWARD, and both must be present or the gas is treated as absent. There is no scalar third line: the keyword, the gas name, then directly the fence and the table. And the energy column is the centre-of-mass energy of the ion–atom pair (Ecm = µg²/2, i.e. M g²/4 for an ion in its parent gas), not the laboratory energy of the ion — the convention of the Phelps ion sets on LxCat, and what the engine computes at every collision test. The gas name must be the same string as in ELECSCAT.DAT.

COMMENT
Ar                          ← same name as in ELECSCAT.DAT
Reference Phelps Database LXCat
-----
ELASTIC                     ← ion momentum-transfer cross section σ_mt(E_cm)
Ar
-----
 1.000e-3   2.413e-18       ← E_cm (eV), σ (m²)
 ...
-----
BACKWARD                    ← charge exchange / backscatter σ_cx(E_cm)
Ar
-----
 ...
-----

The engine interprets ELASTIC as the total momentum-transfer cross section and recovers the isotropic part as σiso = ELASTIC − 2 × BACKWARD (a charge-exchange collision reverses the velocity and counts twice in momentum transfer); it prints the values it will use at a few energies in fortran.log at start-up, which is the place to check a new block. A header line ION in the COMMENT block of a gas in ELECSCAT.DAT makes it borrow the ion set of another gas — the way to give a modified electron set the ion data of its parent gas without duplicating them.

Interpolation and extrapolation. At start-up every table is resampled once onto an internal log-spaced grid of 1000 energies, from 10⁻³ eV up to at least 500 eV (extended if the table goes higher), by linear interpolation between the tabulated points. Outside the tabulated range the cross section is clamped flat: below the first point it takes the first value, above the last point it keeps the last value — so a table that stops at, say, 100 eV silently reuses σ(100 eV) for faster electrons; extend the table if your discharge produces electrons beyond it. The interpolated set actually used by the run is dumped to snap/xsec.dat, which is exactly what the cross-section viewer displays — a convenient check that the file was parsed as intended.

Adding a gas or your own cross sections

Electron set. Append a new gas block to \ELECSCAT.DAT: a COMMENT line, then the gas name on its own line — that exact string becomes the new entry in the Conditions Gas menu (reopen the dialog to refresh the list) — then your reference lines, a -----, and the process blocks in the format above. LXCat exports are close to directly usable; the checklist that matters:

Ion set. Either add a matching-name block to IONSCAT.DAT in the format shown above (ELASTIC = momentum transfer and BACKWARD = charge exchange, both against the centre-of-mass energy in eV, cross sections in m², no threshold line), or use the built-in ion cross-section editor reachable from the Conditions dialog, which validates the tables (at least two points, positive values, increasing energies) and writes a per-gas ION_.DAT into the DATA folder. The engine looks first in the shared IONSCAT.DAT, then for ION_.DAT; if neither has the gas, ion–neutral collisions are simply disabled with a warning in fortran.log.

Verify before running. Open Input → Plot Cross Sections → Electrons / Ions on the new gas: the viewer plots each channel with its threshold, exactly as parsed — a ten-second check that catches unit slips and misplaced fences. If the physical ion mass is not the one implied by the file's me/M (isotopes, model gases), the Change to override on the General tab (mass_ratio_override, M/m) takes precedence without touching the file.

💡 The plot-cross-sections viewer answers "did my file parse the way I meant it to?". For "what will the engine do with it?", open Input → Collisions and Cross Sections… on the new gas: view 1 shows the totals after the EFFECTIVE subtraction described above, view 3 gives the νmax your data imply and the time-step ceiling that follows, and view 6 gives the rate coefficients. A set whose νmax is an order of magnitude above what you expected is a set with a unit problem somewhere.

🧪 PIC in a Nutshell

A self-consistent kinetic description of a plasma is given by the Vlasov–Boltzmann equation, which evolves the distribution function f(x, v, t) of each species in six-dimensional phase space. Solving this equation on a grid is prohibitively expensive: a modest 100-point resolution in each phase-space dimension already requires 1012 cells. The Particle-in-Cell (PIC) method circumvents this difficulty by sampling f with a finite set of computational super-particles, each representing many real particles, and following their trajectories in the self-consistent electric field generated by the rest of the population. PIC is therefore a Lagrangian (particle-following) method for the particles, coupled to an Eulerian (grid-based) method for the fields.

The reason for routing the Coulomb interaction through a grid rather than computing it directly between particle pairs is twofold. First, cost: a direct particle–particle (PP) summation of the long-range Coulomb force would scale as O(N²) per time step, prohibitive for the 105–106 super-particles needed to describe a discharge, whereas the particle–mesh (PM) approach — depositing charge on a grid, solving for the field on the grid, then interpolating the field back to the particles — runs in O(N + Ng log Ng). Second, and more subtle, accuracy: as Birdsall (1991) emphasizes, a direct N-body simulation with the modest 105–106 super-particles available exaggerates the Coulomb binary-collision rate by orders of magnitude, because each super-particle is much too point-like for the density it represents. The grid acts as a low-pass filter that removes precisely those spurious short-range interactions, leaving only the smoothed long-range Coulomb dynamics — which is the regime where the underlying physics actually lives, since real plasmas are essentially "(short-range) collisionless" on the scales of interest. The Monte Carlo Collisions (MCC) procedure then puts back the actually-physical binary collisions with neutrals on top of this clean Coulomb dynamics. The combination of the two is what Birdsall called PIC-MCC, and it is the modeling framework on which JC-PIC is built.

1D3V electrostatic geometry

JC-PIC is a 1D3V electrostatic code: positions are tracked along a single spatial coordinate x — typically between two parallel electrodes or along the axis of a positive column — while velocities retain all three components (vx, vy, vz). The 1D simplification assumes that the discharge is uniform in the transverse directions, which is a good approximation for many parallel-plate RF capacitive discharges and for axial transport in long cylindrical columns. Keeping all three velocity components is essential as soon as a magnetic field is present or as soon as the collision physics is to be treated correctly: an elastic scattering event redistributes energy among components even in a 1D geometry. "Electrostatic" means that the magnetic field is assumed external (not self-generated), which is justified at the densities and currents typical of low-temperature discharges.

The simulation cycle

One time step of the simulation consists of four operations applied in sequence to all super-particles, plus the stochastic collisions described in the next section. The classical PIC loop is illustrated below.

Move particles (Boris) Fᵢ → vᵢ → xᵢ m dv/dt = q (E + v × B) MCC stochastic collisions Weighting (xᵢ, vᵢ) → ρⱼ [charge to grid] Weighting Eⱼ → Fᵢ [grid to particles] Field solve (Poisson, Thomas) ρⱼ → φⱼ → Eⱼ ∂²φ/∂x² = −ρ/ε₀ Δt

PIC-MCC integration cycle, after Birdsall (1991), Fig. 5. Both particle ↔ grid steps are called weighting: the same shape function deposits charge from particles to the grid (right side) and interpolates the field from the grid back to the particles (left side). MCC, absent from Birdsall's original collisionless figure, is inserted here after the move.

1. Charge weighting

The position of each super-particle is mapped onto the cells of the spatial grid, and a weighted contribution to the local charge density ρ(x) is accumulated. JC-PIC uses linear (cloud-in-cell) weighting: a particle at position x contributes to the two surrounding grid points in proportion to its distance from each. This produces a smoother charge density than nearest-grid-point weighting and reduces spurious self-heating.

xj xj+1 Δx particle at x wj = 1 − f wj+1 = f f = (x − x_j) / Δx

Linear (cloud-in-cell) weighting. A particle between nodes xj and xj+1 deposits a fraction 1 − f of its charge on the left node and f on the right, where f is its fractional position in the cell. The same two triangular shape functions are used in reverse to interpolate the field back to the particle — the symmetry that eliminates self-forces.

2. Field solve

The electric potential φ(x) is obtained by solving Poisson's equation, ε0 ∂²φ/∂x² = −ρ, with Dirichlet boundary conditions set by the prescribed electrode voltages. The electric field follows as E = −∂φ/∂x, evaluated at the cell faces by central differences. See "Pusher, Poisson, dt" for the linear solver.

3. Field weighting

The field is weighted from the grid back to each particle position, using exactly the same linear shape function as in step 1 — Birdsall (1991) emphasizes that this symmetry between the two weighting directions is what keeps the scheme self-consistent. It eliminates self-forces (a particle does not exert a net force on itself) and makes the explicit electrostatic PIC scheme exactly momentum-conserving. Energy is only conserved approximately; the small finite-grid heating that remains is the main reason for the Δx ≲ λD resolution requirement (see below).

4. Pusher

The positions and velocities of all super-particles are advanced by one time step under the Newton–Lorentz equation, m dv/dt = q (E + v × B). JC-PIC uses the Boris algorithm — see the next section.

Between push steps, each charged particle has a probability of colliding with a neutral of the background gas. These stochastic events are added on top of the collisionless PIC dynamics through the MCC procedure described in "MC Collisions".

Strengths and noise

The strength of PIC is that the resulting description is fully kinetic: distribution functions are obtained directly, with no Maxwellian (or any other) closure assumption. Non-equilibrium effects such as electron beams accelerated by the sheath, runaway tails, two-temperature distributions, or the strongly anisotropic ion energy distribution at the walls are captured naturally — and these are precisely the effects that fluid models miss.

The price to pay is statistical noise. Because the distribution function is sampled by a finite number of super-particles, every grid quantity carries shot noise of order 1/√Ncell, where Ncell is the number of super-particles per cell. Practical simulations therefore require Ncell from a few hundred to a few thousand, depending on which moment of the distribution is of interest: density and flux are robust, temperatures are noisier, and the high-energy tail of the EEPF requires the most particles.

Resolution requirements

For an electrostatic PIC code to give physically meaningful results, three constraints must be met simultaneously.

ConstraintConditionWhat it sets
SpatialΔx ≲ λDCell size; drives the cell count.
Temporalωpe Δt ≲ 0.2Time step; drives the wall-clock cost.
StatisticalNcell ≳ 100–1000 (or ND = n λD3 ≳ 5–10 in 3D, Birdsall 1991)Controls shot-noise on the moments.

Here λD = (ε0 kB Te / ne e²)1/2 is the electron Debye length and ωpe = (ne e² / ε0 me)1/2 is the electron plasma frequency. Both are set by the local plasma parameters; in a discharge with strong density gradients, the most stringent values (highest density) determine the global Δx and Δt. If any of the three constraints is violated, the simulation either becomes unstable (numerical heating, finite-grid instability) or returns biased moments.

ℹ️ Order of magnitude for a typical capacitive RF argon discharge at 1 Pa: λD ~ 10-4 m, ωpe−1 ~ 10-9 s, with a few hundred cells across the gap and 105–106 super-particles per species in total.

It is important to note that these constraints apply specifically to explicit PIC schemes — the family to which JC-PIC belongs, and which integrate the equations of motion using only quantities known at the current time step. In implicit codes (Mason 1981; Brackbill & Forslund 1982; Langdon 1980; reviewed by Birdsall 1991), the unknowns at step n+1 enter the discretized equations on both sides, so that the field solve and the particle push are coupled through a non-linear iteration. Implicit schemes can take ωpe Δt ≫ 1 and therefore relax both the temporal and the spatial constraints — but only on long-wavelength, slowly-varying components of the dynamics: their accuracy still requires k v Δt ≪ 1 and moderate field gradients. Sub-cycling, energy conservation and statistical noise can no longer be controlled independently; assessing what is and is not resolved in an implicit run is harder than in an explicit one. For most low-temperature discharge problems, the explicit approach used in JC-PIC is the simplest and most transparent route, and is well-suited to the time and space scales involved.

Pusher, Poisson, dt

The Boris pusher

Advancing a charged particle in combined electric and magnetic fields requires more care than a naive Euler step. The reason is that the magnetic part of the Lorentz force, q v × B, does no work; the particle should rotate around B at the cyclotron frequency Ωc = qB/m without losing or gaining energy. A simple explicit Euler scheme cannot satisfy this: every step injects a small amount of spurious energy, and over many cyclotron periods the orbit spirals away from its true path.

The Boris algorithm avoids this defect by splitting one time step into a half electric acceleration, a pure magnetic rotation, and a second half electric acceleration. This is exactly the sequence implemented in the JC-PIC pusher; written out in full, with q/m the charge-to-mass ratio of the species, the six operations applied to each super-particle are:

#OperationFormula
1Half electric kickv = vn + (q/m) E (Δt/2)
2Rotation vectort = (q/m) B (Δt/2)
3Scaled vectors = 2t / (1 + |t|²)
4First cross productv' = v + v × t
5Second cross productv+ = v + v' × s
6Half electric kickvn+1 = v+ + (q/m) E (Δt/2)

Steps 4 and 5 are the two successive cross products that together rotate v into v+ by exactly the angle Ωc Δt about B, with Ωc = |q|B/m the cyclotron frequency. The construction of the auxiliary vectors t and s is what makes the rotation exact for any Δt — there is no small-angle approximation, so the orbit radius is preserved even when Ωc Δt is of order one. The new position then follows from the updated velocity, xn+1 = xn + vxn+1 Δt (only the x coordinate is advanced in this 1D3V geometry; the y and z velocities still enter the rotation and the collisions).

B (into page) v⁻ after ½ E-kick v⁺ before ½ E-kick v' θ = Ωc Δt θ

The magnetic rotation (steps 4–5) in velocity space. Both cross products preserve the length, so v⁻ and v⁺ lie on the same circle and differ only by the rotation angle θ = ΩcΔt about B. The dashed vector v' = v⁻ + v⁻ × t is the geometric intermediate used to reach v⁺ = v⁻ + v' × s in closed form. The two half electric kicks are applied before v⁻ and after v⁺.

When no magnetic field is present (B = 0, the default for most capacitive-discharge cases), JC-PIC short-circuits the rotation entirely and the pusher reduces to a single leapfrog acceleration, vxn+1 = vxn + (q/m) E Δt — algebraically identical to the full scheme with t = 0, but cheaper. The field E is interpolated to the particle with the same linear (CIC) shape function used for the charge deposit.

Boris is second-order accurate in time, time-reversible, and conserves the kinetic energy in a static magnetic field to machine precision. It has been the de facto standard for plasma PIC codes since the 1970s — Birdsall & Langdon trace the modern form to Boris (1970) and Buneman — and remains the appropriate choice for non-relativistic low-temperature plasmas.

Poisson solver (Dirichlet)

In one dimension, the discretized Poisson equation reduces to a tridiagonal linear system, which the Thomas algorithm solves in O(N) operations. A single forward sweep eliminates the sub-diagonal coefficients, then a back-substitution recovers the potential at every grid point. This is fast enough that the field solve is rarely a bottleneck in 1D — the cost is dominated by the pusher and the MCC step, both of which scale with the number of particles, not with the number of cells.

The default boundary conditions are Dirichlet at both electrodes, with the applied potentials VL(t) and VR(t) prescribed by the user. They can be constant (DC), sinusoidal (single-frequency RF), or a sum of harmonics (dual-frequency or tailored-waveform discharges). The Conditions dialog exposes all of these options; see "Discharge Tab". The electric field is then recovered from the potential by centered finite differences, E = −(φk+1 − φk−1)/2Δx — the same stencil used in the periodic case below, and consistent with the CIC interpolation in the pusher so that the discrete scheme stays momentum-conserving.

Poisson solver (periodic)

JC-PIC also supports periodic boundary conditions on the spatial domain, in which a particle that leaves through one end re-enters through the other and the potential satisfies φ(0) = φ(L). This is the natural setting for problems without electrodes — for instance the steady-state positive column of a long DC discharge, where the simulation domain represents one period of an axial striation pattern, or swarm-type problems in which a uniform external field drives the transport. With periodic boundaries the absolute level of the potential is undetermined (only its gradient matters), so the global current rather than a fixed voltage is typically the controlled quantity. The boundary mode is selected together with the heating term in the Heating tab.

Numerically, the periodic case cannot use the plain Thomas algorithm: the wrap-around couples the first grid point to the last, which adds two entries in the top-right and bottom-left corners of the matrix and turns it from purely tridiagonal into cyclic tridiagonal. JC-PIC solves it with a dedicated routine (internally TRIPER) that keeps the O(N) cost of a Thomas sweep but folds in the two corner couplings through a single rank-one (Sherman–Morrison) correction. Two extra steps are needed because the cyclic Laplacian is singular — adding a constant to φ everywhere leaves the equation unchanged:

Tridiagonal — Dirichlet solved by Thomas Cyclic tridiagonal — periodic solved by TRIPER wrap- around

The discrete Laplacian. With Dirichlet electrodes (left) the matrix is purely tridiagonal and the Thomas algorithm applies directly. The periodic wrap (right) adds two off-band corner entries (gold) coupling the first and last grid points — making the matrix cyclic tridiagonal, which JC-PIC solves with the dedicated TRIPER routine at the same O(N) cost.

Finally the field is taken by the same centered difference as in the Dirichlet case, with the neighbours wrapped periodically (φ−1 ≡ φN−1, φN ≡ φ0), and the spatial mean ⟨E⟩ is explicitly subtracted. With charge neutrality and centered differencing this mean is already zero analytically, so the subtraction only removes round-off, but it guarantees that a long run cannot accumulate a spurious bulk drift of the whole plasma.

Time step constraints

The time step Δt must resolve every fast time scale in the problem. JC-PIC forms, at each adaptation check, a candidate Δt from each of the following criteria and takes the most restrictive. Each criterion carries its own safety coefficient (the cfl_* namelist keys), so the user can tighten or relax them individually.

CriterionCandidate ΔtCoefficientOrigin
Plasma frequencyΔtωpe = cflωpe / ωpemaxcfl_wpe ≈ 0.2Resolves the fastest plasma oscillation with small phase error.
Cyclotron frequencyΔtωce = cflωce / ωcemaxcfl_wceResolves the gyration when a magnetic field is present (skipped if B = 0).
CollisionsΔtcol = −ln(1 − cflcol) / νnullcfl_colKeeps the per-step collision probability below cflcol — at most ≈ one collision per particle per step.
Driving periodΔtrf = Trf / 50fixed (÷50)Resolves the RF / heating waveform (and its second harmonic in dual-frequency runs).
Courant (CFL)Δtcfl = cflcou Δx / v*cfl_couComputed and displayed, but not binding — see below. The speed v* is a robust cutoff, not the raw maximum.

The plasma-frequency criterion is normally the most stringent in a well-resolved discharge. Note the distinction between stability and accuracy: the explicit Boris/leapfrog scheme is formally stable up to ωpe Δt < 2 (Birdsall 1991; Donkó 2021), but the plasma oscillation acquires a noticeable phase error well before that bound, which is why cflωpe ≈ 0.2 is the standard practical choice. The collision criterion only becomes tight at high pressure or in very fast tails; it is evaluated against the null-collision frequency νnull, which already bounds the true rate (see "MC Collisions").

The Courant limit Δtcfl = cflcou Δx / v* is computed and reported in the Params viewer, but by design it does not drive the time step in JC-PIC. It is nonetheless worth understanding what the reported value means, because the naive form of this criterion is actively misleading. The raw maximum electron speed vmax is set by a handful of runaway tail electrons; binding Δt to it would shrink the step far below what the bulk dynamics needs and slow the run for no physical benefit — and, worse, its value would drift with the particle count (the maximum of N samples grows like √ln N), so the reported dtcfl would depend on how many super-particles you happened to load. JC-PIC therefore reports the Courant limit against a robust cutoff speed v* instead of vmax. When ionization is active, v* is the speed above which the electrons carry less than a small fraction cfl_iz_frac (default 1 %) of the total ionization rate — i.e. the fastest speed that still matters physically, obtained from the electron energy histogram the engine already builds each adaptation cycle. With no ionization (a collisionless wave or beam case) v* falls back to cfl_xmean·⟨ε⟩ (default 5·⟨ε⟩), capped by the true maximum so a cold beam stays honest. This v* is EMA-smoothed in time (vmax_smooth), so the reported dtcfl is steady rather than jittering with the tail. The deeper reason the criterion is not binding is that PIC is more forgiving than a fluid code — particles may cross several cells per step at only a modest cost in the accuracy of the moment estimates — but the Params viewer now also reports the relevant question directly (see the fast e⁻ step line there): whether the field changes appreciably over v*·Δt, measured against the sheath scale rather than the cell.

Fixed vs. adaptive Δt

Two modes are available, selected by dt_mode in the Parameters dialog:

Whenever Δt changes, the leapfrog staggering between x(t) and v(t − Δt/2) would be broken, so JC-PIC performs a half-kick resync: the velocities are shifted by (Δtold − Δtnew)/2 (and by Nsub times that for the subcycled ions) to restore the correct half-step offset. The collision probabilities Pnull = 1 − exp(−νnullΔt) and the averaging cadence are recomputed at the same time.

💡 In practice, start with the conservative choice cflωpe ≈ 0.1–0.2 and Δx ≲ λDmin. If the simulation is stable, you can usually relax these by a factor of two without measurable impact on the diagnostics. Watch the dt limits: trace printed each diagnostic interval — it shows which criterion is currently binding.

Ion subcycling

Because ions are typically four to five orders of magnitude heavier than electrons, they move much more slowly and require neither the same temporal resolution nor the same numerical care. JC-PIC pushes ions only every Nsub electron steps, with Nsub chosen so that the ion CFL is still satisfied. The cost of the ion push is essentially divided by Nsub, which can speed up a typical capacitive-discharge simulation by a factor of 5 to 10. The ion charge density is held constant between pushes — an excellent approximation given the slow timescale on which it varies — so the field solve still uses up-to-date ρ(x) every step.

🌱 Loading & Injection

Before the first push, the simulation has to be filled with super-particles whose positions and velocities sample the desired initial distribution; and during the run, particles may have to be added at the boundaries to model an emitting electrode or an external source. This section describes how JC-PIC sets the super-particle weight, how it lays down the initial Maxwellian plasma, and how it injects electrons at the left wall. All of the options below are exposed in the Conditions dialog (Initial and Boundaries tabs); here we describe what the code actually does with them.

Super-particle weight

A super-particle (or macro-particle) stands for many real particles. In a 1D code the natural bookkeeping is per unit electrode area, so JC-PIC defines the weight as

w = n0 Δx / Ncell   [real electrons per macro, per m²],

where n0 is the requested initial density (density0), Δx the cell size and Ncell the requested number of macros per cell (npart). With this single weight shared by all electrons (and, separately, all ions), placing Ncell macros in a cell reproduces the density n0 exactly. The weight is fixed once at start-up and never changes; it is the proportionality constant that turns the charge deposited on the grid (∝ number of macros) into a physical charge density. Electrons deposit −e·w/Δx and ions +e·w/Δx at the grid points. The same weight controls the injection rate, so it must be strictly positive even in a vacuum start (see below).

ℹ️ The number of macros per cell is a statistical-noise control, not a physics input: it sets the shot noise 1/√Ncell on the moments. The physical density is carried entirely by the weight w. Doubling npart halves the weight and the noise, at twice the cost.

Volume seeding: the initial Maxwellian

The bulk plasma is loaded cell by cell. In each cell the code places Ncell electrons and Ncell ions at the same positions, so the discharge starts quasi-neutral with zero net charge and therefore zero initial field. Positions are drawn uniformly inside the cell. Each velocity component is drawn from a Maxwellian at the requested temperature using the Box–Muller transform,

vi = vth √(−2 ln u1) cos(2π u2),   vth,e = √(kBTe/me),  vth,i = √(kBTi/mi),

with u1, u2 uniform deviates and all three components (vx, vy, vz) filled independently. The electron temperature is te_init and the ion temperature ti_init. A minimum of two macros per non-empty cell is always enforced so that no cell starts completely empty.

Density profile

The initial plasma need not be uniform. The seeding is restricted to a sub-interval [x1, x2] of the gap (normalised to the gap length) and modulated by a shape function chosen with iprof_type:

ProfileShape on [x1, x2]Typical use
UniformconstantDefault; benchmarks, quick starts.
Cosinecos peaking at the centre, vanishing at x1 and x2A more physical bell-shaped column that relaxes faster to steady state.
From filetabulated n0(x) read from init.inp (2-column ASCII, x reduced to [0,1])Restart-like seeding from a measured or previously-computed profile.

The shape sets only the number of macros placed in each cell (the count is scaled by the local value of the profile); the weight is unchanged, so the local density follows the profile. Cells where the profile is effectively zero are skipped.

x / L n₀(x) x₁ x₂ Cosine Uniform

Initial density profiles on the seeding interval [x₁, x₂]. The uniform profile fills the interval at constant density; the cosine peaks at the centre and vanishes at the edges, giving a smoother column that relaxes faster to steady state. A third option reads an arbitrary tabulated n₀(x) from init.inp.

Initial beam, drift and two-stream

On top of (or instead of) the thermal load, the electron population can be given a directed velocity, which is useful for beam–plasma and instability studies. Three behaviours are available, controlled by the beam fraction (beam_frac_pct), the drift energy (drift_energy) and the two-stream flag:

Wall injection: a constant-current cathode

Independently of the initial load, JC-PIC can inject electrons at the left wall throughout the run at a prescribed current density J (inj_e_jcurr). This models a thermionic or field-emitting cathode, or a fixed external electron source. The number of macros to inject per step is the physical rate divided by the weight,

macro = J / (e w)  per m² per s,

accumulated with a fractional carry so that, for example, 0.3 macro/step is realised as a macro injected on 30 % of the steps at random. Each injected macro is given a small random head-start inside the gap (it is treated as having entered at a random instant within the step and free-flown for the remaining fraction of Δt), which removes the artefact of all injected particles sitting exactly on the wall. The injected velocity follows one of two distributions, set by inj_e_vdist:

Modevx (into the gap)vy, vzModels
Beamvdrift + a symmetric Gaussian of width vth, truncated to vx > 0 (monoenergetic if vth = 0)0 (pure 1D beam)A directed electron beam with an energy spread.
Thermal sourcedrawn from the flux-weighted drifting Maxwellian Γ(v) ∝ v exp[−(v − vdrift)²/2vth²], v > 0, by exact inverse-CDF samplingfull Maxwellians at TeEffusion of electrons from a reservoir at temperature Te (a true emitting surface); vdrift = 0 gives a pure thermal emitter.

The drift velocity is set by the parallel injection energy inj_e_eparr and the spread by the injection temperature inj_e_te. The flux-weighting (the extra factor v inside Γ) is the correct distribution for the particles crossing a surface, as opposed to the population at rest behind it — a subtlety that matters for getting the injected energy spectrum right.

v_x > 0 f(v_x) v_drift Beam Thermal source

The two wall-injection distributions for the normal velocity vx. The beam is a Gaussian centred on the drift velocity, truncated to vx > 0. The thermal source is the flux-weighted drifting Maxwellian Γ(v) ∝ v exp[−(v − vdrift)²/2vth²]: the extra factor v forces it to zero at vx = 0 and shifts its peak to the right of the drift, the correct spectrum for electrons effusing from an emitting surface.

ℹ️ Vacuum / Child–Langmuir start. When the initial density is set to zero but wall injection is on, no bulk plasma is seeded: the gap starts empty and is filled entirely by the injected beam. The code sets the weight from the ballistic beam density nb = J/(e v0) so that it stays positive. This is the natural setup for building up a sheath from vacuum, as in a Child–Langmuir diode problem.

A third boundary option (the perpendicular virtual-Z renewal mode) is used for magnetised problems such as the electron cyclotron drift instability, where particles leaving in an unmodelled transverse direction are re-introduced at a renewed perpendicular coordinate; it is described with the magnetised cases rather than here.

💥 MC Collisions

In a weakly ionized plasma, the dominant collision processes are between charged particles and the neutral atoms or molecules of the background gas. Their rates are linear in the gas density ng, so they can be treated as stochastic events occurring independently for each charged particle — in contrast to charged–charged Coulomb interactions, whose long range requires an entirely different treatment and which are negligible at the lowest ionization fractions typical of low-temperature discharges (10−6 to 10−3). JC-PIC adds these stochastic events on top of the collisionless PIC dynamics through the standard Monte Carlo Collision (MCC) procedure. For the regimes where electron–electron Coulomb collisions do matter, the code also provides an optional Coulomb module based on Nanbu's cumulative small-angle model — see the dedicated section at the end of this chapter. The integration of MCC into the PIC time-step cycle, in the form that became canonical for low-temperature discharges, is the contribution of Birdsall (1991) — see "References".

The straightforward approach

For a particle of energy ε moving through a gas of density ng at velocity v, the probability of suffering a collision of any kind during a time step Δt is

Pcoll(ε) = 1 − exp[ −ng σtot(ε) v Δt ] ,

where σtot(ε) is the sum of the cross sections of all collision channels available to the species. Drawing a uniform random number r and comparing it to Pcoll(ε) decides whether a collision occurs; a second random number then selects the channel, weighted by the partial cross sections σi(ε) / σtot(ε). The drawback is that the total cross section, and therefore each σi, must be evaluated for every particle at every time step. With 106 particles and 105 time steps, this is the kind of inner loop that dictates the wall-clock cost of the simulation.

Null-collision method

A clever trick reduces this cost considerably. Define a constant upper bound

νmax = maxε [ ng σtot(ε) v(ε) ]

over the entire energy range of interest, and compute the corresponding global probability Pmax = 1 − exp(−νmax Δt) once and for all. Each particle has the same nominal probability Pmax of being tested for a collision. Only for the small fraction Pmax of particles selected at random is the actual collision frequency ν(ε) evaluated; with probability ν(ε) / νmax a real channel is then chosen, and with the remaining probability 1 − ν(ε) / νmax a fictitious "null" channel is invoked that leaves the particle unchanged. The trick is statistically exact — the net rate of real collisions is unchanged — but the cross sections need only be evaluated for the small fraction Pmax of particles selected, instead of for all of them.

💡 Views 3 and 4 of the Collisions and Cross Sections module show this in pictures, for the gas and pressure of your choice: ν(ε) under its νmax ceiling with the real fraction and the number of tests per real collision, and then the histogram of the free-flight times actually drawn by the loop, converging on ν exp(−νt). Pushing the time step above 0.2/νmax there is the quickest way to see what that ceiling protects.
ε ν = n_g σ(ε) v ν_max (constant) "null" — no event real collisions ν(ε)

The null-collision construction. Every particle is tested at the constant rate νmax; a test resolves into a real collision with probability ν(ε)/νmax (blue area) and into a fictitious "null" event otherwise (grey area). Only the small fraction actually tested needs its cross sections evaluated, yet the real-collision rate is reproduced exactly.

ℹ️ The null-collision technique was introduced by Skullerud (1968) in the context of swarm calculations and is now ubiquitous in PIC-MCC codes. It costs a small overhead (the fraction of "wasted" tests) in exchange for a major reduction in cross-section evaluations.

Collision channels

JC-PIC tabulates the cross sections at startup from external data files and interpolates them at run time. The set of channels available depends on the gas; for an atomic gas like argon the typical menu is the following.

SpeciesChannelEffect on the incident particle
e Elastic Velocity rotated; small fractional energy loss of order 2 me / M (M = mass of the neutral).
e Excitation Discrete energy εexc subtracted from the kinetic energy; no new particle.
e Ionization Energy εiz subtracted; the remaining ε − εiz is shared between the primary and a newly-created secondary electron, and a new ion is added at the same position.
ion Elastic Small-angle scattering on the neutral; energy redistributed in the centre-of-mass frame.
ion Charge exchange The fast ion's identity is exchanged with that of the neutral: a fast neutral is created (and not tracked), and a thermal ion takes its place at the collision point. Crucial for the IFEDF.
⚠️ No attachment channel in the discharge engine (yet). The PIC-MCC 1D engine does not implement electron attachment: an attachment cross section present in the data file is not turned into a negative-ion creation (the electron is merely frozen). Discharge simulations in electronegative gases (O₂, SF₆, …) are therefore not physical with the present engine. The swarm mode, in contrast, treats attachment rigorously in all three growth models — swarm coefficients for electronegative gases are fully supported.

Scattering kinematics

Once a real channel is selected, the post-collision velocity is built by deflecting the relevant velocity vector through a polar scattering angle χ and an azimuth η. Following the standard recipe (described in detail in Donkó 2021), JC-PIC draws the angles, then rotates the incident direction into the scattered one with the closed-form Euler rotation that takes the original velocity as its polar axis. The azimuth is always uniform, η = 2π R, and the polar angle is isotropic in the relevant frame,

χ = arccos(1 − 2 R),

with R a uniform deviate on [0, 1). This isotropic prescription is used by default for electron elastic and inelastic scattering and for ion elastic scattering alike — for the electrons it can be replaced by a forward-peaked, energy-dependent distribution: see Anisotropic scattering (screened Coulomb) below. The two relevant frames are treated differently:

Ionization: energy sharing and correlated angles

An ionizing collision removes the ionization threshold εiz and must divide the remaining energy ε − εiz between the scattered primary and the ejected secondary electron, then assign each a direction. JC-PIC offers three increasingly physical prescriptions (the ieshare_type option), the first being the default:

ModeEnergy partitionAngles
Equalε1 = ε2 = (ε − εiz)/2both isotropic
OPB + isotropicε1 drawn from the Opal–Peterson–Beaty distribution, ε1 = w tan[R arctan((ε − εiz)/2w)], with the gas-specific width wboth isotropic
OPB + correlated (Donkó)OPB partition as aboveprimary and secondary deflections set by the partition, cos χ = √(εi/(ε − εiz)), with azimuths ηe = ηs + π

The Opal–Peterson–Beaty form gives the realistic, strongly peaked spectrum of secondary energies (most secondaries are slow, with a tail of fast knock-ons), in contrast to the artificial equal split. The fully correlated option additionally ties each electron's scattering angle to the energy it carries away and places the two electrons in opposite azimuthal planes, following Donkó's eduPIC specification — the most faithful representation of the ionization kinematics available in the code. In every case a new ion is created at the collision site with a thermal velocity drawn from a Maxwellian at the gas temperature.

ℹ️ JC-PIC also exposes a "balanced" ionization variant that keeps the electron and ion macro-counts constant (a random existing macro is overwritten rather than a new one appended). It is meant for long periodic-column runs where an ever-growing particle count would otherwise force frequent thinning; the energy and angle treatment is the same as above.

Anisotropic scattering (screened Coulomb)

The isotropic prescription of the previous sections is an excellent approximation at low electron energy, but it is not what the differential cross sections say at high energy. Above a few tens of eV the electron increasingly sees the screened nuclear charge of the target, and the true angular distribution becomes strongly forward-peaked — the higher the energy, the narrower the forward lobe. Wherever a discharge contains genuinely fast electrons — the cathode fall of a DC glow, an injected beam, secondary electrons accelerated through a high-voltage sheath — the isotropic model over-randomizes their direction and therefore misplaces where they deposit their momentum, their energy and, most visibly, their ionization. Benchmark work on exactly this configuration (Carlsson, Khrabrov, Kaganovich et al., 2017 — see "References") showed both that the anisotropy parameters are among the dominant uncertainties of a glow-discharge simulation, on a par with the secondary-emission yield, and that anisotropic scattering is where independent PIC codes disagree most. JC-PIC therefore provides an optional anisotropic model, enabled per collision family from Advanced → Special; it is OFF by default, so legacy simulations are strictly unchanged.

The model

JC-PIC uses the screened-Coulomb (Rutherford) form proposed by Okhrimovskyy, Bogaerts and Gijbels (2002) as a general-purpose Monte-Carlo prescription. The normalized differential cross section is

(1/σ) dσ/dΩ = (1/4π) (1 + ξ) / [1 + ξ sin²(χ/2)]² ,

with a single dimensionless screening parameter ξ that JC-PIC takes proportional to the electron energy,

ξ = ε / e* ,

where e* (the anisotropy energy, in eV) is the one adjustable constant of the model, set per gas in Advanced → Special. ξ → 0 recovers isotropic scattering exactly and continuously; ξ ≫ 1 concentrates the distribution in the forward lobe, as the physics demands. This is the same family of models as the benchmark paper above — their screening energy Eaniso maps onto ours as Eaniso = 8 e*, so their reference value Eaniso ≈ 100 eV for helium corresponds to the JC-PIC default e* = 12.5 eV. Sampling the polar angle from this distribution has a closed inverse: with R a uniform deviate,

cos χ = 1 − 2R / [1 + ξ (1 − R)] .

The azimuth stays uniform and the deflection is applied, as always, by rotation about the incident direction; the elastic energy-transfer factor ε′ = ε[1 − (2me/M)(1 − cos χ)] is unchanged.

The consistency rule — why the elastic rate must change

This is the part that is easy to get wrong, and the reason the option is more than a new random-number formula. The tabulated "elastic" cross section of the standard data files (LXCat/BOLSIG+ convention, see "Cross-section data" below) is the momentum-transfer cross section σm = ∫(1−cos χ) (dσ/dΩ) dΩ, not the total one. The legacy isotropic scheme uses σm directly as the collision rate: since an isotropic deflection has ⟨1−cos χ⟩ = 1, the momentum-transfer frequency νm = ngv σm — the quantity that governs mobility, diffusion and the elastic energy-loss rate — comes out exactly right, even though the angular distribution is wrong at high energy. If one now kept that same rate but drew forward-peaked angles, every collision would transfer less momentum and νm would be silently underestimated. The correct move is to renormalize the elastic rate at the same time as the angles: averaging 1−cos χ over the sampling formula gives, in closed form,

σm / σel = g(ξ) = (2/ξ²) [(1 + ξ) ln(1 + ξ) − ξ] ,

so JC-PIC replaces the elastic entry of its internal tables by the effective total cross section σel = σm/g(ξ) at every energy — this is what feeds the null-collision bound and the channel selection from then on. The product σel · ⟨1−cos χ⟩ = σm holds identically, so νm is preserved exactly: more collisions occur, each deflecting less, and the transport they add up to is unchanged. Because the elastic energy transfer is itself proportional to 1−cos χ, the mean elastic energy-loss rate is preserved by the same identity. What changes is everything that depends on the angular distribution beyond its first moment — the shape of the velocity distribution of fast electrons, and through it the spatial structure of ionization.

The small-angle cutoff

At high energy g(ξ) → 0 and the effective cross section σm/g(ξ) grows without bound — the forward lobe is made of ever more numerous, ever more minuscule deflections that cost CPU and change essentially nothing. JC-PIC therefore truncates the lobe at a minimum deflection angle χmin (default 8°): deflections below χmin are simply never generated, which amounts to drawing R uniformly on [Rmin, 1] with

Rmin = u₀(1 + ξ) / (2 + u₀ξ) ,   u₀ = 1 − cos χmin ,

and the effective cross section is defined against the truncated mean, σeleff = σm / ⟨1−cos χ⟩trunc. By construction σeleff · ⟨1−cos χ⟩trunc = σm remains exact for any choice of χmin — the cutoff only sets how finely the forward lobe is resolved, never the transport it delivers. With the default 8°, the elastic collision count is bounded at roughly 12–17× the isotropic count at ξ = 1000 (i.e. ε ≈ 12 keV·(e*/12.5 eV)), instead of ~85× without the cutoff; at low energy, where ξ ≪ 1, both the cutoff and the anisotropy fade out and the scheme reverts to the legacy σm-plus-isotropic model continuously.

What each switch does

Practical notes

Electron–electron Coulomb collisions (Nanbu model)

Binary collisions between charged particles cannot be treated by the MCC machinery above. The Coulomb interaction is long-range: a test electron is deflected not by rare, large-angle encounters but by the cumulative effect of a great many simultaneous small-angle deflections, and the notion of a discrete collision with a well-defined cross section loses its meaning (the Coulomb cross section formally diverges at small angles). The grid of the PIC scheme handles the collective, long-wavelength part of this interaction self-consistently — but it filters out precisely the short-range encounters responsible for collisional relaxation within a species, i.e. the drive toward a Maxwellian.

At the low ionization degrees of many discharge simulations this relaxation is dominated by electron–neutral collisions and the omission is harmless. It stops being harmless when the electron–electron collision frequency becomes comparable to the electron–neutral one — at high plasma density and/or low gas pressure — where e–e collisions visibly Maxwellianize the bulk of the EEPF and thereby change the rate coefficients of every threshold process. For those regimes JC-PIC implements the Nanbu (1997) model, enabled from Conditions → Special (see that chapter for the controls).

Nanbu's insight is that the accumulated effect of all the small-angle Coulomb deflections a particle suffers during a time interval can be aggregated, exactly in a statistical sense, into a single equivalent scattering event per pair and per application. The particles of each cell are paired at random; each pair is moved to its centre-of-mass frame and the relative velocity g is rotated by a polar angle χ drawn from Nanbu's cumulative distribution, whose shape is governed by one dimensionless parameter,

s = ⟨θ²⟩/2 ∝ ne lnΛ g−3 Δtcoll ,

the mean accumulated square deflection over the interval Δtcoll between applications of the operator. Small s means the pair is barely deflected (weakly collisional limit); large s makes the outgoing direction isotropic (strongly collisional limit); Nanbu's distribution interpolates smoothly and correctly between the two. Because both partners of the pair are updated symmetrically in the centre-of-mass frame, momentum and energy are conserved exactly, pair by pair — the operator redistributes energy within the electron population (driving it toward a Maxwellian) without any net creation or loss.

The Coulomb logarithm lnΛ is computed automatically from the local density and temperature (or imposed via coulomb_lnlam). A density-scale factor (coulomb_factor ≥ 1) multiplies the collisionality seen by the operator, a convenient artifice for accelerating e–e relaxation studies without changing the plasma itself.

Sub-cycling: coulomb_nsub

The Coulomb operator visits every electron once per application — the cell-by-cell pairing, the centre-of-mass rotations, the conservation bookkeeping — so its cost is O(N) each time it runs. Applying it at every PIC step is usually wasteful, because the e–e collision time is generally much longer than Δt: each application would then produce only a minuscule deflection (a tiny s), and one would be paying the full O(N) price for nearly nothing. The coulomb_nsub parameter (call it n) tells the engine to apply the operator once every n time steps only, with the interval between applications, Δtcoll = n Δt, fed into the scattering parameter: since s ∝ Δtcoll, each application delivers a deflection n times larger, and the accumulated scattering per unit of physical time is unchanged. This is not an approximation grafted onto the model — it is the model: Nanbu's distribution is precisely the exact statistical law of the deflection accumulated over a finite time interval, whatever that interval is. Momentum and energy remain conserved pair by pair for any n, and the Coulomb cost is divided by n.

What, then, limits n? Two things, both variants of the same idea — the interval must stay short compared with the physics it straddles:

In practice the tuning loop takes a minute. Start the run with coulomb_nsub = 1 and read the [COUL] line the engine prints in fortran.log: it reports the typical s per application and directly suggests the value to use — e.g. typ s/step=2.1E-04  coulomb_nsub=1 -> for s~0.05 use coulomb_nsub=238. Set coulomb_nsub accordingly (the engine clamps it to ≥ 1) and restart; the Coulomb e-e block of the Params viewer then shows the resulting s live, so you can confirm it stays near the target as the density evolves. If the engine instead warns that s is already large at n = 1, sub-cycling is not the issue — the plasma is strongly e–e collisional at your Δt, and the cure is to reduce Δt itself.

Automatic mode. Alternatively, tick Auto next to the sub-cycle field (equivalently, set coulomb_nsub = 0 in the namelist) and the engine closes this loop by itself: it applies its own [COUL] suggestion, driving n so that the per-application s of the densest cell stays near the 0.05 target. The adjustment is deliberately unhurried — n is re-evaluated at a bounded cadence (at least a few thousand steps between changes, never at every application), a change is only made when the target differs by more than ±30 % (hysteresis), growth is limited to ×4 per adjustment so a cold start at n = 1 walks up to a large value in a few logged moves, while an s overshoot (after a density rise, or a Δt increase by the adaptive time step) bypasses the cadence and shrinks n immediately. Every change is printed as a [COUL] auto: nsub … -> … line, so the run's history remains traceable. One caveat is inherited from any adaptive mechanism: the adjustments change the collision cadence and the random-number consumption, so two runs are no longer bit-for-bit reproducible — for strict reproducibility (benchmarks, RNG comparisons), use a fixed manual value.

ℹ️ Reference: K. Nanbu, Theory of cumulative small-angle collisions in plasmas, Phys. Rev. E 55, 4642 (1997). The pairing scheme within cells and the exact pairwise conservation make the method the de-facto standard for Coulomb collisions in particle codes.

Cross-section data

JC-PIC hard-codes no cross section: the engine reads them at start-up from two plain-text files of the DATA folder, ELECSCAT.DAT (electrons) and IONSCAT.DAT (ions), in the LXCat/BOLSIG+ format. Which gases are shipped, where the data come from, the exact file format and how to add a gas or your own cross sections are described in their own chapter: Cross-Section Files (DATA).

↩️ Secondary Emission

When an energetic particle strikes a solid surface it can liberate one or more electrons from the material. This secondary electron emission (SEE) is a key boundary condition for any plasma code: even a small SEE yield can change the discharge regime entirely, by injecting cold electrons back into the sheath where they are subsequently accelerated and contribute to ionization. SEE is responsible for the so-called γ-mode of DC and low-pressure RF discharges, and it controls the floating-potential balance of dielectric surfaces. Most of the spread between published simulations of "the same" discharge can be traced back to the SEE coefficients used at the walls.

Per-electron yield

For each electron that hits a wall with impact energy ε, JC-PIC evaluates a yield γ1 following the Vahedi–Surendra form,

γ1(ε) = σ0 + (1 − σ0) ε / ε*,

controlled by two parameters in the SEE tab of the Conditions dialog:

The crucial point — and a frequent source of confusion — is what JC-PIC does with γ1, which depends on whether it is below or above one:

ε (impact) γ₁ 1 σ₀ ε* reflection only primary reflected, proba γ₁ reflection + emission + (γ₁−1) cold secondaries

The yield γ1(ε) = σ0 + (1 − σ0) ε/ε*. Below ε* (blue) the yield is under one: the impacting electron is specularly reflected at full energy with probability γ1, and no cold electron is created. Above ε* (gold) the primary is always reflected and γ1 − 1 cold secondaries are emitted. ε* is the impact energy at which γ1 reaches unity.

⚠️ Special case: when σ0 = 0 and ε* = 0 are both set, γ1 = 0 and the wall is a pure absorber: every incident electron is removed and none is reflected or re-emitted. This is the appropriate setting for benchmarks that prescribe perfectly absorbing walls.

Per-ion yield

Ion-induced SEE — the dominant source of secondaries in DC discharges and at high pressure — is included via a constant yield γi per ion impact. Each ion that reaches a wall releases γi secondary electrons (interpreted statistically: γi is a probability when below 1, or an expected number when larger). The released electrons are launched into the plasma with a low energy of the order of the wall temperature, consistent with the Auger-like nature of the process at the impact energies relevant to low-temperature discharges (a few hundred eV at most). For the noble gases on metallic electrodes typical of capacitive discharges, γi ranges from 0.05 to 0.2 depending on the gas–surface combination.

Why the choice of SEE parameters matters

At low pressure, where the electron mean free path is comparable to the gap, even a few percent of secondary yield can change the bulk plasma density by a factor of two and shift the electron temperature by several eV. The reason is that secondaries are accelerated through the full sheath drop (of the order of the applied voltage), arrive in the bulk with energies well above the ionization threshold, and become very efficient ionizers. A small change in σ0 or γi is amplified by this avalanche-like mechanism into a much larger change in the global discharge characteristics.

The SEE parameters are therefore among the most sensitive inputs of the simulation, and matching them to the experiment is often the most demanding part of the validation process. When in doubt, it is good practice to run the same case with two values of σ0 bracketing the expected range, and check how strongly the result depends on the choice.

📑 References

The list below gathers the foundational and most useful references for the methods on which JC-PIC relies. The first two are the standard textbooks on the topic; the others are seminal papers introducing specific algorithms, or review articles and benchmark papers that the user can consult for a deeper or more specialized treatment.

Books

C. K. Birdsall & A. B. Langdon — Plasma Physics via Computer Simulation

Adam Hilger / IOP Publishing, 1991 (reprinted by CRC Press, 2004). The standard textbook on PIC simulation. Covers the explicit electrostatic and electromagnetic schemes, weighting, the Boris pusher, stability and noise analysis, and the relation between the simulated and the physical plasma. Indispensable for anyone starting with PIC.

R. W. Hockney & J. W. Eastwood — Computer Simulation Using Particles

Adam Hilger / IOP Publishing, 1988. The other classic. More mathematical than Birdsall & Langdon, with a thorough treatment of the particle-mesh formalism, alias errors, and the comparison between particle–particle, particle–mesh and particle–particle/particle–mesh methods.

Seminal papers

C. K. Birdsall — Particle-in-cell charged-particle simulations, plus Monte Carlo collisions with neutral atoms, PIC-MCC

IEEE Transactions on Plasma Science 19, 65–85 (1991). The paper that crystallized the PIC-MCC framework as a single integrated methodology, with the now-canonical flowchart of the time-step cycle and an explicit prescription for inserting Monte Carlo collisions between the push and the next charge weighting. Includes a historical retrospective on the development of PIC since the 1950s, the rationale for the particle–mesh formulation over direct particle–particle, and the link to the rapidly-growing field of plasma processing of the early 1990s. The acronym PIC-MCC itself comes from this paper.

J. P. Boris — Relativistic plasma simulation: optimization of a hybrid code

Proceedings of the 4th Conference on Numerical Simulation of Plasmas, Naval Research Laboratory, Washington DC, 1970, pp. 3–67. The original description of the rotation-then-acceleration splitting that bears Boris's name and that is at the heart of the JC-PIC pusher.

H. R. Skullerud — The stochastic computer simulation of ion motion in a gas subjected to a constant electric field

Journal of Physics D: Applied Physics 1, 1567 (1968). Introduces the null-collision method that turns MCC into a constant-frequency procedure and removes the need to evaluate the cross sections at every time step.

V. Vahedi & M. Surendra — A Monte Carlo collision model for the particle-in-cell method: applications to argon and oxygen discharges

Computer Physics Communications 87, 179 (1995). Establishes the practical recipe for combining PIC with MCC for low-temperature discharges — the framework on which most modern PIC-MCC codes (including JC-PIC) are built.

A. Okhrimovskyy, A. Bogaerts & R. Gijbels — Electron anisotropic scattering in gases: A formula for Monte Carlo simulations

Physical Review E 65, 037402 (2002). The screened-Coulomb angular distribution and its one-line sampling formula, proposed as a general-purpose prescription for forward-peaked electron–neutral scattering in Monte-Carlo codes. JC-PIC's anisotropic-scattering option (Advanced → Special) implements this model, with the momentum-transfer-preserving rate renormalization and a small-angle cutoff described in "MC Collisions".

J. Carlsson, A. Khrabrov, I. Kaganovich, T. Sommerer & D. Keating — Validation and benchmarking of two particle-in-cell codes for a glow discharge

Plasma Sources Science and Technology 26, 014003 (2017). Benchmarks EDIPIC and LSP against a helium glow discharge with a precisely measured axial electric field. Demonstrates that the scattering anisotropy and the secondary-emission yield are the dominant model uncertainties, that anisotropic collisions are where independent codes disagree most, and that the quality of the random-number generator becomes visible in exactly that regime — three lessons that shaped JC-PIC's anisotropic-scattering option, its glow validation cases and its selectable RNG.

Swarm analysis & Boltzmann solvers

G. J. M. Hagelaar & L. C. Pitchford — Solving the Boltzmann equation to obtain electron transport coefficients and rate coefficients for fluid models

Plasma Sources Science and Technology 14, 722 (2005). The BOLSIG+ paper: the two-term Boltzmann solution, the definitions and normalizations of the transport and rate coefficients (EEPF normalization, reduced coefficients µN, DN…) that JC-PIC's swarm tables follow, so that the two tools can be compared column by column.

G. J. M. Hagelaar — Beyond BOLSIG+: Monte Carlo simulation of electron and ion swarms to obtain transport and rate coefficients for plasma modeling

Physics of Plasmas 32, 043501 (2025). The paper describing MCIG, the Monte-Carlo swarm code released as a companion to BOLSIG+. The methods implemented in JC-PIC's Swarm mode are directly taken from this paper: the displacement and covariance estimators for the bulk and flux transport coefficients, the per-particle error estimation, and the treatment of ionization/attachment growth in the pulsed-Townsend and steady-state-Townsend regimes.

Reviews

J. P. Verboncoeur — Particle simulation of plasmas: review and advances

Plasma Physics and Controlled Fusion 47, A231 (2005). A compact review covering particle weighting, field solvers, time integration, parallelism and a survey of applications. A good entry point if you want a single article rather than a whole textbook.

Z. Donkó — Particle simulation methods for studies of low-pressure plasma sources

Plasma Sources Science and Technology 20, 024001 (2011). Specifically focused on the low-temperature discharge community: choice of algorithms, common pitfalls, treatment of secondary emission and surface processes, validation strategies. Closer in scope to JC-PIC than the general reviews.

Benchmarks and educational codes

M. M. Turner et al. — Simulation benchmarks for low-pressure plasmas: capacitive discharges

Physics of Plasmas 20, 013507 (2013). Defines the canonical four-point capacitive RF benchmark in helium that is now used to validate every new code. The four cases are bundled with JC-PIC under 06_RF_capacitive_discharges/01_Benchmarks_-_Turner_et_al_Phys_Plasmas_2/.

Z. Donkó, A. Derzsi, M. Vass, B. Horváth, S. Wilczek, B. Hartmann, P. Hartmann — eduPIC: an introductory particle based code for radio-frequency plasma simulation

Plasma Sources Science and Technology 30, 095017 (2021). An open-source educational PIC-MCC code distributed with full documentation. Reading the source is one of the most effective ways to understand how the algorithms in this manual translate into actual code. The benchmark case is bundled under 06_RF_capacitive_discharges/02_EduPIC_-_Donko_et_al_PSST_30_095017_2021/.

🐝 Swarm Mode Overview

Besides the discharge simulation that occupies most of this manual, JC-PIC contains a second, completely independent engine: a Monte-Carlo electron swarm solver. Its purpose is the classic "swarm experiment" of gaseous electronics: release a population of electrons in a neutral gas under a uniform, constant reduced electric field E/N, let them collide with the gas until their velocity distribution reaches equilibrium with the field, and measure the transport and rate coefficients — drift velocity, mobility, longitudinal and transverse diffusion, characteristic energy, mean energy and temperature, ionization/excitation/attachment rate coefficients, energy-loss coefficients, the electron energy probability function (EEPF) and its anisotropy — as functions of E/N. These are exactly the quantities delivered by a Boltzmann solver such as BOLSIG+ (Hagelaar & Pitchford, 2005), computed here instead by direct Monte-Carlo simulation, with statistical error bars, and free of the two-term approximation. The methods are those of MCIG, the Monte-Carlo companion code of BOLSIG+ (Hagelaar, Phys. Plasmas 32, 043501, 2025) — see the theory chapter and the References.

The swarm solver shares its collision machinery (cross sections, null-collision sampling, scattering) with the PIC-MCC engine, but nothing else: there is no grid, no Poisson equation, no space charge and no ions — the field is imposed, not computed. It is therefore not a discharge model; it is the kinetic reference tool that sits underneath discharge modelling — for checking a cross-section set against measured swarm data, generating transport coefficients for fluid models, teaching electron kinetics, or benchmarking against BOLSIG+ and published Monte-Carlo results.

Entering and leaving Swarm mode

Select Files → Mode → Swarm. Because the native menu bar is built once at startup, JC-PIC asks for confirmation and then relaunches itself in the new mode (the same happens in the other direction with Files → Mode → PIC-MCC 1D). After the restart the menu bar is replaced by the swarm-specific menus and the footer of the main window reads Swarm — the footer is always the authoritative indicator of the active mode.

MenuContents
FilesWorking Directory, Mode (PIC-MCC 1D / Swarm), Exit.
InputConditions… — the swarm conditions dialog (next chapter) — and Plot Cross Sections, which opens the Cross-Section Viewer on the selected gas.
Run / PauseStart, pause/resume or stop the calculation (see Run, Convergence & Progress).
Progress…The live convergence monitor, one row per E/N point.
ResultsThe four numerical tables: Transport Parameters, Rate Coefficients, Energy Loss Coefficients, Energy Loss Fractions.
GraphicsThe interactive plots: transport parameters (mean energy/temperature, mobility, diffusion, energy mobility/diffusion, χ/Dufour), rate and energy-loss coefficients, EEPF, and the Legendre components F₀…F₃.
Window / JC-PICThe usual window management (tile, raise, close all…) and Help entries.

The swarm mode has its own input file, input_swarm.nml, written in the working directory next to the PIC input.nml, and writes all of its output to a dedicated snap_swarm/ subfolder — so a swarm calculation never disturbs the PIC results of the same case, and vice versa. The test-case library also contains ready-made swarm cases: their folders carry an input_swarm.nml, they are flagged [swarm] in the case browser tree, and loading one switches the application to Swarm mode automatically.

Workflow at a glance

  1. Input → Conditions… — choose the gas, the E/N value or series, the ionization treatment, and the accuracy targets.
  2. Run — the engine computes all E/N points in parallel; results files are refreshed every couple of seconds.
  3. Progress… — watch each point converge to the requested error.
  4. Results / Graphics — read the coefficients from the tables (with error estimates and BOLSIG+-style units) or plot them; tables and plots refresh live during the run.
💡 A complete argon mobility curve — say 20 E/N points from 0.1 to 1000 Td at 1 % accuracy — is typically a matter of minutes on an ordinary multi-core desktop.

🎚️ Swarm Conditions Dialog

All physical and numerical inputs of a swarm calculation are collected in a single compact dialog, Input → Conditions…, organized in four tabs. Pressing OK writes input_swarm.nml (the &swarm namelist group plus a few ¶ms keys — see Namelist &swarm & Files); the dialog always reopens exactly as it was left, including after an application restart.

Swarm conditions dialog
The swarm Conditions dialog, opened on the Gas & Field tab: choice of the gas (from ELECSCAT.DAT) and definition of the E/N axis — here an exponential series, with the preview line listing the actual values that will be run. The other three tabs are shown below, in their respective sections.

Gas & Field

The Gas menu lists the gases found in ELECSCAT.DAT, exactly as in the PIC Conditions dialog — the cross-section file is the single source of truth. The swarm species is the electron.

The Reduced field E/N frame defines the field axis of the whole calculation, in Townsend (1 Td = 10⁻²¹ V·m²). Either a Single value, or a series — Linear, Quadratic or Exponential (geometric) — defined by from, to and the number of points. A preview line below the fields shows the actual list of E/N values that will be run (up to 64 points). The exponential series is the natural choice when the table spans several decades.

Collisions

Electron–electron Coulomb collisions can be switched on, with the ionization degree ne/N as the controlling parameter (the Coulomb logarithm is computed automatically). This reproduces the e–e option of Boltzmann solvers and matters mainly at high ionization degree, where e–e collisions Maxwellianize the EEPF.

The Ionization radio buttons select how ionization and attachment are treated — the choice that distinguishes the three classical flavours of swarm analysis (see the theory chapter for the physics):

OptionMeaning
Conservative (energy loss only)Ionizing collisions cost the electron the threshold energy but create no secondary; attachment is ignored. The electron number is constant — the fastest and least noisy option, and the correct one whenever the coefficients are to be compared with density-gradient (bulk) data at moderate E/N.
Temporal growth (Pulsed Townsend)Real ionization (equal energy sharing between the two outgoing electrons) and real attachment, with the exponential growth of the electron number handled by renormalization collisions on a fixed ensemble. Bulk and flux coefficients then genuinely differ, as in a pulsed-Townsend experiment.
Spatial growth (SST, Townsend α)The steady-state-Townsend mode: exponential growth in space. Delivers the self-consistent reduced Townsend coefficient α/N (printed to the console and written to swarm_rates.dat), the SST EEDF, and the SST transverse diffusion via DT/μ; the longitudinal diffusion coefficient is not accessible in this mode.
Swarm conditions — Collisions tab
The Collisions tab: electron–electron Coulomb collisions (controlled by the ionization degree ne/N) and the three ionization treatments — conservative, temporal growth (Pulsed Townsend) and spatial growth (SST).

Convergence

The swarm run is organized in two phases per E/N point — relaxation to equilibrium with the field, then accumulation of statistics in successive samples — and this tab controls when each point is considered done.

FieldMeaning
Relax for (× τ)Length of the relaxation phase in units of the energy-relaxation time τ, estimated on the fly for each E/N. Default 10; convergence cannot be trusted much below that, and 20 is the conservative choice.
Target error (%)The requested relative (1σ) statistical error on the mean energy ⟨ε⟩. 0 disables the test (the point runs to the sample ceiling). The three families — energy, drift, diffusion — now have independent targets: an empty target leaves that quantity reported, with its error bar, but out of the convergence gate.
Drift target (%)Separate target for the drift velocity W (sw_tol_w). Empty by default: W is reported but does not gate. Locking the drift is what costs — its statistical error is intrinsically ~vth/W times that of ⟨ε⟩ (a factor of 100 or more at low field), so the same point can take ten times longer with W locked.
Diffusion target (%)Separate target for DL and DT (sw_tol_diff), which converge roughly ten times more slowly than ⟨ε⟩ (they are second-order moments). Asking 1 % for the diffusion while keeping 0.1 % on ⟨ε⟩ is a well-balanced request. At high field, where the swarm growth makes D unmeasurable, the point's diffusion is dropped from the gate automatically (see Run, Convergence & Progress).
Max samples (ceiling)Hard ceiling on the number of accumulation samples per replica (default 50) — the stopping rule when no error target is set.
Max run time (s)Wall-clock budget for the whole run; 0 = no limit. The run stops gracefully at the first of: error target reached everywhere, sample ceiling, or time budget.
Cumulate with previous runPools this run's replicas with those of the previous run (stored in snap_swarm/swarm_accum.dat): the coefficient table is then averaged over all replicas ever run at each E/N, so accuracy can be refined incrementally without starting over. The E/N list must be unchanged.
Field sweep (warm-start)Each replica converges the strongest field first, then steps down the E/N list reusing the equilibrated velocity distribution of the previous point. Only the first (fast, high-field) relaxation is paid in full — a substantial saving on dense tables. Relaxation is still monitored at every field, so accuracy is unaffected. Off by default.
Swarm conditions — Convergence tab
The Convergence tab: relaxation length (× τ), the error targets — with the separate, looser diffusion target — the sample ceiling and time budget, and the two acceleration options, Cumulate with previous run and Field sweep.

Numerics

FieldMeaning
Particles / replicaNumber of electrons in one independent swarm (default 2000).
ThreadsOpenMP threads used by the engine. Defaults to about half the logical cores so the machine stays responsive. Swarm replicas are embarrassingly parallel: on a large machine, raising this towards the core count divides the run time almost proportionally.
Replicas / E/NNumber of statistically independent swarms run per E/N point (blank = automatic = max(8, threads); 8 is also the minimum number of replicas a point needs before it can be declared converged). The error bars are estimated from the spread between replicas (backed by per-particle statistics), and the final coefficients are replica averages. This is the accuracy knob: it fixes the per-point statistics independently of how many E/N points are in the series.
Swarm conditions — Numerics tab
The Numerics tab: particles per replica, OpenMP threads (parallelism), and replicas per E/N (accuracy) — the two roles are deliberately separate controls.
ℹ️ Total statistics per point = particles × replicas × samples. Doubling the number of replicas divides the statistical error by √2 — and, with the Cumulate box ticked, you can add replicas after the fact instead of deciding everything in advance.

⏱️ Run, Convergence & Progress

Press Run. The engine (the same pic_mcc.exe, branching into the swarm solver at startup) distributes the work over the OpenMP threads — replicas of a single E/N, or (replica, E/N) jobs of a series — and rewrites the result files in snap_swarm/ every couple of seconds, so every table and plot can be watched live. Pause suspends the computation threads (paused time is excluded from the elapsed time and the time budget); pressing Run again resumes, and Stop (from the same menu position) ends the run cleanly, keeping everything accumulated so far.

Swarm progress window
The Progress window. Each E/N point reports its active replicas, accumulated samples, worst current error, convergence status and time to convergence.

The Progress window

Progress… opens a single-instance monitor (a second click just raises it). The header shows the overall state — Running…, Converged ✓, Stopped — time budget reached, Finished — the elapsed time against the budget, the worst current error, and a progress bar with the fraction of converged points and the requested target, e.g. target 0.1% (D 0.5%). Below, one row per E/N:

ColumnMeaning
E/N (Td)The field point.
ActiveReplicas still sampling / total replicas. During the relaxation phase it shows ↻N — the number of replicas still relaxing — and the window keeps refreshing (relaxation can be more than 90 % of a low-field point, and used to look like a frozen run).
SamplesAccumulation samples collected (against the ceiling when no error target is set).
err ⟨ε⟩ · err W · err DThe current relative error of each family in its own column. They converge at very different speeds — ⟨ε⟩ typically a hundred times faster than W — which a single "max err" column used to hide.
Status converged  ·  error targets met, waiting for the 8-replica minimum  ·  still sampling  ·  diffusion declared unmeasurable at this field (dropped from the gate)  ·  the point never stabilized.
Time (s)Wall time at which the point converged (— while it hasn't).

What "converged" means

Up to four quantities gate the convergence of a point: the mean energy ⟨ε⟩, the bulk drift velocity W, and the bulk diffusion coefficients DL and DT — each family against its own target (sw_tol, sw_tol_w, sw_tol_diff), and only the families whose target is set actually gate. A point also needs at least 8 replicas to have satisfied their tolerances before it can be declared converged. Their errors are estimated from the spread between the independent replicas, reinforced by per-particle statistics; once a point is declared converged it stays converged (a later fluctuation of the error estimate cannot un-converge it). The remaining outputs — flux diffusion, energy transport coefficients, rate coefficients, EEPF — are computed and error-tagged but deliberately kept out of the gate: some are intrinsically noisier, and gating on them would multiply the run time for little benefit.

At the end of the run the engine also reports, per E/N, the power-balance residue — the mismatch between the power absorbed from the field and the power lost in collisions, which must vanish for a properly relaxed swarm. A console WARNING on this residue is the signature of a too-short relaxation phase: increase Relax for (× τ) and rerun.

Diffusion at high field. Above a growth of roughly G = |γ|·dt₁ ≈ 4 per sampling window (sw_gdtmax), the diffusion coefficients lose their meaning: the swarm multiplies faster than its velocity distribution decorrelates, and the density-gradient expansion behind D no longer applies — the EEDF itself remains perfectly converged. The engine then declares the point's diffusion unmeasurable: it is removed from the convergence gate, flagged in Progress, and every diffusion-derived column of swarm_coeffs.dat (DL, DT, bulk and flux, the energy diffusivities, the characteristic energy and the Dufour coefficient) is left blank for that point. The same happens to a published D that comes out negative.

Series without a field sweep. When the warm-start sweep is off, the E/N list is walked in bands of a few consecutive points (sw_nband, default 3) rather than spread all at once: with many field values and few threads, spreading every replica thinly would leave each point below the 8-replica minimum and nothing would ever converge. Within a band, a replica also yields after batches of samples on a point that is still short of 8 replicas, so the band fills evenly.

💡 Realistic targets. Drift and energy converge fast; diffusion is roughly ten times slower; and the pulsed-Townsend growth mode is another order of magnitude noisier than the conservative one (its bulk corrections live on the ionizing tail of the distribution). 0.1 % on ⟨ε⟩/W with ~1 % on the diffusion is comfortable in conservative mode; in PT or SST mode, 0.5–1 % overall is the sensible request.
ℹ️ The swarm windows participate in the common window management (Window → Manage Viewer Windows…, tile/cascade, Raise All…), with sensible exceptions — the Progress window keeps its size out of tile/resize operations. All swarm window positions and sizes are remembered across sessions.

🧮 Results — Tables & Graphs

Swarm results are delivered in two complementary forms: the Results menu opens numerical tables (the form best suited to comparison with BOLSIG+ or with published tabulations), and the Graphics menu opens interactive plots. Both read the same files in snap_swarm/ and refresh automatically while the engine runs — during a run the plots reload whenever a new point converges, and at rest whenever the files change.

The results tables

Swarm results table
The Swarm Results window: one column per E/N, one coefficient per row — the BOLSIG+ presentation.

A single Swarm Results window serves the four tables, selected from the combo box (each Results menu entry opens it directly on the corresponding table): Transport Parameters, Rate Coefficients (m³/s), Energy Loss Coefficients (eV·m³/s) and Energy Loss Fractions. Columns are the E/N points; rows are the coefficients or the collision processes (labelled from the cross-section file with their thresholds, e.g. C2 Excitation 11.55 eV). The top-bar controls:

ControlWhat it does
Show errors (%)Adds the relative 1σ statistical error under each transport coefficient.
E/p unitsSwitches the whole table between N-reduced units (E/N in Td, µN, D·N, rate coefficients in m³/s) and pressure-reduced units (E/p, p·µ, p·D, collision frequencies ν/p), the older gaseous-electronics convention. The conversion uses N = 3.2188·10²² m⁻³ per Torr at 300 K, i.e. the values at 1 Torr.
Mobility/DiffusionExpands the transport table from the core set (⟨ε⟩, temperatures, flux drift/mobility/diffusion, characteristic energy DT/µ) to the complete set: bulk and flux mobility and diffusion, the energy-transport coefficients µεN, DL,εN, DT,εN, the Dufour coefficient χ, and the EEPF-integral variants of µN, DN, µεN, DεN.
Auto / ReloadAutomatic refresh during the run (the title shows running…), or manual reload.

The graphics

Swarm EEPF plot with its floating settings panel
The EEPF plot window with its floating settings panel: one curve per E/N (BOLSIG+ normalization, log y-axis), shown or hidden through the check-boxes of the scrollable curve list. The same window framework — per-curve styling, draggable and editable texts, Save/Export/Copy — serves every plot category.

The Graphics menu opens one window per category: under Transport ParametersMean Energy / Temperature (⟨ε⟩, T, T, T), Mobility (bulk, flux and EEPF µN), Diffusion coefficients (DLN, DTN bulk and flux, plus the characteristic energy DT/µ), Energy mobility / diffusionεN, DεN) and χ / Dufour — and, at the top level, Rate Coefficients (one curve per collision process), Energy Loss Coefficients, EEPF and Legendre components F₀…F₃. A Plot menu inside each window switches between categories without opening a new one. Curves that are identically zero are dropped automatically (e.g. DL in SST mode, or a process that never fires), as are duplicated bulk≡flux placeholders, so the legend only ever shows meaningful curves.

MenuWhat it does
UnitsN-reduced ↔ pressure-reduced, the same convention switch as the tables (E/N ↔ E/p, µN ↔ p·µ, rate coefficients ↔ collision frequencies per Torr).
X-axisPlot against E/N, against the mean energy ⟨ε⟩, or against the temperature — the last two convenient for comparing with characteristic-energy presentations.

The plot windows share the interactive framework of the 1D viewers: a floating ⚙ settings panel that follows its window, per-curve colour / line width / line style (including markers-only) / marker shape and size, draggable titles, axis labels and legend, double-click editing of any text (with per-text font size), double-click in the plot to drop an annotation, tick direction and subdivision control, axis ranges and log scales, a Labels mode (Full / No titles / Bare) for publication-ready frames, Plot font, Menu font and Plot size steppers, and Save (PNG/PDF/SVG), Export (ASCII columns of the visible curves), Copy (Ctrl+C, image to clipboard) and Reset buttons. Everything is persisted per category in jcpic_config.json.

The Custom plot window

Beyond the fixed plot categories, the Custom entry of the Graphics menu opens a free plot window: any column of swarm_coeffs.dat can be drawn against E/N, alone or overlaid — including quantities no fixed plot shows, such as the alternative closure variants of the EEPF-route diffusion written in the last columns of the file, side by side with the trajectory-route D. Axis decades are folded into the axis title exactly as in the fixed plots. The Dufour plot has a Sign menu (χ, −χ, |χ|), convenient because χ changes sign across the field range and is often compared on a logarithmic axis.

EEPF and Legendre components

The EEPF category plots the equilibrium electron energy probability function F₀(ε) — normalized as ∫√ε·F₀·dε = 1, the BOLSIG+ convention, in eV−3/2 — one curve per E/N, on a logarithmic y-axis; individual fields are shown or hidden with the check-boxes of the curve list. During a run the curves appear one by one as their E/N points converge. Bins with too few counts are masked automatically, which removes the spurious low-energy spikes inherent to logarithmic energy binning.

The Legendre components F₀…F₃ window displays the anisotropy of the velocity distribution: the expansion of f(v) in Legendre polynomials of vx/|v|, for one E/N selected from its menu, as |F|(ε) on a log scale (sign changes appear as sharp dips). F₁ measures the drift anisotropy — precisely what the two-term approximation truncates after — so comparing F₂ and F₃ with F₀ shows directly where a two-term solver like BOLSIG+ is expected to be accurate and where it is not.

Legendre components F0–F3 in nitrogen at 100 Td
Legendre components F₀–F₃ of the electron velocity distribution in nitrogen at 100 Td, obtained with JC-PIC — to be compared with Fig. 7(a) of the MCIG paper: G. J. M. Hagelaar, Phys. Plasmas 32, 043501 (2025). F₂ and F₃ stay orders of magnitude below F₀ — the regime where the two-term approximation is sound — while F₁ approaches F₀ around the 2 eV vibrational-resonance region and in the high-energy tail, where the distribution is most anisotropic.

🧾 Namelist &swarm & Files

Swarm mode reads its inputs from input_swarm.nml in the working directory. The file contains the usual ¶ms group — of which swarm mode uses only a few keys: swarm_mode = 1 (the mode flag), gas (the cross-section set to build), nthreads, and swarm_en_td (a fallback single E/N) — followed by the swarm-specific &swarm group. The Conditions dialog writes both; the keys below are for users who edit the file directly or archive cases.

The &swarm group

KeyTypeDefaultMeaning
speciesstring'electron'Swarm species (electrons).
en_liststring'30.0'Comma- or space-separated list of E/N values in Td (up to 64). Written by the dialog from the Single/Linear/Quadratic/Exponential series.
sw_npartint2000Electrons per replica.
sw_nrepint0Replicas per E/N point; 0 = automatic = max(8, threads) — the recommended setting: a fixed number freezes one machine's footprint into the file for no benefit, since a point stops at its error targets anyway.
sw_consint1Ionization treatment: 1 = conservative (energy loss only), 0 = temporal growth (Pulsed Townsend), 2 = spatial growth (SST).
sw_relaxreal10.0Relaxation length in energy-relaxation times τ.
sw_naccint50Ceiling on accumulation samples per replica.
sw_tolreal0.0Target relative error on ⟨ε⟩ (e.g. 0.001 = 0.1 %); 0 = ⟨ε⟩ does not gate (the point runs to the ceiling).
sw_tol_wreal0.0Separate target for the drift velocity W; 0 (default) = W reported but not gating. Locking W is expensive — its error is intrinsically ~vth/W times that of ⟨ε⟩.
sw_tol_diffreal0.0Separate target for DL, DT; 0 = diffusion reported but not gating.
sw_maxsecreal0.0Wall-time budget for the whole run, in seconds; 0 = no limit.
sw_maxsec_enreal0.0Wall-time budget per E/N point, in seconds; 0 = no limit. Its clock starts when the point begins accumulating, so it does not bound the relaxation phase that precedes it — which is why a low-field point can take far longer in wall-clock time than the budget suggests. See the note below.
sw_rlxtolreal0.0Early exit from the relaxation phase: leave it when ⟨ε⟩, block-averaged and then pooled over the replicas of that E/N, stops drifting by more than this fraction per block, twice in a row. 0 (default) = off, and with 0 the engine is bit-identical to a build without the feature. Pooling is essential rather than cosmetic — the correlation time of ⟨ε⟩ is the relaxation time being looked for, so a block inside a single replica holds about one independent sample and its noise swamps any useful tolerance.
sw_maxtaureal200.0Safety cap on the total simulated time, in units of τ (raised automatically if it would conflict with the sampling request).
sw_eeint0Electron–electron Coulomb collisions on/off.
sw_idegreal0.0Ionization degree ne/N for the e–e term.
sw_lnlamreal−1.0Coulomb logarithm; ≤ 0 = computed automatically (NRL formula).
sw_restartint01 = cumulate with the previous run (pool replicas via swarm_accum.dat).
sw_sweepint01 = field sweep with warm start (strong → weak field).
sw_gdtmaxreal4.0Growth ceiling |γ|·dt₁ per sampling window beyond which the diffusion coefficients are declared unmeasurable: dropped from the convergence gate, flagged ⚠ in Progress, blank in swarm_coeffs.dat.
sw_nbandint3No-sweep series: the E/N list is walked in bands of this many consecutive points, so replicas concentrate instead of spreading below the 8-replica minimum.
ℹ️ Where the wall-clock time actually goes at low E/N. A swarm point has two phases: relaxing the electron energy distribution towards its steady state, then accumulating samples from it. Only the second is budgeted by sw_maxsec_en. At 2 Td, of 826 s of measured wall clock, just 56 s were spent accumulating — 93 % went into the relaxation. And because the relaxation exit is purely time-based (sw_relax × τ), a point warm-started from its neighbour in a descending sweep still integrates the full ten τ even when its distribution is already relaxed. sw_rlxtol exists to cut that short, on the evidence of the pooled drift rather than on a clock.
⚠️ sw_rlxtol is off by default for one reason. At exit, τ comes out some 20 % below its settled value on a small two-replica bench, meaning the samples are slightly more correlated than nominal. In the default growth mode this is harmless — the error bars there come from the replica spread, which is immune to correlation within a replica. In conservative mode (sw_cons = 1) the per-particle errors are used instead, and those do assume independent samples, so the error bars could come out mildly optimistic.

Output files (snap_swarm/)

FileContents
swarm_coeffs.datThe transport-coefficient table: one mean line per E/N (22 columns — E/N, ⟨ε⟩, T, T, T, bulk and flux W, µN, DLN, DTN, energy coefficients, characteristic energy, Dufour χ, EEPF-integral coefficients, and — in the last columns — the alternative closure variants of the EEPF-route diffusion) followed by a # ERR line with the 1σ errors. Diffusion cells of a point whose growth was too fast for D to be measurable are left blank. Plain ASCII, directly loadable in any plotting tool.
swarm_rates.datPer-E/N blocks (# EN …) with one line per collision process: rate coefficient (m³/s), energy-loss coefficient (eV·m³/s) and energy-loss fraction. In SST mode each block also carries the Townsend coefficient as a # ALPHA_N line.
swarm_eepf.datPer-E/N blocks of the energy distribution: ε, F₀(ε) (BOLSIG+ normalization), the raw bin count, and the Legendre components F₁, F₂, F₃.
swarm_status.datThe live convergence state read by the Progress window.
swarm_accum.datThe pooled replica sums used by Cumulate with previous run.
swarm_transport.datLegacy summary table kept for compatibility. Its averages are taken over the replicas that actually sampled each point (a # active replicas: k of N comment precedes each data line; errors = spread/√k).
ℹ️ The snap_swarm/ folder also holds small run-control files (control.dat, swarm_running.flag, done.flag, gui_alive.txt) used by the GUI↔engine handshake — Run/Pause/Stop and a watchdog that stops the engine cleanly if the GUI disappears. They are internal and never need editing.

🎓 Transport-Coefficient Theory

This chapter summarizes what the swarm solver actually computes — enough to interpret every column of the results tables and to compare them safely with Boltzmann solvers and with experiment. The methods are directly taken from Hagelaar's MCIG formulation — G. J. M. Hagelaar, "Beyond BOLSIG+: Monte Carlo simulation of electron and ion swarms to obtain transport and rate coefficients for plasma modeling", Phys. Plasmas 32, 043501 (2025) — which JC-PIC follows in its estimators, growth treatments and error analysis; the distribution-function relations and coefficient normalizations are those of BOLSIG+ (G. J. M. Hagelaar & L. C. Pitchford, "Solving the Boltzmann equation to obtain electron transport coefficients and rate coefficients for fluid models", Plasma Sources Sci. Technol. 14, 722, 2005). Full citations are given in the References chapter.

The numerical experiment

For each E/N, an ensemble of electrons (a replica) moves in a uniform field through the neutral gas, colliding via the same null-collision Monte-Carlo procedure as the PIC engine (see MC Collisions); the null-collision ceiling adapts to the energy range actually visited, which speeds up low-field runs by orders of magnitude. The swarm first relaxes for a prescribed number of energy-relaxation times τ (with νε = eEW/⟨ε⟩ estimated on the fly), until its velocity distribution is in equilibrium with the field; the code then accumulates statistics in successive samples. Several independent replicas are run per E/N; the published value of every coefficient is the replica average and its error bar comes from the replica spread, cross-checked against per-particle variance estimates. A power-balance residue — field input versus collisional losses — is monitored as an a posteriori test of complete relaxation.

Flux and bulk coefficients

Two families of transport coefficients coexist in swarm physics, and they differ as soon as ionization or attachment is active:

The solver measures bulk DL, DT by a low-variance two-interval mean-square-displacement estimator (the quantity that gates convergence), and the flux diffusion by windowed velocity–displacement covariances whose variance stays bounded in time, so both converge as 1/√N. The energy-transport coefficients µε, Dε (the mobility and diffusivity of the energy density, needed by fluid energy equations), the characteristic energy DT/µ (the classical Townsend measurement), and the Dufour coefficient χ complete the table. A last set of coefficients is computed not from trajectories but from integrals over the accumulated EEPF — exactly the way a two-term Boltzmann solver evaluates µN and DN from F₀. Comparing the trajectory values with the EEPF-integral values on the same run measures the two-term approximation itself.

The three growth treatments

Conservative. Ionization only costs the threshold energy and attachment is ignored: the ensemble is fixed, bulk and flux coincide, statistics are optimal. The right choice whenever growth corrections are negligible or a clean cross-section check is wanted.

Temporal growth (Pulsed Townsend). Real ionization (equal energy sharing) and attachment on a fixed-size ensemble, kept normalized by renormalization collisions: the simulated distribution is the normalized f̂ of the exponentially growing swarm, as in a pulsed-Townsend experiment. Bulk coefficients then pick up their growth corrections through density-gradient identities — covariances of the particle displacements with the net production rate S(v) = Nv(σiz − σatt) — so Wbulk − Wflux and Dbulk − Dflux are measured, not modelled. The effective ionization frequency ν̄/N follows from the same accumulators. Because S(v) is carried by the ionizing tail of the distribution, PT statistics are intrinsically ~10× noisier than conservative ones.

Spatial growth (SST). The steady-state-Townsend regime, f(x,v) = eαxΦ(v), simulated through per-particle renormalization at rate αvx with α determined self-consistently as the eigenvalue α = ⟨S⟩/⟨vx⟩ — the reduced Townsend coefficient α/N. The mode also yields the SST drift velocity ⟨vx⟩, the SST energy distribution, and the transverse diffusion through the standard DT/µ ratio; the longitudinal diffusion coefficient is not accessible from an SST experiment (real or numerical) and is reported as zero. At very high E/N the renormalization churn degrades the SST statistics — the pulsed-Townsend mode is then the more robust route to α via the dispersion relation.

Accuracy — what to expect

The statistical error of every published quantity decreases as 1/√(particles × replicas × samples), but the prefactor depends strongly on the moment order: drift velocity and mean energy (first-order moments) converge fastest; diffusion coefficients (second-order) about ten times slower; the flux-diffusion covariances and the energy-diffusion coefficients are noisier still, and the Legendre components F₂, F₃ are the noisiest of all. This hierarchy is why the convergence gate uses ⟨ε⟩, W and the bulk diffusion only, and why a separate (looser) diffusion tolerance is offered. Two physical limitations should also be kept in mind: the gas is at rest and cold (no thermal motion of the neutrals, no superelastic collisions), so results below roughly 1–5 Td — where the electron energy approaches thermal energies — are not meaningful; and everything is computed for the electron cross-section set actually loaded, whose provenance (recorded in the headers of ELECSCAT.DAT) should be cited with any published result.

ℹ️ Validation. The natural cross-checks are BOLSIG+ on the same LXCat cross sections (expect agreement at low anisotropy, controlled deviations where F₂/F₃ grow), the Monte-Carlo swarm literature, and the measured swarm-parameter compilations. The bundled swarm test cases include such comparisons.

🔧 Troubleshooting

Most problems new users meet with JC-PIC fall into a handful of recognizable patterns. Each one below gives the likely cause and the fix. When something is unclear, the status bar and the log lines printed to the console (for example the [HIST] lines) are the quickest way to see what the engine is actually doing.

history.dat appears wiped after Stop + Run

Cause. The run was restarted with Initialization ticked (a fresh start), which deliberately clears the snapshot in snap/ and resets history.dat to begin again from t = 0.

Fix. To continue an existing run, leave Initialization unchecked before pressing Run: the engine then resumes from the last checkpoint and keeps appending to history.dat. The [HIST] lines in the console confirm which path was taken.

A viewer seems to show an old run instead of the current one

Cause. Leftover snap_*.bin files from a previous, longer run in the same folder: their higher step numbers made them sort after the current run's snapshots, and viewers used to pick the "latest" snapshot by file name.

Fix. Viewers now pick the newest snapshot by modification time and prefer the live data stream of a running simulation, so this cannot happen any more. Deleting stale snap_*.bin files from snap/ remains good hygiene when reusing a working directory.

dt becomes very small and the simulation crawls

Cause. The time step is bounded by the explicit scheme's stability limits (the plasma-frequency and CFL constraints), so as the density rises — or on a very fine grid — the largest stable dt shrinks, more steps are needed per unit of simulated time, and the run slows down. This is physics, not a fault.

Fix. Relax the constraint: a coarser grid (ngrid), fewer particles (npart), or a lower pressure all let dt grow. Check that dt_min is not set unrealistically low, and watch dt evolve in the Params Viewer to see whether the plasma-frequency or the CFL term is the one limiting it.

The particle count blows up

Cause. Super-particles are being created faster than the population controls remove them — typically strong ionization, an external source left on (ext_src_mode), or injection feeding in more than is lost.

Fix. Make sure the population controls are active and sized for the case: np_max caps the count, while npart_trigger and thin_remove govern when and how aggressively particles are merged. Then review the source terms and the ionization rate — a runaway count often means the discharge itself is running away (voltage or pressure too high for the configured controls).

Corrupt or unreadable checkpoint

Cause. A checkpoint in snap/ (such as checkpoint.bin) can be left incomplete if the engine is stopped mid-write — a power loss or a forced quit during a save.

Fix. A resume that fails or behaves oddly at start-up usually means a damaged snapshot. Restart the case from t = 0 with Initialization ticked (this rewrites snap/ cleanly), or replace the working directory's snap/ with a known-good copy. Since checkpoints are written periodically (ncheckpoint), keeping an occasional backup of snap/ for a long run is cheap insurance.

The simulation will not start (namelist error)

Cause. input.nml could not be parsed — usually a missing quote around a string (gas = 'Ar'), an integer written where a real number is expected (or the reverse), or the closing / of the ¶ms group left out.

Fix. Open input.nml and check the line reported in the console: strings are quoted, real numbers carry a decimal point, and the group ends with a slash. Simplest of all, set the parameters from the Conditions dialog, which always writes a well-formed file; an unrecognized key can simply be removed and falls back to its built-in default.

A viewer stays blank

Cause. The viewer has no data yet. Diagnostics are written to disk at their own interval, so a viewer opened in the first moments of a run — or one whose diagnostic is switched off — has nothing to show.

Fix. Let the run pass its first diagnostic interval, or open the viewer on a case that already carries a snap/ snapshot. Check that the relevant diagnostic is enabled (for instance avg_enable for the averaged profiles) and that the working directory holds the expected output files. Each viewer re-reads its file on every refresh, so the plot appears on the next update once the data exists.

A parameter change does not take effect

Cause. Most parameters hot-reload while a run is in progress (the engine re-reads input.nml on the fly), but a few structural choices — the grid (ngrid), the geometry, the gas — define the simulation itself and are applied cleanly only from a fresh start.

Fix. For those, stop the run and restart with Initialization ticked. If you edited input.nml by hand, check that the file was saved; changes made through the Conditions dialog are written automatically.

The run stopped on its own after a few hours, and nothing was wrong

Cause. The engine's watchdog concluded that the interface had disappeared. The heartbeat file the interface rewrites every two seconds had fallen behind — a machine going to sleep, a clock correction that moves the epoch, a saturated disk, or a momentary refusal to replace a file Windows had open.

Fix. Nothing is lost: the shutdown is the graceful one, and Run continues from where it stopped. The tolerance is now 90 s and three consecutive stale readings, so the false positive should not recur; if it does, snap\stop_reason.txt and the [WATCHDOG] strike n/3 lines of the log say exactly what the engine saw.

The application starts in C:\Windows\System32 and cannot write anything

Cause. The working directory recorded from the last session no longer exists — usually renamed or moved. The process then stayed in whatever directory Windows gives a shortcut, which is a folder it is not allowed to write in, so model.nml, the configuration and snap\ all failed.

Fix. This is now prevented: a candidate directory must exist, lie outside the Windows and Program Files trees and pass a real write test, and the fallback is C:\JC-PIC\RUN. Pick a working folder with Files → Working Directory and carry on.

Lowering the EEPF start time during a run has no effect

Cause. Until the August 2026 fix, edf_start was the one diagnostic start time the engine did not re-read while running — every other one (xt_start, cur_start, ifedf_start, diag_start_time) was hot-reloadable, so the omission was easy to miss.

Fix. It is now re-read in both directions: moved behind the clock, recording opens at the next step; moved ahead of it, recording opens when the clock gets there. In both cases the accumulators are cleared, so the distribution restarts cleanly. The dialog also compares the announced instant with the real time of the run, read from history.dat, instead of claiming that recording has not started when it has.

The Averaged checkbox is greyed out, or shows an average that does not move

Cause. The engine only accumulates averages after the Averaging start time of Conditions → Diagnostics → General. Before it, there is nothing to average. The second symptom is the older one: after a Reset Time, or after raising the start time during a run, the accumulation counter stayed standing while the engine stopped accumulating, so the viewer showed a frozen average belonging to another time.

Fix. Both are handled. The checkbox greys until the displayed instant is genuinely past the start time and ungreys by itself when a running case crosses it; and the engine now clears the accumulators when the start time is moved ahead of the clock, so the average restarts at the right instant. See Working with Viewers → The Averaged checkbox.

The X-T window is hard to resize, and double-clicking a title moves it instead of opening its dialog

Cause. A map too large to redraw quickly. Tk only generates a double-click if the two clicks are less than 500 ms apart, and it timestamps a click when it processes it — so a redraw longer than that between the two clicks eats the event, leaving the first click's drag as the only thing that happened.

Fix. The X-T viewer now switches from Gouraud to flat shading above 40 000 cells, which divides the redraw time by about seven and puts a 400×400 map comfortably back under the limit. If the symptom appears anywhere else, the immediate workaround is to reduce xt_nt — remembering that this invalidates snap\xt_accum.bin.

Pmag is a flat line, or too small

Cause. Two independent ones. The magnetic term is only deposited when heating_diag = 1, and with the heating diagnostics off it is identically zero, silently. And on a run resumed from a checkpoint the underlying n·uz accumulator cannot be rebuilt, so the term is under-estimated until the position-time accumulators are cleared.

Fix. Set heating_diag = 1 (hot-reloadable, from Diagnostics → General) and, on the first restart of a magnetized case, xt_reset = 1.

The engine stops immediately with a floating-point exception

Cause. nsnapshot set to 0. Zero is not the way to switch snapshots off — it is a division.

Fix. Use a large finite value instead (larger than the number of steps the run will take).

The Avg checkbox has no effect in the profile viewer for a particular quantity

Cause. The profile viewer recognizes a fixed set of plot modes — densities with the field, with the potential, with the mean energy, ionization rate, ionization frequency, absorbed power, and electron/ion energies. Anything outside that set falls through to a default branch that plots the instantaneous data and ignores Avg without saying so.

Fix. Use one of the standard entries of Graphics → 1D Profiles, or the Custom 1D Profile viewer, which handles the averaging itself for every quantity in its palette.

📄 Namelist input.nml

Every parameter of a simulation — physical and numerical alike — lives in a single plain-text file, input.nml, in the working directory. It is an ordinary Fortran namelist: one group, named ¶ms, holding a list of key = value lines and closed by a slash. The engine reads it once at start-up and re-reads it on the fly when you change a parameter during a run (the "hot reload"); it is the single source of truth for the run.

Shape of the file

¶ms
  gas = 'Ar'
  pressure = 0.075  ! torr
  gap = 0.025  ! m
  voltage_rf = 250.0   freq_mhz = 13.56
  ngrid = 256   npart = 200
  ...
/

Strings are quoted (gas = 'Ar'), real numbers are written with a decimal point, integers without. The order of the lines does not matter, and a key left out simply takes the engine's built-in default. Each key corresponds one-to-one to a control in the Conditions dialog — the key name is shown next to every field in the "Conditions Dialog" chapter — so the dialog and the file are two views of the same data.

In normal use you never touch this file directly: the Conditions dialog reads it when it opens and rewrites it when you click OK. But because it is plain text, it can also be edited by hand (in any text editor) for scripting, for bulk parameter sweeps, or to set a key that has no dedicated control yet — provided you spell the keys exactly as the engine expects them. The complete list of keys, with their types and defaults, follows below.

💡 When a case is loaded from the library, its input.nml is copied into your working directory; editing it there never affects the original in the case library. If you hand-edit input.nml while the Conditions dialog is open, reopen the dialog so it picks up your changes (otherwise the next OK will overwrite them).

The reference below is grouped by the Conditions-dialog tab that owns each key; the Conditions Dialog chapter explains the physics behind every one. A key left out of the file simply takes its default. Type is real (a number with a decimal point), int (a whole number), flag (an integer 0/1 switch), or string (quoted). Pressures are in torr, lengths in metres, fields in tesla, energies in eV, times as noted; spatial intervals are fractions of the gap.

General

KeyTypeDefaultMeaning
nthreadsint0OpenMP threads (0 = auto-detect).
gasstring'Ar'Working neutral gas.
pressurereal0.5Neutral pressure (torr).
gas_tempreal300Neutral gas temperature (K).
gapreal0.02Electrode gap / domain length L (m).
ngridint512Number of grid cells (max ng_max = 4096).
auto_adapt_ngridflag0Auto-double ngrid to keep the Debye length resolved.
mass_ratio_overridereal0.0Ion/electron mass ratio override (0 = use the cross-section file value).

Initial

KeyTypeDefaultMeaning
density0real1e14Peak initial plasma density (m−3), ne = ni.
te_initreal2.0Initial electron temperature (eV).
ti_initreal0.026Initial ion temperature (eV).
x1_profile, x2_profilereal0.0, 1.0Density-profile interval (fraction of gap).
profile_typeint00 uniform · 1 sine · 2 external file · 3 raised cosine · 4 Gaussian.
init_file_name_instring'init.inp'External density-profile file (profile_type 2).
drift_energyreal0.0Electron drift / beam energy (eV).
beam_fractionreal0.0Monoenergetic beam fraction (%).
two_streamflag0Seed two counter-streaming Maxwellians.
npartint80Initial super-particles per cell (total = npart×ngrid).
npart_triggerint1600000Thinning threshold (Max #); hard cap np_max = 2×106.
thin_removereal0.20Fraction removed per thinning event.
npart_minint0Auto-split threshold (Min #; 0 = disabled).

Boundaries — injection, sources, secondary emission

KeyTypeDefaultMeaning
einj_left_modeint0Cathode electron injection: 0 off · 1 constant current · 3 virtual z length.
einj_jcurrreal0.0Injected current density (A/m²).
einj_vdistint00 beam (drift+spread) · 1 thermal source (flux).
einj_tereal0.0Injection temperature / spread (eV).
einj_eparrreal0.0Injected directed energy (eV).
einj_vlenreal0.01Virtual perpendicular length (m, mode 3).
vlen_ionsflag1Ion treatment in injection mode 3: 1 (default) the ions feel Ez and are renewed at Lz like the electrons; 0 they ignore Ez and are never renewed — a closed ion population, which exists only to reproduce the published ECDI simulations and is not physical otherwise.
ext_src_modeint0External source: 0 off · 1 constant · 2 re-injection on loss.
ext_jsrcreal0.0Source current density (A/m²).
ext_pct_ions_inreal100Percentage of injected ions.
reinj_trigint0Re-injection trigger: 0 ion loss · 1 electron loss.
ext_x1_in, ext_x2_inreal0.0, 1.0Source interval (fraction of gap).
ext_prof_typeint0Source profile: 0 uniform · 1 sine · 2 file · 3 raised cosine · 4 Gaussian.
ext_te_in, ext_ti_inreal2.0, 0.5Injected electron / ion temperatures (eV).
src_mod_onflag0Time-modulate the source current from a file (mode 1).
srcmod_file_instring'source_mod.inp'Two-column modulation file: time (s), normalized shape f(t) with max|f| = 1.
srcmod_amp_inreal0.0Peak amplitude J₁ (A/m²) of the modulated source: the injected current is J₀·S(x) + J₁·f(t), with J₀ = ext_jsrc and f the normalized shape from the file above. 0 (the default) means the modulation has no effect — set it to drive a wave with a time-dependent source (the Ion-Acoustic-Wave cases).
src_mod_loopflag0Loop the modulation table periodically.
see_sigma0_inreal0.0Electron-impact SEE yield σ₀.
see_epsstar_inreal0.0Electron-impact SEE characteristic energy ε* (eV).
te_see_elec_inreal2.0Temperature of electron-impact secondaries (eV).
see_elec_left_in, see_elec_right_inflag0Enable electron-impact SEE per wall.
gamma_left, gamma_rightreal0.0Ion-impact SEE yield per electrode.
tsee_left, tsee_rightreal2.0Temperature of ion-impact secondaries (eV).

Voltage / heating & external circuit

KeyTypeDefaultMeaning
voltagereal−300DC voltage VDC (V).
voltage_rf, freq_mhzreal0.0, 13.56First RF amplitude (V) and frequency (MHz).
voltage_rf2, freq_mhz2real0.0, 0.0Second RF amplitude (V) and frequency (MHz).
theta_degreal0.0Phase of the first RF component (°).
vprofileint0Drive: 0 formula · 1 external file.
vfile_name_instring'voltage.inp'External V(t) waveform file.
vfile_loopflag0Loop the waveform file periodically.
periodic_bcflag0Periodic boundaries (no electrodes, current-driven).
right_bc_typeint0Right wall: 0 grounded V = 0 · 1 insulated E = 0.
drive_modeint0Drive variable: 0 voltage source · 1 ideal RF current source (Verboncoeur et al. 1993 — electrode surface charge + Neumann boundary). Fresh Start required; forced to 0 in swarm, periodic, E = 0 right-wall and no-Poisson modes. Not hot-reloadable.
cur_dc, cur_rf, cur_rf2real0.0DC and two RF amplitudes of the imposed current density (A/m²), with the shared freq_mhz, freq_mhz2, theta_deg. Hot-reloadable.
series_capreal0.0Series capacitance (nF/m²).
series_resreal0.0Series resistance (Ω·m²).
bias_capreal0.0DC self-bias blocking capacitor CI (nF/m²; 0 = off).
n_avg_bias_inint1RF periods averaged per self-bias update.
heating_typeint00 none · 1 DC/RF field · 2 absorbed power · 3 thermalization.
heating_fieldreal0.0Field (V/m) or absorbed power (W/m²).
heating_freqreal0.0Heating frequency (MHz).
heating_dirint0Direction: 0 parallel (x) · 1 perpendicular (z).
heating_self_adjustflag0Self-adjust Ez (radial positive column).
heating_tempreal0.0Thermalization target temperature (eV).
heating_x1, heating_x2real0.0, 1.0Heating interval (fraction of gap); x1 = x2 with type 3 = mid-plane thermostat.
heating_profileint0Heating profile g(x): 0 uniform · 1 sine · 2 file · 3 raised cosine · 4 Gaussian.
heating_profile_filestring'heating.inp'External g(x) file (profile 2).
no_poissonflag0Laplace field, electrons only (uniform-field swarm / SST mode).

B Field

KeyTypeDefaultMeaning
btypeint00 off · 1 perpendicular Y · 2 perpendicular Z · 3 parallel X · 4 oblique in the x-y plane.
bfield_anglereal90.0Angle α of B to the wall (degrees), used only by btype = 4: Bx = B sin α, By = B cos α. α = 90° reproduces btype = 3 exactly; clamped to [0, 90]. A file without this key is unaffected, since the oblique branch is only taken at btype = 4.
bprofileint00 Gaussian · 1 external file (BField.inp).
ion_unmagflag0Leave the ions unmagnetized (electrons only).
bmagreal0.01Peak field Bmax (tesla).
bleft, brightreal= bmagField at the left / right wall (tesla).
bsigma1, bsigma2real0.2Left / right Gaussian widths (fraction of gap; 0 = linear ramp).
bcenterreal0.5Position of the peak (fraction of gap).

Special

KeyTypeDefaultMeaning
energy_share_typeint0Ionization energy sharing: 0 constant ratio · 1 Vahedi (reserved).
energy_share_rreal0.5Ejected-electron energy fraction r.
energy_share_wreal10.0Vahedi w parameter (eV; reserved).
loss_freq_elec, loss_freq_ionreal0.0Artificial particle-loss frequencies (MHz).
loss_x1, loss_x2real0.0, 1.0Loss interval (fraction of gap).
ioniz_modeint00 normal · 1 as excitation · 2 balanced by uniform losses.
anom_freqreal0.0Anomalous electron collision frequency (MHz).
anom_x1, anom_x2real0.0, 1.0Anomalous-collision interval (fraction of gap).
anom_profileint00 uniform · 1 cosine · 2 parabolic.
coulomb_eeflag0Electron–electron Coulomb collisions (Nanbu model).
coulomb_factorreal1.0Density-scale factor of the Coulomb operator (≥1).
coulomb_nsubint1Coulomb sub-cycling: apply the e–e operator every n steps with Δtcoll = nΔt (same physics, cost ÷ n; keep the per-application s ≲ 0.05 — the engine's [COUL] log line suggests the value). 0 = automatic: the engine tracks the s ≈ 0.05 target itself (bounded cadence, hysteresis, logged). See MC Collisions → Sub-cycling.
coulomb_lnlamreal0.0Coulomb logarithm lnΛ (≤0 = computed automatically).

Control

KeyTypeDefaultMeaning
istart_modeint00 continue from checkpoint · 1 fresh start (Initialization).
end_time_usreal0.0Stop time (µs).
dt_modeint1Time step: 0 user-fixed · 1 code-adaptive.
dtmaxreal1e-10Fixed (user) or maximum (code) time step (s).
dt_smooth_usreal1.0Relaxation time for the adaptive dt (µs).
nsmoothint0Binomial smoothing passes on ne, ni (0–10).
nsub_ionint20Ion subcycling factor (ions pushed every N steps).
part_factorreal1.0One-off particle-count rescaling at run start.
reset_timeflag0Legacy form of the clock reset, honoured at start-up only. The dialog no longer uses it — it always writes 0 and issues the order through snap/reset_time.flag instead, so that it also works during a run and cannot fire again by accident later.
rng_typeint0Random generator: 0 xorshift32 · 1 SplitMix64.
n_phi_smoothint0Legacy key, accepted so that older namelists still parse; it has no effect.
swarm_conv_tol, swarm_max_us, swarm_min_us, swarm_ioniz_consreal, real, real, flag5e-3, 1e3, 0.0, 1Legacy keys of an early in-PIC swarm test. The real swarm solver is a separate mode with its own &swarm group — see Namelist &swarm. Left in place so old input files still parse.
aniso_elasticint0Anisotropic (screened-Coulomb) elastic scattering; the elastic rate switches from σm to σeleffm preserved exactly). Fresh Start required.
aniso_excint0Anisotropic angle draw for excitation (angle only, incident energy).
aniso_ionizint0Anisotropic deflection of both ionization products at their post-collision energies (inactive with the Donkó correlated-angle sharing).
aniso_estarreal12.5Anisotropy energy e* (eV): ξ = ε/e*; Eaniso (Carlsson 2017) = 8e*.
aniso_chiminreal8.0Small-angle cutoff (deg) of the elastic forward lobe; clamped to [0, 45]. Momentum transfer exact for any value.
ion_mass_factorreal1.0Ion-mass convergence accelerator (steady-state Townsend): ions and their collision targets are integrated with mass M/f. Γi, ne, α, the current and the IFEDF are invariant; ion velocities scale as √f, ni as 1/√f — CPU gain of order f. Steady state only, negligible space charge, no B field. Clamp [1, 10⁶]; forced to 1 in swarm mode; Fresh Start required. See Advanced Dialog → Special.

Diagnostics

KeyTypeDefaultMeaning
avg_enableflag1Time-averaged profile accumulation.
diag_start_timereal0.0Time after which averaging starts (µs).
avg_interval, avg_unitreal, int500, 0Accumulation cadence; unit 0 steps · 1 ns.
diag_avg_timereal1.0EMA time constant (µs; 0 = flat average).
diag_reset_avgflag0One-shot: clear the profile averaging accumulators at start-up. Same effect as the Rst Avg button.
heating_diagflag0Electron heating (Schulze power) decomposition.
xt_enableflag0Position–time (x,t) diagnostics.
xt_startreal0.0(x,t) start time (µs).
xt_nx, xt_ntint50, 100(x,t) spatial (≤511) and time/phase (≤512) bins.
xt_modeint10 periodic (phase-averaged) · 1 transient (sliding window).
xt_ncyclesint1RF cycles averaged (periodic mode).
xt_windowreal1000Sliding window (µs, transient mode).
xt_resetflag0One-shot: clear snap/xt_accum.bin at start-up. Needed on the first restart of a magnetized case, because the n·uz accumulator behind Pmag cannot be rebuilt from a checkpoint.
xt_navgint0Number of steps averaged into one (x,t) sample; 0 lets the engine derive the cadence from the window and xt_nt.
xt_avg_dt, xt_avg_windowreal0.0Manual override of that cadence — sampling interval in ns and integration window in µs. Leave both at 0 for the automatic choice, which is what the dialog writes.
cur_navgint0The same, for the current diagnostic: steps averaged per cur.bin sample; 0 = automatic.
edf_enableflag0EEPF and IFEDF accumulation.
edf_startreal0.0EEPF/IFEDF start time (µs).
edf_emax_val, edf_nbinsreal, int100, 200EEPF max energy (eV) and energy bins.
edf_nxbinsint50EEPF spatial slices (EEPF-2D).
ifedf_enableflag0Ion flux–energy distribution at the walls, accumulated independently of the EEPF.
ifedf_startreal0.0IFEDF start time (µs). Note the string ifedf_start contains edf_start, which is why the two are matched separately when the namelist is re-read on the fly.
ifedf_emax, ifedf_nbinsreal, int200, 200IFEDF max energy (eV) and bins.
ifedf_avg_windowreal0.0Sliding integration window for the IFEDF (µs); 0 = accumulate from ifedf_start onwards.
edf_tavg_enable, edf_tavg_interval, edf_tavg_unitflag, real, int0, 1.0, 0EEPF/IFEDF time integration on/off, cadence, unit (0 ns · 1 step).
edf_tavg_resetflag0One-shot: clear the EEPF/IFEDF time integration at start-up.
edf_tmin, edf_avg_windowreal0.0Fixed-start time vs sliding window (µs); only one is non-zero.
nx_phase_in, nv_phase_inint128Phase-space histogram resolution (clamped 16–256).
cur_enableflag0Total-current jT(t) diagnostic.
cur_start, cur_ntreal, int0.0, 500Current start time (µs) and number of time points.
cur_mode, cur_ncycles, cur_windowint, int, real0, 10, 10000 periodic / 1 transient; cycles averaged; window (µs).
ndiagnosticint1000history.dat write interval (steps).
ncheckpointint5000Checkpoint interval (steps).
nsnapshotint500Snapshot / (x,t) / EEPF accumulation interval (steps).
nbarint10Run-bar refresh and stop/pause poll interval (steps).
nodiag_beforereal0.0Skip the heavy recording diagnostics (x,t / EEPF / phase) before this time (µs).
ℹ️ In Swarm mode the engine reads a separate &swarm namelist group (written by the Swarm conditions dialog into input_swarm.nml). Its keys are documented in Namelist &swarm & Files.

Advanced and internal keys

These are read but are rarely changed; most have no control in the dialog and the defaults are appropriate for almost all runs.

KeyTypeDefaultMeaning
dt_start, dtminreal1e-10, 1e-13Initial and minimum time step (s).
cfl_plasma, cfl_cyclo, cfl_courant, cfl_collisionreal0.20, 0.20, 0.50, 0.10Safety factors of the four CFL constraints on the adaptive dt.
cfl_izfrac_inreal0.01Ionization fraction that defines the robust Courant cutoff speed v*: the electrons above v* carry less than this fraction of the total ionization rate. Only affects the reported dtcfl / fast-e⁻-step diagnostic (the Courant limit is not binding). Clamped to (0, 1).
cfl_xmean_inreal5.0Fallback multiplier when there is no ionization: v*² = cfl_xmean_in·⟨v²⟩, capped by the true maximum. Used by the wave / beam cases. Clamped to [1, 100].
dt_change_maxreal2.0Maximum dt change ratio between steps.
ndt_chkint200Interval at which dt is re-evaluated (steps).
icoll_elastic, icoll_exc, icoll_ion, icoll_ionsflag1Enable each collision channel (electron elastic / excitation / ionization; ion collisions).
thin_methodint1Thinning method (0 random · 1 regular stride).
auto_adapt_nu_nullflag0Adapt the MCC null-collision rate to the actual maximum energy.
vmax_smoothreal1.0EMA smoothing factor for v*² in the reported Courant limit (1 = instantaneous, matches the legacy behaviour; smaller = steadier read-out).
rise_timereal0.0Rise time of the applied voltage (s; pulsed cases).
ion_xsec_approx, ion_sigma_elastic, ion_sigma_backwardint, real, real0, 1e-19, 1e-19Use constant approximate ion cross sections (m²) instead of a table.
ntmaxint0Hard cap on the number of steps (0 = unlimited; end_time_us is the normal stop).
nthreads, data_dir, snapshot_dirint, string, string0, (set by GUI), 'snap'Threads, cross-section data folder, and output subfolder (the GUI sets these).
swarm_mode, swarm_en_tdint, real0, 0.0Swarm-mode flag and fallback E/N — set automatically (in input_swarm.nml) by the Swarm conditions dialog; see the Swarm chapters.
ℹ️ A few keys are accepted as aliases or hold internal accumulator state and are not meant to be set by hand — for instance diag_general (an older name for avg_enable), snap_interval/snap_unit, and the *_reset, *_navg, xt_avg_*, edf_tmax, ifedf_* fields. The Conditions dialog manages all of these for you; when in doubt, set parameters through the dialog rather than the file.

✉️ Getting Help

For a question about the program or about a test case, and for any problem or bug, write to the author: jpboeuf@gmail.com (or jpb@laplace.univ-tlse.fr).

What to send with a problem report

Three things make a problem easy to find and fix. Please include them in your message:

  • The version of JC-PIC: menu JC-PIC → About….
  • The file jcpic.log, in the folder where JC-PIC is installed (the folder of JC-PIC.exe). It records what the interface did during the last session.
  • The file fortran.log, in your working folder (the folder of the case you were running). It records what the simulation engine did.

A screenshot of the window or the message you saw, and a sentence on what you were doing when the problem appeared, complete the report. If the problem concerns a case of your own, the input.nml or input_swarm.nml of the working folder is useful too.

💡 Both log files are overwritten at the next start of the program or the next run. Copy them before you try again.

📖 Glossary

A quick reference for the acronyms and physics terms used throughout this manual and in the JC-PIC interface.

TermMeaning
1D3VOne spatial dimension, three velocity components: the code resolves a single coordinate x but tracks all three velocity components of every super-particle, so magnetic fields and the full angular distribution of collisions are handled correctly.
Bohm criterionThe condition that ions enter a sheath with at least the Bohm speed (the ion-sound speed); it sets the ion flux to a wall.
Boris pusherThe standard leapfrog scheme that advances particle velocities, splitting the magnetic rotation from the two half electric kicks; the rotation is exactly energy-conserving.
CCPCapacitively Coupled Plasma — a discharge driven by an RF voltage applied across two electrodes through the sheath capacitance.
CFL numberCourant–Friedrichs–Lewy number; here the fraction of a plasma period resolved per time step. Kept near 0.2 of ωpe−1 for accuracy.
Charge exchange (CX)An ion–neutral collision in which a fast ion captures an electron from a slow neutral: a fast neutral (untracked) and a thermal ion result. Shapes the ion energy distribution at the walls (IFEDF).
Debye length (λD)The screening length of a plasma; the grid spacing must resolve it for the PIC scheme to be valid.
ELECSCAT.DAT / IONSCAT.DATThe two plain-text cross-section files of the DATA folder (electron–neutral and ion–neutral sets, LXCat/BOLSIG+ format) that the engine reads at start-up; the Gas menu lists the gases found in the first. See Cross-Section Files (DATA).
EEDF / EEPFElectron Energy Distribution / Probability Function. The EEPF is the EEDF divided by √ε; a Maxwellian distribution appears as a straight line on a semi-log EEPF plot.
ICPInductively Coupled Plasma — a discharge sustained by an induced RF field. Mentioned for comparison; not driven directly by JC-PIC.
IFEDFIon Flux–Energy Distribution Function: the energy distribution of the ions arriving at a wall.
LxCatThe open-access database of cross sections for low-temperature plasma modelling (www.lxcat.net). The electron sets shipped with JC-PIC come from its SIGLO database (helium from Biagi-v7.1), the ion sets from its Phelps database; publications based on them should acknowledge LxCat and the database used.
Macro-particle weightThe number of real electrons or ions (per unit area in 1D) represented by one super-particle. Adjusted by thinning/splitting so the physical density is never changed — only the statistical resolution.
MCCMonte Carlo Collisions — the stochastic treatment of collisions between charged particles and the neutral background gas, layered on top of the collisionless PIC dynamics.
Namelist (input.nml)The plain-text Fortran namelist file holding every parameter of a simulation — human-readable and directly editable.
Null-collision methodAn efficiency technique that adds a fictitious "null" event so the total collision frequency is constant, avoiding a per-particle cross-section lookup at every step.
PICParticle-In-Cell — the method that pushes super-particles under the Newton–Lorentz equation while solving the fields on a spatial grid (cloud-in-cell weighting).
Plasma frequency (ωpe)The natural electron oscillation frequency; the time step must resolve it (ωpe Δt ≪ 1).
Positive columnThe quasi-neutral, field-aligned body of a long DC or RF discharge, modelled here in periodic mode; the home of striations.
Pre-sheathThe weak-field region ahead of a sheath where ions are accelerated up to the Bohm speed.
SEESecondary Electron Emission — the release of electrons from a wall under ion or electron impact, set by user-controlled coefficients.
Self-biasThe DC potential that builds up on a capacitively-coupled electrode of an asymmetric or dual-frequency discharge.
SheathThe thin, non-neutral, high-field layer that forms between a plasma and a wall or electrode.
SnapshotA binary checkpoint of the full simulation state (in snap/), written continuously; lets a run be paused, resumed, or inspected at any time, even on another machine.
Stored resultsThe converged run of a library case — its diagnostic files (view) and optionally its restart point (view + continue) — kept in the case's snap/ folder and downloaded on demand from the case browser (● / ◐ / ○ in the Results column, Get results, Get all results…). See Test Cases & Browser.
StriationsStanding or moving axial ionization waves in a positive column.
Super-particleA computational particle representing many real electrons or ions (see macro-particle weight); the basic unit pushed by the PIC scheme.
Two-stream / BunemanKinetic instabilities driven by the relative drift of charged-particle populations; classic PIC benchmark cases.
Working directoryThe folder on disk where a simulation lives (input.nml, snapshots, diagnostics). Self-contained: copy it to back up, send it to share, move it to relocate.
Bohm speed (uB)√(kTe/M), the ion-sound speed built on the electron temperature and the ion mass — the minimum speed at which ions enter a sheath.
Case library — shipped vs your ownThe cases installed with JC-PIC (listed in CASES\_shipped.json) are read-only and refreshed by updates; the groups and cases you add with Add my case… are yours (renamable, deletable, kept by updates). Neither kind is ever run in place: a case is always copied to a working folder.
Centre-of-mass energyThe kinetic energy of the relative motion of two colliding particles, Ecm = µg²/2 (M g²/4 for an ion in its parent gas). Ion–neutral cross sections are tabulated against it, and it is the energy the engine looks up at every ion collision test.
Chodura criterionThe magnetized counterpart of the Bohm criterion: when B meets the wall at an angle, the ion flow must reach the sound speed along B at the entrance of the magnetic presheath. Between that point and the Debye sheath, the Chodura layer — a few ion gyroradii thick and quasi-neutral — turns the flow towards the wall normal.
Coulomb logarithm (lnΛ)ln(λD/b90), the ratio of the largest to the smallest impact parameter that matters in Coulomb collisions. It appears because every decade of impact parameter contributes equally to the accumulated deflection, so the sum diverges logarithmically and has to be cut off at the screening length. Typically 10–15 in a low-temperature discharge.
Cyclotron frequency (ωc)qB/m, the angular frequency of the gyration about a magnetic field line. Its ratio to the collision frequency, ωc/ν, is what decides whether a species is magnetized.
Druyvesteyn distributionThe energy distribution obtained when elastic collisions dominate and the cross section is energy-independent: f ∝ exp(−(ε/ε₀)²). Its high-energy tail is much poorer than a Maxwellian of the same mean energy — which is why the ionization rate is so sensitive to the shape of the EEPF, not just its mean.
Hall parameterωc/ν, the number of gyrations a particle completes between collisions. It divides the mobility across the field by 1 + (ωc/ν)², which is the whole content of magnetic confinement in a collisional plasma.
Larmor radius (rL)mv/qB, the radius of the gyration. Being proportional to √m, it separates electrons and ions by √(M/m) — a factor 85 in helium — which is why a discharge can be magnetized for the electrons and not for the ions.
Momentum-transfer cross section (σm)∫(1 − cos χ) dσ, the cross section weighted by the fraction of forward momentum actually lost. Transport — mobility, diffusion, elastic energy loss — depends on this and not on the total cross section, which is why an anisotropic scattering model must preserve it exactly.
Null-collision methodThe standard trick that makes Monte-Carlo collisions affordable: a constant upper bound νmax ≥ ν(ε) is used to draw the time to the next event, and the surplus events are discarded as "null". It removes the need to integrate ν along the trajectory, and it is why the time step must stay below about 0.2/νmax.
Plasma parameter (ND)The number of particles in a Debye sphere, nλD³. It must be large for the plasma description to hold, and its inverse measures the relative importance of collisions against collective behaviour.
Ramsauer minimumThe deep minimum of the electron elastic cross section of argon, krypton and xenon around 0.3–1 eV, a quantum interference effect. Slow electrons become nearly collisionless there, which is why argon behaves unlike the lighter gases at low mean energy.

FAQ

Short answers to the questions new users ask most often.

Can I stop a run and resume it later? Yes. The state is checkpointed continuously to snap/, so a paused or stopped simulation can be resumed at any later time — even after closing JC-PIC, or on a different machine pointing at the same working directory.

What is the difference between Run and Initialization? Run continues from the checkpoint in snap/ if one is present; tick Initialization first to wipe the snapshot and restart from t = 0.

How long does a typical run take? A capacitively-coupled RF benchmark completes in a few hours on an ordinary multi-core desktop. The engine is parallelized with OpenMP and uses every available core automatically; higher-pressure or higher-resolution cases take longer and are best left running overnight.

Where are my results stored? Everything lives in the working directory you chose: input.nml, the GUI state, the snap/ folder, and the diagnostic history files. To back up a run, copy the folder; to share it, send the folder.

Which gases can I use? Whatever gases have cross-section data files installed (helium and argon are the usual ones). The list offered in the Conditions dialog reflects the available data, and the set of collision channels depends on the gas (see MC Collisions).

How do I reproduce a published result? Use Input → Load Test Cases…, pick a case close to what you have in mind, and run it from t = 0 — or open its bundled snapshot for an instant quasi-steady comparison. Most bundled cases reproduce a specific paper, cited in the case description.

My simulation seems slow — what can I do? Make sure all cores are being used (the status bar shows the OpenMP thread count). Beyond that, the cost scales with the number of cells and super-particles and with the collision rate, so a coarser grid, fewer particles per cell, or a lower pressure all speed things up — at the expense of resolution. The population controls (thinning / splitting) keep the particle count bounded automatically.

Can I watch a run from a second machine? Yes. Each viewer reloads its data from disk on every refresh, so a second machine pointing at the same working directory can open any diagnostic while the run proceeds elsewhere.

How do I change the working directory? Files → Working Directory. Loading a test case also switches to the directory you copy it into.

Does JC-PIC need an internet connection or an account? No. It is fully local: no cloud, no telemetry, no account, and it runs offline. Your data never leaves your computer.

Can I build my own case and share it? Yes. A case is just a self-contained folder, so you can copy or send it freely; a case you find interesting can later be folded into the shared library so other users benefit from it.

🔎 Index

An alphabetical index of the namelist variables, interface elements, and physics/numerics terms used in this manual. Each entry links to the place(s) where the term appears — click a link to jump straight to it (the target flashes briefly on arrival). The index is generated automatically from the manual’s own content, so it stays in step as the text evolves.

Building index…