Resources Numerical accuracy Calculation policy

Pressure vessel thickness and support formulas

Works out required shell, head and cone thickness, allowable pressures, nozzle reinforcement areas, saddle and skirt stresses and wind and seismic loads on a vessel.

How the precision is kept

Each result is one closed-form 64-bit expression of the inputs, with allowable stress, joint efficiency and corrosion allowance supplied by the person. Chart-based values are interpolated between points the person types. Rounding appears only in the data sheet text and in the equipment parameters handed to the plant model.

Open item. Keep the unrounded diameter and length in the plant equipment parameters instead of rounding them to whole millimeters.

Calculations under this policy

19 calculations in 2 source files. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.

process/equip/vessel.js CadCraft 0.8.2 64-bit 17 calculations Reviewed

Tests tools/process-test/test-equip.mjs, tools/process-test/test-dec.mjs

Cylindrical shell thickness

64-bit

The required thickness of a cylindrical shell under internal pressure.

t_circ = P·R ÷ (S·E − 0.6P); t_long = P·R ÷ (2S·E + 0.4P); t = larger of the two

Two 64-bit expressions. The first denominator is a difference that shrinks as P approaches S·E ÷ 0.6; a note is added once P exceeds 0.385·S·E, where the thin-wall equations no longer apply. The corrosion allowance is added afterwards.

  • process/equip/vessel.js
  • lines 23 to 28
  • CadCraft 0.8.2
/** Cylindrical shell: R inside radius (or D inside diameter). → { tCirc, tLong, t (governing), tNominalMin (+ ca), governs } */
export function shell({ P, R, D, S, E = 1, ca = 0 }) {
  R = R ?? D / 2; SC(S, 'S'); SC(E, 'E');
  const tCirc = P * R / (S * E - 0.6 * P), tLong = P * R / (2 * S * E + 0.4 * P), t = Math.max(tCirc, tLong);
  return { tCirc, tLong, t, tMin: t + ca, governs: tCirc >= tLong ? 'circumferential' : 'longitudinal', notes: P > 0.385 * S * E ? ['P exceeds 0.385 S E: UG-27 thin-wall equations do not apply (Appendix 1-2)'] : [], source: SOURCES.shell };
}

Formed head thickness

64-bit

The required thickness of an ellipsoidal, torispherical or hemispherical head.

ellipsoidal: t = P·D·K ÷ (2S·E − 0.2P), K = (2 + (D ÷ 2h)²) ÷ 6; torispherical: t = P·L·M ÷ (2S·E − 0.2P), M = (3 + √(L ÷ r)) ÷ 4

One 64-bit expression per head type. K is 1 when no head depth is given; the torispherical crown radius defaults to D and the knuckle radius to 0.06·D.

  • process/equip/vessel.js
  • lines 29 to 39
  • CadCraft 0.8.2
/** Formed head. type: 'ellipsoidal' (2:1; other ratios use K = (2 + (D/2h)²)/6), 'torispherical' (L, r given), 'hemispherical' (R inside radius). */
export function head({ type = 'ellipsoidal', P, D, S, E = 1, ca = 0, h = null, L = null, r = null }) {
  let t, notes = [];
  if (type === 'ellipsoidal') { const K = h ? (2 + Math.pow(D / (2 * h), 2)) / 6 : 1; t = P * D * K / (2 * S * E - 0.2 * P); }
  else if (type === 'torispherical') {
    L = L ?? D; r = r ?? 0.06 * D; const M = 0.25 * (3 + Math.sqrt(L / r)); t = P * L * M / (2 * S * E - 0.2 * P);
    if (r < 0.06 * L) notes.push('knuckle radius below 6 % of L: outside UG-32 limits'); if (r < 3 * t) notes.push('knuckle radius under 3t');
  } else if (type === 'hemispherical') t = P * (D / 2) / (2 * S * E - 0.2 * P);
  else throw new Error('head type: ellipsoidal | torispherical | hemispherical');
  return { t, tMin: t + ca, notes, source: SOURCES.heads };
}

Conical section thickness

64-bit

The required thickness of a cone.

t = P·D ÷ (2·cos α × (S·E − 0.6P))

One expression with the half-apex angle converted by Math.PI ÷ 180; a note is added above 30°.

  • process/equip/vessel.js
  • lines 40 to 43
  • CadCraft 0.8.2
export function cone({ P, D, alpha, S, E = 1, ca = 0 }) {
  const a = alpha * Math.PI / 180, notes = alpha > 30 ? ['half-apex angle above 30 degrees: needs a special analysis (UG-33 / Appendix 1-5)'] : [];
  const t = P * D / (2 * Math.cos(a) * (S * E - 0.6 * P)); return { t, tMin: t + ca, notes, source: SOURCES.cone };
}

Maximum allowable working pressure

64-bit

The pressure a shell of given thickness may carry.

P_c = S·E·t ÷ (R + 0.6t); P_l = 2S·E·t ÷ (R − 0.4t); P = smaller of the two

The algebraic inverse of the shell formulas, in 64-bit.

  • process/equip/vessel.js
  • lines 44 to 45
  • CadCraft 0.8.2
/** Maximum allowable working pressure of a shell of corroded thickness t (inverse of UG-27). */
export function mawp({ t, R, S, E = 1 }) { const Pc = S * E * t / (R + 0.6 * t), Pl = 2 * S * E * t / (R - 0.4 * t); return { P: Math.min(Pc, Pl), governs: Pc <= Pl ? 'circumferential' : 'longitudinal' }; }

Hydrostatic test pressure

64-bit

The test pressure from the allowable working pressure.

P_test = 1.3 × MAWP × stress ratio

One product of three 64-bit numbers.

  • process/equip/vessel.js
  • lines 46 to 47
  • CadCraft 0.8.2
/** Hydrostatic test pressure (UG-99(b)): 1.3 × MAWP × (S at test temperature / S at design temperature). */
export const hydrotest = ({ mawp: m, Sratio = 1 }) => 1.3 * m * Sratio;

External pressure, elastic formulas

64-bit

The critical and allowable external pressure of a plain cylinder.

long: P = 2E·(t ÷ D)³ ÷ (1 − ν²); short: P = 2.42E·(t ÷ D)^2.5 ÷ ((1 − ν²)^0.75 × (L ÷ D − 0.45·√(t ÷ D))); P_a = P_cr ÷ 4

64-bit closed forms; the smaller of the two is used, and the short-cylinder value is ignored when its denominator makes it non-positive. A note says not to use the result when the buckling stress exceeds half the yield strength.

  • process/equip/vessel.js
  • lines 49 to 56
  • CadCraft 0.8.2
/** External pressure on a plain cylinder (no stiffening rings): critical P by the smaller of Windenburg's short-cylinder and Bresse's long-cylinder relations, divided by 4. */
export function externalCylinder({ Do, t, L, E = 2.0e5, nu = 0.3, Sy = 250 }) {
  const rr = t / Do, long = 2 * E * Math.pow(rr, 3) / (1 - nu * nu);
  const short = 2.42 * E * Math.pow(rr, 2.5) / (Math.pow(1 - nu * nu, 0.75) * (L / Do - 0.45 * Math.sqrt(rr)));
  const Pcr = Math.max(Math.min(long, short > 0 ? short : long), 0), Pa = Pcr / 4, sigma = Pcr * Do / (2 * t), notes = [];
  if (sigma > 0.5 * Sy) notes.push('the buckling stress exceeds half the yield strength: the elastic formula over-predicts; the Section II-D chart (not built) governs. Do not use this Pa.');
  return { Pcr, Pa, sigmaCr: sigma, notes, source: SOURCES.external };
}

Limits of reinforcement

64-bit

How far along and normal to the wall material counts as reinforcement of an opening.

along wall = max(d, Rn + tn + t); normal = min(2.5t, 2.5tn + te)

A maximum and a minimum of short 64-bit sums.

  • process/equip/vessel.js
  • lines 58 to 62
  • CadCraft 0.8.2
/** Limits of reinforcement, UG-40: half-width along the vessel wall = the larger of the finished opening diameter d and (Rn + tn + t) (Rn = d/2), height normal to the wall = the smaller of 2.5 t and 2.5 tn + te. mm. */
export function reinforcementLimits({ d, t, tn, te = 0, Rn = null }) {
  Rn = Rn ?? d / 2;
  return { alongWall: Math.max(d, Rn + tn + t), normal: Math.min(2.5 * t, 2.5 * tn + te), source: 'ASME VIII-1 UG-40(b), (c)' };
}

Opening reinforcement areas

64-bit

The area an opening removes and the areas available to replace it.

A = d·tr + 2tn·tr·(1 − fr₁); available = A₁ + A₂ + A₄₁ + A₅; margin = available ÷ A − 1

Short 64-bit expressions; each available area is floored at 0 before the sum. A pad wider than the limit is cut to it. toFixed appears only in the note texts.

  • process/equip/vessel.js
  • lines 63 to 80
  • CadCraft 0.8.2
/**
 * Opening reinforcement, UG-37. Areas in mm². vessel = { t (shell nominal, corroded), tr (required shell thickness), S, E1: 1 }, nozzle = { d (finished opening diameter, corroded),
 * tn (nozzle wall, corroded), trn (required nozzle wall), Sn, fr1?, leg41?, pad?: {Dp, te, fr4} }. F = 1.
 */
export function nozzleReinforcement({ vessel: v, nozzle: n }) {
  const fr1 = n.fr1 ?? Math.min(1, n.Sn / v.S), fr2 = fr1, E1 = v.E1 ?? 1, d = n.d;
  const A = d * v.tr + 2 * n.tn * v.tr * (1 - fr1);
  const x = E1 * v.t - v.tr, A1 = Math.max(d * x - 2 * n.tn * x * (1 - fr1), 2 * (v.t + n.tn) * x - 2 * n.tn * x * (1 - fr1));
  const A2 = Math.min(5 * (n.tn - n.trn) * fr2 * v.t, 5 * (n.tn - n.trn) * fr2 * n.tn);
  const lim = reinforcementLimits({ d, t: v.t, tn: n.tn, te: n.pad ? n.pad.te : 0 }), notes = [];
  // UG-40: material counts only inside the limits; a pad wider than the limit is cut to it
  const padW = n.pad ? Math.min(n.pad.Dp, 2 * lim.alongWall) : 0;
  if (n.pad && n.pad.Dp > 2 * lim.alongWall) notes.push('the pad is wider than the UG-40 limit of ' + (2 * lim.alongWall).toFixed(0) + ' mm: only that width is counted');
  const A41 = (n.leg41 ?? 0) ** 2 * fr2, A5 = n.pad ? (padW - d - 2 * n.tn) * n.pad.te * (n.pad.fr4 ?? fr2) : 0;
  const avail = Math.max(A1, 0) + Math.max(A2, 0) + A41 + Math.max(A5, 0);
  notes.push('limits of reinforcement (UG-40): along the wall ' + lim.alongWall.toFixed(0) + ' mm each side of the centreline, normal to it ' + lim.normal.toFixed(1) + ' mm; the areas above use them (A1 and A2 as UG-37 prints them, the pad cut to the limit)');
  return { A, A1: Math.max(A1, 0), A2: Math.max(A2, 0), A41, A5: Math.max(A5, 0), available: avail, ok: avail >= A, margin: avail / A - 1, limits: lim, source: SOURCES.nozzle, notes };
}

Saddle bending stresses

64-bit

Longitudinal bending moments and stresses of a horizontal vessel on two saddles.

M₁ = Q·a·(1 − (1 − a ÷ L + (R² − H²) ÷ 2aL) ÷ (1 + 4H ÷ 3L)); σ = M ÷ (π·R²·t)

64-bit closed forms. The saddle moment is formed as 1 minus a ratio, so it loses digits whenever that ratio is close to 1.

  • process/equip/vessel.js
  • lines 82 to 89
  • CadCraft 0.8.2
/** Horizontal vessel on two saddles (Zick). W total weight (N), L tangent-to-tangent length, R mean radius, H head depth, a saddle distance from the tangent line, t shell thickness. → stresses in MPa. */
export function saddle({ W, L, R, H, a, t }) {
  const Q = W / 2, k = (R * R - H * H) / (2 * a * L);
  const M1 = Q * a * (1 - (1 - a / L + k) / (1 + 4 * H / (3 * L)));
  const M2 = Q * L / 4 * ((1 + 2 * (R * R - H * H) / (L * L)) / (1 + 4 * H / (3 * L)) - 4 * a / L);
  const s1 = M1 / (Math.PI * R * R * t), s2 = M2 / (Math.PI * R * R * t);
  return { M1, M2, sigmaSaddle: s1, sigmaMid: s2, notes: ['a / R should be at most 0.5 (head stiffening at the saddle); circumferential and web stresses are not included'], source: SOURCES.saddle };
}

Wind velocity pressure

64-bit

The wind pressure on a vessel from the wind speed.

q = 0.613 × Kz × Kzt × Kd × V² × I

One product. The coefficient 0.613 is the three-digit value the cited standard uses.

  • process/equip/vessel.js
  • lines 90 to 91
  • CadCraft 0.8.2
/** Wind velocity pressure (N/m²). */
export const windPressure = ({ V, Kz = 1, Kzt = 1, Kd = 0.95, I = 1 }) => 0.613 * Kz * Kzt * Kd * V * V * I;

Wind force and overturning moment

64-bit

The wind force on a vertical vessel and its moment at the base.

F = q × 10⁻⁶ × Cf × D × H; M = F × H ÷ 2

The pressure is converted from N/m² to N/mm² by multiplying by 1e-6, then a chain of products.

  • process/equip/vessel.js
  • lines 99 to 100
  • CadCraft 0.8.2
/** Wind overturning of a vertical vessel: F = q Cf D_eff H, moment at the base F H/2 (uniform pressure). Units N, mm. */
export const windOnVessel = ({ q, Cf = 0.7, D, H }) => { const F = q * 1e-6 * Cf * D * H; return { F, M: F * H / 2 }; };

Seismic base shear and moment

64-bit

A first estimate of the seismic shear and overturning moment.

V = Cs × W; M = Cs × W × 2H ÷ 3

Two 64-bit products; the overturning arm is two thirds of the height.

  • process/equip/vessel.js
  • lines 92 to 93
  • CadCraft 0.8.2
/** Static seismic base shear (N) = Cs W; overturning at 2/3 of the height as a first estimate. */
export const seismicBase = ({ Cs, W, H }) => ({ V: Cs * W, M: Cs * W * 2 * H / 3 });

Skirt stresses

64-bit

Compressive and tensile stress at the base of a skirt from weight and overturning.

A = π·D·t; Z = π·D²·t ÷ 4; σ = M ÷ Z ± W ÷ A

Thin-ring area and section modulus, then a sum and a difference of the two stress parts.

  • process/equip/vessel.js
  • lines 94 to 98
  • CadCraft 0.8.2
/** Skirt-supported vertical vessel: compressive stress at the skirt-to-shell junction from weight + overturning, and the tension side. D outside mean diameter (mm), t skirt thickness. */
export function skirt({ W, M, D, t }) {
  const A = Math.PI * D * t, Z = Math.PI * D * D * t / 4;
  return { sigmaComp: W / A + M / Z, sigmaTens: M / Z - W / A, notes: ['buckling allowable of the skirt (ASME / Brownell & Young) is the engineer\'s: not computed'] };
}

Flat head thickness

64-bit

The required thickness of a circular flat head or cover.

t = d × √(C·P ÷ (S·E))

One expression. The attachment factor C defaults to 0.33 and a note asks for the real value.

  • process/equip/vessel.js
  • lines 109 to 114
  • CadCraft 0.8.2
/** Flat head or cover, UG-34(c)(2) (circular, attachment factor C from Figure UG-34, the caller's): t = d sqrt(C P / (S E)) + corrosion allowance. d diameter mm, P MPa, S MPa. */
export function flatHead({ P, d, S, E = 1, C = 0.33, ca = 0 }) {
  SC(S, 'S'); SC(E, 'E'); SC(C, 'C');
  const t = d * Math.sqrt(C * P / (S * E));
  return { t, tMin: t + ca, C, notes: C === 0.33 ? ['C = 0.33 is the plain-plate value; the attachment detail of Figure UG-34 sets the real C (0.17 to 0.33 and others): give it'] : [], source: 'ASME VIII-1 UG-34(c)(2), t = d sqrt(C P / S E)' };
}

Minimum design metal temperature

64-bit

The stress ratio and the temperature reduction read from points a person types.

ratio = tr·E ÷ (tn − c); MDMT = base − ΔT(ratio)

The reduction is a straight-line interpolation between the typed points. A ratio at or below 0.35 returns −105 °C, which the code marks as typed from memory.

  • process/equip/vessel.js
  • lines 116 to 133
  • CadCraft 0.8.2
/**
 * Minimum design metal temperature (MDMT), UCS-66, with the figures left to the person. The base temperature of the material curve (Figure UCS-66, curves A to D, by thickness) and the
 * temperature reduction against the stress ratio (Figure UCS-66.1) are READ FROM THE BOOK by the caller: `baseMDMT` in °C, `reduction` = [[ratio, deltaT °C], …] ascending in ratio.
 * This function forms the ratio  tr E* / (tn − c)  (UCS-66(b)(1)(b)), interpolates the reduction and subtracts it. A ratio at or below 0.35 is the UCS-66(b)(3) exemption
 * (−105 °C; typed from memory: check it). Nothing is looked up for you and a missing figure is said, never guessed.
 */
export function mdmt({ baseMDMT = null, tr, tn, E = 1, ca = 0, reduction = null }) {
  const ratio = tr * E / (tn - ca), notes = [], src = 'ASME VIII-1 UCS-66(b)';
  if (!(tn - ca > 0) || !(tr > 0)) throw new Error('give the required thickness tr and the nominal thickness tn (> corrosion allowance)');
  if (ratio <= 0.35) return { ratio, mdmt: -105, exempt: true, notes: ['stress ratio ≤ 0.35: UCS-66(b)(3) lets the MDMT go to −105 °C without impact testing (typed from memory: check against the book)'], source: src };
  if (!Array.isArray(reduction) || reduction.length < 2 || baseMDMT == null) return { ratio, mdmt: null, exempt: false, notes: ['type the base temperature of the material curve (Figure UCS-66) and the reduction points of Figure UCS-66.1 as [[ratio, deltaT °C], …]; none are built in'], source: src };
  const pts = reduction.slice().sort((a, b) => a[0] - b[0]);
  if (ratio > pts[pts.length - 1][0]) return { ratio, mdmt: baseMDMT, exempt: false, notes: ['the ratio is above the last reduction point: no reduction is taken'], source: src };
  let dT = pts[0][1];
  if (ratio >= pts[0][0]) { for (let k = 0; k + 1 < pts.length; k++) if (ratio >= pts[k][0] && ratio <= pts[k + 1][0]) { const f = (ratio - pts[k][0]) / ((pts[k + 1][0] - pts[k][0]) || 1); dT = pts[k][1] + f * (pts[k + 1][1] - pts[k][1]); break; } }
  else notes.push('the ratio is below the first reduction point: the first reduction is used');
  return { ratio, mdmt: baseMDMT - dT, reduction: dT, exempt: false, notes, source: src };
}

Data sheet values

64-bit

The rows and text of the vessel data sheet.

Required thicknesses are written with toFixed(2) and the pressures with toFixed(3), in both the rows and the text; the other values are passed through as given.

  • process/equip/vessel.js
  • lines 102 to 107
  • CadCraft 0.8.2
/** Data sheet: rows of label / value / unit + the lines every sheet must carry. */
export function dataSheet(spec) {
  const rows = [['Design pressure', spec.P, 'MPa'], ['Design temperature', spec.T, '°C'], ['Inside diameter', spec.D, 'mm'], ['Shell thickness required', spec.shellT?.toFixed(2), 'mm'], ['Shell thickness provided (nominal)', spec.tNom, 'mm'], ['Corrosion allowance', spec.ca, 'mm'], ['Allowable stress S', spec.S, 'MPa'], ['Joint efficiency E', spec.E, ''], ['Head', spec.headType, ''], ['Head thickness required', spec.headT?.toFixed(2), 'mm'], ['MAWP (corroded)', spec.mawp?.toFixed(3), 'MPa'], ['Hydrotest pressure', spec.hydro?.toFixed(3), 'MPa']];
  const text = rows.map(([a, b, c]) => `${a}: ${b ?? '-'} ${c}`).join('\n') + '\n\nDrafting and study aid, not an engineering approval. To be checked by an engineer. No representation of ASME Code compliance; no U-stamp. Allowable stress and materials are the user\'s input.';
  return { rows, text, problems: [] };
}

Equipment parameters for the plant model

64-bit

The diameter, length and support height handed to the plant equipment.

Diameter, length and support height are rounded to whole millimeters with Math.round before they are handed over.

  • process/equip/vessel.js
  • lines 166 to 169
  • CadCraft 0.8.2
/** The vessel as BimCraft Plant equipment: its type and dimension parameters (mm). */
export function plantParams({ orientation = 'vertical', D, L, support }) {
  return orientation === 'horizontal' ? { type: 'vessel-h', params: { d: Math.round(D), len: Math.round(L), leg: Math.round(support || 500) } } : { type: 'vessel-v', params: { d: Math.round(D), h: Math.round(L), leg: Math.round(support || 600) } };
}
process/equip/vessel2.js CadCraft 0.8.2 64-bit 2 calculations Reviewed

Tests tools/process-test/test-chem4.mjs

External pressure from chart factors

64-bit

The allowable external pressure of a cylinder from the chart factor A and the material curve a person types.

chart: P_a = 4B ÷ (3·D_o ÷ t); elastic: P_a = 2A·E ÷ (3·D_o ÷ t)

B is interpolated linearly against ln A between the two typed points that bracket A, so the result is as fine as the typed curve. Beyond the last point the last B is used and a note says so.

  • process/equip/vessel2.js
  • lines 14 to 32
  • CadCraft 0.8.2
export function externalPressure({ Do, t, A, curve = null, E = null }) {
  const ratio = Do / t, notes = [];
  if (!(Do > 0 && t > 0 && A > 0)) throw new Error('give Do, t and the chart factor A');
  if (!Array.isArray(curve) || curve.length < 2) {
    if (E) return { Pa: 2 * A * E / (3 * ratio), B: null, region: 'elastic', notes: ['elastic range assumed (left of the curve) with the given E; give the material chart curve for the real answer'], needsSource: NEEDS_SOURCE };
    return { Pa: null, B: null, notes: ['give the material chart curve [[A, B], …] for the design temperature (or E for the elastic line)'], needsSource: NEEDS_SOURCE };
  }
  const pts = curve.slice().sort((a, b) => a[0] - b[0]);
  if (A <= pts[0][0]) {
    if (!E) return { Pa: null, B: null, notes: ['A is left of the curve: give E (the modulus at the temperature) for Pa = 2AE/(3 Do/t)'], needsSource: NEEDS_SOURCE };
    return { Pa: 2 * A * E / (3 * ratio), B: null, region: 'elastic', notes, source: 'ASME VIII-1 UG-28(c)(2)' };
  }
  if (A >= pts[pts.length - 1][0]) { notes.push('A is beyond the last chart point: the last B is used (flat)'); return { Pa: 4 * pts[pts.length - 1][1] / (3 * ratio), B: pts[pts.length - 1][1], region: 'chart', notes, source: 'ASME VIII-1 UG-28(c)(1)' }; }
  for (let k = 0; k + 1 < pts.length; k++) if (A >= pts[k][0] && A <= pts[k + 1][0]) {
    const f = (Math.log(A) - Math.log(pts[k][0])) / (Math.log(pts[k + 1][0]) - Math.log(pts[k][0])), B = pts[k][1] + f * (pts[k + 1][1] - pts[k][1]);
    return { Pa: 4 * B / (3 * ratio), B, region: 'chart', notes, source: 'ASME VIII-1 UG-28(c)(1)' };
  }
  return { Pa: null, B: null, notes: ['chart not readable'], needsSource: NEEDS_SOURCE };
}

Stiffening ring inertia

64-bit

The moment of inertia a stiffening ring must have.

I_s = D_o² × L_s × (t + A_s ÷ L_s) × A ÷ 14

One 64-bit expression of products and one division by 14; the check against a given ring inertia is a plain comparison.

  • process/equip/vessel2.js
  • lines 33 to 36
  • CadCraft 0.8.2
export function stiffeningRing({ Do, Ls, t, As, A, Is = null }) {
  const req = Do * Do * Ls * (t + As / Ls) * A / 14;
  return { Is_required: req, ok: Is == null ? null : Is >= req, source: 'ASME VIII-1 UG-29(a), Is = Do² Ls (t + As/Ls) A / 14', notes: Is == null ? ['give the ring section moment of inertia Is to check it'] : [] };
}

In detail

Method
Thickness, reinforcement and external-pressure equations the files attribute to ASME VIII-1 (UG-27, UG-28, UG-29, UG-32, UG-34, UG-37, UG-40, UCS-66), Zick's saddle analysis, and the ASCE 7-10 velocity pressure, as listed in the files' SOURCES.
Number types
64-bit numbers. Units mm, MPa, N.
Tolerances
Thin-wall note when P > 0.385·S·E. Stress-ratio exemption at ratio ≤ 0.35. External-pressure chart: linear in B against log A between typed points, flat beyond the last point.
Limits
External pressure by the classical elastic formulas is flagged when the buckling stress exceeds half the yield strength. The material charts are not built in.

Approach: 64-bit, direct

Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.

Every policy that takes this approach