Remove concrete-beam2 and unused shore-post-brace assets

This commit is contained in:
smillmorel 2026-09-21 12:33:13 -04:00
commit 27a9cdd707
10 changed files with 0 additions and 1963 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

View file

@ -1,82 +0,0 @@
#let navy = rgb("#1a3a5f")
#let muted = rgb("#626b73")
#let pass = rgb("#1f6b45")
#let fail = rgb("#9b2c2c")
#let calcsheet(
title: "Structural Calculation",
project: "",
prepared-by: "",
body,
) = {
set document(title: title, author: prepared-by)
set page(
paper: "us-letter",
margin: (x: 1in, top: 1.25in, bottom: 1in),
header: context {
grid(
columns: (1fr, 1fr),
align: (left, right),
image("../assets/logo.png", height: 30pt),
[#text(size: 9pt)[Project:] \
#text(size: 10pt, weight: "bold")[#project]],
)
},
footer: context {
set text(size: 8.5pt, fill: muted)
stack(
spacing: 4pt,
line(length: 100%, stroke: 0.5pt + muted),
[#prepared-by],
)
},
)
set text(font: "Libertinus Serif", size: 10pt, lang: "en")
set par(justify: true)
set heading(numbering: none)
show heading.where(level: 1): set text(size: 14pt, weight: "bold", fill: black)
show heading.where(level: 2): set text(size: 11pt, weight: "bold", fill: black)
show heading.where(level: 2): set block(above: 2em, below: 1em)
body
}
#let calcline(formula, note) = grid(
columns: (1.7fr, 1fr),
gutter: 4pt,
align: (left, left),
formula, text(size: 9pt, fill: muted, note),
)
#let check(label, demand, capacity, unit: "", ok: auto, demand-label: "Demand", capacity-label: "Capacity") = {
let utilization = demand / capacity
let passes = if ok == auto { utilization <= 1 } else { ok }
let color = if passes { pass } else { fail }
block(
breakable: false,
width: 100%,
stroke: 0.8pt + black,
inset: 8pt,
radius: 2pt,
)[
#grid(
columns: (1fr, auto),
[#text(weight: "bold")[#label]],
box(stroke: 0.8pt + color, inset: (x: 6pt, y: 2pt))[
#text(weight: "bold", fill: color)[#if passes { "OK" } else { "NOT OK" }]
],
)
#v(4pt)
#grid(
columns: (1fr, auto),
[
#demand-label: #calc.round(demand, digits: 2) #unit #h(14pt)
#capacity-label: #calc.round(capacity, digits: 2) #unit
],
[
D/C: #calc.round(utilization, digits: 2)
],
)
]
}

View file

@ -1,154 +0,0 @@
from __future__ import annotations
import json
import math
import sys
from pathlib import Path
try:
import yaml
except ImportError:
raise SystemExit("Install PyYAML: python -m pip install pyyaml")
try:
from pint import DimensionalityError, UndefinedUnitError, UnitRegistry
except ImportError:
raise SystemExit("Install Pint: python -m pip install pint")
HERE = Path(__file__).resolve().parent
ureg = UnitRegistry()
ureg.define("kip = 1000 * force_pound")
ureg.define("ksi = kip / inch ** 2")
ureg.define("klf = kip / foot")
if "psf" not in ureg:
ureg.define("psf = force_pound / foot ** 2")
if "pcf" not in ureg:
ureg.define("pcf = force_pound / foot ** 3")
def to_magnitude(value, unit: str, name: str) -> float:
try:
quantity = ureg.Quantity(value)
except (UndefinedUnitError, ValueError, TypeError) as exc:
raise ValueError(f"{name}: cannot parse {value!r}") from exc
try:
magnitude = float(quantity.to(unit).magnitude)
except DimensionalityError as exc:
raise ValueError(f"{name}: expected {unit}, got {value!r}") from exc
if magnitude <= 0:
raise ValueError(f"{name} must be positive")
return magnitude
def compute(inp: dict) -> dict:
span_ft = to_magnitude(inp["span"], "ft", "span")
tributary_ft = to_magnitude(inp["tributary"], "ft", "tributary")
D_psf = to_magnitude(inp["D"], "psf", "D")
L_psf = to_magnitude(inp["L"], "psf", "L")
bw_in = to_magnitude(inp["bw"], "in", "bw")
h_in = to_magnitude(inp["h"], "in", "h")
d_in = to_magnitude(inp["d"], "in", "d")
fc_ksi = to_magnitude(inp["fc"], "ksi", "fc")
fy_ksi = to_magnitude(inp["fy"], "ksi", "fy")
As_in2 = to_magnitude(inp["As"], "in**2", "As")
concrete_pcf = to_magnitude(inp["concrete_density"], "pcf", "concrete_density")
self_weight_klf = (bw_in * h_in / 144.0) * concrete_pcf / 1000.0
wD_klf = D_psf * tributary_ft / 1000.0 + self_weight_klf
wL_klf = L_psf * tributary_ft / 1000.0
wu_klf = 1.2 * wD_klf + 1.6 * wL_klf
Mu_kipft = wu_klf * span_ft**2 / 8.0
Vu_kip = wu_klf * span_ft / 2.0
fc_psi = fc_ksi * 1000.0
fy_psi = fy_ksi * 1000.0
a_in = As_in2 * fy_ksi / (0.85 * fc_ksi * bw_in)
beta1 = max(0.65, min(0.85, 0.85 - 0.05 * max(0.0, (fc_psi - 4000.0) / 1000.0)))
c_in = a_in / beta1
et = 0.003 * (d_in - c_in) / c_in if c_in > 0 else 0.0
if et >= 0.005:
phi = 0.90
else:
phi = max(0.65, min(0.90, 0.65 + (et - 0.002) * 250.0 / 3.0))
Mn_kipft = As_in2 * fy_ksi * (d_in - a_in / 2.0) / 12.0
phiMn_kipft = phi * Mn_kipft
rho_min = max(3.0 * math.sqrt(fc_psi) / fy_psi, 200.0 / fy_psi)
As_min_in2 = rho_min * bw_in * d_in
Vc_kip = 2.0 * math.sqrt(fc_psi) * bw_in * d_in / 1000.0
phiVc_kip = 0.75 * Vc_kip
def q(value: float) -> float:
return round(value, 6)
return {
"tool": "concrete_beam2",
"version": "0.1",
"project": inp.get("project", ""),
"prepared_by": inp.get("prepared_by", ""),
"values": {
"span_ft": q(span_ft),
"tributary_ft": q(tributary_ft),
"D_psf": q(D_psf),
"L_psf": q(L_psf),
"self_weight_klf": q(self_weight_klf),
"wD_klf": q(wD_klf),
"wL_klf": q(wL_klf),
"wu_klf": q(wu_klf),
"Mu_kipft": q(Mu_kipft),
"Vu_kip": q(Vu_kip),
"bw_in": q(bw_in),
"h_in": q(h_in),
"d_in": q(d_in),
"fc_ksi": q(fc_ksi),
"fy_ksi": q(fy_ksi),
"As_in2": q(As_in2),
"a_in": q(a_in),
"et": q(et),
"phi": q(phi),
"Mn_kipft": q(Mn_kipft),
"phiMn_kipft": q(phiMn_kipft),
"As_min_in2": q(As_min_in2),
"Vc_kip": q(Vc_kip),
"phiVc_kip": q(phiVc_kip),
},
"checks": {
"flexure": {
"demand": q(Mu_kipft),
"capacity": q(phiMn_kipft),
"ok": Mu_kipft <= phiMn_kipft,
},
"minimum_steel": {
"demand": q(As_min_in2),
"capacity": q(As_in2),
"ok": As_in2 >= As_min_in2,
},
"shear": {
"demand": q(Vu_kip),
"capacity": q(phiVc_kip),
"ok": Vu_kip <= phiVc_kip,
},
},
}
def write_results(result: dict, path: Path) -> None:
path.write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
def main() -> int:
input_path = Path(sys.argv[1]) if len(sys.argv) > 1 else HERE / "input.yaml"
output_path = Path(sys.argv[2]) if len(sys.argv) > 2 else input_path.with_name("results.json")
with input_path.open(encoding="utf-8") as handle:
inp = yaml.safe_load(handle)
result = compute(inp)
write_results(result, output_path)
print(output_path)
return 0
if __name__ == "__main__":
raise SystemExit(main())

File diff suppressed because it is too large Load diff

View file

@ -1,119 +0,0 @@
#import "assets/sheet.typ": calcline, calcsheet, check
#let data = json("results.json")
#let n = data.values
#let checks = data.checks
#let round(value, digits: 2) = calc.round(value, digits: digits)
#show: calcsheet.with(
title: "Concrete Beam Analysis",
project: data.project,
prepared-by: data.prepared_by,
)
= Reinforced Concrete Beam
Simple-span rectangular beam under uniform gravity load. YAML quantities are converted by Pint in `calc.py`. This sheet only presents the results.
#let beam-sketch = {
set align(center)
box(width: 82%, inset: (y: 8pt))[
#line(length: 100%, stroke: 1.4pt)
#v(-7.5pt)
#grid(
columns: (auto, 1fr, auto),
align: (left, center, right),
polygon(fill: black, (0pt, 0pt), (8pt, 10pt), (-8pt, 10pt)),
text(size: 9pt)[$w_u$ uniform factored load],
polygon(fill: black, (0pt, 0pt), (8pt, 10pt), (-8pt, 10pt)),
)
#v(2pt)
#text(size: 9pt)[#n.span_ft ft simple span · #n.bw_in in × #n.h_in in section]
]
}
#figure(
beam-sketch,
caption: [#n.span_ft ft simply supported beam, #n.bw_in in × #n.h_in in rectangular section.],
)
== Loads and Beam Demand
#calcline([$L = #n.span_ft " ft"$], [Simple span])
#calcline([$B_t = #n.tributary_ft " ft"$], [Tributary width])
#calcline([$D = #n.D_psf " psf"$], [Dead load including superimposed dead])
#calcline([$L_L = #n.L_psf " psf"$], [Live load])
#calcline([$w_("sw") = #round(n.self_weight_klf, digits: 3) " kip/ft"$], [Beam self-weight])
#calcline(
[$w_u = 1.2 w_D + 1.6 w_L = #round(n.wu_klf, digits: 3) " kip/ft"$],
[Factored uniform line load],
)
#calcline(
[$M_u = w_u L^2 / 8 = #round(n.Mu_kipft) " kip·ft"$],
[Maximum positive moment],
)
#calcline(
[$V_u = w_u L / 2 = #round(n.Vu_kip) " kip"$],
[Support shear],
)
== Flexural Strength
#calcline([$b_w = #n.bw_in " in"$], [Beam width])
#calcline([$h = #n.h_in " in"$], [Overall depth])
#calcline([$d = #n.d_in " in"$], [Effective depth])
#calcline([$f'_c = #n.fc_ksi " ksi"$], [Concrete compressive strength])
#calcline([$f_y = #n.fy_ksi " ksi"$], [Steel yield strength])
#calcline([$A_s = #n.As_in2 " in"^2$], [Provided tension steel (2 No. 5)])
#calcline(
[$a = A_s f_y / (0.85 f'_c b_w) = #round(n.a_in, digits: 3) " in"$],
[Equivalent compression-block depth],
)
#calcline([$epsilon_t = #round(n.et, digits: 4)$], [Net tensile strain])
#calcline([$phi = #round(n.phi, digits: 2)$], [Strength reduction factor])
#calcline(
[$phi M_n = phi A_s f_y (d - a/2) = #round(n.phiMn_kipft) " kip·ft"$],
[Design flexural strength],
)
#v(7pt)
#check(
"Flexural strength",
checks.flexure.demand,
checks.flexure.capacity,
unit: "kip·ft",
ok: checks.flexure.ok,
demand-label: [$M_u$],
capacity-label: [$phi M_n$],
)
== Minimum Steel and Concrete Shear
#calcline([$A_("s,min") = #round(n.As_min_in2, digits: 3) " in"^2$], [Minimum longitudinal steel])
#calcline([$A_("s,prov") = #round(n.As_in2, digits: 3) " in"^2$], [Provided longitudinal steel])
#v(7pt)
#check(
"Minimum longitudinal reinforcement",
checks.minimum_steel.demand,
checks.minimum_steel.capacity,
unit: "in²",
ok: checks.minimum_steel.ok,
demand-label: [$A_("s,min")$],
capacity-label: [$A_("s,prov")$],
)
#v(10pt)
#calcline([$V_c = 2 sqrt(f'_c) b_w d = #round(n.Vc_kip) " kip"$], [Concrete shear strength])
#calcline([$phi V_c = #round(n.phiVc_kip) " kip"$], [Design concrete shear strength])
#v(7pt)
#check(
"Concrete shear",
checks.shear.demand,
checks.shear.capacity,
unit: "kip",
ok: checks.shear.ok,
demand-label: [$V_u$],
capacity-label: [$phi V_c$],
)

View file

@ -1,15 +0,0 @@
project: "Deer Creek Shoring"
prepared_by: "Conemco Engineering"
span: "16 ft"
tributary: "6.25 ft"
D: "55 psf"
L: "20 psf"
bw: "8 in"
h: "12 in"
d: "1 ft"
fc: "3000 psi"
fy: "50000 psi"
As: "0.62 in^2"
concrete_density: "150 pcf"
load_combination: "1.2D + 1.6L"

View file

@ -1,49 +0,0 @@
{
"tool": "concrete_beam2",
"version": "0.1",
"project": "Deer Creek Shoring",
"prepared_by": "Conemco Engineering",
"values": {
"span_ft": 16.0,
"tributary_ft": 6.25,
"D_psf": 55.0,
"L_psf": 20.0,
"self_weight_klf": 0.1,
"wD_klf": 0.44375,
"wL_klf": 0.125,
"wu_klf": 0.7325,
"Mu_kipft": 23.44,
"Vu_kip": 5.86,
"bw_in": 8.0,
"h_in": 12.0,
"d_in": 12.0,
"fc_ksi": 3.0,
"fy_ksi": 50.0,
"As_in2": 0.62,
"a_in": 1.519608,
"et": 0.017137,
"phi": 0.9,
"Mn_kipft": 29.037173,
"phiMn_kipft": 26.133456,
"As_min_in2": 0.384,
"Vc_kip": 10.516273,
"phiVc_kip": 7.887205
},
"checks": {
"flexure": {
"demand": 23.44,
"capacity": 26.133456,
"ok": true
},
"minimum_steel": {
"demand": 0.384,
"capacity": 0.62,
"ok": true
},
"shear": {
"demand": 5.86,
"capacity": 7.887205,
"ok": true
}
}
}

View file

@ -1,70 +0,0 @@
from pathlib import Path
import importlib.util
import pytest
import yaml
HERE = Path(__file__).resolve().parent
spec = importlib.util.spec_from_file_location("concrete_beam2_calc", HERE / "calc.py")
assert spec is not None and spec.loader is not None
calc_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(calc_module)
compute = calc_module.compute
def load_input():
with (HERE / "input.yaml").open(encoding="utf-8") as handle:
return yaml.safe_load(handle)
@pytest.fixture
def result():
return compute(load_input())
def test_example_demands(result):
v = result["values"]
assert v["self_weight_klf"] == pytest.approx(0.1)
assert v["wu_klf"] == pytest.approx(0.7325)
assert v["Mu_kipft"] == pytest.approx(23.44)
assert v["Vu_kip"] == pytest.approx(5.86)
def test_example_flexure(result):
v = result["values"]
assert v["a_in"] == pytest.approx(1.519608, rel=1e-5)
assert v["et"] == pytest.approx(0.017137, rel=1e-3)
assert v["phi"] == pytest.approx(0.9)
assert v["phiMn_kipft"] == pytest.approx(26.133456, rel=1e-5)
assert result["checks"]["flexure"]["ok"] is True
def test_example_min_steel_and_shear(result):
v = result["values"]
assert v["As_min_in2"] == pytest.approx(0.384, rel=1e-4)
assert v["phiVc_kip"] == pytest.approx(7.887205, rel=1e-4)
assert result["checks"]["minimum_steel"]["ok"] is True
assert result["checks"]["shear"]["ok"] is True
def test_alternate_units_match_default(result):
alt = load_input()
alt.update(
{
"span": "192 in",
"tributary": "75 in",
"fc": "3000 psi",
}
)
converted = compute(alt)
for key in ("span_ft", "tributary_ft", "fc_ksi", "Mu_kipft", "phiMn_kipft", "Vu_kip"):
assert converted["values"][key] == pytest.approx(result["values"][key], rel=1e-6)
def test_wrong_dimension_is_rejected():
bad = load_input()
bad["span"] = "16 kip"
with pytest.raises(ValueError, match="span"):
compute(bad)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

View file

@ -1,82 +0,0 @@
#let navy = rgb("#1a3a5f")
#let muted = rgb("#626b73")
#let pass = rgb("#1f6b45")
#let fail = rgb("#9b2c2c")
#let calcsheet(
title: "Structural Calculation",
project: "",
prepared-by: "",
body,
) = {
set document(title: title, author: prepared-by)
set page(
paper: "us-letter",
margin: (x: 1in, top: 1.25in, bottom: 1in),
header: context {
grid(
columns: (1fr, 1fr),
align: (left, right),
image("../assets/logo.png", height: 30pt),
[#text(size: 9pt)[Project:] \
#text(size: 10pt, weight: "bold")[#project]],
)
},
footer: context {
set text(size: 8.5pt, fill: muted)
stack(
spacing: 4pt,
line(length: 100%, stroke: 0.5pt + muted),
[#prepared-by],
)
},
)
set text(font: "Libertinus Serif", size: 10pt, lang: "en")
set par(justify: true)
set heading(numbering: none)
show heading.where(level: 1): set text(size: 14pt, weight: "bold", fill: black)
show heading.where(level: 2): set text(size: 11pt, weight: "bold", fill: black)
show heading.where(level: 2): set block(above: 2em, below: 1em)
body
}
#let calcline(formula, note) = grid(
columns: (1.7fr, 1fr),
gutter: 4pt,
align: (left, left),
formula, text(size: 9pt, fill: muted, note),
)
#let check(label, demand, capacity, unit: "", ok: auto, demand-label: "Demand", capacity-label: "Capacity") = {
let utilization = demand / capacity
let passes = if ok == auto { utilization <= 1 } else { ok }
let color = if passes { pass } else { fail }
block(
breakable: false,
width: 100%,
stroke: 0.8pt + black,
inset: 8pt,
radius: 2pt,
)[
#grid(
columns: (1fr, auto),
[#text(weight: "bold")[#label]],
box(stroke: 0.8pt + color, inset: (x: 6pt, y: 2pt))[
#text(weight: "bold", fill: color)[#if passes { "OK" } else { "NOT OK" }]
],
)
#v(4pt)
#grid(
columns: (1fr, auto),
[
#demand-label: #calc.round(demand, digits: 2) #unit #h(14pt)
#capacity-label: #calc.round(capacity, digits: 2) #unit
],
[
D/C: #calc.round(utilization, digits: 2)
],
)
]
}