From 8f91baee416ae9a67288a86e01429bd758e70885 Mon Sep 17 00:00:00 2001 From: smillmorel Date: Mon, 21 Sep 2026 12:44:28 -0400 Subject: [PATCH] Use Pint and unit-free variable names in concrete-beam Convert input parsing to Pint (matching the other calculations), carry units in the YAML values, and drop unit suffixes from input keys, local variables, results keys, the Typst sheet, and tests. --- concrete-beam/calc.py | 140 +++++++++++++++------------- concrete-beam/concrete-beam.pdf | 71 +++++++------- concrete-beam/concrete-beam.typ | 44 ++++----- concrete-beam/input.yaml | 22 ++--- concrete-beam/results.json | 44 ++++----- concrete-beam/test_concrete_beam.py | 16 ++-- 6 files changed, 174 insertions(+), 163 deletions(-) diff --git a/concrete-beam/calc.py b/concrete-beam/calc.py index 3aaa1fd..86a1b08 100644 --- a/concrete-beam/calc.py +++ b/concrete-beam/calc.py @@ -10,54 +10,68 @@ try: except ImportError: raise SystemExit("Install PyYAML: python -m pip install pyyaml") +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("psf = force_pound / foot ** 2") +ureg.define("pcf = force_pound / foot ** 3") -def _require_positive(name: str, value: float) -> float: - if value <= 0: + +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 value + return magnitude def compute(inp: dict) -> dict: - span_ft = _require_positive("span_ft", float(inp["span_ft"])) - tributary_ft = _require_positive("tributary_ft", float(inp["tributary_ft"])) - D_psf = _require_positive("D_psf", float(inp["D_psf"])) - L_psf = _require_positive("L_psf", float(inp["L_psf"])) - bw_in = _require_positive("bw_in", float(inp["bw_in"])) - h_in = _require_positive("h_in", float(inp["h_in"])) - d_in = _require_positive("d_in", float(inp["d_in"])) - fc_ksi = _require_positive("fc_ksi", float(inp["fc_ksi"])) - fy_ksi = _require_positive("fy_ksi", float(inp["fy_ksi"])) - As_in2 = _require_positive("As_in2", float(inp["As_in2"])) - concrete_pcf = _require_positive("concrete_pcf", float(inp["concrete_pcf"])) + span = quantity(inp["span"], "ft", "span") + tributary = quantity(inp["tributary"], "ft", "tributary") + D = quantity(inp["D"], "psf", "D") + L = quantity(inp["L"], "psf", "L") + bw = quantity(inp["bw"], "in", "bw") + h = quantity(inp["h"], "in", "h") + d = quantity(inp["d"], "in", "d") + fc = quantity(inp["fc"], "ksi", "fc") + fy = quantity(inp["fy"], "ksi", "fy") + As = quantity(inp["As"], "in**2", "As") + concrete_density = quantity(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 + self_weight = (bw * h / 144.0) * concrete_density / 1000.0 + wD = D * tributary / 1000.0 + self_weight + wL = L * tributary / 1000.0 + wu = 1.2 * wD + 1.6 * wL + Mu = wu * span**2 / 8.0 + Vu = wu * span / 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 + a = As * fy / (0.85 * fc * bw) + beta1 = max(0.65, min(0.85, 0.85 - 0.05 * max(0.0, (fc * 1000.0 - 4000.0) / 1000.0))) + c = a / beta1 + et = 0.003 * (d - c) / c if c > 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 + Mn = As * fy * (d - a / 2.0) / 12.0 + phiMn = phi * Mn - rho_min = max(3.0 * math.sqrt(fc_psi) / fy_psi, 200.0 / fy_psi) - As_min_in2 = rho_min * bw_in * d_in + rho_min = max(3.0 * math.sqrt(fc * 1000.0) / (fy * 1000.0), 200.0 / (fy * 1000.0)) + As_min = rho_min * bw * d - Vc_kip = 2.0 * math.sqrt(fc_psi) * bw_in * d_in / 1000.0 - phiVc_kip = 0.75 * Vc_kip + Vc = 2.0 * math.sqrt(fc * 1000.0) * bw * d / 1000.0 + phiVc = 0.75 * Vc def q(value: float) -> float: return round(value, 6) @@ -68,46 +82,46 @@ def compute(inp: dict) -> dict: "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), + "span": q(span), + "tributary": q(tributary), + "D": q(D), + "L": q(L), + "self_weight": q(self_weight), + "wD": q(wD), + "wL": q(wL), + "wu": q(wu), + "Mu": q(Mu), + "Vu": q(Vu), + "bw": q(bw), + "h": q(h), + "d": q(d), + "fc": q(fc), + "fy": q(fy), + "As": q(As), + "a": q(a), "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), + "Mn": q(Mn), + "phiMn": q(phiMn), + "As_min": q(As_min), + "Vc": q(Vc), + "phiVc": q(phiVc), }, "checks": { "flexure": { - "demand": q(Mu_kipft), - "capacity": q(phiMn_kipft), - "ok": Mu_kipft <= phiMn_kipft, + "demand": q(Mu), + "capacity": q(phiMn), + "ok": Mu <= phiMn, }, "minimum_steel": { - "demand": q(As_min_in2), - "capacity": q(As_in2), - "ok": As_in2 >= As_min_in2, + "demand": q(As_min), + "capacity": q(As), + "ok": As >= As_min, }, "shear": { - "demand": q(Vu_kip), - "capacity": q(phiVc_kip), - "ok": Vu_kip <= phiVc_kip, + "demand": q(Vu), + "capacity": q(phiVc), + "ok": Vu <= phiVc, }, }, } diff --git a/concrete-beam/concrete-beam.pdf b/concrete-beam/concrete-beam.pdf index a5ea0dd..da76c99 100644 --- a/concrete-beam/concrete-beam.pdf +++ b/concrete-beam/concrete-beam.pdf @@ -705,28 +705,25 @@ o endstream endobj 208 0 obj -<> +<> stream -xœÝY tTÕ¹þöùÏžI&™ÉÌ0yBd’8’IB"bbÕÉ‹ &€ ¢„LB"I&f�¦(–‹VF¯i›Zj[û¸\Kéh0EÁªE¯µ@ë«õ]K�´×‚ZŒ›®½ÏL2 ˆ®ë½«kÝ™•™}öÙûû¿ÿûÿ½÷&`â°„¼†•]î£÷™ãì´¼¦Žåm×h+^´!?^ÞººÉÁV˜Ú -Ð�æÆz¿ù^Ì׸°¹¹±>&¤é€y €s›Ûºn2}@—æ{k ¡^{S·æ§åu[ýMü'úy€ùEîöú¶Æ×¦’0 $ÞÙv!Àâ�ôoÈëèlì(zjŸHæ‰á ú{ˆÝ�š„p»v ´‘wûqšbÙìQăÆA¬ÃÌBO±YX‡A‹ô D/v¨™½ô.ºi/ἂnz—Ò£8È!ƒ½†îµBƒ¸ûi=4H‹ØdÖ†�ì§zbÜ¢õ ¤Õ¢Ïé/x·ãv܃�à9Ål»ÀnlÄqlÕŽâjìÆ£xRÏ€€Í°ÁŽàCÜ¢=¤]¢5a#žD/¶c;[‡#ê`¼Á�hÓ±»±À2ìàGøV©?Â�ð¿a'€tSÈä2g±CJ·Ù^6C«Æ!fAæÓµt#½ÂÖëYú*:Š^ ´7ày~ÄäB¯9 ½¦&¶Z_ªÞ=Ò?m•¾”=„£&—y}Œ-Ob‡òØ­Õòj^­¿€&ìÀõÙk|šìxŽNbîÖ»\ŸM—¡=z¶âç! @3qèá›�7ÂCðòÍÔ§õj°íìКØFôjâ9¨ ³Ð„t~ ëÙn“ 0¯A�\ø…ÙÄuÒ²Ýö]š§Ò¿Ëwå"÷Ó‹3¼Ùã.Ýv³{æí²®v‡N�š·HŸÈïâ“v‘'f—îÉzã³n¾áÍž3o‘;Ä’Ë˰åK˼ÙsêíÒ<òªlqF†7»¼LÝ“VwqÏ.î©\ºËÝÐìÞ`ß�U´ÁÞXä…†fѧ7ó� ˜1y/tæ`b®=,†¯Ótä8<4öÃC‡‡ò&82ž GF³Žá M~Gô™mÐiš ûO½¥{ô¤"×—¿ÑºÏŽ�©û’6‘}Sì mK›àŒ‡ivšýø�|‰ùöñ!»8~Ì~âXžÇƲÜpØ‘‘Ÿ”œ˜Ã²2M‰®¤‚ü géž+¾Y+†Å+ÌÃô+·WWÞ³ä'�üxéÖâÂéÓÙEÌÅ\ì¢ó³/.zý7Ï¿qñ¥€†õ§ÞÒ³ôÄaÚ}ç[ÌHsǧ$˜±'żə±ÑýËôMç:·¥XYŠžj³˜âËܺ)ñÒóíLJ åç; - g ÷ÀÛLJ�Ù�Ù�9 -…ÎB‡³0Ï—ž79Ï�—‘—Ù�~Ö¯õ[úãHêOîOéOíO³-‰b>s–#k¦�eeN™yÁ…³™Ê+óÌKYA~Rò9L¼ä;ßýjëÖŸ²G¹øgkôì'ÿˆÝvÏuû®iX´ñÉK¦¸µ‚;;=:­êÓ[ô_ÿøO¤ß¶ú Bç�W[›�¡y? [L“aÅß„X�eOü“´‡“I‡)®*Öf?<4ü¬rghxÈQX˜Ç\I³DÉÊ‘13C»åšÅ¿?ú½Ÿ‹—Øk¬ïk7ï8üýã.0vÐÞa3@°ïÁK‡n—™�;”Ç -Yìèð0›!ž‡Ô{P,Ôçë=°c -|“8\i›l®M1ƒ¶ml?=‘îpÆU$ë0i³ÓíLJòó‡Uôß–ñ?&)yYŽ‚D)ŒÓaײ2§° ¦ŒèÈV=òHÎ6ÿÁwÿüë¦mìo·¯¿mÆÛÖß¾ùÓgL–Þº«Ä¯Ä_Ä_Å3W±¿{ù•#‡_}ÙÐ¥Y,Ôo՗‰~_¹5ÙfÕH³Äi±ñÉDš#Ù §=9Áùå°[mÖ„d›ÍZbŸ`…-v“y¿Ãöć=Áj1ÃìŒqVÚÊ'Èäp$JêùÇ¥”μ9u‹Ìvþ¾Ùþ“mþ¾#¹P^.Î|ø"'cK|iº}¥]‹qÄ8SãS­SlS.rT:*�‹­–%XÂLfÍlcÓÙL™6¬ –ÐÕ9 ™9®ÝÒvåµ¢f?«bûYs÷/ÅÇEÕÕÛ¯; Wo¡VÃW@».ôéýæó®OøÊ LŽ‘½8ôÄô�#ߟlø”ñÁ˜BÆÍðÙpÊÅRô‹é/ û±ýì(Ñ ` -nÀë,že²Vö¦šaÖâ1+`‚;¶I ü*懮Ný 0=PçŸÑfpc0ÜÖƒ?†ÛÕ¯Gµ9Rð§pÛ„Iáv 2YZ¸‡"ö•pÛ:a -[nÛÐìÚ�RÐ�ÕèD –£]pc*0 nä#y(€˰n” ]¢ �hD=Ú� 7*ÑŽäÀ�b´¢nÔŽ`ÕU#‚hD'V¢~äÀ‚24âÔc!ºáFšQ�v,W#ݨWøn´ nt ËЊ4À ?hC½º7§N¡H„¹ ” €V`¡²D‹ê—žå ³ÆÌ�̎̋ݤz �ºÂÞK»Ð�"ä"þðø•èF‚ �h@£šÛ©¼ËA;Ñ…ÙQho#ªŸ®²¼'”£–¡­`¦)Íÿw””1±œÑ²¡\=Üc8Ÿž5x¿Ä[ZÿWd¢ûs|n «(c.{dŒ¥f�X7hú\.Ò³y -¯M¡�æ �ݬî5†ýZ®¬H•%?‰Ó¤î6ŽX3"ld“¼ß…€bØ®æw„óܰÀ2t…#,ÿ–‡}i+ÁìR,Ææx=Ô¸6t„Ñ#r´ÁÝȤFµjŒ ΌʒL99ׯ¾¥ï4 õaÿŒl@7ÚŠäÚ5¢OZÐÎã©#G-Èõ.ùwaU8Ï¥ÅQMdO:€ÝŠç(¿ò@F¬ËЭøŒêðÙ$ºÔ¡­èV(†&«T4«5ßVFÆ{¬GüÑ ްíVfGEG¶¥.£±]¿A4«ž3ù‘=âg®ÚwÜ -ÙXvKXÕ±Ñ?»×å ¶FžŽÍºQ�V)=Ú¾�…ÈjhR{f{ØC#G 4™)Ò“€bTJÜ€F4(ûŠ‘q”÷äw0ÌQÚ9[¾Þ�i—w»Õ¨± -gžµ^ÉÃÿéš•{lëÈ™=ºê"+JVÆÚ“ç’q¾ŒG”s°õjŒD6ÎE™U§×ÿ;Ög{eTZ†Šò\lQêr”+;5¨Æ|e§³1W¡µê^%êàÆ<Ô¢ Q‰2”£LÅ¥XÝ‘÷3Õj¼ -• -± –�Q‹b…½n…-+Õju5•¨F™š[ŽEÊF9êj jö\ÌC*•M£Æ¬F)ª°eª]¡ªQÃ^5jÔ·?Wq1˜ÎGM”Õ±¬$rݳ¹(G-Jqyøn1JP©ð$i¶jW�ðœfZ¬4’ȳ P¥®dïÔbjP§ô”Èea¶Õʇ٨ ûR®‘0•¢ó°X�¨À嘯XHKóÃ#åõ|å�ŒÌ\euŽê5˜Õ„£,Û£(ò9@Ú4xHýŽX®SþW¡Ji+ý­SÊQŒ¹#¸‘Ü©P’·¡ÆåŸäW©<”òžTQêY52²6**2¦Å*n’¹œ/=‘ŠÔ�Ñ“ÚØèœ);"$–Œ›TªJ�®Ã<”£T!=F>V*_KÃÚ˜FÞ9aŒ58ÉøT«È^‰áÞx/Œ"ù�zaD 8üY¥Ùhô%¢äá#³YfÙéªÈõ'™ÈQ2 äUD™c2Jsc½6"q\ÎÏÈÊ«§odEÆ}‘½ÃÀŠØA©§ÔÉ`hì$Õ_ר»Êq“Ú÷:ÂçZð´“;ºz­J£ëÏ쨽6º0vá -5¶mܸÑ^c6άÑgžèîL'Wä)9{\õ©>Œ½Ûx6Š®~ýªN7jÁàHUbœ�‘ÊDVÿFÅyj‘Oƒò|û¼Tv Ï [§cõ¥gX žAͳ�PãŸ%©‘D^¥Úò·$£b¨WcäXÙÿÕqOņ_<_>OÙT§¨¬E[”²žÌ ãvŽ<Ÿ�j"0~ÝjõÑì“hE§Õ¡RƒåQÌåó�QcȺBÚ´|‰ß×r•Þ+Ђ\ÅQν 9ª -ï@RþV¯^§nÆÕá_ŽÇ¾Ìf£ 5p ×>¢­e‰oY‹'±Dô�X"Öªÿ › >�p‚˜Cµíê3ÛA̦Úև߫àÅfÅ‹‡Äâ�b…«FÅÀbfÕ6©1\µuÕOªGS=Ì·X�ôéô‰ “ùô�úx }ôá&þ‘ �öéžXÌ?ÜD®ÕOŸÂO,¦>ýøúû¹üï'éƒ\úoAô×|:æ¢÷ûhè½ ->$h(têß)ý½ -úËQ?ÿKõÓŸ½û§‰ü]AšHïz{½%èÍzãõTþÆIz=•^ë£? -úƒ W_Iä¯ -z%‘^^Lä/ zqs1‘~¿†~WDG6Çñ#EtXСßZø!A¿µÐ ‚~#èù þü$ú¯$zNг}tp£‡ôkAϬ¡§=%èW‚žÜnåíô„ ÇíÛÇ÷¹è—ñ4øØôØÞ%ü±zl­¾wÀÃ÷.¡½>}ÀC� -z¤�B½Åü‚öôó='éçÛ­|· Ÿùéa?ý§�v9é?ýTø>¥Ÿú± 9é!A?ü��ÿ0Ÿ~`£ï?èàߟJ:è{;½ü{kh§—¾+èAßÔÿíTÞï§oËο�Jß²Ó7-´CÐýÛ­ü~AÛ­´mkß&hkÝ×[Ìï룾{xŸ {·,á÷нkõ-wyø–%´Å§ß#èßÝ}—‡ß=@wy¨w£‡÷Ó�›ãø�.ÚG›6zø&?mÜàà=´ÁAwú† ÛݶÞÁo´ÞAÿ&h� ¯;Jø×ëèVAko¢[n^ÃotóZs}MP��¾*h• •‚º»âywu‡|/ë]ñÔµO:)èÓ;Ý(¨CP ½Žú¨½m*o¯£¶©Ô*hE>Ý ¨%ŸšOÒòjÔ(È/¨aÙ9¼AÐ2Øù²s¨^ÐRA× ºîê8~��–øéÚ§éš«ãø5.º:Ž Z䢫-´`b*_�OóÕ ªtåš'¨ÆEÕ‚æ2/Ÿ+¨j€æL¥+*Sø³¨²ÔÉ+Sèòò~¹ ŠR'¯ðÓìò>{€ÊS¨¬ÔÉËfQi‰ƒ—:©4¤ù|±zIq/qPIHƒ/V/öÙxq‡Ø>_¬î»,žûlä ±µ¾Xý²øX~Y<]b>Ÿ_¿TÐ%ÌË/9I_tñT*Tè(á…~ºhF¿hÍt¡×Å/4s]�—Æ/˜Cyi¼@P¾£„ç šáuñi”—F¹^ÏM¡œØ$ž3@Þì Üë"oH“f³íž=�²%Ý>}úù>]Ðù±Iü|MÓŠø4AS�'hJy’J¸§œÎM ,A™ –[-d 1ßn=>–âenÍÒãYb“¸EPlÅØÉ,ÈļÜ$ˆ»ˆ´"N'Ic^®ƒ�3/ÁN,Äüë7³éÿ^øWø’¯tüƒ–—y +xœÝY tTÕ¹þöùÏžI&™ÉÌ0yBt’8’IB"bâkò"¦„@P±„LB"I&fS*-<½b +”¶©¥¶µÕ˵”ŽS*Øj©×Z õÕª­�Ò¦Ôk-ÆM×Þgf2 ˆ®Û{W׺3+3ûì³÷÷ÿ÷ÿ{ïÿLÀ$`M«zÜǾlN°Ð +ZºVtܨ­| ÐF|Eûš[ih@[›ý3¶Ç½ ˜opYkkscÜ^MÌ[\ÔÚÑs›é=º0‡ØÛM�Úïu `~F^w4ÞÖÅѯÌ/pw6v4¿6�¬€ù ùK]�`že‰@æÝ +ºº›»J~¶ß d†ód„pHý=ÌîC-B¸K»Zô‚¦Æ…Ø!v{‡ðFqëñ³ÐÏØl¬Ç0€Åz¡;ÕÌ~z½´‡ñ,^A/½ÃŠé b‡‘Å^C÷ŒY¡a܃4Œ>¦ÅìBÖ�]ìQ}±îÐúÒêÑ�çô<‡»pîÇ.ðœb¶žÝ‡ßb6á¶iÇpöà <­gAÀfØ`Gq +whkWi-Ø„§Ñ�ØÁÖã(‚:˜oð£Ú ìÂì°;ùQ¾MêÁ�ò£ü]ì�i +™\ævXéöÛÇfjµ8Ì,èú‰n¥WØ=G_MÇЯ�–á<Ï�š\è7ç ßÔÂÖèËÔ»Oú§­Ö—±‡qÌä2/§ЧeáiìT{´z^ËkõЂ�Ø©>û�O“ÏÑi¬Ç}š`×êsèô£O¯Á6<àbhnA}|‹ñÆÃx^¾…´>C V¤]…�Z Û„~ížC€*0-ÈäDZ�í1¹óZùQÀ…™M\'�!×mß­yªý»}×-v?³$Ë›;áÒm7»wcþnëwèÌ™ù‹õÉ|Én>e7yâvëžœ7>îæÞܹó»C,µ²" [¹¬Â›;·añnÍ#¯*–deys++Ô=iu7÷ìæžêe»ÝM­î�ö�9%íÍ%^hhz+ß‚îƒÎ\L̵—ÅñõšŽüƒGFfÂ~däÈHÁ$G–ÓåÈjÕ1¤É£o‰³íƒ÷ºMÓ€áÀ™?è½éÈ÷e$n²î·cSúþ”Ídß?LÛ3&9aš“a?q°Pb¾ybÄ.N·Ÿ<^à±±7vd¦¤&籜lS²+¥¨ð²Ùºç3_­£âæaúu;j«ï_úÈCß_¶­´xÆ v9s1»ü’ÜŸ”–¼þËç߸âj@Æ3Ðsô>$`::}—XÌÈp'¦%™±7ͼٙµÉýãÌÍ ;·§YYšžn³˜+ܺ)ùêKì'FŽŽ:Š‹g"ÿà›'FOŒØ�Û�;ŠÅÎb‡³¸À—Ypa�» « {ƒlP´ &<˜2˜:˜6˜>˜a[Ã|ÖlGÎ,ËÉž:ëÒË®`³”WæYW³¢Â”Ô ˜6|Õ7¾y{û¶GÙã�_ñƒußûŇ{ŸÝyÿÍûolZ¼é髦ºµ¢[»š»?1½æ£/<äÿìOz*óÎ5—]ºøâúúÂû ÍÝbºVLõMŠYö&>M{9™t˜jâmö##£¿PŽ8Š‹ ˜+å +–,Y9²feiwܸä7ǾõCñ{� |îó;�zÖdéo¸^üTüIüU<{=;ùë—_9zäÕ— ]ZÅ"ý ú281è«´¦Ú¬i–->1•Hs¤:á´§&Ù!¿v«Íš”j³YË쓬°Åo6pØžšä°'Y-f˜�qÎj[å$™ŽÔbI½ð„”ÒY\0·a±ÙÎÿb¶Ç…ÿd›ÿÅ‘Z,/—d?v¹“±¥¾ ݾʮÅ9âœé‰éÖ©¶©I—;ªÕÎ%VËR,e&³f¶±l–LVϊ膼ª¦ì¼�7mí¸î¦*Qw€Õ°ª¬µ÷Ç⃒ÚÚ7ÔkG·R»á+ ÝúáÞSG?›tåI\'{ñVAôûû?b|8®@4Õ­æ™;D& ¿ðáÝg\|X!ž˜þZq0ÈŽa­¦â¼ÎY6kg¿W3ÌÚE˜�•0AƒÛð뙺:õ7‚Àôx@�F›Á�áp[C~nSL¿ÓæHÃÛá¶ S Âí8d³Œp;%ìÊpÛ:i*[nÛÐêÚ‰rÐ…5èFV =pcš0n¢(‚˱n”¡ =¢ÝhF#:� 7ªÑ‰&äÁ�R´£nÔG±‚êªA4£«Ð ?ò`Ašq ±½p£ ­hD'V¨‘n4*|7ÚÐ 7ºÐ‹åhGšà†t QÝ›ˆÓ P$Â<ЉÊ@+±HÙ¢MõKÏòP„ÙãæGfGæŽÇnQ½†G=a磊=èB ò‘xü*ô"AЋn4¡YÍíVÞå¡ÍèÁœ´ˆ·ÕÏVYÞ“ +ÊQËÑŒv°Ó•æÿ;JʘXÎiÙP®îqœÏÎ ¼ÿÄ[ZÿWd¢û|n «(c.{dŒ¥fÝX 7hùD.Ò³ù +¯C¡�å �ݪî5‡ýZ¡¬H•%?‰Ó¢î6G­6²IÞïA@1ìTó»ÂynX`9z–+¾4…•Ž`ö(ãs¼Mj\ºÂè9ÚàndR³Z5FgÇdI¶ŠœœëWßÒ÷šÐ†Æ°F6¡ +Erí‰êÓ‚6´‡óxZ”㘹Þ%ÿ¬ç¹´8¦‰ìéB7ð£WñcãWȈµa9zŸ1>Þ‚D—:4¡½ +ÅÐdµÊ�Vµæ{ÂÊÈx�÷(‚?–áÁ(Û^¥anLtd[ê2ë±õD«ê9—¹Q?óÕ¾ãVÈÆz0°ÛªŽ�þù½Ž(g°5òÌðp|Ö�y´ZéÑñ©,DVC‹Ú3;Ã9b ÉL‘ž› Râ4£Iácbó¸=¼KF"$=—´EãD‰Z� ³±µ3ŒÅ v/Sàì�@žWfYpÜØÈZé:ç;Oz%×¶)¹Ï�Ï5C c'oÅäê—§MdFlü Îç_12Žòžü†9J;çËûsíáòn¯5^áìóÖ+Ùãbø?]³r�m�žÙc«.²¢da¬=y.çËDD9§ +ѨÆHdã\”Yuvýñ±c}¼WF¥e¨(ÏÅ–¨R×¢RÙ©C-(;u˜ƒ¸¥¨W÷ªÑ7æ£uX„jT *.¥ê޼Ÿ­Vãõ¨VˆuX¨° Œz”*ì%p+lY©Öª«¹¨F-*ÔÜJ,V6*Ñ PëP¯°ça>jP­l5f-ÊQƒ…¨Pí*U�öjQ§¾åøyŠ‹Átêb¬Žg%‘¢Ìæ¡õ(ǵụ(CµÂ“ü¥ý9ª]å9'Ì´Ti$‘%f9¢F]ÉÞ…¨Ç|Ô¡Aé)‘+Âlk•sPö¥R10"a0*Gæc‰Q…k±@±�–„GÊëÊ™yÊê\Õk0« GY¶ÇPäs€´ið�ú/ŠZnPþ× Fi+ýmP*QŠyQÜHîT)ÉÛPc¡òOò«VJ yOª(õ¬‰Ž¬�‰ŠŒi©Š›d.çKO¤" çô$‚6>:çÊŽˆ‰%ã&•ªQ£0•(WHF�‘�ÕÊ×ò°¶¦‘÷FNc N2>µ*²×aax„�7Ñ c…Hþc^( –Çh6}‰(9GøÈl–Yv¶*rýI&r”ÌyQA昌’ÁÜX/†�H†ó3²òj'èYG‘qŸfï0°"¶ÇGPê)u2;Ií§Â5ö®Jܦö½®ð¹<ë䎭ÇªÒØú37f¯�­Œ]¸J�í˜0n¬×ØŸ�3kì™'¶†;×ÉyJÎ�PýFªcï6ž�b«_¿ªÓ�Z0­JŒó#­LdõoT ‘§ù4(Ï—ñÏ{Ae×ð̰u6–Q_Êq†µà9Ô<ß 5ñ Qr‘IäÕª-K2*†F5FŽ•ý·Ox*6|øô1ˆøòIúËÞ :Ee-Ú¦–õd^·;ú|6¦‰TÀøu«cBÔDzO¢•œU‡J VÄ0—ÏwF�!ë +iÓòOü¾–¯ô^‰6ä+ŽrîmÈSUxò'T”ò·zõ:ó"nÿr<þe0¨ƒ ¸éqmK~lëR^:…%cÄ’±Ný�H€Ø$õé„ĪmWŸIØb6Õ¶>öç*^êaV¬±Dx@,… fQxñjTl fVm“ÃU[Wý¤z4ÕÃ|K A­¥QA +:]H¢ÖÒû§6ó÷½¿_?ur ?µ™N­ÓOž˜ÊO.¡“>ýÄTúÛ{ùüo§é½|úoAï +úk!wÑ_häÏU|DÐHèÌ ¾3úŸ«èOÇüüOtÌOôÎÛ“ù;‚ÞžLo zs%ýAÐï‡è�×Óù§éõtzm€~'è·‚^}%™¿*è•dzy€^z1™¿$èÅ- üÅdúÍZúu Ý’À�–ÐA‡eá‡ýÊB/ú¥ ç7:øóSè¿Rè9A¿ C›<ü� Ÿ zv-=#èg‚~*èéV~PÐAO ú‰ ý[ø~ý8‘†Ÿâžܷ”?9DO®Ó÷ yø¾¥´Ï§yè A�P¨¿”ÿHÐÞþR¾÷4ýp‡•ïô?=æ§ÿ´Ñn'ý‡ G…ï#zDÐ÷}ÏI úîwlü»…ô}û!ÿö4zÈAßÚååßZK»¼ôMA +ú† Á¯§óA?}ýkvþõtúš�¾j¡�‚¾²ÃÊ¿"h‡•¶oËãÛmË£/÷—ò/ÐÀC|@Ð[—ò†è�uúÖ{=|ëRÚêÓïôï‚î»×Ãï¢{=Ô¿ÉÃûKéK[ø—\´%�6oòðÍ~Ú´ÑÁ7yh£ƒît· »ݹÁÁï´ÁAÿ&h½ /:Êøè ‚ÖÝFw|~-¿CÐç×ÒÚ ès‚últ» Õ‚V êíIä½IÔbð½¬÷$RÏ~=褠Oït« .A�ΠΎi¼³�:¦Q» •…t‹ ¶Bj=M+†¨EP³ ¿ ¦åð&AËaçË/ FAË}VÐÍ7$ð›m´ÔO7=C7Þ�ÀotÑ ´DÐb]/h‘ …“ÓùÂBZ ¨AP½ ëÖÒ|Au.ª4�yù/M¢ÒÛï‹×}×$rŸ�|!¶Î¯_“ϯI¤kBÌçóëW ºŠyùU§éJAWL£AÅŽ2^ì§ËgfðËçÒlA—y]ü2A³æÒ¥üÒ¹TT�Á‹:Êx¡ ™^Ÿ™A”ïuñü4Ê‹OáyCäÍ�Ľ.ò†4i6×î๓(WÒÐg\âá3]ŸÂ/ñÐt­„O4MÐÅ‚¦&‘'¥Œ{*é¢$Ê”�”ije¹½EÐdØùätÊ”.(MPjJO�C)É^žRFÉ.;Oö’ËN“`ç“\ät”q§ órGÙ“’¸ÝAvC»$["OJ¢$C;›ÕÂm‰d3´³&Æs«…¬!æÛ£'ÆS¢Ì­Ùz‚ K| +·ŠO¡8;™™˜—›q‘VÂé4iÌ˵b°sæ%؉…˜Ã6ãÿÏ ÿjÿä+ÿ¬?—y endstream endobj 209 0 obj @@ -1191,12 +1188,12 @@ r endstream endobj 218 0 obj -<> +<> endobj 219 0 obj <> stream -Concrete Beam AnalysisConemco EngineeringTypst 0.15.1en2026-09-03T20:37:34-04:002026-09-03T20:37:34-04:002application/pdfLV3i1VpQNYDMq1s3457ZEQ==6OKHFztuOUXX7fYilLhfDw==proof1.7 +Concrete Beam AnalysisConemco EngineeringTypst 0.15.1en2026-09-21T12:44:08-04:002026-09-21T12:44:08-04:002application/pdfZKKY70e37OpYXWBmV77P8g==6OKHFztuOUXX7fYilLhfDw==proof1.7 endstream endobj 220 0 obj @@ -1413,20 +1410,20 @@ xref 0000034595 00000 n 0000034672 00000 n 0000035131 00000 n -0000039890 00000 n -0000039972 00000 n -0000040745 00000 n -0000050159 00000 n -0000054744 00000 n -0000056402 00000 n -0000056809 00000 n -0000057152 00000 n -0000104750 00000 n -0000171864 00000 n -0000172035 00000 n -0000173289 00000 n +0000039895 00000 n +0000039977 00000 n +0000040750 00000 n +0000050164 00000 n +0000054749 00000 n +0000056407 00000 n +0000056814 00000 n +0000057157 00000 n +0000104755 00000 n +0000171869 00000 n +0000172040 00000 n +0000173294 00000 n trailer -<> +<> startxref -173474 +173479 %%EOF \ No newline at end of file diff --git a/concrete-beam/concrete-beam.typ b/concrete-beam/concrete-beam.typ index 697813b..3092571 100644 --- a/concrete-beam/concrete-beam.typ +++ b/concrete-beam/concrete-beam.typ @@ -28,51 +28,51 @@ Simple-span rectangular beam under uniform gravity load. Numbers come from `calc 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] + #text(size: 9pt)[#n.span ft simple span · #n.bw in × #n.h in section] ] } #figure( beam-sketch, - caption: [#n.span_ft ft simply supported beam, #n.bw_in in × #n.h_in in rectangular section.], + caption: [#n.span ft simply supported beam, #n.bw in × #n.h 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([$L = #n.span " ft"$], [Simple span]) +#calcline([$B_t = #n.tributary " ft"$], [Tributary width]) +#calcline([$D = #n.D " psf"$], [Dead load including superimposed dead]) +#calcline([$L_L = #n.L " psf"$], [Live load]) +#calcline([$w_("sw") = #round(n.self_weight, 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"$], + [$w_u = 1.2 w_D + 1.6 w_L = #round(n.wu, digits: 3) " kip/ft"$], [Factored uniform line load], ) #calcline( - [$M_u = w_u L^2 / 8 = #round(n.Mu_kipft) " kip·ft"$], + [$M_u = w_u L^2 / 8 = #round(n.Mu) " kip·ft"$], [Maximum positive moment], ) #calcline( - [$V_u = w_u L / 2 = #round(n.Vu_kip) " kip"$], + [$V_u = w_u L / 2 = #round(n.Vu) " 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([$b_w = #n.bw " in"$], [Beam width]) +#calcline([$h = #n.h " in"$], [Overall depth]) +#calcline([$d = #n.d " in"$], [Effective depth]) +#calcline([$f'_c = #n.fc " ksi"$], [Concrete compressive strength]) +#calcline([$f_y = #n.fy " ksi"$], [Steel yield strength]) +#calcline([$A_s = #n.As " 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"$], + [$a = A_s f_y / (0.85 f'_c b_w) = #round(n.a, 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"$], + [$phi M_n = phi A_s f_y (d - a/2) = #round(n.phiMn) " kip·ft"$], [Design flexural strength], ) @@ -89,8 +89,8 @@ Simple-span rectangular beam under uniform gravity load. Numbers come from `calc == 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]) +#calcline([$A_("s,min") = #round(n.As_min, digits: 3) " in"^2$], [Minimum longitudinal steel]) +#calcline([$A_("s,prov") = #round(n.As, digits: 3) " in"^2$], [Provided longitudinal steel]) #v(7pt) #check( @@ -104,8 +104,8 @@ Simple-span rectangular beam under uniform gravity load. Numbers come from `calc ) #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]) +#calcline([$V_c = 2 sqrt(f'_c) b_w d = #round(n.Vc) " kip"$], [Concrete shear strength]) +#calcline([$phi V_c = #round(n.phiVc) " kip"$], [Design concrete shear strength]) #v(7pt) #check( diff --git a/concrete-beam/input.yaml b/concrete-beam/input.yaml index a172770..698db78 100644 --- a/concrete-beam/input.yaml +++ b/concrete-beam/input.yaml @@ -1,15 +1,15 @@ project: "Deer Creek Shoring" prepared_by: "Conemco Engineering" -span_ft: 16 -tributary_ft: 6.25 -D_psf: 55 -L_psf: 20 -bw_in: 8 -h_in: 12 -d_in: 9.5 -fc_ksi: 3.0 -fy_ksi: 60 -As_in2: 0.62 -concrete_pcf: 150 +span: "16 ft" +tributary: "6.25 ft" +D: "55 psf" +L: "20 psf" +bw: "8 in" +h: "12 in" +d: "9.5 in" +fc: "3.0 ksi" +fy: "60 ksi" +As: "0.62 in**2" +concrete_density: "150 pcf" load_combination: "1.2D + 1.6L" diff --git a/concrete-beam/results.json b/concrete-beam/results.json index c4a0513..db84d98 100644 --- a/concrete-beam/results.json +++ b/concrete-beam/results.json @@ -4,30 +4,30 @@ "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": 9.5, - "fc_ksi": 3.0, - "fy_ksi": 60.0, - "As_in2": 0.62, - "a_in": 1.823529, + "span": 16.0, + "tributary": 6.25, + "D": 55.0, + "L": 20.0, + "self_weight": 0.1, + "wD": 0.44375, + "wL": 0.125, + "wu": 0.7325, + "Mu": 23.44, + "Vu": 5.86, + "bw": 8.0, + "h": 12.0, + "d": 9.5, + "fc": 3.0, + "fy": 60.0, + "As": 0.62, + "a": 1.823529, "et": 0.010285, "phi": 0.9, - "Mn_kipft": 26.623529, - "phiMn_kipft": 23.961176, - "As_min_in2": 0.253333, - "Vc_kip": 8.325383, - "phiVc_kip": 6.244037 + "Mn": 26.623529, + "phiMn": 23.961176, + "As_min": 0.253333, + "Vc": 8.325383, + "phiVc": 6.244037 }, "checks": { "flexure": { diff --git a/concrete-beam/test_concrete_beam.py b/concrete-beam/test_concrete_beam.py index c30b0fb..ad4ad51 100644 --- a/concrete-beam/test_concrete_beam.py +++ b/concrete-beam/test_concrete_beam.py @@ -23,24 +23,24 @@ def result(): 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) + assert v["self_weight"] == pytest.approx(0.1) + assert v["wu"] == pytest.approx(0.7325) + assert v["Mu"] == pytest.approx(23.44) + assert v["Vu"] == pytest.approx(5.86) def test_example_flexure(result): v = result["values"] - assert v["a_in"] == pytest.approx(1.823529, rel=1e-5) + assert v["a"] == pytest.approx(1.823529, rel=1e-5) assert v["et"] == pytest.approx(0.010283, rel=1e-3) assert v["phi"] == pytest.approx(0.9) - assert v["phiMn_kipft"] == pytest.approx(23.961176, rel=1e-5) + assert v["phiMn"] == pytest.approx(23.961176, 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.253333, rel=1e-4) - assert v["phiVc_kip"] == pytest.approx(6.244016, rel=1e-4) + assert v["As_min"] == pytest.approx(0.253333, rel=1e-4) + assert v["phiVc"] == pytest.approx(6.244016, rel=1e-4) assert result["checks"]["minimum_steel"]["ok"] is True assert result["checks"]["shear"]["ok"] is True