CoCalc Shared Files2015-10-23-140959.ipynbOpen in CoCalc with one click!
Author: Jason Moore
Views : 7
Description: Jupyter notebook 2015-10-23-140959.ipynb

Plot the ratio of the principal normal and shear stresses to the maximum contact area pressure as a function of the depth below the surface along the z axis for two spheres.

In [51]:
from sympy import symbols, Eq, lambdify, init_printing, pi, Abs, atan, S
In [52]:
from IPython.html.widgets import interactive from IPython.display import display
In [53]:
import matplotlib.pyplot as plt import numpy as np
In [54]:
%matplotlib nbagg
In [55]:
init_printing()

First define all of the known and unknown symbols needed for the calculations for sphere to sphere contact.

In [56]:
a, F, v, v1, v2, E1, E2, d1, d2 = symbols('a, F, nu, nu1, nu2, E1, E2, d1, d2', real=True) p_max, s1, s3, t13, z = symbols('p_max, sigma1, sigma3, tau_13, z', real=True)

Now define the equations for the contact area radius, aa, the maximum pressure at the contact area, pmaxp_{max}, and the principal stresses along the zz axis.

In [57]:
radius_eq = Eq(a, (3 * F / 8 * ((1 - v1**2) / E1 + (1 - v2**2)) / (1 / d1 + 1 / d2))**3) radius_eq
a == 27*F**3*(-nu2**2 + 1 + (-nu1**2 + 1)/E1)**3/(512*(1/d2 + 1/d1)**3)
In [58]:
pressure_eq = Eq(p_max, 3 * F / 2 / pi / a**2) pressure_eq
p_max == 3*F/(2*pi*a**2)
In [59]:
s1_eq = Eq(s1, -p_max * ((1 - Abs(z / a) * atan(1 / Abs(z / a))) * (1 + v) - S(1) / 2 / (1 + z**2 / a**2))) s1_eq
sigma1 == -p_max*((nu + 1)*(-Abs(z/a)*atan(1/Abs(z/a)) + 1) - 1/(2*(1 + z**2/a**2)))
In [60]:
s3_eq = Eq(s3, -p_max / (1 + z**2 / a**2)) s3_eq
sigma3 == -p_max/(1 + z**2/a**2)
In [61]:
t_max_eq = Eq(t13, (s1 - s3) / 2) t_max_eq
tau_13 == sigma1/2 - sigma3/2
In [74]:
t_max_eq.rhs.subs({s1: s1_eq.rhs, s3: s3_eq.rhs}).diff(z).simplify()
-p_max*(3*a**3*z + (a**2 + z**2)*(nu + 1)*(a**2*Abs(z/a) - (a**2 + z**2)*atan(1/Abs(z/a)))*sign(z/a))/(2*a*(a**2 + z**2)**2)
In [63]:
(s1_eq.rhs / pressure_eq.rhs).simplify()
pi*a**2*p_max*(a**2 + 2*(a**2 + z**2)*(nu + 1)*(Abs(z/a)*atan(1/Abs(z/a)) - 1))/(3*F*(a**2 + z**2))

Create some functions to evaluate the expressions that we derived above.

In [64]:
f_a = lambdify((F, v1, v2, E1, E2, d1, d2), radius_eq.rhs, modules='numpy')
In [65]:
f_p_max = lambdify((F, a), pressure_eq.rhs, modules='numpy')
In [66]:
f_s1 = lambdify((p_max, z, a, v), s1_eq.rhs, modules='numpy')
In [67]:
f_s3 = lambdify((p_max, z, a), s3_eq.rhs, modules='numpy')
In [68]:
f_t_max = lambdify((s1, s3), t_max_eq.rhs, modules='numpy')

We need a graph of σ1,σ3,τ1/2pmax\frac{\sigma_1, \sigma_3, \tau_{1/2}}{p_{max}} vs zz so define a function that produces the plot.

In [69]:
def plot_stresses(max_depth=3.0, v1=0.326, v2=0.324, E1=17.2E6, E2=15.4E6, d1=1.0, d2=2.0): """Plots the principal stresses in each sphere versus the depth along the z axis. Parameters =========== max_depth : float The depth is defined as z = max_depth * a. v1, v2 : float Poisson's ratio for sphere 1 and 2. E1, E2 : float Modulus of elasticity for sphere 1 and 2. d1, d2 : float Diameters of sphere 1 and 2. """ fig, axes = plt.subplots(1, 2, sharey=True) F = 1.0 a = f_a(F, v1, v2, E1, E2, d1, d2) z = np.linspace(1E-14, max_depth * a, num=100) p_max = f_p_max(F, a) s1_1 = f_s1(p_max, z, a, v1) s3_1 = f_s3(p_max, z, a) t_13_1 = f_t_max(s1_1, s3_1) s1_2 = f_s1(p_max, z, a, v2) s3_2 = s3_1 t_13_2 = f_t_max(s1_2, s3_2) z = z / a axes[0].plot(z, np.abs(s1_1 / p_max), z, np.abs(s3_1 / p_max), z, np.abs(t_13_1/ p_max)) axes[1].plot(z, np.abs(s1_2 / p_max), z, np.abs(s3_2 / p_max), z, np.abs(t_13_2/ p_max)) axes[0].legend([r'$\sigma_1$', r'$\sigma_2$', r'$\tau_{max}$']) axes[1].legend([r'$\sigma_1$', r'$\sigma_2$', r'$\tau_{max}$']) axes[0].set_xlabel('$z/a$') axes[1].set_xlabel('$z/a$') axes[0].set_ylabel(r'$\frac{\sigma_1, \sigma_3, \tau_{1/2}}{p_{max}}$') axes[0].set_title('Sphere 1') axes[1].set_title('Sphere 2') plt.tight_layout() plt.show()
In [70]:
plot_stresses()
(not running untrusted Javascript)
In [71]:
w = interactive(plot_stresses, v1=(0.2, 0.5), v2=(0.2, 0.5), E1=(0.0, 50.0E6), E2=(0.0, 50.0E6), d1=(-10.0, 10.0), d2=(-10.0, 10.0))
In [72]:
display(w)
(not running untrusted Javascript)
None
In [ ]: