Path: blob/main/latex-templates/templates/mechanical-engineering/stress_analysis.tex
51 views
unlisted
\documentclass[11pt,a4paper]{article}12% Document Setup3\usepackage[utf8]{inputenc}4\usepackage[T1]{fontenc}5\usepackage{lmodern}6\usepackage[margin=1in]{geometry}7\usepackage{amsmath,amssymb}8\usepackage{siunitx}9\usepackage{booktabs}10\usepackage{float}11\usepackage{caption}12\usepackage{hyperref}1314% PythonTeX Setup15\usepackage[makestderr]{pythontex}1617\title{Stress Analysis: Mohr's Circle and Failure Theories}18\author{Mechanical Engineering Laboratory}19\date{\today}2021\begin{document}22\maketitle2324\begin{abstract}25This report presents computational analysis of stress states in solid mechanics. We examine stress transformation using Mohr's circle, principal stresses, von Mises equivalent stress, and common failure theories. Python-based computations provide quantitative analysis with dynamic visualization.26\end{abstract}2728\tableofcontents29\newpage3031\section{Introduction to Stress Analysis}3233Stress analysis is fundamental to mechanical design and failure prediction. This analysis covers:34\begin{itemize}35\item Plane stress transformation36\item Mohr's circle construction37\item Principal stress calculation38\item von Mises yield criterion39\item Failure theories (Tresca, Rankine, Mohr-Coulomb)40\end{itemize}4142% Initialize Python environment43\begin{pycode}44import numpy as np45import matplotlib.pyplot as plt46from matplotlib.patches import Circle, FancyArrowPatch4748plt.rcParams['figure.figsize'] = (8, 5)49plt.rcParams['font.size'] = 1050plt.rcParams['text.usetex'] = True5152def save_fig(filename):53plt.savefig(filename, dpi=150, bbox_inches='tight')54plt.close()55\end{pycode}5657\section{Plane Stress State}5859For a 2D stress state, the stress tensor is:60\begin{equation}61\boldsymbol{\sigma} = \begin{pmatrix} \sigma_x & \tau_{xy} \\ \tau_{xy} & \sigma_y \end{pmatrix}62\end{equation}6364\subsection{Stress Transformation}6566Stresses on a rotated plane (angle $\theta$ from x-axis):67\begin{align}68\sigma_{x'} &= \frac{\sigma_x + \sigma_y}{2} + \frac{\sigma_x - \sigma_y}{2}\cos(2\theta) + \tau_{xy}\sin(2\theta) \\69\tau_{x'y'} &= -\frac{\sigma_x - \sigma_y}{2}\sin(2\theta) + \tau_{xy}\cos(2\theta)70\end{align}7172\begin{pycode}73# Define stress state74sigma_x = 80 # MPa75sigma_y = -40 # MPa76tau_xy = 30 # MPa7778# Calculate center and radius of Mohr's circle79sigma_avg = (sigma_x + sigma_y) / 280R = np.sqrt(((sigma_x - sigma_y) / 2)**2 + tau_xy**2)8182# Principal stresses83sigma_1 = sigma_avg + R84sigma_2 = sigma_avg - R8586# Principal angle87theta_p = 0.5 * np.arctan2(2*tau_xy, sigma_x - sigma_y)88theta_p_deg = np.degrees(theta_p)8990# Maximum shear stress91tau_max = R92theta_s = theta_p + np.pi/49394# Stress transformation for various angles95theta = np.linspace(0, np.pi, 180)96sigma_n = sigma_avg + (sigma_x - sigma_y)/2 * np.cos(2*theta) + tau_xy * np.sin(2*theta)97tau_nt = -(sigma_x - sigma_y)/2 * np.sin(2*theta) + tau_xy * np.cos(2*theta)9899fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))100101# Mohr's Circle102circle = Circle((sigma_avg, 0), R, fill=False, color='blue', linewidth=2)103ax1.add_patch(circle)104105# Plot key points106ax1.plot(sigma_x, tau_xy, 'ro', markersize=10, label=f'X: ({sigma_x}, {tau_xy})')107ax1.plot(sigma_y, -tau_xy, 'go', markersize=10, label=f'Y: ({sigma_y}, {-tau_xy})')108ax1.plot(sigma_1, 0, 'bs', markersize=10, label=f'$\\sigma_1$: {sigma_1:.1f}')109ax1.plot(sigma_2, 0, 'bs', markersize=10, label=f'$\\sigma_2$: {sigma_2:.1f}')110ax1.plot(sigma_avg, tau_max, 'r^', markersize=10)111ax1.plot(sigma_avg, -tau_max, 'r^', markersize=10)112113# Draw XY line114ax1.plot([sigma_x, sigma_y], [tau_xy, -tau_xy], 'k--', linewidth=1)115116ax1.axhline(0, color='k', linewidth=0.5)117ax1.axvline(0, color='k', linewidth=0.5)118ax1.set_xlabel('Normal Stress $\\sigma$ (MPa)')119ax1.set_ylabel('Shear Stress $\\tau$ (MPa)')120ax1.set_title("Mohr's Circle for Plane Stress")121ax1.legend(loc='upper right', fontsize=8)122ax1.grid(True, alpha=0.3)123ax1.axis('equal')124ax1.set_xlim(-80, 120)125ax1.set_ylim(-80, 80)126127# Stress variation with angle128ax2.plot(np.degrees(theta), sigma_n, 'b-', linewidth=2, label='$\\sigma_n$')129ax2.plot(np.degrees(theta), tau_nt, 'r-', linewidth=2, label='$\\tau_{nt}$')130ax2.axhline(sigma_1, color='b', linestyle='--', alpha=0.5)131ax2.axhline(sigma_2, color='b', linestyle='--', alpha=0.5)132ax2.axhline(tau_max, color='r', linestyle='--', alpha=0.5)133ax2.axhline(-tau_max, color='r', linestyle='--', alpha=0.5)134ax2.axvline(theta_p_deg, color='k', linestyle=':', alpha=0.5)135ax2.set_xlabel('Angle $\\theta$ (degrees)')136ax2.set_ylabel('Stress (MPa)')137ax2.set_title('Stress Transformation')138ax2.legend()139ax2.grid(True, alpha=0.3)140141plt.tight_layout()142save_fig('mohr_circle.pdf')143\end{pycode}144145\begin{figure}[H]146\centering147\includegraphics[width=\textwidth]{mohr_circle.pdf}148\caption{Mohr's circle construction and stress transformation with angle.}149\end{figure}150151\begin{table}[H]152\centering153\caption{Principal Stress Results}154\begin{tabular}{lcc}155\toprule156Parameter & Value & Units \\157\midrule158$\sigma_1$ (max principal) & \py{f"{sigma_1:.1f}"} & MPa \\159$\sigma_2$ (min principal) & \py{f"{sigma_2:.1f}"} & MPa \\160$\tau_{max}$ & \py{f"{tau_max:.1f}"} & MPa \\161Principal angle $\theta_p$ & \py{f"{theta_p_deg:.1f}"} & degrees \\162\bottomrule163\end{tabular}164\end{table}165166\section{3D Stress State and von Mises Stress}167168For a general 3D stress state, the von Mises equivalent stress is:169\begin{equation}170\sigma_{VM} = \sqrt{\frac{1}{2}[(\sigma_1-\sigma_2)^2 + (\sigma_2-\sigma_3)^2 + (\sigma_3-\sigma_1)^2]}171\end{equation}172173For plane stress ($\sigma_3 = 0$):174\begin{equation}175\sigma_{VM} = \sqrt{\sigma_1^2 - \sigma_1\sigma_2 + \sigma_2^2}176\end{equation}177178\begin{pycode}179# von Mises stress calculation180sigma_3 = 0 # plane stress181sigma_VM = np.sqrt(sigma_1**2 - sigma_1*sigma_2 + sigma_2**2)182183# von Mises yield surface (ellipse in sigma_1-sigma_2 space)184S_y = 250 # Yield strength (MPa)185186theta_vm = np.linspace(0, 2*np.pi, 200)187# Parametric form of von Mises ellipse188a = S_y * np.sqrt(2/3)189b = S_y * np.sqrt(2)190sigma_1_vm = a * np.cos(theta_vm) + b/2 * np.sin(theta_vm)191sigma_2_vm = -a * np.cos(theta_vm) + b/2 * np.sin(theta_vm)192193# Tresca yield surface (hexagon)194S_tresca = S_y195tresca_points = np.array([196[S_tresca, 0], [S_tresca, S_tresca], [0, S_tresca],197[-S_tresca, 0], [-S_tresca, -S_tresca], [0, -S_tresca], [S_tresca, 0]198])199200fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))201202# von Mises and Tresca yield surfaces203ax1.plot(sigma_1_vm, sigma_2_vm, 'b-', linewidth=2, label='von Mises')204ax1.plot(tresca_points[:, 0], tresca_points[:, 1], 'r--', linewidth=2, label='Tresca')205ax1.plot(sigma_1, sigma_2, 'ko', markersize=10, label=f'Current state')206ax1.axhline(0, color='k', linewidth=0.5)207ax1.axvline(0, color='k', linewidth=0.5)208ax1.set_xlabel('$\\sigma_1$ (MPa)')209ax1.set_ylabel('$\\sigma_2$ (MPa)')210ax1.set_title('Yield Surfaces (Plane Stress)')211ax1.legend()212ax1.grid(True, alpha=0.3)213ax1.axis('equal')214215# Safety factor visualization216SF_VM = S_y / sigma_VM217sigma_range = np.linspace(0, S_y, 100)218219# von Mises boundary at various sigma_2/sigma_1 ratios220ratios = [-1, -0.5, 0, 0.5, 1]221for ratio in ratios:222sigma_2_line = ratio * sigma_range223sigma_VM_line = np.sqrt(sigma_range**2 - sigma_range*sigma_2_line + sigma_2_line**2)224ax2.plot(sigma_range, sigma_VM_line, linewidth=1.5, label=f'$\\sigma_2/\\sigma_1$ = {ratio}')225226ax2.axhline(S_y, color='r', linestyle='--', linewidth=2, label=f'$S_y$ = {S_y} MPa')227ax2.plot(sigma_1, sigma_VM, 'ko', markersize=10)228ax2.set_xlabel('$\\sigma_1$ (MPa)')229ax2.set_ylabel('$\\sigma_{VM}$ (MPa)')230ax2.set_title('von Mises Equivalent Stress')231ax2.legend(fontsize=8)232ax2.grid(True, alpha=0.3)233234plt.tight_layout()235save_fig('von_mises.pdf')236\end{pycode}237238\begin{figure}[H]239\centering240\includegraphics[width=\textwidth]{von_mises.pdf}241\caption{Yield surfaces and von Mises equivalent stress analysis.}242\end{figure}243244von Mises stress: $\sigma_{VM} = \py{f"{sigma_VM:.1f}"}$ MPa, Safety factor = \py{f"{S_y/sigma_VM:.2f}"}245246\section{Failure Theories}247248\begin{pycode}249# Comparison of failure theories250S_y = 250 # Tensile yield strength251S_yc = 300 # Compressive yield strength (for Mohr-Coulomb)252S_ut = 400 # Ultimate tensile strength253254# Create principal stress space255s1 = np.linspace(-400, 400, 200)256s2 = np.linspace(-400, 400, 200)257S1, S2 = np.meshgrid(s1, s2)258259# von Mises criterion260VM = np.sqrt(S1**2 - S1*S2 + S2**2)261262# Tresca criterion263Tresca = np.maximum(np.abs(S1 - S2), np.maximum(np.abs(S1), np.abs(S2)))264265# Rankine (maximum normal stress)266Rankine = np.maximum(np.abs(S1), np.abs(S2))267268# Mohr-Coulomb (simplified)269MC = np.maximum(S1/S_y - S2/S_yc, S2/S_y - S1/S_yc)270271fig, axes = plt.subplots(2, 2, figsize=(12, 10))272273# von Mises274cs1 = axes[0, 0].contour(S1, S2, VM, levels=[S_y], colors='blue', linewidths=2)275axes[0, 0].clabel(cs1, fmt='$S_y$=%d' % S_y)276axes[0, 0].plot(sigma_1, sigma_2, 'ro', markersize=10)277axes[0, 0].axhline(0, color='k', linewidth=0.5)278axes[0, 0].axvline(0, color='k', linewidth=0.5)279axes[0, 0].set_xlabel('$\\sigma_1$ (MPa)')280axes[0, 0].set_ylabel('$\\sigma_2$ (MPa)')281axes[0, 0].set_title('von Mises Criterion')282axes[0, 0].grid(True, alpha=0.3)283axes[0, 0].axis('equal')284285# Tresca286cs2 = axes[0, 1].contour(S1, S2, Tresca, levels=[S_y], colors='red', linewidths=2)287axes[0, 1].clabel(cs2, fmt='$S_y$=%d' % S_y)288axes[0, 1].plot(sigma_1, sigma_2, 'ro', markersize=10)289axes[0, 1].axhline(0, color='k', linewidth=0.5)290axes[0, 1].axvline(0, color='k', linewidth=0.5)291axes[0, 1].set_xlabel('$\\sigma_1$ (MPa)')292axes[0, 1].set_ylabel('$\\sigma_2$ (MPa)')293axes[0, 1].set_title('Tresca (Max Shear) Criterion')294axes[0, 1].grid(True, alpha=0.3)295axes[0, 1].axis('equal')296297# Rankine298cs3 = axes[1, 0].contour(S1, S2, Rankine, levels=[S_ut], colors='green', linewidths=2)299axes[1, 0].clabel(cs3, fmt='$S_{ut}$=%d' % S_ut)300axes[1, 0].plot(sigma_1, sigma_2, 'ro', markersize=10)301axes[1, 0].axhline(0, color='k', linewidth=0.5)302axes[1, 0].axvline(0, color='k', linewidth=0.5)303axes[1, 0].set_xlabel('$\\sigma_1$ (MPa)')304axes[1, 0].set_ylabel('$\\sigma_2$ (MPa)')305axes[1, 0].set_title('Rankine (Max Normal Stress) Criterion')306axes[1, 0].grid(True, alpha=0.3)307axes[1, 0].axis('equal')308309# Comparison310axes[1, 1].contour(S1, S2, VM, levels=[S_y], colors='blue', linewidths=2)311axes[1, 1].contour(S1, S2, Tresca, levels=[S_y], colors='red', linewidths=2, linestyles='--')312axes[1, 1].plot(sigma_1, sigma_2, 'ko', markersize=10, label='Current state')313axes[1, 1].axhline(0, color='k', linewidth=0.5)314axes[1, 1].axvline(0, color='k', linewidth=0.5)315axes[1, 1].set_xlabel('$\\sigma_1$ (MPa)')316axes[1, 1].set_ylabel('$\\sigma_2$ (MPa)')317axes[1, 1].set_title('Comparison: von Mises (blue) vs Tresca (red)')318axes[1, 1].grid(True, alpha=0.3)319axes[1, 1].axis('equal')320321plt.tight_layout()322save_fig('failure_theories.pdf')323\end{pycode}324325\begin{figure}[H]326\centering327\includegraphics[width=\textwidth]{failure_theories.pdf}328\caption{Comparison of failure theories: von Mises, Tresca, and Rankine.}329\end{figure}330331\section{Stress Concentration}332333Stress concentration factors modify nominal stress:334\begin{equation}335\sigma_{max} = K_t \cdot \sigma_{nom}336\end{equation}337338\begin{pycode}339# Stress concentration for plate with hole340def Kt_plate_hole(d_w):341"""Stress concentration factor for plate with central hole under tension"""342return 3.0 - 3.14*d_w + 3.667*d_w**2 - 1.527*d_w**3343344d_w_range = np.linspace(0.01, 0.7, 100)345Kt = [Kt_plate_hole(dw) for dw in d_w_range]346347# For shaft with fillet348def Kt_shaft_fillet(D_d, r_d):349"""Approximate Kt for stepped shaft with fillet"""350C1 = 0.926 + 1.157*np.sqrt(r_d) - 0.099*r_d351C2 = 0.012 - 3.036*np.sqrt(r_d) + 0.961*r_d352return C1 + C2*(2*D_d/(D_d+1))353354D_d_values = [1.1, 1.2, 1.5, 2.0]355r_d_range = np.linspace(0.01, 0.3, 100)356357fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))358359# Plate with hole360ax1.plot(d_w_range, Kt, 'b-', linewidth=2)361ax1.set_xlabel('$d/w$ (hole diameter / plate width)')362ax1.set_ylabel('$K_t$')363ax1.set_title('Plate with Central Hole')364ax1.grid(True, alpha=0.3)365366# Shaft with fillet367for D_d in D_d_values:368Kt_shaft = [Kt_shaft_fillet(D_d, rd) for rd in r_d_range]369ax2.plot(r_d_range, Kt_shaft, linewidth=2, label=f'D/d = {D_d}')370371ax2.set_xlabel('$r/d$ (fillet radius / minor diameter)')372ax2.set_ylabel('$K_t$')373ax2.set_title('Stepped Shaft with Fillet (Tension)')374ax2.legend()375ax2.grid(True, alpha=0.3)376377plt.tight_layout()378save_fig('stress_concentration.pdf')379\end{pycode}380381\begin{figure}[H]382\centering383\includegraphics[width=\textwidth]{stress_concentration.pdf}384\caption{Stress concentration factors for common geometries.}385\end{figure}386387\section{Beam Bending Stress}388389\begin{pycode}390# Cantilever beam with end load391L = 1.0 # m392P = 5000 # N393b = 0.05 # m (width)394h = 0.1 # m (height)395I = b * h**3 / 12396c = h / 2397398x = np.linspace(0, L, 100)399M = P * (L - x) # Moment distribution400sigma_max = M * c / I # Maximum bending stress401V = P * np.ones_like(x) # Shear force402403fig, axes = plt.subplots(2, 2, figsize=(12, 10))404405# Bending moment diagram406axes[0, 0].plot(x, M/1000, 'b-', linewidth=2)407axes[0, 0].fill_between(x, 0, M/1000, alpha=0.3)408axes[0, 0].set_xlabel('Position (m)')409axes[0, 0].set_ylabel('Moment (kN$\\cdot$m)')410axes[0, 0].set_title('Bending Moment Diagram')411axes[0, 0].grid(True, alpha=0.3)412413# Shear force diagram414axes[0, 1].plot(x, V/1000, 'r-', linewidth=2)415axes[0, 1].fill_between(x, 0, V/1000, alpha=0.3, color='red')416axes[0, 1].set_xlabel('Position (m)')417axes[0, 1].set_ylabel('Shear Force (kN)')418axes[0, 1].set_title('Shear Force Diagram')419axes[0, 1].grid(True, alpha=0.3)420421# Stress distribution through depth at root422y = np.linspace(-h/2, h/2, 100)423M_root = P * L424sigma_y = M_root * y / I425426axes[1, 0].plot(sigma_y/1e6, y*1000, 'g-', linewidth=2)427axes[1, 0].axvline(0, color='k', linewidth=0.5)428axes[1, 0].axhline(0, color='k', linewidth=0.5)429axes[1, 0].set_xlabel('Bending Stress (MPa)')430axes[1, 0].set_ylabel('Distance from neutral axis (mm)')431axes[1, 0].set_title('Stress Distribution at Root')432axes[1, 0].grid(True, alpha=0.3)433434# Maximum stress along beam435axes[1, 1].plot(x, sigma_max/1e6, 'm-', linewidth=2)436axes[1, 1].set_xlabel('Position (m)')437axes[1, 1].set_ylabel('Maximum Bending Stress (MPa)')438axes[1, 1].set_title('Maximum Stress Distribution')439axes[1, 1].grid(True, alpha=0.3)440441plt.tight_layout()442save_fig('beam_bending.pdf')443444sigma_max_root = P * L * c / I445\end{pycode}446447\begin{figure}[H]448\centering449\includegraphics[width=\textwidth]{beam_bending.pdf}450\caption{Cantilever beam analysis: moment, shear, and stress distributions.}451\end{figure}452453Maximum bending stress at root: $\sigma_{max} = \py{f"{sigma_max_root/1e6:.1f}"}$ MPa454455\section{Conclusions}456457This analysis demonstrates key aspects of stress analysis:458\begin{enumerate}459\item Mohr's circle provides graphical stress transformation460\item Principal stresses define maximum and minimum normal stresses461\item von Mises criterion is appropriate for ductile materials462\item Tresca is more conservative than von Mises by up to 15\%463\item Stress concentration must be considered at geometric discontinuities464\item Beam bending produces linear stress distribution through depth465\end{enumerate}466467\end{document}468469470