Skip to content
Development documentation — This site follows the main branch and may differ from an installed release. View the changelog.

Case Design Workflow

This page turns the tested official tutorial into a research case: choose geometry, sources, and boundaries, then set time steps and particle sampling to obtain comparable results. Look up types, defaults, and combination constraints in the input parameter reference.

Starting point: Complete the 10-minute tutorial. In the working directory that contains beach.toml and outputs/tutorial, copy the baseline configuration.

Terminal window
cp beach.toml case.toml
beachx lint case.toml

Change one decision at a time and rerun beachx lint case.toml after every change. Keep the tutorial output as the baseline; step 8 assigns a different output directory to the new case.

1. Define the purpose and acceptance criteria

Section titled “1. Define the purpose and acceptance criteria”

Before editing the configuration, write down one sentence for each of these questions:

  • Which particles arrive from which environment, and which surface do they reach?
  • Is the quantity of interest charge, potential, absorption, escape, or runtime?
  • Which conservation check, reference solution, or convergence tolerance must the result pass?

The official tutorial is a teaching case for inter-batch charging feedback. Its particle weight and batch_duration=0 do not describe the time evolution of a particular physical environment. Defining acceptance criteria first limits mesh resolution, particle count, and solver accuracy to what the study actually needs.

Use built-in shapes with mode="template" for simple geometry. Use a triangular OBJ for measured or CAD-derived geometry. When separate objects, especially separate conductors, need distinct identities, use separate templates so that they receive separate mesh_id values.

kindShapeMain dimensionsMain resolution keys
planeXY rectanglesize_x, size_ynx, ny
plate_hole, plane_holeRectangle with a circular hole; the latter is an aliassize_x, size_y, radiusn_theta, n_r
diskDiskradiusn_theta, n_r
annulusAnnulusradius, inner_radiusn_theta, n_r
boxClosed rectangular surfacesizenx, ny, nz
cylinderz-axis cylinderradius, height, capn_theta, n_z
sphereSphereradiusn_lon, n_lat

For example, to replace the tutorial plane with a sphere, replace only the existing [[mesh.templates]] block:

[[mesh.templates]]
kind = "sphere"
enabled = true
surface_side = "outward_closed"
center = [0.5, 0.5, 0.5]
radius = 0.2
n_lon = 24
n_lat = 12

For OBJ input, remove the existing [[mesh.templates]] block and replace [mesh] with:

[mesh]
mode = "obj"
obj_path = "mesh/object.obj" # replace with the actual OBJ path
surface_side = "outward_closed"

Use outward_closed only for a consistently oriented, closed two-manifold. For an open surface, select normal_plus or normal_minus from the OBJ face normals and the vacuum side. See the built-in shape and OBJ reference for placement transforms, element counts, and shape constraints. examples/beach.toml shows multiple built-in shapes.

Goalsurface_modelScope of the current model
Retain charge at the hit locationinsulatorDoes not solve surface conduction, bulk leakage, or dielectric polarization
Conserve object charge and equalize its potentialconductorFloating conductor in free space; requires field_boundary.mode="free"

The tutorial uses insulator. To change a target to a conductor, change this one line in that template or in [mesh] for OBJ input:

surface_model = "conductor"

dielectric, epsilon_r, and resistive surfaces are not available in the current input. A conductor case needs its own validation of object potential and total charge; the tutorial result is not its baseline. See How surfaces charge for model meanings and constraints.

Choose a path from where particles are supplied. When changing source_mode, replace that species entry with the minimum configuration from the dedicated guide so that keys specific to the old mode do not remain.

source_modeUse in a new casePhysical supplyMacro-sampling control
volume_seedPlace a specified count inside the box for initial populations or orbit testsDoes not represent a surface fluxnpcls_per_step
plane_sourceSupply particles one way from an internal rectangleFlux × area × batch_durationw_particle or target_macro_particles_per_batch
photo_raycastEmit from the first surface hit by illumination raysCurrent density × projected area × batch_durationrays_per_batch and ray hit rate
reservoir_faceCompatibility input for deprecated existing configurations onlyDo not use for a new caseDo not use for a new case

To keep the tutorial volume_seed path but change its supply and region, adjust only these values in the existing species entry:

npcls_per_step = 500
pos_low = [0.2, 0.2, 0.8]
pos_high = [0.8, 0.8, 0.8]
drift_velocity = [0.0, 0.0, -1.0e6]

Inflow from external plasma through a complete nonperiodic box face uses [particles.species.boundary_inflow], not another source_mode. The current schema also requires source_mode="volume_seed" and npcls_per_step=0 for a species that uses only boundary inflow. See Choose where particles enter for selection, Inflow through a simulation boundary for boundary inflow, and Photoelectron emission and lifecycle for photoelectrons.

5. Choose the box, field boundary, and particle boundaries

Section titled “5. Choose the box, field boundary, and particle boundaries”

First make the [domain] box contain the mesh and every reachable particle trajectory. Then select the field closure with field_boundary.mode and the outward particle action on nonperiodic faces with [particle_boundary].

DecisionSelection
Free-space field of finite objectsperiodic_axes=[], field_boundary.mode="free"
Field repeated infinitely in x/yperiodic_axes=["x", "y"], field_boundary.mode="periodic2"
Particle reaching a nonperiodic faceopen, reflect, or redistributed_reflect

domain.periodic_axes is the only public setting for periodic topology. Neither [particle_boundary] nor a species override can add, remove, or replace a periodic axis. Because periodic2 currently requires periodic x/y and nonperiodic z, start a new periodic case from the complete examples/periodic2_basic/beach.toml and periodic2 electrostatics. See Particle escape and return for particle-boundary behavior.

sim.field_solverWhen to select itHow to check it
directSmall cases and reference solutionsUse as the baseline for approximate solvers
treecodeMedium free-space casesVary the opening condition and compare observables
fmmLarge cases, many targets, and ordinary periodic2 productionVary tree_theta and tree_leaf_max, then compare with Direct
autoSelect by element count for a free-space caseRead the resolved solver from output

Keep the tutorial reference run at field_solver="direct". Before adopting a faster solver, measure its difference from Direct in a reduced case with the same mesh and particle conditions. See Field evaluation for compatibility and selection, and Use FMM for FMM configuration and accuracy tuning.

First choose physical conditions such as density, temperature, and flux, then decide how many macro-particles will represent them. The weight w_particle is the number of physical particles represented by one simulated particle.

DecisionSettingHow to choose it
Particle orbit stepsim.dtHalve it and compare impact locations and absorption rates
Tracking limit per particlesim.max_stepIncrease it until unresolved particles, survived_max_step, have a sufficiently small effect
Surface-charge update intervalsim.batch_durationUse positive seconds for flux-driven sources and compare with half the interval
Simulation durationsim.batch_countWith a fixed interval, batch_duration × batch_count is the physical end time

When halving the orbit step, double max_step to preserve the available tracking time. With batch_duration_step, the relation is batch_duration = dt × batch_duration_step, so changing dt alone also changes the charge-update interval. Specifying batch_duration in seconds initially makes these two controls independent and their effects easier to compare. The two ways to specify the batch interval are mutually exclusive.

How to increase sampling depends on the selected source.

SourceChange to improve statisticsPhysical conditions to hold fixed
volume_seedIncrease npcls_per_step and decrease w_particle by the same factorPhysical particles per batch, npcls_per_step × w_particle
plane_source / boundary_inflowIncrease target_macro_particles_per_batch, or decrease fixed w_particle; do not specify bothDistribution, density or flux, area, and batch_duration
photo_raycastIncrease rays_per_batchPhotoelectric current density, illumination direction, geometry, and batch_duration

Despite its name, npcls_per_step is a count per batch. For example, changing the tutorial’s npcls_per_step=200, w_particle=2.0e5 to 400, 1.0e5 doubles the sample count while preserving the number of physical particles supplied. Increasing only the particle count also increases the supplied charge and changes the physical case. The photoelectron macro-particle count also depends on the ray hit fraction.

For the tutorial, which does not assign physical seconds, keep batch_duration=0 and compare results by batch. See Choosing batch_duration for interval comparisons and adaptive stepping in flux-driven research cases.

Finally, change only dir in the existing [output] table so that the baseline result is not overwritten.

dir = "outputs/case"

On HPC systems, do not run the simulation directly on a login node; run beach case.toml inside a compute-node allocation.

Terminal window
beachx lint case.toml
beach case.toml
beachx inspect outputs/case

See Run and resume a simulation for local execution, MPI, checkpoints, and resume.

The minimum pass condition is status=ok from lint, process exit code 0, batches from inspect equal to sim.batch_count, and the presence of summary.txt and charges.csv. This proves completion, not physical correctness. See Inspect output files for interpreting each output.

For the observable defined in step 1, check at least the following:

  • processed_particles = absorbed + escaped; its escaped_boundary, survived_max_step, and multiple_box_events_soft_discarded components are explained; and the surface/emission charge ledger closes
  • Refining the mesh does not change the conclusion
  • Varying dt, max_step, batch_duration, batch count, and particle count keeps the conclusion within tolerance
  • A small Treecode or FMM result agrees with the Direct reference
  • Statistical variation across random seeds or repeated runs remains within tolerance
  • The conclusion stays within the scope of the selected surface model, boundaries, and particle source

Compare the same physical quantity at the same physical time before and after a change, and do not vary several numerical controls at once. Follow Validating simulation results for concrete commands and acceptance criteria.