Add structural calculation worksheets
Collection of engineering calculation projects (Python + Typst), each with input, calc script, tests, results, and generated PDF where available.
This commit is contained in:
commit
d5ac3fca7e
81 changed files with 18668 additions and 0 deletions
BIN
wood-stud-column/assets/logo.png
Executable file
BIN
wood-stud-column/assets/logo.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
82
wood-stud-column/assets/sheet.typ
Normal file
82
wood-stud-column/assets/sheet.typ
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#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)
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
163
wood-stud-column/calc.py
Normal file
163
wood-stud-column/calc.py
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import math
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
raise SystemExit("Install dependencies: python -m pip install -r requirements.txt")
|
||||
|
||||
try:
|
||||
from pint import DimensionalityError, UndefinedUnitError, UnitRegistry
|
||||
except ImportError:
|
||||
raise SystemExit("Install dependencies: python -m pip install -r requirements.txt")
|
||||
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
ureg = UnitRegistry()
|
||||
ureg.define("kip = 1000 * force_pound")
|
||||
ureg.define("ksi = kip / inch ** 2")
|
||||
ureg.define("psi = force_pound / inch ** 2")
|
||||
|
||||
|
||||
def quantity(value, unit: str, name: str) -> float:
|
||||
try:
|
||||
q = ureg.Quantity(value).to(unit)
|
||||
except (DimensionalityError, UndefinedUnitError, TypeError, ValueError) as exc:
|
||||
raise ValueError(f"{name}: expected {unit}, got {value!r}") from exc
|
||||
magnitude = float(q.magnitude)
|
||||
if magnitude <= 0:
|
||||
raise ValueError(f"{name} must be positive")
|
||||
return magnitude
|
||||
|
||||
|
||||
def factor(value, name: str) -> float:
|
||||
magnitude = float(value)
|
||||
if magnitude <= 0:
|
||||
raise ValueError(f"{name} must be positive")
|
||||
return magnitude
|
||||
|
||||
|
||||
# NDS 2018 constants for sawn-lumber columns (NDS 3.7.1.5, Eqs. 3.7-1 and 3.7-2).
|
||||
KC_EULER = 0.822 # Euler buckling coefficient for a rectangular section about its
|
||||
# weak axis (pi^2 / 12); appears directly in Eq. 3.7-2.
|
||||
C_SAWN = 0.8 # Column-stability denominator coefficient c for sawn lumber
|
||||
# (Eq. 3.7-1). c = 0.85 for round timber, 0.9 for glulam/SCL/CLT.
|
||||
|
||||
|
||||
def _column_stability_factor(Fc_star: float, Emin_prime: float, Le: float, d: float):
|
||||
"""NDS 3.7.1.5, Eq. 3.7-1 — column stability factor Cp for one buckling axis."""
|
||||
FcE = KC_EULER * Emin_prime / (Le / d) ** 2
|
||||
ratio = FcE / Fc_star
|
||||
Cp = (1.0 + ratio) / (2.0 * C_SAWN) - math.sqrt(((1.0 + ratio) / (2.0 * C_SAWN)) ** 2 - ratio / C_SAWN)
|
||||
if not math.isfinite(Cp) or Cp <= 0:
|
||||
raise ValueError(f"Cp = {Cp:.4f} is not finite/positive; column stability invalid (NDS 3.7.1.4)")
|
||||
return min(Cp, 1.0), FcE, ratio
|
||||
|
||||
|
||||
def compute(inp: dict) -> dict:
|
||||
# Geometry
|
||||
b_in = quantity(inp["width"], "in", "width")
|
||||
d_in = quantity(inp["depth"], "in", "depth")
|
||||
L_in = quantity(inp["length"], "in", "length")
|
||||
Ke = factor(inp["Ke"], "Ke")
|
||||
|
||||
# Material (NDS Supplement reference values)
|
||||
Fc_psi = quantity(inp["Fc"], "psi", "Fc")
|
||||
E_psi = quantity(inp["E"], "psi", "E")
|
||||
Emin_psi = quantity(inp["E_min"], "psi", "E_min")
|
||||
species_grade = str(inp["species_grade"])
|
||||
|
||||
# Adjustment factors (NDS Table 4.3.1)
|
||||
CD = factor(inp["CD"], "CD")
|
||||
CM = factor(inp["CM"], "CM")
|
||||
Ct = factor(inp["Ct"], "Ct")
|
||||
CF = factor(inp["CF"], "CF")
|
||||
Ci = factor(inp["Ci"], "Ci")
|
||||
|
||||
# Checked axial demand (ASD)
|
||||
P_lbf = quantity(inp["P"], "lbf", "P")
|
||||
|
||||
A_in2 = b_in * d_in
|
||||
Le_in = Ke * L_in
|
||||
d_least = min(b_in, d_in)
|
||||
d_great = max(b_in, d_in)
|
||||
|
||||
# Adjusted reference compression (without Cp), NDS 3.7.1.5
|
||||
Fc_star = Fc_psi * CD * CM * Ct * CF * Ci
|
||||
Emin_prime = Emin_psi * CM * Ct * Ci
|
||||
|
||||
# Column stability factor about each axis; the weak axis governs.
|
||||
Cp_weak, FcE_weak, ratio_weak = _column_stability_factor(Fc_star, Emin_prime, Le_in, d_least)
|
||||
Cp_strong, FcE_strong, ratio_strong = _column_stability_factor(Fc_star, Emin_prime, Le_in, d_great)
|
||||
governing_axis = "weak" if Cp_weak <= Cp_strong else "strong"
|
||||
Cp = min(Cp_weak, Cp_strong)
|
||||
FcE = FcE_weak if governing_axis == "weak" else FcE_strong
|
||||
|
||||
# Adjusted compression design value, NDS Table 4.3.1
|
||||
Fc_prime = Fc_star * Cp
|
||||
fc_psi = P_lbf / A_in2
|
||||
Pa_lbf = Fc_prime * A_in2
|
||||
|
||||
def q(value: float) -> float:
|
||||
return round(value, 6)
|
||||
|
||||
values = {
|
||||
"P_lbf": q(P_lbf),
|
||||
"L_in": q(L_in), "b_in": q(b_in), "d_in": q(d_in),
|
||||
"A_in2": q(A_in2), "Ke": q(Ke), "Le_in": q(Le_in),
|
||||
"d_least_in": q(d_least), "d_great_in": q(d_great),
|
||||
"Le_d_weak": q(Le_in / d_least), "Le_d_strong": q(Le_in / d_great),
|
||||
"species_grade": species_grade,
|
||||
"Fc_psi": q(Fc_psi), "E_psi": q(E_psi), "Emin_psi": q(Emin_psi),
|
||||
"CD": q(CD), "CM": q(CM), "Ct": q(Ct), "CF": q(CF), "Ci": q(Ci),
|
||||
"kc_euler": q(KC_EULER), "c_sawn": q(C_SAWN),
|
||||
"Fc_star_psi": q(Fc_star), "Emin_prime_psi": q(Emin_prime),
|
||||
"FcE_weak_psi": q(FcE_weak), "FcE_strong_psi": q(FcE_strong),
|
||||
"ratio_weak": q(ratio_weak), "ratio_strong": q(ratio_strong),
|
||||
"Cp_weak": q(Cp_weak), "Cp_strong": q(Cp_strong),
|
||||
"Cp": q(Cp), "governing_axis": governing_axis,
|
||||
"Fc_prime_psi": q(Fc_prime), "fc_psi": q(fc_psi), "Pa_lbf": q(Pa_lbf),
|
||||
}
|
||||
|
||||
checks = {
|
||||
"axial": {"demand": q(P_lbf), "capacity": q(Pa_lbf), "ok": P_lbf <= Pa_lbf},
|
||||
}
|
||||
|
||||
return {
|
||||
"tool": "wood_stud_column",
|
||||
"version": "0.1",
|
||||
"project": inp.get("project", ""),
|
||||
"prepared_by": inp.get("prepared_by", ""),
|
||||
"values": values,
|
||||
"checks": checks,
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Calculate the wood stud column axial capacity from a YAML input file.")
|
||||
parser.add_argument("--input", "-i", type=Path, default=HERE / "input.yaml", help="YAML input path")
|
||||
parser.add_argument("--output", "-o", type=Path, help="JSON output path; defaults beside the input")
|
||||
parser.add_argument("--stdout", action="store_true", help="Write the complete JSON result to stdout instead of a file")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
input_path = args.input
|
||||
output_path = args.output or input_path.with_name("results.json")
|
||||
with input_path.open(encoding="utf-8") as handle:
|
||||
result = compute(yaml.safe_load(handle))
|
||||
serialized = json.dumps(result, indent=2) + "\n"
|
||||
if args.stdout:
|
||||
sys.stdout.write(serialized)
|
||||
else:
|
||||
output_path.write_text(serialized, encoding="utf-8")
|
||||
print(output_path)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
29
wood-stud-column/input.yaml
Normal file
29
wood-stud-column/input.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Project name shown in the Typst report header.
|
||||
project: "Interior Bearing Wall"
|
||||
# Person or organization shown in the Typst report footer.
|
||||
prepared_by: "Conemco Engineering"
|
||||
|
||||
# Axial load (ASD) checked against the allowable column capacity.
|
||||
P: "400 lbf"
|
||||
|
||||
# Stud geometry (actual dimensions of a nominal 2x4).
|
||||
length: "6 ft" # L, total stud length
|
||||
width: "1.5 in" # b, actual 2x4 width
|
||||
depth: "3.5 in" # d, actual 2x4 depth
|
||||
Ke: 1.0 # effective-length factor, pinned-pinned (NDS 3.7.1.2 / Appendix G)
|
||||
|
||||
# Species and grade label shown in the report. "SP" is read as Southern Pine
|
||||
# (SYP) per NDS Supplement Table 4B; confirm if SPF or SPF-S was intended.
|
||||
species_grade: "SP (Southern Pine) No. 2"
|
||||
|
||||
# NDS Supplement reference design values for Southern Pine (SYP) No. 2, dimension lumber.
|
||||
Fc: "1450 psi" # compression parallel to grain (F_c)
|
||||
E: "1400000 psi" # modulus of elasticity (E)
|
||||
E_min: "510000 psi" # 5th-percentile modulus (E_min)
|
||||
|
||||
# Adjustment factors (NDS Table 4.3.1). All 1.0 except size factor for this example.
|
||||
CD: 1 # load duration factor (1.0 = normal/occupancy duration, NDS 2.3.2)
|
||||
CM: 1 # wet service factor (dry, moisture < 19%, NDS 4.3.3)
|
||||
Ct: 1 # temperature factor (< 100 deg F, NDS 4.3.4)
|
||||
CF: 1.15 # size factor for compression, 2x4 (NDS 4.3.6)
|
||||
Ci: 1 # incising factor (NDS 4.3.8)
|
||||
50
wood-stud-column/results.json
Normal file
50
wood-stud-column/results.json
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"tool": "wood_stud_column",
|
||||
"version": "0.1",
|
||||
"project": "Interior Bearing Wall",
|
||||
"prepared_by": "Conemco Engineering",
|
||||
"values": {
|
||||
"P_lbf": 400.0,
|
||||
"L_in": 72.0,
|
||||
"b_in": 1.5,
|
||||
"d_in": 3.5,
|
||||
"A_in2": 5.25,
|
||||
"Ke": 1.0,
|
||||
"Le_in": 72.0,
|
||||
"d_least_in": 1.5,
|
||||
"d_great_in": 3.5,
|
||||
"Le_d_weak": 48.0,
|
||||
"Le_d_strong": 20.571429,
|
||||
"species_grade": "SP (Southern Pine) No. 2",
|
||||
"Fc_psi": 1450.0,
|
||||
"E_psi": 1400000.0,
|
||||
"Emin_psi": 510000.0,
|
||||
"CD": 1.0,
|
||||
"CM": 1.0,
|
||||
"Ct": 1.0,
|
||||
"CF": 1.15,
|
||||
"Ci": 1.0,
|
||||
"kc_euler": 0.822,
|
||||
"c_sawn": 0.8,
|
||||
"Fc_star_psi": 1667.5,
|
||||
"Emin_prime_psi": 510000.0,
|
||||
"FcE_weak_psi": 181.953125,
|
||||
"FcE_strong_psi": 990.633681,
|
||||
"ratio_weak": 0.109117,
|
||||
"ratio_strong": 0.594083,
|
||||
"Cp_weak": 0.106575,
|
||||
"Cp_strong": 0.496288,
|
||||
"Cp": 0.106575,
|
||||
"governing_axis": "weak",
|
||||
"Fc_prime_psi": 177.71332,
|
||||
"fc_psi": 76.190476,
|
||||
"Pa_lbf": 932.994931
|
||||
},
|
||||
"checks": {
|
||||
"axial": {
|
||||
"demand": 400.0,
|
||||
"capacity": 932.994931,
|
||||
"ok": true
|
||||
}
|
||||
}
|
||||
}
|
||||
65
wood-stud-column/test_wood_stud_column.py
Normal file
65
wood-stud-column/test_wood_stud_column.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
from pathlib import Path
|
||||
import importlib.util
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
spec = importlib.util.spec_from_file_location("wood_stud_column_calc", HERE / "calc.py")
|
||||
assert spec is not None and spec.loader is not None
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
|
||||
def result():
|
||||
with (HERE / "input.yaml").open(encoding="utf-8") as handle:
|
||||
return module.compute(yaml.safe_load(handle))
|
||||
|
||||
|
||||
def test_typst_loads_match_checked_inputs():
|
||||
subprocess.run([sys.executable, str(HERE / "calc.py")], check=True, cwd=HERE.parents[1])
|
||||
query = subprocess.run(
|
||||
[
|
||||
"typst", "eval", "query(<wood-stud-column-loads>)", "--root", ".",
|
||||
"--in", "calcs/wood-stud-column/beam.typ", "--format", "json",
|
||||
],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=HERE.parents[1],
|
||||
)
|
||||
published = json.loads(query.stdout)
|
||||
assert len(published) == 1
|
||||
derived = published[0]["value"]
|
||||
values = result()["values"]
|
||||
assert derived["P_lbf"] == pytest.approx(values["P_lbf"], abs=0.001)
|
||||
assert derived["A_in2"] == pytest.approx(values["A_in2"], abs=0.001)
|
||||
|
||||
|
||||
def test_ground_truth_column_stability():
|
||||
output = result()
|
||||
values = output["values"]
|
||||
assert values["A_in2"] == pytest.approx(5.25)
|
||||
assert values["Le_in"] == pytest.approx(72.0)
|
||||
assert values["Le_d_weak"] == pytest.approx(48.0, abs=0.01)
|
||||
assert values["FcE_weak_psi"] == pytest.approx(181.9, abs=0.5)
|
||||
assert values["Cp_weak"] == pytest.approx(0.107, abs=0.003)
|
||||
assert values["Cp_strong"] == pytest.approx(0.497, abs=0.005)
|
||||
assert values["Fc_prime_psi"] == pytest.approx(177.6, abs=0.5)
|
||||
assert values["Pa_lbf"] == pytest.approx(932.0, abs=3.0)
|
||||
assert output["checks"]["axial"]["ok"] is True
|
||||
|
||||
|
||||
def test_cli_can_write_json_to_stdout():
|
||||
completed = subprocess.run(
|
||||
[sys.executable, str(HERE / "calc.py"), "--input", str(HERE / "input.yaml"), "--stdout"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
output = json.loads(completed.stdout)
|
||||
assert output["values"]["P_lbf"] == pytest.approx(400)
|
||||
assert completed.stderr == ""
|
||||
1342
wood-stud-column/wood-stud-column.pdf
Normal file
1342
wood-stud-column/wood-stud-column.pdf
Normal file
File diff suppressed because it is too large
Load diff
62
wood-stud-column/wood-stud-column.typ
Normal file
62
wood-stud-column/wood-stud-column.typ
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#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: "Wood Stud Column — Axial Capacity",
|
||||
project: data.project,
|
||||
prepared-by: data.prepared_by,
|
||||
)
|
||||
|
||||
= Wood Stud Column — Axial Capacity
|
||||
|
||||
Concentrically loaded 2x4 wood stud (SP / Southern Pine No. 2) analyzed for
|
||||
axial compression parallel to grain per NDS 2018 ASD. Pint parses `input.yaml`;
|
||||
`calc.py` computes the column stability factor $C_p$ (NDS 3.7.1.5, Eq. 3.7-1)
|
||||
and the adjusted compression capacity. The governing limit state is compression
|
||||
with buckling about the weak axis.
|
||||
|
||||
== Geometry And Axial Load
|
||||
|
||||
#let P = 400
|
||||
#let L_ft = 6
|
||||
#let b = 1.5
|
||||
#let d = 3.5
|
||||
#let A = b * d
|
||||
#metadata((P_lbf: P, A_in2: A)) <wood-stud-column-loads>
|
||||
|
||||
#calcline([$P = #P " lbf"$], [Axial load, compression (ASD)])
|
||||
#calcline([$L = #L_ft " ft" = #n.L_in " in"$], [Total stud length])
|
||||
#calcline([$b = #b " in"$, $d = #d " in"$], [Actual dimensions of a nominal 2x4])
|
||||
#calcline([$A = b d = #round(n.A_in2, digits: 2) " in"^2$], [Cross-sectional area])
|
||||
#calcline([$K_e = #n.Ke$], [Effective-length factor, pinned-pinned (NDS 3.7.1.2)])
|
||||
#calcline([$L_e = K_e L = #round(n.Le_in, digits: 1) " in"$], [Effective length])
|
||||
#calcline([$d_"min" = min(b, d) = #n.d_least_in " in"$], [Least dimension; weak-axis buckling governs])
|
||||
#calcline([$L_e / d_"min" = #round(n.Le_in / n.d_least_in, digits: 1) <= 50$], [Slenderness ratio, weak axis; cap $L_e/d <= 50$ (NDS 3.7.1.4)])
|
||||
|
||||
== Material And Adjustment Factors
|
||||
|
||||
#calcline([$"Species/grade" = #n.species_grade$], [NDS Supplement reference values])
|
||||
#calcline([$F_c = #n.Fc_psi " psi"$], [Reference compression parallel to grain])
|
||||
#calcline([$E = #n.E_psi " psi"$, $E'_"min" = #n.Emin_psi " psi"$], [Moduli of elasticity])
|
||||
#calcline([$C_D = #n.CD$, $C_M = #n.CM$, $C_t = #n.Ct$, $C_F = #n.CF$, $C_i = #n.Ci$], [Load duration ($C_D=1.0$ normal/occupancy, NDS 2.3.2), wet service, temperature, size ($C_F=1.15$ for 2x4 compression, NDS 4.3.6), incising (NDS Table 4.3.1)])
|
||||
|
||||
== Column Stability Factor (NDS 3.7.1.4)
|
||||
|
||||
#calcline([$F^*_c = F_c C_D C_M C_t C_F C_i = #round(n.Fc_star_psi, digits: 1) " psi"$], [Adjusted reference compression, NDS 3.7.1.5])
|
||||
#calcline([$E'_"min" = E_"min" C_M C_t C_i = #round(n.Emin_prime_psi, digits: 0) " psi"$], [Adjusted 5th-percentile modulus])
|
||||
#calcline([$F_("cE") = 0.822 E'_"min" / (L_e / d_"min")^2 = #round(n.FcE_weak_psi, digits: 2) " psi"$], [Critical buckling stress, NDS Eq. 3.7-2 (coefficient 0.822)])
|
||||
#calcline([$0.822$ (Euler coeff., NDS Eq. 3.7-2), $c = #n.c_sawn$], [Sawn-lumber column coefficient, NDS Eq. 3.7-1])
|
||||
#calcline([$C_p = (1 + F_("cE")/F^*_c)/(2c) - sqrt(...) = #round(n.Cp, digits: 4)$], [Column stability factor, NDS Eq. 3.7-1 (3.7.1.5); weak axis governs])
|
||||
|
||||
== Adjusted Compression Capacity
|
||||
|
||||
#calcline([$F'_c = F^*_c C_p = #round(n.Fc_prime_psi, digits: 2) " psi"$], [Adjusted compression design value, NDS 3.7.1.5])
|
||||
#calcline([$f_c = P / A = #round(n.fc_psi, digits: 2) " psi"$], [Acting compression stress])
|
||||
#calcline([$P_a = F'_c A = #round(n.Pa_lbf, digits: 1) " lbf"$], [Allowable axial load])
|
||||
|
||||
#v(7pt)
|
||||
#check("Axial Compression", checks.axial.demand, checks.axial.capacity, unit: "lbf", ok: checks.axial.ok, demand-label: [$P$], capacity-label: [$P_a$])
|
||||
Loading…
Reference in a new issue