Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/materials-science/crystal_structure.tex
51 views
unlisted
1
\documentclass[a4paper, 11pt]{article}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath, amssymb, amsthm}
5
\usepackage{graphicx}
6
\usepackage{siunitx}
7
\usepackage{booktabs}
8
\usepackage{float}
9
\usepackage{geometry}
10
\geometry{margin=1in}
11
\usepackage[makestderr]{pythontex}
12
13
\newtheorem{theorem}{Theorem}[section]
14
\newtheorem{definition}[theorem]{Definition}
15
16
\title{Crystal Structure Analysis: Unit Cells, Miller Indices,\\and X-Ray Diffraction Patterns}
17
\author{Materials Science Laboratory}
18
\date{\today}
19
20
\begin{document}
21
\maketitle
22
23
\begin{abstract}
24
This technical report presents a comprehensive analysis of crystal structures in materials science. We examine unit cell geometry, Miller index notation, interplanar spacing calculations, and X-ray diffraction pattern simulation. Computational analysis using Python demonstrates structure factor calculations and powder diffraction profiles for common crystal systems.
25
\end{abstract}
26
27
\section{Introduction}
28
29
Crystallography forms the foundation for understanding material properties. The periodic arrangement of atoms determines mechanical, electrical, and optical characteristics.
30
31
\begin{definition}[Miller Indices]
32
Miller indices $(hkl)$ describe the orientation of crystal planes through the reciprocals of the intercepts on crystallographic axes, reduced to the smallest integers.
33
\end{definition}
34
35
\section{Unit Cell Geometry}
36
37
\begin{pycode}
38
import numpy as np
39
import matplotlib.pyplot as plt
40
from mpl_toolkits.mplot3d import Axes3D
41
42
plt.rc('text', usetex=True)
43
plt.rc('font', family='serif', size=9)
44
np.random.seed(42)
45
46
# Lattice parameters for different crystal systems
47
# FCC Aluminum
48
a_Al = 4.05 # Angstroms
49
# BCC Iron
50
a_Fe = 2.87
51
# HCP Titanium
52
a_Ti = 2.95
53
c_Ti = 4.68
54
55
# Atomic positions for FCC
56
fcc_positions = np.array([
57
[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5]
58
])
59
60
# Atomic positions for BCC
61
bcc_positions = np.array([
62
[0, 0, 0], [0.5, 0.5, 0.5]
63
])
64
65
# Coordination numbers
66
CN_fcc = 12
67
CN_bcc = 8
68
CN_hcp = 12
69
70
# Atomic packing fractions
71
APF_fcc = np.pi * np.sqrt(2) / 6
72
APF_bcc = np.pi * np.sqrt(3) / 8
73
APF_hcp = np.pi * np.sqrt(2) / 6
74
75
fig = plt.figure(figsize=(12, 8))
76
77
# FCC unit cell
78
ax1 = fig.add_subplot(2, 3, 1, projection='3d')
79
for pos in fcc_positions:
80
ax1.scatter(*pos, s=200, c='blue', alpha=0.8)
81
# Draw unit cell edges
82
for i in [0, 1]:
83
for j in [0, 1]:
84
ax1.plot([i, i], [j, j], [0, 1], 'k-', alpha=0.3)
85
ax1.plot([i, i], [0, 1], [j, j], 'k-', alpha=0.3)
86
ax1.plot([0, 1], [i, i], [j, j], 'k-', alpha=0.3)
87
ax1.set_xlabel('x')
88
ax1.set_ylabel('y')
89
ax1.set_zlabel('z')
90
ax1.set_title('FCC Unit Cell')
91
92
# BCC unit cell
93
ax2 = fig.add_subplot(2, 3, 2, projection='3d')
94
for pos in bcc_positions:
95
ax2.scatter(*pos, s=200, c='red', alpha=0.8)
96
for i in [0, 1]:
97
for j in [0, 1]:
98
ax2.plot([i, i], [j, j], [0, 1], 'k-', alpha=0.3)
99
ax2.plot([i, i], [0, 1], [j, j], 'k-', alpha=0.3)
100
ax2.plot([0, 1], [i, i], [j, j], 'k-', alpha=0.3)
101
ax2.set_xlabel('x')
102
ax2.set_ylabel('y')
103
ax2.set_zlabel('z')
104
ax2.set_title('BCC Unit Cell')
105
106
# Packing fraction comparison
107
ax3 = fig.add_subplot(2, 3, 3)
108
structures = ['FCC', 'BCC', 'HCP', 'SC']
109
apfs = [APF_fcc, APF_bcc, APF_hcp, np.pi/6]
110
colors = ['blue', 'red', 'green', 'orange']
111
bars = ax3.bar(structures, apfs, color=colors, alpha=0.7)
112
ax3.set_ylabel('Atomic Packing Fraction')
113
ax3.set_title('Packing Efficiency')
114
ax3.grid(True, alpha=0.3, axis='y')
115
for bar, apf in zip(bars, apfs):
116
ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
117
f'{apf:.3f}', ha='center', fontsize=8)
118
119
# Coordination number
120
ax4 = fig.add_subplot(2, 3, 4)
121
cn_values = [CN_fcc, CN_bcc, CN_hcp, 6]
122
ax4.bar(structures, cn_values, color=colors, alpha=0.7)
123
ax4.set_ylabel('Coordination Number')
124
ax4.set_title('Nearest Neighbors')
125
ax4.grid(True, alpha=0.3, axis='y')
126
127
# Lattice parameter comparison
128
ax5 = fig.add_subplot(2, 3, 5)
129
materials = ['Al (FCC)', 'Fe (BCC)', 'Cu (FCC)', 'Ti (HCP)']
130
a_values = [4.05, 2.87, 3.61, 2.95]
131
ax5.barh(materials, a_values, color=['blue', 'red', 'cyan', 'green'], alpha=0.7)
132
ax5.set_xlabel('Lattice Parameter a (A)')
133
ax5.set_title('Lattice Parameters')
134
ax5.grid(True, alpha=0.3, axis='x')
135
136
# c/a ratio for HCP
137
ax6 = fig.add_subplot(2, 3, 6)
138
hcp_materials = ['Ti', 'Mg', 'Zn', 'Cd', 'Ideal']
139
ca_ratios = [1.587, 1.624, 1.856, 1.886, 1.633]
140
colors_hcp = ['green', 'purple', 'orange', 'brown', 'gray']
141
ax6.bar(hcp_materials, ca_ratios, color=colors_hcp, alpha=0.7)
142
ax6.axhline(y=1.633, color='red', linestyle='--', alpha=0.7, label='Ideal')
143
ax6.set_ylabel('c/a Ratio')
144
ax6.set_title('HCP c/a Ratios')
145
ax6.grid(True, alpha=0.3, axis='y')
146
147
plt.tight_layout()
148
plt.savefig('crystal_structure_plot1.pdf', bbox_inches='tight', dpi=150)
149
plt.close()
150
\end{pycode}
151
152
\begin{figure}[H]
153
\centering
154
\includegraphics[width=0.95\textwidth]{crystal_structure_plot1.pdf}
155
\caption{Unit cell structures and crystallographic parameters for common crystal systems.}
156
\end{figure}
157
158
\begin{table}[H]
159
\centering
160
\caption{Crystal Structure Properties}
161
\begin{tabular}{lcccc}
162
\toprule
163
\textbf{Structure} & \textbf{APF} & \textbf{CN} & \textbf{Atoms/Cell} & \textbf{Examples} \\
164
\midrule
165
FCC & \py{f"{APF_fcc:.3f}"} & \py{CN_fcc} & 4 & Al, Cu, Au \\
166
BCC & \py{f"{APF_bcc:.3f}"} & \py{CN_bcc} & 2 & Fe, W, Cr \\
167
HCP & \py{f"{APF_hcp:.3f}"} & \py{CN_hcp} & 2 & Ti, Mg, Zn \\
168
SC & \py{f"{np.pi/6:.3f}"} & 6 & 1 & Po \\
169
\bottomrule
170
\end{tabular}
171
\end{table}
172
173
\section{Miller Indices and Interplanar Spacing}
174
175
\begin{theorem}[Interplanar Spacing]
176
For a cubic crystal system, the spacing between $(hkl)$ planes is:
177
\begin{equation}
178
d_{hkl} = \frac{a}{\sqrt{h^2 + k^2 + l^2}}
179
\end{equation}
180
\end{theorem}
181
182
\begin{pycode}
183
# Miller indices calculations
184
def d_spacing_cubic(h, k, l, a):
185
"""Calculate interplanar spacing for cubic system"""
186
return a / np.sqrt(h**2 + k**2 + l**2)
187
188
def d_spacing_hexagonal(h, k, l, a, c):
189
"""Calculate interplanar spacing for hexagonal system"""
190
return 1 / np.sqrt((4/3)*(h**2 + h*k + k**2)/a**2 + l**2/c**2)
191
192
# Common planes for FCC
193
planes_fcc = [(1,1,1), (2,0,0), (2,2,0), (3,1,1), (2,2,2), (4,0,0)]
194
d_values_Al = [d_spacing_cubic(h,k,l, a_Al) for h,k,l in planes_fcc]
195
196
# Common planes for BCC
197
planes_bcc = [(1,1,0), (2,0,0), (2,1,1), (2,2,0), (3,1,0), (2,2,2)]
198
d_values_Fe = [d_spacing_cubic(h,k,l, a_Fe) for h,k,l in planes_bcc]
199
200
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
201
202
# d-spacing vs plane index for Al
203
plane_labels = [f'({h}{k}{l})' for h,k,l in planes_fcc]
204
axes[0, 0].bar(plane_labels, d_values_Al, color='blue', alpha=0.7)
205
axes[0, 0].set_ylabel('d-spacing (A)')
206
axes[0, 0].set_title('FCC Aluminum d-spacings')
207
axes[0, 0].tick_params(axis='x', rotation=45)
208
axes[0, 0].grid(True, alpha=0.3, axis='y')
209
210
# d-spacing vs plane index for Fe
211
plane_labels_bcc = [f'({h}{k}{l})' for h,k,l in planes_bcc]
212
axes[0, 1].bar(plane_labels_bcc, d_values_Fe, color='red', alpha=0.7)
213
axes[0, 1].set_ylabel('d-spacing (A)')
214
axes[0, 1].set_title('BCC Iron d-spacings')
215
axes[0, 1].tick_params(axis='x', rotation=45)
216
axes[0, 1].grid(True, alpha=0.3, axis='y')
217
218
# Multiplicity factors
219
multiplicities_fcc = [8, 6, 12, 24, 8, 6]
220
multiplicities_bcc = [12, 6, 24, 12, 24, 8]
221
222
axes[1, 0].bar(plane_labels, multiplicities_fcc, color='green', alpha=0.7)
223
axes[1, 0].set_ylabel('Multiplicity')
224
axes[1, 0].set_title('FCC Plane Multiplicities')
225
axes[1, 0].tick_params(axis='x', rotation=45)
226
axes[1, 0].grid(True, alpha=0.3, axis='y')
227
228
# 1/d^2 relationship
229
h_range = np.arange(1, 6)
230
for k in [0, 1, 2]:
231
inv_d_sq = [(h**2 + k**2) / a_Al**2 for h in h_range]
232
axes[1, 1].plot(h_range, inv_d_sq, 'o-', label=f'k={k}')
233
axes[1, 1].set_xlabel('h index')
234
axes[1, 1].set_ylabel('$1/d^2$ (A$^{-2}$)')
235
axes[1, 1].set_title('$1/d^2$ vs Miller Index')
236
axes[1, 1].legend(loc='upper left', fontsize=8)
237
axes[1, 1].grid(True, alpha=0.3)
238
239
plt.tight_layout()
240
plt.savefig('crystal_structure_plot2.pdf', bbox_inches='tight', dpi=150)
241
plt.close()
242
\end{pycode}
243
244
\begin{figure}[H]
245
\centering
246
\includegraphics[width=0.95\textwidth]{crystal_structure_plot2.pdf}
247
\caption{Interplanar spacing and multiplicity factors for FCC and BCC structures.}
248
\end{figure}
249
250
\section{X-Ray Diffraction Simulation}
251
252
\begin{definition}[Bragg's Law]
253
Constructive interference occurs when:
254
\begin{equation}
255
n\lambda = 2d_{hkl}\sin\theta
256
\end{equation}
257
\end{definition}
258
259
\begin{pycode}
260
# XRD simulation
261
lambda_Cu = 1.5406 # Cu K-alpha wavelength (Angstroms)
262
263
def bragg_angle(d, wavelength=lambda_Cu):
264
"""Calculate Bragg angle for given d-spacing"""
265
sin_theta = wavelength / (2 * d)
266
if sin_theta <= 1:
267
return np.rad2deg(np.arcsin(sin_theta))
268
return None
269
270
# Structure factor for FCC
271
def structure_factor_fcc(h, k, l):
272
"""Calculate structure factor magnitude squared for FCC"""
273
if (h+k) % 2 == 0 and (k+l) % 2 == 0 and (h+l) % 2 == 0:
274
return 16 # All even or all odd
275
elif (h+k) % 2 != 0 or (k+l) % 2 != 0 or (h+l) % 2 != 0:
276
if (h % 2 == k % 2 == l % 2):
277
return 16
278
return 0
279
280
# Structure factor for BCC
281
def structure_factor_bcc(h, k, l):
282
"""Calculate structure factor magnitude squared for BCC"""
283
if (h + k + l) % 2 == 0:
284
return 4
285
return 0
286
287
# Generate XRD pattern
288
two_theta_Al = []
289
intensity_Al = []
290
for h, k, l in planes_fcc:
291
d = d_spacing_cubic(h, k, l, a_Al)
292
theta = bragg_angle(d)
293
if theta and theta < 90:
294
two_theta_Al.append(2 * theta)
295
F2 = structure_factor_fcc(h, k, l)
296
mult = multiplicities_fcc[planes_fcc.index((h,k,l))]
297
intensity_Al.append(F2 * mult / (np.sin(np.deg2rad(theta))**2 * np.cos(np.deg2rad(theta))))
298
299
two_theta_Fe = []
300
intensity_Fe = []
301
for h, k, l in planes_bcc:
302
d = d_spacing_cubic(h, k, l, a_Fe)
303
theta = bragg_angle(d)
304
if theta and theta < 90:
305
two_theta_Fe.append(2 * theta)
306
F2 = structure_factor_bcc(h, k, l)
307
mult = multiplicities_bcc[planes_bcc.index((h,k,l))]
308
intensity_Fe.append(F2 * mult / (np.sin(np.deg2rad(theta))**2 * np.cos(np.deg2rad(theta))))
309
310
# Normalize intensities
311
intensity_Al = np.array(intensity_Al) / max(intensity_Al) * 100
312
intensity_Fe = np.array(intensity_Fe) / max(intensity_Fe) * 100
313
314
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
315
316
# XRD pattern for Al
317
for tt, I, (h,k,l) in zip(two_theta_Al, intensity_Al, planes_fcc):
318
axes[0, 0].vlines(tt, 0, I, colors='blue', linewidth=2)
319
if I > 20:
320
axes[0, 0].text(tt, I+5, f'({h}{k}{l})', ha='center', fontsize=7)
321
axes[0, 0].set_xlabel(r'2$\theta$ (degrees)')
322
axes[0, 0].set_ylabel('Relative Intensity')
323
axes[0, 0].set_title('XRD Pattern: FCC Aluminum')
324
axes[0, 0].set_xlim([20, 120])
325
axes[0, 0].grid(True, alpha=0.3)
326
327
# XRD pattern for Fe
328
for tt, I, (h,k,l) in zip(two_theta_Fe, intensity_Fe, planes_bcc):
329
axes[0, 1].vlines(tt, 0, I, colors='red', linewidth=2)
330
if I > 20:
331
axes[0, 1].text(tt, I+5, f'({h}{k}{l})', ha='center', fontsize=7)
332
axes[0, 1].set_xlabel(r'2$\theta$ (degrees)')
333
axes[0, 1].set_ylabel('Relative Intensity')
334
axes[0, 1].set_title('XRD Pattern: BCC Iron')
335
axes[0, 1].set_xlim([20, 120])
336
axes[0, 1].grid(True, alpha=0.3)
337
338
# Peak broadening simulation (Scherrer equation)
339
crystallite_sizes = np.linspace(10, 100, 50) # nm
340
K = 0.9 # Scherrer constant
341
beta = (K * lambda_Cu * 0.1) / (crystallite_sizes * np.cos(np.deg2rad(22))) # radians
342
beta_deg = np.rad2deg(beta)
343
344
axes[1, 0].plot(crystallite_sizes, beta_deg, 'b-', linewidth=1.5)
345
axes[1, 0].set_xlabel('Crystallite Size (nm)')
346
axes[1, 0].set_ylabel('Peak Width FWHM (degrees)')
347
axes[1, 0].set_title('Scherrer Broadening')
348
axes[1, 0].grid(True, alpha=0.3)
349
350
# Simulated powder pattern with peak shapes
351
two_theta_range = np.linspace(20, 120, 1000)
352
pattern = np.zeros_like(two_theta_range)
353
FWHM = 0.3 # degrees
354
355
for tt, I in zip(two_theta_Al, intensity_Al):
356
# Pseudo-Voigt peak shape
357
pattern += I * np.exp(-4*np.log(2)*((two_theta_range - tt)/FWHM)**2)
358
359
axes[1, 1].plot(two_theta_range, pattern, 'b-', linewidth=1)
360
axes[1, 1].set_xlabel(r'2$\theta$ (degrees)')
361
axes[1, 1].set_ylabel('Intensity')
362
axes[1, 1].set_title('Simulated Powder Pattern (Al)')
363
axes[1, 1].grid(True, alpha=0.3)
364
365
plt.tight_layout()
366
plt.savefig('crystal_structure_plot3.pdf', bbox_inches='tight', dpi=150)
367
plt.close()
368
369
# Calculate first peak position
370
first_peak_Al = two_theta_Al[0] if two_theta_Al else 0
371
\end{pycode}
372
373
\begin{figure}[H]
374
\centering
375
\includegraphics[width=0.95\textwidth]{crystal_structure_plot3.pdf}
376
\caption{X-ray diffraction patterns and peak characteristics for FCC and BCC metals.}
377
\end{figure}
378
379
\section{Structure Factor Analysis}
380
381
\begin{pycode}
382
# Systematic absences and structure factors
383
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
384
385
# Generate all (hkl) combinations
386
hkl_list = []
387
F2_fcc_list = []
388
F2_bcc_list = []
389
390
for h in range(5):
391
for k in range(5):
392
for l in range(5):
393
if h == k == l == 0:
394
continue
395
hkl_list.append((h, k, l))
396
F2_fcc_list.append(structure_factor_fcc(h, k, l))
397
F2_bcc_list.append(structure_factor_bcc(h, k, l))
398
399
# Plot allowed vs forbidden reflections
400
N_squared = [h**2 + k**2 + l**2 for h, k, l in hkl_list]
401
402
# FCC selection rules
403
fcc_allowed = [N for N, F2 in zip(N_squared, F2_fcc_list) if F2 > 0]
404
fcc_forbidden = [N for N, F2 in zip(N_squared, F2_fcc_list) if F2 == 0]
405
406
axes[0, 0].hist(fcc_allowed, bins=range(1, max(N_squared)+2), alpha=0.7,
407
color='blue', label='Allowed', edgecolor='black')
408
axes[0, 0].hist(fcc_forbidden, bins=range(1, max(N_squared)+2), alpha=0.5,
409
color='red', label='Forbidden', edgecolor='black')
410
axes[0, 0].set_xlabel('$h^2 + k^2 + l^2$')
411
axes[0, 0].set_ylabel('Count')
412
axes[0, 0].set_title('FCC Selection Rules')
413
axes[0, 0].legend(loc='upper right', fontsize=8)
414
415
# BCC selection rules
416
bcc_allowed = [N for N, F2 in zip(N_squared, F2_bcc_list) if F2 > 0]
417
bcc_forbidden = [N for N, F2 in zip(N_squared, F2_bcc_list) if F2 == 0]
418
419
axes[0, 1].hist(bcc_allowed, bins=range(1, max(N_squared)+2), alpha=0.7,
420
color='blue', label='Allowed', edgecolor='black')
421
axes[0, 1].hist(bcc_forbidden, bins=range(1, max(N_squared)+2), alpha=0.5,
422
color='red', label='Forbidden', edgecolor='black')
423
axes[0, 1].set_xlabel('$h^2 + k^2 + l^2$')
424
axes[0, 1].set_ylabel('Count')
425
axes[0, 1].set_title('BCC Selection Rules')
426
axes[0, 1].legend(loc='upper right', fontsize=8)
427
428
# Atomic scattering factor (approximate)
429
sin_theta_lambda = np.linspace(0, 1.5, 100)
430
# Simplified atomic scattering factors
431
f_Al = 13 * np.exp(-10 * sin_theta_lambda**2)
432
f_Fe = 26 * np.exp(-8 * sin_theta_lambda**2)
433
f_Cu = 29 * np.exp(-9 * sin_theta_lambda**2)
434
435
axes[1, 0].plot(sin_theta_lambda, f_Al, 'b-', linewidth=1.5, label='Al (Z=13)')
436
axes[1, 0].plot(sin_theta_lambda, f_Fe, 'r-', linewidth=1.5, label='Fe (Z=26)')
437
axes[1, 0].plot(sin_theta_lambda, f_Cu, 'g-', linewidth=1.5, label='Cu (Z=29)')
438
axes[1, 0].set_xlabel(r'$\sin\theta/\lambda$ (A$^{-1}$)')
439
axes[1, 0].set_ylabel('Atomic Scattering Factor')
440
axes[1, 0].set_title('Atomic Scattering Factors')
441
axes[1, 0].legend(loc='upper right', fontsize=8)
442
axes[1, 0].grid(True, alpha=0.3)
443
444
# Temperature factor (Debye-Waller)
445
B_values = [0.5, 1.0, 2.0, 4.0] # Debye-Waller parameter
446
for B in B_values:
447
DW = np.exp(-B * sin_theta_lambda**2)
448
axes[1, 1].plot(sin_theta_lambda, DW, linewidth=1.5, label=f'B = {B}')
449
axes[1, 1].set_xlabel(r'$\sin\theta/\lambda$ (A$^{-1}$)')
450
axes[1, 1].set_ylabel('Debye-Waller Factor')
451
axes[1, 1].set_title('Temperature Factor')
452
axes[1, 1].legend(loc='upper right', fontsize=8)
453
axes[1, 1].grid(True, alpha=0.3)
454
455
plt.tight_layout()
456
plt.savefig('crystal_structure_plot4.pdf', bbox_inches='tight', dpi=150)
457
plt.close()
458
\end{pycode}
459
460
\begin{figure}[H]
461
\centering
462
\includegraphics[width=0.95\textwidth]{crystal_structure_plot4.pdf}
463
\caption{Structure factor analysis: selection rules and scattering factors.}
464
\end{figure}
465
466
\section{Lattice Strain and Defect Analysis}
467
468
\begin{pycode}
469
# Williamson-Hall analysis for strain/size separation
470
# beta * cos(theta) = K*lambda/D + 4*epsilon*sin(theta)
471
472
# Simulated data with strain
473
D_actual = 50 # nm
474
epsilon_actual = 0.002 # strain
475
476
sin_theta_values = np.sin(np.deg2rad(np.array(two_theta_Al)/2))
477
cos_theta_values = np.cos(np.deg2rad(np.array(two_theta_Al)/2))
478
479
# Calculate expected broadening
480
beta_size = K * lambda_Cu * 0.1 / D_actual
481
beta_strain = 4 * epsilon_actual * sin_theta_values
482
beta_total = np.sqrt(beta_size**2 + beta_strain**2)
483
484
# Williamson-Hall plot coordinates
485
x_WH = 4 * sin_theta_values / lambda_Cu
486
y_WH = beta_total * cos_theta_values / lambda_Cu
487
488
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
489
490
# Williamson-Hall plot
491
axes[0, 0].plot(x_WH, y_WH, 'bo-', markersize=8)
492
# Linear fit
493
z_WH = np.polyfit(x_WH, y_WH, 1)
494
p_WH = np.poly1d(z_WH)
495
x_fit = np.linspace(0, max(x_WH)*1.1, 100)
496
axes[0, 0].plot(x_fit, p_WH(x_fit), 'r--', linewidth=1.5)
497
axes[0, 0].set_xlabel(r'$4\sin\theta/\lambda$')
498
axes[0, 0].set_ylabel(r'$\beta\cos\theta/\lambda$')
499
axes[0, 0].set_title('Williamson-Hall Plot')
500
axes[0, 0].grid(True, alpha=0.3)
501
502
# Extract parameters from fit
503
epsilon_fit = z_WH[0]
504
D_fit = K / z_WH[1] if z_WH[1] > 0 else 0
505
506
# Dislocation density estimation
507
rho_disl = 2 * np.sqrt(3) * epsilon_actual / (a_Al * 1e-8 * 100) # per m^2
508
509
# Microstrain distribution
510
strain_range = np.linspace(-0.01, 0.01, 100)
511
strain_dist = np.exp(-strain_range**2 / (2 * epsilon_actual**2))
512
axes[0, 1].plot(strain_range*100, strain_dist, 'b-', linewidth=1.5)
513
axes[0, 1].axvline(x=epsilon_actual*100, color='r', linestyle='--', alpha=0.7)
514
axes[0, 1].axvline(x=-epsilon_actual*100, color='r', linestyle='--', alpha=0.7)
515
axes[0, 1].set_xlabel('Microstrain (%)')
516
axes[0, 1].set_ylabel('Probability')
517
axes[0, 1].set_title('Microstrain Distribution')
518
axes[0, 1].grid(True, alpha=0.3)
519
520
# Crystallite size distribution (lognormal)
521
D_range = np.linspace(1, 200, 200)
522
sigma_D = 0.3
523
D_median = 50
524
size_dist = (1/(D_range * sigma_D * np.sqrt(2*np.pi))) * \
525
np.exp(-(np.log(D_range) - np.log(D_median))**2 / (2*sigma_D**2))
526
axes[1, 0].plot(D_range, size_dist, 'b-', linewidth=1.5)
527
axes[1, 0].axvline(x=D_median, color='r', linestyle='--', alpha=0.7, label='Median')
528
axes[1, 0].set_xlabel('Crystallite Size (nm)')
529
axes[1, 0].set_ylabel('Probability Density')
530
axes[1, 0].set_title('Crystallite Size Distribution')
531
axes[1, 0].legend(loc='upper right', fontsize=8)
532
axes[1, 0].grid(True, alpha=0.3)
533
534
# Stacking fault probability
535
# Affects peak positions and shapes
536
SF_prob = np.linspace(0, 0.1, 100)
537
# Peak shift for FCC (111)
538
delta_theta = 90 * np.sqrt(3) * SF_prob / (np.pi**2)
539
540
axes[1, 1].plot(SF_prob*100, delta_theta, 'b-', linewidth=1.5)
541
axes[1, 1].set_xlabel('Stacking Fault Probability (%)')
542
axes[1, 1].set_ylabel('Peak Shift (degrees)')
543
axes[1, 1].set_title('Stacking Fault Effect on (111) Peak')
544
axes[1, 1].grid(True, alpha=0.3)
545
546
plt.tight_layout()
547
plt.savefig('crystal_structure_plot5.pdf', bbox_inches='tight', dpi=150)
548
plt.close()
549
\end{pycode}
550
551
\begin{figure}[H]
552
\centering
553
\includegraphics[width=0.95\textwidth]{crystal_structure_plot5.pdf}
554
\caption{Microstructural analysis: Williamson-Hall plot and defect characterization.}
555
\end{figure}
556
557
\begin{table}[H]
558
\centering
559
\caption{Microstructural Parameters}
560
\begin{tabular}{lcc}
561
\toprule
562
\textbf{Parameter} & \textbf{Value} & \textbf{Unit} \\
563
\midrule
564
Crystallite Size & \py{f"{D_actual:.0f}"} & nm \\
565
Microstrain & \py{f"{epsilon_actual*100:.2f}"} & \% \\
566
Dislocation Density & \py{f"{rho_disl:.2e}"} & m$^{-2}$ \\
567
\bottomrule
568
\end{tabular}
569
\end{table}
570
571
\section{Conclusions}
572
573
This analysis of crystal structures demonstrated:
574
575
\begin{enumerate}
576
\item \textbf{Unit Cell Geometry}: FCC has the highest packing efficiency (APF = \py{f"{APF_fcc:.3f}"}) with coordination number 12.
577
578
\item \textbf{Miller Indices}: Interplanar spacing follows $d_{hkl} = a/\sqrt{h^2+k^2+l^2}$ for cubic systems, with the (111) plane having the largest d-spacing in FCC.
579
580
\item \textbf{XRD Patterns}: Selection rules determine allowed reflections (all odd or all even for FCC, $h+k+l$ = even for BCC).
581
582
\item \textbf{Structure Factors}: Systematic absences provide fingerprints for crystal structure identification.
583
584
\item \textbf{Defect Analysis}: Williamson-Hall analysis separates size ($D = \py{f"{D_actual:.0f}"}$ nm) and strain ($\epsilon = \py{f"{epsilon_actual*100:.2f}"}\%$) contributions to peak broadening.
585
\end{enumerate}
586
587
\end{document}
588
589