🌐 EN | ζ—₯本θͺž (ζΊ–ε‚™δΈ­) Last sync: 2025-11-16

Chapter 2: Hardness and Impact Testing

Indentation and Dynamic Loading Methods

2.1 Hardness Testing Fundamentals

Hardness is resistance to plastic deformation or indentation. Common methods include Brinell, Vickers, Rockwell, and nanoindentation.

πŸ“ Hardness Definitions
Brinell Hardness (HB): $$HB = \frac{2F}{\pi D(D - \sqrt{D^2 - d^2})}$$ where $F$ is load (kgf), $D$ is ball diameter (mm), $d$ is indentation diameter (mm).

Vickers Hardness (HV): $$HV = \frac{1.854F}{d^2}$$ where $F$ is load (kgf), $d$ is diagonal length (mm).

πŸ’» Code Example 1: Hardness Calculation

# Requirements:
# - Python 3.9+
# - numpy>=1.24.0, <2.0.0

import numpy as np

class HardnessTester:
    """Hardness testing calculator"""
    
    def brinell_hardness(self, force, ball_diameter, indent_diameter):
        """Calculate Brinell hardness (HB)"""
        F = force  # kgf
        D = ball_diameter  # mm
        d = indent_diameter  # mm
        HB = (2 * F) / (np.pi * D * (D - np.sqrt(D**2 - d**2)))
        return HB
    
    def vickers_hardness(self, force, diagonal):
        """Calculate Vickers hardness (HV)"""
        F = force  # kgf
        d = diagonal  # mm
        HV = 1.854 * F / (d**2)
        return HV
    
    def rockwell_c_hardness(self, depth):
        """Calculate Rockwell C hardness (HRC)"""
        HRC = 100 - 500 * depth  # depth in mm
        return HRC

tester = HardnessTester()

# Example calculations
hb = tester.brinell_hardness(force=3000, ball_diameter=10, indent_diameter=4.5)
hv = tester.vickers_hardness(force=30, diagonal=0.5)
hrc = tester.rockwell_c_hardness(depth=0.15)

print(f"Brinell Hardness: {hb:.1f} HB")
print(f"Vickers Hardness: {hv:.1f} HV")
print(f"Rockwell C Hardness: {hrc:.1f} HRC")

2.2 Hardness-Strength Correlations

Hardness correlates with tensile strength. For steels, UTS (MPa) β‰ˆ 3.45 Γ— HB.

πŸ’» Code Example 2: Hardness-Strength Conversion

# Requirements:
# - Python 3.9+
# - matplotlib>=3.7.0

def hardness_to_tensile_strength(hardness, method='HB', material='steel'):
    """Convert hardness to approximate tensile strength"""
    
    if material == 'steel':
        if method == 'HB':
            UTS = 3.45 * hardness
        elif method == 'HV':
            UTS = 3.2 * hardness
        elif method == 'HRC':
            UTS = (HRC + 18) * 10
    
    return UTS

hb_values = np.array([150, 200, 250, 300, 350])
uts_values = [hardness_to_tensile_strength(hb, 'HB') for hb in hb_values]

import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.plot(hb_values, uts_values, 'bo-', linewidth=2, markersize=8)
plt.xlabel('Brinell Hardness (HB)')
plt.ylabel('Tensile Strength (MPa)')
plt.title('Hardness-Strength Correlation for Steel')
plt.grid(True, alpha=0.3)
plt.show()

2.3 Impact Testing

Impact tests measure energy absorbed during dynamic loading. Charpy and Izod tests assess toughness and ductile-brittle transition.

πŸ“ Impact Energy
Charpy impact energy: $$E = mgh_0 - mgh_f = mgh_0(1 - \cos\alpha)$$ where $m$ is hammer mass, $h_0$ is initial height, $\alpha$ is swing angle.

πŸ’» Code Example 3: Impact Energy Calculation

class ImpactTest:
    """Charpy/Izod impact test calculator"""
    
    def __init__(self, hammer_mass=25, pendulum_length=0.75):
        self.mass = hammer_mass  # kg
        self.length = pendulum_length  # m
        self.g = 9.81  # m/s^2
    
    def calculate_energy(self, initial_angle, final_angle):
        """Calculate absorbed energy"""
        theta_0 = np.radians(initial_angle)
        theta_f = np.radians(final_angle)
        
        h_0 = self.length * (1 - np.cos(theta_0))
        h_f = self.length * (1 - np.cos(theta_f))
        
        E = self.mass * self.g * (h_0 - h_f)
        return E

impact = ImpactTest()
energy = impact.calculate_energy(initial_angle=140, final_angle=45)
print(f"Impact Energy Absorbed: {energy:.1f} J")

2.4 Ductile-Brittle Transition

Many materials exhibit transition from ductile to brittle behavior at low temperatures, critical for cryogenic applications.

πŸ’» Code Example 4: DBTT Analysis

def dbtt_curve(temperature, T_dbtt=-20, E_upper=200, E_lower=20):
    """Model ductile-brittle transition temperature (DBTT)"""
    # Sigmoid transition
    k = 0.1
    energy = E_lower + (E_upper - E_lower) / (1 + np.exp(-k * (temperature - T_dbtt)))
    return energy

temperatures = np.linspace(-100, 100, 200)
energies = dbtt_curve(temperatures)

plt.figure(figsize=(10, 6))
plt.plot(temperatures, energies, 'b-', linewidth=2)
plt.axvline(-20, color='r', linestyle='--', label='DBTT = -20Β°C')
plt.axhline(110, color='g', linestyle='--', alpha=0.5, label='50% Energy')
plt.xlabel('Temperature (Β°C)')
plt.ylabel('Impact Energy (J)')
plt.title('Ductile-Brittle Transition Curve')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

2.5 Nanoindentation

Nanoindentation measures mechanical properties at nanoscale using continuous load-depth measurement.

πŸ’» Code Example 5: Oliver-Pharr Analysis

def oliver_pharr_analysis(load, depth, tip_angle=70.3):
    """Oliver-Pharr method for nanoindentation"""
    # Berkovich indenter area function
    C = 24.5  # Constant for Berkovich
    A_c = C * depth**2
    
    # Hardness
    H = load / A_c
    
    # Reduced modulus (simplified)
    S = np.gradient(load, depth)[-1]  # Stiffness
    E_r = (np.sqrt(np.pi) / 2) * S / np.sqrt(A_c)
    
    return H, E_r, A_c

depths = np.linspace(0, 1000, 100)  # nm
loads = 0.1 * depths**1.5  # Simulated data

H, E_r, A_c = oliver_pharr_analysis(loads, depths)
print(f"Hardness: {H[-1]:.2f} GPa")
print(f"Reduced Modulus: {E_r:.1f} GPa")

2.6 Microhardness Mapping

Spatial hardness mapping reveals microstructural variations and phase distributions.

πŸ’» Code Example 6: Hardness Mapping

def generate_hardness_map(grid_size=20):
    """Generate synthetic hardness map"""
    x = np.linspace(0, 10, grid_size)
    y = np.linspace(0, 10, grid_size)
    X, Y = np.meshgrid(x, y)
    
    # Simulate hardness variation
    HV = 200 + 50 * np.sin(X) + 30 * np.cos(Y) + 10 * np.random.randn(grid_size, grid_size)
    
    return X, Y, HV

X, Y, HV = generate_hardness_map()

plt.figure(figsize=(10, 8))
contour = plt.contourf(X, Y, HV, levels=20, cmap='viridis')
plt.colorbar(contour, label='Vickers Hardness (HV)')
plt.xlabel('X Position (mm)')
plt.ylabel('Y Position (mm)')
plt.title('Microhardness Map')
plt.show()

2.7 Statistical Analysis

Multiple measurements and statistical analysis ensure reliable hardness characterization.

πŸ’» Code Example 7: Statistical Hardness Analysis

# Requirements:
# - Python 3.9+
# - scipy>=1.11.0

from scipy import stats

def analyze_hardness_data(measurements):
    """Statistical analysis of hardness measurements"""
    
    mean = np.mean(measurements)
    std = np.std(measurements, ddof=1)
    sem = stats.sem(measurements)
    
    # 95% confidence interval
    ci = stats.t.interval(0.95, len(measurements)-1, mean, sem)
    
    # Outlier detection (3-sigma)
    outliers = np.abs(measurements - mean) > 3 * std
    
    return {
        'mean': mean,
        'std': std,
        'cv': (std/mean)*100,
        'confidence_interval': ci,
        'outliers': np.where(outliers)[0]
    }

# Example dataset
hardness_data = np.array([220, 225, 218, 230, 222, 226, 219, 280, 224, 221])
results = analyze_hardness_data(hardness_data)

print(f"Mean Hardness: {results['mean']:.1f} Β± {results['std']:.1f} HV")
print(f"CV: {results['cv']:.2f}%")
print(f"95% CI: [{results['confidence_interval'][0]:.1f}, {results['confidence_interval'][1]:.1f}]")
print(f"Outliers at indices: {results['outliers']}")

πŸ“ Chapter Exercises

✏️ Exercises
  1. Calculate Brinell hardness for 3000 kgf load, 10 mm ball, 4.2 mm indent diameter.
  2. Estimate tensile strength of steel with 280 HB using empirical correlation.
  3. Determine impact energy absorbed in Charpy test with 140Β° initial and 50Β° final angles.
  4. Analyze DBTT curve and predict impact energy at -40Β°C.
  5. Perform statistical analysis on 10 hardness measurements and identify outliers.

Summary

Disclaimer