Skip to content

Instantly share code, notes, and snippets.

@joreilly86
Last active April 25, 2025 19:59
Show Gist options
  • Select an option

  • Save joreilly86/a4a4b2517337608ba3f65925f1bd9e75 to your computer and use it in GitHub Desktop.

Select an option

Save joreilly86/a4a4b2517337608ba3f65925f1bd9e75 to your computer and use it in GitHub Desktop.
#068 - Structuring Engineering Calculations in Python | 01 - The Basics
# ---- 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