2D Mohr's Circle
Understanding stress and strain in materials is crucial in various engineering disciplines. Mohr’s Circle, a graphical representation, helps visualize stress components within materials.
# -*- coding: utf-8 -*-
"""
@author: A Aditya
"""
import PySimpleGUI as sg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
# Function to create Mohr's Circle
def create_mohrs_circle(sigma_x, sigma_y, tau_xy):
center = (sigma_x + sigma_y) / 2
radius = np.sqrt(((sigma_x - sigma_y) / 2) ** 2 + tau_xy ** 2)
angle = np.linspace(0, 2 * np.pi, 200)
x = center + radius * np.cos(angle)
y = radius * np.sin(angle)
return x, y, center, radius
# GUI Layout
layout = [
[sg.Text('Sigma X'), sg.Slider((-100, 100), default_value=50, orientation='h', size=(20, 10), key='-SIGMAX-'),
sg.Text('Sigma Y'), sg.Slider((-100, 100), default_value=20, orientation='h', size=(20, 10), key='-SIGMAY-'),
sg.Text('Tau XY'), sg.Slider((-100, 100), default_value=10, orientation='h', size=(20, 10), key='-TAUXY-')],
[sg.Canvas(key='-CANVAS-', size=(400, 400), background_color='#40516c'),
sg.Table(values=[['', '', '', '']], headings=['Important Results ', 'Values'], auto_size_columns=True,
num_rows=7, justification='center', key='-TABLE-', background_color='#40516c')],
]
# Create the window
window = sg.Window('Mohr\'s Circle', layout, finalize=True)
# Create initial Mohr's Circle data
sigma_x = 50
sigma_y = 20
tau_xy = 10
x, y, center, radius = create_mohrs_circle(sigma_x, sigma_y, tau_xy)
sigma_1 = center + radius # maximum principal stress
sigma_2 = center - radius # minimum principal stress
# Create initial Mohr's Circle plot
fig, ax = plt.subplots(figsize=(4, 4), facecolor='#40516c')
ax.set_xlim(center - 60, center + 60)
ax.set_ylim(-radius - 10, radius + 10)
ax.grid(True)
# Draw the initial Mohr's Circle plot on the canvas
fig_canvas_agg = FigureCanvasTkAgg(fig, window['-CANVAS-'].TKCanvas)
fig_canvas_agg.draw()
fig_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
# Event loop
while True:
event, values = window.read(timeout=100)
if event == sg.WIN_CLOSED:
break
# Retrieve values from sliders
sigma_x = values['-SIGMAX-']
sigma_y = values['-SIGMAY-']
tau_xy = values['-TAUXY-']
# Create updated Mohr's Circle
x, y, center, radius = create_mohrs_circle(sigma_x, sigma_y, tau_xy)
# Update Mohr's Circle plot
ax.clear()
ax.plot(x, y, color='black')
ax.plot([sigma_x, sigma_y], [-tau_xy, tau_xy], 'ko') # Points σ1, σ2
ax.plot(center, 0, 'ko') # Point c (Center)
ax.plot([sigma_1, sigma_2], [0, 0], 'ko') # Points max principal stress and min principal stress
ax.plot([center, center], [radius, -radius], 'ko') # Points max principal stress and min principal stress
ax.text(sigma_x, -tau_xy, 'σx, -τxy', ha='right', va='bottom', color='black', fontsize=9) # Label for σ1
ax.text(sigma_y, tau_xy, 'σy, τxy', ha='right', va='top', color='black', fontsize=9) # Label for σ2
ax.text(sigma_1, 0, f" σ1 = {sigma_1:.2f}", ha='right', va='bottom', color='black', fontsize=9) # Max Principal Stress
ax.text(sigma_2, 0, f" σ2 = {sigma_2:.2f}", ha='left', va='top', color='black', fontsize=9) # Min Principal Stress
ax.text(center, radius, f" τmax = {radius:.2f}", ha='right', va='bottom', color='black', fontsize=9) # Max Shear Stress
ax.text(center, -radius, f" τmin = {-radius:.2f}", ha='right', va='bottom', color='black', fontsize=9) # Min Shear Stress
ax.text(center, 0, f" C ({center:.2f}, 0)", ha='left', va='top', color='black', fontsize=9) # Point c
# Shade region between the lines and x-axis
ax.fill_between([sigma_x, sigma_y, center], [-tau_xy, tau_xy, 0], color='lightgreen', alpha=0.5)
ax.fill_between([sigma_y, sigma_x, center], [tau_xy, -tau_xy, 0], color='lightgreen', alpha=0.5)
# Draw lines connecting the points to the x-axis
ax.plot([sigma_x, sigma_x], [-tau_xy, 0], 'k-')
ax.plot([sigma_y, sigma_y], [tau_xy, 0], 'k-')
ax.plot([center, center], [0, 0], 'k--')
ax.plot([sigma_1, sigma_2], [0, 0], 'k-')
ax.plot([center, center], [radius, -radius], 'k-')
ax.plot([sigma_x, sigma_y], [-tau_xy, tau_xy], 'k-')
# Calculate and display the angle covered by the line from x-axis
angle_rad = (np.arctan((2 * tau_xy) / (sigma_x - sigma_y)))/2
angle_deg = np.degrees(angle_rad)
ax.text(center - 8, 2, f'θₚ₂: {angle_deg:.2f}°', color='black')
ax.set_title("Mohr's Circle")
ax.set_xlabel("Normal Stress", fontsize=9)
ax.set_ylabel("Shear Stress", fontsize=9)
ax.grid(True, linestyle='--', color='black')
ax.set_facecolor('#40516c')
plt.tight_layout()
# Update Mohr's Circle table with principal stresses
sigma_1 = center + radius
sigma_2 = center - radius
max_shear_stress = (sigma_1 - sigma_2) / 2
table_data = [['Max. Principal Stress', f"{sigma_1:.2f}"],
['Min. Principal Stress', f"{sigma_2:.2f}"],
['Max. Shear Stress', f"{max_shear_stress:.2f}"],
['Min. Shear Stress', f"{-max_shear_stress:.2f}"],
['σ_avg', f"{center:.2f}"]
]
window['-TABLE-'].update(values=table_data)
# Convert updated plot to a format that PySimpleGUI can display
fig_canvas_agg.draw_idle()
window.close()