Reference guide for AI agents operating BEACH simulations.
Intended to be loaded from CLAUDE.md with @import docs//BEACH/en/agent-user-guide.html.
Normal BEACH users do not need to read this page. Start from BEACH Documentation instead.
BEACH (BEM + Accumulated CHarge) is a hybrid boundary-element-method plus particle-tracking simulator for charge accumulation on insulator surfaces.
Fortran core : particle dynamics, electric-field solver, collision detection, charge deposition
Python layer : configuration management, post-processing, visualization
Version : 1.4.0
# 2. Create a configuration file
# 3. Validate the configuration
beachx inspect outputs/latest
Item Requirement Fortran compiler gfortran, or compatible fpm v0.10+ Python 3.10+ Main Python dependencies matplotlib >= 3.8, numpy >= 1.24
make check # development build check with fixed dev version
make build # build with git describe version
make run CONFIG=beach.toml # run with fixed dev version
make install-generic # portable gfortran build
make install-camphor # Intel compiler optimized build
make test # L1: Python + quick Fortran tests
make check / make test / make run use BEACH_VERSION_MODE=dev and keep the version macro passed to Fortran stable. Because the fpm compile-flag hash does not change when the git hash changes, incremental compilation during development is easier to reuse. When an executable with the git hash is required, use make build VERSION_MODE=git or make install.
fpm run --profile release --flag " -fopenmp " -- beach.toml
FPM_FC = mpiifort fpm run --profile release \
--flag " -fpp -DUSE_MPI -qopenmp " \
--runner " mpirun -n 4 " -- beach.toml
make test-l0 # L0: static/schema/build check
make test # L1: normal development loop
make test-l2 # L2: contract/integration
make test-l3 # L3: heavy/release gate
make test-heavy # heavy Fortran targets only
make test-fortran-far-correction # explicit oracle far-correction diagnostics
make test-full # unfiltered fpm test
make test is the L1 alias and is the normal default for the inner AI/development loop.
Long-running FMM targets are run explicitly with make test-l3 / make test-heavy / make test-fortran-heavy / make test-full. m2l_root_oracle far-correction diagnostics are opt-in through make test-fortran-far-correction or make test-full.
Individual targets can be checked with FPM_ACTION=test ./build.sh --target <name>.
beach.toml : the normal file to edit, read directly by the Fortran executable
beachx lint : validates TOML parsing, JSON Schema, high-level notation, and known constraints
Fortran parser : normalizes high-level notation into final keys such as box_min / box_max / center
Parameter Type Default Description dtfloat 1.0e-9 Time step [s] rng_seedint 12345 Random seed batch_countint 1 Number of batches in normal runs. During resume, cumulative target batch count batch_durationfloat - Batch duration [s], mutually exclusive with batch_duration_step batch_duration_stepfloat - Resolved as batch_duration = dt * batch_duration_step max_stepint 400 Maximum integration steps per particle tol_relfloat 1.0e-8 Monitoring metric, not an early-stop condition q_floorfloat 1.0e-30 Denominator floor for relative-change calculation softeningfloat 1.0e-6 Electric-field softening length [m]
Parameter Type Default Choices Description field_solverstring ”auto” direct, treecode, fmm, auto Electric-field evaluation method field_bc_modestring ”free” free, periodic2 Boundary condition; periodic2 requires fmm field_periodic_image_layersint 1 >= 0 Number of periodic2 image-shell layers field_periodic_far_correctionstring ”none” auto, none, m2l_root_oracle Far correction; auto is treated as none for compatibility field_periodic_ewald_alphafloat 0.0 >= 0 Ewald splitting parameter, 0 means automatic field_periodic_ewald_layersint 4 >= 0 Ewald shell depth tree_thetafloat 0.5 (0, 1] Tree-method MAC parameter tree_leaf_maxint 16 >= 1 Maximum number of elements per leaf node tree_min_nelemint 256 >= 1 Threshold for auto -> treecode switch
auto estimation table (when tree_theta / tree_leaf_max are unspecified):
Element count theta leaf_max < 1500 0.40 12 1500-9999 0.50 16 10000-49999 0.58 20 50000+ 0.65 24
Parameter Type Default Description b0float[3] [0, 0, 0] Uniform magnetic field [T] reservoir_potential_modelstring ”none” none, infinity_barrier phi_inftyfloat 0.0 Infinity reference potential [V] injection_face_phi_grid_nint 3 Injection-face potential grid resolution NxN raycast_max_bounceint 16 Maximum number of ray reflections for photo_raycast
Parameter Type Default Description sheath_injection_modelstring ”none” none, zhao_auto, zhao_a, zhao_b, zhao_c, floating_no_photo sheath_alpha_degfloat 60.0 Solar elevation angle [deg] sheath_photoelectron_ref_density_cm3float 64.0 Reference photoelectron density [cm^-3] sheath_reference_coordinatefloat - Sheath reference-plane coordinate [m] sheath_electron_drift_modestring ”normal” normal, full sheath_ion_drift_modestring ”normal” normal, full
Parameter Type Default Description use_boxbool false Enable box boundary box_minfloat[3] [-1, -1, -1] Lower limit [m] box_maxfloat[3] [1, 1, 1] Upper limit [m] bc_{x,y,z}_{low,high}string ”open” open, reflect, periodic
periodic2 constraint : exactly two axes are periodic, and the remaining one axis is open/reflect.
Parameter Type Default Description enabledbool true Enable this species source_modestring ”volume_seed” volume_seed, reservoir_face, photo_raycast q_particlefloat -1.602e-19 Particle charge [C] m_particlefloat 9.109e-31 Particle mass [kg] pos_lowfloat[3] [-0.4, -0.4, 0.2] Lower generation-position limit [m] pos_highfloat[3] [0.4, 0.4, 0.5] Upper generation-position limit [m] drift_velocityfloat[3] [0, 0, -8e5] Drift velocity [m/s] temperature_kfloat 20000 Temperature [K], mutually exclusive with temperature_ev temperature_evfloat - Temperature [eV]
Parameter Type Default Description npcls_per_stepint 0 Number of particles generated per batch w_particlefloat 1.0 Macro-particle weight
Constraint : sum of npcls_per_step across all species >= 1.
Parameter Type Default Description number_density_cm3float - Upstream density [cm^-3], mutually exclusive with number_density_m3 number_density_m3float - Upstream density [m^-3] w_particlefloat - Macro-particle weight, mutually exclusive with target_macro_particles_per_batch target_macro_particles_per_batchint - Target number of macro particles per batch; -1 reuses the species[1] weight inject_facestring required x_low, x_high, y_low, y_high, z_low, z_high
Constraint : use_box = true and batch_duration > 0 are required. pos_low/pos_high are placed on the specified face.
Parameter Type Default Description emit_current_density_a_m2float required Emission current density [A/m^2] rays_per_batchint required Number of rays per batch deposit_opposite_charge_on_emitbool false Deposit opposite-sign charge on the emitting element photo_escape_modelstring "none"none / boltzmann_cutoff. The latter Boltzmann-suppresses PE escape current at positive potential barriersnormal_drift_speedfloat 0.0 Normal-direction drift speed [m/s] ray_directionfloat[3] inward normal Ray direction vector
Parameter Type Default Description modestring ”auto” auto, obj, template obj_pathstring examples/simple_plate.obj OBJ file path surface_modelstring ”insulator” Surface model for the whole OBJ mesh (insulator, conductor, dielectric) epsilon_rfloat 1.0 Relative permittivity for the whole OBJ mesh (>= 1) obj_scalefloat 1.0 Scale factor obj_rotationfloat[3] [0, 0, 0] Rotation angles [deg], extrinsic x->y->z obj_offsetfloat[3] [0, 0, 0] Translation [m]
Transform order : scale -> rotate -> offset
Common: enabled (bool), kind (enum), surface_model (enum), epsilon_r (float), center (float[3])
conductor is redistributed as an equipotential floating conductor per mesh_id. The current implementation supports only sim.field_bc_mode = "free". OBJ input reads the entire file as mesh_id = 1, so separated conductor parts in a single OBJ are also treated as the same floating conductor. To treat them as independent conductors, split their mesh_id values, for example by using template input. dielectric is currently metadata that retains per-object epsilon_r; physical branches for dielectric polarization are an extension point.
kind Main parameters planesize_x, size_y, nx, nyplate_holesize_x, size_y, radius, n_theta, n_rdiskradius, n_theta, n_rannulusradius, inner_radius, n_theta, n_rboxsize (float[3]), nx, ny, nzcylinderradius, height, n_theta, n_z, cap, cap_top, cap_bottomsphereradius, n_lon, n_lat
Parameter Type Default Description write_filesbool true Enable file output write_mesh_potentialbool false Output element potentials to mesh_potential.csv write_potential_historybool false Output potential history dirstring ”outputs/latest” Output directory history_strideint 1 History output interval [batches], disabled at 0 resumebool false Resume from a checkpoint restart_fromstring none Checkpoint read source when resume=true. New output is saved to dir
Output destination: the directory specified by output.dir, default outputs/latest/
File Format Contents summary.txtText (key-value) Run metadata and statistics charges.csvCSV: elem_idx, charge_C Final element charge mesh_triangles.csvCSV: elem_idx, v0x, v0y, v0z, v1x, v1y, v1z, v2x, v2y, v2z, charge_C, mesh_id Triangle vertices, charge, and mesh_id mesh_sources.csvCSV: mesh_id, source_kind, template_kind, surface_model, epsilon_r, elem_count Mesh source metadata rng_state.txtText Random state, for resume
File Condition Format charge_history.csvhistory_stride > 0CSV: batch, elem_idx, charge_C potential_history.csvwrite_potential_history = true and history_stride > 0CSV: batch, elem_idx, potential_V mesh_potential.csvwrite_mesh_potential = trueCSV: elem_idx, potential_V macro_residuals.csvWhen reservoir_face is used CSV: injection residual state performance_profile.csvWhen the BEACH_PROFILE=1 environment variable is set CSV: measured times for each region
rng_state_rank00000.txt, rng_state_rank00001.txt, …
macro_residuals_rank00000.csv, macro_residuals_rank00001.csv, …
beachx lint [beach.toml] # check schema and semantic constraints
beachx config init [beach.toml] # create a new beach.toml
beachx config validate [beach.toml] # validate high-level notation and constraints
beachx config diff left.toml right.toml # compare configurations
beachx inspect [output_dir] # print summary
beachx inspect outputs/latest --show # display plots
beachx inspect outputs/latest --save-bar charges.png
beachx inspect outputs/latest --save-mesh charges_mesh.png
beachx inspect outputs/latest --save-potential-mesh potential_mesh.png
beachx inspect outputs/latest --apply-periodic2-mesh
beachx inspect outputs/latest --periodic2-repeat 1
beachx animate [output_dir] # 履歴アニメーション
beachx animate outputs/latest --quantity charge # 電荷 (デフォルト)
beachx animate outputs/latest --quantity potential # ポテンシャル
beachx animate outputs/latest --save-gif charge.gif
beachx animate outputs/latest --total-frames 200
beachx animate outputs/latest --frame-stride 2 --fps 15
beachx slices [output_dir]
beachx slices outputs/latest --grid-n 200
beachx slices outputs/latest --xy-z 0.5 --yz-x 0.5 --xz-y 0.5
beachx slices outputs/latest --vmin -20 --vmax 20
beachx slices outputs/latest --save slices.png
beachx coulomb [output_dir]
beachx coulomb outputs/latest --component z
beachx coulomb outputs/latest --target-kinds sphere
beachx coulomb outputs/latest --save forces.png
beachx mobility [output_dir]
beachx mobility outputs/latest --density-kg-m3 2500
beachx mobility outputs/latest --mu-static 0.4
beachx mobility outputs/latest --save-csv mobility.csv
beachx workload beach.toml
beachx workload beach.toml --threads 8
run = Beach ( " outputs/latest " )
fig, ax = run. plot_charges ( step =- 1 )
fig, ax = run. plot_mesh ()
fig, ax = run. plot_mesh_source_boxplot ( quantity = " charge " , step =- 1 )
fig, ax = run. plot_potential ()
slices = run. compute_potential_slices ( grid_n = 200 )
fig, axes = run. plot_potential_slices ( slices )
fig, ax = run. plot_coulomb_force_matrix ( component = " z " )
result = run. analyze_coulomb_mobility ( density_kg_m3 = 2500 , mu_static = 0.4 )
field = run. compute_electric_field_points ( points )
lines = run. trace_field_lines ( seed_points , direction = " forward " )
fig = run. plot_field_lines_3d ( lines )
run. animate_mesh ( quantity = " charge " , save_path = " charge.gif " )
Function Purpose plot_mesh()3D mesh visualization plot_potential()3D potential mesh plot_charges()Bar chart of element charge plot_mesh_source_boxplot()Box plot by mesh source animate_mesh()Mesh animation from history compute_potential_mesh()Element-potential reconstruction compute_potential_points()Potential evaluation at arbitrary points compute_potential_slices()Section-data calculation compute_electric_field_points()Electric-field vector evaluation plot_potential_slices()2D section plots plot_coulomb_force_matrix()Force-matrix heatmap analyze_coulomb_mobility()Mobility analysis trace_field_lines()Field-line integration plot_field_lines_3d()Field-line plus mesh drawing
The Fortran parser normalizes helper keys in beach.toml into runtime keys while loading the file.
sim.box_origin + sim.box_size -> sim.box_min / sim.box_max
inject_region_mode = "face_fraction" + uv_low / uv_high -> pos_low / pos_high
mesh.templates placement_mode = "box_anchor" -> center
mesh.groups.* scale_from / placement_mode -> actual size and coordinates for each template
Runtime settings belong under sim, particles, mesh, and output.
source_mode = " volume_seed "
field_bc_mode = " periodic2 "
box_min = [ 0.0 , 0.0 , 0.0 ]
box_max = [ 1.0 , 1.0 , 10.0 ]
source_mode = " volume_seed "
q_particle = -1.602176634e-19
m_particle = 9.10938356e-31
source_mode = " volume_seed "
q_particle = 1.602176634e-19
m_particle = 1.672482821616e-27
beachx inspect outputs/latest --save-mesh charges.png
beachx animate outputs/latest --quantity charge --save-gif charge.gif
beachx slices outputs/latest --save slices.png
beachx coulomb outputs/latest --save forces.png
beachx mobility outputs/latest --density-kg-m3 2500 --mu-static 0.4
Feature Required conditions reservoir_faceuse_box=true, batch_duration>0, inject_face specifiedphoto_raycastuse_box=true, batch_duration>0, emit_current_density_a_m2>0, rays_per_batch>=1periodic2field_solver=fmm, exactly two periodic axes, use_box=trueSheath model Compatible with reservoir_potential_model = "none" Resume write_files=true, checkpoint file exists, in the restart_from directory when specified, MPI size matchesPerformance profiling Environment variable BEACH_PROFILE=1 MPI run Compiled with -DUSE_MPI, MPI compiler wrapper used
├── app/main.f90 # Fortran entry point
├── src/ # Fortran library modules
│ ├── config/ # configuration parser
│ ├── core/ # simulator main loop
│ ├── mesh/ # triangle mesh management
│ ├── particles/ # particle dynamics (Boris pusher)
│ ├── physics/ # electric-field solvers (direct, treecode, FMM)
│ └── runtime/ # output and restart
├── beach/ # Python package
│ ├── cli/ # CLI subcommands
│ ├── config/ # configuration validation
│ └── fortran_results/ # post-processing and visualization
├── schemas/ # JSON Schema for validation
│ └── beach.schema.json # beach.toml schema
├── examples/ # sample configurations and scripts
├── docs/ # documentation
├── fpm.toml # Fortran package manifest
├── pyproject.toml # Python package metadata
├── Makefile # build automation
├── SPEC.md # Fortran implementation specification
└── AGENTS.md # agent configuration
Document Contents SPEC.mdFortran implementation specification, authoritative docs//BEACH/en/output-guide.htmlHow to read output files docs//BEACH/en/configuration-recipes.htmlCommon configuration recipes docs//BEACH/en/parameters.htmlDetailed parameter specification docs//BEACH/en/workflow.htmlExecution workflow and I/O docs//BEACH/en/algorithms.htmlAlgorithm overview docs//BEACH/en/field-solvers.htmlField solvers and periodic2 field boundary docs//BEACH/en/particle-charge-loop.htmlParticle tracking, collision, and charge accumulation docs//BEACH/en/fmm-core.htmlFMM math and Ewald docs//BEACH/en/batch-duration-stability.htmlbatch_duration stabilitydocs//BEACH/en/configuration.htmlbeachx config and high-level notationdocs//BEACH/en/postprocess-tutorial.htmlPost-processing tutorial docs//BEACH/en/python-postprocess-api.htmlPython API reference schemas/beach.schema.jsonJSON Schema for IDE validation