Remove concrete-beam2 and unused shore-post-brace assets
This commit is contained in:
parent
d5ac3fca7e
commit
27a9cdd707
10 changed files with 0 additions and 1963 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 99 KiB |
|
|
@ -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)
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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$],
|
||||
)
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 |
|
|
@ -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)
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in a new issue