Reference documentation

Theory & User Guide

How PIBS's interior-ballistics solver actually works, and everything needed to run it — from a first install to a worked recoilless-gun case. Every number below comes from solving the presets already bundled with the project; nothing is invented.

Part I

Theoretical Model

A direct read of pibs/ballistics/ — what the solver computes, not a black-box description. Follows the Serebryakov-system reduced-variable formulation used in Soviet/PRC ballistics literature (§References).

§1Scope: what "interior ballistics" means here

Interior ballistics covers the phase from primer ignition to shot exit: propellant burns, gas pressure builds, the shot accelerates down the bore. PIBS solves the forward problem (given a design, compute its pressure/velocity trace, §1–§10) and the inverse/constrained problem (given performance targets, solve for the grain web size and barrel length, §11) — both available in either GUI.

The model is 0-dimensional in the combustion chamber (space-mean pressure) with a 1-dimensional correction for the pressure gradient along the bore (§6). It is not a CFD simulation — no radial structure, no turbulence, no ignition transient. That trade-off buys design-level accuracy in seconds rather than hours.

§2Reduced (dimensionless) variables

Rather than integrate pressure, travel, velocity and time in SI units directly, the solver non-dimensionalizes everything against charge/gun-specific scales — this is what "reduced form" means in the README, and why gun.py variable names look like p_bar, l_bar, v_bar, t_bar: the _bar suffix denotes the dimensionless version.

QuantityScaleReduced variable
Pressurep_scale = f·Δp_bar = p / p_scale
Travell₀ = V₀ / Sl_bar = l / l₀
Velocityv_j = √(2f·w / (θ·φ·m))v_bar = v / v_j
Timet_scale = l₀ / v_jt_bar = t / t_scale
Burnt fractionweb-normalizedZ = e / e₁ ∈ [0, Z_b]

where f is propellant force (specific combustion energy, J/kg); Δ = w/V₀ is loading density; w/m are charge/shot mass; θ is the reduced adiabatic index (θ=γ−1); φ is the fictitious mass factor (§5) — shot mass alone under-accounts for how much mass the pressure has to accelerate, since the propellant gas itself has inertia; e₁ is grain half-web (Z=1 is when the primary grain shape burns through, Z=Z_b≥1 is complete combustion — §3).

v_j is the theoretical maximum velocity the charge could impart to the shot in the idealized limit of complete, instantaneous burning with no losses — the natural velocity scale for the problem.

§3Propellant charge model

3.1 Form functions

As a grain burns, its burning-surface area changes with the fraction of web consumed — the "form function". PIBS uses the standard cubic form function:

ψ(Z) = χ·Z·(1 + λ·Z + μ·Z²) for 0 ≤ Z ≤ 1 ψ(Z) = χₛ·Z·(1 + λₛ·Z) for 1 < Z ≤ Z_b (secondary / sliver phase) σ(Z) = dψ/dZ (relative burning surface)

ψ(Z) is the burnt mass fraction; σ(Z) its derivative — the burning-surface area relative to the initial grain surface. The coefficients (χ, λ, μ) — and (χₛ, λₛ, Z_b) for grains that keep burning past Z=1 — are not free parameters; they're derived from grain geometry:

  • Simple geometries (SimpleGeometry): sphere, cylinder, tube, strip. Two shape ratios α=e₁/b, β=e₁/c fully determine (χ,λ,μ); these grains burn out at Z_b=1 — no secondary phase.
  • Multi-perforated geometries (MultPerfGeometry): 7/14/19-perf cylinders, rosettes, hexagons. Start progressive (burning surface increases as perforations enlarge) until the web between perforations is consumed at Z=1, then the grain fragments into slivers that burn degressively for 1<Z≤Z_b. This progressive-then-degressive shape is why multi-perf propellant is standard in high-performance guns — it front-loads surface growth to offset falling pressure as chamber volume increases with shot travel.

A Propellant can mix two grain populations (main + auxiliary, independently sized/shaped) plus an optional combustible-cartridge fraction (case material that itself burns and contributes gas).

3.2 Burn rate law

Grains regress per Vieille's/Muraour's law — linear in pressure raised to a propellant-specific exponent:

dZ/dt = u₁·p^n / e₁

u₁ (burn rate coefficient) and n (pressure exponent) come from the propellant composition (propellants.csv — 40 bundled compositions from published references), independent of geometry (grain shape) — composition × geometry = grain, combined multiplicatively in the Propellant class.

§4Equation of state & space-mean pressure

Propellant gas is modeled with the Nobel–Abel (covolume) equation of state — ideal gas with a correction α for the finite volume the gas molecules occupy at high density. Combined with conservation of energy (chemical energy released = kinetic energy of shot and gas + friction/counter-pressure work), the space-mean pressure falls out as an algebraic function of the current state — no separate energy ODE needed:

p_bar = (ψ − v_bar²) / (l_bar + l_ψ_bar) l_ψ_bar = 1 − Δ·[(1−ψ)/ρ_p + α·ψ]

l_ψ_bar is the "unburnt propellant + covolume" correction to available expansion length: (1−ψ)/ρ_p accounts for volume still occupied by solid unburnt propellant, α·ψ for the covolume of gas already produced. This is Gun.f_p_bar() — evaluated fresh every integration step, not itself an ODE state variable.

§5Equation of motion

With p_bar available algebraically, the reduced-variable ODE system (time domain) is:

dZ/dt_bar = √(θ/2b) · p_bar^n (burn progress) dl_bar/dt_bar = v_bar (kinematics) dv_bar/dt_bar = (θ/2)·(p_bar − p_ad_bar(v_bar)) (Newton's 2nd law, reduced)

b is a dimensionless grouping of burn-rate/geometry/energy terms: b = S²e₁² / (f·φ·w·m·u₁²) · (f·Δ)^(2(1−n)) (S = bore area). p_ad_bar is the ambient aerodynamic counter-pressure (§7).

gun.py solves this system in three different independent variables depending on numerical convenience at each stage: ode_t (time), ode_l (travel — needed once v_bar is no longer small, since 1/v_bar blows up at t=0), ode_z (burnt fraction — robustly locates burnout/exit even as dZ/dt→0 near full burn). Same physics, three re-parameterizations for robustness at different phases of the shot.

The φ (fictitious mass) factor

Newton's law needs a mass to divide by, but only the shot's mass is truly rigid — the propellant gas behind it also accelerates and carries kinetic energy. Rather than track the gas velocity field explicitly, this is lumped into a correction factor:

φ = φ₁ + λ₂·cc·(w/m)

φ₁ = 1/(1−drag_coefficient) is the separate correction for bore friction/engraving resistance (the "Resistance %" input). λ₂ and the chambrage correction cc come from the pressure-gradient solution (§6) — where charge-to-shot mass ratio and gun geometry feed back into the acceleration itself, not just the pressure distribution.

§6Pressure gradient along the bore

Space-mean pressure (§4) is one number, but at any instant local pressure is highest at the breech (accelerating the gas column behind it) and lowest at the shot base — the classical Lagrange problem: gas of nonzero mass filling a tube, accelerated by pressure with a fixed shot at one end.

Two dimensionless distribution coefficients λ₁, λ₂ are computed once per gun, from one of three models (the "Gradient" setting):

  • SOL_LAGRANGE — the classical simplifying assumption: gas density uniform along the tube at every instant. Closed form λ₁=1/2, λ₂=1/3 directly, no iteration.
  • SOL_PIDDUCK — self-similar solution for a gas with adiabatic index θ+1, solved via the integral equation
    ∫₀¹ (1 − Ω·ξ²)^[1/(k−1)] dξ = [w/(2φ₁m)]·[(k−1)/k]·(1−Ω)^[k/(k−1)] / Ω
    for Ω (root-found with the Dekker method) — w/(φ₁m) is charge mass relative to the friction-corrected ("fictitious") shot mass, not the raw shot mass. λ₁,λ₂ follow from Ω by further quadrature. The more physically complete model, and the default.
  • SOL_MAMONTOV — the k→1 (isothermal-gas) limit of the same Pidduck family, evaluated as a separate closed form to avoid the numerical 0/0 at k=1.

Given λ₁,λ₂ and a chambrage correction cc (chamber wider than bore, χ_k = chamber area / bore area), breech and shot-base pressures recover from space-mean pressure:

P_s / P = 1 / (1 + λ₂'·w/(φ₁·m)) P_b / P = (φ₁·m + λ₂'·w) / (φ₁·m + λ₁'·w)

with λ₁',λ₂' further adjusted for shot travel. Pressure at an arbitrary axial probe point interpolates assuming a quadratic (Lagrangian) profile in the gas velocity field — this powers the desktop app's "Barrel Trace" plot and the tube-strength calculation.

Why three peak pressures"Peak Avg", "Peak Breech" and "Peak Shot" are three different numbers at three different times — each found by an independent Golden Section Search over its own pressure trace (§8), not read off one shared peak.

§7Ambient / aerodynamic drag

Once propellant is exhausted (or even before, for high-velocity shots), the atmosphere ahead of the shot pushes back. Modeled as a counter-pressure term from the shot's velocity relative to local sound speed, using ambient density/pressure/adiabatic-index inputs (func_p_ad_bar()) — a standard supersonic-projectile drag correction. Switchable off (ambient density → 0), solving as if firing in vacuum ahead of the shot.

§8Characteristic points & numerical methods

The solver doesn't just uniformly sample the trajectory — it explicitly locates named events, each via the method suited to it:

EventMeaningMethod
SHOT_STARTignition, Z=Z₀initial condition
FRACTUREZ=1, primary shape consumed (multi-perf only)direct integration to Z=1
BURNOUTZ=Z_b, propellant fully consumeddirect integration to Z=Z_b
SHOT_EXITl=l_g, barrel length reacheddirect integration to l_bar=l_g_bar
PEAK_AVG/BREECH/SHOT_Pmaxima of each pressure trace vs. timeGolden Section Search, independently

Z₀ (burnt fraction at ignition) is itself root-found: given a user-specified start pressure (needed to shear the shot's rotating band / begin motion), the solver finds ψ(Z₀)=ψ₀ where ψ₀ comes from inverting the Nobel-Abel EOS at that pressure and zero travel — via the Dekker method (bisection/secant/inverse-quadratic hybrid, similar to Brent's method).

The ODE system integrates with an adaptive embedded Runge–Kutta–Fehlberg scheme, self-adjusting step size to a user-set relative tolerance (-log10(ε) in the UI — e.g. 4 means tolerance 1e-4), with early-abort conditions (pressure exceeding the 600 MPa Nobel-Abel validity ceiling, or a squib condition where the shot stalls).

§9Recoilless guns

A recoilless gun vents propellant gas backward through a nozzle, countering breech reaction so the weapon needs no recoil mechanism. Recoilless extends the conventional model with two coupled state variables tracked through every step:

  • η (eta) — cumulative mass fraction of propellant gas that has flowed out the nozzle rather than remaining in chamber/bore
  • τ (tau) — a reduced temperature/energy ratio, since gas leaving through the nozzle carries away energy the simple closed-form pressure equation (§4) no longer captures alone

Space-mean pressure becomes p_bar = τ/(l_bar+l_ψ_bar)·(ψ−η) — compare §4: (ψ−η) replaces ψ, since only gas mass retained in the gun contributes to pressure — with dη, dτ integrated alongside Z, l_bar, v_bar.

The recoilless condition Zero net reaction force is enforced by sizing the throat area, not an extra force-balance ODE. At construction, the solver computes the required dimensionless throat area from nozzle expansion ratio and nozzle efficiency via the standard isentropic converging-diverging nozzle thrust-coefficient relation, then checks it physically fits within the breech face — raising a clear error if it doesn't (an infeasible design, not a numerical failure).

Because a meaningful fraction of chemical energy is deliberately vented rather than accelerating the shot, recoilless guns have markedly lower thermal/ballistic efficiency than closed-breech guns for the same propellant — confirmed by the bundled examples: the 105mm M40A1 recoilless design solves to ~7% thermal efficiency vs. ~33% for the 76mm ZiS-3 conventional gun (Part II §5). Expected physical trade-off for eliminating recoil, not a modeling artifact.

§10Efficiencies

Three figures derived from the solved trace:

thermal efficiency te = (v_muzzle / v_j)² ballistic efficiency be = te / φ piezometric efficiency pe = ½·φ·m·v_muzzle² / (P_max·S·l_g)

te measures how much of the theoretical maximum velocity (§2) was realized. be further corrects for φ, isolating losses from charge-to-shot mass ratio and pressure gradient rather than incomplete combustion. pe measures how efficiently peak pressure was "used" — flat-and-high for the whole travel (ideal) gives pe→1; a sharp early spike that decays wastes barrel length at sub-peak pressure and scores low.

§11Constrained design, optimization, and structural sizing

Everything above solves the forward problem: given a design, compute its performance. The pieces below build on that same core solver to solve the inverse problem (given performance targets, find a design) and to size the resulting barrel. All four are available in both the desktop app and the web GUI.

11.1 Constrained design (the inverse problem)

ConstrainedGun/ConstrainedRecoilless solve for grain web size and barrel length given a target velocity v_d and pressure p_d, via nested root-finding:

  1. For a chosen charge-to-shot mass ratio w/m and chamber loading density Δ/ρ_p ("load fraction"), the charge mass and chamber volume — and hence l₀, Δ — are fixed.
  2. The web (via half-web e₁) is root-found with the Dekker method so the chosen pressure constraint point (space-mean, breech, or shot-base) exactly peaks at p_d: probing outward from a small starting web, doubling/halving until the sign of p_peak(e₁) − p_d brackets a root, then converging on it.
  3. With e₁ fixed, the gun is integrated forward from that peak point until velocity reaches v_d, giving the required barrel length l_g.
  4. Because the chambrage correction cc (§6) depends on l_g, and the pressure-gradient coefficients in step 2 depend on cc, steps 2–3 repeat with the newly-converged cc until l_g itself stops changing (bounded by a max iteration count).

An error here ("Solution requires excessive tube length...", "Design velocity exceeded before peak pressure point...") means the chosen charge ratio and loading density can't physically reach the target within the barrel-length search ceiling — not a numerical failure.

11.2 Optimization: minimum bore volume / minimum barrel length

Constrained.find_min_v() treats load fraction as a free variable instead of a fixed input: it searches it with Golden Section Search between the minimum load fraction (below which the design pressure is unreachable even in the closed-bomb limit — ψ₀ would exceed 1, §8) and the maximum (found by probing upward until the constrained solve in §11.1 stops converging), minimizing either total chamber+barrel volume (MIN_BARR_VOLUME) or barrel length alone (MIN_PROJ_TRAVEL).

11.3 Tube strength & autofrettage

Given the solved pressure trace, Gun.structure() sizes barrel wall thickness at each axial probe point using thick-walled cylinder theory under the Tresca (maximum shear stress) yield criterion, against the highest pressure ever reached at that axial position across the entire trace (not just when the shot happens to pass it — the pressure envelope over time, §6), scaled by a safety factor.

Monoblock (single-piece barrel) — for inner:outer radius ratio k:

k = (1 − 2p/σ_y)^(−1/2)

Thickening the wall (raising k) lets it contain a higher p without the bore exceeding yield strength σ_y — but this construction is mathematically impossible above p = σ_y/2, regardless of wall thickness.

Autofrettage — the barrel is first pressurized beyond yield so it retains a residual compressive pre-stress at the bore once depressurized; working pressure must overcome that pre-stress before the bore sees net tension. The optimal autofrettage radius ratio:

m = exp(p / σ_y), k = m (full autofrettage)

has no p = σ_y/2 ceiling — which is why high-pressure guns are routinely autofrettaged rather than built monoblock. Barrel volume (and hence estimated tube mass) is integrated from these radius ratios along the bore.

11.4 Guidance diagrams

A guidance diagram maps every design — across a grid of charge-to-shot mass ratios and chamber loading densities — that satisfies a given velocity/pressure target, showing how barrel length and chamber volume trade off across that space. It's §11.1's constrained solve repeated at every grid point: for each charge ratio, the maximum feasible load fraction is found, then every load fraction from the minimum up to that maximum (in steps) is solved individually, keeping only the combinations that converge to a physically valid design.

The desktop app parallelizes this sweep across CPU cores, since a single diagram can mean solving hundreds of individual designs. The web GUI instead runs it sequentially — spawning worker processes from inside a Streamlit rerun is unsafe on Windows' spawn start method, since each worker would try to re-import and re-run the Streamlit script itself — so keep the sweep grid modest there.


RefsReferences

As cited in the source (docstrings, pidduck() in gun.py, and bundled example descriptions):

  • 金志明 (2014). 《枪炮内弹道学》(Interior Ballistics of Guns).
  • 鲍廷钰,邱文坚 (1995). 《内弹道学》(Interior Ballistics).
  • 王连荣,张佩勤 (1987). 《火炮内弹道计算手册》, National Defense Industry Press.
  • 兵器工业部第二管理局 (1982). 《国产火炮手册》.
  • Multiple Russian-language ordnance service manuals, cited per-example in pibs/examples/*.json.
Part II

User Guide — Zero to Hundred

Installing PIBS, running both GUIs, understanding every input and output, and two full worked examples — using only the presets already bundled with the project. Nothing here is invented.

§1Which interface do I use?

Desktop appWeb app
Forward calculation
Constrained design
Optimization
Tube strength / autofrettage
Guidance diagrams
Runs headless / on a server
Conventional guns
Recoilless guns
Save/load custom design & propellant files
Localization (English / 中文)

Both interfaces now cover the same calculations. Use the web app if you don't have a desktop session, want to explore designs quickly, or are deploying somewhere headless; use the desktop app if you need to save/load your own custom design or propellant files, or want the Chinese-language interface.

§2Installation

git clone https://github.com/timeout187/Phoenix-s-Interior-Ballistic-Solver-PIBS.git cd Phoenix-s-Interior-Ballistic-Solver-PIBS python -m venv .venv

Activate the environment:

# Windows .venv\Scripts\activate.bat # Linux / macOS source .venv/bin/activate

Install what you need:

pip install -e ".[dev]" # desktop app + dev tools pip install -e ".[streamlit]" # web app pip install -e ".[dev,streamlit]" # both

Requires Python ≥ 3.9 (the desktop app additionally needs tkinter and a display — standard on Windows/most Linux desktops, not on headless servers).

§3Running the apps

python run_pibs.py # desktop GUI streamlit run streamlit_app.py # web GUI → http://localhost:8501

§4Worked example — Web GUI, demo mode, conventional gun

Exactly what you'll see using the bundled Guns/76x385_ZiS-3_UOF-354AM preset — the 76×385mm round fired from the Soviet ZiS-3 divisional gun (M1942).

  1. Open the web app, leave the sidebar on "Demo (load example)".
  2. In the Example dropdown, pick Guns/76x385_ZiS-3_UOF-354AM.
  3. Click Load & Solve.

The design loaded, verbatim from the bundled JSON:

Caliber76.2 mm
Shot mass6.2 kg
Charge mass1.08 kg
Chamber volume1.484 L
Chambrage ratio1.1
Start pressure30.0 MPa
Travel2687.0 mm
Web (grain thickness)8.2872 mm
Propellant[GAU Table]
Grain geometrySEVEN_PERF_CYLINDER

Solved result (actual solver output, reproducible by running the preset yourself):

Muzzle velocity
684.8 m/s (target 680)
Peak avg. pressure
261.3 MPa (target 261.3)
Time to exit
7.32 ms
Burnout travel
1548 mm · 57.6%
Thermal eff.
33.0 %
Ballistic eff.
28.9 %
Selected points from the full trace
EventTimeTravelBurntVelocityAvg PBreech PShot P
SHOT_START0 ms0 mm2.4%0 m/s30.030.728.6
PEAK_AVG_P2.80 ms262 mm51.7%270 m/s261.3267.6248.9
BURNOUT5.57 ms1548 mm100%603 m/s100.2102.895.3
SHOT_EXIT7.32 ms2687 mm100%684.8 m/s53.254.650.6

Breech pressure is always a little higher than average, which is always higher than shot-base pressure — the pressure gradient from Part I §6, not numerical noise. The propellant is fully burnt well before the shot exits (57.6% of the way down the barrel) — pressure past that point falls purely from volume expansion of already-generated gas.

§5Worked example — recoilless gun

Can I use this for recoilless guns?Yes. Fully supported in both GUIs, same solver fidelity as conventional guns. Four recoilless presets ship with the project (75–105mm), every one solving within ~1% of its stated target (Part II §11).

Recoilless/105x607_Type75(M40A1)_HEAT-FS — the 105mm HEAT-FS round for the Type 75 (M40A1) recoilless rifle. In the web app, pick this preset under Demo, or select Manual input → Gun Type RECOILLESS (pre-fills matching defaults for a from-scratch recoilless design).

Caliber105.0 mm
Shot mass7.96 kg
Charge mass3.6 kg
Chamber volume7.2 L
Chambrage ratio1.7
Start pressure5.48 MPa
Travel2683.0 mm
Web0.834 mm
PropellantPyroxylin
Grain geometryFOURTEEN_PERF_ROSETTE
Nozzle expansion ratio1.125
Nozzle efficiency100%
Muzzle velocity
502.9 m/s (target 503)
Peak breech P
71.30 MPa (target 71.3)
Thermal eff.
7.3 %
Ballistic eff.
6.2 %
Piezo eff.
71.0 %

Compare 7.3% thermal efficiency here against 33.0% for the conventional ZiS-3 above — a similar-caliber, similar-pressure comparison. That ~4–5× gap is the real, expected physical cost of a recoilless gun venting propellant gas out the nozzle to cancel recoil (Part I §9), not a bug.

Nozzle Expansion Ratio is the nozzle exit-to-throat area ratio; Nozzle Efficiency is a 0–100% loss factor for non-ideal nozzle flow. If caliber/chambrage/expansion-ratio can't physically fit a large-enough throat into the breech face, the solver raises "Achieving recoilless condition necessitates a larger throat area than could be fit into breech face" — an infeasible-design error, not a numerical failure; widen chambrage or reduce nozzle expansion to fix it.

Constrained design and tube structural sizing for recoilless guns are also available in the web GUI — see §7 and §8.

§6Manual input mode

Use this to explore a design of your own rather than a bundled preset. Switching the Gun Type radio immediately reloads all fields with a self-consistent starting design for that type — a conventional gun and a recoilless gun need very different pressure/web combinations (see the two worked examples above for why). Click Solve Gun immediately to see a working baseline, then change fields from there.

FieldMeaningCore parameter
CaliberBore diametercaliber
Shot MassProjectile massshot_mass
Charge MassPropellant masscharge_mass
Chamber VolumeVolume behind shot at startchamber_volume
Travel / Barrel LengthDistance shot travels in borelength_gun
Chambrage RatioChamber area ÷ bore areachambrage
Start PressurePressure at which shot begins to movestart_pressure
WebGrain half-thickness × 2web
Bore ResistanceFriction/engraving work, %drag_coefficient
Propellant CompositionChemical propellantpropellant.composition
Grain GeometryPhysical grain shapepropellant.main_geom
Grain 1/α, 1/βShape ratios (Part I §3.1)main_r1/r2
Sample PointsPoints sampled along the tracestep
Nozzle Expansion Ratio (recoilless)Exit ÷ throat areanozzle_expansion
Nozzle Efficiency (recoilless)Non-ideal flow loss factornozzle_efficiency

§7Constrained design mode (web GUI)

Select Constrained design in the sidebar. This solves the inverse problem (Part I §11.1): given a target velocity and pressure, a chosen charge-to-shot mass ratio, and a chamber loading density, it finds the grain web size and barrel length that hit those targets exactly — rather than you specifying web/length directly.

Worked example: leave everything at its CONVENTIONAL default (which mirrors the ZiS-3 example's real charge ratio and loading density — Charge / Shot Mass Ratio 0.174, Load Fraction 45.5%) and click Solve Constrained Design. Solved output (reproducible):

Solved quantityValueReference (ZiS-3 actual)
Web8.2849 mm8.2872 mm
Chamber Volume1.482 L1.484 L
Barrel Length2596.7 mm2687.0 mm
Charge Mass1.079 kg1.08 kg

Running the resulting design forward gives muzzle velocity 680.0 m/s and peak avg. pressure 261.3 MPa — exactly the target values entered, by construction. The small differences from the ZiS-3 reference numbers come from the constrained solver finding a self-consistent design meeting those two targets at that charge ratio and loading density, not necessarily bit-identical geometry to the historical gun (which had other constraints, like a fixed production barrel length, that this solve doesn't know about).

Optimize load fractionToggle this on to have the solver search for the loading density that minimizes chamber+barrel volume or barrel length alone (find_min_v(), Part I §11.2), instead of using the fixed value you specify. This searches the entire feasible range and can land near the Max Barrel Length search ceiling — if solving fails with "Solution requires excessive tube length", raise that ceiling or narrow the charge ratio.

Lock barrel length: check this to fix barrel length yourself and solve only for web size, useful when barrel length is a hard constraint (e.g. matching an existing gun) rather than something to solve for.

This mode works identically for RECOILLESS — switching Gun Type reloads matching defaults (based on the 105mm M40A1 example) and adds the Nozzle Expansion Ratio / Nozzle Efficiency fields, same as manual input mode.

§8Tube strength & autofrettage (web GUI)

After any successful solve — demo, manual, or constrained — an optional "Tube strength & autofrettage" section appears below the results. Expand it, set material density, yield strength, and safety factor, choose whether to autofrettage, and click Compute Tube Strength (Part I §11.3).

It reports estimated tube mass and plots the barrel cross-section: bore radius, outer radius, and (if autofrettaged) the elastic-plastic junction radius, along the length of the tube. For the ZiS-3 constrained-design result above with steel at 7850 kg/m³ density, 1000 MPa yield strength, 1.35 safety factor, and autofrettage enabled, this comes out to ~55 kg of tube — a plausible mass for a 76mm gun barrel.

§9Guidance diagram mode (web GUI)

Select Guidance diagram in the sidebar. This sweeps a grid of charge-to-shot mass ratios and chamber loading densities and plots every combination that reaches the target velocity/pressure (Part I §11.4) — a scatter of feasible designs, colored by the resulting barrel length, so you can see the volume/length trade-off across the whole design space at a glance, plus a full data table (downloadable as CSV).

Runs sequentiallyThis mode runs the sweep sequentially in the browser session (no multiprocessing — see Part I §11.4 for why), so it's slower than the desktop app's parallelized version. The form caps the sweep at 40 charge-ratio steps and warns if you exceed it; keep Step no finer than you need. A default-sized sweep (charge ratio 0.10–0.30 in steps of 0.02, 5% load-fraction steps) for a conventional gun takes on the order of 30 seconds and finds several dozen feasible designs.

§10Reading the output

Summary metrics: muzzle velocity, time to exit, three peak pressures, burnout travel, three efficiency figures.

Table Data — one row per named event plus evenly-spaced samples:

ColumnMeaning
EventSHOT_START, SAMPLE, FRACTURE, BURNOUT, PEAK_*_P, SHOT_EXIT (Part I §8)
TimeElapsed since ignition
TravelShot position in the bore
BurnupFraction of propellant consumed (ψ, as %)
VelocityShot velocity
Avg / Breech / Shot PressureThe three pressure definitions
TemperatureLocal gas temperature (Nobel-Abel EOS)

Download the table as CSV from the button below it for further analysis.

§11Running the full bundled example set

run_examples.py solves every preset under pibs/examples/ — the same corpus the web GUI's demo dropdown draws from — checking computed muzzle velocity and design-constrained peak pressure against each preset's own recorded target:

python run_examples.py # every example python run_examples.py Recoilless # only labels containing "Recoilless" python run_examples.py --csv out.csv # dump every sampled event too
Current result48 of 48 examples solve successfully, computed muzzle velocity within ~1–2% of the stated target for essentially every case — autocannons, howitzers, gun-howitzers, and all 4 recoilless designs.

This script is a regression check: modify the solver core, re-run it — any example that starts failing or drifting materially off-target is worth investigating. To add a new case, drop a new preset JSON in the same schema under pibs/examples/ (e.g. saved from the desktop app's Design → Save) — both this script and the web GUI's demo dropdown pick it up automatically, no code changes needed.

§12Troubleshooting

Errors are raised by the solver with a specific cause — the common ones:

ErrorCauseFix
"Initial burnup fraction is solved to be negative"Loading density Δ = charge/chamber volume exceeds the propellant's own solid density (~1600 kg/m³)Reduce charge mass or increase chamber volume so Δ < ρ_p
"...greater than unity"Start pressure too high relative to loading density (roughly, start_pressure > f·Δ)Lower start pressure, or raise charge mass / lower chamber volume
"Squib load condition detected"Shot stalls in bore — insufficient propulsive forceWeb/geometry mismatch (see below), or genuinely too little charge for shot mass and travel
"Nobel-Abel EoS is generally accurate enough below 600MPa..."Pressure exceeded the model's validity ceilingWeb too small / geometry too fast-burning for the charge and chamber
"...larger throat area than could be fit into breech face" (recoilless)Nozzle can't physically fitIncrease chambrage ratio or reduce nozzle expansion ratio
"Auxiliary grains must complete combustion in advance..."Mixed-charge web ratio inconsistentAdjust Web Aux/Main so auxiliary grain burns out first
"Solution requires excessive tube length..." (constrained)Charge ratio / loading density can't reach the design velocity within the barrel-length search ceilingRaise Max Barrel Length, increase charge ratio, or lower the velocity target
"Propellant load too low to achieve design velocity" (constrained)Even at 100% burn, this charge can't reach the target velocityIncrease charge-to-shot mass ratio
"Design velocity exceeded before peak pressure point..." (constrained)Inconsistent target/charge combinationLower the velocity target or raise the pressure target relative to it
Most common from-scratch mistakePairing a web thickness tuned for one grain geometry with a different geometry default. A given web value means something very different for a sphere vs. a 7-perforation cylinder — surface-to-volume ratio and burn progression are shape-dependent (Part I §3.1). The web GUI's manual mode keys its defaults to grain geometry per gun type to avoid this; if you change geometry, re-check the web value still makes sense for that shape.

§13Where to go next

  • Part I — Theoretical Model — the full physical/numerical model.
  • pibs/examples/ — all 48 bundled reference designs (Autocannons, Guns, Howitzers, Gun-Howitzer, Recoilless). excluded_examples/ holds additional presets (including Naval) not wired into the demo dropdown/runner by default.
  • pibs/ballistics/resource/propellants.csv — the 40 bundled propellant compositions with literature sourcing.
  • Desktop app Data menu — load/save designs and propellants, including your own.