Skip to content

Commit 20f3c45

Browse files
committed
Multiple changes and updates for paper
1 parent f5d8178 commit 20f3c45

File tree

1 file changed

+57
-13
lines changed

1 file changed

+57
-13
lines changed

slippy/contact/hertz.py

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def solve_hertz_line(*, r_rel: float = None,
2828
max_shear_stress: float = None,
2929
max_von_mises: float = None,
3030
contact_width: float = None,
31-
_system: dict = None):
31+
_system: dict = None) -> HertzLineSolution:
3232
"""
3333
Finds remaining hertz parameter for a line contact
3434
@@ -333,7 +333,7 @@ def solve_hertz_point(*, r_rel=None,
333333
if is_none != 'e_star':
334334
_system[is_none] = max(solve((1 - 2 * _system['v1']) * ((6 * _system['load'] * _system['e_star'] ** 2 /
335335
np.pi ** 3 / _system['r_rel'] ** 2) ** (
336-
1 / 3)) / 3 -
336+
1 / 3)) / 3 -
337337
max_tensile_stress, _system[is_none]))
338338
elif sum(mats_none) == 2:
339339
is_none = None # To stop the materials being solved for next
@@ -514,10 +514,7 @@ def hertz_full(r1: typing.Union[typing.Sequence, float], r2: typing.Union[typing
514514
Returns
515515
-------
516516
results : dict
517-
Dictionary of the results:
518-
line contact : True is it is a line contact
519-
r_eff : The effective radius of the contact
520-
517+
Dictionary of the results the keys available in the dictionary will depend on the contact solved.
521518
522519
See Also
523520
--------
@@ -530,7 +527,7 @@ def hertz_full(r1: typing.Union[typing.Sequence, float], r2: typing.Union[typing
530527
radii should be given in mm and the load should be given in N. etc.
531528
532529
The range for the k parameter (ratio of the contact radii) for elliptical
533-
contacts is set to 10e-5, practically contacts which are more smaller
530+
contacts is set to 1e-4, practically contacts which are more smaller
534531
ratios will not converge, in these cases consider treating as a line
535532
contact.
536533
@@ -656,14 +653,15 @@ def line_opt_fn(psi, v1):
656653
_displacement_spherical_contact(moduli[1], v[1], a, p0)]
657654
results['pressure_f'] = _pressure_spherical_contact(a, p0)
658655
results['max_tensile_stress_b'] = [(1 - 2 * v1) * p0 / 3 for v1 in v]
659-
results['stress_z_axis_b'] = [_stress_z_axis_spherical(a, p0, v1)
660-
for v1 in v]
656+
results['stress_z_axis_b_f'] = [_stress_z_axis_spherical(a, p0, v1) for v1 in v]
661657

662658
# The following is taken from Deeg
663659
results['max_von_mises_stress_b'] = [p0 * (1.30075 + 0.87825 * v1 +
664660
0.54373 * v1 ** 2) for v1 in v]
665661
results['max_von_mises_depth_b'] = [a * (0.38167 + 0.33136 * v1) for v1 in v]
666662

663+
results['stress_surface_axis_b_f'] = [_stress_surface_spherical(a, p0, v1) for v1 in v]
664+
667665
shear_opts = [
668666
optimize.minimize(lambda psi: -0.5 * (-1 + 3 / 2 / (1 + psi ** 2) + psi * (1 + v1) * np.arctan(1 / psi)),
669667
np.array([0.48086782]), bounds=[[0, 10]]) for v1 in v]
@@ -1053,13 +1051,59 @@ def stress(z):
10531051
Returns
10541052
-------
10551053
stress : dict
1056-
The stresses at the points of interest with keys: {'sigma_r',
1057-
'sigma_theta', 'sigma_z'}
1054+
The stresses at the points of interest with keys: {'sigma_r', 'sigma_theta', 'sigma_z'}
1055+
each value will be an array with the same shape as r
10581056
"""
10591057
z = np.asarray(z)
1060-
sig_r = -1 * p0 * (1 + v) * (1 - (z / a) * np.arctan(a / z)) + 1 / (0.5 * (1 + z ** 2 / a ** 2))
1058+
sig_r = p0 * (- (1 + v) * (1 - (z / a) * np.arctan(a / z)) + 0.5 * 1 / (1 + z ** 2 / a ** 2))
10611059
sig_theta = sig_r.copy()
1062-
sig_z = -1 * p0 * (1 + z ** 2 / a ** 2) ** -1
1060+
sig_z = -p0 / (1 + z ** 2 / a ** 2)
1061+
return {'sigma_r': sig_r, 'sigma_theta': sig_theta, 'sigma_z': sig_z}
1062+
1063+
return stress
1064+
1065+
1066+
def _stress_surface_spherical(a, p0, v):
1067+
""" Gives a list of closures for the stresses on each surface
1068+
1069+
Parameters
1070+
----------
1071+
a : float
1072+
The contact radius
1073+
p0 : float
1074+
The maximum contact pressure
1075+
v : float
1076+
The possions ratio of the surface
1077+
"""
1078+
1079+
def stress(r):
1080+
"""Stresses on the surface for a spherical contact
1081+
1082+
Parameters
1083+
----------
1084+
r : array-like
1085+
The radial coordinate of the points of interest
1086+
1087+
Returns
1088+
-------
1089+
stresses : dict
1090+
The stresses at each point on the surface, with keys: {'sigma_r', 'sigma_theta', 'sigma_z'}
1091+
each value will be an array with the same shape as r
1092+
"""
1093+
r = np.asarray(r)
1094+
r2 = r ** 2
1095+
r2a2 = r2 / a ** 2
1096+
inside = r <= a
1097+
sig_r, sig_theta, sig_z = np.zeros_like(r), np.zeros_like(r), np.zeros_like(r)
1098+
sig_r[inside] = p0 * ((1 - 2 * v) / 3 * (a ** 2 / r[inside] ** 2) * (1 - (1 - r2a2[inside]) ** (3 / 2)) -
1099+
np.sqrt(1 - r2a2[inside]))
1100+
sig_theta[inside] = -p0 * ((1 - 2 * v) / 3 * (a ** 2 / r[inside] ** 2) * (1 - (1 - r2a2[inside]) ** (3 / 2)) -
1101+
2 * v * np.sqrt(1 - r2a2[inside]))
1102+
sig_z[inside] = -np.sqrt(1 - r2a2[inside]) * p0
1103+
outside = np.logical_not(inside)
1104+
sr_out = p0*(1-2*v)*a**2/3/r2[outside]
1105+
sig_r[outside] = sr_out
1106+
sig_theta[outside] = -sr_out
10631107
return {'sigma_r': sig_r, 'sigma_theta': sig_theta, 'sigma_z': sig_z}
10641108

10651109
return stress

0 commit comments

Comments
 (0)