std/ — the PWE standard library
A foundational package of PWE modules (import "std/<name>") covering the
domains a general simulation language needs: mathematics, point kinematics,
forces, rigid-body mechanics, chemistry, thermal physics, acoustics, optics,
electromagnetism, robotics, the periodic table (std/periodic lookup by
atomic number, plus one module per element in std/elements/), and
atomic structure (std/atoms/, nucleus + orbiting electron shells), signal processing / DSP (std/signal, decibels, one-pole filters, RBJ biquads, envelope followers), molecular dynamics (std/md, periodic boundary conditions, kinetic temperature, the Berendsen thermostat/barostat), and
molecules (std/molecules/, renderable atoms + bond lines).
How modules are used
import "std/forces"
import "std/thermal"
world {
gravity = (0, 0, 0)
entity body { state = (x = 1.0, vx = 0.0, temp = 353.15) }
}
systems {
update { on = body; dt = 0.1
vx = forces.spring_accel(2.0, x, 1.0) + forces.damping_accel(0.3, vx, 1.0) + 0.0
x = vx + 0.0
temp = thermal.newton_cooling(temp, 293.15, 0.05) + 0.0
}
}
Every module is plain PWE: it declares pure scalar functions and physical
parameters (namespaced, e.g. chemistry.R_gas). A program imports the
modules whose laws it needs; parameters merge into the model and are
overridable with pwe run --param <module>.<name>=…. Functions are called
through the module's namespace (math.lerp(...)).
A composing example lives at cli/examples/domains.pwe.
Modules
| module | contents |
|---|---|
std/math |
clamp clamp01 lerp mix inv_lerp remap step smoothstep smootherstep wrap sqr deg rad hypot2 hypot3 min3 max3 sgn deadzone ease_in ease_out |
std/particles |
terminal_velocity drag_step ballistic_x ballistic_y ballistic_vy bounce_vy reflect radius_from_mass stopping_distance freefall_time speed |
std/micro |
Micro-scale interaction laws: lj_potential lj_force lj_r_min (van der Waals), morse_potential morse_force (chemical bond), bond_potential bond_force bond_omega (harmonic), coulomb_energy coulomb_force screened_coulomb, hbond_energy, accel |
std/forces |
hooke spring_accel damping_accel drag_linear_accel drag_quadratic_accel coulomb_force gravity_force inverse_square_accel buoyancy_force thrust_accel damper_force |
std/mechanics |
momentum kinetic_energy reduced_mass elastic_1d_v1 elastic_1d_v2 impulse friction_force normal_impulse inertia_rod inertia_disk inertia_sphere torque angular_accel angular_kinetic |
std/chemistry |
Periodic table 1–118: atomic_mass element_period element_group valence_electrons shell_capacity neutrons, plus mol_from_mass mass_from_mol molecules molarity dilute ideal_pressure ideal_volume arrhenius rate_constant activation_ratio ph h_from_ph neutralization_volume half_life_decay radioactive_amount (params R_gas, avogadro) |
std/thermal |
celsius kelvin newton_cooling heat_capacity sensible_heat conduction_flux stefan_boltzmann radiative_cooling thermal_diffusivity thermostat_hysteresis mixing_temp (param sigma_sb) |
std/acoustics |
speed_of_sound_air wavelength spl pressure_from_spl acoustic_impedance doppler inverse_square sound_intensity beat_frequency (params rho_air, c_air, p_ref) |
std/optics |
inverse_square_intensity beer_lambert snell_angle critical_angle fresnel_reflectance reflect_axis wien_peak photon_energy photon_energy_wavelength focal_length (params h_planck, c_light) |
std/em |
coulomb_force electric_field potential lorentz_force cyclotron_radius biot_savart_wire poynting plane_wave_b plane_wave_e impedance_free_space (params c_light, k_coulomb, mu0) |
std/robotics |
planar2_x planar2_y planar2_ik_q1 planar2_ik_q2 pid joint_accel diff_drive_v_left diff_drive_v_right trapezoid_peak reach rotate_x rotate_y |
std/units |
kmh_to_ms ms_to_kmh mph_to_ms knot_to_ms fahrenheit_to_celsius celsius_to_fahrenheit celsius_to_kelvin kelvin_to_celsius kwh_to_j cal_to_j kcal_to_j ev_to_j btu_to_j atm_to_pa bar_to_pa psi_to_pa mmhg_to_pa angstrom_to_m nm_to_m au_to_m ly_to_m parsec_to_m mile_to_m nautical_mile_to_m foot_to_m inch_to_m lb_to_kg oz_to_kg tonne_to_kg deg_to_rad rad_to_deg arcmin_to_rad arcsec_to_rad g_to_ms2 lbf_to_n |
std/atoms |
Schematic atomic internal structure: shape <Sym>_atom (nucleus + one ring per shell + orbiting electrons) and shape <Sym>_nucleus (nucleus only) to attach to an entity |
std/molecules |
Renderable molecules: each module declares one entity per atom (CPK colour, size) with bond lines and exposes molar_mass() / atom_count() composed from std/elements/ |
std/des |
Discrete-event statistics over the priority event calendar: utilization availability throughput wait_time queue_length mean variance ewma littles_law (all pure, trap-free — zero denominators yield a finite fallback) |
std/control |
first_order second_order low_pass complementary integrate derivative pid pid_clamped feedforward state_feedback bang_bang hysteresis rate_limit_delta lead within slew |
std/md |
Molecular-dynamics scaffolding: wrap wrap_signed min_image min_image_dist min_image_dist2 number_density box_from_density lattice_sc lattice_bcc lattice_fcc nn_dist_sc nn_dist_bcc nn_dist_fcc degrees_of_freedom temperature kinetic_energy temperature_from_velocity berendsen_lambda tau_from_steps heat_to_apply berendsen_baro_lambda compressibility rdf_bin rdf msd diffusion half_kick drift reduced_length reduced_energy (periodic boundary conditions + temperature + Berendsen thermostat/barostat; pure, trap-free) |
std/signal |
Sampled-data / DSP: db from_db power_db alpha_from_tau one_pole alpha_from_fc lowpass_rc highpass_rc dc_block integrate_trap derivative w0 bq_alpha bq_a0 lowpass_b0 lowpass_b1 lowpass_b2 lowpass_a1 lowpass_a2 biquad biquad_dc_gain envelope rms crest_factor zcr midband midi_to_hz hz_to_midi phase_inc osc_sin soft_clip quantize (all pure, trap-free — filter memory is the caller's state) |
Field solver system kinds
Continuum domains step a grid field with a solver declaration instead of an explicit loop:
diffuse { field = <name>; rate = r }— explicit diffusion,T += r·∇²Tper step. Implemented as a Jacobi sweep (two passes over the cells), so with the zero-flux stencil the total is exactly conserved. Stability:rate ≤ 1/4in 2D,≤ 1/6in 3D.poisson { field = <name>; source = <name>?; iters = n; scale = s }— Gauss–Seidel relaxation of∇²φ = ρ·scale; boundary cells are held fixed (fixed potentials).wave { field = <name>; prev = <name>; velocity = c; dt = h }— second-order leapfrogu_tt = c²∇²uover two fields (prevholdsu(t−h)); the initial pulse splits into a spherical wavefront. Stabilityc·h/dx ≤ 1/√2(2D),≤ 1/√3(3D);absorb/absorb_widthadd a graded sponge layer that soaks up outgoing waves (open boundary), and an optionaldampingscales the temporal term.
Both run once per step (only the first dynamic entity emits the sweep), lower
to the existing fget/fset/flap EIR — so the interpreter and JIT stay
byte-identical — and are covered by cross-backend tests.
Conventions
- Functions are pure and scalar; vectors are passed/returned as separate
components (
planar2_x(q1, q2),planar2_y(q1, q2)) because PWE expressions are scalar. - Physical constants are module parameters so they can be overridden
without editing the library. Builtins
pi/eare available directly. - Units are annotated on parameters; functions are unit-agnostic.
Non-goals
- Causal/networked multi-world concerns (handled by
send/recv, channels). - Target backends (GPU/NPU/SIMD — see
tasks/todo.md). - Anything requiring dynamic entity creation (the entity set is fixed at compile time until object-pool activation lands).