📖 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:
- 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).
- 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.
- 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.
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.
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.
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.
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.
💻 Installation
Section to be filled once the installer is ready: download the .exe installer, walk-through of the setup wizard, default install folder, what gets installed (JC-PIC executable, cross sections, test case library).
What Gets Installed
To be written: JC-PIC.exe, xsec/ folder (electron + ion cross sections), CASES/ folder (preloaded test cases — see "Test Cases & Browser"), Start Menu and Desktop shortcuts.
First Launch
To be written: starting the GUI, choosing a working directory, sanity check.
Updating
To be written.
Uninstalling
To be written.
🚀 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.
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
- 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.
- 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.
- Choose a working directory. A folder picker opens. 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 insideCASES).- 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.
- The case is copied in. JC-PIC copies the case — its
input.nml, its saved configuration, any input-data files, and its precomputed snapshot (the already-computed results) — 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. - See the precomputed result right away. Because the case ships with a snapshot, 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.
- 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.
- 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:
- An empty folder — JC-PIC copies your current run (its
input.nml, snapshot and input files) into it and continues there, so you carry your setup with you. - A folder that already contains a run — JC-PIC asks what to do: Yes erases that folder and replaces it with the current run; No simply switches to it and uses the run already stored there (no changes). This is how you move between several saved studies.
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.
Files Menu
The Files menu groups the actions related to where the simulation runs and which mode it operates in.
Working Directory
Opens a folder picker that lets the user choose the directory in which the simulation will run. JC-PIC reads input.nml, writes snapshots and stores all diagnostics inside this 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.
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 runs the same MCC machinery on a population of electrons in a uniform applied field, with no Poisson solve — the standard setting for computing electron transport coefficients (drift velocity, characteristic energy, ionization and attachment rates) as a function of E/N. The choice is reflected in the footer label.
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.
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.
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.
| State | What is shown | Window 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, throughput in million particles per second, 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 Interface 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.
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. 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.
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 radial profiles displayed in the profile viewer: densities together with the electric field, the potential, the mean energy, the ionization rate, the absorbed power, or the ionization frequency. A separate entry launches the heating viewer with the Schulze decomposition of the electron power.
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).
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.
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. It holds two entries.
Manage Viewer Windows…
Opens a small Viewer Windows panel docked to the main window. It lists every viewer currently open — each row carries a close (✕) button — 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, the Viewers follow the main window checkbox makes the whole 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). It is the quickest way to tidy a screen cluttered with a dozen diagnostic windows. See Working with Viewers for the full walk-through.
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's affiliation, and a link to the project page. The same dialog can be summoned at any time without affecting the running simulation.
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 the central place where a simulation is defined. It is opened from Input → Conditions… and exposes the physical and numerical parameters of the run, organized into eight tabs that are visited roughly in the order one would set up an experiment: General (gas, neutral background, domain and grid), Initial (starting particles, temperatures and injection), Boundaries (wall and electrode conditions), Voltage/heating (the applied waveform and electron heating), B Field (an optional magnetic field), Special (collision and ionization options), 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.
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 two govern how a run starts and stops and are described under the Control tab below.
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
| 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_) |
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_ 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. |
pressure (in torr) and gas_temp are saved; the density and the pascal value are reconstructed on the next open.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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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: Uniform (0), Cosine (1, a cosine-shaped profile that tapers toward the interval edges), 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. |
| 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. |
| 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). |
Boundaries Tab
The Boundaries tab governs how charged particles enter and leave the simulation: electrons injected at the cathode, electron–ion pairs created in the volume (either at a prescribed rate or to replace particles lost at the walls), and secondary electrons emitted from the electrodes under electron or ion impact. The tab is split into three nested sub-tabs — Electron Injection, External Source and Secondary Emission.
right_bc_type, periodic_bc). The Boundaries tab is about particles at the boundaries, not the electrostatic potential.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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
External Source sub-tab
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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: Uniform (0), Cosine (1), or External file (2), which reads a Src.inp table. |
| Injected temperatures Te, Ti (eV) | ext_te_in, ext_ti_in |
(modes 1 & 2) The temperatures of the injected electrons and ions. |
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.
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).
| Field | input.nml key | Meaning |
|---|---|---|
| σ₀ | 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.
| Field | input.nml key | Meaning |
|---|---|---|
| γ (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/heating Tab
This tab sets how the discharge is driven: the voltage applied to the electrodes (or the periodic, current-driven alternative), an optional supplementary electron-heating mechanism, and the external electrical circuit placed in series with the discharge. It is divided into three sub-tabs — Voltage, Electron heating and External circuit.
Voltage sub-tab
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
| 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/(tlast−tfirst) 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. |
Electron heating sub-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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
External circuit sub-tab
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
bias_cap = 0 for a file-driven waveform). The series RC, by contrast, stays active in every driving mode.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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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; or Parallel B field X (3) — along the axis, which rotates the transverse velocity components. |
| 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. |
bleft) and k = 2 for x ≥ xBmax (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).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.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, and an anomalous (artificial) electron collision frequency. 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).
| Field | input.nml key | Meaning |
|---|---|---|
| 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). |
| Coulomb collisions scale factor | coulomb_factor |
A multiplicative factor applied to the electron–electron Coulomb collision operator. Set to 0 to disable Coulomb collisions (the usual choice for low-density, weakly coupled discharges). |
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
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.
General sub-tab
Controls the time-averaged plasma-property profiles (density, field, energy, ionization rate, power) read by the Profile viewers.
| Field | input.nml key | Meaning |
|---|---|---|
| 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. |
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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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.
| Field | input.nml key | Meaning |
|---|---|---|
| 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.
| Field | input.nml key | Meaning |
|---|---|---|
| Reset Time | reset_time |
When ticked, the simulation clock is reset to 0 at the start of the next run while all particle positions and velocities are kept — a way to re-zero time on an existing plasma. |
| 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. |
📚 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:
- Teaching. A set of basic plasma-physics test cases — sheaths, emission-limited diodes, glow discharges, two-stream and Buneman instabilities, striations — lets a student read about a phenomenon, then load the corresponding simulation, run it, and watch it unfold in the viewers. The physical intuition this gives is hard to obtain from a static figure.
- Reproducing the literature. Many cases reproduce the conditions of recently published PIC-MCC studies (Turner's RF benchmarks, the eduPIC reference, Schulze's power-absorption series, Hall-thruster E×B instabilities, and others). Loading one of these and comparing JC-PIC's output with the published figures is the quickest way to both validate the code and understand the original paper from the inside.
- Exploring. Each case is a natural starting point for your own study: load it, then change the pressure, voltage, frequency, magnetic field or geometry in the Conditions dialog and see how the discharge responds. The bundled case fixes a well-understood reference point; the interesting physics is often in how things change around it.
- Contributing. If you build a case you find interesting — a new regime, a clean illustration of an effect, a reproduction of another paper — it can later be folded into the shared library so that other users benefit from it. In that sense the library is a collaborative, openly consultable resource that the user community can grow over time.
How to Load a Case
- Open Input → Load Test Cases…. The case browser opens in a separate window.
- Walk the tree (rubric → sub-rubric → case) and select a case. Its Markdown description appears in the right-hand panel.
- Click Load selected case and choose a working directory.
- JC-PIC copies the case folder —
input.nml, the saved GUI state, and the precomputedsnap/state if any — into that directory and switches to it. Run then continues from the checkpoint insnap/(if present), or starts from t = 0 if you tick Initialization first.
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 a snap/ folder with a precomputed state for an instant quasi-steady comparison. The library can be reorganized from the browser itself (rename, regroup, delete).The Case Library
Rubrics are numbered, which sets their display order. The library is still being filled in: some rubrics are present as headings but not yet populated, and a few cases are placeholders or aliases (pointing to the canonical copy of a case that lives in another rubric). Most cases ship with a precomputed snap/ state, 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.
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–02 — Sheath & potential, equilibrium & diffusion
Two introductory rubrics, Plasma sheath – plasma potential and Plasma equilibrium and diffusion, are reserved in the tree but not yet populated. They are natural homes for the most elementary teaching cases and will be filled in later.
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.
| Case | What it shows | Key parameters |
|---|---|---|
| Vacuum Diode — a plane diode in vacuum (cathode at −V, grounded anode). | ||
| Child–Langmuir | The 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. |
| Virtual Cathode Oscillations | A beam injected above the space-charge limit forms and oscillates a virtual cathode. | Vacuum, V = 50 V, gap 2 cm, beam 50 A/m² at 20 eV. |
| Thermionic Emission | Stable thermionic emission (half-Maxwellian flux with drift), no oscillation. | Vacuum, V = −50 V, gap 2 cm, J = 50 A/m², Te = 3 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 Instability | A 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-Oscillations | The 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.
| Case | What it shows | Key parameters |
|---|---|---|
| Helium Glow Discharge | A DC glow discharge in helium with secondary electron emission. | He ≈1 Torr, gap 4 cm, V = −160 V, γSEE = 0.32. |
| Helium GD Benchmark | A more highly resolved benchmark variant. | He 3.5 Torr, gap 6 mm, V = −211 V, 1024 cells. |
| Supersonic PIII | Plasma-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 PIII | The 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 / case | What it shows | Key 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 1 | Lowest pressure, highest voltage. | He 0.030 Torr (≈4 Pa), VRF = 450 V. |
| Case 2 / 3 / 4 | Increasing pressure, decreasing voltage along the benchmark series. | He 0.10 / 0.30 / 1.0 Torr; VRF = 200 / 150 / 120 V. |
| EduPIC — replicas of the open-source eduPIC reference. Ref: Donkó et al., PSST 30, 095017 (2021). Argon, gap 2.5 cm, 250 V, 13.56 MHz. | ||
| Case 1 / 2 | The unmagnetized argon reference. | Ar 0.075 Torr. |
| Case 3 | The same with a magnetic field added. | Ar 0.075 Torr, B 2→5 mT. |
| 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° / 75° / 60° / 45° | A sweep of the phase angle θ showing how the self-bias and the ion energy at each electrode follow it. | θ = 90°, 75°, 60°, 45°. |
| 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 Pa | Four 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 through frequency and voltage. Ref: Sharma et al., Phys. Plasmas 25, 080705 (2018). Argon 0.0075 Torr, gap 3.2 cm. | ||
| 60 MHz / 100 MHz | Two driving frequencies at the matching voltage. | 54.7 V @ 60 MHz; 23.2 V @ 100 MHz. |
| Magnetized — RF discharge with an asymmetric magnetic-field profile (left→right). Ref: Yang et al. (2017). Argon 0.03 Torr, gap 2.5 cm, 150 V, Bright = 100 G. | ||
| 0–100 / 10–100 / 30–100 / 50–100 G | A sweep of the field at the left electrode, from 0 to 50 G. | Bleft = 0, 10, 30, 50 G. |
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 / case | What it shows | Key parameters |
|---|---|---|
| Striations — axial ionization waves. Refs: Boeuf, Phys. Plasmas 29, 022105 (2022); Dosbolayev et al., Phys. Plasmas 31, 073509 (2024). | ||
| DC Periodic | A 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 bounded | Standing 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 — radial non-equilibrium / non-local transport. Ref: Nakamura & Ingold, J. Phys. D 34, 3150 (2001). Cases 1 and 2 are placeholders (headings only), to be built. | ||
| 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 G | A field sweep showing the onset of the Hall field and the E×B drift. | B = 0, 50, 100, 150 G. |
08 — Magnetized Plasma
A Hall-thruster-style azimuthal (E×B) configuration exhibiting the electron-cyclotron drift instability.
| Case | What it shows | Key parameters |
|---|---|---|
| Hall Thruster – E×B Instability (and two variants) | A collisionless azimuthal E×B simulation developing the E×B (electron-cyclotron drift) instability; the variants differ in domain length. | Xe, periodic, collisionless, B = 200 G, gap 1 cm (variant: 2.67 cm). |
10 — Plasma Instabilities
Kinetic beam-driven instabilities in their cleanest, periodic form.
| Case | What it shows | Key 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. |
| Buneman Instability | The 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-Stream | Two 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). | ||
| ECDI – Hall thrusters — reserved heading, not yet populated. | ||
🖱️ 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 OK.
The panel groups its controls into rows. The exact set depends on the viewer, but the recurring ones are:
| Control | What it does |
|---|---|
| min / max / step | The range and tick spacing of each axis. Type a number, or leave auto for automatic scaling. |
| Log + dec | Switch an axis to a logarithmic scale; dec sets how many decades are shown. |
| Auto / Fix | Auto returns every range to automatic; Fix freezes the current ranges as fixed numbers. |
| Grid | Toggles the background grid. |
| Labels: Full / No titles / Bare | How 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. |
| Colours | A swatch per curve opens a colour picker; 2D viewers instead offer a colour-map picker and a Flip button. |
| Rst Pos / Rst All | Rst 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.
- Move a title or an axis label — left-click it and drag. If you drag a title past the edge of the window, the window grows to keep it visible while the plot keeps its size and screen position.
- Resize the plot area — left-click and drag any edge of the plot (within a few pixels of it) to change its margins.
- Adjust tick spacing — drag the tick numbers to move them away from, or closer to, the axis.
- 2D viewers — the colour bar can be dragged to reposition and resize it, and its tick labels and ×10ⁿ offset are draggable too.
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.
- Create — double-click an empty spot in the plot. A small dialog lets you type the text, choose its size, bold/italic and colour. Mathematical notation written in LaTeX between dollar signs is rendered, e.g.
$n_e$,$10^{15}$or$\varepsilon$. - Edit or delete — double-click an existing label to reopen the dialog (with a Delete button).
- Move — left-click and drag the label.
- Restyle a title — double-click a title to change its text, size, bold/italic and colour; double-click the tick numbers to change their size.
Text labels are saved with the viewer and reappear the next time it is opened.
Saving, exporting and recording
- Save — the Save button writes the current figure to PNG, PDF or SVG. Ctrl+C copies it to the clipboard where supported.
- Export data — where a viewer offers an Export button (the Profile, Heating and EEPF viewers, and the 1D slice popups of the X-T and EEPF-2D viewers), it writes the plotted data as a multi-column ASCII/CSV table for use in other tools.
- Record an animation — the Profile and Phase Space viewers can record the live plot to an animated GIF or an MP4 (MP4 needs
ffmpegon the system PATH). The Record dialog has two rates: Capture FPS — how often a frame is grabbed (e.g. 0.1 grabs one frame every 10 s, for slowly evolving runs) — and Playback FPS, the speed of the saved file. Setting capture below playback makes a sped-up movie; equal rates give real time. Click Start, let the run evolve, then Stop & Save and choose where to write the file.
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 list. Every open viewer appears as a row; the ✕ at the end of a row closes that viewer. Its window size and position are remembered, so it reopens where you left it.
- Tile / Cascade. Tile lays the open viewers out side by side without overlap; Cascade stacks them with a fixed diagonal offset. Both bring the windows to a common size.
- Move and resize them together. The pad at the bottom of the panel acts on every viewer at once — drag it to shift all the viewers by the same amount, and scroll on it to grow or shrink them all in step.
- Viewers follow the main window. With this box ticked, moving the main window carries every viewer with it, so the whole arrangement travels as a block — handy on a multi-monitor desktop; unticked, the viewers stay put.
📈 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 any of six pre-selected combinations of physical quantities. Six instances are available, one 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.
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 entry | Mode | Left axis | Right axis |
|---|---|---|---|
| Densities & Field | field | ne, ni | Electric field E(x) |
| Densities & Potential | potential | ne, ni | Potential Φ(x) |
| Densities & Energy | energy | ne, ni | Mean electron energy ε(x) |
| Energy & Ionization | ioniz | Mean electron energy ε(x) | Ionization rate Si(x) |
| Power Absorbed | power | Electron power Pe(x) | Ion power Pi(x) |
| Energy & νioniz | nuioniz | Mean electron energy ε(x) | Ionization frequency νi(x) |
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:
| Control | What it does |
|---|---|
| Avg | Show the time-averaged profile (default) or, unchecked, the instantaneous profile of the latest snapshot. |
| Rst Avg | Discard 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 axis | The left axis (densities) and the right axis (the accompanying quantity) each have their own independent log scale and decade count. |
| Time | Overlays the current simulation time in a corner of the plot (draggable and editable, like any label). |
| → All 1D | Propagate the look (axis ranges, colours, line width, font, label mode…) to all six profile viewers at once. |
| Export | Write 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. |
| ● Rec | Record the live plot to an animated GIF or MP4 — see Working with Viewers → Saving, exporting and recording. |
🌊 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.
What can be plotted
The X-T viewer supports twelve quantities. Six are the standard "primary" diagnostics, available as long as the X-T accumulator is enabled in the Conditions dialog; the other six 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.
| Group | Menu entry | Symbol | Unit |
|---|---|---|---|
| Primary | Electron Density | ne | m−3 |
| Ion Density | ni | m−3 | |
| Electric Field | E(x, t) | V/m | |
| Mean Electron Energy | ⟨εe⟩ | eV | |
| Ionization Rate | Siz | m−3 s−1 | |
| Electron Power | Pe | W/m3 | |
| Schulze | Ptot | Total electron power | W/m3 |
| Pohm | Ohmic component | W/m3 | |
| Ppress | Total pressure component | W/m3 | |
| Ppress,T | Pressure (temperature term) | W/m3 | |
| Ppress,n | Pressure (density term) | W/m3 | |
| Pin | Inertial component | W/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.
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. Being a 2D colour map, the X-T panel adds:
| Control | What it does |
|---|---|
| Cmap / Flip | A 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 / dtick | Show or hide the colour bar and set its tick spacing. |
| z min / z max, Log, dec | The 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 / > zmax | Two swatches set the colour given to values below / above the scale (the "under" / "over" colours); right-click a swatch to clear it. |
| Contour | Overlay iso-value contour lines — an automatic count N or an explicit list of levels, with a chosen colour and width. |
| smooth | A Gaussian spatial smoothing (sigma) applied before display — useful for noisy quantities such as the ionization rate at low statistics. 0 = none. |
| Transpose | Swap the x and t axes. |
| → All XT | Apply the current look (colour map, scale, contour, smoothing, fonts…) to every open X-T viewer at once — for a consistent multi-quantity figure. |
| Export | Write the full x–t matrix as an ASCII grid (Origin-compatible) for external analysis. |
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.
- Probe — left-click and drag on the map. A white crosshair follows the cursor and a small box reports the (x, t, value) underneath it. Best for reading off a single value or tracing a feature by eye; releasing the mouse hides the crosshair.
- 1D slice — right-click on the map. A popup opens showing the quantity's profile versus x at the clicked time; a dashed line on the map marks the slice, and holding and dragging the cursor re-slices in real time. The popup is itself a small 1D viewer, with its own ⚙ panel (axis ranges, log, label mode, fonts, Plot Size), draggable text labels, and an Export button.
- Colour bar — right-click to cycle palettes (top third → next map, bottom third → previous, middle → flip), or drag it to reposition and resize it.
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.
🌀 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.
What can be plotted
| Menu entry | Mode | Distribution | What it shows |
|---|---|---|---|
| Electrons f(x, vx) | e_xvx | fe(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_xvx | fi(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_xeps | fe(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_xeps | fi(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:
| Control | What it does |
|---|---|
| Avg | Show the instantaneous distribution (latest frame) or the time-averaged accumulator. |
| Rst Avg | Discard 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 / Cbar | The visual colour-map picker (standard and custom palettes), map reversal, and colour-bar on/off. |
| z min / z max, Log, dec | The colour-scale range and an optional logarithmic scale with its decade count. |
| vx max / ε max | The 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 / Smooth | Iso-density contour lines (count, colour, width) and an optional Gaussian smoothing of the map. |
| vx=0 axis colour | A swatch sets the colour of the reference line drawn at vx = 0 (in the velocity modes). |
| Time | Overlays the current simulation time in a corner of the plot (draggable, like any label). |
| → All PS | Apply the current look to all four phase-space viewers at once. |
| ● Rec | Record 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.
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:
| Control | What 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 avg | Replace the per-position curves with a single gap-averaged EEPF. |
| ε max, f min, f max | The 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. |
| Legend | A draggable legend listing each curve by its real x value, colour-matched to the lines; toggle on/off. |
| Export | Write the data as an ASCII table — an energy column plus one f_x…cm column per position. |
| → All 1D | Propagate the style (fonts, line width, label mode, ranges) to the other 1D viewers. |
🗺️ 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, ε).
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:
| Control | What it does |
|---|---|
| Normalization | Choose between the normalized f(ε,x) and f(ε,x) × ne(x). |
| Cmap / Flip / Colorbar / dtick | The visual colour-map picker (standard and custom palettes), map reversal, colour-bar on/off and tick spacing. |
| z min / z max, Log, dec | The colour-scale range and decade count; the scale is logarithmic by default, since the EEPF spans many orders of magnitude. |
| < zmin / > zmax | Out-of-range "under" / "over" colours; right-click a swatch to clear it. |
| ε max | The upper bound of the energy axis. |
| Contour / smooth / Transpose | Iso-value contour lines, a Gaussian smoothing of the map, and swapping the x and ε axes. |
| Export | Write the full x–ε grid as an ASCII file. |
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.
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:
| Control | What 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 F | Switch 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/dF | The energy and probability axis ranges and tick spacings. |
| Legend | Toggle the "Left" / "Right" legend. |
ifedf.bin using the format documented at the top of ifedf_viewer.py.⚡ 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-Voltage — Total current & Voltage for the standard view, or Charged particle currents for the per-species (per-wall) view.
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:
| Configuration | Left axis | Right axis | Time 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.
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:
| Control | What it does |
|---|---|
| t / V / J ranges | Independent 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. |
| V / j colours | A 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. |
cur.bin using the format documented at the top of cur_viewer.py. The accumulator state survives restarts (the cur_accum.bin trailer), so a paused or resumed run keeps its running averages.🔥 Heating Viewer
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
| Curve | Mechanism |
|---|---|
| Ptot | The total absorbed power, ⟨Je·E⟩ — the same quantity as the Profile viewer's electron power. |
| Pohm | Ohmic (collisional) heating, me⟨ne νm vx²⟩ — dominant in the bulk. |
| Ppress | The pressure-heating term (the sum of the two below) — dominant near the sheath edges, where it captures the "stochastic" / pressure-driven heating. |
| Ppress,T | The temperature-gradient part of the pressure term, ⟨ve ne e ∂Te/∂x⟩. |
| Ppress,n | The density-gradient part, ⟨ve e Te ∂ne/∂x⟩. |
| Pinert | The 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.
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:
| Control | What it does |
|---|---|
| Curves | A 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. |
| Legend | A 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. |
| Log | A 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³). |
🕰️ 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 entry | Window | Quantities |
|---|---|---|
| Particle History | Standalone viewer (separate window with floating settings panel) | Ne(t), Ni(t) — total super-particle counts of each species |
| Energy History | Standalone viewer — see the Energy Viewer chapter | ⟨ε⟩e(t), ⟨ε⟩i(t), total kinetic energy and field energy |
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 just the time and particle-count axis ranges and a colour swatch for each of the two curves (Ne, Ni). The count axis is always linear, which keeps the steady-state portion legible even for runs that span orders of magnitude in N.
⚖️ 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.
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 10−n J/m² with an automatic decade scaling.
| Curve | Symbol | Axis | Definition |
|---|---|---|---|
| ⟨ε⟩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 + eki)·w | 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.
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:
| Control | What it does |
|---|---|
| Show ⟨ε⟩e / ⟨ε⟩i / KE / U | A 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 ranges | Independent 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. |
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.
| Observation | Interpretation |
|---|---|
| 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. |
🎯 Cross-Section Viewer
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
| Control | What it does |
|---|---|
| Electrons / Ions | A toggle switching between the electron–neutral and ion–neutral data sets. |
| Gas | A 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, Legend | The usual axis ranges, grid and legend toggle, plus the title and text dragging common to all viewers (see Working with Viewers). |
📋 Params Viewer
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 and no settings panel; it is a passive monitor, the quickest way to confirm that a run is well resolved. It is opened from the Parameters menu.
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. The cyclotron line is hidden when there is no magnetic field, and the RF line when there is no RF source.
🎨 Palette Editor
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. The upper one lists the built-in matplotlib palettes as gradient bars; clicking a bar opens it in the curve editor. When the optional scikit-image package is available, each bar is split in two — click the left half to edit in RGB, the right half to edit in CIELAB (a perceptually uniform space). 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.
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; Points −/+ changes how many there are, and 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.
custom_palettes.json automatically), then open the viewer's colour-map picker (the Cmap button) and pick it from the Custom section.▶️ 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 action | Resulting mode | Effect |
|---|---|---|
| Init checked + Run | Fresh Start | Everything reset to t = 0; checkpoint, history.dat and accumulators wiped. |
| Init unchecked + Run (run had ended/closed) | Continue | Restart from the checkpoint; history and running averages preserved. |
| Pause, then Run | Resume | Pick 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.
💾 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.
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.
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.
🗂️ 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)
| File | Contents / viewer |
|---|---|
history.dat | The 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_*.bin | The 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.bin | The phase-space histograms f(x,vx) and f(x,ε), live and time-averaged. Read by the Phase Space viewer. |
xt_diag.bin, xt_accum.bin | The position–time matrices (and the moment data for the Schulze power decomposition). Read by the X-T and Heating viewers. |
eepf.bin | The electron energy probability function, bulk and position-resolved. Read by the EEPF and EEPF-2D viewers. |
ifedf.bin | The ion flux–energy distribution at each electrode. Read by the IFEDF viewer. |
cur.bin, cur_accum.bin | The discharge current and applied voltage waveforms. Read by the Currents viewer. |
status.bin, runbar.bin | The live plasma parameters (for the Params viewer) and the main-window progress bar. |
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. You never edit these by hand.
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.
live_reader.py, phase_reader.py), so the data can be read by any external tool. 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.🧪 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.
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.
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.
| Constraint | Condition | What it sets |
|---|---|---|
| Spatial | Δx ≲ λD | Cell size; drives the cell count. |
| Temporal | ωpe Δt ≲ 0.2 | Time step; drives the wall-clock cost. |
| Statistical | Ncell ≳ 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.
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:
| # | Operation | Formula |
|---|---|---|
| 1 | Half electric kick | v− = vn + (q/m) E (Δt/2) |
| 2 | Rotation vector | t = (q/m) B (Δt/2) |
| 3 | Scaled vector | s = 2t / (1 + |t|²) |
| 4 | First cross product | v' = v− + v− × t |
| 5 | Second cross product | v+ = v− + v' × s |
| 6 | Half electric kick | vn+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).
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:
- Solvability. A singular system has a solution only if the right-hand side has no component along the null space, i.e. only if the total charge is neutral, Σk ρk = 0. The solver therefore subtracts the mean charge density before solving — physically, the periodic column must be globally neutral, and any small numerical imbalance is removed rather than allowed to drive an unphysical field.
- Gauge. The leftover constant (the undetermined potential offset) is fixed by a simple gauge, setting φ to zero at one reference point. This has no effect on the physics since only ∇φ enters the equations of motion.
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.
| Criterion | Candidate Δt | Coefficient | Origin |
|---|---|---|---|
| Plasma frequency | Δtωpe = cflωpe / ωpemax | cfl_wpe ≈ 0.2 | Resolves the fastest plasma oscillation with small phase error. |
| Cyclotron frequency | Δtωce = cflωce / ωcemax | cfl_wce | Resolves the gyration when a magnetic field is present (skipped if B = 0). |
| Collisions | Δtcol = −ln(1 − cflcol) / νnull | cfl_col | Keeps the per-step collision probability below cflcol — at most ≈ one collision per particle per step. |
| Driving period | Δtrf = Trf / 50 | fixed (÷50) | Resolves the RF / heating waveform (and its second harmonic in dual-frequency runs). |
| Courant (CFL) | Δtcfl = cflcou Δx / vmax | cfl_cou | Computed and displayed, but not binding — see below. |
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 / vmax is computed and reported in the Params viewer, but by design it does not drive the time step in JC-PIC. The reason is practical: vmax is set by a handful of runaway tail electrons, so binding Δt to it would shrink the step far below what the bulk dynamics needs and slow the run for no physical benefit. PIC is more forgiving than a fluid code here — particles may cross several cells per step at only a modest cost in the accuracy of the moment estimates. The user is, of course, free to keep an eye on the displayed value.
Fixed vs. adaptive Δt
Two modes are available, selected by dt_mode in the Parameters dialog:
- Fixed (
dt_mode= 0): Δt is frozen atdt_maxfor the whole run. The CFL machinery is short-circuited. This is the appropriate choice for benchmarks that prescribe a fixed step. - Adaptive (
dt_mode= 1, the default): Δt tracks the most restrictive of the criteria above, always clamped to the user-set interval [dt_min,dt_max]. Changes are smoothed in time (the step relaxes toward its target over a user-set time constant rather than jumping), which damps the feedback between Δt and the diagnostics. A severe violation — a sudden density spike or a runaway that more than halves the allowable step — bypasses the smoothing and drops Δt immediately.
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.
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).
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:
| Profile | Shape on [x1, x2] | Typical use |
|---|---|---|
| Uniform | constant | Default; benchmarks, quick starts. |
| Cosine | cos peaking at the centre, vanishing at x1 and x2 | A more physical bell-shaped column that relaxes faster to steady state. |
| From file | tabulated 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.
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:
- Partial beam. A fraction p of the electrons in each cell is made monoenergetic at the drift energy, with all the kinetic energy along +x (vy = vz = 0); the remaining 1 − p stay Maxwellian. This superposes a cold beam on a warm background.
- Drifting Maxwellian. With the beam fraction at zero but a non-zero drift energy, the whole electron Maxwellian is shifted by +vd = +√(2Edrift/me) along x.
- Two-stream. With the two-stream flag on, the population is split into two equal halves drifting at +vd and −vd — the classic symmetric two-stream setup. Ions are never given a drift.
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:
| Mode | vx (into the gap) | vy, vz | Models |
|---|---|---|---|
| Beam | vdrift + 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 source | drawn from the flux-weighted drifting Maxwellian Γ(v) ∝ v exp[−(v − vdrift)²/2vth²], v > 0, by exact inverse-CDF sampling | full Maxwellians at Te | Effusion 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.
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.
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 would require an entirely different treatment and which are negligible at the 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. 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.
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.
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.
| Species | Channel | Effect 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. |
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 for electron elastic and inelastic scattering and for ion elastic scattering alike. The two relevant frames are treated differently:
- Electrons. Because the electron is so much lighter than the neutral, the centre-of-mass essentially coincides with the neutral at rest, and the deflection is applied directly to the electron velocity. For an elastic event the speed is reduced by the small recoil fraction before the rotation: ε' = ε [1 − (2me/M)(1 − cos χ)], which is the standard energy-transfer factor for a light projectile on a heavy target. For excitation, the threshold energy is subtracted and the slowed electron is scattered isotropically.
- Ions. Ion–neutral collisions are done properly in the centre-of-mass frame. A neutral target is drawn from a Maxwellian at the gas temperature, the relative velocity g = vion − vneutral and the CM velocity w are formed, the collision energy is εc = ¼M g² (reduced mass M/2 for equal masses), and the post-collision velocity is reconstructed as w ± ½g. For elastic scattering the magnitude of g is preserved and only its direction is rotated isotropically. For charge exchange the outgoing ion is given the velocity of the (cold) neutral — the resonant, near-head-on limit appropriate for noble gases — which is what makes charge exchange the dominant brake on ion transport and the shaper of the IFEDF.
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:
| Mode | Energy partition | Angles |
|---|---|---|
| Equal | ε1 = ε2 = (ε − εiz)/2 | both isotropic |
| OPB + isotropic | ε1 drawn from the Opal–Peterson–Beaty distribution, ε1 = w tan[R arctan((ε − εiz)/2w)], with the gas-specific width w | both isotropic |
| OPB + correlated (Donkó) | OPB partition as above | primary 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.
Cross-section data (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.
To be completed: where the files live (the DATA/ folder of the distribution), the gases currently provided (argon, helium, …), and the data source / reference behind each set (e.g. the LXCat databases) — without endorsing a specific dataset.
File format
To be completed: the column layout (an energy grid in eV, then one cross-section column per channel — elastic / excitation / ionization for electrons, elastic / charge exchange for ions), the units of the cross sections (m² vs cm²), the header lines, the threshold energies, and how values are interpolated between grid points and extrapolated beyond the tabulated range.
Adding a gas or your own cross sections
To be completed: how to drop in a new data file, the expected file name and location, how a gas is registered so it appears in the Conditions dialog, and the consistency checks that matter (a monotonic energy grid, thresholds aligned with the excitation/ionization columns, consistent units).
↩️ 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:
- σ0: the yield extrapolated to zero impact energy — the low-energy electron-reflection coefficient. If σ0 = 0.3, then 30 % of slow electrons hitting the wall are reflected back into the plasma and 70 % are absorbed.
- ε*: the impact energy at which the yield reaches unity. It sets how fast γ1 rises with energy: a small ε* means even moderately energetic electrons start producing true secondaries. Setting ε* = 0 removes the energy-dependent rise and uses σ0 as a constant yield.
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:
- γ1 < 1 (the usual low-energy case): the incident electron is specularly reflected with probability γ1, keeping its full energy and simply reversing its normal velocity component; with probability 1 − γ1 it is absorbed. No new, cold electron is created in this regime — the returning electron is the original, at its full impact energy.
- γ1 ≥ 1 (high impact energy): the primary is always reflected, and γ1 − 1 genuine secondary electrons (rounded statistically) are emitted from the wall. These secondaries are the only electrons launched cold: their velocity is drawn from a flux-weighted half-Maxwellian at the wall-electron temperature (
te_see_elec, fractions of an eV), directed away from the surface.
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.
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.
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/.
🔧 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.
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.
📄 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.
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
| Key | Type | Default | Meaning |
|---|---|---|---|
nthreads | int | 0 | OpenMP threads (0 = auto-detect). |
gas | string | 'Ar' | Working neutral gas. |
pressure | real | 0.5 | Neutral pressure (torr). |
gas_temp | real | 300 | Neutral gas temperature (K). |
gap | real | 0.02 | Electrode gap / domain length L (m). |
ngrid | int | 512 | Number of grid cells (max ng_max = 4096). |
auto_adapt_ngrid | flag | 0 | Auto-double ngrid to keep the Debye length resolved. |
mass_ratio_override | real | 0.0 | Ion/electron mass ratio override (0 = use the cross-section file value). |
Initial
| Key | Type | Default | Meaning |
|---|---|---|---|
density0 | real | 1e14 | Peak initial plasma density (m−3), ne = ni. |
te_init | real | 2.0 | Initial electron temperature (eV). |
ti_init | real | 0.026 | Initial ion temperature (eV). |
x1_profile, x2_profile | real | 0.0, 1.0 | Density-profile interval (fraction of gap). |
profile_type | int | 0 | 0 uniform · 1 cosine · 2 external file. |
init_file_name_in | string | 'init.inp' | External density-profile file (profile_type 2). |
drift_energy | real | 0.0 | Electron drift / beam energy (eV). |
beam_fraction | real | 0.0 | Monoenergetic beam fraction (%). |
two_stream | flag | 0 | Seed two counter-streaming Maxwellians. |
npart | int | 80 | Initial super-particles per cell (total = npart×ngrid). |
npart_trigger | int | 1600000 | Thinning threshold (Max #); hard cap np_max = 2×106. |
thin_remove | real | 0.20 | Fraction removed per thinning event. |
npart_min | int | 0 | Auto-split threshold (Min #; 0 = disabled). |
Boundaries — injection, sources, secondary emission
| Key | Type | Default | Meaning |
|---|---|---|---|
einj_left_mode | int | 0 | Cathode electron injection: 0 off · 1 constant current · 3 virtual z length. |
einj_jcurr | real | 0.0 | Injected current density (A/m²). |
einj_vdist | int | 0 | 0 beam (drift+spread) · 1 thermal source (flux). |
einj_te | real | 0.0 | Injection temperature / spread (eV). |
einj_eparr | real | 0.0 | Injected directed energy (eV). |
einj_vlen | real | 0.01 | Virtual perpendicular length (m, mode 3). |
ext_src_mode | int | 0 | External source: 0 off · 1 constant · 2 re-injection on loss. |
ext_jsrc | real | 0.0 | Source current density (A/m²). |
ext_pct_ions_in | real | 100 | Percentage of injected ions. |
reinj_trig | int | 0 | Re-injection trigger: 0 ion loss · 1 electron loss. |
ext_x1_in, ext_x2_in | real | 0.0, 1.0 | Source interval (fraction of gap). |
ext_prof_type | int | 0 | Source profile: 0 uniform · 1 cosine · 2 file. |
ext_te_in, ext_ti_in | real | 2.0, 0.5 | Injected electron / ion temperatures (eV). |
see_sigma0_in | real | 0.0 | Electron-impact SEE yield σ₀. |
see_epsstar_in | real | 0.0 | Electron-impact SEE characteristic energy ε* (eV). |
te_see_elec_in | real | 2.0 | Temperature of electron-impact secondaries (eV). |
see_elec_left_in, see_elec_right_in | flag | 0 | Enable electron-impact SEE per wall. |
gamma_left, gamma_right | real | 0.0 | Ion-impact SEE yield per electrode. |
tsee_left, tsee_right | real | 2.0 | Temperature of ion-impact secondaries (eV). |
Voltage / heating & external circuit
| Key | Type | Default | Meaning |
|---|---|---|---|
voltage | real | −300 | DC voltage VDC (V). |
voltage_rf, freq_mhz | real | 0.0, 13.56 | First RF amplitude (V) and frequency (MHz). |
voltage_rf2, freq_mhz2 | real | 0.0, 0.0 | Second RF amplitude (V) and frequency (MHz). |
theta_deg | real | 0.0 | Phase of the first RF component (°). |
vprofile | int | 0 | Drive: 0 formula · 1 external file. |
vfile_name_in | string | 'voltage.inp' | External V(t) waveform file. |
vfile_loop | flag | 0 | Loop the waveform file periodically. |
periodic_bc | flag | 0 | Periodic boundaries (no electrodes, current-driven). |
right_bc_type | int | 0 | Right wall: 0 grounded V = 0 · 1 insulated E = 0. |
series_cap | real | 0.0 | Series capacitance (nF/m²). |
series_res | real | 0.0 | Series resistance (Ω·m²). |
bias_cap | real | 0.0 | DC self-bias blocking capacitor CI (nF/m²; 0 = off). |
n_avg_bias_in | int | 1 | RF periods averaged per self-bias update. |
heating_type | int | 0 | 0 none · 1 DC/RF field · 2 absorbed power · 3 thermalization. |
heating_field | real | 0.0 | Field (V/m) or absorbed power (W/m²). |
heating_freq | real | 0.0 | Heating frequency (MHz). |
heating_dir | int | 0 | Direction: 0 parallel (x) · 1 perpendicular (z). |
heating_self_adjust | flag | 0 | Self-adjust Ez (radial positive column). |
heating_temp | real | 0.0 | Thermalization target temperature (eV). |
heating_x1, heating_x2 | real | 0.0, 1.0 | Heating interval (fraction of gap). |
B Field
| Key | Type | Default | Meaning |
|---|---|---|---|
btype | int | 0 | 0 off · 1 perpendicular Y · 2 perpendicular Z · 3 parallel X. |
bprofile | int | 0 | 0 Gaussian · 1 external file (BField.inp). |
ion_unmag | flag | 0 | Leave the ions unmagnetized (electrons only). |
bmag | real | 0.01 | Peak field Bmax (tesla). |
bleft, bright | real | = bmag | Field at the left / right wall (tesla). |
bsigma1, bsigma2 | real | 0.2 | Left / right Gaussian widths (fraction of gap; 0 = linear ramp). |
bcenter | real | 0.5 | Position of the peak (fraction of gap). |
Special
| Key | Type | Default | Meaning |
|---|---|---|---|
energy_share_type | int | 0 | Ionization energy sharing: 0 constant ratio · 1 Vahedi (reserved). |
energy_share_r | real | 0.5 | Ejected-electron energy fraction r. |
energy_share_w | real | 10.0 | Vahedi w parameter (eV; reserved). |
loss_freq_elec, loss_freq_ion | real | 0.0 | Artificial particle-loss frequencies (MHz). |
loss_x1, loss_x2 | real | 0.0, 1.0 | Loss interval (fraction of gap). |
ioniz_mode | int | 0 | 0 normal · 1 as excitation · 2 balanced by uniform losses. |
anom_freq | real | 0.0 | Anomalous electron collision frequency (MHz). |
anom_x1, anom_x2 | real | 0.0, 1.0 | Anomalous-collision interval (fraction of gap). |
anom_profile | int | 0 | 0 uniform · 1 cosine · 2 parabolic. |
coulomb_factor | real | 0.0 | Electron–electron Coulomb collision scale (0 = off). |
Control
| Key | Type | Default | Meaning |
|---|---|---|---|
istart_mode | int | 0 | 0 continue from checkpoint · 1 fresh start (Initialization). |
end_time_us | real | 0.0 | Stop time (µs). |
dt_mode | int | 1 | Time step: 0 user-fixed · 1 code-adaptive. |
dtmax | real | 1e-10 | Fixed (user) or maximum (code) time step (s). |
dt_smooth_us | real | 1.0 | Relaxation time for the adaptive dt (µs). |
nsmooth | int | 0 | Binomial smoothing passes on ne, ni (0–10). |
nsub_ion | int | 20 | Ion subcycling factor (ions pushed every N steps). |
part_factor | real | 1.0 | One-off particle-count rescaling at run start. |
reset_time | flag | 0 | Reset the clock to 0 at the next run, keeping particles. |
Diagnostics
| Key | Type | Default | Meaning |
|---|---|---|---|
avg_enable | flag | 1 | Time-averaged profile accumulation. |
diag_start_time | real | 0.0 | Time after which averaging starts (µs). |
avg_interval, avg_unit | real, int | 500, 0 | Accumulation cadence; unit 0 steps · 1 ns. |
diag_avg_time | real | 1.0 | EMA time constant (µs; 0 = flat average). |
heating_diag | flag | 0 | Electron heating (Schulze power) decomposition. |
xt_enable | flag | 0 | Position–time (x,t) diagnostics. |
xt_start | real | 0.0 | (x,t) start time (µs). |
xt_nx, xt_nt | int | 50, 100 | (x,t) spatial (≤511) and time/phase (≤512) bins. |
xt_mode | int | 1 | 0 periodic (phase-averaged) · 1 transient (sliding window). |
xt_ncycles | int | 1 | RF cycles averaged (periodic mode). |
xt_window | real | 1000 | Sliding window (µs, transient mode). |
edf_enable | flag | 0 | EEPF and IFEDF accumulation. |
edf_start | real | 0.0 | EEPF/IFEDF start time (µs). |
edf_emax_val, edf_nbins | real, int | 100, 200 | EEPF max energy (eV) and energy bins. |
edf_nxbins | int | 50 | EEPF spatial slices (EEPF-2D). |
ifedf_emax, ifedf_nbins | real, int | 200, 200 | IFEDF max energy (eV) and bins. |
edf_tavg_enable, edf_tavg_interval, edf_tavg_unit | flag, real, int | 0, 1.0, 0 | EEPF/IFEDF time integration on/off, cadence, unit (0 ns · 1 step). |
edf_tmin, edf_avg_window | real | 0.0 | Fixed-start time vs sliding window (µs); only one is non-zero. |
nx_phase_in, nv_phase_in | int | 128 | Phase-space histogram resolution (clamped 16–256). |
cur_enable | flag | 0 | Total-current jT(t) diagnostic. |
cur_start, cur_nt | real, int | 0.0, 500 | Current start time (µs) and number of time points. |
cur_mode, cur_ncycles, cur_window | int, int, real | 0, 10, 1000 | 0 periodic / 1 transient; cycles averaged; window (µs). |
ndiagnostic | int | 1000 | history.dat write interval (steps). |
ncheckpoint | int | 5000 | Checkpoint interval (steps). |
nsnapshot | int | 500 | Snapshot / (x,t) / EEPF accumulation interval (steps). |
nbar | int | 10 | Run-bar refresh and stop/pause poll interval (steps). |
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.
| Key | Type | Default | Meaning |
|---|---|---|---|
dt_start, dtmin | real | 1e-10, 1e-13 | Initial and minimum time step (s). |
cfl_plasma, cfl_cyclo, cfl_courant, cfl_collision | real | 0.20, 0.20, 0.50, 0.10 | Safety factors of the four CFL constraints on the adaptive dt. |
dt_change_max | real | 2.0 | Maximum dt change ratio between steps. |
ndt_chk | int | 200 | Interval at which dt is re-evaluated (steps). |
icoll_elastic, icoll_exc, icoll_ion, icoll_ions | flag | 1 | Enable each collision channel (electron elastic / excitation / ionization; ion collisions). |
thin_method | int | 1 | Thinning method (0 random · 1 regular stride). |
auto_adapt_nu_null | flag | 0 | Adapt the MCC null-collision rate to the actual maximum energy. |
vmax_smooth | real | 1.0 | Smoothing factor for the velocity bound used by the collision rate. |
rise_time | real | 0.0 | Rise time of the applied voltage (s; pulsed cases). |
ion_xsec_approx, ion_sigma_elastic, ion_sigma_backward | int, real, real | 0, 1e-19, 1e-19 | Use constant approximate ion cross sections (m²) instead of a table. |
ntmax | int | 0 | Hard cap on the number of steps (0 = unlimited; end_time_us is the normal stop). |
nthreads, data_dir, snapshot_dir | int, string, string | 0, (set by GUI), 'snap' | Threads, cross-section data folder, and output subfolder (the GUI sets these). |
swarm_mode, swarm_en_td | int, real | 0, 0.0 | Swarm (Townsend) mode and its E/N (not yet fully exposed in the GUI). |
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.📖 Glossary
A quick reference for the acronyms and physics terms used throughout this manual and in the JC-PIC interface.
| Term | Meaning |
|---|---|
| 1D3V | One 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 criterion | The 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 pusher | The standard leapfrog scheme that advances particle velocities, splitting the magnetic rotation from the two half electric kicks; the rotation is exactly energy-conserving. |
| CCP | Capacitively Coupled Plasma — a discharge driven by an RF voltage applied across two electrodes through the sheath capacitance. |
| CFL number | Courant–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. |
| EEDF / EEPF | Electron 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. |
| ICP | Inductively Coupled Plasma — a discharge sustained by an induced RF field. Mentioned for comparison; not driven directly by JC-PIC. |
| IFEDF | Ion Flux–Energy Distribution Function: the energy distribution of the ions arriving at a wall. |
| Macro-particle weight | The 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. |
| MCC | Monte 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 method | An 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. |
| PIC | Particle-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 column | The quasi-neutral, field-aligned body of a long DC or RF discharge, modelled here in periodic mode; the home of striations. |
| Pre-sheath | The weak-field region ahead of a sheath where ions are accelerated up to the Bohm speed. |
| SEE | Secondary Electron Emission — the release of electrons from a wall under ion or electron impact, set by user-controlled coefficients. |
| Self-bias | The DC potential that builds up on a capacitively-coupled electrode of an asymmetric or dual-frequency discharge. |
| Sheath | The thin, non-neutral, high-field layer that forms between a plasma and a wall or electrode. |
| Snapshot | A 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. |
| Striations | Standing or moving axial ionization waves in a positive column. |
| Super-particle | A computational particle representing many real electrons or ions (see macro-particle weight); the basic unit pushed by the PIC scheme. |
| Two-stream / Buneman | Kinetic instabilities driven by the relative drift of charged-particle populations; classic PIC benchmark cases. |
| Working directory | The 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. |
❓ 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…