Last active
April 25, 2025 19:59
-
-
Save joreilly86/a4a4b2517337608ba3f65925f1bd9e75 to your computer and use it in GitHub Desktop.
#068 - Structuring Engineering Calculations in Python | 01 - The Basics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ---- FULL CONSOLIDATED SCRIPT FROM FLOCODE NEWSLETTER #068 - Structuring Engineering Calculations in Python | 01 - The Basics | |
| # https://flocode.substack.com/ | |
| import math # Provides math constants (pi) and functions (sqrt) | |
| # ---- FUNDAMENTAL INPUT PARAMETERS & ASSUMPTIONS ---- | |
| # Basic geometry, material properties, loads, factors per ACI 318-19 | |
| # Anchor Properties | |
| da = 0.75 # Anchor diameter (in) | |
| futa = 58 # Anchor steel ultimate tensile strength (ksi) | |
| hef = 12 # Effective embedment depth (in) | |
| # Concrete Properties | |
| fc = 5 # Concrete compressive strength (ksi) | |
| lambda_a = 1.0 # Modification for lightweight concrete (17.2.6) - 1.0 for normalweight | |
| # Anchor Group Geometry (Rectangular Group Assumed) | |
| Nx = 2 # Number of anchors in group along X-axis (direction of ca1/ca2) | |
| Ny = 2 # Number of anchors in group along Y-axis (direction of ca1_p/ca2_p) | |
| sx = 6.0 # Spacing between anchors along X-axis (in) | |
| sy = 6.0 # Spacing between anchors along Y-axis (in) | |
| # Edge Distances (Defined relative to the CL of outermost anchors) | |
| ca1 = 17.5 # Max edge distance, X-dir (in) - Direction // to Shear Vu | |
| ca2 = 14.5 # Min edge distance, X-dir (in) - Opposite ca1 | |
| ca1_p = 20.5 # Max edge distance, Y-dir (in) - Direction perp. to Shear Vu | |
| ca2_p = 17.5 # Min edge distance, Y-dir (in) - Opposite ca1_p | |
| # Applied Load | |
| V_app = 7.96 # Applied factored shear load (kips) - Assumed acting along X-axis | |
| # Design Assumptions & Factors (ACI 318-19 References) | |
| phi_vs = 0.70 # Strength reduction factor, steel shear (Table 21.2.1, Sec 17.3.3) | |
| phi_vc = 0.70 # Strength reduction factor, concrete breakout/pryout (Table 21.2.1, Sec 17.3.3) | |
| cracked = True # Assumed condition: True or False (Affects psi_c factors) | |
| # ---- GEOMETRY CALCULATIONS (DERIVED INPUTS) ---- | |
| # Calculate projected areas based on fundamental geometry inputs | |
| # Assumes rectangular group & edge distances to CL of outermost anchors | |
| # NOTE: ACI projected area calculations can be complex. This is a simplified interpretation based on 1.5*hef boundaries. VERIFY FOR REAL DESIGNS. | |
| # Width of failure prism in X-direction (influenced by ca1, ca2) | |
| group_width_x = (Nx - 1) * sx if Nx > 1 else 0 | |
| width_boundary_x1 = min(1.5 * hef, ca1) # Boundary distance from outer anchor CL towards edge ca1 | |
| width_boundary_x2 = min(1.5 * hef, ca2) # Boundary distance from outer anchor CL towards edge ca2 | |
| projected_width_for_AVc = group_width_x + width_boundary_x1 + width_boundary_x2 | |
| # Height of failure prism in Y-direction (influenced by ca1_p, ca2_p) | |
| group_width_y = (Ny - 1) * sy if Ny > 1 else 0 | |
| width_boundary_y1 = min(1.5 * hef, ca1_p) | |
| width_boundary_y2 = min(1.5 * hef, ca2_p) | |
| projected_height_for_AVc = group_width_y + width_boundary_y1 + width_boundary_y2 | |
| AVc = projected_width_for_AVc * projected_height_for_AVc # Projected area // to load direction (in^2) | |
| # AVc_p: projected area resisting shear perpendicular to edge (hypothetical load in Y-dir) | |
| projected_width_for_AVcp = group_width_x + width_boundary_x1 + width_boundary_x2 | |
| projected_height_for_AVcp = group_width_y + width_boundary_y1 + width_boundary_y2 | |
| AVc_p = projected_width_for_AVcp * projected_height_for_AVcp # Projected area perp to load direction (in^2) - Recheck logic | |
| # Projected Area for Tension Breakout (ANc) - Used for Pryout calc Vcp = kcp*Ncbg | |
| c_min_overall = min(ca1, ca2, ca1_p, ca2_p) | |
| width_anc = group_width_x + 2 * min(1.5 * hef, ca1, ca2) | |
| height_anc = group_width_y + 2 * min(1.5 * hef, ca1_p, ca2_p) | |
| ANc = width_anc * height_anc # Projected area for tension breakout (in^2) | |
| # Single anchor projected areas (calculated for use in ACI group formulas) | |
| AVco = 4.5 * ca1**2 # Area single anchor // load direction (Fig R17.7.2.1(b)) | |
| AVco_p = 4.5 * ca1_p**2 # Area single anchor perp load direction | |
| ANco = 9 * hef**2 # Area single anchor tension (Fig R17.6.2.1(b)) | |
| # ---- CORE ENGINEERING CALCULATIONS (ACI 318-19 Ch 17) ---- | |
| # Organized by failure mode, using previously defined or calculated variables | |
| # --- Steel Strength (ACI 17.7.1) --- | |
| N_anchors = Nx * Ny | |
| Ase = math.pi * da**2 / 4 | |
| Vsa_single = 0.8 * Ase * futa # Nominal steel shear strength per anchor (kips) - Eq (17.7.1.2b) simplified | |
| Vsa = N_anchors * Vsa_single # Group nominal steel strength (kips) - Assumes direct summation; verify ACI group effects | |
| phiVsa = phi_vs * Vsa # Design steel shear strength (kips) | |
| # --- Concrete Breakout Strength (Direction of Load) (ACI 17.7.2) --- | |
| le = min(hef, 8 * da) # Effective length for breakout (in) - 17.7.2.3 | |
| Vb1 = 7 * (le / da)**0.2 * math.sqrt(da) * lambda_a * math.sqrt(fc * 1000) * ca1**1.5 / 1000 # Eq (17.7.2.2a) | |
| Vb2 = 9 * lambda_a * math.sqrt(fc * 1000) * ca1**1.5 / 1000 # Eq (17.7.2.2b) | |
| Vb = min(Vb1, Vb2) # Basic concrete breakout strength (kips) - 17.7.2.2 | |
| psi_ed = 0.7 + 0.3 * ca2 / (1.5 * ca1) if ca2 < 1.5 * ca1 else 1.0 # Edge effect (psi_ed,V - 17.7.2.5a) | |
| psi_ec = 1.0 # Eccentricity (psi_ec,V - 17.7.2.4): Assumed 1.0 | |
| psi_c = 1.0 if cracked and lambda_a == 1.0 else (1.25 if cracked and lambda_a < 1.0 else 1.4) # Cracked concrete (psi_c,V - 17.7.2.7) - Check Table carefully | |
| psi_h = 1.0 # Member thickness (psi_h,V - 17.7.2.8): Assumed 1.0 | |
| Vcbg = (AVc / AVco) * psi_ec * psi_ed * psi_c * psi_h * Vb # Group breakout strength (kips) - Eq (17.7.2.1b) | |
| phiVcbg = phi_vc * Vcbg # Design group breakout strength (kips) | |
| # --- Concrete Breakout Strength (Perpendicular to Load) (ACI 17.7.2) --- | |
| Vb1_p = 7 * (le / da)**0.2 * math.sqrt(da) * lambda_a * math.sqrt(fc * 1000) * ca1_p**1.5 / 1000 | |
| Vb2_p = 9 * lambda_a * math.sqrt(fc * 1000) * ca1_p**1.5 / 1000 | |
| Vb_p = min(Vb1_p, Vb2_p) | |
| psi_ed_p = 0.7 + 0.3 * ca2_p / (1.5 * ca1_p) if ca2_p < 1.5 * ca1_p else 1.0 # Edge effect factor based on ca2_p | |
| # Factor of 2 applies under specific geometric conditions (ACI Fig R17.7.2.1(c)) - Verify applicability! | |
| Vcbg_p = 2 * (AVc_p / AVco_p) * psi_ec * psi_ed_p * psi_c * psi_h * Vb_p # Factor of 2 applied | |
| phiVcbg_p = phi_vc * Vcbg_p | |
| # --- Concrete Pryout Strength (ACI 17.7.3) --- | |
| Nb_single = 16 * lambda_a * math.sqrt(fc * 1000) * hef**(5/3) / 1000 # Basic tension breakout single anchor (kips) - Eq (17.6.2.2a) | |
| psi_ec_N = 1.0 # Eccentricity factor tension (Assume concentric) - 17.6.2.5 | |
| psi_ed_N = 0.7 + 0.3 * c_min_overall / (1.5 * hef) if c_min_overall < 1.5 * hef else 1.0 # Edge factor tension (Eq 17.6.2.6a) | |
| psi_c_N = 1.0 if cracked else 1.25 # Cracking factor tension (psi_c,N - 17.6.2.7) | |
| psi_cp_N = 1.0 # Splitting factor tension (psi_cp,N - 17.6.2.8) | |
| Ncbg = (ANc / ANco) * psi_ec_N * psi_ed_N * psi_c_N * psi_cp_N * Nb_single # Group tension breakout (kips) - Eq (17.6.2.1b) | |
| kcp = 1.0 if hef < 2.5 else 2.0 # Pryout coefficient - 17.7.3.1 | |
| Vcpg = kcp * Ncbg # Pryout strength (kips) - Eq (17.7.3.1b) | |
| phiVcpg = phi_vc * Vcpg # Design pryout strength (kips) | |
| # ---- HELPER FUNCTIONS ---- | |
| def format_check(label, capacity_value, applied_load): | |
| """Compares capacity to load and returns a formatted status string.""" | |
| status = "PASS" if capacity_value >= applied_load else "FAIL" | |
| # f-string provides clear control over alignment and precision | |
| return f"{label:<55s} = {capacity_value:>7.2f} kips | Status: {status}" | |
| # ---- INTERMEDIATE RESULTS (Calculated Geometry) ---- | |
| print("--- Calculated Geometric Areas ---") | |
| print(f"{'Projected Area // Load (AVc):':<35s} = {AVc:>7.2f} in^2") | |
| print(f"{'Projected Area perp Load (AVc_p):':<35s} = {AVc_p:>7.2f} in^2") | |
| print(f"{'Projected Area Tension (ANc):':<35s} = {ANc:>7.2f} in^2") | |
| print(f"{'Single Anchor Area // (AVco):':<35s} = {AVco:>7.2f} in^2") | |
| print(f"{'Single Anchor Area perp (AVco_p):':<35s} = {AVco_p:>7.2f} in^2") | |
| print(f"{'Single Anchor Area Tension (ANco):':<35s} = {ANco:>7.2f} in^2") | |
| print("-" * 45) | |
| # ---- FINAL RESULTS (Design Check Summary) ---- | |
| print(f"\n{'--- Design Check Summary ---':^75}") # Centered title | |
| print(f"{'Applied Factored Shear Load (Vu):':<55s} = {V_app:>7.2f} kips") | |
| print("-" * 75) | |
| print(format_check("Design Steel Shear Strength (ΦVsa)", phiVsa, V_app)) | |
| print(format_check("Design Concrete Breakout (ΦVcbg - // load)", phiVcbg, V_app)) | |
| print(format_check("Design Concrete Breakout (ΦVcbg - perp load)", phiVcbg_p, V_app)) | |
| print(format_check("Design Concrete Pryout Strength (ΦVcpg)", phiVcpg, V_app)) | |
| print("-" * 75) | |
| # Determine controlling failure mode and overall status | |
| min_capacity = min(phiVsa, phiVcbg, phiVcbg_p, phiVcpg) | |
| overall_status = "PASS" if min_capacity >= V_app else "FAIL" | |
| print(f"\n{'Overall Shear Check:':<55s} Minimum Capacity = {min_capacity:.2f} kips → {overall_status}") | |
| # ---- FINAL PRINTOUT FOR VERIFICATION ---- | |
| print(f"\n\n{'='*25} FINAL VERIFICATION PRINTOUT {'='*25}") | |
| # Print Fundamental Inputs | |
| print("\n--- Fundamental Inputs & Assumptions ---") | |
| print(f"{'Anchor Diameter (da):':<35s} = {da} in") | |
| print(f"{'Anchor Steel Strength (futa):':<35s} = {futa} ksi") | |
| print(f"{'Embedment Depth (hef):':<35s} = {hef} in") | |
| print(f"{'Concrete Strength (fc):':<35s} = {fc} ksi") | |
| print(f"{'Lightweight Mod (lambda_a):':<35s} = {lambda_a}") | |
| print(f"{'Number Anchors X (Nx):':<35s} = {Nx}") | |
| print(f"{'Number Anchors Y (Ny):':<35s} = {Ny}") | |
| print(f"{'Spacing X (sx):':<35s} = {sx} in") | |
| print(f"{'Spacing Y (sy):':<35s} = {sy} in") | |
| print(f"{'Edge Dist Max X (ca1):':<35s} = {ca1} in") | |
| print(f"{'Edge Dist Min X (ca2):':<35s} = {ca2} in") | |
| print(f"{'Edge Dist Max Y (ca1_p):':<35s} = {ca1_p} in") | |
| print(f"{'Edge Dist Min Y (ca2_p):':<35s} = {ca2_p} in") | |
| print(f"{'Applied Shear (V_app):':<35s} = {V_app} kips") | |
| print(f"{'Phi Factor Steel (phi_vs):':<35s} = {phi_vs}") | |
| print(f"{'Phi Factor Concrete (phi_vc):':<35s} = {phi_vc}") | |
| print(f"{'Cracked Concrete Assumed:':<35s} = {cracked}") | |
| # Print Derived Geometric Inputs | |
| print("\n--- Derived Geometric Inputs ---") | |
| print(f"{'Projected Area // Load (AVc):':<35s} = {AVc:>7.2f} in^2") | |
| print(f"{'Projected Area perp Load (AVc_p):':<35s} = {AVc_p:>7.2f} in^2") | |
| print(f"{'Projected Area Tension (ANc):':<35s} = {ANc:>7.2f} in^2") | |
| print(f"{'Single Anchor Area // (AVco):':<35s} = {AVco:>7.2f} in^2") | |
| print(f"{'Single Anchor Area perp (AVco_p):':<35s} = {AVco_p:>7.2f} in^2") | |
| print(f"{'Single Anchor Area Tension (ANco):':<35s} = {ANco:>7.2f} in^2") | |
| print(f"{'Min Overall Edge Dist (c_min):':<35s} = {c_min_overall} in") | |
| # Print Intermediate Calculation Results (Selected Key Values) | |
| print("\n--- Intermediate Calculation Results ---") | |
| print(f"{'Number of Anchors (N_anchors):':<35s} = {N_anchors}") | |
| print(f"{'Anchor Steel Area (Ase):':<35s} = {Ase:.3f} in^2") | |
| print(f"{'Effective Length (le):':<35s} = {le:.2f} in") | |
| print(f"{'Basic Breakout Strength (Vb):':<35s} = {Vb:.2f} kips") | |
| print(f"{'Basic Breakout Strength Perp (Vb_p):':<35s} = {Vb_p:.2f} kips") | |
| print(f"{'Basic Tension Breakout Single (Nb_s):':<35s} = {Nb_single:.2f} kips") | |
| print(f"{'Group Tension Breakout (Ncbg):':<35s} = {Ncbg:.2f} kips") | |
| # Add modification factors if needed for detailed review: | |
| # print(f"{'Psi_ed (//):':<35s} = {psi_ed:.3f}") | |
| # print(f"{'Psi_c (//):':<35s} = {psi_c:.3f}") | |
| # print(f"{'Psi_ed_p (perp):':<35s} = {psi_ed_p:.3f}") | |
| # print(f"{'Psi_ed_N (tension):':<35s} = {psi_ed_N:.3f}") | |
| # print(f"{'Psi_c_N (tension):':<35s} = {psi_c_N:.3f}") | |
| # Print Final Outputs (Nominal & Design Capacities) | |
| print("\n--- Final Nominal Capacities ---") | |
| print(f"{'Nominal Steel Shear (Vsa):':<35s} = {Vsa:.2f} kips") | |
| print(f"{'Nominal Breakout // (Vcbg):':<35s} = {Vcbg:.2f} kips") | |
| print(f"{'Nominal Breakout perp (Vcbg_p):':<35s} = {Vcbg_p:.2f} kips") | |
| print(f"{'Nominal Pryout (Vcpg):':<35s} = {Vcpg:.2f} kips") | |
| print("\n--- Final Design Capacities & Status ---") | |
| print(f"{'Design Steel Shear (ΦVsa):':<35s} = {phiVsa:.2f} kips") | |
| print(f"{'Design Breakout // (ΦVcbg):':<35s} = {phiVcbg:.2f} kips") | |
| print(f"{'Design Breakout perp (ΦVcbg_p):':<35s} = {phiVcbg_p:.2f} kips") | |
| print(f"{'Design Pryout (ΦVcpg):':<35s} = {phiVcpg:.2f} kips") | |
| print(f"{'Applied Load (Vu):':<35s} = {V_app:.2f} kips") | |
| print(f"{'Minimum Design Capacity:':<35s} = {min_capacity:.2f} kips") | |
| print(f"{'Overall Status:':<35s} = {overall_status}") | |
| print(f"\n{'='*25} END VERIFICATION PRINTOUT {'='*27}\n") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment