The design strengths of a rectangular reinforced concrete section in bending, shear and combined axial force and bending.
How the precision is kept
The formulas are the code's, in 64-bit numbers, with the SI coefficients the code prints. The axial force and moment diagram is a polygon through 121 sampled neutral axis depths plus the named points, and a load is checked against straight lines between them. The required steel formula subtracts nearly equal numbers for a small moment.
Open item. Compute the required steel as 2 Rn b d ÷ (fy (1 + √(1 − 2 Rn ÷ 0.85 f′c))), which is the same value without the subtraction of nearly equal numbers.
Calculations under this policy
9 calculations in 1 source file. 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.
The depth of the equivalent stress block as a share of the neutral axis depth.
0.85 for f′c ≤ 28; 0.85 − 0.05 (f′c − 28) ÷ 7; 0.65 for f′c ≥ 55
One linear expression between the two limits, with the code's own numbers.
frame/rc-aci318.js
lines 44 to 48
CadCraft 0.8.2
export function beta1(fc) {
if (fc <= 28) return 0.85;
if (fc >= 55) return 0.65;
return 0.85 - 0.05 * (fc - 28) / 7;
}
Strength reduction factor
64-bit
The factor φ for axial force and bending from the strain in the extreme tension steel.
0.90 for ε_t ≥ ε_ty + 0.003; 0.65 (0.75 spiral) for ε_t ≤ ε_ty; a straight line between
The limits are compared without a tolerance here; the flexure function adds its own 1e-12 allowance when it reports whether a section is tension-controlled.
frame/rc-aci318.js
lines 49 to 54
CadCraft 0.8.2
export function phiAxialFlexure(epsT, epsTy, spiral = false) {
const lo = spiral ? 0.75 : 0.65;
if (epsT >= epsTy + 0.003) return 0.9;
if (epsT <= epsTy) return lo;
return lo + (0.9 - lo) * (epsT - epsTy) / 0.003;
}
Square root of the concrete strength in shear
64-bit
The √f′c used in the shear formulas.
min(√f′c, 8.3)
The cap of 8.3 MPa is the code's limit in 22.5.3.1.
The nominal and design moment of a section at zero axial force, with the minimum steel and ductility tests.
c from P(c) = 0; Mn = M(c); φMn; As,min = max(0.25 √f′c ÷ fy, 1.4 ÷ fy) b d
The neutral axis comes from the bisection, so Mn carries its 1e-12 stopping tolerance. The minimum steel test allows 1e-9 mm² and the strain tests 1e-12, both absolute.
The steel area a singly reinforced section needs for a factored moment.
Rn = Mu ÷ (φ b d²); As = (0.85 f′c ÷ fy) (1 − √(1 − 2 Rn ÷ 0.85 f′c)) b d
For a small moment the square root is close to 1 and 1 − √(…) subtracts two nearly equal numbers, so the required area loses digits. A section too small for the moment returns nothing.
frame/rc-aci318.js
lines 77 to 82
CadCraft 0.8.2
export function requiredAs({ b, d, fc, fy, Mu, phi = 0.9 }) {
const Rn = Mu / (phi * b * d * d);
const disc = 1 - 2 * Rn / (0.85 * fc);
if (disc < 0) return null;
return 0.85 * fc / fy * (1 - Math.sqrt(disc)) * b * d;
}
One-way shear strength
64-bit
The concrete and stirrup contributions to shear strength, the minimum stirrups and the spacing limit.
Vc by Table 22.5.5.1 (a), (b) or (c); λs = min(1, √(2 ÷ (1 + 0.004 d))); Vs = Av fyt d ÷ s; φVn = 0.75 (Vc + Vs)
Closed-form expressions with the code's SI coefficients (0.17, 0.66, 0.42, 0.083, 0.062, 0.35). The cube root is Math.cbrt. Comparisons with limits allow 1e-9 in N, mm² or mm, absolute.
The nominal and design strength outline of a column section for bending about one axis.
(Mn, Pn) at 121 depths c from 20 h down to 0.001 h, plus the balanced, tension-controlled and P = 0 points; Po = 0.85 f′c (Ag − Ast) + fy Ast
Each point is exact strain compatibility for its depth; the outline between points is a straight line. The depths are spaced by a constant ratio. Design axial strength is capped at φ times 0.80 Po (0.85 with a spiral).
frame/rc-aci318.js
lines 108 to 133
CadCraft 0.8.2
export function interaction({ b, h, bars, layers, fc, fy, Es = ES, axis = 'y', spiral = false, n = 120 }) {
const m = material({ fc, fy, Es });
const L = layers ? { depth: h, width: b, layers } : layersFor({ b, h, bars }, axis, 1);
const Ast = L.layers.reduce((s, l) => s + l.As, 0), Ag = b * h;
const Po = 0.85 * fc * (Ag - Ast) + fy * Ast;
const PnMax = (spiral ? 0.85 : 0.8) * Po;
const lo = spiral ? 0.75 : 0.65, epsTy = fy / m.Es;
const dt = Math.max(...L.layers.map((l) => l.d));
const pts = [];
// c from deep (nearly pure compression) to shallow, geometric, plus the named points
const cs = new Set();
for (let k = 0; k <= n; k++) cs.add(L.depth * 20 * Math.pow(1e-3 / 20, k / n));
cs.add(dt * 0.003 / (0.003 + epsTy)); // balanced (εt = εty)
cs.add(dt * 0.003 / (0.006 + epsTy)); // tension-controlled limit (εt = εty + 0.003)
const c0 = neutralAxisForP(L, 0, m);
if (c0) cs.add(c0);
for (const c of [...cs].sort((x, y) => y - x)) {
const f = forcesAt(L, c, m);
const phi = phiAxialFlexure(f.epsT, epsTy, spiral);
pts.push({ c, Pn: f.P, Mn: f.M, phi, phiPn: Math.min(phi * f.P, lo * PnMax), phiMn: phi * f.M, epsT: f.epsT, capped: phi * f.P > lo * PnMax });
}
const Pnt = -fy * Ast;
pts.push({ c: 0, Pn: Pnt, Mn: 0, phi: 0.9, phiPn: 0.9 * Pnt, phiMn: 0, epsT: Infinity, capped: false });
return { points: pts, Po, PnMax, phiPnMax: lo * PnMax, Pnt, phiPnt: 0.9 * Pnt, Ast, Ag, axis, spiral,
clauses: ['ACI 318-19 22.4.2.1', 'ACI 318-19 22.4.2.2', 'ACI 318-19 22.4.3.1', 'ACI 318-19 Table 21.2.2', 'ACI 318-19 22.2'] };
}
Utilization on the diagram
64-bit
How far a factored axial force and moment are along the ray from the origin to the diagram.
ratio = √(Mu² + Pu²) ÷ t, t = where the ray meets the outline
The ray's direction is rebuilt from the angle atan2(Pu, Mu) with a cosine and a sine. A segment nearly parallel to the ray is skipped when the cross product is below 1e-18, an absolute limit. A load below 1e-12 in size returns 0.
frame/rc-aci318.js
lines 135 to 152
CadCraft 0.8.2
/** Utilisation of (Pu, Mu) against the φ diagram: |(Mu, Pu)| over the distance to the diagram along the same ray. */
export function pmRatio(D, Pu, Mu) {
const M = Math.abs(Mu);
// the closed φ outline: (0, φPn,max cap) … (φMn, φPn) … (0, φPnt), polar about the origin
const poly = [{ x: 0, y: D.phiPnMax }, ...D.points.map((p) => ({ x: p.phiMn, y: p.phiPn }))];
if (Math.hypot(M, Pu) < 1e-12) return 0;
const ang = Math.atan2(Pu, M);
for (let k = 0; k + 1 < poly.length; k++) {
const A = poly[k], B = poly[k + 1];
// ray t·(cos, sin) meets segment A + s (B − A)
const dx = Math.cos(ang), dy = Math.sin(ang), ex = B.x - A.x, ey = B.y - A.y;
const den = dx * ey - dy * ex;
if (Math.abs(den) < 1e-18) continue;
const t = (A.x * ey - A.y * ex) / den, s = (A.x * dy - A.y * dx) / den;
if (t > 0 && s >= -1e-12 && s <= 1 + 1e-12) return Math.hypot(M, Pu) / t;
}
return Infinity;
}
Threshold torsion
64-bit
The torque above which torsion would have to be designed for.
ACI 318-19 (SI): 22.2 strain compatibility, Table 21.2.2 strength reduction, 22.4 axial strength, 9.6.1.2 minimum steel, 22.5 one-way shear, 22.7.4.1 threshold torsion. Each result carries its clauses.
Number types
64-bit numbers. Units mm, N, MPa, N·mm.
Tolerances
Comparisons allow 1e-9 on areas, forces and spacings and 1e-12 on strains (absolute). The ray test on the diagram skips a segment when the cross product is below 1e-18 and accepts a hit within 1e-12 of a segment's ends.
Limits
Rectangular nonprestressed sections. √f′c is capped at 8.3 MPa in shear. Between two sampled points the diagram is a straight line.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.