Drop unit suffixes from steel-beam variables and results
Rename calc.py locals and result keys, add inline unit comments, and normalize Lp/Lr/Lb to feet. Update steel-beam.typ references and the tests (current W10X15 input, --stdout summary behavior).
This commit is contained in:
parent
6ed3246555
commit
ddd5ecff58
5 changed files with 129 additions and 133 deletions
|
|
@ -99,13 +99,13 @@ def _column_number(reference: str) -> int:
|
||||||
|
|
||||||
|
|
||||||
def compute(inp: dict, database: Path = DATABASE) -> dict:
|
def compute(inp: dict, database: Path = DATABASE) -> dict:
|
||||||
beam_length = quantity(inp["beam_length"], "ft", "beam_length")
|
beam_length = quantity(inp["beam_length"], "ft", "beam_length") # ft
|
||||||
unbraced_length = quantity(inp["unbraced_length"], "in", "unbraced_length")
|
unbraced_length = quantity(inp["unbraced_length"], "in", "unbraced_length") # in
|
||||||
moment_kipft = quantity(inp["Mu"], "kip * ft", "Mu")
|
moment = quantity(inp["Mu"], "kip * ft", "Mu") # kip-ft
|
||||||
shear_kip = quantity(inp["Vu"], "kip", "Vu")
|
shear = quantity(inp["Vu"], "kip", "Vu") # kip
|
||||||
E = quantity(inp["steel_modulus"], "ksi", "steel_modulus")
|
E = quantity(inp["steel_modulus"], "ksi", "steel_modulus") # ksi
|
||||||
Fy = quantity(inp["steel_yield"], "ksi", "steel_yield")
|
Fy = quantity(inp["steel_yield"], "ksi", "steel_yield") # ksi
|
||||||
service_load = quantity(inp["service_load"], "lbf/ft", "service_load")
|
service_load = quantity(inp["service_load"], "lbf/ft", "service_load") # lbf/ft
|
||||||
Cb = float(inp.get("cb", 1))
|
Cb = float(inp.get("cb", 1))
|
||||||
c = float(inp.get("c", 1))
|
c = float(inp.get("c", 1))
|
||||||
if Cb <= 0 or c <= 0:
|
if Cb <= 0 or c <= 0:
|
||||||
|
|
@ -116,73 +116,73 @@ def compute(inp: dict, database: Path = DATABASE) -> dict:
|
||||||
# the connector (used here as the factored shear). They arrive from the load
|
# the connector (used here as the factored shear). They arrive from the load
|
||||||
# determination, which is based on a uniform gravity load, so the equivalent
|
# determination, which is based on a uniform gravity load, so the equivalent
|
||||||
# factored uniform load is recovered from the shear: w_u = 2 V_u / L.
|
# factored uniform load is recovered from the shear: w_u = 2 V_u / L.
|
||||||
factored_uniform_load_kipft = 2.0 * shear_kip / beam_length
|
factored_uniform_load = 2.0 * shear / beam_length # kip/ft
|
||||||
|
|
||||||
Lb = unbraced_length
|
Lb = unbraced_length # in
|
||||||
Lp = 1.76 * float(section["ry"]) * math.sqrt(E / Fy)
|
Lp = 1.76 * float(section["ry"]) * math.sqrt(E / Fy) # in
|
||||||
rts = float(section["rts"])
|
rts = float(section["rts"]) # in
|
||||||
Sx = float(section["Sx"])
|
Sx = float(section["Sx"]) # in^3
|
||||||
ho = float(section["ho"])
|
ho = float(section["ho"]) # in
|
||||||
J = float(section["J"])
|
J = float(section["J"]) # in^4
|
||||||
Lr = 1.95 * rts * E / (0.7 * Fy) * math.sqrt(J * c / (Sx * ho) + math.sqrt((J * c / (Sx * ho)) ** 2 + 6.76 * (0.7 * Fy / E) ** 2))
|
Lr = 1.95 * rts * E / (0.7 * Fy) * math.sqrt(J * c / (Sx * ho) + math.sqrt((J * c / (Sx * ho)) ** 2 + 6.76 * (0.7 * Fy / E) ** 2)) # in
|
||||||
Fcr = Cb * math.pi**2 * E / (Lb / rts) ** 2 * math.sqrt(1 + 0.078 * J * c / (Sx * ho) * (Lb / rts) ** 2)
|
Fcr = Cb * math.pi**2 * E / (Lb / rts) ** 2 * math.sqrt(1 + 0.078 * J * c / (Sx * ho) * (Lb / rts) ** 2) # ksi
|
||||||
Mp = Fy * float(section["Zx"]) / 12.0
|
Mp = Fy * float(section["Zx"]) / 12.0 # kip-ft
|
||||||
if Lb <= Lp:
|
if Lb <= Lp:
|
||||||
Mn_ltb = Mp
|
MnLTB = Mp
|
||||||
ltb_mode = "yielding"
|
ltb_mode = "yielding"
|
||||||
elif Lb <= Lr:
|
elif Lb <= Lr:
|
||||||
Mn_ltb = Cb * (Mp - (Mp - 0.7 * Fy * Sx / 12.0) * (Lb - Lp) / (Lr - Lp))
|
MnLTB = Cb * (Mp - (Mp - 0.7 * Fy * Sx / 12.0) * (Lb - Lp) / (Lr - Lp))
|
||||||
ltb_mode = "inelastic LTB"
|
ltb_mode = "inelastic LTB"
|
||||||
else:
|
else:
|
||||||
Mn_ltb = Fcr * Sx / 12.0
|
MnLTB = Fcr * Sx / 12.0
|
||||||
ltb_mode = "elastic LTB"
|
ltb_mode = "elastic LTB"
|
||||||
Mn = min(Mp, Mn_ltb)
|
Mn = min(Mp, MnLTB) # kip-ft
|
||||||
phi_mn = 0.9 * Mn
|
phiMn = 0.9 * Mn # kip-ft
|
||||||
|
|
||||||
Aw = float(section["d"]) * float(section["tw"])
|
Aw = float(section["d"]) * float(section["tw"]) # in^2
|
||||||
lambda_lim = 2.24 * math.sqrt(E / Fy)
|
lambda_lim = 2.24 * math.sqrt(E / Fy)
|
||||||
kv = 5.34
|
kv = 5.34
|
||||||
lambda_web = float(section["lambda"])
|
lambda_web = float(section["lambda"])
|
||||||
cv1 = 1.0 if lambda_web <= 1.10 * math.sqrt(kv * E / Fy) else 1.10 * math.sqrt(kv * E / Fy) / lambda_web
|
cv1 = 1.0 if lambda_web <= 1.10 * math.sqrt(kv * E / Fy) else 1.10 * math.sqrt(kv * E / Fy) / lambda_web
|
||||||
phi_v = 1.0 if lambda_web <= lambda_lim else 0.9
|
phi_v = 1.0 if lambda_web <= lambda_lim else 0.9
|
||||||
phi_vn = phi_v * 0.6 * Fy * Aw * cv1
|
phiVn = phi_v * 0.6 * Fy * Aw * cv1 # kip
|
||||||
|
|
||||||
# Serviceability deflection under the service uniform load (L/240 limit).
|
# Serviceability deflection under the service uniform load (L/240 limit).
|
||||||
L_in = beam_length * 12.0
|
L = beam_length * 12.0 # in
|
||||||
w_serv_lbf_in = service_load / 12.0
|
w_service = service_load / 12.0 # lbf/in
|
||||||
delta_limit = L_in / 240.0
|
delta_limit = L / 240.0 # in
|
||||||
delta = 5.0 * w_serv_lbf_in * L_in ** 4 / (384.0 * (E * 1000.0) * float(section["Ix"]))
|
delta = 5.0 * w_service * L ** 4 / (384.0 * (E * 1000.0) * float(section["Ix"])) # in
|
||||||
|
|
||||||
def q(value: float) -> float:
|
def q(value: float) -> float:
|
||||||
return round(value, 6)
|
return round(value, 6)
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
"beam_length_ft": q(beam_length),
|
"beam_length": q(beam_length),
|
||||||
"unbraced_length_in": q(Lb),
|
"unbraced_length": q(Lb),
|
||||||
"factored_uniform_load_kipft": q(factored_uniform_load_kipft),
|
"factored_uniform_load": q(factored_uniform_load),
|
||||||
"service_load_lbf_ft": q(service_load),
|
"service_load": q(service_load),
|
||||||
"moment_kipft": q(moment_kipft),
|
"moment": q(moment),
|
||||||
"shear_kip": q(shear_kip),
|
"shear": q(shear),
|
||||||
"E_ksi": q(E),
|
"E": q(E),
|
||||||
"Fy_ksi": q(Fy),
|
"Fy": q(Fy),
|
||||||
"Lp_in": q(Lp),
|
"Lp": q(Lp / 12),
|
||||||
"Lr_ft": q(Lr / 12),
|
"Lr": q(Lr / 12),
|
||||||
"Lb_ft": q(Lb / 12),
|
"Lb": q(Lb / 12),
|
||||||
"rts_in": q(rts),
|
"rts": q(rts),
|
||||||
"Fcr_ksi": q(Fcr),
|
"Fcr": q(Fcr),
|
||||||
"Mp_kipft": q(Mp),
|
"Mp": q(Mp),
|
||||||
"MnLTB_kipft": q(Mn_ltb),
|
"MnLTB": q(MnLTB),
|
||||||
"Mn_kipft": q(Mn),
|
"Mn": q(Mn),
|
||||||
"phiMn_kipft": q(phi_mn),
|
"phiMn": q(phiMn),
|
||||||
"Aw_in2": q(Aw),
|
"Aw": q(Aw),
|
||||||
"lambda": q(lambda_web),
|
"lambda": q(lambda_web),
|
||||||
"lambda_lim": q(lambda_lim),
|
"lambda_lim": q(lambda_lim),
|
||||||
"kv": q(kv),
|
"kv": q(kv),
|
||||||
"Cv1": q(cv1),
|
"Cv1": q(cv1),
|
||||||
"phi_v": q(phi_v),
|
"phi_v": q(phi_v),
|
||||||
"phiVn_kip": q(phi_vn),
|
"phiVn": q(phiVn),
|
||||||
"delta_limit_in": q(delta_limit),
|
"delta_limit": q(delta_limit),
|
||||||
"delta_in": q(delta),
|
"delta": q(delta),
|
||||||
"ltb_mode": ltb_mode,
|
"ltb_mode": ltb_mode,
|
||||||
}
|
}
|
||||||
values.update({f"section_{key}": q(float(value)) for key, value in section.items() if key != "label"})
|
values.update({f"section_{key}": q(float(value)) for key, value in section.items() if key != "label"})
|
||||||
|
|
@ -194,8 +194,8 @@ def compute(inp: dict, database: Path = DATABASE) -> dict:
|
||||||
"section": section["label"],
|
"section": section["label"],
|
||||||
"values": values,
|
"values": values,
|
||||||
"checks": {
|
"checks": {
|
||||||
"flexure": {"demand": q(moment_kipft), "capacity": q(phi_mn), "ok": moment_kipft <= phi_mn},
|
"flexure": {"demand": q(moment), "capacity": q(phiMn), "ok": moment <= phiMn},
|
||||||
"shear": {"demand": q(shear_kip), "capacity": q(phi_vn), "ok": shear_kip <= phi_vn},
|
"shear": {"demand": q(shear), "capacity": q(phiVn), "ok": shear <= phiVn},
|
||||||
"deflection": {"demand": q(delta), "capacity": q(delta_limit), "ok": delta <= delta_limit},
|
"deflection": {"demand": q(delta), "capacity": q(delta_limit), "ok": delta <= delta_limit},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -213,20 +213,20 @@ def summary(result: dict) -> str:
|
||||||
"Steel Beam Design Summary",
|
"Steel Beam Design Summary",
|
||||||
f"Project: {result['project']}",
|
f"Project: {result['project']}",
|
||||||
f"Section: {result['section']}",
|
f"Section: {result['section']}",
|
||||||
f"Span: {values['beam_length_ft']:.2f} ft",
|
f"Span: {values['beam_length']:.2f} ft",
|
||||||
"",
|
"",
|
||||||
"Demands",
|
"Demands",
|
||||||
f" Factored moment, Mu: {values['moment_kipft']:.3f} kip-ft",
|
f" Factored moment, Mu: {values['moment']:.3f} kip-ft",
|
||||||
f" Factored shear, Vu: {values['shear_kip']:.3f} kip",
|
f" Factored shear, Vu: {values['shear']:.3f} kip",
|
||||||
f" Service load: {values.get('service_load_lbf_ft', 'see input')} lbf/ft",
|
f" Service load: {values.get('service_load', 'see input')} lbf/ft",
|
||||||
"",
|
"",
|
||||||
"Strength",
|
"Strength",
|
||||||
f" Flexure: {status('flexure')} ({values['phiMn_kipft']:.3f} kip-ft capacity, D/C {values['moment_kipft'] / values['phiMn_kipft']:.3f})",
|
f" Flexure: {status('flexure')} ({values['phiMn']:.3f} kip-ft capacity, D/C {values['moment'] / values['phiMn']:.3f})",
|
||||||
f" Shear: {status('shear')} ({values['phiVn_kip']:.3f} kip capacity, D/C {values['shear_kip'] / values['phiVn_kip']:.3f})",
|
f" Shear: {status('shear')} ({values['phiVn']:.3f} kip capacity, D/C {values['shear'] / values['phiVn']:.3f})",
|
||||||
f" LTB mode: {values['ltb_mode']}",
|
f" LTB mode: {values['ltb_mode']}",
|
||||||
"",
|
"",
|
||||||
"Serviceability",
|
"Serviceability",
|
||||||
f" Deflection: {status('deflection')} ({values['delta_in']:.3f} in / {values['delta_limit_in']:.3f} in limit, D/C {values['delta_in'] / values['delta_limit_in']:.3f})",
|
f" Deflection: {status('deflection')} ({values['delta']:.3f} in / {values['delta_limit']:.3f} in limit, D/C {values['delta'] / values['delta_limit']:.3f})",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,32 +5,32 @@
|
||||||
"prepared_by": "Conemco Engineering",
|
"prepared_by": "Conemco Engineering",
|
||||||
"section": "W10X15",
|
"section": "W10X15",
|
||||||
"values": {
|
"values": {
|
||||||
"beam_length_ft": 9.0,
|
"beam_length": 9.0,
|
||||||
"unbraced_length_in": 108.0,
|
"unbraced_length": 108.0,
|
||||||
"factored_uniform_load_kipft": 0.802444,
|
"factored_uniform_load": 0.802444,
|
||||||
"service_load_lbf_ft": 548.98,
|
"service_load": 548.98,
|
||||||
"moment_kipft": 8.124,
|
"moment": 8.124,
|
||||||
"shear_kip": 3.611,
|
"shear": 3.611,
|
||||||
"E_ksi": 29000.0,
|
"E": 29000.0,
|
||||||
"Fy_ksi": 50.0,
|
"Fy": 50.0,
|
||||||
"Lp_in": 34.332994,
|
"Lp": 2.861083,
|
||||||
"Lr_ft": 8.608917,
|
"Lr": 8.608917,
|
||||||
"Lb_ft": 9.0,
|
"Lb": 9.0,
|
||||||
"rts_in": 1.01,
|
"rts": 1.01,
|
||||||
"Fcr_ksi": 32.555772,
|
"Fcr": 32.555772,
|
||||||
"Mp_kipft": 66.666667,
|
"Mp": 66.666667,
|
||||||
"MnLTB_kipft": 37.439137,
|
"MnLTB": 37.439137,
|
||||||
"Mn_kipft": 37.439137,
|
"Mn": 37.439137,
|
||||||
"phiMn_kipft": 33.695224,
|
"phiMn": 33.695224,
|
||||||
"Aw_in2": 2.5,
|
"Aw": 2.5,
|
||||||
"lambda": 38.5,
|
"lambda": 38.5,
|
||||||
"lambda_lim": 53.946344,
|
"lambda_lim": 53.946344,
|
||||||
"kv": 5.34,
|
"kv": 5.34,
|
||||||
"Cv1": 1.0,
|
"Cv1": 1.0,
|
||||||
"phi_v": 1.0,
|
"phi_v": 1.0,
|
||||||
"phiVn_kip": 75.0,
|
"phiVn": 75.0,
|
||||||
"delta_limit_in": 0.45,
|
"delta_limit": 0.45,
|
||||||
"delta_in": 0.040559,
|
"delta": 0.040559,
|
||||||
"ltb_mode": "elastic LTB",
|
"ltb_mode": "elastic LTB",
|
||||||
"section_A": 4.41,
|
"section_A": 4.41,
|
||||||
"section_d": 10.0,
|
"section_d": 10.0,
|
||||||
|
|
|
||||||
|
|
@ -1438,12 +1438,12 @@ r
|
||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
290 0 obj
|
290 0 obj
|
||||||
<</Title(Steel Beam Design)/Author(Conemco Engineering)/Creator(Typst 0.15.1)/ModDate(D:20260903203734-04'00)/CreationDate(D:20260903203734-04'00)>>
|
<</Title(Steel Beam Design)/Author(Conemco Engineering)/Creator(Typst 0.15.1)/ModDate(D:20260921200845-04'00)/CreationDate(D:20260921200845-04'00)>>
|
||||||
endobj
|
endobj
|
||||||
291 0 obj
|
291 0 obj
|
||||||
<</Length 1171/Type/Metadata/Subtype/XML>>
|
<</Length 1171/Type/Metadata/Subtype/XML>>
|
||||||
stream
|
stream
|
||||||
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><dc:title><rdf:Alt><rdf:li xml:lang="x-default">Steel Beam Design</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>Conemco Engineering</rdf:li></rdf:Seq></dc:creator><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-09-03T20:37:34-04:00</xmp:ModifyDate><xmp:CreateDate>2026-09-03T20:37:34-04:00</xmp:CreateDate><xmpTPg:NPages>2</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>FYTTKTOt3I6wHI8XKA53lg==</xmpMM:InstanceID><xmpMM:DocumentID>pB5rntuth5VxEVEbYV7Trw==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?>
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><dc:title><rdf:Alt><rdf:li xml:lang="x-default">Steel Beam Design</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>Conemco Engineering</rdf:li></rdf:Seq></dc:creator><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-09-21T20:08:45-04:00</xmp:ModifyDate><xmp:CreateDate>2026-09-21T20:08:45-04:00</xmp:CreateDate><xmpTPg:NPages>2</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>AustUdjx2Kca/OqRG7qSyw==</xmpMM:InstanceID><xmpMM:DocumentID>pB5rntuth5VxEVEbYV7Trw==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?>
|
||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
292 0 obj
|
292 0 obj
|
||||||
|
|
@ -1745,7 +1745,7 @@ xref
|
||||||
0000189396 00000 n
|
0000189396 00000 n
|
||||||
0000190645 00000 n
|
0000190645 00000 n
|
||||||
trailer
|
trailer
|
||||||
<</Size 293/Root 292 0 R/Info 290 0 R/ID[(pB5rntuth5VxEVEbYV7Trw==)(FYTTKTOt3I6wHI8XKA53lg==)]>>
|
<</Size 293/Root 292 0 R/Info 290 0 R/ID[(pB5rntuth5VxEVEbYV7Trw==)(AustUdjx2Kca/OqRG7qSyw==)]>>
|
||||||
startxref
|
startxref
|
||||||
190830
|
190830
|
||||||
%%EOF
|
%%EOF
|
||||||
|
|
@ -19,22 +19,18 @@ the new beam takes all load, non-composite action with concrete slab.
|
||||||
== Factored Demands
|
== Factored Demands
|
||||||
As determined in "Load Determination section"
|
As determined in "Load Determination section"
|
||||||
|
|
||||||
#let Mu_lbf = n.moment_kipft * 1000
|
#let L = n.beam_length // ft
|
||||||
#let Vu_lbf = n.shear_kip * 1000
|
|
||||||
#let L = n.beam_length_ft
|
|
||||||
#let wu_kipft = n.factored_uniform_load_kipft
|
|
||||||
#let wu_lbf = wu_kipft * 1000
|
|
||||||
|
|
||||||
#calcline([$M_u = #round(n.moment_kipft, digits: 2) "kip·ft"$], [Factored moment from load determination])
|
#calcline([$M_u = #round(n.moment, digits: 2) "kip·ft"$], [Factored moment from load determination])
|
||||||
#calcline([$V_u = #round(n.shear_kip, digits: 2) "kip"$], [Factored reaction on connector (factored shear)])
|
#calcline([$V_u = #round(n.shear, digits: 2) "kip"$], [Factored reaction on connector (factored shear)])
|
||||||
#calcline([$L = #L "ft"$], [Beam span])
|
#calcline([$L = #L "ft"$], [Beam span])
|
||||||
|
|
||||||
#metadata((Mu_kipft: n.moment_kipft, Vu_kip: n.shear_kip)) <load-demands>
|
#metadata((Mu: n.moment, Vu: n.shear)) <load-demands>
|
||||||
|
|
||||||
== Material And Section Properties
|
== Material And Section Properties
|
||||||
|
|
||||||
#calcline([$E = #n.E_ksi "ksi"$], [Steel Young's modulus])
|
#calcline([$E = #n.E "ksi"$], [Steel Young's modulus])
|
||||||
#calcline([$F_y = #n.Fy_ksi "ksi"$], [Steel yield strength])
|
#calcline([$F_y = #n.Fy "ksi"$], [Steel yield strength])
|
||||||
#calcline([$"Section" = #data.section$], [AISC W-shape])
|
#calcline([$"Section" = #data.section$], [AISC W-shape])
|
||||||
#calcline([$d = #n.section_d "in"$, $b = #n.section_b "in"$], [Depth and flange width])
|
#calcline([$d = #n.section_d "in"$, $b = #n.section_b "in"$], [Depth and flange width])
|
||||||
#calcline([$t_f = #n.section_tf "in"$, $t_w = #n.section_tw "in"$], [Flange and web thickness])
|
#calcline([$t_f = #n.section_tf "in"$, $t_w = #n.section_tw "in"$], [Flange and web thickness])
|
||||||
|
|
@ -48,37 +44,37 @@ As determined in "Load Determination section"
|
||||||
|
|
||||||
== Bending About Major Axis
|
== Bending About Major Axis
|
||||||
|
|
||||||
#calcline([$L_b = #round(n.Lb_ft, digits: 2) "ft"$], [Unbraced length of compression flange])
|
#calcline([$L_b = #round(n.Lb, digits: 2) "ft"$], [Unbraced length of compression flange])
|
||||||
#calcline([$L_p = 1.76 r_y sqrt(E / F_y) = #round(n.Lp_in / 12, digits: 2) "ft"$], [Limit for yielding])
|
#calcline([$L_p = 1.76 r_y sqrt(E / F_y) = #round(n.Lp, digits: 2) "ft"$], [Limit for yielding])
|
||||||
#calcline([$C_b = 1$, $c = 1$], [Moment gradient and I-shape coefficient])
|
#calcline([$C_b = 1$, $c = 1$], [Moment gradient and I-shape coefficient])
|
||||||
#calcline([$r_"ts" = sqrt(I_y h_o / (2 S_x)) = #round(n.section_rts, digits: 2) "in"$], [Effective radius of gyration])
|
#calcline([$r_"ts" = sqrt(I_y h_o / (2 S_x)) = #round(n.section_rts, digits: 2) "in"$], [Effective radius of gyration])
|
||||||
#calcline([$L_r = 1.95 r_"ts" E / (0.7 F_y) sqrt((J c)/(S_x h_o) + sqrt(((J c)/(S_x h_o))^2 + 6.76 (0.7 F_y / E)^2)) = #round(n.Lr_ft, digits: 2) "ft"$], [Limit for inelastic torsional buckling])
|
#calcline([$L_r = 1.95 r_"ts" E / (0.7 F_y) sqrt((J c)/(S_x h_o) + sqrt(((J c)/(S_x h_o))^2 + 6.76 (0.7 F_y / E)^2)) = #round(n.Lr, digits: 2) "ft"$], [Limit for inelastic torsional buckling])
|
||||||
#calcline([$F_"cr" = (C_b pi^2 E)/(L_b/r_"ts")^2 sqrt(1 + 0.078 (J c)/(S_x h_o) (L_b/r_"ts")^2) = #round(n.Fcr_ksi, digits: 2) "ksi"$], [Elastic lateral-torsional-buckling stress])
|
#calcline([$F_"cr" = (C_b pi^2 E)/(L_b/r_"ts")^2 sqrt(1 + 0.078 (J c)/(S_x h_o) (L_b/r_"ts")^2) = #round(n.Fcr, digits: 2) "ksi"$], [Elastic lateral-torsional-buckling stress])
|
||||||
#calcline([$M_p = F_y Z_x = #round(n.Mp_kipft, digits: 2) "kip·ft"$], [Plastic moment])
|
#calcline([$M_p = F_y Z_x = #round(n.Mp, digits: 2) "kip·ft"$], [Plastic moment])
|
||||||
#calcline([$M_n("LTB") = M_p, "for" L_b <= L_p$], [LTB moment for yielding range])
|
#calcline([$M_n("LTB") = M_p, "for" L_b <= L_p$], [LTB moment for yielding range])
|
||||||
#calcline([$M_n("LTB") = C_b [M_p - (M_p - 0.7 F_y S_x)(L_b - L_p)/(L_r - L_p)], "for" L_p < L_b <= L_r$], [LTB moment for inelastic range])
|
#calcline([$M_n("LTB") = C_b [M_p - (M_p - 0.7 F_y S_x)(L_b - L_p)/(L_r - L_p)], "for" L_p < L_b <= L_r$], [LTB moment for inelastic range])
|
||||||
#calcline([$M_n("LTB") = F_"cr" S_x, "for" L_b > L_r$], [LTB moment for elastic range])
|
#calcline([$M_n("LTB") = F_"cr" S_x, "for" L_b > L_r$], [LTB moment for elastic range])
|
||||||
#calcline([$M_n("LTB") = #round(n.MnLTB_kipft, digits: 2) "kip·ft"$], [Lateral-torsional-buckling strength])
|
#calcline([$M_n("LTB") = #round(n.MnLTB, digits: 2) "kip·ft"$], [Lateral-torsional-buckling strength])
|
||||||
#calcline([$M_n = min(M_p, M_n("LTB")) = #round(n.Mn_kipft, digits: 2) "kip·ft"$], [Nominal bending capacity])
|
#calcline([$M_n = min(M_p, M_n("LTB")) = #round(n.Mn, digits: 2) "kip·ft"$], [Nominal bending capacity])
|
||||||
#calcline([$phi M_n = 0.9 M_n = #round(n.phiMn_kipft, digits: 2) "kip·ft"$], [Design bending capacity])
|
#calcline([$phi M_n = 0.9 M_n = #round(n.phiMn, digits: 2) "kip·ft"$], [Design bending capacity])
|
||||||
|
|
||||||
#check("Flexure", checks.flexure.demand, checks.flexure.capacity, unit: "kip·ft", ok: checks.flexure.ok, demand-label: [$M_u$], capacity-label: [$phi M_n$])
|
#check("Flexure", checks.flexure.demand, checks.flexure.capacity, unit: "kip·ft", ok: checks.flexure.ok, demand-label: [$M_u$], capacity-label: [$phi M_n$])
|
||||||
|
|
||||||
== Shear Of Web
|
== Shear Of Web
|
||||||
|
|
||||||
#calcline([$A_w = d t_w = #round(n.Aw_in2, digits: 3) "in"^2$], [Web area])
|
#calcline([$A_w = d t_w = #round(n.Aw, digits: 3) "in"^2$], [Web area])
|
||||||
#calcline([$lambda_lim = 2.24 sqrt(E / F_y) = #round(n.lambda_lim, digits: 3)$], [Limiting web slenderness])
|
#calcline([$lambda_lim = 2.24 sqrt(E / F_y) = #round(n.lambda_lim, digits: 3)$], [Limiting web slenderness])
|
||||||
#calcline([$k_v = #n.kv$], [Web shear buckling coefficient])
|
#calcline([$k_v = #n.kv$], [Web shear buckling coefficient])
|
||||||
#calcline([$C_"v1" = #n.Cv1$], [Web shear strength coefficient])
|
#calcline([$C_"v1" = #n.Cv1$], [Web shear strength coefficient])
|
||||||
#calcline([$phi_v = #n.phi_v$], [Shear reduction factor])
|
#calcline([$phi_v = #n.phi_v$], [Shear reduction factor])
|
||||||
#calcline([$phi V_n = phi_v 0.6 F_y A_w C_"v1" = #round(n.phiVn_kip, digits: 3) "kip"$], [Design shear capacity])
|
#calcline([$phi V_n = phi_v 0.6 F_y A_w C_"v1" = #round(n.phiVn, digits: 3) "kip"$], [Design shear capacity])
|
||||||
|
|
||||||
#check("Shear", checks.shear.demand, checks.shear.capacity, unit: "kip", ok: checks.shear.ok, demand-label: [$V_u$], capacity-label: [$phi V_n$])
|
#check("Shear", checks.shear.demand, checks.shear.capacity, unit: "kip", ok: checks.shear.ok, demand-label: [$V_u$], capacity-label: [$phi V_n$])
|
||||||
|
|
||||||
== Deflection
|
== Deflection
|
||||||
|
|
||||||
#calcline([$delta_max = L / 240 = #round(n.delta_limit_in, digits: 3) "in"$], [Maximum allowed deflection])
|
#calcline([$delta_max = L / 240 = #round(n.delta_limit, digits: 3) "in"$], [Maximum allowed deflection])
|
||||||
#calcline([$delta = 5/384 (w L^4) / (E I_x) = #round(n.delta_in, digits: 3) "in"$], [Expected center deflection under service uniform load])
|
#calcline([$delta = 5/384 (w L^4) / (E I_x) = #round(n.delta, digits: 3) "in"$], [Expected center deflection under service uniform load])
|
||||||
|
|
||||||
#check("Deflection", checks.deflection.demand, checks.deflection.capacity, unit: "in", ok: checks.deflection.ok, demand-label: [$delta$], capacity-label: [$delta_"max"$])
|
#check("Deflection", checks.deflection.demand, checks.deflection.capacity, unit: "in", ok: checks.deflection.ok, demand-label: [$delta$], capacity-label: [$delta_"max"$])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,42 +35,42 @@ def test_typst_load_demands_match_checked_inputs():
|
||||||
assert len(published) == 1
|
assert len(published) == 1
|
||||||
derived = published[0]["value"]
|
derived = published[0]["value"]
|
||||||
values = result()["values"]
|
values = result()["values"]
|
||||||
assert derived["Mu_kipft"] == pytest.approx(values["moment_kipft"], abs=0.001)
|
assert derived["Mu"] == pytest.approx(values["moment"], abs=0.001)
|
||||||
assert derived["Vu_kip"] == pytest.approx(values["shear_kip"], abs=0.001)
|
assert derived["Vu"] == pytest.approx(values["shear"], abs=0.001)
|
||||||
|
|
||||||
|
|
||||||
def test_ground_truth_section_properties():
|
def test_section_properties():
|
||||||
values = result()["values"]
|
values = result()["values"]
|
||||||
assert values["section_d"] == pytest.approx(5.875)
|
assert values["section_d"] == pytest.approx(10.0)
|
||||||
assert values["section_A"] == pytest.approx(2.52)
|
assert values["section_A"] == pytest.approx(4.41)
|
||||||
assert values["section_Sx"] == pytest.approx(5.1)
|
assert values["section_Sx"] == pytest.approx(13.8)
|
||||||
assert values["section_Zx"] == pytest.approx(5.73)
|
assert values["section_Zx"] == pytest.approx(16.0)
|
||||||
assert values["section_rts"] == pytest.approx(1.05)
|
assert values["section_rts"] == pytest.approx(1.01)
|
||||||
|
|
||||||
|
|
||||||
def test_ground_truth_demands_and_flexure():
|
def test_demands_and_flexure():
|
||||||
output = result()
|
output = result()
|
||||||
values = output["values"]
|
values = output["values"]
|
||||||
assert values["point_load_lbf"] == pytest.approx(7500)
|
assert values["moment"] == pytest.approx(8.124)
|
||||||
assert values["moment_kipft"] == pytest.approx(9.375)
|
assert values["shear"] == pytest.approx(3.611)
|
||||||
assert values["shear_kip"] == pytest.approx(3.75)
|
assert values["Lp"] == pytest.approx(2.861, abs=0.01)
|
||||||
assert values["Lp_in"] == pytest.approx(37.7, abs=0.1)
|
assert values["Lr"] == pytest.approx(8.609, abs=0.01)
|
||||||
assert values["Lr_ft"] == pytest.approx(9.48, abs=0.01)
|
assert values["Lb"] == pytest.approx(9.0)
|
||||||
assert values["Fcr_ksi"] == pytest.approx(99.57, abs=0.25)
|
assert values["Fcr"] == pytest.approx(32.556, abs=0.01)
|
||||||
assert values["Mp_kipft"] == pytest.approx(23.875)
|
assert values["Mp"] == pytest.approx(66.667, abs=0.01)
|
||||||
assert values["MnLTB_kipft"] == pytest.approx(21.235, abs=0.01)
|
assert values["MnLTB"] == pytest.approx(37.439, abs=0.01)
|
||||||
assert values["phiMn_kipft"] == pytest.approx(19.1, abs=0.1)
|
assert values["phiMn"] == pytest.approx(33.695, abs=0.01)
|
||||||
assert output["checks"]["flexure"]["ok"] is True
|
assert output["checks"]["flexure"]["ok"] is True
|
||||||
|
|
||||||
|
|
||||||
def test_ground_truth_shear_and_deflection():
|
def test_shear_and_deflection():
|
||||||
output = result()
|
output = result()
|
||||||
values = output["values"]
|
values = output["values"]
|
||||||
assert values["Aw_in2"] == pytest.approx(1.102, abs=0.001)
|
assert values["Aw"] == pytest.approx(2.5)
|
||||||
assert values["Cv1"] == pytest.approx(1)
|
assert values["Cv1"] == pytest.approx(1)
|
||||||
assert values["phiVn_kip"] == pytest.approx(33.047, abs=0.1)
|
assert values["phiVn"] == pytest.approx(75.0)
|
||||||
assert values["delta_limit_in"] == pytest.approx(0.25)
|
assert values["delta_limit"] == pytest.approx(0.45)
|
||||||
assert values["delta_in"] == pytest.approx(0.078, abs=0.001)
|
assert values["delta"] == pytest.approx(0.040559, abs=1e-5)
|
||||||
assert all(output["checks"][name]["ok"] for name in ("shear", "deflection"))
|
assert all(output["checks"][name]["ok"] for name in ("shear", "deflection"))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -79,14 +79,14 @@ def test_invalid_section_is_rejected():
|
||||||
module.compute({**yaml.safe_load((HERE / "input.yaml").read_text()), "section": "W0X0"})
|
module.compute({**yaml.safe_load((HERE / "input.yaml").read_text()), "section": "W0X0"})
|
||||||
|
|
||||||
|
|
||||||
def test_cli_can_write_json_to_stdout():
|
def test_cli_stdout_prints_summary():
|
||||||
completed = subprocess.run(
|
completed = subprocess.run(
|
||||||
[sys.executable, str(HERE / "calc.py"), "--input", str(HERE / "input.yaml"), "--stdout"],
|
[sys.executable, str(HERE / "calc.py"), "--input", str(HERE / "input.yaml"), "--stdout"],
|
||||||
check=True,
|
check=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
output = json.loads(completed.stdout)
|
|
||||||
assert output["section"] == "W6X8.5"
|
|
||||||
assert output["values"]["moment_kipft"] == pytest.approx(9.375)
|
|
||||||
assert completed.stderr == ""
|
assert completed.stderr == ""
|
||||||
|
assert "Steel Beam Design Summary" in completed.stdout
|
||||||
|
assert "Section: W10X15" in completed.stdout
|
||||||
|
assert "Flexure: OK" in completed.stdout
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue